From ac8640bfd1e47c0d441b037485977907c94ed62e Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Wed, 29 Jan 2025 12:58:28 -0700 Subject: [PATCH 01/28] docs: add a dedicated section to desktop LDAP discovery (#51515) Closes #51485 --- .../desktop-access/active-directory.mdx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/pages/enroll-resources/desktop-access/active-directory.mdx b/docs/pages/enroll-resources/desktop-access/active-directory.mdx index 6615ecc4b5ce8..26e11fd4291e3 100644 --- a/docs/pages/enroll-resources/desktop-access/active-directory.mdx +++ b/docs/pages/enroll-resources/desktop-access/active-directory.mdx @@ -689,6 +689,61 @@ To connect to a Windows desktop: To view the recording, select **Management** in the Teleport Web UI, then click **Session Recordings** in the Activity section. +## LDAP Discovery + +In Active Directory environments, Teleport can be configured to discover hosts +via LDAP. LDAP discovery is enabled by setting the `discovery.base_dn` field in +the Teleport Windows Desktop Service configuration. You can set `base_dn` to a +wildcard `'*` to search from the root of the domain, or you can specify an alternate +base distinguished name to search from. + +```yaml +windows_desktop_service: + enabled: yes + discovery: + base_dn: '*' +``` + +### Filters + +Teleport optionally accepts a set of filters that can be used to narrow the +search results for discovery. The filters are specified with [LDAP +Filter](https://ldap.com/ldap-filters/) syntax. Teleport will automatically +compute a logical AND of all filters specified. + +```yaml +windows_desktop_service: + enabled: yes + discovery: + base_dn: '*' + filters: + - '(location=Oakland)' + - '(!(primaryGroupID=516))' +``` + +### Labeling + +It is often necessary to apply labels to discovered hosts to control access. You +can configure Teleport to convert LDAP attributes to Teleport labels by setting +the `discovery.label_attributes` field in the Teleport Windows Desktop Service +configuration. + +```yaml +windows_desktop_service: + enabled: yes + discovery: + base_dn: '*' + label_attributes: + - 'location' + - 'department' +``` + +Each of the specified attributes will be placed in a Teleport label prefixed with `ldap/`. + +For example, if an AD computer object had a location attribute with a value of Oakland, +and a department attribute with a value of Engineering, the Teleport resource for this +host would have both `ldap/location=Oakland` and `ldap/department=Engineering` labels. + ## Security hardening By default, the Default Domain Policy grants the **Add workstations to domain From 46c5e1901c7f2619716f2b28bacf517d3c7d1366 Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Wed, 29 Jan 2025 12:04:36 -0800 Subject: [PATCH 02/28] Migrate AWS SecretsManager clients to AWS SDK v2 (#51150) --- integrations/event-handler/go.mod | 1 + integrations/event-handler/go.sum | 2 + integrations/terraform/go.mod | 1 + integrations/terraform/go.sum | 2 + lib/cloud/aws/tags_helpers.go | 6 +- lib/cloud/clients.go | 23 ---- .../mocks/aws_secretsmanager.go} | 123 +++++++++++------- lib/srv/db/access_test.go | 6 +- lib/srv/db/cloud/users/elasticache.go | 9 +- lib/srv/db/cloud/users/helpers.go | 21 +-- lib/srv/db/cloud/users/memorydb.go | 7 +- lib/srv/db/cloud/users/user_test.go | 3 +- lib/srv/db/cloud/users/users.go | 7 + lib/srv/db/cloud/users/users_test.go | 19 ++- lib/srv/db/secrets/aws_secrets_manager.go | 69 +++++----- .../db/secrets/aws_secrets_manager_test.go | 18 +-- 16 files changed, 168 insertions(+), 149 deletions(-) rename lib/{srv/db/secrets/aws_mocks.go => cloud/mocks/aws_secretsmanager.go} (52%) diff --git a/integrations/event-handler/go.mod b/integrations/event-handler/go.mod index fc4a30c54baf5..610c00494799a 100644 --- a/integrations/event-handler/go.mod +++ b/integrations/event-handler/go.mod @@ -94,6 +94,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/redshift v1.53.1 // indirect github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.25.1 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.8 // indirect github.com/aws/aws-sdk-go-v2/service/ssm v1.56.2 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.29.8 // indirect diff --git a/integrations/event-handler/go.sum b/integrations/event-handler/go.sum index e0348b813bbf1..ba2e2f8088537 100644 --- a/integrations/event-handler/go.sum +++ b/integrations/event-handler/go.sum @@ -184,6 +184,8 @@ github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.25.1 h1:anb79RuKbIO8z github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.25.1/go.mod h1:u4NPdVb3te3+QB4rdjFGE9Of4V3vPqrPbTk6fAR6qf8= github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 h1:SAfh4pNx5LuTafKKWR02Y+hL3A+3TX8cTKG1OIAJaBk= github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.8 h1:WT3EPriVEpHE2jeNqHqj7l43JCIWPoZjNNRluZ7agII= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.8/go.mod h1:By/yiMzR0yfhPaqRWE3GrT9B/Z6871z1GfWGc+vf4Y8= github.com/aws/aws-sdk-go-v2/service/ssm v1.56.2 h1:MOxvXH2kRP5exvqJxAZ0/H9Ar51VmADJh95SgZE8u60= github.com/aws/aws-sdk-go-v2/service/ssm v1.56.2/go.mod h1:RKWoqC9FlgMCkrfVOtgfqfwdaUIaq8H93UAt4xNaR0A= github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= diff --git a/integrations/terraform/go.mod b/integrations/terraform/go.mod index a2392d407ea12..739fae1eaaa53 100644 --- a/integrations/terraform/go.mod +++ b/integrations/terraform/go.mod @@ -106,6 +106,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/redshift v1.53.1 // indirect github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.25.1 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.8 // indirect github.com/aws/aws-sdk-go-v2/service/ssm v1.56.2 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect github.com/aws/aws-sdk-go-v2/service/ssoadmin v1.29.8 // indirect diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index 2123467d057f3..aff7ab483cd6d 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -288,6 +288,8 @@ github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.25.1 h1:anb79RuKbIO8z github.com/aws/aws-sdk-go-v2/service/redshiftserverless v1.25.1/go.mod h1:u4NPdVb3te3+QB4rdjFGE9Of4V3vPqrPbTk6fAR6qf8= github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 h1:SAfh4pNx5LuTafKKWR02Y+hL3A+3TX8cTKG1OIAJaBk= github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.8 h1:WT3EPriVEpHE2jeNqHqj7l43JCIWPoZjNNRluZ7agII= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.8/go.mod h1:By/yiMzR0yfhPaqRWE3GrT9B/Z6871z1GfWGc+vf4Y8= github.com/aws/aws-sdk-go-v2/service/sns v1.33.8 h1:zKokiUMOfbZSrAUVqw+bSjr6gl9u/JcvPzHTmL+tmdQ= github.com/aws/aws-sdk-go-v2/service/sns v1.33.8/go.mod h1:Nf9YEyqE51C+Dyj0DWSATxvsr39jBFIss6Jee9Hyqx4= github.com/aws/aws-sdk-go-v2/service/sqs v1.37.4 h1:WpoMCoS4+qOkkuWQommvDRboKYzK91En6eXO/k5dXr0= diff --git a/lib/cloud/aws/tags_helpers.go b/lib/cloud/aws/tags_helpers.go index 73a3c0615bbbc..3b18ec6178467 100644 --- a/lib/cloud/aws/tags_helpers.go +++ b/lib/cloud/aws/tags_helpers.go @@ -30,7 +30,7 @@ import ( rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" redshifttypes "github.com/aws/aws-sdk-go-v2/service/redshift/types" rsstypes "github.com/aws/aws-sdk-go-v2/service/redshiftserverless/types" - "github.com/aws/aws-sdk-go/service/secretsmanager" + smtypes "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" "github.com/gravitational/teleport/api/types" ) @@ -46,7 +46,7 @@ type ResourceTag interface { memorydbtypes.Tag | rsstypes.Tag | opensearchtypes.Tag | - *secretsmanager.Tag + smtypes.Tag } // TagsToLabels converts a list of AWS resource tags to a label map. @@ -84,7 +84,7 @@ func resourceTagToKeyValue[Tag ResourceTag](tag Tag) (string, string) { return aws.ToString(v.Key), aws.ToString(v.Value) case opensearchtypes.Tag: return aws.ToString(v.Key), aws.ToString(v.Value) - case *secretsmanager.Tag: + case smtypes.Tag: return aws.ToString(v.Key), aws.ToString(v.Value) default: return "", "" diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go index bba6e777e5f93..a9101dd1db977 100644 --- a/lib/cloud/clients.go +++ b/lib/cloud/clients.go @@ -39,8 +39,6 @@ import ( "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/request" awssession "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" "github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/service/sts/stsiface" "github.com/gravitational/trace" @@ -93,8 +91,6 @@ type GCPClients interface { type AWSClients interface { // GetAWSSession returns AWS session for the specified region and any role(s). GetAWSSession(ctx context.Context, region string, opts ...AWSOptionsFn) (*awssession.Session, error) - // GetAWSSecretsManagerClient returns AWS Secrets Manager client for the specified region. - GetAWSSecretsManagerClient(ctx context.Context, region string, opts ...AWSOptionsFn) (secretsmanageriface.SecretsManagerAPI, error) // GetAWSSTSClient returns AWS STS client for the specified region. GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) } @@ -472,15 +468,6 @@ func (c *cloudClients) GetAWSSession(ctx context.Context, region string, opts .. return c.getAWSSessionForRole(ctx, region, options) } -// GetAWSSecretsManagerClient returns AWS Secrets Manager client for the specified region. -func (c *cloudClients) GetAWSSecretsManagerClient(ctx context.Context, region string, opts ...AWSOptionsFn) (secretsmanageriface.SecretsManagerAPI, error) { - session, err := c.GetAWSSession(ctx, region, opts...) - if err != nil { - return nil, trace.Wrap(err) - } - return secretsmanager.New(session), nil -} - // GetAWSSTSClient returns AWS STS client for the specified region. func (c *cloudClients) GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) { session, err := c.GetAWSSession(ctx, region, opts...) @@ -915,7 +902,6 @@ var _ Clients = (*TestCloudClients)(nil) // TestCloudClients are used in tests. type TestCloudClients struct { - SecretsManager secretsmanageriface.SecretsManagerAPI STS stsiface.STSAPI GCPSQL gcp.SQLAdminClient GCPGKE gcp.GKEClient @@ -978,15 +964,6 @@ func (c *TestCloudClients) getAWSSessionForRegion(region string) (*awssession.Se }) } -// GetAWSSecretsManagerClient returns AWS Secrets Manager client for the specified region. -func (c *TestCloudClients) GetAWSSecretsManagerClient(ctx context.Context, region string, opts ...AWSOptionsFn) (secretsmanageriface.SecretsManagerAPI, error) { - _, err := c.GetAWSSession(ctx, region, opts...) - if err != nil { - return nil, trace.Wrap(err) - } - return c.SecretsManager, nil -} - // GetAWSSTSClient returns AWS STS client for the specified region. func (c *TestCloudClients) GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) { _, err := c.GetAWSSession(ctx, region, opts...) diff --git a/lib/srv/db/secrets/aws_mocks.go b/lib/cloud/mocks/aws_secretsmanager.go similarity index 52% rename from lib/srv/db/secrets/aws_mocks.go rename to lib/cloud/mocks/aws_secretsmanager.go index 7a9274805d6d7..c5370455a4ad9 100644 --- a/lib/srv/db/secrets/aws_mocks.go +++ b/lib/cloud/mocks/aws_secretsmanager.go @@ -1,6 +1,6 @@ /* * Teleport - * Copyright (C) 2023 Gravitational, Inc. + * Copyright (C) 2025 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 @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package secrets +package mocks import ( "context" @@ -24,24 +24,23 @@ import ( "sync" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" ) -// MockSecretsManagerClientConfig is the config for MockSecretsManagerClient. -type MockSecretsManagerClientConfig struct { +// SecretsManagerClientConfig is the config for [SecretsManagerClient]. +type SecretsManagerClientConfig struct { Region string Account string Clock clockwork.Clock } -// SetDefaults sets defaults. -func (c *MockSecretsManagerClientConfig) SetDefaults() { +// setDefaults sets defaults. +func (c *SecretsManagerClientConfig) setDefaults() { if c.Region == "" { c.Region = "us-east-1" } @@ -53,35 +52,33 @@ func (c *MockSecretsManagerClientConfig) SetDefaults() { } } -// MockSecretsManagerClient is a mock implementation of +// SecretsManagerClient is a mock implementation of // secretsmanageriface.SecretsManagerAPI that makes AWSSecretsManager a // functional in-memory Secrets. // // Only used for testing. -type MockSecretsManagerClient struct { - secretsmanageriface.SecretsManagerAPI - - cfg MockSecretsManagerClientConfig +type SecretsManagerClient struct { + cfg SecretsManagerClientConfig secrets map[string]*secretsmanager.DescribeSecretOutput values map[string]*secretsmanager.GetSecretValueOutput mu sync.RWMutex } -// NewMockSecretsManagerClient creates a new MockSecretsManagerClient. -func NewMockSecretsManagerClient(cfg MockSecretsManagerClientConfig) *MockSecretsManagerClient { - cfg.SetDefaults() - return &MockSecretsManagerClient{ +// NewSecretsManagerClient creates a new [SecretsManagerClient]. +func NewSecretsManagerClient(cfg SecretsManagerClientConfig) *SecretsManagerClient { + cfg.setDefaults() + return &SecretsManagerClient{ cfg: cfg, secrets: make(map[string]*secretsmanager.DescribeSecretOutput), values: make(map[string]*secretsmanager.GetSecretValueOutput), } } -func (m *MockSecretsManagerClient) CreateSecretWithContext(_ context.Context, input *secretsmanager.CreateSecretInput, _ ...request.Option) (*secretsmanager.CreateSecretOutput, error) { +func (m *SecretsManagerClient) CreateSecret(_ context.Context, input *secretsmanager.CreateSecretInput, _ ...func(*secretsmanager.Options)) (*secretsmanager.CreateSecretOutput, error) { m.mu.Lock() defer m.mu.Unlock() - key := aws.StringValue(input.Name) + key := aws.ToString(input.Name) if _, found := m.secrets[key]; found { return nil, trace.AlreadyExists("%v already exists", key) } @@ -96,7 +93,7 @@ func (m *MockSecretsManagerClient) CreateSecretWithContext(_ context.Context, in Tags: input.Tags, } if m.secrets[key].KmsKeyId == nil { - defaultKMS, _ := defaultKMSKeyID(aws.StringValue(m.secrets[key].ARN)) + defaultKMS, _ := defaultKMSKeyID(aws.ToString(m.secrets[key].ARN)) m.secrets[key].KmsKeyId = aws.String(defaultKMS) } @@ -112,11 +109,11 @@ func (m *MockSecretsManagerClient) CreateSecretWithContext(_ context.Context, in }, nil } -func (m *MockSecretsManagerClient) DescribeSecretWithContext(_ context.Context, input *secretsmanager.DescribeSecretInput, _ ...request.Option) (*secretsmanager.DescribeSecretOutput, error) { +func (m *SecretsManagerClient) DescribeSecret(_ context.Context, input *secretsmanager.DescribeSecretInput, _ ...func(*secretsmanager.Options)) (*secretsmanager.DescribeSecretOutput, error) { m.mu.RLock() defer m.mu.RUnlock() - key := aws.StringValue(input.SecretId) + key := aws.ToString(input.SecretId) output, found := m.secrets[key] if !found { return nil, trace.NotFound("%v not found", key) @@ -124,11 +121,11 @@ func (m *MockSecretsManagerClient) DescribeSecretWithContext(_ context.Context, return output, nil } -func (m *MockSecretsManagerClient) UpdateSecretWithContext(_ context.Context, input *secretsmanager.UpdateSecretInput, _ ...request.Option) (*secretsmanager.UpdateSecretOutput, error) { +func (m *SecretsManagerClient) UpdateSecret(_ context.Context, input *secretsmanager.UpdateSecretInput, _ ...func(*secretsmanager.Options)) (*secretsmanager.UpdateSecretOutput, error) { m.mu.RLock() defer m.mu.RUnlock() - key := aws.StringValue(input.SecretId) + key := aws.ToString(input.SecretId) if _, found := m.secrets[key]; !found { return nil, trace.NotFound("%v not found", key) } @@ -140,11 +137,11 @@ func (m *MockSecretsManagerClient) UpdateSecretWithContext(_ context.Context, in }, nil } -func (m *MockSecretsManagerClient) DeleteSecretWithContext(_ context.Context, input *secretsmanager.DeleteSecretInput, _ ...request.Option) (*secretsmanager.DeleteSecretOutput, error) { +func (m *SecretsManagerClient) DeleteSecret(_ context.Context, input *secretsmanager.DeleteSecretInput, _ ...func(*secretsmanager.Options)) (*secretsmanager.DeleteSecretOutput, error) { m.mu.Lock() defer m.mu.Unlock() - key := aws.StringValue(input.SecretId) + key := aws.ToString(input.SecretId) output, found := m.secrets[key] if !found { return nil, trace.NotFound("%v not found", key) @@ -152,7 +149,7 @@ func (m *MockSecretsManagerClient) DeleteSecretWithContext(_ context.Context, in delete(m.secrets, key) for versionID, value := range m.values { - if aws.StringValue(value.Name) == key { + if aws.ToString(value.Name) == key { delete(m.values, versionID) } } @@ -162,21 +159,21 @@ func (m *MockSecretsManagerClient) DeleteSecretWithContext(_ context.Context, in }, nil } -func (m *MockSecretsManagerClient) GetSecretValueWithContext(_ context.Context, input *secretsmanager.GetSecretValueInput, _ ...request.Option) (*secretsmanager.GetSecretValueOutput, error) { +func (m *SecretsManagerClient) GetSecretValue(_ context.Context, input *secretsmanager.GetSecretValueInput, _ ...func(*secretsmanager.Options)) (*secretsmanager.GetSecretValueOutput, error) { m.mu.RLock() defer m.mu.RUnlock() - key := aws.StringValue(input.SecretId) + key := aws.ToString(input.SecretId) if _, found := m.secrets[key]; !found { return nil, trace.NotFound("secret %v not found", key) } - versionID := aws.StringValue(input.VersionId) + versionID := aws.ToString(input.VersionId) // Find version ID by version stage. - if aws.StringValue(input.VersionStage) != "" { + if aws.ToString(input.VersionStage) != "" { for matchVersionID, stages := range m.secrets[key].VersionIdsToStages { - if len(stages) > 0 && aws.StringValue(stages[0]) == aws.StringValue(input.VersionStage) { + if len(stages) > 0 && stages[0] == aws.ToString(input.VersionStage) { versionID = matchVersionID break } @@ -185,24 +182,24 @@ func (m *MockSecretsManagerClient) GetSecretValueWithContext(_ context.Context, output, found := m.values[versionID] if !found { - return nil, trace.NotFound("version %v not found", aws.StringValue(input.VersionId)) + return nil, trace.NotFound("version %v not found", aws.ToString(input.VersionId)) } return output, nil } -func (m *MockSecretsManagerClient) PutSecretValueWithContext(_ context.Context, input *secretsmanager.PutSecretValueInput, _ ...request.Option) (*secretsmanager.PutSecretValueOutput, error) { +func (m *SecretsManagerClient) PutSecretValue(_ context.Context, input *secretsmanager.PutSecretValueInput, _ ...func(*secretsmanager.Options)) (*secretsmanager.PutSecretValueOutput, error) { m.mu.Lock() defer m.mu.Unlock() - key := aws.StringValue(input.SecretId) + key := aws.ToString(input.SecretId) if _, found := m.secrets[key]; !found { return nil, trace.NotFound("%v not found", key) } // Test client token before putting new value. - if aws.StringValue(input.ClientRequestToken) != "" { - if _, found := m.values[aws.StringValue(input.ClientRequestToken)]; found { - return nil, trace.BadParameter("version %v is already created", aws.StringValue(input.ClientRequestToken)) + if aws.ToString(input.ClientRequestToken) != "" { + if _, found := m.values[aws.ToString(input.ClientRequestToken)]; found { + return nil, trace.BadParameter("version %v is already created", aws.ToString(input.ClientRequestToken)) } } @@ -211,18 +208,22 @@ func (m *MockSecretsManagerClient) PutSecretValueWithContext(_ context.Context, ARN: m.secrets[key].ARN, Name: m.secrets[key].Name, VersionId: newVersionID, - VersionStages: aws.StringSlice([]string{stageCurrent}), + VersionStages: []string{stageCurrent}, }, nil } +func (m *SecretsManagerClient) TagResource(context.Context, *secretsmanager.TagResourceInput, ...func(*secretsmanager.Options)) (*secretsmanager.TagResourceOutput, error) { + return nil, trace.NotImplemented("TagResource not implemented") +} + // putValue is a helper function to add a new value for the secret with // provided key and returns the version ID of the new value. -func (m *MockSecretsManagerClient) putValue(key string, binary []byte, versionID *string, createdAt time.Time) *string { - if aws.StringValue(versionID) == "" { +func (m *SecretsManagerClient) putValue(key string, binary []byte, versionID *string, createdAt time.Time) *string { + if aws.ToString(versionID) == "" { versionID = aws.String(uuid.NewString()) } - m.values[aws.StringValue(versionID)] = &secretsmanager.GetSecretValueOutput{ + m.values[aws.ToString(versionID)] = &secretsmanager.GetSecretValueOutput{ ARN: m.secrets[key].ARN, Name: m.secrets[key].Name, CreatedDate: aws.Time(createdAt), @@ -230,14 +231,40 @@ func (m *MockSecretsManagerClient) putValue(key string, binary []byte, versionID VersionId: versionID, } - newVersionsMap := map[string][]*string{ - aws.StringValue(versionID): aws.StringSlice([]string{stageCurrent}), + newVersionsMap := map[string][]string{ + aws.ToString(versionID): {stageCurrent}, } for oldVersion, stages := range m.secrets[key].VersionIdsToStages { - if len(stages) > 0 && aws.StringValue(stages[0]) == stageCurrent { // Demote current to previous. - newVersionsMap[oldVersion] = aws.StringSlice([]string{stagePrevious}) + if len(stages) > 0 && stages[0] == stageCurrent { // Demote current to previous. + newVersionsMap[oldVersion] = []string{stagePrevious} } } m.secrets[key].VersionIdsToStages = newVersionsMap return versionID } + +const ( + // stageCurrent is the stage for current version of the secret. + stageCurrent = "AWSCURRENT" + // stagePrevious is the stage for previous version of the secret. + stagePrevious = "AWSPREVIOUS" +) + +// defaultKMSKeyID returns the default KMS Key ID for provided secret. +func defaultKMSKeyID(secretARN string) (string, error) { + parsed, err := arn.Parse(secretARN) + if err != nil { + return "", trace.Wrap(err) + } + + // Secrets manager default KMS alias looks like this. + // arn:aws:kms:us-east-1:1234567890:alias/aws/secretsmanager + arn := arn.ARN{ + Partition: parsed.Partition, + Service: "kms", + Region: parsed.Region, + AccountID: parsed.AccountID, + Resource: "alias/aws/secretsmanager", + } + return arn.String(), nil +} diff --git a/lib/srv/db/access_test.go b/lib/srv/db/access_test.go index 73a9aa2405467..6da256f8b2654 100644 --- a/lib/srv/db/access_test.go +++ b/lib/srv/db/access_test.go @@ -91,7 +91,6 @@ import ( "github.com/gravitational/teleport/lib/srv/db/postgres" "github.com/gravitational/teleport/lib/srv/db/redis" redisprotocol "github.com/gravitational/teleport/lib/srv/db/redis/protocol" - "github.com/gravitational/teleport/lib/srv/db/secrets" "github.com/gravitational/teleport/lib/srv/db/snowflake" "github.com/gravitational/teleport/lib/srv/db/spanner" "github.com/gravitational/teleport/lib/srv/db/sqlserver" @@ -2484,9 +2483,8 @@ func (p *agentParams) setDefaults(c *testContext) { if p.CloudClients == nil { p.CloudClients = &clients.TestCloudClients{ - STS: &mocks.STSClientV1{}, - SecretsManager: secrets.NewMockSecretsManagerClient(secrets.MockSecretsManagerClientConfig{}), - GCPSQL: p.GCPSQL, + STS: &mocks.STSClientV1{}, + GCPSQL: p.GCPSQL, } } if p.AWSConfigProvider == nil { diff --git a/lib/srv/db/cloud/users/elasticache.go b/lib/srv/db/cloud/users/elasticache.go index ebf282261427c..4e46bb5e4ab3d 100644 --- a/lib/srv/db/cloud/users/elasticache.go +++ b/lib/srv/db/cloud/users/elasticache.go @@ -88,22 +88,23 @@ func (f *elastiCacheFetcher) FetchDatabaseUsers(ctx context.Context, database ty if err != nil { return nil, trace.Wrap(err) } - client := f.cfg.awsClients.getElastiCacheClient(awsCfg) - secrets, err := newSecretStore(ctx, database, f.cfg.Clients, f.cfg.ClusterName) + smClt := f.cfg.awsClients.getSecretsManagerClient(awsCfg) + secrets, err := newSecretStore(database.GetSecretStore(), smClt, f.cfg.ClusterName) if err != nil { return nil, trace.Wrap(err) } + ecClient := f.cfg.awsClients.getElastiCacheClient(awsCfg) users := []User{} for _, userGroupID := range meta.ElastiCache.UserGroupIDs { - managedUsers, err := f.getManagedUsersForGroup(ctx, meta.Region, userGroupID, client) + managedUsers, err := f.getManagedUsersForGroup(ctx, meta.Region, userGroupID, ecClient) if err != nil { return nil, trace.Wrap(err) } for _, managedUser := range managedUsers { - user, err := f.createUser(&managedUser, client, secrets) + user, err := f.createUser(&managedUser, ecClient, secrets) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/db/cloud/users/helpers.go b/lib/srv/db/cloud/users/helpers.go index 73c78ba17fc24..f4d97180f1659 100644 --- a/lib/srv/db/cloud/users/helpers.go +++ b/lib/srv/db/cloud/users/helpers.go @@ -19,15 +19,13 @@ package users import ( - "context" "strings" "sync" - "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/gravitational/trace" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/srv/db/secrets" "github.com/gravitational/teleport/lib/utils" ) @@ -166,21 +164,10 @@ func genRandomPassword(length int) (string, error) { } // newSecretStore create a new secrets store helper for provided database. -func newSecretStore(ctx context.Context, database types.Database, clients cloud.Clients, clusterName string) (secrets.Secrets, error) { - secretStoreConfig := database.GetSecretStore() - - meta := database.GetAWS() - client, err := clients.GetAWSSecretsManagerClient(ctx, meta.Region, - cloud.WithAssumeRoleFromAWSMeta(meta), - cloud.WithAmbientCredentials(), - ) - if err != nil { - return nil, trace.Wrap(err) - } - +func newSecretStore(ss types.SecretStore, client secrets.SecretsManagerClient, clusterName string) (secrets.Secrets, error) { return secrets.NewAWSSecretsManager(secrets.AWSSecretsManagerConfig{ - KeyPrefix: secretStoreConfig.KeyPrefix, - KMSKeyID: secretStoreConfig.KMSKeyID, + KeyPrefix: ss.KeyPrefix, + KMSKeyID: ss.KMSKeyID, Client: client, ClusterName: clusterName, }) diff --git a/lib/srv/db/cloud/users/memorydb.go b/lib/srv/db/cloud/users/memorydb.go index efaba83489f44..6b4c09b3561a7 100644 --- a/lib/srv/db/cloud/users/memorydb.go +++ b/lib/srv/db/cloud/users/memorydb.go @@ -89,19 +89,20 @@ func (f *memoryDBFetcher) FetchDatabaseUsers(ctx context.Context, database types if err != nil { return nil, trace.Wrap(err) } - clt := f.cfg.awsClients.getMemoryDBClient(awsCfg) - secrets, err := newSecretStore(ctx, database, f.cfg.Clients, f.cfg.ClusterName) + smClt := f.cfg.awsClients.getSecretsManagerClient(awsCfg) + secrets, err := newSecretStore(database.GetSecretStore(), smClt, f.cfg.ClusterName) if err != nil { return nil, trace.Wrap(err) } - users := []User{} + clt := f.cfg.awsClients.getMemoryDBClient(awsCfg) mdbUsers, err := f.getManagedUsersForACL(ctx, meta.Region, meta.MemoryDB.ACLName, clt) if err != nil { return nil, trace.Wrap(err) } + users := []User{} for _, mdbUser := range mdbUsers { user, err := f.createUser(&mdbUser, clt, secrets) if err != nil { diff --git a/lib/srv/db/cloud/users/user_test.go b/lib/srv/db/cloud/users/user_test.go index 9b4245ac45d3e..284ba702d987b 100644 --- a/lib/srv/db/cloud/users/user_test.go +++ b/lib/srv/db/cloud/users/user_test.go @@ -28,6 +28,7 @@ import ( "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" + "github.com/gravitational/teleport/lib/cloud/mocks" libsecrets "github.com/gravitational/teleport/lib/srv/db/secrets" ) @@ -39,7 +40,7 @@ func TestBaseUser(t *testing.T) { mockCloudResource := newMockCloudResource() secrets, err := libsecrets.NewAWSSecretsManager(libsecrets.AWSSecretsManagerConfig{ - Client: libsecrets.NewMockSecretsManagerClient(libsecrets.MockSecretsManagerClientConfig{ + Client: mocks.NewSecretsManagerClient(mocks.SecretsManagerClientConfig{ Clock: clock, }), ClusterName: "example.teleport.sh", diff --git a/lib/srv/db/cloud/users/users.go b/lib/srv/db/cloud/users/users.go index 6a5ef66efe24b..45eeba3c3bd7d 100644 --- a/lib/srv/db/cloud/users/users.go +++ b/lib/srv/db/cloud/users/users.go @@ -26,6 +26,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" elasticache "github.com/aws/aws-sdk-go-v2/service/elasticache" memorydb "github.com/aws/aws-sdk-go-v2/service/memorydb" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" @@ -34,6 +35,7 @@ import ( "github.com/gravitational/teleport/api/utils/retryutils" "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" + "github.com/gravitational/teleport/lib/srv/db/secrets" "github.com/gravitational/teleport/lib/utils/interval" ) @@ -63,6 +65,7 @@ type Config struct { type awsClientProvider interface { getElastiCacheClient(cfg aws.Config, optFns ...func(*elasticache.Options)) elasticacheClient getMemoryDBClient(cfg aws.Config, optFns ...func(*memorydb.Options)) memoryDBClient + getSecretsManagerClient(cfg aws.Config, optFns ...func(*secretsmanager.Options)) secrets.SecretsManagerClient } type defaultAWSClients struct{} @@ -75,6 +78,10 @@ func (defaultAWSClients) getMemoryDBClient(cfg aws.Config, optFns ...func(*memor return memorydb.NewFromConfig(cfg, optFns...) } +func (defaultAWSClients) getSecretsManagerClient(cfg aws.Config, optFns ...func(*secretsmanager.Options)) secrets.SecretsManagerClient { + return secretsmanager.NewFromConfig(cfg, optFns...) +} + // CheckAndSetDefaults validates the config and set defaults. func (c *Config) CheckAndSetDefaults() error { if c.AWSConfigProvider == nil { diff --git a/lib/srv/db/cloud/users/users_test.go b/lib/srv/db/cloud/users/users_test.go index 23cb5c70b7cf7..9d817db844884 100644 --- a/lib/srv/db/cloud/users/users_test.go +++ b/lib/srv/db/cloud/users/users_test.go @@ -30,6 +30,7 @@ import ( ectypes "github.com/aws/aws-sdk-go-v2/service/elasticache/types" memorydb "github.com/aws/aws-sdk-go-v2/service/memorydb" memorydbtypes "github.com/aws/aws-sdk-go-v2/service/memorydb/types" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" @@ -39,7 +40,7 @@ import ( libaws "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/defaults" - libsecrets "github.com/gravitational/teleport/lib/srv/db/secrets" + "github.com/gravitational/teleport/lib/srv/db/secrets" "github.com/gravitational/teleport/lib/utils" ) @@ -60,7 +61,7 @@ func TestUsers(t *testing.T) { t.Cleanup(cancel) clock := clockwork.NewFakeClock() - smMock := libsecrets.NewMockSecretsManagerClient(libsecrets.MockSecretsManagerClientConfig{ + smMock := mocks.NewSecretsManagerClient(mocks.SecretsManagerClientConfig{ Clock: clock, }) ecMock := &mocks.ElastiCacheClient{} @@ -84,10 +85,8 @@ func TestUsers(t *testing.T) { users, err := NewUsers(Config{ AWSConfigProvider: &mocks.AWSConfigProvider{}, - Clients: &clients.TestCloudClients{ - SecretsManager: smMock, - }, - Clock: clock, + Clients: &clients.TestCloudClients{}, + Clock: clock, UpdateMeta: func(_ context.Context, database types.Database) error { // Update db1 to group3 when setupAllDatabases. if database == db1 { @@ -101,6 +100,7 @@ func TestUsers(t *testing.T) { awsClients: fakeAWSClients{ ecClient: ecMock, mdbClient: mdbMock, + smClient: smMock, }, }) require.NoError(t, err) @@ -218,8 +218,9 @@ func memoryDBUser(name string, aclNames ...string) memorydbtypes.User { } type fakeAWSClients struct { - mdbClient memoryDBClient ecClient elasticacheClient + mdbClient memoryDBClient + smClient secrets.SecretsManagerClient } func (f fakeAWSClients) getElastiCacheClient(cfg aws.Config, optFns ...func(*elasticache.Options)) elasticacheClient { @@ -229,3 +230,7 @@ func (f fakeAWSClients) getElastiCacheClient(cfg aws.Config, optFns ...func(*ela func (f fakeAWSClients) getMemoryDBClient(cfg aws.Config, optFns ...func(*memorydb.Options)) memoryDBClient { return f.mdbClient } + +func (f fakeAWSClients) getSecretsManagerClient(cfg aws.Config, optFns ...func(*secretsmanager.Options)) secrets.SecretsManagerClient { + return f.smClient +} diff --git a/lib/srv/db/secrets/aws_secrets_manager.go b/lib/srv/db/secrets/aws_secrets_manager.go index c0bed4e72144b..70c96a326370d 100644 --- a/lib/srv/db/secrets/aws_secrets_manager.go +++ b/lib/srv/db/secrets/aws_secrets_manager.go @@ -23,17 +23,27 @@ import ( "errors" "maps" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + smtypes "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" "github.com/google/uuid" "github.com/gravitational/trace" libaws "github.com/gravitational/teleport/lib/cloud/aws" ) +// SecretsManagerClient defines a subset of the AWS SecretsManager client API. +type SecretsManagerClient interface { + CreateSecret(context.Context, *secretsmanager.CreateSecretInput, ...func(*secretsmanager.Options)) (*secretsmanager.CreateSecretOutput, error) + DeleteSecret(context.Context, *secretsmanager.DeleteSecretInput, ...func(*secretsmanager.Options)) (*secretsmanager.DeleteSecretOutput, error) + DescribeSecret(context.Context, *secretsmanager.DescribeSecretInput, ...func(*secretsmanager.Options)) (*secretsmanager.DescribeSecretOutput, error) + GetSecretValue(context.Context, *secretsmanager.GetSecretValueInput, ...func(*secretsmanager.Options)) (*secretsmanager.GetSecretValueOutput, error) + PutSecretValue(context.Context, *secretsmanager.PutSecretValueInput, ...func(*secretsmanager.Options)) (*secretsmanager.PutSecretValueOutput, error) + TagResource(context.Context, *secretsmanager.TagResourceInput, ...func(*secretsmanager.Options)) (*secretsmanager.TagResourceOutput, error) + UpdateSecret(context.Context, *secretsmanager.UpdateSecretInput, ...func(*secretsmanager.Options)) (*secretsmanager.UpdateSecretOutput, error) +} + // AWSSecretsManagerConfig is the config for AWSSecretsManager. type AWSSecretsManagerConfig struct { // KeyPrefix is the key path prefix for all keys used by Secrets. @@ -42,7 +52,7 @@ type AWSSecretsManagerConfig struct { // decrypt the secret value. KMSKeyID string `yaml:"kms_key_id,omitempty"` // Client is the AWS API client for Secrets Manager. - Client secretsmanageriface.SecretsManagerAPI + Client SecretsManagerClient // ClusterName is the name of the Teleport cluster (for tagging purpose). ClusterName string } @@ -98,7 +108,7 @@ func (s *AWSSecretsManager) CreateOrUpdate(ctx context.Context, key string, valu input.KmsKeyId = aws.String(s.cfg.KMSKeyID) } - if _, err := s.cfg.Client.CreateSecretWithContext(ctx, input); err != nil { + if _, err := s.cfg.Client.CreateSecret(ctx, input); err != nil { err = convertSecretsManagerError(err) switch { @@ -118,8 +128,8 @@ func (s *AWSSecretsManager) CreateOrUpdate(ctx context.Context, key string, valu return nil } -func (s *AWSSecretsManager) makeTags() []*secretsmanager.Tag { - return []*secretsmanager.Tag{ +func (s *AWSSecretsManager) makeTags() []smtypes.Tag { + return []smtypes.Tag{ { Key: aws.String(libaws.TagKeyTeleportCreated), Value: aws.String(libaws.TagValueTrue), @@ -138,7 +148,7 @@ func (s *AWSSecretsManager) Delete(ctx context.Context, key string) error { return trace.Wrap(err) } - _, err = s.cfg.Client.DeleteSecretWithContext(ctx, &secretsmanager.DeleteSecretInput{ + _, err = s.cfg.Client.DeleteSecret(ctx, &secretsmanager.DeleteSecretInput{ SecretId: secretID, // Remove secret immediately. Otherwise, secret will be hidden but @@ -171,16 +181,16 @@ func (s *AWSSecretsManager) GetValue(ctx context.Context, key string, version st input.VersionId = aws.String(version) } - output, err := s.cfg.Client.GetSecretValueWithContext(ctx, input) + output, err := s.cfg.Client.GetSecretValue(ctx, input) if err != nil { return nil, trace.Wrap(convertSecretsManagerError(err)) } return &Value{ - Key: aws.StringValue(output.Name), + Key: aws.ToString(output.Name), Value: string(output.SecretBinary), - Version: aws.StringValue(output.VersionId), - CreatedAt: aws.TimeValue(output.CreatedDate), + Version: aws.ToString(output.VersionId), + CreatedAt: aws.ToTime(output.CreatedDate), }, nil } @@ -206,7 +216,7 @@ func (s *AWSSecretsManager) PutValue(ctx context.Context, key, value, currentVer input.ClientRequestToken = aws.String(uuid.New().String()) } - if _, err := s.cfg.Client.PutSecretValueWithContext(ctx, input); err != nil { + if _, err := s.cfg.Client.PutSecretValue(ctx, input); err != nil { return trace.Wrap(convertSecretsManagerError(err)) } return nil @@ -219,7 +229,7 @@ func (s *AWSSecretsManager) update(ctx context.Context, key string) error { return trace.Wrap(err) } - secret, err := s.cfg.Client.DescribeSecretWithContext(ctx, &secretsmanager.DescribeSecretInput{ + secret, err := s.cfg.Client.DescribeSecret(ctx, &secretsmanager.DescribeSecretInput{ SecretId: secretID, }) if err != nil { @@ -231,7 +241,7 @@ func (s *AWSSecretsManager) update(ctx context.Context, key string) error { } configKMSKeyID := s.cfg.KMSKeyID - if aws.StringValue(secret.KmsKeyId) == configKMSKeyID { + if aws.ToString(secret.KmsKeyId) == configKMSKeyID { return nil } @@ -239,16 +249,16 @@ func (s *AWSSecretsManager) update(ctx context.Context, key string) error { // populate configKMSKeyID to the default AWS managed KMS key for Secrets // Manager then compare again. if configKMSKeyID == "" { - if configKMSKeyID, err = defaultKMSKeyID(aws.StringValue(secret.ARN)); err != nil { + if configKMSKeyID, err = defaultKMSKeyID(aws.ToString(secret.ARN)); err != nil { return trace.Wrap(err) } - if aws.StringValue(secret.KmsKeyId) == configKMSKeyID { + if aws.ToString(secret.KmsKeyId) == configKMSKeyID { return nil } } - _, err = s.cfg.Client.UpdateSecretWithContext(ctx, &secretsmanager.UpdateSecretInput{ + _, err = s.cfg.Client.UpdateSecret(ctx, &secretsmanager.UpdateSecretInput{ SecretId: secretID, KmsKeyId: aws.String(configKMSKeyID), }) @@ -260,7 +270,7 @@ func (s *AWSSecretsManager) maybeUpdateTags(ctx context.Context, secert *secrets if maps.Equal(libaws.TagsToLabels(wantTags), libaws.TagsToLabels(secert.Tags)) { return nil } - _, err := s.cfg.Client.TagResource(&secretsmanager.TagResourceInput{ + _, err := s.cfg.Client.TagResource(ctx, &secretsmanager.TagResourceInput{ SecretId: secert.ARN, Tags: wantTags, }) @@ -304,21 +314,18 @@ func convertSecretsManagerError(err error) error { return nil } - var awsError awserr.Error - if !errors.As(err, &awsError) { - return trace.Wrap(err) + var resourceExistsErr *smtypes.ResourceExistsException + if errors.As(err, &resourceExistsErr) { + return trace.AlreadyExists(resourceExistsErr.Error()) } - // Match by exception code as many errors are sharing the same status code. - switch awsError.Code() { - case secretsmanager.ErrCodeResourceExistsException: - return trace.AlreadyExists(awsError.Error()) - case secretsmanager.ErrCodeResourceNotFoundException: - return trace.NotFound(awsError.Error()) + var notFoundErr *smtypes.ResourceNotFoundException + if errors.As(err, ¬FoundErr) { + return trace.NotFound(notFoundErr.Error()) } // Match by status code. - return trace.Wrap(libaws.ConvertRequestFailureError(err)) + return trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) } const ( diff --git a/lib/srv/db/secrets/aws_secrets_manager_test.go b/lib/srv/db/secrets/aws_secrets_manager_test.go index b1d043d96c0af..9950fedbf7055 100644 --- a/lib/srv/db/secrets/aws_secrets_manager_test.go +++ b/lib/srv/db/secrets/aws_secrets_manager_test.go @@ -23,16 +23,18 @@ import ( "strings" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/gravitational/trace" "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/lib/cloud/mocks" ) func TestAWSSecretsManager(t *testing.T) { createFunc := func(_ context.Context) (Secrets, error) { secrets, err := NewAWSSecretsManager(AWSSecretsManagerConfig{ - Client: NewMockSecretsManagerClient(MockSecretsManagerClientConfig{}), + Client: mocks.NewSecretsManagerClient(mocks.SecretsManagerClientConfig{}), ClusterName: "example.teleport.sh", }) if err != nil { @@ -69,7 +71,7 @@ func TestAWSSecretsManager(t *testing.T) { t.Cleanup(cancel) // Create secret for the first time with default KMS. - client := NewMockSecretsManagerClient(MockSecretsManagerClientConfig{}) + client := mocks.NewSecretsManagerClient(mocks.SecretsManagerClientConfig{}) secrets, err := NewAWSSecretsManager(AWSSecretsManagerConfig{ Client: client, ClusterName: "example.teleport.sh", @@ -77,11 +79,11 @@ func TestAWSSecretsManager(t *testing.T) { require.NoError(t, err) require.NoError(t, secrets.CreateOrUpdate(ctx, "key", "value")) - output1, err := client.DescribeSecretWithContext(ctx, &secretsmanager.DescribeSecretInput{ + output1, err := client.DescribeSecret(ctx, &secretsmanager.DescribeSecretInput{ SecretId: aws.String("teleport/key"), }) require.NoError(t, err) - require.Equal(t, "arn:aws:kms:us-east-1:123456789012:alias/aws/secretsmanager", aws.StringValue(output1.KmsKeyId)) + require.Equal(t, "arn:aws:kms:us-east-1:123456789012:alias/aws/secretsmanager", aws.ToString(output1.KmsKeyId)) // Create secret for the second time with custom KMS. Create returns // IsAlreadyExists but KMSKeyID should be updated. @@ -93,11 +95,11 @@ func TestAWSSecretsManager(t *testing.T) { require.NoError(t, err) require.True(t, trace.IsAlreadyExists(secrets.CreateOrUpdate(ctx, "key", "value"))) - output2, err := client.DescribeSecretWithContext(ctx, &secretsmanager.DescribeSecretInput{ + output2, err := client.DescribeSecret(ctx, &secretsmanager.DescribeSecretInput{ SecretId: aws.String("teleport/key"), }) require.NoError(t, err) - require.Equal(t, "customKMS", aws.StringValue(output2.KmsKeyId)) + require.Equal(t, "customKMS", aws.ToString(output2.KmsKeyId)) // Verify the versions are kept. require.Equal(t, output1.VersionIdsToStages, output2.VersionIdsToStages) From a67d70b43688ba5c0ba40152b095a6dc3ffee538 Mon Sep 17 00:00:00 2001 From: Andrew Burke <31974658+atburke@users.noreply.github.com> Date: Wed, 29 Jan 2025 12:11:16 -0800 Subject: [PATCH 03/28] OCI join - add proto and client (#51444) This change adds protos, the client, and a bunch of boilerplate for the Oracle join method. --- api/client/joinservice.go | 60 + api/client/joinservice_test.go | 113 +- api/client/proto/joinservice.go | 19 +- api/client/proto/joinservice.pb.go | 1382 +++- .../legacy/client/proto/joinservice.proto | 39 + api/proto/teleport/legacy/types/types.proto | 24 + api/types/provisioning.go | 30 + api/types/types.pb.go | 5547 +++++++++-------- ...resources-teleport-dev-provisiontokens.mdx | 15 + ...sources-teleport-dev-trustedclustersv2.mdx | 41 + .../data-sources/provision_token.mdx | 17 + .../resources/provision_token.mdx | 17 + ...esources.teleport.dev_provisiontokens.yaml | 26 + ...esources.teleport.dev_provisiontokens.yaml | 26 + .../tfschema/token/types_terraform.go | 361 ++ lib/auth/join.go | 4 +- lib/auth/join/join.go | 20 +- lib/auth/join_oracle.go | 37 + lib/joinserver/joinserver.go | 195 +- lib/joinserver/joinserver_test.go | 10 +- lib/service/service.go | 3 +- 21 files changed, 5287 insertions(+), 2699 deletions(-) create mode 100644 docs/pages/reference/operator-resources/resources-teleport-dev-trustedclustersv2.mdx create mode 100644 lib/auth/join_oracle.go diff --git a/api/client/joinservice.go b/api/client/joinservice.go index 0e46ec5bacf42..bc30c8a541e6c 100644 --- a/api/client/joinservice.go +++ b/api/client/joinservice.go @@ -55,6 +55,11 @@ type RegisterAzureChallengeResponseFunc func(challenge string) (*proto.RegisterU // error. type RegisterTPMChallengeResponseFunc func(challenge *proto.TPMEncryptedCredential) (*proto.RegisterUsingTPMMethodChallengeResponse, error) +// RegisterOracleChallengeResponseFunc is a function type meant to be passed to +// RegisterUsingOracleMethod: It must return a +// *proto.OracleSignedRequest for a given challenge, or an error. +type RegisterOracleChallengeResponseFunc func(challenge string) (*proto.OracleSignedRequest, error) + // RegisterUsingIAMMethod registers the caller using the IAM join method and // returns signed certs to join the cluster. // @@ -202,6 +207,61 @@ func (c *JoinServiceClient) RegisterUsingTPMMethod( return certs, nil } +// RegisterUsingOracleMethod registers the caller using the Oracle join method and +// returns signed certs to join the cluster. The caller must provide a +// ChallengeResponseFunc which returns a *proto.OracleSignedRequest +// for a given challenge, or an error. +func (c *JoinServiceClient) RegisterUsingOracleMethod( + ctx context.Context, + tokenReq *types.RegisterUsingTokenRequest, + oracleRequestFromChallenge RegisterOracleChallengeResponseFunc, +) (*proto.Certs, error) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + oracleJoinClient, err := c.grpcClient.RegisterUsingOracleMethod(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + if err := oracleJoinClient.Send(&proto.RegisterUsingOracleMethodRequest{ + Request: &proto.RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest{ + RegisterUsingTokenRequest: tokenReq, + }, + }); err != nil { + return nil, trace.Wrap(err) + } + + challengeResp, err := oracleJoinClient.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + challenge := challengeResp.GetChallenge() + if challenge == "" { + return nil, trace.BadParameter("missing challenge") + } + oracleSignedReq, err := oracleRequestFromChallenge(challenge) + if err != nil { + return nil, trace.Wrap(err) + } + if err := oracleJoinClient.Send(&proto.RegisterUsingOracleMethodRequest{ + Request: &proto.RegisterUsingOracleMethodRequest_OracleRequest{ + OracleRequest: oracleSignedReq, + }, + }); err != nil { + return nil, trace.Wrap(err) + } + + certsResp, err := oracleJoinClient.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + certs := certsResp.GetCerts() + if certs == nil { + return nil, trace.BadParameter("expected certificate response, got %T", certsResp.Response) + } + return certs, nil +} + // RegisterUsingToken registers the caller using a token and returns signed // certs. // This is used where a more specific RPC has not been introduced for the join diff --git a/api/client/joinservice_test.go b/api/client/joinservice_test.go index c0068f4be47f7..f3f7db52a8f26 100644 --- a/api/client/joinservice_test.go +++ b/api/client/joinservice_test.go @@ -35,13 +35,18 @@ import ( type mockJoinServiceServer struct { proto.UnimplementedJoinServiceServer - registerUsingTPMMethod func(srv proto.JoinService_RegisterUsingTPMMethodServer) error + registerUsingTPMMethod func(srv proto.JoinService_RegisterUsingTPMMethodServer) error + registerUsingOracleMethod func(srv proto.JoinService_RegisterUsingOracleMethodServer) error } func (m *mockJoinServiceServer) RegisterUsingTPMMethod(srv proto.JoinService_RegisterUsingTPMMethodServer) error { return m.registerUsingTPMMethod(srv) } +func (m *mockJoinServiceServer) RegisterUsingOracleMethod(srv proto.JoinService_RegisterUsingOracleMethodServer) error { + return m.registerUsingOracleMethod(srv) +} + func TestJoinServiceClient_RegisterUsingTPMMethod(t *testing.T) { t.Parallel() @@ -109,11 +114,11 @@ func TestJoinServiceClient_RegisterUsingTPMMethod(t *testing.T) { proto.RegisterJoinServiceServer(srv, mockService) go func() { + defer cancel() err := srv.Serve(lis) if err != nil && !errors.Is(err, grpc.ErrServerStopped) { assert.NoError(t, err) } - cancel() }() // grpc.NewClient attempts to DNS resolve addr, whereas grpc.Dial doesn't. @@ -140,3 +145,107 @@ func TestJoinServiceClient_RegisterUsingTPMMethod(t *testing.T) { assert.Empty(t, cmp.Diff(mockCerts, certs)) } } + +func TestJoinServiceClient_RegisterUsingOracleMethod(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + lis := bufconn.Listen(100) + t.Cleanup(func() { + assert.NoError(t, lis.Close()) + }) + + tokenReq := &types.RegisterUsingTokenRequest{ + Token: "token", + } + mockTokenRequest := &proto.RegisterUsingOracleMethodRequest{ + Request: &proto.RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest{ + RegisterUsingTokenRequest: tokenReq, + }, + } + mockChallenge := "challenge" + oracleReq := &proto.OracleSignedRequest{ + Headers: map[string]string{ + "x-teleport-challenge": mockChallenge, + }, + PayloadHeaders: map[string]string{ + "x-teleport-challenge": mockChallenge, + }, + } + + mockOracleRequest := &proto.RegisterUsingOracleMethodRequest{ + Request: &proto.RegisterUsingOracleMethodRequest_OracleRequest{ + OracleRequest: oracleReq, + }, + } + mockCerts := &proto.Certs{ + TLS: []byte("cert"), + } + mockService := &mockJoinServiceServer{ + registerUsingOracleMethod: func(srv proto.JoinService_RegisterUsingOracleMethodServer) error { + tokenReq, err := srv.Recv() + if !assert.NoError(t, err) { + return err + } + assert.Empty(t, cmp.Diff(mockTokenRequest, tokenReq)) + err = srv.Send(&proto.RegisterUsingOracleMethodResponse{ + Response: &proto.RegisterUsingOracleMethodResponse_Challenge{ + Challenge: mockChallenge, + }, + }) + if !assert.NoError(t, err) { + return err + } + headerReq, err := srv.Recv() + if !assert.NoError(t, err) { + return err + } + assert.Empty(t, cmp.Diff(mockOracleRequest, headerReq)) + + err = srv.Send(&proto.RegisterUsingOracleMethodResponse{ + Response: &proto.RegisterUsingOracleMethodResponse_Certs{ + Certs: mockCerts, + }, + }) + if !assert.NoError(t, err) { + return err + } + return nil + }, + } + srv := grpc.NewServer() + t.Cleanup(srv.Stop) + proto.RegisterJoinServiceServer(srv, mockService) + + go func() { + defer cancel() + err := srv.Serve(lis) + if err != nil && !errors.Is(err, grpc.ErrServerStopped) { + assert.NoError(t, err) + } + }() + + // grpc.NewClient attempts to DNS resolve addr, whereas grpc.Dial doesn't. + c, err := grpc.Dial( + "bufconn", + grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) { + return lis.DialContext(ctx) + }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + require.NoError(t, err) + + joinClient := NewJoinServiceClient(proto.NewJoinServiceClient(c)) + certs, err := joinClient.RegisterUsingOracleMethod( + ctx, + tokenReq, + func(challenge string) (*proto.OracleSignedRequest, error) { + assert.Equal(t, mockChallenge, challenge) + return oracleReq, nil + }, + ) + if assert.NoError(t, err) { + assert.Empty(t, cmp.Diff(mockCerts, certs)) + } +} diff --git a/api/client/proto/joinservice.go b/api/client/proto/joinservice.go index e31ad10b95759..5e0364324580a 100644 --- a/api/client/proto/joinservice.go +++ b/api/client/proto/joinservice.go @@ -16,7 +16,9 @@ limitations under the License. package proto -import "github.com/gravitational/trace" +import ( + "github.com/gravitational/trace" +) func (r *RegisterUsingIAMMethodRequest) CheckAndSetDefaults() error { if len(r.StsIdentityRequest) == 0 { @@ -34,3 +36,18 @@ func (r *RegisterUsingAzureMethodRequest) CheckAndSetDefaults() error { } return trace.Wrap(r.RegisterUsingTokenRequest.CheckAndSetDefaults()) } + +func (r *RegisterUsingOracleMethodRequest) CheckAndSetDefaults() error { + switch req := r.Request.(type) { + case *RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest: + return trace.Wrap(req.RegisterUsingTokenRequest.CheckAndSetDefaults()) + case *RegisterUsingOracleMethodRequest_OracleRequest: + if len(req.OracleRequest.Headers) == 0 { + return trace.BadParameter("missing parameter Headers") + } + if len(req.OracleRequest.PayloadHeaders) == 0 { + return trace.BadParameter("missing parameter PayloadHeaders") + } + } + return trace.BadParameter("invalid request type: %T", r.Request) +} diff --git a/api/client/proto/joinservice.pb.go b/api/client/proto/joinservice.pb.go index d8d425c87a891..4365a7a365073 100644 --- a/api/client/proto/joinservice.pb.go +++ b/api/client/proto/joinservice.pb.go @@ -776,6 +776,248 @@ func (m *TPMEncryptedCredential) GetSecret() []byte { return nil } +// OracleSignedRequest holds the headers and payload for a signed request to +// the Oracle API. +type OracleSignedRequest struct { + // Headers is the signed headers for a request to the Oracle authorizeClient + // endpoint. + Headers map[string]string `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // PayloadHeaders is the signed headers that are the payload to the authorizeClient + // request signified by Headers. + PayloadHeaders map[string]string `protobuf:"bytes,2,rep,name=payload_headers,json=payloadHeaders,proto3" json:"payload_headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OracleSignedRequest) Reset() { *m = OracleSignedRequest{} } +func (m *OracleSignedRequest) String() string { return proto.CompactTextString(m) } +func (*OracleSignedRequest) ProtoMessage() {} +func (*OracleSignedRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d7e760ce923b836e, []int{10} +} +func (m *OracleSignedRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OracleSignedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OracleSignedRequest.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 *OracleSignedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OracleSignedRequest.Merge(m, src) +} +func (m *OracleSignedRequest) XXX_Size() int { + return m.Size() +} +func (m *OracleSignedRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OracleSignedRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_OracleSignedRequest proto.InternalMessageInfo + +func (m *OracleSignedRequest) GetHeaders() map[string]string { + if m != nil { + return m.Headers + } + return nil +} + +func (m *OracleSignedRequest) GetPayloadHeaders() map[string]string { + if m != nil { + return m.PayloadHeaders + } + return nil +} + +// RegisterUsingOracleMethodRequest is the request for registration via the +// Oracle join method. +type RegisterUsingOracleMethodRequest struct { + // Types that are valid to be assigned to Request: + // *RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest + // *RegisterUsingOracleMethodRequest_OracleRequest + Request isRegisterUsingOracleMethodRequest_Request `protobuf_oneof:"request"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RegisterUsingOracleMethodRequest) Reset() { *m = RegisterUsingOracleMethodRequest{} } +func (m *RegisterUsingOracleMethodRequest) String() string { return proto.CompactTextString(m) } +func (*RegisterUsingOracleMethodRequest) ProtoMessage() {} +func (*RegisterUsingOracleMethodRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d7e760ce923b836e, []int{11} +} +func (m *RegisterUsingOracleMethodRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RegisterUsingOracleMethodRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RegisterUsingOracleMethodRequest.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 *RegisterUsingOracleMethodRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RegisterUsingOracleMethodRequest.Merge(m, src) +} +func (m *RegisterUsingOracleMethodRequest) XXX_Size() int { + return m.Size() +} +func (m *RegisterUsingOracleMethodRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RegisterUsingOracleMethodRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RegisterUsingOracleMethodRequest proto.InternalMessageInfo + +type isRegisterUsingOracleMethodRequest_Request interface { + isRegisterUsingOracleMethodRequest_Request() + MarshalTo([]byte) (int, error) + Size() int +} + +type RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest struct { + RegisterUsingTokenRequest *types.RegisterUsingTokenRequest `protobuf:"bytes,1,opt,name=register_using_token_request,json=registerUsingTokenRequest,proto3,oneof" json:"register_using_token_request,omitempty"` +} +type RegisterUsingOracleMethodRequest_OracleRequest struct { + OracleRequest *OracleSignedRequest `protobuf:"bytes,2,opt,name=oracle_request,json=oracleRequest,proto3,oneof" json:"oracle_request,omitempty"` +} + +func (*RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest) isRegisterUsingOracleMethodRequest_Request() { +} +func (*RegisterUsingOracleMethodRequest_OracleRequest) isRegisterUsingOracleMethodRequest_Request() {} + +func (m *RegisterUsingOracleMethodRequest) GetRequest() isRegisterUsingOracleMethodRequest_Request { + if m != nil { + return m.Request + } + return nil +} + +func (m *RegisterUsingOracleMethodRequest) GetRegisterUsingTokenRequest() *types.RegisterUsingTokenRequest { + if x, ok := m.GetRequest().(*RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest); ok { + return x.RegisterUsingTokenRequest + } + return nil +} + +func (m *RegisterUsingOracleMethodRequest) GetOracleRequest() *OracleSignedRequest { + if x, ok := m.GetRequest().(*RegisterUsingOracleMethodRequest_OracleRequest); ok { + return x.OracleRequest + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*RegisterUsingOracleMethodRequest) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest)(nil), + (*RegisterUsingOracleMethodRequest_OracleRequest)(nil), + } +} + +// RegisterUsingOracleMethodResponse is a stream response and will contain either +// a Challenge or signed Certs to join the cluster. +type RegisterUsingOracleMethodResponse struct { + // Types that are valid to be assigned to Response: + // *RegisterUsingOracleMethodResponse_Challenge + // *RegisterUsingOracleMethodResponse_Certs + Response isRegisterUsingOracleMethodResponse_Response `protobuf_oneof:"response"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RegisterUsingOracleMethodResponse) Reset() { *m = RegisterUsingOracleMethodResponse{} } +func (m *RegisterUsingOracleMethodResponse) String() string { return proto.CompactTextString(m) } +func (*RegisterUsingOracleMethodResponse) ProtoMessage() {} +func (*RegisterUsingOracleMethodResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d7e760ce923b836e, []int{12} +} +func (m *RegisterUsingOracleMethodResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RegisterUsingOracleMethodResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RegisterUsingOracleMethodResponse.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 *RegisterUsingOracleMethodResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RegisterUsingOracleMethodResponse.Merge(m, src) +} +func (m *RegisterUsingOracleMethodResponse) XXX_Size() int { + return m.Size() +} +func (m *RegisterUsingOracleMethodResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RegisterUsingOracleMethodResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RegisterUsingOracleMethodResponse proto.InternalMessageInfo + +type isRegisterUsingOracleMethodResponse_Response interface { + isRegisterUsingOracleMethodResponse_Response() + MarshalTo([]byte) (int, error) + Size() int +} + +type RegisterUsingOracleMethodResponse_Challenge struct { + Challenge string `protobuf:"bytes,1,opt,name=challenge,proto3,oneof" json:"challenge,omitempty"` +} +type RegisterUsingOracleMethodResponse_Certs struct { + Certs *Certs `protobuf:"bytes,2,opt,name=certs,proto3,oneof" json:"certs,omitempty"` +} + +func (*RegisterUsingOracleMethodResponse_Challenge) isRegisterUsingOracleMethodResponse_Response() {} +func (*RegisterUsingOracleMethodResponse_Certs) isRegisterUsingOracleMethodResponse_Response() {} + +func (m *RegisterUsingOracleMethodResponse) GetResponse() isRegisterUsingOracleMethodResponse_Response { + if m != nil { + return m.Response + } + return nil +} + +func (m *RegisterUsingOracleMethodResponse) GetChallenge() string { + if x, ok := m.GetResponse().(*RegisterUsingOracleMethodResponse_Challenge); ok { + return x.Challenge + } + return "" +} + +func (m *RegisterUsingOracleMethodResponse) GetCerts() *Certs { + if x, ok := m.GetResponse().(*RegisterUsingOracleMethodResponse_Certs); ok { + return x.Certs + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*RegisterUsingOracleMethodResponse) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*RegisterUsingOracleMethodResponse_Challenge)(nil), + (*RegisterUsingOracleMethodResponse_Certs)(nil), + } +} + func init() { proto.RegisterType((*RegisterUsingIAMMethodRequest)(nil), "proto.RegisterUsingIAMMethodRequest") proto.RegisterType((*RegisterUsingIAMMethodResponse)(nil), "proto.RegisterUsingIAMMethodResponse") @@ -787,6 +1029,11 @@ func init() { proto.RegisterType((*RegisterUsingTPMMethodResponse)(nil), "proto.RegisterUsingTPMMethodResponse") proto.RegisterType((*TPMAttestationParameters)(nil), "proto.TPMAttestationParameters") proto.RegisterType((*TPMEncryptedCredential)(nil), "proto.TPMEncryptedCredential") + proto.RegisterType((*OracleSignedRequest)(nil), "proto.OracleSignedRequest") + proto.RegisterMapType((map[string]string)(nil), "proto.OracleSignedRequest.HeadersEntry") + proto.RegisterMapType((map[string]string)(nil), "proto.OracleSignedRequest.PayloadHeadersEntry") + proto.RegisterType((*RegisterUsingOracleMethodRequest)(nil), "proto.RegisterUsingOracleMethodRequest") + proto.RegisterType((*RegisterUsingOracleMethodResponse)(nil), "proto.RegisterUsingOracleMethodResponse") } func init() { @@ -794,57 +1041,69 @@ func init() { } var fileDescriptor_d7e760ce923b836e = []byte{ - // 795 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6e, 0x22, 0x47, - 0x10, 0x66, 0xfc, 0x83, 0xe3, 0x82, 0x24, 0xa6, 0x15, 0x39, 0x18, 0xd9, 0x18, 0x4f, 0x9c, 0x98, - 0x28, 0x0a, 0x58, 0xe4, 0x05, 0x02, 0xd8, 0x12, 0x4e, 0xe2, 0xc8, 0x1a, 0x3b, 0x87, 0xe4, 0x32, - 0x6a, 0x86, 0x12, 0xee, 0x30, 0x9e, 0x99, 0x74, 0x37, 0x96, 0xc8, 0xa3, 0xe4, 0x92, 0x27, 0xd8, - 0xdb, 0x3e, 0xc4, 0x1e, 0x56, 0xab, 0x7d, 0x84, 0x95, 0xdf, 0x61, 0xef, 0xab, 0xe9, 0xee, 0x81, - 0x61, 0x00, 0x7b, 0x57, 0x5a, 0xed, 0x85, 0x51, 0x57, 0x55, 0x57, 0xd5, 0xf7, 0xd5, 0x4f, 0x03, - 0x0d, 0x89, 0x3e, 0x46, 0x21, 0x97, 0x4d, 0x1f, 0x87, 0xd4, 0x9b, 0x34, 0x3d, 0x9f, 0x61, 0x20, - 0x9b, 0x11, 0x0f, 0x65, 0xd8, 0xfc, 0x3b, 0x64, 0x81, 0x40, 0x7e, 0xcf, 0x3c, 0x6c, 0x28, 0x09, - 0xd9, 0x54, 0x9f, 0x4a, 0xfd, 0xd1, 0x6b, 0x1e, 0x72, 0x29, 0xf4, 0x85, 0xca, 0x51, 0xd6, 0x52, - 0x4e, 0x22, 0x14, 0xfa, 0x57, 0x9b, 0xd8, 0xcf, 0x2d, 0x38, 0x70, 0x70, 0xc8, 0x84, 0x44, 0xfe, - 0x87, 0x60, 0xc1, 0xf0, 0xa2, 0x7d, 0x79, 0x89, 0xf2, 0x36, 0x1c, 0x38, 0xf8, 0xcf, 0x18, 0x85, - 0x24, 0x14, 0xf6, 0xb9, 0x31, 0x70, 0xc7, 0xb1, 0x85, 0x2b, 0xc3, 0x11, 0x06, 0x2e, 0xd7, 0xfa, - 0xb2, 0x55, 0xb3, 0xea, 0x85, 0x56, 0xad, 0xa1, 0xbd, 0xce, 0xf9, 0xba, 0x89, 0x0d, 0x8d, 0x1f, - 0x67, 0x8f, 0xaf, 0x52, 0x91, 0x53, 0xf8, 0x4a, 0x48, 0xe1, 0xb2, 0x01, 0x06, 0x92, 0xc9, 0xc9, - 0xd4, 0xf5, 0x5a, 0xcd, 0xaa, 0x17, 0x1d, 0x22, 0xa4, 0xb8, 0x30, 0x2a, 0x73, 0xc3, 0xee, 0x43, - 0x75, 0x55, 0xd6, 0x22, 0x0a, 0x03, 0x81, 0x64, 0x1f, 0xb6, 0xbd, 0x5b, 0xea, 0xfb, 0x18, 0x0c, - 0x51, 0xe5, 0xb8, 0xed, 0xcc, 0x04, 0xc4, 0x86, 0x4d, 0x45, 0x94, 0x0a, 0x51, 0x68, 0x15, 0x35, - 0x1b, 0x8d, 0x6e, 0x2c, 0x73, 0xb4, 0xca, 0x7e, 0x69, 0xc1, 0xe1, 0x5c, 0x90, 0xf6, 0xbf, 0x63, - 0x8e, 0x9f, 0x9c, 0x9c, 0x6f, 0xe0, 0x73, 0x2a, 0x25, 0x0a, 0x89, 0x03, 0x77, 0x40, 0x25, 0x35, - 0xac, 0x14, 0x13, 0xe1, 0x19, 0x95, 0x94, 0x1c, 0x41, 0x91, 0x7a, 0x1e, 0x0a, 0xa1, 0xe3, 0x97, - 0xd7, 0x15, 0xe0, 0x82, 0x96, 0x29, 0x77, 0xf6, 0x00, 0x6a, 0xab, 0xd1, 0x7c, 0x34, 0xd2, 0xce, - 0xe1, 0x64, 0x1e, 0xe5, 0x95, 0x29, 0x4c, 0x37, 0x71, 0x33, 0x0d, 0x56, 0x81, 0xcf, 0x44, 0xe8, - 0x8f, 0x25, 0x0b, 0x03, 0x15, 0xab, 0xe8, 0x4c, 0xcf, 0xf6, 0x5b, 0x0b, 0x8e, 0x97, 0xfb, 0xb9, - 0x08, 0x98, 0x64, 0xd4, 0x4f, 0xd8, 0xe9, 0x42, 0x31, 0x1e, 0x94, 0x0f, 0x26, 0xbc, 0x10, 0xdf, - 0x4a, 0x9c, 0xec, 0xc1, 0x16, 0x8e, 0xdc, 0x18, 0x80, 0x26, 0xb7, 0x97, 0x73, 0xf2, 0x38, 0x8a, - 0x71, 0x91, 0xaf, 0x21, 0x8f, 0x23, 0x77, 0x84, 0x13, 0x45, 0x69, 0xac, 0xd9, 0xc4, 0xd1, 0xaf, - 0x38, 0x21, 0xbf, 0x03, 0xd1, 0x15, 0xa0, 0x71, 0xc2, 0x6e, 0x44, 0x39, 0xbd, 0x13, 0xe5, 0x0d, - 0x15, 0xfe, 0xd0, 0x30, 0x73, 0x73, 0x75, 0xd9, 0x9e, 0xd9, 0x5c, 0xc5, 0x26, 0x28, 0x91, 0x0b, - 0xa7, 0x44, 0x33, 0x62, 0xd1, 0xd9, 0x80, 0x35, 0x1c, 0xd9, 0xaf, 0xb2, 0xe3, 0x38, 0xc5, 0x9d, - 0xe4, 0xda, 0x86, 0x0d, 0x16, 0xb0, 0x04, 0xe8, 0x0f, 0x26, 0xd2, 0xfb, 0x70, 0xd5, 0xcb, 0x39, - 0xea, 0x2a, 0x71, 0x81, 0x4c, 0x8b, 0xea, 0x72, 0x53, 0x0e, 0x53, 0xd4, 0xc6, 0xa3, 0x0e, 0x17, - 0x8a, 0xd8, 0xcb, 0x39, 0x25, 0x2f, 0x2b, 0xec, 0x6c, 0xc3, 0x56, 0x44, 0x27, 0x7e, 0x48, 0x07, - 0xf6, 0xff, 0x56, 0x66, 0x52, 0x53, 0x80, 0x4c, 0x1f, 0xfc, 0x06, 0xa5, 0x74, 0x3a, 0xe9, 0x3a, - 0x1e, 0xcc, 0x88, 0x3c, 0x0f, 0x3c, 0x3e, 0x89, 0x24, 0x0e, 0xba, 0x1c, 0xd5, 0x32, 0xa0, 0x7e, - 0x2f, 0xe7, 0xec, 0xa4, 0x82, 0x6b, 0x7e, 0x8e, 0x1f, 0x69, 0xd2, 0xb8, 0x7a, 0x4a, 0x99, 0xce, - 0xf0, 0x99, 0x05, 0xe5, 0x55, 0x85, 0x22, 0xbb, 0x90, 0x8f, 0xc6, 0x7d, 0x9f, 0x79, 0xa6, 0x43, - 0xcd, 0x89, 0x1c, 0x42, 0xc1, 0xe3, 0x48, 0x25, 0xa6, 0x47, 0x12, 0xb4, 0x48, 0x0d, 0xe4, 0x8f, - 0x40, 0x8c, 0x41, 0xaa, 0xd4, 0xba, 0x87, 0x9c, 0x92, 0xd6, 0xa4, 0x22, 0x92, 0xef, 0x61, 0xc7, - 0x98, 0x0b, 0x36, 0x0c, 0xa8, 0x1c, 0x73, 0x54, 0xbd, 0x54, 0x74, 0xbe, 0xd4, 0xf2, 0xeb, 0x44, - 0x6c, 0xff, 0x09, 0xbb, 0xcb, 0xe9, 0x20, 0x27, 0x10, 0x1b, 0x9b, 0x93, 0xdb, 0xf7, 0xc3, 0xbe, - 0xc9, 0xfa, 0x8b, 0x99, 0xb8, 0xe3, 0x87, 0xfd, 0x18, 0x95, 0x40, 0x8f, 0x63, 0xb2, 0x61, 0xcd, - 0xa9, 0xf5, 0xdf, 0x3a, 0x14, 0x7e, 0x09, 0x59, 0x70, 0xad, 0x9f, 0x1d, 0xc2, 0x60, 0x77, 0xf9, - 0x96, 0x25, 0xc7, 0xcb, 0xda, 0x24, 0xfb, 0x74, 0x54, 0xbe, 0x7d, 0xc2, 0x4a, 0x37, 0x40, 0xdd, - 0x3a, 0xb5, 0x48, 0x08, 0xe5, 0x55, 0xdb, 0x89, 0x7c, 0xb7, 0xcc, 0xcd, 0xe2, 0x32, 0xae, 0x9c, - 0x3c, 0x69, 0x97, 0x0a, 0x98, 0xc5, 0x36, 0xed, 0xcb, 0xe5, 0xd8, 0xb2, 0x73, 0xb8, 0x1c, 0xdb, - 0x42, 0x73, 0xab, 0x50, 0x67, 0x40, 0x16, 0x17, 0x11, 0x79, 0x72, 0x47, 0x55, 0xe6, 0x7a, 0xb7, - 0xf3, 0xf3, 0x8b, 0x87, 0xaa, 0xf5, 0xfa, 0xa1, 0x6a, 0xbd, 0x79, 0xa8, 0x5a, 0x7f, 0xb5, 0x86, - 0x4c, 0xde, 0x8e, 0xfb, 0x0d, 0x2f, 0xbc, 0x6b, 0x0e, 0x39, 0xbd, 0x67, 0xba, 0x91, 0xa8, 0xdf, - 0x9c, 0xbe, 0xf9, 0x34, 0x62, 0x73, 0x7f, 0x0d, 0xfa, 0x79, 0xf5, 0xf9, 0xe9, 0x5d, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xb7, 0xb8, 0x98, 0xf9, 0x78, 0x08, 0x00, 0x00, + // 983 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6e, 0x23, 0x45, + 0x10, 0xf6, 0x38, 0x7f, 0x9b, 0xb2, 0x37, 0x9b, 0xf4, 0xae, 0x82, 0x33, 0xda, 0x75, 0x9c, 0x21, + 0x10, 0x23, 0x84, 0xbd, 0x32, 0x17, 0xb4, 0x27, 0x1c, 0x6f, 0x24, 0x07, 0x08, 0x44, 0xb3, 0x8b, + 0x10, 0x5c, 0x46, 0xed, 0x71, 0xc9, 0x69, 0x3c, 0x3b, 0x33, 0x74, 0xb7, 0x23, 0x99, 0x87, 0xe0, + 0x15, 0x78, 0x02, 0x24, 0x0e, 0x3c, 0x04, 0x07, 0x84, 0xb8, 0x71, 0x45, 0x79, 0x07, 0xee, 0x68, + 0xba, 0x7b, 0x9c, 0xf1, 0x78, 0xec, 0xec, 0x4a, 0x2b, 0x2e, 0x1e, 0x77, 0x75, 0x55, 0x7d, 0x5d, + 0x5f, 0xfd, 0x74, 0x43, 0x4b, 0x62, 0x80, 0x71, 0xc4, 0x65, 0x3b, 0xc0, 0x11, 0xf5, 0xa7, 0x6d, + 0x3f, 0x60, 0x18, 0xca, 0x76, 0xcc, 0x23, 0x19, 0xb5, 0xbf, 0x8f, 0x58, 0x28, 0x90, 0x5f, 0x33, + 0x1f, 0x5b, 0x4a, 0x42, 0x36, 0xd4, 0xc7, 0x6e, 0xae, 0x34, 0xf3, 0x91, 0x4b, 0xa1, 0x0d, 0xec, + 0xa3, 0xbc, 0xa6, 0x9c, 0xc6, 0x28, 0xf4, 0xaf, 0x56, 0x71, 0x7e, 0xb3, 0xe0, 0x89, 0x8b, 0x23, + 0x26, 0x24, 0xf2, 0xaf, 0x05, 0x0b, 0x47, 0xe7, 0xdd, 0x8b, 0x0b, 0x94, 0x57, 0xd1, 0xd0, 0xc5, + 0x1f, 0x26, 0x28, 0x24, 0xa1, 0xf0, 0x98, 0x1b, 0x05, 0x6f, 0x92, 0x68, 0x78, 0x32, 0x1a, 0x63, + 0xe8, 0x71, 0xbd, 0x5f, 0xb3, 0x1a, 0x56, 0xb3, 0xd2, 0x69, 0xb4, 0xb4, 0xd7, 0x39, 0x5f, 0x2f, + 0x13, 0x45, 0xe3, 0xc7, 0x3d, 0xe0, 0xcb, 0xb6, 0xc8, 0x53, 0x78, 0x24, 0xa4, 0xf0, 0xd8, 0x10, + 0x43, 0xc9, 0xe4, 0x74, 0xe6, 0xba, 0xdc, 0xb0, 0x9a, 0x55, 0x97, 0x08, 0x29, 0xce, 0xcd, 0x96, + 0xb1, 0x70, 0x06, 0x50, 0x5f, 0x76, 0x6a, 0x11, 0x47, 0xa1, 0x40, 0xf2, 0x18, 0xb6, 0xfd, 0x2b, + 0x1a, 0x04, 0x18, 0x8e, 0x50, 0x9d, 0x71, 0xdb, 0xbd, 0x15, 0x10, 0x07, 0x36, 0x14, 0x51, 0x0a, + 0xa2, 0xd2, 0xa9, 0x6a, 0x36, 0x5a, 0xbd, 0x44, 0xe6, 0xea, 0x2d, 0xe7, 0x0f, 0x0b, 0x0e, 0xe7, + 0x40, 0xba, 0x3f, 0x4e, 0x38, 0xfe, 0xef, 0xe4, 0xbc, 0x0b, 0xf7, 0xa9, 0x94, 0x28, 0x24, 0x0e, + 0xbd, 0x21, 0x95, 0xd4, 0xb0, 0x52, 0x4d, 0x85, 0xcf, 0xa9, 0xa4, 0xe4, 0x08, 0xaa, 0xd4, 0xf7, + 0x51, 0x08, 0x8d, 0x5f, 0x5b, 0x53, 0x01, 0x57, 0xb4, 0x4c, 0xb9, 0x73, 0x86, 0xd0, 0x58, 0x1e, + 0xcd, 0x5b, 0x23, 0xed, 0x0c, 0x4e, 0xe6, 0xa3, 0xbc, 0x34, 0x89, 0xe9, 0xa5, 0x6e, 0x66, 0x60, + 0x36, 0xdc, 0x13, 0x51, 0x30, 0x91, 0x2c, 0x0a, 0x15, 0x56, 0xd5, 0x9d, 0xad, 0x9d, 0x7f, 0x2d, + 0x38, 0x2e, 0xf6, 0x73, 0x1e, 0x32, 0xc9, 0x68, 0x90, 0xb2, 0xd3, 0x83, 0x6a, 0xd2, 0x28, 0x6f, + 0x4c, 0x78, 0x25, 0xb1, 0x4a, 0x9d, 0x1c, 0xc0, 0x16, 0x8e, 0xbd, 0x24, 0x00, 0x4d, 0x6e, 0xbf, + 0xe4, 0x6e, 0xe2, 0x38, 0x89, 0x8b, 0xbc, 0x03, 0x9b, 0x38, 0xf6, 0xc6, 0x38, 0x55, 0x94, 0x26, + 0x3b, 0x1b, 0x38, 0xfe, 0x1c, 0xa7, 0xe4, 0x4b, 0x20, 0x3a, 0x03, 0x34, 0x39, 0xb0, 0x17, 0x53, + 0x4e, 0x5f, 0x89, 0xda, 0xba, 0x82, 0x3f, 0x34, 0xcc, 0xbc, 0xbc, 0xbc, 0xe8, 0xde, 0xea, 0x5c, + 0x26, 0x2a, 0x28, 0x91, 0x0b, 0x77, 0x8f, 0xe6, 0xc4, 0xe2, 0x74, 0x1d, 0xca, 0x38, 0x76, 0xfe, + 0xcc, 0xb7, 0xe3, 0x2c, 0xee, 0xf4, 0xac, 0x5d, 0x58, 0x67, 0x21, 0x4b, 0x03, 0xfd, 0xd0, 0x20, + 0xbd, 0x0e, 0x57, 0xfd, 0x92, 0xab, 0x4c, 0x89, 0x07, 0x64, 0x96, 0x54, 0x8f, 0x9b, 0x74, 0x98, + 0xa4, 0xb6, 0x56, 0x3a, 0x5c, 0x48, 0x62, 0xbf, 0xe4, 0xee, 0xf9, 0x79, 0xe1, 0xe9, 0x36, 0x6c, + 0xc5, 0x74, 0x1a, 0x44, 0x74, 0xe8, 0xfc, 0x6c, 0xe5, 0x3a, 0x35, 0x13, 0x90, 0xa9, 0x83, 0x2f, + 0x60, 0x2f, 0x7b, 0x9c, 0x6c, 0x1e, 0x9f, 0xdc, 0x12, 0x79, 0x16, 0xfa, 0x7c, 0x1a, 0x4b, 0x1c, + 0xf6, 0x38, 0xaa, 0x61, 0x40, 0x83, 0x7e, 0xc9, 0xdd, 0xcd, 0x80, 0x6b, 0x7e, 0x8e, 0x57, 0x14, + 0x69, 0x92, 0x3d, 0xb5, 0x99, 0x3d, 0xe1, 0x2f, 0x16, 0xd4, 0x96, 0x25, 0x8a, 0xec, 0xc3, 0x66, + 0x3c, 0x19, 0x04, 0xcc, 0x37, 0x15, 0x6a, 0x56, 0xe4, 0x10, 0x2a, 0x3e, 0x47, 0x2a, 0x31, 0xdb, + 0x92, 0xa0, 0x45, 0xaa, 0x21, 0x3f, 0x02, 0x62, 0x14, 0x32, 0xa9, 0xd6, 0x35, 0xe4, 0xee, 0xe9, + 0x9d, 0x0c, 0x22, 0xf9, 0x00, 0x76, 0x8d, 0xba, 0x60, 0xa3, 0x90, 0xca, 0x09, 0x47, 0x55, 0x4b, + 0x55, 0xf7, 0x81, 0x96, 0xbf, 0x48, 0xc5, 0xce, 0xb7, 0xb0, 0x5f, 0x4c, 0x07, 0x39, 0x81, 0x44, + 0xd9, 0xac, 0xbc, 0x41, 0x10, 0x0d, 0xcc, 0xa9, 0x77, 0x6e, 0xc5, 0xa7, 0x41, 0x34, 0x48, 0xa2, + 0x12, 0xe8, 0x73, 0x4c, 0x27, 0xac, 0x59, 0x39, 0xbf, 0x96, 0xe1, 0xe1, 0x57, 0x9c, 0xfa, 0x81, + 0x82, 0xc3, 0x4c, 0xcd, 0x6d, 0x5d, 0x21, 0x1d, 0x22, 0x17, 0x35, 0xab, 0xb1, 0xd6, 0xac, 0x74, + 0x4e, 0x0c, 0xab, 0x05, 0xca, 0xad, 0xbe, 0xd6, 0x3c, 0x0b, 0x25, 0x9f, 0xba, 0xa9, 0x1d, 0xf9, + 0x06, 0x1e, 0x18, 0xc2, 0xbd, 0xd4, 0x55, 0x59, 0xb9, 0x6a, 0xad, 0x70, 0x75, 0xa9, 0x2d, 0xe6, + 0x3c, 0xee, 0xc4, 0x73, 0x42, 0xfb, 0x19, 0x54, 0xb3, 0xfb, 0x64, 0x17, 0xd6, 0x92, 0x6e, 0xd5, + 0xc3, 0x2b, 0xf9, 0x4b, 0x1e, 0xc1, 0xc6, 0x35, 0x0d, 0x26, 0xba, 0xc2, 0xb7, 0x5d, 0xbd, 0x78, + 0x56, 0xfe, 0xc4, 0xb2, 0xbb, 0xf0, 0xb0, 0x00, 0xe2, 0x4d, 0x5c, 0x38, 0x7f, 0x5b, 0xb9, 0xb1, + 0xaa, 0xe3, 0x98, 0xef, 0x59, 0xff, 0xed, 0xdc, 0x12, 0xfd, 0xd2, 0xaa, 0x7b, 0xa2, 0x07, 0x3b, + 0x91, 0xc2, 0x9e, 0xbb, 0x3e, 0x2b, 0x1d, 0x7b, 0x39, 0xc1, 0xfd, 0x92, 0x7b, 0x5f, 0xdb, 0x18, + 0x41, 0xd2, 0x17, 0xc6, 0xda, 0x99, 0xc0, 0xd1, 0x8a, 0xc0, 0x4c, 0xef, 0xd6, 0x17, 0x2e, 0x8c, + 0x7e, 0x29, 0x7b, 0x65, 0xbc, 0x5e, 0x37, 0x02, 0xdc, 0x4b, 0xc7, 0x50, 0xe7, 0xa7, 0x75, 0xa8, + 0x7c, 0x16, 0xb1, 0xf0, 0x85, 0x7e, 0xfa, 0x10, 0x06, 0xfb, 0xc5, 0x37, 0x3d, 0x39, 0x2e, 0x1a, + 0x55, 0xf9, 0xe7, 0x8b, 0xfd, 0xde, 0x1d, 0x5a, 0x1a, 0xb6, 0x69, 0x3d, 0xb5, 0x48, 0x04, 0xb5, + 0x65, 0x37, 0x24, 0x79, 0xbf, 0xc8, 0xcd, 0xe2, 0x83, 0xc0, 0x3e, 0xb9, 0x53, 0x2f, 0x03, 0x98, + 0x8f, 0x6d, 0x36, 0x1b, 0x8b, 0x63, 0xcb, 0xdf, 0x05, 0xc5, 0xb1, 0x2d, 0x0c, 0x58, 0x05, 0xc5, + 0xe1, 0x60, 0x69, 0x36, 0x49, 0xe1, 0xa1, 0x0b, 0x0a, 0xd9, 0x6e, 0xde, 0xad, 0x98, 0xc1, 0x7c, + 0x0e, 0x64, 0xb1, 0x96, 0xc9, 0x9d, 0x65, 0x6e, 0xcf, 0x55, 0xc9, 0xe9, 0xa7, 0xbf, 0xdf, 0xd4, + 0xad, 0xbf, 0x6e, 0xea, 0xd6, 0x3f, 0x37, 0x75, 0xeb, 0xbb, 0xce, 0x88, 0xc9, 0xab, 0xc9, 0xa0, + 0xe5, 0x47, 0xaf, 0xda, 0x23, 0x4e, 0xaf, 0x99, 0x1e, 0xa0, 0x34, 0x68, 0xcf, 0xde, 0xba, 0x34, + 0x66, 0x73, 0x4f, 0xe2, 0xc1, 0xa6, 0xfa, 0x7c, 0xfc, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9b, + 0x47, 0xf1, 0x87, 0x70, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -868,6 +1127,9 @@ type JoinServiceClient interface { // RegisterUsingTPMMethod allows registration of a new agent or Bot to the // cluster using a known TPM. RegisterUsingTPMMethod(ctx context.Context, opts ...grpc.CallOption) (JoinService_RegisterUsingTPMMethodClient, error) + // RegisterUsingOracleMethod allows registration of a new node to the cluster + // using the Oracle join method. + RegisterUsingOracleMethod(ctx context.Context, opts ...grpc.CallOption) (JoinService_RegisterUsingOracleMethodClient, error) // RegisterUsingToken is used to register a new node to the cluster using one // of the legacy join methods which do not yet have their own gRPC method. RegisterUsingToken(ctx context.Context, in *types.RegisterUsingTokenRequest, opts ...grpc.CallOption) (*Certs, error) @@ -974,6 +1236,37 @@ func (x *joinServiceRegisterUsingTPMMethodClient) Recv() (*RegisterUsingTPMMetho return m, nil } +func (c *joinServiceClient) RegisterUsingOracleMethod(ctx context.Context, opts ...grpc.CallOption) (JoinService_RegisterUsingOracleMethodClient, error) { + stream, err := c.cc.NewStream(ctx, &_JoinService_serviceDesc.Streams[3], "/proto.JoinService/RegisterUsingOracleMethod", opts...) + if err != nil { + return nil, err + } + x := &joinServiceRegisterUsingOracleMethodClient{stream} + return x, nil +} + +type JoinService_RegisterUsingOracleMethodClient interface { + Send(*RegisterUsingOracleMethodRequest) error + Recv() (*RegisterUsingOracleMethodResponse, error) + grpc.ClientStream +} + +type joinServiceRegisterUsingOracleMethodClient struct { + grpc.ClientStream +} + +func (x *joinServiceRegisterUsingOracleMethodClient) Send(m *RegisterUsingOracleMethodRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *joinServiceRegisterUsingOracleMethodClient) Recv() (*RegisterUsingOracleMethodResponse, error) { + m := new(RegisterUsingOracleMethodResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *joinServiceClient) RegisterUsingToken(ctx context.Context, in *types.RegisterUsingTokenRequest, opts ...grpc.CallOption) (*Certs, error) { out := new(Certs) err := c.cc.Invoke(ctx, "/proto.JoinService/RegisterUsingToken", in, out, opts...) @@ -994,6 +1287,9 @@ type JoinServiceServer interface { // RegisterUsingTPMMethod allows registration of a new agent or Bot to the // cluster using a known TPM. RegisterUsingTPMMethod(JoinService_RegisterUsingTPMMethodServer) error + // RegisterUsingOracleMethod allows registration of a new node to the cluster + // using the Oracle join method. + RegisterUsingOracleMethod(JoinService_RegisterUsingOracleMethodServer) error // RegisterUsingToken is used to register a new node to the cluster using one // of the legacy join methods which do not yet have their own gRPC method. RegisterUsingToken(context.Context, *types.RegisterUsingTokenRequest) (*Certs, error) @@ -1012,6 +1308,9 @@ func (*UnimplementedJoinServiceServer) RegisterUsingAzureMethod(srv JoinService_ func (*UnimplementedJoinServiceServer) RegisterUsingTPMMethod(srv JoinService_RegisterUsingTPMMethodServer) error { return status.Errorf(codes.Unimplemented, "method RegisterUsingTPMMethod not implemented") } +func (*UnimplementedJoinServiceServer) RegisterUsingOracleMethod(srv JoinService_RegisterUsingOracleMethodServer) error { + return status.Errorf(codes.Unimplemented, "method RegisterUsingOracleMethod not implemented") +} func (*UnimplementedJoinServiceServer) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*Certs, error) { return nil, status.Errorf(codes.Unimplemented, "method RegisterUsingToken not implemented") } @@ -1098,6 +1397,32 @@ func (x *joinServiceRegisterUsingTPMMethodServer) Recv() (*RegisterUsingTPMMetho return m, nil } +func _JoinService_RegisterUsingOracleMethod_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(JoinServiceServer).RegisterUsingOracleMethod(&joinServiceRegisterUsingOracleMethodServer{stream}) +} + +type JoinService_RegisterUsingOracleMethodServer interface { + Send(*RegisterUsingOracleMethodResponse) error + Recv() (*RegisterUsingOracleMethodRequest, error) + grpc.ServerStream +} + +type joinServiceRegisterUsingOracleMethodServer struct { + grpc.ServerStream +} + +func (x *joinServiceRegisterUsingOracleMethodServer) Send(m *RegisterUsingOracleMethodResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *joinServiceRegisterUsingOracleMethodServer) Recv() (*RegisterUsingOracleMethodRequest, error) { + m := new(RegisterUsingOracleMethodRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func _JoinService_RegisterUsingToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(types.RegisterUsingTokenRequest) if err := dec(in); err != nil { @@ -1144,6 +1469,12 @@ var _JoinService_serviceDesc = grpc.ServiceDesc{ ServerStreams: true, ClientStreams: true, }, + { + StreamName: "RegisterUsingOracleMethod", + Handler: _JoinService_RegisterUsingOracleMethod_Handler, + ServerStreams: true, + ClientStreams: true, + }, }, Metadata: "teleport/legacy/client/proto/joinservice.proto", } @@ -1717,66 +2048,280 @@ func (m *TPMEncryptedCredential) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func encodeVarintJoinservice(dAtA []byte, offset int, v uint64) int { - offset -= sovJoinservice(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *OracleSignedRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *RegisterUsingIAMMethodRequest) Size() (n int) { - if m == nil { - return 0 - } + +func (m *OracleSignedRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OracleSignedRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.RegisterUsingTokenRequest != nil { - l = m.RegisterUsingTokenRequest.Size() - n += 1 + l + sovJoinservice(uint64(l)) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - l = len(m.StsIdentityRequest) - if l > 0 { - n += 1 + l + sovJoinservice(uint64(l)) + if len(m.PayloadHeaders) > 0 { + for k := range m.PayloadHeaders { + v := m.PayloadHeaders[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintJoinservice(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintJoinservice(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintJoinservice(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + if len(m.Headers) > 0 { + for k := range m.Headers { + v := m.Headers[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintJoinservice(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintJoinservice(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintJoinservice(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0xa + } } - return n + return len(dAtA) - i, nil } -func (m *RegisterUsingIAMMethodResponse) Size() (n int) { - if m == nil { - return 0 +func (m *RegisterUsingOracleMethodRequest) 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 *RegisterUsingOracleMethodRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterUsingOracleMethodRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Challenge) - if l > 0 { - n += 1 + l + sovJoinservice(uint64(l)) - } - if m.Certs != nil { - l = m.Certs.Size() - n += 1 + l + sovJoinservice(uint64(l)) - } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n + if m.Request != nil { + { + size := m.Request.Size() + i -= size + if _, err := m.Request.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil } -func (m *RegisterUsingAzureMethodRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l +func (m *RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) if m.RegisterUsingTokenRequest != nil { - l = m.RegisterUsingTokenRequest.Size() - n += 1 + l + sovJoinservice(uint64(l)) + { + size, err := m.RegisterUsingTokenRequest.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintJoinservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *RegisterUsingOracleMethodRequest_OracleRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterUsingOracleMethodRequest_OracleRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.OracleRequest != nil { + { + size, err := m.OracleRequest.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintJoinservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *RegisterUsingOracleMethodResponse) 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 *RegisterUsingOracleMethodResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterUsingOracleMethodResponse) 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.Response != nil { + { + size := m.Response.Size() + i -= size + if _, err := m.Response.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *RegisterUsingOracleMethodResponse_Challenge) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterUsingOracleMethodResponse_Challenge) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i -= len(m.Challenge) + copy(dAtA[i:], m.Challenge) + i = encodeVarintJoinservice(dAtA, i, uint64(len(m.Challenge))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} +func (m *RegisterUsingOracleMethodResponse_Certs) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisterUsingOracleMethodResponse_Certs) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Certs != nil { + { + size, err := m.Certs.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintJoinservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func encodeVarintJoinservice(dAtA []byte, offset int, v uint64) int { + offset -= sovJoinservice(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *RegisterUsingIAMMethodRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RegisterUsingTokenRequest != nil { + l = m.RegisterUsingTokenRequest.Size() + n += 1 + l + sovJoinservice(uint64(l)) + } + l = len(m.StsIdentityRequest) + if l > 0 { + n += 1 + l + sovJoinservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RegisterUsingIAMMethodResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Challenge) + if l > 0 { + n += 1 + l + sovJoinservice(uint64(l)) + } + if m.Certs != nil { + l = m.Certs.Size() + n += 1 + l + sovJoinservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RegisterUsingAzureMethodRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RegisterUsingTokenRequest != nil { + l = m.RegisterUsingTokenRequest.Size() + n += 1 + l + sovJoinservice(uint64(l)) } l = len(m.AttestedData) if l > 0 { @@ -2001,6 +2546,111 @@ func (m *TPMEncryptedCredential) Size() (n int) { return n } +func (m *OracleSignedRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Headers) > 0 { + for k, v := range m.Headers { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovJoinservice(uint64(len(k))) + 1 + len(v) + sovJoinservice(uint64(len(v))) + n += mapEntrySize + 1 + sovJoinservice(uint64(mapEntrySize)) + } + } + if len(m.PayloadHeaders) > 0 { + for k, v := range m.PayloadHeaders { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovJoinservice(uint64(len(k))) + 1 + len(v) + sovJoinservice(uint64(len(v))) + n += mapEntrySize + 1 + sovJoinservice(uint64(mapEntrySize)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RegisterUsingOracleMethodRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Request != nil { + n += m.Request.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RegisterUsingTokenRequest != nil { + l = m.RegisterUsingTokenRequest.Size() + n += 1 + l + sovJoinservice(uint64(l)) + } + return n +} +func (m *RegisterUsingOracleMethodRequest_OracleRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OracleRequest != nil { + l = m.OracleRequest.Size() + n += 1 + l + sovJoinservice(uint64(l)) + } + return n +} +func (m *RegisterUsingOracleMethodResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Response != nil { + n += m.Response.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RegisterUsingOracleMethodResponse_Challenge) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Challenge) + n += 1 + l + sovJoinservice(uint64(l)) + return n +} +func (m *RegisterUsingOracleMethodResponse_Certs) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Certs != nil { + l = m.Certs.Size() + n += 1 + l + sovJoinservice(uint64(l)) + } + return n +} + func sovJoinservice(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3341,6 +3991,550 @@ func (m *TPMEncryptedCredential) Unmarshal(dAtA []byte) error { } return nil } +func (m *OracleSignedRequest) 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 ErrIntOverflowJoinservice + } + 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: OracleSignedRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OracleSignedRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJoinservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthJoinservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthJoinservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Headers == nil { + m.Headers = 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 ErrIntOverflowJoinservice + } + 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 ErrIntOverflowJoinservice + } + 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 ErrInvalidLengthJoinservice + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthJoinservice + } + 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 ErrIntOverflowJoinservice + } + 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 ErrInvalidLengthJoinservice + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthJoinservice + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipJoinservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthJoinservice + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Headers[mapkey] = mapvalue + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PayloadHeaders", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJoinservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthJoinservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthJoinservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PayloadHeaders == nil { + m.PayloadHeaders = 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 ErrIntOverflowJoinservice + } + 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 ErrIntOverflowJoinservice + } + 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 ErrInvalidLengthJoinservice + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthJoinservice + } + 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 ErrIntOverflowJoinservice + } + 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 ErrInvalidLengthJoinservice + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthJoinservice + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipJoinservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthJoinservice + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.PayloadHeaders[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipJoinservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthJoinservice + } + 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 *RegisterUsingOracleMethodRequest) 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 ErrIntOverflowJoinservice + } + 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: RegisterUsingOracleMethodRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisterUsingOracleMethodRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RegisterUsingTokenRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJoinservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthJoinservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthJoinservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &types.RegisterUsingTokenRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &RegisterUsingOracleMethodRequest_RegisterUsingTokenRequest{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OracleRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJoinservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthJoinservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthJoinservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &OracleSignedRequest{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Request = &RegisterUsingOracleMethodRequest_OracleRequest{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipJoinservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthJoinservice + } + 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 *RegisterUsingOracleMethodResponse) 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 ErrIntOverflowJoinservice + } + 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: RegisterUsingOracleMethodResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisterUsingOracleMethodResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Challenge", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJoinservice + } + 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 ErrInvalidLengthJoinservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthJoinservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Response = &RegisterUsingOracleMethodResponse_Challenge{string(dAtA[iNdEx:postIndex])} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Certs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJoinservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthJoinservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthJoinservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &Certs{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Response = &RegisterUsingOracleMethodResponse_Certs{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipJoinservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthJoinservice + } + 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 skipJoinservice(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/api/proto/teleport/legacy/client/proto/joinservice.proto b/api/proto/teleport/legacy/client/proto/joinservice.proto index 4448558693d58..5d4c251805102 100644 --- a/api/proto/teleport/legacy/client/proto/joinservice.proto +++ b/api/proto/teleport/legacy/client/proto/joinservice.proto @@ -158,6 +158,42 @@ message TPMEncryptedCredential { bytes secret = 2; } +// OracleSignedRequest holds the headers and payload for a signed request to +// the Oracle API. +message OracleSignedRequest { + // Headers is the signed headers for a request to the Oracle authorizeClient + // endpoint. + map headers = 1; + // PayloadHeaders is the signed headers that are the payload to the authorizeClient + // request signified by Headers. + map payload_headers = 2; +} + +// RegisterUsingOracleMethodRequest is the request for registration via the +// Oracle join method. +message RegisterUsingOracleMethodRequest { + oneof request { + // RegisterUsingTokenRequest holds registration parameters common to all join + // methods. + types.RegisterUsingTokenRequest register_using_token_request = 1; + // OracleRequest holds the headers and payload for a signed request to + // the Oracle API. + OracleSignedRequest oracle_request = 2; + } +} + +// RegisterUsingOracleMethodResponse is a stream response and will contain either +// a Challenge or signed Certs to join the cluster. +message RegisterUsingOracleMethodResponse { + oneof response { + // Challenge is a crypto-random string that should be included in the signed + // headers. + string challenge = 1; + // Certs is the returned signed certs. + Certs certs = 2; + } +} + // JoinService provides methods which allow Teleport nodes, proxies, and other // services to join the Teleport cluster by fetching signed cluster // certificates. It is implemented on both the Auth and Proxy servers to serve @@ -173,6 +209,9 @@ service JoinService { // RegisterUsingTPMMethod allows registration of a new agent or Bot to the // cluster using a known TPM. rpc RegisterUsingTPMMethod(stream RegisterUsingTPMMethodRequest) returns (stream RegisterUsingTPMMethodResponse); + // RegisterUsingOracleMethod allows registration of a new node to the cluster + // using the Oracle join method. + rpc RegisterUsingOracleMethod(stream RegisterUsingOracleMethodRequest) returns (stream RegisterUsingOracleMethodResponse); // RegisterUsingToken is used to register a new node to the cluster using one // of the legacy join methods which do not yet have their own gRPC method. rpc RegisterUsingToken(types.RegisterUsingTokenRequest) returns (Certs); diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 7c522d9fd30ae..5ef26f33d3b05 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -1407,6 +1407,8 @@ message ProvisionTokenSpecV2 { ProvisionTokenSpecV2TerraformCloud TerraformCloud = 16 [(gogoproto.jsontag) = "terraform_cloud,omitempty"]; // Bitbucket allows the configuration of options specific to the "bitbucket" join method. ProvisionTokenSpecV2Bitbucket Bitbucket = 17 [(gogoproto.jsontag) = "bitbucket,omitempty"]; + // Oracle allows the configuration of options specific to the "oracle" join method. + ProvisionTokenSpecV2Oracle Oracle = 18 [(gogoproto.jsontag) = "oracle,omitempty"]; } // ProvisionTokenSpecV2TPM contains the TPM-specific part of the @@ -1795,6 +1797,28 @@ message ProvisionTokenSpecV2Bitbucket { string IdentityProviderURL = 3 [(gogoproto.jsontag) = "identity_provider_url,omitempty"]; } +// ProvisionTokenSpecV2Oracle contains Oracle-specific parts of the +// ProvisionTokenSpecV2. +message ProvisionTokenSpecV2Oracle { + // Rule is a set of properties the Oracle instance might have to be allowed + // to use this ProvisionToken. + message Rule { + // Tenancy is the OCID of the instance's tenancy. Required. + string Tenancy = 1 [(gogoproto.jsontag) = "tenancy"]; + // ParentCompartments is a list of the OCIDs of compartments an instance is + // allowed to join from. Only direct parents are allowed, i.e. no nested + // compartments. If empty, any compartment is allowed. + repeated string ParentCompartments = 2 [(gogoproto.jsontag) = "parent_compartments,omitempty"]; + // Regions is a list of regions an instance is allowed to join from. Both + // full region names ("us-phoenix-1") and abbreviations ("phx") are allowed. + // If empty, any region is allowed. + repeated string Regions = 3 [(gogoproto.jsontag) = "regions,omitempty"]; + } + // Allow is a list of Rules, nodes using this token must match one + // allow rule to use this token. + repeated Rule Allow = 1 [(gogoproto.jsontag) = "allow,omitempty"]; +} + // StaticTokensV2 implements the StaticTokens interface. message StaticTokensV2 { option (gogoproto.goproto_stringer) = false; diff --git a/api/types/provisioning.go b/api/types/provisioning.go index 359568137876e..21d6885c789dd 100644 --- a/api/types/provisioning.go +++ b/api/types/provisioning.go @@ -77,6 +77,9 @@ const ( // JoinMethodBitbucket indicates that the node will join using the Bitbucket // join method. See lib/bitbucket for more. JoinMethodBitbucket JoinMethod = "bitbucket" + // JoinMethodOracle indicates that the node will join using the Oracle join + // method. + JoinMethodOracle JoinMethod = "oracle" ) var JoinMethods = []JoinMethod{ @@ -93,6 +96,7 @@ var JoinMethods = []JoinMethod{ JoinMethodToken, JoinMethodTPM, JoinMethodTerraformCloud, + JoinMethodOracle, } func ValidateJoinMethod(method JoinMethod) error { @@ -378,6 +382,17 @@ func (p *ProvisionTokenV2) CheckAndSetDefaults() error { if err := providerCfg.checkAndSetDefaults(); err != nil { return trace.Wrap(err, "spec.bitbucket: failed validation") } + case JoinMethodOracle: + providerCfg := p.Spec.Oracle + if providerCfg == nil { + return trace.BadParameter( + "spec.oracle: must be configured for the join method %q", + JoinMethodOracle, + ) + } + if err := providerCfg.checkAndSetDefaults(); err != nil { + return trace.Wrap(err, "spec.oracle: failed validation") + } default: return trace.BadParameter("unknown join method %q", p.Spec.JoinMethod) } @@ -905,3 +920,18 @@ func (a *ProvisionTokenSpecV2Bitbucket) checkAndSetDefaults() error { return nil } + +func (a *ProvisionTokenSpecV2Oracle) checkAndSetDefaults() error { + if len(a.Allow) == 0 { + return trace.BadParameter("the %q join method requires at least one allow rule", JoinMethodOracle) + } + for i, rule := range a.Allow { + if rule.Tenancy == "" { + return trace.BadParameter( + "allow[%d]: tenancy must be set", + i, + ) + } + } + return nil +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index bba2b7fd821ca..8b7501b928414 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -1124,7 +1124,7 @@ func (x ClusterAuditConfigSpecV2_FIPSEndpointState) String() string { } func (ClusterAuditConfigSpecV2_FIPSEndpointState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{81, 0} + return fileDescriptor_9198ee693835762e, []int{82, 0} } // TraceType is an identification of the checkpoint. @@ -1194,7 +1194,7 @@ func (x ConnectionDiagnosticTrace_TraceType) String() string { } func (ConnectionDiagnosticTrace_TraceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{264, 0} + return fileDescriptor_9198ee693835762e, []int{265, 0} } // StatusType describes whether this was a success or a failure. @@ -1223,7 +1223,7 @@ func (x ConnectionDiagnosticTrace_StatusType) String() string { } func (ConnectionDiagnosticTrace_StatusType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{264, 1} + return fileDescriptor_9198ee693835762e, []int{265, 1} } // OktaAssignmentStatus represents the status of an Okta assignment. @@ -1263,7 +1263,7 @@ func (x OktaAssignmentSpecV1_OktaAssignmentStatus) String() string { } func (OktaAssignmentSpecV1_OktaAssignmentStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{350, 0} + return fileDescriptor_9198ee693835762e, []int{351, 0} } // OktaAssignmentTargetType is the type of Okta object that an assignment is targeting. @@ -1295,7 +1295,7 @@ func (x OktaAssignmentTargetV1_OktaAssignmentTargetType) String() string { } func (OktaAssignmentTargetV1_OktaAssignmentTargetType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{351, 0} + return fileDescriptor_9198ee693835762e, []int{352, 0} } type KeepAlive struct { @@ -4631,10 +4631,12 @@ type ProvisionTokenSpecV2 struct { // TerraformCloud allows the configuration of options specific to the "terraform_cloud" join method. TerraformCloud *ProvisionTokenSpecV2TerraformCloud `protobuf:"bytes,16,opt,name=TerraformCloud,proto3" json:"terraform_cloud,omitempty"` // Bitbucket allows the configuration of options specific to the "bitbucket" join method. - Bitbucket *ProvisionTokenSpecV2Bitbucket `protobuf:"bytes,17,opt,name=Bitbucket,proto3" json:"bitbucket,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Bitbucket *ProvisionTokenSpecV2Bitbucket `protobuf:"bytes,17,opt,name=Bitbucket,proto3" json:"bitbucket,omitempty"` + // Oracle allows the configuration of options specific to the "oracle" join method. + Oracle *ProvisionTokenSpecV2Oracle `protobuf:"bytes,18,opt,name=Oracle,proto3" json:"oracle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ProvisionTokenSpecV2) Reset() { *m = ProvisionTokenSpecV2{} } @@ -5801,6 +5803,101 @@ func (m *ProvisionTokenSpecV2Bitbucket_Rule) XXX_DiscardUnknown() { var xxx_messageInfo_ProvisionTokenSpecV2Bitbucket_Rule proto.InternalMessageInfo +// ProvisionTokenSpecV2Oracle contains Oracle-specific parts of the +// ProvisionTokenSpecV2. +type ProvisionTokenSpecV2Oracle struct { + // Allow is a list of Rules, nodes using this token must match one + // allow rule to use this token. + Allow []*ProvisionTokenSpecV2Oracle_Rule `protobuf:"bytes,1,rep,name=Allow,proto3" json:"allow,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProvisionTokenSpecV2Oracle) Reset() { *m = ProvisionTokenSpecV2Oracle{} } +func (m *ProvisionTokenSpecV2Oracle) String() string { return proto.CompactTextString(m) } +func (*ProvisionTokenSpecV2Oracle) ProtoMessage() {} +func (*ProvisionTokenSpecV2Oracle) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{76} +} +func (m *ProvisionTokenSpecV2Oracle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ProvisionTokenSpecV2Oracle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ProvisionTokenSpecV2Oracle.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 *ProvisionTokenSpecV2Oracle) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProvisionTokenSpecV2Oracle.Merge(m, src) +} +func (m *ProvisionTokenSpecV2Oracle) XXX_Size() int { + return m.Size() +} +func (m *ProvisionTokenSpecV2Oracle) XXX_DiscardUnknown() { + xxx_messageInfo_ProvisionTokenSpecV2Oracle.DiscardUnknown(m) +} + +var xxx_messageInfo_ProvisionTokenSpecV2Oracle proto.InternalMessageInfo + +// Rule is a set of properties the Oracle instance might have to be allowed +// to use this ProvisionToken. +type ProvisionTokenSpecV2Oracle_Rule struct { + // Tenancy is the OCID of the instance's tenancy. Required. + Tenancy string `protobuf:"bytes,1,opt,name=Tenancy,proto3" json:"tenancy"` + // ParentCompartments is a list of the OCIDs of compartments an instance is + // allowed to join from. Only direct parents are allowed, i.e. no nested + // compartments. If empty, any compartment is allowed. + ParentCompartments []string `protobuf:"bytes,2,rep,name=ParentCompartments,proto3" json:"parent_compartments,omitempty"` + // Regions is a list of regions an instance is allowed to join from. Both + // full region names ("us-phoenix-1") and abbreviations ("phx") are allowed. + // If empty, any region is allowed. + Regions []string `protobuf:"bytes,3,rep,name=Regions,proto3" json:"regions,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProvisionTokenSpecV2Oracle_Rule) Reset() { *m = ProvisionTokenSpecV2Oracle_Rule{} } +func (m *ProvisionTokenSpecV2Oracle_Rule) String() string { return proto.CompactTextString(m) } +func (*ProvisionTokenSpecV2Oracle_Rule) ProtoMessage() {} +func (*ProvisionTokenSpecV2Oracle_Rule) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{76, 0} +} +func (m *ProvisionTokenSpecV2Oracle_Rule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ProvisionTokenSpecV2Oracle_Rule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ProvisionTokenSpecV2Oracle_Rule.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 *ProvisionTokenSpecV2Oracle_Rule) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProvisionTokenSpecV2Oracle_Rule.Merge(m, src) +} +func (m *ProvisionTokenSpecV2Oracle_Rule) XXX_Size() int { + return m.Size() +} +func (m *ProvisionTokenSpecV2Oracle_Rule) XXX_DiscardUnknown() { + xxx_messageInfo_ProvisionTokenSpecV2Oracle_Rule.DiscardUnknown(m) +} + +var xxx_messageInfo_ProvisionTokenSpecV2Oracle_Rule proto.InternalMessageInfo + // StaticTokensV2 implements the StaticTokens interface. type StaticTokensV2 struct { // Kind is a resource kind @@ -5821,7 +5918,7 @@ type StaticTokensV2 struct { func (m *StaticTokensV2) Reset() { *m = StaticTokensV2{} } func (*StaticTokensV2) ProtoMessage() {} func (*StaticTokensV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{76} + return fileDescriptor_9198ee693835762e, []int{77} } func (m *StaticTokensV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5864,7 +5961,7 @@ func (m *StaticTokensSpecV2) Reset() { *m = StaticTokensSpecV2{} } func (m *StaticTokensSpecV2) String() string { return proto.CompactTextString(m) } func (*StaticTokensSpecV2) ProtoMessage() {} func (*StaticTokensSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{77} + return fileDescriptor_9198ee693835762e, []int{78} } func (m *StaticTokensSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5913,7 +6010,7 @@ type ClusterNameV2 struct { func (m *ClusterNameV2) Reset() { *m = ClusterNameV2{} } func (*ClusterNameV2) ProtoMessage() {} func (*ClusterNameV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{78} + return fileDescriptor_9198ee693835762e, []int{79} } func (m *ClusterNameV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5959,7 +6056,7 @@ func (m *ClusterNameSpecV2) Reset() { *m = ClusterNameSpecV2{} } func (m *ClusterNameSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNameSpecV2) ProtoMessage() {} func (*ClusterNameSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{79} + return fileDescriptor_9198ee693835762e, []int{80} } func (m *ClusterNameSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6009,7 +6106,7 @@ func (m *ClusterAuditConfigV2) Reset() { *m = ClusterAuditConfigV2{} } func (m *ClusterAuditConfigV2) String() string { return proto.CompactTextString(m) } func (*ClusterAuditConfigV2) ProtoMessage() {} func (*ClusterAuditConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{80} + return fileDescriptor_9198ee693835762e, []int{81} } func (m *ClusterAuditConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6079,7 +6176,7 @@ func (m *ClusterAuditConfigSpecV2) Reset() { *m = ClusterAuditConfigSpec func (m *ClusterAuditConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterAuditConfigSpecV2) ProtoMessage() {} func (*ClusterAuditConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{81} + return fileDescriptor_9198ee693835762e, []int{82} } func (m *ClusterAuditConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6130,7 +6227,7 @@ func (m *ClusterNetworkingConfigV2) Reset() { *m = ClusterNetworkingConf func (m *ClusterNetworkingConfigV2) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigV2) ProtoMessage() {} func (*ClusterNetworkingConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{82} + return fileDescriptor_9198ee693835762e, []int{83} } func (m *ClusterNetworkingConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6209,7 +6306,7 @@ func (m *ClusterNetworkingConfigSpecV2) Reset() { *m = ClusterNetworking func (m *ClusterNetworkingConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigSpecV2) ProtoMessage() {} func (*ClusterNetworkingConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{83} + return fileDescriptor_9198ee693835762e, []int{84} } func (m *ClusterNetworkingConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6254,7 +6351,7 @@ func (m *TunnelStrategyV1) Reset() { *m = TunnelStrategyV1{} } func (m *TunnelStrategyV1) String() string { return proto.CompactTextString(m) } func (*TunnelStrategyV1) ProtoMessage() {} func (*TunnelStrategyV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{84} + return fileDescriptor_9198ee693835762e, []int{85} } func (m *TunnelStrategyV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6339,7 +6436,7 @@ func (m *AgentMeshTunnelStrategy) Reset() { *m = AgentMeshTunnelStrategy func (m *AgentMeshTunnelStrategy) String() string { return proto.CompactTextString(m) } func (*AgentMeshTunnelStrategy) ProtoMessage() {} func (*AgentMeshTunnelStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{85} + return fileDescriptor_9198ee693835762e, []int{86} } func (m *AgentMeshTunnelStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6380,7 +6477,7 @@ func (m *ProxyPeeringTunnelStrategy) Reset() { *m = ProxyPeeringTunnelSt func (m *ProxyPeeringTunnelStrategy) String() string { return proto.CompactTextString(m) } func (*ProxyPeeringTunnelStrategy) ProtoMessage() {} func (*ProxyPeeringTunnelStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{86} + return fileDescriptor_9198ee693835762e, []int{87} } func (m *ProxyPeeringTunnelStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6431,7 +6528,7 @@ func (m *SessionRecordingConfigV2) Reset() { *m = SessionRecordingConfig func (m *SessionRecordingConfigV2) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigV2) ProtoMessage() {} func (*SessionRecordingConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{87} + return fileDescriptor_9198ee693835762e, []int{88} } func (m *SessionRecordingConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6477,7 +6574,7 @@ func (m *SessionRecordingConfigSpecV2) Reset() { *m = SessionRecordingCo func (m *SessionRecordingConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigSpecV2) ProtoMessage() {} func (*SessionRecordingConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{88} + return fileDescriptor_9198ee693835762e, []int{89} } func (m *SessionRecordingConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6527,7 +6624,7 @@ type AuthPreferenceV2 struct { func (m *AuthPreferenceV2) Reset() { *m = AuthPreferenceV2{} } func (*AuthPreferenceV2) ProtoMessage() {} func (*AuthPreferenceV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{89} + return fileDescriptor_9198ee693835762e, []int{90} } func (m *AuthPreferenceV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6626,7 +6723,7 @@ func (m *AuthPreferenceSpecV2) Reset() { *m = AuthPreferenceSpecV2{} } func (m *AuthPreferenceSpecV2) String() string { return proto.CompactTextString(m) } func (*AuthPreferenceSpecV2) ProtoMessage() {} func (*AuthPreferenceSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{90} + return fileDescriptor_9198ee693835762e, []int{91} } func (m *AuthPreferenceSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6677,7 +6774,7 @@ func (m *StableUNIXUserConfig) Reset() { *m = StableUNIXUserConfig{} } func (m *StableUNIXUserConfig) String() string { return proto.CompactTextString(m) } func (*StableUNIXUserConfig) ProtoMessage() {} func (*StableUNIXUserConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{91} + return fileDescriptor_9198ee693835762e, []int{92} } func (m *StableUNIXUserConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6728,7 +6825,7 @@ func (m *U2F) Reset() { *m = U2F{} } func (m *U2F) String() string { return proto.CompactTextString(m) } func (*U2F) ProtoMessage() {} func (*U2F) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{92} + return fileDescriptor_9198ee693835762e, []int{93} } func (m *U2F) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6796,7 +6893,7 @@ func (m *Webauthn) Reset() { *m = Webauthn{} } func (m *Webauthn) String() string { return proto.CompactTextString(m) } func (*Webauthn) ProtoMessage() {} func (*Webauthn) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{93} + return fileDescriptor_9198ee693835762e, []int{94} } func (m *Webauthn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6867,7 +6964,7 @@ func (m *DeviceTrust) Reset() { *m = DeviceTrust{} } func (m *DeviceTrust) String() string { return proto.CompactTextString(m) } func (*DeviceTrust) ProtoMessage() {} func (*DeviceTrust) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{94} + return fileDescriptor_9198ee693835762e, []int{95} } func (m *DeviceTrust) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6914,7 +7011,7 @@ func (m *HardwareKey) Reset() { *m = HardwareKey{} } func (m *HardwareKey) String() string { return proto.CompactTextString(m) } func (*HardwareKey) ProtoMessage() {} func (*HardwareKey) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{95} + return fileDescriptor_9198ee693835762e, []int{96} } func (m *HardwareKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6961,7 +7058,7 @@ func (m *HardwareKeySerialNumberValidation) Reset() { *m = HardwareKeySe func (m *HardwareKeySerialNumberValidation) String() string { return proto.CompactTextString(m) } func (*HardwareKeySerialNumberValidation) ProtoMessage() {} func (*HardwareKeySerialNumberValidation) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{96} + return fileDescriptor_9198ee693835762e, []int{97} } func (m *HardwareKeySerialNumberValidation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7011,7 +7108,7 @@ func (m *Namespace) Reset() { *m = Namespace{} } func (m *Namespace) String() string { return proto.CompactTextString(m) } func (*Namespace) ProtoMessage() {} func (*Namespace) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{97} + return fileDescriptor_9198ee693835762e, []int{98} } func (m *Namespace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7051,7 +7148,7 @@ func (m *NamespaceSpec) Reset() { *m = NamespaceSpec{} } func (m *NamespaceSpec) String() string { return proto.CompactTextString(m) } func (*NamespaceSpec) ProtoMessage() {} func (*NamespaceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{98} + return fileDescriptor_9198ee693835762e, []int{99} } func (m *NamespaceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7099,7 +7196,7 @@ type UserTokenV3 struct { func (m *UserTokenV3) Reset() { *m = UserTokenV3{} } func (*UserTokenV3) ProtoMessage() {} func (*UserTokenV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{99} + return fileDescriptor_9198ee693835762e, []int{100} } func (m *UserTokenV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7146,7 +7243,7 @@ func (m *UserTokenSpecV3) Reset() { *m = UserTokenSpecV3{} } func (m *UserTokenSpecV3) String() string { return proto.CompactTextString(m) } func (*UserTokenSpecV3) ProtoMessage() {} func (*UserTokenSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{100} + return fileDescriptor_9198ee693835762e, []int{101} } func (m *UserTokenSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7194,7 +7291,7 @@ type UserTokenSecretsV3 struct { func (m *UserTokenSecretsV3) Reset() { *m = UserTokenSecretsV3{} } func (*UserTokenSecretsV3) ProtoMessage() {} func (*UserTokenSecretsV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{101} + return fileDescriptor_9198ee693835762e, []int{102} } func (m *UserTokenSecretsV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7239,7 +7336,7 @@ func (m *UserTokenSecretsSpecV3) Reset() { *m = UserTokenSecretsSpecV3{} func (m *UserTokenSecretsSpecV3) String() string { return proto.CompactTextString(m) } func (*UserTokenSecretsSpecV3) ProtoMessage() {} func (*UserTokenSecretsSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{102} + return fileDescriptor_9198ee693835762e, []int{103} } func (m *UserTokenSecretsSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7288,7 +7385,7 @@ type AccessRequestV3 struct { func (m *AccessRequestV3) Reset() { *m = AccessRequestV3{} } func (*AccessRequestV3) ProtoMessage() {} func (*AccessRequestV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{103} + return fileDescriptor_9198ee693835762e, []int{104} } func (m *AccessRequestV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7340,7 +7437,7 @@ func (m *AccessReviewThreshold) Reset() { *m = AccessReviewThreshold{} } func (m *AccessReviewThreshold) String() string { return proto.CompactTextString(m) } func (*AccessReviewThreshold) ProtoMessage() {} func (*AccessReviewThreshold) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{104} + return fileDescriptor_9198ee693835762e, []int{105} } func (m *AccessReviewThreshold) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7385,7 +7482,7 @@ func (m *PromotedAccessList) Reset() { *m = PromotedAccessList{} } func (m *PromotedAccessList) String() string { return proto.CompactTextString(m) } func (*PromotedAccessList) ProtoMessage() {} func (*PromotedAccessList) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{105} + return fileDescriptor_9198ee693835762e, []int{106} } func (m *PromotedAccessList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7446,7 +7543,7 @@ func (m *AccessReview) Reset() { *m = AccessReview{} } func (m *AccessReview) String() string { return proto.CompactTextString(m) } func (*AccessReview) ProtoMessage() {} func (*AccessReview) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{106} + return fileDescriptor_9198ee693835762e, []int{107} } func (m *AccessReview) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7491,7 +7588,7 @@ func (m *AccessReviewSubmission) Reset() { *m = AccessReviewSubmission{} func (m *AccessReviewSubmission) String() string { return proto.CompactTextString(m) } func (*AccessReviewSubmission) ProtoMessage() {} func (*AccessReviewSubmission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{107} + return fileDescriptor_9198ee693835762e, []int{108} } func (m *AccessReviewSubmission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7534,7 +7631,7 @@ func (m *ThresholdIndexSet) Reset() { *m = ThresholdIndexSet{} } func (m *ThresholdIndexSet) String() string { return proto.CompactTextString(m) } func (*ThresholdIndexSet) ProtoMessage() {} func (*ThresholdIndexSet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{108} + return fileDescriptor_9198ee693835762e, []int{109} } func (m *ThresholdIndexSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7577,7 +7674,7 @@ func (m *ThresholdIndexSets) Reset() { *m = ThresholdIndexSets{} } func (m *ThresholdIndexSets) String() string { return proto.CompactTextString(m) } func (*ThresholdIndexSets) ProtoMessage() {} func (*ThresholdIndexSets) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{109} + return fileDescriptor_9198ee693835762e, []int{110} } func (m *ThresholdIndexSets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7682,7 +7779,7 @@ func (m *AccessRequestSpecV3) Reset() { *m = AccessRequestSpecV3{} } func (m *AccessRequestSpecV3) String() string { return proto.CompactTextString(m) } func (*AccessRequestSpecV3) ProtoMessage() {} func (*AccessRequestSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{110} + return fileDescriptor_9198ee693835762e, []int{111} } func (m *AccessRequestSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7739,7 +7836,7 @@ func (m *AccessRequestFilter) Reset() { *m = AccessRequestFilter{} } func (m *AccessRequestFilter) String() string { return proto.CompactTextString(m) } func (*AccessRequestFilter) ProtoMessage() {} func (*AccessRequestFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{111} + return fileDescriptor_9198ee693835762e, []int{112} } func (m *AccessRequestFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7795,7 +7892,7 @@ func (m *AccessCapabilities) Reset() { *m = AccessCapabilities{} } func (m *AccessCapabilities) String() string { return proto.CompactTextString(m) } func (*AccessCapabilities) ProtoMessage() {} func (*AccessCapabilities) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{112} + return fileDescriptor_9198ee693835762e, []int{113} } func (m *AccessCapabilities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7853,7 +7950,7 @@ func (m *AccessCapabilitiesRequest) Reset() { *m = AccessCapabilitiesReq func (m *AccessCapabilitiesRequest) String() string { return proto.CompactTextString(m) } func (*AccessCapabilitiesRequest) ProtoMessage() {} func (*AccessCapabilitiesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{113} + return fileDescriptor_9198ee693835762e, []int{114} } func (m *AccessCapabilitiesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7897,7 +7994,7 @@ func (m *RequestKubernetesResource) Reset() { *m = RequestKubernetesReso func (m *RequestKubernetesResource) String() string { return proto.CompactTextString(m) } func (*RequestKubernetesResource) ProtoMessage() {} func (*RequestKubernetesResource) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{114} + return fileDescriptor_9198ee693835762e, []int{115} } func (m *RequestKubernetesResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7950,7 +8047,7 @@ func (m *ResourceID) Reset() { *m = ResourceID{} } func (m *ResourceID) String() string { return proto.CompactTextString(m) } func (*ResourceID) ProtoMessage() {} func (*ResourceID) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{115} + return fileDescriptor_9198ee693835762e, []int{116} } func (m *ResourceID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7999,7 +8096,7 @@ type PluginDataV3 struct { func (m *PluginDataV3) Reset() { *m = PluginDataV3{} } func (*PluginDataV3) ProtoMessage() {} func (*PluginDataV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{116} + return fileDescriptor_9198ee693835762e, []int{117} } func (m *PluginDataV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8042,7 +8139,7 @@ func (m *PluginDataEntry) Reset() { *m = PluginDataEntry{} } func (m *PluginDataEntry) String() string { return proto.CompactTextString(m) } func (*PluginDataEntry) ProtoMessage() {} func (*PluginDataEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{117} + return fileDescriptor_9198ee693835762e, []int{118} } func (m *PluginDataEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8084,7 +8181,7 @@ func (m *PluginDataSpecV3) Reset() { *m = PluginDataSpecV3{} } func (m *PluginDataSpecV3) String() string { return proto.CompactTextString(m) } func (*PluginDataSpecV3) ProtoMessage() {} func (*PluginDataSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{118} + return fileDescriptor_9198ee693835762e, []int{119} } func (m *PluginDataSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8131,7 +8228,7 @@ func (m *PluginDataFilter) Reset() { *m = PluginDataFilter{} } func (m *PluginDataFilter) String() string { return proto.CompactTextString(m) } func (*PluginDataFilter) ProtoMessage() {} func (*PluginDataFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{119} + return fileDescriptor_9198ee693835762e, []int{120} } func (m *PluginDataFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8182,7 +8279,7 @@ func (m *PluginDataUpdateParams) Reset() { *m = PluginDataUpdateParams{} func (m *PluginDataUpdateParams) String() string { return proto.CompactTextString(m) } func (*PluginDataUpdateParams) ProtoMessage() {} func (*PluginDataUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{120} + return fileDescriptor_9198ee693835762e, []int{121} } func (m *PluginDataUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8226,7 +8323,7 @@ func (m *RoleFilter) Reset() { *m = RoleFilter{} } func (m *RoleFilter) String() string { return proto.CompactTextString(m) } func (*RoleFilter) ProtoMessage() {} func (*RoleFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{121} + return fileDescriptor_9198ee693835762e, []int{122} } func (m *RoleFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8276,7 +8373,7 @@ type RoleV6 struct { func (m *RoleV6) Reset() { *m = RoleV6{} } func (*RoleV6) ProtoMessage() {} func (*RoleV6) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{122} + return fileDescriptor_9198ee693835762e, []int{123} } func (m *RoleV6) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8323,7 +8420,7 @@ func (m *RoleSpecV6) Reset() { *m = RoleSpecV6{} } func (m *RoleSpecV6) String() string { return proto.CompactTextString(m) } func (*RoleSpecV6) ProtoMessage() {} func (*RoleSpecV6) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{123} + return fileDescriptor_9198ee693835762e, []int{124} } func (m *RoleSpecV6) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8364,7 +8461,7 @@ func (m *SSHLocalPortForwarding) Reset() { *m = SSHLocalPortForwarding{} func (m *SSHLocalPortForwarding) String() string { return proto.CompactTextString(m) } func (*SSHLocalPortForwarding) ProtoMessage() {} func (*SSHLocalPortForwarding) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{124} + return fileDescriptor_9198ee693835762e, []int{125} } func (m *SSHLocalPortForwarding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8405,7 +8502,7 @@ func (m *SSHRemotePortForwarding) Reset() { *m = SSHRemotePortForwarding func (m *SSHRemotePortForwarding) String() string { return proto.CompactTextString(m) } func (*SSHRemotePortForwarding) ProtoMessage() {} func (*SSHRemotePortForwarding) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{125} + return fileDescriptor_9198ee693835762e, []int{126} } func (m *SSHRemotePortForwarding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8449,7 +8546,7 @@ func (m *SSHPortForwarding) Reset() { *m = SSHPortForwarding{} } func (m *SSHPortForwarding) String() string { return proto.CompactTextString(m) } func (*SSHPortForwarding) ProtoMessage() {} func (*SSHPortForwarding) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{126} + return fileDescriptor_9198ee693835762e, []int{127} } func (m *SSHPortForwarding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8581,7 +8678,7 @@ func (m *RoleOptions) Reset() { *m = RoleOptions{} } func (m *RoleOptions) String() string { return proto.CompactTextString(m) } func (*RoleOptions) ProtoMessage() {} func (*RoleOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{127} + return fileDescriptor_9198ee693835762e, []int{128} } func (m *RoleOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8627,7 +8724,7 @@ func (m *RecordSession) Reset() { *m = RecordSession{} } func (m *RecordSession) String() string { return proto.CompactTextString(m) } func (*RecordSession) ProtoMessage() {} func (*RecordSession) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{128} + return fileDescriptor_9198ee693835762e, []int{129} } func (m *RecordSession) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8679,7 +8776,7 @@ func (m *CertExtension) Reset() { *m = CertExtension{} } func (m *CertExtension) String() string { return proto.CompactTextString(m) } func (*CertExtension) ProtoMessage() {} func (*CertExtension) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{129} + return fileDescriptor_9198ee693835762e, []int{130} } func (m *CertExtension) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8824,7 +8921,7 @@ func (m *RoleConditions) Reset() { *m = RoleConditions{} } func (m *RoleConditions) String() string { return proto.CompactTextString(m) } func (*RoleConditions) ProtoMessage() {} func (*RoleConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{130} + return fileDescriptor_9198ee693835762e, []int{131} } func (m *RoleConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8867,7 +8964,7 @@ func (m *IdentityCenterAccountAssignment) Reset() { *m = IdentityCenterA func (m *IdentityCenterAccountAssignment) String() string { return proto.CompactTextString(m) } func (*IdentityCenterAccountAssignment) ProtoMessage() {} func (*IdentityCenterAccountAssignment) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{131} + return fileDescriptor_9198ee693835762e, []int{132} } func (m *IdentityCenterAccountAssignment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8908,7 +9005,7 @@ func (m *GitHubPermission) Reset() { *m = GitHubPermission{} } func (m *GitHubPermission) String() string { return proto.CompactTextString(m) } func (*GitHubPermission) ProtoMessage() {} func (*GitHubPermission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{132} + return fileDescriptor_9198ee693835762e, []int{133} } func (m *GitHubPermission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8984,7 +9081,7 @@ func (m *SPIFFERoleCondition) Reset() { *m = SPIFFERoleCondition{} } func (m *SPIFFERoleCondition) String() string { return proto.CompactTextString(m) } func (*SPIFFERoleCondition) ProtoMessage() {} func (*SPIFFERoleCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{133} + return fileDescriptor_9198ee693835762e, []int{134} } func (m *SPIFFERoleCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9028,7 +9125,7 @@ func (m *DatabasePermission) Reset() { *m = DatabasePermission{} } func (m *DatabasePermission) String() string { return proto.CompactTextString(m) } func (*DatabasePermission) ProtoMessage() {} func (*DatabasePermission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{134} + return fileDescriptor_9198ee693835762e, []int{135} } func (m *DatabasePermission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9078,7 +9175,7 @@ func (m *KubernetesResource) Reset() { *m = KubernetesResource{} } func (m *KubernetesResource) String() string { return proto.CompactTextString(m) } func (*KubernetesResource) ProtoMessage() {} func (*KubernetesResource) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{135} + return fileDescriptor_9198ee693835762e, []int{136} } func (m *KubernetesResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9131,7 +9228,7 @@ func (m *SessionRequirePolicy) Reset() { *m = SessionRequirePolicy{} } func (m *SessionRequirePolicy) String() string { return proto.CompactTextString(m) } func (*SessionRequirePolicy) ProtoMessage() {} func (*SessionRequirePolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{136} + return fileDescriptor_9198ee693835762e, []int{137} } func (m *SessionRequirePolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9179,7 +9276,7 @@ func (m *SessionJoinPolicy) Reset() { *m = SessionJoinPolicy{} } func (m *SessionJoinPolicy) String() string { return proto.CompactTextString(m) } func (*SessionJoinPolicy) ProtoMessage() {} func (*SessionJoinPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{137} + return fileDescriptor_9198ee693835762e, []int{138} } func (m *SessionJoinPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9255,7 +9352,7 @@ func (m *AccessRequestConditions) Reset() { *m = AccessRequestConditions func (m *AccessRequestConditions) String() string { return proto.CompactTextString(m) } func (*AccessRequestConditions) ProtoMessage() {} func (*AccessRequestConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{138} + return fileDescriptor_9198ee693835762e, []int{139} } func (m *AccessRequestConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9301,7 +9398,7 @@ func (m *AccessRequestConditionsReason) Reset() { *m = AccessRequestCond func (m *AccessRequestConditionsReason) String() string { return proto.CompactTextString(m) } func (*AccessRequestConditionsReason) ProtoMessage() {} func (*AccessRequestConditionsReason) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{139} + return fileDescriptor_9198ee693835762e, []int{140} } func (m *AccessRequestConditionsReason) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9354,7 +9451,7 @@ func (m *AccessReviewConditions) Reset() { *m = AccessReviewConditions{} func (m *AccessReviewConditions) String() string { return proto.CompactTextString(m) } func (*AccessReviewConditions) ProtoMessage() {} func (*AccessReviewConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{140} + return fileDescriptor_9198ee693835762e, []int{141} } func (m *AccessReviewConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9396,7 +9493,7 @@ func (m *AccessRequestAllowedPromotion) Reset() { *m = AccessRequestAllo func (m *AccessRequestAllowedPromotion) String() string { return proto.CompactTextString(m) } func (*AccessRequestAllowedPromotion) ProtoMessage() {} func (*AccessRequestAllowedPromotion) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{141} + return fileDescriptor_9198ee693835762e, []int{142} } func (m *AccessRequestAllowedPromotion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9439,7 +9536,7 @@ func (m *AccessRequestAllowedPromotions) Reset() { *m = AccessRequestAll func (m *AccessRequestAllowedPromotions) String() string { return proto.CompactTextString(m) } func (*AccessRequestAllowedPromotions) ProtoMessage() {} func (*AccessRequestAllowedPromotions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{142} + return fileDescriptor_9198ee693835762e, []int{143} } func (m *AccessRequestAllowedPromotions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9485,7 +9582,7 @@ func (m *ClaimMapping) Reset() { *m = ClaimMapping{} } func (m *ClaimMapping) String() string { return proto.CompactTextString(m) } func (*ClaimMapping) ProtoMessage() {} func (*ClaimMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{143} + return fileDescriptor_9198ee693835762e, []int{144} } func (m *ClaimMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9531,7 +9628,7 @@ func (m *TraitMapping) Reset() { *m = TraitMapping{} } func (m *TraitMapping) String() string { return proto.CompactTextString(m) } func (*TraitMapping) ProtoMessage() {} func (*TraitMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{144} + return fileDescriptor_9198ee693835762e, []int{145} } func (m *TraitMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9580,7 +9677,7 @@ func (m *Rule) Reset() { *m = Rule{} } func (m *Rule) String() string { return proto.CompactTextString(m) } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{145} + return fileDescriptor_9198ee693835762e, []int{146} } func (m *Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9628,7 +9725,7 @@ func (m *ImpersonateConditions) Reset() { *m = ImpersonateConditions{} } func (m *ImpersonateConditions) String() string { return proto.CompactTextString(m) } func (*ImpersonateConditions) ProtoMessage() {} func (*ImpersonateConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{146} + return fileDescriptor_9198ee693835762e, []int{147} } func (m *ImpersonateConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9670,7 +9767,7 @@ func (m *BoolValue) Reset() { *m = BoolValue{} } func (m *BoolValue) String() string { return proto.CompactTextString(m) } func (*BoolValue) ProtoMessage() {} func (*BoolValue) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{147} + return fileDescriptor_9198ee693835762e, []int{148} } func (m *BoolValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9712,7 +9809,7 @@ func (m *UserFilter) Reset() { *m = UserFilter{} } func (m *UserFilter) String() string { return proto.CompactTextString(m) } func (*UserFilter) ProtoMessage() {} func (*UserFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{148} + return fileDescriptor_9198ee693835762e, []int{149} } func (m *UserFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9763,7 +9860,7 @@ type UserV2 struct { func (m *UserV2) Reset() { *m = UserV2{} } func (*UserV2) ProtoMessage() {} func (*UserV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{149} + return fileDescriptor_9198ee693835762e, []int{150} } func (m *UserV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9812,7 +9909,7 @@ func (m *UserStatusV2) Reset() { *m = UserStatusV2{} } func (m *UserStatusV2) String() string { return proto.CompactTextString(m) } func (*UserStatusV2) ProtoMessage() {} func (*UserStatusV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{150} + return fileDescriptor_9198ee693835762e, []int{151} } func (m *UserStatusV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9886,7 +9983,7 @@ func (m *UserSpecV2) Reset() { *m = UserSpecV2{} } func (m *UserSpecV2) String() string { return proto.CompactTextString(m) } func (*UserSpecV2) ProtoMessage() {} func (*UserSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{151} + return fileDescriptor_9198ee693835762e, []int{152} } func (m *UserSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9936,7 +10033,7 @@ type ExternalIdentity struct { func (m *ExternalIdentity) Reset() { *m = ExternalIdentity{} } func (*ExternalIdentity) ProtoMessage() {} func (*ExternalIdentity) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{152} + return fileDescriptor_9198ee693835762e, []int{153} } func (m *ExternalIdentity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9984,7 +10081,7 @@ func (m *LoginStatus) Reset() { *m = LoginStatus{} } func (m *LoginStatus) String() string { return proto.CompactTextString(m) } func (*LoginStatus) ProtoMessage() {} func (*LoginStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{153} + return fileDescriptor_9198ee693835762e, []int{154} } func (m *LoginStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10029,7 +10126,7 @@ type CreatedBy struct { func (m *CreatedBy) Reset() { *m = CreatedBy{} } func (*CreatedBy) ProtoMessage() {} func (*CreatedBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{154} + return fileDescriptor_9198ee693835762e, []int{155} } func (m *CreatedBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10078,7 +10175,7 @@ func (m *LocalAuthSecrets) Reset() { *m = LocalAuthSecrets{} } func (m *LocalAuthSecrets) String() string { return proto.CompactTextString(m) } func (*LocalAuthSecrets) ProtoMessage() {} func (*LocalAuthSecrets) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{155} + return fileDescriptor_9198ee693835762e, []int{156} } func (m *LocalAuthSecrets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10135,7 +10232,7 @@ func (m *MFADevice) Reset() { *m = MFADevice{} } func (m *MFADevice) String() string { return proto.CompactTextString(m) } func (*MFADevice) ProtoMessage() {} func (*MFADevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{156} + return fileDescriptor_9198ee693835762e, []int{157} } func (m *MFADevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10245,7 +10342,7 @@ func (m *TOTPDevice) Reset() { *m = TOTPDevice{} } func (m *TOTPDevice) String() string { return proto.CompactTextString(m) } func (*TOTPDevice) ProtoMessage() {} func (*TOTPDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{157} + return fileDescriptor_9198ee693835762e, []int{158} } func (m *TOTPDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10291,7 +10388,7 @@ func (m *U2FDevice) Reset() { *m = U2FDevice{} } func (m *U2FDevice) String() string { return proto.CompactTextString(m) } func (*U2FDevice) ProtoMessage() {} func (*U2FDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{158} + return fileDescriptor_9198ee693835762e, []int{159} } func (m *U2FDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10373,7 +10470,7 @@ func (m *WebauthnDevice) Reset() { *m = WebauthnDevice{} } func (m *WebauthnDevice) String() string { return proto.CompactTextString(m) } func (*WebauthnDevice) ProtoMessage() {} func (*WebauthnDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{159} + return fileDescriptor_9198ee693835762e, []int{160} } func (m *WebauthnDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10419,7 +10516,7 @@ func (m *SSOMFADevice) Reset() { *m = SSOMFADevice{} } func (m *SSOMFADevice) String() string { return proto.CompactTextString(m) } func (*SSOMFADevice) ProtoMessage() {} func (*SSOMFADevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{160} + return fileDescriptor_9198ee693835762e, []int{161} } func (m *SSOMFADevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10462,7 +10559,7 @@ func (m *WebauthnLocalAuth) Reset() { *m = WebauthnLocalAuth{} } func (m *WebauthnLocalAuth) String() string { return proto.CompactTextString(m) } func (*WebauthnLocalAuth) ProtoMessage() {} func (*WebauthnLocalAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{161} + return fileDescriptor_9198ee693835762e, []int{162} } func (m *WebauthnLocalAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10508,7 +10605,7 @@ func (m *ConnectorRef) Reset() { *m = ConnectorRef{} } func (m *ConnectorRef) String() string { return proto.CompactTextString(m) } func (*ConnectorRef) ProtoMessage() {} func (*ConnectorRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{162} + return fileDescriptor_9198ee693835762e, []int{163} } func (m *ConnectorRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10550,7 +10647,7 @@ func (m *UserRef) Reset() { *m = UserRef{} } func (m *UserRef) String() string { return proto.CompactTextString(m) } func (*UserRef) ProtoMessage() {} func (*UserRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{163} + return fileDescriptor_9198ee693835762e, []int{164} } func (m *UserRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10600,7 +10697,7 @@ func (m *ReverseTunnelV2) Reset() { *m = ReverseTunnelV2{} } func (m *ReverseTunnelV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelV2) ProtoMessage() {} func (*ReverseTunnelV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{164} + return fileDescriptor_9198ee693835762e, []int{165} } func (m *ReverseTunnelV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10647,7 +10744,7 @@ func (m *ReverseTunnelSpecV2) Reset() { *m = ReverseTunnelSpecV2{} } func (m *ReverseTunnelSpecV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelSpecV2) ProtoMessage() {} func (*ReverseTunnelSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{165} + return fileDescriptor_9198ee693835762e, []int{166} } func (m *ReverseTunnelSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10696,7 +10793,7 @@ type TunnelConnectionV2 struct { func (m *TunnelConnectionV2) Reset() { *m = TunnelConnectionV2{} } func (*TunnelConnectionV2) ProtoMessage() {} func (*TunnelConnectionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{166} + return fileDescriptor_9198ee693835762e, []int{167} } func (m *TunnelConnectionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10744,7 +10841,7 @@ func (m *TunnelConnectionSpecV2) Reset() { *m = TunnelConnectionSpecV2{} func (m *TunnelConnectionSpecV2) String() string { return proto.CompactTextString(m) } func (*TunnelConnectionSpecV2) ProtoMessage() {} func (*TunnelConnectionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{167} + return fileDescriptor_9198ee693835762e, []int{168} } func (m *TunnelConnectionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10792,7 +10889,7 @@ func (m *SemaphoreFilter) Reset() { *m = SemaphoreFilter{} } func (m *SemaphoreFilter) String() string { return proto.CompactTextString(m) } func (*SemaphoreFilter) ProtoMessage() {} func (*SemaphoreFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{168} + return fileDescriptor_9198ee693835762e, []int{169} } func (m *SemaphoreFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10843,7 +10940,7 @@ func (m *AcquireSemaphoreRequest) Reset() { *m = AcquireSemaphoreRequest func (m *AcquireSemaphoreRequest) String() string { return proto.CompactTextString(m) } func (*AcquireSemaphoreRequest) ProtoMessage() {} func (*AcquireSemaphoreRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{169} + return fileDescriptor_9198ee693835762e, []int{170} } func (m *AcquireSemaphoreRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10891,7 +10988,7 @@ func (m *SemaphoreLease) Reset() { *m = SemaphoreLease{} } func (m *SemaphoreLease) String() string { return proto.CompactTextString(m) } func (*SemaphoreLease) ProtoMessage() {} func (*SemaphoreLease) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{170} + return fileDescriptor_9198ee693835762e, []int{171} } func (m *SemaphoreLease) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10937,7 +11034,7 @@ func (m *SemaphoreLeaseRef) Reset() { *m = SemaphoreLeaseRef{} } func (m *SemaphoreLeaseRef) String() string { return proto.CompactTextString(m) } func (*SemaphoreLeaseRef) ProtoMessage() {} func (*SemaphoreLeaseRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{171} + return fileDescriptor_9198ee693835762e, []int{172} } func (m *SemaphoreLeaseRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10986,7 +11083,7 @@ type SemaphoreV3 struct { func (m *SemaphoreV3) Reset() { *m = SemaphoreV3{} } func (*SemaphoreV3) ProtoMessage() {} func (*SemaphoreV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{172} + return fileDescriptor_9198ee693835762e, []int{173} } func (m *SemaphoreV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11028,7 +11125,7 @@ func (m *SemaphoreSpecV3) Reset() { *m = SemaphoreSpecV3{} } func (m *SemaphoreSpecV3) String() string { return proto.CompactTextString(m) } func (*SemaphoreSpecV3) ProtoMessage() {} func (*SemaphoreSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{173} + return fileDescriptor_9198ee693835762e, []int{174} } func (m *SemaphoreSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11077,7 +11174,7 @@ type WebSessionV2 struct { func (m *WebSessionV2) Reset() { *m = WebSessionV2{} } func (*WebSessionV2) ProtoMessage() {} func (*WebSessionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{174} + return fileDescriptor_9198ee693835762e, []int{175} } func (m *WebSessionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11162,7 +11259,7 @@ func (m *WebSessionSpecV2) Reset() { *m = WebSessionSpecV2{} } func (m *WebSessionSpecV2) String() string { return proto.CompactTextString(m) } func (*WebSessionSpecV2) ProtoMessage() {} func (*WebSessionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{175} + return fileDescriptor_9198ee693835762e, []int{176} } func (m *WebSessionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11207,7 +11304,7 @@ func (m *DeviceWebToken) Reset() { *m = DeviceWebToken{} } func (m *DeviceWebToken) String() string { return proto.CompactTextString(m) } func (*DeviceWebToken) ProtoMessage() {} func (*DeviceWebToken) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{176} + return fileDescriptor_9198ee693835762e, []int{177} } func (m *DeviceWebToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11249,7 +11346,7 @@ func (m *WebSessionFilter) Reset() { *m = WebSessionFilter{} } func (m *WebSessionFilter) String() string { return proto.CompactTextString(m) } func (*WebSessionFilter) ProtoMessage() {} func (*WebSessionFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{177} + return fileDescriptor_9198ee693835762e, []int{178} } func (m *WebSessionFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11320,7 +11417,7 @@ func (m *SAMLSessionData) Reset() { *m = SAMLSessionData{} } func (m *SAMLSessionData) String() string { return proto.CompactTextString(m) } func (*SAMLSessionData) ProtoMessage() {} func (*SAMLSessionData) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{178} + return fileDescriptor_9198ee693835762e, []int{179} } func (m *SAMLSessionData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11369,7 +11466,7 @@ func (m *SAMLAttribute) Reset() { *m = SAMLAttribute{} } func (m *SAMLAttribute) String() string { return proto.CompactTextString(m) } func (*SAMLAttribute) ProtoMessage() {} func (*SAMLAttribute) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{179} + return fileDescriptor_9198ee693835762e, []int{180} } func (m *SAMLAttribute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11416,7 +11513,7 @@ func (m *SAMLAttributeValue) Reset() { *m = SAMLAttributeValue{} } func (m *SAMLAttributeValue) String() string { return proto.CompactTextString(m) } func (*SAMLAttributeValue) ProtoMessage() {} func (*SAMLAttributeValue) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{180} + return fileDescriptor_9198ee693835762e, []int{181} } func (m *SAMLAttributeValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11467,7 +11564,7 @@ func (m *SAMLNameID) Reset() { *m = SAMLNameID{} } func (m *SAMLNameID) String() string { return proto.CompactTextString(m) } func (*SAMLNameID) ProtoMessage() {} func (*SAMLNameID) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{181} + return fileDescriptor_9198ee693835762e, []int{182} } func (m *SAMLNameID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11516,7 +11613,7 @@ type RemoteClusterV3 struct { func (m *RemoteClusterV3) Reset() { *m = RemoteClusterV3{} } func (*RemoteClusterV3) ProtoMessage() {} func (*RemoteClusterV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{182} + return fileDescriptor_9198ee693835762e, []int{183} } func (m *RemoteClusterV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11560,7 +11657,7 @@ func (m *RemoteClusterStatusV3) Reset() { *m = RemoteClusterStatusV3{} } func (m *RemoteClusterStatusV3) String() string { return proto.CompactTextString(m) } func (*RemoteClusterStatusV3) ProtoMessage() {} func (*RemoteClusterStatusV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{183} + return fileDescriptor_9198ee693835762e, []int{184} } func (m *RemoteClusterStatusV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11610,7 +11707,7 @@ func (m *KubernetesCluster) Reset() { *m = KubernetesCluster{} } func (m *KubernetesCluster) String() string { return proto.CompactTextString(m) } func (*KubernetesCluster) ProtoMessage() {} func (*KubernetesCluster) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{184} + return fileDescriptor_9198ee693835762e, []int{185} } func (m *KubernetesCluster) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11659,7 +11756,7 @@ type KubernetesClusterV3 struct { func (m *KubernetesClusterV3) Reset() { *m = KubernetesClusterV3{} } func (*KubernetesClusterV3) ProtoMessage() {} func (*KubernetesClusterV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{185} + return fileDescriptor_9198ee693835762e, []int{186} } func (m *KubernetesClusterV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11710,7 +11807,7 @@ func (m *KubernetesClusterSpecV3) Reset() { *m = KubernetesClusterSpecV3 func (m *KubernetesClusterSpecV3) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterSpecV3) ProtoMessage() {} func (*KubernetesClusterSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{186} + return fileDescriptor_9198ee693835762e, []int{187} } func (m *KubernetesClusterSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11758,7 +11855,7 @@ func (m *KubeAzure) Reset() { *m = KubeAzure{} } func (m *KubeAzure) String() string { return proto.CompactTextString(m) } func (*KubeAzure) ProtoMessage() {} func (*KubeAzure) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{187} + return fileDescriptor_9198ee693835762e, []int{188} } func (m *KubeAzure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11804,7 +11901,7 @@ func (m *KubeAWS) Reset() { *m = KubeAWS{} } func (m *KubeAWS) String() string { return proto.CompactTextString(m) } func (*KubeAWS) ProtoMessage() {} func (*KubeAWS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{188} + return fileDescriptor_9198ee693835762e, []int{189} } func (m *KubeAWS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11850,7 +11947,7 @@ func (m *KubeGCP) Reset() { *m = KubeGCP{} } func (m *KubeGCP) String() string { return proto.CompactTextString(m) } func (*KubeGCP) ProtoMessage() {} func (*KubeGCP) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{189} + return fileDescriptor_9198ee693835762e, []int{190} } func (m *KubeGCP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11892,7 +11989,7 @@ func (m *KubernetesClusterV3List) Reset() { *m = KubernetesClusterV3List func (m *KubernetesClusterV3List) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterV3List) ProtoMessage() {} func (*KubernetesClusterV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{190} + return fileDescriptor_9198ee693835762e, []int{191} } func (m *KubernetesClusterV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11941,7 +12038,7 @@ type KubernetesServerV3 struct { func (m *KubernetesServerV3) Reset() { *m = KubernetesServerV3{} } func (*KubernetesServerV3) ProtoMessage() {} func (*KubernetesServerV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{191} + return fileDescriptor_9198ee693835762e, []int{192} } func (m *KubernetesServerV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11993,7 +12090,7 @@ func (m *KubernetesServerSpecV3) Reset() { *m = KubernetesServerSpecV3{} func (m *KubernetesServerSpecV3) String() string { return proto.CompactTextString(m) } func (*KubernetesServerSpecV3) ProtoMessage() {} func (*KubernetesServerSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{192} + return fileDescriptor_9198ee693835762e, []int{193} } func (m *KubernetesServerSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12045,7 +12142,7 @@ type WebTokenV3 struct { func (m *WebTokenV3) Reset() { *m = WebTokenV3{} } func (*WebTokenV3) ProtoMessage() {} func (*WebTokenV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{193} + return fileDescriptor_9198ee693835762e, []int{194} } func (m *WebTokenV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12089,7 +12186,7 @@ func (m *WebTokenSpecV3) Reset() { *m = WebTokenSpecV3{} } func (m *WebTokenSpecV3) String() string { return proto.CompactTextString(m) } func (*WebTokenSpecV3) ProtoMessage() {} func (*WebTokenSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{194} + return fileDescriptor_9198ee693835762e, []int{195} } func (m *WebTokenSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12133,7 +12230,7 @@ func (m *GetWebSessionRequest) Reset() { *m = GetWebSessionRequest{} } func (m *GetWebSessionRequest) String() string { return proto.CompactTextString(m) } func (*GetWebSessionRequest) ProtoMessage() {} func (*GetWebSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{195} + return fileDescriptor_9198ee693835762e, []int{196} } func (m *GetWebSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12177,7 +12274,7 @@ func (m *DeleteWebSessionRequest) Reset() { *m = DeleteWebSessionRequest func (m *DeleteWebSessionRequest) String() string { return proto.CompactTextString(m) } func (*DeleteWebSessionRequest) ProtoMessage() {} func (*DeleteWebSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{196} + return fileDescriptor_9198ee693835762e, []int{197} } func (m *DeleteWebSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12221,7 +12318,7 @@ func (m *GetWebTokenRequest) Reset() { *m = GetWebTokenRequest{} } func (m *GetWebTokenRequest) String() string { return proto.CompactTextString(m) } func (*GetWebTokenRequest) ProtoMessage() {} func (*GetWebTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{197} + return fileDescriptor_9198ee693835762e, []int{198} } func (m *GetWebTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12265,7 +12362,7 @@ func (m *DeleteWebTokenRequest) Reset() { *m = DeleteWebTokenRequest{} } func (m *DeleteWebTokenRequest) String() string { return proto.CompactTextString(m) } func (*DeleteWebTokenRequest) ProtoMessage() {} func (*DeleteWebTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{198} + return fileDescriptor_9198ee693835762e, []int{199} } func (m *DeleteWebTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12307,7 +12404,7 @@ func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } func (m *ResourceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceRequest) ProtoMessage() {} func (*ResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{199} + return fileDescriptor_9198ee693835762e, []int{200} } func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12351,7 +12448,7 @@ func (m *ResourceWithSecretsRequest) Reset() { *m = ResourceWithSecretsR func (m *ResourceWithSecretsRequest) String() string { return proto.CompactTextString(m) } func (*ResourceWithSecretsRequest) ProtoMessage() {} func (*ResourceWithSecretsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{200} + return fileDescriptor_9198ee693835762e, []int{201} } func (m *ResourceWithSecretsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12393,7 +12490,7 @@ func (m *ResourcesWithSecretsRequest) Reset() { *m = ResourcesWithSecret func (m *ResourcesWithSecretsRequest) String() string { return proto.CompactTextString(m) } func (*ResourcesWithSecretsRequest) ProtoMessage() {} func (*ResourcesWithSecretsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{201} + return fileDescriptor_9198ee693835762e, []int{202} } func (m *ResourcesWithSecretsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12437,7 +12534,7 @@ func (m *ResourceInNamespaceRequest) Reset() { *m = ResourceInNamespaceR func (m *ResourceInNamespaceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceInNamespaceRequest) ProtoMessage() {} func (*ResourceInNamespaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{202} + return fileDescriptor_9198ee693835762e, []int{203} } func (m *ResourceInNamespaceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12479,7 +12576,7 @@ func (m *ResourcesInNamespaceRequest) Reset() { *m = ResourcesInNamespac func (m *ResourcesInNamespaceRequest) String() string { return proto.CompactTextString(m) } func (*ResourcesInNamespaceRequest) ProtoMessage() {} func (*ResourcesInNamespaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{203} + return fileDescriptor_9198ee693835762e, []int{204} } func (m *ResourcesInNamespaceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12530,7 +12627,7 @@ func (m *OIDCConnectorV3) Reset() { *m = OIDCConnectorV3{} } func (m *OIDCConnectorV3) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorV3) ProtoMessage() {} func (*OIDCConnectorV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{204} + return fileDescriptor_9198ee693835762e, []int{205} } func (m *OIDCConnectorV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12572,7 +12669,7 @@ func (m *OIDCConnectorV3List) Reset() { *m = OIDCConnectorV3List{} } func (m *OIDCConnectorV3List) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorV3List) ProtoMessage() {} func (*OIDCConnectorV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{205} + return fileDescriptor_9198ee693835762e, []int{206} } func (m *OIDCConnectorV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12660,7 +12757,7 @@ func (m *OIDCConnectorSpecV3) Reset() { *m = OIDCConnectorSpecV3{} } func (m *OIDCConnectorSpecV3) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorSpecV3) ProtoMessage() {} func (*OIDCConnectorSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{206} + return fileDescriptor_9198ee693835762e, []int{207} } func (m *OIDCConnectorSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12702,7 +12799,7 @@ func (m *MaxAge) Reset() { *m = MaxAge{} } func (m *MaxAge) String() string { return proto.CompactTextString(m) } func (*MaxAge) ProtoMessage() {} func (*MaxAge) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{207} + return fileDescriptor_9198ee693835762e, []int{208} } func (m *MaxAge) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12747,7 +12844,7 @@ func (m *SSOClientRedirectSettings) Reset() { *m = SSOClientRedirectSett func (m *SSOClientRedirectSettings) String() string { return proto.CompactTextString(m) } func (*SSOClientRedirectSettings) ProtoMessage() {} func (*SSOClientRedirectSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{208} + return fileDescriptor_9198ee693835762e, []int{209} } func (m *SSOClientRedirectSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12804,7 +12901,7 @@ func (m *OIDCConnectorMFASettings) Reset() { *m = OIDCConnectorMFASettin func (m *OIDCConnectorMFASettings) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorMFASettings) ProtoMessage() {} func (*OIDCConnectorMFASettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{209} + return fileDescriptor_9198ee693835762e, []int{210} } func (m *OIDCConnectorMFASettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12906,7 +13003,7 @@ func (m *OIDCAuthRequest) Reset() { *m = OIDCAuthRequest{} } func (m *OIDCAuthRequest) String() string { return proto.CompactTextString(m) } func (*OIDCAuthRequest) ProtoMessage() {} func (*OIDCAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{210} + return fileDescriptor_9198ee693835762e, []int{211} } func (m *OIDCAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12957,7 +13054,7 @@ func (m *SAMLConnectorV2) Reset() { *m = SAMLConnectorV2{} } func (m *SAMLConnectorV2) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorV2) ProtoMessage() {} func (*SAMLConnectorV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{211} + return fileDescriptor_9198ee693835762e, []int{212} } func (m *SAMLConnectorV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12999,7 +13096,7 @@ func (m *SAMLConnectorV2List) Reset() { *m = SAMLConnectorV2List{} } func (m *SAMLConnectorV2List) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorV2List) ProtoMessage() {} func (*SAMLConnectorV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{212} + return fileDescriptor_9198ee693835762e, []int{213} } func (m *SAMLConnectorV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13081,7 +13178,7 @@ func (m *SAMLConnectorSpecV2) Reset() { *m = SAMLConnectorSpecV2{} } func (m *SAMLConnectorSpecV2) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorSpecV2) ProtoMessage() {} func (*SAMLConnectorSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{213} + return fileDescriptor_9198ee693835762e, []int{214} } func (m *SAMLConnectorSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13140,7 +13237,7 @@ func (m *SAMLConnectorMFASettings) Reset() { *m = SAMLConnectorMFASettin func (m *SAMLConnectorMFASettings) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorMFASettings) ProtoMessage() {} func (*SAMLConnectorMFASettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{214} + return fileDescriptor_9198ee693835762e, []int{215} } func (m *SAMLConnectorMFASettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13236,7 +13333,7 @@ func (m *SAMLAuthRequest) Reset() { *m = SAMLAuthRequest{} } func (m *SAMLAuthRequest) String() string { return proto.CompactTextString(m) } func (*SAMLAuthRequest) ProtoMessage() {} func (*SAMLAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{215} + return fileDescriptor_9198ee693835762e, []int{216} } func (m *SAMLAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13282,7 +13379,7 @@ func (m *AttributeMapping) Reset() { *m = AttributeMapping{} } func (m *AttributeMapping) String() string { return proto.CompactTextString(m) } func (*AttributeMapping) ProtoMessage() {} func (*AttributeMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{216} + return fileDescriptor_9198ee693835762e, []int{217} } func (m *AttributeMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13327,7 +13424,7 @@ func (m *AsymmetricKeyPair) Reset() { *m = AsymmetricKeyPair{} } func (m *AsymmetricKeyPair) String() string { return proto.CompactTextString(m) } func (*AsymmetricKeyPair) ProtoMessage() {} func (*AsymmetricKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{217} + return fileDescriptor_9198ee693835762e, []int{218} } func (m *AsymmetricKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13378,7 +13475,7 @@ func (m *GithubConnectorV3) Reset() { *m = GithubConnectorV3{} } func (m *GithubConnectorV3) String() string { return proto.CompactTextString(m) } func (*GithubConnectorV3) ProtoMessage() {} func (*GithubConnectorV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{218} + return fileDescriptor_9198ee693835762e, []int{219} } func (m *GithubConnectorV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13420,7 +13517,7 @@ func (m *GithubConnectorV3List) Reset() { *m = GithubConnectorV3List{} } func (m *GithubConnectorV3List) String() string { return proto.CompactTextString(m) } func (*GithubConnectorV3List) ProtoMessage() {} func (*GithubConnectorV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{219} + return fileDescriptor_9198ee693835762e, []int{220} } func (m *GithubConnectorV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13483,7 +13580,7 @@ func (m *GithubConnectorSpecV3) Reset() { *m = GithubConnectorSpecV3{} } func (m *GithubConnectorSpecV3) String() string { return proto.CompactTextString(m) } func (*GithubConnectorSpecV3) ProtoMessage() {} func (*GithubConnectorSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{220} + return fileDescriptor_9198ee693835762e, []int{221} } func (m *GithubConnectorSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13580,7 +13677,7 @@ func (m *GithubAuthRequest) Reset() { *m = GithubAuthRequest{} } func (m *GithubAuthRequest) String() string { return proto.CompactTextString(m) } func (*GithubAuthRequest) ProtoMessage() {} func (*GithubAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{221} + return fileDescriptor_9198ee693835762e, []int{222} } func (m *GithubAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13624,7 +13721,7 @@ func (m *SSOWarnings) Reset() { *m = SSOWarnings{} } func (m *SSOWarnings) String() string { return proto.CompactTextString(m) } func (*SSOWarnings) ProtoMessage() {} func (*SSOWarnings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{222} + return fileDescriptor_9198ee693835762e, []int{223} } func (m *SSOWarnings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13680,7 +13777,7 @@ func (m *CreateUserParams) Reset() { *m = CreateUserParams{} } func (m *CreateUserParams) String() string { return proto.CompactTextString(m) } func (*CreateUserParams) ProtoMessage() {} func (*CreateUserParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{223} + return fileDescriptor_9198ee693835762e, []int{224} } func (m *CreateUserParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13765,7 +13862,7 @@ func (m *SSODiagnosticInfo) Reset() { *m = SSODiagnosticInfo{} } func (m *SSODiagnosticInfo) String() string { return proto.CompactTextString(m) } func (*SSODiagnosticInfo) ProtoMessage() {} func (*SSODiagnosticInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{224} + return fileDescriptor_9198ee693835762e, []int{225} } func (m *SSODiagnosticInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13809,7 +13906,7 @@ func (m *GithubTokenInfo) Reset() { *m = GithubTokenInfo{} } func (m *GithubTokenInfo) String() string { return proto.CompactTextString(m) } func (*GithubTokenInfo) ProtoMessage() {} func (*GithubTokenInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{225} + return fileDescriptor_9198ee693835762e, []int{226} } func (m *GithubTokenInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13860,7 +13957,7 @@ func (m *GithubClaims) Reset() { *m = GithubClaims{} } func (m *GithubClaims) String() string { return proto.CompactTextString(m) } func (*GithubClaims) ProtoMessage() {} func (*GithubClaims) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{226} + return fileDescriptor_9198ee693835762e, []int{227} } func (m *GithubClaims) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13912,7 +14009,7 @@ func (m *TeamMapping) Reset() { *m = TeamMapping{} } func (m *TeamMapping) String() string { return proto.CompactTextString(m) } func (*TeamMapping) ProtoMessage() {} func (*TeamMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{227} + return fileDescriptor_9198ee693835762e, []int{228} } func (m *TeamMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13958,7 +14055,7 @@ func (m *TeamRolesMapping) Reset() { *m = TeamRolesMapping{} } func (m *TeamRolesMapping) String() string { return proto.CompactTextString(m) } func (*TeamRolesMapping) ProtoMessage() {} func (*TeamRolesMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{228} + return fileDescriptor_9198ee693835762e, []int{229} } func (m *TeamRolesMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14008,7 +14105,7 @@ type TrustedClusterV2 struct { func (m *TrustedClusterV2) Reset() { *m = TrustedClusterV2{} } func (*TrustedClusterV2) ProtoMessage() {} func (*TrustedClusterV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{229} + return fileDescriptor_9198ee693835762e, []int{230} } func (m *TrustedClusterV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14050,7 +14147,7 @@ func (m *TrustedClusterV2List) Reset() { *m = TrustedClusterV2List{} } func (m *TrustedClusterV2List) String() string { return proto.CompactTextString(m) } func (*TrustedClusterV2List) ProtoMessage() {} func (*TrustedClusterV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{230} + return fileDescriptor_9198ee693835762e, []int{231} } func (m *TrustedClusterV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14106,7 +14203,7 @@ func (m *TrustedClusterSpecV2) Reset() { *m = TrustedClusterSpecV2{} } func (m *TrustedClusterSpecV2) String() string { return proto.CompactTextString(m) } func (*TrustedClusterSpecV2) ProtoMessage() {} func (*TrustedClusterSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{231} + return fileDescriptor_9198ee693835762e, []int{232} } func (m *TrustedClusterSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14160,7 +14257,7 @@ func (m *LockV2) Reset() { *m = LockV2{} } func (m *LockV2) String() string { return proto.CompactTextString(m) } func (*LockV2) ProtoMessage() {} func (*LockV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{232} + return fileDescriptor_9198ee693835762e, []int{233} } func (m *LockV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14210,7 +14307,7 @@ func (m *LockSpecV2) Reset() { *m = LockSpecV2{} } func (m *LockSpecV2) String() string { return proto.CompactTextString(m) } func (*LockSpecV2) ProtoMessage() {} func (*LockSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{233} + return fileDescriptor_9198ee693835762e, []int{234} } func (m *LockSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14271,7 +14368,7 @@ type LockTarget struct { func (m *LockTarget) Reset() { *m = LockTarget{} } func (*LockTarget) ProtoMessage() {} func (*LockTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{234} + return fileDescriptor_9198ee693835762e, []int{235} } func (m *LockTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14315,7 +14412,7 @@ func (m *AddressCondition) Reset() { *m = AddressCondition{} } func (m *AddressCondition) String() string { return proto.CompactTextString(m) } func (*AddressCondition) ProtoMessage() {} func (*AddressCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{235} + return fileDescriptor_9198ee693835762e, []int{236} } func (m *AddressCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14358,7 +14455,7 @@ func (m *NetworkRestrictionsSpecV4) Reset() { *m = NetworkRestrictionsSp func (m *NetworkRestrictionsSpecV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsSpecV4) ProtoMessage() {} func (*NetworkRestrictionsSpecV4) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{236} + return fileDescriptor_9198ee693835762e, []int{237} } func (m *NetworkRestrictionsSpecV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14411,7 +14508,7 @@ func (m *NetworkRestrictionsV4) Reset() { *m = NetworkRestrictionsV4{} } func (m *NetworkRestrictionsV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsV4) ProtoMessage() {} func (*NetworkRestrictionsV4) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{237} + return fileDescriptor_9198ee693835762e, []int{238} } func (m *NetworkRestrictionsV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14455,7 +14552,7 @@ func (m *WindowsDesktopServiceV3) Reset() { *m = WindowsDesktopServiceV3 func (m *WindowsDesktopServiceV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceV3) ProtoMessage() {} func (*WindowsDesktopServiceV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{238} + return fileDescriptor_9198ee693835762e, []int{239} } func (m *WindowsDesktopServiceV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14503,7 +14600,7 @@ func (m *WindowsDesktopServiceSpecV3) Reset() { *m = WindowsDesktopServi func (m *WindowsDesktopServiceSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceSpecV3) ProtoMessage() {} func (*WindowsDesktopServiceSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{239} + return fileDescriptor_9198ee693835762e, []int{240} } func (m *WindowsDesktopServiceSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14547,7 +14644,7 @@ func (m *WindowsDesktopFilter) Reset() { *m = WindowsDesktopFilter{} } func (m *WindowsDesktopFilter) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopFilter) ProtoMessage() {} func (*WindowsDesktopFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{240} + return fileDescriptor_9198ee693835762e, []int{241} } func (m *WindowsDesktopFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14591,7 +14688,7 @@ func (m *WindowsDesktopV3) Reset() { *m = WindowsDesktopV3{} } func (m *WindowsDesktopV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopV3) ProtoMessage() {} func (*WindowsDesktopV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{241} + return fileDescriptor_9198ee693835762e, []int{242} } func (m *WindowsDesktopV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14644,7 +14741,7 @@ func (m *WindowsDesktopSpecV3) Reset() { *m = WindowsDesktopSpecV3{} } func (m *WindowsDesktopSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopSpecV3) ProtoMessage() {} func (*WindowsDesktopSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{242} + return fileDescriptor_9198ee693835762e, []int{243} } func (m *WindowsDesktopSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14688,7 +14785,7 @@ func (m *DynamicWindowsDesktopV1) Reset() { *m = DynamicWindowsDesktopV1 func (m *DynamicWindowsDesktopV1) String() string { return proto.CompactTextString(m) } func (*DynamicWindowsDesktopV1) ProtoMessage() {} func (*DynamicWindowsDesktopV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{243} + return fileDescriptor_9198ee693835762e, []int{244} } func (m *DynamicWindowsDesktopV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14739,7 +14836,7 @@ func (m *DynamicWindowsDesktopSpecV1) Reset() { *m = DynamicWindowsDeskt func (m *DynamicWindowsDesktopSpecV1) String() string { return proto.CompactTextString(m) } func (*DynamicWindowsDesktopSpecV1) ProtoMessage() {} func (*DynamicWindowsDesktopSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{244} + return fileDescriptor_9198ee693835762e, []int{245} } func (m *DynamicWindowsDesktopSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14780,7 +14877,7 @@ func (m *Resolution) Reset() { *m = Resolution{} } func (m *Resolution) String() string { return proto.CompactTextString(m) } func (*Resolution) ProtoMessage() {} func (*Resolution) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{245} + return fileDescriptor_9198ee693835762e, []int{246} } func (m *Resolution) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14863,7 +14960,7 @@ func (m *RegisterUsingTokenRequest) Reset() { *m = RegisterUsingTokenReq func (m *RegisterUsingTokenRequest) String() string { return proto.CompactTextString(m) } func (*RegisterUsingTokenRequest) ProtoMessage() {} func (*RegisterUsingTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{246} + return fileDescriptor_9198ee693835762e, []int{247} } func (m *RegisterUsingTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14917,7 +15014,7 @@ func (m *RecoveryCodesV1) Reset() { *m = RecoveryCodesV1{} } func (m *RecoveryCodesV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesV1) ProtoMessage() {} func (*RecoveryCodesV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{247} + return fileDescriptor_9198ee693835762e, []int{248} } func (m *RecoveryCodesV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14962,7 +15059,7 @@ func (m *RecoveryCodesSpecV1) Reset() { *m = RecoveryCodesSpecV1{} } func (m *RecoveryCodesSpecV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesSpecV1) ProtoMessage() {} func (*RecoveryCodesSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{248} + return fileDescriptor_9198ee693835762e, []int{249} } func (m *RecoveryCodesSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15006,7 +15103,7 @@ func (m *RecoveryCode) Reset() { *m = RecoveryCode{} } func (m *RecoveryCode) String() string { return proto.CompactTextString(m) } func (*RecoveryCode) ProtoMessage() {} func (*RecoveryCode) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{249} + return fileDescriptor_9198ee693835762e, []int{250} } func (m *RecoveryCode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15046,7 +15143,7 @@ func (m *NullableSessionState) Reset() { *m = NullableSessionState{} } func (m *NullableSessionState) String() string { return proto.CompactTextString(m) } func (*NullableSessionState) ProtoMessage() {} func (*NullableSessionState) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{250} + return fileDescriptor_9198ee693835762e, []int{251} } func (m *NullableSessionState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15092,7 +15189,7 @@ func (m *SessionTrackerFilter) Reset() { *m = SessionTrackerFilter{} } func (m *SessionTrackerFilter) String() string { return proto.CompactTextString(m) } func (*SessionTrackerFilter) ProtoMessage() {} func (*SessionTrackerFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{251} + return fileDescriptor_9198ee693835762e, []int{252} } func (m *SessionTrackerFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15136,7 +15233,7 @@ func (m *SessionTrackerV1) Reset() { *m = SessionTrackerV1{} } func (m *SessionTrackerV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerV1) ProtoMessage() {} func (*SessionTrackerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{252} + return fileDescriptor_9198ee693835762e, []int{253} } func (m *SessionTrackerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15234,7 +15331,7 @@ func (m *SessionTrackerSpecV1) Reset() { *m = SessionTrackerSpecV1{} } func (m *SessionTrackerSpecV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerSpecV1) ProtoMessage() {} func (*SessionTrackerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{253} + return fileDescriptor_9198ee693835762e, []int{254} } func (m *SessionTrackerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15281,7 +15378,7 @@ func (m *SessionTrackerPolicySet) Reset() { *m = SessionTrackerPolicySet func (m *SessionTrackerPolicySet) String() string { return proto.CompactTextString(m) } func (*SessionTrackerPolicySet) ProtoMessage() {} func (*SessionTrackerPolicySet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{254} + return fileDescriptor_9198ee693835762e, []int{255} } func (m *SessionTrackerPolicySet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15329,7 +15426,7 @@ func (m *Participant) Reset() { *m = Participant{} } func (m *Participant) String() string { return proto.CompactTextString(m) } func (*Participant) ProtoMessage() {} func (*Participant) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{255} + return fileDescriptor_9198ee693835762e, []int{256} } func (m *Participant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15373,7 +15470,7 @@ func (m *UIConfigV1) Reset() { *m = UIConfigV1{} } func (m *UIConfigV1) String() string { return proto.CompactTextString(m) } func (*UIConfigV1) ProtoMessage() {} func (*UIConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{256} + return fileDescriptor_9198ee693835762e, []int{257} } func (m *UIConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15419,7 +15516,7 @@ func (m *UIConfigSpecV1) Reset() { *m = UIConfigSpecV1{} } func (m *UIConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*UIConfigSpecV1) ProtoMessage() {} func (*UIConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{257} + return fileDescriptor_9198ee693835762e, []int{258} } func (m *UIConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15470,7 +15567,7 @@ func (m *InstallerV1) Reset() { *m = InstallerV1{} } func (m *InstallerV1) String() string { return proto.CompactTextString(m) } func (*InstallerV1) ProtoMessage() {} func (*InstallerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{258} + return fileDescriptor_9198ee693835762e, []int{259} } func (m *InstallerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15512,7 +15609,7 @@ func (m *InstallerSpecV1) Reset() { *m = InstallerSpecV1{} } func (m *InstallerSpecV1) String() string { return proto.CompactTextString(m) } func (*InstallerSpecV1) ProtoMessage() {} func (*InstallerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{259} + return fileDescriptor_9198ee693835762e, []int{260} } func (m *InstallerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15554,7 +15651,7 @@ func (m *InstallerV1List) Reset() { *m = InstallerV1List{} } func (m *InstallerV1List) String() string { return proto.CompactTextString(m) } func (*InstallerV1List) ProtoMessage() {} func (*InstallerV1List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{260} + return fileDescriptor_9198ee693835762e, []int{261} } func (m *InstallerV1List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15598,7 +15695,7 @@ func (m *SortBy) Reset() { *m = SortBy{} } func (m *SortBy) String() string { return proto.CompactTextString(m) } func (*SortBy) ProtoMessage() {} func (*SortBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{261} + return fileDescriptor_9198ee693835762e, []int{262} } func (m *SortBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15644,7 +15741,7 @@ func (m *ConnectionDiagnosticV1) Reset() { *m = ConnectionDiagnosticV1{} func (m *ConnectionDiagnosticV1) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticV1) ProtoMessage() {} func (*ConnectionDiagnosticV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{262} + return fileDescriptor_9198ee693835762e, []int{263} } func (m *ConnectionDiagnosticV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15694,7 +15791,7 @@ func (m *ConnectionDiagnosticSpecV1) Reset() { *m = ConnectionDiagnostic func (m *ConnectionDiagnosticSpecV1) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticSpecV1) ProtoMessage() {} func (*ConnectionDiagnosticSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{263} + return fileDescriptor_9198ee693835762e, []int{264} } func (m *ConnectionDiagnosticSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15740,7 +15837,7 @@ func (m *ConnectionDiagnosticTrace) Reset() { *m = ConnectionDiagnosticT func (m *ConnectionDiagnosticTrace) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticTrace) ProtoMessage() {} func (*ConnectionDiagnosticTrace) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{264} + return fileDescriptor_9198ee693835762e, []int{265} } func (m *ConnectionDiagnosticTrace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15783,7 +15880,7 @@ func (m *DatabaseServiceV1) Reset() { *m = DatabaseServiceV1{} } func (m *DatabaseServiceV1) String() string { return proto.CompactTextString(m) } func (*DatabaseServiceV1) ProtoMessage() {} func (*DatabaseServiceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{265} + return fileDescriptor_9198ee693835762e, []int{266} } func (m *DatabaseServiceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15827,7 +15924,7 @@ func (m *DatabaseServiceSpecV1) Reset() { *m = DatabaseServiceSpecV1{} } func (m *DatabaseServiceSpecV1) String() string { return proto.CompactTextString(m) } func (*DatabaseServiceSpecV1) ProtoMessage() {} func (*DatabaseServiceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{266} + return fileDescriptor_9198ee693835762e, []int{267} } func (m *DatabaseServiceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15869,7 +15966,7 @@ func (m *DatabaseResourceMatcher) Reset() { *m = DatabaseResourceMatcher func (m *DatabaseResourceMatcher) String() string { return proto.CompactTextString(m) } func (*DatabaseResourceMatcher) ProtoMessage() {} func (*DatabaseResourceMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{267} + return fileDescriptor_9198ee693835762e, []int{268} } func (m *DatabaseResourceMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15913,7 +16010,7 @@ func (m *ResourceMatcherAWS) Reset() { *m = ResourceMatcherAWS{} } func (m *ResourceMatcherAWS) String() string { return proto.CompactTextString(m) } func (*ResourceMatcherAWS) ProtoMessage() {} func (*ResourceMatcherAWS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{268} + return fileDescriptor_9198ee693835762e, []int{269} } func (m *ResourceMatcherAWS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15955,7 +16052,7 @@ func (m *ClusterAlert) Reset() { *m = ClusterAlert{} } func (m *ClusterAlert) String() string { return proto.CompactTextString(m) } func (*ClusterAlert) ProtoMessage() {} func (*ClusterAlert) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{269} + return fileDescriptor_9198ee693835762e, []int{270} } func (m *ClusterAlert) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16001,7 +16098,7 @@ func (m *ClusterAlertSpec) Reset() { *m = ClusterAlertSpec{} } func (m *ClusterAlertSpec) String() string { return proto.CompactTextString(m) } func (*ClusterAlertSpec) ProtoMessage() {} func (*ClusterAlertSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{270} + return fileDescriptor_9198ee693835762e, []int{271} } func (m *ClusterAlertSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16054,7 +16151,7 @@ func (m *GetClusterAlertsRequest) Reset() { *m = GetClusterAlertsRequest func (m *GetClusterAlertsRequest) String() string { return proto.CompactTextString(m) } func (*GetClusterAlertsRequest) ProtoMessage() {} func (*GetClusterAlertsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{271} + return fileDescriptor_9198ee693835762e, []int{272} } func (m *GetClusterAlertsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16104,7 +16201,7 @@ func (m *AlertAcknowledgement) Reset() { *m = AlertAcknowledgement{} } func (m *AlertAcknowledgement) String() string { return proto.CompactTextString(m) } func (*AlertAcknowledgement) ProtoMessage() {} func (*AlertAcknowledgement) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{272} + return fileDescriptor_9198ee693835762e, []int{273} } func (m *AlertAcknowledgement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16156,7 +16253,7 @@ func (m *Release) Reset() { *m = Release{} } func (m *Release) String() string { return proto.CompactTextString(m) } func (*Release) ProtoMessage() {} func (*Release) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{273} + return fileDescriptor_9198ee693835762e, []int{274} } func (m *Release) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16214,7 +16311,7 @@ func (m *Asset) Reset() { *m = Asset{} } func (m *Asset) String() string { return proto.CompactTextString(m) } func (*Asset) ProtoMessage() {} func (*Asset) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{274} + return fileDescriptor_9198ee693835762e, []int{275} } func (m *Asset) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16267,7 +16364,7 @@ func (m *PluginV1) Reset() { *m = PluginV1{} } func (m *PluginV1) String() string { return proto.CompactTextString(m) } func (*PluginV1) ProtoMessage() {} func (*PluginV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{275} + return fileDescriptor_9198ee693835762e, []int{276} } func (m *PluginV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16335,7 +16432,7 @@ func (m *PluginSpecV1) Reset() { *m = PluginSpecV1{} } func (m *PluginSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginSpecV1) ProtoMessage() {} func (*PluginSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{276} + return fileDescriptor_9198ee693835762e, []int{277} } func (m *PluginSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16613,7 +16710,7 @@ func (m *PluginSlackAccessSettings) Reset() { *m = PluginSlackAccessSett func (m *PluginSlackAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginSlackAccessSettings) ProtoMessage() {} func (*PluginSlackAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{277} + return fileDescriptor_9198ee693835762e, []int{278} } func (m *PluginSlackAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16654,7 +16751,7 @@ func (m *PluginGitlabSettings) Reset() { *m = PluginGitlabSettings{} } func (m *PluginGitlabSettings) String() string { return proto.CompactTextString(m) } func (*PluginGitlabSettings) ProtoMessage() {} func (*PluginGitlabSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{278} + return fileDescriptor_9198ee693835762e, []int{279} } func (m *PluginGitlabSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16701,7 +16798,7 @@ func (m *PluginOpsgenieAccessSettings) Reset() { *m = PluginOpsgenieAcce func (m *PluginOpsgenieAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginOpsgenieAccessSettings) ProtoMessage() {} func (*PluginOpsgenieAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{279} + return fileDescriptor_9198ee693835762e, []int{280} } func (m *PluginOpsgenieAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16749,7 +16846,7 @@ func (m *PluginServiceNowSettings) Reset() { *m = PluginServiceNowSettin func (m *PluginServiceNowSettings) String() string { return proto.CompactTextString(m) } func (*PluginServiceNowSettings) ProtoMessage() {} func (*PluginServiceNowSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{280} + return fileDescriptor_9198ee693835762e, []int{281} } func (m *PluginServiceNowSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16795,7 +16892,7 @@ func (m *PluginPagerDutySettings) Reset() { *m = PluginPagerDutySettings func (m *PluginPagerDutySettings) String() string { return proto.CompactTextString(m) } func (*PluginPagerDutySettings) ProtoMessage() {} func (*PluginPagerDutySettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{281} + return fileDescriptor_9198ee693835762e, []int{282} } func (m *PluginPagerDutySettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16841,7 +16938,7 @@ func (m *PluginJiraSettings) Reset() { *m = PluginJiraSettings{} } func (m *PluginJiraSettings) String() string { return proto.CompactTextString(m) } func (*PluginJiraSettings) ProtoMessage() {} func (*PluginJiraSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{282} + return fileDescriptor_9198ee693835762e, []int{283} } func (m *PluginJiraSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16881,7 +16978,7 @@ func (m *PluginOpenAISettings) Reset() { *m = PluginOpenAISettings{} } func (m *PluginOpenAISettings) String() string { return proto.CompactTextString(m) } func (*PluginOpenAISettings) ProtoMessage() {} func (*PluginOpenAISettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{283} + return fileDescriptor_9198ee693835762e, []int{284} } func (m *PluginOpenAISettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16932,7 +17029,7 @@ func (m *PluginMattermostSettings) Reset() { *m = PluginMattermostSettin func (m *PluginMattermostSettings) String() string { return proto.CompactTextString(m) } func (*PluginMattermostSettings) ProtoMessage() {} func (*PluginMattermostSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{284} + return fileDescriptor_9198ee693835762e, []int{285} } func (m *PluginMattermostSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16974,7 +17071,7 @@ func (m *PluginJamfSettings) Reset() { *m = PluginJamfSettings{} } func (m *PluginJamfSettings) String() string { return proto.CompactTextString(m) } func (*PluginJamfSettings) ProtoMessage() {} func (*PluginJamfSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{285} + return fileDescriptor_9198ee693835762e, []int{286} } func (m *PluginJamfSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17026,7 +17123,7 @@ func (m *PluginOktaSettings) Reset() { *m = PluginOktaSettings{} } func (m *PluginOktaSettings) String() string { return proto.CompactTextString(m) } func (*PluginOktaSettings) ProtoMessage() {} func (*PluginOktaSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{286} + return fileDescriptor_9198ee693835762e, []int{287} } func (m *PluginOktaSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17073,7 +17170,7 @@ func (m *PluginOktaCredentialsInfo) Reset() { *m = PluginOktaCredentials func (m *PluginOktaCredentialsInfo) String() string { return proto.CompactTextString(m) } func (*PluginOktaCredentialsInfo) ProtoMessage() {} func (*PluginOktaCredentialsInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{287} + return fileDescriptor_9198ee693835762e, []int{288} } func (m *PluginOktaCredentialsInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17160,7 +17257,7 @@ func (m *PluginOktaSyncSettings) Reset() { *m = PluginOktaSyncSettings{} func (m *PluginOktaSyncSettings) String() string { return proto.CompactTextString(m) } func (*PluginOktaSyncSettings) ProtoMessage() {} func (*PluginOktaSyncSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{288} + return fileDescriptor_9198ee693835762e, []int{289} } func (m *PluginOktaSyncSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17201,7 +17298,7 @@ func (m *DiscordChannels) Reset() { *m = DiscordChannels{} } func (m *DiscordChannels) String() string { return proto.CompactTextString(m) } func (*DiscordChannels) ProtoMessage() {} func (*DiscordChannels) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{289} + return fileDescriptor_9198ee693835762e, []int{290} } func (m *DiscordChannels) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17245,7 +17342,7 @@ func (m *PluginDiscordSettings) Reset() { *m = PluginDiscordSettings{} } func (m *PluginDiscordSettings) String() string { return proto.CompactTextString(m) } func (*PluginDiscordSettings) ProtoMessage() {} func (*PluginDiscordSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{290} + return fileDescriptor_9198ee693835762e, []int{291} } func (m *PluginDiscordSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17290,7 +17387,7 @@ func (m *PluginEntraIDSettings) Reset() { *m = PluginEntraIDSettings{} } func (m *PluginEntraIDSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDSettings) ProtoMessage() {} func (*PluginEntraIDSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{291} + return fileDescriptor_9198ee693835762e, []int{292} } func (m *PluginEntraIDSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17344,7 +17441,7 @@ func (m *PluginEntraIDSyncSettings) Reset() { *m = PluginEntraIDSyncSett func (m *PluginEntraIDSyncSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDSyncSettings) ProtoMessage() {} func (*PluginEntraIDSyncSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{292} + return fileDescriptor_9198ee693835762e, []int{293} } func (m *PluginEntraIDSyncSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17389,7 +17486,7 @@ func (m *PluginEntraIDAccessGraphSettings) Reset() { *m = PluginEntraIDA func (m *PluginEntraIDAccessGraphSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDAccessGraphSettings) ProtoMessage() {} func (*PluginEntraIDAccessGraphSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{293} + return fileDescriptor_9198ee693835762e, []int{294} } func (m *PluginEntraIDAccessGraphSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17435,7 +17532,7 @@ func (m *PluginEntraIDAppSSOSettings) Reset() { *m = PluginEntraIDAppSSO func (m *PluginEntraIDAppSSOSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDAppSSOSettings) ProtoMessage() {} func (*PluginEntraIDAppSSOSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{294} + return fileDescriptor_9198ee693835762e, []int{295} } func (m *PluginEntraIDAppSSOSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17481,7 +17578,7 @@ func (m *PluginSCIMSettings) Reset() { *m = PluginSCIMSettings{} } func (m *PluginSCIMSettings) String() string { return proto.CompactTextString(m) } func (*PluginSCIMSettings) ProtoMessage() {} func (*PluginSCIMSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{295} + return fileDescriptor_9198ee693835762e, []int{296} } func (m *PluginSCIMSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17525,7 +17622,7 @@ func (m *PluginDatadogAccessSettings) Reset() { *m = PluginDatadogAccess func (m *PluginDatadogAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginDatadogAccessSettings) ProtoMessage() {} func (*PluginDatadogAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{296} + return fileDescriptor_9198ee693835762e, []int{297} } func (m *PluginDatadogAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17608,7 +17705,7 @@ func (m *PluginAWSICSettings) Reset() { *m = PluginAWSICSettings{} } func (m *PluginAWSICSettings) String() string { return proto.CompactTextString(m) } func (*PluginAWSICSettings) ProtoMessage() {} func (*PluginAWSICSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{297} + return fileDescriptor_9198ee693835762e, []int{298} } func (m *PluginAWSICSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17657,7 +17754,7 @@ func (m *AWSICResourceFilter) Reset() { *m = AWSICResourceFilter{} } func (m *AWSICResourceFilter) String() string { return proto.CompactTextString(m) } func (*AWSICResourceFilter) ProtoMessage() {} func (*AWSICResourceFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{298} + return fileDescriptor_9198ee693835762e, []int{299} } func (m *AWSICResourceFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17744,7 +17841,7 @@ func (m *AWSICUserSyncFilter) Reset() { *m = AWSICUserSyncFilter{} } func (m *AWSICUserSyncFilter) String() string { return proto.CompactTextString(m) } func (*AWSICUserSyncFilter) ProtoMessage() {} func (*AWSICUserSyncFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{299} + return fileDescriptor_9198ee693835762e, []int{300} } func (m *AWSICUserSyncFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17791,7 +17888,7 @@ func (m *AWSICProvisioningSpec) Reset() { *m = AWSICProvisioningSpec{} } func (m *AWSICProvisioningSpec) String() string { return proto.CompactTextString(m) } func (*AWSICProvisioningSpec) ProtoMessage() {} func (*AWSICProvisioningSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{300} + return fileDescriptor_9198ee693835762e, []int{301} } func (m *AWSICProvisioningSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17833,7 +17930,7 @@ func (m *PluginAWSICStatusV1) Reset() { *m = PluginAWSICStatusV1{} } func (m *PluginAWSICStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginAWSICStatusV1) ProtoMessage() {} func (*PluginAWSICStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{301} + return fileDescriptor_9198ee693835762e, []int{302} } func (m *PluginAWSICStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17878,7 +17975,7 @@ func (m *AWSICGroupImportStatus) Reset() { *m = AWSICGroupImportStatus{} func (m *AWSICGroupImportStatus) String() string { return proto.CompactTextString(m) } func (*AWSICGroupImportStatus) ProtoMessage() {} func (*AWSICGroupImportStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{302} + return fileDescriptor_9198ee693835762e, []int{303} } func (m *AWSICGroupImportStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17929,7 +18026,7 @@ func (m *PluginEmailSettings) Reset() { *m = PluginEmailSettings{} } func (m *PluginEmailSettings) String() string { return proto.CompactTextString(m) } func (*PluginEmailSettings) ProtoMessage() {} func (*PluginEmailSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{303} + return fileDescriptor_9198ee693835762e, []int{304} } func (m *PluginEmailSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18017,7 +18114,7 @@ func (m *MailgunSpec) Reset() { *m = MailgunSpec{} } func (m *MailgunSpec) String() string { return proto.CompactTextString(m) } func (*MailgunSpec) ProtoMessage() {} func (*MailgunSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{304} + return fileDescriptor_9198ee693835762e, []int{305} } func (m *MailgunSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18064,7 +18161,7 @@ func (m *SMTPSpec) Reset() { *m = SMTPSpec{} } func (m *SMTPSpec) String() string { return proto.CompactTextString(m) } func (*SMTPSpec) ProtoMessage() {} func (*SMTPSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{305} + return fileDescriptor_9198ee693835762e, []int{306} } func (m *SMTPSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18114,7 +18211,7 @@ func (m *PluginMSTeamsSettings) Reset() { *m = PluginMSTeamsSettings{} } func (m *PluginMSTeamsSettings) String() string { return proto.CompactTextString(m) } func (*PluginMSTeamsSettings) ProtoMessage() {} func (*PluginMSTeamsSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{306} + return fileDescriptor_9198ee693835762e, []int{307} } func (m *PluginMSTeamsSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18161,7 +18258,7 @@ func (m *PluginNetIQSettings) Reset() { *m = PluginNetIQSettings{} } func (m *PluginNetIQSettings) String() string { return proto.CompactTextString(m) } func (*PluginNetIQSettings) ProtoMessage() {} func (*PluginNetIQSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{307} + return fileDescriptor_9198ee693835762e, []int{308} } func (m *PluginNetIQSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18206,7 +18303,7 @@ func (m *PluginBootstrapCredentialsV1) Reset() { *m = PluginBootstrapCre func (m *PluginBootstrapCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginBootstrapCredentialsV1) ProtoMessage() {} func (*PluginBootstrapCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{308} + return fileDescriptor_9198ee693835762e, []int{309} } func (m *PluginBootstrapCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18306,7 +18403,7 @@ func (m *PluginIdSecretCredential) Reset() { *m = PluginIdSecretCredenti func (m *PluginIdSecretCredential) String() string { return proto.CompactTextString(m) } func (*PluginIdSecretCredential) ProtoMessage() {} func (*PluginIdSecretCredential) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{309} + return fileDescriptor_9198ee693835762e, []int{310} } func (m *PluginIdSecretCredential) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18349,7 +18446,7 @@ func (m *PluginOAuth2AuthorizationCodeCredentials) Reset() { func (m *PluginOAuth2AuthorizationCodeCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AuthorizationCodeCredentials) ProtoMessage() {} func (*PluginOAuth2AuthorizationCodeCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{310} + return fileDescriptor_9198ee693835762e, []int{311} } func (m *PluginOAuth2AuthorizationCodeCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18409,7 +18506,7 @@ func (m *PluginStatusV1) Reset() { *m = PluginStatusV1{} } func (m *PluginStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginStatusV1) ProtoMessage() {} func (*PluginStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{311} + return fileDescriptor_9198ee693835762e, []int{312} } func (m *PluginStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18538,7 +18635,7 @@ func (m *PluginNetIQStatusV1) Reset() { *m = PluginNetIQStatusV1{} } func (m *PluginNetIQStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginNetIQStatusV1) ProtoMessage() {} func (*PluginNetIQStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{312} + return fileDescriptor_9198ee693835762e, []int{313} } func (m *PluginNetIQStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18584,7 +18681,7 @@ func (m *PluginGitlabStatusV1) Reset() { *m = PluginGitlabStatusV1{} } func (m *PluginGitlabStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginGitlabStatusV1) ProtoMessage() {} func (*PluginGitlabStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{313} + return fileDescriptor_9198ee693835762e, []int{314} } func (m *PluginGitlabStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18628,7 +18725,7 @@ func (m *PluginEntraIDStatusV1) Reset() { *m = PluginEntraIDStatusV1{} } func (m *PluginEntraIDStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDStatusV1) ProtoMessage() {} func (*PluginEntraIDStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{314} + return fileDescriptor_9198ee693835762e, []int{315} } func (m *PluginEntraIDStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18682,7 +18779,7 @@ func (m *PluginOktaStatusV1) Reset() { *m = PluginOktaStatusV1{} } func (m *PluginOktaStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusV1) ProtoMessage() {} func (*PluginOktaStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{315} + return fileDescriptor_9198ee693835762e, []int{316} } func (m *PluginOktaStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18730,7 +18827,7 @@ func (m *PluginOktaStatusDetailsSSO) Reset() { *m = PluginOktaStatusDeta func (m *PluginOktaStatusDetailsSSO) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsSSO) ProtoMessage() {} func (*PluginOktaStatusDetailsSSO) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{316} + return fileDescriptor_9198ee693835762e, []int{317} } func (m *PluginOktaStatusDetailsSSO) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18787,7 +18884,7 @@ func (m *PluginOktaStatusDetailsAppGroupSync) Reset() { *m = PluginOktaS func (m *PluginOktaStatusDetailsAppGroupSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsAppGroupSync) ProtoMessage() {} func (*PluginOktaStatusDetailsAppGroupSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{317} + return fileDescriptor_9198ee693835762e, []int{318} } func (m *PluginOktaStatusDetailsAppGroupSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18841,7 +18938,7 @@ func (m *PluginOktaStatusDetailsUsersSync) Reset() { *m = PluginOktaStat func (m *PluginOktaStatusDetailsUsersSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsUsersSync) ProtoMessage() {} func (*PluginOktaStatusDetailsUsersSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{318} + return fileDescriptor_9198ee693835762e, []int{319} } func (m *PluginOktaStatusDetailsUsersSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18884,7 +18981,7 @@ func (m *PluginOktaStatusDetailsSCIM) Reset() { *m = PluginOktaStatusDet func (m *PluginOktaStatusDetailsSCIM) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsSCIM) ProtoMessage() {} func (*PluginOktaStatusDetailsSCIM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{319} + return fileDescriptor_9198ee693835762e, []int{320} } func (m *PluginOktaStatusDetailsSCIM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18946,7 +19043,7 @@ func (m *PluginOktaStatusDetailsAccessListsSync) Reset() { func (m *PluginOktaStatusDetailsAccessListsSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsAccessListsSync) ProtoMessage() {} func (*PluginOktaStatusDetailsAccessListsSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{320} + return fileDescriptor_9198ee693835762e, []int{321} } func (m *PluginOktaStatusDetailsAccessListsSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18994,7 +19091,7 @@ func (m *PluginCredentialsV1) Reset() { *m = PluginCredentialsV1{} } func (m *PluginCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginCredentialsV1) ProtoMessage() {} func (*PluginCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{321} + return fileDescriptor_9198ee693835762e, []int{322} } func (m *PluginCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19105,7 +19202,7 @@ func (m *PluginOAuth2AccessTokenCredentials) Reset() { *m = PluginOAuth2 func (m *PluginOAuth2AccessTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AccessTokenCredentials) ProtoMessage() {} func (*PluginOAuth2AccessTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{322} + return fileDescriptor_9198ee693835762e, []int{323} } func (m *PluginOAuth2AccessTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19146,7 +19243,7 @@ func (m *PluginBearerTokenCredentials) Reset() { *m = PluginBearerTokenC func (m *PluginBearerTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginBearerTokenCredentials) ProtoMessage() {} func (*PluginBearerTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{323} + return fileDescriptor_9198ee693835762e, []int{324} } func (m *PluginBearerTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19188,7 +19285,7 @@ func (m *PluginStaticCredentialsRef) Reset() { *m = PluginStaticCredenti func (m *PluginStaticCredentialsRef) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsRef) ProtoMessage() {} func (*PluginStaticCredentialsRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{324} + return fileDescriptor_9198ee693835762e, []int{325} } func (m *PluginStaticCredentialsRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19230,7 +19327,7 @@ func (m *PluginListV1) Reset() { *m = PluginListV1{} } func (m *PluginListV1) String() string { return proto.CompactTextString(m) } func (*PluginListV1) ProtoMessage() {} func (*PluginListV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{325} + return fileDescriptor_9198ee693835762e, []int{326} } func (m *PluginListV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19273,7 +19370,7 @@ type PluginStaticCredentialsV1 struct { func (m *PluginStaticCredentialsV1) Reset() { *m = PluginStaticCredentialsV1{} } func (*PluginStaticCredentialsV1) ProtoMessage() {} func (*PluginStaticCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{326} + return fileDescriptor_9198ee693835762e, []int{327} } func (m *PluginStaticCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19320,7 +19417,7 @@ func (m *PluginStaticCredentialsSpecV1) Reset() { *m = PluginStaticCrede func (m *PluginStaticCredentialsSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsSpecV1) ProtoMessage() {} func (*PluginStaticCredentialsSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{327} + return fileDescriptor_9198ee693835762e, []int{328} } func (m *PluginStaticCredentialsSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19435,7 +19532,7 @@ func (m *PluginStaticCredentialsBasicAuth) Reset() { *m = PluginStaticCr func (m *PluginStaticCredentialsBasicAuth) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsBasicAuth) ProtoMessage() {} func (*PluginStaticCredentialsBasicAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{328} + return fileDescriptor_9198ee693835762e, []int{329} } func (m *PluginStaticCredentialsBasicAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19481,7 +19578,7 @@ func (m *PluginStaticCredentialsOAuthClientSecret) Reset() { func (m *PluginStaticCredentialsOAuthClientSecret) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsOAuthClientSecret) ProtoMessage() {} func (*PluginStaticCredentialsOAuthClientSecret) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{329} + return fileDescriptor_9198ee693835762e, []int{330} } func (m *PluginStaticCredentialsOAuthClientSecret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19529,7 +19626,7 @@ func (m *PluginStaticCredentialsSSHCertAuthorities) String() string { } func (*PluginStaticCredentialsSSHCertAuthorities) ProtoMessage() {} func (*PluginStaticCredentialsSSHCertAuthorities) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{330} + return fileDescriptor_9198ee693835762e, []int{331} } func (m *PluginStaticCredentialsSSHCertAuthorities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19572,7 +19669,7 @@ type SAMLIdPServiceProviderV1 struct { func (m *SAMLIdPServiceProviderV1) Reset() { *m = SAMLIdPServiceProviderV1{} } func (*SAMLIdPServiceProviderV1) ProtoMessage() {} func (*SAMLIdPServiceProviderV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{331} + return fileDescriptor_9198ee693835762e, []int{332} } func (m *SAMLIdPServiceProviderV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19643,7 +19740,7 @@ func (m *SAMLIdPServiceProviderSpecV1) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderSpecV1) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderSpecV1) ProtoMessage() {} func (*SAMLIdPServiceProviderSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{332} + return fileDescriptor_9198ee693835762e, []int{333} } func (m *SAMLIdPServiceProviderSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19690,7 +19787,7 @@ func (m *SAMLAttributeMapping) Reset() { *m = SAMLAttributeMapping{} } func (m *SAMLAttributeMapping) String() string { return proto.CompactTextString(m) } func (*SAMLAttributeMapping) ProtoMessage() {} func (*SAMLAttributeMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{333} + return fileDescriptor_9198ee693835762e, []int{334} } func (m *SAMLAttributeMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19732,7 +19829,7 @@ func (m *IdPOptions) Reset() { *m = IdPOptions{} } func (m *IdPOptions) String() string { return proto.CompactTextString(m) } func (*IdPOptions) ProtoMessage() {} func (*IdPOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{334} + return fileDescriptor_9198ee693835762e, []int{335} } func (m *IdPOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19774,7 +19871,7 @@ func (m *IdPSAMLOptions) Reset() { *m = IdPSAMLOptions{} } func (m *IdPSAMLOptions) String() string { return proto.CompactTextString(m) } func (*IdPSAMLOptions) ProtoMessage() {} func (*IdPSAMLOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{335} + return fileDescriptor_9198ee693835762e, []int{336} } func (m *IdPSAMLOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19824,7 +19921,7 @@ func (m *KubernetesResourceV1) Reset() { *m = KubernetesResourceV1{} } func (m *KubernetesResourceV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceV1) ProtoMessage() {} func (*KubernetesResourceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{336} + return fileDescriptor_9198ee693835762e, []int{337} } func (m *KubernetesResourceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19866,7 +19963,7 @@ func (m *KubernetesResourceSpecV1) Reset() { *m = KubernetesResourceSpec func (m *KubernetesResourceSpecV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceSpecV1) ProtoMessage() {} func (*KubernetesResourceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{337} + return fileDescriptor_9198ee693835762e, []int{338} } func (m *KubernetesResourceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19912,7 +20009,7 @@ func (m *ClusterMaintenanceConfigV1) Reset() { *m = ClusterMaintenanceCo func (m *ClusterMaintenanceConfigV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigV1) ProtoMessage() {} func (*ClusterMaintenanceConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{338} + return fileDescriptor_9198ee693835762e, []int{339} } func (m *ClusterMaintenanceConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19954,7 +20051,7 @@ func (m *ClusterMaintenanceConfigSpecV1) Reset() { *m = ClusterMaintenan func (m *ClusterMaintenanceConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigSpecV1) ProtoMessage() {} func (*ClusterMaintenanceConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{339} + return fileDescriptor_9198ee693835762e, []int{340} } func (m *ClusterMaintenanceConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20000,7 +20097,7 @@ func (m *AgentUpgradeWindow) Reset() { *m = AgentUpgradeWindow{} } func (m *AgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeWindow) ProtoMessage() {} func (*AgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{340} + return fileDescriptor_9198ee693835762e, []int{341} } func (m *AgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20047,7 +20144,7 @@ func (m *ScheduledAgentUpgradeWindow) Reset() { *m = ScheduledAgentUpgra func (m *ScheduledAgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*ScheduledAgentUpgradeWindow) ProtoMessage() {} func (*ScheduledAgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{341} + return fileDescriptor_9198ee693835762e, []int{342} } func (m *ScheduledAgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20090,7 +20187,7 @@ func (m *AgentUpgradeSchedule) Reset() { *m = AgentUpgradeSchedule{} } func (m *AgentUpgradeSchedule) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeSchedule) ProtoMessage() {} func (*AgentUpgradeSchedule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{342} + return fileDescriptor_9198ee693835762e, []int{343} } func (m *AgentUpgradeSchedule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20133,7 +20230,7 @@ type UserGroupV1 struct { func (m *UserGroupV1) Reset() { *m = UserGroupV1{} } func (*UserGroupV1) ProtoMessage() {} func (*UserGroupV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{343} + return fileDescriptor_9198ee693835762e, []int{344} } func (m *UserGroupV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20175,7 +20272,7 @@ func (m *UserGroupSpecV1) Reset() { *m = UserGroupSpecV1{} } func (m *UserGroupSpecV1) String() string { return proto.CompactTextString(m) } func (*UserGroupSpecV1) ProtoMessage() {} func (*UserGroupSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{344} + return fileDescriptor_9198ee693835762e, []int{345} } func (m *UserGroupSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20219,7 +20316,7 @@ func (m *OktaImportRuleSpecV1) Reset() { *m = OktaImportRuleSpecV1{} } func (m *OktaImportRuleSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleSpecV1) ProtoMessage() {} func (*OktaImportRuleSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{345} + return fileDescriptor_9198ee693835762e, []int{346} } func (m *OktaImportRuleSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20263,7 +20360,7 @@ func (m *OktaImportRuleMappingV1) Reset() { *m = OktaImportRuleMappingV1 func (m *OktaImportRuleMappingV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMappingV1) ProtoMessage() {} func (*OktaImportRuleMappingV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{346} + return fileDescriptor_9198ee693835762e, []int{347} } func (m *OktaImportRuleMappingV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20306,7 +20403,7 @@ type OktaImportRuleV1 struct { func (m *OktaImportRuleV1) Reset() { *m = OktaImportRuleV1{} } func (*OktaImportRuleV1) ProtoMessage() {} func (*OktaImportRuleV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{347} + return fileDescriptor_9198ee693835762e, []int{348} } func (m *OktaImportRuleV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20354,7 +20451,7 @@ func (m *OktaImportRuleMatchV1) Reset() { *m = OktaImportRuleMatchV1{} } func (m *OktaImportRuleMatchV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMatchV1) ProtoMessage() {} func (*OktaImportRuleMatchV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{348} + return fileDescriptor_9198ee693835762e, []int{349} } func (m *OktaImportRuleMatchV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20397,7 +20494,7 @@ type OktaAssignmentV1 struct { func (m *OktaAssignmentV1) Reset() { *m = OktaAssignmentV1{} } func (*OktaAssignmentV1) ProtoMessage() {} func (*OktaAssignmentV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{349} + return fileDescriptor_9198ee693835762e, []int{350} } func (m *OktaAssignmentV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20451,7 +20548,7 @@ func (m *OktaAssignmentSpecV1) Reset() { *m = OktaAssignmentSpecV1{} } func (m *OktaAssignmentSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentSpecV1) ProtoMessage() {} func (*OktaAssignmentSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{350} + return fileDescriptor_9198ee693835762e, []int{351} } func (m *OktaAssignmentSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20495,7 +20592,7 @@ func (m *OktaAssignmentTargetV1) Reset() { *m = OktaAssignmentTargetV1{} func (m *OktaAssignmentTargetV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentTargetV1) ProtoMessage() {} func (*OktaAssignmentTargetV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{351} + return fileDescriptor_9198ee693835762e, []int{352} } func (m *OktaAssignmentTargetV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20540,7 +20637,7 @@ type IntegrationV1 struct { func (m *IntegrationV1) Reset() { *m = IntegrationV1{} } func (*IntegrationV1) ProtoMessage() {} func (*IntegrationV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{352} + return fileDescriptor_9198ee693835762e, []int{353} } func (m *IntegrationV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20588,7 +20685,7 @@ func (m *IntegrationSpecV1) Reset() { *m = IntegrationSpecV1{} } func (m *IntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*IntegrationSpecV1) ProtoMessage() {} func (*IntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{353} + return fileDescriptor_9198ee693835762e, []int{354} } func (m *IntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20707,7 +20804,7 @@ func (m *AWSOIDCIntegrationSpecV1) Reset() { *m = AWSOIDCIntegrationSpec func (m *AWSOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AWSOIDCIntegrationSpecV1) ProtoMessage() {} func (*AWSOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{354} + return fileDescriptor_9198ee693835762e, []int{355} } func (m *AWSOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20753,7 +20850,7 @@ func (m *AzureOIDCIntegrationSpecV1) Reset() { *m = AzureOIDCIntegration func (m *AzureOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AzureOIDCIntegrationSpecV1) ProtoMessage() {} func (*AzureOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{355} + return fileDescriptor_9198ee693835762e, []int{356} } func (m *AzureOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20795,7 +20892,7 @@ func (m *GitHubIntegrationSpecV1) Reset() { *m = GitHubIntegrationSpecV1 func (m *GitHubIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*GitHubIntegrationSpecV1) ProtoMessage() {} func (*GitHubIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{356} + return fileDescriptor_9198ee693835762e, []int{357} } func (m *GitHubIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20856,7 +20953,7 @@ func (m *HeadlessAuthentication) Reset() { *m = HeadlessAuthentication{} func (m *HeadlessAuthentication) String() string { return proto.CompactTextString(m) } func (*HeadlessAuthentication) ProtoMessage() {} func (*HeadlessAuthentication) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{357} + return fileDescriptor_9198ee693835762e, []int{358} } func (m *HeadlessAuthentication) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20913,7 +21010,7 @@ func (m *WatchKind) Reset() { *m = WatchKind{} } func (m *WatchKind) String() string { return proto.CompactTextString(m) } func (*WatchKind) ProtoMessage() {} func (*WatchKind) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{358} + return fileDescriptor_9198ee693835762e, []int{359} } func (m *WatchKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20963,7 +21060,7 @@ func (m *WatchStatusV1) Reset() { *m = WatchStatusV1{} } func (m *WatchStatusV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusV1) ProtoMessage() {} func (*WatchStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{359} + return fileDescriptor_9198ee693835762e, []int{360} } func (m *WatchStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21004,7 +21101,7 @@ func (m *WatchStatusSpecV1) Reset() { *m = WatchStatusSpecV1{} } func (m *WatchStatusSpecV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusSpecV1) ProtoMessage() {} func (*WatchStatusSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{360} + return fileDescriptor_9198ee693835762e, []int{361} } func (m *WatchStatusSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21054,7 +21151,7 @@ func (m *ServerInfoV1) Reset() { *m = ServerInfoV1{} } func (m *ServerInfoV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoV1) ProtoMessage() {} func (*ServerInfoV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{361} + return fileDescriptor_9198ee693835762e, []int{362} } func (m *ServerInfoV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21096,7 +21193,7 @@ func (m *ServerInfoSpecV1) Reset() { *m = ServerInfoSpecV1{} } func (m *ServerInfoSpecV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoSpecV1) ProtoMessage() {} func (*ServerInfoSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{362} + return fileDescriptor_9198ee693835762e, []int{363} } func (m *ServerInfoSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21153,7 +21250,7 @@ func (m *JamfSpecV1) Reset() { *m = JamfSpecV1{} } func (m *JamfSpecV1) String() string { return proto.CompactTextString(m) } func (*JamfSpecV1) ProtoMessage() {} func (*JamfSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{363} + return fileDescriptor_9198ee693835762e, []int{364} } func (m *JamfSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21218,7 +21315,7 @@ func (m *JamfInventoryEntry) Reset() { *m = JamfInventoryEntry{} } func (m *JamfInventoryEntry) String() string { return proto.CompactTextString(m) } func (*JamfInventoryEntry) ProtoMessage() {} func (*JamfInventoryEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{364} + return fileDescriptor_9198ee693835762e, []int{365} } func (m *JamfInventoryEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21275,7 +21372,7 @@ type MessageWithHeader struct { func (m *MessageWithHeader) Reset() { *m = MessageWithHeader{} } func (*MessageWithHeader) ProtoMessage() {} func (*MessageWithHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{365} + return fileDescriptor_9198ee693835762e, []int{366} } func (m *MessageWithHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21339,7 +21436,7 @@ func (m *AWSMatcher) Reset() { *m = AWSMatcher{} } func (m *AWSMatcher) String() string { return proto.CompactTextString(m) } func (*AWSMatcher) ProtoMessage() {} func (*AWSMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{366} + return fileDescriptor_9198ee693835762e, []int{367} } func (m *AWSMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21384,7 +21481,7 @@ func (m *AssumeRole) Reset() { *m = AssumeRole{} } func (m *AssumeRole) String() string { return proto.CompactTextString(m) } func (*AssumeRole) ProtoMessage() {} func (*AssumeRole) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{367} + return fileDescriptor_9198ee693835762e, []int{368} } func (m *AssumeRole) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21446,7 +21543,7 @@ func (m *InstallerParams) Reset() { *m = InstallerParams{} } func (m *InstallerParams) String() string { return proto.CompactTextString(m) } func (*InstallerParams) ProtoMessage() {} func (*InstallerParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{368} + return fileDescriptor_9198ee693835762e, []int{369} } func (m *InstallerParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21489,7 +21586,7 @@ func (m *AWSSSM) Reset() { *m = AWSSSM{} } func (m *AWSSSM) String() string { return proto.CompactTextString(m) } func (*AWSSSM) ProtoMessage() {} func (*AWSSSM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{369} + return fileDescriptor_9198ee693835762e, []int{370} } func (m *AWSSSM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21532,7 +21629,7 @@ func (m *AzureInstallerParams) Reset() { *m = AzureInstallerParams{} } func (m *AzureInstallerParams) String() string { return proto.CompactTextString(m) } func (*AzureInstallerParams) ProtoMessage() {} func (*AzureInstallerParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{370} + return fileDescriptor_9198ee693835762e, []int{371} } func (m *AzureInstallerParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21586,7 +21683,7 @@ func (m *AzureMatcher) Reset() { *m = AzureMatcher{} } func (m *AzureMatcher) String() string { return proto.CompactTextString(m) } func (*AzureMatcher) ProtoMessage() {} func (*AzureMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{371} + return fileDescriptor_9198ee693835762e, []int{372} } func (m *AzureMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21641,7 +21738,7 @@ func (m *GCPMatcher) Reset() { *m = GCPMatcher{} } func (m *GCPMatcher) String() string { return proto.CompactTextString(m) } func (*GCPMatcher) ProtoMessage() {} func (*GCPMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{372} + return fileDescriptor_9198ee693835762e, []int{373} } func (m *GCPMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21687,7 +21784,7 @@ func (m *KubernetesMatcher) Reset() { *m = KubernetesMatcher{} } func (m *KubernetesMatcher) String() string { return proto.CompactTextString(m) } func (*KubernetesMatcher) ProtoMessage() {} func (*KubernetesMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{373} + return fileDescriptor_9198ee693835762e, []int{374} } func (m *KubernetesMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21729,7 +21826,7 @@ func (m *OktaOptions) Reset() { *m = OktaOptions{} } func (m *OktaOptions) String() string { return proto.CompactTextString(m) } func (*OktaOptions) ProtoMessage() {} func (*OktaOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{374} + return fileDescriptor_9198ee693835762e, []int{375} } func (m *OktaOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21775,7 +21872,7 @@ func (m *AccessGraphSync) Reset() { *m = AccessGraphSync{} } func (m *AccessGraphSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphSync) ProtoMessage() {} func (*AccessGraphSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{375} + return fileDescriptor_9198ee693835762e, []int{376} } func (m *AccessGraphSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21821,7 +21918,7 @@ func (m *AccessGraphAWSSync) Reset() { *m = AccessGraphAWSSync{} } func (m *AccessGraphAWSSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphAWSSync) ProtoMessage() {} func (*AccessGraphAWSSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{376} + return fileDescriptor_9198ee693835762e, []int{377} } func (m *AccessGraphAWSSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21865,7 +21962,7 @@ func (m *AccessGraphAzureSync) Reset() { *m = AccessGraphAzureSync{} } func (m *AccessGraphAzureSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphAzureSync) ProtoMessage() {} func (*AccessGraphAzureSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{377} + return fileDescriptor_9198ee693835762e, []int{378} } func (m *AccessGraphAzureSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22022,6 +22119,8 @@ func init() { proto.RegisterType((*ProvisionTokenSpecV2TerraformCloud_Rule)(nil), "types.ProvisionTokenSpecV2TerraformCloud.Rule") proto.RegisterType((*ProvisionTokenSpecV2Bitbucket)(nil), "types.ProvisionTokenSpecV2Bitbucket") proto.RegisterType((*ProvisionTokenSpecV2Bitbucket_Rule)(nil), "types.ProvisionTokenSpecV2Bitbucket.Rule") + proto.RegisterType((*ProvisionTokenSpecV2Oracle)(nil), "types.ProvisionTokenSpecV2Oracle") + proto.RegisterType((*ProvisionTokenSpecV2Oracle_Rule)(nil), "types.ProvisionTokenSpecV2Oracle.Rule") proto.RegisterType((*StaticTokensV2)(nil), "types.StaticTokensV2") proto.RegisterType((*StaticTokensSpecV2)(nil), "types.StaticTokensSpecV2") proto.RegisterType((*ClusterNameV2)(nil), "types.ClusterNameV2") @@ -22344,1936 +22443,1943 @@ func init() { func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } var fileDescriptor_9198ee693835762e = []byte{ - // 30863 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, 0xf3, 0x68, 0x4e, - 0xcd, 0x0c, 0x87, 0x9c, 0x9d, 0x21, 0x97, 0xe0, 0x0e, 0x77, 0x67, 0xe7, 0xb5, 0x8d, 0x6e, 0x90, - 0x68, 0x12, 0x04, 0x7b, 0xab, 0x01, 0x62, 0x47, 0xfb, 0xa8, 0x2d, 0x74, 0x27, 0x80, 0x1a, 0x74, - 0x77, 0xf5, 0x56, 0x55, 0x93, 0x84, 0xf6, 0x64, 0x3d, 0xf7, 0x64, 0x85, 0xac, 0xe7, 0x49, 0xa7, - 0x3d, 0x87, 0x4e, 0xbe, 0x90, 0xef, 0x7c, 0x8a, 0x73, 0x48, 0x71, 0x96, 0x2c, 0xfb, 0xec, 0x0b, - 0xcb, 0x92, 0xe3, 0x2c, 0xcb, 0x8a, 0x8b, 0x93, 0xe2, 0x7c, 0xb6, 0xc3, 0xeb, 0x33, 0x64, 0x59, - 0xfe, 0x85, 0x08, 0x47, 0x48, 0xbe, 0x08, 0x47, 0x78, 0x1d, 0xba, 0x73, 0xe4, 0x97, 0x99, 0x55, - 0x99, 0x55, 0xd5, 0x8d, 0xc6, 0x90, 0xa3, 0x13, 0x27, 0xf4, 0x87, 0x44, 0x7f, 0xf9, 0x7d, 0x5f, - 0x56, 0xbe, 0xbf, 0xfc, 0xf2, 0x7b, 0xc0, 0x8b, 0x01, 0x6d, 0xd1, 0xae, 0xeb, 0x05, 0x57, 0x5b, - 0x74, 0xcf, 0x6e, 0x1c, 0x5e, 0x0d, 0x0e, 0xbb, 0xd4, 0xe7, 0xff, 0x5e, 0xe9, 0x7a, 0x6e, 0xe0, - 0x92, 0x51, 0xfc, 0xb1, 0xb4, 0xb0, 0xe7, 0xee, 0xb9, 0x08, 0xb9, 0xca, 0xfe, 0xe2, 0x85, 0x4b, - 0x2f, 0xec, 0xb9, 0xee, 0x5e, 0x8b, 0x5e, 0xc5, 0x5f, 0x3b, 0xbd, 0xdd, 0xab, 0xcd, 0x9e, 0x67, - 0x07, 0x8e, 0xdb, 0x11, 0xe5, 0xc5, 0x78, 0x79, 0xe0, 0xb4, 0xa9, 0x1f, 0xd8, 0xed, 0x6e, 0x3f, - 0x06, 0x0f, 0x3d, 0xbb, 0xdb, 0xa5, 0x9e, 0xa8, 0x7d, 0xe9, 0x72, 0xf8, 0x81, 0x76, 0x10, 0x30, - 0x4a, 0xc6, 0xfc, 0xea, 0x83, 0x6b, 0xea, 0x4f, 0x81, 0x7a, 0xa3, 0x4f, 0x5b, 0xbc, 0x9e, 0x1f, - 0xd0, 0xa6, 0xd5, 0xa4, 0x0f, 0x9c, 0x06, 0xb5, 0x3c, 0xfa, 0x8d, 0x9e, 0xe3, 0xd1, 0x36, 0xed, - 0x04, 0x82, 0xee, 0x8d, 0x74, 0x3a, 0xf9, 0x21, 0xb1, 0x2f, 0x32, 0x7e, 0x29, 0x07, 0x13, 0x77, - 0x28, 0xed, 0x96, 0x5a, 0xce, 0x03, 0x4a, 0x5e, 0x82, 0x91, 0x0d, 0xbb, 0x4d, 0x17, 0x33, 0x17, - 0x32, 0x97, 0x26, 0x56, 0x66, 0x8f, 0x8f, 0x8a, 0x93, 0x3e, 0xf5, 0x1e, 0x50, 0xcf, 0xea, 0xd8, - 0x6d, 0x6a, 0x62, 0x21, 0xf9, 0x14, 0x4c, 0xb0, 0xff, 0xfd, 0xae, 0xdd, 0xa0, 0x8b, 0x59, 0xc4, - 0x9c, 0x3e, 0x3e, 0x2a, 0x4e, 0x74, 0x24, 0xd0, 0x8c, 0xca, 0x49, 0x15, 0xc6, 0x57, 0x1f, 0x75, - 0x1d, 0x8f, 0xfa, 0x8b, 0x23, 0x17, 0x32, 0x97, 0x26, 0x97, 0x97, 0xae, 0xf0, 0x3e, 0xba, 0x22, - 0xfb, 0xe8, 0xca, 0xa6, 0xec, 0xc4, 0x95, 0xf9, 0xdf, 0x3b, 0x2a, 0x3e, 0x73, 0x7c, 0x54, 0x1c, - 0xa7, 0x9c, 0xe4, 0xa7, 0xff, 0xa8, 0x98, 0x31, 0x25, 0x3d, 0x79, 0x07, 0x46, 0x36, 0x0f, 0xbb, - 0x74, 0x71, 0xe2, 0x42, 0xe6, 0xd2, 0xcc, 0xf2, 0x0b, 0x57, 0xf8, 0xb0, 0x86, 0x1f, 0x1f, 0xfd, - 0xc5, 0xb0, 0x56, 0xf2, 0xc7, 0x47, 0xc5, 0x11, 0x86, 0x62, 0x22, 0x15, 0x79, 0x03, 0xc6, 0xd6, - 0x5c, 0x3f, 0xa8, 0x56, 0x16, 0x01, 0x3f, 0xf9, 0xcc, 0xf1, 0x51, 0x71, 0x6e, 0xdf, 0xf5, 0x03, - 0xcb, 0x69, 0xbe, 0xee, 0xb6, 0x9d, 0x80, 0xb6, 0xbb, 0xc1, 0xa1, 0x29, 0x90, 0x8c, 0x47, 0x30, - 0xad, 0xf1, 0x23, 0x93, 0x30, 0xbe, 0xb5, 0x71, 0x67, 0xe3, 0xde, 0xf6, 0x46, 0xe1, 0x19, 0x92, - 0x87, 0x91, 0x8d, 0x7b, 0x95, 0xd5, 0x42, 0x86, 0x8c, 0x43, 0xae, 0x54, 0xab, 0x15, 0xb2, 0x64, - 0x0a, 0xf2, 0x95, 0xd2, 0x66, 0x69, 0xa5, 0x54, 0x5f, 0x2d, 0xe4, 0xc8, 0x3c, 0xcc, 0x6e, 0x57, - 0x37, 0x2a, 0xf7, 0xb6, 0xeb, 0x56, 0x65, 0xb5, 0x7e, 0x67, 0xf3, 0x5e, 0xad, 0x30, 0x42, 0x66, - 0x00, 0xee, 0x6c, 0xad, 0xac, 0x9a, 0x1b, 0xab, 0x9b, 0xab, 0xf5, 0xc2, 0x28, 0x59, 0x80, 0x82, - 0x24, 0xb1, 0xea, 0xab, 0xe6, 0xfd, 0x6a, 0x79, 0xb5, 0x30, 0x76, 0x7b, 0x24, 0x9f, 0x2b, 0x8c, - 0x98, 0xe3, 0xeb, 0xd4, 0xf6, 0x69, 0xb5, 0x62, 0xfc, 0x87, 0x39, 0xc8, 0xdf, 0xa5, 0x81, 0xdd, - 0xb4, 0x03, 0x9b, 0x3c, 0xa7, 0x8d, 0x0f, 0x36, 0x51, 0x19, 0x98, 0x97, 0x92, 0x03, 0x33, 0x7a, - 0x7c, 0x54, 0xcc, 0xbc, 0xa1, 0x0e, 0xc8, 0xdb, 0x30, 0x59, 0xa1, 0x7e, 0xc3, 0x73, 0xba, 0x6c, - 0xb2, 0x2d, 0xe6, 0x10, 0xed, 0xfc, 0xf1, 0x51, 0xf1, 0x4c, 0x33, 0x02, 0x2b, 0x1d, 0xa2, 0x62, - 0x93, 0x2a, 0x8c, 0xad, 0xdb, 0x3b, 0xb4, 0xe5, 0x2f, 0x8e, 0x5e, 0xc8, 0x5d, 0x9a, 0x5c, 0x7e, - 0x56, 0x0c, 0x82, 0xfc, 0xc0, 0x2b, 0xbc, 0x74, 0xb5, 0x13, 0x78, 0x87, 0x2b, 0x0b, 0xc7, 0x47, - 0xc5, 0x42, 0x0b, 0x01, 0x6a, 0x07, 0x73, 0x14, 0x52, 0x8f, 0x26, 0xc6, 0xd8, 0x89, 0x13, 0xe3, - 0xf9, 0xdf, 0x3b, 0x2a, 0x66, 0xd8, 0x80, 0x89, 0x89, 0x11, 0xf1, 0xd3, 0xa7, 0xc8, 0x32, 0xe4, - 0x4d, 0xfa, 0xc0, 0xf1, 0x59, 0xcb, 0xf2, 0xd8, 0xb2, 0xb3, 0xc7, 0x47, 0x45, 0xe2, 0x09, 0x98, - 0xf2, 0x19, 0x21, 0xde, 0xd2, 0x5b, 0x30, 0xa9, 0x7c, 0x35, 0x29, 0x40, 0xee, 0x80, 0x1e, 0xf2, - 0x1e, 0x36, 0xd9, 0x9f, 0x64, 0x01, 0x46, 0x1f, 0xd8, 0xad, 0x9e, 0xe8, 0x52, 0x93, 0xff, 0xf8, - 0x7c, 0xf6, 0x73, 0x99, 0xdb, 0x23, 0xf9, 0xf1, 0x42, 0xde, 0xcc, 0x56, 0x2b, 0xc6, 0xcf, 0x8e, - 0x40, 0xde, 0x74, 0xf9, 0x02, 0x26, 0x97, 0x61, 0xb4, 0x1e, 0xd8, 0x81, 0x1c, 0xa6, 0xf9, 0xe3, - 0xa3, 0xe2, 0x2c, 0x5b, 0xdc, 0x54, 0xa9, 0x9f, 0x63, 0x30, 0xd4, 0xda, 0xbe, 0xed, 0xcb, 0xe1, - 0x42, 0xd4, 0x2e, 0x03, 0xa8, 0xa8, 0x88, 0x41, 0x2e, 0xc2, 0xc8, 0x5d, 0xb7, 0x49, 0xc5, 0x88, - 0x91, 0xe3, 0xa3, 0xe2, 0x4c, 0xdb, 0x6d, 0xaa, 0x88, 0x58, 0x4e, 0x5e, 0x87, 0x89, 0x72, 0xcf, - 0xf3, 0x68, 0x87, 0xcd, 0xf5, 0x11, 0x44, 0x9e, 0x39, 0x3e, 0x2a, 0x42, 0x83, 0x03, 0x2d, 0xa7, - 0x69, 0x46, 0x08, 0x6c, 0x18, 0xea, 0x81, 0xed, 0x05, 0xb4, 0xb9, 0x38, 0x3a, 0xd4, 0x30, 0xb0, - 0xf5, 0x39, 0xe7, 0x73, 0x92, 0xf8, 0x30, 0x08, 0x4e, 0x64, 0x0d, 0x26, 0x6f, 0x79, 0x76, 0x83, - 0xd6, 0xa8, 0xe7, 0xb8, 0x4d, 0x1c, 0xdf, 0xdc, 0xca, 0xc5, 0xe3, 0xa3, 0xe2, 0xd9, 0x3d, 0x06, - 0xb6, 0xba, 0x08, 0x8f, 0xa8, 0xbf, 0x7b, 0x54, 0xcc, 0x57, 0xc4, 0x56, 0x6b, 0xaa, 0xa4, 0xe4, - 0xeb, 0x6c, 0x70, 0xfc, 0x00, 0xbb, 0x96, 0x36, 0x17, 0xc7, 0x4f, 0xfc, 0x44, 0x43, 0x7c, 0xe2, - 0xd9, 0x96, 0xed, 0x07, 0x96, 0xc7, 0xe9, 0x62, 0xdf, 0xa9, 0xb2, 0x24, 0xf7, 0x20, 0x5f, 0x6f, - 0xec, 0xd3, 0x66, 0xaf, 0x45, 0x71, 0xca, 0x4c, 0x2e, 0x9f, 0x13, 0x93, 0x5a, 0x8e, 0xa7, 0x2c, - 0x5e, 0x59, 0x12, 0xbc, 0x89, 0x2f, 0x20, 0xea, 0x7c, 0x92, 0x58, 0x9f, 0xcf, 0x7f, 0xfb, 0xef, - 0x14, 0x9f, 0xf9, 0x81, 0x7f, 0x79, 0xe1, 0x19, 0xe3, 0x3f, 0xcf, 0x42, 0x21, 0xce, 0x84, 0xec, - 0xc2, 0xf4, 0x56, 0xb7, 0x69, 0x07, 0xb4, 0xdc, 0x72, 0x68, 0x27, 0xf0, 0x71, 0x92, 0x0c, 0x6e, - 0xd3, 0xcb, 0xa2, 0xde, 0xc5, 0x1e, 0x12, 0x5a, 0x0d, 0x4e, 0x19, 0x6b, 0x95, 0xce, 0x36, 0xaa, - 0xa7, 0x8e, 0x1b, 0xb8, 0x8f, 0x33, 0xec, 0x74, 0xf5, 0xf0, 0xad, 0xbf, 0x4f, 0x3d, 0x82, 0xad, - 0x98, 0x40, 0x9d, 0xe6, 0xce, 0x21, 0xce, 0xcc, 0xe1, 0x27, 0x10, 0x23, 0x49, 0x99, 0x40, 0x0c, - 0x6c, 0xfc, 0x9f, 0x19, 0x98, 0x31, 0xa9, 0xef, 0xf6, 0xbc, 0x06, 0x5d, 0xa3, 0x76, 0x93, 0x7a, - 0x6c, 0xfa, 0xdf, 0x71, 0x3a, 0x4d, 0xb1, 0xa6, 0x70, 0xfa, 0x1f, 0x38, 0x1d, 0x75, 0xeb, 0xc6, - 0x72, 0xf2, 0x69, 0x18, 0xaf, 0xf7, 0x76, 0x10, 0x35, 0x1b, 0xed, 0x00, 0x7e, 0x6f, 0xc7, 0x8a, - 0xa1, 0x4b, 0x34, 0x72, 0x15, 0xc6, 0xef, 0x53, 0xcf, 0x8f, 0x76, 0x43, 0x3c, 0x1a, 0x1e, 0x70, - 0x90, 0x4a, 0x20, 0xb0, 0xc8, 0xad, 0x68, 0x47, 0x16, 0x87, 0xda, 0x6c, 0x6c, 0x1f, 0x8c, 0xa6, - 0x4a, 0x5b, 0x40, 0xd4, 0xa9, 0x22, 0xb1, 0x8c, 0x9f, 0xc9, 0x42, 0xa1, 0x62, 0x07, 0xf6, 0x8e, - 0xed, 0x8b, 0xfe, 0xbc, 0x7f, 0x9d, 0xed, 0xf1, 0x4a, 0x43, 0x71, 0x8f, 0x67, 0x5f, 0xfe, 0x91, - 0x9b, 0xf7, 0x4a, 0xbc, 0x79, 0x93, 0xec, 0x84, 0x15, 0xcd, 0x8b, 0x1a, 0xf5, 0xee, 0xc9, 0x8d, - 0x2a, 0x88, 0x46, 0xe5, 0x65, 0xa3, 0xa2, 0xa6, 0x90, 0x77, 0x61, 0xa4, 0xde, 0xa5, 0x0d, 0xb1, - 0x89, 0xc8, 0x73, 0x41, 0x6f, 0x1c, 0x43, 0xb8, 0x7f, 0x7d, 0x65, 0x4a, 0xb0, 0x19, 0xf1, 0xbb, - 0xb4, 0x61, 0x22, 0x99, 0xb2, 0x68, 0xfe, 0x51, 0x0e, 0x16, 0xd2, 0xc8, 0xd4, 0x76, 0x8c, 0x0d, - 0x68, 0xc7, 0x25, 0xc8, 0xb3, 0x23, 0x9c, 0x1d, 0x8b, 0xb8, 0x5d, 0x4c, 0xac, 0x4c, 0xb1, 0x4f, - 0xde, 0x17, 0x30, 0x33, 0x2c, 0x25, 0x2f, 0x85, 0x12, 0x41, 0x3e, 0xe2, 0x27, 0x24, 0x02, 0x29, - 0x07, 0xb0, 0xb1, 0x96, 0x4b, 0x18, 0x05, 0x87, 0xa8, 0x5b, 0x24, 0x38, 0x1a, 0x6b, 0x4f, 0x40, - 0xb4, 0x63, 0x46, 0x1e, 0x0a, 0xab, 0x90, 0x97, 0xcd, 0x5a, 0x9c, 0x42, 0x46, 0x73, 0xb1, 0x4e, - 0xba, 0x7f, 0x9d, 0x0f, 0x66, 0x53, 0xfc, 0x56, 0xd9, 0x48, 0x1c, 0x72, 0x1d, 0xf2, 0x35, 0xcf, - 0x7d, 0x74, 0x58, 0xad, 0xf8, 0x8b, 0xd3, 0x17, 0x72, 0x97, 0x26, 0x56, 0xce, 0x1d, 0x1f, 0x15, - 0xe7, 0xbb, 0x0c, 0x66, 0x39, 0x4d, 0xf5, 0xa4, 0x0d, 0x11, 0x6f, 0x8f, 0xe4, 0x33, 0x85, 0xec, - 0xed, 0x91, 0x7c, 0xb6, 0x90, 0xe3, 0xe2, 0xc5, 0xed, 0x91, 0xfc, 0x48, 0x61, 0xf4, 0xf6, 0x48, - 0x7e, 0x14, 0x05, 0x8e, 0x89, 0x02, 0xdc, 0x1e, 0xc9, 0x4f, 0x16, 0xa6, 0xb4, 0xd3, 0x1e, 0x19, - 0x04, 0x6e, 0xc3, 0x6d, 0x99, 0xb9, 0x2d, 0xb3, 0x6a, 0x8e, 0x95, 0x4b, 0x65, 0xea, 0x05, 0x66, - 0xae, 0xb4, 0x5d, 0x37, 0xa7, 0x2b, 0x87, 0x1d, 0xbb, 0xed, 0x34, 0xf8, 0xd1, 0x69, 0xe6, 0x6e, - 0x95, 0x6b, 0x46, 0x09, 0x66, 0xa2, 0xb6, 0xac, 0x3b, 0x7e, 0x40, 0xae, 0xc2, 0x84, 0x84, 0xb0, - 0x8d, 0x2e, 0x97, 0xda, 0x6a, 0x33, 0xc2, 0x31, 0x7e, 0x37, 0x0b, 0x10, 0x95, 0x3c, 0xa5, 0x6b, - 0xe1, 0xb3, 0xda, 0x5a, 0x38, 0x13, 0x5f, 0x0b, 0x7d, 0x57, 0x01, 0x79, 0x1f, 0xc6, 0x98, 0x58, - 0xd0, 0x93, 0x22, 0xd1, 0xb9, 0x38, 0x29, 0x16, 0xde, 0xbf, 0xbe, 0x32, 0x23, 0x88, 0xc7, 0x7c, - 0x84, 0x98, 0x82, 0x4c, 0x59, 0x46, 0xbf, 0x34, 0x1e, 0x0d, 0x86, 0x58, 0x40, 0x97, 0x20, 0x1c, - 0x50, 0xd1, 0xa1, 0xb8, 0x32, 0xba, 0x72, 0x90, 0xc3, 0x52, 0x72, 0x1e, 0xd8, 0x80, 0x8b, 0x4e, - 0x1d, 0x3f, 0x3e, 0x2a, 0xe6, 0x7a, 0x9e, 0x83, 0x93, 0x80, 0x5c, 0x05, 0x31, 0x0d, 0x44, 0x07, - 0xb2, 0xd9, 0x37, 0xd7, 0xb0, 0xad, 0x06, 0xf5, 0x82, 0xa8, 0xc7, 0x17, 0x33, 0x72, 0xb6, 0x90, - 0x2e, 0xe8, 0x53, 0x65, 0x71, 0x04, 0xa7, 0xc1, 0xa5, 0xd4, 0x5e, 0xb9, 0xa2, 0xa1, 0x72, 0x31, - 0xf2, 0x82, 0x3c, 0x95, 0x9a, 0xbc, 0xcc, 0x4a, 0x88, 0x94, 0x7a, 0x05, 0xe4, 0x3a, 0xb0, 0x19, - 0x2a, 0x7a, 0x1f, 0x44, 0x3d, 0xa5, 0xed, 0xfa, 0xca, 0x19, 0xc1, 0x69, 0xda, 0x7e, 0xa8, 0x92, - 0x33, 0x6c, 0xf2, 0x36, 0xb0, 0x29, 0x2c, 0xfa, 0x9d, 0x08, 0xa2, 0x5b, 0xe5, 0x5a, 0xb9, 0xe5, - 0xf6, 0x9a, 0xf5, 0x2f, 0xae, 0x47, 0xc4, 0x7b, 0x8d, 0xae, 0x4a, 0x7c, 0xab, 0x5c, 0x23, 0x6f, - 0xc3, 0x68, 0xe9, 0x7b, 0x7b, 0x1e, 0x15, 0xf2, 0xc9, 0x94, 0xac, 0x93, 0xc1, 0x56, 0xce, 0x09, - 0xc2, 0x59, 0x9b, 0xfd, 0x54, 0xe5, 0x3a, 0x2c, 0x67, 0x35, 0x6f, 0xae, 0xd7, 0x85, 0xec, 0x41, - 0x62, 0xdd, 0xb2, 0xb9, 0xae, 0x7c, 0x76, 0xa0, 0xb5, 0x9a, 0x51, 0x91, 0xab, 0x90, 0x2d, 0x55, - 0xf0, 0x46, 0x34, 0xb9, 0x3c, 0x21, 0xab, 0xad, 0xac, 0x2c, 0x08, 0x92, 0x29, 0x5b, 0x5d, 0x06, - 0xd9, 0x52, 0x85, 0xac, 0xc0, 0xe8, 0xdd, 0xc3, 0xfa, 0x17, 0xd7, 0xc5, 0x66, 0x36, 0x2f, 0xe7, - 0x35, 0x83, 0xdd, 0xc3, 0x65, 0xef, 0x47, 0x5f, 0xdc, 0x3e, 0xf4, 0xbf, 0xd1, 0x52, 0xbf, 0x18, - 0xd1, 0x48, 0x0d, 0x26, 0x4a, 0xcd, 0xb6, 0xd3, 0xd9, 0xf2, 0xa9, 0xb7, 0x38, 0x89, 0x7c, 0x16, - 0x63, 0xdf, 0x1d, 0x96, 0xaf, 0x2c, 0x1e, 0x1f, 0x15, 0x17, 0x6c, 0xf6, 0xd3, 0xea, 0xf9, 0xd4, - 0x53, 0xb8, 0x45, 0x4c, 0x48, 0x0d, 0xe0, 0xae, 0xdb, 0xd9, 0x73, 0x4b, 0x41, 0xcb, 0xf6, 0x63, - 0xdb, 0x63, 0x54, 0x10, 0x8a, 0x0f, 0x67, 0xda, 0x0c, 0x66, 0xd9, 0x0c, 0xa8, 0x30, 0x54, 0x78, - 0x90, 0x9b, 0x30, 0x76, 0xcf, 0xb3, 0x1b, 0x2d, 0xba, 0x38, 0x8d, 0xdc, 0x16, 0x04, 0x37, 0x0e, - 0x94, 0x2d, 0x5d, 0x14, 0x0c, 0x0b, 0x2e, 0x82, 0xd5, 0x6b, 0x0a, 0x47, 0x5c, 0xda, 0x06, 0x92, - 0x9c, 0x93, 0x29, 0x97, 0x84, 0x4f, 0xa9, 0x97, 0x84, 0x68, 0xd1, 0x97, 0xdd, 0x76, 0xdb, 0xee, - 0x34, 0x91, 0xf6, 0xfe, 0xb2, 0x72, 0x77, 0x30, 0xbe, 0x01, 0x73, 0x89, 0xce, 0x3a, 0xe1, 0x7e, - 0xf7, 0x1e, 0xcc, 0x56, 0xe8, 0xae, 0xdd, 0x6b, 0x05, 0xe1, 0x49, 0xc2, 0x97, 0x28, 0xde, 0xb4, - 0x9a, 0xbc, 0xc8, 0x92, 0xc7, 0x87, 0x19, 0x47, 0x36, 0xde, 0x85, 0x69, 0xad, 0xf9, 0xec, 0xaa, - 0x50, 0xea, 0x35, 0x9d, 0x00, 0x07, 0x32, 0x13, 0x5d, 0x15, 0x6c, 0x06, 0xc4, 0xe1, 0x32, 0x23, - 0x04, 0xe3, 0xef, 0xaa, 0xd2, 0x8a, 0xd8, 0x89, 0xd8, 0xb5, 0x5a, 0xec, 0x07, 0x99, 0x48, 0x76, - 0x4a, 0xec, 0x07, 0xe1, 0x6e, 0x70, 0x99, 0xaf, 0xcd, 0x6c, 0x62, 0x6d, 0x4e, 0x8a, 0x91, 0xc8, - 0xd9, 0x0f, 0x7d, 0xbe, 0x22, 0xc3, 0x99, 0x9a, 0xfb, 0xe8, 0x33, 0xf5, 0x7d, 0x98, 0xba, 0x6b, - 0x77, 0xec, 0x3d, 0xda, 0x64, 0x2d, 0xe0, 0x7b, 0xcf, 0xc4, 0xca, 0xb3, 0xc7, 0x47, 0xc5, 0x73, - 0x6d, 0x0e, 0xc7, 0x56, 0xaa, 0x93, 0x48, 0x23, 0x20, 0xd7, 0xe4, 0xca, 0x1e, 0x4d, 0x59, 0xd9, - 0xd3, 0xa2, 0xf6, 0x51, 0x5c, 0xd9, 0x62, 0x3d, 0x1b, 0xbf, 0x3d, 0x81, 0x6d, 0x24, 0xaf, 0xc3, - 0x98, 0x49, 0xf7, 0xd8, 0x51, 0x93, 0x89, 0x06, 0xc9, 0x43, 0x88, 0xda, 0x31, 0x1c, 0x07, 0xe5, - 0x0c, 0xda, 0xf4, 0xf7, 0x9d, 0xdd, 0x40, 0xf4, 0x4e, 0x28, 0x67, 0x08, 0xb0, 0x22, 0x67, 0x08, - 0x88, 0x7e, 0x9d, 0xe5, 0x30, 0xb6, 0xfb, 0x99, 0x95, 0xba, 0xe8, 0x34, 0xd9, 0xc3, 0x66, 0x45, - 0xd9, 0x46, 0x3c, 0x4d, 0x4a, 0x60, 0xd8, 0xe4, 0x06, 0x4c, 0x94, 0x1a, 0x0d, 0xb7, 0xa7, 0xdc, - 0x19, 0xf9, 0xba, 0xe5, 0x40, 0x5d, 0x45, 0x12, 0xa1, 0x92, 0x3a, 0x4c, 0xae, 0xb2, 0x8b, 0x96, - 0x53, 0xb6, 0x1b, 0xfb, 0xb2, 0x93, 0xe4, 0x1e, 0xa6, 0x94, 0x44, 0x2b, 0x97, 0x22, 0xb0, 0xc1, - 0x80, 0xaa, 0x92, 0x41, 0xc1, 0x25, 0x9b, 0x30, 0x59, 0xa7, 0x0d, 0x8f, 0x06, 0xf5, 0xc0, 0xf5, - 0x68, 0x6c, 0x4b, 0x56, 0x4a, 0x56, 0x5e, 0x90, 0x77, 0x3d, 0x1f, 0x81, 0x96, 0xcf, 0xa0, 0x2a, - 0x57, 0x05, 0x99, 0x0b, 0xed, 0x6d, 0xd7, 0x3b, 0xac, 0xac, 0x88, 0x6d, 0x3a, 0x3a, 0xd3, 0x39, - 0x58, 0x15, 0xda, 0x19, 0xa4, 0xb9, 0xa3, 0x0b, 0xed, 0x1c, 0x0b, 0x47, 0xaa, 0x52, 0x47, 0xd9, - 0x4a, 0x6c, 0xda, 0xb3, 0x51, 0x2f, 0x23, 0x58, 0x19, 0xa9, 0xa6, 0x8f, 0x92, 0x99, 0x36, 0x52, - 0x02, 0x8b, 0x74, 0x81, 0xc8, 0x51, 0xe3, 0x82, 0x6e, 0x8b, 0xfa, 0xbe, 0xd8, 0xcb, 0xcf, 0xc7, - 0x06, 0x3f, 0x42, 0x58, 0x79, 0x45, 0x30, 0x7f, 0x5e, 0x4e, 0x03, 0x71, 0x4f, 0x63, 0x85, 0x4a, - 0x3d, 0x29, 0xbc, 0xc9, 0x5b, 0x00, 0xab, 0x8f, 0x02, 0xea, 0x75, 0xec, 0x56, 0xa8, 0x07, 0x43, - 0xd5, 0x0f, 0x15, 0x50, 0x7d, 0xa0, 0x15, 0x64, 0x52, 0x86, 0xe9, 0x92, 0xef, 0xf7, 0xda, 0xd4, - 0x74, 0x5b, 0xb4, 0x64, 0x6e, 0xe0, 0xbe, 0x3f, 0xb1, 0xf2, 0xfc, 0xf1, 0x51, 0xf1, 0xbc, 0x8d, - 0x05, 0x96, 0xe7, 0xb6, 0xa8, 0x65, 0x7b, 0xea, 0xec, 0xd6, 0x69, 0xc8, 0x3d, 0x80, 0x7b, 0x5d, - 0xda, 0xa9, 0x53, 0xdb, 0x6b, 0xec, 0xc7, 0xb6, 0xf9, 0xa8, 0x60, 0xe5, 0x39, 0xd1, 0xc2, 0x05, - 0xb7, 0x4b, 0x3b, 0x3e, 0xc2, 0xd4, 0xaf, 0x8a, 0x30, 0xc9, 0x36, 0xcc, 0x56, 0x4b, 0x77, 0x6b, - 0x6e, 0xcb, 0x69, 0x1c, 0x0a, 0xc9, 0x69, 0x06, 0xb5, 0x83, 0x67, 0x05, 0xd7, 0x58, 0x29, 0xdf, - 0x9e, 0x1c, 0xbb, 0x6d, 0x75, 0x11, 0x6a, 0x09, 0xf9, 0x29, 0xce, 0x85, 0x7c, 0xc0, 0xe6, 0xa0, - 0xcf, 0x84, 0xc1, 0x4d, 0x7b, 0xcf, 0x5f, 0x9c, 0xd5, 0xb4, 0x5d, 0xa5, 0xed, 0xfa, 0x15, 0xa5, - 0x94, 0x8b, 0x29, 0x4b, 0x7c, 0x22, 0x22, 0xd4, 0x0a, 0xec, 0x3d, 0x5f, 0x9f, 0x88, 0x21, 0x36, - 0xb9, 0x0d, 0x50, 0x71, 0x1b, 0xbd, 0x36, 0xed, 0x04, 0x95, 0x95, 0xc5, 0x82, 0x7e, 0x15, 0x08, - 0x0b, 0xa2, 0xad, 0xad, 0xe9, 0x36, 0xb4, 0x99, 0xa8, 0x50, 0x2f, 0xbd, 0x07, 0x85, 0xf8, 0x87, - 0x9c, 0x52, 0x81, 0x35, 0x5d, 0x98, 0x51, 0x5a, 0xbf, 0xfa, 0xc8, 0xf1, 0x03, 0xdf, 0xf8, 0xa6, - 0xb6, 0x02, 0xd9, 0xee, 0x70, 0x87, 0x1e, 0xd6, 0x3c, 0xba, 0xeb, 0x3c, 0x12, 0x9b, 0x19, 0xee, - 0x0e, 0x07, 0xf4, 0xd0, 0xea, 0x22, 0x54, 0xdd, 0x1d, 0x42, 0x54, 0xf2, 0x19, 0xc8, 0xdf, 0xb9, - 0x5b, 0xbf, 0x43, 0x0f, 0xab, 0x15, 0x71, 0x50, 0x71, 0xb2, 0xb6, 0x6f, 0x31, 0x52, 0x6d, 0xae, - 0x85, 0x98, 0xc6, 0x4a, 0xb4, 0x13, 0xb2, 0x9a, 0xcb, 0xad, 0x9e, 0x1f, 0x50, 0xaf, 0x5a, 0x51, - 0x6b, 0x6e, 0x70, 0x60, 0x6c, 0x5f, 0x0a, 0x51, 0x8d, 0x7f, 0x93, 0xc5, 0x5d, 0x90, 0x4d, 0xf8, - 0x6a, 0xc7, 0x0f, 0xec, 0x4e, 0x83, 0x86, 0x0c, 0x70, 0xc2, 0x3b, 0x02, 0x1a, 0x9b, 0xf0, 0x11, - 0xb2, 0x5e, 0x75, 0x76, 0xe8, 0xaa, 0x59, 0x95, 0x52, 0x73, 0x51, 0xad, 0xa8, 0xea, 0x55, 0x4f, - 0x40, 0x63, 0x55, 0x46, 0xc8, 0xe4, 0x22, 0x8c, 0x57, 0x4b, 0x77, 0x4b, 0xbd, 0x60, 0x1f, 0xf7, - 0xe0, 0x3c, 0x97, 0xcf, 0xd9, 0x6c, 0xb5, 0x7b, 0xc1, 0xbe, 0x29, 0x0b, 0xc9, 0x55, 0xbc, 0xf7, - 0x74, 0x68, 0xc0, 0xd5, 0xb0, 0xe2, 0xd0, 0xf5, 0x39, 0x28, 0x76, 0xed, 0x61, 0x20, 0xf2, 0x1a, - 0x8c, 0xde, 0xaf, 0x95, 0xab, 0x15, 0x71, 0x71, 0xc6, 0x93, 0xe8, 0x41, 0xb7, 0xa1, 0x7f, 0x09, - 0x47, 0x21, 0xab, 0x30, 0x53, 0xa7, 0x8d, 0x9e, 0xe7, 0x04, 0x87, 0xb7, 0x3c, 0xb7, 0xd7, 0xf5, - 0x17, 0xc7, 0xb1, 0x0e, 0x5c, 0xe9, 0xbe, 0x28, 0xb1, 0xf6, 0xb0, 0x48, 0xa1, 0x8e, 0x11, 0x19, - 0xbf, 0x93, 0x89, 0xb6, 0x49, 0x72, 0x51, 0x13, 0x6b, 0x50, 0x77, 0xc3, 0xc4, 0x1a, 0x55, 0x77, - 0x83, 0x02, 0x8e, 0x09, 0xa4, 0xdc, 0xf3, 0x03, 0xb7, 0xbd, 0xda, 0x69, 0x76, 0x5d, 0xa7, 0x13, - 0x20, 0x15, 0xef, 0x7c, 0xe3, 0xf8, 0xa8, 0xf8, 0x42, 0x03, 0x4b, 0x2d, 0x2a, 0x8a, 0xad, 0x18, - 0x97, 0x14, 0xea, 0xc7, 0x18, 0x0f, 0xe3, 0xf7, 0xb3, 0xda, 0xf1, 0xc6, 0x3e, 0xcf, 0xa4, 0xdd, - 0x96, 0xd3, 0xc0, 0x1b, 0x3d, 0x36, 0x34, 0x9c, 0x55, 0xf8, 0x79, 0x5e, 0x54, 0xca, 0x7b, 0x48, - 0xe7, 0x9d, 0x42, 0x4d, 0xbe, 0x00, 0x53, 0x4c, 0xd2, 0x10, 0x3f, 0xfd, 0xc5, 0x2c, 0x76, 0xf6, - 0x73, 0xa8, 0x85, 0xf3, 0xa9, 0x17, 0xb2, 0xd1, 0x44, 0x14, 0x95, 0x82, 0x34, 0x61, 0x71, 0xd3, - 0xb3, 0x3b, 0xbe, 0x13, 0xac, 0x76, 0x1a, 0xde, 0x21, 0x4a, 0x46, 0xab, 0x1d, 0x7b, 0xa7, 0x45, - 0x9b, 0xd8, 0xdc, 0xfc, 0xca, 0xa5, 0xe3, 0xa3, 0xe2, 0xcb, 0x01, 0xc7, 0xb1, 0x68, 0x88, 0x64, - 0x51, 0x8e, 0xa5, 0x70, 0xee, 0xcb, 0x89, 0x49, 0x52, 0xb2, 0x5b, 0xf1, 0x11, 0x86, 0x0b, 0x09, - 0x28, 0x49, 0x85, 0xa3, 0xc1, 0xf6, 0x30, 0xf5, 0x33, 0x55, 0x02, 0xe3, 0xff, 0xc9, 0x44, 0x07, - 0x30, 0x79, 0x07, 0x26, 0xc5, 0x8a, 0x51, 0xe6, 0x05, 0xee, 0xa0, 0x72, 0x79, 0xc5, 0x46, 0x56, - 0x45, 0x67, 0xf7, 0xfe, 0x52, 0x79, 0x5d, 0x99, 0x1b, 0x78, 0xef, 0xb7, 0x1b, 0xad, 0x38, 0x95, - 0x44, 0x63, 0x93, 0x60, 0x73, 0xbd, 0xae, 0xf7, 0x0a, 0x4e, 0x82, 0xa0, 0xe5, 0xa7, 0x74, 0x83, - 0x82, 0xfc, 0xf8, 0x0d, 0xff, 0x9f, 0x33, 0x69, 0xe7, 0x3c, 0x59, 0x81, 0xe9, 0x6d, 0xd7, 0x3b, - 0xc0, 0xf1, 0x55, 0x3a, 0x01, 0x47, 0xfe, 0xa1, 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, 0x6d, 0xa7, 0xa3, 0x34, 0x87, 0x3f, 0x2c, 0x21, 0x34, 0xfe, 0x25, 0x0a, 0x32, 0xb9, 0x0e, - 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, 0xd4, 0xc3, 0x26, 0x76, 0xc8, 0x64, 0x4f, - 0x73, 0xc8, 0x3c, 0x76, 0x13, 0x7e, 0x20, 0x03, 0x93, 0x8a, 0x96, 0x82, 0xb5, 0xa1, 0xe6, 0xb9, - 0x1f, 0xd2, 0x46, 0xa0, 0xb7, 0xa1, 0xcb, 0x81, 0xb1, 0x36, 0x84, 0xa8, 0x8f, 0xd1, 0x06, 0xe3, - 0xcf, 0x32, 0xe2, 0x8e, 0x34, 0xf4, 0x36, 0xaf, 0x6f, 0xc9, 0xd9, 0xd3, 0x1c, 0x91, 0x5f, 0x80, - 0x51, 0x93, 0x36, 0x1d, 0x5f, 0xdc, 0x6f, 0xe6, 0xd4, 0xfb, 0x18, 0x16, 0x44, 0x72, 0x93, 0xc7, - 0x7e, 0xaa, 0xe7, 0x1b, 0x96, 0x33, 0x41, 0xb6, 0xea, 0xdf, 0x6c, 0xd1, 0x47, 0x0e, 0x5f, 0x8c, - 0xe2, 0xa8, 0xc5, 0xe3, 0xcd, 0xf1, 0xad, 0x5d, 0x56, 0x22, 0x24, 0x6a, 0x75, 0xe1, 0x69, 0x34, - 0xc6, 0x07, 0x00, 0x51, 0x95, 0xe4, 0x0e, 0x14, 0xc4, 0x6c, 0x70, 0x3a, 0x7b, 0x5c, 0x90, 0x12, - 0x7d, 0x50, 0x3c, 0x3e, 0x2a, 0x3e, 0xdb, 0x08, 0xcb, 0x84, 0xd4, 0xa9, 0xf0, 0x4d, 0x10, 0x1a, - 0x7f, 0x3f, 0x0b, 0xd9, 0x12, 0x0e, 0xc8, 0x1d, 0x7a, 0x18, 0xd8, 0x3b, 0x37, 0x9d, 0x96, 0xb6, - 0x98, 0x0e, 0x10, 0x6a, 0xed, 0x3a, 0x9a, 0xba, 0x42, 0x41, 0x66, 0x8b, 0xe9, 0x8e, 0xb7, 0xf3, - 0x26, 0x12, 0x2a, 0x8b, 0xe9, 0xc0, 0xdb, 0x79, 0x33, 0x4e, 0x16, 0x22, 0x12, 0x03, 0xc6, 0xf8, - 0xc2, 0x12, 0x73, 0x10, 0x8e, 0x8f, 0x8a, 0x63, 0x7c, 0xfd, 0x99, 0xa2, 0x84, 0x9c, 0x87, 0x5c, - 0xbd, 0xb6, 0x21, 0x76, 0x40, 0x54, 0x0b, 0xfa, 0xdd, 0x8e, 0xc9, 0x60, 0xac, 0xce, 0xf5, 0x4a, - 0xa9, 0x86, 0x8a, 0x80, 0xd1, 0xa8, 0xce, 0x56, 0xd3, 0xee, 0xc6, 0x55, 0x01, 0x21, 0x22, 0x79, - 0x17, 0x26, 0xef, 0x54, 0xca, 0x6b, 0xae, 0xcf, 0x77, 0xaf, 0xb1, 0x68, 0xf2, 0x1f, 0x34, 0x1b, - 0x16, 0x6a, 0xe2, 0xe3, 0xc7, 0x80, 0x82, 0x6f, 0x7c, 0x2b, 0x0b, 0x93, 0x8a, 0x9e, 0x8c, 0x7c, - 0x46, 0x3c, 0x90, 0x66, 0xb4, 0x1b, 0x80, 0x82, 0xc1, 0x4a, 0xb9, 0x52, 0xa5, 0xed, 0x36, 0xa9, - 0x78, 0x2e, 0x8d, 0x14, 0x18, 0xd9, 0x61, 0x14, 0x18, 0x6f, 0x01, 0xf0, 0x39, 0x80, 0x9f, 0xac, - 0x88, 0x13, 0x8a, 0x9d, 0x84, 0x3a, 0x2e, 0x11, 0x32, 0xb9, 0x0f, 0xf3, 0x9b, 0x5e, 0xcf, 0x0f, - 0xea, 0x87, 0x7e, 0x40, 0xdb, 0x8c, 0x5b, 0xcd, 0x75, 0x5b, 0x62, 0xfe, 0xbd, 0x7c, 0x7c, 0x54, - 0xbc, 0x80, 0xc6, 0x1d, 0x96, 0x8f, 0xe5, 0xf8, 0x01, 0x56, 0xd7, 0x75, 0x55, 0xb5, 0x46, 0x1a, - 0x03, 0xc3, 0x84, 0x29, 0x55, 0x29, 0xc2, 0x4e, 0x16, 0xf1, 0x98, 0x24, 0x54, 0xdd, 0xca, 0xc9, - 0x22, 0xbe, 0x32, 0xf9, 0xb8, 0xa5, 0x93, 0x18, 0x9f, 0x51, 0x15, 0x72, 0xc3, 0x2e, 0x6c, 0xe3, - 0x87, 0x32, 0xd1, 0x36, 0x72, 0xff, 0x1a, 0x79, 0x1b, 0xc6, 0xf8, 0xe3, 0x9d, 0x78, 0xe3, 0x3c, - 0x13, 0x5e, 0x6a, 0xd5, 0x97, 0x3d, 0xae, 0x09, 0xff, 0x43, 0xfe, 0xc0, 0xff, 0x8c, 0x29, 0x48, - 0x42, 0x25, 0xba, 0xae, 0x4f, 0x93, 0xdc, 0x51, 0x5d, 0x7c, 0x2d, 0x4d, 0x89, 0x6e, 0xfc, 0xc4, - 0x28, 0xcc, 0xe8, 0x68, 0xea, 0x0b, 0x5f, 0x66, 0xa8, 0x17, 0xbe, 0x2f, 0x40, 0x9e, 0xf5, 0x87, - 0xd3, 0xa0, 0x52, 0x22, 0x7b, 0x19, 0x9f, 0x16, 0x04, 0x4c, 0x7b, 0xb9, 0x06, 0x3e, 0x1c, 0xec, - 0x8e, 0x6b, 0x86, 0x54, 0x64, 0x59, 0x79, 0x86, 0xca, 0x45, 0x42, 0x8a, 0x7c, 0x86, 0x52, 0xd7, - 0x43, 0xf8, 0x20, 0xf5, 0x06, 0x8c, 0x31, 0xf9, 0x3e, 0x54, 0xc1, 0xe0, 0x57, 0x32, 0xd1, 0x3f, - 0x66, 0xa2, 0xc2, 0x91, 0xc8, 0x36, 0xe4, 0xd7, 0x6d, 0x3f, 0xa8, 0x53, 0xda, 0x19, 0xe2, 0xed, - 0xbe, 0x28, 0xba, 0x6a, 0x1e, 0x1f, 0xc6, 0x7d, 0x4a, 0x3b, 0xb1, 0xc7, 0xd7, 0x90, 0x19, 0xf9, - 0x2a, 0x40, 0xd9, 0xed, 0x04, 0x9e, 0xdb, 0x5a, 0x77, 0xf7, 0x16, 0xc7, 0xf0, 0xee, 0xfb, 0x42, - 0x6c, 0x00, 0x22, 0x04, 0x7e, 0xfd, 0x0d, 0x15, 0x3c, 0x0d, 0x5e, 0x60, 0xb5, 0xdc, 0x3d, 0x75, - 0x1d, 0x44, 0xf8, 0xe4, 0x26, 0x14, 0xa4, 0x62, 0x61, 0xab, 0xbb, 0xe7, 0xe1, 0x04, 0x19, 0x8f, - 0x24, 0x0f, 0xfa, 0x28, 0xb0, 0x7a, 0x02, 0xae, 0xee, 0x94, 0x71, 0x1a, 0xf2, 0x15, 0x38, 0x17, - 0x87, 0xc9, 0x51, 0xce, 0x47, 0x32, 0xb9, 0xca, 0x2e, 0x65, 0xde, 0xf7, 0x63, 0x41, 0x6e, 0xc1, - 0x2c, 0xeb, 0x90, 0xbb, 0xd4, 0xf6, 0x7b, 0xdc, 0xc0, 0x4a, 0xa8, 0x66, 0x9e, 0x97, 0x9a, 0x28, - 0xbe, 0x0a, 0x5b, 0x6e, 0xe3, 0x40, 0x41, 0x32, 0xe3, 0x54, 0xc6, 0x51, 0x16, 0xce, 0xa6, 0xe3, - 0x92, 0xef, 0x87, 0x33, 0xa2, 0x5f, 0x5a, 0xd4, 0x53, 0x70, 0x86, 0xb0, 0x09, 0x78, 0x43, 0xf4, - 0xf7, 0x8b, 0x8d, 0x90, 0x41, 0xb8, 0x71, 0x30, 0x16, 0xb1, 0xc1, 0x4d, 0xaf, 0x87, 0x7c, 0x1d, - 0x26, 0xd5, 0x6a, 0xb3, 0xc3, 0x9b, 0x57, 0x0c, 0xa8, 0x4b, 0x65, 0x49, 0x6c, 0x98, 0x35, 0xe9, - 0x37, 0x7a, 0xd4, 0x0f, 0xa4, 0x81, 0x87, 0x38, 0xba, 0xcf, 0x27, 0x6a, 0x91, 0x08, 0xa1, 0xfe, - 0xa7, 0xe0, 0x71, 0x4a, 0x4b, 0x9a, 0xe1, 0x7d, 0x9b, 0xb1, 0x8f, 0xf3, 0x33, 0xbe, 0x9b, 0x85, - 0x73, 0x7d, 0xa6, 0x25, 0xdb, 0xb9, 0x50, 0xb0, 0x52, 0x76, 0xae, 0x98, 0x3c, 0xc5, 0xad, 0xc3, - 0x2e, 0x40, 0x56, 0x88, 0x22, 0x23, 0x2b, 0x85, 0xe3, 0xa3, 0xe2, 0x94, 0xb6, 0xe2, 0xb2, 0xd5, - 0x0a, 0xb9, 0x0d, 0x23, 0xac, 0x1b, 0x86, 0x30, 0x72, 0x90, 0xda, 0xbf, 0x99, 0xc0, 0x51, 0x17, - 0x3a, 0xf6, 0x0d, 0xf2, 0x20, 0x9f, 0x81, 0xdc, 0xe6, 0xe6, 0x3a, 0xae, 0xf2, 0x1c, 0xce, 0xd2, - 0xe9, 0x20, 0x68, 0x69, 0x9b, 0xca, 0x34, 0xa3, 0x0d, 0x7b, 0xc4, 0x64, 0xe8, 0xe4, 0x4b, 0x31, - 0xe3, 0xab, 0xd7, 0x06, 0x2f, 0xc9, 0xe1, 0x6d, 0xb1, 0x1e, 0xc3, 0x04, 0xca, 0xf8, 0xc5, 0x6c, - 0xb4, 0xdb, 0xde, 0x74, 0x5a, 0x01, 0xf5, 0xc8, 0x12, 0xdf, 0x3c, 0x23, 0x31, 0xda, 0x0c, 0x7f, - 0x93, 0xc5, 0x68, 0x27, 0xe6, 0xac, 0xc2, 0x2d, 0xf7, 0x35, 0x65, 0xcb, 0xcd, 0xe1, 0x96, 0x3b, - 0xd3, 0x77, 0x73, 0x7d, 0x2d, 0x65, 0x07, 0xc1, 0x2d, 0x33, 0x65, 0x97, 0x78, 0x19, 0xa6, 0x37, - 0xdc, 0xd5, 0x47, 0x41, 0x88, 0xc8, 0xb6, 0xca, 0xbc, 0xa9, 0x03, 0x19, 0xc7, 0x7b, 0xad, 0x26, - 0xf5, 0x36, 0xf7, 0xed, 0x8e, 0x66, 0x65, 0x60, 0x26, 0xe0, 0x0c, 0x77, 0x83, 0x3e, 0xd4, 0x71, - 0xc7, 0x39, 0x6e, 0x1c, 0x6e, 0xfc, 0x60, 0x56, 0x76, 0xc6, 0xfd, 0xe5, 0xa7, 0xf4, 0x35, 0xfb, - 0x4d, 0xed, 0x35, 0x7b, 0x3e, 0xd4, 0xc3, 0x87, 0xa6, 0x19, 0xcb, 0x27, 0x58, 0x74, 0xfc, 0xdd, - 0x31, 0x98, 0x52, 0xd1, 0x59, 0x3f, 0x94, 0x9a, 0x4d, 0x4f, 0xed, 0x07, 0xbb, 0xd9, 0xf4, 0x4c, - 0x84, 0x6a, 0x06, 0x1c, 0xb9, 0x81, 0x06, 0x1c, 0x5f, 0x83, 0x89, 0x72, 0xbb, 0xa9, 0x3d, 0x2b, - 0x1b, 0x29, 0x9f, 0x77, 0x25, 0x44, 0xe2, 0x6b, 0x21, 0x54, 0x2f, 0x37, 0xda, 0xcd, 0xe4, 0x63, - 0x72, 0xc4, 0x52, 0xb3, 0xfd, 0x18, 0x7d, 0x1c, 0xdb, 0x8f, 0x1b, 0x30, 0xb1, 0xe5, 0xd3, 0xcd, - 0x5e, 0xa7, 0x43, 0x5b, 0x38, 0xad, 0xf2, 0xfc, 0x56, 0xd6, 0xf3, 0xa9, 0x15, 0x20, 0x54, 0xfd, - 0x80, 0x10, 0x55, 0x1d, 0xe0, 0xf1, 0x01, 0x03, 0x7c, 0x1d, 0xf2, 0x35, 0x4a, 0x3d, 0xec, 0xd3, - 0xc9, 0x48, 0xf8, 0xee, 0x52, 0xea, 0x59, 0xac, 0x63, 0x35, 0x9b, 0x10, 0x81, 0xa8, 0x19, 0x92, - 0x4c, 0x0d, 0x69, 0x48, 0x42, 0x5e, 0x84, 0xa9, 0x6e, 0x6f, 0xa7, 0xe5, 0x34, 0x90, 0xaf, 0xb0, - 0x40, 0x31, 0x27, 0x39, 0x8c, 0xb1, 0xf5, 0xc9, 0x97, 0x60, 0x1a, 0x6f, 0xa3, 0xe1, 0x94, 0x9b, - 0xd1, 0xde, 0x5f, 0xb5, 0x32, 0x2e, 0x93, 0x36, 0x18, 0xc8, 0x4a, 0x31, 0x94, 0xd2, 0x19, 0x91, - 0xdb, 0x30, 0xbe, 0xe7, 0x04, 0xd6, 0x7e, 0x6f, 0x67, 0x71, 0x56, 0xb3, 0x32, 0xba, 0xe5, 0x04, - 0x6b, 0xbd, 0x1d, 0x3e, 0xe4, 0x21, 0x6b, 0xdc, 0xf1, 0xf6, 0x9c, 0x60, 0xbf, 0xa7, 0x2a, 0xcf, - 0xc7, 0xf6, 0x10, 0x77, 0xa9, 0x0e, 0x33, 0xfa, 0xac, 0x78, 0x02, 0x4f, 0xba, 0xa1, 0x81, 0x4d, - 0xbe, 0x30, 0x71, 0x7b, 0x24, 0x0f, 0x85, 0x49, 0x6e, 0x5a, 0x63, 0x42, 0x2d, 0xec, 0x1f, 0x93, - 0xdc, 0xe9, 0xed, 0x50, 0xaf, 0x43, 0x03, 0xea, 0x8b, 0xab, 0x9f, 0x6f, 0x8e, 0x94, 0xba, 0x5d, - 0xdf, 0xf8, 0x4f, 0xb3, 0x30, 0x5e, 0xda, 0xae, 0x57, 0x3b, 0xbb, 0x2e, 0x3e, 0xcc, 0x86, 0xef, - 0x71, 0xea, 0xc3, 0x6c, 0xf8, 0x1e, 0xa7, 0xbe, 0xc2, 0x5d, 0x4d, 0xb9, 0xbc, 0xa3, 0xed, 0xb6, - 0x72, 0x79, 0xd7, 0xd4, 0x0e, 0xd1, 0xd3, 0x64, 0x6e, 0x88, 0xa7, 0xc9, 0x50, 0x7b, 0x3c, 0x72, - 0xb2, 0xf6, 0xf8, 0x6d, 0x98, 0xac, 0x76, 0x02, 0xba, 0xe7, 0x45, 0xab, 0x26, 0x54, 0x24, 0x84, - 0x60, 0xf5, 0x42, 0xa7, 0x60, 0xb3, 0x29, 0xc9, 0x35, 0xd6, 0xa1, 0xa6, 0x1a, 0xa7, 0x24, 0x57, - 0x6c, 0xc7, 0xb4, 0x40, 0x12, 0xd1, 0xa8, 0xc4, 0xe6, 0x9b, 0x34, 0xff, 0xe0, 0x22, 0xd4, 0x4c, - 0xf4, 0x64, 0xc3, 0x3a, 0x76, 0x65, 0x2e, 0xdd, 0xfc, 0xc3, 0xf8, 0x1b, 0x19, 0x58, 0x48, 0x9b, - 0x46, 0xe4, 0x3d, 0x98, 0x72, 0xbd, 0x3d, 0xbb, 0xe3, 0x7c, 0x2f, 0x6f, 0x91, 0xa2, 0xaa, 0x54, - 0xe1, 0xaa, 0x82, 0x46, 0x85, 0xb3, 0x0e, 0x51, 0x5a, 0xae, 0x6b, 0x56, 0x52, 0x3b, 0x44, 0x01, - 0x1b, 0x3f, 0x9a, 0x85, 0xc9, 0x52, 0xb7, 0xfb, 0x94, 0x9b, 0x06, 0x7e, 0x4e, 0x3b, 0x40, 0xe4, - 0xbd, 0x3c, 0x6c, 0xd7, 0x50, 0x56, 0x81, 0xbf, 0x96, 0x85, 0xd9, 0x18, 0x85, 0xfa, 0xf5, 0x99, - 0x21, 0x0d, 0x02, 0xb3, 0x43, 0x1a, 0x04, 0xe6, 0x86, 0x33, 0x08, 0x1c, 0x79, 0x9c, 0x43, 0xe1, - 0x55, 0xc8, 0x95, 0xba, 0xdd, 0xb8, 0x61, 0x41, 0xb7, 0x7b, 0xff, 0x3a, 0xd7, 0xad, 0xd8, 0xdd, - 0xae, 0xc9, 0x30, 0xb4, 0x9d, 0x7a, 0x6c, 0xc8, 0x9d, 0xda, 0x78, 0x03, 0x26, 0x90, 0x17, 0x9a, - 0xe1, 0x5d, 0x00, 0xdc, 0x62, 0x84, 0x05, 0x9e, 0x56, 0x97, 0xd8, 0x7c, 0xfe, 0xbf, 0x0c, 0x8c, - 0xe2, 0xef, 0xa7, 0x74, 0x8e, 0x2d, 0x6b, 0x73, 0xac, 0xa0, 0xcc, 0xb1, 0x61, 0x66, 0xd7, 0x3f, - 0xc8, 0x01, 0x94, 0xef, 0x99, 0x75, 0xae, 0x82, 0x23, 0x37, 0x61, 0xd6, 0x6e, 0xb5, 0xdc, 0x87, - 0xb4, 0x69, 0xb9, 0x9e, 0xb3, 0xe7, 0x74, 0x78, 0xcf, 0xc9, 0xd7, 0x6e, 0xbd, 0x48, 0x7d, 0x03, - 0x13, 0x45, 0xf7, 0x78, 0x89, 0xca, 0xa7, 0x4d, 0x83, 0x7d, 0xb7, 0x29, 0x95, 0x09, 0x1a, 0x1f, - 0x51, 0x94, 0xc2, 0xe7, 0x2e, 0x2f, 0x51, 0xf9, 0xec, 0xa3, 0x72, 0x44, 0x4a, 0xc8, 0x1a, 0x1f, - 0x51, 0x94, 0xc2, 0x87, 0x6b, 0x54, 0x7c, 0xb2, 0x0e, 0x73, 0x08, 0xb1, 0x1a, 0x1e, 0x6d, 0xd2, - 0x4e, 0xe0, 0xd8, 0x2d, 0x5f, 0xa8, 0x9f, 0x50, 0x51, 0x99, 0x28, 0x54, 0xaf, 0xdf, 0x58, 0x58, - 0x8e, 0xca, 0xc8, 0x15, 0x18, 0x6f, 0xdb, 0x8f, 0x2c, 0x7b, 0x8f, 0xdb, 0x7d, 0x4c, 0x73, 0x75, - 0x85, 0x00, 0xa9, 0xc7, 0x48, 0xdb, 0x7e, 0x54, 0xda, 0xa3, 0xac, 0x15, 0xf4, 0x51, 0xd7, 0xf5, - 0x95, 0x56, 0x8c, 0x45, 0xad, 0x88, 0x15, 0xa9, 0xad, 0x10, 0x45, 0xa2, 0x15, 0xc6, 0xaf, 0x66, - 0xe0, 0xd9, 0x2a, 0x7e, 0x45, 0x70, 0x58, 0xa6, 0x9d, 0x80, 0x7a, 0x35, 0xea, 0xb5, 0x1d, 0x7c, - 0x05, 0xaf, 0xd3, 0x80, 0xbc, 0x04, 0xb9, 0x92, 0xb9, 0x21, 0xe6, 0x2f, 0xdf, 0xef, 0x35, 0x9b, - 0x04, 0x56, 0x1a, 0x6a, 0xb4, 0xb2, 0x27, 0xa8, 0xaa, 0x4b, 0x30, 0x55, 0xf2, 0x7d, 0x67, 0xaf, - 0xd3, 0xe6, 0xfe, 0x14, 0x39, 0xcd, 0xea, 0x41, 0xc0, 0x13, 0x6f, 0x2c, 0x2a, 0x89, 0xf1, 0x9f, - 0x65, 0x60, 0xae, 0xd4, 0xed, 0xea, 0x9f, 0xac, 0x5b, 0xdc, 0x64, 0x86, 0xb7, 0xb8, 0x71, 0x60, - 0x46, 0x6b, 0x2e, 0x9f, 0x52, 0x91, 0xe0, 0x3b, 0xa0, 0x67, 0xf8, 0x67, 0x77, 0x43, 0x90, 0xe5, - 0xeb, 0xcf, 0xc5, 0x31, 0xc6, 0xc6, 0x7f, 0x30, 0x8e, 0x7b, 0x88, 0xd8, 0x6d, 0x85, 0x4d, 0x68, - 0x26, 0xc5, 0x26, 0xf4, 0x2d, 0x50, 0x24, 0x1c, 0xf5, 0x88, 0x53, 0x64, 0x45, 0x55, 0x17, 0x14, - 0x21, 0x93, 0x83, 0xb8, 0x75, 0x68, 0x0e, 0x5b, 0xf3, 0x52, 0x7c, 0x01, 0x3f, 0x11, 0xc3, 0xd0, - 0x35, 0x20, 0xd5, 0x0e, 0x3e, 0x61, 0xd3, 0xfa, 0x81, 0xd3, 0xbd, 0x4f, 0x3d, 0x67, 0xf7, 0x50, - 0x2c, 0x00, 0xec, 0x7c, 0x47, 0x94, 0x5a, 0xfe, 0x81, 0xd3, 0xb5, 0x1e, 0x60, 0xb9, 0x99, 0x42, - 0x43, 0xde, 0x87, 0x71, 0x93, 0x3e, 0xf4, 0x9c, 0x40, 0xda, 0x3c, 0xcd, 0x84, 0xaa, 0x4d, 0x84, - 0xf2, 0xb5, 0xe0, 0xf1, 0x1f, 0xea, 0xae, 0x28, 0xca, 0xc9, 0x32, 0x17, 0x52, 0xb8, 0x6d, 0xd3, - 0x74, 0xd4, 0xda, 0xd2, 0x76, 0xbd, 0x9f, 0x8c, 0x42, 0x2e, 0xc3, 0x28, 0x4a, 0x3a, 0xe2, 0x2e, - 0x80, 0xbe, 0x42, 0x28, 0x3b, 0xab, 0x62, 0x18, 0x62, 0x90, 0x17, 0x00, 0xc2, 0x37, 0x62, 0x7f, - 0x31, 0x8f, 0x52, 0xba, 0x02, 0x89, 0x8b, 0x69, 0x13, 0xa7, 0x12, 0xd3, 0xd6, 0xa1, 0x60, 0x72, - 0xb7, 0xc3, 0x66, 0xa9, 0x8b, 0x0f, 0x91, 0xfe, 0x22, 0xe0, 0x4a, 0xbe, 0x70, 0x7c, 0x54, 0x7c, - 0x4e, 0xb8, 0x24, 0x36, 0x2d, 0xbb, 0xcb, 0xdf, 0x2f, 0xb5, 0x6d, 0x24, 0x4e, 0x49, 0xde, 0x82, - 0x11, 0xb6, 0xf5, 0x0a, 0x3b, 0x52, 0xf9, 0xa0, 0x13, 0xed, 0xc6, 0x7c, 0x71, 0x36, 0x5c, 0x6d, - 0x4f, 0x40, 0x12, 0x62, 0xc1, 0x8c, 0x3e, 0xdd, 0x85, 0x49, 0xd1, 0x62, 0xd4, 0x9f, 0x7a, 0xb9, - 0x78, 0xe5, 0x11, 0x30, 0xab, 0x81, 0x40, 0x75, 0x05, 0xc4, 0x16, 0xe9, 0x2a, 0xe4, 0x37, 0xcb, - 0xb5, 0x9a, 0xeb, 0x05, 0xfc, 0xaa, 0x13, 0x9d, 0x2c, 0x0c, 0x66, 0xda, 0x9d, 0x3d, 0xca, 0xcf, - 0xe2, 0xa0, 0xd1, 0xb5, 0xba, 0x0c, 0x4d, 0x3d, 0x8b, 0x25, 0xe9, 0xc7, 0x67, 0x43, 0xfa, 0x6b, - 0x59, 0x78, 0x29, 0x94, 0x8a, 0xee, 0x79, 0xf5, 0xd2, 0xdd, 0xf5, 0x6a, 0xb3, 0x26, 0xd4, 0x24, - 0x35, 0xcf, 0x7d, 0xe0, 0x34, 0xa9, 0x77, 0xff, 0xda, 0x09, 0x67, 0xfa, 0x3a, 0x5f, 0xe6, 0xfc, - 0x35, 0x2c, 0xab, 0x59, 0xdb, 0x29, 0xc2, 0xa7, 0xd8, 0x9e, 0xba, 0xdd, 0xc4, 0xe3, 0xd8, 0xda, - 0x33, 0x66, 0xc4, 0x80, 0xfc, 0x50, 0x06, 0xce, 0xa6, 0x7f, 0x88, 0x50, 0x9d, 0x15, 0xe5, 0x15, - 0xbd, 0xcf, 0xd7, 0xae, 0xbc, 0x7a, 0x7c, 0x54, 0x7c, 0xc9, 0xb7, 0xdb, 0x2d, 0xcb, 0x69, 0xf2, - 0xda, 0x9c, 0x06, 0xb5, 0xba, 0x02, 0x41, 0xab, 0xb7, 0x4f, 0x4d, 0x9f, 0x07, 0x79, 0xb4, 0x2f, - 0x66, 0x56, 0x00, 0xf2, 0xf2, 0xc1, 0xc1, 0xf8, 0xcd, 0x0c, 0x28, 0x4b, 0x30, 0x6f, 0xd2, 0xa6, - 0xe3, 0xd1, 0x46, 0x20, 0x8e, 0x77, 0xe1, 0x2b, 0xc8, 0x61, 0x31, 0xe3, 0x4a, 0x84, 0x91, 0xf7, - 0x60, 0x5c, 0x1c, 0x43, 0x62, 0xdb, 0x95, 0x4b, 0x57, 0x3c, 0x65, 0x70, 0xa7, 0xd2, 0xc4, 0x11, - 0x26, 0x89, 0xd8, 0xae, 0x7f, 0x7b, 0x7b, 0xb3, 0xdc, 0xb2, 0x9d, 0xb6, 0x2f, 0xce, 0x12, 0xec, - 0xd6, 0x0f, 0x1f, 0x06, 0x56, 0x03, 0xa1, 0xea, 0xae, 0x1f, 0xa2, 0x1a, 0xb7, 0xe4, 0x4b, 0xca, - 0x09, 0x16, 0xc2, 0x45, 0x18, 0xbd, 0x1f, 0xe9, 0xe9, 0x56, 0x26, 0x8e, 0x8f, 0x8a, 0x7c, 0xba, - 0x98, 0x1c, 0x6e, 0x50, 0x98, 0x08, 0xa7, 0x2e, 0xe3, 0xc5, 0x7e, 0x20, 0xaf, 0x69, 0xce, 0x8b, - 0x4d, 0x62, 0x13, 0xa1, 0x4c, 0xd4, 0x5b, 0xed, 0x34, 0x11, 0x21, 0x8b, 0x08, 0xd8, 0x3d, 0xb4, - 0xd3, 0xc4, 0x99, 0xae, 0xb6, 0x4e, 0xa0, 0x29, 0x02, 0xd5, 0x8f, 0x67, 0x60, 0x46, 0x9f, 0xb6, - 0xe4, 0x0a, 0x8c, 0x09, 0x77, 0xc0, 0x0c, 0xaa, 0x3d, 0x19, 0xb7, 0x31, 0xee, 0x08, 0xa8, 0xb9, - 0xff, 0x09, 0x2c, 0x26, 0x37, 0x0a, 0x0e, 0x42, 0x68, 0x42, 0xb9, 0xb1, 0xc1, 0x41, 0xa6, 0x2c, - 0x23, 0x06, 0xbb, 0xca, 0xfa, 0xbd, 0x56, 0xa0, 0xbe, 0x5b, 0x7a, 0x08, 0x31, 0x45, 0x89, 0x51, - 0x86, 0x31, 0xbe, 0xb5, 0xc6, 0x0c, 0x20, 0x33, 0xa7, 0x30, 0x80, 0x34, 0x8e, 0x32, 0x00, 0xf5, - 0xfa, 0xda, 0x1d, 0x7a, 0x58, 0xb3, 0x1d, 0x3c, 0xbf, 0xf9, 0x31, 0x76, 0x47, 0xac, 0xe1, 0x29, - 0xf1, 0xd0, 0xce, 0x8f, 0xbc, 0x03, 0x7a, 0xa8, 0x3d, 0xb4, 0x4b, 0x54, 0x3c, 0x2b, 0x3d, 0xe7, - 0x81, 0x1d, 0x50, 0x46, 0x98, 0x45, 0x42, 0x7e, 0x56, 0x72, 0x68, 0x8c, 0x52, 0x41, 0x26, 0x5f, - 0x85, 0x99, 0xe8, 0x57, 0x68, 0x2e, 0x30, 0x13, 0xee, 0x13, 0x7a, 0xe1, 0xca, 0x0b, 0xc7, 0x47, - 0xc5, 0x25, 0x85, 0x6b, 0xdc, 0x90, 0x20, 0xc6, 0xcc, 0xf8, 0xe5, 0x0c, 0x1a, 0xc9, 0xc8, 0x06, - 0x5e, 0x84, 0x91, 0xd0, 0xac, 0x7b, 0x4a, 0x6c, 0xc2, 0xfa, 0x93, 0x28, 0x96, 0x33, 0x71, 0x2b, - 0x6a, 0x09, 0x1e, 0x5d, 0x7a, 0x0b, 0x58, 0x29, 0xb9, 0x05, 0xe3, 0x43, 0x7d, 0x33, 0x4e, 0xb1, - 0x94, 0x6f, 0x95, 0xd4, 0x38, 0x0a, 0xb7, 0xb7, 0x37, 0x3f, 0xb9, 0xa3, 0xf0, 0x53, 0x59, 0x98, - 0x65, 0xfd, 0x5a, 0xea, 0x05, 0xfb, 0xae, 0xe7, 0x04, 0x87, 0x4f, 0xad, 0xde, 0xf8, 0x1d, 0xed, - 0x4a, 0xb6, 0x24, 0x0f, 0x33, 0xb5, 0x6d, 0x43, 0xa9, 0x8f, 0xff, 0xe9, 0x28, 0xcc, 0xa7, 0x50, - 0x91, 0xd7, 0xb5, 0xa7, 0x9d, 0x45, 0xe9, 0xee, 0xff, 0xdd, 0xa3, 0xe2, 0x94, 0x44, 0xdf, 0x8c, - 0xdc, 0xff, 0x97, 0x75, 0x8b, 0x33, 0xde, 0x53, 0xf8, 0xd2, 0xa3, 0x5a, 0x9c, 0xe9, 0x76, 0x66, - 0x97, 0x61, 0xd4, 0x74, 0x5b, 0x54, 0x5a, 0x59, 0xa2, 0xc0, 0xe5, 0x31, 0x80, 0x66, 0x55, 0xc2, - 0x00, 0x64, 0x0d, 0xc6, 0xd9, 0x1f, 0x77, 0xed, 0xae, 0x78, 0x2f, 0x25, 0xa1, 0x52, 0x00, 0xa1, - 0x5d, 0xa7, 0xb3, 0xa7, 0xea, 0x05, 0x5a, 0xd4, 0x6a, 0xdb, 0x5d, 0x4d, 0x32, 0xe4, 0x88, 0x9a, - 0x7e, 0x21, 0xdf, 0x5f, 0xbf, 0x90, 0x39, 0x51, 0xbf, 0xb0, 0x0b, 0x50, 0x77, 0xf6, 0x3a, 0x4e, - 0x67, 0xaf, 0xd4, 0xda, 0x13, 0x41, 0x13, 0x2e, 0xf7, 0x1f, 0x85, 0x2b, 0x11, 0x32, 0x4e, 0xdc, - 0x67, 0xd1, 0xa8, 0x81, 0xc3, 0x2c, 0xbb, 0xb5, 0xa7, 0x39, 0x77, 0x29, 0x9c, 0xc9, 0x06, 0x40, - 0xa9, 0x11, 0x38, 0x0f, 0xd8, 0x14, 0xf6, 0x85, 0x18, 0x27, 0x3f, 0xb9, 0x5c, 0xba, 0x43, 0x0f, - 0xf1, 0xea, 0x21, 0x9f, 0x87, 0x6d, 0x44, 0x65, 0x2b, 0x41, 0xf3, 0xdc, 0x89, 0x38, 0x90, 0x2e, - 0x9c, 0x29, 0x35, 0x9b, 0x0e, 0x6b, 0x83, 0xdd, 0xda, 0xe4, 0xe1, 0x2e, 0x90, 0xf5, 0x54, 0x3a, - 0xeb, 0xcb, 0xf2, 0x25, 0xd4, 0x0e, 0xa9, 0x2c, 0x19, 0x25, 0x23, 0x56, 0x4d, 0x3a, 0x63, 0xa3, - 0x0e, 0x33, 0x7a, 0xe3, 0xf5, 0x60, 0x0f, 0x53, 0x90, 0x37, 0xeb, 0x25, 0xab, 0xbe, 0x56, 0xba, - 0x56, 0xc8, 0x90, 0x02, 0x4c, 0x89, 0x5f, 0xcb, 0xd6, 0xf2, 0x9b, 0x37, 0x0a, 0x59, 0x0d, 0xf2, - 0xe6, 0xb5, 0xe5, 0x42, 0x6e, 0x29, 0xbb, 0x98, 0x89, 0xf9, 0x59, 0x8e, 0x17, 0xf2, 0x5c, 0x25, - 0x6c, 0xfc, 0x7a, 0x06, 0xf2, 0xf2, 0xdb, 0xc9, 0x0d, 0xc8, 0xd5, 0xeb, 0x6b, 0x31, 0xcf, 0xc8, - 0xe8, 0x94, 0xe1, 0xfb, 0xa9, 0xef, 0xab, 0xe6, 0xef, 0x8c, 0x80, 0xd1, 0x6d, 0xae, 0xd7, 0x85, - 0x0c, 0x22, 0xe9, 0xa2, 0xcd, 0x9b, 0xd3, 0xa5, 0xb8, 0x8b, 0xdd, 0x80, 0xdc, 0xed, 0xed, 0x4d, - 0x71, 0xc9, 0x92, 0x74, 0xd1, 0x7e, 0xca, 0xe9, 0x3e, 0x7c, 0xa8, 0xee, 0xf2, 0x8c, 0xc0, 0x30, - 0x61, 0x52, 0x99, 0xc8, 0xfc, 0xd0, 0x6d, 0xbb, 0x61, 0x84, 0x03, 0x71, 0xe8, 0x32, 0x88, 0x29, - 0x4a, 0x98, 0x28, 0xb2, 0xee, 0x36, 0xec, 0x96, 0x38, 0xbd, 0x51, 0x14, 0x69, 0x31, 0x80, 0xc9, - 0xe1, 0xc6, 0xef, 0x64, 0xa0, 0x80, 0x02, 0x1b, 0x9a, 0xaf, 0xbb, 0x07, 0xb4, 0x73, 0xff, 0x1a, - 0x79, 0x43, 0x2e, 0xb9, 0x4c, 0xa8, 0xe8, 0x1a, 0xc5, 0x25, 0x17, 0x7b, 0x0b, 0x14, 0xcb, 0x4e, - 0x09, 0x22, 0x91, 0x1d, 0xde, 0xf9, 0xfc, 0x84, 0x20, 0x12, 0x45, 0x18, 0xc5, 0xcf, 0x11, 0x9b, - 0x23, 0x7e, 0x79, 0xc0, 0x00, 0x26, 0x87, 0x2b, 0x7b, 0xd3, 0xcf, 0x64, 0x13, 0x6d, 0x58, 0xfe, - 0x44, 0x39, 0x70, 0xeb, 0x8d, 0x1b, 0x6a, 0xbf, 0xfe, 0x00, 0x16, 0xe2, 0x5d, 0x82, 0x4a, 0xc8, - 0x12, 0xcc, 0xea, 0x70, 0xa9, 0x8f, 0x3c, 0x97, 0x5a, 0xd7, 0xfd, 0x65, 0x33, 0x8e, 0x6f, 0xfc, - 0x1f, 0x19, 0x98, 0xc0, 0x3f, 0xcd, 0x5e, 0x0b, 0xcd, 0x08, 0x4b, 0xdb, 0x75, 0xa1, 0x1a, 0x51, - 0x85, 0x39, 0xfb, 0xa1, 0x6f, 0x09, 0x3d, 0x8a, 0xb6, 0xc7, 0x84, 0xc8, 0x82, 0x94, 0xbf, 0x6f, - 0x48, 0xa5, 0x5c, 0x48, 0xca, 0x1f, 0x42, 0xfc, 0x18, 0xa9, 0x40, 0x46, 0xe3, 0xe3, 0xed, 0x3a, - 0x9b, 0x7e, 0xaa, 0x5d, 0x0f, 0xd2, 0xb9, 0x2d, 0xdd, 0xf8, 0x98, 0xa3, 0xa1, 0x59, 0xcf, 0x76, - 0xbd, 0x64, 0x6e, 0x68, 0x66, 0x3d, 0xec, 0x1b, 0x35, 0xbd, 0x94, 0x40, 0x32, 0x7e, 0x71, 0x32, - 0xde, 0x81, 0xe2, 0xc0, 0x3b, 0xe5, 0xda, 0x78, 0x1b, 0x46, 0x4b, 0xad, 0x96, 0xfb, 0x50, 0xec, - 0x12, 0xf2, 0xe6, 0x1a, 0xf6, 0x1f, 0x3f, 0xcf, 0x50, 0xad, 0xa7, 0x39, 0xa5, 0x32, 0x00, 0x29, - 0xc3, 0x44, 0x69, 0xbb, 0x5e, 0xad, 0x56, 0x36, 0x37, 0xb9, 0x03, 0x5e, 0x6e, 0xe5, 0x15, 0xd9, - 0x3f, 0x8e, 0xd3, 0xb4, 0xe2, 0xf6, 0x0a, 0x91, 0xfc, 0x1e, 0xd1, 0x91, 0x77, 0x01, 0x6e, 0xbb, - 0x4e, 0x87, 0xab, 0x31, 0x45, 0xe3, 0xd9, 0x0d, 0x7c, 0xf2, 0x43, 0xd7, 0xe9, 0x08, 0xbd, 0x27, - 0xfb, 0xf6, 0x08, 0xc9, 0x54, 0xfe, 0x66, 0x3d, 0xbd, 0xe2, 0x72, 0xd3, 0xc0, 0xd1, 0xa8, 0xa7, - 0x77, 0xdc, 0x84, 0xbe, 0x4d, 0xa2, 0x91, 0x36, 0xcc, 0xd6, 0x7b, 0x7b, 0x7b, 0x94, 0xed, 0xec, - 0x42, 0x9f, 0x34, 0x26, 0xae, 0xd2, 0x61, 0xd8, 0x23, 0x7e, 0x1f, 0x61, 0x97, 0x21, 0x7f, 0xe5, - 0x75, 0x36, 0x91, 0xbf, 0x73, 0x54, 0x14, 0x76, 0x10, 0x4c, 0x54, 0xf3, 0x25, 0x7d, 0x52, 0x9b, - 0x14, 0xe7, 0x4d, 0xee, 0xc1, 0x18, 0x7f, 0x33, 0x12, 0x0e, 0x65, 0x2f, 0x0e, 0x58, 0x34, 0x1c, - 0xb1, 0xdf, 0xab, 0x24, 0x2f, 0x25, 0xdb, 0x90, 0x2f, 0x3b, 0x5e, 0xa3, 0x45, 0xcb, 0x55, 0x71, - 0xf6, 0xbf, 0x34, 0x80, 0xa5, 0x44, 0xe5, 0xfd, 0xd2, 0xc0, 0x5f, 0x0d, 0x47, 0x95, 0x05, 0x24, - 0x06, 0xf9, 0x1b, 0x19, 0x78, 0x36, 0xfc, 0xfa, 0xd2, 0x1e, 0xed, 0x04, 0x77, 0xed, 0xa0, 0xb1, - 0x4f, 0x3d, 0xd1, 0x4b, 0x13, 0x83, 0x7a, 0xe9, 0xf3, 0x89, 0x5e, 0xba, 0x14, 0xf5, 0x92, 0xcd, - 0x98, 0x59, 0x6d, 0xce, 0x2d, 0xd9, 0x67, 0x83, 0x6a, 0x25, 0x16, 0x40, 0xf4, 0x1a, 0x2a, 0x1c, - 0x92, 0x5f, 0x19, 0xd0, 0xe0, 0x08, 0x59, 0x38, 0x12, 0x85, 0xbf, 0x35, 0x4b, 0xd8, 0x10, 0x4a, - 0xee, 0x48, 0xef, 0x4d, 0x2e, 0x95, 0x5c, 0x18, 0xc0, 0x9b, 0x7b, 0x74, 0xce, 0x0f, 0xf0, 0xd3, - 0xe6, 0xa3, 0xbd, 0x6e, 0xef, 0x08, 0x41, 0xe4, 0x84, 0xd1, 0x5e, 0xb7, 0xa3, 0xd1, 0x6e, 0xd9, - 0xf1, 0xd1, 0x5e, 0xb7, 0x77, 0x48, 0x99, 0xbb, 0x9c, 0x73, 0xff, 0xe4, 0x17, 0x06, 0x71, 0x2b, - 0xd7, 0xf8, 0xc9, 0x9c, 0xe2, 0x7a, 0xfe, 0x65, 0x98, 0xa8, 0x77, 0xed, 0x06, 0x6d, 0x39, 0xbb, - 0x81, 0x78, 0x6a, 0x7f, 0x79, 0x00, 0xab, 0x10, 0x57, 0x3c, 0xad, 0xca, 0x9f, 0xea, 0x35, 0x29, - 0xc4, 0x61, 0x5f, 0xb8, 0x59, 0xbb, 0x2b, 0x5e, 0xdb, 0x07, 0x7d, 0xe1, 0x66, 0xed, 0xae, 0x90, - 0x39, 0xba, 0x6d, 0x4d, 0xe6, 0xa8, 0xdd, 0x25, 0x5d, 0x98, 0xd9, 0xa4, 0x9e, 0x67, 0xef, 0xba, - 0x5e, 0x9b, 0xeb, 0x2f, 0xb9, 0xcf, 0xdb, 0xe5, 0x41, 0xfc, 0x34, 0x02, 0xae, 0xb6, 0x0b, 0x24, - 0xcc, 0x8a, 0x2b, 0x3d, 0x63, 0xfc, 0x59, 0x9f, 0xac, 0x38, 0xc1, 0x4e, 0xaf, 0x71, 0x40, 0x83, - 0xc5, 0xb9, 0x13, 0xfb, 0x24, 0xc4, 0xe5, 0x7d, 0xb2, 0x23, 0x7f, 0xaa, 0x7d, 0x12, 0xe2, 0x18, - 0xff, 0x38, 0x07, 0xe7, 0xfa, 0x74, 0x01, 0xd9, 0x90, 0x5b, 0x6e, 0x46, 0xd3, 0x62, 0xf7, 0x41, - 0xbf, 0x72, 0xe2, 0x2e, 0xbc, 0x0e, 0x85, 0xd5, 0x3b, 0x28, 0xab, 0xf3, 0x87, 0x9c, 0x72, 0x49, - 0x1e, 0x56, 0xa8, 0x69, 0xa5, 0x07, 0x68, 0x23, 0x2c, 0x1f, 0x80, 0x1a, 0x9a, 0x33, 0x7c, 0x82, - 0x72, 0xe9, 0x07, 0xb3, 0x30, 0x82, 0x07, 0x67, 0x2c, 0x04, 0x58, 0xe6, 0x54, 0x21, 0xc0, 0xbe, - 0x00, 0x53, 0xab, 0x77, 0xf8, 0x4d, 0x7a, 0xcd, 0xf6, 0xf7, 0xc5, 0xb6, 0x8e, 0x86, 0x1c, 0xf4, - 0xc0, 0x12, 0x17, 0xef, 0x7d, 0x5b, 0x93, 0x59, 0x35, 0x0a, 0xb2, 0x05, 0xf3, 0xfc, 0xdb, 0x9c, - 0x5d, 0xa7, 0xc1, 0x23, 0x09, 0x39, 0x76, 0x4b, 0xec, 0xf1, 0x2f, 0x1d, 0x1f, 0x15, 0x8b, 0xf4, - 0x00, 0xad, 0x9f, 0x45, 0xb9, 0xe5, 0x23, 0x82, 0x6a, 0x06, 0x9d, 0x42, 0xaf, 0x86, 0x37, 0x31, - 0x27, 0xb0, 0x42, 0x56, 0x1b, 0xab, 0x9b, 0xe1, 0x72, 0x24, 0xe3, 0x4f, 0x47, 0x61, 0xa9, 0xff, - 0xf6, 0x4c, 0xbe, 0xa8, 0x0f, 0xe0, 0xc5, 0x13, 0x37, 0xf4, 0x93, 0xc7, 0xf0, 0x4b, 0xb0, 0xb0, - 0xda, 0x09, 0xa8, 0xd7, 0xf5, 0x1c, 0x19, 0xd0, 0x66, 0xcd, 0xf5, 0xa5, 0xb5, 0x39, 0x9a, 0x7d, - 0xd3, 0xb0, 0x5c, 0xe8, 0x56, 0xd1, 0xf6, 0x5d, 0x61, 0x95, 0xca, 0x81, 0xac, 0xc2, 0x8c, 0x02, - 0x6f, 0xf5, 0xf6, 0xd4, 0xd7, 0x29, 0x95, 0x67, 0xab, 0xa7, 0x9a, 0xe2, 0xc6, 0x88, 0xd0, 0xa2, - 0x9d, 0x5d, 0x19, 0x1b, 0xb7, 0xb7, 0xef, 0xd4, 0xc5, 0x70, 0x72, 0x8b, 0x76, 0x84, 0x5a, 0x1f, - 0x3e, 0x3c, 0xd0, 0xf6, 0xd7, 0x08, 0x79, 0xe9, 0x97, 0x73, 0x62, 0x46, 0xbd, 0x04, 0xb9, 0x7a, - 0x6f, 0x47, 0x7d, 0x73, 0xf3, 0xb5, 0x03, 0x8e, 0x95, 0x92, 0xcf, 0x01, 0x98, 0xb4, 0xeb, 0xfa, - 0x4e, 0xe0, 0x7a, 0x87, 0xaa, 0x4b, 0xa5, 0x17, 0x42, 0x75, 0xaf, 0x0f, 0x09, 0x25, 0x6b, 0x30, - 0x1b, 0xfd, 0xba, 0xf7, 0xb0, 0x23, 0x74, 0xc9, 0x13, 0x5c, 0xbb, 0x12, 0x91, 0x5b, 0x2e, 0x2b, - 0x53, 0x8f, 0xec, 0x18, 0x19, 0x59, 0x86, 0xfc, 0xb6, 0xeb, 0x1d, 0xec, 0xb2, 0x31, 0x1e, 0x89, - 0x84, 0x8a, 0x87, 0x02, 0xa6, 0x1e, 0x9e, 0x12, 0x8f, 0x2d, 0x97, 0xd5, 0xce, 0x03, 0xc7, 0x73, - 0xf1, 0x45, 0x4f, 0xb5, 0x69, 0xa1, 0x11, 0x58, 0x73, 0x66, 0x8f, 0xc0, 0xe4, 0x32, 0x8c, 0x96, - 0x1a, 0x81, 0xeb, 0x09, 0x83, 0x16, 0x3e, 0x53, 0x18, 0x40, 0x9b, 0x29, 0x0c, 0xc0, 0x3a, 0xd1, - 0xa4, 0xbb, 0xe2, 0x75, 0x07, 0x3b, 0xd1, 0xa3, 0xbb, 0x9a, 0xa7, 0x3e, 0xdd, 0x65, 0x42, 0x91, - 0x49, 0x77, 0x51, 0xf1, 0xa1, 0x05, 0xb8, 0xdb, 0x4d, 0xa8, 0xcc, 0x04, 0x9a, 0xf1, 0x7b, 0x13, - 0x7d, 0xa7, 0x3c, 0x3b, 0x85, 0x4e, 0x37, 0xe5, 0xd7, 0xed, 0x21, 0xa6, 0xfc, 0xeb, 0xa1, 0x2f, - 0x89, 0x1a, 0x9e, 0x02, 0x21, 0xea, 0x31, 0xc8, 0x71, 0x96, 0x7e, 0x25, 0x7f, 0x9a, 0x49, 0x24, - 0x3a, 0x29, 0x3b, 0x6c, 0x27, 0xe5, 0x86, 0xea, 0x24, 0xb2, 0x02, 0xd3, 0x61, 0x88, 0xc4, 0x9a, - 0x1d, 0x68, 0xdb, 0x5a, 0x18, 0xd7, 0xd2, 0xea, 0xda, 0x81, 0xba, 0xad, 0xe9, 0x24, 0xe4, 0x1d, - 0x98, 0x14, 0x0e, 0x55, 0xc8, 0x61, 0x34, 0xb2, 0x14, 0x92, 0xde, 0x57, 0x31, 0x7a, 0x15, 0x9d, - 0xad, 0xe6, 0x9a, 0xd3, 0xa5, 0x2d, 0xa7, 0x43, 0xeb, 0xf8, 0x58, 0x21, 0x66, 0x0c, 0x7f, 0xb4, - 0x15, 0x25, 0x16, 0x7f, 0xc7, 0xd0, 0xf4, 0x87, 0x1a, 0x51, 0x7c, 0xb2, 0x8e, 0x9f, 0x6a, 0xb2, - 0x72, 0x3b, 0x45, 0x6f, 0xdd, 0xdd, 0x73, 0xa4, 0x0d, 0xbd, 0xb4, 0x53, 0xf4, 0xac, 0x16, 0x83, - 0xc6, 0xec, 0x14, 0x39, 0x2a, 0xbb, 0xe1, 0xb0, 0x1f, 0xd5, 0x8a, 0x78, 0x49, 0xc4, 0x1b, 0x0e, - 0x12, 0xe9, 0x8e, 0x0b, 0x1c, 0x49, 0x56, 0xb3, 0xda, 0xb6, 0x9d, 0x96, 0x88, 0x42, 0x10, 0x55, - 0x43, 0x19, 0x34, 0x5e, 0x0d, 0xa2, 0x92, 0x06, 0x4c, 0x99, 0x74, 0xb7, 0xe6, 0xb9, 0x01, 0x6d, - 0x04, 0xb4, 0x29, 0xa4, 0x3a, 0x79, 0xb1, 0x59, 0x71, 0x5d, 0x2e, 0xb1, 0xa2, 0x6d, 0x7c, 0xe6, - 0x3b, 0x47, 0x45, 0x60, 0x20, 0xee, 0x15, 0x73, 0x7c, 0x54, 0x3c, 0xc7, 0xc6, 0xbf, 0x2b, 0x89, - 0xd5, 0xd3, 0x49, 0x65, 0x4a, 0xbe, 0xc9, 0xf6, 0xeb, 0xb0, 0x4b, 0xa2, 0xca, 0xa6, 0xfa, 0x54, - 0xf6, 0x66, 0x6a, 0x65, 0x45, 0xa5, 0xb7, 0x53, 0x2b, 0x4d, 0xad, 0x84, 0xbc, 0x0b, 0x93, 0xe5, - 0x6a, 0xd9, 0xed, 0xec, 0x3a, 0x7b, 0xf5, 0xb5, 0x12, 0x8a, 0x86, 0xc2, 0x23, 0xaa, 0xe1, 0x58, - 0x0d, 0x84, 0x5b, 0xfe, 0xbe, 0xad, 0x39, 0xc6, 0x46, 0xf8, 0xe4, 0x16, 0xcc, 0xc8, 0x9f, 0x26, - 0xdd, 0xdd, 0x32, 0xab, 0x28, 0x11, 0x4a, 0x37, 0xb4, 0x90, 0x03, 0xeb, 0x88, 0x9e, 0xa7, 0xde, - 0x14, 0x62, 0x64, 0x6c, 0x32, 0x56, 0x68, 0xb7, 0xe5, 0x1e, 0xb2, 0xcf, 0xdb, 0x74, 0xa8, 0x87, - 0x32, 0xa0, 0x98, 0x8c, 0xcd, 0xb0, 0xc4, 0x0a, 0x1c, 0xfd, 0xfd, 0x54, 0x27, 0x22, 0x1b, 0x30, - 0x27, 0xa6, 0xf8, 0x7d, 0xc7, 0x77, 0x76, 0x9c, 0x96, 0x13, 0x1c, 0xa2, 0xf4, 0x27, 0x04, 0x18, - 0xb9, 0x2e, 0x1e, 0x84, 0xa5, 0x0a, 0xb3, 0x24, 0xa9, 0xf1, 0xeb, 0x59, 0x78, 0x6e, 0xd0, 0x4d, - 0x88, 0xd4, 0xf5, 0xcd, 0xec, 0xd2, 0x10, 0xb7, 0xa7, 0x93, 0xb7, 0xb3, 0x55, 0x98, 0xb9, 0xa7, - 0x98, 0xf4, 0x85, 0x26, 0x96, 0xd8, 0x19, 0xaa, 0xb1, 0x9f, 0x3e, 0xdb, 0x63, 0x44, 0x4b, 0x0f, - 0xc4, 0x36, 0xf7, 0x51, 0x5d, 0x34, 0x6f, 0xc0, 0x44, 0xd9, 0xed, 0x04, 0xf4, 0x51, 0x10, 0x0b, - 0x48, 0xc0, 0x81, 0x71, 0xf7, 0x54, 0x89, 0x6a, 0xfc, 0x9b, 0x2c, 0x3c, 0x3f, 0xf0, 0x2a, 0x40, - 0x36, 0xf5, 0x5e, 0xbb, 0x3c, 0xcc, 0xfd, 0xe1, 0xe4, 0x6e, 0x5b, 0x4e, 0xd8, 0xdd, 0x9d, 0xe8, - 0x01, 0xb5, 0xf4, 0x3f, 0x64, 0x44, 0x27, 0x7d, 0x1a, 0xc6, 0xb1, 0xaa, 0xb0, 0x8b, 0xb8, 0x96, - 0x0c, 0x77, 0x61, 0x47, 0xd7, 0x92, 0x71, 0x34, 0x72, 0x1d, 0xf2, 0x65, 0xbb, 0xd5, 0x52, 0xc2, - 0x35, 0xa0, 0x34, 0xdf, 0x40, 0x58, 0xcc, 0x78, 0x54, 0x22, 0x32, 0xd9, 0x87, 0xff, 0xad, 0x9c, - 0x15, 0xb8, 0x59, 0x0a, 0xb2, 0xd8, 0x71, 0xa1, 0x20, 0x63, 0x90, 0xd7, 0x86, 0x1b, 0x3a, 0x84, - 0xf3, 0x20, 0xaf, 0x0c, 0xa0, 0x05, 0x79, 0x65, 0x00, 0xe3, 0x37, 0x72, 0xf0, 0xc2, 0xe0, 0xfb, - 0x2c, 0xd9, 0xd2, 0x87, 0xe0, 0xb5, 0xa1, 0x6e, 0xc1, 0x27, 0x8f, 0x81, 0x0c, 0x99, 0xcc, 0x3b, - 0xe4, 0x52, 0xd2, 0xfd, 0xe5, 0xbb, 0x47, 0x45, 0xc5, 0x22, 0xf9, 0xb6, 0xeb, 0x74, 0x94, 0x37, - 0x93, 0x6f, 0x68, 0x92, 0x21, 0x7f, 0xbd, 0xbf, 0x31, 0xdc, 0x97, 0x45, 0x74, 0x7c, 0x5f, 0x19, - 0x56, 0xa2, 0xfc, 0x3c, 0x14, 0xe2, 0xa4, 0xe4, 0x22, 0x8c, 0xe0, 0x07, 0x28, 0x3e, 0x3c, 0x31, - 0x0e, 0x58, 0xbe, 0x74, 0x57, 0xcc, 0x1d, 0x8c, 0x60, 0x81, 0xf6, 0x00, 0xba, 0x6e, 0x50, 0x44, - 0xb0, 0xe0, 0xe6, 0x04, 0x49, 0xfd, 0x60, 0x8c, 0xc8, 0xf8, 0xf3, 0x0c, 0x9c, 0xef, 0xab, 0x29, - 0x20, 0x35, 0x7d, 0xc0, 0x5e, 0x39, 0x49, 0xb5, 0x70, 0xe2, 0x58, 0x2d, 0xfd, 0x84, 0x9c, 0xfb, - 0xef, 0xc1, 0x54, 0xbd, 0xb7, 0x13, 0xbf, 0x9f, 0xf1, 0xf8, 0x32, 0x0a, 0x5c, 0x3d, 0xc1, 0x54, - 0x7c, 0xd6, 0x7e, 0x69, 0xf0, 0x20, 0x0c, 0x80, 0x14, 0xab, 0xc3, 0xd0, 0xc5, 0x3a, 0x19, 0xc1, - 0x43, 0x27, 0x32, 0x7e, 0x2d, 0x9b, 0x7e, 0xd1, 0xbd, 0x55, 0xae, 0x9d, 0xe6, 0xa2, 0x7b, 0xab, - 0x5c, 0x3b, 0xb9, 0xed, 0xff, 0x8d, 0x6c, 0x3b, 0x3e, 0xcc, 0x8a, 0x1d, 0x4f, 0x2a, 0x3a, 0xc5, - 0xc3, 0xac, 0xdc, 0x1d, 0x7d, 0xfd, 0x61, 0x56, 0x22, 0x93, 0x37, 0x61, 0x62, 0xdd, 0xe5, 0xc1, - 0x35, 0x64, 0x8b, 0xb9, 0x0f, 0xb2, 0x04, 0xaa, 0xdb, 0x63, 0x88, 0xc9, 0xee, 0x16, 0xfa, 0xc0, - 0x4b, 0xe3, 0x4a, 0xbc, 0x5b, 0xc4, 0xa6, 0x8b, 0xae, 0x0e, 0xd4, 0xc9, 0x8c, 0xff, 0x64, 0x14, - 0x8c, 0x93, 0x95, 0x19, 0xe4, 0x03, 0xbd, 0xef, 0xae, 0x0c, 0xad, 0x06, 0x19, 0x6a, 0xcb, 0x2d, - 0xf5, 0x9a, 0x0e, 0xed, 0x34, 0xf4, 0xc8, 0x18, 0x02, 0xa6, 0x6e, 0x81, 0x12, 0xef, 0xa3, 0x38, - 0xaa, 0x2e, 0xfd, 0x77, 0xb9, 0x68, 0xa9, 0xc5, 0x8e, 0xc6, 0xcc, 0x47, 0x38, 0x1a, 0xc9, 0x1d, - 0x28, 0xa8, 0x10, 0xe5, 0x85, 0x16, 0x25, 0x17, 0x8d, 0x51, 0xec, 0xa3, 0x12, 0x84, 0xfa, 0xf9, - 0x9a, 0x1b, 0xfe, 0x7c, 0x8d, 0xc4, 0x77, 0xac, 0x7f, 0x24, 0x29, 0xbe, 0xc7, 0x9d, 0xd1, 0x15, - 0x74, 0x19, 0x49, 0xc3, 0x17, 0x87, 0xd6, 0xa8, 0x1e, 0x49, 0x23, 0xe5, 0xe0, 0x52, 0xd1, 0x65, - 0x30, 0x10, 0xfc, 0xa9, 0xf8, 0xc2, 0x87, 0xc1, 0x40, 0x38, 0x7d, 0x5a, 0x30, 0x90, 0x90, 0x84, - 0x1d, 0x80, 0x66, 0xaf, 0xc3, 0xa3, 0x89, 0x8f, 0x47, 0x07, 0xa0, 0xd7, 0xeb, 0x58, 0xf1, 0x88, - 0xe2, 0x21, 0xa2, 0xf1, 0x8f, 0x46, 0xd2, 0x85, 0x83, 0x50, 0xdf, 0x75, 0x1a, 0xe1, 0x20, 0x24, - 0xfa, 0x78, 0x66, 0xea, 0x16, 0xcc, 0x4b, 0xfb, 0x3c, 0x69, 0xe8, 0xb5, 0x65, 0xae, 0x8b, 0x21, - 0x46, 0xbd, 0x51, 0x68, 0xd9, 0x27, 0x8d, 0xc5, 0xac, 0x9e, 0xa7, 0xe9, 0x8d, 0x52, 0xe8, 0x97, - 0x7e, 0x53, 0xaa, 0xc5, 0xd4, 0x41, 0xd8, 0xda, 0x0a, 0xe7, 0x72, 0x6c, 0x10, 0x7a, 0x3d, 0x6d, - 0x18, 0x75, 0x12, 0xbe, 0xf7, 0x4a, 0x95, 0x03, 0x32, 0x51, 0x64, 0x45, 0x45, 0x51, 0x11, 0xe3, - 0x12, 0x23, 0x22, 0x7b, 0x70, 0x3e, 0x12, 0xa5, 0x95, 0x9b, 0x02, 0x72, 0xe4, 0x0d, 0xbe, 0x7c, - 0x7c, 0x54, 0x7c, 0x45, 0x11, 0xc5, 0xd5, 0x0b, 0x47, 0x8c, 0x7b, 0x7f, 0x5e, 0x6c, 0xbf, 0x5d, - 0xf1, 0xec, 0x4e, 0x63, 0x5f, 0x99, 0xf3, 0xb8, 0xdf, 0xee, 0x20, 0x34, 0x11, 0xce, 0x20, 0x42, - 0x36, 0x7e, 0x22, 0x0b, 0x33, 0xfc, 0xac, 0xe6, 0xaf, 0x73, 0x4f, 0xed, 0xcb, 0xe7, 0xdb, 0xda, - 0xcb, 0xa7, 0x8c, 0xbc, 0xa7, 0x36, 0x6d, 0xa8, 0x77, 0xcf, 0x7d, 0x20, 0x49, 0x1a, 0x62, 0xc2, - 0x94, 0x0a, 0x1d, 0xfc, 0xe4, 0x79, 0x2d, 0x0a, 0xd2, 0x28, 0x44, 0x25, 0x7c, 0x77, 0xf6, 0x4d, - 0x8d, 0x87, 0xf1, 0xe3, 0x59, 0x98, 0x56, 0xec, 0x54, 0x9e, 0xda, 0x8e, 0xff, 0xbc, 0xd6, 0xf1, - 0x8b, 0xa1, 0x87, 0x60, 0xd8, 0xb2, 0xa1, 0xfa, 0xbd, 0x07, 0x73, 0x09, 0x92, 0xb8, 0xb9, 0x4f, - 0x66, 0x18, 0x73, 0x9f, 0xd7, 0x93, 0x11, 0xdf, 0x78, 0xe2, 0x84, 0x30, 0xfe, 0x8f, 0x1a, 0x62, - 0xee, 0xa7, 0xb2, 0xb0, 0x20, 0x7e, 0x61, 0x88, 0x54, 0x2e, 0xac, 0x3e, 0xb5, 0x63, 0x51, 0xd2, - 0xc6, 0xa2, 0xa8, 0x8f, 0x85, 0xd2, 0xc0, 0xfe, 0x43, 0x62, 0xfc, 0x08, 0xc0, 0x62, 0x3f, 0x82, - 0xa1, 0x1d, 0xf1, 0x23, 0xd7, 0xc4, 0xec, 0x10, 0xae, 0x89, 0xeb, 0x50, 0xc0, 0xaa, 0x44, 0x10, - 0x44, 0x7f, 0xcb, 0xac, 0x8a, 0x4e, 0x42, 0xfd, 0x02, 0x8f, 0x63, 0x2b, 0x82, 0x32, 0xfa, 0x31, - 0x9d, 0x47, 0x82, 0x92, 0xfc, 0x72, 0x06, 0x66, 0x10, 0xb8, 0xfa, 0x80, 0x76, 0x02, 0x64, 0x36, - 0x22, 0x7c, 0xd6, 0xc2, 0x87, 0xd1, 0x7a, 0xe0, 0x39, 0x9d, 0x3d, 0xf1, 0x32, 0xba, 0x23, 0x5e, - 0x46, 0xdf, 0xe1, 0x2f, 0xba, 0x57, 0x1a, 0x6e, 0xfb, 0xea, 0x9e, 0x67, 0x3f, 0x70, 0xb8, 0x09, - 0x96, 0xdd, 0xba, 0x1a, 0xe5, 0xfb, 0xe9, 0x3a, 0xb1, 0x4c, 0x3c, 0x82, 0x15, 0xbe, 0x3a, 0xf3, - 0x0f, 0xa5, 0x58, 0x6d, 0x5c, 0x35, 0xa3, 0x7f, 0x11, 0xf9, 0x1e, 0x38, 0xc7, 0x43, 0x93, 0xb1, - 0x1b, 0xbe, 0xd3, 0xe9, 0xb9, 0x3d, 0x7f, 0xc5, 0x6e, 0x1c, 0x30, 0x31, 0x9f, 0x7b, 0x16, 0x63, - 0xcb, 0x1b, 0x61, 0xa1, 0xb5, 0xc3, 0x4b, 0xb5, 0x98, 0x17, 0xe9, 0x0c, 0xc8, 0x1a, 0xcc, 0xf1, - 0xa2, 0x52, 0x2f, 0x70, 0xeb, 0x0d, 0xbb, 0xe5, 0x74, 0xf6, 0x50, 0x96, 0xc8, 0x73, 0x51, 0xc6, - 0xee, 0x05, 0xae, 0xe5, 0x73, 0xb8, 0xaa, 0xa9, 0x49, 0x10, 0x91, 0x2a, 0xcc, 0x9a, 0xd4, 0x6e, - 0xde, 0xb5, 0x1f, 0x95, 0xed, 0xae, 0xdd, 0x70, 0x02, 0x1e, 0x2b, 0x35, 0xc7, 0x05, 0x3a, 0x8f, - 0xda, 0x4d, 0xab, 0x6d, 0x3f, 0xb2, 0x1a, 0xa2, 0x50, 0x57, 0xd9, 0x6b, 0x74, 0x21, 0x2b, 0xa7, - 0x13, 0xb2, 0x9a, 0x88, 0xb3, 0x72, 0x3a, 0xfd, 0x59, 0x45, 0x74, 0x92, 0xd5, 0xa6, 0xed, 0xed, - 0xd1, 0x80, 0x1b, 0x4a, 0xc3, 0x85, 0xcc, 0xa5, 0x8c, 0xc2, 0x2a, 0xc0, 0x32, 0x0b, 0x8d, 0xa6, - 0xe3, 0xac, 0x14, 0x3a, 0x36, 0xf3, 0xb6, 0x3d, 0x27, 0xa0, 0x6a, 0x0b, 0x27, 0xf1, 0xb3, 0xb0, - 0xff, 0xd1, 0xc4, 0xbc, 0x5f, 0x13, 0x13, 0x94, 0x11, 0x37, 0xa5, 0x91, 0x53, 0x09, 0x6e, 0xe9, - 0xad, 0x4c, 0x50, 0x86, 0xdc, 0xd4, 0x76, 0x4e, 0x63, 0x3b, 0x15, 0x6e, 0x7d, 0x1a, 0x9a, 0xa0, - 0x24, 0x1b, 0xac, 0xd3, 0x02, 0x26, 0x37, 0xb9, 0x1d, 0x61, 0xc1, 0x3d, 0x83, 0x9f, 0xf6, 0xb2, - 0x30, 0x43, 0x2c, 0x78, 0xb2, 0xd8, 0x4a, 0xb1, 0xe7, 0x8e, 0x13, 0x93, 0xbf, 0x06, 0xb3, 0x5b, - 0x3e, 0xbd, 0x59, 0xad, 0xd5, 0x65, 0x24, 0x33, 0x54, 0x2e, 0xce, 0x2c, 0x5f, 0x3b, 0x61, 0xd3, - 0xb9, 0xa2, 0xd2, 0x60, 0xfa, 0x1c, 0x3e, 0x6e, 0x3d, 0x9f, 0x5a, 0xbb, 0x4e, 0xd7, 0x0f, 0xc3, - 0x42, 0xaa, 0xe3, 0x16, 0xab, 0xca, 0x58, 0x83, 0xb9, 0x04, 0x1b, 0x32, 0x03, 0xc0, 0x80, 0xd6, - 0xd6, 0x46, 0x7d, 0x75, 0xb3, 0xf0, 0x0c, 0x29, 0xc0, 0x14, 0xfe, 0x5e, 0xdd, 0x28, 0xad, 0xac, - 0xaf, 0x56, 0x0a, 0x19, 0x32, 0x07, 0xd3, 0x08, 0xa9, 0x54, 0xeb, 0x1c, 0x94, 0xe5, 0xc9, 0x13, - 0xcc, 0x02, 0x5f, 0xba, 0x01, 0x5b, 0x00, 0x78, 0xa6, 0x18, 0x7f, 0x2b, 0x0b, 0xe7, 0xe5, 0xb1, - 0x42, 0x03, 0x26, 0x38, 0x3a, 0x9d, 0xbd, 0xa7, 0xfc, 0x74, 0xb8, 0xa9, 0x9d, 0x0e, 0x2f, 0xc7, - 0x4e, 0xea, 0x58, 0x2b, 0x07, 0x1c, 0x11, 0xbf, 0x3d, 0x01, 0xcf, 0x0f, 0xa4, 0x22, 0x5f, 0x64, - 0xa7, 0xb9, 0x43, 0x3b, 0x41, 0xb5, 0xd9, 0xa2, 0x9b, 0x4e, 0x9b, 0xba, 0xbd, 0x40, 0x78, 0x0c, - 0xbc, 0x84, 0xfa, 0x3c, 0x2c, 0xb4, 0x9c, 0x66, 0x8b, 0x5a, 0x01, 0x2f, 0xd6, 0xa6, 0x5b, 0x92, - 0x9a, 0xb1, 0x0c, 0x53, 0x79, 0x55, 0x3b, 0x01, 0xf5, 0x1e, 0xa0, 0x55, 0x62, 0xc8, 0xf2, 0x80, - 0xd2, 0xae, 0x65, 0xb3, 0x52, 0xcb, 0x11, 0xc5, 0x3a, 0xcb, 0x04, 0x35, 0xb9, 0xa9, 0xb0, 0x2c, - 0xb3, 0xdb, 0xff, 0x5d, 0xfb, 0x91, 0x30, 0x93, 0x12, 0x91, 0x71, 0x43, 0x96, 0xdc, 0x9d, 0xaf, - 0x6d, 0x3f, 0x32, 0x93, 0x24, 0xe4, 0xab, 0x70, 0x46, 0x1c, 0x40, 0x22, 0x78, 0x8b, 0x6c, 0x31, - 0x0f, 0x0d, 0xf3, 0xea, 0xf1, 0x51, 0xf1, 0x9c, 0x8c, 0x29, 0x2c, 0x03, 0x2b, 0xa5, 0xb5, 0x3a, - 0x9d, 0x0b, 0xd9, 0x64, 0x07, 0x72, 0xac, 0x3b, 0xee, 0x52, 0xdf, 0x97, 0x3e, 0x9b, 0xe2, 0x66, - 0xac, 0x76, 0xa6, 0xd5, 0xe6, 0xe5, 0x66, 0x5f, 0x4a, 0xb2, 0x06, 0x33, 0xdb, 0x74, 0x47, 0x1d, - 0x9f, 0xb1, 0x70, 0xab, 0x2a, 0x3c, 0xa4, 0x3b, 0xfd, 0x07, 0x27, 0x46, 0x47, 0x1c, 0x7c, 0x1f, - 0x78, 0x74, 0xb8, 0xee, 0xf8, 0x01, 0xed, 0x50, 0x0f, 0xc3, 0xb7, 0x8d, 0xe3, 0x66, 0xb0, 0x18, - 0x49, 0xc8, 0x7a, 0xf9, 0xca, 0x8b, 0xc7, 0x47, 0xc5, 0xe7, 0xb9, 0xf3, 0x73, 0x4b, 0xc0, 0xad, - 0x58, 0x22, 0xac, 0x24, 0x57, 0xf2, 0x75, 0x98, 0x35, 0xdd, 0x5e, 0xe0, 0x74, 0xf6, 0xea, 0x81, - 0x67, 0x07, 0x74, 0x8f, 0x1f, 0x48, 0x51, 0x9c, 0xb8, 0x58, 0xa9, 0x78, 0x5a, 0xe6, 0x40, 0xcb, - 0x17, 0x50, 0xed, 0x44, 0xd0, 0x09, 0xc8, 0xd7, 0x60, 0x86, 0x87, 0xed, 0x08, 0x2b, 0x98, 0xd0, - 0x92, 0x78, 0xe8, 0x85, 0xf7, 0xaf, 0x09, 0xab, 0x16, 0x84, 0xa6, 0x55, 0x10, 0xe3, 0x46, 0xbe, - 0x2c, 0x3a, 0xab, 0xe6, 0x74, 0xf6, 0xc2, 0x69, 0x0c, 0xd8, 0xf3, 0x6f, 0x44, 0x5d, 0xd2, 0x65, - 0x9f, 0x2b, 0xa7, 0x71, 0x1f, 0x13, 0xbd, 0x24, 0x1f, 0x12, 0xc0, 0xf3, 0x25, 0xdf, 0x77, 0xfc, - 0x40, 0xf8, 0xd5, 0xac, 0x3e, 0xa2, 0x8d, 0x1e, 0x43, 0x66, 0xd7, 0x5b, 0xea, 0x71, 0xbb, 0xee, - 0xd1, 0x95, 0x2b, 0xc7, 0x47, 0xc5, 0xd7, 0x6c, 0x44, 0xb4, 0x84, 0x2b, 0x8e, 0x45, 0x25, 0xaa, - 0xf5, 0x90, 0xe3, 0x2a, 0x6d, 0x18, 0xcc, 0x94, 0x7c, 0x0d, 0xce, 0x96, 0x6d, 0x9f, 0x56, 0x3b, - 0x3e, 0xed, 0xf8, 0x4e, 0xe0, 0x3c, 0xa0, 0xa2, 0x53, 0xf1, 0xf0, 0xcb, 0x63, 0xca, 0x30, 0xa3, - 0x61, 0xfb, 0x6c, 0x61, 0x86, 0x28, 0x96, 0x18, 0x14, 0xa5, 0x9a, 0x3e, 0x5c, 0x88, 0x09, 0x33, - 0xf5, 0xfa, 0x5a, 0xc5, 0xb1, 0xc3, 0x75, 0x35, 0x8d, 0xfd, 0xf5, 0x1a, 0xaa, 0xf6, 0xfc, 0x7d, - 0xab, 0xe9, 0xd8, 0xe1, 0x82, 0xea, 0xd3, 0x59, 0x31, 0x0e, 0xc6, 0x51, 0x06, 0x0a, 0xf1, 0xa1, - 0x24, 0x5f, 0x82, 0x09, 0x6e, 0xdf, 0x46, 0xfd, 0x7d, 0x11, 0x79, 0x42, 0x9a, 0x4b, 0x85, 0x70, - 0x9d, 0x48, 0xb8, 0xd3, 0x71, 0xeb, 0x39, 0xaa, 0x5a, 0xcb, 0xa0, 0x3b, 0x9d, 0x24, 0x22, 0x4d, - 0x98, 0xe2, 0xa3, 0x45, 0x31, 0x48, 0xa4, 0x30, 0x73, 0x7e, 0x51, 0x5d, 0x1d, 0xa2, 0x28, 0xc6, - 0x1f, 0x5f, 0x0d, 0xc5, 0x9c, 0xe0, 0x08, 0x5a, 0x15, 0x1a, 0xd7, 0x15, 0x80, 0xbc, 0x24, 0x34, - 0xce, 0xc3, 0xb9, 0x3e, 0xdf, 0x6c, 0x3c, 0x40, 0x4b, 0x82, 0x3e, 0x35, 0x92, 0x2f, 0xc1, 0x02, - 0x12, 0x96, 0xdd, 0x4e, 0x87, 0x36, 0x02, 0xdc, 0x8e, 0xa4, 0xf6, 0x3d, 0xc7, 0x2d, 0x5d, 0x78, - 0x7b, 0x1b, 0x21, 0x82, 0x15, 0x57, 0xc2, 0xa7, 0x72, 0x30, 0x7e, 0x21, 0x0b, 0x8b, 0x62, 0x87, - 0x33, 0x69, 0xc3, 0xf5, 0x9a, 0x4f, 0xff, 0x89, 0xba, 0xaa, 0x9d, 0xa8, 0x2f, 0x85, 0x61, 0x8b, - 0xd2, 0x1a, 0x39, 0xe0, 0x40, 0xfd, 0xb5, 0x0c, 0x3c, 0x37, 0x88, 0x88, 0xf5, 0x4e, 0x18, 0x14, - 0x73, 0x22, 0x11, 0xfc, 0xb2, 0x0b, 0xf3, 0x38, 0xa0, 0xe5, 0x7d, 0xda, 0x38, 0xf0, 0xd7, 0x5c, - 0x3f, 0x40, 0x4f, 0x8b, 0x6c, 0x9f, 0xb7, 0xee, 0xd7, 0x53, 0xdf, 0xba, 0xcf, 0xf2, 0x59, 0xd6, - 0x40, 0x1e, 0x3c, 0x6c, 0xe7, 0x01, 0x3d, 0xf4, 0xcd, 0x34, 0xd6, 0x68, 0x31, 0x5f, 0xea, 0x05, - 0xfb, 0x35, 0x8f, 0xee, 0x52, 0x8f, 0x76, 0x1a, 0xf4, 0x13, 0x66, 0x31, 0xaf, 0x37, 0x6e, 0x28, - 0x0d, 0xc6, 0xb7, 0x67, 0x60, 0x21, 0x8d, 0x8c, 0xf5, 0x8b, 0x72, 0x69, 0x8e, 0x67, 0x34, 0xfd, - 0x56, 0x06, 0xa6, 0xea, 0xb4, 0xe1, 0x76, 0x9a, 0x37, 0xd1, 0xa2, 0x48, 0xf4, 0x8e, 0xcd, 0x85, - 0x06, 0x06, 0xb7, 0x76, 0x63, 0xa6, 0x46, 0xdf, 0x3d, 0x2a, 0x7e, 0x61, 0xb8, 0xbb, 0x6a, 0xc3, - 0xc5, 0x70, 0x41, 0x01, 0x66, 0xdc, 0x08, 0xab, 0xe0, 0x5f, 0x63, 0x6a, 0xd5, 0x92, 0x15, 0x98, - 0x16, 0x0b, 0xd6, 0x55, 0xa3, 0xa2, 0xf2, 0xd8, 0x4e, 0xb2, 0x20, 0xa1, 0xbc, 0xd6, 0x48, 0xc8, - 0x75, 0xc8, 0x6d, 0x2d, 0xdf, 0x14, 0xa3, 0x20, 0xb3, 0x96, 0x6c, 0x2d, 0xdf, 0x44, 0x85, 0x18, - 0xbb, 0x64, 0x4c, 0xf7, 0x96, 0x35, 0x33, 0x9f, 0xad, 0xe5, 0x9b, 0xe4, 0xfb, 0xe1, 0x4c, 0xc5, - 0xf1, 0x45, 0x15, 0xdc, 0x7b, 0xa3, 0x89, 0x3e, 0x8b, 0x63, 0x7d, 0xe6, 0xef, 0x67, 0x53, 0xe7, - 0xef, 0x8b, 0xcd, 0x90, 0x89, 0xc5, 0x5d, 0x43, 0x9a, 0xf1, 0xe8, 0xaf, 0xe9, 0xf5, 0x90, 0x0f, - 0x61, 0x06, 0xd5, 0xd9, 0xe8, 0xd0, 0x82, 0x71, 0xfb, 0xc7, 0xfb, 0xd4, 0xfc, 0xe9, 0xd4, 0x9a, - 0x97, 0x78, 0xc4, 0x0d, 0x74, 0x8b, 0xc1, 0x18, 0xff, 0xda, 0xbd, 0x5f, 0xe3, 0x4c, 0x6e, 0xc3, - 0xac, 0x10, 0xc0, 0xee, 0xed, 0x6e, 0xee, 0xd3, 0x8a, 0x7d, 0x28, 0x2c, 0x74, 0xf0, 0x4e, 0x27, - 0xa4, 0x36, 0xcb, 0xdd, 0xb5, 0x82, 0x7d, 0x6a, 0x35, 0x6d, 0x4d, 0x54, 0x89, 0x11, 0x92, 0x6f, - 0xc2, 0xe4, 0xba, 0xdb, 0x60, 0xb2, 0x37, 0xee, 0x0d, 0xdc, 0x68, 0xe7, 0x03, 0xcc, 0x9a, 0xc9, - 0xc1, 0x31, 0x81, 0xea, 0xbb, 0x47, 0xc5, 0xb7, 0x4f, 0x3b, 0x6d, 0x94, 0x0a, 0x4c, 0xb5, 0x36, - 0x52, 0x86, 0xfc, 0x36, 0xdd, 0x61, 0xad, 0x8d, 0x67, 0xd4, 0x93, 0x60, 0x61, 0x93, 0x27, 0x7e, - 0x69, 0x36, 0x79, 0x02, 0x46, 0x3c, 0x98, 0xc3, 0xfe, 0xa9, 0xd9, 0xbe, 0xff, 0xd0, 0xf5, 0x9a, - 0x98, 0x3a, 0xa5, 0x9f, 0x3d, 0xd0, 0x72, 0x6a, 0xe7, 0x3f, 0xc7, 0x3b, 0xbf, 0xab, 0x70, 0x50, - 0x45, 0xc8, 0x04, 0x7b, 0xf2, 0x75, 0x98, 0x11, 0xd1, 0x0b, 0xee, 0xde, 0x2c, 0xe1, 0x4a, 0x98, - 0xd2, 0x3c, 0x3f, 0xf5, 0x42, 0x2e, 0xa7, 0x8a, 0x60, 0x08, 0x52, 0x07, 0x65, 0xb5, 0x77, 0x6d, - 0x5d, 0xed, 0xaf, 0x92, 0x90, 0x1a, 0x4c, 0x56, 0x30, 0xaf, 0x33, 0x7a, 0xa7, 0x09, 0xcb, 0xf0, - 0x30, 0x25, 0x58, 0x54, 0xc2, 0xb5, 0x31, 0x22, 0x05, 0x34, 0xfa, 0xba, 0xe9, 0xd6, 0xba, 0x21, - 0x22, 0xb9, 0x01, 0xb9, 0x6a, 0xa5, 0x26, 0x0c, 0xc3, 0xe7, 0xc2, 0x18, 0x21, 0x35, 0x99, 0x40, - 0x09, 0x2d, 0xe8, 0x9c, 0xa6, 0x66, 0x56, 0x5e, 0xad, 0xd4, 0xc8, 0x2e, 0x4c, 0x63, 0x07, 0xac, - 0x51, 0x9b, 0xf7, 0xed, 0x6c, 0x9f, 0xbe, 0xbd, 0x92, 0xda, 0xb7, 0x8b, 0xbc, 0x6f, 0xf7, 0x05, - 0xb5, 0x96, 0x11, 0x46, 0x65, 0xcb, 0x84, 0x5a, 0x91, 0xa5, 0x4a, 0xe6, 0x31, 0xd9, 0x5c, 0x47, - 0x0b, 0x21, 0x21, 0xd4, 0xca, 0xa4, 0x56, 0x61, 0x62, 0x95, 0xbe, 0x7e, 0x27, 0x49, 0x3e, 0xe4, - 0xf3, 0x30, 0x72, 0xef, 0x20, 0xb0, 0x85, 0x09, 0xb8, 0xec, 0x47, 0x06, 0x92, 0xcd, 0x47, 0x3d, - 0xa4, 0x7b, 0xa0, 0x45, 0x9d, 0x43, 0x1a, 0x36, 0x14, 0x6b, 0xb6, 0xd7, 0x7c, 0x68, 0x7b, 0xe8, - 0x22, 0x3c, 0xaf, 0xb1, 0x50, 0x4a, 0xf8, 0x50, 0xec, 0x0b, 0x40, 0xcc, 0x6f, 0x58, 0x65, 0x41, - 0xbe, 0x07, 0xce, 0xfb, 0xce, 0x5e, 0xc7, 0x0e, 0x7a, 0x1e, 0xb5, 0xec, 0xd6, 0x9e, 0xeb, 0x39, - 0xc1, 0x7e, 0xdb, 0xf2, 0x7b, 0x4e, 0x40, 0x17, 0x17, 0xb4, 0x9c, 0xd6, 0x75, 0x89, 0x57, 0x92, - 0x68, 0x75, 0x86, 0x65, 0x9e, 0xf3, 0xd3, 0x0b, 0xc8, 0x97, 0x61, 0x5a, 0xdd, 0x92, 0xfd, 0xc5, - 0x33, 0x17, 0x72, 0x97, 0x66, 0xc2, 0xab, 0x47, 0x7c, 0x0b, 0x97, 0xb1, 0xa0, 0x95, 0x33, 0xc2, - 0xd7, 0x63, 0x41, 0x2b, 0xbc, 0x88, 0x09, 0xe7, 0x7c, 0xae, 0xdf, 0xe8, 0x75, 0x9c, 0x47, 0x98, - 0x30, 0x4b, 0x58, 0x92, 0x2d, 0x9e, 0xd5, 0x8e, 0xbe, 0x3a, 0x62, 0x6d, 0x6d, 0x54, 0xbf, 0xb4, - 0xe5, 0x53, 0x4f, 0x18, 0x94, 0x2d, 0x70, 0xda, 0xad, 0x8e, 0xf3, 0x28, 0x82, 0x86, 0x99, 0x27, - 0x49, 0x61, 0xde, 0x9c, 0x13, 0xab, 0x40, 0x8c, 0xdc, 0xdd, 0x9b, 0x25, 0x73, 0xbc, 0x56, 0xbd, - 0x5f, 0x6f, 0xb9, 0x81, 0xb1, 0x0f, 0x0b, 0x69, 0x5c, 0xc9, 0x22, 0x8c, 0x8b, 0xb4, 0x0d, 0x78, - 0x38, 0xe6, 0x4d, 0xf9, 0x93, 0x3c, 0x0b, 0x13, 0xbb, 0x8e, 0xe7, 0x07, 0x56, 0xcf, 0xe1, 0xf2, - 0xc2, 0xa8, 0x99, 0x47, 0xc0, 0x96, 0xd3, 0x24, 0xe7, 0x21, 0x8f, 0xe1, 0x8f, 0x59, 0x59, 0x0e, - 0xcb, 0xc6, 0xd9, 0xef, 0x2d, 0xa7, 0x69, 0xfc, 0x17, 0x19, 0x3c, 0x82, 0xc8, 0x6b, 0x18, 0x08, - 0x2b, 0x7c, 0xfd, 0x43, 0xfd, 0xb3, 0xdd, 0x8d, 0xa5, 0x41, 0xe0, 0x28, 0xe4, 0x75, 0x18, 0xbb, - 0x69, 0x37, 0x64, 0x10, 0x1e, 0x81, 0xbc, 0x8b, 0x10, 0x55, 0x59, 0xcd, 0x71, 0x98, 0x7c, 0xcc, - 0x97, 0x66, 0x29, 0x4a, 0xf6, 0x5e, 0x2e, 0x49, 0x73, 0x03, 0x94, 0x8f, 0xc5, 0x92, 0x56, 0xb2, - 0xc1, 0xc7, 0xac, 0xfa, 0x53, 0x39, 0x18, 0x7f, 0x9a, 0x89, 0xf6, 0x54, 0xf2, 0x2a, 0x8c, 0x98, - 0xb5, 0xf0, 0xfb, 0xb9, 0xd3, 0x72, 0xec, 0xf3, 0x11, 0x81, 0x7c, 0x19, 0xce, 0x28, 0x7c, 0x12, - 0x2e, 0x06, 0xaf, 0xa0, 0x4f, 0xad, 0xf2, 0x25, 0xe9, 0x7e, 0x06, 0xe9, 0x3c, 0xf0, 0x32, 0x10, - 0x15, 0x54, 0x68, 0xc7, 0xe1, 0xbc, 0x95, 0xc6, 0xaa, 0xbc, 0x9b, 0x88, 0x10, 0x6f, 0x6c, 0x1a, - 0x07, 0xee, 0x52, 0x6b, 0xfc, 0x56, 0x46, 0xdb, 0x2b, 0xc3, 0xec, 0xd8, 0x99, 0x13, 0xb2, 0x63, - 0xbf, 0x05, 0x50, 0xea, 0x05, 0xee, 0x6a, 0xc7, 0x73, 0x5b, 0x5c, 0x0b, 0x24, 0x32, 0x81, 0xa0, - 0x6e, 0x9b, 0x22, 0x58, 0xf3, 0xfc, 0x0b, 0x91, 0x53, 0xbd, 0x31, 0x72, 0x1f, 0xd5, 0x1b, 0xc3, - 0xf8, 0xfd, 0x8c, 0xb6, 0xc3, 0x30, 0x29, 0x57, 0x4c, 0x7a, 0xd5, 0xe2, 0xad, 0xeb, 0x3c, 0xb0, - 0xfc, 0x96, 0xab, 0x85, 0xdb, 0x10, 0x68, 0xe4, 0xdf, 0xcd, 0xc0, 0x59, 0xee, 0xd6, 0xb0, 0xd1, - 0x6b, 0xef, 0x50, 0xef, 0xbe, 0xdd, 0x72, 0x9a, 0x51, 0x98, 0xc1, 0xc8, 0xfc, 0x51, 0xa9, 0x26, - 0x1d, 0x9f, 0x5f, 0xb4, 0xb9, 0x9b, 0x85, 0xd5, 0xc1, 0x42, 0xeb, 0x41, 0x58, 0xaa, 0x5e, 0xb4, - 0xd3, 0xe9, 0x8d, 0x5f, 0xcf, 0xc0, 0x8b, 0x27, 0xd6, 0x42, 0xae, 0xc2, 0xf8, 0xaa, 0xba, 0x68, - 0xb9, 0x9d, 0x70, 0x32, 0xfd, 0x8a, 0xc4, 0x22, 0x5f, 0x81, 0x33, 0x2a, 0xab, 0x4d, 0xcf, 0x76, - 0xd4, 0x44, 0x27, 0x29, 0x5f, 0x1d, 0x30, 0x94, 0xb8, 0xac, 0x99, 0xce, 0xc4, 0xf8, 0x7f, 0x33, - 0x4a, 0xbe, 0xfc, 0xa7, 0xf4, 0x0e, 0x72, 0x43, 0xbb, 0x83, 0xc8, 0x20, 0xab, 0x61, 0xab, 0x58, - 0x59, 0xea, 0xbd, 0x71, 0x56, 0xb1, 0x77, 0x47, 0xc0, 0x8f, 0x66, 0x61, 0x92, 0xed, 0xaf, 0xfc, - 0x21, 0xfa, 0x93, 0x15, 0x6a, 0x32, 0x6c, 0xd7, 0x50, 0xc1, 0x00, 0xff, 0x38, 0x83, 0x0f, 0x14, - 0x2a, 0x05, 0xeb, 0x0d, 0x25, 0x47, 0x26, 0xf6, 0x06, 0x66, 0xc7, 0x44, 0x28, 0x0f, 0x8d, 0xb6, - 0xae, 0xa7, 0xcb, 0xc5, 0x9c, 0xc9, 0xeb, 0xe4, 0x0b, 0x30, 0xba, 0x85, 0xea, 0x56, 0x3d, 0x48, - 0x48, 0xc8, 0x1f, 0x0b, 0xf9, 0x26, 0xdd, 0xf3, 0xf5, 0xb8, 0x79, 0x9c, 0x90, 0xd4, 0x61, 0xbc, - 0xec, 0x51, 0xcc, 0x7e, 0x3f, 0x32, 0xbc, 0x8b, 0x7b, 0x83, 0x93, 0xc4, 0x5d, 0xdc, 0x05, 0x27, - 0xe3, 0xe7, 0xb3, 0x40, 0xa2, 0x36, 0x62, 0xaa, 0x37, 0xff, 0xa9, 0x1d, 0xf4, 0xf7, 0xb5, 0x41, - 0x7f, 0x3e, 0x31, 0xe8, 0xbc, 0x79, 0x43, 0x8d, 0xfd, 0xef, 0x64, 0xe0, 0x6c, 0x3a, 0x21, 0x79, - 0x09, 0xc6, 0xee, 0x6d, 0xd6, 0x64, 0x9c, 0x19, 0xd1, 0x14, 0xb7, 0x8b, 0xba, 0x0e, 0x53, 0x14, - 0x91, 0x37, 0x60, 0xec, 0x8b, 0x66, 0x99, 0x9d, 0x43, 0x4a, 0x32, 0x91, 0x6f, 0x30, 0x71, 0x49, - 0x3b, 0x8a, 0x04, 0x92, 0x3a, 0xb6, 0xb9, 0x27, 0x36, 0xb6, 0x3f, 0x95, 0x85, 0xd9, 0x52, 0xa3, - 0x41, 0x7d, 0x5f, 0x04, 0xca, 0x7f, 0x6a, 0x07, 0x36, 0x3d, 0x82, 0x8c, 0xd6, 0xb6, 0xa1, 0x46, - 0xf5, 0x77, 0x33, 0x70, 0x46, 0x52, 0x3d, 0x70, 0xe8, 0xc3, 0xcd, 0x7d, 0x8f, 0xfa, 0xfb, 0x6e, - 0xab, 0x39, 0x74, 0xc6, 0x22, 0x26, 0xe8, 0x61, 0x70, 0x7b, 0xd5, 0x2a, 0x61, 0x17, 0x21, 0x9a, - 0xa0, 0xc7, 0x03, 0xe0, 0x5f, 0x85, 0xf1, 0x52, 0xb7, 0xeb, 0xb9, 0x0f, 0xf8, 0xb2, 0x17, 0x91, - 0x31, 0x6d, 0x0e, 0xd2, 0x22, 0x04, 0x70, 0x10, 0xfb, 0x8c, 0x0a, 0xed, 0xf0, 0x50, 0x84, 0xd3, - 0xfc, 0x33, 0x9a, 0xb4, 0xa3, 0xde, 0x24, 0xb0, 0xdc, 0xa8, 0x03, 0xa9, 0x79, 0x6e, 0xdb, 0x0d, - 0x68, 0x93, 0xb7, 0x07, 0x03, 0x2b, 0x9c, 0x18, 0x12, 0x6c, 0xd3, 0x09, 0x5a, 0x5a, 0x48, 0xb0, - 0x80, 0x01, 0x4c, 0x0e, 0x37, 0xfe, 0xef, 0x51, 0x98, 0x52, 0x7b, 0x87, 0x18, 0x3c, 0x0d, 0x89, - 0xeb, 0xa9, 0xd1, 0x3d, 0x6c, 0x84, 0x98, 0xa2, 0x24, 0x0a, 0x8d, 0x93, 0x3d, 0x31, 0x34, 0xce, - 0x36, 0x4c, 0xd7, 0x3c, 0x17, 0x43, 0x78, 0xe2, 0x6b, 0xab, 0xd8, 0x0a, 0xe7, 0x95, 0x5b, 0x33, - 0x1b, 0x48, 0x7c, 0xcf, 0xc5, 0x7b, 0x49, 0x57, 0x60, 0x63, 0x72, 0x4e, 0x4d, 0x67, 0xa4, 0xf1, - 0xe1, 0xa6, 0x22, 0xb6, 0x2f, 0xe2, 0xf0, 0x86, 0xa6, 0x22, 0x0c, 0xa2, 0x9b, 0x8a, 0x30, 0x88, - 0xba, 0xd6, 0x46, 0x9f, 0xd4, 0x5a, 0x23, 0x3f, 0x9f, 0x81, 0xc9, 0x52, 0xa7, 0x23, 0x42, 0xee, - 0x9c, 0x10, 0x6d, 0xe0, 0x2b, 0xc2, 0x5a, 0xe4, 0xed, 0x8f, 0x64, 0x2d, 0x82, 0x72, 0x8b, 0x8f, - 0x92, 0x6a, 0x54, 0xa1, 0x7a, 0xd7, 0x54, 0xbe, 0x83, 0xbc, 0x0d, 0x85, 0x70, 0x92, 0x57, 0x3b, - 0x4d, 0xfa, 0x88, 0xf2, 0x34, 0x8e, 0xd3, 0x22, 0x2e, 0xb8, 0x2a, 0x99, 0xc6, 0x11, 0xc9, 0x26, - 0x80, 0x1d, 0xce, 0xae, 0x58, 0x3e, 0xda, 0xe4, 0xf4, 0x13, 0xd2, 0x33, 0xfe, 0xc6, 0x07, 0x39, - 0x55, 0x7a, 0x8e, 0xf8, 0x90, 0x36, 0xcc, 0xf2, 0x64, 0xb0, 0xf5, 0xc0, 0xf6, 0x02, 0x4c, 0xa5, - 0x01, 0x27, 0x8e, 0xc3, 0xab, 0x42, 0xfb, 0xf7, 0xac, 0x48, 0x31, 0xeb, 0x33, 0x5a, 0x2b, 0x25, - 0xaf, 0x46, 0x9c, 0x37, 0x8f, 0xc2, 0x6e, 0x9e, 0x4b, 0x7e, 0x2f, 0x9f, 0xf4, 0x3f, 0x95, 0x81, - 0xb3, 0xea, 0xa4, 0xaf, 0xf7, 0x76, 0x44, 0xe8, 0x53, 0x72, 0x05, 0x26, 0xc4, 0x9c, 0x0c, 0x2f, - 0x51, 0xc9, 0x8c, 0x20, 0x11, 0x0a, 0x59, 0x65, 0xd3, 0x90, 0xf1, 0x10, 0x52, 0xf7, 0x7c, 0x6c, - 0x9f, 0x62, 0x45, 0x51, 0xa2, 0x71, 0x0f, 0x7f, 0xeb, 0xf3, 0x93, 0x41, 0x8c, 0xf7, 0x60, 0x4e, - 0x1f, 0x89, 0x3a, 0x0d, 0xc8, 0x65, 0x18, 0x97, 0xc3, 0x97, 0x49, 0x1f, 0x3e, 0x59, 0x6e, 0x6c, - 0x03, 0x49, 0xd0, 0xfb, 0x68, 0xd6, 0xc5, 0xee, 0xa7, 0xdc, 0xec, 0x50, 0x3e, 0xaa, 0x26, 0x10, - 0x57, 0xe6, 0xc5, 0xf7, 0x4d, 0x6a, 0x6e, 0x15, 0x18, 0x06, 0xf6, 0x9f, 0xcf, 0xc2, 0x7c, 0xca, - 0x9e, 0x7b, 0x82, 0x4c, 0x54, 0xd4, 0x37, 0x88, 0x89, 0x30, 0x58, 0x89, 0xdc, 0x16, 0xde, 0x83, - 0xd1, 0x13, 0xb7, 0x03, 0xee, 0x54, 0x13, 0xdb, 0x05, 0x38, 0xd9, 0xc7, 0x22, 0x17, 0xa9, 0xf1, - 0x84, 0x46, 0x9f, 0x58, 0x3c, 0xa1, 0x15, 0x98, 0x16, 0xad, 0x12, 0xdb, 0x95, 0x62, 0xdc, 0x2d, - 0x33, 0xdc, 0x24, 0xb6, 0x2d, 0x9d, 0x84, 0xf3, 0xf0, 0xdd, 0xd6, 0x03, 0x2a, 0x78, 0x8c, 0xab, - 0x3c, 0xb0, 0x20, 0x95, 0x87, 0x42, 0x42, 0xfe, 0x63, 0x4c, 0x44, 0x89, 0x10, 0x75, 0xcf, 0xca, - 0x0f, 0xda, 0xb3, 0x9a, 0x4f, 0x66, 0xcf, 0x7a, 0x5e, 0x7e, 0x63, 0xfa, 0xde, 0x95, 0xf2, 0x59, - 0xe4, 0x57, 0x32, 0x30, 0xc7, 0x83, 0xda, 0xa8, 0x1f, 0x3b, 0x30, 0x50, 0x49, 0xe3, 0xc9, 0x7c, - 0xec, 0x73, 0x22, 0xb7, 0x51, 0xfa, 0xb7, 0x26, 0x3f, 0x8a, 0x7c, 0x0f, 0x40, 0xb8, 0xa2, 0x78, - 0x28, 0xdc, 0xc9, 0xe5, 0xe7, 0x52, 0x76, 0x81, 0x10, 0x29, 0x4a, 0x41, 0x12, 0x84, 0x74, 0x5a, - 0xfa, 0xd1, 0x10, 0x4a, 0xbe, 0x1f, 0x16, 0xd8, 0x7a, 0x09, 0x21, 0x22, 0x04, 0xd7, 0xe2, 0x24, - 0xd6, 0xf2, 0x99, 0xfe, 0x32, 0xd1, 0x95, 0x34, 0x32, 0x1e, 0x38, 0x39, 0xca, 0x04, 0x1f, 0xa8, - 0xd1, 0x3a, 0x52, 0x2b, 0xc2, 0xc8, 0x76, 0xf8, 0xf5, 0x3c, 0x4d, 0x48, 0x9f, 0xfd, 0xed, 0xbc, - 0x5c, 0x0b, 0x7c, 0x7f, 0xf3, 0x75, 0x1f, 0x6b, 0x04, 0x91, 0x2f, 0x02, 0x09, 0xa3, 0xc1, 0x70, - 0x18, 0x95, 0x29, 0x44, 0xb8, 0xb2, 0x3c, 0x8a, 0x2a, 0xe3, 0xc9, 0x62, 0x75, 0x92, 0x24, 0x89, - 0x09, 0x85, 0x05, 0xd1, 0x68, 0x06, 0x95, 0x59, 0x22, 0xfd, 0xc5, 0x19, 0x2d, 0xc0, 0x59, 0x54, - 0x12, 0xa5, 0x8c, 0x57, 0x52, 0x4d, 0x6a, 0x2a, 0xa7, 0x34, 0x76, 0xe4, 0x06, 0x4c, 0xa0, 0xa3, - 0xf3, 0x9a, 0x34, 0x56, 0x13, 0x86, 0x33, 0xe8, 0x12, 0x6d, 0xed, 0xeb, 0x26, 0x67, 0x11, 0x2a, - 0xbb, 0x0e, 0x54, 0xbc, 0x43, 0xb3, 0xd7, 0x41, 0x95, 0xb6, 0xd0, 0x77, 0x34, 0xbd, 0x43, 0xcb, - 0xeb, 0xe9, 0x9e, 0xf0, 0x88, 0x44, 0xbe, 0x0e, 0x93, 0x77, 0xed, 0x47, 0x61, 0x9e, 0xac, 0xb9, - 0xe1, 0xb3, 0x71, 0xb5, 0xed, 0x47, 0x61, 0x92, 0xac, 0x78, 0x36, 0x2e, 0x85, 0x25, 0xf9, 0x2a, - 0x80, 0xa2, 0x67, 0x27, 0x27, 0x56, 0xf0, 0xa2, 0x0c, 0xdb, 0x97, 0xaa, 0x7f, 0x47, 0xfe, 0x0a, - 0xc3, 0x98, 0xe4, 0xb0, 0xf0, 0xf1, 0x49, 0x0e, 0x67, 0x3e, 0x3e, 0xc9, 0x81, 0x3f, 0xf3, 0xf0, - 0xb1, 0xc7, 0x1d, 0xfc, 0x50, 0x68, 0xb9, 0x07, 0xd5, 0xf6, 0x9c, 0x34, 0x85, 0xc4, 0xa3, 0xe0, - 0x30, 0x56, 0x45, 0x8c, 0xdf, 0xd2, 0x0e, 0x9c, 0xef, 0xbb, 0x38, 0x53, 0xc2, 0x42, 0x5f, 0xd5, - 0xc3, 0x42, 0x9f, 0xef, 0x77, 0x88, 0xfb, 0x7a, 0x2e, 0x9a, 0xf9, 0xc2, 0x42, 0x7f, 0xf9, 0xe7, - 0x3b, 0xd9, 0xd8, 0xa1, 0x2e, 0xae, 0x2e, 0x3c, 0x0f, 0x5a, 0x3f, 0xa9, 0x27, 0x8b, 0x49, 0xca, - 0xf9, 0xb1, 0xaf, 0x44, 0xce, 0x67, 0xc7, 0xbe, 0x2a, 0x36, 0xa0, 0x00, 0xf0, 0xb8, 0xe7, 0xfb, - 0x3b, 0x30, 0xc3, 0xf3, 0x0a, 0xdf, 0xa1, 0x87, 0x0f, 0x5d, 0xaf, 0xc9, 0x33, 0x3c, 0x09, 0x29, - 0xdf, 0xc7, 0x12, 0xdd, 0x79, 0x53, 0xc5, 0x25, 0x15, 0xe9, 0x9d, 0x3b, 0x8a, 0xb5, 0x9f, 0x4f, - 0xdd, 0x27, 0x19, 0xc2, 0x20, 0xc7, 0x5d, 0xf2, 0x66, 0x28, 0x0a, 0x52, 0x4f, 0xcd, 0x48, 0xe3, - 0x49, 0x60, 0x8a, 0x44, 0x48, 0x3d, 0xe3, 0x5f, 0xe6, 0x80, 0xf0, 0x9a, 0xca, 0x76, 0xd7, 0x46, - 0xdf, 0x75, 0x07, 0xa3, 0x51, 0x15, 0x04, 0x8e, 0xbd, 0xd3, 0xa2, 0x6a, 0x28, 0x37, 0x61, 0x7e, - 0x1c, 0x96, 0x59, 0xf1, 0xab, 0x54, 0x82, 0xb0, 0xcf, 0x66, 0x9a, 0x7d, 0x9c, 0xcd, 0xf4, 0xeb, - 0xf0, 0x6c, 0xa9, 0x8b, 0x09, 0xca, 0x65, 0x2d, 0x37, 0x5d, 0x4f, 0x4e, 0x5d, 0xcd, 0x2b, 0xd2, - 0x0e, 0xd1, 0x12, 0x5f, 0x3a, 0x88, 0x85, 0x22, 0x09, 0xb1, 0x79, 0xd9, 0x0d, 0xd4, 0x28, 0x1b, - 0x52, 0x12, 0xea, 0x62, 0x49, 0x8a, 0x24, 0xc4, 0x49, 0x24, 0x0f, 0xc7, 0x93, 0x92, 0x10, 0xe6, - 0x73, 0x8b, 0x78, 0x38, 0x1e, 0xed, 0x23, 0x4d, 0x85, 0x24, 0xe4, 0x1d, 0x98, 0x2c, 0xf5, 0x02, - 0x57, 0x30, 0x16, 0x76, 0xf3, 0x91, 0x85, 0xbb, 0xf8, 0x14, 0xed, 0x72, 0x15, 0xa1, 0x1b, 0x7f, - 0x92, 0x83, 0xf3, 0xc9, 0xe1, 0x15, 0xa5, 0xe1, 0xfa, 0xc8, 0x9c, 0xb0, 0x3e, 0xd2, 0x66, 0x43, - 0x36, 0xca, 0xc5, 0xf1, 0x24, 0x66, 0x03, 0xcf, 0x73, 0xfe, 0x11, 0x67, 0x43, 0x1d, 0x26, 0xd5, - 0x13, 0x75, 0xe4, 0xa3, 0x9e, 0xa8, 0x2a, 0x17, 0x72, 0x19, 0x46, 0x79, 0x70, 0x91, 0xd1, 0xe8, - 0x71, 0x2a, 0x1e, 0x57, 0x84, 0x63, 0x90, 0x7f, 0x07, 0x2e, 0xf0, 0x3d, 0x29, 0xde, 0xd8, 0x95, - 0x43, 0xc9, 0x51, 0x0c, 0xdc, 0xf2, 0xf1, 0x51, 0xf1, 0x0a, 0x57, 0xc6, 0x58, 0x89, 0x6e, 0xb3, - 0x76, 0x0e, 0x2d, 0xf9, 0x65, 0x4a, 0x25, 0x27, 0xf2, 0x36, 0xca, 0x70, 0x5e, 0x94, 0x46, 0x6e, - 0xed, 0xb2, 0x90, 0x0d, 0xf2, 0x41, 0xa4, 0x4f, 0xc3, 0x41, 0x8e, 0xa9, 0xca, 0xb0, 0x1c, 0x33, - 0xa4, 0x2b, 0xd9, 0xab, 0xdf, 0x48, 0xf3, 0x4a, 0xe2, 0x71, 0xcd, 0x39, 0x58, 0x77, 0x48, 0x92, - 0x5a, 0xbb, 0x6c, 0xaa, 0xd6, 0x4e, 0xaa, 0x7d, 0x72, 0xa9, 0x6a, 0x9f, 0x0a, 0xcc, 0xd6, 0x7b, - 0x3b, 0xb2, 0xee, 0xb8, 0x47, 0xab, 0xdf, 0xdb, 0x49, 0xeb, 0x95, 0x38, 0x89, 0xf1, 0x63, 0x59, - 0x98, 0xaa, 0xb5, 0x7a, 0x7b, 0x4e, 0xa7, 0x62, 0x07, 0xf6, 0x53, 0xab, 0x48, 0x7c, 0x4b, 0x53, - 0x24, 0x86, 0xce, 0x77, 0x61, 0xc3, 0x86, 0xd2, 0x22, 0xfe, 0x5c, 0x06, 0x66, 0x23, 0x12, 0x7e, - 0x58, 0xaf, 0xc1, 0x08, 0xfb, 0x21, 0xae, 0xd7, 0x17, 0x12, 0x8c, 0x79, 0x22, 0xce, 0xf0, 0x2f, - 0xa1, 0xda, 0xd3, 0xb3, 0xdc, 0x21, 0x87, 0xa5, 0xcf, 0xc2, 0x44, 0xc4, 0xf6, 0x34, 0x09, 0x38, - 0x7f, 0x23, 0x03, 0x85, 0x78, 0x4b, 0xc8, 0x1d, 0x18, 0x67, 0x9c, 0x1c, 0x2a, 0x6f, 0xfe, 0x2f, - 0xf7, 0x69, 0xf3, 0x15, 0x81, 0xc6, 0x3f, 0x0f, 0x3b, 0x9f, 0x72, 0x88, 0x29, 0x39, 0x2c, 0x99, - 0x30, 0xa5, 0x62, 0xa5, 0x7c, 0xdd, 0xeb, 0xba, 0x84, 0x72, 0x36, 0xbd, 0x1f, 0xb4, 0xb4, 0xa1, - 0xda, 0x57, 0x0b, 0xe1, 0xe3, 0xa2, 0x36, 0xb9, 0x52, 0x57, 0x15, 0x4e, 0x9a, 0xe5, 0x28, 0xa3, - 0x83, 0x3a, 0xcf, 0x52, 0x26, 0x74, 0x88, 0x47, 0x5e, 0x87, 0x31, 0x5e, 0x9f, 0x9a, 0xf2, 0xae, - 0x8b, 0x10, 0x55, 0x12, 0xe7, 0x38, 0xc6, 0xdf, 0xce, 0xc1, 0xd9, 0xe8, 0xf3, 0xb6, 0xba, 0x4d, - 0x3b, 0xa0, 0x35, 0xdb, 0xb3, 0xdb, 0xfe, 0x09, 0x2b, 0xe0, 0x52, 0xe2, 0xd3, 0x30, 0xd9, 0x98, - 0xfc, 0x34, 0xe5, 0x83, 0x8c, 0xd8, 0x07, 0xa1, 0x96, 0x95, 0x7f, 0x90, 0xfc, 0x0c, 0x72, 0x07, - 0x72, 0x75, 0x1a, 0x88, 0xbd, 0xf7, 0x62, 0xa2, 0x57, 0xd5, 0xef, 0xba, 0x52, 0xa7, 0x01, 0x1f, - 0x44, 0x1e, 0x39, 0x4b, 0x0b, 0x5f, 0xc8, 0xb8, 0x90, 0x6d, 0x18, 0x5b, 0x7d, 0xd4, 0xa5, 0x8d, - 0x40, 0xa4, 0x8f, 0xbd, 0x3c, 0x98, 0x1f, 0xc7, 0x55, 0xb2, 0xc7, 0x52, 0x04, 0xa8, 0x9d, 0xc5, - 0x51, 0x96, 0x6e, 0x40, 0x5e, 0x56, 0x7e, 0x9a, 0x99, 0xbb, 0xf4, 0x16, 0x4c, 0x2a, 0x95, 0x9c, - 0x6a, 0xd2, 0xff, 0x12, 0xdb, 0x57, 0xdd, 0x96, 0xcc, 0x38, 0xbb, 0x9a, 0x90, 0x15, 0x95, 0x7c, - 0x5d, 0x5c, 0x56, 0xb4, 0x0e, 0x44, 0xd1, 0x00, 0xa1, 0xb1, 0x0a, 0xb3, 0xf5, 0x03, 0xa7, 0x1b, - 0x85, 0xd2, 0xd5, 0x4e, 0x64, 0xcc, 0x09, 0x24, 0x54, 0x03, 0xf1, 0x13, 0x39, 0x4e, 0x67, 0xfc, - 0x79, 0x06, 0xc6, 0xd8, 0x5f, 0xf7, 0x6f, 0x3c, 0xa5, 0x5b, 0xe6, 0x75, 0x6d, 0xcb, 0x9c, 0x53, - 0xa2, 0xd9, 0xe3, 0xc6, 0x71, 0xe3, 0x84, 0xcd, 0xf2, 0x48, 0x0c, 0x10, 0x47, 0x26, 0xb7, 0x60, - 0x5c, 0x98, 0x5c, 0x09, 0xeb, 0x78, 0x35, 0x3c, 0xbe, 0x34, 0xc6, 0x0a, 0x75, 0x08, 0x6e, 0x37, - 0xae, 0x74, 0x91, 0xd4, 0x4c, 0xae, 0x97, 0x41, 0x8d, 0xb5, 0x8c, 0xf2, 0x2e, 0xba, 0x33, 0xf2, - 0xe0, 0xee, 0xfe, 0xca, 0x39, 0xc1, 0xa9, 0x5f, 0xf4, 0x81, 0x92, 0x78, 0x6f, 0xc9, 0x0d, 0x62, - 0x72, 0x56, 0xa6, 0x71, 0x4e, 0x7d, 0x8a, 0x69, 0xc3, 0xd9, 0x7a, 0x7d, 0x0d, 0xcd, 0x33, 0x6b, - 0xae, 0x17, 0xdc, 0x74, 0xbd, 0x87, 0x36, 0x5a, 0x5f, 0xa3, 0x0e, 0x51, 0xb1, 0x72, 0x48, 0x33, - 0x9a, 0x7b, 0x35, 0xd5, 0x68, 0x6e, 0x80, 0x25, 0x84, 0xd1, 0x81, 0x73, 0xf5, 0xfa, 0x1a, 0x0f, - 0xad, 0xfe, 0x17, 0x51, 0xdf, 0x6f, 0x64, 0x60, 0xae, 0x5e, 0x5f, 0x8b, 0x55, 0xb5, 0x2e, 0x63, - 0xba, 0x67, 0xf4, 0x4c, 0xe8, 0xa9, 0x1d, 0x81, 0xa3, 0x90, 0xe1, 0x12, 0x5e, 0x43, 0x0b, 0xdf, - 0xc9, 0x99, 0x90, 0x5a, 0x18, 0x45, 0x3e, 0xab, 0x79, 0x4c, 0xf4, 0x69, 0x28, 0xea, 0xd0, 0x85, - 0xbf, 0x21, 0x2b, 0xd5, 0x75, 0xe8, 0x0c, 0x62, 0xfc, 0xb7, 0x67, 0x79, 0x9c, 0x7a, 0x39, 0x5b, - 0xde, 0x85, 0x29, 0x41, 0x8f, 0x6e, 0x05, 0xc2, 0xea, 0xe4, 0x3c, 0xdb, 0x20, 0x77, 0x39, 0x9c, - 0xc7, 0x2f, 0xfe, 0xee, 0x51, 0x71, 0x84, 0x75, 0x8d, 0xa9, 0xa1, 0x93, 0x7b, 0x30, 0x7d, 0xd7, - 0x7e, 0xa4, 0x28, 0x4c, 0xb8, 0xd3, 0xd8, 0x65, 0xb6, 0xab, 0xb4, 0xed, 0x47, 0x43, 0x18, 0x25, - 0xea, 0xf4, 0xe4, 0x00, 0x66, 0xf4, 0x36, 0x89, 0x19, 0x98, 0x1c, 0xb1, 0x6b, 0xa9, 0x23, 0x76, - 0xbe, 0xeb, 0x7a, 0x81, 0xb5, 0x1b, 0x92, 0x6b, 0x39, 0x19, 0x62, 0xac, 0xc9, 0xbb, 0x30, 0xa7, - 0x04, 0x49, 0xbd, 0xe9, 0x7a, 0x6d, 0x5b, 0x5e, 0xb8, 0xf0, 0x15, 0x01, 0xad, 0x95, 0x76, 0x11, - 0x6c, 0x26, 0x31, 0xc9, 0x97, 0xd3, 0x1c, 0xf1, 0x46, 0x23, 0xcb, 0xcc, 0x14, 0x47, 0xbc, 0x7e, - 0x96, 0x99, 0x49, 0x97, 0xbc, 0xbd, 0x41, 0x96, 0xdb, 0x79, 0xde, 0xfa, 0xa1, 0x2c, 0xb3, 0xc3, - 0x91, 0xeb, 0x63, 0xa1, 0xbd, 0x0c, 0xb9, 0x95, 0xda, 0x4d, 0x7c, 0xfb, 0x92, 0x66, 0x5a, 0x9d, - 0x7d, 0xbb, 0xd3, 0xc0, 0x8b, 0x90, 0xf0, 0x97, 0x50, 0x0f, 0xca, 0x95, 0xda, 0x4d, 0x62, 0xc3, - 0x3c, 0x66, 0xc2, 0x0b, 0xbe, 0x74, 0xed, 0x9a, 0x32, 0x54, 0x79, 0xfc, 0xb4, 0xab, 0xe2, 0xd3, - 0x8a, 0x98, 0x47, 0x2f, 0xb0, 0x1e, 0x5d, 0xbb, 0x96, 0x3a, 0x20, 0xe1, 0x87, 0xa5, 0xf1, 0x62, - 0x07, 0xd6, 0x5d, 0xfb, 0x51, 0xe4, 0xe6, 0xe2, 0x0b, 0x97, 0xe6, 0xe7, 0xe5, 0xd4, 0x8a, 0x5c, - 0x64, 0xb4, 0x03, 0x4b, 0x27, 0x62, 0xf7, 0xd8, 0x68, 0x82, 0xf9, 0xc2, 0x19, 0x6c, 0x49, 0x2a, - 0x04, 0xa5, 0xdf, 0xbb, 0x7a, 0x19, 0x53, 0xd0, 0xc9, 0x56, 0x78, 0x1b, 0xe7, 0xb7, 0x59, 0x91, - 0x3b, 0xfa, 0xaa, 0x7a, 0x1b, 0xe7, 0x6a, 0x38, 0xad, 0x59, 0xb3, 0xa1, 0x0a, 0x87, 0xfb, 0xfd, - 0x98, 0x3a, 0x97, 0xe4, 0x25, 0x7f, 0xea, 0xf4, 0x97, 0x7c, 0x0a, 0x23, 0xeb, 0x6e, 0xe3, 0x40, - 0x84, 0x2f, 0xfc, 0x22, 0xdb, 0x85, 0x5b, 0x6e, 0xe3, 0xe0, 0xc9, 0x59, 0xa4, 0x23, 0x7b, 0xb2, - 0xc1, 0x3e, 0x95, 0xcd, 0x02, 0xd1, 0x27, 0xc2, 0xca, 0x79, 0x21, 0xbc, 0xe5, 0x2a, 0x65, 0x5c, - 0x1e, 0xe5, 0x93, 0x46, 0x76, 0xad, 0xa9, 0x93, 0x13, 0x0a, 0x85, 0x0a, 0xf5, 0x0f, 0x02, 0xb7, - 0x5b, 0x6e, 0x39, 0xdd, 0x1d, 0xd7, 0xf6, 0x64, 0xb0, 0xeb, 0xa1, 0xf7, 0xe4, 0x26, 0xa7, 0xb7, - 0x1a, 0x92, 0x81, 0x99, 0x60, 0x49, 0xbe, 0x0c, 0x33, 0x6c, 0x72, 0xaf, 0x3e, 0x0a, 0x68, 0x87, - 0x8f, 0xfc, 0x1c, 0x4a, 0x74, 0x0b, 0x4a, 0x76, 0x97, 0xb0, 0x90, 0xcf, 0x29, 0x5c, 0xec, 0x34, - 0x24, 0xd0, 0x42, 0x3f, 0x6a, 0xac, 0x48, 0x13, 0x16, 0xef, 0xda, 0x8f, 0x94, 0x2c, 0xd5, 0xca, - 0x24, 0x25, 0x38, 0xc1, 0x2e, 0x1d, 0x1f, 0x15, 0x5f, 0x66, 0x13, 0x2c, 0x8a, 0xbf, 0xde, 0x67, - 0xbe, 0xf6, 0xe5, 0x44, 0xbe, 0x09, 0xe7, 0x44, 0xb3, 0x2a, 0x98, 0x59, 0xcd, 0xf5, 0x0e, 0xeb, - 0xfb, 0x36, 0x7a, 0xb8, 0xcd, 0xf7, 0xe9, 0xb0, 0xab, 0xe9, 0x5b, 0xa2, 0xec, 0xb0, 0xa6, 0xe4, - 0x63, 0xf9, 0x9c, 0x91, 0xd9, 0xaf, 0x06, 0xf2, 0x21, 0xcc, 0xf0, 0x07, 0xbf, 0x35, 0xd7, 0x0f, - 0x50, 0x59, 0xb3, 0x70, 0x3a, 0xb7, 0x0d, 0xfe, 0x8a, 0xc8, 0x5d, 0x9d, 0x62, 0xca, 0x9d, 0x18, - 0x67, 0xf2, 0x36, 0x4c, 0xd6, 0x9c, 0x0e, 0x0f, 0xce, 0x5a, 0xad, 0xa1, 0xe2, 0x5a, 0x9c, 0x40, - 0x5d, 0xa7, 0x63, 0x49, 0x8d, 0x49, 0x37, 0xdc, 0x2e, 0x54, 0x6c, 0xb2, 0x0d, 0x93, 0xf5, 0xfa, - 0xda, 0x4d, 0x87, 0xc9, 0x25, 0x5d, 0xa9, 0x87, 0x4e, 0x7e, 0xe5, 0x4b, 0xa9, 0x5f, 0x39, 0xed, - 0xfb, 0xfb, 0xd6, 0xae, 0xd3, 0xa2, 0x56, 0xc3, 0xed, 0x1e, 0x9a, 0x2a, 0xa7, 0x14, 0x57, 0x86, - 0x73, 0x4f, 0xd8, 0x95, 0xa1, 0x0a, 0xb3, 0x8a, 0x79, 0x2e, 0x9a, 0xe6, 0x2e, 0x46, 0x11, 0xbd, - 0x54, 0xd7, 0x85, 0xb8, 0xf3, 0x6e, 0x9c, 0x4e, 0xfa, 0x30, 0x9c, 0x3f, 0xad, 0x0f, 0x83, 0x03, - 0x73, 0x7c, 0x30, 0xc4, 0x3c, 0xc0, 0x91, 0x5e, 0xea, 0xd3, 0x87, 0x97, 0x53, 0xfb, 0x70, 0x5e, - 0x8c, 0xb4, 0x9c, 0x64, 0xf8, 0xc0, 0x9d, 0xe4, 0x4a, 0x76, 0x81, 0x08, 0xa0, 0x1d, 0xd8, 0x3b, - 0xb6, 0x4f, 0xb1, 0xae, 0x67, 0xfb, 0xd4, 0xf5, 0x72, 0x6a, 0x5d, 0x33, 0xb2, 0xae, 0x1d, 0x5e, - 0x4d, 0x0a, 0x47, 0xd2, 0x91, 0xf5, 0xc8, 0xf9, 0x85, 0x1d, 0xfb, 0x9c, 0xa6, 0xe3, 0x4e, 0x22, - 0xf0, 0xe0, 0x58, 0xf1, 0x49, 0x1b, 0xef, 0xf7, 0x14, 0xce, 0xe4, 0x11, 0x9c, 0x4d, 0x7e, 0x05, - 0xd6, 0xf9, 0x3c, 0xd6, 0xf9, 0xbc, 0x56, 0x67, 0x1c, 0x89, 0xcf, 0x1b, 0xbd, 0x59, 0xf1, 0x5a, - 0xfb, 0xf0, 0x27, 0x3f, 0x92, 0x81, 0x73, 0x77, 0x6f, 0x96, 0x30, 0xdf, 0xaa, 0xc3, 0x63, 0xf5, - 0x85, 0x4e, 0xcf, 0x2f, 0x88, 0x77, 0x90, 0xf8, 0x7b, 0x8c, 0x94, 0x38, 0x70, 0xab, 0x60, 0xa2, - 0xfb, 0x4b, 0xed, 0x5d, 0x9b, 0xa7, 0x71, 0x15, 0x2c, 0x52, 0x3c, 0xa3, 0xbf, 0xfd, 0x47, 0xc5, - 0x8c, 0xd9, 0xaf, 0x2a, 0xd2, 0x82, 0x25, 0xbd, 0x5b, 0xa4, 0x97, 0xc9, 0x3e, 0x6d, 0xb5, 0x16, - 0x8b, 0x38, 0xa3, 0x5f, 0x3f, 0x3e, 0x2a, 0x5e, 0x4a, 0xf4, 0x6e, 0xe8, 0xb9, 0xc2, 0x30, 0x95, - 0x06, 0x0f, 0xe0, 0x47, 0xda, 0x29, 0x42, 0xf7, 0xe2, 0x05, 0x2d, 0x3a, 0x52, 0xa2, 0x7c, 0xe5, - 0x15, 0x21, 0x91, 0x3c, 0xcf, 0xd6, 0x7b, 0x5f, 0x01, 0xd1, 0x4c, 0x72, 0xbe, 0x3d, 0x92, 0x9f, - 0x2e, 0xcc, 0xa4, 0xb8, 0x5f, 0x18, 0xbf, 0x9d, 0x8d, 0x1d, 0x8c, 0xa4, 0x0a, 0xe3, 0x62, 0xbe, - 0xf7, 0xbd, 0x64, 0x3c, 0x9f, 0x3a, 0xab, 0xc7, 0xc5, 0xd2, 0x31, 0x25, 0x3d, 0x79, 0xc8, 0x58, - 0x61, 0xa3, 0xc5, 0x8d, 0xf7, 0xab, 0xfc, 0xdc, 0x43, 0x90, 0x76, 0xc2, 0x57, 0x4e, 0xef, 0xaa, - 0xa8, 0x7b, 0xc2, 0xe2, 0x51, 0x2f, 0x6b, 0x23, 0x07, 0x3c, 0xd9, 0x56, 0x2e, 0xf4, 0x76, 0xd3, - 0x33, 0x6b, 0x3d, 0xb1, 0x0a, 0x59, 0x2d, 0xc6, 0x6f, 0x65, 0x60, 0x5a, 0x3b, 0x59, 0xc9, 0x0d, - 0xc5, 0x99, 0x33, 0x8a, 0x6f, 0xa0, 0xe1, 0xe0, 0x66, 0x1b, 0x77, 0xf3, 0xbc, 0x21, 0x3c, 0x1b, - 0xb2, 0xfd, 0xe9, 0x70, 0xb1, 0xc5, 0x7d, 0x7b, 0x07, 0xeb, 0x87, 0xc3, 0x4c, 0xa1, 0x23, 0x7d, - 0x32, 0x85, 0xfe, 0xfd, 0x22, 0xcc, 0xe8, 0x37, 0x62, 0xf2, 0x3a, 0x8c, 0xa1, 0x6e, 0x5e, 0xaa, - 0x57, 0x50, 0x2d, 0x84, 0xea, 0x7b, 0xcd, 0xdd, 0x85, 0xe3, 0x90, 0x57, 0x00, 0x42, 0x13, 0x73, - 0xf9, 0x32, 0x35, 0x7a, 0x7c, 0x54, 0xcc, 0xbc, 0x61, 0x2a, 0x05, 0xe4, 0x6b, 0x00, 0x1b, 0x6e, - 0x93, 0x86, 0xe9, 0x9f, 0x07, 0xd8, 0x77, 0xbc, 0x9a, 0x48, 0x44, 0x73, 0xa6, 0xe3, 0x36, 0x69, - 0x32, 0xeb, 0x8c, 0xc2, 0x91, 0x7c, 0x1e, 0x46, 0xcd, 0x5e, 0x8b, 0xca, 0x17, 0x8c, 0x49, 0x79, - 0xc2, 0xf5, 0x5a, 0x34, 0xd2, 0x13, 0x78, 0xbd, 0xb8, 0xe9, 0x22, 0x03, 0x90, 0xf7, 0x79, 0x82, - 0x1a, 0x11, 0x45, 0x75, 0x34, 0x7a, 0xab, 0x53, 0x24, 0x9f, 0x44, 0x1c, 0x55, 0x85, 0x84, 0xdc, - 0x83, 0x71, 0xf5, 0x91, 0x49, 0x89, 0x0a, 0xa0, 0x3e, 0x44, 0x2a, 0x4a, 0x07, 0x91, 0x37, 0x3a, - 0xfe, 0xfe, 0x24, 0xb9, 0x90, 0x77, 0x60, 0x82, 0xb1, 0x67, 0x3b, 0x87, 0x2f, 0x6e, 0x35, 0xf8, - 0x22, 0xa7, 0x7c, 0x10, 0xdb, 0x7d, 0xb4, 0x58, 0xa7, 0x21, 0x01, 0xf9, 0x32, 0x66, 0xfa, 0x15, - 0x5d, 0x3d, 0xd0, 0xee, 0xe7, 0x62, 0xa2, 0xab, 0x31, 0xf5, 0x6f, 0xa2, 0xa7, 0x23, 0x7e, 0x64, - 0x2f, 0x0c, 0x4a, 0x37, 0x4c, 0x52, 0xa1, 0xd7, 0x12, 0x15, 0x2c, 0xca, 0x38, 0x6b, 0xc9, 0x34, - 0xde, 0x1a, 0x5f, 0xd2, 0x85, 0x42, 0x24, 0x54, 0x8a, 0xba, 0x60, 0x50, 0x5d, 0x6f, 0x24, 0xea, - 0x52, 0x07, 0x30, 0x51, 0x5d, 0x82, 0x3b, 0x69, 0xc2, 0x8c, 0x3c, 0xa0, 0x44, 0x7d, 0x93, 0x83, - 0xea, 0x7b, 0x25, 0x51, 0xdf, 0x7c, 0x73, 0x27, 0x59, 0x4f, 0x8c, 0x27, 0x79, 0x07, 0xa6, 0x25, - 0x84, 0x27, 0xd5, 0x9e, 0x8a, 0xb2, 0x12, 0x37, 0x77, 0x12, 0xa9, 0xb4, 0x75, 0x64, 0x95, 0x9a, - 0xcf, 0x8e, 0x69, 0x8d, 0x3a, 0x3e, 0x2b, 0x74, 0x64, 0xf2, 0x01, 0x4c, 0x56, 0xdb, 0xac, 0x21, - 0x6e, 0xc7, 0x0e, 0xa8, 0xf0, 0x17, 0x95, 0x36, 0x4c, 0x4a, 0x89, 0x32, 0x55, 0x79, 0xba, 0xf0, - 0xa8, 0x48, 0x4b, 0x17, 0x1e, 0x81, 0x59, 0xe7, 0xf1, 0x57, 0x45, 0x31, 0x87, 0xa5, 0x2f, 0xe9, - 0xf3, 0x29, 0x76, 0x44, 0x0a, 0x7b, 0x11, 0x31, 0x93, 0x41, 0xe5, 0xab, 0x5e, 0x2c, 0x5a, 0xb1, - 0xca, 0x93, 0xbc, 0x0b, 0x93, 0x22, 0xdf, 0x5a, 0xc9, 0xdc, 0xf0, 0x17, 0x0b, 0xd8, 0x78, 0x8c, - 0x81, 0x21, 0x53, 0xb3, 0x59, 0xb6, 0x17, 0x33, 0x98, 0x8d, 0xf0, 0xc9, 0x97, 0x60, 0x61, 0xdb, - 0xe9, 0x34, 0xdd, 0x87, 0xbe, 0x38, 0xa6, 0xc4, 0x46, 0x37, 0x17, 0xb9, 0xab, 0x3d, 0xe4, 0xe5, - 0xa1, 0x2c, 0x98, 0xd8, 0xf8, 0x52, 0x39, 0x90, 0xef, 0x4b, 0x70, 0xe6, 0x33, 0x88, 0x0c, 0x9a, - 0x41, 0xcb, 0x89, 0x19, 0x94, 0xac, 0x3e, 0x3e, 0x9d, 0x52, 0xab, 0x21, 0x2e, 0x10, 0xfd, 0x7c, - 0xbf, 0xed, 0x3a, 0x9d, 0xc5, 0x79, 0xdc, 0x0b, 0x9f, 0x8d, 0x47, 0x9d, 0x40, 0x3c, 0x91, 0x76, - 0xdd, 0x38, 0x3e, 0x2a, 0xbe, 0x10, 0x97, 0xf9, 0x3f, 0x74, 0xb5, 0xe7, 0x92, 0x14, 0xd6, 0xe4, - 0x03, 0x98, 0x62, 0xff, 0x87, 0x4a, 0x89, 0x05, 0xcd, 0xf2, 0x54, 0xc1, 0x14, 0xf5, 0xe0, 0x18, - 0x61, 0x42, 0xb8, 0x14, 0x7d, 0x85, 0xc6, 0x8a, 0xbc, 0x05, 0xc0, 0xc4, 0x26, 0xb1, 0x1d, 0x9f, - 0x89, 0x82, 0x43, 0xa3, 0xd4, 0x95, 0xdc, 0x88, 0x23, 0x64, 0xf2, 0x0e, 0x4c, 0xb2, 0x5f, 0xf5, - 0x5e, 0xd3, 0x65, 0x6b, 0xe3, 0x2c, 0xd2, 0x72, 0xd7, 0x5d, 0x46, 0xeb, 0x73, 0xb8, 0xe6, 0xba, - 0x1b, 0xa1, 0x93, 0x35, 0x98, 0xc5, 0x20, 0xde, 0x22, 0x7c, 0xac, 0x43, 0xfd, 0xc5, 0x73, 0x8a, - 0x35, 0x04, 0x2b, 0xb2, 0x9c, 0xb0, 0x4c, 0xbd, 0xcb, 0xc4, 0xc8, 0x88, 0x0f, 0xf3, 0xc9, 0xe7, - 0x64, 0x7f, 0x71, 0x11, 0x3b, 0x49, 0x4a, 0xf0, 0x49, 0x0c, 0xbe, 0x1f, 0xb3, 0x11, 0x51, 0x36, - 0x2e, 0xf9, 0xa8, 0xa4, 0x56, 0x98, 0xc6, 0x9d, 0x98, 0x40, 0x6e, 0x95, 0x6b, 0xf1, 0x28, 0xd7, - 0xe7, 0xb1, 0x05, 0x38, 0xcc, 0x7b, 0x8d, 0x28, 0xcf, 0x7a, 0x4a, 0xa4, 0xeb, 0x14, 0x6a, 0xf2, - 0xbd, 0x70, 0x46, 0xee, 0x20, 0xa2, 0x48, 0xcc, 0xeb, 0xa5, 0x53, 0xee, 0xc4, 0xcd, 0x9d, 0xb0, - 0xea, 0xc4, 0x94, 0x4e, 0xaf, 0x82, 0xd8, 0x30, 0x89, 0xc3, 0x2a, 0x6a, 0x7c, 0x76, 0x50, 0x8d, - 0x97, 0x12, 0x35, 0x9e, 0xc5, 0x89, 0x92, 0xac, 0x4c, 0xe5, 0x49, 0x56, 0x60, 0x5a, 0xac, 0x23, - 0x31, 0xdb, 0x9e, 0xc3, 0xde, 0x42, 0x25, 0x96, 0x5c, 0x81, 0x89, 0x09, 0xa7, 0x93, 0xa8, 0x3b, - 0x32, 0x7f, 0x4c, 0x7a, 0x5e, 0xdb, 0x91, 0xe3, 0x6f, 0x48, 0x3a, 0x32, 0xdb, 0x91, 0x22, 0x29, - 0x66, 0xf5, 0x51, 0xd7, 0x13, 0x2a, 0xaa, 0x17, 0xa2, 0xbc, 0x51, 0x8a, 0xf0, 0x63, 0xd1, 0x10, - 0x43, 0xdd, 0x12, 0xd2, 0x38, 0x90, 0x2d, 0x98, 0x0f, 0x4f, 0x6d, 0x85, 0x71, 0x31, 0x8a, 0xa3, - 0x1c, 0x1d, 0xf5, 0xe9, 0x7c, 0xd3, 0xe8, 0x89, 0x0d, 0xe7, 0xb4, 0x73, 0x5a, 0x61, 0x7d, 0x01, - 0x59, 0x63, 0x5e, 0x7f, 0xfd, 0x90, 0x4f, 0x67, 0xdf, 0x8f, 0x0f, 0xf9, 0x10, 0x96, 0xe2, 0x67, - 0xb3, 0x52, 0xcb, 0x8b, 0x58, 0xcb, 0x6b, 0xc7, 0x47, 0xc5, 0x8b, 0x89, 0xe3, 0x3d, 0xbd, 0xa2, - 0x01, 0xdc, 0xc8, 0xd7, 0x60, 0x51, 0x3f, 0x9f, 0x95, 0x9a, 0x0c, 0xac, 0x09, 0x97, 0x4e, 0x78, - 0xb0, 0xa7, 0xd7, 0xd0, 0x97, 0x07, 0x09, 0xa0, 0x98, 0x3a, 0xbb, 0x95, 0x6a, 0x5e, 0x8a, 0x1a, - 0x94, 0x58, 0x25, 0xe9, 0xd5, 0x9d, 0xc4, 0x92, 0x3c, 0x84, 0x17, 0xd2, 0x8e, 0x09, 0xa5, 0xd2, - 0x97, 0x43, 0x25, 0xf0, 0xa7, 0xd2, 0x8f, 0x9c, 0xf4, 0x9a, 0x4f, 0x60, 0x4b, 0xbe, 0x0c, 0x67, - 0x94, 0xf5, 0xa5, 0xd4, 0xf7, 0x0a, 0xd6, 0x87, 0xce, 0xe6, 0xea, 0xc2, 0x4c, 0xaf, 0x25, 0x9d, - 0x07, 0x69, 0xc3, 0xbc, 0x6c, 0x38, 0x6a, 0xdb, 0xc5, 0xd1, 0x73, 0x51, 0xdb, 0x55, 0x93, 0x18, - 0x2b, 0x17, 0xc4, 0xae, 0xba, 0xd8, 0xdc, 0xb1, 0xba, 0x11, 0xa1, 0x3a, 0xd3, 0x53, 0xf8, 0x92, - 0x35, 0x18, 0xab, 0xd7, 0xaa, 0x37, 0x6f, 0xae, 0x2e, 0xbe, 0x8a, 0x35, 0x48, 0xcf, 0x34, 0x0e, - 0xd4, 0x2e, 0x4d, 0xc2, 0x5c, 0xb1, 0xeb, 0xec, 0xee, 0x6a, 0x0f, 0x56, 0x1c, 0x95, 0x7c, 0x1f, - 0x1a, 0x0a, 0xb2, 0x1d, 0xb5, 0xe4, 0xfb, 0xce, 0x1e, 0xc6, 0xe5, 0xf6, 0x17, 0x5f, 0xd3, 0xde, - 0xfb, 0x65, 0xcc, 0xf2, 0x32, 0xa6, 0x74, 0x4b, 0xa0, 0x73, 0x69, 0x93, 0xdd, 0xff, 0xc5, 0xce, - 0x6d, 0xd9, 0x11, 0x2b, 0x75, 0x13, 0x4f, 0x56, 0xc4, 0xfa, 0x6d, 0xcf, 0x09, 0xac, 0xfd, 0x9e, - 0xd6, 0xfc, 0xc5, 0x4f, 0x69, 0x31, 0xaa, 0x79, 0xa2, 0x3b, 0xa5, 0xd7, 0x5e, 0x16, 0x15, 0x3e, - 0xc7, 0x6f, 0xcb, 0x7d, 0x7a, 0x6e, 0x6e, 0x2f, 0x46, 0xe7, 0x93, 0x1f, 0xce, 0xc0, 0xd9, 0x6d, - 0xd7, 0x3b, 0x68, 0xb9, 0x76, 0x53, 0xb6, 0x4a, 0xec, 0xe1, 0xaf, 0x0f, 0xda, 0xc3, 0x3f, 0x93, - 0xd8, 0xc3, 0x8d, 0x87, 0x82, 0x8d, 0x15, 0x86, 0x7c, 0x4f, 0xec, 0xe7, 0x7d, 0xaa, 0x22, 0xdf, - 0x07, 0x17, 0xd2, 0x4b, 0x94, 0x49, 0xf9, 0x06, 0x4e, 0xca, 0x6b, 0xc7, 0x47, 0xc5, 0x37, 0xfa, - 0xd5, 0x94, 0x3e, 0x41, 0x4f, 0x64, 0x7d, 0x7b, 0x24, 0x7f, 0xa9, 0x70, 0xf9, 0xf6, 0x48, 0xfe, - 0x72, 0xe1, 0x35, 0xf3, 0xb9, 0x7a, 0xe9, 0xee, 0x7a, 0xb5, 0x29, 0x0f, 0x57, 0x19, 0x95, 0x9e, - 0xd3, 0x98, 0x17, 0x07, 0x95, 0x46, 0x1c, 0x8d, 0xbf, 0x99, 0x81, 0xe2, 0x09, 0x93, 0x84, 0x9d, - 0x67, 0xd1, 0x48, 0xd4, 0x69, 0xa0, 0xc6, 0xb6, 0x8f, 0xc6, 0xcf, 0xd2, 0xcd, 0x46, 0x74, 0x12, - 0x74, 0x6b, 0x14, 0x09, 0x55, 0x14, 0xef, 0xd6, 0x64, 0x22, 0x15, 0x89, 0x65, 0xac, 0x43, 0x21, - 0x3e, 0x79, 0xc8, 0xe7, 0x60, 0x5a, 0x4d, 0xe7, 0x20, 0x55, 0x09, 0x3c, 0x10, 0x8b, 0xb7, 0xa7, - 0x1d, 0x88, 0x1a, 0xa2, 0xf1, 0x4b, 0x19, 0x98, 0x4f, 0x59, 0x61, 0xe4, 0x22, 0x8c, 0x60, 0xbe, - 0x35, 0xc5, 0x6a, 0x28, 0x96, 0x67, 0x0d, 0xcb, 0xc9, 0xa7, 0x61, 0xbc, 0xb2, 0x51, 0xaf, 0x97, - 0x36, 0xa4, 0x32, 0x82, 0x1f, 0xc4, 0x1d, 0xdf, 0xf2, 0x6d, 0xdd, 0xd8, 0x40, 0xa0, 0x91, 0x37, - 0x60, 0xac, 0x5a, 0x43, 0x02, 0x6e, 0xfb, 0x8a, 0xed, 0x75, 0xba, 0x71, 0x7c, 0x81, 0x64, 0xfc, - 0x44, 0x06, 0x48, 0x72, 0xbb, 0x20, 0xd7, 0x60, 0x52, 0xdd, 0x94, 0x78, 0x7b, 0xf1, 0x05, 0x56, - 0x59, 0x38, 0xa6, 0x8a, 0x43, 0x2a, 0x30, 0x8a, 0x99, 0x72, 0x43, 0x2b, 0x87, 0xd4, 0x65, 0x71, - 0x2e, 0xb1, 0x2c, 0x46, 0x31, 0x0f, 0xaf, 0xc9, 0x89, 0x8d, 0xdf, 0xcd, 0x00, 0x49, 0xb7, 0x5d, - 0x1c, 0xca, 0xca, 0xea, 0x4d, 0x25, 0x3a, 0x82, 0x9a, 0x51, 0x29, 0x4c, 0x87, 0xa7, 0xaa, 0x01, - 0xa2, 0x38, 0x0a, 0x17, 0x35, 0xb5, 0x53, 0x7f, 0x97, 0xda, 0xcb, 0x30, 0x7a, 0x9f, 0x7a, 0x3b, - 0xd2, 0xac, 0x1b, 0x4d, 0x41, 0x1f, 0x30, 0x80, 0xaa, 0x86, 0x41, 0x0c, 0xe3, 0x4f, 0x32, 0xb0, - 0x90, 0x76, 0x47, 0x39, 0xc1, 0xf3, 0xd5, 0x88, 0x39, 0xed, 0xa2, 0x85, 0x15, 0xb7, 0x13, 0x0d, - 0x5d, 0x75, 0x8b, 0x30, 0xca, 0x1a, 0x2b, 0x47, 0x18, 0xd5, 0x60, 0xac, 0x37, 0x7c, 0x93, 0xc3, - 0x19, 0x02, 0x8f, 0x62, 0x38, 0x82, 0x01, 0x30, 0x11, 0x01, 0x67, 0xb7, 0xc9, 0xe1, 0x0c, 0xe1, - 0xae, 0xdb, 0xa4, 0x52, 0x3d, 0x84, 0x08, 0x6d, 0x06, 0x30, 0x39, 0x9c, 0x5c, 0x84, 0xf1, 0x7b, - 0x9d, 0x75, 0x6a, 0x3f, 0x90, 0x59, 0x3d, 0xd0, 0x22, 0xcc, 0xed, 0x58, 0x2d, 0x06, 0x33, 0x65, - 0xa1, 0xf1, 0x73, 0x19, 0x98, 0x4b, 0x5c, 0x8f, 0x4e, 0x76, 0xee, 0x1d, 0xec, 0x65, 0x37, 0x4c, - 0xfb, 0xf8, 0xe7, 0x8f, 0xa4, 0x7f, 0xbe, 0xf1, 0xdf, 0x8f, 0xc1, 0xb9, 0x3e, 0xda, 0xaa, 0xc8, - 0x0b, 0x38, 0x73, 0xa2, 0x17, 0xf0, 0x57, 0x60, 0xba, 0xdc, 0xb2, 0x9d, 0xb6, 0xbf, 0xe9, 0x46, - 0x5f, 0x1c, 0x39, 0x13, 0x61, 0x99, 0xf0, 0x83, 0x08, 0xbd, 0x4e, 0xce, 0x37, 0x90, 0xc2, 0x0a, - 0xdc, 0xa4, 0xb0, 0xac, 0x31, 0x4b, 0xf8, 0xe1, 0xe6, 0xfe, 0x92, 0xf8, 0xe1, 0xea, 0x9e, 0x61, - 0x23, 0x4f, 0xd4, 0x33, 0x2c, 0xdd, 0xe6, 0x7b, 0xf4, 0x71, 0x3c, 0x00, 0xca, 0x30, 0xcd, 0x4d, - 0xe2, 0x4a, 0x3e, 0x1f, 0xa4, 0xb1, 0x84, 0x19, 0x9d, 0xed, 0x27, 0xc7, 0x42, 0xa3, 0x21, 0x6b, - 0xba, 0x17, 0xd3, 0x38, 0xbe, 0x19, 0x5f, 0xec, 0xef, 0xa5, 0xa4, 0xd9, 0x8a, 0x68, 0xde, 0x4a, - 0xdf, 0x84, 0x85, 0xb4, 0xeb, 0xee, 0x62, 0x5e, 0xb3, 0xb6, 0xed, 0x6b, 0xa5, 0x3d, 0xfc, 0xa5, - 0xf9, 0x20, 0xf5, 0xd2, 0x2c, 0xbd, 0xcb, 0x27, 0xb4, 0xa0, 0xd7, 0x7d, 0xd6, 0x02, 0xc7, 0x1d, - 0xec, 0x83, 0x6e, 0x7c, 0x05, 0x9e, 0x1f, 0x48, 0x4e, 0xde, 0xd6, 0xa2, 0x18, 0xbd, 0x9a, 0x8c, - 0x62, 0xf4, 0xdd, 0xa3, 0xe2, 0x9c, 0xe6, 0x19, 0x7a, 0x37, 0x54, 0xf8, 0x1b, 0x3f, 0x97, 0xd5, - 0x7d, 0x9a, 0xff, 0x32, 0x2e, 0xd4, 0xcb, 0x30, 0xba, 0xbd, 0x4f, 0x3d, 0x79, 0x3c, 0xe0, 0x87, - 0x3c, 0x64, 0x00, 0xf5, 0x43, 0x10, 0x83, 0xdc, 0x84, 0x99, 0x1a, 0x9f, 0xb8, 0x72, 0x36, 0x8e, - 0x44, 0x3a, 0x97, 0xae, 0xd0, 0x0c, 0xa6, 0x4c, 0xc7, 0x18, 0x95, 0x71, 0x2b, 0xd6, 0xe9, 0x22, - 0x06, 0x13, 0xf7, 0x8c, 0xe2, 0x02, 0xc4, 0x4c, 0xe4, 0x6d, 0x16, 0x6d, 0xb6, 0x66, 0x0c, 0x6a, - 0xec, 0xc2, 0x0b, 0x03, 0x19, 0xb1, 0x73, 0x1b, 0xba, 0xe1, 0xaf, 0x98, 0xe5, 0xf5, 0x40, 0x52, - 0x53, 0xa1, 0x33, 0xbe, 0x09, 0x53, 0x6a, 0x2f, 0xe3, 0x11, 0xc4, 0x7e, 0x8b, 0x59, 0xc1, 0x8f, - 0x20, 0x06, 0x30, 0x39, 0x3c, 0x7a, 0xcb, 0xc9, 0xa6, 0xbf, 0xe5, 0x44, 0xc3, 0x9f, 0x3b, 0x69, - 0xf8, 0x59, 0xe5, 0xb8, 0xc3, 0x29, 0x95, 0xe3, 0x6f, 0xb5, 0x72, 0x0c, 0xb2, 0x64, 0x72, 0xf8, - 0x13, 0xad, 0xfc, 0x9f, 0xc8, 0x34, 0x70, 0xe8, 0x78, 0x25, 0x97, 0x7b, 0x26, 0xca, 0xe5, 0x96, - 0xb6, 0x7a, 0x23, 0xcc, 0x48, 0xa6, 0xc8, 0x9e, 0x24, 0x53, 0x9c, 0x66, 0x22, 0xa2, 0xdc, 0xcb, - 0x87, 0x74, 0x24, 0x92, 0x03, 0xed, 0x84, 0xb5, 0x8b, 0xc4, 0x32, 0xbe, 0x9d, 0x81, 0x33, 0xa9, - 0x3a, 0x73, 0x56, 0x2b, 0x57, 0xce, 0x2b, 0xeb, 0x30, 0xae, 0x99, 0xe7, 0x18, 0xa7, 0x89, 0xb0, - 0x31, 0x7c, 0x5b, 0x8c, 0x17, 0x61, 0x22, 0x7c, 0xb1, 0x25, 0x0b, 0x72, 0xe8, 0x78, 0x08, 0x3d, - 0xf1, 0xf0, 0x57, 0x07, 0x60, 0x5f, 0xf0, 0x44, 0x4d, 0xab, 0x8d, 0x7f, 0x92, 0xe5, 0x29, 0x82, - 0x9f, 0xda, 0x60, 0xbf, 0xe9, 0xf6, 0xd0, 0xac, 0x49, 0xfd, 0x43, 0xfc, 0x92, 0x55, 0x18, 0xab, - 0x07, 0x76, 0xd0, 0x93, 0x81, 0x41, 0xe6, 0x55, 0x32, 0x2c, 0xb8, 0xbf, 0x1c, 0x85, 0x86, 0xf0, - 0x11, 0xa2, 0x69, 0x09, 0x10, 0xa2, 0x98, 0x55, 0xff, 0x41, 0x06, 0xa6, 0x54, 0x62, 0xf2, 0x01, - 0xcc, 0xc8, 0x00, 0xa6, 0x3c, 0x5c, 0x8a, 0x78, 0x5e, 0x96, 0xa6, 0x60, 0x32, 0x80, 0xa9, 0x1a, - 0x5e, 0x45, 0xc3, 0x57, 0xb7, 0xea, 0xae, 0x8a, 0x4c, 0x9a, 0x40, 0xda, 0xbb, 0xb6, 0xf5, 0x90, - 0xda, 0x07, 0xd4, 0x0f, 0x2c, 0x6e, 0xb2, 0x23, 0x5e, 0xa1, 0x25, 0xfb, 0xbb, 0x37, 0x4b, 0xdc, - 0x5a, 0x87, 0x8d, 0x84, 0x88, 0x44, 0x9b, 0xa0, 0x51, 0x9f, 0xd6, 0xda, 0xbb, 0xf6, 0x36, 0x2f, - 0xe4, 0x74, 0xc6, 0x9f, 0x8e, 0xf1, 0xe9, 0x26, 0x22, 0x1e, 0xef, 0xc0, 0xcc, 0xbd, 0x6a, 0xa5, - 0xac, 0x28, 0xda, 0xf5, 0x84, 0x59, 0xab, 0x8f, 0x02, 0xea, 0x75, 0xec, 0x96, 0xbc, 0xef, 0x46, - 0x47, 0x90, 0xeb, 0x34, 0x1b, 0xe9, 0x4a, 0xf8, 0x18, 0x47, 0x56, 0x07, 0xbf, 0x59, 0x87, 0x75, - 0x64, 0x87, 0xac, 0xc3, 0xb7, 0xdb, 0xad, 0x3e, 0x75, 0xe8, 0x1c, 0xc9, 0x3e, 0x5e, 0x7d, 0xf7, - 0x7b, 0x3b, 0x4a, 0x2d, 0xb9, 0xc1, 0xb5, 0xbc, 0x24, 0x6a, 0x79, 0x56, 0xa8, 0x55, 0x52, 0xeb, - 0x49, 0x70, 0x8d, 0xf6, 0x89, 0x91, 0x13, 0xf7, 0x89, 0xbf, 0x9e, 0x81, 0x31, 0x2e, 0xbe, 0x8a, - 0x69, 0xdc, 0x47, 0x40, 0xde, 0x7e, 0x32, 0x02, 0x72, 0x01, 0xcf, 0x09, 0x6d, 0x42, 0xf3, 0x32, - 0x52, 0x89, 0xad, 0x0b, 0xe9, 0x0d, 0x80, 0x4f, 0x66, 0xbc, 0xe4, 0xe4, 0x65, 0x41, 0xaa, 0x51, - 0xb0, 0x8e, 0xf1, 0x13, 0x3d, 0xb4, 0x65, 0x80, 0x93, 0x71, 0x11, 0xac, 0x43, 0x0f, 0xd1, 0xb1, - 0x0e, 0x13, 0x22, 0x04, 0xc8, 0xca, 0xa1, 0x78, 0x18, 0x2f, 0x68, 0xa6, 0x4d, 0xcd, 0x95, 0xc3, - 0x48, 0x34, 0x17, 0x41, 0x44, 0xac, 0x9d, 0x43, 0x2d, 0xe3, 0xb2, 0x44, 0x24, 0xf7, 0x78, 0x26, - 0x52, 0x1e, 0x11, 0x5a, 0x4f, 0x02, 0x11, 0xc2, 0x45, 0x70, 0x31, 0x19, 0x47, 0x20, 0x25, 0x00, - 0x74, 0xc4, 0x83, 0xac, 0x43, 0x01, 0xcd, 0xe1, 0x68, 0x93, 0xaf, 0x9a, 0x6a, 0x85, 0x87, 0x99, - 0x10, 0x26, 0xcd, 0x01, 0x2f, 0x13, 0xcb, 0x2d, 0xe6, 0x7f, 0x99, 0xa0, 0x34, 0x7e, 0x36, 0x0b, - 0x85, 0xf8, 0xec, 0x23, 0xef, 0xc0, 0x64, 0x18, 0x91, 0x3b, 0xf4, 0x00, 0xc7, 0x07, 0xb2, 0x28, - 0x84, 0xb7, 0x9e, 0xbf, 0x52, 0x41, 0x27, 0xcb, 0x90, 0x67, 0x8b, 0x38, 0x9e, 0xeb, 0xb9, 0x27, - 0x60, 0xaa, 0x47, 0x96, 0xc4, 0x23, 0x75, 0x98, 0x67, 0x8b, 0xa6, 0xee, 0x74, 0xf6, 0x5a, 0x74, - 0xdd, 0xdd, 0x73, 0x7b, 0x41, 0x94, 0xce, 0x91, 0x5f, 0x60, 0xec, 0x76, 0x4b, 0x2b, 0xd6, 0x93, - 0x39, 0xa6, 0x50, 0x2b, 0x99, 0xe8, 0x47, 0x86, 0xc8, 0x44, 0xaf, 0xec, 0xac, 0x7f, 0x94, 0x85, - 0x49, 0x65, 0xfa, 0x91, 0xcb, 0x90, 0xaf, 0xfa, 0xeb, 0x6e, 0xe3, 0x20, 0x0c, 0x56, 0x39, 0x7d, - 0x7c, 0x54, 0x9c, 0x70, 0x7c, 0xab, 0x85, 0x40, 0x33, 0x2c, 0x26, 0x2b, 0x30, 0xcd, 0xff, 0x92, - 0xa9, 0x55, 0xb2, 0x91, 0x6e, 0x8d, 0x23, 0xcb, 0xa4, 0x2a, 0xea, 0x66, 0xab, 0x91, 0x90, 0xaf, - 0x02, 0x70, 0x00, 0x86, 0x37, 0xc8, 0x0d, 0x1f, 0x98, 0x41, 0x54, 0x90, 0x12, 0xd8, 0x40, 0x61, - 0x48, 0xbe, 0xce, 0x03, 0x7e, 0xcb, 0xe5, 0x32, 0x32, 0x7c, 0x64, 0x09, 0xc6, 0xdf, 0x4a, 0x0f, - 0x70, 0xa3, 0xb2, 0x14, 0xd9, 0x90, 0x96, 0x4c, 0xda, 0x70, 0x1f, 0x50, 0xef, 0xb0, 0x14, 0x20, - 0xa2, 0x82, 0x61, 0xfc, 0x2f, 0x19, 0x65, 0x91, 0x91, 0x0d, 0xcc, 0x66, 0xce, 0x27, 0x90, 0x30, - 0x29, 0x0b, 0xaf, 0x18, 0x12, 0x6e, 0xd2, 0xdd, 0x95, 0x67, 0x85, 0x75, 0xdb, 0x7c, 0x38, 0x0d, - 0x63, 0x59, 0xce, 0x39, 0x90, 0x7c, 0x01, 0x46, 0xb0, 0xeb, 0xb2, 0x27, 0x36, 0x4d, 0x9e, 0xf2, - 0x23, 0xac, 0xcf, 0xb0, 0x21, 0x48, 0x49, 0x3e, 0x2d, 0x1c, 0xb7, 0x79, 0xe7, 0xcf, 0x28, 0x47, - 0x35, 0xfb, 0x8e, 0xf0, 0x78, 0x8f, 0x62, 0x1c, 0x29, 0xb3, 0xe7, 0x6f, 0x66, 0xa1, 0x10, 0x5f, - 0xda, 0xe4, 0x7d, 0x98, 0x92, 0xc7, 0xef, 0x9a, 0x2d, 0xf2, 0x82, 0x4c, 0x89, 0xbc, 0x1c, 0xf2, - 0x0c, 0xde, 0xb7, 0x55, 0x13, 0x34, 0x53, 0x23, 0x60, 0xb2, 0xd0, 0xa6, 0x88, 0x39, 0xa8, 0x2c, - 0xaa, 0xc0, 0x0d, 0xba, 0xb1, 0x38, 0xd3, 0x12, 0x8d, 0xbc, 0x09, 0xb9, 0xbb, 0x37, 0x4b, 0xc2, - 0xc1, 0xaf, 0x10, 0x3f, 0xa4, 0xb9, 0xa5, 0xac, 0x6e, 0xb7, 0xcb, 0xf0, 0xc9, 0xba, 0x12, 0x92, - 0x7d, 0x4c, 0x33, 0x37, 0x94, 0xe0, 0xb0, 0x71, 0x27, 0xc7, 0x66, 0xbf, 0x3d, 0x92, 0xcf, 0x15, - 0x46, 0x44, 0x98, 0xde, 0x7f, 0x9e, 0x83, 0x89, 0xb0, 0x7e, 0x42, 0x54, 0xb7, 0x69, 0xee, 0x22, - 0x4d, 0xce, 0x43, 0x5e, 0x4a, 0x77, 0xc2, 0xcf, 0x6f, 0xdc, 0x17, 0x92, 0xdd, 0x22, 0x48, 0x31, - 0x8e, 0xef, 0x0a, 0xa6, 0xfc, 0x49, 0xae, 0x41, 0x28, 0xa3, 0xf5, 0x13, 0xe6, 0x46, 0xd8, 0x80, - 0x99, 0x21, 0x1a, 0x99, 0x81, 0xac, 0xc3, 0x43, 0xbf, 0x4d, 0x98, 0x59, 0xa7, 0x49, 0xde, 0x87, - 0xbc, 0xdd, 0x6c, 0xd2, 0xa6, 0x65, 0x4b, 0xdb, 0xac, 0x41, 0x93, 0x26, 0xcf, 0xb8, 0xf1, 0x33, - 0x03, 0xa9, 0x4a, 0x01, 0x29, 0xc1, 0x04, 0x8f, 0x25, 0xed, 0xd3, 0xe6, 0x10, 0x07, 0x50, 0xc4, - 0x01, 0x43, 0x50, 0x6f, 0xf9, 0xb4, 0x49, 0x5e, 0x85, 0x11, 0x36, 0x9a, 0xe2, 0xc4, 0x91, 0x42, - 0x25, 0x1b, 0x4c, 0xde, 0x61, 0x6b, 0xcf, 0x98, 0x88, 0x40, 0x5e, 0x86, 0x5c, 0x6f, 0x79, 0x57, - 0x9c, 0x25, 0x85, 0x28, 0x3d, 0x42, 0x88, 0xc6, 0x8a, 0xc9, 0x75, 0xc8, 0x3f, 0xd4, 0x23, 0xeb, - 0x9f, 0x89, 0x0d, 0x63, 0x88, 0x1f, 0x22, 0x92, 0x57, 0x21, 0xe7, 0xfb, 0xae, 0x30, 0x68, 0x9a, - 0x0f, 0xad, 0x4c, 0xef, 0x85, 0xa3, 0xc6, 0xb8, 0xfb, 0xbe, 0xbb, 0x92, 0x87, 0x31, 0x7e, 0xc0, - 0x18, 0x2f, 0x00, 0x44, 0xdf, 0x98, 0xf4, 0xdb, 0x34, 0xbe, 0x0a, 0x13, 0xe1, 0xb7, 0x91, 0xe7, - 0x01, 0x0e, 0xe8, 0xa1, 0xb5, 0x6f, 0x77, 0x9a, 0x2d, 0x2e, 0x9d, 0x4e, 0x99, 0x13, 0x07, 0xf4, - 0x70, 0x0d, 0x01, 0xe4, 0x1c, 0x8c, 0x77, 0xd9, 0xf0, 0x8b, 0x39, 0x3e, 0x65, 0x8e, 0x75, 0x7b, - 0x3b, 0x6c, 0x2a, 0x2f, 0xc2, 0x38, 0xea, 0x59, 0xc5, 0x8a, 0x9c, 0x36, 0xe5, 0x4f, 0xe3, 0xcf, - 0x72, 0x98, 0x80, 0x4a, 0x69, 0x10, 0x79, 0x09, 0xa6, 0x1b, 0x1e, 0xc5, 0xb3, 0xcc, 0x66, 0x12, - 0x9a, 0xa8, 0x67, 0x2a, 0x02, 0x56, 0x9b, 0xe4, 0x22, 0xcc, 0x76, 0x7b, 0x3b, 0x2d, 0xa7, 0xc1, - 0x6a, 0xb3, 0x1a, 0x3b, 0x22, 0x63, 0xc6, 0x94, 0x39, 0xcd, 0xc1, 0x77, 0xe8, 0x61, 0x79, 0x07, - 0x63, 0x1b, 0x16, 0xd4, 0xd0, 0xd4, 0xac, 0x47, 0xc4, 0xfc, 0x9b, 0x55, 0xe0, 0x68, 0x9b, 0x79, - 0x16, 0xc6, 0x6c, 0x7b, 0xaf, 0xe7, 0xf0, 0x18, 0x64, 0x53, 0xa6, 0xf8, 0x45, 0x3e, 0x05, 0x73, - 0x51, 0xac, 0x77, 0xd9, 0x8c, 0x51, 0x6c, 0x46, 0x21, 0x2c, 0x28, 0x73, 0x38, 0x79, 0x03, 0x88, - 0x5a, 0x9f, 0xbb, 0xf3, 0x21, 0x6d, 0xf0, 0x39, 0x39, 0x65, 0xce, 0x29, 0x25, 0xf7, 0xb0, 0x80, - 0xbc, 0x08, 0x53, 0x1e, 0xf5, 0x51, 0x3a, 0xc4, 0x6e, 0xc3, 0xfc, 0x8c, 0xe6, 0xa4, 0x84, 0xb1, - 0xbe, 0xbb, 0x04, 0x05, 0xa5, 0x3b, 0x30, 0xfa, 0x37, 0x4f, 0x16, 0x61, 0xce, 0x44, 0x70, 0xb3, - 0x5b, 0x6d, 0x92, 0x2f, 0xc1, 0x92, 0x82, 0xc9, 0x53, 0x45, 0x5a, 0xb4, 0xe5, 0xec, 0x39, 0x3b, - 0x2d, 0x2a, 0xe6, 0x5b, 0x72, 0x56, 0x87, 0x57, 0x48, 0x73, 0x31, 0xa2, 0xe6, 0x49, 0x24, 0x57, - 0x05, 0x2d, 0x59, 0x87, 0x85, 0x18, 0x67, 0xda, 0xb4, 0x7a, 0xdd, 0xbe, 0x41, 0xff, 0x22, 0x9e, - 0x44, 0xe7, 0x49, 0x9b, 0x5b, 0x5d, 0xe3, 0x9b, 0x30, 0xa5, 0xce, 0x49, 0xd6, 0x09, 0xaa, 0x5c, - 0x22, 0x66, 0xdf, 0x64, 0x08, 0xab, 0xb2, 0x7b, 0xe1, 0x4c, 0x84, 0x82, 0x83, 0xc8, 0xb7, 0x97, - 0xe9, 0x10, 0x8a, 0x43, 0xf8, 0x22, 0x4c, 0x35, 0x1d, 0xbf, 0xdb, 0xb2, 0x0f, 0xad, 0x28, 0x07, - 0xba, 0x39, 0x29, 0x60, 0xa8, 0xf8, 0x59, 0x81, 0xb9, 0xc4, 0x3e, 0xa8, 0x48, 0x1a, 0x7c, 0x5f, - 0x1f, 0x2c, 0x69, 0x18, 0x1d, 0x98, 0x52, 0xcf, 0xb5, 0x13, 0x52, 0xbb, 0x9c, 0xc5, 0x30, 0x3c, - 0x7c, 0xd3, 0x1f, 0x3b, 0x3e, 0x2a, 0x66, 0x9d, 0x26, 0x06, 0xdf, 0xb9, 0x04, 0x79, 0x29, 0xb1, - 0x09, 0x41, 0x09, 0x1f, 0x13, 0xe4, 0xd3, 0xa4, 0x19, 0x96, 0x1a, 0xaf, 0xc2, 0xb8, 0x38, 0xba, - 0x06, 0x3f, 0x21, 0x18, 0xdf, 0xca, 0xc2, 0xac, 0x49, 0xd9, 0xc6, 0x4a, 0x79, 0x3e, 0xa7, 0xa7, - 0xf6, 0x8a, 0x9e, 0x1e, 0x2e, 0x56, 0x6b, 0xdb, 0x80, 0x4c, 0x4a, 0xbf, 0x9a, 0x81, 0xf9, 0x14, - 0xdc, 0x8f, 0x94, 0x49, 0xf8, 0x06, 0x4c, 0x54, 0x1c, 0xbb, 0x55, 0x6a, 0x36, 0xc3, 0x98, 0x3c, - 0x28, 0xe7, 0x63, 0xba, 0x31, 0x9b, 0x41, 0x55, 0x21, 0x26, 0x44, 0x25, 0xaf, 0x89, 0x49, 0x11, - 0xe5, 0xe1, 0xc7, 0x49, 0xf1, 0xdd, 0xa3, 0x22, 0xf0, 0x6f, 0xda, 0x0c, 0xa7, 0x08, 0x86, 0x70, - 0xe6, 0xc0, 0xc8, 0xaf, 0xea, 0xa9, 0x1d, 0xba, 0xf4, 0x10, 0xce, 0xf1, 0xe6, 0x0d, 0x95, 0x4c, - 0xe9, 0x27, 0xb3, 0x70, 0x36, 0x9d, 0xf0, 0xa3, 0x26, 0x85, 0xc6, 0x34, 0x56, 0x4a, 0xd8, 0x79, - 0x4c, 0x0a, 0xcd, 0x73, 0x5e, 0x21, 0x7e, 0x84, 0x40, 0x76, 0x61, 0x7a, 0xdd, 0xf6, 0x83, 0x35, - 0x6a, 0x7b, 0xc1, 0x0e, 0xb5, 0x83, 0x21, 0x24, 0x79, 0x69, 0x4d, 0xb1, 0x88, 0xc2, 0xc4, 0xbe, - 0xa4, 0x8c, 0xc9, 0xda, 0x3a, 0xdb, 0x70, 0xa2, 0x8c, 0x0c, 0x31, 0x51, 0xbe, 0x01, 0xb3, 0x75, - 0xda, 0xb6, 0xbb, 0xfb, 0xae, 0x27, 0xe3, 0x25, 0x5c, 0x81, 0xe9, 0x10, 0x94, 0x3a, 0x5b, 0xf4, - 0x62, 0x0d, 0x5f, 0xe9, 0x88, 0x68, 0x2b, 0xd1, 0x8b, 0x8d, 0xbf, 0x95, 0x85, 0x73, 0xa5, 0x86, - 0x30, 0x0d, 0x15, 0x05, 0xd2, 0x82, 0xfd, 0x63, 0xae, 0x9b, 0x5c, 0x85, 0x89, 0xbb, 0xf6, 0xa3, - 0x75, 0x6a, 0xfb, 0xd4, 0x17, 0x29, 0x39, 0xb9, 0xd8, 0x6b, 0x3f, 0x8a, 0x1e, 0x7f, 0xcc, 0x08, - 0x47, 0x55, 0x23, 0x8c, 0x3c, 0xa6, 0x1a, 0xc1, 0x80, 0xb1, 0x35, 0xb7, 0xd5, 0x14, 0x67, 0xbd, - 0x78, 0x71, 0xde, 0x47, 0x88, 0x29, 0x4a, 0x8c, 0x3f, 0xc9, 0xc0, 0x4c, 0xf8, 0xc5, 0xf8, 0x09, - 0x1f, 0x7b, 0x97, 0x5c, 0x84, 0x71, 0xac, 0xa8, 0x5a, 0x51, 0x0f, 0x8d, 0x16, 0xc5, 0xc4, 0x8a, - 0x4d, 0x53, 0x16, 0xaa, 0x3d, 0x31, 0xfa, 0x78, 0x3d, 0x61, 0xfc, 0x03, 0x7c, 0xcc, 0x56, 0x5b, - 0xc9, 0x4e, 0x22, 0xe5, 0x43, 0x32, 0x43, 0x7e, 0x48, 0xf6, 0x89, 0x0d, 0x49, 0xae, 0xef, 0x90, - 0xfc, 0x68, 0x16, 0x26, 0xc3, 0x8f, 0xfd, 0x84, 0xe5, 0x3e, 0x08, 0xdb, 0x35, 0x54, 0x8c, 0xa3, - 0xba, 0xb2, 0x57, 0x88, 0x50, 0x42, 0x5f, 0x80, 0x31, 0xb1, 0x98, 0x32, 0x31, 0x4b, 0xee, 0xd8, - 0xe8, 0xae, 0xcc, 0x08, 0xd6, 0x63, 0x38, 0xa0, 0xbe, 0x29, 0xe8, 0x30, 0x88, 0xd4, 0x36, 0xdd, - 0x11, 0xb6, 0x0d, 0x4f, 0xed, 0x19, 0x95, 0x1e, 0x44, 0x2a, 0x6a, 0xd8, 0x50, 0xa7, 0xd3, 0x3f, - 0xcb, 0x43, 0x21, 0x4e, 0x72, 0x72, 0x76, 0x89, 0x5a, 0x6f, 0x87, 0x5f, 0x55, 0x78, 0x76, 0x89, - 0x6e, 0x6f, 0xc7, 0x64, 0x30, 0x34, 0x7d, 0xf2, 0x9c, 0x07, 0xd8, 0xea, 0x29, 0x61, 0xfa, 0xe4, - 0x39, 0x0f, 0x34, 0xd3, 0x27, 0xcf, 0x79, 0x80, 0x8a, 0x84, 0xf5, 0x3a, 0x06, 0x58, 0xc0, 0x7b, - 0x8a, 0x50, 0x24, 0xb4, 0xfc, 0x78, 0x9e, 0x3b, 0x89, 0xc6, 0x8e, 0xca, 0x15, 0x6a, 0x7b, 0x22, - 0x13, 0x82, 0xd8, 0xce, 0xf0, 0xa8, 0xdc, 0x41, 0xb0, 0x15, 0x30, 0xb8, 0xa9, 0x22, 0x91, 0x16, - 0x10, 0xe5, 0xa7, 0x5c, 0xc0, 0x27, 0xdf, 0xad, 0xa5, 0x15, 0xe6, 0x82, 0xca, 0xda, 0x52, 0x57, - 0x73, 0x0a, 0xdf, 0x27, 0xa9, 0xfd, 0xad, 0x89, 0xf0, 0xae, 0xa8, 0x40, 0xca, 0x9f, 0xc8, 0x4c, - 0x06, 0x86, 0x01, 0x1e, 0xfe, 0x35, 0x54, 0x23, 0x45, 0x4c, 0xc8, 0x7b, 0x30, 0xa9, 0x86, 0xcd, - 0xe0, 0xc1, 0x1d, 0x9e, 0xe3, 0xf1, 0x34, 0xfb, 0xe4, 0x46, 0x56, 0x09, 0xc8, 0x0e, 0x9c, 0x2b, - 0xbb, 0x1d, 0xbf, 0xd7, 0x96, 0x91, 0x3b, 0xa3, 0x88, 0xe4, 0x80, 0x43, 0x81, 0x3e, 0xf8, 0x0d, - 0x81, 0x22, 0xa2, 0x34, 0x48, 0x37, 0x19, 0xfd, 0x02, 0xd2, 0x8f, 0x11, 0xd9, 0x84, 0x49, 0xd4, - 0xa0, 0x0a, 0x93, 0xc7, 0x49, 0x7d, 0xdb, 0x88, 0x4a, 0x2a, 0x6c, 0x61, 0xf0, 0xa8, 0x71, 0x76, - 0xbb, 0x25, 0xbd, 0x34, 0x54, 0x4d, 0xb0, 0x82, 0x4c, 0xbe, 0x0a, 0x33, 0xfc, 0x8a, 0xb6, 0x4d, - 0x77, 0xf8, 0xdc, 0x99, 0xd2, 0x34, 0x11, 0x7a, 0x21, 0x7f, 0xcc, 0x17, 0x7a, 0xeb, 0x87, 0x74, - 0x87, 0x8f, 0xbd, 0xe6, 0x23, 0xa5, 0xe1, 0x93, 0x2d, 0x98, 0x5f, 0xb3, 0x7d, 0x0e, 0x54, 0xe2, - 0x1f, 0x4c, 0xa3, 0x86, 0x16, 0x6d, 0xd7, 0xf7, 0x6d, 0x5f, 0x2a, 0xc2, 0x53, 0xe3, 0x1d, 0xa4, - 0xd1, 0x93, 0x6f, 0x65, 0x60, 0x51, 0xd3, 0x93, 0x0b, 0x3b, 0xb3, 0x36, 0xed, 0x04, 0xe8, 0x0c, - 0x35, 0xb3, 0x5c, 0x94, 0x42, 0x69, 0x1f, 0x34, 0x3e, 0x24, 0x31, 0x55, 0xbc, 0x17, 0x95, 0xab, - 0x46, 0xe1, 0xfd, 0x78, 0x88, 0x85, 0x8a, 0x6b, 0x7a, 0x56, 0x5f, 0xa8, 0xb1, 0x75, 0x2d, 0xd1, - 0x8c, 0x1b, 0xf1, 0xfe, 0x16, 0x8a, 0xae, 0x4c, 0xa8, 0xe8, 0x5a, 0x80, 0x51, 0xec, 0x55, 0x19, - 0x45, 0x0b, 0x7f, 0x18, 0x9f, 0x56, 0xf7, 0x21, 0x21, 0x16, 0x0e, 0xdc, 0x87, 0x8c, 0xff, 0x71, - 0x0c, 0x66, 0x63, 0xd3, 0x42, 0xdc, 0x53, 0x33, 0x89, 0x7b, 0x6a, 0x1d, 0x80, 0xab, 0x7a, 0x87, - 0xd4, 0xc9, 0x4a, 0x47, 0xcc, 0x49, 0xe1, 0x46, 0x1d, 0xae, 0x29, 0x85, 0x0d, 0x63, 0xca, 0x57, - 0xec, 0x90, 0x3a, 0xf2, 0x90, 0x29, 0x5f, 0xf4, 0x0a, 0xd3, 0x88, 0x0d, 0x29, 0xc2, 0x28, 0xc6, - 0xcf, 0x55, 0xfd, 0x60, 0x1d, 0x06, 0x30, 0x39, 0x9c, 0xbc, 0x04, 0x63, 0x4c, 0x88, 0xaa, 0x56, - 0xc4, 0x26, 0x88, 0x67, 0x0b, 0x93, 0xb2, 0x98, 0xc4, 0x22, 0x8a, 0xc8, 0x0d, 0x98, 0xe2, 0x7f, - 0x89, 0x30, 0x3b, 0x63, 0xba, 0xf1, 0xa3, 0xe5, 0x34, 0x65, 0xa4, 0x1d, 0x0d, 0x8f, 0xdd, 0x2e, - 0xea, 0x3d, 0x54, 0xeb, 0x54, 0x2b, 0x22, 0xa4, 0x3b, 0xde, 0x2e, 0x7c, 0x0e, 0x64, 0x55, 0x44, - 0x08, 0x4c, 0x96, 0x11, 0xde, 0x28, 0x79, 0xbc, 0x53, 0xa2, 0x2c, 0xc3, 0xbd, 0x50, 0x4c, 0x51, - 0x42, 0x2e, 0xf3, 0x97, 0x18, 0x14, 0x0b, 0x79, 0x5e, 0x4f, 0x7c, 0xb7, 0x40, 0xc5, 0x04, 0xca, - 0x86, 0x61, 0x31, 0xab, 0x9c, 0xfd, 0xbd, 0xda, 0xb6, 0x9d, 0x96, 0xd8, 0x56, 0xb0, 0x72, 0xc4, - 0xa5, 0x0c, 0x6a, 0x46, 0x08, 0xe4, 0x1d, 0x98, 0xe1, 0xf9, 0xf7, 0xda, 0x6d, 0xb7, 0x83, 0xec, - 0x27, 0xa3, 0x40, 0x7a, 0x22, 0x27, 0x20, 0x2b, 0xe2, 0xb5, 0xc4, 0x70, 0xd9, 0x79, 0x82, 0xaf, - 0xbc, 0x3d, 0xfe, 0x46, 0x34, 0x15, 0x9d, 0x27, 0x48, 0xea, 0x73, 0xb8, 0xa9, 0x22, 0x91, 0xb7, - 0x60, 0x9a, 0xfd, 0xbc, 0xe5, 0x3c, 0xa0, 0xbc, 0xc2, 0xe9, 0xc8, 0xbc, 0x01, 0xa9, 0xf6, 0x58, - 0x09, 0xaf, 0x4f, 0xc7, 0x24, 0x5f, 0x84, 0x33, 0xc8, 0xa9, 0xe1, 0x76, 0x69, 0xb3, 0xb4, 0xbb, - 0xeb, 0xb4, 0x1c, 0x6e, 0x8d, 0xc6, 0x03, 0xca, 0xa0, 0x0e, 0x9e, 0x57, 0x8c, 0x18, 0x96, 0x1d, - 0xa1, 0x98, 0xe9, 0x94, 0x64, 0x1b, 0x0a, 0xe5, 0x9e, 0x1f, 0xb8, 0xed, 0x52, 0x10, 0x78, 0xce, - 0x4e, 0x2f, 0xa0, 0xfe, 0xe2, 0xac, 0x16, 0x76, 0x85, 0x2d, 0x8e, 0xb0, 0x90, 0xeb, 0x83, 0x1a, - 0x48, 0x61, 0xd9, 0x21, 0x89, 0x99, 0x60, 0x62, 0xfc, 0x8b, 0x0c, 0x4c, 0x6b, 0xa4, 0xe4, 0x4d, - 0x98, 0xba, 0xe9, 0x39, 0xb4, 0xd3, 0x6c, 0x1d, 0x2a, 0x17, 0x55, 0xbc, 0xc5, 0xec, 0x0a, 0x38, - 0x6f, 0xb5, 0x86, 0x16, 0xea, 0x79, 0xb2, 0xa9, 0xa6, 0xa2, 0x57, 0xb9, 0x3b, 0xb6, 0x98, 0xa0, - 0xb9, 0x28, 0x0e, 0x14, 0x4e, 0x50, 0x31, 0x3b, 0x15, 0x14, 0xf2, 0x2e, 0x8c, 0xf1, 0xf7, 0x60, - 0x61, 0xb7, 0x78, 0x3e, 0xad, 0x99, 0xdc, 0xf5, 0x1f, 0x27, 0x22, 0x1a, 0xfd, 0xf8, 0xa6, 0x20, - 0x32, 0x7e, 0x3e, 0x03, 0x24, 0x89, 0x7a, 0x82, 0xde, 0xeb, 0x44, 0x63, 0xa2, 0x2f, 0x84, 0xab, - 0x31, 0xa7, 0xe9, 0xcc, 0x59, 0x4d, 0xbc, 0x80, 0x77, 0xbc, 0x58, 0x75, 0xaa, 0x22, 0x8e, 0x17, - 0x1b, 0x3f, 0x92, 0x05, 0x88, 0xb0, 0xc9, 0xe7, 0x78, 0x22, 0xb4, 0x2f, 0xf6, 0xec, 0x96, 0xb3, - 0xeb, 0xe8, 0x71, 0x7b, 0x91, 0xc9, 0x37, 0x64, 0x89, 0xa9, 0x23, 0x92, 0xf7, 0x61, 0xb6, 0x5e, - 0xd3, 0x69, 0x15, 0xb3, 0x78, 0xbf, 0x6b, 0xc5, 0xc8, 0xe3, 0xd8, 0x68, 0x9f, 0xac, 0x8e, 0x06, - 0xb7, 0x4f, 0xe6, 0x03, 0x21, 0x4a, 0xd8, 0xc6, 0x52, 0xaf, 0x09, 0xcb, 0xff, 0x66, 0xf8, 0xaa, - 0x89, 0x5f, 0xe7, 0x77, 0xad, 0xae, 0x70, 0x09, 0x60, 0xfb, 0x84, 0x86, 0x17, 0x75, 0xe4, 0x68, - 0x1f, 0xf7, 0xfe, 0x5f, 0x40, 0xb5, 0x5f, 0xdb, 0x0d, 0xa8, 0xd0, 0x76, 0x3c, 0xb5, 0xf7, 0x9e, - 0xc8, 0x98, 0x60, 0x54, 0xf3, 0x5a, 0xd6, 0x5a, 0x27, 0x0c, 0x66, 0xae, 0x47, 0x97, 0x14, 0x6e, - 0x56, 0x90, 0x62, 0x63, 0xf3, 0xf7, 0x32, 0x70, 0x26, 0x95, 0x96, 0x5c, 0x01, 0x88, 0x74, 0x4a, - 0xa2, 0x97, 0x70, 0xc7, 0x8c, 0xa2, 0x1f, 0x99, 0x0a, 0x06, 0xf9, 0x4a, 0x5c, 0x1b, 0x74, 0xf2, - 0x41, 0xb8, 0x24, 0x83, 0x0e, 0xea, 0xda, 0xa0, 0x14, 0x1d, 0x90, 0xf1, 0xab, 0x39, 0x98, 0x53, - 0x82, 0x2b, 0xf1, 0x6f, 0x3d, 0xc1, 0x5e, 0xfc, 0x00, 0xa6, 0x58, 0x6b, 0x9c, 0x86, 0x70, 0xbb, - 0xe1, 0x86, 0x2f, 0xaf, 0x25, 0xfc, 0x4e, 0x05, 0xb7, 0x2b, 0x2a, 0x32, 0x0f, 0x05, 0x8a, 0x5b, - 0x27, 0x3e, 0x48, 0x34, 0x92, 0x2e, 0x37, 0x1a, 0x73, 0xe2, 0xc3, 0x74, 0xe5, 0xb0, 0x63, 0xb7, - 0xc3, 0xda, 0xb8, 0x01, 0xcc, 0xa7, 0xfa, 0xd6, 0xa6, 0x61, 0xf3, 0xea, 0x22, 0x0f, 0x2d, 0x5e, - 0x96, 0x12, 0x1c, 0x40, 0xa3, 0x5a, 0x7a, 0x1f, 0xe6, 0x12, 0x1f, 0x7d, 0xaa, 0xa8, 0xa4, 0xdb, - 0x40, 0x92, 0xdf, 0x91, 0xc2, 0xe1, 0x53, 0x7a, 0xcc, 0xdb, 0x33, 0xe1, 0xe3, 0x75, 0xbb, 0x6d, - 0x77, 0x9a, 0xdc, 0x9c, 0x66, 0x59, 0x8d, 0x59, 0xfa, 0x0b, 0x59, 0xd5, 0xf7, 0xf7, 0x69, 0x5f, - 0x75, 0x5f, 0xd0, 0x6e, 0xc3, 0x2f, 0xf4, 0x1b, 0xd3, 0xa1, 0xb4, 0x0e, 0xdf, 0xc9, 0xc1, 0xb9, - 0x3e, 0x94, 0xe4, 0x30, 0x3e, 0x89, 0xb8, 0x16, 0xe2, 0xda, 0xe0, 0x0a, 0x9f, 0xc4, 0x54, 0x22, - 0x9f, 0xe3, 0xd1, 0x3f, 0x44, 0xaa, 0x63, 0x7e, 0xff, 0x46, 0x35, 0xfe, 0x41, 0x08, 0x8d, 0x87, - 0xfd, 0xe0, 0x50, 0xf2, 0x3e, 0x8c, 0xa2, 0xe3, 0x77, 0x2c, 0xbc, 0x23, 0xc3, 0x40, 0xb8, 0x12, - 0xa0, 0x94, 0xfd, 0xd4, 0x02, 0x94, 0x32, 0x00, 0xf9, 0x2c, 0xe4, 0x4a, 0xdb, 0x75, 0x31, 0x2e, - 0x33, 0x2a, 0xf9, 0x76, 0x3d, 0x4a, 0xdf, 0x62, 0x6b, 0x79, 0x56, 0x18, 0x05, 0x23, 0xbc, 0x55, - 0xae, 0x89, 0x51, 0x51, 0x09, 0x6f, 0x95, 0x6b, 0x11, 0xe1, 0x5e, 0x43, 0x0b, 0x96, 0x75, 0xab, - 0x5c, 0xfb, 0xf8, 0xa6, 0xfd, 0xbf, 0x97, 0xe5, 0x21, 0x4b, 0x78, 0xc3, 0xde, 0x87, 0x29, 0x2d, - 0x26, 0x79, 0x26, 0x92, 0xc7, 0xc2, 0xf8, 0xf1, 0x31, 0x8b, 0x21, 0x8d, 0x40, 0x26, 0x42, 0x62, - 0xbf, 0x51, 0xe2, 0x55, 0x8d, 0x6d, 0x42, 0x0e, 0x28, 0x13, 0xc7, 0x13, 0x21, 0x85, 0x24, 0xe4, - 0x3a, 0xe4, 0x37, 0x69, 0xc7, 0xee, 0x04, 0xa1, 0x42, 0x14, 0x8d, 0x8b, 0x03, 0x84, 0xe9, 0x52, - 0x43, 0x88, 0x88, 0x86, 0xb0, 0xbd, 0x1d, 0xbf, 0xe1, 0x39, 0x18, 0xda, 0x28, 0x3c, 0x8b, 0xb9, - 0x21, 0xac, 0x52, 0xa2, 0x33, 0x88, 0x11, 0x19, 0xbf, 0x90, 0x81, 0x71, 0x31, 0x90, 0x3c, 0x81, - 0xdd, 0x5e, 0x74, 0x96, 0x08, 0xe7, 0x81, 0x3d, 0x27, 0xee, 0x3c, 0xb0, 0xc7, 0xe3, 0x07, 0x4d, - 0x08, 0xc7, 0xba, 0xf0, 0x69, 0x10, 0x67, 0xa3, 0x74, 0xfb, 0xd4, 0xf3, 0x93, 0x85, 0xa8, 0xc3, - 0x3a, 0x64, 0x19, 0x7f, 0x5b, 0x7c, 0xd9, 0xad, 0x72, 0x8d, 0x2c, 0x43, 0x7e, 0xdd, 0xe5, 0xa1, - 0xb0, 0xd4, 0x6c, 0xc4, 0x2d, 0x01, 0x53, 0x3b, 0x48, 0xe2, 0xb1, 0xef, 0xab, 0x79, 0xae, 0xb8, - 0xcb, 0x28, 0xdf, 0xd7, 0xe5, 0xc0, 0xd8, 0xf7, 0x85, 0xa8, 0x43, 0x7f, 0x1f, 0x4d, 0xd9, 0x24, - 0xee, 0x5f, 0xc7, 0x0c, 0x31, 0xb7, 0x55, 0x47, 0x37, 0x51, 0x24, 0x77, 0x8a, 0xa5, 0x7e, 0x3b, - 0xc5, 0xfd, 0xeb, 0x66, 0x0a, 0x15, 0xbe, 0xab, 0x45, 0xe0, 0x3a, 0xf5, 0x1e, 0x3c, 0xc5, 0xbb, - 0x74, 0xfa, 0xbb, 0x5a, 0xbc, 0x79, 0x43, 0x6d, 0xd2, 0x7f, 0x90, 0x85, 0xb3, 0xe9, 0x84, 0x6a, - 0x5b, 0x32, 0x03, 0xda, 0x72, 0x09, 0xf2, 0x6b, 0xae, 0x1f, 0x28, 0x46, 0x82, 0xa8, 0xfe, 0xdf, - 0x17, 0x30, 0x33, 0x2c, 0x65, 0x77, 0x6e, 0xf6, 0x77, 0xb8, 0x3c, 0x91, 0x1f, 0x06, 0xea, 0x60, - 0x77, 0x6e, 0x5e, 0x44, 0x6e, 0x41, 0xde, 0x14, 0x8e, 0x56, 0xb1, 0xae, 0x91, 0xe0, 0x50, 0x9a, - 0x22, 0x9e, 0x80, 0x68, 0xa1, 0xe1, 0x05, 0x8c, 0x94, 0x60, 0x5c, 0x8c, 0x7e, 0xec, 0xe9, 0x38, - 0x65, 0xca, 0xe8, 0xd9, 0x1a, 0x24, 0x1d, 0xdb, 0x51, 0xf0, 0x11, 0xb0, 0x5a, 0x91, 0x3e, 0x53, - 0xb8, 0xa3, 0xf0, 0x47, 0x42, 0xdd, 0x1e, 0x33, 0x44, 0x34, 0xbe, 0x95, 0x05, 0x90, 0x5a, 0x9b, - 0xa7, 0x76, 0x86, 0x7d, 0x56, 0x9b, 0x61, 0x8a, 0xbd, 0xd1, 0xf0, 0x09, 0x97, 0xef, 0xa1, 0x39, - 0xcf, 0xf0, 0xe9, 0x96, 0x8b, 0x30, 0xba, 0x19, 0x29, 0xb4, 0x84, 0x4b, 0x0a, 0xaa, 0xa3, 0x39, - 0xdc, 0xd8, 0x81, 0x85, 0x5b, 0x34, 0x88, 0xd4, 0x5b, 0xf2, 0xe9, 0x71, 0x30, 0xdb, 0xd7, 0x61, - 0x42, 0xe0, 0x87, 0xfb, 0x17, 0xd7, 0xc5, 0x88, 0xd8, 0x37, 0xa8, 0x8b, 0x91, 0x08, 0x6c, 0x37, - 0xaa, 0xd0, 0x16, 0x0d, 0xe8, 0xc7, 0x5b, 0x4d, 0x1d, 0x08, 0x6f, 0x0a, 0xb6, 0x6c, 0xb8, 0x1a, - 0x4e, 0xec, 0x9f, 0xfb, 0x70, 0x26, 0xfc, 0xf6, 0x27, 0xc9, 0xf7, 0x2a, 0xbb, 0x52, 0x8a, 0x44, - 0x07, 0x11, 0xc7, 0x01, 0xb6, 0x27, 0x8f, 0x60, 0x49, 0x12, 0x6c, 0x3b, 0xa1, 0xe1, 0xe4, 0x50, - 0xb4, 0xe4, 0x1d, 0x98, 0x54, 0x68, 0x44, 0xa0, 0x7e, 0x54, 0x53, 0x3f, 0x74, 0x82, 0x7d, 0xcb, - 0xe7, 0x70, 0x55, 0x4d, 0xad, 0xa0, 0x1b, 0x5f, 0x86, 0x67, 0x43, 0xb7, 0xa1, 0x94, 0xaa, 0x63, - 0xcc, 0x33, 0xa7, 0x63, 0xbe, 0x11, 0x35, 0xab, 0xda, 0x09, 0x3d, 0xa3, 0x25, 0x6f, 0xa2, 0x36, - 0x4b, 0x34, 0xe6, 0xb9, 0x84, 0xaf, 0xb5, 0xe2, 0x52, 0x6d, 0xbc, 0xad, 0x7c, 0x6c, 0x0a, 0x43, - 0x8d, 0x38, 0x13, 0x27, 0xfe, 0x56, 0x16, 0x66, 0xef, 0x55, 0x2b, 0xe5, 0xd0, 0xfa, 0xe8, 0x13, - 0x96, 0x0e, 0x5a, 0x6b, 0x5b, 0xff, 0xfd, 0xc6, 0xd8, 0x82, 0xf9, 0x58, 0x37, 0xa0, 0xe8, 0xf0, - 0x1e, 0x77, 0x38, 0x09, 0xc1, 0x52, 0x6c, 0x38, 0x9b, 0xc6, 0xfe, 0xfe, 0x75, 0x33, 0x86, 0x6d, - 0xfc, 0x97, 0x10, 0xe3, 0x2b, 0xb6, 0xb0, 0xd7, 0x61, 0xa2, 0xea, 0xfb, 0x3d, 0xea, 0x6d, 0x99, - 0xeb, 0xaa, 0xaa, 0xc0, 0x41, 0xa0, 0xd5, 0xf3, 0x5a, 0x66, 0x84, 0x40, 0x2e, 0x43, 0x5e, 0x04, - 0x49, 0x97, 0x7b, 0x02, 0x6a, 0x6d, 0xc3, 0x18, 0xeb, 0x66, 0x58, 0x4c, 0xde, 0x84, 0x29, 0xfe, - 0x37, 0x9f, 0x6d, 0xa2, 0xc3, 0x51, 0x39, 0x28, 0xd0, 0xf9, 0xec, 0x34, 0x35, 0x34, 0xf2, 0x1a, - 0xe4, 0x4a, 0x65, 0x53, 0xa8, 0x83, 0x84, 0xdc, 0xe8, 0x59, 0x5c, 0x67, 0xa7, 0x5d, 0x22, 0xca, - 0x26, 0x93, 0xfe, 0x64, 0xb0, 0x09, 0xa1, 0xc9, 0xc6, 0x19, 0x20, 0xb5, 0x4d, 0xb1, 0xc3, 0x0c, - 0x61, 0xe4, 0x2a, 0x8c, 0x57, 0xb8, 0xc9, 0x9c, 0xd0, 0x63, 0xf3, 0x5c, 0x87, 0x1c, 0xa4, 0x05, - 0x57, 0xe0, 0x20, 0x72, 0x59, 0x66, 0x68, 0xcb, 0x47, 0x7e, 0x2b, 0x7d, 0xd2, 0xb0, 0xbd, 0x0e, - 0x63, 0x22, 0x94, 0xf8, 0x84, 0x92, 0xbb, 0x25, 0x1e, 0x42, 0x5c, 0xe0, 0x24, 0x1d, 0x58, 0xe1, - 0x49, 0x3a, 0xb0, 0xee, 0xc0, 0xb9, 0x5b, 0xa8, 0xbd, 0xd1, 0x03, 0x62, 0x6d, 0x99, 0x55, 0xa1, - 0x0f, 0xc7, 0x67, 0x20, 0xae, 0xe0, 0x89, 0xc7, 0xd4, 0xb2, 0x7a, 0x9e, 0x9a, 0xba, 0xb7, 0x1f, - 0x23, 0xf2, 0x25, 0x58, 0x48, 0x2b, 0x12, 0x5a, 0x73, 0x0c, 0xfd, 0x94, 0x5e, 0x81, 0x1a, 0xfa, - 0x29, 0x8d, 0x03, 0x59, 0x87, 0x02, 0x87, 0x97, 0x9a, 0x6d, 0xa7, 0xc3, 0x35, 0xff, 0x5c, 0xab, - 0x8e, 0x8e, 0x24, 0x82, 0xab, 0xcd, 0x0a, 0xf9, 0x0b, 0x80, 0xe6, 0x7a, 0x14, 0xa3, 0x24, 0x3f, - 0x9d, 0x61, 0xb7, 0x39, 0x1e, 0x78, 0x7b, 0xcb, 0x5c, 0xf7, 0x45, 0xd8, 0xc0, 0xb3, 0x91, 0x57, - 0x51, 0x3d, 0xf0, 0x9c, 0xce, 0x9e, 0x70, 0x2b, 0xda, 0x14, 0x6e, 0x45, 0xef, 0x7c, 0x24, 0xb7, - 0x22, 0xce, 0xca, 0x3f, 0x3e, 0x2a, 0x4e, 0x79, 0xa2, 0x4e, 0x5c, 0x45, 0xda, 0x17, 0xb0, 0xae, - 0x43, 0xdf, 0xda, 0xad, 0x0e, 0x0f, 0xfb, 0x4b, 0x9b, 0xbc, 0x91, 0xb3, 0xb8, 0x83, 0x63, 0xd7, - 0x61, 0x4e, 0x10, 0xab, 0x17, 0x22, 0x24, 0x1a, 0x9a, 0xca, 0x81, 0x5d, 0x3c, 0xa5, 0xeb, 0x0a, - 0xf7, 0xc6, 0x2d, 0x44, 0x17, 0x4f, 0xe9, 0xe7, 0x62, 0xe1, 0x34, 0x52, 0x27, 0x8f, 0x46, 0x42, - 0xae, 0xc2, 0xd8, 0x5d, 0xfb, 0x51, 0x69, 0x8f, 0x8a, 0xdc, 0x9e, 0xd3, 0x72, 0xfb, 0x43, 0xe0, - 0x4a, 0xfe, 0x0f, 0xb9, 0xaf, 0xc3, 0x33, 0xa6, 0x40, 0x23, 0x3f, 0x90, 0x81, 0xb3, 0x7c, 0x19, - 0xcb, 0x56, 0xd6, 0x69, 0x10, 0xb0, 0x7e, 0x10, 0xf1, 0x03, 0x2f, 0x44, 0x06, 0xdb, 0xe9, 0x78, - 0xe8, 0x79, 0x6f, 0x88, 0x9d, 0x21, 0xec, 0x38, 0x5f, 0x94, 0x6a, 0x81, 0x98, 0x53, 0xe9, 0xc9, - 0x26, 0x4c, 0xde, 0xbd, 0x59, 0x0a, 0xab, 0xe5, 0xd1, 0xd9, 0x8b, 0x69, 0xbb, 0xa3, 0x82, 0x96, - 0xe6, 0x69, 0xa0, 0xb2, 0x11, 0xde, 0x01, 0x9f, 0x95, 0xfd, 0x41, 0xde, 0x50, 0x5d, 0x51, 0x73, - 0x28, 0x3d, 0x8f, 0xb7, 0xed, 0x47, 0x96, 0xbd, 0x47, 0xb5, 0x57, 0x72, 0xa1, 0xbd, 0xfe, 0xb9, - 0x0c, 0x9c, 0xef, 0xdb, 0x64, 0x72, 0x03, 0xce, 0xd9, 0xdc, 0xc1, 0xda, 0xda, 0x0f, 0x82, 0xae, - 0x6f, 0xc9, 0x2b, 0x86, 0x70, 0x5e, 0x35, 0xcf, 0x88, 0xe2, 0x35, 0x56, 0x2a, 0x6f, 0x1d, 0x3e, - 0x79, 0x1f, 0x9e, 0x73, 0x3a, 0x3e, 0x6d, 0xf4, 0x3c, 0x6a, 0x49, 0x06, 0x0d, 0xa7, 0xe9, 0x59, - 0x9e, 0xdd, 0xd9, 0x93, 0x9e, 0xb8, 0xe6, 0x79, 0x89, 0x23, 0x9c, 0xb8, 0xcb, 0x4e, 0xd3, 0x33, - 0x11, 0xc1, 0xf8, 0x17, 0x19, 0x58, 0xec, 0xd7, 0x25, 0x64, 0x11, 0xc6, 0xa9, 0x92, 0xa7, 0x25, - 0x6f, 0xca, 0x9f, 0xe4, 0x59, 0x88, 0x76, 0x7a, 0x71, 0xfa, 0xe7, 0x1b, 0x22, 0x67, 0x06, 0x9a, - 0xb6, 0xab, 0xfb, 0xba, 0x30, 0x50, 0x9e, 0x6a, 0xa8, 0xbb, 0xfb, 0xf3, 0x00, 0xd1, 0x76, 0xce, - 0x15, 0x13, 0xe6, 0x84, 0xdd, 0xf0, 0xf8, 0xca, 0x23, 0x67, 0x61, 0x8c, 0x6f, 0x97, 0xc2, 0xff, - 0x41, 0xfc, 0x62, 0xe7, 0xb6, 0xe8, 0x64, 0xdc, 0xe7, 0x73, 0x2b, 0x53, 0x5a, 0x67, 0x8f, 0xb5, - 0x71, 0x70, 0x8c, 0x9f, 0x99, 0xe6, 0x22, 0x44, 0xa9, 0x17, 0xec, 0x4b, 0xa1, 0x63, 0x39, 0xcd, - 0x5f, 0x8c, 0xdb, 0x52, 0x2a, 0x76, 0xd9, 0xba, 0x97, 0x98, 0x7c, 0xfb, 0xc9, 0xa6, 0xbe, 0xfd, - 0xbc, 0x0e, 0x13, 0xe5, 0x7d, 0xda, 0x38, 0x08, 0x9d, 0x70, 0xf2, 0x42, 0xb9, 0xce, 0x80, 0x3c, - 0x24, 0x7a, 0x84, 0x40, 0xae, 0x02, 0xa0, 0x9b, 0x2a, 0x97, 0x48, 0x95, 0xb4, 0x26, 0xe8, 0xd5, - 0x2a, 0xcc, 0x53, 0x14, 0x14, 0x64, 0x5f, 0x37, 0x6f, 0xaa, 0xf6, 0x2c, 0x9c, 0xbd, 0xef, 0xed, - 0x0a, 0xf4, 0x08, 0x81, 0x35, 0x4f, 0xd9, 0x57, 0xc4, 0x29, 0x58, 0x48, 0x6c, 0x3e, 0x2a, 0x12, - 0xb9, 0x02, 0x13, 0x35, 0xe9, 0x48, 0x80, 0x87, 0xe0, 0x14, 0x52, 0x40, 0xe4, 0x74, 0xb0, 0x98, - 0x31, 0x23, 0x14, 0xf2, 0x59, 0x18, 0x2f, 0x53, 0x2f, 0xd8, 0xdc, 0x5c, 0x47, 0xa3, 0x13, 0x9e, - 0xfd, 0x23, 0x8f, 0x99, 0x1a, 0x82, 0xa0, 0xf5, 0xdd, 0xa3, 0xe2, 0x74, 0xe0, 0xb4, 0x69, 0x18, - 0xd5, 0xdc, 0x94, 0xd8, 0x64, 0x05, 0x0a, 0xfc, 0x59, 0x3c, 0xba, 0x7b, 0xe0, 0xc9, 0x98, 0xe7, - 0xe7, 0xb4, 0x78, 0x43, 0x7f, 0x48, 0x77, 0xc2, 0x3c, 0x15, 0x09, 0x7c, 0xb2, 0x2a, 0xd3, 0xbb, - 0xa8, 0xcd, 0x84, 0x48, 0x19, 0x16, 0xdf, 0x31, 0x58, 0x6b, 0x93, 0x14, 0xa4, 0x04, 0xd3, 0x65, - 0xb7, 0xdd, 0xb5, 0x03, 0x07, 0xf3, 0x60, 0x1e, 0x8a, 0x43, 0x10, 0x15, 0x7a, 0x0d, 0xb5, 0x40, - 0x3b, 0x51, 0xd5, 0x02, 0x72, 0x13, 0x66, 0x4c, 0xb7, 0xc7, 0x86, 0x49, 0xde, 0xc2, 0xf9, 0x39, - 0x87, 0xa6, 0x21, 0x1e, 0x2b, 0x61, 0xc7, 0xb2, 0xb8, 0x72, 0x6b, 0x11, 0x60, 0x35, 0x2a, 0xb2, - 0x91, 0xf2, 0x1c, 0xa2, 0x1e, 0x6e, 0x6a, 0xb6, 0x8a, 0x04, 0xb3, 0x94, 0x97, 0x94, 0xeb, 0x30, - 0x59, 0xaf, 0xdf, 0xdb, 0xa4, 0x7e, 0x70, 0xb3, 0xe5, 0x3e, 0xc4, 0xb3, 0x2d, 0x2f, 0x92, 0xab, - 0xf9, 0xae, 0x15, 0x50, 0x3f, 0xb0, 0x76, 0x5b, 0xee, 0x43, 0x53, 0xc5, 0x22, 0x5f, 0x63, 0xfd, - 0xa1, 0x48, 0x82, 0x22, 0xd6, 0xed, 0x20, 0x61, 0x15, 0x4f, 0x90, 0x68, 0xd1, 0x30, 0x91, 0x55, - 0xef, 0x2c, 0x05, 0x1d, 0x7d, 0xca, 0x3c, 0xf7, 0xd1, 0x61, 0xa9, 0xd9, 0xf4, 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, 0xae, 0xc8, 0x43, - 0xf8, 0x8a, 0x82, 0x76, 0xe5, 0xc1, 0xb5, 0x2b, 0xa5, 0xe8, 0x67, 0x5d, 0x12, 0x61, 0xdc, 0xbe, - 0x62, 0x2a, 0x3f, 0x2d, 0x37, 0xd1, 0x82, 0x9d, 0x42, 0x4c, 0xca, 0x4c, 0x52, 0x63, 0x33, 0x0a, - 0x0d, 0xa7, 0xaa, 0x35, 0x3c, 0xd3, 0x84, 0x46, 0x55, 0xcc, 0x3f, 0x6e, 0x62, 0xe5, 0x74, 0x75, - 0x81, 0x4c, 0xa1, 0x21, 0x55, 0x98, 0xe5, 0x00, 0xb6, 0x2d, 0xf0, 0x34, 0x4f, 0xf3, 0x51, 0xa2, - 0x09, 0xc1, 0x06, 0xdf, 0xfa, 0x31, 0xd5, 0x93, 0x1a, 0x9c, 0x35, 0x46, 0x47, 0xde, 0x87, 0x19, - 0x8c, 0xa1, 0x1f, 0xad, 0xd7, 0x05, 0x5c, 0xc5, 0x18, 0x63, 0x56, 0x94, 0xc4, 0x3c, 0xef, 0xa6, - 0x7c, 0x7f, 0x3f, 0x5a, 0xd1, 0xef, 0xc3, 0x0c, 0xda, 0xea, 0x44, 0x0c, 0xce, 0x44, 0x0c, 0x44, - 0x49, 0x9c, 0x41, 0xd0, 0xf2, 0x23, 0x06, 0x3f, 0x9b, 0x81, 0xf3, 0xac, 0xa2, 0xf4, 0x11, 0x3a, - 0xfb, 0x51, 0x46, 0x08, 0xa3, 0x6e, 0xf6, 0xe5, 0xa9, 0x8a, 0xa3, 0xbe, 0xbf, 0x9f, 0xc6, 0x01, - 0x3f, 0x8a, 0x7d, 0x7c, 0xfa, 0x47, 0x9d, 0xfb, 0xc8, 0x1f, 0xd5, 0x97, 0xa7, 0xfa, 0x51, 0x41, - 0xcb, 0x4f, 0xe3, 0x80, 0xd7, 0xda, 0x7a, 0xe9, 0xee, 0x7a, 0x74, 0x37, 0xfb, 0x64, 0xb9, 0xad, - 0x68, 0x6d, 0x1b, 0xe0, 0xb6, 0xb2, 0xc5, 0xbd, 0xa8, 0x95, 0x6e, 0x90, 0xd7, 0x5a, 0x0d, 0x1c, - 0xbf, 0xd6, 0xc6, 0x68, 0xcc, 0x18, 0xb6, 0xf1, 0xcb, 0x10, 0xe3, 0x2b, 0x4c, 0x55, 0x0d, 0x18, - 0xe3, 0xb7, 0x56, 0xd1, 0xc9, 0x68, 0xb3, 0xc0, 0xef, 0xb4, 0xa6, 0x28, 0x21, 0xe7, 0x21, 0x57, - 0xaf, 0xdf, 0x13, 0x9d, 0x8c, 0x06, 0xab, 0xbe, 0xef, 0x9a, 0x0c, 0xc6, 0x46, 0x08, 0xad, 0x50, - 0x95, 0x9c, 0x04, 0xec, 0xbc, 0x33, 0x11, 0xca, 0xfa, 0x5b, 0xde, 0x21, 0x47, 0xa2, 0xfe, 0x16, - 0x77, 0xc8, 0xe8, 0xe6, 0x58, 0x86, 0xc5, 0x92, 0xef, 0x53, 0x8f, 0x4d, 0x08, 0x61, 0xdc, 0xe8, - 0x89, 0x7b, 0x8e, 0x38, 0xd8, 0xb1, 0x52, 0xbb, 0xe1, 0x9b, 0x7d, 0x11, 0xc9, 0x25, 0xc8, 0x97, - 0x7a, 0x4d, 0x87, 0x76, 0x1a, 0x5a, 0x58, 0x36, 0x5b, 0xc0, 0xcc, 0xb0, 0x94, 0x7c, 0x11, 0xce, - 0xc4, 0x22, 0x30, 0x8a, 0x1e, 0x18, 0x8f, 0xf6, 0x5e, 0x79, 0x0f, 0x8b, 0x0c, 0x32, 0x78, 0x97, - 0xa4, 0x53, 0x92, 0x12, 0x14, 0x56, 0xd1, 0x4d, 0xab, 0x42, 0xf9, 0xdb, 0x90, 0xeb, 0x71, 0xff, - 0x3c, 0x7e, 0x6b, 0x16, 0x71, 0x26, 0x9b, 0x61, 0xa1, 0x99, 0x40, 0x27, 0x77, 0x60, 0x3e, 0x0e, - 0x63, 0x27, 0x38, 0xbf, 0x20, 0xe3, 0x7e, 0x93, 0xe0, 0x82, 0x67, 0x78, 0x1a, 0x15, 0xd9, 0x81, - 0xb9, 0xc8, 0x20, 0x49, 0xbf, 0x36, 0x4b, 0x3b, 0xe7, 0xb0, 0x5c, 0x5e, 0x9d, 0x9f, 0x15, 0x93, - 0x71, 0x3e, 0x32, 0x6e, 0x0a, 0xaf, 0xcf, 0x66, 0x92, 0x1d, 0x69, 0xc2, 0x4c, 0xdd, 0xd9, 0xeb, - 0x38, 0x9d, 0xbd, 0x3b, 0xf4, 0xb0, 0x66, 0x3b, 0x9e, 0xb0, 0x38, 0x95, 0xf6, 0xe4, 0x25, 0xff, - 0xb0, 0xdd, 0xa6, 0x81, 0x87, 0x1b, 0x21, 0x2b, 0x47, 0x1f, 0x74, 0x76, 0x1d, 0x5a, 0xf2, 0x39, - 0x1d, 0xba, 0x6d, 0x76, 0x6d, 0x47, 0x13, 0x02, 0x74, 0x9e, 0x9a, 0xea, 0x62, 0x6a, 0x48, 0xd5, - 0x45, 0x0b, 0xe6, 0x56, 0x3b, 0x0d, 0xef, 0x10, 0x9f, 0xe8, 0xe4, 0xc7, 0x4d, 0x9f, 0xf0, 0x71, - 0x2f, 0x8b, 0x8f, 0x7b, 0xce, 0x96, 0x33, 0x2c, 0xed, 0xf3, 0x92, 0x8c, 0x49, 0x1d, 0xe6, 0xf0, - 0xe2, 0x50, 0xad, 0xd4, 0xaa, 0x1d, 0x27, 0x70, 0xec, 0x80, 0x36, 0x85, 0x70, 0x11, 0x66, 0x72, - 0xe1, 0x57, 0x54, 0xa7, 0xd9, 0xb5, 0x1c, 0x89, 0xa2, 0x32, 0x4d, 0xd0, 0x0f, 0xba, 0x27, 0xce, - 0xfe, 0x05, 0xdd, 0x13, 0xab, 0x30, 0x1b, 0x0f, 0xe5, 0x50, 0x88, 0xce, 0x61, 0x1f, 0x8b, 0xd8, - 0x71, 0xee, 0xf6, 0x50, 0x98, 0xd4, 0x92, 0xa7, 0xc6, 0x82, 0x38, 0xc4, 0xae, 0x9c, 0x73, 0xda, - 0x95, 0x53, 0xdb, 0x95, 0x4e, 0x71, 0xe5, 0x24, 0x35, 0x80, 0x9b, 0xae, 0xd7, 0xa0, 0x25, 0xf4, - 0x8f, 0x26, 0x5a, 0xbe, 0x2b, 0xc6, 0x34, 0x2a, 0xe4, 0xeb, 0x67, 0x97, 0xfd, 0xb6, 0xe2, 0x6e, - 0xee, 0x0a, 0x0f, 0xe3, 0xc7, 0xb3, 0xb0, 0xd8, 0xef, 0x73, 0x06, 0x5c, 0xf7, 0x3e, 0x05, 0xc9, - 0x15, 0x2e, 0xae, 0x7d, 0x05, 0x1a, 0x5f, 0xe7, 0xcb, 0x90, 0xbe, 0x90, 0xc5, 0x35, 0x70, 0x3e, - 0x4e, 0xb0, 0xe5, 0xb5, 0xc8, 0x0d, 0x98, 0x54, 0x3e, 0x1e, 0xf7, 0xd2, 0x7e, 0x4d, 0x35, 0x61, - 0x37, 0xfc, 0x9b, 0x5d, 0x13, 0xf9, 0xbe, 0x25, 0xaf, 0x89, 0xfc, 0x17, 0x29, 0x70, 0x17, 0xf1, - 0x31, 0x6e, 0x05, 0xe0, 0xfb, 0x2e, 0x21, 0x80, 0xfb, 0x36, 0xdf, 0x02, 0x4d, 0xfc, 0xdb, 0xf8, - 0xcd, 0x29, 0x7e, 0x22, 0xab, 0xb7, 0xc4, 0x7e, 0xf6, 0xc1, 0xb1, 0xdb, 0x63, 0xf6, 0x34, 0xb7, - 0xc7, 0xdc, 0xc9, 0xb7, 0xc7, 0x91, 0x93, 0x6e, 0x8f, 0xb1, 0xeb, 0xdd, 0xe8, 0xa9, 0xaf, 0x77, - 0x63, 0xa7, 0xba, 0xde, 0x8d, 0x9f, 0xea, 0x7a, 0xa7, 0xdd, 0x54, 0xf3, 0x27, 0xdd, 0x54, 0xff, - 0xea, 0x32, 0xf8, 0xb4, 0x5e, 0x06, 0xd3, 0x44, 0xbc, 0x53, 0x5d, 0x06, 0x7f, 0xb4, 0xef, 0x5d, - 0xae, 0xf0, 0x51, 0x84, 0xf2, 0x97, 0x86, 0xb8, 0xcb, 0x0d, 0x7b, 0x93, 0x9b, 0x7b, 0x32, 0x37, - 0x39, 0xf2, 0xc4, 0x6e, 0x72, 0xf3, 0x8f, 0x7b, 0x93, 0x5b, 0x78, 0x92, 0x37, 0xb9, 0x33, 0x7f, - 0x19, 0x6f, 0x72, 0x67, 0xff, 0xed, 0xdc, 0xe4, 0xfe, 0x1a, 0x14, 0xe2, 0xc2, 0xe5, 0xc9, 0x51, - 0x8f, 0x9f, 0x58, 0xc8, 0x49, 0x26, 0xfa, 0xc6, 0x85, 0x3b, 0x72, 0x15, 0xa0, 0xe6, 0x39, 0x0f, - 0xec, 0x80, 0xde, 0x91, 0xd6, 0x6f, 0x22, 0x62, 0x37, 0x87, 0xb2, 0x91, 0x37, 0x15, 0x94, 0xf0, - 0x5e, 0x93, 0x4d, 0xbb, 0xd7, 0x18, 0x3f, 0x96, 0x85, 0x39, 0x1e, 0xb7, 0xed, 0xe9, 0x7f, 0x84, - 0x7d, 0x4f, 0xbb, 0xad, 0x3e, 0x17, 0xe5, 0x08, 0x50, 0x5b, 0x37, 0xe0, 0x19, 0xf6, 0xab, 0x70, - 0x26, 0xd1, 0x15, 0x78, 0x63, 0xad, 0xc8, 0x88, 0x79, 0x89, 0x3b, 0xeb, 0x62, 0x7a, 0x25, 0xf7, - 0xaf, 0x9b, 0x09, 0x0a, 0xe3, 0xcf, 0x46, 0x12, 0xfc, 0xc5, 0x83, 0xac, 0xfa, 0xc4, 0x9a, 0x39, - 0xdd, 0x13, 0x6b, 0x76, 0xb8, 0x27, 0xd6, 0x98, 0x50, 0x91, 0x1b, 0x46, 0xa8, 0xf8, 0x22, 0x4c, - 0x6f, 0x52, 0xbb, 0xed, 0x6f, 0xba, 0x22, 0xe1, 0x14, 0xf7, 0xb5, 0x90, 0x01, 0xf1, 0x58, 0x99, - 0xbc, 0x70, 0x85, 0x36, 0xa3, 0x01, 0x23, 0x60, 0xc7, 0x20, 0xcf, 0x40, 0x65, 0xea, 0x1c, 0xd4, - 0x5b, 0xf4, 0xe8, 0x80, 0x5b, 0x74, 0x1d, 0xa6, 0x04, 0x5d, 0x14, 0xea, 0x39, 0xba, 0xee, 0xb1, - 0x22, 0x84, 0xcb, 0xda, 0xc3, 0x6c, 0xf8, 0x61, 0xed, 0xfc, 0xa6, 0xa7, 0x31, 0x61, 0x5d, 0xb0, - 0xda, 0x69, 0x76, 0x5d, 0xa7, 0x83, 0x5d, 0x30, 0x1e, 0x75, 0x01, 0x15, 0x60, 0xde, 0x05, 0x0a, - 0x12, 0x79, 0x07, 0x66, 0x4a, 0xb5, 0xaa, 0x4a, 0x96, 0x8f, 0x5e, 0x79, 0xed, 0xae, 0x63, 0x69, - 0xa4, 0x31, 0xdc, 0x41, 0x37, 0x9f, 0x89, 0xbf, 0x98, 0x9b, 0x8f, 0xf1, 0x4f, 0xa7, 0xe5, 0xf2, - 0xfe, 0x78, 0x1f, 0x48, 0xf4, 0x27, 0x8f, 0xdc, 0x29, 0x9f, 0x3c, 0x46, 0x4e, 0x12, 0x24, 0x35, - 0xf9, 0x76, 0xf4, 0x54, 0xf2, 0xed, 0xd8, 0x63, 0x3f, 0x5f, 0x8c, 0x9f, 0x52, 0x62, 0x8d, 0xad, - 0xb5, 0xfc, 0x30, 0x6b, 0x2d, 0x55, 0xca, 0x9d, 0x78, 0x7c, 0x29, 0x17, 0x4e, 0x2d, 0xe5, 0xd6, - 0x23, 0xdf, 0xe5, 0xc9, 0x13, 0x5d, 0x42, 0x9e, 0x17, 0x5a, 0x81, 0xb9, 0xf4, 0x28, 0x7c, 0xa1, - 0x17, 0xf3, 0x27, 0x4a, 0x74, 0xfe, 0x7a, 0xba, 0xe8, 0x3c, 0xf8, 0xbc, 0x39, 0x95, 0xf0, 0xfc, - 0x63, 0x4f, 0x56, 0x78, 0x7e, 0xb2, 0x0f, 0x21, 0x7f, 0x25, 0x3e, 0xff, 0x95, 0xf8, 0x3c, 0x9c, - 0xf8, 0x4c, 0xee, 0x01, 0xb1, 0x7b, 0xc1, 0x3e, 0xed, 0x04, 0x4e, 0x03, 0xa3, 0xd2, 0xb2, 0x21, - 0xc6, 0x57, 0x19, 0xb1, 0x5e, 0x93, 0xa5, 0xea, 0x7a, 0xd5, 0x4a, 0xd1, 0xcf, 0xdb, 0xc3, 0xf5, - 0xba, 0x6d, 0x7b, 0x1d, 0xd4, 0x63, 0x5d, 0x85, 0x71, 0x19, 0xd7, 0x34, 0x13, 0xa9, 0xa8, 0x93, - 0x01, 0x4d, 0x25, 0x16, 0x59, 0x86, 0xbc, 0x24, 0x56, 0x13, 0xed, 0x3c, 0x14, 0x30, 0x2d, 0x64, - 0xa4, 0x80, 0x19, 0xff, 0xd1, 0x88, 0x3c, 0x13, 0xd8, 0x27, 0xd4, 0x6c, 0xcf, 0x6e, 0x63, 0x0e, - 0xbe, 0x70, 0xc9, 0x2a, 0xb7, 0x81, 0xd8, 0x2a, 0x8f, 0xf9, 0x0a, 0xe8, 0x24, 0x1f, 0x29, 0x30, - 0x6d, 0x94, 0xe6, 0x38, 0x37, 0x44, 0x9a, 0xe3, 0xb7, 0xb4, 0x1c, 0xc1, 0x23, 0x51, 0x52, 0x4a, - 0xb6, 0x4f, 0x0e, 0xce, 0x0e, 0x7c, 0x43, 0x4d, 0xe6, 0x3b, 0x1a, 0x85, 0x09, 0x43, 0xca, 0x01, - 0x69, 0x7c, 0xc3, 0xeb, 0xcd, 0xd8, 0x69, 0x42, 0x3e, 0x8f, 0xff, 0x5b, 0x0d, 0xf9, 0xbc, 0x0a, - 0x20, 0xce, 0xee, 0xc8, 0xde, 0xe1, 0x15, 0xdc, 0x4e, 0x84, 0xdd, 0x73, 0x10, 0xb4, 0xfa, 0xe4, - 0x04, 0x51, 0x08, 0x8d, 0xdf, 0x27, 0x30, 0x57, 0xaf, 0xdf, 0xab, 0x38, 0xf6, 0x5e, 0xc7, 0xf5, - 0x03, 0xa7, 0x51, 0xed, 0xec, 0xba, 0x4c, 0xb6, 0x0f, 0xcf, 0x17, 0x25, 0x58, 0x6f, 0x74, 0xb6, - 0x84, 0xc5, 0xec, 0xee, 0xb8, 0xea, 0x79, 0x52, 0xe1, 0xca, 0xef, 0x8e, 0x94, 0x01, 0x4c, 0x0e, - 0x67, 0xe2, 0x73, 0xbd, 0x87, 0xa1, 0x32, 0x84, 0x11, 0x0a, 0x8a, 0xcf, 0x3e, 0x07, 0x99, 0xb2, - 0x8c, 0xd0, 0xe4, 0x84, 0x15, 0xd7, 0xa9, 0x73, 0x5a, 0xe0, 0xe8, 0xa8, 0x98, 0xaf, 0x46, 0x21, - 0xdd, 0xe0, 0x3e, 0xdc, 0x45, 0xb8, 0x6a, 0x62, 0x97, 0x58, 0x03, 0x87, 0x70, 0x46, 0x73, 0xa2, - 0x1e, 0xf6, 0x75, 0xe6, 0x35, 0x21, 0xae, 0x1b, 0x18, 0xb3, 0x23, 0xe5, 0x89, 0x46, 0x4d, 0xaa, - 0x97, 0x5a, 0x03, 0x3b, 0x20, 0x9f, 0x4f, 0x2d, 0x09, 0x57, 0xf7, 0xa4, 0x16, 0xbc, 0x5b, 0xd9, - 0x34, 0x78, 0xfa, 0xc0, 0x7e, 0x55, 0x5b, 0x29, 0x5b, 0xc1, 0xe0, 0x9a, 0xc8, 0x3f, 0xce, 0xc0, - 0x39, 0x0d, 0x23, 0xdc, 0xff, 0xfc, 0x30, 0xbe, 0x48, 0xea, 0xbc, 0xfe, 0xf0, 0xc9, 0xcc, 0xeb, - 0x97, 0xf4, 0xb6, 0x44, 0x3b, 0xb4, 0xda, 0x86, 0x7e, 0x5f, 0x48, 0x1e, 0xc0, 0x1c, 0x16, 0xc9, - 0x97, 0x22, 0x36, 0x67, 0xc5, 0x03, 0xd3, 0x42, 0xf4, 0xd9, 0x3c, 0x30, 0x00, 0xa6, 0x80, 0x5f, - 0xfe, 0xce, 0x51, 0x71, 0x5a, 0x43, 0x97, 0xe1, 0xb0, 0xad, 0xe8, 0xb9, 0xc9, 0xe9, 0xec, 0xba, - 0x5a, 0x7e, 0xff, 0x78, 0x15, 0xe4, 0xbf, 0xce, 0xf0, 0xf7, 0x09, 0xde, 0x8c, 0x9b, 0x9e, 0xdb, - 0x0e, 0xcb, 0xa5, 0xad, 0x66, 0x9f, 0x6e, 0x6b, 0x3d, 0x99, 0x6e, 0x7b, 0x05, 0x3f, 0x99, 0xef, - 0x09, 0xd6, 0xae, 0xe7, 0xb6, 0xa3, 0xcf, 0x57, 0x3b, 0xae, 0xef, 0x47, 0x92, 0x1f, 0xcc, 0xc0, - 0x79, 0x4d, 0x4d, 0xaa, 0xe6, 0x26, 0x11, 0xe1, 0x17, 0xe6, 0xc3, 0xc0, 0x2c, 0x51, 0xd1, 0xca, - 0x15, 0x31, 0xff, 0x2f, 0xe2, 0x17, 0x28, 0x71, 0x40, 0x19, 0x92, 0xd5, 0xe6, 0x58, 0xca, 0x27, - 0xf4, 0xaf, 0x85, 0x38, 0x30, 0x87, 0x66, 0x3b, 0x9a, 0x4d, 0xf1, 0x42, 0x7f, 0x9b, 0xe2, 0x30, - 0xeb, 0x10, 0x66, 0x24, 0xe8, 0x6f, 0x58, 0x9c, 0xe4, 0x4a, 0xbe, 0x0f, 0xce, 0x27, 0x80, 0xe1, - 0x6a, 0x3b, 0xd3, 0x77, 0xb5, 0x7d, 0xea, 0xf8, 0xa8, 0xf8, 0x6a, 0x5a, 0x6d, 0x69, 0x2b, 0xad, - 0x7f, 0x0d, 0xc4, 0x06, 0x88, 0x0a, 0x85, 0x3c, 0x93, 0x3e, 0x41, 0x3f, 0x25, 0xe6, 0x87, 0x82, - 0xcf, 0xf6, 0x72, 0xe5, 0x1b, 0xd4, 0x23, 0x2f, 0x42, 0x22, 0x14, 0xa6, 0x94, 0x6c, 0x0c, 0x87, - 0xc2, 0x7a, 0xa4, 0x4f, 0x25, 0xdf, 0x39, 0x2a, 0x6a, 0xd8, 0xec, 0x86, 0xa5, 0xa6, 0x79, 0xd0, - 0xc4, 0x47, 0x15, 0x91, 0xfc, 0x46, 0x06, 0x16, 0x18, 0x20, 0x9a, 0x54, 0xa2, 0x51, 0x8b, 0x83, - 0x66, 0xfd, 0xfe, 0x93, 0x99, 0xf5, 0x2f, 0xe2, 0x37, 0xaa, 0xb3, 0x3e, 0xd1, 0x25, 0xa9, 0x1f, - 0x87, 0xb3, 0x5d, 0xb3, 0x10, 0xd3, 0x66, 0xfb, 0xf9, 0x21, 0x66, 0x3b, 0x1f, 0x80, 0x93, 0x67, - 0x7b, 0xdf, 0x5a, 0xc8, 0x26, 0x4c, 0x89, 0xcb, 0x15, 0xef, 0xb0, 0x17, 0xb4, 0xb8, 0xd0, 0x6a, - 0x11, 0xbf, 0xf1, 0x8a, 0x64, 0x15, 0x89, 0x16, 0x6a, 0x5c, 0x48, 0x07, 0xe6, 0xf9, 0x6f, 0x5d, - 0xd9, 0x55, 0xec, 0xab, 0xec, 0xba, 0x24, 0x5a, 0x74, 0x41, 0xf0, 0x8f, 0xe9, 0xbc, 0xd4, 0x78, - 0x4e, 0x29, 0x8c, 0x49, 0x17, 0x88, 0x06, 0xe6, 0x8b, 0xf6, 0xc2, 0x60, 0x15, 0xd7, 0xab, 0xa2, - 0xce, 0x62, 0xbc, 0xce, 0xf8, 0xca, 0x4d, 0xe1, 0x4d, 0x6c, 0x98, 0x15, 0x50, 0xf7, 0x80, 0xf2, - 0x1d, 0xfe, 0x45, 0x2d, 0xa2, 0x56, 0xac, 0x94, 0xdf, 0xca, 0x64, 0x4d, 0x18, 0xf1, 0x2c, 0xb6, - 0xa1, 0xc7, 0xf9, 0x91, 0x7b, 0x30, 0x57, 0xea, 0x76, 0x5b, 0x0e, 0x6d, 0x62, 0x2b, 0xcd, 0x1e, - 0x6b, 0x93, 0x11, 0xe5, 0x7b, 0xb3, 0x79, 0xa1, 0xb8, 0x2a, 0x7a, 0xbd, 0xd8, 0x76, 0x93, 0xa0, - 0x35, 0x7e, 0x34, 0x93, 0xf8, 0x68, 0xf2, 0x3a, 0x4c, 0xe0, 0x0f, 0x25, 0x48, 0x0b, 0xea, 0x8c, - 0xf8, 0x27, 0xa2, 0x36, 0x2a, 0x42, 0x60, 0xc2, 0x92, 0x1a, 0xa8, 0x31, 0xc7, 0x85, 0x25, 0xa1, - 0xa8, 0x88, 0x54, 0x13, 0x45, 0xe9, 0xeb, 0x91, 0x8b, 0x84, 0x2e, 0xf4, 0xf5, 0x10, 0x1e, 0x1e, - 0xc6, 0x3f, 0xcc, 0xea, 0xd3, 0x8e, 0x5c, 0x52, 0xe4, 0x76, 0x25, 0x54, 0xa4, 0x94, 0xdb, 0x15, - 0x69, 0xfd, 0xef, 0x65, 0x60, 0xfe, 0x9e, 0x92, 0x28, 0x74, 0xd3, 0xc5, 0x71, 0x19, 0x9c, 0x3a, - 0xf3, 0x49, 0xa5, 0x00, 0x54, 0x33, 0x94, 0xb2, 0x99, 0x82, 0x53, 0xc6, 0x4c, 0xfb, 0x1e, 0xf4, - 0x9e, 0xc3, 0x0f, 0x53, 0x32, 0x31, 0x72, 0x74, 0x0e, 0x3f, 0x65, 0xea, 0x0a, 0xe3, 0x27, 0xb3, - 0x30, 0xa9, 0xac, 0x18, 0xf2, 0x19, 0x98, 0x52, 0xab, 0x55, 0x15, 0x8e, 0xea, 0x57, 0x9a, 0x1a, - 0x16, 0x6a, 0x1c, 0xa9, 0xdd, 0xd6, 0x34, 0x8e, 0x6c, 0x5d, 0x20, 0xf4, 0x94, 0x37, 0xa1, 0xf7, - 0x53, 0x6e, 0x42, 0x38, 0xcb, 0x15, 0x8d, 0xd1, 0xc0, 0xfb, 0xd0, 0x3b, 0xc9, 0xfb, 0x10, 0x2a, - 0xaf, 0x14, 0xfa, 0xfe, 0xb7, 0x22, 0xe3, 0x67, 0x32, 0x50, 0x88, 0xaf, 0xe9, 0x8f, 0xa5, 0x57, - 0x4e, 0xf1, 0xba, 0xf4, 0x13, 0xd9, 0x30, 0x73, 0x8b, 0x74, 0x21, 0x7e, 0x5a, 0xcd, 0x14, 0xdf, - 0xd5, 0x1e, 0x7e, 0x9e, 0xd5, 0xa3, 0xe1, 0xa9, 0xc1, 0x37, 0xd2, 0x43, 0x60, 0x8e, 0x7c, 0xfb, - 0xef, 0x14, 0x9f, 0x31, 0x3e, 0x80, 0x85, 0x78, 0x77, 0xe0, 0xe3, 0x4f, 0x09, 0x66, 0x75, 0x78, - 0x3c, 0xef, 0x53, 0x9c, 0xca, 0x8c, 0xe3, 0x1b, 0x7f, 0x98, 0x8d, 0xf3, 0x16, 0x26, 0x8b, 0x6c, - 0x8f, 0x52, 0x0d, 0x71, 0xc4, 0x1e, 0xc5, 0x41, 0xa6, 0x2c, 0x3b, 0x4d, 0xbe, 0xb5, 0xd0, 0x11, - 0x36, 0x97, 0xee, 0x08, 0x4b, 0x6e, 0xc4, 0xac, 0xb4, 0x95, 0xa8, 0x4d, 0x0f, 0xe9, 0x8e, 0x15, - 0x59, 0x6a, 0xc7, 0x8c, 0xb3, 0xcb, 0xb0, 0xa0, 0x85, 0x20, 0x97, 0xf4, 0xa3, 0x91, 0xae, 0x3f, - 0xc0, 0x02, 0x4e, 0x9c, 0x8a, 0x4c, 0xd6, 0x60, 0x9c, 0x7d, 0xe6, 0x5d, 0xbb, 0x2b, 0xde, 0x74, - 0x48, 0xe8, 0x16, 0xdf, 0x0a, 0xef, 0x87, 0x8a, 0x67, 0x7c, 0x8b, 0x32, 0x09, 0x41, 0x9d, 0x58, - 0x02, 0xd1, 0xf8, 0x57, 0x19, 0xb6, 0xfe, 0x1b, 0x07, 0x9f, 0xb0, 0xa4, 0x6d, 0xac, 0x49, 0x03, - 0x2c, 0x6a, 0xff, 0x38, 0xcb, 0x73, 0xf1, 0x88, 0xe9, 0xf3, 0x16, 0x8c, 0x6d, 0xda, 0xde, 0x9e, - 0x48, 0x99, 0xad, 0x73, 0xe1, 0x05, 0x51, 0x4c, 0xa9, 0x00, 0x7f, 0x9b, 0x82, 0x40, 0x55, 0x9d, - 0x65, 0x87, 0x52, 0x9d, 0x29, 0xef, 0x02, 0xb9, 0x27, 0xf6, 0x2e, 0xf0, 0x3d, 0x61, 0xda, 0x9d, - 0x52, 0x30, 0x44, 0x84, 0xeb, 0x0b, 0xf1, 0x2c, 0x57, 0x89, 0x58, 0xe4, 0x11, 0x3b, 0x72, 0x43, - 0xcd, 0x9b, 0xa5, 0xf8, 0x96, 0x9e, 0x90, 0x21, 0xcb, 0xf8, 0xe3, 0x1c, 0xef, 0x63, 0xd1, 0x51, - 0x17, 0x35, 0xbf, 0x73, 0x5c, 0x27, 0x31, 0x3d, 0x25, 0xf7, 0x40, 0xbf, 0x08, 0x23, 0x6c, 0x6e, - 0x8a, 0xde, 0x44, 0x3c, 0x36, 0x7f, 0x55, 0x3c, 0x56, 0xce, 0xd6, 0x32, 0x9e, 0x49, 0x6a, 0x42, - 0x44, 0x3c, 0xb6, 0xd4, 0xb5, 0x8c, 0x18, 0xe4, 0x12, 0x8c, 0x6c, 0xb8, 0x4d, 0x19, 0x49, 0x7d, - 0x01, 0xa3, 0x8f, 0x68, 0x19, 0x57, 0x17, 0x33, 0x26, 0x62, 0xb0, 0xb6, 0x86, 0xf9, 0x27, 0xd4, - 0xb6, 0xb6, 0x77, 0xed, 0x64, 0xa2, 0x3b, 0x25, 0xe9, 0xcd, 0x2a, 0xcc, 0x6c, 0x3b, 0x9d, 0xa6, - 0xfb, 0xd0, 0xaf, 0x50, 0xff, 0x20, 0x70, 0xbb, 0xc2, 0xde, 0x18, 0xb5, 0xfb, 0x0f, 0x79, 0x89, - 0xd5, 0xe4, 0x45, 0xea, 0xb3, 0x8c, 0x4e, 0x44, 0x56, 0x60, 0x5a, 0x8b, 0xe0, 0x2a, 0x1e, 0x57, - 0x51, 0x1b, 0xaa, 0xc7, 0x7f, 0x55, 0xb5, 0xa1, 0x1a, 0x09, 0x3b, 0xcf, 0xc5, 0xf7, 0x2b, 0x4f, - 0xac, 0x89, 0x6f, 0x17, 0x38, 0xe4, 0x3a, 0xe4, 0x79, 0x98, 0x8f, 0x6a, 0x45, 0x7d, 0x26, 0xf3, - 0x11, 0x16, 0x0b, 0x93, 0x23, 0x11, 0x95, 0xb0, 0x0e, 0x9f, 0x86, 0x82, 0xd8, 0x92, 0xa2, 0x5c, - 0xed, 0xcf, 0xc1, 0x48, 0xb9, 0x5a, 0x31, 0xd5, 0x6d, 0xa4, 0xe1, 0x34, 0x3d, 0x13, 0xa1, 0xe8, - 0xd5, 0xb7, 0x41, 0x83, 0x87, 0xae, 0x77, 0x60, 0x52, 0x3f, 0xf0, 0x1c, 0x9e, 0x4f, 0x13, 0x17, - 0xe2, 0x67, 0xc8, 0x3b, 0x30, 0x8a, 0x86, 0xaf, 0xb1, 0x93, 0x21, 0x5e, 0xc7, 0xca, 0xb4, 0x98, - 0xc0, 0xa3, 0x68, 0x45, 0x6b, 0x72, 0x22, 0xf2, 0x16, 0x8c, 0x54, 0x68, 0xe7, 0x30, 0x96, 0xea, - 0x2f, 0x41, 0x1c, 0x6e, 0x08, 0x4d, 0xda, 0x39, 0x34, 0x91, 0xc4, 0xf8, 0x99, 0x2c, 0x9c, 0x49, - 0xf9, 0xac, 0xfb, 0x9f, 0x79, 0x4a, 0x77, 0xc5, 0x15, 0x6d, 0x57, 0x94, 0xef, 0xe3, 0x7d, 0x3b, - 0x3e, 0x75, 0x93, 0xfc, 0xc5, 0x0c, 0x9c, 0xd3, 0x27, 0xa8, 0xb0, 0x74, 0xbf, 0x7f, 0x9d, 0xbc, - 0x0d, 0x63, 0x6b, 0xd4, 0x6e, 0x52, 0x99, 0xd7, 0xeb, 0x4c, 0x18, 0x90, 0x8f, 0xc7, 0x30, 0xe0, - 0x85, 0x9c, 0x6d, 0xe4, 0xf1, 0xca, 0xa1, 0xa4, 0x22, 0x3e, 0x8e, 0x8b, 0xef, 0x86, 0x8c, 0x27, - 0x92, 0x56, 0xd5, 0x00, 0x2b, 0x93, 0xef, 0x64, 0xe0, 0xd9, 0x01, 0x34, 0x6c, 0xe0, 0xd8, 0xd0, - 0xab, 0x03, 0x87, 0x27, 0x2a, 0x42, 0xc9, 0x7b, 0x30, 0xbb, 0x29, 0xc4, 0x7f, 0x39, 0x1c, 0xd9, - 0x68, 0xbd, 0xc8, 0x9b, 0x81, 0x25, 0xc7, 0x25, 0x8e, 0xac, 0x05, 0xba, 0xc9, 0x0d, 0x0c, 0x74, - 0xa3, 0xc6, 0x8d, 0x19, 0x19, 0x36, 0x6e, 0xcc, 0x07, 0xb0, 0xa0, 0xb7, 0x4d, 0x84, 0xef, 0x8d, - 0xa2, 0xe6, 0x64, 0xfa, 0x47, 0xcd, 0x19, 0x18, 0x24, 0xd4, 0xf8, 0xc9, 0x0c, 0x14, 0x74, 0xde, - 0x8f, 0x3b, 0x9e, 0xef, 0x6a, 0xe3, 0xf9, 0x6c, 0xfa, 0x78, 0xf6, 0x1f, 0xc8, 0xff, 0x2b, 0x13, - 0x6f, 0xec, 0x50, 0x23, 0x68, 0xc0, 0x58, 0xc5, 0x6d, 0xdb, 0x4e, 0x47, 0x4d, 0xfd, 0xdf, 0x44, - 0x88, 0x29, 0x4a, 0x86, 0x0b, 0x32, 0x74, 0x01, 0x46, 0x37, 0xdc, 0x4e, 0xa9, 0x22, 0x4c, 0x8a, - 0x91, 0x4f, 0xc7, 0xed, 0x58, 0x76, 0xd3, 0xe4, 0x05, 0x64, 0x1d, 0xa0, 0xde, 0xf0, 0x28, 0xed, - 0xd4, 0x9d, 0xef, 0xa5, 0x31, 0x49, 0x83, 0xf5, 0x50, 0xab, 0x87, 0x1b, 0x0b, 0x7f, 0x3a, 0x45, - 0x44, 0xcb, 0x77, 0xbe, 0x57, 0xdd, 0x6f, 0x15, 0x7a, 0x5c, 0x57, 0x22, 0x0e, 0x5b, 0x6c, 0x1c, - 0xae, 0x7d, 0x1c, 0xeb, 0x2a, 0xb5, 0x2a, 0xec, 0xe1, 0x6b, 0xa9, 0xc3, 0xf1, 0x07, 0x19, 0x78, - 0x76, 0x00, 0xcd, 0x13, 0x18, 0x95, 0xbf, 0xe8, 0x0e, 0xa7, 0x00, 0x11, 0x11, 0x66, 0x52, 0x76, - 0x9a, 0x01, 0xcf, 0xd5, 0x37, 0x2d, 0x32, 0x29, 0x33, 0x80, 0x96, 0x49, 0x99, 0x01, 0xd8, 0x59, - 0xba, 0x46, 0x9d, 0xbd, 0x7d, 0x6e, 0x1e, 0x36, 0xcd, 0xf7, 0x86, 0x7d, 0x84, 0xa8, 0x67, 0x29, - 0xc7, 0x31, 0xfe, 0xf5, 0x28, 0x9c, 0x37, 0xe9, 0x9e, 0xc3, 0xee, 0x25, 0x5b, 0xbe, 0xd3, 0xd9, - 0xd3, 0xe2, 0xee, 0x18, 0xb1, 0x95, 0x2b, 0x92, 0x54, 0x30, 0x48, 0x38, 0x13, 0x2f, 0x43, 0x9e, - 0x89, 0x21, 0xca, 0xe2, 0xc5, 0x37, 0x2e, 0x26, 0xac, 0x88, 0xc0, 0xce, 0xb2, 0x98, 0xbc, 0x26, - 0xc4, 0x24, 0x25, 0x8d, 0x10, 0x13, 0x93, 0xbe, 0x7b, 0x54, 0x84, 0xfa, 0xa1, 0x1f, 0x50, 0xbc, - 0x22, 0x0b, 0x51, 0x29, 0xbc, 0xcb, 0x8c, 0xf4, 0xb9, 0xcb, 0xdc, 0x85, 0x85, 0x52, 0x93, 0x9f, - 0x8e, 0x76, 0xab, 0xe6, 0x39, 0x9d, 0x86, 0xd3, 0xb5, 0x5b, 0xf2, 0x7e, 0x8e, 0xbd, 0x6c, 0x87, - 0xe5, 0x56, 0x37, 0x44, 0x30, 0x53, 0xc9, 0x58, 0x33, 0x2a, 0x1b, 0x75, 0x0c, 0x4f, 0x23, 0x9e, - 0x2f, 0xb1, 0x19, 0xcd, 0x8e, 0x8f, 0xad, 0xf0, 0xcd, 0xb0, 0x18, 0x6f, 0x51, 0x68, 0x10, 0xb0, - 0xb9, 0x5e, 0x8f, 0x5c, 0xaa, 0x79, 0x96, 0x03, 0x6e, 0x58, 0x10, 0xb4, 0x7c, 0x34, 0xc5, 0xd4, - 0xf0, 0x22, 0xba, 0x7a, 0x7d, 0x8d, 0xd1, 0xe5, 0x13, 0x74, 0xbe, 0xbf, 0xaf, 0xd2, 0x71, 0x3c, - 0x72, 0x95, 0x4d, 0x85, 0xb6, 0x1b, 0x50, 0x9c, 0xc2, 0x13, 0xd1, 0x9d, 0xcb, 0x43, 0x28, 0xbf, - 0x73, 0x29, 0x28, 0xe4, 0x1d, 0x98, 0x5f, 0x2d, 0x2f, 0x4b, 0xa5, 0x73, 0xc5, 0x6d, 0xf4, 0xd0, - 0x10, 0x00, 0xb0, 0x3e, 0x1c, 0x43, 0xda, 0x58, 0x66, 0xbb, 0x49, 0x1a, 0x1a, 0xb9, 0x08, 0xe3, - 0xd5, 0x0a, 0xef, 0xfb, 0x49, 0x35, 0x95, 0x97, 0xb0, 0xcc, 0x92, 0x85, 0xe4, 0x5e, 0x74, 0x29, - 0x98, 0x3a, 0x51, 0x7a, 0x3f, 0x3f, 0xc4, 0x85, 0xe0, 0x2d, 0x98, 0x5e, 0x71, 0x83, 0x6a, 0xc7, - 0x0f, 0xec, 0x4e, 0x83, 0x56, 0x2b, 0x6a, 0x5c, 0xed, 0x1d, 0x37, 0xb0, 0x1c, 0x51, 0xc2, 0xbe, - 0x5c, 0xc7, 0x24, 0x9f, 0x43, 0xd2, 0x5b, 0xb4, 0x43, 0xbd, 0x28, 0x9e, 0xf6, 0x28, 0xef, 0x5b, - 0x46, 0xba, 0x17, 0x96, 0x98, 0x3a, 0xa2, 0x48, 0x33, 0xc6, 0x93, 0x83, 0x96, 0xdd, 0x26, 0xf5, - 0xf9, 0x6e, 0xf1, 0x09, 0x4a, 0x33, 0xa6, 0xb4, 0x6d, 0xc0, 0x0e, 0xfa, 0xef, 0x63, 0x9a, 0xb1, - 0x04, 0x2e, 0xf9, 0x1c, 0x8c, 0xe2, 0x4f, 0x21, 0xdd, 0xce, 0xa7, 0xb0, 0x8d, 0x24, 0xdb, 0x06, - 0xc3, 0x34, 0x39, 0x01, 0xa9, 0xc2, 0xb8, 0xb8, 0x58, 0x9d, 0x26, 0x59, 0x8e, 0xb8, 0xa1, 0xf1, - 0x99, 0x21, 0xe8, 0x8d, 0x26, 0x4c, 0xa9, 0x15, 0xb2, 0x15, 0xb1, 0x66, 0xfb, 0xfb, 0xb4, 0xc9, - 0x7e, 0x89, 0x3c, 0x77, 0xb8, 0x22, 0xf6, 0x11, 0x6a, 0xb1, 0xef, 0x30, 0x15, 0x14, 0x76, 0xa6, - 0x56, 0xfd, 0x2d, 0x5f, 0x7c, 0x8a, 0x50, 0xb5, 0x38, 0xa8, 0xb6, 0x6b, 0x9a, 0xa2, 0xc8, 0xf8, - 0x1e, 0x58, 0xd8, 0xe8, 0xb5, 0x5a, 0xf6, 0x4e, 0x8b, 0xca, 0x3c, 0x28, 0x98, 0x70, 0x7c, 0x05, - 0x46, 0xeb, 0x4a, 0x0a, 0xf3, 0x30, 0x17, 0xa5, 0x82, 0x83, 0x46, 0xb0, 0x19, 0x0c, 0x15, 0x14, - 0x4b, 0x5e, 0xce, 0x49, 0x8d, 0xdf, 0xcb, 0xc0, 0x82, 0x34, 0x17, 0xf0, 0xec, 0xc6, 0x41, 0x98, - 0xc7, 0xfe, 0xa2, 0x36, 0xd7, 0x70, 0xc2, 0xc6, 0xa6, 0x11, 0x9f, 0x75, 0xb7, 0xe5, 0x47, 0xe8, - 0x02, 0x4b, 0xda, 0x07, 0x9f, 0xf4, 0x31, 0xe4, 0x1d, 0x98, 0x14, 0xc7, 0xa3, 0x12, 0xe0, 0x12, - 0xa3, 0x88, 0x89, 0xeb, 0x5e, 0xdc, 0x78, 0x45, 0x45, 0x47, 0x59, 0x4c, 0x6f, 0xca, 0xe3, 0xca, - 0x00, 0xe9, 0xb2, 0x98, 0x5e, 0xc7, 0x80, 0xa9, 0xfb, 0xdb, 0x93, 0xf1, 0xbe, 0x15, 0x73, 0xf7, - 0x86, 0x1a, 0xd2, 0x2e, 0x13, 0xdd, 0x8c, 0xa3, 0x90, 0x76, 0xea, 0xcd, 0x38, 0x44, 0x0d, 0xc7, - 0x24, 0x7b, 0xc2, 0x98, 0xbc, 0x27, 0xc7, 0x24, 0xd7, 0x7f, 0x62, 0xcc, 0x0f, 0x18, 0x87, 0x7a, - 0xb4, 0x42, 0x46, 0x86, 0x52, 0xab, 0x3c, 0x83, 0xb1, 0xfb, 0x39, 0x49, 0x7c, 0x17, 0x15, 0x9c, - 0x54, 0x5d, 0xcd, 0xe8, 0xf0, 0x4c, 0x4f, 0xd8, 0x9a, 0x3f, 0x0f, 0x53, 0xa5, 0x20, 0xb0, 0x1b, - 0xfb, 0xb4, 0x59, 0x61, 0xdb, 0x93, 0x12, 0x7d, 0xcb, 0x16, 0x70, 0xf5, 0x8d, 0x4d, 0xc5, 0xe5, - 0xd1, 0x64, 0x6d, 0x5f, 0x18, 0xd3, 0x86, 0xd1, 0x64, 0x19, 0x44, 0x8f, 0x26, 0xcb, 0x20, 0xe4, - 0x2a, 0x8c, 0x57, 0x3b, 0x0f, 0x1c, 0xd6, 0x27, 0x3c, 0x00, 0x17, 0xea, 0xa6, 0x1c, 0x0e, 0x52, - 0x37, 0x57, 0x81, 0x45, 0xde, 0x52, 0x2e, 0x35, 0x13, 0x91, 0x02, 0x83, 0xab, 0xbc, 0xc2, 0x08, - 0x3b, 0xea, 0x85, 0x25, 0xbc, 0xe5, 0xdc, 0x80, 0x71, 0xa9, 0xc9, 0x84, 0x48, 0x69, 0x21, 0x28, - 0x93, 0x01, 0x2b, 0x24, 0x32, 0xe6, 0x24, 0x57, 0xf2, 0xf5, 0x4d, 0x2a, 0x39, 0xc9, 0x95, 0x7c, - 0x7d, 0x5a, 0x4e, 0x72, 0x25, 0x73, 0x5f, 0xa8, 0x04, 0x9a, 0x3a, 0x51, 0x09, 0x74, 0x1f, 0xa6, - 0x6a, 0xb6, 0x17, 0x38, 0x4c, 0x46, 0xe9, 0x04, 0xfe, 0xe2, 0xb4, 0xa6, 0x37, 0x55, 0x8a, 0x56, - 0x5e, 0x90, 0x79, 0xb1, 0xbb, 0x0a, 0xbe, 0x9e, 0xc0, 0x39, 0x82, 0xa7, 0x9b, 0xd2, 0xce, 0x3c, - 0x8e, 0x29, 0x2d, 0x76, 0x2a, 0xea, 0xca, 0x66, 0x23, 0x8d, 0x0c, 0x5e, 0x5a, 0x62, 0x0a, 0xb3, - 0x10, 0x91, 0x7c, 0x05, 0xa6, 0xd8, 0xdf, 0x35, 0xb7, 0xe5, 0x34, 0x1c, 0xea, 0x2f, 0x16, 0xb0, - 0x71, 0x2f, 0xa4, 0xae, 0x7e, 0x44, 0x3a, 0xac, 0xd3, 0x80, 0x2f, 0x60, 0x64, 0x1c, 0x57, 0x82, - 0x6b, 0xdc, 0xc8, 0xfb, 0x30, 0xc5, 0x66, 0xdf, 0x8e, 0xed, 0x73, 0xd1, 0x74, 0x2e, 0x32, 0x86, - 0x6e, 0x0a, 0x78, 0x22, 0xa0, 0xb3, 0x4a, 0xc0, 0x8e, 0xf9, 0x52, 0x97, 0x6f, 0x90, 0x44, 0x99, - 0xed, 0xdd, 0xc4, 0xe6, 0x28, 0xd1, 0xc8, 0x17, 0x60, 0xaa, 0xd4, 0xed, 0x46, 0x3b, 0xce, 0xbc, - 0xa2, 0x08, 0xeb, 0x76, 0xad, 0xd4, 0x5d, 0x47, 0xa3, 0x88, 0x6f, 0xcc, 0x0b, 0xa7, 0xda, 0x98, - 0xc9, 0x1b, 0xa1, 0xb4, 0x7e, 0x26, 0xd2, 0xea, 0x8a, 0x8b, 0xa3, 0x26, 0xfa, 0x73, 0xc1, 0xbd, - 0x0c, 0xd3, 0x5c, 0xcd, 0x29, 0xa5, 0x99, 0xb3, 0x89, 0xd5, 0x93, 0x22, 0xd4, 0xe8, 0x34, 0x64, - 0x15, 0x66, 0xb8, 0xb7, 0x77, 0x4b, 0x44, 0xda, 0x5e, 0x3c, 0x87, 0xab, 0x16, 0xb9, 0x70, 0x27, - 0xf1, 0x16, 0x26, 0x60, 0xb1, 0x35, 0x2e, 0x31, 0x22, 0xe3, 0x4f, 0x32, 0x70, 0xae, 0xcf, 0x88, - 0x87, 0x71, 0x98, 0x33, 0x83, 0xe3, 0x30, 0xb3, 0x9d, 0x43, 0xd7, 0x8a, 0x60, 0xfb, 0x85, 0x94, - 0xa5, 0x8e, 0x97, 0x94, 0xb7, 0x5c, 0x20, 0x22, 0xc7, 0x91, 0xa8, 0xfa, 0xb6, 0x8b, 0xaa, 0xd9, - 0x5c, 0xf2, 0x10, 0x12, 0x78, 0xfc, 0xa3, 0x56, 0x8c, 0xe3, 0xa3, 0xe2, 0x0b, 0x22, 0x85, 0x52, - 0x38, 0xac, 0x1f, 0xba, 0xda, 0x0a, 0x4e, 0x61, 0x6d, 0x1c, 0x65, 0x60, 0x52, 0x59, 0x87, 0xe4, - 0x82, 0xe2, 0x85, 0x5c, 0xe0, 0x49, 0xb8, 0x14, 0x0e, 0x59, 0x7e, 0x12, 0xe1, 0xa2, 0xca, 0x9e, - 0xac, 0x80, 0xbe, 0xcb, 0x44, 0x21, 0x25, 0x56, 0x75, 0x5b, 0xd3, 0x16, 0x9b, 0x58, 0x8e, 0xe9, - 0xfc, 0x6d, 0x3f, 0x28, 0x35, 0x02, 0xe7, 0x01, 0x1d, 0xe2, 0xd0, 0x89, 0xd2, 0xf9, 0xdb, 0x7e, - 0x60, 0xd9, 0x48, 0x96, 0x48, 0xe7, 0x1f, 0x32, 0x34, 0x7e, 0x28, 0x03, 0xb0, 0x55, 0x2d, 0x63, - 0xb0, 0xf9, 0xc7, 0x15, 0x0a, 0xd2, 0x03, 0xf8, 0x4a, 0xee, 0x03, 0xc4, 0x81, 0xff, 0x29, 0x03, - 0x33, 0x3a, 0x1a, 0x79, 0x0f, 0x66, 0xeb, 0x0d, 0xcf, 0x6d, 0xb5, 0x76, 0xec, 0xc6, 0xc1, 0xba, - 0xd3, 0xa1, 0x3c, 0x74, 0xea, 0x28, 0x3f, 0x8b, 0xfc, 0xb0, 0xc8, 0x6a, 0xb1, 0x32, 0x33, 0x8e, - 0x4c, 0x7e, 0x38, 0x03, 0xd3, 0xf5, 0x7d, 0xf7, 0x61, 0x18, 0xed, 0x54, 0x0c, 0xc8, 0x57, 0xd9, - 0xda, 0xf6, 0xf7, 0xdd, 0x87, 0x51, 0x06, 0x4f, 0xcd, 0x56, 0xf4, 0xdd, 0xe1, 0x9e, 0xf1, 0x1b, - 0x2e, 0xde, 0x64, 0x02, 0xff, 0x8a, 0x56, 0x89, 0xa9, 0xd7, 0x69, 0xfc, 0x79, 0x06, 0x26, 0xf1, - 0xce, 0xd3, 0x6a, 0xa1, 0xcc, 0xf5, 0x49, 0x4a, 0x07, 0x19, 0xb6, 0x6b, 0xc0, 0xc0, 0xbe, 0x09, - 0xb3, 0x31, 0x34, 0x62, 0xc0, 0x58, 0x1d, 0x03, 0x0c, 0xa8, 0x0a, 0x0a, 0x1e, 0x72, 0xc0, 0x14, - 0x25, 0xc6, 0xaa, 0x42, 0x76, 0xff, 0x1a, 0x3e, 0xeb, 0x2e, 0x03, 0x38, 0x12, 0x24, 0x6f, 0x36, - 0x24, 0xfe, 0x25, 0xf7, 0xaf, 0x99, 0x0a, 0x96, 0xb1, 0x01, 0x63, 0x75, 0xd7, 0x0b, 0x56, 0x0e, - 0xf9, 0x65, 0xa2, 0x42, 0xfd, 0x86, 0xfa, 0x6e, 0xeb, 0xe0, 0x5b, 0x49, 0xc3, 0x14, 0x45, 0xa4, - 0x08, 0xa3, 0x37, 0x1d, 0xda, 0x6a, 0xaa, 0xf6, 0xbc, 0xbb, 0x0c, 0x60, 0x72, 0x38, 0xbb, 0x70, - 0x9d, 0x8d, 0x72, 0xb2, 0x44, 0x86, 0xc3, 0x8f, 0xbb, 0x6e, 0xca, 0x5a, 0xff, 0xbe, 0x18, 0xe6, - 0x41, 0x48, 0xd6, 0x34, 0xa0, 0xab, 0xff, 0x61, 0x06, 0x96, 0xfa, 0x93, 0xa8, 0xb6, 0xc8, 0x99, - 0x01, 0xb6, 0xc8, 0xaf, 0xc4, 0xdf, 0x19, 0x11, 0x4d, 0xbc, 0x33, 0x46, 0xaf, 0x8b, 0x15, 0x34, - 0x05, 0x6f, 0x50, 0x99, 0x88, 0xe5, 0xc2, 0x80, 0x6f, 0x46, 0x44, 0x3e, 0xcc, 0x01, 0xd2, 0x98, - 0x82, 0xd6, 0xf8, 0xad, 0x11, 0x38, 0xdf, 0x97, 0x82, 0xac, 0x29, 0xe9, 0x9d, 0x66, 0xc2, 0xc4, - 0x32, 0x7d, 0xf1, 0xaf, 0xe0, 0xbf, 0x68, 0xed, 0x17, 0xf7, 0x76, 0xbb, 0x17, 0xa6, 0xf5, 0xc9, - 0x22, 0xaf, 0x4f, 0x9d, 0xc8, 0x8b, 0xa3, 0x23, 0x33, 0x48, 0x66, 0xf8, 0x41, 0xbf, 0x48, 0x1a, - 0xd8, 0x4e, 0xcb, 0x57, 0x97, 0x5d, 0x93, 0x83, 0x4c, 0x59, 0x16, 0x19, 0x88, 0x8f, 0xa4, 0x1b, - 0x88, 0x1b, 0xff, 0x3a, 0x03, 0x13, 0xe1, 0x67, 0x93, 0x25, 0x38, 0xbb, 0x69, 0x96, 0xca, 0xab, - 0xd6, 0xe6, 0x07, 0xb5, 0x55, 0x6b, 0x6b, 0xa3, 0x5e, 0x5b, 0x2d, 0x57, 0x6f, 0x56, 0x57, 0x2b, - 0x85, 0x67, 0xc8, 0x1c, 0x4c, 0x6f, 0x6d, 0xdc, 0xd9, 0xb8, 0xb7, 0xbd, 0x61, 0xad, 0x9a, 0xe6, - 0x3d, 0xb3, 0x90, 0x21, 0xd3, 0x30, 0x61, 0xae, 0x94, 0xca, 0xd6, 0xc6, 0xbd, 0xca, 0x6a, 0x21, - 0x4b, 0x0a, 0x30, 0x55, 0xbe, 0xb7, 0xb1, 0xb1, 0x5a, 0xde, 0xac, 0xde, 0xaf, 0x6e, 0x7e, 0x50, - 0xc8, 0x11, 0x02, 0x33, 0x88, 0x50, 0x33, 0xab, 0x1b, 0xe5, 0x6a, 0xad, 0xb4, 0x5e, 0x18, 0x61, - 0x30, 0x86, 0xaf, 0xc0, 0x46, 0x43, 0x46, 0x77, 0xb6, 0x56, 0x56, 0x0b, 0x63, 0x0c, 0x85, 0xfd, - 0xa5, 0xa0, 0x8c, 0xb3, 0xea, 0x11, 0xa5, 0x52, 0xda, 0x2c, 0xad, 0x94, 0xea, 0xab, 0x85, 0x3c, - 0x39, 0x07, 0xf3, 0x1a, 0xc8, 0x5a, 0xbf, 0x77, 0xab, 0xba, 0x51, 0x98, 0x20, 0x0b, 0x50, 0x08, - 0x61, 0x95, 0x15, 0x6b, 0xab, 0xbe, 0x6a, 0x16, 0x20, 0x0e, 0xdd, 0x28, 0xdd, 0x5d, 0x2d, 0x4c, - 0x1a, 0xef, 0x72, 0x3f, 0x44, 0xde, 0xd5, 0xe4, 0x2c, 0x90, 0xfa, 0x66, 0x69, 0x73, 0xab, 0x1e, - 0x6b, 0xfc, 0x24, 0x8c, 0xd7, 0xb7, 0xca, 0xe5, 0xd5, 0x7a, 0xbd, 0x90, 0x21, 0x00, 0x63, 0x37, - 0x4b, 0xd5, 0xf5, 0xd5, 0x4a, 0x21, 0x6b, 0xfc, 0x74, 0x06, 0xe6, 0xa4, 0x04, 0x28, 0x1f, 0x8d, - 0x1e, 0x73, 0x2d, 0xbe, 0xa7, 0x5d, 0x6c, 0xa5, 0x93, 0x58, 0xac, 0x92, 0x01, 0xcb, 0xf0, 0x17, - 0x33, 0x70, 0x26, 0x15, 0x9b, 0x7c, 0x00, 0x05, 0xf9, 0x05, 0x77, 0xed, 0xa0, 0xb1, 0x1f, 0xed, - 0x63, 0x2f, 0xc4, 0x6a, 0x89, 0xa1, 0x71, 0xb5, 0x66, 0x94, 0x70, 0x3a, 0xc1, 0x66, 0xf8, 0x74, - 0x08, 0xc6, 0xb7, 0x33, 0x70, 0xae, 0x4f, 0x35, 0xa4, 0x0c, 0x63, 0x61, 0x62, 0x9c, 0x01, 0x06, - 0x6f, 0x0b, 0xdf, 0x39, 0x2a, 0x0a, 0x44, 0xcc, 0xd0, 0x8b, 0x7f, 0x99, 0x63, 0x61, 0xa6, 0x1b, - 0x4c, 0x37, 0xc3, 0xbb, 0xef, 0x7c, 0xac, 0xe7, 0x45, 0x4d, 0xa5, 0xed, 0xfa, 0xca, 0xa4, 0xe8, - 0xbb, 0x9c, 0xfd, 0xd0, 0xc7, 0x7c, 0x33, 0xc6, 0xcf, 0x65, 0x98, 0x70, 0x17, 0x47, 0x64, 0x32, - 0x6f, 0xc9, 0xf7, 0x7b, 0x6d, 0x6a, 0xba, 0x2d, 0x5a, 0x32, 0x37, 0xc4, 0xb1, 0x81, 0xd2, 0xaa, - 0x8d, 0x05, 0x78, 0xad, 0xb0, 0x6c, 0xaf, 0xa3, 0xbd, 0x56, 0xab, 0x34, 0xe4, 0x2d, 0x80, 0xd5, - 0x47, 0x01, 0xf5, 0x3a, 0x76, 0x2b, 0x8c, 0x11, 0xc3, 0x23, 0x5b, 0x09, 0xa8, 0x2e, 0x6f, 0x2b, - 0xc8, 0xc6, 0x5f, 0xcf, 0xc0, 0x94, 0xb8, 0x34, 0x95, 0x5a, 0xd4, 0x0b, 0x1e, 0x6f, 0x7a, 0xbd, - 0xa5, 0x4d, 0xaf, 0xd0, 0xbf, 0x43, 0xe1, 0xcf, 0x8a, 0x53, 0x67, 0xd6, 0x3f, 0xcb, 0x40, 0x21, - 0x8e, 0x48, 0xde, 0x83, 0x7c, 0x9d, 0x3e, 0xa0, 0x9e, 0x13, 0x1c, 0x8a, 0x8d, 0x52, 0xa6, 0x10, - 0xe4, 0x38, 0xa2, 0x8c, 0xcf, 0x07, 0x5f, 0xfc, 0x32, 0x43, 0x9a, 0x61, 0xf7, 0x7b, 0x45, 0xed, - 0x91, 0x7b, 0x52, 0x6a, 0x0f, 0xe3, 0x7f, 0xcf, 0xc2, 0xb9, 0x5b, 0x34, 0x50, 0xdb, 0x14, 0x9a, - 0x17, 0x7c, 0x7a, 0xb8, 0x76, 0x29, 0x2d, 0x59, 0x84, 0x71, 0x2c, 0x92, 0xe3, 0x6b, 0xca, 0x9f, - 0x64, 0x25, 0x9c, 0xd7, 0x39, 0x2d, 0x47, 0x59, 0x9f, 0xba, 0xaf, 0x28, 0x59, 0x8b, 0xc2, 0x69, - 0x7d, 0x11, 0x66, 0x30, 0x2c, 0x7f, 0x8f, 0x2d, 0x07, 0xda, 0x14, 0xea, 0x9f, 0xbc, 0x19, 0x83, - 0x92, 0xd7, 0xa0, 0xc0, 0x20, 0xa5, 0xc6, 0x41, 0xc7, 0x7d, 0xd8, 0xa2, 0xcd, 0x3d, 0xda, 0xc4, - 0x63, 0x3d, 0x6f, 0x26, 0xe0, 0x92, 0xe7, 0x56, 0x87, 0x5f, 0xdd, 0x68, 0x13, 0x75, 0x34, 0x82, - 0x67, 0x04, 0x5d, 0x7a, 0x0b, 0x26, 0x3f, 0x62, 0x06, 0x32, 0xe3, 0x7f, 0xcd, 0xc0, 0x02, 0x36, - 0x4e, 0xa9, 0x58, 0x66, 0x87, 0x95, 0xbd, 0xa5, 0x24, 0xe5, 0xb1, 0x19, 0x48, 0x5f, 0x0a, 0x61, - 0x2f, 0x46, 0x3a, 0xa1, 0xec, 0x10, 0x3a, 0xa1, 0xfa, 0x69, 0x32, 0xe1, 0x0f, 0xa9, 0xd2, 0xba, - 0x3d, 0x92, 0xcf, 0x15, 0x46, 0xa2, 0x21, 0x37, 0x7e, 0x38, 0x0b, 0xe3, 0x26, 0xc5, 0x14, 0xe1, - 0xe4, 0x22, 0x8c, 0x6f, 0xb8, 0x01, 0xf5, 0xef, 0x6a, 0xf9, 0xe0, 0x3b, 0x0c, 0x64, 0xb5, 0x9b, - 0xa6, 0x2c, 0x64, 0x13, 0xbe, 0xe6, 0xb9, 0xcd, 0x5e, 0x23, 0x50, 0x27, 0x7c, 0x97, 0x83, 0x4c, - 0x59, 0x46, 0x5e, 0x87, 0x09, 0xc1, 0x39, 0x7c, 0xd4, 0x45, 0xdb, 0x65, 0x8f, 0x86, 0x29, 0xe6, - 0x23, 0x04, 0x94, 0x69, 0xb9, 0x80, 0x31, 0xa2, 0xc8, 0xb4, 0x09, 0x99, 0x41, 0x8a, 0xea, 0xa3, - 0x03, 0x44, 0xf5, 0x4f, 0xc3, 0x58, 0xc9, 0xf7, 0x69, 0x20, 0xa3, 0x28, 0x4c, 0x85, 0x61, 0xe3, - 0x7c, 0x1a, 0x70, 0xc6, 0x36, 0x96, 0x9b, 0x02, 0xcf, 0xf8, 0x57, 0x59, 0x18, 0xc5, 0x3f, 0xf1, - 0xc9, 0xd4, 0x6b, 0xec, 0x6b, 0x4f, 0xa6, 0x5e, 0x63, 0xdf, 0x44, 0x28, 0xb9, 0x86, 0x9a, 0x0a, - 0x99, 0x3f, 0x4a, 0xb4, 0x1e, 0x55, 0xf0, 0xcd, 0x08, 0x6c, 0xaa, 0x38, 0xe1, 0x0b, 0x7f, 0x2e, - 0x35, 0x76, 0xca, 0x59, 0xc8, 0xde, 0xab, 0x8b, 0x16, 0x63, 0x44, 0x2e, 0xd7, 0x37, 0xb3, 0xf7, - 0xea, 0xd8, 0x1b, 0x6b, 0xa5, 0xe5, 0x37, 0x6f, 0x88, 0x86, 0xf2, 0xde, 0xd8, 0xb7, 0x97, 0xdf, - 0xbc, 0x61, 0x8a, 0x12, 0xd6, 0xbf, 0xf8, 0xcd, 0xf8, 0xf0, 0xca, 0x7d, 0xfe, 0xb1, 0x7f, 0xb1, - 0x6d, 0xf8, 0xc8, 0x6a, 0x46, 0x08, 0x64, 0x19, 0x26, 0x45, 0xac, 0x09, 0xc4, 0x57, 0x62, 0x41, - 0x88, 0x58, 0x14, 0x9c, 0x42, 0x45, 0xe2, 0x4f, 0x70, 0x62, 0x80, 0x64, 0x96, 0x5b, 0xf1, 0x04, - 0x27, 0x87, 0xd0, 0x37, 0x15, 0x14, 0xf6, 0x49, 0xfc, 0x0d, 0x2f, 0xf2, 0xe5, 0x9f, 0x51, 0x82, - 0x16, 0x60, 0x9a, 0x85, 0x10, 0xc1, 0xf8, 0x95, 0x2c, 0xe4, 0x6b, 0xad, 0xde, 0x9e, 0xd3, 0xb9, - 0x7f, 0x8d, 0x10, 0xc0, 0x6b, 0x9c, 0xcc, 0xc3, 0xc1, 0xfe, 0x26, 0xe7, 0x21, 0x2f, 0x6f, 0x6e, - 0x72, 0x43, 0xf2, 0xc5, 0xad, 0x6d, 0x11, 0xe4, 0xb8, 0x8b, 0xd0, 0x6b, 0xf2, 0x27, 0xb9, 0x06, - 0xe1, 0xfd, 0xab, 0xdf, 0x45, 0x6d, 0x84, 0x2d, 0x16, 0x33, 0x44, 0x23, 0x6f, 0x00, 0x1e, 0x12, - 0xe2, 0xf2, 0x20, 0x15, 0xda, 0xfc, 0xd3, 0x84, 0x9c, 0xc2, 0x49, 0x10, 0x8d, 0x5c, 0x07, 0x31, - 0x31, 0x45, 0x36, 0xf5, 0x33, 0x3a, 0x01, 0xcf, 0x4f, 0x29, 0x49, 0x04, 0x2a, 0x79, 0x07, 0x26, - 0x1b, 0x1e, 0xc5, 0x57, 0x47, 0xbb, 0x15, 0x25, 0x49, 0x57, 0x29, 0xcb, 0x51, 0xf9, 0xfd, 0x6b, - 0xa6, 0x8a, 0x6e, 0xfc, 0x6f, 0x79, 0x98, 0x52, 0xbf, 0x87, 0x98, 0x30, 0xef, 0xb7, 0xd8, 0xdd, - 0x5d, 0x18, 0x9b, 0x75, 0xb1, 0x50, 0x1c, 0xa7, 0x17, 0xf4, 0x0f, 0x62, 0x78, 0xdc, 0xf2, 0x4c, - 0x06, 0xc9, 0x58, 0x7b, 0xc6, 0x9c, 0xf3, 0x23, 0x30, 0xc7, 0x23, 0x25, 0xc8, 0xbb, 0x5d, 0x7f, - 0x8f, 0x76, 0x1c, 0xf9, 0xde, 0xf2, 0x92, 0xc6, 0xe8, 0x9e, 0x28, 0x4c, 0xf0, 0x0a, 0xc9, 0xc8, - 0x9b, 0x30, 0xe6, 0x76, 0x69, 0xc7, 0x76, 0xc4, 0x19, 0xf7, 0x6c, 0x8c, 0x01, 0xed, 0x94, 0xaa, - 0x0a, 0xa1, 0x40, 0x26, 0x57, 0x61, 0xc4, 0x3d, 0x08, 0xc7, 0xeb, 0xbc, 0x4e, 0x74, 0x10, 0xd8, - 0x0a, 0x09, 0x22, 0x32, 0x82, 0x0f, 0xed, 0xf6, 0xae, 0x18, 0x31, 0x9d, 0xe0, 0xb6, 0xdd, 0xde, - 0x55, 0x09, 0x18, 0x22, 0x79, 0x1f, 0xa0, 0x6b, 0xef, 0x51, 0xcf, 0x6a, 0xf6, 0x82, 0x43, 0x31, - 0x6e, 0x2f, 0x68, 0x64, 0x35, 0x56, 0x5c, 0xe9, 0x05, 0x87, 0x0a, 0xed, 0x44, 0x57, 0x02, 0x49, - 0x09, 0xa0, 0x6d, 0x07, 0x01, 0xf5, 0xda, 0xae, 0xb0, 0xf6, 0x8b, 0x82, 0x20, 0x72, 0x06, 0x77, - 0xc3, 0x62, 0x85, 0x83, 0x42, 0x84, 0x1f, 0xed, 0x78, 0xb6, 0xc8, 0x69, 0x1f, 0xfb, 0x68, 0xc7, - 0xd3, 0x5a, 0xc9, 0x10, 0xc9, 0xe7, 0x60, 0xbc, 0xe9, 0xf8, 0x0d, 0xd7, 0x6b, 0x8a, 0xe8, 0x29, - 0xcf, 0x69, 0x34, 0x15, 0x5e, 0xa6, 0x90, 0x49, 0x74, 0xf6, 0xb5, 0x22, 0x08, 0xea, 0x86, 0xfb, - 0x10, 0xd5, 0xfc, 0xf1, 0xaf, 0xad, 0x87, 0xc5, 0xea, 0xd7, 0x46, 0x44, 0x6c, 0x28, 0xf7, 0x9c, - 0xa0, 0x65, 0xef, 0x88, 0x77, 0x6e, 0x7d, 0x28, 0x6f, 0x61, 0x91, 0x3a, 0x94, 0x1c, 0x99, 0xbc, - 0x05, 0x79, 0xda, 0x09, 0x3c, 0xdb, 0x72, 0x9a, 0xc2, 0xa9, 0x52, 0xff, 0x68, 0x76, 0x00, 0xdb, - 0xd5, 0x8a, 0xfa, 0xd1, 0x88, 0x5f, 0x6d, 0xb2, 0xfe, 0xf1, 0x1b, 0x4e, 0x5b, 0xf8, 0x42, 0xea, - 0xfd, 0x53, 0x2f, 0x57, 0xef, 0xaa, 0xfd, 0xc3, 0x10, 0xc9, 0x7b, 0x30, 0xce, 0xd6, 0x6f, 0xd3, - 0xdd, 0x13, 0x01, 0x29, 0xfe, 0x7f, 0xf6, 0xbe, 0x2d, 0xc6, 0x91, 0xeb, 0x38, 0x74, 0x9b, 0xe4, - 0xcc, 0x70, 0x8a, 0xf3, 0xe8, 0x39, 0x3b, 0xbb, 0x33, 0x9a, 0x7d, 0x69, 0x5b, 0xab, 0xf5, 0x2e, - 0x65, 0xc9, 0xda, 0xd5, 0x95, 0xf5, 0xb0, 0x65, 0xb9, 0x87, 0xd3, 0x33, 0xe4, 0x2e, 0x5f, 0xee, - 0x26, 0x67, 0xbd, 0x96, 0xed, 0x76, 0x2f, 0xd9, 0x33, 0xd3, 0x16, 0x87, 0xa4, 0xd8, 0xa4, 0xd6, - 0x63, 0x5c, 0xe0, 0xda, 0xb8, 0xb8, 0x36, 0x70, 0xf3, 0x70, 0xe2, 0x24, 0x88, 0xe0, 0x1f, 0x07, - 0x88, 0x90, 0xe4, 0xc3, 0xf9, 0x0f, 0xe2, 0x2f, 0xff, 0x19, 0x30, 0x0c, 0x18, 0xc8, 0x9f, 0x13, - 0x08, 0x89, 0x80, 0x04, 0x41, 0x92, 0xbf, 0x20, 0xf9, 0x30, 0x10, 0x20, 0x38, 0x75, 0xce, 0xe9, - 0x3e, 0xfd, 0x20, 0x77, 0xd6, 0x92, 0x92, 0x18, 0xf0, 0xd7, 0x0c, 0xeb, 0x54, 0x55, 0x9f, 0xf7, - 0xa9, 0x53, 0x75, 0xaa, 0x4a, 0x8b, 0xf6, 0x0f, 0x2b, 0x4b, 0x4c, 0x57, 0x41, 0x44, 0x17, 0xb2, - 0xf3, 0xd0, 0xb7, 0xbd, 0x0e, 0x0f, 0x32, 0x11, 0x5d, 0x8e, 0xfa, 0x3d, 0xab, 0x52, 0x92, 0xc8, - 0xe6, 0x9c, 0x87, 0x7e, 0xa5, 0x43, 0x6e, 0xc3, 0x1c, 0xa6, 0xa8, 0xe0, 0x81, 0x30, 0xa3, 0x34, - 0x98, 0x9c, 0x42, 0xa6, 0x41, 0x54, 0x3a, 0x90, 0xc7, 0x3e, 0xba, 0x97, 0xf0, 0x44, 0x11, 0xd1, - 0x3e, 0xa9, 0x59, 0xe8, 0x73, 0x22, 0x57, 0x91, 0xa3, 0xd3, 0x2a, 0xf6, 0xdd, 0xb1, 0xed, 0xbd, - 0xc5, 0x53, 0x3d, 0x44, 0x3f, 0x57, 0x77, 0xc7, 0x95, 0xcf, 0xc9, 0x9f, 0xeb, 0xbb, 0xe3, 0xca, - 0x5b, 0xe4, 0x32, 0x40, 0x68, 0xfa, 0x67, 0x86, 0x1a, 0x53, 0x82, 0xbc, 0x9a, 0xfb, 0xc7, 0x3f, - 0xba, 0xa2, 0x6c, 0x03, 0xe4, 0x45, 0x58, 0x1d, 0xad, 0x0a, 0x4f, 0x4c, 0xdd, 0x2c, 0xc8, 0x4d, - 0x50, 0x0f, 0x1c, 0xae, 0x2a, 0xec, 0x1c, 0x39, 0xfd, 0xbe, 0xdb, 0xe3, 0xdb, 0xf4, 0xaa, 0x80, - 0x97, 0x18, 0x98, 0x71, 0xd6, 0x5e, 0x87, 0xf5, 0xb4, 0x59, 0x42, 0xae, 0xc2, 0x92, 0x1c, 0x41, - 0x88, 0x33, 0x29, 0x38, 0x43, 0x4f, 0xc4, 0x10, 0xe2, 0x0c, 0x7e, 0xa8, 0xc0, 0xc5, 0x59, 0x7b, - 0x0e, 0xd9, 0x82, 0xfc, 0x70, 0xe4, 0x0d, 0x50, 0xb6, 0xe5, 0x29, 0x1a, 0xc4, 0x6f, 0xcc, 0xbe, - 0x80, 0x42, 0xd8, 0xd8, 0x39, 0xe4, 0x5e, 0x21, 0xe6, 0x22, 0x42, 0x5a, 0xce, 0xa1, 0x4f, 0x9e, - 0x81, 0xb5, 0xae, 0x7b, 0xe0, 0x4c, 0x7a, 0x63, 0xdb, 0xef, 0x1c, 0xb9, 0x5d, 0xf4, 0xdb, 0xc2, - 0xd7, 0x7e, 0xa6, 0xca, 0x0b, 0x2c, 0x01, 0x4f, 0xd4, 0x78, 0x6e, 0x4a, 0x8d, 0xef, 0xe4, 0xf2, - 0x8a, 0x9a, 0x31, 0xf1, 0x79, 0x95, 0xf6, 0x8d, 0x0c, 0x6c, 0x4e, 0x5b, 0x64, 0xe4, 0xb5, 0xb4, - 0x3e, 0x60, 0xd6, 0x0e, 0x19, 0x2e, 0x5b, 0x3b, 0xa4, 0xaf, 0x91, 0xdb, 0x10, 0x78, 0x5d, 0x3d, - 0x2a, 0x82, 0x82, 0x80, 0x51, 0x9a, 0xa1, 0xe3, 0xfb, 0x0f, 0xe9, 0x3e, 0x92, 0x95, 0xa2, 0xf0, - 0x72, 0x98, 0x4c, 0x23, 0x60, 0xe4, 0x25, 0x80, 0x4e, 0x6f, 0xe0, 0xbb, 0xf8, 0xa8, 0x80, 0x0b, - 0x28, 0xec, 0x2d, 0x79, 0x00, 0x95, 0xad, 0xc8, 0x08, 0x2d, 0x0d, 0xba, 0x2e, 0x1f, 0x40, 0x07, - 0x36, 0xa6, 0xec, 0xaa, 0x74, 0x78, 0xc2, 0x94, 0xf6, 0x22, 0x41, 0xd6, 0x24, 0x48, 0x6c, 0x1f, - 0xef, 0xf1, 0xcc, 0xb4, 0x39, 0x72, 0x02, 0x24, 0xb9, 0x75, 0x52, 0xee, 0xfc, 0x45, 0xf4, 0x64, - 0x14, 0x70, 0x67, 0x90, 0xf6, 0xa8, 0x47, 0xae, 0x40, 0x41, 0x24, 0xc0, 0xa4, 0x17, 0x00, 0xc6, - 0x1c, 0x38, 0xe8, 0xae, 0x8b, 0x93, 0x07, 0xc3, 0xac, 0xa2, 0x6f, 0x1d, 0x17, 0x2d, 0x16, 0x11, - 0xd2, 0x3a, 0x19, 0x8a, 0xd6, 0x5d, 0x14, 0xf3, 0x3b, 0x7a, 0xa0, 0xf1, 0xd2, 0x3f, 0x50, 0xc4, - 0xf0, 0x27, 0x4f, 0x84, 0x47, 0xd5, 0x8f, 0x00, 0xba, 0x36, 0xf1, 0x8a, 0xe1, 0xff, 0x54, 0xd4, - 0x11, 0xab, 0x8e, 0x8b, 0x3a, 0xfc, 0x27, 0xb9, 0x0e, 0xab, 0x23, 0xf6, 0xf8, 0x75, 0x3c, 0xe0, - 0xfd, 0xc9, 0x92, 0x8d, 0x2c, 0x33, 0x70, 0x6b, 0x80, 0x7d, 0xca, 0xeb, 0x75, 0x27, 0xe8, 0x30, - 0xe9, 0x80, 0x24, 0xcf, 0xc1, 0x22, 0x3d, 0x20, 0x31, 0x3c, 0x4f, 0xcc, 0xa7, 0x02, 0xf1, 0x50, - 0xdc, 0x30, 0xf3, 0x5f, 0xe5, 0xff, 0x73, 0x5e, 0xef, 0x64, 0x04, 0x33, 0xf9, 0x78, 0x26, 0x1b, - 0xb0, 0x30, 0x18, 0x1d, 0x4a, 0x4d, 0x9b, 0x1f, 0x8c, 0x0e, 0x69, 0xbb, 0x6e, 0x80, 0xca, 0x5c, - 0x7c, 0x58, 0xa8, 0x05, 0xff, 0xa4, 0xcf, 0xee, 0xef, 0x79, 0x73, 0x85, 0xc1, 0x31, 0xcb, 0xff, - 0x49, 0xbf, 0x43, 0x31, 0x7d, 0x7f, 0x60, 0xcb, 0x51, 0xb9, 0x78, 0xb3, 0x57, 0x7c, 0x7f, 0x10, - 0x86, 0xe7, 0xea, 0x92, 0x6d, 0x58, 0xa6, 0x7c, 0x82, 0xd8, 0x60, 0x5c, 0x7a, 0xb8, 0x94, 0x94, - 0x1e, 0x4e, 0xfa, 0x1d, 0x51, 0x45, 0x73, 0xc9, 0x97, 0x7e, 0x91, 0xbb, 0xa0, 0x4a, 0x62, 0x16, - 0xfa, 0x7c, 0xc6, 0x1e, 0x62, 0x87, 0x6c, 0x24, 0xf1, 0xac, 0xd2, 0x3f, 0x18, 0x98, 0xab, 0x9d, - 0x28, 0x80, 0x77, 0xcd, 0xf7, 0x15, 0xb1, 0x97, 0xa6, 0x10, 0x11, 0x0d, 0x96, 0x8f, 0x1c, 0xdf, - 0xf6, 0xfd, 0x63, 0xf6, 0xb0, 0x8c, 0x47, 0x23, 0x2e, 0x1c, 0x39, 0xbe, 0xe5, 0x1f, 0x8b, 0x6c, - 0x27, 0xe7, 0x28, 0xce, 0xc0, 0x99, 0x8c, 0x8f, 0x6c, 0x59, 0x68, 0x64, 0x3d, 0x76, 0xf6, 0xc8, - 0xf1, 0x1b, 0xb4, 0x4c, 0xe2, 0x4d, 0xae, 0xc1, 0x0a, 0xf2, 0xed, 0x78, 0x82, 0x31, 0x86, 0xcb, - 0x30, 0x97, 0x28, 0xe3, 0x8e, 0xc7, 0x38, 0xf3, 0x1a, 0xfe, 0x69, 0x16, 0xce, 0xa7, 0xf7, 0x0e, - 0x4e, 0x4f, 0xda, 0xa7, 0xe8, 0xd8, 0xc7, 0xeb, 0xb6, 0x48, 0x21, 0x2c, 0xd4, 0x49, 0xda, 0xe0, - 0x64, 0x52, 0x07, 0xa7, 0x08, 0x6b, 0xc8, 0x88, 0x8b, 0xa7, 0x3d, 0xcf, 0x1f, 0xf3, 0x08, 0x1e, - 0xe6, 0x2a, 0x2d, 0x60, 0xfb, 0x79, 0x95, 0x82, 0xc9, 0xd3, 0xb0, 0x22, 0x76, 0xe4, 0xc1, 0xc3, - 0x3e, 0xfd, 0x30, 0xdb, 0x8e, 0x97, 0x39, 0xb4, 0x81, 0x40, 0x72, 0x0e, 0xe6, 0x9d, 0xe1, 0x90, - 0x7e, 0x92, 0xed, 0xc2, 0x73, 0xce, 0x70, 0xc8, 0x32, 0xf2, 0xa0, 0x1b, 0xa3, 0x7d, 0x80, 0x4f, - 0x8b, 0xf8, 0x3b, 0x46, 0x73, 0x09, 0x81, 0xec, 0xb9, 0x91, 0x4f, 0xd7, 0x3d, 0xa5, 0x15, 0x28, - 0x0b, 0x88, 0x02, 0xce, 0x30, 0x40, 0x78, 0x02, 0xf2, 0xc2, 0xc8, 0xcd, 0xbc, 0x31, 0xcc, 0x05, - 0x87, 0x1b, 0xb8, 0x5f, 0x84, 0x8d, 0xae, 0xe7, 0xe3, 0xe4, 0x65, 0x4d, 0x1a, 0x0e, 0xb9, 0xe3, - 0x24, 0x8b, 0xec, 0x6b, 0xae, 0xf3, 0x62, 0xda, 0x93, 0xfa, 0x70, 0x18, 0xb8, 0x4f, 0x6e, 0x09, - 0xb2, 0x07, 0x1e, 0x8b, 0x57, 0xc6, 0x1e, 0x65, 0xe2, 0xe4, 0x07, 0xa4, 0xdc, 0xe4, 0x18, 0xdb, - 0x32, 0x02, 0x65, 0xc3, 0x47, 0xea, 0x65, 0x58, 0xe5, 0x42, 0x1e, 0x3f, 0x60, 0xb1, 0x25, 0x7c, - 0xf9, 0xd3, 0xdb, 0x17, 0xcf, 0xa0, 0x04, 0x1c, 0x54, 0xe9, 0x8a, 0x4d, 0xe8, 0x6f, 0x14, 0x38, - 0x97, 0x2a, 0x25, 0x92, 0xaf, 0x00, 0xf3, 0x32, 0x1b, 0x0f, 0xec, 0x91, 0xdb, 0xf1, 0x86, 0x1e, - 0x86, 0xed, 0x60, 0x5a, 0xd4, 0xdb, 0xb3, 0xe4, 0x4b, 0xf4, 0x58, 0x6b, 0x0d, 0xcc, 0x80, 0x88, - 0xa9, 0x77, 0xd4, 0x51, 0x0c, 0xbc, 0xf5, 0x06, 0x9c, 0x4b, 0x45, 0x4d, 0x51, 0xbb, 0x7c, 0x3c, - 0x9a, 0xbf, 0x5a, 0xd8, 0xc5, 0x62, 0x8d, 0x96, 0xd4, 0x31, 0xbc, 0x79, 0x3f, 0x0a, 0x9a, 0x17, - 0x93, 0x27, 0x89, 0x11, 0xdf, 0x15, 0xd2, 0xae, 0x44, 0x82, 0x68, 0xfa, 0xc6, 0xf0, 0x06, 0x9c, - 0xe3, 0x53, 0xf7, 0x70, 0xe4, 0x0c, 0x8f, 0x42, 0x76, 0xac, 0xa2, 0x1f, 0x4b, 0x63, 0xc7, 0xe6, - 0xf4, 0x1e, 0xc5, 0x0f, 0xb8, 0x9e, 0x75, 0x92, 0x40, 0xde, 0x86, 0x6f, 0x66, 0xc4, 0x46, 0x91, - 0x52, 0x9d, 0x94, 0x45, 0xa1, 0xa4, 0x2d, 0x8a, 0xd3, 0xaf, 0xc8, 0x3a, 0x10, 0x79, 0xab, 0x63, - 0x8a, 0x56, 0xfe, 0x86, 0x4b, 0x5c, 0x0d, 0x78, 0x45, 0xa4, 0x8d, 0xc5, 0x62, 0xf9, 0x43, 0xd7, - 0x3a, 0x71, 0x10, 0xb9, 0x00, 0x8b, 0x41, 0x8a, 0x6e, 0x7e, 0xec, 0xe4, 0x19, 0xa0, 0xd2, 0x25, - 0x4f, 0xc2, 0x12, 0xbb, 0x05, 0x44, 0x56, 0x2c, 0x20, 0x4c, 0xa7, 0xcb, 0x56, 0xf4, 0x81, 0x02, - 0x4f, 0x3e, 0xaa, 0x0f, 0xc9, 0x3d, 0x38, 0x8f, 0x2f, 0x49, 0xfc, 0x41, 0x30, 0x0c, 0x76, 0xc7, - 0xe9, 0x1c, 0xb9, 0x7c, 0xd6, 0x6a, 0xa9, 0x83, 0x31, 0x1c, 0x5a, 0x56, 0x43, 0x1a, 0x87, 0xe1, - 0xd0, 0xf2, 0x07, 0xe2, 0x77, 0x89, 0x92, 0xf3, 0x3a, 0x74, 0xe1, 0xc2, 0x0c, 0x4a, 0x69, 0xdb, - 0x51, 0xe4, 0x6d, 0xe7, 0x06, 0xa8, 0x07, 0x6e, 0x97, 0x4a, 0xd4, 0x6e, 0x17, 0xab, 0xf6, 0xf6, - 0x6d, 0x96, 0x94, 0xde, 0x5c, 0x09, 0xe0, 0x96, 0x3f, 0xd8, 0xbf, 0xcd, 0xbf, 0x72, 0x2c, 0x0e, - 0x4c, 0xf9, 0x26, 0x43, 0x9e, 0x83, 0xb3, 0xb1, 0x90, 0x28, 0xa1, 0x8f, 0xbd, 0xb9, 0x46, 0x8b, - 0xa2, 0x01, 0xb4, 0xae, 0xc2, 0x92, 0x98, 0x15, 0xa3, 0xc0, 0xf5, 0xce, 0x2c, 0x70, 0x18, 0x5d, - 0x75, 0xfc, 0x73, 0x13, 0xd1, 0xa8, 0xd4, 0x4b, 0xd0, 0x29, 0x24, 0x71, 0xf2, 0x2c, 0x90, 0x40, - 0xea, 0x0f, 0x36, 0x0a, 0xfe, 0xc1, 0x35, 0x51, 0x12, 0xac, 0x70, 0xfe, 0xd9, 0x3f, 0x9f, 0x83, - 0xb3, 0x29, 0xb7, 0x27, 0x7a, 0x85, 0xf0, 0xfa, 0x63, 0xf7, 0x90, 0x5d, 0x40, 0xe4, 0x46, 0xae, - 0x4a, 0x70, 0xae, 0x12, 0x9b, 0x67, 0x49, 0xd7, 0xf9, 0xb7, 0xf8, 0x2f, 0xba, 0x79, 0x38, 0x23, - 0xa1, 0xed, 0xa1, 0xff, 0x92, 0x0a, 0xac, 0x61, 0x26, 0x09, 0xdf, 0x1b, 0x60, 0x42, 0x0a, 0x14, - 0x61, 0x72, 0x91, 0xfb, 0x15, 0xd6, 0xa2, 0x29, 0x21, 0x51, 0x19, 0xc6, 0x54, 0x87, 0x31, 0x08, - 0xf9, 0x14, 0x6c, 0x49, 0x27, 0x95, 0x1d, 0x5b, 0x79, 0xf8, 0xb8, 0xde, 0xdc, 0x70, 0x82, 0x33, - 0x6b, 0x27, 0xb2, 0x06, 0xb7, 0xe1, 0x32, 0x0e, 0xa2, 0xd7, 0x1d, 0xda, 0x89, 0xd4, 0x23, 0xd8, - 0x54, 0x16, 0xab, 0x7f, 0x8b, 0x62, 0x55, 0xba, 0xc3, 0x58, 0x16, 0x12, 0x6c, 0x75, 0x35, 0x75, - 0x75, 0x2e, 0xe0, 0xea, 0xbc, 0x24, 0x37, 0xe6, 0x54, 0x6b, 0xf3, 0x10, 0xd6, 0x02, 0x39, 0x2b, - 0x38, 0xf4, 0xf2, 0x91, 0x04, 0xec, 0xc8, 0x4c, 0x48, 0x5d, 0xec, 0x14, 0x64, 0xe1, 0x01, 0x12, - 0x84, 0x72, 0x10, 0x8c, 0x49, 0x84, 0xc0, 0x27, 0x55, 0x58, 0xa7, 0x37, 0x68, 0x9e, 0xf0, 0xd2, - 0x0f, 0xbe, 0xb5, 0x98, 0xfc, 0x96, 0xb0, 0xed, 0x30, 0x52, 0x93, 0x38, 0x0f, 0x7d, 0x9e, 0x07, - 0xd3, 0x17, 0xdc, 0xbe, 0x0a, 0x84, 0x1d, 0xe5, 0x91, 0x7a, 0xc3, 0xa3, 0x78, 0xf1, 0x6c, 0x99, - 0x09, 0x4a, 0x39, 0x94, 0x17, 0x96, 0x4a, 0x35, 0xe7, 0xf3, 0xf5, 0xff, 0x29, 0x70, 0x36, 0x85, - 0x23, 0xd1, 0x20, 0x23, 0x16, 0x7c, 0xf2, 0x8d, 0x52, 0xf9, 0x8c, 0x99, 0xf1, 0xba, 0xe4, 0x15, - 0x00, 0xcc, 0x32, 0x39, 0x72, 0x0f, 0xdd, 0xaf, 0xc9, 0x29, 0xf6, 0x43, 0x68, 0x84, 0x66, 0x11, - 0xf5, 0xbe, 0x14, 0xcc, 0x2f, 0xe0, 0x8b, 0xb0, 0xe0, 0xf5, 0x3b, 0xbd, 0x49, 0xd7, 0xd5, 0x7e, - 0x20, 0xea, 0x11, 0x1d, 0x11, 0xd2, 0x02, 0x6e, 0x1c, 0xe4, 0xa3, 0x77, 0x7d, 0xfa, 0xe8, 0xc9, - 0x36, 0x17, 0x1e, 0x1a, 0x02, 0x01, 0xb2, 0x65, 0x81, 0x41, 0x3e, 0x80, 0x35, 0x84, 0x77, 0xdb, - 0x1b, 0x70, 0x2e, 0x75, 0x65, 0x51, 0x31, 0x0a, 0xdf, 0x18, 0x86, 0x37, 0x80, 0x05, 0xfa, 0x9b, - 0x5e, 0x01, 0xae, 0xc2, 0xd2, 0x03, 0xd7, 0x19, 0xb9, 0x23, 0x2e, 0x9f, 0xf2, 0xad, 0x8b, 0xc1, - 0x64, 0xf1, 0xb4, 0x1b, 0xdd, 0x42, 0xb8, 0x3a, 0x95, 0xd4, 0xe0, 0x2c, 0x1b, 0x62, 0xef, 0x18, - 0xaf, 0x3c, 0x5c, 0x05, 0xab, 0x44, 0x84, 0x7e, 0x24, 0x41, 0x01, 0xac, 0x82, 0x58, 0x8c, 0xda, - 0x5c, 0x3b, 0x8c, 0x83, 0xe8, 0xc9, 0x73, 0x3e, 0x1d, 0x9b, 0x6c, 0x43, 0x81, 0x31, 0x67, 0x97, - 0x5f, 0x66, 0x3b, 0xbb, 0x3a, 0xf3, 0x0b, 0x25, 0x7c, 0x7a, 0xef, 0x07, 0xff, 0x53, 0xa9, 0x14, - 0x9f, 0x29, 0xd8, 0xc7, 0xb2, 0x69, 0xd0, 0x5c, 0x42, 0x20, 0x37, 0x09, 0x6a, 0x7f, 0xa5, 0x88, - 0xa6, 0x46, 0xf4, 0x46, 0x74, 0x0b, 0xf4, 0xdd, 0xbe, 0x30, 0x8f, 0x2e, 0x9a, 0xfc, 0xd7, 0x63, - 0x6e, 0xc9, 0xe4, 0x25, 0x58, 0xa2, 0x6c, 0x0f, 0x27, 0x7d, 0xb6, 0x35, 0x66, 0x23, 0x21, 0xab, - 0x6a, 0xac, 0x88, 0x0e, 0x5b, 0xf9, 0x8c, 0x59, 0x38, 0x0e, 0x7f, 0xd2, 0x3b, 0xa1, 0x7f, 0x3c, - 0x1e, 0xca, 0x1b, 0xaa, 0xd0, 0xa1, 0x5b, 0xb5, 0x56, 0x93, 0x93, 0xe4, 0x29, 0x4e, 0x78, 0x27, - 0xdc, 0x9e, 0x67, 0x5a, 0x74, 0xed, 0x19, 0x28, 0x48, 0xbc, 0x69, 0x63, 0x98, 0x53, 0x99, 0x68, - 0x0c, 0xfb, 0xc5, 0x07, 0xfb, 0x01, 0xe4, 0x05, 0x4b, 0x7a, 0xf9, 0x3d, 0x1a, 0xf8, 0xe2, 0x30, - 0xc2, 0xff, 0x29, 0x8c, 0xf6, 0x32, 0x36, 0x72, 0xce, 0xc4, 0xff, 0x51, 0xe6, 0x19, 0x3b, 0xf4, - 0xd6, 0xdb, 0xf3, 0xed, 0x21, 0x3e, 0x4e, 0x0c, 0xae, 0x88, 0x14, 0xde, 0xea, 0xf9, 0xec, 0xc9, - 0x22, 0xff, 0xc6, 0x5f, 0x04, 0xc2, 0x62, 0x4c, 0xd1, 0x36, 0xed, 0x6c, 0x8f, 0x88, 0x36, 0x99, - 0xa4, 0x68, 0xc3, 0x42, 0x11, 0x71, 0x4a, 0xf6, 0x65, 0x40, 0x18, 0x8a, 0x36, 0xd2, 0x09, 0x96, - 0x8b, 0x9c, 0x60, 0x92, 0xe6, 0x29, 0x1c, 0x3d, 0x26, 0x19, 0x09, 0xcd, 0x53, 0xfc, 0x3c, 0x7d, - 0x37, 0x98, 0x21, 0x11, 0x55, 0x1f, 0xbd, 0x22, 0xb2, 0xeb, 0x21, 0x4f, 0x60, 0x1d, 0x3b, 0xc8, - 0xcf, 0x62, 0x21, 0x4b, 0x6f, 0x15, 0x1c, 0xe8, 0x8f, 0xd6, 0xac, 0x90, 0xe7, 0x61, 0x3d, 0x48, - 0xb9, 0xea, 0xbf, 0xe9, 0x0d, 0x6d, 0x4c, 0xba, 0x7b, 0xc2, 0x2f, 0x6e, 0x44, 0x94, 0x59, 0x6f, - 0x7a, 0xc3, 0x7d, 0x2c, 0xe1, 0xd5, 0xfc, 0x93, 0x8c, 0xd0, 0xd7, 0x6d, 0x0f, 0x06, 0x63, 0x7f, - 0x3c, 0x72, 0x86, 0x11, 0x63, 0x06, 0x39, 0x86, 0x27, 0xb0, 0x4a, 0xb7, 0x31, 0x09, 0xce, 0x60, - 0x24, 0x82, 0xf4, 0x04, 0x0b, 0xac, 0x70, 0xfb, 0x13, 0xd1, 0x0b, 0xb7, 0x4e, 0xb1, 0x75, 0x19, - 0x99, 0xae, 0x2b, 0x89, 0x6b, 0xf9, 0x8c, 0xb9, 0xc1, 0x78, 0x26, 0xb0, 0x48, 0x39, 0x65, 0xaf, - 0x89, 0x5b, 0x33, 0xb6, 0xc3, 0x8d, 0x27, 0xca, 0x55, 0xde, 0x92, 0xc8, 0x67, 0x60, 0xd1, 0xeb, - 0xca, 0xb9, 0x5e, 0xe3, 0x7a, 0xf4, 0x4a, 0x97, 0xc5, 0x9b, 0x0f, 0x79, 0xd0, 0xa5, 0xe1, 0x71, - 0xe8, 0xf6, 0x72, 0xc4, 0xec, 0xa3, 0x6d, 0x0b, 0xd5, 0x50, 0x92, 0x8c, 0xac, 0x84, 0x67, 0x0e, - 0x9e, 0x2f, 0xb8, 0x0b, 0x84, 0x11, 0xef, 0x4d, 0xfe, 0x4b, 0xfb, 0xdf, 0x70, 0xe3, 0xb4, 0x7d, - 0x44, 0x77, 0x8c, 0x29, 0x1d, 0xbe, 0xc8, 0x82, 0xcd, 0x46, 0xfb, 0xed, 0x2a, 0xc8, 0x01, 0xbb, - 0x3d, 0x31, 0x45, 0x04, 0xac, 0x3d, 0xf2, 0xb4, 0x7f, 0xc9, 0xc2, 0x4a, 0xd4, 0xd0, 0x45, 0x9e, - 0x81, 0x9c, 0xb4, 0x51, 0x6e, 0xa4, 0x58, 0xc3, 0x70, 0x7b, 0x44, 0xa4, 0x53, 0x6d, 0x8c, 0xe4, - 0x0e, 0xac, 0xe0, 0xd3, 0x5b, 0x3c, 0xcd, 0xc7, 0x1e, 0x37, 0x9f, 0xce, 0xb6, 0x80, 0xe7, 0x7f, - 0xfc, 0xde, 0x95, 0x33, 0x68, 0xec, 0x5e, 0xa2, 0xb4, 0xf4, 0x60, 0xa4, 0x85, 0x92, 0x1d, 0x23, - 0x37, 0xdd, 0x8e, 0xc1, 0x9b, 0x32, 0xc5, 0x8e, 0x31, 0x37, 0xc3, 0x8e, 0x11, 0x52, 0xca, 0x76, - 0x0c, 0xb4, 0x66, 0x2d, 0x4c, 0xb3, 0x66, 0x85, 0x34, 0xcc, 0x9a, 0x15, 0xda, 0x21, 0xf2, 0x53, - 0xed, 0x10, 0x21, 0x0d, 0xb7, 0x43, 0x84, 0x96, 0x81, 0xc5, 0xa9, 0x96, 0x01, 0x89, 0x88, 0x59, - 0x06, 0xae, 0xf1, 0x8e, 0x1d, 0x39, 0x0f, 0x6d, 0xec, 0x71, 0x2e, 0x9a, 0x62, 0x97, 0x99, 0xce, - 0x43, 0x7c, 0x53, 0x47, 0x05, 0x13, 0xfe, 0x10, 0x4f, 0xfb, 0x61, 0x6c, 0x03, 0x12, 0x63, 0xfe, - 0x34, 0xac, 0xb0, 0x73, 0x98, 0x07, 0x31, 0x66, 0x07, 0xf1, 0xb2, 0xb9, 0x2c, 0xa0, 0x4c, 0x61, - 0xf4, 0x31, 0x58, 0x0d, 0xd0, 0xb8, 0xce, 0x04, 0xfd, 0x73, 0xcd, 0x80, 0x9a, 0x6b, 0x4b, 0x64, - 0x7e, 0x23, 0x1e, 0xce, 0x29, 0xc2, 0x8f, 0xc5, 0xfa, 0x79, 0x16, 0x48, 0x88, 0x16, 0x3c, 0x4b, - 0xce, 0x21, 0xea, 0x5a, 0x80, 0x1a, 0xbc, 0x1d, 0xfe, 0x3d, 0x25, 0x66, 0x89, 0xf8, 0xa8, 0xaa, - 0xff, 0x0c, 0x04, 0x5f, 0xb7, 0xb9, 0x36, 0x59, 0xb4, 0x40, 0x15, 0x05, 0x4d, 0x0e, 0xd7, 0x0e, - 0xe3, 0xba, 0x8b, 0x8f, 0xa8, 0x56, 0xda, 0x8f, 0xb2, 0x11, 0x2d, 0xad, 0xf8, 0x0c, 0x95, 0x6f, - 0xfc, 0x81, 0xcd, 0x87, 0x98, 0x6f, 0xbf, 0x57, 0xa7, 0x4c, 0x53, 0xfe, 0x10, 0xd3, 0xb2, 0x1a, - 0x26, 0xf8, 0xfe, 0x40, 0xbc, 0xcb, 0xb4, 0xd9, 0x9d, 0x5c, 0x12, 0xba, 0x05, 0x3b, 0xb6, 0xd7, - 0x16, 0x67, 0xb3, 0x13, 0x6a, 0x32, 0xba, 0x4a, 0xf1, 0x6e, 0x1e, 0xfc, 0x12, 0x1f, 0x68, 0x03, - 0x1a, 0x35, 0xfc, 0x28, 0xf3, 0x6c, 0x8a, 0xf6, 0x25, 0xc1, 0x1c, 0x7b, 0x09, 0x39, 0xab, 0x13, - 0xf1, 0xaf, 0x60, 0x6b, 0xc0, 0x12, 0xea, 0x48, 0x05, 0xc3, 0x5c, 0x8a, 0xdd, 0x30, 0xd9, 0xf8, - 0x52, 0xa5, 0x66, 0x16, 0x28, 0x9d, 0x60, 0x73, 0x04, 0x4f, 0xc8, 0x9a, 0xcd, 0x68, 0x25, 0xe7, - 0x44, 0xe8, 0xf1, 0x99, 0x3d, 0x10, 0x2a, 0x40, 0xb1, 0xaa, 0xe7, 0x9d, 0x28, 0x80, 0xa3, 0x69, - 0x47, 0xb0, 0x35, 0x7d, 0x48, 0x66, 0xa4, 0xb5, 0x0b, 0x45, 0x9b, 0x8c, 0x2c, 0xda, 0xc8, 0x7a, - 0xce, 0x6c, 0x44, 0xcf, 0xa9, 0xfd, 0x71, 0x16, 0x9e, 0x3a, 0xc5, 0x70, 0xcd, 0xf8, 0xe6, 0x67, - 0xa3, 0x82, 0x73, 0x26, 0xa2, 0x5b, 0xa2, 0x4c, 0xf9, 0x99, 0x70, 0xd2, 0xef, 0x4c, 0x11, 0x9b, - 0xbf, 0x02, 0xab, 0x6c, 0xe3, 0x67, 0x6f, 0xa9, 0x0f, 0x26, 0xbd, 0x53, 0xec, 0xfc, 0x17, 0x84, - 0xe3, 0x67, 0x8c, 0x14, 0x0f, 0x03, 0xdc, 0xef, 0xac, 0x00, 0x46, 0x5a, 0x50, 0x40, 0xb4, 0x03, - 0xc7, 0xeb, 0x9d, 0xca, 0x03, 0x51, 0xb8, 0x95, 0xca, 0x64, 0xcc, 0x05, 0x84, 0x02, 0x76, 0xf1, - 0x37, 0xb9, 0x0e, 0xab, 0xfd, 0xc9, 0x31, 0x15, 0x09, 0xd9, 0x5c, 0xe0, 0x4f, 0xd6, 0xe6, 0xcc, - 0xe5, 0xfe, 0xe4, 0x58, 0x1f, 0x0e, 0x71, 0x48, 0xf1, 0x6d, 0xdb, 0x1a, 0xc5, 0x63, 0xab, 0x56, - 0x60, 0xce, 0x23, 0x26, 0x65, 0xc0, 0xd6, 0x2d, 0xc7, 0x5d, 0x07, 0xf6, 0xd2, 0x99, 0xa7, 0xf5, - 0x63, 0x3f, 0xb4, 0x7f, 0xcf, 0x08, 0x8d, 0xd9, 0xf4, 0x79, 0xff, 0xeb, 0x21, 0x4a, 0x19, 0xa2, - 0x1b, 0xa0, 0xd2, 0xae, 0x0f, 0x37, 0x95, 0x60, 0x8c, 0x56, 0xfa, 0x93, 0xe3, 0xa0, 0xef, 0xe4, - 0x8e, 0x9f, 0x97, 0x3b, 0xfe, 0x25, 0xa1, 0x51, 0x4b, 0xdd, 0x1e, 0xa6, 0x77, 0x39, 0x95, 0x98, - 0xae, 0x9f, 0x6e, 0x13, 0xf8, 0xf5, 0xb8, 0xa5, 0x8c, 0x5b, 0xcc, 0x74, 0x33, 0x97, 0x30, 0xdd, - 0xa4, 0xac, 0xbd, 0xf9, 0xb4, 0xb5, 0x97, 0x30, 0x14, 0x2d, 0xa4, 0x18, 0x8a, 0x52, 0x17, 0x68, - 0xfe, 0x11, 0x0b, 0x74, 0x51, 0x9e, 0x27, 0xff, 0x90, 0x11, 0x12, 0x53, 0xf4, 0x0a, 0xf4, 0x06, - 0x9c, 0x15, 0x57, 0x20, 0x76, 0x72, 0x84, 0xf6, 0xbf, 0xc2, 0xed, 0x9b, 0x69, 0x97, 0x1f, 0x44, - 0x4b, 0xb9, 0xa0, 0xac, 0xf1, 0x6b, 0x4f, 0x58, 0xfe, 0x3f, 0xe7, 0xc2, 0x43, 0xee, 0xc3, 0x79, - 0x4c, 0x8a, 0xd1, 0x91, 0x2d, 0x97, 0xf6, 0xc8, 0x3d, 0xe0, 0xf3, 0xe1, 0x6a, 0xe2, 0x7a, 0xe0, - 0x75, 0xa4, 0xea, 0x98, 0xee, 0x41, 0xf9, 0x8c, 0xb9, 0xee, 0xa7, 0xc0, 0xe3, 0x77, 0xa9, 0x1f, - 0x28, 0xa0, 0x3d, 0xba, 0xbf, 0xf0, 0xda, 0x1b, 0xef, 0x70, 0x7a, 0xed, 0x95, 0x7a, 0xef, 0x29, - 0x58, 0x1e, 0xb9, 0x07, 0x23, 0xd7, 0x3f, 0x8a, 0xe8, 0xa6, 0x96, 0x38, 0x50, 0x74, 0x8c, 0x88, - 0xa4, 0xfb, 0x58, 0x97, 0x11, 0x41, 0xa4, 0xed, 0x06, 0x57, 0xe4, 0xd4, 0x71, 0xa0, 0xb3, 0x49, - 0xae, 0x20, 0xfb, 0x71, 0x27, 0x97, 0xcf, 0xa8, 0x59, 0x93, 0xc7, 0xfb, 0x3d, 0xf0, 0x7a, 0xae, - 0xf6, 0x97, 0x8a, 0x90, 0x08, 0xd2, 0x3a, 0x8f, 0xbc, 0x21, 0x79, 0x20, 0x64, 0x13, 0x62, 0x48, - 0x1a, 0xc9, 0x69, 0x14, 0x87, 0xd5, 0x0f, 0x49, 0x71, 0xf8, 0x8a, 0x78, 0xc6, 0x48, 0xf7, 0xbc, - 0xfd, 0x5b, 0xe4, 0x26, 0x2c, 0xb0, 0x97, 0x8b, 0xa2, 0xba, 0xab, 0x91, 0xea, 0xee, 0xdf, 0x32, - 0x45, 0xb9, 0xf6, 0x4e, 0x60, 0x57, 0x4f, 0x34, 0x62, 0xff, 0x16, 0x79, 0xe9, 0x74, 0x1e, 0x05, - 0x79, 0xe1, 0x51, 0x10, 0x78, 0x13, 0xbc, 0x1c, 0xf1, 0x26, 0xb8, 0x36, 0xbb, 0xb7, 0xf8, 0x6b, - 0x08, 0x16, 0x43, 0x35, 0x8c, 0xad, 0xf7, 0xf3, 0x0c, 0x5c, 0x9a, 0x49, 0x41, 0x2e, 0x42, 0x5e, - 0x6f, 0x56, 0x5a, 0xe1, 0xf8, 0xd2, 0x35, 0x23, 0x20, 0x64, 0x0f, 0x16, 0xb7, 0x1d, 0xdf, 0xeb, - 0xd0, 0x69, 0x9c, 0x6a, 0x60, 0x4c, 0xb0, 0x0d, 0xd0, 0xcb, 0x67, 0xcc, 0x90, 0x96, 0xd8, 0xb0, - 0x86, 0x6b, 0x21, 0x92, 0x2f, 0x2f, 0x9b, 0xa2, 0x5e, 0x49, 0x30, 0x4c, 0x90, 0xd1, 0x7d, 0x26, - 0x01, 0x24, 0x0f, 0x80, 0x58, 0x56, 0xb9, 0xe4, 0x8e, 0xc6, 0x5c, 0xed, 0x30, 0xf6, 0x82, 0xe7, - 0xe9, 0xcf, 0x3f, 0xa2, 0xef, 0x12, 0x74, 0xe5, 0x33, 0x66, 0x0a, 0xb7, 0xf8, 0x32, 0x7f, 0x5b, - 0xc8, 0x3b, 0xd3, 0x3b, 0xe1, 0x31, 0xe2, 0x53, 0xdf, 0x80, 0x7c, 0x53, 0xbc, 0x85, 0x92, 0xdc, - 0x7c, 0xc4, 0xbb, 0x27, 0x33, 0x28, 0xd5, 0x7e, 0x53, 0x11, 0x7a, 0x96, 0x47, 0x77, 0x96, 0x94, - 0xce, 0xb0, 0x3b, 0x3b, 0x9d, 0x61, 0xf7, 0x97, 0x4c, 0x67, 0xa8, 0x79, 0x70, 0xf3, 0xd4, 0x1d, - 0x4b, 0x3e, 0x0d, 0x2a, 0x66, 0x7e, 0x73, 0xa4, 0x41, 0x62, 0xeb, 0x6b, 0x2d, 0x48, 0x58, 0x50, - 0xe6, 0xe9, 0x35, 0xcd, 0xd5, 0x4e, 0x94, 0x5a, 0xfb, 0x33, 0x9e, 0xa8, 0xa2, 0xd2, 0x6d, 0xc6, - 0x4c, 0x55, 0x1f, 0xd4, 0x33, 0xcc, 0x88, 0x2c, 0xb6, 0xa7, 0xa4, 0xcc, 0xbb, 0xc9, 0x6f, 0x4d, - 0x77, 0x10, 0x93, 0x56, 0xde, 0x1f, 0x66, 0xe1, 0xe2, 0x2c, 0xf2, 0xd4, 0xdc, 0xfe, 0xca, 0xe3, - 0xe5, 0xf6, 0xbf, 0x09, 0x79, 0x06, 0x0b, 0xdc, 0x9e, 0x70, 0x6c, 0x39, 0x29, 0x1d, 0x5b, 0x51, - 0x4c, 0x9e, 0x82, 0x79, 0xbd, 0x64, 0x85, 0xe9, 0x26, 0xd1, 0x3f, 0xc1, 0xe9, 0xf8, 0xf8, 0xf2, - 0x9d, 0x17, 0x91, 0x2f, 0x27, 0x33, 0xac, 0xf2, 0x3c, 0x93, 0x17, 0xa4, 0x0e, 0x49, 0xe4, 0x90, - 0xc1, 0xfa, 0x86, 0x39, 0x4f, 0x78, 0x1a, 0x01, 0x33, 0x99, 0xad, 0x55, 0x83, 0xf9, 0xe6, 0xc8, - 0xf5, 0xdd, 0xb1, 0xec, 0x3b, 0x30, 0x44, 0x88, 0xc9, 0x4b, 0xf8, 0xcb, 0x7e, 0xe7, 0x84, 0x05, - 0x72, 0x99, 0x97, 0x83, 0x6b, 0xa1, 0x2b, 0x00, 0x05, 0x9b, 0x12, 0x0a, 0x25, 0xa8, 0x3a, 0x93, - 0x7e, 0xe7, 0xa8, 0x6d, 0x56, 0xb9, 0xe4, 0xc4, 0x08, 0x7a, 0x08, 0xa5, 0x0d, 0xf4, 0x4d, 0x09, - 0x45, 0xfb, 0xb6, 0x02, 0xeb, 0x69, 0xed, 0x20, 0x17, 0x21, 0xd7, 0x4f, 0x4d, 0x26, 0xdb, 0x67, - 0xf1, 0x27, 0x0a, 0x68, 0x3e, 0x3b, 0x18, 0x8c, 0x8e, 0x9d, 0xb1, 0xec, 0x61, 0x21, 0x81, 0x4d, - 0x34, 0xbc, 0xed, 0xe2, 0xff, 0xe4, 0x8a, 0x38, 0x72, 0xb2, 0x89, 0xf4, 0xb3, 0xf8, 0x47, 0xd3, - 0x01, 0x2a, 0xdd, 0x66, 0x63, 0xc8, 0x72, 0x98, 0xbc, 0x00, 0x39, 0x5a, 0xad, 0xd8, 0xec, 0xa5, - 0xf3, 0x47, 0xaf, 0x55, 0x39, 0x12, 0xab, 0x95, 0xef, 0x1c, 0xf7, 0x4c, 0x44, 0xd6, 0xee, 0xc1, - 0x4a, 0x14, 0x83, 0x18, 0xd1, 0x30, 0xd6, 0x85, 0xdb, 0x2a, 0xe7, 0xb4, 0x3d, 0x18, 0x30, 0x2f, - 0xbf, 0xed, 0x27, 0x7e, 0xfe, 0xde, 0x15, 0xa0, 0x3f, 0x19, 0x4d, 0x5a, 0x98, 0x6b, 0xed, 0x3b, - 0x19, 0x58, 0x0f, 0x03, 0x8b, 0x88, 0x35, 0xf4, 0x2b, 0xeb, 0xe5, 0xae, 0x47, 0xbc, 0xb0, 0x85, - 0xdc, 0x98, 0x6c, 0xe0, 0x0c, 0xe7, 0xcf, 0x3d, 0xd8, 0x9c, 0x86, 0x4f, 0x9e, 0x81, 0x45, 0x8c, - 0x45, 0x37, 0x74, 0x3a, 0xae, 0xbc, 0xcd, 0xf6, 0x05, 0xd0, 0x0c, 0xcb, 0xb5, 0x9f, 0x2a, 0xb0, - 0xc5, 0x7d, 0xd3, 0x6a, 0x8e, 0xd7, 0x47, 0xfb, 0x4d, 0xc7, 0xfd, 0x70, 0xa2, 0x34, 0xec, 0x45, - 0xf6, 0xb1, 0xa7, 0xa3, 0x2e, 0x88, 0x89, 0xaf, 0x4d, 0x6f, 0x2d, 0xb9, 0x89, 0xf1, 0x15, 0xf9, - 0x3b, 0x9c, 0x1c, 0x8b, 0x8a, 0xd3, 0xa7, 0x00, 0x39, 0x2a, 0x0e, 0x62, 0x68, 0xff, 0x07, 0x2e, - 0xcf, 0xfe, 0x00, 0xf9, 0x12, 0x2c, 0x63, 0xc2, 0xc0, 0xf6, 0xf0, 0x70, 0xe4, 0x74, 0x5d, 0xa1, - 0xd9, 0x13, 0x0a, 0x68, 0xb9, 0x8c, 0x85, 0x8b, 0xe4, 0x51, 0x5a, 0x0e, 0x31, 0x15, 0x21, 0x27, - 0x8a, 0x38, 0x80, 0xca, 0xdc, 0xb4, 0x6f, 0x28, 0x40, 0x92, 0x3c, 0xc8, 0x27, 0x61, 0xa9, 0xdd, - 0x2a, 0x59, 0x63, 0x67, 0x34, 0x2e, 0x0f, 0x26, 0x23, 0x1e, 0xab, 0x91, 0x05, 0xed, 0x18, 0x77, - 0x6c, 0x66, 0xa9, 0x3b, 0x1a, 0x4c, 0x46, 0x66, 0x04, 0x0f, 0x13, 0xd3, 0xb9, 0xee, 0x9b, 0x5d, - 0xe7, 0x24, 0x9a, 0x98, 0x8e, 0xc3, 0x22, 0x89, 0xe9, 0x38, 0x4c, 0x7b, 0x57, 0x81, 0x0b, 0xe2, - 0x71, 0x76, 0x37, 0xa5, 0x2e, 0x25, 0x0c, 0x4d, 0x35, 0x12, 0xc1, 0xc1, 0x67, 0x49, 0xe8, 0x6b, - 0x22, 0x7a, 0x1b, 0x56, 0x10, 0x45, 0x75, 0x46, 0x4b, 0x3e, 0x0b, 0x39, 0x6b, 0x3c, 0x18, 0x9e, - 0x22, 0x7c, 0x9b, 0x1a, 0x8c, 0xe8, 0x78, 0x30, 0x44, 0x16, 0x48, 0xa9, 0xb9, 0xb0, 0x2e, 0x57, - 0x4e, 0xd4, 0x98, 0xd4, 0x60, 0x81, 0xc7, 0xe9, 0x8c, 0xbd, 0x5c, 0x9a, 0xd1, 0xa6, 0xed, 0x55, - 0x11, 0x23, 0x8e, 0x07, 0xa7, 0x36, 0x05, 0x0f, 0xed, 0xb7, 0x15, 0x28, 0x50, 0xc1, 0x06, 0x2f, - 0xa5, 0x1f, 0x74, 0x4a, 0x47, 0xe5, 0x60, 0xf1, 0x10, 0x2f, 0x60, 0x7f, 0xaa, 0xd3, 0xf8, 0x45, - 0x58, 0x8d, 0x11, 0x10, 0x0d, 0xa3, 0x03, 0xf5, 0xbc, 0x8e, 0xc3, 0xf2, 0x5c, 0xb1, 0x47, 0x6c, - 0x11, 0x98, 0xf6, 0xff, 0x15, 0x58, 0x6f, 0xbc, 0x39, 0x76, 0x98, 0x41, 0xdd, 0x9c, 0xf4, 0xc4, - 0x7a, 0xa7, 0xc2, 0x9a, 0x78, 0xe5, 0xcf, 0x22, 0x97, 0x30, 0x61, 0x8d, 0xc3, 0xcc, 0xa0, 0x94, - 0x94, 0x21, 0xcf, 0xcf, 0x17, 0x9f, 0xc7, 0x94, 0xbe, 0x2c, 0xe9, 0x46, 0x42, 0xc6, 0x1c, 0x89, - 0xb6, 0x04, 0xb7, 0x30, 0x4e, 0x63, 0x06, 0xd4, 0xda, 0xbf, 0x2a, 0xb0, 0x31, 0x85, 0x86, 0xbc, - 0x06, 0x73, 0xe8, 0x55, 0xcd, 0x47, 0xef, 0xe2, 0x94, 0x4f, 0x8c, 0x3b, 0x47, 0xfb, 0xb7, 0xd8, - 0x41, 0x74, 0x4c, 0x7f, 0x98, 0x8c, 0x8a, 0xbc, 0x01, 0x8b, 0x7a, 0xb7, 0xcb, 0x6f, 0x67, 0x99, - 0xc8, 0xed, 0x6c, 0xca, 0x17, 0x9f, 0x0b, 0xf0, 0xd9, 0xed, 0x8c, 0xf9, 0xf7, 0x75, 0xbb, 0x36, - 0xf7, 0x18, 0x0f, 0xf9, 0x6d, 0x7d, 0x1a, 0x56, 0xa2, 0xc8, 0x8f, 0xe5, 0xe4, 0xfa, 0x8e, 0x02, - 0x6a, 0xb4, 0x0e, 0x1f, 0x4d, 0x74, 0xbb, 0xb4, 0x61, 0x7e, 0xc4, 0xa4, 0xfa, 0xdd, 0x0c, 0x9c, - 0x4b, 0xed, 0x61, 0xf2, 0x2c, 0xcc, 0xeb, 0xc3, 0x61, 0x65, 0x87, 0xcf, 0x2a, 0x2e, 0x21, 0xa1, - 0xd2, 0x3b, 0x72, 0x79, 0x65, 0x48, 0xe4, 0x05, 0xc8, 0xb3, 0x77, 0x1b, 0x3b, 0x62, 0xc3, 0xc1, - 0x70, 0x5d, 0xfc, 0x51, 0x49, 0x34, 0xba, 0xb3, 0x40, 0x24, 0xbb, 0xb0, 0xc2, 0x03, 0x5d, 0xe1, - 0xcb, 0x9d, 0x20, 0xcd, 0x08, 0x66, 0x42, 0x11, 0x9a, 0x74, 0xf6, 0xd8, 0x27, 0xb2, 0x77, 0xc6, - 0xa8, 0x48, 0x15, 0x54, 0xe4, 0x29, 0x73, 0x62, 0x21, 0xa6, 0xa5, 0xc7, 0x4b, 0x53, 0x78, 0x25, - 0x28, 0x83, 0xe1, 0xd2, 0x7d, 0xdf, 0x3b, 0xec, 0x1f, 0xbb, 0xfd, 0xf1, 0x47, 0x37, 0x5c, 0xe1, - 0x37, 0x4e, 0x35, 0x5c, 0xbf, 0x9f, 0x63, 0x8b, 0x39, 0x4e, 0x46, 0x25, 0x1a, 0x29, 0xab, 0x00, - 0x4a, 0x34, 0xf4, 0x7e, 0xc6, 0x43, 0x39, 0xed, 0xc0, 0x02, 0x0b, 0xb1, 0x25, 0x56, 0xc6, 0xa5, - 0xd4, 0x2a, 0x30, 0x9c, 0xfd, 0x5b, 0x4c, 0x7c, 0x61, 0xee, 0xdd, 0xbe, 0x29, 0x48, 0xc9, 0x3e, - 0x14, 0x4a, 0x3d, 0xd7, 0xe9, 0x4f, 0x86, 0xad, 0xd3, 0x19, 0x8d, 0x37, 0x79, 0x5b, 0x96, 0x3a, - 0x8c, 0x0c, 0x8d, 0xcd, 0xb8, 0x93, 0xcb, 0x8c, 0x48, 0x2b, 0xf0, 0xf8, 0xcc, 0xa1, 0xe2, 0xf5, - 0xf9, 0x19, 0xfd, 0x13, 0x07, 0x22, 0x5d, 0xd4, 0x9d, 0x99, 0xbb, 0x84, 0xda, 0xb0, 0x52, 0x75, - 0xfc, 0x71, 0x6b, 0xe4, 0xf4, 0x7d, 0x0c, 0xcd, 0x7b, 0x8a, 0xd0, 0x85, 0x17, 0x44, 0xda, 0x79, - 0x54, 0x99, 0x8e, 0x03, 0x52, 0xa6, 0x90, 0x8d, 0xb2, 0xa3, 0xf2, 0xd2, 0xae, 0xd7, 0x77, 0x7a, - 0xde, 0xd7, 0x85, 0x63, 0x3c, 0x93, 0x97, 0x0e, 0x04, 0xd0, 0x0c, 0xcb, 0xb5, 0x2f, 0x26, 0xc6, - 0x8d, 0xd5, 0xb2, 0x00, 0x0b, 0x3c, 0x6c, 0x0a, 0x0b, 0x23, 0xd2, 0x34, 0xea, 0x3b, 0x95, 0xfa, - 0x9e, 0xaa, 0x90, 0x15, 0x80, 0xa6, 0xd9, 0x28, 0x19, 0x96, 0x45, 0x7f, 0x67, 0xe8, 0x6f, 0x1e, - 0x63, 0x64, 0xb7, 0x5d, 0x55, 0xb3, 0x52, 0x98, 0x91, 0x9c, 0xf6, 0x13, 0x05, 0xce, 0xa7, 0x0f, - 0x25, 0x69, 0x01, 0x06, 0x9a, 0xe1, 0xcf, 0x07, 0x3e, 0x39, 0x73, 0xdc, 0x53, 0xc1, 0xf1, 0x80, - 0x35, 0x63, 0x16, 0x08, 0x25, 0x23, 0x6c, 0x5f, 0xcc, 0xb3, 0xda, 0xeb, 0x9a, 0x19, 0xaf, 0xab, - 0x95, 0x60, 0x73, 0x1a, 0x8f, 0x68, 0x53, 0x57, 0xa1, 0xa0, 0x37, 0x9b, 0xd5, 0x4a, 0x49, 0x6f, - 0x55, 0x1a, 0x75, 0x55, 0x21, 0x8b, 0x30, 0xb7, 0x67, 0x36, 0xda, 0x4d, 0x35, 0xa3, 0x7d, 0x57, - 0x81, 0xe5, 0x4a, 0xf8, 0x6e, 0xf5, 0x83, 0x2e, 0xbe, 0x57, 0x23, 0x8b, 0x6f, 0x33, 0x08, 0xc9, - 0x14, 0x7c, 0xe0, 0x54, 0x2b, 0xef, 0xfd, 0x0c, 0xac, 0x25, 0x68, 0x88, 0x05, 0x0b, 0xfa, 0x3d, - 0xab, 0x51, 0xd9, 0x29, 0xf1, 0x9a, 0x5d, 0x09, 0x1f, 0xb2, 0x61, 0x92, 0xbe, 0xc4, 0x57, 0x58, - 0x18, 0x83, 0x87, 0xbe, 0x3d, 0xf0, 0xba, 0x9d, 0xc8, 0x0b, 0x46, 0xc1, 0x09, 0x4f, 0xb2, 0xaf, - 0x4f, 0x46, 0x2e, 0xb2, 0xcd, 0x44, 0xf4, 0xba, 0x01, 0x3c, 0xc9, 0x18, 0x1f, 0x47, 0x3a, 0xb4, - 0x3c, 0xc9, 0x3a, 0xe4, 0x47, 0xea, 0x30, 0xbf, 0xe7, 0x8d, 0xcb, 0x93, 0x07, 0x7c, 0xfd, 0x5e, - 0x0e, 0x53, 0xb6, 0x95, 0x27, 0x0f, 0x92, 0x6c, 0x51, 0x65, 0xc9, 0x42, 0x8e, 0x45, 0x58, 0x72, - 0x2e, 0x71, 0xcf, 0xeb, 0xdc, 0x63, 0x79, 0x5e, 0x6f, 0x2f, 0x43, 0x81, 0xdf, 0xa1, 0xf0, 0x7a, - 0xf2, 0x23, 0x05, 0x36, 0xa7, 0xf5, 0x1c, 0xbd, 0x96, 0x45, 0x23, 0xac, 0x9c, 0x0f, 0x72, 0xfa, - 0x44, 0x43, 0xab, 0x08, 0x34, 0xf2, 0x3a, 0x14, 0xd8, 0x2b, 0x2d, 0xeb, 0x85, 0xb6, 0x59, 0xe1, - 0xd3, 0xf5, 0xd2, 0x3f, 0xbd, 0x77, 0x65, 0x83, 0x3f, 0xec, 0xf2, 0x5f, 0xb0, 0x27, 0x23, 0x2f, - 0x92, 0xff, 0x44, 0xa6, 0xa0, 0x52, 0xb4, 0x33, 0xe9, 0x7a, 0xae, 0xb8, 0x43, 0x88, 0x28, 0x14, - 0x1c, 0x26, 0x9f, 0x69, 0x02, 0xa6, 0x7d, 0x4b, 0x81, 0xad, 0xe9, 0xc3, 0x44, 0xcf, 0xc9, 0x16, - 0x7b, 0xec, 0x26, 0xe2, 0x40, 0xe0, 0x39, 0x19, 0xbc, 0x88, 0x93, 0x79, 0x0a, 0x44, 0x4a, 0xc4, - 0x35, 0x5c, 0x42, 0x49, 0x22, 0x27, 0xf1, 0x8f, 0x12, 0x09, 0x44, 0xed, 0x3e, 0x6c, 0x4c, 0x19, - 0x54, 0xf2, 0x99, 0xd4, 0x4c, 0x61, 0xe8, 0x26, 0x29, 0x67, 0x0a, 0x8b, 0xa4, 0x9c, 0x94, 0xe0, - 0xda, 0x3f, 0x67, 0xe0, 0x3c, 0x5d, 0x5d, 0x3d, 0xd7, 0xf7, 0xf5, 0x30, 0xa9, 0x36, 0xdd, 0x15, - 0x5f, 0x82, 0xf9, 0xa3, 0xc7, 0x53, 0x15, 0x33, 0x74, 0x42, 0x00, 0x4f, 0x2c, 0xe1, 0x9c, 0x47, - 0xff, 0x27, 0x57, 0x01, 0xa4, 0xb4, 0xea, 0x59, 0x8c, 0xc9, 0x9c, 0xd9, 0x54, 0xcc, 0xc5, 0x61, - 0x90, 0x3c, 0xfd, 0x65, 0x98, 0x43, 0x7d, 0x0a, 0x3f, 0x3b, 0x84, 0xcc, 0x9f, 0x5e, 0x3b, 0xd4, - 0xb6, 0x98, 0x8c, 0x80, 0x7c, 0x02, 0x20, 0x4c, 0x67, 0xc3, 0x0f, 0x07, 0xa1, 0x67, 0x08, 0x32, - 0xda, 0x98, 0x8b, 0xc7, 0x07, 0x0e, 0xcf, 0x11, 0x53, 0x84, 0x35, 0xd1, 0xe3, 0x43, 0x11, 0xca, - 0x95, 0x5b, 0x31, 0x57, 0x59, 0x41, 0x65, 0x28, 0xc2, 0xb9, 0x5e, 0x4b, 0x64, 0x95, 0xc7, 0x88, - 0xee, 0xb1, 0xd4, 0xf1, 0xd7, 0x12, 0xa9, 0xe3, 0xf3, 0x0c, 0x4b, 0xce, 0x0f, 0xaf, 0xfd, 0x7d, - 0x06, 0x16, 0xef, 0x51, 0xa9, 0x0c, 0x75, 0x0d, 0xb3, 0x75, 0x17, 0xb7, 0xa1, 0x50, 0x1d, 0x38, - 0xdc, 0x5c, 0xc4, 0x7d, 0xda, 0xd8, 0x1b, 0xeb, 0xde, 0xc0, 0x11, 0x96, 0x27, 0xdf, 0x94, 0x91, - 0x1e, 0x11, 0x44, 0xe3, 0x0e, 0xcc, 0x33, 0xf3, 0x1d, 0x57, 0xa3, 0x09, 0xb9, 0x3c, 0xa8, 0xd1, - 0x73, 0xac, 0x58, 0xb2, 0x70, 0x30, 0x13, 0xa0, 0x2c, 0x24, 0xf2, 0x07, 0xd7, 0x92, 0x66, 0x65, - 0xee, 0x74, 0x9a, 0x15, 0x29, 0x00, 0xe7, 0xfc, 0x69, 0x02, 0x70, 0x6e, 0xbd, 0x02, 0x05, 0xa9, - 0x3e, 0x8f, 0x25, 0xa6, 0x7f, 0x33, 0x03, 0xcb, 0xd8, 0xaa, 0xe0, 0x2d, 0xcf, 0xaf, 0xa6, 0x9e, - 0xe8, 0xd5, 0x88, 0x9e, 0x68, 0x53, 0x1e, 0x2f, 0xd6, 0xb2, 0x19, 0x0a, 0xa2, 0x3b, 0xb0, 0x96, - 0x40, 0x24, 0x2f, 0xc2, 0x1c, 0xad, 0xbe, 0xb8, 0x57, 0xab, 0xf1, 0x19, 0x10, 0x06, 0x6b, 0xa7, - 0x0d, 0xf7, 0x4d, 0x86, 0xad, 0xfd, 0x9b, 0x02, 0x4b, 0x3c, 0x57, 0x52, 0xff, 0x60, 0xf0, 0xc8, - 0xee, 0xbc, 0x1e, 0xef, 0x4e, 0x16, 0x12, 0x8a, 0x77, 0xe7, 0x7f, 0x75, 0x27, 0xbe, 0x12, 0xe9, - 0xc4, 0x8d, 0x20, 0x74, 0xab, 0x68, 0xce, 0x8c, 0x3e, 0xfc, 0x21, 0x06, 0x33, 0x8f, 0x22, 0x92, - 0x2f, 0xc3, 0x62, 0xdd, 0x7d, 0x18, 0xb9, 0x9e, 0x5e, 0x9f, 0xc2, 0xf4, 0xb9, 0x00, 0x91, 0xad, - 0x29, 0xe6, 0xf6, 0xe0, 0x3e, 0xb4, 0x13, 0x96, 0xc3, 0x90, 0x25, 0xbd, 0xa1, 0x46, 0xc9, 0x1e, - 0x67, 0xea, 0x73, 0x07, 0x7b, 0x8c, 0x72, 0xf6, 0xed, 0x2c, 0x40, 0xe8, 0x9b, 0x4c, 0x17, 0x60, - 0xe4, 0xd1, 0x84, 0xd0, 0xec, 0x23, 0x48, 0x9e, 0xe3, 0xe2, 0x2d, 0xc5, 0x75, 0xae, 0x81, 0xce, - 0x4c, 0x0f, 0xad, 0x8b, 0xba, 0xe8, 0x12, 0x77, 0x86, 0xed, 0xba, 0x3d, 0x87, 0xed, 0xed, 0xd9, - 0xed, 0x6b, 0x18, 0x49, 0x3d, 0x80, 0x4e, 0xc9, 0x91, 0x8f, 0x2e, 0xb3, 0x3b, 0x14, 0x21, 0xe1, - 0xef, 0x9f, 0x7b, 0x3c, 0x7f, 0xff, 0x26, 0x2c, 0x7a, 0xfd, 0xb7, 0xdd, 0xfe, 0x78, 0x30, 0x3a, - 0x41, 0xb5, 0x7b, 0xa8, 0xcf, 0xa3, 0x5d, 0x50, 0x11, 0x65, 0x6c, 0x1c, 0xf0, 0xcc, 0x0d, 0xf0, - 0xe5, 0x61, 0x08, 0x80, 0x41, 0xbc, 0x82, 0x39, 0x75, 0xfe, 0x4e, 0x2e, 0x3f, 0xaf, 0x2e, 0xdc, - 0xc9, 0xe5, 0xf3, 0xea, 0xe2, 0x9d, 0x5c, 0x7e, 0x51, 0x05, 0x53, 0xb2, 0x99, 0x05, 0x36, 0x31, - 0xc9, 0x8c, 0x15, 0x35, 0x51, 0x69, 0xbf, 0xc8, 0x00, 0x49, 0x56, 0x83, 0xbc, 0x0a, 0x05, 0xb6, - 0xc1, 0xda, 0x23, 0xff, 0x2d, 0xee, 0x08, 0xc2, 0x62, 0xc5, 0x49, 0x60, 0x39, 0x56, 0x1c, 0x03, - 0x9b, 0xfe, 0x5b, 0x3d, 0xf2, 0x25, 0x38, 0x8b, 0xdd, 0x3b, 0x74, 0x47, 0xde, 0xa0, 0x6b, 0x63, - 0x60, 0x6f, 0xa7, 0xc7, 0xf3, 0xd9, 0x3e, 0x8b, 0x89, 0xd7, 0x93, 0xc5, 0x53, 0x86, 0x01, 0x5d, - 0x90, 0x9b, 0x88, 0xd9, 0x64, 0x88, 0xa4, 0x05, 0xaa, 0x4c, 0x7f, 0x30, 0xe9, 0xf5, 0xf8, 0xc8, - 0x16, 0xe9, 0x8d, 0x3e, 0x5e, 0x36, 0x85, 0xf1, 0x4a, 0xc8, 0x78, 0x77, 0xd2, 0xeb, 0x91, 0x97, - 0x00, 0x06, 0x7d, 0xfb, 0xd8, 0xf3, 0x7d, 0x66, 0xcc, 0x09, 0x5c, 0x81, 0x42, 0xa8, 0x3c, 0x18, - 0x83, 0x7e, 0x8d, 0x01, 0xc9, 0xff, 0x02, 0x0c, 0x31, 0x83, 0xb1, 0x97, 0xd8, 0x6b, 0x24, 0x9e, - 0x72, 0x4a, 0x00, 0xa3, 0xc1, 0x19, 0x0e, 0x5d, 0xcb, 0xfb, 0xba, 0x70, 0xf1, 0xfb, 0x02, 0xac, - 0xf1, 0xf7, 0xd2, 0xf7, 0xbc, 0xf1, 0x11, 0xbf, 0x4a, 0x7c, 0x90, 0x7b, 0x88, 0x74, 0x97, 0xf8, - 0xeb, 0x1c, 0x80, 0x7e, 0xcf, 0x12, 0x61, 0x0d, 0x6f, 0xc2, 0x1c, 0xbd, 0x20, 0x09, 0x45, 0x0b, - 0xaa, 0xa9, 0x91, 0xaf, 0xac, 0xa6, 0x46, 0x0c, 0xba, 0x1a, 0x4d, 0x74, 0x77, 0x10, 0x4a, 0x16, - 0x5c, 0x8d, 0xcc, 0x03, 0x22, 0x12, 0x56, 0x9e, 0x63, 0x91, 0x2a, 0x40, 0x18, 0x68, 0x90, 0x8b, - 0xfc, 0x6b, 0x61, 0xc4, 0x2e, 0x5e, 0xc0, 0x53, 0xdb, 0x84, 0xc1, 0x0a, 0xe5, 0xe9, 0x13, 0xa2, - 0x91, 0xbb, 0x90, 0x6b, 0x39, 0x41, 0x2c, 0x80, 0x29, 0xe1, 0x17, 0x9f, 0xe4, 0xf9, 0x86, 0xc3, - 0x10, 0x8c, 0x2b, 0x63, 0x27, 0x92, 0x96, 0x1d, 0x99, 0x10, 0x03, 0xe6, 0x9b, 0xce, 0xc8, 0x39, - 0xf6, 0xa7, 0x85, 0xed, 0x65, 0xa5, 0x22, 0x58, 0x3f, 0x02, 0x65, 0x99, 0x82, 0x15, 0x93, 0xdb, - 0x90, 0xb5, 0xac, 0x1a, 0x0f, 0x3a, 0xb4, 0x1c, 0x5e, 0xbf, 0x2c, 0xab, 0xc6, 0xec, 0xbe, 0xbe, - 0x7f, 0x2c, 0x91, 0x51, 0x64, 0xf2, 0x29, 0x28, 0x48, 0x42, 0x31, 0x0f, 0xd7, 0x85, 0x7d, 0x20, - 0xf9, 0x4b, 0xca, 0x9b, 0x86, 0x84, 0x4d, 0xaa, 0xa0, 0xde, 0x9d, 0x3c, 0x70, 0xf5, 0xe1, 0x10, - 0x1d, 0xa9, 0xdf, 0x76, 0x47, 0x4c, 0x6c, 0xcb, 0x87, 0x71, 0xee, 0xd1, 0x7b, 0xa5, 0x2b, 0x4a, - 0x65, 0x65, 0x53, 0x9c, 0x92, 0x34, 0x61, 0xcd, 0x72, 0xc7, 0x93, 0x21, 0x7b, 0x5f, 0xb3, 0x3b, - 0x18, 0xd1, 0xfb, 0x0d, 0x0b, 0xee, 0x85, 0x21, 0xc1, 0x7d, 0x5a, 0x28, 0x1e, 0x35, 0x1d, 0x0c, - 0x46, 0xb1, 0xbb, 0x4e, 0x92, 0x58, 0x73, 0xe5, 0x21, 0xa7, 0xa7, 0x6a, 0xf4, 0xd6, 0x84, 0xa7, - 0xaa, 0xb8, 0x35, 0x85, 0x77, 0xa5, 0x4f, 0xa4, 0x04, 0xa0, 0x44, 0xcb, 0xa0, 0x14, 0x80, 0x32, - 0x12, 0x76, 0xf2, 0xdd, 0x9c, 0x14, 0x03, 0x99, 0x8f, 0xc5, 0x6b, 0x00, 0x77, 0x06, 0x5e, 0xbf, - 0xe6, 0x8e, 0x8f, 0x06, 0x5d, 0x29, 0x0e, 0x66, 0xe1, 0xab, 0x03, 0xaf, 0x6f, 0x1f, 0x23, 0xf8, - 0x17, 0xef, 0x5d, 0x91, 0x90, 0x4c, 0xe9, 0x7f, 0xf2, 0x71, 0x58, 0xa4, 0xbf, 0x5a, 0xe1, 0x2b, - 0x21, 0xa6, 0x93, 0x45, 0x6a, 0x96, 0x29, 0x28, 0x44, 0x20, 0xaf, 0x60, 0x6e, 0x2c, 0x6f, 0x38, - 0x96, 0x84, 0x57, 0x91, 0x08, 0xcb, 0x1b, 0x8e, 0xe3, 0x61, 0xed, 0x25, 0x64, 0x52, 0x0e, 0xaa, - 0x2e, 0xd2, 0xd9, 0xf1, 0x14, 0x5c, 0xa8, 0x78, 0xe4, 0x73, 0xcd, 0x16, 0xf1, 0xb4, 0x65, 0x17, - 0xcd, 0x18, 0x19, 0x56, 0xc2, 0x2a, 0xef, 0x30, 0x4b, 0x11, 0x17, 0x6a, 0x59, 0x25, 0xfc, 0xa3, - 0xae, 0xdd, 0x41, 0x70, 0xa4, 0x12, 0x01, 0x32, 0xd9, 0x86, 0x55, 0x26, 0xe3, 0x07, 0x69, 0x71, - 0xb9, 0x88, 0x8b, 0x7b, 0x5b, 0x98, 0x37, 0x57, 0xfe, 0x7c, 0x8c, 0x80, 0xec, 0xc2, 0x1c, 0xde, - 0x35, 0xb9, 0x37, 0xc4, 0x05, 0x59, 0x4d, 0x10, 0x5f, 0x47, 0xb8, 0xaf, 0xa0, 0x82, 0x40, 0xde, - 0x57, 0x10, 0x95, 0x7c, 0x1e, 0xc0, 0xe8, 0x8f, 0x06, 0xbd, 0x1e, 0x46, 0x7c, 0xcf, 0x47, 0x1c, - 0x63, 0x39, 0x1f, 0xe4, 0x12, 0x22, 0xf1, 0xe8, 0xa4, 0xf8, 0xdb, 0x8e, 0xc5, 0x85, 0x97, 0x78, - 0x69, 0x15, 0x98, 0x67, 0x8b, 0x11, 0xb3, 0x27, 0xf0, 0x7c, 0x50, 0x52, 0xec, 0x7d, 0x96, 0x3d, - 0x81, 0xc3, 0x93, 0xd9, 0x13, 0x24, 0x02, 0xed, 0x2e, 0xac, 0xa7, 0x35, 0x2c, 0x72, 0x3b, 0x56, - 0x4e, 0x7b, 0x3b, 0xfe, 0x7e, 0x16, 0x96, 0x90, 0x9b, 0xd8, 0x85, 0x75, 0x58, 0xb6, 0x26, 0x0f, - 0x82, 0xd0, 0x82, 0x62, 0x37, 0xc6, 0xfa, 0xf9, 0x72, 0x81, 0x6c, 0xc3, 0x8b, 0x50, 0x10, 0x03, - 0x56, 0xc4, 0x49, 0xb0, 0x27, 0x3c, 0x07, 0x82, 0xc4, 0x05, 0xc2, 0xa1, 0x22, 0x99, 0x16, 0x3c, - 0x46, 0x14, 0x9e, 0x07, 0xd9, 0xc7, 0x39, 0x0f, 0x72, 0xa7, 0x3a, 0x0f, 0xde, 0x80, 0x25, 0xf1, - 0x35, 0xdc, 0xc9, 0xe7, 0x3e, 0xd8, 0x4e, 0x1e, 0x61, 0x46, 0xaa, 0xc1, 0x8e, 0x3e, 0x3f, 0x73, - 0x47, 0x47, 0xc3, 0xa8, 0x58, 0x65, 0x43, 0x84, 0x25, 0x37, 0x76, 0xcc, 0x9b, 0xbb, 0x57, 0x6a, - 0xfe, 0x12, 0xa7, 0xe4, 0x8b, 0xb0, 0x58, 0x1d, 0x08, 0x9b, 0x98, 0x64, 0x8c, 0xe8, 0x09, 0xa0, - 0x2c, 0x2e, 0x04, 0x98, 0xc1, 0xe9, 0x96, 0xfd, 0x30, 0x4e, 0xb7, 0x57, 0x00, 0xb8, 0x4b, 0x4a, - 0x98, 0xef, 0x12, 0x97, 0x8c, 0x88, 0x90, 0x14, 0xb5, 0x89, 0x48, 0xc8, 0x74, 0x77, 0xe2, 0xcf, - 0x6d, 0x84, 0x0b, 0xb7, 0x9c, 0x20, 0x5e, 0xf8, 0xc0, 0x0b, 0xaf, 0x70, 0x79, 0x7b, 0x88, 0x91, - 0x7d, 0xb8, 0x03, 0x42, 0x3e, 0x17, 0x3c, 0x7e, 0x5c, 0x98, 0xd5, 0x43, 0x5a, 0xa2, 0x87, 0xa6, - 0x3e, 0x79, 0xd4, 0x7e, 0xa2, 0xc8, 0x59, 0x63, 0x7e, 0x89, 0xa1, 0x7e, 0x19, 0x20, 0x78, 0x94, - 0x20, 0xc6, 0x3a, 0x70, 0x13, 0x67, 0x50, 0xb9, 0x97, 0x43, 0x5c, 0xa9, 0x35, 0xd9, 0x0f, 0xab, - 0x35, 0x2d, 0x28, 0x34, 0xde, 0x1c, 0x3b, 0xe1, 0x2b, 0x16, 0xb0, 0x02, 0x49, 0x16, 0x77, 0xa6, - 0xec, 0xf6, 0xd3, 0x78, 0x36, 0x84, 0x72, 0xf0, 0x14, 0x11, 0x58, 0x22, 0xd4, 0xfe, 0x43, 0x81, - 0x55, 0x39, 0x70, 0xc7, 0x49, 0xbf, 0x43, 0x3e, 0xc3, 0x82, 0x58, 0x2b, 0x91, 0x2b, 0x8b, 0x84, - 0x44, 0xb7, 0xdc, 0x93, 0x7e, 0x87, 0x09, 0x40, 0xce, 0x43, 0xb9, 0xb2, 0x94, 0x90, 0x3c, 0x80, - 0xa5, 0xe6, 0xa0, 0xd7, 0xa3, 0x62, 0xcd, 0xe8, 0x6d, 0x7e, 0x01, 0xa0, 0x8c, 0xe2, 0xa6, 0x11, - 0x51, 0xa1, 0xed, 0xa7, 0xf8, 0x3d, 0x77, 0x63, 0x48, 0xf7, 0x7b, 0x8f, 0xd3, 0x85, 0x6c, 0xdf, - 0x41, 0xd7, 0x40, 0x99, 0x67, 0x78, 0x36, 0x45, 0xb3, 0x9f, 0xc8, 0xb5, 0xa4, 0xc5, 0x58, 0xcf, - 0x19, 0x67, 0x93, 0xf6, 0x33, 0x05, 0x48, 0xb2, 0x69, 0xf2, 0xd6, 0xa7, 0xfc, 0x37, 0x88, 0xc2, - 0x31, 0x11, 0x32, 0xf7, 0x38, 0x22, 0xa4, 0xf6, 0x3d, 0x05, 0xd6, 0xd3, 0xfa, 0x81, 0x9e, 0x20, - 0xf2, 0x91, 0x12, 0x1c, 0x68, 0x78, 0x82, 0xc8, 0xa7, 0x50, 0xf4, 0x58, 0x8b, 0x11, 0xc5, 0x2b, - 0x97, 0x79, 0x9c, 0xca, 0x15, 0x7f, 0x47, 0x81, 0xd5, 0x8a, 0x5e, 0xe3, 0xc9, 0x72, 0x98, 0x99, - 0xea, 0x2a, 0x5c, 0xaa, 0xe8, 0x35, 0xbb, 0xd9, 0xa8, 0x56, 0x4a, 0xf7, 0xed, 0xd4, 0x18, 0xf8, - 0x97, 0xe0, 0x89, 0x24, 0x4a, 0x68, 0xce, 0xba, 0x08, 0x9b, 0xc9, 0x62, 0x11, 0x27, 0x3f, 0x9d, - 0x58, 0x84, 0xd4, 0xcf, 0x16, 0x5f, 0x87, 0x55, 0x11, 0x13, 0xbe, 0x55, 0xb5, 0x30, 0xeb, 0xcc, - 0x2a, 0x14, 0xf6, 0x0d, 0xb3, 0xb2, 0x7b, 0xdf, 0xde, 0x6d, 0x57, 0xab, 0xea, 0x19, 0xb2, 0x0c, - 0x8b, 0x1c, 0x50, 0xd2, 0x55, 0x85, 0x2c, 0x41, 0xbe, 0x52, 0xb7, 0x8c, 0x52, 0xdb, 0x34, 0xd4, - 0x4c, 0xf1, 0x75, 0x58, 0x69, 0x8e, 0xbc, 0xb7, 0x9d, 0xb1, 0x7b, 0xd7, 0x3d, 0x41, 0x6b, 0xd4, - 0x02, 0x64, 0x4d, 0xfd, 0x9e, 0x7a, 0x86, 0x00, 0xcc, 0x37, 0xef, 0x96, 0xac, 0x5b, 0xb7, 0x54, - 0x85, 0x14, 0x60, 0x61, 0xaf, 0xd4, 0xb4, 0xef, 0xd6, 0x2c, 0x35, 0x43, 0x7f, 0xe8, 0xf7, 0x2c, - 0xfc, 0x91, 0x2d, 0x3e, 0x0f, 0x6b, 0x28, 0x75, 0x55, 0x3d, 0x7f, 0xec, 0xf6, 0xdd, 0x11, 0xd6, - 0x61, 0x09, 0xf2, 0x96, 0x4b, 0xb7, 0xcb, 0xb1, 0xcb, 0x2a, 0x50, 0x9b, 0xf4, 0xc6, 0xde, 0xb0, - 0xe7, 0x7e, 0x4d, 0x55, 0x8a, 0xaf, 0xc0, 0xaa, 0x39, 0x98, 0x8c, 0xbd, 0xfe, 0xa1, 0x35, 0xa6, - 0x18, 0x87, 0x27, 0xe4, 0x1c, 0xac, 0xb5, 0xeb, 0x7a, 0x6d, 0xbb, 0xb2, 0xd7, 0x6e, 0xb4, 0x2d, - 0xbb, 0xa6, 0xb7, 0x4a, 0x65, 0x66, 0x0b, 0xab, 0x35, 0xac, 0x96, 0x6d, 0x1a, 0x25, 0xa3, 0xde, - 0x52, 0x95, 0xe2, 0x77, 0x50, 0x81, 0xd4, 0x19, 0xf4, 0xbb, 0xbb, 0x4e, 0x67, 0x3c, 0x18, 0x61, - 0x85, 0x35, 0xb8, 0x6c, 0x19, 0xa5, 0x46, 0x7d, 0xc7, 0xde, 0xd5, 0x4b, 0xad, 0x86, 0x99, 0x96, - 0x84, 0x61, 0x0b, 0xce, 0xa7, 0xe0, 0x34, 0x5a, 0x4d, 0x55, 0x21, 0x57, 0xe0, 0x42, 0x4a, 0xd9, - 0x3d, 0x63, 0x5b, 0x6f, 0xb7, 0xca, 0x75, 0x35, 0x33, 0x85, 0xd8, 0xb2, 0x1a, 0x6a, 0xb6, 0xf8, - 0x1b, 0x0a, 0xac, 0xb4, 0x7d, 0xfe, 0xae, 0xbe, 0x8d, 0x5e, 0xc4, 0x4f, 0xc2, 0xc5, 0xb6, 0x65, - 0x98, 0x76, 0xab, 0x71, 0xd7, 0xa8, 0xdb, 0x6d, 0x4b, 0xdf, 0x8b, 0xd7, 0xe6, 0x0a, 0x5c, 0x90, - 0x30, 0x4c, 0xa3, 0xd4, 0xd8, 0x37, 0x4c, 0xbb, 0xa9, 0x5b, 0xd6, 0xbd, 0x86, 0xb9, 0xa3, 0x2a, - 0xf4, 0x8b, 0x29, 0x08, 0xb5, 0x5d, 0x9d, 0xd5, 0x26, 0x52, 0x56, 0x37, 0xee, 0xe9, 0x55, 0x7b, - 0xbb, 0xd1, 0x52, 0xb3, 0xc5, 0x1a, 0x15, 0x62, 0x30, 0x14, 0x3a, 0x7b, 0x3e, 0x99, 0x87, 0x5c, - 0xbd, 0x51, 0x37, 0xe2, 0x16, 0xd4, 0x25, 0xc8, 0xeb, 0xcd, 0xa6, 0xd9, 0xd8, 0xc7, 0x29, 0x06, - 0x30, 0xbf, 0x63, 0xd4, 0x69, 0xcd, 0xb2, 0xb4, 0xa4, 0x69, 0x36, 0x6a, 0x8d, 0x96, 0xb1, 0xa3, - 0xe6, 0x8a, 0xa6, 0xd8, 0x5f, 0x04, 0xd3, 0xce, 0x80, 0x99, 0x2b, 0x77, 0x8c, 0x5d, 0xbd, 0x5d, - 0x6d, 0xf1, 0x21, 0xba, 0x6f, 0x9b, 0xc6, 0xe7, 0xda, 0x86, 0xd5, 0xb2, 0x54, 0x85, 0xa8, 0xb0, - 0x54, 0x37, 0x8c, 0x1d, 0xcb, 0x36, 0x8d, 0xfd, 0x8a, 0x71, 0x4f, 0xcd, 0x50, 0x9e, 0xec, 0x7f, - 0xfa, 0x85, 0xe2, 0xbb, 0x0a, 0x10, 0x16, 0x46, 0x5e, 0xe4, 0x26, 0xc3, 0x19, 0x73, 0x19, 0xb6, - 0xca, 0x74, 0xa8, 0xb1, 0x69, 0xb5, 0xc6, 0x4e, 0xbc, 0xcb, 0xce, 0x03, 0x89, 0x95, 0x37, 0x76, - 0x77, 0x55, 0x85, 0x5c, 0x80, 0xb3, 0x31, 0xf8, 0x8e, 0xd9, 0x68, 0xaa, 0x99, 0xad, 0x4c, 0x5e, - 0x21, 0x1b, 0x89, 0xc2, 0xbb, 0x86, 0xd1, 0x54, 0xb3, 0x74, 0x88, 0x62, 0x05, 0x62, 0x49, 0x30, - 0xf2, 0x5c, 0xf1, 0x5b, 0x0a, 0x9c, 0x67, 0xd5, 0x14, 0xeb, 0x2b, 0xa8, 0xea, 0x45, 0xd8, 0xe4, - 0xc9, 0x31, 0xd2, 0x2a, 0xba, 0x0e, 0x6a, 0xa4, 0x94, 0x55, 0xf3, 0x1c, 0xac, 0x45, 0xa0, 0x58, - 0x8f, 0x0c, 0xdd, 0x3d, 0x22, 0xe0, 0x6d, 0xc3, 0x6a, 0xd9, 0xc6, 0xee, 0x6e, 0xc3, 0x6c, 0xb1, - 0x8a, 0x64, 0x8b, 0x1a, 0xac, 0x95, 0xdc, 0xd1, 0x98, 0xde, 0x2f, 0xfb, 0xbe, 0x37, 0xe8, 0x63, - 0x15, 0x96, 0x61, 0xd1, 0xf8, 0x7c, 0xcb, 0xa8, 0x5b, 0x95, 0x46, 0x5d, 0x3d, 0x53, 0xbc, 0x18, - 0xc3, 0x11, 0xeb, 0xd8, 0xb2, 0xca, 0xea, 0x99, 0xa2, 0x03, 0xcb, 0xe2, 0x75, 0x39, 0x9b, 0x15, - 0x97, 0x61, 0x4b, 0xcc, 0x35, 0xdc, 0x51, 0xe2, 0x4d, 0xd8, 0x84, 0xf5, 0x64, 0xb9, 0xd1, 0x52, - 0x15, 0x3a, 0x0a, 0xb1, 0x12, 0x0a, 0xcf, 0x14, 0xff, 0xaf, 0x02, 0xcb, 0x81, 0x65, 0x08, 0x75, - 0xd1, 0x57, 0xe0, 0x42, 0x6d, 0x57, 0xb7, 0x77, 0x8c, 0xfd, 0x4a, 0xc9, 0xb0, 0xef, 0x56, 0xea, - 0x3b, 0xb1, 0x8f, 0x3c, 0x01, 0xe7, 0x52, 0x10, 0xf0, 0x2b, 0x9b, 0xb0, 0x1e, 0x2f, 0x6a, 0xd1, - 0xa5, 0x9a, 0xa1, 0x5d, 0x1f, 0x2f, 0x09, 0xd6, 0x69, 0xb6, 0xb8, 0x0f, 0x2b, 0x96, 0x5e, 0xab, - 0xee, 0x0e, 0x46, 0x1d, 0x57, 0x9f, 0x8c, 0x8f, 0xfa, 0xe4, 0x02, 0x6c, 0xec, 0x36, 0xcc, 0x92, - 0x61, 0x23, 0x4a, 0xac, 0x06, 0x67, 0x61, 0x55, 0x2e, 0xbc, 0x6f, 0xd0, 0xe9, 0x4b, 0x60, 0x45, - 0x06, 0xd6, 0x1b, 0x6a, 0xa6, 0xf8, 0x45, 0x58, 0x8a, 0xa4, 0x28, 0xdd, 0x80, 0xb3, 0xf2, 0xef, - 0xa6, 0xdb, 0xef, 0x7a, 0xfd, 0x43, 0xf5, 0x4c, 0xbc, 0xc0, 0x9c, 0xf4, 0xfb, 0xb4, 0x00, 0xd7, - 0xb3, 0x5c, 0xd0, 0x72, 0x47, 0xc7, 0x5e, 0xdf, 0x19, 0xbb, 0x5d, 0x35, 0x53, 0x7c, 0x0e, 0x96, - 0x23, 0x89, 0x11, 0xe8, 0xc0, 0x55, 0x1b, 0x7c, 0x03, 0xae, 0x19, 0x3b, 0x95, 0x76, 0x4d, 0x9d, - 0xa3, 0x2b, 0xb9, 0x5c, 0xd9, 0x2b, 0xab, 0x50, 0xfc, 0xae, 0x42, 0x2f, 0x53, 0x98, 0xee, 0xac, - 0xb6, 0xab, 0x8b, 0xa1, 0xa6, 0xd3, 0x8c, 0xa5, 0x5b, 0x31, 0x2c, 0x8b, 0x3d, 0x1c, 0xb8, 0x08, - 0x9b, 0xfc, 0x87, 0xad, 0xd7, 0x77, 0xec, 0xb2, 0x6e, 0xee, 0xdc, 0xd3, 0x4d, 0x3a, 0xf7, 0xee, - 0xab, 0x19, 0x5c, 0x50, 0x12, 0xc4, 0x6e, 0x35, 0xda, 0xa5, 0xb2, 0x9a, 0xa5, 0xf3, 0x37, 0x02, - 0x6f, 0x56, 0xea, 0x6a, 0x0e, 0x97, 0x67, 0x02, 0x1b, 0xd9, 0xd2, 0xf2, 0xb9, 0xe2, 0xfb, 0x0a, - 0x6c, 0x58, 0xde, 0x61, 0xdf, 0x19, 0x4f, 0x46, 0xae, 0xde, 0x3b, 0x1c, 0x8c, 0xbc, 0xf1, 0xd1, - 0xb1, 0x35, 0xf1, 0xc6, 0x2e, 0xb9, 0x09, 0x4f, 0x5b, 0x95, 0xbd, 0xba, 0xde, 0xa2, 0xcb, 0x4b, - 0xaf, 0xee, 0x35, 0xcc, 0x4a, 0xab, 0x5c, 0xb3, 0xad, 0x76, 0x25, 0x31, 0xf3, 0xae, 0xc1, 0x93, - 0xd3, 0x51, 0xab, 0xc6, 0x9e, 0x5e, 0xba, 0xaf, 0x2a, 0xb3, 0x19, 0x6e, 0xeb, 0x55, 0xbd, 0x5e, - 0x32, 0x76, 0xec, 0xfd, 0x5b, 0x6a, 0x86, 0x3c, 0x0d, 0x57, 0xa7, 0xa3, 0xee, 0x56, 0x9a, 0x16, - 0x45, 0xcb, 0xce, 0xfe, 0x6e, 0xd9, 0xaa, 0x51, 0xac, 0x5c, 0xf1, 0x7b, 0x0a, 0x6c, 0x4e, 0x0b, - 0x55, 0x47, 0xae, 0x83, 0x66, 0xd4, 0x5b, 0xa6, 0x5e, 0xd9, 0xb1, 0x4b, 0xa6, 0xb1, 0x63, 0xd4, - 0x5b, 0x15, 0xbd, 0x6a, 0xd9, 0x56, 0xa3, 0x4d, 0x67, 0x53, 0xf8, 0xbe, 0xe3, 0x29, 0xb8, 0x32, - 0x03, 0xaf, 0x51, 0xd9, 0x29, 0xa9, 0x0a, 0xb9, 0x05, 0xcf, 0xce, 0x40, 0xb2, 0xee, 0x5b, 0x2d, - 0xa3, 0x26, 0x97, 0xa8, 0x19, 0xdc, 0xb0, 0xd2, 0x23, 0x75, 0xd1, 0xd6, 0x61, 0xc9, 0xec, 0x8a, - 0x5d, 0x85, 0x4b, 0x53, 0xb1, 0x78, 0xb5, 0x9e, 0x82, 0x2b, 0x53, 0x51, 0x58, 0xa5, 0xd4, 0x4c, - 0xb1, 0x04, 0x5b, 0xd3, 0x83, 0x15, 0xd1, 0xf3, 0x22, 0x3a, 0xe4, 0x79, 0xc8, 0xed, 0xd0, 0x23, - 0x2a, 0x92, 0x1e, 0xa8, 0xe8, 0x81, 0x1a, 0x0f, 0xe4, 0x91, 0x78, 0x11, 0x64, 0xb6, 0xeb, 0x75, - 0x76, 0x9e, 0xad, 0x42, 0xa1, 0xd1, 0x2a, 0x1b, 0x26, 0x4f, 0xb0, 0x84, 0x19, 0x95, 0xda, 0x75, - 0xba, 0x82, 0x1b, 0x66, 0xe5, 0x0b, 0x78, 0xb0, 0x6d, 0xc2, 0xba, 0x55, 0xd5, 0x4b, 0x77, 0xed, - 0x7a, 0xa3, 0x65, 0x57, 0xea, 0x76, 0xa9, 0xac, 0xd7, 0xeb, 0x46, 0x55, 0x05, 0x1c, 0xd5, 0x69, - 0x9e, 0xac, 0xe4, 0xe3, 0x70, 0xa3, 0x71, 0xb7, 0xa5, 0xdb, 0xcd, 0x6a, 0x7b, 0xaf, 0x52, 0xb7, - 0xad, 0xfb, 0xf5, 0x92, 0x10, 0xc2, 0x4a, 0xc9, 0xbd, 0xff, 0x06, 0x5c, 0x9b, 0x89, 0x1d, 0xa6, - 0x42, 0xba, 0x0e, 0xda, 0x4c, 0x4c, 0xde, 0x90, 0xe2, 0x4f, 0x15, 0xb8, 0x30, 0xc3, 0x62, 0x4f, - 0x9e, 0x85, 0x9b, 0x65, 0x43, 0xdf, 0xa9, 0x1a, 0x96, 0x85, 0x3b, 0x16, 0x1d, 0x14, 0xf6, 0x72, - 0x28, 0x75, 0x67, 0xbf, 0x09, 0x4f, 0xcf, 0x46, 0x0f, 0x65, 0x84, 0x1b, 0x70, 0x6d, 0x36, 0x2a, - 0x97, 0x19, 0x32, 0xa4, 0x08, 0xd7, 0x67, 0x63, 0x06, 0xb2, 0x46, 0xb6, 0xf8, 0x5b, 0x0a, 0x9c, - 0x4f, 0x57, 0x9b, 0xd1, 0xba, 0x55, 0xea, 0x56, 0x4b, 0xaf, 0x56, 0xed, 0xa6, 0x6e, 0xea, 0x35, - 0xdb, 0xa8, 0x9b, 0x8d, 0x6a, 0x35, 0xed, 0x8c, 0xbd, 0x06, 0x4f, 0x4e, 0x47, 0xb5, 0x4a, 0x66, - 0xa5, 0x49, 0x8f, 0x11, 0x0d, 0x2e, 0x4f, 0xc7, 0x32, 0x2a, 0x25, 0x43, 0xcd, 0x6c, 0xbf, 0xf6, - 0xe3, 0xbf, 0xbb, 0x7c, 0xe6, 0xc7, 0xef, 0x5f, 0x56, 0x7e, 0xf6, 0xfe, 0x65, 0xe5, 0x6f, 0xdf, - 0xbf, 0xac, 0x7c, 0xe1, 0x99, 0xd3, 0x65, 0x11, 0xc4, 0xdb, 0xd1, 0x83, 0x79, 0xbc, 0x0f, 0xbe, - 0xf0, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x5f, 0x08, 0x73, 0x73, 0xc6, 0x01, 0x00, + // 30968 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xfd, 0x7b, 0x70, 0x5c, 0x59, + 0x7a, 0x18, 0x86, 0x4f, 0x77, 0xe3, 0xd1, 0xf8, 0xf0, 0x6a, 0x1c, 0x80, 0x24, 0x88, 0x79, 0x34, + 0xe7, 0xce, 0x0c, 0x87, 0x9c, 0x9d, 0x21, 0x97, 0xe0, 0x0e, 0x77, 0x67, 0xe7, 0xb5, 0x8d, 0x6e, + 0x90, 0x68, 0x12, 0x04, 0x7b, 0x6e, 0x03, 0xc4, 0x8e, 0xf6, 0x71, 0xf7, 0xa2, 0xfb, 0x00, 0xb8, + 0x83, 0xee, 0xbe, 0xbd, 0xf7, 0xde, 0x26, 0x09, 0xad, 0xf5, 0xb3, 0x5e, 0x6b, 0xfd, 0x54, 0x8a, + 0x9e, 0x96, 0xac, 0x75, 0x4a, 0x56, 0x5c, 0xb2, 0x1d, 0xab, 0x9c, 0x92, 0xca, 0x96, 0xa2, 0xc4, + 0x89, 0x2b, 0x8a, 0x94, 0x72, 0x14, 0x45, 0xe5, 0xb2, 0x54, 0x8e, 0x93, 0x54, 0x36, 0x0e, 0x14, + 0x45, 0xf9, 0x0b, 0x55, 0xae, 0x92, 0xe2, 0xaa, 0x54, 0x65, 0x53, 0xb2, 0x53, 0xe7, 0x3b, 0xe7, + 0xdc, 0x7b, 0xce, 0xbd, 0xb7, 0x1b, 0x8d, 0x21, 0x47, 0x16, 0xb7, 0xf4, 0x0f, 0x89, 0xfe, 0xce, + 0xf7, 0x7d, 0xe7, 0x9e, 0xf7, 0x77, 0xbe, 0xf3, 0x3d, 0xe0, 0xc5, 0x80, 0xb6, 0x68, 0xd7, 0xf5, + 0x82, 0xab, 0x2d, 0xba, 0x67, 0x37, 0x0e, 0xaf, 0x06, 0x87, 0x5d, 0xea, 0xf3, 0x7f, 0xaf, 0x74, + 0x3d, 0x37, 0x70, 0xc9, 0x28, 0xfe, 0x58, 0x5a, 0xd8, 0x73, 0xf7, 0x5c, 0x84, 0x5c, 0x65, 0x7f, + 0xf1, 0xc2, 0xa5, 0x17, 0xf6, 0x5c, 0x77, 0xaf, 0x45, 0xaf, 0xe2, 0xaf, 0x9d, 0xde, 0xee, 0xd5, + 0x66, 0xcf, 0xb3, 0x03, 0xc7, 0xed, 0x88, 0xf2, 0x62, 0xbc, 0x3c, 0x70, 0xda, 0xd4, 0x0f, 0xec, + 0x76, 0xb7, 0x1f, 0x83, 0x87, 0x9e, 0xdd, 0xed, 0x52, 0x4f, 0xd4, 0xbe, 0x74, 0x39, 0xfc, 0x40, + 0x3b, 0x08, 0x18, 0x25, 0x63, 0x7e, 0xf5, 0xc1, 0x35, 0xf5, 0xa7, 0x40, 0xbd, 0xd1, 0xa7, 0x2d, + 0x5e, 0xcf, 0x0f, 0x68, 0xd3, 0x6a, 0xd2, 0x07, 0x4e, 0x83, 0x5a, 0x1e, 0xfd, 0x7a, 0xcf, 0xf1, + 0x68, 0x9b, 0x76, 0x02, 0x41, 0xf7, 0x46, 0x3a, 0x9d, 0xfc, 0x90, 0xd8, 0x17, 0x19, 0xbf, 0x98, + 0x83, 0x89, 0x3b, 0x94, 0x76, 0x4b, 0x2d, 0xe7, 0x01, 0x25, 0x2f, 0xc1, 0xc8, 0x86, 0xdd, 0xa6, + 0x8b, 0x99, 0x0b, 0x99, 0x4b, 0x13, 0x2b, 0xb3, 0xc7, 0x47, 0xc5, 0x49, 0x9f, 0x7a, 0x0f, 0xa8, + 0x67, 0x75, 0xec, 0x36, 0x35, 0xb1, 0x90, 0x7c, 0x0a, 0x26, 0xd8, 0xff, 0x7e, 0xd7, 0x6e, 0xd0, + 0xc5, 0x2c, 0x62, 0x4e, 0x1f, 0x1f, 0x15, 0x27, 0x3a, 0x12, 0x68, 0x46, 0xe5, 0xa4, 0x0a, 0xe3, + 0xab, 0x8f, 0xba, 0x8e, 0x47, 0xfd, 0xc5, 0x91, 0x0b, 0x99, 0x4b, 0x93, 0xcb, 0x4b, 0x57, 0x78, + 0x1f, 0x5d, 0x91, 0x7d, 0x74, 0x65, 0x53, 0x76, 0xe2, 0xca, 0xfc, 0xef, 0x1e, 0x15, 0x9f, 0x39, + 0x3e, 0x2a, 0x8e, 0x53, 0x4e, 0xf2, 0x53, 0x7f, 0x58, 0xcc, 0x98, 0x92, 0x9e, 0xbc, 0x03, 0x23, + 0x9b, 0x87, 0x5d, 0xba, 0x38, 0x71, 0x21, 0x73, 0x69, 0x66, 0xf9, 0x85, 0x2b, 0x7c, 0x58, 0xc3, + 0x8f, 0x8f, 0xfe, 0x62, 0x58, 0x2b, 0xf9, 0xe3, 0xa3, 0xe2, 0x08, 0x43, 0x31, 0x91, 0x8a, 0xbc, + 0x01, 0x63, 0x6b, 0xae, 0x1f, 0x54, 0x2b, 0x8b, 0x80, 0x9f, 0x7c, 0xe6, 0xf8, 0xa8, 0x38, 0xb7, + 0xef, 0xfa, 0x81, 0xe5, 0x34, 0x5f, 0x77, 0xdb, 0x4e, 0x40, 0xdb, 0xdd, 0xe0, 0xd0, 0x14, 0x48, + 0xc6, 0x23, 0x98, 0xd6, 0xf8, 0x91, 0x49, 0x18, 0xdf, 0xda, 0xb8, 0xb3, 0x71, 0x6f, 0x7b, 0xa3, + 0xf0, 0x0c, 0xc9, 0xc3, 0xc8, 0xc6, 0xbd, 0xca, 0x6a, 0x21, 0x43, 0xc6, 0x21, 0x57, 0xaa, 0xd5, + 0x0a, 0x59, 0x32, 0x05, 0xf9, 0x4a, 0x69, 0xb3, 0xb4, 0x52, 0xaa, 0xaf, 0x16, 0x72, 0x64, 0x1e, + 0x66, 0xb7, 0xab, 0x1b, 0x95, 0x7b, 0xdb, 0x75, 0xab, 0xb2, 0x5a, 0xbf, 0xb3, 0x79, 0xaf, 0x56, + 0x18, 0x21, 0x33, 0x00, 0x77, 0xb6, 0x56, 0x56, 0xcd, 0x8d, 0xd5, 0xcd, 0xd5, 0x7a, 0x61, 0x94, + 0x2c, 0x40, 0x41, 0x92, 0x58, 0xf5, 0x55, 0xf3, 0x7e, 0xb5, 0xbc, 0x5a, 0x18, 0xbb, 0x3d, 0x92, + 0xcf, 0x15, 0x46, 0xcc, 0xf1, 0x75, 0x6a, 0xfb, 0xb4, 0x5a, 0x31, 0xfe, 0x4e, 0x0e, 0xf2, 0x77, + 0x69, 0x60, 0x37, 0xed, 0xc0, 0x26, 0xcf, 0x69, 0xe3, 0x83, 0x4d, 0x54, 0x06, 0xe6, 0xa5, 0xe4, + 0xc0, 0x8c, 0x1e, 0x1f, 0x15, 0x33, 0x6f, 0xa8, 0x03, 0xf2, 0x36, 0x4c, 0x56, 0xa8, 0xdf, 0xf0, + 0x9c, 0x2e, 0x9b, 0x6c, 0x8b, 0x39, 0x44, 0x3b, 0x7f, 0x7c, 0x54, 0x3c, 0xd3, 0x8c, 0xc0, 0x4a, + 0x87, 0xa8, 0xd8, 0xa4, 0x0a, 0x63, 0xeb, 0xf6, 0x0e, 0x6d, 0xf9, 0x8b, 0xa3, 0x17, 0x72, 0x97, + 0x26, 0x97, 0x9f, 0x15, 0x83, 0x20, 0x3f, 0xf0, 0x0a, 0x2f, 0x5d, 0xed, 0x04, 0xde, 0xe1, 0xca, + 0xc2, 0xf1, 0x51, 0xb1, 0xd0, 0x42, 0x80, 0xda, 0xc1, 0x1c, 0x85, 0xd4, 0xa3, 0x89, 0x31, 0x76, + 0xe2, 0xc4, 0x78, 0xfe, 0x77, 0x8f, 0x8a, 0x19, 0x36, 0x60, 0x62, 0x62, 0x44, 0xfc, 0xf4, 0x29, + 0xb2, 0x0c, 0x79, 0x93, 0x3e, 0x70, 0x7c, 0xd6, 0xb2, 0x3c, 0xb6, 0xec, 0xec, 0xf1, 0x51, 0x91, + 0x78, 0x02, 0xa6, 0x7c, 0x46, 0x88, 0xb7, 0xf4, 0x16, 0x4c, 0x2a, 0x5f, 0x4d, 0x0a, 0x90, 0x3b, + 0xa0, 0x87, 0xbc, 0x87, 0x4d, 0xf6, 0x27, 0x59, 0x80, 0xd1, 0x07, 0x76, 0xab, 0x27, 0xba, 0xd4, + 0xe4, 0x3f, 0x3e, 0x9f, 0xfd, 0x5c, 0xe6, 0xf6, 0x48, 0x7e, 0xbc, 0x90, 0x37, 0xb3, 0xd5, 0x8a, + 0xf1, 0x33, 0x23, 0x90, 0x37, 0x5d, 0xbe, 0x80, 0xc9, 0x65, 0x18, 0xad, 0x07, 0x76, 0x20, 0x87, + 0x69, 0xfe, 0xf8, 0xa8, 0x38, 0xcb, 0x16, 0x37, 0x55, 0xea, 0xe7, 0x18, 0x0c, 0xb5, 0xb6, 0x6f, + 0xfb, 0x72, 0xb8, 0x10, 0xb5, 0xcb, 0x00, 0x2a, 0x2a, 0x62, 0x90, 0x8b, 0x30, 0x72, 0xd7, 0x6d, + 0x52, 0x31, 0x62, 0xe4, 0xf8, 0xa8, 0x38, 0xd3, 0x76, 0x9b, 0x2a, 0x22, 0x96, 0x93, 0xd7, 0x61, + 0xa2, 0xdc, 0xf3, 0x3c, 0xda, 0x61, 0x73, 0x7d, 0x04, 0x91, 0x67, 0x8e, 0x8f, 0x8a, 0xd0, 0xe0, + 0x40, 0xcb, 0x69, 0x9a, 0x11, 0x02, 0x1b, 0x86, 0x7a, 0x60, 0x7b, 0x01, 0x6d, 0x2e, 0x8e, 0x0e, + 0x35, 0x0c, 0x6c, 0x7d, 0xce, 0xf9, 0x9c, 0x24, 0x3e, 0x0c, 0x82, 0x13, 0x59, 0x83, 0xc9, 0x5b, + 0x9e, 0xdd, 0xa0, 0x35, 0xea, 0x39, 0x6e, 0x13, 0xc7, 0x37, 0xb7, 0x72, 0xf1, 0xf8, 0xa8, 0x78, + 0x76, 0x8f, 0x81, 0xad, 0x2e, 0xc2, 0x23, 0xea, 0xef, 0x1c, 0x15, 0xf3, 0x15, 0xb1, 0xd5, 0x9a, + 0x2a, 0x29, 0xf9, 0x1a, 0x1b, 0x1c, 0x3f, 0xc0, 0xae, 0xa5, 0xcd, 0xc5, 0xf1, 0x13, 0x3f, 0xd1, + 0x10, 0x9f, 0x78, 0xb6, 0x65, 0xfb, 0x81, 0xe5, 0x71, 0xba, 0xd8, 0x77, 0xaa, 0x2c, 0xc9, 0x3d, + 0xc8, 0xd7, 0x1b, 0xfb, 0xb4, 0xd9, 0x6b, 0x51, 0x9c, 0x32, 0x93, 0xcb, 0xe7, 0xc4, 0xa4, 0x96, + 0xe3, 0x29, 0x8b, 0x57, 0x96, 0x04, 0x6f, 0xe2, 0x0b, 0x88, 0x3a, 0x9f, 0x24, 0xd6, 0xe7, 0xf3, + 0xdf, 0xfa, 0xdb, 0xc5, 0x67, 0xbe, 0xff, 0x5f, 0x5d, 0x78, 0xc6, 0xf8, 0xcf, 0xb3, 0x50, 0x88, + 0x33, 0x21, 0xbb, 0x30, 0xbd, 0xd5, 0x6d, 0xda, 0x01, 0x2d, 0xb7, 0x1c, 0xda, 0x09, 0x7c, 0x9c, + 0x24, 0x83, 0xdb, 0xf4, 0xb2, 0xa8, 0x77, 0xb1, 0x87, 0x84, 0x56, 0x83, 0x53, 0xc6, 0x5a, 0xa5, + 0xb3, 0x8d, 0xea, 0xa9, 0xe3, 0x06, 0xee, 0xe3, 0x0c, 0x3b, 0x5d, 0x3d, 0x7c, 0xeb, 0xef, 0x53, + 0x8f, 0x60, 0x2b, 0x26, 0x50, 0xa7, 0xb9, 0x73, 0x88, 0x33, 0x73, 0xf8, 0x09, 0xc4, 0x48, 0x52, + 0x26, 0x10, 0x03, 0x1b, 0xff, 0x67, 0x06, 0x66, 0x4c, 0xea, 0xbb, 0x3d, 0xaf, 0x41, 0xd7, 0xa8, + 0xdd, 0xa4, 0x1e, 0x9b, 0xfe, 0x77, 0x9c, 0x4e, 0x53, 0xac, 0x29, 0x9c, 0xfe, 0x07, 0x4e, 0x47, + 0xdd, 0xba, 0xb1, 0x9c, 0x7c, 0x1a, 0xc6, 0xeb, 0xbd, 0x1d, 0x44, 0xcd, 0x46, 0x3b, 0x80, 0xdf, + 0xdb, 0xb1, 0x62, 0xe8, 0x12, 0x8d, 0x5c, 0x85, 0xf1, 0xfb, 0xd4, 0xf3, 0xa3, 0xdd, 0x10, 0x8f, + 0x86, 0x07, 0x1c, 0xa4, 0x12, 0x08, 0x2c, 0x72, 0x2b, 0xda, 0x91, 0xc5, 0xa1, 0x36, 0x1b, 0xdb, + 0x07, 0xa3, 0xa9, 0xd2, 0x16, 0x10, 0x75, 0xaa, 0x48, 0x2c, 0xe3, 0xa7, 0xb3, 0x50, 0xa8, 0xd8, + 0x81, 0xbd, 0x63, 0xfb, 0xa2, 0x3f, 0xef, 0x5f, 0x67, 0x7b, 0xbc, 0xd2, 0x50, 0xdc, 0xe3, 0xd9, + 0x97, 0x7f, 0xec, 0xe6, 0xbd, 0x12, 0x6f, 0xde, 0x24, 0x3b, 0x61, 0x45, 0xf3, 0xa2, 0x46, 0xbd, + 0x7b, 0x72, 0xa3, 0x0a, 0xa2, 0x51, 0x79, 0xd9, 0xa8, 0xa8, 0x29, 0xe4, 0x5d, 0x18, 0xa9, 0x77, + 0x69, 0x43, 0x6c, 0x22, 0xf2, 0x5c, 0xd0, 0x1b, 0xc7, 0x10, 0xee, 0x5f, 0x5f, 0x99, 0x12, 0x6c, + 0x46, 0xfc, 0x2e, 0x6d, 0x98, 0x48, 0xa6, 0x2c, 0x9a, 0x7f, 0x9c, 0x83, 0x85, 0x34, 0x32, 0xb5, + 0x1d, 0x63, 0x03, 0xda, 0x71, 0x09, 0xf2, 0xec, 0x08, 0x67, 0xc7, 0x22, 0x6e, 0x17, 0x13, 0x2b, + 0x53, 0xec, 0x93, 0xf7, 0x05, 0xcc, 0x0c, 0x4b, 0xc9, 0x4b, 0xa1, 0x44, 0x90, 0x8f, 0xf8, 0x09, + 0x89, 0x40, 0xca, 0x01, 0x6c, 0xac, 0xe5, 0x12, 0x46, 0xc1, 0x21, 0xea, 0x16, 0x09, 0x8e, 0xc6, + 0xda, 0x13, 0x10, 0xed, 0x98, 0x91, 0x87, 0xc2, 0x2a, 0xe4, 0x65, 0xb3, 0x16, 0xa7, 0x90, 0xd1, + 0x5c, 0xac, 0x93, 0xee, 0x5f, 0xe7, 0x83, 0xd9, 0x14, 0xbf, 0x55, 0x36, 0x12, 0x87, 0x5c, 0x87, + 0x7c, 0xcd, 0x73, 0x1f, 0x1d, 0x56, 0x2b, 0xfe, 0xe2, 0xf4, 0x85, 0xdc, 0xa5, 0x89, 0x95, 0x73, + 0xc7, 0x47, 0xc5, 0xf9, 0x2e, 0x83, 0x59, 0x4e, 0x53, 0x3d, 0x69, 0x43, 0xc4, 0xdb, 0x23, 0xf9, + 0x4c, 0x21, 0x7b, 0x7b, 0x24, 0x9f, 0x2d, 0xe4, 0xb8, 0x78, 0x71, 0x7b, 0x24, 0x3f, 0x52, 0x18, + 0xbd, 0x3d, 0x92, 0x1f, 0x45, 0x81, 0x63, 0xa2, 0x00, 0xb7, 0x47, 0xf2, 0x93, 0x85, 0x29, 0xed, + 0xb4, 0x47, 0x06, 0x81, 0xdb, 0x70, 0x5b, 0x66, 0x6e, 0xcb, 0xac, 0x9a, 0x63, 0xe5, 0x52, 0x99, + 0x7a, 0x81, 0x99, 0x2b, 0x6d, 0xd7, 0xcd, 0xe9, 0xca, 0x61, 0xc7, 0x6e, 0x3b, 0x0d, 0x7e, 0x74, + 0x9a, 0xb9, 0x5b, 0xe5, 0x9a, 0x51, 0x82, 0x99, 0xa8, 0x2d, 0xeb, 0x8e, 0x1f, 0x90, 0xab, 0x30, + 0x21, 0x21, 0x6c, 0xa3, 0xcb, 0xa5, 0xb6, 0xda, 0x8c, 0x70, 0x8c, 0xdf, 0xc9, 0x02, 0x44, 0x25, + 0x4f, 0xe9, 0x5a, 0xf8, 0xac, 0xb6, 0x16, 0xce, 0xc4, 0xd7, 0x42, 0xdf, 0x55, 0x40, 0xde, 0x87, + 0x31, 0x26, 0x16, 0xf4, 0xa4, 0x48, 0x74, 0x2e, 0x4e, 0x8a, 0x85, 0xf7, 0xaf, 0xaf, 0xcc, 0x08, + 0xe2, 0x31, 0x1f, 0x21, 0xa6, 0x20, 0x53, 0x96, 0xd1, 0x2f, 0x8e, 0x47, 0x83, 0x21, 0x16, 0xd0, + 0x25, 0x08, 0x07, 0x54, 0x74, 0x28, 0xae, 0x8c, 0xae, 0x1c, 0xe4, 0xb0, 0x94, 0x9c, 0x07, 0x36, + 0xe0, 0xa2, 0x53, 0xc7, 0x8f, 0x8f, 0x8a, 0xb9, 0x9e, 0xe7, 0xe0, 0x24, 0x20, 0x57, 0x41, 0x4c, + 0x03, 0xd1, 0x81, 0x6c, 0xf6, 0xcd, 0x35, 0x6c, 0xab, 0x41, 0xbd, 0x20, 0xea, 0xf1, 0xc5, 0x8c, + 0x9c, 0x2d, 0xa4, 0x0b, 0xfa, 0x54, 0x59, 0x1c, 0xc1, 0x69, 0x70, 0x29, 0xb5, 0x57, 0xae, 0x68, + 0xa8, 0x5c, 0x8c, 0xbc, 0x20, 0x4f, 0xa5, 0x26, 0x2f, 0xb3, 0x12, 0x22, 0xa5, 0x5e, 0x01, 0xb9, + 0x0e, 0x6c, 0x86, 0x8a, 0xde, 0x07, 0x51, 0x4f, 0x69, 0xbb, 0xbe, 0x72, 0x46, 0x70, 0x9a, 0xb6, + 0x1f, 0xaa, 0xe4, 0x0c, 0x9b, 0xbc, 0x0d, 0x6c, 0x0a, 0x8b, 0x7e, 0x27, 0x82, 0xe8, 0x56, 0xb9, + 0x56, 0x6e, 0xb9, 0xbd, 0x66, 0xfd, 0x83, 0xf5, 0x88, 0x78, 0xaf, 0xd1, 0x55, 0x89, 0x6f, 0x95, + 0x6b, 0xe4, 0x6d, 0x18, 0x2d, 0x7d, 0x6f, 0xcf, 0xa3, 0x42, 0x3e, 0x99, 0x92, 0x75, 0x32, 0xd8, + 0xca, 0x39, 0x41, 0x38, 0x6b, 0xb3, 0x9f, 0xaa, 0x5c, 0x87, 0xe5, 0xac, 0xe6, 0xcd, 0xf5, 0xba, + 0x90, 0x3d, 0x48, 0xac, 0x5b, 0x36, 0xd7, 0x95, 0xcf, 0x0e, 0xb4, 0x56, 0x33, 0x2a, 0x72, 0x15, + 0xb2, 0xa5, 0x0a, 0xde, 0x88, 0x26, 0x97, 0x27, 0x64, 0xb5, 0x95, 0x95, 0x05, 0x41, 0x32, 0x65, + 0xab, 0xcb, 0x20, 0x5b, 0xaa, 0x90, 0x15, 0x18, 0xbd, 0x7b, 0x58, 0xff, 0x60, 0x5d, 0x6c, 0x66, + 0xf3, 0x72, 0x5e, 0x33, 0xd8, 0x3d, 0x5c, 0xf6, 0x7e, 0xf4, 0xc5, 0xed, 0x43, 0xff, 0xeb, 0x2d, + 0xf5, 0x8b, 0x11, 0x8d, 0xd4, 0x60, 0xa2, 0xd4, 0x6c, 0x3b, 0x9d, 0x2d, 0x9f, 0x7a, 0x8b, 0x93, + 0xc8, 0x67, 0x31, 0xf6, 0xdd, 0x61, 0xf9, 0xca, 0xe2, 0xf1, 0x51, 0x71, 0xc1, 0x66, 0x3f, 0xad, + 0x9e, 0x4f, 0x3d, 0x85, 0x5b, 0xc4, 0x84, 0xd4, 0x00, 0xee, 0xba, 0x9d, 0x3d, 0xb7, 0x14, 0xb4, + 0x6c, 0x3f, 0xb6, 0x3d, 0x46, 0x05, 0xa1, 0xf8, 0x70, 0xa6, 0xcd, 0x60, 0x96, 0xcd, 0x80, 0x0a, + 0x43, 0x85, 0x07, 0xb9, 0x09, 0x63, 0xf7, 0x3c, 0xbb, 0xd1, 0xa2, 0x8b, 0xd3, 0xc8, 0x6d, 0x41, + 0x70, 0xe3, 0x40, 0xd9, 0xd2, 0x45, 0xc1, 0xb0, 0xe0, 0x22, 0x58, 0xbd, 0xa6, 0x70, 0xc4, 0xa5, + 0x6d, 0x20, 0xc9, 0x39, 0x99, 0x72, 0x49, 0xf8, 0x94, 0x7a, 0x49, 0x88, 0x16, 0x7d, 0xd9, 0x6d, + 0xb7, 0xed, 0x4e, 0x13, 0x69, 0xef, 0x2f, 0x2b, 0x77, 0x07, 0xe3, 0xeb, 0x30, 0x97, 0xe8, 0xac, + 0x13, 0xee, 0x77, 0xef, 0xc1, 0x6c, 0x85, 0xee, 0xda, 0xbd, 0x56, 0x10, 0x9e, 0x24, 0x7c, 0x89, + 0xe2, 0x4d, 0xab, 0xc9, 0x8b, 0x2c, 0x79, 0x7c, 0x98, 0x71, 0x64, 0xe3, 0x5d, 0x98, 0xd6, 0x9a, + 0xcf, 0xae, 0x0a, 0xa5, 0x5e, 0xd3, 0x09, 0x70, 0x20, 0x33, 0xd1, 0x55, 0xc1, 0x66, 0x40, 0x1c, + 0x2e, 0x33, 0x42, 0x30, 0xfe, 0xae, 0x2a, 0xad, 0x88, 0x9d, 0x88, 0x5d, 0xab, 0xc5, 0x7e, 0x90, + 0x89, 0x64, 0xa7, 0xc4, 0x7e, 0x10, 0xee, 0x06, 0x97, 0xf9, 0xda, 0xcc, 0x26, 0xd6, 0xe6, 0xa4, + 0x18, 0x89, 0x9c, 0xfd, 0xd0, 0xe7, 0x2b, 0x32, 0x9c, 0xa9, 0xb9, 0x8f, 0x3f, 0x53, 0xdf, 0x87, + 0xa9, 0xbb, 0x76, 0xc7, 0xde, 0xa3, 0x4d, 0xd6, 0x02, 0xbe, 0xf7, 0x4c, 0xac, 0x3c, 0x7b, 0x7c, + 0x54, 0x3c, 0xd7, 0xe6, 0x70, 0x6c, 0xa5, 0x3a, 0x89, 0x34, 0x02, 0x72, 0x4d, 0xae, 0xec, 0xd1, + 0x94, 0x95, 0x3d, 0x2d, 0x6a, 0x1f, 0xc5, 0x95, 0x2d, 0xd6, 0xb3, 0xf1, 0x5b, 0x13, 0xd8, 0x46, + 0xf2, 0x3a, 0x8c, 0x99, 0x74, 0x8f, 0x1d, 0x35, 0x99, 0x68, 0x90, 0x3c, 0x84, 0xa8, 0x1d, 0xc3, + 0x71, 0x50, 0xce, 0xa0, 0x4d, 0x7f, 0xdf, 0xd9, 0x0d, 0x44, 0xef, 0x84, 0x72, 0x86, 0x00, 0x2b, + 0x72, 0x86, 0x80, 0xe8, 0xd7, 0x59, 0x0e, 0x63, 0xbb, 0x9f, 0x59, 0xa9, 0x8b, 0x4e, 0x93, 0x3d, + 0x6c, 0x56, 0x94, 0x6d, 0xc4, 0xd3, 0xa4, 0x04, 0x86, 0x4d, 0x6e, 0xc0, 0x44, 0xa9, 0xd1, 0x70, + 0x7b, 0xca, 0x9d, 0x91, 0xaf, 0x5b, 0x0e, 0xd4, 0x55, 0x24, 0x11, 0x2a, 0xa9, 0xc3, 0xe4, 0x2a, + 0xbb, 0x68, 0x39, 0x65, 0xbb, 0xb1, 0x2f, 0x3b, 0x49, 0xee, 0x61, 0x4a, 0x49, 0xb4, 0x72, 0x29, + 0x02, 0x1b, 0x0c, 0xa8, 0x2a, 0x19, 0x14, 0x5c, 0xb2, 0x09, 0x93, 0x75, 0xda, 0xf0, 0x68, 0x50, + 0x0f, 0x5c, 0x8f, 0xc6, 0xb6, 0x64, 0xa5, 0x64, 0xe5, 0x05, 0x79, 0xd7, 0xf3, 0x11, 0x68, 0xf9, + 0x0c, 0xaa, 0x72, 0x55, 0x90, 0xb9, 0xd0, 0xde, 0x76, 0xbd, 0xc3, 0xca, 0x8a, 0xd8, 0xa6, 0xa3, + 0x33, 0x9d, 0x83, 0x55, 0xa1, 0x9d, 0x41, 0x9a, 0x3b, 0xba, 0xd0, 0xce, 0xb1, 0x70, 0xa4, 0x2a, + 0x75, 0x94, 0xad, 0xc4, 0xa6, 0x3d, 0x1b, 0xf5, 0x32, 0x82, 0x95, 0x91, 0x6a, 0xfa, 0x28, 0x99, + 0x69, 0x23, 0x25, 0xb0, 0x48, 0x17, 0x88, 0x1c, 0x35, 0x2e, 0xe8, 0xb6, 0xa8, 0xef, 0x8b, 0xbd, + 0xfc, 0x7c, 0x6c, 0xf0, 0x23, 0x84, 0x95, 0x57, 0x04, 0xf3, 0xe7, 0xe5, 0x34, 0x10, 0xf7, 0x34, + 0x56, 0xa8, 0xd4, 0x93, 0xc2, 0x9b, 0xbc, 0x05, 0xb0, 0xfa, 0x28, 0xa0, 0x5e, 0xc7, 0x6e, 0x85, + 0x7a, 0x30, 0x54, 0xfd, 0x50, 0x01, 0xd5, 0x07, 0x5a, 0x41, 0x26, 0x65, 0x98, 0x2e, 0xf9, 0x7e, + 0xaf, 0x4d, 0x4d, 0xb7, 0x45, 0x4b, 0xe6, 0x06, 0xee, 0xfb, 0x13, 0x2b, 0xcf, 0x1f, 0x1f, 0x15, + 0xcf, 0xdb, 0x58, 0x60, 0x79, 0x6e, 0x8b, 0x5a, 0xb6, 0xa7, 0xce, 0x6e, 0x9d, 0x86, 0xdc, 0x03, + 0xb8, 0xd7, 0xa5, 0x9d, 0x3a, 0xb5, 0xbd, 0xc6, 0x7e, 0x6c, 0x9b, 0x8f, 0x0a, 0x56, 0x9e, 0x13, + 0x2d, 0x5c, 0x70, 0xbb, 0xb4, 0xe3, 0x23, 0x4c, 0xfd, 0xaa, 0x08, 0x93, 0x6c, 0xc3, 0x6c, 0xb5, + 0x74, 0xb7, 0xe6, 0xb6, 0x9c, 0xc6, 0xa1, 0x90, 0x9c, 0x66, 0x50, 0x3b, 0x78, 0x56, 0x70, 0x8d, + 0x95, 0xf2, 0xed, 0xc9, 0xb1, 0xdb, 0x56, 0x17, 0xa1, 0x96, 0x90, 0x9f, 0xe2, 0x5c, 0xc8, 0x87, + 0x6c, 0x0e, 0xfa, 0x4c, 0x18, 0xdc, 0xb4, 0xf7, 0xfc, 0xc5, 0x59, 0x4d, 0xdb, 0x55, 0xda, 0xae, + 0x5f, 0x51, 0x4a, 0xb9, 0x98, 0xb2, 0xc4, 0x27, 0x22, 0x42, 0xad, 0xc0, 0xde, 0xf3, 0xf5, 0x89, + 0x18, 0x62, 0x93, 0xdb, 0x00, 0x15, 0xb7, 0xd1, 0x6b, 0xd3, 0x4e, 0x50, 0x59, 0x59, 0x2c, 0xe8, + 0x57, 0x81, 0xb0, 0x20, 0xda, 0xda, 0x9a, 0x6e, 0x43, 0x9b, 0x89, 0x0a, 0xf5, 0xd2, 0x7b, 0x50, + 0x88, 0x7f, 0xc8, 0x29, 0x15, 0x58, 0xd3, 0x85, 0x19, 0xa5, 0xf5, 0xab, 0x8f, 0x1c, 0x3f, 0xf0, + 0x8d, 0x6f, 0x68, 0x2b, 0x90, 0xed, 0x0e, 0x77, 0xe8, 0x61, 0xcd, 0xa3, 0xbb, 0xce, 0x23, 0xb1, + 0x99, 0xe1, 0xee, 0x70, 0x40, 0x0f, 0xad, 0x2e, 0x42, 0xd5, 0xdd, 0x21, 0x44, 0x25, 0x9f, 0x81, + 0xfc, 0x9d, 0xbb, 0xf5, 0x3b, 0xf4, 0xb0, 0x5a, 0x11, 0x07, 0x15, 0x27, 0x6b, 0xfb, 0x16, 0x23, + 0xd5, 0xe6, 0x5a, 0x88, 0x69, 0xac, 0x44, 0x3b, 0x21, 0xab, 0xb9, 0xdc, 0xea, 0xf9, 0x01, 0xf5, + 0xaa, 0x15, 0xb5, 0xe6, 0x06, 0x07, 0xc6, 0xf6, 0xa5, 0x10, 0xd5, 0xf8, 0x77, 0x59, 0xdc, 0x05, + 0xd9, 0x84, 0xaf, 0x76, 0xfc, 0xc0, 0xee, 0x34, 0x68, 0xc8, 0x00, 0x27, 0xbc, 0x23, 0xa0, 0xb1, + 0x09, 0x1f, 0x21, 0xeb, 0x55, 0x67, 0x87, 0xae, 0x9a, 0x55, 0x29, 0x35, 0x17, 0xd5, 0x8a, 0xaa, + 0x5e, 0xf5, 0x04, 0x34, 0x56, 0x65, 0x84, 0x4c, 0x2e, 0xc2, 0x78, 0xb5, 0x74, 0xb7, 0xd4, 0x0b, + 0xf6, 0x71, 0x0f, 0xce, 0x73, 0xf9, 0x9c, 0xcd, 0x56, 0xbb, 0x17, 0xec, 0x9b, 0xb2, 0x90, 0x5c, + 0xc5, 0x7b, 0x4f, 0x87, 0x06, 0x5c, 0x0d, 0x2b, 0x0e, 0x5d, 0x9f, 0x83, 0x62, 0xd7, 0x1e, 0x06, + 0x22, 0xaf, 0xc1, 0xe8, 0xfd, 0x5a, 0xb9, 0x5a, 0x11, 0x17, 0x67, 0x3c, 0x89, 0x1e, 0x74, 0x1b, + 0xfa, 0x97, 0x70, 0x14, 0xb2, 0x0a, 0x33, 0x75, 0xda, 0xe8, 0x79, 0x4e, 0x70, 0x78, 0xcb, 0x73, + 0x7b, 0x5d, 0x7f, 0x71, 0x1c, 0xeb, 0xc0, 0x95, 0xee, 0x8b, 0x12, 0x6b, 0x0f, 0x8b, 0x14, 0xea, + 0x18, 0x91, 0xf1, 0xdb, 0x99, 0x68, 0x9b, 0x24, 0x17, 0x35, 0xb1, 0x06, 0x75, 0x37, 0x4c, 0xac, + 0x51, 0x75, 0x37, 0x28, 0xe0, 0x98, 0x40, 0xca, 0x3d, 0x3f, 0x70, 0xdb, 0xab, 0x9d, 0x66, 0xd7, + 0x75, 0x3a, 0x01, 0x52, 0xf1, 0xce, 0x37, 0x8e, 0x8f, 0x8a, 0x2f, 0x34, 0xb0, 0xd4, 0xa2, 0xa2, + 0xd8, 0x8a, 0x71, 0x49, 0xa1, 0x7e, 0x8c, 0xf1, 0x30, 0x7e, 0x2f, 0xab, 0x1d, 0x6f, 0xec, 0xf3, + 0x4c, 0xda, 0x6d, 0x39, 0x0d, 0xbc, 0xd1, 0x63, 0x43, 0xc3, 0x59, 0x85, 0x9f, 0xe7, 0x45, 0xa5, + 0xbc, 0x87, 0x74, 0xde, 0x29, 0xd4, 0xe4, 0x0b, 0x30, 0xc5, 0x24, 0x0d, 0xf1, 0xd3, 0x5f, 0xcc, + 0x62, 0x67, 0x3f, 0x87, 0x5a, 0x38, 0x9f, 0x7a, 0x21, 0x1b, 0x4d, 0x44, 0x51, 0x29, 0x48, 0x13, + 0x16, 0x37, 0x3d, 0xbb, 0xe3, 0x3b, 0xc1, 0x6a, 0xa7, 0xe1, 0x1d, 0xa2, 0x64, 0xb4, 0xda, 0xb1, + 0x77, 0x5a, 0xb4, 0x89, 0xcd, 0xcd, 0xaf, 0x5c, 0x3a, 0x3e, 0x2a, 0xbe, 0x1c, 0x70, 0x1c, 0x8b, + 0x86, 0x48, 0x16, 0xe5, 0x58, 0x0a, 0xe7, 0xbe, 0x9c, 0x98, 0x24, 0x25, 0xbb, 0x15, 0x1f, 0x61, + 0xb8, 0x90, 0x80, 0x92, 0x54, 0x38, 0x1a, 0x6c, 0x0f, 0x53, 0x3f, 0x53, 0x25, 0x30, 0xfe, 0xef, + 0x4c, 0x74, 0x00, 0x93, 0x77, 0x60, 0x52, 0xac, 0x18, 0x65, 0x5e, 0xe0, 0x0e, 0x2a, 0x97, 0x57, + 0x6c, 0x64, 0x55, 0x74, 0x76, 0xef, 0x2f, 0x95, 0xd7, 0x95, 0xb9, 0x81, 0xf7, 0x7e, 0xbb, 0xd1, + 0x8a, 0x53, 0x49, 0x34, 0x36, 0x09, 0x36, 0xd7, 0xeb, 0x7a, 0xaf, 0xe0, 0x24, 0x08, 0x5a, 0x7e, + 0x4a, 0x37, 0x28, 0xc8, 0x8f, 0xdf, 0xf0, 0xff, 0x39, 0x93, 0x76, 0xce, 0x93, 0x15, 0x98, 0xde, + 0x76, 0xbd, 0x03, 0x1c, 0x5f, 0xa5, 0x13, 0x70, 0xe4, 0x1f, 0xca, 0x82, 0x78, 0x83, 0x74, 0x12, + 0xf5, 0xdb, 0x94, 0xde, 0xd0, 0xbf, 0x2d, 0xc6, 0x41, 0x23, 0x60, 0xe3, 0x10, 0x72, 0x0c, 0x57, + 0x07, 0x8e, 0x43, 0xf4, 0x09, 0xda, 0x14, 0x56, 0xd1, 0x8d, 0xff, 0x2a, 0xa3, 0x9e, 0xe7, 0xac, + 0x93, 0x2b, 0x6e, 0xdb, 0x76, 0x3a, 0x4a, 0x73, 0xf8, 0xc3, 0x12, 0x42, 0xe3, 0x5f, 0xa2, 0x20, + 0x93, 0xeb, 0x90, 0xe7, 0xbf, 0xc2, 0xbd, 0x16, 0xb5, 0x5a, 0x82, 0x50, 0x3f, 0x28, 0x24, 0x62, + 0x62, 0x64, 0x72, 0xa7, 0x1d, 0x99, 0xdf, 0xca, 0xa8, 0x47, 0xf1, 0xc7, 0x3d, 0x6c, 0x62, 0x87, + 0x4c, 0xf6, 0x34, 0x87, 0xcc, 0x63, 0x37, 0xe1, 0xfb, 0x33, 0x30, 0xa9, 0x68, 0x29, 0x58, 0x1b, + 0x6a, 0x9e, 0xfb, 0x11, 0x6d, 0x04, 0x7a, 0x1b, 0xba, 0x1c, 0x18, 0x6b, 0x43, 0x88, 0xfa, 0x18, + 0x6d, 0x30, 0xfe, 0x34, 0x23, 0xee, 0x48, 0x43, 0x6f, 0xf3, 0xfa, 0x96, 0x9c, 0x3d, 0xcd, 0x11, + 0xf9, 0x05, 0x18, 0x35, 0x69, 0xd3, 0xf1, 0xc5, 0xfd, 0x66, 0x4e, 0xbd, 0x8f, 0x61, 0x41, 0x24, + 0x37, 0x79, 0xec, 0xa7, 0x7a, 0xbe, 0x61, 0x39, 0x13, 0x64, 0xab, 0xfe, 0xcd, 0x16, 0x7d, 0xe4, + 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, 0x40, 0x41, 0xcc, 0x06, 0xa7, 0xb3, 0xc7, + 0x05, 0x29, 0xd1, 0x07, 0xc5, 0xe3, 0xa3, 0xe2, 0xb3, 0x8d, 0xb0, 0x4c, 0x48, 0x9d, 0x0a, 0xdf, + 0x04, 0xa1, 0xf1, 0xf7, 0xb3, 0x90, 0x2d, 0xe1, 0x80, 0xdc, 0xa1, 0x87, 0x81, 0xbd, 0x73, 0xd3, + 0x69, 0x69, 0x8b, 0xe9, 0x00, 0xa1, 0xd6, 0xae, 0xa3, 0xa9, 0x2b, 0x14, 0x64, 0xb6, 0x98, 0xee, + 0x78, 0x3b, 0x6f, 0x22, 0xa1, 0xb2, 0x98, 0x0e, 0xbc, 0x9d, 0x37, 0xe3, 0x64, 0x21, 0x22, 0x31, + 0x60, 0x8c, 0x2f, 0x2c, 0x31, 0x07, 0xe1, 0xf8, 0xa8, 0x38, 0xc6, 0xd7, 0x9f, 0x29, 0x4a, 0xc8, + 0x79, 0xc8, 0xd5, 0x6b, 0x1b, 0x62, 0x07, 0x44, 0xb5, 0xa0, 0xdf, 0xed, 0x98, 0x0c, 0xc6, 0xea, + 0x5c, 0xaf, 0x94, 0x6a, 0xa8, 0x08, 0x18, 0x8d, 0xea, 0x6c, 0x35, 0xed, 0x6e, 0x5c, 0x15, 0x10, + 0x22, 0x92, 0x77, 0x61, 0xf2, 0x4e, 0xa5, 0xbc, 0xe6, 0xfa, 0x7c, 0xf7, 0x1a, 0x8b, 0x26, 0xff, + 0x41, 0xb3, 0x61, 0xa1, 0x26, 0x3e, 0x7e, 0x0c, 0x28, 0xf8, 0xc6, 0x37, 0xb3, 0x30, 0xa9, 0xe8, + 0xc9, 0xc8, 0x67, 0xc4, 0x03, 0x69, 0x46, 0xbb, 0x01, 0x28, 0x18, 0xac, 0x94, 0x2b, 0x55, 0xda, + 0x6e, 0x93, 0x8a, 0xe7, 0xd2, 0x48, 0x81, 0x91, 0x1d, 0x46, 0x81, 0xf1, 0x16, 0x00, 0x9f, 0x03, + 0xf8, 0xc9, 0x8a, 0x38, 0xa1, 0xd8, 0x49, 0xa8, 0xe3, 0x12, 0x21, 0x93, 0xfb, 0x30, 0xbf, 0xe9, + 0xf5, 0xfc, 0xa0, 0x7e, 0xe8, 0x07, 0xb4, 0xcd, 0xb8, 0xd5, 0x5c, 0xb7, 0x25, 0xe6, 0xdf, 0xcb, + 0xc7, 0x47, 0xc5, 0x0b, 0x68, 0xdc, 0x61, 0xf9, 0x58, 0x8e, 0x1f, 0x60, 0x75, 0x5d, 0x57, 0x55, + 0x6b, 0xa4, 0x31, 0x30, 0x4c, 0x98, 0x52, 0x95, 0x22, 0xec, 0x64, 0x11, 0x8f, 0x49, 0x42, 0xd5, + 0xad, 0x9c, 0x2c, 0xe2, 0x2b, 0x93, 0x8f, 0x5b, 0x3a, 0x89, 0xf1, 0x19, 0x55, 0x21, 0x37, 0xec, + 0xc2, 0x36, 0x7e, 0x30, 0x13, 0x6d, 0x23, 0xf7, 0xaf, 0x91, 0xb7, 0x61, 0x8c, 0x3f, 0xde, 0x89, + 0x37, 0xce, 0x33, 0xe1, 0xa5, 0x56, 0x7d, 0xd9, 0xe3, 0x9a, 0xf0, 0x3f, 0xe0, 0x0f, 0xfc, 0xcf, + 0x98, 0x82, 0x24, 0x54, 0xa2, 0xeb, 0xfa, 0x34, 0xc9, 0x1d, 0xd5, 0xc5, 0xd7, 0xd2, 0x94, 0xe8, + 0xc6, 0x8f, 0x8f, 0xc2, 0x8c, 0x8e, 0xa6, 0xbe, 0xf0, 0x65, 0x86, 0x7a, 0xe1, 0xfb, 0x02, 0xe4, + 0x59, 0x7f, 0x38, 0x0d, 0x2a, 0x25, 0xb2, 0x97, 0xf1, 0x69, 0x41, 0xc0, 0xb4, 0x97, 0x6b, 0xe0, + 0xc3, 0xc1, 0xee, 0xb8, 0x66, 0x48, 0x45, 0x96, 0x95, 0x67, 0xa8, 0x5c, 0x24, 0xa4, 0xc8, 0x67, + 0x28, 0x75, 0x3d, 0x84, 0x0f, 0x52, 0x6f, 0xc0, 0x18, 0x93, 0xef, 0x43, 0x15, 0x0c, 0x7e, 0x25, + 0x13, 0xfd, 0x63, 0x26, 0x2a, 0x1c, 0x89, 0x6c, 0x43, 0x7e, 0xdd, 0xf6, 0x83, 0x3a, 0xa5, 0x9d, + 0x21, 0xde, 0xee, 0x8b, 0xa2, 0xab, 0xe6, 0xf1, 0x61, 0xdc, 0xa7, 0xb4, 0x13, 0x7b, 0x7c, 0x0d, + 0x99, 0x91, 0xaf, 0x00, 0x94, 0xdd, 0x4e, 0xe0, 0xb9, 0xad, 0x75, 0x77, 0x6f, 0x71, 0x0c, 0xef, + 0xbe, 0x2f, 0xc4, 0x06, 0x20, 0x42, 0xe0, 0xd7, 0xdf, 0x50, 0xc1, 0xd3, 0xe0, 0x05, 0x56, 0xcb, + 0xdd, 0x53, 0xd7, 0x41, 0x84, 0x4f, 0x6e, 0x42, 0x41, 0x2a, 0x16, 0xb6, 0xba, 0x7b, 0x1e, 0x4e, + 0x90, 0xf1, 0x48, 0xf2, 0xa0, 0x8f, 0x02, 0xab, 0x27, 0xe0, 0xea, 0x4e, 0x19, 0xa7, 0x21, 0x5f, + 0x86, 0x73, 0x71, 0x98, 0x1c, 0xe5, 0x7c, 0x24, 0x93, 0xab, 0xec, 0x52, 0xe6, 0x7d, 0x3f, 0x16, + 0xe4, 0x16, 0xcc, 0xb2, 0x0e, 0xb9, 0x4b, 0x6d, 0xbf, 0xc7, 0x0d, 0xac, 0x84, 0x6a, 0xe6, 0x79, + 0xa9, 0x89, 0xe2, 0xab, 0xb0, 0xe5, 0x36, 0x0e, 0x14, 0x24, 0x33, 0x4e, 0x65, 0x1c, 0x65, 0xe1, + 0x6c, 0x3a, 0x2e, 0xf9, 0xab, 0x70, 0x46, 0xf4, 0x4b, 0x8b, 0x7a, 0x0a, 0xce, 0x10, 0x36, 0x01, + 0x6f, 0x88, 0xfe, 0x7e, 0xb1, 0x11, 0x32, 0x08, 0x37, 0x0e, 0xc6, 0x22, 0x36, 0xb8, 0xe9, 0xf5, + 0x90, 0xaf, 0xc1, 0xa4, 0x5a, 0x6d, 0x76, 0x78, 0xf3, 0x8a, 0x01, 0x75, 0xa9, 0x2c, 0x89, 0x0d, + 0xb3, 0x26, 0xfd, 0x7a, 0x8f, 0xfa, 0x81, 0x34, 0xf0, 0x10, 0x47, 0xf7, 0xf9, 0x44, 0x2d, 0x12, + 0x21, 0xd4, 0xff, 0x14, 0x3c, 0x4e, 0x69, 0x49, 0x33, 0xbc, 0x6f, 0x31, 0xf6, 0x71, 0x7e, 0xc6, + 0x77, 0xb2, 0x70, 0xae, 0xcf, 0xb4, 0x64, 0x3b, 0x17, 0x0a, 0x56, 0xca, 0xce, 0x15, 0x93, 0xa7, + 0xb8, 0x75, 0xd8, 0x05, 0xc8, 0x0a, 0x51, 0x64, 0x64, 0xa5, 0x70, 0x7c, 0x54, 0x9c, 0xd2, 0x56, + 0x5c, 0xb6, 0x5a, 0x21, 0xb7, 0x61, 0x84, 0x75, 0xc3, 0x10, 0x46, 0x0e, 0x52, 0xfb, 0x37, 0x13, + 0x38, 0xea, 0x42, 0xc7, 0xbe, 0x41, 0x1e, 0xe4, 0x33, 0x90, 0xdb, 0xdc, 0x5c, 0xc7, 0x55, 0x9e, + 0xc3, 0x59, 0x3a, 0x1d, 0x04, 0x2d, 0x6d, 0x53, 0x99, 0x66, 0xb4, 0x61, 0x8f, 0x98, 0x0c, 0x9d, + 0x7c, 0x31, 0x66, 0x7c, 0xf5, 0xda, 0xe0, 0x25, 0x39, 0xbc, 0x2d, 0xd6, 0x63, 0x98, 0x40, 0x19, + 0xbf, 0x90, 0x8d, 0x76, 0xdb, 0x9b, 0x4e, 0x2b, 0xa0, 0x1e, 0x59, 0xe2, 0x9b, 0x67, 0x24, 0x46, + 0x9b, 0xe1, 0x6f, 0xb2, 0x18, 0xed, 0xc4, 0x9c, 0x55, 0xb8, 0xe5, 0xbe, 0xa6, 0x6c, 0xb9, 0x39, + 0xdc, 0x72, 0x67, 0xfa, 0x6e, 0xae, 0xaf, 0xa5, 0xec, 0x20, 0xb8, 0x65, 0xa6, 0xec, 0x12, 0x2f, + 0xc3, 0xf4, 0x86, 0xbb, 0xfa, 0x28, 0x08, 0x11, 0xd9, 0x56, 0x99, 0x37, 0x75, 0x20, 0xe3, 0x78, + 0xaf, 0xd5, 0xa4, 0xde, 0xe6, 0xbe, 0xdd, 0xd1, 0xac, 0x0c, 0xcc, 0x04, 0x9c, 0xe1, 0x6e, 0xd0, + 0x87, 0x3a, 0xee, 0x38, 0xc7, 0x8d, 0xc3, 0x8d, 0x1f, 0xc8, 0xca, 0xce, 0xb8, 0xbf, 0xfc, 0x94, + 0xbe, 0x66, 0xbf, 0xa9, 0xbd, 0x66, 0xcf, 0x87, 0x7a, 0xf8, 0xd0, 0x34, 0x63, 0xf9, 0x04, 0x8b, + 0x8e, 0xbf, 0x3b, 0x06, 0x53, 0x2a, 0x3a, 0xeb, 0x87, 0x52, 0xb3, 0xe9, 0xa9, 0xfd, 0x60, 0x37, + 0x9b, 0x9e, 0x89, 0x50, 0xcd, 0x80, 0x23, 0x37, 0xd0, 0x80, 0xe3, 0xab, 0x30, 0x51, 0x6e, 0x37, + 0xb5, 0x67, 0x65, 0x23, 0xe5, 0xf3, 0xae, 0x84, 0x48, 0x7c, 0x2d, 0x84, 0xea, 0xe5, 0x46, 0xbb, + 0x99, 0x7c, 0x4c, 0x8e, 0x58, 0x6a, 0xb6, 0x1f, 0xa3, 0x8f, 0x63, 0xfb, 0x71, 0x03, 0x26, 0xb6, + 0x7c, 0xba, 0xd9, 0xeb, 0x74, 0x68, 0x0b, 0xa7, 0x55, 0x9e, 0xdf, 0xca, 0x7a, 0x3e, 0xb5, 0x02, + 0x84, 0xaa, 0x1f, 0x10, 0xa2, 0xaa, 0x03, 0x3c, 0x3e, 0x60, 0x80, 0xaf, 0x43, 0xbe, 0x46, 0xa9, + 0x87, 0x7d, 0x3a, 0x19, 0x09, 0xdf, 0x5d, 0x4a, 0x3d, 0x8b, 0x75, 0xac, 0x66, 0x13, 0x22, 0x10, + 0x35, 0x43, 0x92, 0xa9, 0x21, 0x0d, 0x49, 0xc8, 0x8b, 0x30, 0xd5, 0xed, 0xed, 0xb4, 0x9c, 0x06, + 0xf2, 0x15, 0x16, 0x28, 0xe6, 0x24, 0x87, 0x31, 0xb6, 0x3e, 0xf9, 0x22, 0x4c, 0xe3, 0x6d, 0x34, + 0x9c, 0x72, 0x33, 0xda, 0xfb, 0xab, 0x56, 0xc6, 0x65, 0xd2, 0x06, 0x03, 0x59, 0x29, 0x86, 0x52, + 0x3a, 0x23, 0x72, 0x1b, 0xc6, 0xf7, 0x9c, 0xc0, 0xda, 0xef, 0xed, 0x2c, 0xce, 0x6a, 0x56, 0x46, + 0xb7, 0x9c, 0x60, 0xad, 0xb7, 0xc3, 0x87, 0x3c, 0x64, 0x8d, 0x3b, 0xde, 0x9e, 0x13, 0xec, 0xf7, + 0x54, 0xe5, 0xf9, 0xd8, 0x1e, 0xe2, 0x2e, 0xd5, 0x61, 0x46, 0x9f, 0x15, 0x4f, 0xe0, 0x49, 0x37, + 0x34, 0xb0, 0xc9, 0x17, 0x26, 0x6e, 0x8f, 0xe4, 0xa1, 0x30, 0xc9, 0x4d, 0x6b, 0x4c, 0xa8, 0x85, + 0xfd, 0x63, 0x92, 0x3b, 0xbd, 0x1d, 0xea, 0x75, 0x68, 0x40, 0x7d, 0x71, 0xf5, 0xf3, 0xcd, 0x91, + 0x52, 0xb7, 0xeb, 0x1b, 0xff, 0x69, 0x16, 0xc6, 0x4b, 0xdb, 0xf5, 0x6a, 0x67, 0xd7, 0xc5, 0x87, + 0xd9, 0xf0, 0x3d, 0x4e, 0x7d, 0x98, 0x0d, 0xdf, 0xe3, 0xd4, 0x57, 0xb8, 0xab, 0x29, 0x97, 0x77, + 0xb4, 0xdd, 0x56, 0x2e, 0xef, 0x9a, 0xda, 0x21, 0x7a, 0x9a, 0xcc, 0x0d, 0xf1, 0x34, 0x19, 0x6a, + 0x8f, 0x47, 0x4e, 0xd6, 0x1e, 0xbf, 0x0d, 0x93, 0xd5, 0x4e, 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, 0x89, 0x9e, 0x6c, 0x58, 0xc7, 0xae, 0xcc, 0xa5, 0x9b, 0x7f, 0x18, 0x7f, 0x3d, 0x03, + 0x0b, 0x69, 0xd3, 0x88, 0xbc, 0x07, 0x53, 0xae, 0xb7, 0x67, 0x77, 0x9c, 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, 0xb2, 0x30, 0x59, 0xea, 0x76, 0x9f, 0x72, 0xd3, 0xc0, 0xcf, 0x69, + 0x07, 0x88, 0xbc, 0x97, 0x87, 0xed, 0x1a, 0xca, 0x2a, 0xf0, 0x57, 0xb3, 0x30, 0x1b, 0xa3, 0x50, + 0xbf, 0x3e, 0x33, 0xa4, 0x41, 0x60, 0x76, 0x48, 0x83, 0xc0, 0xdc, 0x70, 0x06, 0x81, 0x23, 0x8f, + 0x73, 0x28, 0xbc, 0x0a, 0xb9, 0x52, 0xb7, 0x1b, 0x37, 0x2c, 0xe8, 0x76, 0xef, 0x5f, 0xe7, 0xba, + 0x15, 0xbb, 0xdb, 0x35, 0x19, 0x86, 0xb6, 0x53, 0x8f, 0x0d, 0xb9, 0x53, 0x1b, 0x6f, 0xc0, 0x04, + 0xf2, 0x42, 0x33, 0xbc, 0x0b, 0x80, 0x5b, 0x8c, 0xb0, 0xc0, 0xd3, 0xea, 0x12, 0x9b, 0xcf, 0xff, + 0x9b, 0x81, 0x51, 0xfc, 0xfd, 0x94, 0xce, 0xb1, 0x65, 0x6d, 0x8e, 0x15, 0x94, 0x39, 0x36, 0xcc, + 0xec, 0xfa, 0x07, 0x39, 0x80, 0xf2, 0x3d, 0xb3, 0xce, 0x55, 0x70, 0xe4, 0x26, 0xcc, 0xda, 0xad, + 0x96, 0xfb, 0x90, 0x36, 0x2d, 0xd7, 0x73, 0xf6, 0x9c, 0x0e, 0xef, 0x39, 0xf9, 0xda, 0xad, 0x17, + 0xa9, 0x6f, 0x60, 0xa2, 0xe8, 0x1e, 0x2f, 0x51, 0xf9, 0xb4, 0x69, 0xb0, 0xef, 0x36, 0xa5, 0x32, + 0x41, 0xe3, 0x23, 0x8a, 0x52, 0xf8, 0xdc, 0xe5, 0x25, 0x2a, 0x9f, 0x7d, 0x54, 0x8e, 0x48, 0x09, + 0x59, 0xe3, 0x23, 0x8a, 0x52, 0xf8, 0x70, 0x8d, 0x8a, 0x4f, 0xd6, 0x61, 0x0e, 0x21, 0x56, 0xc3, + 0xa3, 0x4d, 0xda, 0x09, 0x1c, 0xbb, 0xe5, 0x0b, 0xf5, 0x13, 0x2a, 0x2a, 0x13, 0x85, 0xea, 0xf5, + 0x1b, 0x0b, 0xcb, 0x51, 0x19, 0xb9, 0x02, 0xe3, 0x6d, 0xfb, 0x91, 0x65, 0xef, 0x71, 0xbb, 0x8f, + 0x69, 0xae, 0xae, 0x10, 0x20, 0xf5, 0x18, 0x69, 0xdb, 0x8f, 0x4a, 0x7b, 0x94, 0xb5, 0x82, 0x3e, + 0xea, 0xba, 0xbe, 0xd2, 0x8a, 0xb1, 0xa8, 0x15, 0xb1, 0x22, 0xb5, 0x15, 0xa2, 0x48, 0xb4, 0xc2, + 0xf8, 0x95, 0x0c, 0x3c, 0x5b, 0xc5, 0xaf, 0x08, 0x0e, 0xcb, 0xb4, 0x13, 0x50, 0xaf, 0x46, 0xbd, + 0xb6, 0x83, 0xaf, 0xe0, 0x75, 0x1a, 0x90, 0x97, 0x20, 0x57, 0x32, 0x37, 0xc4, 0xfc, 0xe5, 0xfb, + 0xbd, 0x66, 0x93, 0xc0, 0x4a, 0x43, 0x8d, 0x56, 0xf6, 0x04, 0x55, 0x75, 0x09, 0xa6, 0x4a, 0xbe, + 0xef, 0xec, 0x75, 0xda, 0xdc, 0x9f, 0x22, 0xa7, 0x59, 0x3d, 0x08, 0x78, 0xe2, 0x8d, 0x45, 0x25, + 0x31, 0xfe, 0xb3, 0x0c, 0xcc, 0x95, 0xba, 0x5d, 0xfd, 0x93, 0x75, 0x8b, 0x9b, 0xcc, 0xf0, 0x16, + 0x37, 0x0e, 0xcc, 0x68, 0xcd, 0xe5, 0x53, 0x2a, 0x12, 0x7c, 0x07, 0xf4, 0x0c, 0xff, 0xec, 0x6e, + 0x08, 0xb2, 0x7c, 0xfd, 0xb9, 0x38, 0xc6, 0xd8, 0xf8, 0x8f, 0xc6, 0x71, 0x0f, 0x11, 0xbb, 0xad, + 0xb0, 0x09, 0xcd, 0xa4, 0xd8, 0x84, 0xbe, 0x05, 0x8a, 0x84, 0xa3, 0x1e, 0x71, 0x8a, 0xac, 0xa8, + 0xea, 0x82, 0x22, 0x64, 0x72, 0x10, 0xb7, 0x0e, 0xcd, 0x61, 0x6b, 0x5e, 0x8a, 0x2f, 0xe0, 0x27, + 0x62, 0x18, 0xba, 0x06, 0xa4, 0xda, 0xc1, 0x27, 0x6c, 0x5a, 0x3f, 0x70, 0xba, 0xf7, 0xa9, 0xe7, + 0xec, 0x1e, 0x8a, 0x05, 0x80, 0x9d, 0xef, 0x88, 0x52, 0xcb, 0x3f, 0x70, 0xba, 0xd6, 0x03, 0x2c, + 0x37, 0x53, 0x68, 0xc8, 0xfb, 0x30, 0x6e, 0xd2, 0x87, 0x9e, 0x13, 0x48, 0x9b, 0xa7, 0x99, 0x50, + 0xb5, 0x89, 0x50, 0xbe, 0x16, 0x3c, 0xfe, 0x43, 0xdd, 0x15, 0x45, 0x39, 0x59, 0xe6, 0x42, 0x0a, + 0xb7, 0x6d, 0x9a, 0x8e, 0x5a, 0x5b, 0xda, 0xae, 0xf7, 0x93, 0x51, 0xc8, 0x65, 0x18, 0x45, 0x49, + 0x47, 0xdc, 0x05, 0xd0, 0x57, 0x08, 0x65, 0x67, 0x55, 0x0c, 0x43, 0x0c, 0xf2, 0x02, 0x40, 0xf8, + 0x46, 0xec, 0x2f, 0xe6, 0x51, 0x4a, 0x57, 0x20, 0x71, 0x31, 0x6d, 0xe2, 0x54, 0x62, 0xda, 0x3a, + 0x14, 0x4c, 0xee, 0x76, 0xd8, 0x2c, 0x75, 0xf1, 0x21, 0xd2, 0x5f, 0x04, 0x5c, 0xc9, 0x17, 0x8e, + 0x8f, 0x8a, 0xcf, 0x09, 0x97, 0xc4, 0xa6, 0x65, 0x77, 0xf9, 0xfb, 0xa5, 0xb6, 0x8d, 0xc4, 0x29, + 0xc9, 0x5b, 0x30, 0xc2, 0xb6, 0x5e, 0x61, 0x47, 0x2a, 0x1f, 0x74, 0xa2, 0xdd, 0x98, 0x2f, 0xce, + 0x86, 0xab, 0xed, 0x09, 0x48, 0x42, 0x2c, 0x98, 0xd1, 0xa7, 0xbb, 0x30, 0x29, 0x5a, 0x8c, 0xfa, + 0x53, 0x2f, 0x17, 0xaf, 0x3c, 0x02, 0x66, 0x35, 0x10, 0xa8, 0xae, 0x80, 0xd8, 0x22, 0x5d, 0x85, + 0xfc, 0x66, 0xb9, 0x56, 0x73, 0xbd, 0x80, 0x5f, 0x75, 0xa2, 0x93, 0x85, 0xc1, 0x4c, 0xbb, 0xb3, + 0x47, 0xf9, 0x59, 0x1c, 0x34, 0xba, 0x56, 0x97, 0xa1, 0xa9, 0x67, 0xb1, 0x24, 0xfd, 0xe4, 0x6c, + 0x48, 0x7f, 0x35, 0x0b, 0x2f, 0x85, 0x52, 0xd1, 0x3d, 0xaf, 0x5e, 0xba, 0xbb, 0x5e, 0x6d, 0xd6, + 0x84, 0x9a, 0xa4, 0xe6, 0xb9, 0x0f, 0x9c, 0x26, 0xf5, 0xee, 0x5f, 0x3b, 0xe1, 0x4c, 0x5f, 0xe7, + 0xcb, 0x9c, 0xbf, 0x86, 0x65, 0x35, 0x6b, 0x3b, 0x45, 0xf8, 0x14, 0xdb, 0x53, 0xb7, 0x9b, 0x78, + 0x1c, 0x5b, 0x7b, 0xc6, 0x8c, 0x18, 0x90, 0x1f, 0xcc, 0xc0, 0xd9, 0xf4, 0x0f, 0x11, 0xaa, 0xb3, + 0xa2, 0xbc, 0xa2, 0xf7, 0xf9, 0xda, 0x95, 0x57, 0x8f, 0x8f, 0x8a, 0x2f, 0xf9, 0x76, 0xbb, 0x65, + 0x39, 0x4d, 0x5e, 0x9b, 0xd3, 0xa0, 0x56, 0x57, 0x20, 0x68, 0xf5, 0xf6, 0xa9, 0xe9, 0xf3, 0x20, + 0x8f, 0xf6, 0xc5, 0xcc, 0x0a, 0x40, 0x5e, 0x3e, 0x38, 0x18, 0xbf, 0x91, 0x01, 0x65, 0x09, 0xe6, + 0x4d, 0xda, 0x74, 0x3c, 0xda, 0x08, 0xc4, 0xf1, 0x2e, 0x7c, 0x05, 0x39, 0x2c, 0x66, 0x5c, 0x89, + 0x30, 0xf2, 0x1e, 0x8c, 0x8b, 0x63, 0x48, 0x6c, 0xbb, 0x72, 0xe9, 0x8a, 0xa7, 0x0c, 0xee, 0x54, + 0x9a, 0x38, 0xc2, 0x24, 0x11, 0xdb, 0xf5, 0x6f, 0x6f, 0x6f, 0x96, 0x5b, 0xb6, 0xd3, 0xf6, 0xc5, + 0x59, 0x82, 0xdd, 0xfa, 0xd1, 0xc3, 0xc0, 0x6a, 0x20, 0x54, 0xdd, 0xf5, 0x43, 0x54, 0xe3, 0x96, + 0x7c, 0x49, 0x39, 0xc1, 0x42, 0xb8, 0x08, 0xa3, 0xf7, 0x23, 0x3d, 0xdd, 0xca, 0xc4, 0xf1, 0x51, + 0x91, 0x4f, 0x17, 0x93, 0xc3, 0x0d, 0x0a, 0x13, 0xe1, 0xd4, 0x65, 0xbc, 0xd8, 0x0f, 0xe4, 0x35, + 0xcd, 0x79, 0xb1, 0x49, 0x6c, 0x22, 0x94, 0x89, 0x7a, 0xab, 0x9d, 0x26, 0x22, 0x64, 0x11, 0x01, + 0xbb, 0x87, 0x76, 0x9a, 0x38, 0xd3, 0xd5, 0xd6, 0x09, 0x34, 0x45, 0xa0, 0xfa, 0xb1, 0x0c, 0xcc, + 0xe8, 0xd3, 0x96, 0x5c, 0x81, 0x31, 0xe1, 0x0e, 0x98, 0x41, 0xb5, 0x27, 0xe3, 0x36, 0xc6, 0x1d, + 0x01, 0x35, 0xf7, 0x3f, 0x81, 0xc5, 0xe4, 0x46, 0xc1, 0x41, 0x08, 0x4d, 0x28, 0x37, 0x36, 0x38, + 0xc8, 0x94, 0x65, 0xc4, 0x60, 0x57, 0x59, 0xbf, 0xd7, 0x0a, 0xd4, 0x77, 0x4b, 0x0f, 0x21, 0xa6, + 0x28, 0x31, 0xca, 0x30, 0xc6, 0xb7, 0xd6, 0x98, 0x01, 0x64, 0xe6, 0x14, 0x06, 0x90, 0xc6, 0x51, + 0x06, 0xa0, 0x5e, 0x5f, 0xbb, 0x43, 0x0f, 0x6b, 0xb6, 0x83, 0xe7, 0x37, 0x3f, 0xc6, 0xee, 0x88, + 0x35, 0x3c, 0x25, 0x1e, 0xda, 0xf9, 0x91, 0x77, 0x40, 0x0f, 0xb5, 0x87, 0x76, 0x89, 0x8a, 0x67, + 0xa5, 0xe7, 0x3c, 0xb0, 0x03, 0xca, 0x08, 0xb3, 0x48, 0xc8, 0xcf, 0x4a, 0x0e, 0x8d, 0x51, 0x2a, + 0xc8, 0xe4, 0x2b, 0x30, 0x13, 0xfd, 0x0a, 0xcd, 0x05, 0x66, 0xc2, 0x7d, 0x42, 0x2f, 0x5c, 0x79, + 0xe1, 0xf8, 0xa8, 0xb8, 0xa4, 0x70, 0x8d, 0x1b, 0x12, 0xc4, 0x98, 0x19, 0xbf, 0x94, 0x41, 0x23, + 0x19, 0xd9, 0xc0, 0x8b, 0x30, 0x12, 0x9a, 0x75, 0x4f, 0x89, 0x4d, 0x58, 0x7f, 0x12, 0xc5, 0x72, + 0x26, 0x6e, 0x45, 0x2d, 0xc1, 0xa3, 0x4b, 0x6f, 0x01, 0x2b, 0x25, 0xb7, 0x60, 0x7c, 0xa8, 0x6f, + 0xc6, 0x29, 0x96, 0xf2, 0xad, 0x92, 0x1a, 0x47, 0xe1, 0xf6, 0xf6, 0xe6, 0x77, 0xef, 0x28, 0xfc, + 0x64, 0x16, 0x66, 0x59, 0xbf, 0x96, 0x7a, 0xc1, 0xbe, 0xeb, 0x39, 0xc1, 0xe1, 0x53, 0xab, 0x37, + 0x7e, 0x47, 0xbb, 0x92, 0x2d, 0xc9, 0xc3, 0x4c, 0x6d, 0xdb, 0x50, 0xea, 0xe3, 0x7f, 0x36, 0x0a, + 0xf3, 0x29, 0x54, 0xe4, 0x75, 0xed, 0x69, 0x67, 0x51, 0xba, 0xfb, 0x7f, 0xe7, 0xa8, 0x38, 0x25, + 0xd1, 0x37, 0x23, 0xf7, 0xff, 0x65, 0xdd, 0xe2, 0x8c, 0xf7, 0x14, 0xbe, 0xf4, 0xa8, 0x16, 0x67, + 0xba, 0x9d, 0xd9, 0x65, 0x18, 0x35, 0xdd, 0x16, 0x95, 0x56, 0x96, 0x28, 0x70, 0x79, 0x0c, 0xa0, + 0x59, 0x95, 0x30, 0x00, 0x59, 0x83, 0x71, 0xf6, 0xc7, 0x5d, 0xbb, 0x2b, 0xde, 0x4b, 0x49, 0xa8, + 0x14, 0x40, 0x68, 0xd7, 0xe9, 0xec, 0xa9, 0x7a, 0x81, 0x16, 0xb5, 0xda, 0x76, 0x57, 0x93, 0x0c, + 0x39, 0xa2, 0xa6, 0x5f, 0xc8, 0xf7, 0xd7, 0x2f, 0x64, 0x4e, 0xd4, 0x2f, 0xec, 0x02, 0xd4, 0x9d, + 0xbd, 0x8e, 0xd3, 0xd9, 0x2b, 0xb5, 0xf6, 0x44, 0xd0, 0x84, 0xcb, 0xfd, 0x47, 0xe1, 0x4a, 0x84, + 0x8c, 0x13, 0xf7, 0x59, 0x34, 0x6a, 0xe0, 0x30, 0xcb, 0x6e, 0xed, 0x69, 0xce, 0x5d, 0x0a, 0x67, + 0xb2, 0x01, 0x50, 0x6a, 0x04, 0xce, 0x03, 0x36, 0x85, 0x7d, 0x21, 0xc6, 0xc9, 0x4f, 0x2e, 0x97, + 0xee, 0xd0, 0x43, 0xbc, 0x7a, 0xc8, 0xe7, 0x61, 0x1b, 0x51, 0xd9, 0x4a, 0xd0, 0x3c, 0x77, 0x22, + 0x0e, 0xa4, 0x0b, 0x67, 0x4a, 0xcd, 0xa6, 0xc3, 0xda, 0x60, 0xb7, 0x36, 0x79, 0xb8, 0x0b, 0x64, + 0x3d, 0x95, 0xce, 0xfa, 0xb2, 0x7c, 0x09, 0xb5, 0x43, 0x2a, 0x4b, 0x46, 0xc9, 0x88, 0x55, 0x93, + 0xce, 0xd8, 0xa8, 0xc3, 0x8c, 0xde, 0x78, 0x3d, 0xd8, 0xc3, 0x14, 0xe4, 0xcd, 0x7a, 0xc9, 0xaa, + 0xaf, 0x95, 0xae, 0x15, 0x32, 0xa4, 0x00, 0x53, 0xe2, 0xd7, 0xb2, 0xb5, 0xfc, 0xe6, 0x8d, 0x42, + 0x56, 0x83, 0xbc, 0x79, 0x6d, 0xb9, 0x90, 0x5b, 0xca, 0x2e, 0x66, 0x62, 0x7e, 0x96, 0xe3, 0x85, + 0x3c, 0x57, 0x09, 0x1b, 0xbf, 0x96, 0x81, 0xbc, 0xfc, 0x76, 0x72, 0x03, 0x72, 0xf5, 0xfa, 0x5a, + 0xcc, 0x33, 0x32, 0x3a, 0x65, 0xf8, 0x7e, 0xea, 0xfb, 0xaa, 0xf9, 0x3b, 0x23, 0x60, 0x74, 0x9b, + 0xeb, 0x75, 0x21, 0x83, 0x48, 0xba, 0x68, 0xf3, 0xe6, 0x74, 0x29, 0xee, 0x62, 0x37, 0x20, 0x77, + 0x7b, 0x7b, 0x53, 0x5c, 0xb2, 0x24, 0x5d, 0xb4, 0x9f, 0x72, 0xba, 0x8f, 0x1e, 0xaa, 0xbb, 0x3c, + 0x23, 0x30, 0x4c, 0x98, 0x54, 0x26, 0x32, 0x3f, 0x74, 0xdb, 0x6e, 0x18, 0xe1, 0x40, 0x1c, 0xba, + 0x0c, 0x62, 0x8a, 0x12, 0x26, 0x8a, 0xac, 0xbb, 0x0d, 0xbb, 0x25, 0x4e, 0x6f, 0x14, 0x45, 0x5a, + 0x0c, 0x60, 0x72, 0xb8, 0xf1, 0xdb, 0x19, 0x28, 0xa0, 0xc0, 0x86, 0xe6, 0xeb, 0xee, 0x01, 0xed, + 0xdc, 0xbf, 0x46, 0xde, 0x90, 0x4b, 0x2e, 0x13, 0x2a, 0xba, 0x46, 0x71, 0xc9, 0xc5, 0xde, 0x02, + 0xc5, 0xb2, 0x53, 0x82, 0x48, 0x64, 0x87, 0x77, 0x3e, 0x3f, 0x21, 0x88, 0x44, 0x11, 0x46, 0xf1, + 0x73, 0xc4, 0xe6, 0x88, 0x5f, 0x1e, 0x30, 0x80, 0xc9, 0xe1, 0xca, 0xde, 0xf4, 0xd3, 0xd9, 0x44, + 0x1b, 0x96, 0xbf, 0xab, 0x1c, 0xb8, 0xf5, 0xc6, 0x0d, 0xb5, 0x5f, 0x7f, 0x08, 0x0b, 0xf1, 0x2e, + 0x41, 0x25, 0x64, 0x09, 0x66, 0x75, 0xb8, 0xd4, 0x47, 0x9e, 0x4b, 0xad, 0xeb, 0xfe, 0xb2, 0x19, + 0xc7, 0x37, 0xfe, 0x8f, 0x0c, 0x4c, 0xe0, 0x9f, 0x66, 0xaf, 0x85, 0x66, 0x84, 0xa5, 0xed, 0xba, + 0x50, 0x8d, 0xa8, 0xc2, 0x9c, 0xfd, 0xd0, 0xb7, 0x84, 0x1e, 0x45, 0xdb, 0x63, 0x42, 0x64, 0x41, + 0xca, 0xdf, 0x37, 0xa4, 0x52, 0x2e, 0x24, 0xe5, 0x0f, 0x21, 0x7e, 0x8c, 0x54, 0x20, 0xa3, 0xf1, + 0xf1, 0x76, 0x9d, 0x4d, 0x3f, 0xd5, 0xae, 0x07, 0xe9, 0xdc, 0x96, 0x6e, 0x7c, 0xcc, 0xd1, 0xd0, + 0xac, 0x67, 0xbb, 0x5e, 0x32, 0x37, 0x34, 0xb3, 0x1e, 0xf6, 0x8d, 0x9a, 0x5e, 0x4a, 0x20, 0x19, + 0xff, 0x7a, 0x32, 0xde, 0x81, 0xe2, 0xc0, 0x3b, 0xe5, 0xda, 0x78, 0x1b, 0x46, 0x4b, 0xad, 0x96, + 0xfb, 0x50, 0xec, 0x12, 0xf2, 0xe6, 0x1a, 0xf6, 0x1f, 0x3f, 0xcf, 0x50, 0xad, 0xa7, 0x39, 0xa5, + 0x32, 0x00, 0x29, 0xc3, 0x44, 0x69, 0xbb, 0x5e, 0xad, 0x56, 0x36, 0x37, 0xb9, 0x03, 0x5e, 0x6e, + 0xe5, 0x15, 0xd9, 0x3f, 0x8e, 0xd3, 0xb4, 0xe2, 0xf6, 0x0a, 0x91, 0xfc, 0x1e, 0xd1, 0x91, 0x77, + 0x01, 0x6e, 0xbb, 0x4e, 0x87, 0xab, 0x31, 0x45, 0xe3, 0xd9, 0x0d, 0x7c, 0xf2, 0x23, 0xd7, 0xe9, + 0x08, 0xbd, 0x27, 0xfb, 0xf6, 0x08, 0xc9, 0x54, 0xfe, 0x66, 0x3d, 0xbd, 0xe2, 0x72, 0xd3, 0xc0, + 0xd1, 0xa8, 0xa7, 0x77, 0xdc, 0x84, 0xbe, 0x4d, 0xa2, 0x91, 0x36, 0xcc, 0xd6, 0x7b, 0x7b, 0x7b, + 0x94, 0xed, 0xec, 0x42, 0x9f, 0x34, 0x26, 0xae, 0xd2, 0x61, 0xd8, 0x23, 0x7e, 0x1f, 0x61, 0x97, + 0x21, 0x7f, 0xe5, 0x75, 0x36, 0x91, 0xbf, 0x7d, 0x54, 0x14, 0x76, 0x10, 0x4c, 0x54, 0xf3, 0x25, + 0x7d, 0x52, 0x9b, 0x14, 0xe7, 0x4d, 0xee, 0xc1, 0x18, 0x7f, 0x33, 0x12, 0x0e, 0x65, 0x2f, 0x0e, + 0x58, 0x34, 0x1c, 0xb1, 0xdf, 0xab, 0x24, 0x2f, 0x25, 0xdb, 0x90, 0x2f, 0x3b, 0x5e, 0xa3, 0x45, + 0xcb, 0x55, 0x71, 0xf6, 0xbf, 0x34, 0x80, 0xa5, 0x44, 0xe5, 0xfd, 0xd2, 0xc0, 0x5f, 0x0d, 0x47, + 0x95, 0x05, 0x24, 0x06, 0xf9, 0xeb, 0x19, 0x78, 0x36, 0xfc, 0xfa, 0xd2, 0x1e, 0xed, 0x04, 0x77, + 0xed, 0xa0, 0xb1, 0x4f, 0x3d, 0xd1, 0x4b, 0x13, 0x83, 0x7a, 0xe9, 0xf3, 0x89, 0x5e, 0xba, 0x14, + 0xf5, 0x92, 0xcd, 0x98, 0x59, 0x6d, 0xce, 0x2d, 0xd9, 0x67, 0x83, 0x6a, 0x25, 0x16, 0x40, 0xf4, + 0x1a, 0x2a, 0x1c, 0x92, 0x5f, 0x19, 0xd0, 0xe0, 0x08, 0x59, 0x38, 0x12, 0x85, 0xbf, 0x35, 0x4b, + 0xd8, 0x10, 0x4a, 0xee, 0x48, 0xef, 0x4d, 0x2e, 0x95, 0x5c, 0x18, 0xc0, 0x9b, 0x7b, 0x74, 0xce, + 0x0f, 0xf0, 0xd3, 0xe6, 0xa3, 0xbd, 0x6e, 0xef, 0x08, 0x41, 0xe4, 0x84, 0xd1, 0x5e, 0xb7, 0xa3, + 0xd1, 0x6e, 0xd9, 0xf1, 0xd1, 0x5e, 0xb7, 0x77, 0x48, 0x99, 0xbb, 0x9c, 0x73, 0xff, 0xe4, 0x17, + 0x06, 0x71, 0x2b, 0xd7, 0xf8, 0xc9, 0x9c, 0xe2, 0x7a, 0xfe, 0x25, 0x98, 0xa8, 0x77, 0xed, 0x06, + 0x6d, 0x39, 0xbb, 0x81, 0x78, 0x6a, 0x7f, 0x79, 0x00, 0xab, 0x10, 0x57, 0x3c, 0xad, 0xca, 0x9f, + 0xea, 0x35, 0x29, 0xc4, 0x61, 0x5f, 0xb8, 0x59, 0xbb, 0x2b, 0x5e, 0xdb, 0x07, 0x7d, 0xe1, 0x66, + 0xed, 0xae, 0x90, 0x39, 0xba, 0x6d, 0x4d, 0xe6, 0xa8, 0xdd, 0x25, 0x5d, 0x98, 0xd9, 0xa4, 0x9e, + 0x67, 0xef, 0xba, 0x5e, 0x9b, 0xeb, 0x2f, 0xb9, 0xcf, 0xdb, 0xe5, 0x41, 0xfc, 0x34, 0x02, 0xae, + 0xb6, 0x0b, 0x24, 0xcc, 0x8a, 0x2b, 0x3d, 0x63, 0xfc, 0x59, 0x9f, 0xac, 0x38, 0xc1, 0x4e, 0xaf, + 0x71, 0x40, 0x83, 0xc5, 0xb9, 0x13, 0xfb, 0x24, 0xc4, 0xe5, 0x7d, 0xb2, 0x23, 0x7f, 0xaa, 0x7d, + 0x12, 0xe2, 0xb0, 0x69, 0x20, 0x1c, 0xcb, 0xc9, 0x89, 0xd3, 0x80, 0x23, 0xf2, 0x69, 0xd0, 0xcf, + 0xc3, 0xdc, 0xf8, 0x27, 0x39, 0x38, 0xd7, 0xa7, 0x4f, 0xc9, 0x86, 0xdc, 0xc3, 0x33, 0x9a, 0x5a, + 0xbc, 0x0f, 0xfa, 0x95, 0x13, 0xb7, 0xf5, 0x75, 0x28, 0xac, 0xde, 0x41, 0xe1, 0x9f, 0xbf, 0x0c, + 0x95, 0x4b, 0xf2, 0xf4, 0x43, 0xd5, 0x2d, 0x3d, 0x40, 0xa3, 0x63, 0xf9, 0xa2, 0xd4, 0xd0, 0xbc, + 0xeb, 0x13, 0x94, 0x4b, 0x3f, 0x90, 0x85, 0x11, 0x3c, 0x89, 0x63, 0x31, 0xc5, 0x32, 0xa7, 0x8a, + 0x29, 0xf6, 0x05, 0x98, 0x5a, 0xbd, 0xc3, 0xaf, 0xe6, 0x6b, 0xb6, 0xbf, 0x2f, 0xce, 0x09, 0xb4, + 0x0c, 0xa1, 0x07, 0x96, 0xb8, 0xc9, 0xef, 0xdb, 0x9a, 0x10, 0xac, 0x51, 0x90, 0x2d, 0x98, 0xe7, + 0xdf, 0xe6, 0xec, 0x3a, 0x0d, 0x1e, 0x9a, 0xc8, 0xb1, 0x5b, 0xe2, 0xd0, 0x78, 0xe9, 0xf8, 0xa8, + 0x58, 0xa4, 0x07, 0x68, 0x4e, 0x2d, 0xca, 0x2d, 0x1f, 0x11, 0x54, 0xbb, 0xea, 0x14, 0x7a, 0x35, + 0x5e, 0x8a, 0x39, 0x81, 0x15, 0xb2, 0xda, 0x58, 0xdd, 0x0c, 0x97, 0x23, 0x19, 0x7f, 0x32, 0x0a, + 0x4b, 0xfd, 0xf7, 0x7b, 0xf2, 0x81, 0x3e, 0x80, 0x17, 0x4f, 0x3c, 0x21, 0x4e, 0x1e, 0xc3, 0x2f, + 0xc2, 0xc2, 0x6a, 0x27, 0xa0, 0x5e, 0xd7, 0x73, 0x64, 0x84, 0x9c, 0x35, 0xd7, 0x97, 0xe6, 0xeb, + 0x68, 0x47, 0x4e, 0xc3, 0x72, 0xa1, 0xac, 0x45, 0x63, 0x7a, 0x85, 0x55, 0x2a, 0x07, 0xb2, 0x0a, + 0x33, 0x0a, 0xbc, 0xd5, 0xdb, 0x53, 0x9f, 0xbb, 0x54, 0x9e, 0xad, 0x9e, 0x6a, 0xdb, 0x1b, 0x23, + 0x42, 0x13, 0x79, 0x76, 0x07, 0x6d, 0xdc, 0xde, 0xbe, 0x53, 0x17, 0xc3, 0xc9, 0x4d, 0xe4, 0x11, + 0x6a, 0x7d, 0xf4, 0xf0, 0x40, 0xdb, 0xb0, 0x23, 0xe4, 0xa5, 0x5f, 0xca, 0x89, 0x19, 0xf5, 0x12, + 0xe4, 0xea, 0xbd, 0x1d, 0xf5, 0x11, 0xcf, 0xd7, 0x4e, 0x4c, 0x56, 0x4a, 0x3e, 0x07, 0x60, 0xd2, + 0xae, 0xeb, 0x3b, 0x81, 0xeb, 0x1d, 0xaa, 0x3e, 0x9a, 0x5e, 0x08, 0xd5, 0xdd, 0x48, 0x24, 0x94, + 0xac, 0xc1, 0x6c, 0xf4, 0xeb, 0xde, 0xc3, 0x8e, 0x50, 0x4e, 0x4f, 0x70, 0x75, 0x4d, 0x44, 0x6e, + 0xb9, 0xac, 0x4c, 0x95, 0x01, 0x62, 0x64, 0x64, 0x19, 0xf2, 0xdb, 0xae, 0x77, 0xb0, 0xcb, 0xc6, + 0x78, 0x24, 0x92, 0x52, 0x1e, 0x0a, 0x98, 0x7a, 0x1a, 0x4b, 0x3c, 0xb6, 0x5c, 0x56, 0x3b, 0x0f, + 0x1c, 0xcf, 0xc5, 0x27, 0x42, 0xd5, 0x48, 0x86, 0x46, 0x60, 0xcd, 0x3b, 0x3e, 0x02, 0x93, 0xcb, + 0x30, 0x5a, 0x6a, 0x04, 0xae, 0x27, 0x2c, 0x64, 0xf8, 0x4c, 0x61, 0x00, 0x6d, 0xa6, 0x30, 0x00, + 0xeb, 0x44, 0x93, 0xee, 0x8a, 0xe7, 0x22, 0xec, 0x44, 0x8f, 0xee, 0x6a, 0xae, 0xff, 0x74, 0x97, + 0x49, 0x59, 0x26, 0xdd, 0x45, 0x4d, 0x8a, 0x16, 0x31, 0x6f, 0x37, 0xa1, 0x83, 0x13, 0x68, 0xc6, + 0xef, 0x4e, 0xf4, 0x9d, 0xf2, 0xec, 0x58, 0x3b, 0xdd, 0x94, 0x5f, 0xb7, 0x87, 0x98, 0xf2, 0xaf, + 0x87, 0xce, 0x29, 0x6a, 0xbc, 0x0b, 0x84, 0xa8, 0x1b, 0x2a, 0xc7, 0x59, 0xfa, 0xe5, 0xfc, 0x69, + 0x26, 0x91, 0xe8, 0xa4, 0xec, 0xb0, 0x9d, 0x94, 0x1b, 0xaa, 0x93, 0xc8, 0x0a, 0x4c, 0x87, 0x31, + 0x17, 0x6b, 0x76, 0xa0, 0x6d, 0x6b, 0x61, 0xa0, 0x4c, 0xab, 0x6b, 0x07, 0xea, 0xb6, 0xa6, 0x93, + 0x90, 0x77, 0x60, 0x52, 0x78, 0x68, 0x21, 0x87, 0xd1, 0xc8, 0xf4, 0x48, 0xba, 0x73, 0xc5, 0xe8, + 0x55, 0x74, 0xb6, 0x9a, 0x6b, 0x4e, 0x97, 0xb6, 0x9c, 0x0e, 0xad, 0xe3, 0xeb, 0x87, 0x98, 0x31, + 0xfc, 0x15, 0x58, 0x94, 0x58, 0xfc, 0x61, 0x44, 0x53, 0x48, 0x6a, 0x44, 0xf1, 0xc9, 0x3a, 0x7e, + 0xaa, 0xc9, 0xca, 0x0d, 0x1f, 0xbd, 0x75, 0x77, 0xcf, 0x91, 0x46, 0xf9, 0xd2, 0xf0, 0xd1, 0xb3, + 0x5a, 0x0c, 0x1a, 0x33, 0x7c, 0xe4, 0xa8, 0xec, 0xca, 0xc4, 0x7e, 0x54, 0x2b, 0xe2, 0x69, 0x12, + 0xaf, 0x4c, 0x48, 0xa4, 0x7b, 0x42, 0x70, 0x24, 0x59, 0xcd, 0x6a, 0xdb, 0x76, 0x5a, 0x22, 0xac, + 0x41, 0x54, 0x0d, 0x65, 0xd0, 0x78, 0x35, 0x88, 0x4a, 0x1a, 0x30, 0x65, 0xd2, 0xdd, 0x9a, 0xe7, + 0x06, 0xb4, 0x11, 0xd0, 0xa6, 0x10, 0x13, 0xe5, 0x4d, 0x69, 0xc5, 0x75, 0xb9, 0x08, 0x8c, 0xc6, + 0xf6, 0x99, 0x6f, 0x1f, 0x15, 0x81, 0x81, 0xb8, 0x9b, 0xcd, 0xf1, 0x51, 0xf1, 0x1c, 0x1b, 0xff, + 0xae, 0x24, 0x56, 0x4f, 0x27, 0x95, 0x29, 0xf9, 0x06, 0xdb, 0xaf, 0xc3, 0x2e, 0x89, 0x2a, 0x9b, + 0xea, 0x53, 0xd9, 0x9b, 0xa9, 0x95, 0x15, 0x95, 0xde, 0x4e, 0xad, 0x34, 0xb5, 0x12, 0xf2, 0x2e, + 0x4c, 0x96, 0xab, 0x65, 0xb7, 0xb3, 0xeb, 0xec, 0xd5, 0xd7, 0x4a, 0x28, 0x6b, 0x0a, 0x17, 0xab, + 0x86, 0x63, 0x35, 0x10, 0x6e, 0xf9, 0xfb, 0xb6, 0xe6, 0x69, 0x1b, 0xe1, 0x93, 0x5b, 0x30, 0x23, + 0x7f, 0x9a, 0x74, 0x77, 0xcb, 0xac, 0xa2, 0x88, 0x29, 0xfd, 0xda, 0x42, 0x0e, 0xac, 0x23, 0x7a, + 0x9e, 0x7a, 0xf5, 0x88, 0x91, 0xb1, 0xc9, 0x58, 0xa1, 0xdd, 0x96, 0x7b, 0xc8, 0x3e, 0x6f, 0xd3, + 0xa1, 0x1e, 0x0a, 0x95, 0x62, 0x32, 0x36, 0xc3, 0x12, 0x2b, 0x70, 0xf4, 0x07, 0x59, 0x9d, 0x88, + 0x6c, 0xc0, 0x9c, 0x98, 0xe2, 0xf7, 0x1d, 0xdf, 0xd9, 0x71, 0x5a, 0x4e, 0x70, 0x88, 0xe2, 0xa4, + 0x10, 0x60, 0xe4, 0xba, 0x78, 0x10, 0x96, 0x2a, 0xcc, 0x92, 0xa4, 0xc6, 0xaf, 0x65, 0xe1, 0xb9, + 0x41, 0x57, 0x2b, 0x52, 0xd7, 0x37, 0xb3, 0x4b, 0x43, 0x5c, 0xc7, 0x4e, 0xde, 0xce, 0x56, 0x61, + 0xe6, 0x9e, 0x62, 0x23, 0x18, 0xda, 0x6c, 0x62, 0x67, 0xa8, 0xd6, 0x83, 0xfa, 0x6c, 0x8f, 0x11, + 0x2d, 0x3d, 0x10, 0xdb, 0xdc, 0xc7, 0xf5, 0xf9, 0xbc, 0x01, 0x13, 0x65, 0xb7, 0x13, 0xd0, 0x47, + 0x41, 0x2c, 0xc2, 0x01, 0x07, 0xc6, 0xfd, 0x5d, 0x25, 0xaa, 0xf1, 0xef, 0xb2, 0xf0, 0xfc, 0xc0, + 0xbb, 0x05, 0xd9, 0xd4, 0x7b, 0xed, 0xf2, 0x30, 0x17, 0x92, 0x93, 0xbb, 0x6d, 0x39, 0x61, 0xc8, + 0x77, 0xa2, 0x4b, 0xd5, 0xd2, 0xff, 0x90, 0x11, 0x9d, 0xf4, 0x69, 0x18, 0xc7, 0xaa, 0xc2, 0x2e, + 0xe2, 0x6a, 0x37, 0xdc, 0x85, 0x1d, 0x5d, 0xed, 0xc6, 0xd1, 0xc8, 0x75, 0xc8, 0x97, 0xed, 0x56, + 0x4b, 0x89, 0xff, 0x80, 0xd7, 0x83, 0x06, 0xc2, 0x62, 0xd6, 0xa8, 0x12, 0x91, 0xc9, 0x3e, 0xfc, + 0x6f, 0xe5, 0xac, 0xc0, 0xcd, 0x52, 0x90, 0xc5, 0x8e, 0x0b, 0x05, 0x19, 0xa3, 0xc6, 0x36, 0xdc, + 0xd0, 0xc3, 0x9c, 0x47, 0x8d, 0x65, 0x00, 0x2d, 0x6a, 0x2c, 0x03, 0x18, 0xbf, 0x9e, 0x83, 0x17, + 0x06, 0x5f, 0x90, 0xc9, 0x96, 0x3e, 0x04, 0xaf, 0x0d, 0x75, 0xad, 0x3e, 0x79, 0x0c, 0x64, 0x0c, + 0x66, 0xde, 0x21, 0x97, 0x92, 0xfe, 0x34, 0xdf, 0x39, 0x2a, 0x2a, 0x26, 0xce, 0xb7, 0x5d, 0xa7, + 0xa3, 0x3c, 0xc2, 0x7c, 0x5d, 0x93, 0x0c, 0xb9, 0x39, 0xc0, 0x8d, 0xe1, 0xbe, 0x2c, 0xa2, 0xe3, + 0xfb, 0xca, 0xb0, 0x12, 0xe5, 0xe7, 0xa1, 0x10, 0x27, 0x25, 0x17, 0x61, 0x04, 0x3f, 0x40, 0x71, + 0x0a, 0x8a, 0x71, 0xc0, 0xf2, 0xa5, 0xbb, 0x62, 0xee, 0x60, 0x48, 0x0c, 0x34, 0x30, 0xd0, 0x95, + 0x8d, 0x22, 0x24, 0x06, 0xb7, 0x4f, 0x48, 0x2a, 0x1c, 0x63, 0x44, 0xc6, 0x9f, 0x65, 0xe0, 0x7c, + 0x5f, 0xd5, 0x03, 0xa9, 0xe9, 0x03, 0xf6, 0xca, 0x49, 0xba, 0x8a, 0x13, 0xc7, 0x6a, 0xe9, 0xc7, + 0xe5, 0xdc, 0x7f, 0x0f, 0xa6, 0xea, 0xbd, 0x9d, 0xf8, 0xfd, 0x8c, 0x07, 0xac, 0x51, 0xe0, 0xea, + 0x09, 0xa6, 0xe2, 0xb3, 0xf6, 0x4b, 0x0b, 0x0a, 0x61, 0x51, 0xa4, 0x98, 0x31, 0x86, 0x3e, 0xdb, + 0xc9, 0x90, 0x20, 0x3a, 0x91, 0xf1, 0xab, 0xd9, 0xf4, 0x8b, 0xee, 0xad, 0x72, 0xed, 0x34, 0x17, + 0xdd, 0x5b, 0xe5, 0xda, 0xc9, 0x6d, 0xff, 0x6f, 0x64, 0xdb, 0xf1, 0xa5, 0x57, 0xec, 0x78, 0x52, + 0x73, 0x2a, 0x5e, 0x7a, 0xe5, 0xee, 0xe8, 0xeb, 0x2f, 0xbd, 0x12, 0x99, 0xbc, 0x09, 0x13, 0xeb, + 0x2e, 0x8f, 0xd6, 0x21, 0x5b, 0xcc, 0x9d, 0x9a, 0x25, 0x50, 0xdd, 0x1e, 0x43, 0x4c, 0x76, 0xb7, + 0xd0, 0x07, 0x5e, 0x5a, 0x6b, 0xe2, 0xdd, 0x22, 0x36, 0x5d, 0x74, 0xfd, 0xa2, 0x4e, 0x66, 0xfc, + 0xa3, 0x51, 0x30, 0x4e, 0xd6, 0x8e, 0x90, 0x0f, 0xf5, 0xbe, 0xbb, 0x32, 0xb4, 0x5e, 0x65, 0xa8, + 0x2d, 0xb7, 0xd4, 0x6b, 0x3a, 0xb4, 0xd3, 0xd0, 0x43, 0x6d, 0x08, 0x98, 0xba, 0x05, 0x4a, 0xbc, + 0x8f, 0xe3, 0xf9, 0xba, 0xf4, 0xdf, 0xe5, 0xa2, 0xa5, 0x16, 0x3b, 0x1a, 0x33, 0x1f, 0xe3, 0x68, + 0x24, 0x77, 0xa0, 0xa0, 0x42, 0x94, 0x27, 0x5f, 0x94, 0x5c, 0x34, 0x46, 0xb1, 0x8f, 0x4a, 0x10, + 0xea, 0xe7, 0x6b, 0x6e, 0xf8, 0xf3, 0x35, 0x12, 0xdf, 0xb1, 0xfe, 0x91, 0xa4, 0xf8, 0x1e, 0xf7, + 0x6e, 0x57, 0xd0, 0x65, 0x68, 0x0e, 0x5f, 0x1c, 0x5a, 0xa3, 0x7a, 0x68, 0x8e, 0x94, 0x83, 0x4b, + 0x45, 0x97, 0xd1, 0x45, 0xf0, 0xa7, 0xe2, 0x5c, 0x1f, 0x46, 0x17, 0xe1, 0xf4, 0x69, 0xd1, 0x45, + 0x42, 0x12, 0x76, 0x00, 0x9a, 0xbd, 0x0e, 0x0f, 0x4f, 0x3e, 0x1e, 0x1d, 0x80, 0x5e, 0xaf, 0x63, + 0xc5, 0x43, 0x94, 0x87, 0x88, 0xc6, 0x3f, 0x1e, 0x49, 0x17, 0x0e, 0x22, 0x05, 0xda, 0x29, 0x84, + 0x83, 0x90, 0xe8, 0x93, 0x99, 0xa9, 0x5b, 0x30, 0x2f, 0x0d, 0xfe, 0xa4, 0xe5, 0xd8, 0x96, 0xb9, + 0x2e, 0x86, 0x18, 0xf5, 0x46, 0xa1, 0xa9, 0xa0, 0xb4, 0x3e, 0xb3, 0x7a, 0x9e, 0xa6, 0x37, 0x4a, + 0xa1, 0x5f, 0xfa, 0x0d, 0xa9, 0x16, 0x53, 0x07, 0x61, 0x6b, 0x2b, 0x9c, 0xcb, 0xb1, 0x41, 0xe8, + 0xf5, 0xb4, 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, 0xf2, 0xf1, 0x51, 0xf1, 0x15, 0x45, 0x14, 0x57, 0x2f, 0x1c, 0x31, 0xee, 0xfd, 0x79, 0xb1, + 0xfd, 0x76, 0xc5, 0xb3, 0x3b, 0x8d, 0x7d, 0x65, 0xce, 0xe3, 0x7e, 0xbb, 0x83, 0xd0, 0x44, 0x7c, + 0x84, 0x08, 0xd9, 0xf8, 0x3b, 0xd9, 0x74, 0xbd, 0x02, 0xd7, 0x93, 0x9e, 0x46, 0xaf, 0xc0, 0x29, + 0x4e, 0x3e, 0x25, 0xfe, 0x91, 0x3c, 0x25, 0x5e, 0x81, 0xf1, 0x4d, 0xda, 0xb1, 0x3b, 0x61, 0xe0, + 0x0e, 0x7c, 0x62, 0x0d, 0x38, 0xc8, 0x94, 0x65, 0xe4, 0x03, 0x20, 0x35, 0xdb, 0xa3, 0x9d, 0xa0, + 0xec, 0xb6, 0xbb, 0xb6, 0x17, 0xb4, 0x31, 0x80, 0x3b, 0x3f, 0x1a, 0x5e, 0x3c, 0x3e, 0x2a, 0x3e, + 0xdf, 0xc5, 0x52, 0xab, 0xa1, 0x14, 0xab, 0xf1, 0x9f, 0x92, 0xc4, 0xe4, 0x2a, 0x8c, 0xcb, 0x67, + 0xc8, 0x5c, 0x14, 0xcb, 0x2b, 0xf9, 0x04, 0x29, 0xb1, 0x8c, 0x1f, 0xcf, 0xc2, 0x0c, 0x97, 0x68, + 0xf8, 0xa3, 0xe8, 0x53, 0xfb, 0xe0, 0xfc, 0xb6, 0xf6, 0xe0, 0x2c, 0x03, 0x1e, 0xaa, 0x4d, 0x1b, + 0xea, 0xb9, 0x79, 0x1f, 0x48, 0x92, 0x86, 0x98, 0x30, 0xa5, 0x42, 0x07, 0xbf, 0x34, 0x5f, 0x8b, + 0x62, 0x63, 0x0a, 0x81, 0x12, 0x9f, 0xfb, 0x7d, 0x53, 0xe3, 0x61, 0xfc, 0x58, 0x16, 0xa6, 0x15, + 0xf3, 0xa0, 0xa7, 0xb6, 0xe3, 0x3f, 0xaf, 0x75, 0xfc, 0x62, 0xe8, 0x98, 0x19, 0xb6, 0x6c, 0xa8, + 0x7e, 0xef, 0xc1, 0x5c, 0x82, 0x24, 0x6e, 0x65, 0x95, 0x19, 0xc6, 0xca, 0xea, 0xf5, 0x64, 0xa0, + 0x3d, 0x9e, 0xaf, 0x22, 0x0c, 0xbb, 0xa4, 0x46, 0xf6, 0xfb, 0xc9, 0x2c, 0x2c, 0x88, 0x5f, 0x18, + 0x99, 0x96, 0x8b, 0xf4, 0x4f, 0xed, 0x58, 0x94, 0xb4, 0xb1, 0x28, 0xea, 0x63, 0xa1, 0x34, 0xb0, + 0xff, 0x90, 0x18, 0x3f, 0x0c, 0xb0, 0xd8, 0x8f, 0x60, 0xe8, 0xf8, 0x07, 0x91, 0x47, 0x68, 0x76, + 0x08, 0x8f, 0xd0, 0x75, 0x28, 0x60, 0x55, 0x22, 0xf6, 0xa4, 0xbf, 0x65, 0x56, 0x45, 0x27, 0xa1, + 0x16, 0x86, 0x87, 0x0f, 0x16, 0xb1, 0x30, 0xfd, 0x98, 0x66, 0x28, 0x41, 0x49, 0x7e, 0x29, 0x03, + 0x33, 0x08, 0x5c, 0x7d, 0xc0, 0xb6, 0x44, 0xc6, 0x6c, 0x44, 0xb8, 0x0a, 0x86, 0xef, 0xd1, 0xf5, + 0xc0, 0x73, 0x3a, 0x7b, 0xe2, 0x41, 0x7a, 0x47, 0x3c, 0x48, 0xbf, 0xc3, 0x1f, 0xd2, 0xaf, 0x34, + 0xdc, 0xf6, 0xd5, 0x3d, 0xcf, 0x7e, 0xe0, 0x70, 0xcb, 0x37, 0xbb, 0x75, 0x35, 0x4a, 0xb3, 0xd4, + 0x75, 0x62, 0x09, 0x90, 0x04, 0x2b, 0x7c, 0xec, 0xe7, 0x1f, 0x4a, 0xb1, 0xda, 0xb8, 0x02, 0x4b, + 0xff, 0x22, 0xf2, 0x3d, 0x70, 0x8e, 0x47, 0x84, 0x2b, 0xbb, 0x9d, 0xc0, 0xe9, 0xf4, 0xdc, 0x9e, + 0xbf, 0x62, 0x37, 0x0e, 0xd8, 0x65, 0x88, 0x3b, 0x74, 0x63, 0xcb, 0x1b, 0x61, 0xa1, 0xb5, 0xc3, + 0x4b, 0xb5, 0x50, 0x23, 0xe9, 0x0c, 0xc8, 0x1a, 0xcc, 0xf1, 0xa2, 0x52, 0x2f, 0x70, 0xeb, 0x0d, + 0xbb, 0xe5, 0x74, 0xf6, 0x50, 0xe2, 0xca, 0x73, 0x81, 0xcf, 0xee, 0x05, 0xae, 0xe5, 0x73, 0xb8, + 0xaa, 0xcf, 0x4a, 0x10, 0x91, 0x2a, 0xcc, 0x9a, 0xd4, 0x6e, 0xde, 0xb5, 0x1f, 0x95, 0xed, 0xae, + 0xdd, 0x70, 0x02, 0x1e, 0xa2, 0x36, 0xc7, 0xc5, 0x5e, 0x8f, 0xda, 0x4d, 0xab, 0x6d, 0x3f, 0xb2, + 0x1a, 0xa2, 0x50, 0x7f, 0xd8, 0xd0, 0xe8, 0x42, 0x56, 0x4e, 0x27, 0x64, 0x35, 0x11, 0x67, 0xe5, + 0x74, 0xfa, 0xb3, 0x8a, 0xe8, 0x24, 0xab, 0x4d, 0xdb, 0xdb, 0xa3, 0x01, 0xb7, 0x4f, 0x87, 0x0b, + 0x99, 0x4b, 0x19, 0x85, 0x55, 0x80, 0x65, 0x16, 0xda, 0xaa, 0xc7, 0x59, 0x29, 0x74, 0x6c, 0xe6, + 0x6d, 0x7b, 0x4e, 0x40, 0xd5, 0x16, 0x4e, 0xe2, 0x67, 0x61, 0xff, 0xa3, 0x65, 0x7f, 0xbf, 0x26, + 0x26, 0x28, 0x23, 0x6e, 0x4a, 0x23, 0xa7, 0x12, 0xdc, 0xd2, 0x5b, 0x99, 0xa0, 0x0c, 0xb9, 0xa9, + 0xed, 0x9c, 0xc6, 0x76, 0x2a, 0xdc, 0xfa, 0x34, 0x34, 0x41, 0x49, 0x36, 0x58, 0xa7, 0x05, 0x4c, + 0xba, 0x74, 0x3b, 0xc2, 0x70, 0x7e, 0x06, 0x3f, 0xed, 0x65, 0x61, 0xfd, 0x59, 0xf0, 0x64, 0xb1, + 0x95, 0x62, 0x46, 0x1f, 0x27, 0x26, 0x7f, 0x05, 0x66, 0xb7, 0x7c, 0x7a, 0xb3, 0x5a, 0xab, 0xcb, + 0x00, 0x72, 0xa8, 0x82, 0x9d, 0x59, 0xbe, 0x76, 0xc2, 0xa6, 0x73, 0x45, 0xa5, 0xc1, 0xac, 0x45, + 0x7c, 0xdc, 0x7a, 0x3e, 0xb5, 0x76, 0x9d, 0xae, 0x1f, 0x46, 0xe3, 0x54, 0xc7, 0x2d, 0x56, 0x95, + 0xb1, 0x06, 0x73, 0x09, 0x36, 0x64, 0x06, 0x80, 0x01, 0xad, 0xad, 0x8d, 0xfa, 0xea, 0x66, 0xe1, + 0x19, 0x52, 0x80, 0x29, 0xfc, 0xbd, 0xba, 0x51, 0x5a, 0x59, 0x5f, 0xad, 0x14, 0x32, 0x64, 0x0e, + 0xa6, 0x11, 0x52, 0xa9, 0xd6, 0x39, 0x28, 0xcb, 0x73, 0x56, 0x98, 0x05, 0xbe, 0x74, 0x03, 0xb6, + 0x00, 0xf0, 0x4c, 0x31, 0xfe, 0x66, 0x16, 0xce, 0xcb, 0x63, 0x85, 0x06, 0x4c, 0xbc, 0x76, 0x3a, + 0x7b, 0x4f, 0xf9, 0xe9, 0x70, 0x53, 0x3b, 0x1d, 0x5e, 0x8e, 0x9d, 0xd4, 0xb1, 0x56, 0x0e, 0x38, + 0x22, 0x7e, 0x6b, 0x02, 0x9e, 0x1f, 0x48, 0x45, 0x3e, 0x60, 0xa7, 0xb9, 0x43, 0x3b, 0x41, 0xb5, + 0xd9, 0xa2, 0x9b, 0x4e, 0x9b, 0xba, 0xbd, 0x40, 0x38, 0x6a, 0xbc, 0x84, 0x5a, 0x4f, 0x2c, 0xb4, + 0x9c, 0x66, 0x8b, 0x5a, 0x01, 0x2f, 0xd6, 0xa6, 0x5b, 0x92, 0x9a, 0xb1, 0x0c, 0x33, 0xa8, 0x55, + 0x3b, 0x01, 0xf5, 0x1e, 0xa0, 0x31, 0x68, 0xc8, 0xf2, 0x80, 0xd2, 0xae, 0x65, 0xb3, 0x52, 0xcb, + 0x11, 0xc5, 0x3a, 0xcb, 0x04, 0x35, 0xb9, 0xa9, 0xb0, 0x2c, 0xbb, 0xbd, 0x4e, 0x70, 0xd7, 0x7e, + 0x24, 0xac, 0xd3, 0x44, 0x40, 0xe2, 0x90, 0x25, 0xf7, 0xa2, 0x6c, 0xdb, 0x8f, 0xcc, 0x24, 0x09, + 0xf9, 0x0a, 0x9c, 0x11, 0x07, 0x90, 0x88, 0x99, 0x23, 0x5b, 0xcc, 0x23, 0xf2, 0xbc, 0x7a, 0x7c, + 0x54, 0x3c, 0x27, 0x43, 0x39, 0xcb, 0x78, 0x56, 0x69, 0xad, 0x4e, 0xe7, 0x42, 0x36, 0xd9, 0x81, + 0x1c, 0xeb, 0x8e, 0xbb, 0xd4, 0xf7, 0xa5, 0xab, 0xac, 0xd0, 0x1f, 0xa8, 0x9d, 0x69, 0xb5, 0x79, + 0xb9, 0xd9, 0x97, 0x92, 0xac, 0xc1, 0xcc, 0x36, 0xdd, 0x51, 0xc7, 0x67, 0x2c, 0xdc, 0xaa, 0x0a, + 0x0f, 0xe9, 0x4e, 0xff, 0xc1, 0x89, 0xd1, 0x11, 0x07, 0x5f, 0x51, 0x1e, 0x1d, 0xae, 0x3b, 0x7e, + 0x40, 0x3b, 0xd4, 0xc3, 0xa8, 0x79, 0xe3, 0xb8, 0x19, 0x2c, 0x46, 0x12, 0xb2, 0x5e, 0x2e, 0xee, + 0x37, 0xe8, 0x73, 0xde, 0x12, 0x70, 0x2b, 0x96, 0x7f, 0x2c, 0xc9, 0x95, 0x7c, 0x0d, 0x66, 0x4d, + 0xb7, 0x17, 0x38, 0x9d, 0xbd, 0x7a, 0xe0, 0xd9, 0x01, 0xdd, 0xe3, 0x07, 0x52, 0x14, 0x9e, 0x2f, + 0x56, 0x2a, 0x1e, 0xe0, 0x39, 0xd0, 0xf2, 0x05, 0x54, 0x3b, 0x11, 0x74, 0x02, 0xf2, 0x55, 0x98, + 0xe1, 0xd1, 0x52, 0xc2, 0x0a, 0x26, 0xb4, 0xdc, 0x29, 0x7a, 0xe1, 0xfd, 0x6b, 0xc2, 0x98, 0x08, + 0xa1, 0x69, 0x15, 0xc4, 0xb8, 0x91, 0x2f, 0x89, 0xce, 0xaa, 0x39, 0x9d, 0xbd, 0x70, 0x1a, 0x03, + 0xf6, 0xfc, 0x1b, 0x51, 0x97, 0x74, 0xd9, 0xe7, 0xca, 0x69, 0xdc, 0xc7, 0x32, 0x32, 0xc9, 0x87, + 0x04, 0xf0, 0x7c, 0xc9, 0xf7, 0x1d, 0x3f, 0x10, 0xee, 0x4c, 0xab, 0x8f, 0x68, 0xa3, 0xc7, 0x90, + 0xb7, 0x5d, 0xef, 0x80, 0x7a, 0xdc, 0x9c, 0x7e, 0x74, 0xe5, 0xca, 0xf1, 0x51, 0xf1, 0x35, 0x1b, + 0x11, 0x2d, 0xe1, 0x01, 0x65, 0x51, 0x89, 0x6a, 0x3d, 0xe4, 0xb8, 0x4a, 0x1b, 0x06, 0x33, 0x25, + 0x5f, 0x85, 0xb3, 0x65, 0xdb, 0xa7, 0xd5, 0x8e, 0x4f, 0x3b, 0xbe, 0x13, 0x38, 0x0f, 0xa8, 0xe8, + 0x54, 0x3c, 0xfc, 0xf2, 0x98, 0xa9, 0xcd, 0x68, 0xd8, 0x3e, 0x5b, 0x98, 0x21, 0x8a, 0x25, 0x06, + 0x45, 0xa9, 0xa6, 0x0f, 0x17, 0x62, 0xc2, 0x4c, 0xbd, 0xbe, 0x56, 0x71, 0xec, 0x70, 0x5d, 0x4d, + 0x63, 0x7f, 0xbd, 0x86, 0x0a, 0x50, 0x7f, 0xdf, 0x6a, 0x3a, 0x76, 0xb8, 0xa0, 0xfa, 0x74, 0x56, + 0x8c, 0x83, 0x71, 0x94, 0x81, 0x42, 0x7c, 0x28, 0xc9, 0x17, 0x61, 0x82, 0x9b, 0x15, 0x52, 0x7f, + 0x5f, 0x04, 0xfc, 0x90, 0x56, 0x6a, 0x21, 0x5c, 0x27, 0x12, 0x5e, 0x8c, 0xdc, 0x68, 0x91, 0xaa, + 0x36, 0x45, 0xe8, 0xc5, 0x28, 0x89, 0x48, 0x13, 0xa6, 0xf8, 0x68, 0x51, 0x8c, 0xcd, 0x29, 0xac, + 0xcb, 0x5f, 0x54, 0x57, 0x87, 0x28, 0x8a, 0xf1, 0xc7, 0xb7, 0x55, 0x31, 0x27, 0x38, 0x82, 0x56, + 0x85, 0xc6, 0x75, 0x05, 0x20, 0x2f, 0x09, 0x8d, 0xf3, 0x70, 0xae, 0xcf, 0x37, 0x1b, 0x0f, 0x50, + 0x2f, 0xd2, 0xa7, 0x46, 0xf2, 0x45, 0x58, 0x40, 0xc2, 0xb2, 0xdb, 0xe9, 0xd0, 0x46, 0x80, 0xdb, + 0x91, 0x7c, 0xa3, 0xc8, 0x71, 0x7b, 0x20, 0xde, 0xde, 0x46, 0x88, 0x60, 0xc5, 0x9f, 0x2a, 0x52, + 0x39, 0x18, 0x3f, 0x9f, 0x85, 0x45, 0xb1, 0xc3, 0x99, 0xb4, 0xe1, 0x7a, 0xcd, 0xa7, 0xff, 0x44, + 0x5d, 0xd5, 0x4e, 0xd4, 0x97, 0xc2, 0x68, 0x51, 0x69, 0x8d, 0x1c, 0x70, 0xa0, 0xfe, 0x6a, 0x06, + 0x9e, 0x1b, 0x44, 0xc4, 0x7a, 0x27, 0x8c, 0x45, 0x3a, 0x91, 0x88, 0x39, 0xda, 0x85, 0x79, 0x1c, + 0xd0, 0xf2, 0x3e, 0x6d, 0x1c, 0xf8, 0x6b, 0xae, 0x1f, 0xa0, 0x83, 0x4b, 0xb6, 0x8f, 0x45, 0xc0, + 0xeb, 0xa9, 0x16, 0x01, 0x67, 0xf9, 0x2c, 0x6b, 0x20, 0x0f, 0x1e, 0x2d, 0xf5, 0x80, 0x1e, 0xfa, + 0x66, 0x1a, 0x6b, 0x74, 0x54, 0x28, 0xf5, 0x82, 0xfd, 0x9a, 0x47, 0x77, 0xa9, 0x47, 0x3b, 0x0d, + 0xfa, 0x5d, 0xe6, 0xa8, 0xa0, 0x37, 0x6e, 0x28, 0x0d, 0xc6, 0xb7, 0x66, 0x60, 0x21, 0x8d, 0x8c, + 0xf5, 0x8b, 0x72, 0x69, 0x8e, 0x27, 0x92, 0xfd, 0x66, 0x06, 0xa6, 0xea, 0xb4, 0xe1, 0x76, 0x9a, + 0x37, 0xd1, 0xee, 0x4a, 0xf4, 0x8e, 0xcd, 0x85, 0x06, 0x06, 0xb7, 0x76, 0x63, 0x06, 0x59, 0xdf, + 0x39, 0x2a, 0x7e, 0x61, 0xb8, 0xbb, 0x6a, 0xc3, 0xc5, 0x28, 0x4d, 0x01, 0x26, 0x3a, 0x09, 0xab, + 0xe0, 0x5f, 0x63, 0x6a, 0xd5, 0x92, 0x15, 0x98, 0x16, 0x0b, 0xd6, 0x55, 0x83, 0xd1, 0xf2, 0x90, + 0x5a, 0xb2, 0x20, 0xa1, 0xe2, 0xd7, 0x48, 0xc8, 0x75, 0xc8, 0x6d, 0x2d, 0xdf, 0x14, 0xa3, 0x20, + 0x93, 0xc5, 0x6c, 0x2d, 0xdf, 0x44, 0x85, 0x18, 0xbb, 0x64, 0x4c, 0xf7, 0x96, 0x35, 0x63, 0xa8, + 0xad, 0xe5, 0x9b, 0xe4, 0xaf, 0xc2, 0x99, 0x8a, 0xe3, 0x8b, 0x2a, 0xb8, 0xd3, 0x4c, 0x13, 0x5d, + 0x45, 0xc7, 0xfa, 0xcc, 0xdf, 0xcf, 0xa6, 0xce, 0xdf, 0x17, 0x9b, 0x21, 0x13, 0x8b, 0x7b, 0xe4, + 0x34, 0xe3, 0x41, 0x77, 0xd3, 0xeb, 0x21, 0x1f, 0xc1, 0x0c, 0xea, 0x6f, 0xd1, 0x8f, 0x08, 0xd3, + 0x25, 0x8c, 0xf7, 0xa9, 0xf9, 0xd3, 0xa9, 0x35, 0x2f, 0xf1, 0x40, 0x27, 0xe8, 0x8d, 0x84, 0xa9, + 0x15, 0xb4, 0x7b, 0xbf, 0xc6, 0x99, 0xdc, 0x86, 0x59, 0x21, 0x80, 0xdd, 0xdb, 0xdd, 0xdc, 0xa7, + 0x15, 0xfb, 0x50, 0xd8, 0x31, 0xe1, 0x9d, 0x4e, 0x48, 0x6d, 0x96, 0xbb, 0x6b, 0x05, 0xfb, 0xd4, + 0x6a, 0xda, 0x9a, 0xa8, 0x12, 0x23, 0x24, 0xdf, 0x80, 0xc9, 0x75, 0xb7, 0xc1, 0x64, 0x6f, 0xdc, + 0x1b, 0xb8, 0x69, 0xd3, 0x87, 0x98, 0xac, 0x94, 0x83, 0x63, 0x02, 0xd5, 0x77, 0x8e, 0x8a, 0x6f, + 0x9f, 0x76, 0xda, 0x28, 0x15, 0x98, 0x6a, 0x6d, 0xa4, 0x0c, 0xf9, 0x6d, 0xba, 0xc3, 0x5a, 0x1b, + 0x4f, 0x64, 0x28, 0xc1, 0xc2, 0x72, 0x51, 0xfc, 0xd2, 0x2c, 0x17, 0x05, 0x8c, 0x78, 0x30, 0x87, + 0xfd, 0x53, 0xb3, 0x7d, 0xff, 0xa1, 0xeb, 0x35, 0x31, 0x63, 0x4d, 0x3f, 0xab, 0xa9, 0xe5, 0xd4, + 0xce, 0x7f, 0x8e, 0x77, 0x7e, 0x57, 0xe1, 0xa0, 0x8a, 0x90, 0x09, 0xf6, 0xe4, 0x6b, 0x30, 0x23, + 0x82, 0x46, 0xdc, 0xbd, 0x59, 0xc2, 0x95, 0x30, 0xa5, 0x39, 0xdc, 0xea, 0x85, 0x5c, 0x4e, 0x15, + 0x31, 0x28, 0xa4, 0x0e, 0xca, 0x6a, 0xef, 0xda, 0xfa, 0xe3, 0x88, 0x4a, 0x42, 0x6a, 0x30, 0x59, + 0xc1, 0x74, 0xda, 0xe8, 0x14, 0x28, 0x0c, 0xf2, 0xc3, 0x4c, 0x6c, 0x51, 0x09, 0xd7, 0xc6, 0x88, + 0xcc, 0xdb, 0xe8, 0x62, 0xa8, 0xdb, 0x34, 0x87, 0x88, 0xe4, 0x06, 0xe4, 0xaa, 0x95, 0x9a, 0xb0, + 0xc7, 0x9f, 0x0b, 0x43, 0xb3, 0xd4, 0x64, 0xde, 0x2a, 0xb4, 0x33, 0x74, 0x9a, 0x9a, 0x35, 0x7f, + 0xb5, 0x52, 0x23, 0xbb, 0x30, 0x8d, 0x1d, 0xb0, 0x46, 0x6d, 0xde, 0xb7, 0xb3, 0x7d, 0xfa, 0xf6, + 0x4a, 0x6a, 0xdf, 0x2e, 0xf2, 0xbe, 0xdd, 0x17, 0xd4, 0x5a, 0x22, 0x1e, 0x95, 0x2d, 0x13, 0x6a, + 0x45, 0x72, 0x30, 0x99, 0x3e, 0x66, 0x73, 0x1d, 0xed, 0xa8, 0x84, 0x50, 0x2b, 0x73, 0x89, 0x85, + 0xf9, 0x6c, 0xfa, 0xba, 0xfb, 0x24, 0xf9, 0x90, 0xcf, 0xc3, 0xc8, 0xbd, 0x83, 0xc0, 0x16, 0x96, + 0xf7, 0xb2, 0x1f, 0x19, 0x48, 0x36, 0x1f, 0xf5, 0x90, 0xee, 0x81, 0x16, 0xec, 0x0f, 0x69, 0xd8, + 0x50, 0xac, 0xd9, 0x5e, 0xf3, 0xa1, 0xed, 0xa1, 0x67, 0xf6, 0xbc, 0xc6, 0x42, 0x29, 0xe1, 0x43, + 0xb1, 0x2f, 0x00, 0x31, 0x77, 0x6d, 0x95, 0x05, 0xf9, 0x1e, 0x38, 0xef, 0x3b, 0x7b, 0x1d, 0x3b, + 0xe8, 0x79, 0xd4, 0xb2, 0x5b, 0x7b, 0xae, 0xe7, 0x04, 0xfb, 0x6d, 0xcb, 0xef, 0x39, 0x01, 0x5d, + 0x5c, 0xd0, 0x52, 0x89, 0xd7, 0x25, 0x5e, 0x49, 0xa2, 0xd5, 0x19, 0x96, 0x79, 0xce, 0x4f, 0x2f, + 0x20, 0x5f, 0x82, 0x69, 0x75, 0x4b, 0xf6, 0x17, 0xcf, 0x5c, 0xc8, 0x5d, 0x9a, 0x09, 0xaf, 0x1e, + 0xf1, 0x2d, 0x5c, 0x86, 0xe0, 0x56, 0xce, 0x08, 0x5f, 0x0f, 0xc1, 0xad, 0xf0, 0x22, 0x26, 0x9c, + 0xf3, 0xb9, 0x7e, 0xa3, 0xd7, 0x71, 0x1e, 0x61, 0x9e, 0x32, 0x61, 0x6f, 0xb7, 0x78, 0x56, 0x3b, + 0xfa, 0xea, 0x88, 0xb5, 0xb5, 0x51, 0xfd, 0xe2, 0x96, 0x4f, 0x3d, 0x61, 0x76, 0xb7, 0xc0, 0x69, + 0xb7, 0x3a, 0xce, 0xa3, 0x08, 0x1a, 0x26, 0xfc, 0x24, 0x85, 0x79, 0x73, 0x4e, 0xac, 0x02, 0x31, + 0x72, 0x77, 0x6f, 0x96, 0xcc, 0xf1, 0x5a, 0xf5, 0x7e, 0xbd, 0xe5, 0x06, 0xc6, 0x3e, 0x2c, 0xa4, + 0x71, 0x25, 0x8b, 0x30, 0x2e, 0xb2, 0x65, 0xe0, 0xe1, 0x98, 0x37, 0xe5, 0x4f, 0xf2, 0x2c, 0x4c, + 0xec, 0x3a, 0x9e, 0x1f, 0x58, 0x3d, 0x87, 0xcb, 0x0b, 0xa3, 0x66, 0x1e, 0x01, 0x5b, 0x4e, 0x93, + 0x9c, 0x87, 0x3c, 0x46, 0x9d, 0x66, 0x65, 0x39, 0x2c, 0x1b, 0x67, 0xbf, 0xb7, 0x9c, 0xa6, 0xf1, + 0x5f, 0x64, 0xf0, 0x08, 0x22, 0xaf, 0x61, 0xfc, 0xb1, 0xf0, 0x8d, 0x14, 0xf5, 0xcf, 0x76, 0x37, + 0x96, 0x7d, 0x82, 0xa3, 0x90, 0xd7, 0x61, 0xec, 0xa6, 0xdd, 0xa0, 0xe1, 0xd3, 0x1b, 0x22, 0xef, + 0x22, 0x44, 0x55, 0x56, 0x73, 0x1c, 0x26, 0x1f, 0xf3, 0xa5, 0x59, 0x8a, 0x72, 0xec, 0x97, 0x4b, + 0xf2, 0xb9, 0x0d, 0xe5, 0x63, 0xb1, 0xa4, 0x95, 0x24, 0xfc, 0x31, 0xdf, 0x87, 0x54, 0x0e, 0xc6, + 0x9f, 0x64, 0xa2, 0x3d, 0x95, 0xbc, 0x0a, 0x23, 0x66, 0x2d, 0xfc, 0x7e, 0xee, 0x2b, 0x1e, 0xfb, + 0x7c, 0x44, 0x20, 0x5f, 0x82, 0x33, 0x0a, 0x9f, 0x84, 0x23, 0xc6, 0x2b, 0xe8, 0xca, 0xac, 0x7c, + 0x49, 0xba, 0x37, 0x46, 0x3a, 0x0f, 0xbc, 0x0c, 0x44, 0x05, 0x15, 0xda, 0x71, 0x38, 0x6f, 0xa5, + 0xb1, 0x2a, 0xef, 0x26, 0x22, 0xc4, 0x1b, 0x9b, 0xc6, 0x81, 0x7b, 0x32, 0x1b, 0xbf, 0x99, 0xd1, + 0xf6, 0xca, 0x30, 0x29, 0x79, 0xe6, 0x84, 0xa4, 0xe4, 0x6f, 0x01, 0x94, 0x7a, 0x81, 0xbb, 0xda, + 0xf1, 0xdc, 0x16, 0xd7, 0x02, 0x89, 0x04, 0x2c, 0xa8, 0xdb, 0xa6, 0x08, 0xd6, 0x1c, 0x2e, 0x43, + 0xe4, 0x54, 0x9f, 0x95, 0xdc, 0xc7, 0xf5, 0x59, 0x31, 0x7e, 0x2f, 0xa3, 0xed, 0x30, 0x4c, 0xca, + 0x15, 0x93, 0x5e, 0xb5, 0x0b, 0xec, 0x3a, 0x0f, 0x2c, 0xbf, 0xe5, 0x6a, 0x51, 0x4e, 0x04, 0x1a, + 0xf9, 0xff, 0x67, 0xe0, 0x2c, 0x77, 0xfe, 0xd8, 0xe8, 0xb5, 0x77, 0xa8, 0x77, 0xdf, 0x6e, 0x39, + 0xcd, 0x28, 0xba, 0x63, 0x64, 0x24, 0xaa, 0x54, 0x93, 0x8e, 0xcf, 0x2f, 0xda, 0xdc, 0x19, 0xc5, + 0xea, 0x60, 0xa1, 0xf5, 0x20, 0x2c, 0x55, 0x2f, 0xda, 0xe9, 0xf4, 0xc6, 0xaf, 0x65, 0xe0, 0xc5, + 0x13, 0x6b, 0x21, 0x57, 0x61, 0x7c, 0x55, 0x5d, 0xb4, 0xfc, 0x89, 0x39, 0x99, 0xf5, 0x46, 0x62, + 0x91, 0x2f, 0xc3, 0x19, 0x95, 0xd5, 0xa6, 0x67, 0x3b, 0x6a, 0x7e, 0x99, 0x94, 0xaf, 0x0e, 0x18, + 0x4a, 0x5c, 0xd6, 0x4c, 0x67, 0x62, 0xfc, 0x3f, 0x19, 0x98, 0x08, 0xed, 0xdc, 0x9f, 0xd2, 0x3b, + 0xc8, 0x0d, 0xed, 0x0e, 0x22, 0x63, 0xdb, 0x86, 0xad, 0x62, 0x65, 0xa9, 0xf7, 0xc6, 0x59, 0xc5, + 0x2b, 0x00, 0x01, 0x3f, 0x92, 0x85, 0x49, 0xb6, 0xbf, 0xf2, 0x87, 0xe8, 0xef, 0xae, 0x08, 0x9f, + 0x61, 0xbb, 0x86, 0x8a, 0xc1, 0xf8, 0x47, 0x19, 0x7c, 0xa0, 0x50, 0x29, 0x58, 0x6f, 0x28, 0xa9, + 0x49, 0xb1, 0x37, 0x30, 0x29, 0x29, 0x42, 0x79, 0x44, 0xba, 0x75, 0x3d, 0x4b, 0x31, 0xa6, 0xaa, + 0x5e, 0x27, 0x5f, 0x80, 0xd1, 0x2d, 0x54, 0xb7, 0xea, 0xb1, 0x59, 0x42, 0xfe, 0x58, 0xc8, 0x37, + 0xe9, 0x9e, 0xaf, 0x87, 0x2b, 0xe4, 0x84, 0xa4, 0x0e, 0xe3, 0x65, 0x8f, 0xda, 0x01, 0x6d, 0x8a, + 0x0e, 0x19, 0x2a, 0xb2, 0x40, 0x83, 0x93, 0xc4, 0x23, 0x0b, 0x08, 0x4e, 0xc6, 0xcf, 0x65, 0x81, + 0x44, 0x6d, 0xc4, 0x0c, 0x7b, 0xfe, 0x53, 0x3b, 0xe8, 0xef, 0x6b, 0x83, 0xfe, 0x7c, 0x62, 0xd0, + 0x79, 0xf3, 0x86, 0x1a, 0xfb, 0xdf, 0xce, 0xc0, 0xd9, 0x74, 0x42, 0xf2, 0x12, 0x8c, 0xdd, 0xdb, + 0xac, 0xc9, 0xf0, 0x3e, 0xa2, 0x29, 0x6e, 0x17, 0x75, 0x1d, 0xa6, 0x28, 0x22, 0x6f, 0xc0, 0xd8, + 0x07, 0x66, 0x99, 0x9d, 0x43, 0x4a, 0x0e, 0x97, 0xaf, 0x33, 0x71, 0x49, 0x3b, 0x8a, 0x04, 0x92, + 0x3a, 0xb6, 0xb9, 0x27, 0x36, 0xb6, 0x3f, 0x99, 0x85, 0xd9, 0x52, 0xa3, 0x41, 0x7d, 0x5f, 0xe4, + 0x27, 0x78, 0x6a, 0x07, 0x36, 0x3d, 0x70, 0x8f, 0xd6, 0xb6, 0xa1, 0x46, 0xf5, 0x77, 0x32, 0x70, + 0x46, 0x52, 0x3d, 0x70, 0xe8, 0xc3, 0xcd, 0x7d, 0x8f, 0xfa, 0xfb, 0x6e, 0xab, 0x39, 0x74, 0xa2, + 0x28, 0x26, 0xe8, 0x61, 0x4e, 0x01, 0xd5, 0x2a, 0x61, 0x17, 0x21, 0x9a, 0xa0, 0xc7, 0xf3, 0x0e, + 0x5c, 0x85, 0xf1, 0x52, 0xb7, 0xeb, 0xb9, 0x0f, 0xf8, 0xb2, 0x17, 0x01, 0x49, 0x6d, 0x0e, 0xd2, + 0x02, 0x33, 0x70, 0x10, 0xfb, 0x8c, 0x0a, 0xed, 0xf0, 0x08, 0x90, 0xd3, 0xfc, 0x33, 0x9a, 0xb4, + 0xa3, 0xde, 0x24, 0xb0, 0xdc, 0xa8, 0x03, 0xa9, 0x79, 0x6e, 0xdb, 0x0d, 0x68, 0x93, 0xb7, 0x07, + 0xe3, 0x59, 0x9c, 0x18, 0x89, 0x6d, 0xd3, 0x09, 0x5a, 0x5a, 0x24, 0xb6, 0x80, 0x01, 0x4c, 0x0e, + 0x37, 0xfe, 0xaf, 0x51, 0x98, 0x52, 0x7b, 0x87, 0x18, 0x3c, 0xfb, 0x8b, 0xeb, 0xa9, 0x41, 0x55, + 0x6c, 0x84, 0x98, 0xa2, 0x24, 0x8a, 0x48, 0x94, 0x3d, 0x31, 0x22, 0xd1, 0x36, 0x4c, 0xd7, 0x3c, + 0x17, 0x23, 0xa7, 0xe2, 0x6b, 0xab, 0xd8, 0x0a, 0xe7, 0x95, 0x5b, 0x33, 0x1b, 0x48, 0x7c, 0xcf, + 0xc5, 0x7b, 0x49, 0x57, 0x60, 0x63, 0x4e, 0x54, 0x4d, 0x67, 0xa4, 0xf1, 0xe1, 0xa6, 0x22, 0xb6, + 0x2f, 0xc2, 0x1f, 0x87, 0xa6, 0x22, 0x0c, 0xa2, 0x9b, 0x8a, 0x30, 0x88, 0xba, 0xd6, 0x46, 0x9f, + 0xd4, 0x5a, 0x23, 0x3f, 0x97, 0x81, 0xc9, 0x52, 0xa7, 0x23, 0x22, 0x1d, 0x9d, 0x10, 0xe4, 0xe1, + 0xcb, 0xc2, 0x5a, 0xe4, 0xed, 0x8f, 0x65, 0x2d, 0x82, 0x72, 0x8b, 0x8f, 0x92, 0x6a, 0x54, 0xa1, + 0x7a, 0xd7, 0x54, 0xbe, 0x83, 0xbc, 0x0d, 0x85, 0x70, 0x92, 0x57, 0x3b, 0x4d, 0xfa, 0x88, 0xf2, + 0xec, 0x99, 0xd3, 0x22, 0x1c, 0xbb, 0x2a, 0x99, 0xc6, 0x11, 0xc9, 0x26, 0x80, 0x1d, 0xce, 0xae, + 0x58, 0x1a, 0xe0, 0xe4, 0xf4, 0x13, 0xd2, 0x33, 0xfe, 0xc6, 0x07, 0x39, 0x55, 0x7a, 0x8e, 0xf8, + 0x90, 0x36, 0xcc, 0xf2, 0x1c, 0xbc, 0xf5, 0xc0, 0xf6, 0x02, 0xcc, 0x60, 0x02, 0x27, 0x8e, 0xc3, + 0xab, 0x42, 0xfb, 0xf7, 0xac, 0xc8, 0xec, 0xeb, 0x33, 0x5a, 0x2b, 0x25, 0x9d, 0x49, 0x9c, 0x37, + 0x0f, 0x7e, 0x6f, 0x9e, 0x4b, 0x7e, 0x2f, 0x9f, 0xf4, 0x3f, 0x99, 0x81, 0xb3, 0xea, 0xa4, 0xaf, + 0xf7, 0x76, 0x44, 0xc4, 0x59, 0x72, 0x05, 0x26, 0xc4, 0x9c, 0x0c, 0x2f, 0x51, 0xc9, 0x44, 0x2c, + 0x11, 0x0a, 0x59, 0x65, 0xd3, 0x90, 0xf1, 0x10, 0x52, 0xf7, 0x7c, 0x6c, 0x9f, 0x62, 0x45, 0x51, + 0x7e, 0x77, 0x0f, 0x7f, 0xeb, 0xf3, 0x93, 0x41, 0x8c, 0xf7, 0x60, 0x4e, 0x1f, 0x89, 0x3a, 0x0d, + 0xc8, 0x65, 0x18, 0x97, 0xc3, 0x97, 0x49, 0x1f, 0x3e, 0x59, 0x6e, 0x6c, 0x03, 0x49, 0xd0, 0xfb, + 0x68, 0xd6, 0xc5, 0xee, 0xa7, 0xdc, 0xec, 0x50, 0x3e, 0xaa, 0x26, 0x10, 0x57, 0xe6, 0xc5, 0xf7, + 0x4d, 0x6a, 0xce, 0x27, 0x18, 0x7d, 0xf7, 0x5f, 0xcc, 0xc2, 0x7c, 0xca, 0x9e, 0x7b, 0x82, 0x4c, + 0x54, 0xd4, 0x37, 0x88, 0x89, 0x30, 0x46, 0x8c, 0xdc, 0x16, 0xde, 0x83, 0xd1, 0x13, 0xb7, 0x03, + 0xee, 0x7a, 0x14, 0xdb, 0x05, 0x38, 0xd9, 0x27, 0x22, 0x17, 0xa9, 0x61, 0x9c, 0x46, 0x9f, 0x58, + 0x18, 0xa7, 0x15, 0x98, 0x16, 0xad, 0x12, 0xdb, 0x95, 0x62, 0x02, 0x2f, 0x13, 0x0b, 0x25, 0xb6, + 0x2d, 0x9d, 0x84, 0xf3, 0xf0, 0xdd, 0xd6, 0x03, 0x2a, 0x78, 0x8c, 0xab, 0x3c, 0xb0, 0x20, 0x95, + 0x87, 0x42, 0x42, 0xfe, 0x13, 0xcc, 0xff, 0x89, 0x10, 0x75, 0xcf, 0xca, 0x0f, 0xda, 0xb3, 0x9a, + 0x4f, 0x66, 0xcf, 0x7a, 0x5e, 0x7e, 0x63, 0xfa, 0xde, 0x95, 0xf2, 0x59, 0xe4, 0x97, 0x33, 0x30, + 0xc7, 0x63, 0x09, 0xa9, 0x1f, 0x3b, 0x30, 0x3e, 0x4c, 0xe3, 0xc9, 0x7c, 0xec, 0x73, 0x22, 0xa5, + 0x54, 0xfa, 0xb7, 0x26, 0x3f, 0x8a, 0x7c, 0x0f, 0x40, 0xb8, 0xa2, 0x78, 0x04, 0xe2, 0xc9, 0xe5, + 0xe7, 0x52, 0x76, 0x81, 0x10, 0x29, 0xca, 0xfc, 0x12, 0x84, 0x74, 0x5a, 0xd6, 0xd7, 0x10, 0x4a, + 0xfe, 0x2a, 0x2c, 0xb0, 0xf5, 0x12, 0x42, 0x44, 0xe4, 0xb3, 0xc5, 0x49, 0xac, 0xe5, 0x33, 0xfd, + 0x65, 0xa2, 0x2b, 0x69, 0x64, 0x3c, 0x5e, 0x75, 0x94, 0x80, 0x3f, 0x50, 0x83, 0xa4, 0xa4, 0x56, + 0x84, 0x01, 0x05, 0xf1, 0xeb, 0x79, 0x76, 0x96, 0x3e, 0xfb, 0xdb, 0x79, 0xb9, 0x16, 0xf8, 0xfe, + 0x16, 0x33, 0x18, 0x47, 0x10, 0xf9, 0x00, 0x48, 0x18, 0x84, 0x87, 0xc3, 0xa8, 0xcc, 0xdc, 0xc2, + 0x95, 0xe5, 0x51, 0x30, 0x1f, 0x4f, 0x16, 0xab, 0x93, 0x24, 0x49, 0x4c, 0x28, 0x2c, 0x88, 0x46, + 0x33, 0xa8, 0x4c, 0xce, 0xe9, 0x2f, 0xce, 0x68, 0x71, 0xe5, 0xa2, 0x92, 0x28, 0x53, 0xbf, 0x92, + 0xe1, 0x53, 0x53, 0x39, 0xa5, 0xb1, 0x23, 0x37, 0x60, 0x02, 0xdd, 0xc1, 0xd7, 0xa4, 0xb1, 0x9a, + 0x30, 0x9c, 0x41, 0xc7, 0x71, 0x6b, 0x5f, 0x37, 0x39, 0x8b, 0x50, 0xd9, 0x75, 0xa0, 0xe2, 0x1d, + 0x9a, 0xbd, 0x0e, 0xaa, 0xb4, 0x85, 0xbe, 0xa3, 0xe9, 0x1d, 0x5a, 0x5e, 0x4f, 0x8f, 0x17, 0x80, + 0x48, 0xe4, 0x6b, 0x30, 0x79, 0xd7, 0x7e, 0x14, 0xa6, 0x27, 0x9b, 0x1b, 0x3e, 0x09, 0x5a, 0xdb, + 0x7e, 0x14, 0xe6, 0x26, 0x8b, 0x27, 0x41, 0x53, 0x58, 0x92, 0xaf, 0x00, 0x28, 0x7a, 0x76, 0x72, + 0x62, 0x05, 0x2f, 0xca, 0x68, 0x89, 0xa9, 0xfa, 0x77, 0xe4, 0xaf, 0x30, 0x8c, 0x49, 0x0e, 0x0b, + 0x9f, 0x9c, 0xe4, 0x70, 0xe6, 0x93, 0x93, 0x1c, 0xf8, 0x33, 0x0f, 0x1f, 0x7b, 0xdc, 0xc1, 0x0f, + 0x85, 0x96, 0x7b, 0x50, 0x6d, 0xcf, 0x49, 0x53, 0x48, 0x3c, 0x0a, 0x0e, 0x63, 0x55, 0xc4, 0xf8, + 0x2d, 0xed, 0xc0, 0xf9, 0xbe, 0x8b, 0x33, 0x25, 0x1a, 0xf7, 0x55, 0x3d, 0x1a, 0xf7, 0xf9, 0x7e, + 0x87, 0xb8, 0xaf, 0xa7, 0x00, 0x9a, 0x2f, 0x2c, 0xf4, 0x97, 0x7f, 0xbe, 0x9d, 0x8d, 0x1d, 0xea, + 0xe2, 0xea, 0xc2, 0xd3, 0xcf, 0xf5, 0x93, 0x7a, 0xb2, 0x98, 0x1b, 0x9e, 0x1f, 0xfb, 0x4a, 0xc2, + 0x02, 0x76, 0xec, 0xab, 0x62, 0x03, 0x0a, 0x00, 0x8f, 0x7b, 0xbe, 0xbf, 0x03, 0x33, 0x3c, 0x9d, + 0xf3, 0x1d, 0x7a, 0xf8, 0xd0, 0xf5, 0x9a, 0x3c, 0xb1, 0x96, 0x90, 0xf2, 0x7d, 0x2c, 0xd1, 0x5d, + 0x5c, 0x55, 0x5c, 0x52, 0x91, 0x3e, 0xcc, 0xa3, 0x58, 0xfb, 0xf9, 0xd4, 0x7d, 0x92, 0x21, 0x0c, + 0x72, 0x6f, 0x26, 0x6f, 0x86, 0xa2, 0x20, 0xf5, 0xd4, 0x44, 0x40, 0x9e, 0x04, 0xa6, 0x48, 0x84, + 0xd4, 0x33, 0xfe, 0x55, 0x0e, 0x08, 0xaf, 0xa9, 0x6c, 0x77, 0x6d, 0xf4, 0xf0, 0x77, 0x30, 0x08, + 0x58, 0x41, 0xe0, 0xd8, 0x3b, 0x2d, 0xaa, 0x46, 0xd0, 0x13, 0xe6, 0xc7, 0x61, 0x99, 0x15, 0xbf, + 0x4a, 0x25, 0x08, 0xfb, 0x6c, 0xa6, 0xd9, 0xc7, 0xd9, 0x4c, 0xbf, 0x06, 0xcf, 0x96, 0xba, 0x98, + 0x17, 0x5e, 0xd6, 0x72, 0xd3, 0xf5, 0xe4, 0xd4, 0xd5, 0x7c, 0x47, 0xed, 0x10, 0x2d, 0xf1, 0xa5, + 0x83, 0x58, 0x28, 0x92, 0x10, 0x9b, 0x97, 0xdd, 0x40, 0x8d, 0x45, 0x22, 0x25, 0xa1, 0x2e, 0x96, + 0xa4, 0x48, 0x42, 0x9c, 0x44, 0xf2, 0x70, 0x3c, 0x29, 0x09, 0x61, 0x1a, 0xbd, 0x88, 0x87, 0xe3, + 0xd1, 0x3e, 0xd2, 0x54, 0x48, 0x42, 0xde, 0x81, 0xc9, 0x52, 0x2f, 0x70, 0x05, 0x63, 0x61, 0x37, + 0x1f, 0x59, 0xb8, 0x8b, 0x4f, 0xd1, 0x2e, 0x57, 0x11, 0xba, 0xf1, 0xc7, 0x39, 0x38, 0x9f, 0x1c, + 0x5e, 0x51, 0x1a, 0xae, 0x8f, 0xcc, 0x09, 0xeb, 0x23, 0x6d, 0x36, 0x64, 0xa3, 0x14, 0x28, 0x4f, + 0x62, 0x36, 0xf0, 0xf4, 0xf2, 0x1f, 0x73, 0x36, 0xd4, 0x61, 0x52, 0x3d, 0x51, 0x47, 0x3e, 0xee, + 0x89, 0xaa, 0x72, 0x21, 0x97, 0x61, 0x94, 0x87, 0x60, 0x19, 0x8d, 0x1e, 0xa7, 0xe2, 0xd1, 0x57, + 0x38, 0x06, 0xf9, 0xff, 0xc1, 0x05, 0xbe, 0x27, 0xc5, 0x1b, 0xbb, 0x72, 0x28, 0x39, 0x8a, 0x81, + 0x5b, 0x3e, 0x3e, 0x2a, 0x5e, 0xe1, 0xca, 0x18, 0x2b, 0xd1, 0x6d, 0xd6, 0xce, 0xa1, 0x25, 0xbf, + 0x4c, 0xa9, 0xe4, 0x44, 0xde, 0x46, 0x19, 0xce, 0x8b, 0xd2, 0xc8, 0xf9, 0x5f, 0x16, 0xb2, 0x41, + 0x3e, 0x88, 0xf4, 0x69, 0x38, 0xc8, 0x31, 0x55, 0x19, 0x96, 0x63, 0x62, 0x7a, 0x25, 0x69, 0xf8, + 0x1b, 0x69, 0x5e, 0x49, 0x3c, 0x9c, 0x3c, 0x07, 0xeb, 0x0e, 0x49, 0x52, 0x6b, 0x97, 0x4d, 0xd5, + 0xda, 0x49, 0xb5, 0x4f, 0x2e, 0x55, 0xed, 0x53, 0x81, 0xd9, 0x7a, 0x6f, 0x47, 0xd6, 0x1d, 0xf7, + 0xfb, 0xf5, 0x7b, 0x3b, 0x69, 0xbd, 0x12, 0x27, 0x31, 0x7e, 0x34, 0x0b, 0x53, 0xb5, 0x56, 0x6f, + 0xcf, 0xe9, 0x54, 0xec, 0xc0, 0x7e, 0x6a, 0x15, 0x89, 0x6f, 0x69, 0x8a, 0xc4, 0xd0, 0xf9, 0x2e, + 0x6c, 0xd8, 0x50, 0x5a, 0xc4, 0x9f, 0xcd, 0xc0, 0x6c, 0x44, 0xc2, 0x0f, 0xeb, 0x35, 0x18, 0x61, + 0x3f, 0xc4, 0xf5, 0xfa, 0x42, 0x82, 0x31, 0xcf, 0x7f, 0x1a, 0xfe, 0x25, 0x54, 0x7b, 0x7a, 0x72, + 0x41, 0xe4, 0xb0, 0xf4, 0x59, 0x98, 0x88, 0xd8, 0x9e, 0x26, 0xef, 0xe9, 0xaf, 0x67, 0xa0, 0x10, + 0x6f, 0x09, 0xb9, 0x03, 0xe3, 0x8c, 0x93, 0x43, 0xe5, 0xcd, 0xff, 0xe5, 0x3e, 0x6d, 0xbe, 0x22, + 0xd0, 0xf8, 0xe7, 0x61, 0xe7, 0x53, 0x0e, 0x31, 0x25, 0x87, 0x25, 0x13, 0xa6, 0x54, 0xac, 0x94, + 0xaf, 0x7b, 0x5d, 0x97, 0x50, 0xce, 0xa6, 0xf7, 0x83, 0x96, 0xad, 0x55, 0xfb, 0x6a, 0x21, 0x7c, + 0x5c, 0xd4, 0x26, 0x57, 0xea, 0xaa, 0xc2, 0x49, 0xb3, 0x1c, 0x25, 0xd2, 0x50, 0xe7, 0x59, 0xca, + 0x84, 0x0e, 0xf1, 0xc8, 0xeb, 0x30, 0xc6, 0xeb, 0x53, 0x33, 0x0d, 0x76, 0x11, 0xa2, 0x4a, 0xe2, + 0x1c, 0xc7, 0xf8, 0x5b, 0x39, 0x38, 0x1b, 0x7d, 0xde, 0x56, 0xb7, 0x69, 0x07, 0xb4, 0x66, 0x7b, + 0x76, 0xdb, 0x3f, 0x61, 0x05, 0x5c, 0x4a, 0x7c, 0x1a, 0xe6, 0x78, 0x93, 0x9f, 0xa6, 0x7c, 0x90, + 0x11, 0xfb, 0x20, 0xd4, 0xb2, 0xf2, 0x0f, 0x92, 0x9f, 0x41, 0xee, 0x40, 0xae, 0x4e, 0x03, 0xb1, + 0xf7, 0x5e, 0x4c, 0xf4, 0xaa, 0xfa, 0x5d, 0x57, 0xea, 0x34, 0xe0, 0x83, 0xc8, 0xe3, 0x8b, 0x69, + 0x51, 0x23, 0x19, 0x17, 0xb2, 0x0d, 0x63, 0xab, 0x8f, 0xba, 0xb4, 0x11, 0x88, 0xac, 0xbd, 0x97, + 0x07, 0xf3, 0xe3, 0xb8, 0x4a, 0xd2, 0x5e, 0x8a, 0x00, 0xb5, 0xb3, 0x38, 0xca, 0xd2, 0x0d, 0xc8, + 0xcb, 0xca, 0x4f, 0x33, 0x73, 0x97, 0xde, 0x82, 0x49, 0xa5, 0x92, 0x53, 0x4d, 0xfa, 0x5f, 0x64, + 0xfb, 0xaa, 0xdb, 0x92, 0x89, 0x7e, 0x57, 0x13, 0xb2, 0xa2, 0x92, 0x26, 0x8d, 0xcb, 0x8a, 0xd6, + 0x81, 0x28, 0x1a, 0x20, 0x34, 0x56, 0x61, 0xb6, 0x7e, 0xe0, 0x74, 0xa3, 0x08, 0xc6, 0xda, 0x89, + 0x8c, 0xa9, 0x98, 0x84, 0x6a, 0x20, 0x7e, 0x22, 0xc7, 0xe9, 0x8c, 0x3f, 0xcb, 0xc0, 0x18, 0xfb, + 0xeb, 0xfe, 0x8d, 0xa7, 0x74, 0xcb, 0xbc, 0xae, 0x6d, 0x99, 0x73, 0x4a, 0x12, 0x01, 0xdc, 0x38, + 0x6e, 0x9c, 0xb0, 0x59, 0x1e, 0x89, 0x01, 0xe2, 0xc8, 0xe4, 0x16, 0x8c, 0x0b, 0x93, 0x2b, 0x61, + 0x1d, 0xaf, 0x66, 0x25, 0x90, 0xc6, 0x58, 0xa1, 0x0e, 0xc1, 0xed, 0xc6, 0x95, 0x2e, 0x92, 0x9a, + 0xc9, 0xf5, 0x32, 0x96, 0xb4, 0x96, 0xc8, 0xdf, 0x45, 0x77, 0x46, 0x1e, 0x53, 0xdf, 0x5f, 0x39, + 0x27, 0x38, 0xf5, 0x8b, 0xd1, 0x50, 0x12, 0xef, 0x2d, 0xb9, 0x41, 0x4c, 0xce, 0xca, 0xec, 0xd9, + 0xa9, 0x4f, 0x31, 0x6d, 0x38, 0x5b, 0xaf, 0xaf, 0xa1, 0x79, 0x66, 0xcd, 0xf5, 0x82, 0x9b, 0xae, + 0xf7, 0xd0, 0x46, 0xeb, 0x6b, 0xd4, 0x21, 0x2a, 0x56, 0x0e, 0x69, 0x46, 0x73, 0xaf, 0xa6, 0x1a, + 0xcd, 0x0d, 0xb0, 0x84, 0x30, 0x3a, 0x70, 0xae, 0x5e, 0x5f, 0xe3, 0x11, 0xed, 0xff, 0x3c, 0xea, + 0xfb, 0xf5, 0x0c, 0xcc, 0xd5, 0xeb, 0x6b, 0xb1, 0xaa, 0xd6, 0x65, 0x28, 0xfd, 0x8c, 0x9e, 0x80, + 0x3e, 0xb5, 0x23, 0x70, 0x14, 0x32, 0x5c, 0xc2, 0x6b, 0x68, 0x41, 0x4e, 0x39, 0x13, 0x52, 0x0b, + 0x83, 0xf7, 0x67, 0x35, 0x8f, 0x89, 0x3e, 0x0d, 0x45, 0x1d, 0xba, 0xf0, 0x37, 0x64, 0xa5, 0xba, + 0x0e, 0x9d, 0x41, 0x8c, 0xff, 0xf6, 0x2c, 0x4f, 0x0f, 0x20, 0x67, 0xcb, 0xbb, 0x30, 0x25, 0xe8, + 0xd1, 0xad, 0x40, 0x58, 0x9d, 0x9c, 0x67, 0x1b, 0xe4, 0x2e, 0x87, 0xf3, 0xb0, 0xd1, 0xdf, 0x39, + 0x2a, 0x8e, 0xb0, 0xae, 0x31, 0x35, 0x74, 0x72, 0x0f, 0xa6, 0xef, 0xda, 0x8f, 0x14, 0x85, 0x09, + 0x77, 0x1a, 0xbb, 0xcc, 0x76, 0x95, 0xb6, 0xfd, 0x68, 0x08, 0xa3, 0x44, 0x9d, 0x9e, 0x1c, 0xc0, + 0x8c, 0xde, 0x26, 0x31, 0x03, 0x93, 0x23, 0x76, 0x2d, 0x75, 0xc4, 0xce, 0x77, 0x5d, 0x2f, 0xb0, + 0x76, 0x43, 0x72, 0x2d, 0x15, 0x46, 0x8c, 0x35, 0x79, 0x17, 0xe6, 0x94, 0x50, 0xb2, 0x37, 0x5d, + 0xaf, 0x6d, 0xcb, 0x0b, 0x17, 0xbe, 0x22, 0xa0, 0xb5, 0xd2, 0x2e, 0x82, 0xcd, 0x24, 0x26, 0xf9, + 0x52, 0x9a, 0x23, 0xde, 0x68, 0x64, 0x99, 0x99, 0xe2, 0x88, 0xd7, 0xcf, 0x32, 0x33, 0xe9, 0x92, + 0xb7, 0x37, 0xc8, 0x72, 0x3b, 0xcf, 0x5b, 0x3f, 0x94, 0x65, 0x76, 0x38, 0x72, 0x7d, 0x2c, 0xb4, + 0x97, 0x21, 0xb7, 0x52, 0xbb, 0x89, 0x6f, 0x5f, 0xd2, 0x4c, 0xab, 0xb3, 0x6f, 0x77, 0x1a, 0x78, + 0x11, 0x12, 0xfe, 0x12, 0xea, 0x41, 0xb9, 0x52, 0xbb, 0x49, 0x6c, 0x98, 0xc7, 0x04, 0x84, 0xc1, + 0x17, 0xaf, 0x5d, 0x53, 0x86, 0x2a, 0x8f, 0x9f, 0x76, 0x55, 0x7c, 0x5a, 0x11, 0xd3, 0x17, 0x06, + 0xd6, 0xa3, 0x6b, 0xd7, 0x52, 0x07, 0x24, 0xfc, 0xb0, 0x34, 0x5e, 0xec, 0xc0, 0xba, 0x6b, 0x3f, + 0x8a, 0xdc, 0x5c, 0x7c, 0xe1, 0xd2, 0xfc, 0xbc, 0x9c, 0x5a, 0x91, 0x8b, 0x8c, 0x76, 0x60, 0xe9, + 0x44, 0xec, 0x1e, 0x1b, 0x4d, 0x30, 0x5f, 0x38, 0x83, 0x2d, 0x49, 0x85, 0xa0, 0xf4, 0x7b, 0x57, + 0x2f, 0x63, 0x0a, 0x3a, 0xd9, 0x0a, 0x6f, 0xe3, 0xfc, 0x36, 0x2b, 0x52, 0x76, 0x5f, 0x55, 0x6f, + 0xe3, 0x5c, 0x0d, 0xa7, 0x35, 0x6b, 0x36, 0x54, 0xe1, 0x70, 0xbf, 0x1f, 0x53, 0xe7, 0x92, 0xbc, + 0xe4, 0x4f, 0x9d, 0xfe, 0x92, 0x4f, 0x61, 0x64, 0xdd, 0x6d, 0x1c, 0x88, 0x20, 0x8f, 0x1f, 0xb0, + 0x5d, 0xb8, 0xe5, 0x36, 0x0e, 0x9e, 0x9c, 0x45, 0x3a, 0xb2, 0x27, 0x1b, 0xec, 0x53, 0xd9, 0x2c, + 0x10, 0x7d, 0x22, 0xac, 0x9c, 0x17, 0xc2, 0x5b, 0xae, 0x52, 0xc6, 0xe5, 0x51, 0x3e, 0x69, 0x64, + 0xd7, 0x9a, 0x3a, 0x39, 0xa1, 0x50, 0xa8, 0x50, 0xff, 0x20, 0x70, 0xbb, 0xe5, 0x96, 0xd3, 0xdd, + 0x71, 0x6d, 0x4f, 0xc6, 0x18, 0x1f, 0x7a, 0x4f, 0x6e, 0x72, 0x7a, 0xab, 0x21, 0x19, 0x98, 0x09, + 0x96, 0xe4, 0x4b, 0x30, 0xc3, 0x26, 0xf7, 0xea, 0xa3, 0x80, 0x76, 0xf8, 0xc8, 0xcf, 0xa1, 0x44, + 0xb7, 0xa0, 0x24, 0xd5, 0x09, 0x0b, 0xf9, 0x9c, 0xc2, 0xc5, 0x4e, 0x43, 0x02, 0x2d, 0x40, 0xa6, + 0xc6, 0x8a, 0x34, 0x61, 0xf1, 0xae, 0xfd, 0x48, 0x49, 0x0e, 0xae, 0x4c, 0x52, 0x82, 0x13, 0xec, + 0xd2, 0xf1, 0x51, 0xf1, 0x65, 0x36, 0xc1, 0xa2, 0xb0, 0xf7, 0x7d, 0xe6, 0x6b, 0x5f, 0x4e, 0xe4, + 0x1b, 0x70, 0x4e, 0x34, 0xab, 0x82, 0x09, 0xed, 0x5c, 0xef, 0xb0, 0xbe, 0x6f, 0xa3, 0x87, 0xdb, + 0x7c, 0x9f, 0x0e, 0xbb, 0x9a, 0xbe, 0x25, 0xca, 0x0e, 0x6b, 0x4a, 0x3e, 0x96, 0xcf, 0x19, 0x99, + 0xfd, 0x6a, 0x20, 0x1f, 0xc1, 0x0c, 0x7f, 0xf0, 0x5b, 0x73, 0xfd, 0x00, 0x95, 0x35, 0x0b, 0xa7, + 0x73, 0xdb, 0xe0, 0xaf, 0x88, 0xdc, 0xd5, 0x29, 0xa6, 0xdc, 0x89, 0x71, 0x26, 0x6f, 0xc3, 0x64, + 0xcd, 0xe9, 0xf0, 0x10, 0xb6, 0xd5, 0x1a, 0x2a, 0xae, 0xc5, 0x09, 0xd4, 0x75, 0x3a, 0x96, 0xd4, + 0x98, 0x74, 0xc3, 0xed, 0x42, 0xc5, 0x26, 0xdb, 0x30, 0x59, 0xaf, 0xaf, 0xdd, 0x74, 0x98, 0x5c, + 0xd2, 0x95, 0x7a, 0xe8, 0xe4, 0x57, 0xbe, 0x94, 0xfa, 0x95, 0xd3, 0xbe, 0xbf, 0x6f, 0xed, 0x3a, + 0x2d, 0x6a, 0x35, 0xdc, 0xee, 0xa1, 0xa9, 0x72, 0x4a, 0x71, 0x65, 0x38, 0xf7, 0x84, 0x5d, 0x19, + 0xaa, 0x30, 0xab, 0x98, 0xe7, 0xa2, 0x69, 0xee, 0x62, 0x14, 0xf7, 0x4c, 0x75, 0x5d, 0x88, 0x3b, + 0xef, 0xc6, 0xe9, 0xa4, 0x0f, 0xc3, 0xf9, 0xd3, 0xfa, 0x30, 0x38, 0x30, 0xc7, 0x07, 0x43, 0xcc, + 0x03, 0x1c, 0xe9, 0xa5, 0x3e, 0x7d, 0x78, 0x39, 0xb5, 0x0f, 0xe7, 0xc5, 0x48, 0xcb, 0x49, 0x86, + 0x0f, 0xdc, 0x49, 0xae, 0x64, 0x17, 0x88, 0x00, 0xda, 0x81, 0xbd, 0x63, 0xfb, 0x14, 0xeb, 0x7a, + 0xb6, 0x4f, 0x5d, 0x2f, 0xa7, 0xd6, 0x35, 0x23, 0xeb, 0xda, 0xe1, 0xd5, 0xa4, 0x70, 0x24, 0x1d, + 0x59, 0x8f, 0x9c, 0x5f, 0xd8, 0xb1, 0xcf, 0x69, 0x3a, 0xee, 0x24, 0x02, 0x0f, 0x21, 0x16, 0x9f, + 0xb4, 0xf1, 0x7e, 0x4f, 0xe1, 0x4c, 0x1e, 0xc1, 0xd9, 0xe4, 0x57, 0x60, 0x9d, 0xcf, 0x63, 0x9d, + 0xcf, 0x6b, 0x75, 0xc6, 0x91, 0xf8, 0xbc, 0xd1, 0x9b, 0x15, 0xaf, 0xb5, 0x0f, 0x7f, 0xf2, 0xc3, + 0x19, 0x38, 0x77, 0xf7, 0x66, 0x09, 0xd3, 0xdc, 0x3a, 0x3c, 0xa2, 0x61, 0xe8, 0xf4, 0xfc, 0x82, + 0x78, 0x07, 0x89, 0xbf, 0xc7, 0x48, 0x89, 0x03, 0xb7, 0x0a, 0x26, 0xba, 0xbf, 0xd4, 0xde, 0xb5, + 0x79, 0xf6, 0x5c, 0xc1, 0x22, 0xc5, 0x33, 0xfa, 0x5b, 0x7f, 0x58, 0xcc, 0x98, 0xfd, 0xaa, 0x22, + 0x2d, 0x58, 0xd2, 0xbb, 0x45, 0x7a, 0x99, 0xec, 0xd3, 0x56, 0x6b, 0xb1, 0x88, 0x33, 0xfa, 0xf5, + 0xe3, 0xa3, 0xe2, 0xa5, 0x44, 0xef, 0x86, 0x9e, 0x2b, 0x0c, 0x53, 0x69, 0xf0, 0x00, 0x7e, 0xa4, + 0x9d, 0x22, 0x74, 0x2f, 0x5e, 0xd0, 0xa2, 0x23, 0x25, 0xca, 0x57, 0x5e, 0x11, 0x12, 0xc9, 0xf3, + 0x6c, 0xbd, 0xf7, 0x15, 0x10, 0xcd, 0x24, 0xe7, 0xdb, 0x23, 0xf9, 0xe9, 0xc2, 0x4c, 0x8a, 0xfb, + 0x85, 0xf1, 0x5b, 0xd9, 0xd8, 0xc1, 0x48, 0xaa, 0x30, 0x2e, 0xe6, 0x7b, 0xdf, 0x4b, 0xc6, 0xf3, + 0xa9, 0xb3, 0x7a, 0x5c, 0x2c, 0x1d, 0x53, 0xd2, 0x93, 0x87, 0x8c, 0x15, 0x36, 0x5a, 0xdc, 0x78, + 0xbf, 0xc2, 0xcf, 0x3d, 0x04, 0x69, 0x27, 0x7c, 0xe5, 0xf4, 0xae, 0x8a, 0xba, 0x27, 0x2c, 0x1e, + 0xf5, 0xb2, 0x36, 0x72, 0xc0, 0x73, 0x9c, 0xe5, 0x42, 0x6f, 0x37, 0x3d, 0xa1, 0xd9, 0x13, 0xab, + 0x90, 0xd5, 0x62, 0xfc, 0x66, 0x06, 0xa6, 0xb5, 0x93, 0x95, 0xdc, 0x50, 0x9c, 0x39, 0xa3, 0xf8, + 0x06, 0x1a, 0x0e, 0x6e, 0xb6, 0x71, 0x37, 0xcf, 0x1b, 0xc2, 0xb3, 0x21, 0xdb, 0x9f, 0x0e, 0x17, + 0x5b, 0xdc, 0xb7, 0x77, 0xb0, 0x7e, 0x38, 0x4c, 0xd0, 0x3a, 0xd2, 0x27, 0x41, 0xeb, 0xdf, 0x2f, + 0xc2, 0x8c, 0x7e, 0x23, 0x26, 0xaf, 0xc3, 0x18, 0xea, 0xe6, 0xa5, 0x7a, 0x05, 0xd5, 0x42, 0xa8, + 0xbe, 0xd7, 0xdc, 0x5d, 0x38, 0x0e, 0x79, 0x05, 0x20, 0x34, 0x31, 0x97, 0x2f, 0x53, 0xa3, 0xc7, + 0x47, 0xc5, 0xcc, 0x1b, 0xa6, 0x52, 0x40, 0xbe, 0x0a, 0xb0, 0xe1, 0x36, 0x69, 0x98, 0x75, 0x7b, + 0x80, 0x7d, 0xc7, 0xab, 0x89, 0xfc, 0x3f, 0x67, 0x3a, 0x6e, 0x93, 0x26, 0x93, 0xfd, 0x28, 0x1c, + 0xc9, 0xe7, 0x61, 0xd4, 0xec, 0xb5, 0xa8, 0x7c, 0xc1, 0x98, 0x94, 0x27, 0x5c, 0xaf, 0x45, 0x23, + 0x3d, 0x81, 0xd7, 0x8b, 0x9b, 0x2e, 0x32, 0x00, 0x79, 0x9f, 0xe7, 0x05, 0x12, 0xb1, 0x66, 0x47, + 0xa3, 0xb7, 0x3a, 0x45, 0xf2, 0x49, 0x44, 0x9b, 0x55, 0x48, 0xc8, 0x3d, 0x18, 0x57, 0x1f, 0x99, + 0x94, 0xa8, 0x00, 0xea, 0x43, 0xa4, 0xa2, 0x74, 0x10, 0x41, 0xf7, 0xe2, 0xef, 0x4f, 0x92, 0x0b, + 0x79, 0x07, 0x26, 0x18, 0x7b, 0xb6, 0x73, 0xf8, 0xe2, 0x56, 0x83, 0x2f, 0x72, 0xca, 0x07, 0xb1, + 0xdd, 0x47, 0x8b, 0x08, 0x1b, 0x12, 0x90, 0x2f, 0x61, 0x82, 0x65, 0xd1, 0xd5, 0x03, 0xed, 0x7e, + 0x2e, 0x26, 0xba, 0x1a, 0x33, 0x2e, 0x27, 0x7a, 0x3a, 0xe2, 0x47, 0xf6, 0xc2, 0xa0, 0x74, 0xc3, + 0xe4, 0x72, 0x7a, 0x2d, 0x51, 0xc1, 0xa2, 0x8c, 0xb3, 0x96, 0xcc, 0x9e, 0xae, 0xf1, 0x25, 0x5d, + 0x28, 0x44, 0x42, 0xa5, 0xa8, 0x0b, 0x06, 0xd5, 0xf5, 0x46, 0xa2, 0x2e, 0x75, 0x00, 0x13, 0xd5, + 0x25, 0xb8, 0x93, 0x26, 0xcc, 0xc8, 0x03, 0x4a, 0xd4, 0x37, 0x39, 0xa8, 0xbe, 0x57, 0x12, 0xf5, + 0xcd, 0x37, 0x77, 0x92, 0xf5, 0xc4, 0x78, 0x92, 0x77, 0x60, 0x5a, 0x42, 0x78, 0x2e, 0xf3, 0xa9, + 0x28, 0x19, 0x74, 0x73, 0x27, 0x91, 0xc1, 0x5c, 0x47, 0x56, 0xa9, 0xf9, 0xec, 0x98, 0xd6, 0xa8, + 0xe3, 0xb3, 0x42, 0x47, 0x26, 0x1f, 0xc2, 0x64, 0xb5, 0xcd, 0x1a, 0xe2, 0x76, 0xec, 0x80, 0x0a, + 0x7f, 0x51, 0x69, 0xc3, 0xa4, 0x94, 0x28, 0x53, 0x95, 0x67, 0x69, 0x8f, 0x8a, 0xb4, 0x2c, 0xed, + 0x11, 0x98, 0x75, 0x1e, 0x7f, 0x55, 0x14, 0x73, 0x58, 0xfa, 0x92, 0x3e, 0x9f, 0x62, 0x47, 0xa4, + 0xb0, 0x17, 0x71, 0x45, 0x19, 0x54, 0xbe, 0xea, 0xc5, 0x62, 0x3a, 0xab, 0x3c, 0xc9, 0xbb, 0x30, + 0x29, 0xd2, 0xdc, 0x95, 0xcc, 0x0d, 0x7f, 0xb1, 0x80, 0x8d, 0xc7, 0x18, 0x18, 0x32, 0x23, 0x9e, + 0x65, 0x7b, 0x31, 0x83, 0xd9, 0x08, 0x9f, 0x7c, 0x11, 0x16, 0xb6, 0x9d, 0x4e, 0xd3, 0x7d, 0xe8, + 0x8b, 0x63, 0x4a, 0x6c, 0x74, 0x73, 0x91, 0xbb, 0xda, 0x43, 0x5e, 0x1e, 0xca, 0x82, 0x89, 0x8d, + 0x2f, 0x95, 0x03, 0xf9, 0xbe, 0x04, 0x67, 0x3e, 0x83, 0xc8, 0xa0, 0x19, 0xb4, 0x9c, 0x98, 0x41, + 0xc9, 0xea, 0xe3, 0xd3, 0x29, 0xb5, 0x1a, 0xe2, 0x02, 0xd1, 0xcf, 0xf7, 0xdb, 0xae, 0xd3, 0x59, + 0x9c, 0xc7, 0xbd, 0xf0, 0xd9, 0x78, 0xd4, 0x09, 0xc4, 0x13, 0xd9, 0xee, 0x8d, 0xe3, 0xa3, 0xe2, + 0x0b, 0x71, 0x99, 0xff, 0x23, 0x57, 0x7b, 0x2e, 0x49, 0x61, 0x4d, 0x3e, 0x84, 0x29, 0xf6, 0x7f, + 0xa8, 0x94, 0x58, 0xd0, 0x2c, 0x4f, 0x15, 0x4c, 0x51, 0x0f, 0x8e, 0x11, 0xe6, 0xe1, 0x4b, 0xd1, + 0x57, 0x68, 0xac, 0xc8, 0x5b, 0x00, 0x4c, 0x6c, 0x12, 0xdb, 0xf1, 0x99, 0x28, 0x84, 0x36, 0x4a, + 0x5d, 0xc9, 0x8d, 0x38, 0x42, 0x26, 0xef, 0xc0, 0x24, 0xfb, 0x55, 0xef, 0x35, 0x5d, 0xb6, 0x36, + 0xce, 0x22, 0x2d, 0x77, 0xdd, 0x65, 0xb4, 0x3e, 0x87, 0x6b, 0xae, 0xbb, 0x11, 0x3a, 0x59, 0x83, + 0x59, 0x0c, 0x75, 0x2e, 0x82, 0xec, 0x3a, 0xd4, 0x5f, 0x3c, 0xa7, 0x58, 0x43, 0xb0, 0x22, 0xcb, + 0x09, 0xcb, 0xd4, 0xbb, 0x4c, 0x8c, 0x8c, 0xf8, 0x30, 0x9f, 0x7c, 0x4e, 0xf6, 0x17, 0x17, 0xb1, + 0x93, 0xa4, 0x04, 0x9f, 0xc4, 0xe0, 0xfb, 0x31, 0x1b, 0x11, 0x65, 0xe3, 0x92, 0x8f, 0x4a, 0x6a, + 0x85, 0x69, 0xdc, 0x89, 0x09, 0xe4, 0x56, 0xb9, 0x16, 0x8f, 0x05, 0x7e, 0x1e, 0x5b, 0x80, 0xc3, + 0xbc, 0xd7, 0x88, 0xd2, 0xdb, 0xa7, 0xc4, 0x03, 0x4f, 0xa1, 0x26, 0xdf, 0x0b, 0x67, 0xe4, 0x0e, + 0x22, 0x8a, 0xc4, 0xbc, 0x5e, 0x3a, 0xe5, 0x4e, 0xdc, 0xdc, 0x09, 0xab, 0x4e, 0x4c, 0xe9, 0xf4, + 0x2a, 0x88, 0x0d, 0x93, 0x38, 0xac, 0xa2, 0xc6, 0x67, 0x07, 0xd5, 0x78, 0x29, 0x51, 0xe3, 0x59, + 0x9c, 0x28, 0xc9, 0xca, 0x54, 0x9e, 0x64, 0x05, 0xa6, 0xc5, 0x3a, 0x12, 0xb3, 0xed, 0x39, 0xec, + 0x2d, 0x54, 0x62, 0xc9, 0x15, 0x98, 0x98, 0x70, 0x3a, 0x89, 0xba, 0x23, 0xf3, 0xc7, 0xa4, 0xe7, + 0xb5, 0x1d, 0x39, 0xfe, 0x86, 0xa4, 0x23, 0xb3, 0x1d, 0x29, 0x92, 0x62, 0x56, 0x1f, 0x75, 0x3d, + 0xa1, 0xa2, 0x7a, 0x21, 0xca, 0xae, 0xa5, 0x08, 0x3f, 0x16, 0x0d, 0x31, 0xd4, 0x2d, 0x21, 0x8d, + 0x03, 0xd9, 0x82, 0xf9, 0xf0, 0xd4, 0x56, 0x18, 0x17, 0xa3, 0x68, 0xd3, 0xd1, 0x51, 0x9f, 0xce, + 0x37, 0x8d, 0x9e, 0xd8, 0x70, 0x4e, 0x3b, 0xa7, 0x15, 0xd6, 0x17, 0x90, 0xf5, 0xab, 0xec, 0x46, + 0xa6, 0x1f, 0xf2, 0xe9, 0xec, 0xfb, 0xf1, 0x21, 0x1f, 0xc1, 0x52, 0xfc, 0x6c, 0x56, 0x6a, 0x79, + 0x11, 0x6b, 0x79, 0xed, 0xf8, 0xa8, 0x78, 0x31, 0x71, 0xbc, 0xa7, 0x57, 0x34, 0x80, 0x1b, 0xf9, + 0x2a, 0x2c, 0xea, 0xe7, 0xb3, 0x52, 0x93, 0x81, 0x35, 0xe1, 0xd2, 0x09, 0x0f, 0xf6, 0xf4, 0x1a, + 0xfa, 0xf2, 0x20, 0x01, 0x14, 0x53, 0x67, 0xb7, 0x52, 0xcd, 0x4b, 0x51, 0x83, 0x12, 0xab, 0x24, + 0xbd, 0xba, 0x93, 0x58, 0x92, 0x87, 0xf0, 0x42, 0xda, 0x31, 0xa1, 0x54, 0xfa, 0x72, 0xa8, 0x04, + 0xfe, 0x54, 0xfa, 0x91, 0x93, 0x5e, 0xf3, 0x09, 0x6c, 0xc9, 0x97, 0xe0, 0x8c, 0xb2, 0xbe, 0x94, + 0xfa, 0x5e, 0xc1, 0xfa, 0xd0, 0xd9, 0x5c, 0x5d, 0x98, 0xe9, 0xb5, 0xa4, 0xf3, 0x20, 0x6d, 0x98, + 0x97, 0x0d, 0x47, 0x6d, 0xbb, 0x38, 0x7a, 0x2e, 0x6a, 0xbb, 0x6a, 0x12, 0x63, 0xe5, 0x82, 0xd8, + 0x55, 0x17, 0x9b, 0x3b, 0x56, 0x37, 0x22, 0x54, 0x67, 0x7a, 0x0a, 0x5f, 0xb2, 0x06, 0x63, 0xf5, + 0x5a, 0xf5, 0xe6, 0xcd, 0xd5, 0xc5, 0x57, 0xb1, 0x06, 0xe9, 0x99, 0xc6, 0x81, 0xda, 0xa5, 0x49, + 0x98, 0x2b, 0x76, 0x9d, 0xdd, 0x5d, 0xed, 0xc1, 0x8a, 0xa3, 0x92, 0xef, 0x43, 0x43, 0x41, 0xb6, + 0xa3, 0x96, 0x7c, 0xdf, 0xd9, 0xeb, 0xf0, 0x38, 0xde, 0xaf, 0x69, 0xef, 0xfd, 0x32, 0xb2, 0x7b, + 0x19, 0x13, 0xdf, 0x25, 0xd0, 0xb9, 0xb4, 0xc9, 0xee, 0xff, 0x62, 0xe7, 0xb6, 0xec, 0x88, 0x95, + 0xba, 0x89, 0x27, 0x2b, 0x62, 0xfd, 0xb6, 0xe7, 0x04, 0xd6, 0x7e, 0x4f, 0x6b, 0xfe, 0xe2, 0xa7, + 0xb4, 0x18, 0xd5, 0x3c, 0x1d, 0xa0, 0xd2, 0x6b, 0x2f, 0x8b, 0x0a, 0x9f, 0xe3, 0xb7, 0xe5, 0x3e, + 0x3d, 0x37, 0xb7, 0x17, 0xa3, 0xf3, 0xc9, 0x0f, 0x65, 0xe0, 0xec, 0xb6, 0xeb, 0x1d, 0xb4, 0x5c, + 0xbb, 0x29, 0x5b, 0x25, 0xf6, 0xf0, 0xd7, 0x07, 0xed, 0xe1, 0x9f, 0x49, 0xec, 0xe1, 0xc6, 0x43, + 0xc1, 0xc6, 0x0a, 0x03, 0xe3, 0x27, 0xf6, 0xf3, 0x3e, 0x55, 0x91, 0xef, 0x83, 0x0b, 0xe9, 0x25, + 0xca, 0xa4, 0x7c, 0x03, 0x27, 0xe5, 0xb5, 0xe3, 0xa3, 0xe2, 0x1b, 0xfd, 0x6a, 0x4a, 0x9f, 0xa0, + 0x27, 0xb2, 0xbe, 0x3d, 0x92, 0xbf, 0x54, 0xb8, 0x7c, 0x7b, 0x24, 0x7f, 0xb9, 0xf0, 0x9a, 0xf9, + 0x5c, 0xbd, 0x74, 0x77, 0xbd, 0xda, 0x94, 0x87, 0xab, 0x8c, 0xdd, 0xcf, 0x69, 0xcc, 0x8b, 0x83, + 0x4a, 0x23, 0x8e, 0xc6, 0xdf, 0xc8, 0x40, 0xf1, 0x84, 0x49, 0xc2, 0xce, 0xb3, 0x68, 0x24, 0xea, + 0x34, 0x50, 0x33, 0x00, 0x44, 0xe3, 0x67, 0xe9, 0x66, 0x23, 0x3a, 0x09, 0xba, 0x35, 0x8a, 0xb4, + 0x33, 0x8a, 0x77, 0x6b, 0x32, 0xdd, 0x8c, 0xc4, 0x32, 0xd6, 0xa1, 0x10, 0x9f, 0x3c, 0xe4, 0x73, + 0x30, 0xad, 0x26, 0xbd, 0x90, 0xaa, 0x04, 0x1e, 0x88, 0xc5, 0xdb, 0xd3, 0x0e, 0x44, 0x0d, 0xd1, + 0xf8, 0xc5, 0x0c, 0xcc, 0xa7, 0xac, 0x30, 0x72, 0x11, 0x46, 0x30, 0x2b, 0x9d, 0x62, 0x35, 0x14, + 0xcb, 0x46, 0x87, 0xe5, 0xe4, 0xd3, 0x30, 0x5e, 0xd9, 0xa8, 0xd7, 0x4b, 0x1b, 0x52, 0x19, 0xc1, + 0x0f, 0xe2, 0x8e, 0x6f, 0xf9, 0xb6, 0x6e, 0x6c, 0x20, 0xd0, 0xc8, 0x1b, 0x30, 0x56, 0xad, 0x21, + 0x81, 0x12, 0x11, 0xdf, 0xe9, 0xc6, 0xf1, 0x05, 0x92, 0xf1, 0xe3, 0x19, 0x20, 0xc9, 0xed, 0x82, + 0x5c, 0x83, 0x49, 0x75, 0x53, 0xe2, 0xed, 0xc5, 0x17, 0x58, 0x65, 0xe1, 0x98, 0x2a, 0x0e, 0xa9, + 0xc0, 0x28, 0x26, 0x28, 0x0e, 0xad, 0x1c, 0x52, 0x97, 0xc5, 0xb9, 0xc4, 0xb2, 0x18, 0xc5, 0xf4, + 0xc7, 0x26, 0x27, 0x36, 0x7e, 0x27, 0x03, 0x24, 0xdd, 0x76, 0x71, 0x28, 0x2b, 0xab, 0x37, 0x95, + 0xe8, 0x08, 0x6a, 0xde, 0xa9, 0x30, 0x69, 0xa0, 0xaa, 0x06, 0x88, 0xe2, 0x28, 0x5c, 0xd4, 0xd4, + 0x4e, 0xfd, 0x5d, 0x6a, 0x2f, 0xc3, 0xe8, 0x7d, 0xea, 0xed, 0x48, 0xb3, 0x6e, 0x34, 0x05, 0x7d, + 0xc0, 0x00, 0xaa, 0x1a, 0x06, 0x31, 0x8c, 0x3f, 0xce, 0xc0, 0x42, 0xda, 0x1d, 0xe5, 0x04, 0xcf, + 0x57, 0x23, 0xe6, 0xb4, 0x8b, 0x16, 0x56, 0xdc, 0x4e, 0x34, 0x74, 0xd5, 0x2d, 0xc2, 0x28, 0x6b, + 0xac, 0x1c, 0x61, 0x54, 0x83, 0xb1, 0xde, 0xf0, 0x4d, 0x0e, 0x67, 0x08, 0x3c, 0x8a, 0xe1, 0x08, + 0x06, 0xc0, 0x44, 0x04, 0x9c, 0xdd, 0x26, 0x87, 0x33, 0x84, 0xbb, 0x6e, 0x93, 0x4a, 0xf5, 0x10, + 0x22, 0xb4, 0x19, 0xc0, 0xe4, 0x70, 0x72, 0x11, 0xc6, 0xef, 0x75, 0xd6, 0xa9, 0xfd, 0x40, 0xe6, + 0x3e, 0x41, 0x8b, 0x30, 0xb7, 0x63, 0xb5, 0x18, 0xcc, 0x94, 0x85, 0xc6, 0xcf, 0x66, 0x60, 0x2e, + 0x71, 0x3d, 0x3a, 0xd9, 0xb9, 0x77, 0xb0, 0x97, 0xdd, 0x30, 0xed, 0xe3, 0x9f, 0x3f, 0x92, 0xfe, + 0xf9, 0xc6, 0x7f, 0x3f, 0x06, 0xe7, 0xfa, 0x68, 0xab, 0x22, 0x2f, 0xe0, 0xcc, 0x89, 0x5e, 0xc0, + 0x5f, 0x86, 0xe9, 0x72, 0xcb, 0x76, 0xda, 0xfe, 0xa6, 0x1b, 0x7d, 0x71, 0xe4, 0x4c, 0x84, 0x65, + 0xc2, 0x0f, 0x22, 0xf4, 0x3a, 0x39, 0xdf, 0x40, 0x0a, 0x2b, 0x70, 0x93, 0xc2, 0xb2, 0xc6, 0x2c, + 0xe1, 0x87, 0x9b, 0xfb, 0x0b, 0xe2, 0x87, 0xab, 0x7b, 0x86, 0x8d, 0x3c, 0x51, 0xcf, 0xb0, 0x74, + 0x9b, 0xef, 0xd1, 0xc7, 0xf1, 0x00, 0x28, 0xc3, 0x34, 0x37, 0x89, 0x2b, 0xf9, 0x7c, 0x90, 0xc6, + 0x12, 0x66, 0x74, 0xb6, 0x9f, 0x1c, 0x0b, 0x8d, 0x86, 0xac, 0xe9, 0x5e, 0x4c, 0xe3, 0xf8, 0x66, + 0x7c, 0xb1, 0xbf, 0x97, 0x92, 0x66, 0x2b, 0xa2, 0x79, 0x2b, 0x7d, 0x03, 0x16, 0xd2, 0xae, 0xbb, + 0x8b, 0x79, 0xcd, 0xda, 0xb6, 0xaf, 0x95, 0xf6, 0xf0, 0x97, 0xe6, 0x83, 0xd4, 0x4b, 0xb3, 0xf4, + 0x2e, 0x9f, 0xd0, 0x82, 0x5e, 0xf7, 0x59, 0x0b, 0x1c, 0x77, 0xb0, 0x0f, 0xba, 0xf1, 0x65, 0x78, + 0x7e, 0x20, 0x39, 0x79, 0x5b, 0x8b, 0x62, 0xf4, 0x6a, 0x32, 0x8a, 0xd1, 0x77, 0x8e, 0x8a, 0x73, + 0x9a, 0x67, 0xe8, 0xdd, 0x50, 0xe1, 0x6f, 0xfc, 0x6c, 0x56, 0xf7, 0x69, 0xfe, 0x8b, 0xb8, 0x50, + 0x2f, 0xc3, 0xe8, 0xf6, 0x3e, 0xf5, 0xe4, 0xf1, 0x80, 0x1f, 0xf2, 0x90, 0x01, 0xd4, 0x0f, 0x41, + 0x0c, 0x72, 0x13, 0x66, 0x6a, 0x7c, 0xe2, 0xca, 0xd9, 0x38, 0x12, 0xe9, 0x5c, 0xba, 0x42, 0x33, + 0x98, 0x32, 0x1d, 0x63, 0x54, 0xc6, 0xad, 0x58, 0xa7, 0x8b, 0x18, 0x4c, 0xdc, 0x33, 0x8a, 0x0b, + 0x10, 0x33, 0x91, 0xb7, 0x59, 0xb4, 0xd9, 0x9a, 0x31, 0xa8, 0xb1, 0x0b, 0x2f, 0x0c, 0x64, 0xc4, + 0xce, 0x6d, 0xe8, 0x86, 0xbf, 0x62, 0x96, 0xd7, 0x03, 0x49, 0x4d, 0x85, 0xce, 0xf8, 0x06, 0x4c, + 0xa9, 0xbd, 0x8c, 0x47, 0x10, 0xfb, 0x2d, 0x66, 0x05, 0x3f, 0x82, 0x18, 0xc0, 0xe4, 0xf0, 0xe8, + 0x2d, 0x27, 0x9b, 0xfe, 0x96, 0x13, 0x0d, 0x7f, 0xee, 0xa4, 0xe1, 0x67, 0x95, 0xe3, 0x0e, 0xa7, + 0x54, 0x8e, 0xbf, 0xd5, 0xca, 0x31, 0xc8, 0x92, 0xc9, 0xe1, 0x4f, 0xb4, 0xf2, 0x7f, 0x2a, 0xd3, + 0x20, 0xa1, 0xe3, 0x95, 0x5c, 0xee, 0x99, 0x28, 0xe3, 0x5d, 0xda, 0xea, 0x8d, 0x30, 0x23, 0x99, + 0x22, 0x7b, 0x92, 0x4c, 0x71, 0x9a, 0x89, 0x88, 0x72, 0x2f, 0x1f, 0xd2, 0x91, 0x48, 0x0e, 0xb4, + 0x13, 0xd6, 0x2e, 0x12, 0xcb, 0xf8, 0x56, 0x06, 0xce, 0xa4, 0xea, 0xcc, 0x59, 0xad, 0x5c, 0x39, + 0xaf, 0xac, 0xc3, 0xb8, 0x66, 0x9e, 0x63, 0x9c, 0x26, 0xc2, 0xc6, 0xf0, 0x6d, 0x31, 0x5e, 0x84, + 0x89, 0xf0, 0xc5, 0x96, 0x2c, 0xc8, 0xa1, 0xe3, 0x21, 0xf4, 0xc4, 0xc3, 0x5f, 0x1d, 0x80, 0x7d, + 0xc1, 0x13, 0x35, 0xad, 0x36, 0xfe, 0x69, 0x96, 0x27, 0x52, 0x7e, 0x6a, 0x83, 0xfd, 0xa6, 0xdb, + 0x43, 0xb3, 0x26, 0xf5, 0x0f, 0xf1, 0x4b, 0x56, 0x61, 0xac, 0x1e, 0xd8, 0x41, 0x4f, 0x06, 0x06, + 0x99, 0x57, 0xc9, 0xb0, 0xe0, 0xfe, 0x72, 0x14, 0x1a, 0xc2, 0x47, 0x88, 0xa6, 0x25, 0x40, 0x88, + 0x62, 0x56, 0xfd, 0xfb, 0x19, 0x98, 0x52, 0x89, 0xc9, 0x87, 0x30, 0x23, 0x03, 0x98, 0xf2, 0x70, + 0x29, 0xe2, 0x79, 0x59, 0x9a, 0x82, 0xc9, 0x00, 0xa6, 0x6a, 0x78, 0x15, 0x0d, 0x5f, 0xdd, 0xaa, + 0xbb, 0x2a, 0x32, 0x69, 0x02, 0x69, 0xef, 0xda, 0xd6, 0x43, 0x6a, 0x1f, 0x50, 0x3f, 0xb0, 0xb8, + 0xc9, 0x8e, 0x78, 0x85, 0x96, 0xec, 0xef, 0xde, 0x2c, 0x71, 0x6b, 0x1d, 0x36, 0x12, 0x22, 0x12, + 0x6d, 0x82, 0x46, 0x7d, 0x5a, 0x6b, 0xef, 0xda, 0xdb, 0xbc, 0x90, 0xd3, 0x19, 0x7f, 0x32, 0xc6, + 0xa7, 0x9b, 0x88, 0x78, 0xbc, 0x03, 0x33, 0xf7, 0xaa, 0x95, 0xb2, 0xa2, 0x68, 0xd7, 0x13, 0x66, + 0xad, 0x3e, 0x0a, 0xa8, 0xd7, 0xb1, 0x5b, 0xf2, 0xbe, 0x1b, 0x1d, 0x41, 0xae, 0xd3, 0x6c, 0xa4, + 0x2b, 0xe1, 0x63, 0x1c, 0x59, 0x1d, 0xfc, 0x66, 0x1d, 0xd6, 0x91, 0x1d, 0xb2, 0x0e, 0xdf, 0x6e, + 0xb7, 0xfa, 0xd4, 0xa1, 0x73, 0x24, 0xfb, 0x78, 0xf5, 0xdd, 0xef, 0xed, 0x28, 0xb5, 0xe4, 0x06, + 0xd7, 0xf2, 0x92, 0xa8, 0xe5, 0x59, 0xa1, 0x56, 0x49, 0xad, 0x27, 0xc1, 0x35, 0xda, 0x27, 0x46, + 0x4e, 0xdc, 0x27, 0xfe, 0x5a, 0x06, 0xc6, 0xb8, 0xf8, 0x2a, 0xa6, 0x71, 0x1f, 0x01, 0x79, 0xfb, + 0xc9, 0x08, 0xc8, 0x05, 0x3c, 0x27, 0xb4, 0x09, 0xcd, 0xcb, 0x48, 0x25, 0xb6, 0x2e, 0xa4, 0x37, + 0x00, 0x3e, 0x99, 0xf1, 0x92, 0x93, 0x97, 0x05, 0xa9, 0x46, 0xc1, 0x3a, 0xc6, 0x4f, 0xf4, 0xd0, + 0x96, 0x01, 0x4e, 0xc6, 0x45, 0xb0, 0x0e, 0x3d, 0x44, 0xc7, 0x3a, 0x4c, 0x88, 0x10, 0x20, 0x2b, + 0x87, 0xe2, 0x61, 0xbc, 0xa0, 0x99, 0x36, 0x35, 0x57, 0x0e, 0x23, 0xd1, 0x5c, 0x04, 0x11, 0xb1, + 0x76, 0x0e, 0xb5, 0xbc, 0xd4, 0x12, 0x91, 0xdc, 0xe3, 0xf9, 0x5a, 0x79, 0x44, 0x68, 0x3d, 0x09, + 0x44, 0x08, 0x17, 0xc1, 0xc5, 0x64, 0x1c, 0x81, 0x94, 0x00, 0xd0, 0x11, 0x0f, 0xb2, 0x0e, 0x05, + 0x34, 0x87, 0xa3, 0x4d, 0xbe, 0x6a, 0xaa, 0x15, 0x1e, 0x66, 0x42, 0x98, 0x34, 0x07, 0xbc, 0x4c, + 0x2c, 0xb7, 0x98, 0xff, 0x65, 0x82, 0xd2, 0xf8, 0x99, 0x2c, 0x14, 0xe2, 0xb3, 0x8f, 0xbc, 0x03, + 0x93, 0x61, 0x44, 0xee, 0xd0, 0x03, 0x1c, 0x1f, 0xc8, 0xa2, 0x10, 0xde, 0x7a, 0x96, 0x4f, 0x05, + 0x9d, 0x2c, 0x43, 0x9e, 0x2d, 0xe2, 0x78, 0x46, 0xec, 0x9e, 0x80, 0xa9, 0x1e, 0x59, 0x12, 0x8f, + 0xd4, 0x61, 0x9e, 0x2d, 0x9a, 0xba, 0xd3, 0xd9, 0x6b, 0xd1, 0x75, 0x77, 0xcf, 0xed, 0x05, 0x51, + 0xd2, 0x4b, 0x7e, 0x81, 0xb1, 0xdb, 0x2d, 0xad, 0x58, 0x4f, 0x79, 0x99, 0x42, 0xad, 0xe4, 0xeb, + 0x1f, 0x19, 0x22, 0x5f, 0xbf, 0xb2, 0xb3, 0xfe, 0x61, 0x16, 0x26, 0x95, 0xe9, 0x47, 0x2e, 0x43, + 0xbe, 0xea, 0xaf, 0xbb, 0x8d, 0x83, 0x30, 0x58, 0xe5, 0xf4, 0xf1, 0x51, 0x71, 0xc2, 0xf1, 0xad, + 0x16, 0x02, 0xcd, 0xb0, 0x98, 0xac, 0xc0, 0x34, 0xff, 0x4b, 0xa6, 0x56, 0xc9, 0x46, 0xba, 0x35, + 0x8e, 0x2c, 0x93, 0xaa, 0xa8, 0x9b, 0xad, 0x46, 0x42, 0xbe, 0x02, 0xc0, 0x01, 0x18, 0xde, 0x20, + 0x37, 0x7c, 0x60, 0x06, 0x51, 0x41, 0x4a, 0x60, 0x03, 0x85, 0x21, 0xf9, 0x1a, 0x0f, 0xf8, 0x2d, + 0x97, 0xcb, 0xc8, 0xf0, 0x91, 0x25, 0x18, 0x7f, 0x2b, 0x3d, 0xc0, 0x8d, 0xca, 0x52, 0x64, 0x43, + 0x5a, 0x32, 0x69, 0xc3, 0x7d, 0x40, 0xbd, 0xc3, 0x52, 0x80, 0x88, 0x0a, 0x86, 0xf1, 0xbf, 0x64, + 0x94, 0x45, 0x46, 0x36, 0x30, 0xe7, 0x3b, 0x9f, 0x40, 0xc2, 0xa4, 0x2c, 0xbc, 0x62, 0x48, 0xb8, + 0x49, 0x77, 0x57, 0x9e, 0x15, 0xd6, 0x6d, 0xf3, 0xe1, 0x34, 0x8c, 0xe5, 0x82, 0xe7, 0x40, 0xf2, + 0x05, 0x18, 0xc1, 0xae, 0xcb, 0x9e, 0xd8, 0x34, 0x79, 0xca, 0x8f, 0xb0, 0x3e, 0xc3, 0x86, 0x20, + 0x25, 0xf9, 0xb4, 0x70, 0xdc, 0xe6, 0x9d, 0x3f, 0xa3, 0x1c, 0xd5, 0xec, 0x3b, 0xc2, 0xe3, 0x3d, + 0x8a, 0x71, 0xa4, 0xcc, 0x9e, 0xbf, 0x91, 0x85, 0x42, 0x7c, 0x69, 0x93, 0xf7, 0x61, 0x4a, 0x1e, + 0xbf, 0x6b, 0xb6, 0xc8, 0x0b, 0x32, 0x25, 0xf2, 0x72, 0xc8, 0x33, 0x78, 0xdf, 0x56, 0x4d, 0xd0, + 0x4c, 0x8d, 0x80, 0xc9, 0x42, 0x9b, 0x22, 0xe6, 0xa0, 0xb2, 0xa8, 0x02, 0x37, 0xe8, 0xc6, 0xe2, + 0x4c, 0x4b, 0x34, 0xf2, 0x26, 0xe4, 0xee, 0xde, 0x2c, 0x09, 0x07, 0xbf, 0x42, 0xfc, 0x90, 0xe6, + 0x96, 0xb2, 0xba, 0xdd, 0x2e, 0xc3, 0x27, 0xeb, 0x4a, 0x48, 0xf6, 0x31, 0xcd, 0xdc, 0x50, 0x82, + 0xc3, 0xc6, 0x9d, 0x1c, 0x9b, 0xfd, 0xf6, 0x48, 0x3e, 0x57, 0x18, 0x11, 0x61, 0x7a, 0xff, 0x45, + 0x0e, 0x26, 0xc2, 0xfa, 0x09, 0x51, 0xdd, 0xa6, 0xb9, 0x8b, 0x34, 0x39, 0x0f, 0x79, 0x29, 0xdd, + 0x09, 0x3f, 0xbf, 0x71, 0x5f, 0x48, 0x76, 0x8b, 0x20, 0xc5, 0x38, 0xbe, 0x2b, 0x98, 0xf2, 0x27, + 0xb9, 0x06, 0xa1, 0x8c, 0xd6, 0x4f, 0x98, 0x1b, 0x61, 0x03, 0x66, 0x86, 0x68, 0x64, 0x06, 0xb2, + 0x0e, 0x0f, 0xfd, 0x36, 0x61, 0x66, 0x9d, 0x26, 0x79, 0x1f, 0xf2, 0x76, 0xb3, 0x49, 0x9b, 0x96, + 0x2d, 0x6d, 0xb3, 0x06, 0x4d, 0x9a, 0x3c, 0xe3, 0xc6, 0xcf, 0x0c, 0xa4, 0x2a, 0x05, 0xa4, 0x04, + 0x13, 0x3c, 0x96, 0xb4, 0x4f, 0x9b, 0x43, 0x1c, 0x40, 0x11, 0x07, 0x0c, 0x41, 0xbd, 0xe5, 0xd3, + 0x26, 0x79, 0x15, 0x46, 0xd8, 0x68, 0x8a, 0x13, 0x47, 0x0a, 0x95, 0x6c, 0x30, 0x79, 0x87, 0xad, + 0x3d, 0x63, 0x22, 0x02, 0x79, 0x19, 0x72, 0xbd, 0xe5, 0x5d, 0x71, 0x96, 0x14, 0xa2, 0xf4, 0x08, + 0x21, 0x1a, 0x2b, 0x26, 0xd7, 0x21, 0xff, 0x50, 0x8f, 0xac, 0x7f, 0x26, 0x36, 0x8c, 0x21, 0x7e, + 0x88, 0x48, 0x5e, 0x85, 0x9c, 0xef, 0xbb, 0xc2, 0xa0, 0x69, 0x3e, 0xb4, 0x32, 0xbd, 0x17, 0x8e, + 0x1a, 0xe3, 0xee, 0xfb, 0xee, 0x4a, 0x1e, 0xc6, 0xf8, 0x01, 0x63, 0xbc, 0x00, 0x10, 0x7d, 0x63, + 0xd2, 0x6f, 0xd3, 0xf8, 0x0a, 0x4c, 0x84, 0xdf, 0x46, 0x9e, 0x07, 0x38, 0xa0, 0x87, 0xd6, 0xbe, + 0xdd, 0x69, 0xb6, 0xb8, 0x74, 0x3a, 0x65, 0x4e, 0x1c, 0xd0, 0xc3, 0x35, 0x04, 0x90, 0x73, 0x30, + 0xde, 0x65, 0xc3, 0x2f, 0xe6, 0xf8, 0x94, 0x39, 0xd6, 0xed, 0xed, 0xb0, 0xa9, 0xbc, 0x08, 0xe3, + 0xa8, 0x67, 0x15, 0x2b, 0x72, 0xda, 0x94, 0x3f, 0x8d, 0x3f, 0xcd, 0x61, 0x02, 0x2a, 0xa5, 0x41, + 0xe4, 0x25, 0x98, 0x6e, 0x78, 0x14, 0xcf, 0x32, 0x9b, 0x49, 0x68, 0xa2, 0x9e, 0xa9, 0x08, 0x58, + 0x6d, 0x92, 0x8b, 0x30, 0xdb, 0xed, 0xed, 0xb4, 0x9c, 0x06, 0xab, 0xcd, 0x6a, 0xec, 0x88, 0x8c, + 0x19, 0x53, 0xe6, 0x34, 0x07, 0xdf, 0xa1, 0x87, 0xe5, 0x1d, 0x8c, 0x6d, 0x58, 0x50, 0x43, 0x53, + 0xb3, 0x1e, 0x11, 0xf3, 0x6f, 0x56, 0x81, 0xa3, 0x6d, 0xe6, 0x59, 0x18, 0xb3, 0xed, 0xbd, 0x9e, + 0xc3, 0x63, 0x90, 0x4d, 0x99, 0xe2, 0x17, 0xf9, 0x14, 0xcc, 0x45, 0xb1, 0xde, 0x65, 0x33, 0x46, + 0xb1, 0x19, 0x85, 0xb0, 0xa0, 0xcc, 0xe1, 0xe4, 0x0d, 0x20, 0x6a, 0x7d, 0xee, 0xce, 0x47, 0xb4, + 0xc1, 0xe7, 0xe4, 0x94, 0x39, 0xa7, 0x94, 0xdc, 0xc3, 0x02, 0xf2, 0x22, 0x4c, 0x79, 0xd4, 0x47, + 0xe9, 0x10, 0xbb, 0x0d, 0xf3, 0x33, 0x9a, 0x93, 0x12, 0xc6, 0xfa, 0xee, 0x12, 0x14, 0x94, 0xee, + 0xc0, 0xe8, 0xdf, 0x3c, 0x59, 0x84, 0x39, 0x13, 0xc1, 0xcd, 0x6e, 0xb5, 0x49, 0xbe, 0x08, 0x4b, + 0x0a, 0x26, 0x4f, 0x15, 0x69, 0xd1, 0x96, 0xb3, 0xe7, 0xec, 0xb4, 0xa8, 0x98, 0x6f, 0xc9, 0x59, + 0x1d, 0x5e, 0x21, 0xcd, 0xc5, 0x88, 0x9a, 0x27, 0x91, 0x5c, 0x15, 0xb4, 0x64, 0x1d, 0x16, 0x62, + 0x9c, 0x69, 0xd3, 0xea, 0x75, 0xfb, 0x06, 0xfd, 0x8b, 0x78, 0x12, 0x9d, 0x27, 0x6d, 0x6e, 0x75, + 0x8d, 0x6f, 0xc0, 0x94, 0x3a, 0x27, 0x59, 0x27, 0xa8, 0x72, 0x89, 0x98, 0x7d, 0x93, 0x21, 0xac, + 0xca, 0xee, 0x85, 0x33, 0x11, 0x0a, 0x0e, 0x22, 0xdf, 0x5e, 0xa6, 0x43, 0x28, 0x0e, 0xe1, 0x8b, + 0x30, 0xd5, 0x74, 0xfc, 0x6e, 0xcb, 0x3e, 0xb4, 0xa2, 0x4c, 0xf1, 0xe6, 0xa4, 0x80, 0xa1, 0xe2, + 0x67, 0x05, 0xe6, 0x12, 0xfb, 0xa0, 0x22, 0x69, 0xf0, 0x7d, 0x7d, 0xb0, 0xa4, 0x61, 0x74, 0x60, + 0x4a, 0x3d, 0xd7, 0x4e, 0x48, 0xed, 0x72, 0x16, 0xc3, 0xf0, 0xf0, 0x4d, 0x7f, 0xec, 0xf8, 0xa8, + 0x98, 0x75, 0x9a, 0x18, 0x7c, 0xe7, 0x12, 0xe4, 0xa5, 0xc4, 0x26, 0x04, 0x25, 0x7c, 0x4c, 0x90, + 0x4f, 0x93, 0x66, 0x58, 0x6a, 0xbc, 0x0a, 0xe3, 0xe2, 0xe8, 0x1a, 0xfc, 0x84, 0x60, 0x7c, 0x33, + 0x0b, 0xb3, 0x26, 0x65, 0x1b, 0x2b, 0xe5, 0xf9, 0x9c, 0x9e, 0xda, 0x2b, 0x7a, 0x7a, 0xb8, 0x58, + 0xad, 0x6d, 0x03, 0x32, 0x29, 0xfd, 0x4a, 0x06, 0xe6, 0x53, 0x70, 0x3f, 0x56, 0x26, 0xe1, 0x1b, + 0x30, 0x51, 0x71, 0xec, 0x56, 0xa9, 0xd9, 0x0c, 0x63, 0xf2, 0xa0, 0x9c, 0x8f, 0xe9, 0xc6, 0x6c, + 0x06, 0x55, 0x85, 0x98, 0x10, 0x95, 0xbc, 0x26, 0x26, 0x45, 0x2e, 0xec, 0x56, 0x9c, 0x14, 0xdf, + 0x39, 0x2a, 0x02, 0xff, 0xa6, 0xcd, 0x70, 0x8a, 0x60, 0x08, 0x67, 0x0e, 0x8c, 0xfc, 0xaa, 0x9e, + 0xda, 0xa1, 0x4b, 0x0f, 0xe1, 0x1c, 0x6f, 0xde, 0x50, 0xc9, 0x94, 0x7e, 0x22, 0x0b, 0x67, 0xd3, + 0x09, 0x3f, 0x6e, 0x52, 0x68, 0x4c, 0x63, 0xa5, 0x84, 0x9d, 0xc7, 0xa4, 0xd0, 0x3c, 0xe7, 0x15, + 0xe2, 0x47, 0x08, 0x64, 0x17, 0xa6, 0xd7, 0x6d, 0x3f, 0x58, 0xa3, 0xb6, 0x17, 0xec, 0x50, 0x3b, + 0x18, 0x42, 0x92, 0x97, 0xd6, 0x14, 0x8b, 0x28, 0x4c, 0xec, 0x4b, 0xca, 0x98, 0xac, 0xad, 0xb3, + 0x0d, 0x27, 0xca, 0xc8, 0x10, 0x13, 0xe5, 0xeb, 0x30, 0x5b, 0xa7, 0x6d, 0xbb, 0xbb, 0xef, 0x7a, + 0x32, 0x5e, 0xc2, 0x15, 0x98, 0x0e, 0x41, 0xa9, 0xb3, 0x45, 0x2f, 0xd6, 0xf0, 0x95, 0x8e, 0x88, + 0xb6, 0x12, 0xbd, 0xd8, 0xf8, 0x9b, 0x59, 0x38, 0x57, 0x6a, 0x08, 0xd3, 0x50, 0x51, 0x20, 0x2d, + 0xd8, 0x3f, 0xe1, 0xba, 0xc9, 0x55, 0x98, 0xb8, 0x6b, 0x3f, 0x5a, 0xa7, 0xb6, 0x4f, 0x7d, 0x91, + 0x92, 0x93, 0x8b, 0xbd, 0xf6, 0xa3, 0xe8, 0xf1, 0xc7, 0x8c, 0x70, 0x54, 0x35, 0xc2, 0xc8, 0x63, + 0xaa, 0x11, 0x0c, 0x18, 0x5b, 0x73, 0x5b, 0x4d, 0x71, 0xd6, 0x8b, 0x17, 0xe7, 0x7d, 0x84, 0x98, + 0xa2, 0xc4, 0xf8, 0xe3, 0x0c, 0xcc, 0x84, 0x5f, 0x8c, 0x9f, 0xf0, 0x89, 0x77, 0xc9, 0x45, 0x18, + 0xc7, 0x8a, 0xaa, 0x15, 0xf5, 0xd0, 0x68, 0x51, 0x4c, 0xac, 0xd8, 0x34, 0x65, 0xa1, 0xda, 0x13, + 0xa3, 0x8f, 0xd7, 0x13, 0xc6, 0x3f, 0xc0, 0xc7, 0x6c, 0xb5, 0x95, 0xec, 0x24, 0x52, 0x3e, 0x24, + 0x33, 0xe4, 0x87, 0x64, 0x9f, 0xd8, 0x90, 0xe4, 0xfa, 0x0e, 0xc9, 0x8f, 0x64, 0x61, 0x32, 0xfc, + 0xd8, 0xef, 0xb2, 0xdc, 0x07, 0x61, 0xbb, 0x86, 0x8a, 0x71, 0x54, 0x57, 0xf6, 0x0a, 0x11, 0x4a, + 0xe8, 0x0b, 0x30, 0x26, 0x16, 0x53, 0x26, 0x66, 0xc9, 0x1d, 0x1b, 0xdd, 0x95, 0x19, 0xc1, 0x7a, + 0x0c, 0x07, 0xd4, 0x37, 0x05, 0x1d, 0x06, 0x91, 0xda, 0xa6, 0x3b, 0xc2, 0xb6, 0xe1, 0xa9, 0x3d, + 0xa3, 0xd2, 0x83, 0x48, 0x45, 0x0d, 0x1b, 0xea, 0x74, 0xfa, 0xe7, 0x79, 0x28, 0xc4, 0x49, 0x4e, + 0xce, 0x2e, 0x51, 0xeb, 0xed, 0xf0, 0xab, 0x0a, 0xcf, 0x2e, 0xd1, 0xed, 0xed, 0x98, 0x0c, 0x86, + 0xa6, 0x4f, 0x9e, 0xf3, 0x00, 0x5b, 0x3d, 0x25, 0x4c, 0x9f, 0x3c, 0xe7, 0x81, 0x66, 0xfa, 0xe4, + 0x39, 0x0f, 0x50, 0x91, 0xb0, 0x5e, 0xc7, 0x00, 0x0b, 0x78, 0x4f, 0x11, 0x8a, 0x84, 0x96, 0x1f, + 0xcf, 0x73, 0x27, 0xd1, 0xd8, 0x51, 0xb9, 0x42, 0x6d, 0x4f, 0x64, 0x42, 0x10, 0xdb, 0x19, 0x1e, + 0x95, 0x3b, 0x08, 0xb6, 0x02, 0x06, 0x37, 0x55, 0x24, 0xd2, 0x02, 0xa2, 0xfc, 0x94, 0x0b, 0xf8, + 0xe4, 0xbb, 0xb5, 0xb4, 0xc2, 0x5c, 0x50, 0x59, 0x5b, 0xea, 0x6a, 0x4e, 0xe1, 0xfb, 0x24, 0xb5, + 0xbf, 0x35, 0x11, 0xde, 0x15, 0x15, 0x48, 0xf9, 0x13, 0x99, 0xc9, 0xc0, 0x30, 0xc0, 0xc3, 0xbf, + 0x86, 0x6a, 0xa4, 0x88, 0x09, 0x79, 0x0f, 0x26, 0xd5, 0xb0, 0x19, 0x3c, 0xb8, 0xc3, 0x73, 0x3c, + 0x9e, 0x66, 0x9f, 0xdc, 0xc8, 0x2a, 0x01, 0xd9, 0x81, 0x73, 0x65, 0xb7, 0xe3, 0xf7, 0xda, 0x32, + 0x72, 0x67, 0x14, 0x91, 0x1c, 0x70, 0x28, 0xd0, 0x07, 0xbf, 0x21, 0x50, 0x44, 0x94, 0x06, 0xe9, + 0x26, 0xa3, 0x5f, 0x40, 0xfa, 0x31, 0x22, 0x9b, 0x30, 0x89, 0x1a, 0x54, 0x61, 0xf2, 0x38, 0xa9, + 0x6f, 0x1b, 0x51, 0x49, 0x85, 0x2d, 0x0c, 0x1e, 0x35, 0xce, 0x6e, 0xb7, 0xa4, 0x97, 0x86, 0xaa, + 0x09, 0x56, 0x90, 0xc9, 0x57, 0x60, 0x86, 0x5f, 0xd1, 0xb6, 0xe9, 0x0e, 0x9f, 0x3b, 0x53, 0x9a, + 0x26, 0x42, 0x2f, 0xe4, 0x8f, 0xf9, 0x42, 0x6f, 0xfd, 0x90, 0xee, 0xf0, 0xb1, 0xd7, 0x7c, 0xa4, + 0x34, 0x7c, 0xb2, 0x05, 0xf3, 0x6b, 0xb6, 0xcf, 0x81, 0x4a, 0xfc, 0x83, 0x69, 0xd4, 0xd0, 0xa2, + 0xed, 0xfa, 0xbe, 0xed, 0x4b, 0x45, 0x78, 0x6a, 0xbc, 0x83, 0x34, 0x7a, 0xf2, 0xcd, 0x0c, 0x2c, + 0x6a, 0x7a, 0x72, 0x61, 0x67, 0xd6, 0xa6, 0x9d, 0x00, 0x9d, 0xa1, 0x66, 0x96, 0x8b, 0x52, 0x28, + 0xed, 0x83, 0xc6, 0x87, 0x24, 0xa6, 0x8a, 0xf7, 0xa2, 0x72, 0xd5, 0x28, 0xbc, 0x1f, 0x0f, 0xb1, + 0x50, 0x71, 0x4d, 0xcf, 0xea, 0x0b, 0x35, 0xb6, 0xae, 0x25, 0x9a, 0x71, 0x23, 0xde, 0xdf, 0x42, + 0xd1, 0x95, 0x09, 0x15, 0x5d, 0x0b, 0x30, 0x8a, 0xbd, 0x2a, 0xa3, 0x68, 0xe1, 0x0f, 0xe3, 0xd3, + 0xea, 0x3e, 0x24, 0xc4, 0xc2, 0x81, 0xfb, 0x90, 0xf1, 0x3f, 0x8e, 0xc1, 0x6c, 0x6c, 0x5a, 0x88, + 0x7b, 0x6a, 0x26, 0x71, 0x4f, 0xad, 0x03, 0x70, 0x55, 0xef, 0x90, 0x3a, 0x59, 0xe9, 0x88, 0x39, + 0x29, 0xdc, 0xa8, 0xc3, 0x35, 0xa5, 0xb0, 0x61, 0x4c, 0xf9, 0x8a, 0x1d, 0x52, 0x47, 0x1e, 0x32, + 0xe5, 0x8b, 0x5e, 0x61, 0x1a, 0xb1, 0x21, 0x45, 0x18, 0xc5, 0xf8, 0xb9, 0xaa, 0x1f, 0xac, 0xc3, + 0x00, 0x26, 0x87, 0x93, 0x97, 0x60, 0x8c, 0x09, 0x51, 0xd5, 0x8a, 0xd8, 0x04, 0xf1, 0x6c, 0x61, + 0x52, 0x16, 0x93, 0x58, 0x44, 0x11, 0xb9, 0x01, 0x53, 0xfc, 0x2f, 0x11, 0x66, 0x67, 0x4c, 0x37, + 0x7e, 0xb4, 0x9c, 0xa6, 0x8c, 0xb4, 0xa3, 0xe1, 0xb1, 0xdb, 0x45, 0xbd, 0x87, 0x6a, 0x9d, 0x6a, + 0x45, 0x84, 0x74, 0xc7, 0xdb, 0x85, 0xcf, 0x81, 0xac, 0x8a, 0x08, 0x81, 0xc9, 0x32, 0xc2, 0x1b, + 0x25, 0x8f, 0x77, 0x4a, 0x94, 0x65, 0xb8, 0x17, 0x8a, 0x29, 0x4a, 0xc8, 0x65, 0xfe, 0x12, 0x83, + 0x62, 0x21, 0xcf, 0xeb, 0x89, 0xef, 0x16, 0xa8, 0x98, 0x40, 0xd9, 0x30, 0x2c, 0x66, 0x95, 0xb3, + 0xbf, 0x57, 0xdb, 0xb6, 0xd3, 0x12, 0xdb, 0x0a, 0x56, 0x8e, 0xb8, 0x94, 0x41, 0xcd, 0x08, 0x81, + 0xbc, 0x03, 0x33, 0x3c, 0xff, 0x5e, 0xbb, 0xed, 0x76, 0x90, 0xfd, 0x64, 0x14, 0x48, 0x4f, 0xe4, + 0x04, 0x64, 0x45, 0xbc, 0x96, 0x18, 0x2e, 0x3b, 0x4f, 0xf0, 0x95, 0xb7, 0xc7, 0xdf, 0x88, 0xa6, + 0xa2, 0xf3, 0x04, 0x49, 0x7d, 0x0e, 0x37, 0x55, 0x24, 0xf2, 0x16, 0x4c, 0xb3, 0x9f, 0xb7, 0x9c, + 0x07, 0x94, 0x57, 0x38, 0x1d, 0x99, 0x37, 0x20, 0xd5, 0x1e, 0x2b, 0xe1, 0xf5, 0xe9, 0x98, 0xe4, + 0x03, 0x38, 0x83, 0x9c, 0x1a, 0x6e, 0x97, 0x36, 0x4b, 0xbb, 0xbb, 0x4e, 0xcb, 0xe1, 0xd6, 0x68, + 0x3c, 0xa0, 0x0c, 0xea, 0xe0, 0x79, 0xc5, 0x88, 0x61, 0xd9, 0x11, 0x8a, 0x99, 0x4e, 0x49, 0xb6, + 0xa1, 0x50, 0xee, 0xf9, 0x81, 0xdb, 0x2e, 0x05, 0x81, 0xe7, 0xec, 0xf4, 0x02, 0xea, 0x2f, 0xce, + 0x6a, 0x61, 0x57, 0xd8, 0xe2, 0x08, 0x0b, 0xb9, 0x3e, 0xa8, 0x81, 0x14, 0x96, 0x1d, 0x92, 0x98, + 0x09, 0x26, 0xc6, 0xbf, 0xcc, 0xc0, 0xb4, 0x46, 0x4a, 0xde, 0x84, 0xa9, 0x9b, 0x9e, 0x43, 0x3b, + 0xcd, 0xd6, 0xa1, 0x72, 0x51, 0xc5, 0x5b, 0xcc, 0xae, 0x80, 0xf3, 0x56, 0x6b, 0x68, 0xa1, 0x9e, + 0x27, 0x9b, 0x6a, 0x2a, 0x7a, 0x95, 0xbb, 0x63, 0x8b, 0x09, 0x9a, 0x8b, 0xe2, 0x40, 0xe1, 0x04, + 0x15, 0xb3, 0x53, 0x41, 0x21, 0xef, 0xc2, 0x18, 0x7f, 0x0f, 0x16, 0x76, 0x8b, 0xe7, 0xd3, 0x9a, + 0xc9, 0x5d, 0xff, 0x71, 0x22, 0xa2, 0xd1, 0x8f, 0x6f, 0x0a, 0x22, 0xe3, 0xe7, 0x32, 0x40, 0x92, + 0xa8, 0x27, 0xe8, 0xbd, 0x4e, 0x34, 0x26, 0xfa, 0x42, 0xb8, 0x1a, 0x73, 0x9a, 0xce, 0x9c, 0xd5, + 0xc4, 0x0b, 0x78, 0xc7, 0x8b, 0x55, 0xa7, 0x2a, 0xe2, 0x78, 0xb1, 0xf1, 0xc3, 0x59, 0x80, 0x08, + 0x9b, 0x7c, 0x8e, 0x27, 0x42, 0xfb, 0xa0, 0x67, 0xb7, 0x9c, 0x5d, 0x47, 0x8f, 0xdb, 0x8b, 0x4c, + 0xbe, 0x2e, 0x4b, 0x4c, 0x1d, 0x91, 0xbc, 0x0f, 0xb3, 0xf5, 0x9a, 0x4e, 0xab, 0x98, 0xc5, 0xfb, + 0x5d, 0x2b, 0x46, 0x1e, 0xc7, 0x46, 0xfb, 0x64, 0x75, 0x34, 0xb8, 0x7d, 0x32, 0x1f, 0x08, 0x51, + 0xc2, 0x36, 0x96, 0x7a, 0x4d, 0x58, 0xfe, 0x37, 0xc3, 0x57, 0x4d, 0xfc, 0x3a, 0xbf, 0x6b, 0x75, + 0x85, 0x4b, 0x00, 0xdb, 0x27, 0x34, 0xbc, 0xa8, 0x23, 0x47, 0xfb, 0xb8, 0xf7, 0xff, 0x3c, 0xaa, + 0xfd, 0xda, 0x6e, 0x40, 0x85, 0xb6, 0xe3, 0xa9, 0xbd, 0xf7, 0x44, 0xc6, 0x04, 0xa3, 0x9a, 0xd7, + 0xb2, 0xd6, 0x3a, 0x61, 0x30, 0x73, 0x3d, 0xba, 0xa4, 0x70, 0xb3, 0x82, 0x14, 0x1b, 0x9b, 0xbf, + 0x97, 0x81, 0x33, 0xa9, 0xb4, 0xe4, 0x0a, 0x40, 0xa4, 0x53, 0x12, 0xbd, 0x84, 0x3b, 0x66, 0x14, + 0xfd, 0xc8, 0x54, 0x30, 0xc8, 0x97, 0xe3, 0xda, 0xa0, 0x93, 0x0f, 0xc2, 0x25, 0x19, 0x74, 0x50, + 0xd7, 0x06, 0xa5, 0xe8, 0x80, 0x8c, 0x5f, 0xc9, 0xc1, 0x9c, 0x12, 0x5c, 0x89, 0x7f, 0xeb, 0x09, + 0xf6, 0xe2, 0x07, 0x30, 0xc5, 0x5a, 0xe3, 0x34, 0x84, 0xdb, 0x0d, 0x37, 0x7c, 0x79, 0x2d, 0xe1, + 0x77, 0x2a, 0xb8, 0x5d, 0x51, 0x91, 0x79, 0x28, 0x50, 0xdc, 0x3a, 0xf1, 0x41, 0xa2, 0x91, 0x74, + 0xb9, 0xd1, 0x98, 0x13, 0x1f, 0xa6, 0x2b, 0x87, 0x1d, 0xbb, 0x1d, 0xd6, 0xc6, 0x0d, 0x60, 0x3e, + 0xd5, 0xb7, 0x36, 0x0d, 0x9b, 0x57, 0x17, 0x79, 0x68, 0xf1, 0xb2, 0x94, 0xe0, 0x00, 0x1a, 0xd5, + 0xd2, 0xfb, 0x30, 0x97, 0xf8, 0xe8, 0x53, 0x45, 0x25, 0xdd, 0x06, 0x92, 0xfc, 0x8e, 0x14, 0x0e, + 0x9f, 0xd2, 0x63, 0xde, 0x9e, 0x09, 0x1f, 0xaf, 0xdb, 0x6d, 0xbb, 0xd3, 0xe4, 0xe6, 0x34, 0xcb, + 0x6a, 0xcc, 0xd2, 0x9f, 0xcf, 0xaa, 0xbe, 0xbf, 0x4f, 0xfb, 0xaa, 0xfb, 0x82, 0x76, 0x1b, 0x7e, + 0xa1, 0xdf, 0x98, 0x0e, 0xa5, 0x75, 0xf8, 0x76, 0x0e, 0xce, 0xf5, 0xa1, 0x24, 0x87, 0xf1, 0x49, + 0xc4, 0xb5, 0x10, 0xd7, 0x06, 0x57, 0xf8, 0x24, 0xa6, 0x12, 0xf9, 0x1c, 0x8f, 0xfe, 0x21, 0x52, + 0x1d, 0xf3, 0xfb, 0x37, 0xaa, 0xf1, 0x0f, 0x42, 0x68, 0x3c, 0xec, 0x07, 0x87, 0x92, 0xf7, 0x61, + 0x14, 0x1d, 0xbf, 0x63, 0xe1, 0x1d, 0x19, 0x06, 0xc2, 0x95, 0x00, 0xa5, 0xec, 0xa7, 0x16, 0xa0, + 0x94, 0x01, 0xc8, 0x67, 0x21, 0x57, 0xda, 0xae, 0x8b, 0x71, 0x99, 0x51, 0xc9, 0xb7, 0xeb, 0x51, + 0xfa, 0x16, 0x5b, 0xcb, 0xb3, 0xc2, 0x28, 0x18, 0xe1, 0xad, 0x72, 0x4d, 0x8c, 0x8a, 0x4a, 0x78, + 0xab, 0x5c, 0x8b, 0x08, 0xf7, 0x1a, 0x5a, 0xb0, 0xac, 0x5b, 0xe5, 0xda, 0x27, 0x37, 0xed, 0xff, + 0x83, 0x2c, 0x0f, 0x59, 0xc2, 0x1b, 0xf6, 0x3e, 0x4c, 0x69, 0x31, 0xc9, 0x33, 0x91, 0x3c, 0x16, + 0xc6, 0x8f, 0x8f, 0x59, 0x0c, 0x69, 0x04, 0x32, 0x11, 0x12, 0xfb, 0x8d, 0x12, 0xaf, 0x6a, 0x6c, + 0x13, 0x72, 0x40, 0x99, 0x38, 0x9e, 0x08, 0x29, 0x24, 0x21, 0xd7, 0x21, 0xbf, 0x49, 0x3b, 0x76, + 0x27, 0x08, 0x15, 0xa2, 0x68, 0x5c, 0x1c, 0x20, 0x4c, 0x97, 0x1a, 0x42, 0x44, 0x34, 0x84, 0xed, + 0xed, 0xf8, 0x0d, 0xcf, 0xc1, 0xd0, 0x46, 0xe1, 0x59, 0xcc, 0x0d, 0x61, 0x95, 0x12, 0x9d, 0x41, + 0x8c, 0xc8, 0xf8, 0xf9, 0x0c, 0x8c, 0x8b, 0x81, 0xe4, 0x09, 0xec, 0xf6, 0xa2, 0xb3, 0x44, 0x38, + 0x0f, 0xec, 0x39, 0x71, 0xe7, 0x81, 0x3d, 0x1e, 0x3f, 0x68, 0x42, 0x38, 0xd6, 0x85, 0x4f, 0x83, + 0x38, 0x1b, 0xa5, 0xdb, 0xa7, 0x9e, 0x9f, 0x2c, 0x44, 0x1d, 0xd6, 0x21, 0xcb, 0xf8, 0x5b, 0xe2, + 0xcb, 0x6e, 0x95, 0x6b, 0x64, 0x19, 0xf2, 0xeb, 0x2e, 0x0f, 0x85, 0xa5, 0x66, 0x23, 0x6e, 0x09, + 0x98, 0xda, 0x41, 0x12, 0x8f, 0x7d, 0x5f, 0xcd, 0x73, 0xc5, 0x5d, 0x46, 0xf9, 0xbe, 0x2e, 0x07, + 0xc6, 0xbe, 0x2f, 0x44, 0x1d, 0xfa, 0xfb, 0x68, 0xca, 0x26, 0x71, 0xff, 0x3a, 0x66, 0x88, 0xb9, + 0xad, 0x3a, 0xba, 0x89, 0x22, 0xb9, 0x53, 0x2c, 0xf5, 0xdb, 0x29, 0xee, 0x5f, 0x37, 0x53, 0xa8, + 0xf0, 0x5d, 0x2d, 0x02, 0xd7, 0xa9, 0xf7, 0xe0, 0x29, 0xde, 0xa5, 0xd3, 0xdf, 0xd5, 0xe2, 0xcd, + 0x1b, 0x6a, 0x93, 0xfe, 0xfd, 0x2c, 0x9c, 0x4d, 0x27, 0x54, 0xdb, 0x92, 0x19, 0xd0, 0x96, 0x4b, + 0x90, 0x5f, 0x73, 0xfd, 0x40, 0x31, 0x12, 0x44, 0xf5, 0xff, 0xbe, 0x80, 0x99, 0x61, 0x29, 0xbb, + 0x73, 0xb3, 0xbf, 0xc3, 0xe5, 0x89, 0xfc, 0x30, 0x50, 0x07, 0xbb, 0x73, 0xf3, 0x22, 0x72, 0x0b, + 0xf2, 0xa6, 0x70, 0xb4, 0x8a, 0x75, 0x8d, 0x04, 0x87, 0xd2, 0x14, 0xf1, 0x04, 0x44, 0x0b, 0x0d, + 0x2f, 0x60, 0xa4, 0x04, 0xe3, 0x62, 0xf4, 0x63, 0x4f, 0xc7, 0x29, 0x53, 0x46, 0xcf, 0xd6, 0x20, + 0xe9, 0xd8, 0x8e, 0x82, 0x8f, 0x80, 0xd5, 0x8a, 0xf4, 0x99, 0xc2, 0x1d, 0x85, 0x3f, 0x12, 0xea, + 0xf6, 0x98, 0x21, 0xa2, 0xf1, 0xcd, 0x2c, 0x80, 0xd4, 0xda, 0x3c, 0xb5, 0x33, 0xec, 0xb3, 0xda, + 0x0c, 0x53, 0xec, 0x8d, 0x86, 0x4f, 0xb8, 0x7c, 0x0f, 0xcd, 0x79, 0x86, 0x4f, 0xb7, 0x5c, 0x84, + 0xd1, 0xcd, 0x48, 0xa1, 0x25, 0x5c, 0x52, 0x50, 0x1d, 0xcd, 0xe1, 0xc6, 0x0e, 0x2c, 0xdc, 0xa2, + 0x41, 0xa4, 0xde, 0x92, 0x4f, 0x8f, 0x83, 0xd9, 0xbe, 0x0e, 0x13, 0x02, 0x3f, 0xdc, 0xbf, 0xb8, + 0x2e, 0x46, 0xc4, 0xbe, 0x41, 0x5d, 0x8c, 0x44, 0x60, 0xbb, 0x51, 0x85, 0xb6, 0x68, 0x40, 0x3f, + 0xd9, 0x6a, 0xea, 0x40, 0x78, 0x53, 0xb0, 0x65, 0xc3, 0xd5, 0x70, 0x62, 0xff, 0xdc, 0x87, 0x33, + 0xe1, 0xb7, 0x3f, 0x49, 0xbe, 0x57, 0xd9, 0x95, 0x52, 0x24, 0x3a, 0x88, 0x38, 0x0e, 0xb0, 0x3d, + 0x79, 0x04, 0x4b, 0x92, 0x60, 0xdb, 0x09, 0x0d, 0x27, 0x87, 0xa2, 0x25, 0xef, 0xc0, 0xa4, 0x42, + 0x23, 0x02, 0xf5, 0xa3, 0x9a, 0xfa, 0xa1, 0x13, 0xec, 0x5b, 0x3e, 0x87, 0xab, 0x6a, 0x6a, 0x05, + 0xdd, 0xf8, 0x12, 0x3c, 0x1b, 0xba, 0x0d, 0xa5, 0x54, 0x1d, 0x63, 0x9e, 0x39, 0x1d, 0xf3, 0x8d, + 0xa8, 0x59, 0xd5, 0x4e, 0xe8, 0x19, 0x2d, 0x79, 0x13, 0xb5, 0x59, 0xa2, 0x31, 0xcf, 0x25, 0x7c, + 0xad, 0x15, 0x97, 0x6a, 0xe3, 0x6d, 0xe5, 0x63, 0x53, 0x18, 0x6a, 0xc4, 0x99, 0x38, 0xf1, 0x37, + 0xb3, 0x30, 0x7b, 0xaf, 0x5a, 0x29, 0x87, 0xd6, 0x47, 0xdf, 0x65, 0xe9, 0xa0, 0xb5, 0xb6, 0xf5, + 0xdf, 0x6f, 0x8c, 0x2d, 0x98, 0x8f, 0x75, 0x03, 0x8a, 0x0e, 0xef, 0x71, 0x87, 0x93, 0x10, 0x2c, + 0xc5, 0x86, 0xb3, 0x69, 0xec, 0xef, 0x5f, 0x37, 0x63, 0xd8, 0xc6, 0x7f, 0x09, 0x31, 0xbe, 0x62, + 0x0b, 0x7b, 0x1d, 0x26, 0xaa, 0xbe, 0xdf, 0xa3, 0xde, 0x96, 0xb9, 0xae, 0xaa, 0x0a, 0x1c, 0x04, + 0x5a, 0x3d, 0xaf, 0x65, 0x46, 0x08, 0xe4, 0x32, 0xe4, 0x45, 0x90, 0x74, 0xb9, 0x27, 0xa0, 0xd6, + 0x36, 0x8c, 0xb1, 0x6e, 0x86, 0xc5, 0xe4, 0x4d, 0x98, 0xe2, 0x7f, 0xf3, 0xd9, 0x26, 0x3a, 0x1c, + 0x95, 0x83, 0x02, 0x9d, 0xcf, 0x4e, 0x53, 0x43, 0x23, 0xaf, 0x41, 0xae, 0x54, 0x36, 0x85, 0x3a, + 0x48, 0xc8, 0x8d, 0x9e, 0xc5, 0x75, 0x76, 0xda, 0x25, 0xa2, 0x6c, 0x32, 0xe9, 0x4f, 0x06, 0x9b, + 0x10, 0x9a, 0x6c, 0x9c, 0x01, 0x52, 0xdb, 0x14, 0x3b, 0xcc, 0x10, 0x46, 0xae, 0xc2, 0x78, 0x85, + 0x9b, 0xcc, 0x09, 0x3d, 0x36, 0xcf, 0x75, 0xc8, 0x41, 0x5a, 0x70, 0x05, 0x0e, 0x22, 0x97, 0x65, + 0x86, 0xb6, 0x7c, 0xe4, 0xb7, 0xd2, 0x27, 0x0d, 0xdb, 0xeb, 0x30, 0x26, 0x42, 0x89, 0x4f, 0x28, + 0xb9, 0x5b, 0xe2, 0x21, 0xc4, 0x05, 0x4e, 0xd2, 0x81, 0x15, 0x9e, 0xa4, 0x03, 0xeb, 0x0e, 0x9c, + 0xbb, 0x85, 0xda, 0x1b, 0x3d, 0x20, 0xd6, 0x96, 0x59, 0x15, 0xfa, 0x70, 0x7c, 0x06, 0xe2, 0x0a, + 0x9e, 0x78, 0x4c, 0x2d, 0xab, 0xe7, 0xa9, 0xa9, 0x7b, 0xfb, 0x31, 0x22, 0x5f, 0x84, 0x85, 0xb4, + 0x22, 0xa1, 0x35, 0xc7, 0xd0, 0x4f, 0xe9, 0x15, 0xa8, 0xa1, 0x9f, 0xd2, 0x38, 0x90, 0x75, 0x28, + 0x70, 0x78, 0xa9, 0xd9, 0x76, 0x3a, 0x5c, 0xf3, 0xcf, 0xb5, 0xea, 0xe8, 0x48, 0x22, 0xb8, 0xda, + 0xac, 0x90, 0xbf, 0x00, 0x68, 0xae, 0x47, 0x31, 0x4a, 0xf2, 0x53, 0x19, 0x76, 0x9b, 0xe3, 0x81, + 0xb7, 0xb7, 0xcc, 0x75, 0x5f, 0x84, 0x0d, 0x3c, 0x1b, 0x79, 0x15, 0xd5, 0x03, 0xcf, 0xe9, 0xec, + 0x09, 0xb7, 0xa2, 0x4d, 0xe1, 0x56, 0xf4, 0xce, 0xc7, 0x72, 0x2b, 0xe2, 0xac, 0xfc, 0xe3, 0xa3, + 0xe2, 0x94, 0x27, 0xea, 0xc4, 0x55, 0xa4, 0x7d, 0x01, 0xeb, 0x3a, 0xf4, 0xad, 0xdd, 0xea, 0xf0, + 0xb0, 0xbf, 0xb4, 0xc9, 0x1b, 0x39, 0x8b, 0x3b, 0x38, 0x76, 0x1d, 0xe6, 0x04, 0xb1, 0x7a, 0x21, + 0x42, 0xa2, 0xa1, 0xa9, 0x1c, 0xd8, 0xc5, 0x53, 0xba, 0xae, 0x70, 0x6f, 0xdc, 0x42, 0x74, 0xf1, + 0x94, 0x7e, 0x2e, 0x16, 0x4e, 0x23, 0x75, 0xf2, 0x68, 0x24, 0xe4, 0x2a, 0x8c, 0xdd, 0xb5, 0x1f, + 0x95, 0xf6, 0xa8, 0xc8, 0xed, 0x39, 0x2d, 0xb7, 0x3f, 0x04, 0xae, 0xe4, 0xff, 0x80, 0xfb, 0x3a, + 0x3c, 0x63, 0x0a, 0x34, 0xf2, 0xfd, 0x19, 0x38, 0xcb, 0x97, 0xb1, 0x6c, 0x65, 0x9d, 0x06, 0x01, + 0xeb, 0x07, 0x11, 0x3f, 0xf0, 0x42, 0x64, 0xb0, 0x9d, 0x8e, 0x87, 0x9e, 0xf7, 0x86, 0xd8, 0x19, + 0xc2, 0x8e, 0xf3, 0x45, 0xa9, 0x16, 0x88, 0x39, 0x95, 0x9e, 0x6c, 0xc2, 0xe4, 0xdd, 0x9b, 0xa5, + 0xb0, 0x5a, 0x1e, 0x9d, 0xbd, 0x98, 0xb6, 0x3b, 0x2a, 0x68, 0x69, 0x9e, 0x06, 0x2a, 0x1b, 0xe1, + 0x1d, 0xf0, 0x59, 0xd9, 0x1f, 0xe4, 0x0d, 0xd5, 0x15, 0x35, 0x87, 0xd2, 0xf3, 0x78, 0xdb, 0x7e, + 0x64, 0xd9, 0x7b, 0x54, 0x7b, 0x25, 0x17, 0xda, 0xeb, 0x9f, 0xcd, 0xc0, 0xf9, 0xbe, 0x4d, 0x26, + 0x37, 0xe0, 0x9c, 0xcd, 0x1d, 0xac, 0xad, 0xfd, 0x20, 0xe8, 0xfa, 0x96, 0xbc, 0x62, 0x08, 0xe7, + 0x55, 0xf3, 0x8c, 0x28, 0x5e, 0x63, 0xa5, 0xf2, 0xd6, 0xe1, 0x93, 0xf7, 0xe1, 0x39, 0xa7, 0xe3, + 0xd3, 0x46, 0xcf, 0xa3, 0x96, 0x64, 0xd0, 0x70, 0x9a, 0x9e, 0xe5, 0xd9, 0x9d, 0x3d, 0xe9, 0x89, + 0x6b, 0x9e, 0x97, 0x38, 0xc2, 0x89, 0xbb, 0xec, 0x34, 0x3d, 0x13, 0x11, 0x8c, 0x7f, 0x99, 0x81, + 0xc5, 0x7e, 0x5d, 0x42, 0x16, 0x61, 0x9c, 0x2a, 0x79, 0x5a, 0xf2, 0xa6, 0xfc, 0x49, 0x9e, 0x85, + 0x68, 0xa7, 0x17, 0xa7, 0x7f, 0xbe, 0x21, 0x72, 0x66, 0xa0, 0x69, 0xbb, 0xba, 0xaf, 0x0b, 0x03, + 0xe5, 0xa9, 0x86, 0xba, 0xbb, 0x3f, 0x0f, 0x10, 0x6d, 0xe7, 0x5c, 0x31, 0x61, 0x4e, 0xd8, 0x0d, + 0x8f, 0xaf, 0x3c, 0x72, 0x16, 0xc6, 0xf8, 0x76, 0x29, 0xfc, 0x1f, 0xc4, 0x2f, 0x76, 0x6e, 0x8b, + 0x4e, 0xc6, 0x7d, 0x3e, 0xb7, 0x32, 0xa5, 0x75, 0xf6, 0x58, 0x1b, 0x07, 0xc7, 0xf8, 0xe9, 0x69, + 0x2e, 0x42, 0x94, 0x7a, 0xc1, 0xbe, 0x14, 0x3a, 0x96, 0xd3, 0xfc, 0xc5, 0xb8, 0x2d, 0xa5, 0x62, + 0x97, 0xad, 0x7b, 0x89, 0xc9, 0xb7, 0x9f, 0x6c, 0xea, 0xdb, 0xcf, 0xeb, 0x30, 0x51, 0xde, 0xa7, + 0x8d, 0x83, 0xd0, 0x09, 0x27, 0x2f, 0x94, 0xeb, 0x0c, 0xc8, 0x43, 0xa2, 0x47, 0x08, 0xe4, 0x2a, + 0x00, 0xba, 0xa9, 0x72, 0x89, 0x54, 0x49, 0x6b, 0x82, 0x5e, 0xad, 0xc2, 0x3c, 0x45, 0x41, 0x41, + 0xf6, 0x75, 0xf3, 0xa6, 0x6a, 0xcf, 0xc2, 0xd9, 0xfb, 0xde, 0xae, 0x40, 0x8f, 0x10, 0x58, 0xf3, + 0x94, 0x7d, 0x45, 0x9c, 0x82, 0x85, 0xc4, 0xe6, 0xa3, 0x22, 0x91, 0x2b, 0x30, 0x51, 0x93, 0x8e, + 0x04, 0x78, 0x08, 0x4e, 0x21, 0x05, 0x44, 0x4e, 0x07, 0x8b, 0x19, 0x33, 0x42, 0x21, 0x9f, 0x85, + 0xf1, 0x32, 0xf5, 0x82, 0xcd, 0xcd, 0x75, 0x34, 0x3a, 0xe1, 0xd9, 0x3f, 0xf2, 0x98, 0xa9, 0x21, + 0x08, 0x5a, 0xdf, 0x39, 0x2a, 0x4e, 0x07, 0x4e, 0x9b, 0x86, 0x51, 0xcd, 0x4d, 0x89, 0x4d, 0x56, + 0xa0, 0xc0, 0x9f, 0xc5, 0xa3, 0xbb, 0x07, 0x9e, 0x8c, 0x79, 0x7e, 0x4e, 0x8b, 0x37, 0xf4, 0x87, + 0x74, 0x27, 0xcc, 0x53, 0x91, 0xc0, 0x27, 0xab, 0x32, 0xbd, 0x8b, 0xda, 0x4c, 0x88, 0x94, 0x61, + 0xf1, 0x1d, 0x83, 0xb5, 0x36, 0x49, 0x41, 0x4a, 0x30, 0x5d, 0x76, 0xdb, 0x5d, 0x3b, 0x70, 0x30, + 0x0f, 0xe6, 0xa1, 0x38, 0x04, 0x51, 0xa1, 0xd7, 0x50, 0x0b, 0xb4, 0x13, 0x55, 0x2d, 0x20, 0x37, + 0x61, 0xc6, 0x74, 0x7b, 0x6c, 0x98, 0xe4, 0x2d, 0x9c, 0x9f, 0x73, 0x68, 0x1a, 0xe2, 0xb1, 0x12, + 0x76, 0x2c, 0x8b, 0x2b, 0xb7, 0x16, 0x01, 0x56, 0xa3, 0x22, 0x1b, 0x29, 0xcf, 0x21, 0xea, 0xe1, + 0xa6, 0x66, 0xab, 0x48, 0x30, 0x4b, 0x79, 0x49, 0xb9, 0x0e, 0x93, 0xf5, 0xfa, 0xbd, 0x4d, 0xea, + 0x07, 0x37, 0x5b, 0xee, 0x43, 0x3c, 0xdb, 0xf2, 0x22, 0xb9, 0x9a, 0xef, 0x5a, 0x01, 0xf5, 0x03, + 0x6b, 0xb7, 0xe5, 0x3e, 0x34, 0x55, 0x2c, 0xf2, 0x55, 0xd6, 0x1f, 0x8a, 0x24, 0x28, 0x62, 0xdd, + 0x0e, 0x12, 0x56, 0xf1, 0x04, 0x89, 0x16, 0x0d, 0x13, 0x59, 0xf5, 0xce, 0x52, 0xd0, 0xd1, 0xa7, + 0xcc, 0x73, 0x1f, 0x1d, 0x96, 0x9a, 0x4d, 0x8f, 0xfa, 0xbe, 0x38, 0x84, 0xb8, 0x4f, 0x19, 0x2a, + 0x1b, 0x6c, 0x5e, 0xa0, 0xf9, 0x94, 0x29, 0x04, 0xe4, 0x47, 0x33, 0x70, 0x46, 0xf5, 0x36, 0xc1, + 0xe5, 0x82, 0x66, 0x2e, 0xfc, 0x48, 0x7a, 0xe3, 0x8a, 0x3c, 0x84, 0xaf, 0x28, 0x68, 0x57, 0x1e, + 0x5c, 0xbb, 0x52, 0x8a, 0x7e, 0xd6, 0x25, 0x11, 0xc6, 0xed, 0x2b, 0xa6, 0xf2, 0xd3, 0x72, 0x13, + 0x2d, 0xd8, 0x29, 0xc4, 0xa4, 0xcc, 0x24, 0x35, 0x36, 0xa3, 0xd0, 0x70, 0xaa, 0x5a, 0xc3, 0x33, + 0x4d, 0x68, 0x54, 0xc5, 0xfc, 0xe3, 0x26, 0x56, 0x4e, 0x57, 0x17, 0xc8, 0x14, 0x1a, 0x52, 0x85, + 0x59, 0x0e, 0x60, 0xdb, 0x02, 0x4f, 0xf3, 0x34, 0x1f, 0x25, 0x9a, 0x10, 0x6c, 0xf0, 0xad, 0x1f, + 0x53, 0x3d, 0xa9, 0xc1, 0x59, 0x63, 0x74, 0xe4, 0x7d, 0x98, 0xc1, 0x18, 0xfa, 0xd1, 0x7a, 0x5d, + 0xc0, 0x55, 0x8c, 0x31, 0x66, 0x45, 0x49, 0xcc, 0xf3, 0x6e, 0xca, 0xf7, 0xf7, 0xa3, 0x15, 0xfd, + 0x3e, 0xcc, 0xa0, 0xad, 0x4e, 0xc4, 0xe0, 0x4c, 0xc4, 0x40, 0x94, 0xc4, 0x19, 0x04, 0x2d, 0x3f, + 0x62, 0xf0, 0x33, 0x19, 0x38, 0xcf, 0x2a, 0x4a, 0x1f, 0xa1, 0xb3, 0x1f, 0x67, 0x84, 0x30, 0xea, + 0x66, 0x5f, 0x9e, 0xaa, 0x38, 0xea, 0xfb, 0xfb, 0x69, 0x1c, 0xf0, 0xa3, 0xd8, 0xc7, 0xa7, 0x7f, + 0xd4, 0xb9, 0x8f, 0xfd, 0x51, 0x7d, 0x79, 0xaa, 0x1f, 0x15, 0xb4, 0xfc, 0x34, 0x0e, 0x78, 0xad, + 0xad, 0x97, 0xee, 0xae, 0x47, 0x77, 0xb3, 0xef, 0x2e, 0xb7, 0x15, 0xad, 0x6d, 0x03, 0xdc, 0x56, + 0xb6, 0xb8, 0x17, 0xb5, 0xd2, 0x0d, 0xf2, 0x5a, 0xab, 0x81, 0xe3, 0xd7, 0xda, 0x18, 0x8d, 0x19, + 0xc3, 0x36, 0x7e, 0x09, 0x62, 0x7c, 0x85, 0xa9, 0xaa, 0x01, 0x63, 0xfc, 0xd6, 0x2a, 0x3a, 0x19, + 0x6d, 0x16, 0xf8, 0x9d, 0xd6, 0x14, 0x25, 0xe4, 0x3c, 0xe4, 0xea, 0xf5, 0x7b, 0xa2, 0x93, 0xd1, + 0x60, 0xd5, 0xf7, 0x5d, 0x93, 0xc1, 0xd8, 0x08, 0xa1, 0x15, 0xaa, 0x92, 0x93, 0x80, 0x9d, 0x77, + 0x26, 0x42, 0x59, 0x7f, 0xcb, 0x3b, 0xe4, 0x48, 0xd4, 0xdf, 0xe2, 0x0e, 0x19, 0xdd, 0x1c, 0xcb, + 0xb0, 0x58, 0xf2, 0x7d, 0xea, 0xb1, 0x09, 0x21, 0x8c, 0x1b, 0x3d, 0x71, 0xcf, 0x11, 0x07, 0x3b, + 0x56, 0x6a, 0x37, 0x7c, 0xb3, 0x2f, 0x22, 0xb9, 0x04, 0xf9, 0x52, 0xaf, 0xe9, 0xd0, 0x4e, 0x43, + 0x0b, 0xcb, 0x66, 0x0b, 0x98, 0x19, 0x96, 0x92, 0x0f, 0xe0, 0x4c, 0x2c, 0x02, 0xa3, 0xe8, 0x81, + 0xf1, 0x68, 0xef, 0x95, 0xf7, 0xb0, 0xc8, 0x20, 0x83, 0x77, 0x49, 0x3a, 0x25, 0x29, 0x41, 0x61, + 0x15, 0xdd, 0xb4, 0x2a, 0x94, 0xbf, 0x0d, 0xb9, 0x1e, 0xf7, 0xcf, 0xe3, 0xb7, 0x66, 0x11, 0x67, + 0xb2, 0x19, 0x16, 0x9a, 0x09, 0x74, 0x72, 0x07, 0xe6, 0xe3, 0x30, 0x76, 0x82, 0xf3, 0x0b, 0x32, + 0xee, 0x37, 0x09, 0x2e, 0x78, 0x86, 0xa7, 0x51, 0x91, 0x1d, 0x98, 0x8b, 0x0c, 0x92, 0xf4, 0x6b, + 0xb3, 0xb4, 0x73, 0x0e, 0xcb, 0xe5, 0xd5, 0xf9, 0x59, 0x31, 0x19, 0xe7, 0x23, 0xe3, 0xa6, 0xf0, + 0xfa, 0x6c, 0x26, 0xd9, 0x91, 0x26, 0xcc, 0xd4, 0x9d, 0xbd, 0x8e, 0xd3, 0xd9, 0xbb, 0x43, 0x0f, + 0x6b, 0xb6, 0xe3, 0x09, 0x8b, 0x53, 0x69, 0x4f, 0x5e, 0xf2, 0x0f, 0xdb, 0x6d, 0x1a, 0x78, 0xb8, + 0x11, 0xb2, 0x72, 0xf4, 0x41, 0x67, 0xd7, 0xa1, 0x25, 0x9f, 0xd3, 0xa1, 0xdb, 0x66, 0xd7, 0x76, + 0x34, 0x21, 0x40, 0xe7, 0xa9, 0xa9, 0x2e, 0xa6, 0x86, 0x54, 0x5d, 0xb4, 0x60, 0x6e, 0xb5, 0xd3, + 0xf0, 0x0e, 0xf1, 0x89, 0x4e, 0x7e, 0xdc, 0xf4, 0x09, 0x1f, 0xf7, 0xb2, 0xf8, 0xb8, 0xe7, 0x6c, + 0x39, 0xc3, 0xd2, 0x3e, 0x2f, 0xc9, 0x98, 0xd4, 0x61, 0x0e, 0x2f, 0x0e, 0xd5, 0x4a, 0xad, 0xda, + 0x71, 0x02, 0xc7, 0x0e, 0x68, 0x53, 0x08, 0x17, 0x61, 0x26, 0x17, 0x7e, 0x45, 0x75, 0x9a, 0x5d, + 0xcb, 0x91, 0x28, 0x2a, 0xd3, 0x04, 0xfd, 0xa0, 0x7b, 0xe2, 0xec, 0x9f, 0xd3, 0x3d, 0xb1, 0x0a, + 0xb3, 0xf1, 0x50, 0x0e, 0x85, 0xe8, 0x1c, 0xf6, 0xb1, 0x88, 0x1d, 0xe7, 0x6e, 0x0f, 0x85, 0x49, + 0x2d, 0x79, 0x6a, 0x2c, 0x88, 0x43, 0xec, 0xca, 0x39, 0xa7, 0x5d, 0x39, 0xb5, 0x5d, 0xe9, 0x14, + 0x57, 0x4e, 0x52, 0x03, 0xb8, 0xe9, 0x7a, 0x0d, 0x5a, 0x42, 0xff, 0x68, 0xa2, 0xe5, 0xbb, 0x62, + 0x4c, 0xa3, 0x42, 0xbe, 0x7e, 0x76, 0xd9, 0x6f, 0x2b, 0xee, 0xe6, 0xae, 0xf0, 0x30, 0x7e, 0x2c, + 0x0b, 0x8b, 0xfd, 0x3e, 0x67, 0xc0, 0x75, 0xef, 0x53, 0x90, 0x5c, 0xe1, 0xe2, 0xda, 0x57, 0xa0, + 0xf1, 0x75, 0xbe, 0x0c, 0xe9, 0x0b, 0x59, 0x5c, 0x03, 0xe7, 0xe3, 0x04, 0x5b, 0x5e, 0x8b, 0xdc, + 0x80, 0x49, 0xe5, 0xe3, 0x71, 0x2f, 0xed, 0xd7, 0x54, 0x13, 0x76, 0xc3, 0xbf, 0xd9, 0x35, 0x91, + 0xef, 0x5b, 0xf2, 0x9a, 0xc8, 0x7f, 0x91, 0x02, 0x77, 0x11, 0x1f, 0xe3, 0x56, 0x00, 0xbe, 0xef, + 0x12, 0x02, 0xb8, 0x6f, 0xf3, 0x2d, 0xd0, 0xc4, 0xbf, 0x8d, 0xdf, 0x98, 0xe2, 0x27, 0xb2, 0x7a, + 0x4b, 0xec, 0x67, 0x1f, 0x1c, 0xbb, 0x3d, 0x66, 0x4f, 0x73, 0x7b, 0xcc, 0x9d, 0x7c, 0x7b, 0x1c, + 0x39, 0xe9, 0xf6, 0x18, 0xbb, 0xde, 0x8d, 0x9e, 0xfa, 0x7a, 0x37, 0x76, 0xaa, 0xeb, 0xdd, 0xf8, + 0xa9, 0xae, 0x77, 0xda, 0x4d, 0x35, 0x7f, 0xd2, 0x4d, 0xf5, 0x2f, 0x2f, 0x83, 0x4f, 0xeb, 0x65, + 0x30, 0x4d, 0xc4, 0x3b, 0xd5, 0x65, 0xf0, 0x47, 0xfa, 0xde, 0xe5, 0x0a, 0x1f, 0x47, 0x28, 0x7f, + 0x69, 0x88, 0xbb, 0xdc, 0xb0, 0x37, 0xb9, 0xb9, 0x27, 0x73, 0x93, 0x23, 0x4f, 0xec, 0x26, 0x37, + 0xff, 0xb8, 0x37, 0xb9, 0x85, 0x27, 0x79, 0x93, 0x3b, 0xf3, 0x17, 0xf1, 0x26, 0x77, 0xf6, 0xdf, + 0xcf, 0x4d, 0xee, 0xaf, 0x40, 0x21, 0x2e, 0x5c, 0x9e, 0x1c, 0xf5, 0xf8, 0x89, 0x85, 0x9c, 0x64, + 0xa2, 0x6f, 0x5c, 0xb8, 0x23, 0x57, 0x01, 0x6a, 0x9e, 0xf3, 0xc0, 0x0e, 0xe8, 0x1d, 0x69, 0xfd, + 0x26, 0x22, 0x76, 0x73, 0x28, 0x1b, 0x79, 0x53, 0x41, 0x09, 0xef, 0x35, 0xd9, 0xb4, 0x7b, 0x8d, + 0xf1, 0xa3, 0x59, 0x98, 0xe3, 0x71, 0xdb, 0x9e, 0xfe, 0x47, 0xd8, 0xf7, 0xb4, 0xdb, 0xea, 0x73, + 0x51, 0x8e, 0x00, 0xb5, 0x75, 0x03, 0x9e, 0x61, 0xbf, 0x02, 0x67, 0x12, 0x5d, 0x81, 0x37, 0xd6, + 0x8a, 0x8c, 0x98, 0x97, 0xb8, 0xb3, 0x2e, 0xa6, 0x57, 0x72, 0xff, 0xba, 0x99, 0xa0, 0x30, 0xfe, + 0x74, 0x24, 0xc1, 0x5f, 0x3c, 0xc8, 0xaa, 0x4f, 0xac, 0x99, 0xd3, 0x3d, 0xb1, 0x66, 0x87, 0x7b, + 0x62, 0x8d, 0x09, 0x15, 0xb9, 0x61, 0x84, 0x8a, 0x0f, 0x60, 0x7a, 0x93, 0xda, 0x6d, 0x7f, 0xd3, + 0x15, 0x09, 0xa7, 0xb8, 0xaf, 0x85, 0x0c, 0x88, 0xc7, 0xca, 0xe4, 0x85, 0x2b, 0xb4, 0x19, 0x0d, + 0x18, 0x01, 0x3b, 0x06, 0x79, 0x06, 0x2a, 0x53, 0xe7, 0xa0, 0xde, 0xa2, 0x47, 0x07, 0xdc, 0xa2, + 0xeb, 0x30, 0x25, 0xe8, 0xa2, 0x50, 0xcf, 0xd1, 0x75, 0x8f, 0x15, 0x21, 0x5c, 0xd6, 0x1e, 0x66, + 0xc3, 0x0f, 0x6b, 0xe7, 0x37, 0x3d, 0x8d, 0x09, 0xeb, 0x82, 0xd5, 0x4e, 0xb3, 0xeb, 0x3a, 0x1d, + 0xec, 0x82, 0xf1, 0xa8, 0x0b, 0xa8, 0x00, 0xf3, 0x2e, 0x50, 0x90, 0xc8, 0x3b, 0x30, 0x53, 0xaa, + 0x55, 0x55, 0xb2, 0x7c, 0xf4, 0xca, 0x6b, 0x77, 0x1d, 0x4b, 0x23, 0x8d, 0xe1, 0x0e, 0xba, 0xf9, + 0x4c, 0xfc, 0xf9, 0xdc, 0x7c, 0x8c, 0x7f, 0x36, 0x2d, 0x97, 0xf7, 0x27, 0xfb, 0x40, 0xa2, 0x3f, + 0x79, 0xe4, 0x4e, 0xf9, 0xe4, 0x31, 0x72, 0x92, 0x20, 0xa9, 0xc9, 0xb7, 0xa3, 0xa7, 0x92, 0x6f, + 0xc7, 0x1e, 0xfb, 0xf9, 0x62, 0xfc, 0x94, 0x12, 0x6b, 0x6c, 0xad, 0xe5, 0x87, 0x59, 0x6b, 0xa9, + 0x52, 0xee, 0xc4, 0xe3, 0x4b, 0xb9, 0x70, 0x6a, 0x29, 0xb7, 0x1e, 0xf9, 0x2e, 0x4f, 0x9e, 0xe8, + 0x12, 0xf2, 0xbc, 0xd0, 0x0a, 0xcc, 0xa5, 0x47, 0xe1, 0x0b, 0xbd, 0x98, 0xbf, 0xab, 0x44, 0xe7, + 0xaf, 0xa5, 0x8b, 0xce, 0x83, 0xcf, 0x9b, 0x53, 0x09, 0xcf, 0x3f, 0xfa, 0x64, 0x85, 0xe7, 0x27, + 0xfb, 0x10, 0xf2, 0x97, 0xe2, 0xf3, 0x5f, 0x8a, 0xcf, 0xc3, 0x89, 0xcf, 0xe4, 0x1e, 0x10, 0xbb, + 0x17, 0xec, 0xd3, 0x4e, 0xe0, 0x34, 0x30, 0x2a, 0x2d, 0x1b, 0x62, 0x7c, 0x95, 0x11, 0xeb, 0x35, + 0x59, 0xaa, 0xae, 0x57, 0xad, 0x14, 0xfd, 0xbc, 0x3d, 0x5c, 0xaf, 0xdb, 0xb6, 0xd7, 0x41, 0x3d, + 0xd6, 0x55, 0x18, 0x97, 0x71, 0x4d, 0x33, 0x91, 0x8a, 0x3a, 0x19, 0xd0, 0x54, 0x62, 0x91, 0x65, + 0xc8, 0x4b, 0x62, 0x35, 0xd1, 0xce, 0x43, 0x01, 0xd3, 0x42, 0x46, 0x0a, 0x98, 0xf1, 0x1f, 0x8f, + 0xc8, 0x33, 0x81, 0x7d, 0x42, 0xcd, 0xf6, 0xec, 0x36, 0xe6, 0xe0, 0x0b, 0x97, 0xac, 0x72, 0x1b, + 0x88, 0xad, 0xf2, 0x98, 0xaf, 0x80, 0x4e, 0xf2, 0xb1, 0x02, 0xd3, 0x46, 0x69, 0x8e, 0x73, 0x43, + 0xa4, 0x39, 0x7e, 0x4b, 0xcb, 0x11, 0x3c, 0x12, 0x25, 0xa5, 0x64, 0xfb, 0xe4, 0xe0, 0xec, 0xc0, + 0x37, 0xd4, 0x64, 0xbe, 0xa3, 0x51, 0x98, 0x30, 0xa4, 0x1c, 0x90, 0xc6, 0x37, 0xbc, 0xde, 0x8c, + 0x9d, 0x26, 0xe4, 0xf3, 0xf8, 0xbf, 0xd7, 0x90, 0xcf, 0xab, 0x00, 0xe2, 0xec, 0x8e, 0xec, 0x1d, + 0x5e, 0xc1, 0xed, 0x44, 0xd8, 0x3d, 0x07, 0x41, 0xab, 0x4f, 0x4e, 0x10, 0x85, 0xd0, 0xf8, 0x3d, + 0x02, 0x73, 0xf5, 0xfa, 0xbd, 0x8a, 0x63, 0xef, 0x75, 0x5c, 0x3f, 0x70, 0x1a, 0xd5, 0xce, 0xae, + 0xcb, 0x64, 0xfb, 0xf0, 0x7c, 0x51, 0x82, 0xf5, 0x46, 0x67, 0x4b, 0x58, 0xcc, 0xee, 0x8e, 0xab, + 0x9e, 0x27, 0x15, 0xae, 0xfc, 0xee, 0x48, 0x19, 0xc0, 0xe4, 0x70, 0x26, 0x3e, 0xd7, 0x7b, 0x18, + 0x2a, 0x43, 0x18, 0xa1, 0xa0, 0xf8, 0xec, 0x73, 0x90, 0x29, 0xcb, 0x08, 0x4d, 0x4e, 0x58, 0x71, + 0x9d, 0x3a, 0xa7, 0x05, 0x8e, 0x8e, 0x8a, 0xf9, 0x6a, 0x14, 0xd2, 0x0d, 0xee, 0xc3, 0x5d, 0x84, + 0xab, 0x26, 0x76, 0x89, 0x35, 0x70, 0x08, 0x67, 0x34, 0x27, 0xea, 0x61, 0x5f, 0x67, 0x5e, 0x13, + 0xe2, 0xba, 0x81, 0x31, 0x3b, 0x52, 0x9e, 0x68, 0xd4, 0xa4, 0x7a, 0xa9, 0x35, 0xb0, 0x03, 0xf2, + 0xf9, 0xd4, 0x92, 0x70, 0x75, 0x4f, 0x6a, 0xc1, 0xbb, 0x95, 0x4d, 0x83, 0xa7, 0x0f, 0xec, 0x57, + 0xb5, 0x95, 0xb2, 0x15, 0x0c, 0xae, 0x89, 0xfc, 0x93, 0x0c, 0x9c, 0xd3, 0x30, 0xc2, 0xfd, 0xcf, + 0x0f, 0xe3, 0x8b, 0xa4, 0xce, 0xeb, 0x8f, 0x9e, 0xcc, 0xbc, 0x7e, 0x49, 0x6f, 0x4b, 0xb4, 0x43, + 0xab, 0x6d, 0xe8, 0xf7, 0x85, 0xe4, 0x01, 0xcc, 0x61, 0x91, 0x7c, 0x29, 0x62, 0x73, 0x56, 0x3c, + 0x30, 0x2d, 0x44, 0x9f, 0xcd, 0x03, 0x03, 0x60, 0x0a, 0xf8, 0xe5, 0x6f, 0x1f, 0x15, 0xa7, 0x35, + 0x74, 0x19, 0x0e, 0xdb, 0x8a, 0x9e, 0x9b, 0x9c, 0xce, 0xae, 0xab, 0xe5, 0xf7, 0x8f, 0x57, 0x41, + 0xfe, 0xeb, 0x0c, 0x7f, 0x9f, 0xe0, 0xcd, 0xb8, 0xe9, 0xb9, 0xed, 0xb0, 0x5c, 0xda, 0x6a, 0xf6, + 0xe9, 0xb6, 0xd6, 0x93, 0xe9, 0xb6, 0x57, 0xf0, 0x93, 0xf9, 0x9e, 0x60, 0xed, 0x7a, 0x6e, 0x3b, + 0xfa, 0x7c, 0xb5, 0xe3, 0xfa, 0x7e, 0x24, 0xf9, 0x81, 0x0c, 0x9c, 0xd7, 0xd4, 0xa4, 0x6a, 0x6e, + 0x12, 0x11, 0x7e, 0x61, 0x3e, 0x0c, 0xcc, 0x12, 0x15, 0xad, 0x5c, 0x11, 0xf3, 0xff, 0x22, 0x7e, + 0x81, 0x12, 0x07, 0x94, 0x21, 0x59, 0x6d, 0x8e, 0xa5, 0x7c, 0x42, 0xff, 0x5a, 0x88, 0x03, 0x73, + 0x68, 0xb6, 0xa3, 0xd9, 0x14, 0x2f, 0xf4, 0xb7, 0x29, 0x0e, 0xb3, 0x0e, 0x61, 0x46, 0x82, 0xfe, + 0x86, 0xc5, 0x49, 0xae, 0xe4, 0xfb, 0xe0, 0x7c, 0x02, 0x18, 0xae, 0xb6, 0x33, 0x7d, 0x57, 0xdb, + 0xa7, 0x8e, 0x8f, 0x8a, 0xaf, 0xa6, 0xd5, 0x96, 0xb6, 0xd2, 0xfa, 0xd7, 0x40, 0x6c, 0x80, 0xa8, + 0x50, 0xc8, 0x33, 0xe9, 0x13, 0xf4, 0x53, 0x62, 0x7e, 0x28, 0xf8, 0x6c, 0x2f, 0x57, 0xbe, 0x41, + 0x3d, 0xf2, 0x22, 0x24, 0x42, 0x61, 0x4a, 0xc9, 0xc6, 0x70, 0x28, 0xac, 0x47, 0xfa, 0x54, 0xf2, + 0xed, 0xa3, 0xa2, 0x86, 0xcd, 0x6e, 0x58, 0x6a, 0x9a, 0x07, 0x4d, 0x7c, 0x54, 0x11, 0xc9, 0xaf, + 0x67, 0x60, 0x81, 0x01, 0xa2, 0x49, 0x25, 0x1a, 0xb5, 0x38, 0x68, 0xd6, 0xef, 0x3f, 0x99, 0x59, + 0xff, 0x22, 0x7e, 0xa3, 0x3a, 0xeb, 0x13, 0x5d, 0x92, 0xfa, 0x71, 0x38, 0xdb, 0x35, 0x0b, 0x31, + 0x6d, 0xb6, 0x9f, 0x1f, 0x62, 0xb6, 0xf3, 0x01, 0x38, 0x79, 0xb6, 0xf7, 0xad, 0x85, 0x6c, 0xc2, + 0x94, 0xb8, 0x5c, 0xf1, 0x0e, 0x7b, 0x41, 0x8b, 0x0b, 0xad, 0x16, 0xf1, 0x1b, 0xaf, 0x48, 0x56, + 0x91, 0x68, 0xa1, 0xc6, 0x85, 0x74, 0x60, 0x9e, 0xff, 0xd6, 0x95, 0x5d, 0xc5, 0xbe, 0xca, 0xae, + 0x4b, 0xa2, 0x45, 0x17, 0x04, 0xff, 0x98, 0xce, 0x4b, 0x8d, 0xe7, 0x94, 0xc2, 0x98, 0x74, 0x81, + 0x68, 0x60, 0xbe, 0x68, 0x2f, 0x0c, 0x56, 0x71, 0xbd, 0x2a, 0xea, 0x2c, 0xc6, 0xeb, 0x8c, 0xaf, + 0xdc, 0x14, 0xde, 0xc4, 0x86, 0x59, 0x01, 0x75, 0x0f, 0x28, 0xdf, 0xe1, 0x5f, 0xd4, 0x22, 0x6a, + 0xc5, 0x4a, 0xf9, 0xad, 0x4c, 0xd6, 0x84, 0x11, 0xcf, 0x62, 0x1b, 0x7a, 0x9c, 0x1f, 0xb9, 0x07, + 0x73, 0xa5, 0x6e, 0xb7, 0xe5, 0xd0, 0x26, 0xb6, 0xd2, 0xec, 0xb1, 0x36, 0x19, 0x51, 0xbe, 0x37, + 0x9b, 0x17, 0x8a, 0xab, 0xa2, 0xd7, 0x8b, 0x6d, 0x37, 0x09, 0x5a, 0xe3, 0x47, 0x32, 0x89, 0x8f, + 0x26, 0xaf, 0xc3, 0x04, 0xfe, 0x50, 0x82, 0xb4, 0xa0, 0xce, 0x88, 0x7f, 0x22, 0x6a, 0xa3, 0x22, + 0x04, 0x26, 0x2c, 0xa9, 0x81, 0x1a, 0x73, 0x5c, 0x58, 0x12, 0x8a, 0x8a, 0x48, 0x35, 0x51, 0x94, + 0xbe, 0x1e, 0xb9, 0x48, 0xe8, 0x42, 0x5f, 0x0f, 0xe1, 0xe1, 0x61, 0xfc, 0xc3, 0xac, 0x3e, 0xed, + 0xc8, 0x25, 0x45, 0x6e, 0x57, 0x42, 0x45, 0x4a, 0xb9, 0x5d, 0x91, 0xd6, 0xff, 0x5e, 0x06, 0xe6, + 0xef, 0x29, 0x89, 0x42, 0x37, 0x5d, 0x1c, 0x97, 0xc1, 0xa9, 0x33, 0x9f, 0x54, 0x0a, 0x40, 0x35, + 0x43, 0x29, 0x9b, 0x29, 0x38, 0x65, 0xcc, 0xb4, 0xef, 0x41, 0xef, 0x39, 0xfc, 0x30, 0x25, 0x13, + 0x23, 0x47, 0xe7, 0xf0, 0x53, 0xa6, 0xae, 0x30, 0x7e, 0x22, 0x0b, 0x93, 0xca, 0x8a, 0x21, 0x9f, + 0x81, 0x29, 0xb5, 0x5a, 0x55, 0xe1, 0xa8, 0x7e, 0xa5, 0xa9, 0x61, 0xa1, 0xc6, 0x91, 0xda, 0x6d, + 0x4d, 0xe3, 0xc8, 0xd6, 0x05, 0x42, 0x4f, 0x79, 0x13, 0x7a, 0x3f, 0xe5, 0x26, 0x84, 0xb3, 0x5c, + 0xd1, 0x18, 0x0d, 0xbc, 0x0f, 0xbd, 0x93, 0xbc, 0x0f, 0xa1, 0xf2, 0x4a, 0xa1, 0xef, 0x7f, 0x2b, + 0x32, 0x7e, 0x3a, 0x03, 0x85, 0xf8, 0x9a, 0xfe, 0x44, 0x7a, 0xe5, 0x14, 0xaf, 0x4b, 0x3f, 0x9e, + 0x0d, 0x33, 0xb7, 0x48, 0x17, 0xe2, 0xa7, 0xd5, 0x4c, 0xf1, 0x5d, 0xed, 0xe1, 0xe7, 0x59, 0x3d, + 0x1a, 0x9e, 0x1a, 0x7c, 0x23, 0x3d, 0x04, 0xe6, 0xc8, 0xb7, 0xfe, 0x76, 0xf1, 0x19, 0xe3, 0x43, + 0x58, 0x88, 0x77, 0x07, 0x3e, 0xfe, 0x94, 0x60, 0x56, 0x87, 0xc7, 0xf3, 0x3e, 0xc5, 0xa9, 0xcc, + 0x38, 0xbe, 0xf1, 0x07, 0xd9, 0x38, 0x6f, 0x61, 0xb2, 0xc8, 0xf6, 0x28, 0xd5, 0x10, 0x47, 0xec, + 0x51, 0x1c, 0x64, 0xca, 0xb2, 0xd3, 0xe4, 0x5b, 0x0b, 0x1d, 0x61, 0x73, 0xe9, 0x8e, 0xb0, 0xe4, + 0x46, 0xcc, 0x4a, 0x5b, 0x89, 0xda, 0xf4, 0x90, 0xee, 0x58, 0x91, 0xa5, 0x76, 0xcc, 0x38, 0xbb, + 0x0c, 0x0b, 0x5a, 0x08, 0x72, 0x49, 0x3f, 0x1a, 0xe9, 0xfa, 0x03, 0x2c, 0xe0, 0xc4, 0xa9, 0xc8, + 0x64, 0x0d, 0xc6, 0xd9, 0x67, 0xde, 0xb5, 0xbb, 0xe2, 0x4d, 0x87, 0x84, 0x6e, 0xf1, 0xad, 0xf0, + 0x7e, 0xa8, 0x78, 0xc6, 0xb7, 0x28, 0x93, 0x10, 0xd4, 0x89, 0x25, 0x10, 0x8d, 0x7f, 0x93, 0x61, + 0xeb, 0xbf, 0x71, 0xf0, 0x5d, 0x96, 0xb4, 0x8d, 0x35, 0x69, 0x80, 0x45, 0xed, 0x1f, 0x65, 0x79, + 0x2e, 0x1e, 0x31, 0x7d, 0xde, 0x82, 0xb1, 0x4d, 0xdb, 0xdb, 0x13, 0x29, 0xb3, 0x75, 0x2e, 0xbc, + 0x20, 0x8a, 0x29, 0x15, 0xe0, 0x6f, 0x53, 0x10, 0xa8, 0xaa, 0xb3, 0xec, 0x50, 0xaa, 0x33, 0xe5, + 0x5d, 0x20, 0xf7, 0xc4, 0xde, 0x05, 0xbe, 0x27, 0x4c, 0xbb, 0x53, 0x0a, 0x86, 0x88, 0x70, 0x7d, + 0x21, 0x9e, 0xe5, 0x2a, 0x11, 0x8b, 0x3c, 0x62, 0x47, 0x6e, 0xa8, 0x79, 0xb3, 0x14, 0xdf, 0xd2, + 0x13, 0x32, 0x64, 0x19, 0x7f, 0x94, 0xe3, 0x7d, 0x2c, 0x3a, 0xea, 0xa2, 0xe6, 0x77, 0x8e, 0xeb, + 0x24, 0xa6, 0xa7, 0xe4, 0x1e, 0xe8, 0x17, 0x61, 0x84, 0xcd, 0x4d, 0xd1, 0x9b, 0x88, 0xc7, 0xe6, + 0xaf, 0x8a, 0xc7, 0xca, 0xd9, 0x5a, 0xc6, 0x33, 0x49, 0x4d, 0x88, 0x88, 0xc7, 0x96, 0xba, 0x96, + 0x11, 0x83, 0x5c, 0x82, 0x91, 0x0d, 0xb7, 0x29, 0x23, 0xa9, 0x2f, 0x60, 0xf4, 0x11, 0x2d, 0xe3, + 0xea, 0x62, 0xc6, 0x44, 0x0c, 0xd6, 0xd6, 0x30, 0xff, 0x84, 0xda, 0xd6, 0xf6, 0xae, 0x9d, 0x4c, + 0x74, 0xa7, 0x24, 0xbd, 0x59, 0x85, 0x99, 0x6d, 0xa7, 0xd3, 0x74, 0x1f, 0xfa, 0x15, 0xea, 0x1f, + 0x04, 0x6e, 0x57, 0xd8, 0x1b, 0xa3, 0x76, 0xff, 0x21, 0x2f, 0xb1, 0x9a, 0xbc, 0x48, 0x7d, 0x96, + 0xd1, 0x89, 0xc8, 0x0a, 0x4c, 0x6b, 0x11, 0x5c, 0xc5, 0xe3, 0x2a, 0x6a, 0x43, 0xf5, 0xf8, 0xaf, + 0xaa, 0x36, 0x54, 0x23, 0x61, 0xe7, 0xb9, 0xf8, 0x7e, 0xe5, 0x89, 0x35, 0xf1, 0xed, 0x02, 0x87, + 0x5c, 0x87, 0x3c, 0x0f, 0xf3, 0x51, 0xad, 0xa8, 0xcf, 0x64, 0x3e, 0xc2, 0x62, 0x61, 0x72, 0x24, + 0xa2, 0x12, 0xd6, 0xe1, 0xd3, 0x50, 0x10, 0x5b, 0x52, 0x94, 0xab, 0xfd, 0x39, 0x18, 0x29, 0x57, + 0x2b, 0xa6, 0xba, 0x8d, 0x34, 0x9c, 0xa6, 0x67, 0x22, 0x14, 0xbd, 0xfa, 0x36, 0x68, 0xf0, 0xd0, + 0xf5, 0x0e, 0x4c, 0xea, 0x07, 0x9e, 0xc3, 0xf3, 0x69, 0xe2, 0x42, 0xfc, 0x0c, 0x79, 0x07, 0x46, + 0xd1, 0xf0, 0x35, 0x76, 0x32, 0xc4, 0xeb, 0x58, 0x99, 0x16, 0x13, 0x78, 0x14, 0xad, 0x68, 0x4d, + 0x4e, 0x44, 0xde, 0x82, 0x91, 0x0a, 0xed, 0x1c, 0xc6, 0x52, 0xfd, 0x25, 0x88, 0xc3, 0x0d, 0xa1, + 0x49, 0x3b, 0x87, 0x26, 0x92, 0x18, 0x3f, 0x9d, 0x85, 0x33, 0x29, 0x9f, 0x75, 0xff, 0x33, 0x4f, + 0xe9, 0xae, 0xb8, 0xa2, 0xed, 0x8a, 0xf2, 0x7d, 0xbc, 0x6f, 0xc7, 0xa7, 0x6e, 0x92, 0xbf, 0x90, + 0x81, 0x73, 0xfa, 0x04, 0x15, 0x96, 0xee, 0xf7, 0xaf, 0x93, 0xb7, 0x61, 0x6c, 0x8d, 0xda, 0x4d, + 0x2a, 0xf3, 0x7a, 0x9d, 0x09, 0x03, 0xf2, 0xf1, 0x18, 0x06, 0xbc, 0x90, 0xb3, 0x8d, 0x3c, 0x5e, + 0x39, 0x94, 0x54, 0xc4, 0xc7, 0x71, 0xf1, 0xdd, 0x90, 0xf1, 0x44, 0xd2, 0xaa, 0x1a, 0x60, 0x65, + 0xf2, 0xed, 0x0c, 0x3c, 0x3b, 0x80, 0x86, 0x0d, 0x1c, 0x1b, 0x7a, 0x75, 0xe0, 0xf0, 0x44, 0x45, + 0x28, 0x79, 0x0f, 0x66, 0x37, 0x85, 0xf8, 0x2f, 0x87, 0x23, 0x1b, 0xad, 0x17, 0x79, 0x33, 0xb0, + 0xe4, 0xb8, 0xc4, 0x91, 0xb5, 0x40, 0x37, 0xb9, 0x81, 0x81, 0x6e, 0xd4, 0xb8, 0x31, 0x23, 0xc3, + 0xc6, 0x8d, 0xf9, 0x10, 0x16, 0xf4, 0xb6, 0x89, 0xf0, 0xbd, 0x51, 0xd4, 0x9c, 0x4c, 0xff, 0xa8, + 0x39, 0x03, 0x83, 0x84, 0x1a, 0x3f, 0x91, 0x81, 0x82, 0xce, 0xfb, 0x71, 0xc7, 0xf3, 0x5d, 0x6d, + 0x3c, 0x9f, 0x4d, 0x1f, 0xcf, 0xfe, 0x03, 0xf9, 0xaf, 0x33, 0xf1, 0xc6, 0x0e, 0x35, 0x82, 0x06, + 0x8c, 0x55, 0xdc, 0xb6, 0xed, 0x74, 0xd4, 0xd4, 0xff, 0x4d, 0x84, 0x98, 0xa2, 0x64, 0xb8, 0x20, + 0x43, 0x17, 0x60, 0x74, 0xc3, 0xed, 0x94, 0x2a, 0xc2, 0xa4, 0x18, 0xf9, 0x74, 0xdc, 0x8e, 0x65, + 0x37, 0x4d, 0x5e, 0x40, 0xd6, 0x01, 0xea, 0x0d, 0x8f, 0xd2, 0x4e, 0xdd, 0xf9, 0x5e, 0x1a, 0x93, + 0x34, 0x58, 0x0f, 0xb5, 0x7a, 0xb8, 0xb1, 0xf0, 0xa7, 0x53, 0x44, 0xb4, 0x7c, 0xe7, 0x7b, 0xd5, + 0xfd, 0x56, 0xa1, 0xc7, 0x75, 0x25, 0xe2, 0xb0, 0xc5, 0xc6, 0xe1, 0xda, 0x27, 0xb1, 0xae, 0x52, + 0xab, 0xc2, 0x1e, 0xbe, 0x96, 0x3a, 0x1c, 0xbf, 0x9f, 0x81, 0x67, 0x07, 0xd0, 0x3c, 0x81, 0x51, + 0xf9, 0xf3, 0xee, 0x70, 0x0a, 0x10, 0x11, 0x61, 0x26, 0x65, 0xa7, 0x19, 0xf0, 0x5c, 0x7d, 0xd3, + 0x22, 0x93, 0x32, 0x03, 0x68, 0x99, 0x94, 0x19, 0x80, 0x9d, 0xa5, 0x6b, 0xd4, 0xd9, 0xdb, 0xe7, + 0xe6, 0x61, 0xd3, 0x7c, 0x6f, 0xd8, 0x47, 0x88, 0x7a, 0x96, 0x72, 0x1c, 0xe3, 0xdf, 0x8e, 0xc2, + 0x79, 0x93, 0xee, 0x39, 0xec, 0x5e, 0xb2, 0xe5, 0x3b, 0x9d, 0x3d, 0x2d, 0xee, 0x8e, 0x11, 0x5b, + 0xb9, 0x22, 0x49, 0x05, 0x83, 0x84, 0x33, 0xf1, 0x32, 0xe4, 0x99, 0x18, 0xa2, 0x2c, 0x5e, 0x7c, + 0xe3, 0x62, 0xc2, 0x8a, 0x08, 0xec, 0x2c, 0x8b, 0xc9, 0x6b, 0x42, 0x4c, 0x52, 0xd2, 0x08, 0x31, + 0x31, 0xe9, 0x3b, 0x47, 0x45, 0xa8, 0x1f, 0xfa, 0x01, 0xc5, 0x2b, 0xb2, 0x10, 0x95, 0xc2, 0xbb, + 0xcc, 0x48, 0x9f, 0xbb, 0xcc, 0x5d, 0x58, 0x28, 0x35, 0xf9, 0xe9, 0x68, 0xb7, 0x6a, 0x9e, 0xd3, + 0x69, 0x38, 0x5d, 0xbb, 0x25, 0xef, 0xe7, 0xd8, 0xcb, 0x76, 0x58, 0x6e, 0x75, 0x43, 0x04, 0x33, + 0x95, 0x8c, 0x35, 0xa3, 0xb2, 0x51, 0xc7, 0xf0, 0x34, 0xe2, 0xf9, 0x12, 0x9b, 0xd1, 0xec, 0xf8, + 0xd8, 0x0a, 0xdf, 0x0c, 0x8b, 0xf1, 0x16, 0x85, 0x06, 0x01, 0x9b, 0xeb, 0xf5, 0xc8, 0xa5, 0x9a, + 0x67, 0x39, 0xe0, 0x86, 0x05, 0x41, 0xcb, 0x47, 0x53, 0x4c, 0x0d, 0x2f, 0xa2, 0xab, 0xd7, 0xd7, + 0x18, 0x5d, 0x3e, 0x41, 0xe7, 0xfb, 0xfb, 0x2a, 0x1d, 0xc7, 0x23, 0x57, 0xd9, 0x54, 0x68, 0xbb, + 0x01, 0xc5, 0x29, 0x3c, 0x11, 0xdd, 0xb9, 0x3c, 0x84, 0xf2, 0x3b, 0x97, 0x82, 0x42, 0xde, 0x81, + 0xf9, 0xd5, 0xf2, 0xb2, 0x54, 0x3a, 0x57, 0xdc, 0x46, 0x0f, 0x0d, 0x01, 0x00, 0xeb, 0xc3, 0x31, + 0xa4, 0x8d, 0x65, 0xb6, 0x9b, 0xa4, 0xa1, 0x91, 0x8b, 0x30, 0x5e, 0xad, 0xf0, 0xbe, 0x9f, 0x54, + 0x53, 0x79, 0x09, 0xcb, 0x2c, 0x59, 0x48, 0xee, 0x45, 0x97, 0x82, 0xa9, 0x13, 0xa5, 0xf7, 0xf3, + 0x43, 0x5c, 0x08, 0xde, 0x82, 0xe9, 0x15, 0x37, 0xa8, 0x76, 0xfc, 0xc0, 0xee, 0x34, 0x68, 0xb5, + 0xa2, 0xc6, 0xd5, 0xde, 0x71, 0x03, 0xcb, 0x11, 0x25, 0xec, 0xcb, 0x75, 0x4c, 0xf2, 0x39, 0x24, + 0xbd, 0x45, 0x3b, 0xd4, 0x8b, 0xe2, 0x69, 0x8f, 0xf2, 0xbe, 0x65, 0xa4, 0x7b, 0x61, 0x89, 0xa9, + 0x23, 0x8a, 0x34, 0x63, 0x3c, 0x39, 0x68, 0xd9, 0x6d, 0x52, 0x9f, 0xef, 0x16, 0xdf, 0x45, 0x69, + 0xc6, 0x94, 0xb6, 0x0d, 0xd8, 0x41, 0xff, 0x43, 0x4c, 0x33, 0x96, 0xc0, 0x25, 0x9f, 0x83, 0x51, + 0xfc, 0x29, 0xa4, 0xdb, 0xf9, 0x14, 0xb6, 0x91, 0x64, 0xdb, 0x60, 0x98, 0x26, 0x27, 0x20, 0x55, + 0x18, 0x17, 0x17, 0xab, 0xd3, 0x24, 0xcb, 0x11, 0x37, 0x34, 0x3e, 0x33, 0x04, 0xbd, 0xd1, 0x84, + 0x29, 0xb5, 0x42, 0xb6, 0x22, 0xd6, 0x6c, 0x7f, 0x9f, 0x36, 0xd9, 0x2f, 0x91, 0xe7, 0x0e, 0x57, + 0xc4, 0x3e, 0x42, 0x2d, 0xf6, 0x1d, 0xa6, 0x82, 0xc2, 0xce, 0xd4, 0xaa, 0xbf, 0xe5, 0x8b, 0x4f, + 0x11, 0xaa, 0x16, 0x07, 0xd5, 0x76, 0x4d, 0x53, 0x14, 0x19, 0xdf, 0x03, 0x0b, 0x1b, 0xbd, 0x56, + 0xcb, 0xde, 0x69, 0x51, 0x99, 0x07, 0x05, 0x13, 0x8e, 0xaf, 0xc0, 0x68, 0x5d, 0x49, 0x61, 0x1e, + 0xe6, 0xa2, 0x54, 0x70, 0xd0, 0x08, 0x36, 0x83, 0xa1, 0x82, 0x62, 0xc9, 0xcb, 0x39, 0xa9, 0xf1, + 0xbb, 0x19, 0x58, 0x90, 0xe6, 0x02, 0x9e, 0xdd, 0x38, 0x08, 0xf3, 0xd8, 0x5f, 0xd4, 0xe6, 0x1a, + 0x4e, 0xd8, 0xd8, 0x34, 0xe2, 0xb3, 0xee, 0xb6, 0xfc, 0x08, 0x5d, 0x60, 0x49, 0xfb, 0xe0, 0x93, + 0x3e, 0x86, 0xbc, 0x03, 0x93, 0xe2, 0x78, 0x54, 0x02, 0x5c, 0x62, 0x14, 0x31, 0x71, 0xdd, 0x8b, + 0x1b, 0xaf, 0xa8, 0xe8, 0x28, 0x8b, 0xe9, 0x4d, 0x79, 0x5c, 0x19, 0x20, 0x5d, 0x16, 0xd3, 0xeb, + 0x18, 0x30, 0x75, 0x7f, 0x6b, 0x32, 0xde, 0xb7, 0x62, 0xee, 0xde, 0x50, 0x43, 0xda, 0x65, 0xa2, + 0x9b, 0x71, 0x14, 0xd2, 0x4e, 0xbd, 0x19, 0x87, 0xa8, 0xe1, 0x98, 0x64, 0x4f, 0x18, 0x93, 0xf7, + 0xe4, 0x98, 0xe4, 0xfa, 0x4f, 0x8c, 0xf9, 0x01, 0xe3, 0x50, 0x8f, 0x56, 0xc8, 0xc8, 0x50, 0x6a, + 0x95, 0x67, 0x30, 0x76, 0x3f, 0x27, 0x89, 0xef, 0xa2, 0x82, 0x93, 0xaa, 0xab, 0x19, 0x1d, 0x9e, + 0xe9, 0x09, 0x5b, 0xf3, 0xe7, 0x61, 0xaa, 0x14, 0x04, 0x76, 0x63, 0x9f, 0x36, 0x2b, 0x6c, 0x7b, + 0x52, 0xa2, 0x6f, 0xd9, 0x02, 0xae, 0xbe, 0xb1, 0xa9, 0xb8, 0x3c, 0x9a, 0xac, 0xed, 0x0b, 0x63, + 0xda, 0x30, 0x9a, 0x2c, 0x83, 0xe8, 0xd1, 0x64, 0x19, 0x84, 0x5c, 0x85, 0xf1, 0x6a, 0xe7, 0x81, + 0xc3, 0xfa, 0x84, 0x07, 0xe0, 0x42, 0xdd, 0x94, 0xc3, 0x41, 0xea, 0xe6, 0x2a, 0xb0, 0xc8, 0x5b, + 0xca, 0xa5, 0x66, 0x22, 0x52, 0x60, 0x70, 0x95, 0x57, 0x18, 0x61, 0x47, 0xbd, 0xb0, 0x84, 0xb7, + 0x9c, 0x1b, 0x30, 0x2e, 0x35, 0x99, 0x10, 0x29, 0x2d, 0x04, 0x65, 0x32, 0x60, 0x85, 0x44, 0xc6, + 0x9c, 0xe4, 0x4a, 0xbe, 0xbe, 0x49, 0x25, 0x27, 0xb9, 0x92, 0xaf, 0x4f, 0xcb, 0x49, 0xae, 0x64, + 0xee, 0x0b, 0x95, 0x40, 0x53, 0x27, 0x2a, 0x81, 0xee, 0xc3, 0x54, 0xcd, 0xf6, 0x02, 0x87, 0xc9, + 0x28, 0x9d, 0xc0, 0x5f, 0x9c, 0xd6, 0xf4, 0xa6, 0x4a, 0xd1, 0xca, 0x0b, 0x32, 0x2f, 0x76, 0x57, + 0xc1, 0xd7, 0x13, 0x38, 0x47, 0xf0, 0x74, 0x53, 0xda, 0x99, 0xc7, 0x31, 0xa5, 0xc5, 0x4e, 0x45, + 0x5d, 0xd9, 0x6c, 0xa4, 0x91, 0xc1, 0x4b, 0x4b, 0x4c, 0x61, 0x16, 0x22, 0x92, 0x2f, 0xc3, 0x14, + 0xfb, 0xbb, 0xe6, 0xb6, 0x9c, 0x86, 0x43, 0xfd, 0xc5, 0x02, 0x36, 0xee, 0x85, 0xd4, 0xd5, 0x8f, + 0x48, 0x87, 0x75, 0x1a, 0xf0, 0x05, 0x8c, 0x8c, 0xe3, 0x4a, 0x70, 0x8d, 0x1b, 0x79, 0x1f, 0xa6, + 0xd8, 0xec, 0xdb, 0xb1, 0x7d, 0x2e, 0x9a, 0xce, 0x45, 0xc6, 0xd0, 0x4d, 0x01, 0x4f, 0x04, 0x74, + 0x56, 0x09, 0xd8, 0x31, 0x5f, 0xea, 0xf2, 0x0d, 0x92, 0x28, 0xb3, 0xbd, 0x9b, 0xd8, 0x1c, 0x25, + 0x1a, 0xf9, 0x02, 0x4c, 0x95, 0xba, 0xdd, 0x68, 0xc7, 0x99, 0x57, 0x14, 0x61, 0xdd, 0xae, 0x95, + 0xba, 0xeb, 0x68, 0x14, 0xf1, 0x8d, 0x79, 0xe1, 0x54, 0x1b, 0x33, 0x79, 0x23, 0x94, 0xd6, 0xcf, + 0x44, 0x5a, 0x5d, 0x71, 0x71, 0xd4, 0x44, 0x7f, 0x2e, 0xb8, 0x97, 0x61, 0x9a, 0xab, 0x39, 0xa5, + 0x34, 0x73, 0x36, 0xb1, 0x7a, 0x52, 0x84, 0x1a, 0x9d, 0x86, 0xac, 0xc2, 0x0c, 0xf7, 0xf6, 0x6e, + 0x89, 0x48, 0xdb, 0x8b, 0xe7, 0x70, 0xd5, 0x22, 0x17, 0xee, 0x24, 0xde, 0xc2, 0x04, 0x2c, 0xb6, + 0xc6, 0x25, 0x46, 0x64, 0xfc, 0x71, 0x06, 0xce, 0xf5, 0x19, 0xf1, 0x30, 0x0e, 0x73, 0x66, 0x70, + 0x1c, 0x66, 0xb6, 0x73, 0xe8, 0x5a, 0x11, 0x6c, 0xbf, 0x90, 0xb2, 0xd4, 0xf1, 0x92, 0xf2, 0x96, + 0x0b, 0x44, 0xe4, 0x38, 0x12, 0x55, 0xdf, 0x76, 0x51, 0x35, 0x9b, 0x4b, 0x1e, 0x42, 0x02, 0x8f, + 0x7f, 0xd4, 0x8a, 0x71, 0x7c, 0x54, 0x7c, 0x41, 0xa4, 0x50, 0x0a, 0x87, 0xf5, 0x23, 0x57, 0x5b, + 0xc1, 0x29, 0xac, 0x8d, 0xa3, 0x0c, 0x4c, 0x2a, 0xeb, 0x90, 0x5c, 0x50, 0xbc, 0x90, 0x0b, 0x3c, + 0x09, 0x97, 0xc2, 0x21, 0xcb, 0x4f, 0x22, 0x5c, 0x54, 0xd9, 0x93, 0x15, 0xd0, 0x77, 0x99, 0x28, + 0xa4, 0xc4, 0xaa, 0x6e, 0x6b, 0xda, 0x62, 0x13, 0xcb, 0x31, 0x9d, 0xbf, 0xed, 0x07, 0xa5, 0x46, + 0xe0, 0x3c, 0xa0, 0x43, 0x1c, 0x3a, 0x51, 0x3a, 0x7f, 0xdb, 0x0f, 0x2c, 0x1b, 0xc9, 0x12, 0xe9, + 0xfc, 0x43, 0x86, 0xc6, 0x0f, 0x66, 0x00, 0xb6, 0xaa, 0x65, 0x0c, 0x36, 0xff, 0xb8, 0x42, 0x41, + 0x7a, 0x00, 0x5f, 0xc9, 0x7d, 0x80, 0x38, 0xf0, 0x3f, 0x65, 0x60, 0x46, 0x47, 0x23, 0xef, 0xc1, + 0x6c, 0xbd, 0xe1, 0xb9, 0xad, 0xd6, 0x8e, 0xdd, 0x38, 0x58, 0x77, 0x3a, 0x94, 0x87, 0x4e, 0x1d, + 0xe5, 0x67, 0x91, 0x1f, 0x16, 0x59, 0x2d, 0x56, 0x66, 0xc6, 0x91, 0xc9, 0x0f, 0x65, 0x60, 0xba, + 0xbe, 0xef, 0x3e, 0x0c, 0xa3, 0x9d, 0x8a, 0x01, 0xf9, 0x0a, 0x5b, 0xdb, 0xfe, 0xbe, 0xfb, 0x30, + 0xca, 0xe0, 0xa9, 0xd9, 0x8a, 0xbe, 0x3b, 0xdc, 0x33, 0x7e, 0xc3, 0xc5, 0x9b, 0x4c, 0xe0, 0x5f, + 0xd1, 0x2a, 0x31, 0xf5, 0x3a, 0x8d, 0x3f, 0xcb, 0xc0, 0x24, 0xde, 0x79, 0x5a, 0x2d, 0x94, 0xb9, + 0xbe, 0x9b, 0xd2, 0x41, 0x86, 0xed, 0x1a, 0x30, 0xb0, 0x6f, 0xc2, 0x6c, 0x0c, 0x8d, 0x18, 0x30, + 0x56, 0xc7, 0x00, 0x03, 0xaa, 0x82, 0x82, 0x87, 0x1c, 0x30, 0x45, 0x89, 0xb1, 0xaa, 0x90, 0xdd, + 0xbf, 0x86, 0xcf, 0xba, 0xcb, 0x00, 0x8e, 0x04, 0xc9, 0x9b, 0x0d, 0x89, 0x7f, 0xc9, 0xfd, 0x6b, + 0xa6, 0x82, 0x65, 0x6c, 0xc0, 0x58, 0xdd, 0xf5, 0x82, 0x95, 0x43, 0x7e, 0x99, 0xa8, 0x50, 0xbf, + 0xa1, 0xbe, 0xdb, 0x3a, 0xf8, 0x56, 0xd2, 0x30, 0x45, 0x11, 0x29, 0xc2, 0xe8, 0x4d, 0x87, 0xb6, + 0x9a, 0xaa, 0x3d, 0xef, 0x2e, 0x03, 0x98, 0x1c, 0xce, 0x2e, 0x5c, 0x67, 0xa3, 0x9c, 0x2c, 0x91, + 0xe1, 0xf0, 0xe3, 0xae, 0x9b, 0xb2, 0xd6, 0xbf, 0x2f, 0x86, 0x79, 0x10, 0x92, 0x35, 0x0d, 0xe8, + 0xea, 0x7f, 0x98, 0x81, 0xa5, 0xfe, 0x24, 0xaa, 0x2d, 0x72, 0x66, 0x80, 0x2d, 0xf2, 0x2b, 0xf1, + 0x77, 0x46, 0x44, 0x13, 0xef, 0x8c, 0xd1, 0xeb, 0x62, 0x05, 0x4d, 0xc1, 0x1b, 0x54, 0x26, 0x62, + 0xb9, 0x30, 0xe0, 0x9b, 0x11, 0x91, 0x0f, 0x73, 0x80, 0x34, 0xa6, 0xa0, 0x35, 0x7e, 0x73, 0x04, + 0xce, 0xf7, 0xa5, 0x20, 0x6b, 0x4a, 0x7a, 0xa7, 0x99, 0x30, 0xb1, 0x4c, 0x5f, 0xfc, 0x2b, 0xf8, + 0x2f, 0x5a, 0xfb, 0xc5, 0xbd, 0xdd, 0xee, 0x85, 0x69, 0x7d, 0xb2, 0xc8, 0xeb, 0x53, 0x27, 0xf2, + 0xe2, 0xe8, 0xc8, 0x0c, 0x92, 0x19, 0x7e, 0xd0, 0x2f, 0x92, 0x06, 0xb6, 0xd3, 0xf2, 0xd5, 0x65, + 0xd7, 0xe4, 0x20, 0x53, 0x96, 0x45, 0x06, 0xe2, 0x23, 0xe9, 0x06, 0xe2, 0xc6, 0xbf, 0xcd, 0xc0, + 0x44, 0xf8, 0xd9, 0x64, 0x09, 0xce, 0x6e, 0x9a, 0xa5, 0xf2, 0xaa, 0xb5, 0xf9, 0x61, 0x6d, 0xd5, + 0xda, 0xda, 0xa8, 0xd7, 0x56, 0xcb, 0xd5, 0x9b, 0xd5, 0xd5, 0x4a, 0xe1, 0x19, 0x32, 0x07, 0xd3, + 0x5b, 0x1b, 0x77, 0x36, 0xee, 0x6d, 0x6f, 0x58, 0xab, 0xa6, 0x79, 0xcf, 0x2c, 0x64, 0xc8, 0x34, + 0x4c, 0x98, 0x2b, 0xa5, 0xb2, 0xb5, 0x71, 0xaf, 0xb2, 0x5a, 0xc8, 0x92, 0x02, 0x4c, 0x95, 0xef, + 0x6d, 0x6c, 0xac, 0x96, 0x37, 0xab, 0xf7, 0xab, 0x9b, 0x1f, 0x16, 0x72, 0x84, 0xc0, 0x0c, 0x22, + 0xd4, 0xcc, 0xea, 0x46, 0xb9, 0x5a, 0x2b, 0xad, 0x17, 0x46, 0x18, 0x8c, 0xe1, 0x2b, 0xb0, 0xd1, + 0x90, 0xd1, 0x9d, 0xad, 0x95, 0xd5, 0xc2, 0x18, 0x43, 0x61, 0x7f, 0x29, 0x28, 0xe3, 0xac, 0x7a, + 0x44, 0xa9, 0x94, 0x36, 0x4b, 0x2b, 0xa5, 0xfa, 0x6a, 0x21, 0x4f, 0xce, 0xc1, 0xbc, 0x06, 0xb2, + 0xd6, 0xef, 0xdd, 0xaa, 0x6e, 0x14, 0x26, 0xc8, 0x02, 0x14, 0x42, 0x58, 0x65, 0xc5, 0xda, 0xaa, + 0xaf, 0x9a, 0x05, 0x88, 0x43, 0x37, 0x4a, 0x77, 0x57, 0x0b, 0x93, 0xc6, 0xbb, 0xdc, 0x0f, 0x91, + 0x77, 0x35, 0x39, 0x0b, 0xa4, 0xbe, 0x59, 0xda, 0xdc, 0xaa, 0xc7, 0x1a, 0x3f, 0x09, 0xe3, 0xf5, + 0xad, 0x72, 0x79, 0xb5, 0x5e, 0x2f, 0x64, 0x08, 0xc0, 0xd8, 0xcd, 0x52, 0x75, 0x7d, 0xb5, 0x52, + 0xc8, 0x1a, 0x3f, 0x95, 0x81, 0x39, 0x29, 0x01, 0xca, 0x47, 0xa3, 0xc7, 0x5c, 0x8b, 0xef, 0x69, + 0x17, 0x5b, 0xe9, 0x24, 0x16, 0xab, 0x64, 0xc0, 0x32, 0xfc, 0x85, 0x0c, 0x9c, 0x49, 0xc5, 0x26, + 0x1f, 0x42, 0x41, 0x7e, 0xc1, 0x5d, 0x3b, 0x68, 0xec, 0x47, 0xfb, 0xd8, 0x0b, 0xb1, 0x5a, 0x62, + 0x68, 0x5c, 0xad, 0x19, 0x25, 0x9c, 0x4e, 0xb0, 0x19, 0x3e, 0x1d, 0x82, 0xf1, 0xad, 0x0c, 0x9c, + 0xeb, 0x53, 0x0d, 0x29, 0xc3, 0x58, 0x98, 0x18, 0x67, 0x80, 0xc1, 0xdb, 0xc2, 0xb7, 0x8f, 0x8a, + 0x02, 0x11, 0x33, 0xf4, 0xe2, 0x5f, 0xe6, 0x58, 0x98, 0xe9, 0x06, 0xd3, 0xcd, 0xf0, 0xee, 0x3b, + 0x1f, 0xeb, 0x79, 0x51, 0x53, 0x69, 0xbb, 0xbe, 0x32, 0x29, 0xfa, 0x2e, 0x67, 0x3f, 0xf4, 0x31, + 0xdf, 0x8c, 0xf1, 0xb3, 0x19, 0x26, 0xdc, 0xc5, 0x11, 0x99, 0xcc, 0x5b, 0xf2, 0xfd, 0x5e, 0x9b, + 0x9a, 0x6e, 0x8b, 0x96, 0xcc, 0x0d, 0x71, 0x6c, 0xa0, 0xb4, 0x6a, 0x63, 0x01, 0x5e, 0x2b, 0x2c, + 0xdb, 0xeb, 0x68, 0xaf, 0xd5, 0x2a, 0x0d, 0x79, 0x0b, 0x60, 0xf5, 0x51, 0x40, 0xbd, 0x8e, 0xdd, + 0x0a, 0x63, 0xc4, 0xf0, 0xc8, 0x56, 0x02, 0xaa, 0xcb, 0xdb, 0x0a, 0xb2, 0xf1, 0xd7, 0x32, 0x30, + 0x25, 0x2e, 0x4d, 0xa5, 0x16, 0xf5, 0x82, 0xc7, 0x9b, 0x5e, 0x6f, 0x69, 0xd3, 0x2b, 0xf4, 0xef, + 0x50, 0xf8, 0xb3, 0xe2, 0xd4, 0x99, 0xf5, 0xcf, 0x33, 0x50, 0x88, 0x23, 0x92, 0xf7, 0x20, 0x5f, + 0xa7, 0x0f, 0xa8, 0xe7, 0x04, 0x87, 0x62, 0xa3, 0x94, 0x29, 0x04, 0x39, 0x8e, 0x28, 0xe3, 0xf3, + 0xc1, 0x17, 0xbf, 0xcc, 0x90, 0x66, 0xd8, 0xfd, 0x5e, 0x51, 0x7b, 0xe4, 0x9e, 0x94, 0xda, 0xc3, + 0xf8, 0xdf, 0xb3, 0x70, 0xee, 0x16, 0x0d, 0xd4, 0x36, 0x85, 0xe6, 0x05, 0x9f, 0x1e, 0xae, 0x5d, + 0x4a, 0x4b, 0x16, 0x61, 0x1c, 0x8b, 0xe4, 0xf8, 0x9a, 0xf2, 0x27, 0x59, 0x09, 0xe7, 0x75, 0x4e, + 0xcb, 0x51, 0xd6, 0xa7, 0xee, 0x2b, 0x4a, 0xd6, 0xa2, 0x70, 0x5a, 0x5f, 0x84, 0x19, 0x0c, 0xcb, + 0xdf, 0x63, 0xcb, 0x81, 0x36, 0x85, 0xfa, 0x27, 0x6f, 0xc6, 0xa0, 0xe4, 0x35, 0x28, 0x30, 0x48, + 0xa9, 0x71, 0xd0, 0x71, 0x1f, 0xb6, 0x68, 0x73, 0x8f, 0x36, 0xf1, 0x58, 0xcf, 0x9b, 0x09, 0xb8, + 0xe4, 0xb9, 0xd5, 0xe1, 0x57, 0x37, 0xda, 0x44, 0x1d, 0x8d, 0xe0, 0x19, 0x41, 0x97, 0xde, 0x82, + 0xc9, 0x8f, 0x99, 0x81, 0xcc, 0xf8, 0x5f, 0x33, 0xb0, 0x80, 0x8d, 0x53, 0x2a, 0x96, 0xd9, 0x61, + 0x65, 0x6f, 0x29, 0x49, 0x79, 0x6c, 0x06, 0xd2, 0x97, 0x42, 0xd8, 0x8b, 0x91, 0x4e, 0x28, 0x3b, + 0x84, 0x4e, 0xa8, 0x7e, 0x9a, 0x4c, 0xf8, 0x43, 0xaa, 0xb4, 0x6e, 0x8f, 0xe4, 0x73, 0x85, 0x91, + 0x68, 0xc8, 0x8d, 0x1f, 0xca, 0xc2, 0xb8, 0x49, 0x31, 0x45, 0x38, 0xb9, 0x08, 0xe3, 0x1b, 0x6e, + 0x40, 0xfd, 0xbb, 0x5a, 0x3e, 0xf8, 0x0e, 0x03, 0x59, 0xed, 0xa6, 0x29, 0x0b, 0xd9, 0x84, 0xaf, + 0x79, 0x6e, 0xb3, 0xd7, 0x08, 0xd4, 0x09, 0xdf, 0xe5, 0x20, 0x53, 0x96, 0x91, 0xd7, 0x61, 0x42, + 0x70, 0x0e, 0x1f, 0x75, 0xd1, 0x76, 0xd9, 0xa3, 0x61, 0x8a, 0xf9, 0x08, 0x01, 0x65, 0x5a, 0x2e, + 0x60, 0x8c, 0x28, 0x32, 0x6d, 0x42, 0x66, 0x90, 0xa2, 0xfa, 0xe8, 0x00, 0x51, 0xfd, 0xd3, 0x30, + 0x56, 0xf2, 0x7d, 0x1a, 0xc8, 0x28, 0x0a, 0x53, 0x61, 0xd8, 0x38, 0x9f, 0x06, 0x9c, 0xb1, 0x8d, + 0xe5, 0xa6, 0xc0, 0x33, 0xfe, 0x4d, 0x16, 0x46, 0xf1, 0x4f, 0x7c, 0x32, 0xf5, 0x1a, 0xfb, 0xda, + 0x93, 0xa9, 0xd7, 0xd8, 0x37, 0x11, 0x4a, 0xae, 0xa1, 0xa6, 0x42, 0xe6, 0x8f, 0x12, 0xad, 0x47, + 0x15, 0x7c, 0x33, 0x02, 0x9b, 0x2a, 0x4e, 0xf8, 0xc2, 0x9f, 0x4b, 0x8d, 0x9d, 0x72, 0x16, 0xb2, + 0xf7, 0xea, 0xa2, 0xc5, 0x18, 0x91, 0xcb, 0xf5, 0xcd, 0xec, 0xbd, 0x3a, 0xf6, 0xc6, 0x5a, 0x69, + 0xf9, 0xcd, 0x1b, 0xa2, 0xa1, 0xbc, 0x37, 0xf6, 0xed, 0xe5, 0x37, 0x6f, 0x98, 0xa2, 0x84, 0xf5, + 0x2f, 0x7e, 0x33, 0x3e, 0xbc, 0x72, 0x9f, 0x7f, 0xec, 0x5f, 0x6c, 0x1b, 0x3e, 0xb2, 0x9a, 0x11, + 0x02, 0x59, 0x86, 0x49, 0x11, 0x6b, 0x02, 0xf1, 0x95, 0x58, 0x10, 0x22, 0x16, 0x05, 0xa7, 0x50, + 0x91, 0xf8, 0x13, 0x9c, 0x18, 0x20, 0x99, 0xe5, 0x56, 0x3c, 0xc1, 0xc9, 0x21, 0xf4, 0x4d, 0x05, + 0x85, 0x7d, 0x12, 0x7f, 0xc3, 0x8b, 0x7c, 0xf9, 0x67, 0x94, 0xa0, 0x05, 0x98, 0x66, 0x21, 0x44, + 0x30, 0x7e, 0x39, 0x0b, 0xf9, 0x5a, 0xab, 0xb7, 0xe7, 0x74, 0xee, 0x5f, 0x23, 0x04, 0xf0, 0x1a, + 0x27, 0xf3, 0x70, 0xb0, 0xbf, 0xc9, 0x79, 0xc8, 0xcb, 0x9b, 0x9b, 0xdc, 0x90, 0x7c, 0x71, 0x6b, + 0x5b, 0x04, 0x39, 0xee, 0x22, 0xf4, 0x9a, 0xfc, 0x49, 0xae, 0x41, 0x78, 0xff, 0xea, 0x77, 0x51, + 0x1b, 0x61, 0x8b, 0xc5, 0x0c, 0xd1, 0xc8, 0x1b, 0x80, 0x87, 0x84, 0xb8, 0x3c, 0x48, 0x85, 0x36, + 0xff, 0x34, 0x21, 0xa7, 0x70, 0x12, 0x44, 0x23, 0xd7, 0x41, 0x4c, 0x4c, 0x91, 0x4d, 0xfd, 0x8c, + 0x4e, 0xc0, 0xf3, 0x53, 0x4a, 0x12, 0x81, 0x4a, 0xde, 0x81, 0xc9, 0x86, 0x47, 0xf1, 0xd5, 0xd1, + 0x6e, 0x45, 0x49, 0xd2, 0x55, 0xca, 0x72, 0x54, 0x7e, 0xff, 0x9a, 0xa9, 0xa2, 0x1b, 0xff, 0x5b, + 0x1e, 0xa6, 0xd4, 0xef, 0x21, 0x26, 0xcc, 0xfb, 0x2d, 0x76, 0x77, 0x17, 0xc6, 0x66, 0x5d, 0x2c, + 0x14, 0xc7, 0xe9, 0x05, 0xfd, 0x83, 0x18, 0x1e, 0xb7, 0x3c, 0x93, 0x41, 0x32, 0xd6, 0x9e, 0x31, + 0xe7, 0xfc, 0x08, 0xcc, 0xf1, 0x48, 0x09, 0xf2, 0x6e, 0xd7, 0xdf, 0xa3, 0x1d, 0x47, 0xbe, 0xb7, + 0xbc, 0xa4, 0x31, 0xba, 0x27, 0x0a, 0x13, 0xbc, 0x42, 0x32, 0xf2, 0x26, 0x8c, 0xb9, 0x5d, 0xda, + 0xb1, 0x1d, 0x71, 0xc6, 0x3d, 0x1b, 0x63, 0x40, 0x3b, 0xa5, 0xaa, 0x42, 0x28, 0x90, 0xc9, 0x55, + 0x18, 0x71, 0x0f, 0xc2, 0xf1, 0x3a, 0xaf, 0x13, 0x1d, 0x04, 0xb6, 0x42, 0x82, 0x88, 0x8c, 0xe0, + 0x23, 0xbb, 0xbd, 0x2b, 0x46, 0x4c, 0x27, 0xb8, 0x6d, 0xb7, 0x77, 0x55, 0x02, 0x86, 0x48, 0xde, + 0x07, 0xe8, 0xda, 0x7b, 0xd4, 0xb3, 0x9a, 0xbd, 0xe0, 0x50, 0x8c, 0xdb, 0x0b, 0x1a, 0x59, 0x8d, + 0x15, 0x57, 0x7a, 0xc1, 0xa1, 0x42, 0x3b, 0xd1, 0x95, 0x40, 0x52, 0x02, 0x68, 0xdb, 0x41, 0x40, + 0xbd, 0xb6, 0x2b, 0xac, 0xfd, 0xa2, 0x20, 0x88, 0x9c, 0xc1, 0xdd, 0xb0, 0x58, 0xe1, 0xa0, 0x10, + 0xe1, 0x47, 0x3b, 0x9e, 0x2d, 0x72, 0xda, 0xc7, 0x3e, 0xda, 0xf1, 0xb4, 0x56, 0x32, 0x44, 0xf2, + 0x39, 0x18, 0x6f, 0x3a, 0xfe, 0xff, 0xc7, 0xde, 0xd7, 0xc5, 0x46, 0x72, 0x1c, 0x07, 0xdf, 0xec, + 0x2e, 0xc9, 0x65, 0xf1, 0x6f, 0xd8, 0xc7, 0x3b, 0x52, 0xbc, 0x3f, 0xdd, 0xe8, 0x74, 0xbe, 0x5b, + 0x59, 0xb2, 0xee, 0xf4, 0xc9, 0xd2, 0xc9, 0x96, 0xe4, 0xe1, 0xee, 0x90, 0xdc, 0xbb, 0xfd, 0xf3, + 0xcc, 0x92, 0xe7, 0xb3, 0x6c, 0x8f, 0xe7, 0x76, 0x87, 0xe4, 0x58, 0xcb, 0x9d, 0xd5, 0xce, 0xae, + 0xce, 0x67, 0x7c, 0x40, 0x6c, 0x04, 0xb1, 0x81, 0xfc, 0x39, 0x71, 0x12, 0x44, 0xf0, 0x8b, 0x03, + 0x44, 0x48, 0xf2, 0xe0, 0xbc, 0x07, 0xf1, 0x93, 0xdf, 0x0c, 0x18, 0x06, 0x0c, 0xe4, 0xcd, 0x09, + 0x84, 0x44, 0x40, 0x82, 0x20, 0xc9, 0x5b, 0x90, 0x3c, 0x18, 0x08, 0x10, 0x74, 0x75, 0xf7, 0x4c, + 0xcf, 0xcf, 0xee, 0xf1, 0x2c, 0x29, 0x89, 0x01, 0x3f, 0x91, 0x5b, 0x5d, 0x55, 0xd3, 0xff, 0x5d, + 0x5d, 0xd5, 0x55, 0xd5, 0xf1, 0x87, 0x5d, 0x1e, 0x3d, 0xe5, 0x7c, 0x8c, 0xa6, 0xc2, 0xca, 0x24, + 0x32, 0x81, 0x4e, 0x6b, 0xcb, 0x83, 0xa0, 0x36, 0xfc, 0x07, 0xa8, 0xe6, 0x4f, 0xd6, 0xd6, 0x0a, + 0x8b, 0xe5, 0xda, 0x46, 0x44, 0x74, 0x28, 0x0f, 0xbd, 0x51, 0xcf, 0xb9, 0xcf, 0xed, 0xdc, 0xf1, + 0xa1, 0xdc, 0xc1, 0x22, 0x79, 0x28, 0x19, 0x32, 0xb9, 0x05, 0x45, 0xb7, 0x3f, 0x1a, 0x3a, 0xb6, + 0xd7, 0xe5, 0x4e, 0x95, 0xf1, 0x4a, 0xd3, 0x03, 0xd8, 0xa9, 0x56, 0xe4, 0x4a, 0x23, 0x7e, 0xb5, + 0x4b, 0xfb, 0x27, 0xe8, 0x78, 0xc7, 0xdc, 0x17, 0x32, 0xde, 0x3f, 0x56, 0xb9, 0x5a, 0x97, 0xfb, + 0x87, 0x22, 0x92, 0xd7, 0x60, 0x8e, 0xae, 0xdf, 0xae, 0x7f, 0xc8, 0x03, 0x52, 0x68, 0xf1, 0xfe, + 0x61, 0x65, 0xa9, 0xe9, 0x2a, 0x88, 0xe8, 0x42, 0x76, 0x1e, 0x04, 0xb6, 0xd7, 0xe1, 0x41, 0x26, + 0xe2, 0xcb, 0x51, 0xbf, 0x6b, 0x55, 0xcb, 0x12, 0xd9, 0x8c, 0xf3, 0x20, 0xa8, 0x76, 0xc8, 0x4d, + 0x98, 0xc1, 0x14, 0x15, 0x3c, 0x10, 0x66, 0x9c, 0x06, 0x93, 0x53, 0xc8, 0x34, 0x88, 0x4a, 0x07, + 0xf2, 0x38, 0x40, 0xf7, 0x12, 0x9e, 0x28, 0x22, 0xde, 0x27, 0x75, 0x0b, 0x7d, 0x4e, 0xe4, 0x2a, + 0x72, 0x74, 0x5a, 0xc5, 0xbe, 0x3b, 0xb2, 0xbd, 0xb7, 0x78, 0xaa, 0x87, 0xf8, 0xe7, 0x1a, 0xee, + 0xa8, 0xfa, 0x59, 0xf9, 0x73, 0x7d, 0x77, 0x54, 0x7d, 0x8b, 0x5c, 0x04, 0x88, 0x4c, 0xff, 0xcc, + 0x50, 0x63, 0x4a, 0x90, 0x57, 0x0a, 0xff, 0xfc, 0x27, 0x97, 0x94, 0x2d, 0x80, 0xa2, 0x08, 0xab, + 0xa3, 0xd5, 0xe0, 0x89, 0x89, 0x9b, 0x05, 0xb9, 0x0e, 0xea, 0x81, 0xc3, 0x55, 0x85, 0x9d, 0x23, + 0xa7, 0xdf, 0x77, 0x7b, 0x7c, 0x9b, 0x5e, 0x11, 0xf0, 0x32, 0x03, 0x33, 0xce, 0xda, 0xeb, 0xb0, + 0x96, 0x35, 0x4b, 0xc8, 0x65, 0x58, 0x94, 0x23, 0x08, 0x71, 0x26, 0x0b, 0xce, 0xc0, 0x13, 0x31, + 0x84, 0x38, 0x83, 0x1f, 0x28, 0x70, 0x7e, 0xda, 0x9e, 0x43, 0x36, 0xa1, 0x38, 0x18, 0x7a, 0x3e, + 0xca, 0xb6, 0x3c, 0x45, 0x83, 0xf8, 0x8d, 0xd9, 0x17, 0x50, 0x08, 0x1b, 0x39, 0x87, 0xdc, 0x2b, + 0xc4, 0x9c, 0x47, 0x48, 0xdb, 0x39, 0x0c, 0xc8, 0x33, 0xb0, 0xda, 0x75, 0x0f, 0x9c, 0x71, 0x6f, + 0x64, 0x07, 0x9d, 0x23, 0xb7, 0x8b, 0x7e, 0x5b, 0xf8, 0xda, 0xcf, 0x54, 0x79, 0x81, 0x25, 0xe0, + 0xa9, 0x1a, 0xcf, 0x4c, 0xa8, 0xf1, 0xed, 0x42, 0x51, 0x51, 0x73, 0x26, 0x3e, 0xaf, 0xd2, 0xbe, + 0x9e, 0x83, 0x8d, 0x49, 0x8b, 0x8c, 0xbc, 0x9a, 0xd5, 0x07, 0xcc, 0xda, 0x21, 0xc3, 0x65, 0x6b, + 0x87, 0xf4, 0x35, 0x72, 0x13, 0x42, 0xaf, 0xab, 0x47, 0x45, 0x50, 0x10, 0x30, 0x4a, 0x33, 0x70, + 0x82, 0xe0, 0x01, 0xdd, 0x47, 0xf2, 0x52, 0x14, 0x5e, 0x0e, 0x93, 0x69, 0x04, 0x8c, 0xbc, 0x04, + 0xd0, 0xe9, 0xf9, 0x81, 0x8b, 0x8f, 0x0a, 0xb8, 0x80, 0xc2, 0xde, 0x92, 0x87, 0x50, 0xd9, 0x8a, + 0x8c, 0xd0, 0xb2, 0xdf, 0x75, 0xf9, 0x00, 0x3a, 0xb0, 0x3e, 0x61, 0x57, 0xa5, 0xc3, 0x13, 0xa5, + 0xb4, 0x17, 0x09, 0xb2, 0xc6, 0x61, 0x62, 0xfb, 0x64, 0x8f, 0xe7, 0x26, 0xcd, 0x91, 0x87, 0x40, + 0xd2, 0x5b, 0x27, 0xe5, 0xce, 0x5f, 0x44, 0x8f, 0x87, 0x21, 0x77, 0x06, 0xd9, 0x1b, 0xf6, 0xc8, + 0x25, 0x58, 0x10, 0x09, 0x30, 0xe9, 0x05, 0x80, 0x31, 0x07, 0x0e, 0xba, 0xe3, 0xe2, 0xe4, 0xc1, + 0x30, 0xab, 0xe8, 0x5b, 0xc7, 0x45, 0x8b, 0x79, 0x84, 0xb4, 0x1f, 0x0e, 0x44, 0xeb, 0xce, 0x8b, + 0xf9, 0x1d, 0x3f, 0xd0, 0x78, 0xe9, 0x1f, 0x29, 0x62, 0xf8, 0xd3, 0x27, 0xc2, 0xa3, 0xea, 0x47, + 0x00, 0x5d, 0x9b, 0x78, 0xc5, 0xf0, 0x7f, 0x2a, 0xea, 0x88, 0x55, 0xc7, 0x45, 0x1d, 0xfe, 0x93, + 0x5c, 0x85, 0x95, 0x21, 0x7b, 0xfc, 0x3a, 0xf2, 0x79, 0x7f, 0xb2, 0x64, 0x23, 0x4b, 0x0c, 0xdc, + 0xf6, 0xb1, 0x4f, 0x79, 0xbd, 0x6e, 0x87, 0x1d, 0x26, 0x1d, 0x90, 0xe4, 0x39, 0x98, 0xa7, 0x07, + 0x24, 0x86, 0xe7, 0x49, 0xf8, 0x54, 0x20, 0x1e, 0x8a, 0x1b, 0x66, 0xf1, 0x2b, 0xfc, 0x7f, 0xce, + 0xeb, 0x9d, 0x9c, 0x60, 0x26, 0x1f, 0xcf, 0x64, 0x1d, 0xe6, 0xfc, 0xe1, 0xa1, 0xd4, 0xb4, 0x59, + 0x7f, 0x78, 0x48, 0xdb, 0x75, 0x0d, 0x54, 0xe6, 0xe2, 0xc3, 0x42, 0x2d, 0x04, 0x0f, 0xfb, 0xec, + 0xfe, 0x5e, 0x34, 0x97, 0x19, 0x1c, 0xb3, 0xfc, 0x3f, 0xec, 0x77, 0x28, 0x66, 0x10, 0xf8, 0xb6, + 0x1c, 0x95, 0x8b, 0x37, 0x7b, 0x39, 0x08, 0xfc, 0x28, 0x3c, 0x57, 0x97, 0x6c, 0xc1, 0x12, 0xe5, + 0x13, 0xc6, 0x06, 0xe3, 0xd2, 0xc3, 0x85, 0xb4, 0xf4, 0xf0, 0xb0, 0xdf, 0x11, 0x55, 0x34, 0x17, + 0x03, 0xe9, 0x17, 0xb9, 0x03, 0xaa, 0x24, 0x66, 0xa1, 0xcf, 0x67, 0xe2, 0x21, 0x76, 0xc4, 0x46, + 0x12, 0xcf, 0xaa, 0xfd, 0x03, 0xdf, 0x5c, 0xe9, 0xc4, 0x01, 0xbc, 0x6b, 0xbe, 0xa7, 0x88, 0xbd, + 0x34, 0x83, 0x88, 0x68, 0xb0, 0x74, 0xe4, 0x04, 0x76, 0x10, 0x1c, 0xb3, 0x87, 0x65, 0x3c, 0x1a, + 0xf1, 0xc2, 0x91, 0x13, 0x58, 0xc1, 0xb1, 0xc8, 0x76, 0x72, 0x86, 0xe2, 0xf8, 0xce, 0x78, 0x74, + 0x64, 0xcb, 0x42, 0x23, 0xeb, 0xb1, 0xd3, 0x47, 0x4e, 0xd0, 0xa4, 0x65, 0x12, 0x6f, 0x72, 0x05, + 0x96, 0x91, 0x6f, 0xc7, 0x13, 0x8c, 0x31, 0x5c, 0x86, 0xb9, 0x48, 0x19, 0x77, 0x3c, 0xc6, 0x99, + 0xd7, 0xf0, 0xcf, 0xf3, 0x70, 0x36, 0xbb, 0x77, 0x70, 0x7a, 0xd2, 0x3e, 0x45, 0xc7, 0x3e, 0x5e, + 0xb7, 0x79, 0x0a, 0x61, 0xa1, 0x4e, 0xb2, 0x06, 0x27, 0x97, 0x39, 0x38, 0x25, 0x58, 0x45, 0x46, + 0x5c, 0x3c, 0xed, 0x79, 0xc1, 0x88, 0x47, 0xf0, 0x30, 0x57, 0x68, 0x01, 0xdb, 0xcf, 0x6b, 0x14, + 0x4c, 0x9e, 0x86, 0x65, 0xb1, 0x23, 0xfb, 0x0f, 0xfa, 0xf4, 0xc3, 0x6c, 0x3b, 0x5e, 0xe2, 0xd0, + 0x26, 0x02, 0xc9, 0x19, 0x98, 0x75, 0x06, 0x03, 0xfa, 0x49, 0xb6, 0x0b, 0xcf, 0x38, 0x83, 0x01, + 0xcb, 0xc8, 0x83, 0x6e, 0x8c, 0xf6, 0x01, 0x3e, 0x2d, 0xe2, 0xef, 0x18, 0xcd, 0x45, 0x04, 0xb2, + 0xe7, 0x46, 0x01, 0x5d, 0xf7, 0x94, 0x56, 0xa0, 0xcc, 0x21, 0x0a, 0x38, 0x83, 0x10, 0xe1, 0x09, + 0x28, 0x0a, 0x23, 0x37, 0xf3, 0xc6, 0x30, 0xe7, 0x1c, 0x6e, 0xe0, 0x7e, 0x11, 0xd6, 0xbb, 0x5e, + 0x80, 0x93, 0x97, 0x35, 0x69, 0x30, 0xe0, 0x8e, 0x93, 0x2c, 0xb2, 0xaf, 0xb9, 0xc6, 0x8b, 0x69, + 0x4f, 0xea, 0x83, 0x41, 0xe8, 0x3e, 0xb9, 0x29, 0xc8, 0xee, 0x7b, 0x2c, 0x5e, 0x19, 0x7b, 0x94, + 0x89, 0x93, 0x1f, 0x90, 0x72, 0x83, 0x63, 0x6c, 0xc9, 0x08, 0x94, 0x0d, 0x1f, 0xa9, 0x97, 0x61, + 0x85, 0x0b, 0x79, 0xfc, 0x80, 0xc5, 0x96, 0xf0, 0xe5, 0x4f, 0x6f, 0x5f, 0x3c, 0x83, 0x12, 0x70, + 0x50, 0xb5, 0x2b, 0x36, 0xa1, 0xbf, 0x53, 0xe0, 0x4c, 0xa6, 0x94, 0x48, 0xbe, 0x0c, 0xcc, 0xcb, + 0x6c, 0xe4, 0xdb, 0x43, 0xb7, 0xe3, 0x0d, 0x3c, 0x0c, 0xdb, 0xc1, 0xb4, 0xa8, 0x37, 0xa7, 0xc9, + 0x97, 0xe8, 0xb1, 0xd6, 0xf6, 0xcd, 0x90, 0x88, 0xa9, 0x77, 0xd4, 0x61, 0x02, 0xbc, 0xf9, 0x06, + 0x9c, 0xc9, 0x44, 0xcd, 0x50, 0xbb, 0x7c, 0x3c, 0x9e, 0xbf, 0x5a, 0xd8, 0xc5, 0x12, 0x8d, 0x96, + 0xd4, 0x31, 0xbc, 0x79, 0x3f, 0x0c, 0x9b, 0x97, 0x90, 0x27, 0x89, 0x91, 0xdc, 0x15, 0xb2, 0xae, + 0x44, 0x82, 0x68, 0xf2, 0xc6, 0xf0, 0x06, 0x9c, 0xe1, 0x53, 0xf7, 0x70, 0xe8, 0x0c, 0x8e, 0x22, + 0x76, 0xac, 0xa2, 0x1f, 0xcb, 0x62, 0xc7, 0xe6, 0xf4, 0x0e, 0xc5, 0x0f, 0xb9, 0x9e, 0x76, 0xd2, + 0x40, 0xde, 0x86, 0x6f, 0xe4, 0xc4, 0x46, 0x91, 0x51, 0x9d, 0x8c, 0x45, 0xa1, 0x64, 0x2d, 0x8a, + 0x93, 0xaf, 0xc8, 0x06, 0x10, 0x79, 0xab, 0x63, 0x8a, 0x56, 0xfe, 0x86, 0x4b, 0x5c, 0x0d, 0x78, + 0x45, 0xa4, 0x8d, 0xc5, 0x62, 0xf9, 0x43, 0x57, 0x3b, 0x49, 0x10, 0x39, 0x07, 0xf3, 0x61, 0x8a, + 0x6e, 0x7e, 0xec, 0x14, 0x19, 0xa0, 0xda, 0x25, 0x4f, 0xc2, 0x22, 0xbb, 0x05, 0xc4, 0x56, 0x2c, + 0x20, 0x4c, 0xa7, 0xcb, 0x56, 0xf4, 0x81, 0x02, 0x4f, 0x3e, 0xaa, 0x0f, 0xc9, 0x5d, 0x38, 0x8b, + 0x2f, 0x49, 0x02, 0x3f, 0x1c, 0x06, 0xbb, 0xe3, 0x74, 0x8e, 0x5c, 0x3e, 0x6b, 0xb5, 0xcc, 0xc1, + 0x18, 0x0c, 0x2c, 0xab, 0x29, 0x8d, 0xc3, 0x60, 0x60, 0x05, 0xbe, 0xf8, 0x5d, 0xa6, 0xe4, 0xbc, + 0x0e, 0x5d, 0x38, 0x37, 0x85, 0x52, 0xda, 0x76, 0x14, 0x79, 0xdb, 0xb9, 0x06, 0xea, 0x81, 0xdb, + 0xa5, 0x12, 0xb5, 0xdb, 0xc5, 0xaa, 0xbd, 0x7d, 0x93, 0x25, 0xa5, 0x37, 0x97, 0x43, 0xb8, 0x15, + 0xf8, 0xfb, 0x37, 0xf9, 0x57, 0x8e, 0xc5, 0x81, 0x29, 0xdf, 0x64, 0xc8, 0x73, 0x70, 0x3a, 0x11, + 0x12, 0x25, 0xf2, 0xb1, 0x37, 0x57, 0x69, 0x51, 0x3c, 0x80, 0xd6, 0x65, 0x58, 0x14, 0xb3, 0x62, + 0x18, 0xba, 0xde, 0x99, 0x0b, 0x1c, 0x46, 0x57, 0x1d, 0xff, 0xdc, 0x58, 0x34, 0x2a, 0xf3, 0x12, + 0x74, 0x02, 0x49, 0x9c, 0x3c, 0x0b, 0x24, 0x94, 0xfa, 0xc3, 0x8d, 0x82, 0x7f, 0x70, 0x55, 0x94, + 0x84, 0x2b, 0x9c, 0x7f, 0xf6, 0x2f, 0x67, 0xe0, 0x74, 0xc6, 0xed, 0x89, 0x5e, 0x21, 0xbc, 0xfe, + 0xc8, 0x3d, 0x64, 0x17, 0x10, 0xb9, 0x91, 0x2b, 0x12, 0x9c, 0xab, 0xc4, 0x66, 0x59, 0xd2, 0x75, + 0xfe, 0x2d, 0xfe, 0x8b, 0x6e, 0x1e, 0xce, 0x50, 0x68, 0x7b, 0xe8, 0xbf, 0xa4, 0x0a, 0xab, 0x98, + 0x49, 0x22, 0xf0, 0x7c, 0x4c, 0x48, 0x81, 0x22, 0x4c, 0x21, 0x76, 0xbf, 0xc2, 0x5a, 0xb4, 0x24, + 0x24, 0x2a, 0xc3, 0x98, 0xea, 0x20, 0x01, 0x21, 0x9f, 0x82, 0x4d, 0xe9, 0xa4, 0xb2, 0x13, 0x2b, + 0x0f, 0x1f, 0xd7, 0x9b, 0xeb, 0x4e, 0x78, 0x66, 0x55, 0x62, 0x6b, 0x70, 0x0b, 0x2e, 0xe2, 0x20, + 0x7a, 0xdd, 0x81, 0x9d, 0x4a, 0x3d, 0x82, 0x4d, 0x65, 0xb1, 0xfa, 0x37, 0x29, 0x56, 0xb5, 0x3b, + 0x48, 0x64, 0x21, 0xc1, 0x56, 0xd7, 0x32, 0x57, 0xe7, 0x1c, 0xae, 0xce, 0x0b, 0x72, 0x63, 0x4e, + 0xb4, 0x36, 0x0f, 0x61, 0x35, 0x94, 0xb3, 0xc2, 0x43, 0xaf, 0x18, 0x4b, 0xc0, 0x8e, 0xcc, 0x84, + 0xd4, 0xc5, 0x4e, 0x41, 0x16, 0x1e, 0x20, 0x45, 0x28, 0x07, 0xc1, 0x18, 0xc7, 0x08, 0x02, 0x52, + 0x83, 0x35, 0x7a, 0x83, 0xe6, 0x09, 0x2f, 0x83, 0xf0, 0x5b, 0xf3, 0xe9, 0x6f, 0x09, 0xdb, 0x0e, + 0x23, 0x35, 0x89, 0xf3, 0x20, 0xe0, 0x79, 0x30, 0x03, 0xc1, 0xed, 0x2b, 0x40, 0xd8, 0x51, 0x1e, + 0xab, 0x37, 0x3c, 0x8a, 0x17, 0xcf, 0x96, 0x99, 0xa2, 0x94, 0x43, 0x79, 0x61, 0xa9, 0x54, 0x73, + 0x3e, 0x5f, 0x7f, 0x43, 0x81, 0xd3, 0x19, 0x1c, 0x89, 0x06, 0x39, 0xb1, 0xe0, 0xd3, 0x6f, 0x94, + 0x76, 0x4f, 0x99, 0x39, 0xaf, 0x4b, 0x6e, 0x01, 0x60, 0x96, 0xc9, 0xa1, 0x7b, 0xe8, 0x7e, 0x55, + 0x4e, 0xb1, 0x1f, 0x41, 0x63, 0x34, 0xf3, 0xa8, 0xf7, 0xa5, 0x60, 0x7e, 0x01, 0x9f, 0x87, 0x39, + 0xaf, 0xdf, 0xe9, 0x8d, 0xbb, 0xae, 0xf6, 0x7d, 0x51, 0x8f, 0xf8, 0x88, 0x90, 0x36, 0x70, 0xe3, + 0x20, 0x1f, 0xbd, 0xab, 0x93, 0x47, 0x4f, 0xb6, 0xb9, 0xf0, 0xd0, 0x10, 0x08, 0x90, 0x2d, 0x0b, + 0x0c, 0xf2, 0x01, 0xac, 0x21, 0xbc, 0xdb, 0xde, 0x80, 0x33, 0x99, 0x2b, 0x8b, 0x8a, 0x51, 0xf8, + 0xc6, 0x30, 0xba, 0x01, 0xcc, 0xd1, 0xdf, 0xf4, 0x0a, 0x70, 0x19, 0x16, 0xef, 0xbb, 0xce, 0xd0, + 0x1d, 0x72, 0xf9, 0x94, 0x6f, 0x5d, 0x0c, 0x26, 0x8b, 0xa7, 0xdd, 0xf8, 0x16, 0xc2, 0xd5, 0xa9, + 0xa4, 0x0e, 0xa7, 0xd9, 0x10, 0x7b, 0xc7, 0x78, 0xe5, 0xe1, 0x2a, 0x58, 0x25, 0x26, 0xf4, 0x23, + 0x09, 0x0a, 0x60, 0x55, 0xc4, 0x62, 0xd4, 0xe6, 0xea, 0x61, 0x12, 0x44, 0x4f, 0x9e, 0xb3, 0xd9, + 0xd8, 0x64, 0x0b, 0x16, 0x18, 0x73, 0x76, 0xf9, 0x65, 0xb6, 0xb3, 0xcb, 0x53, 0xbf, 0x50, 0xc6, + 0xa7, 0xf7, 0x41, 0xf8, 0x3f, 0x95, 0x4a, 0xf1, 0x99, 0x82, 0x7d, 0x2c, 0x9b, 0x06, 0xcd, 0x45, + 0x04, 0x72, 0x93, 0xa0, 0xf6, 0x37, 0x8a, 0x68, 0x6a, 0x4c, 0x6f, 0x44, 0xb7, 0xc0, 0xc0, 0xed, + 0x0b, 0xf3, 0xe8, 0xbc, 0xc9, 0x7f, 0x3d, 0xe6, 0x96, 0x4c, 0x5e, 0x82, 0x45, 0xca, 0xf6, 0x70, + 0xdc, 0x67, 0x5b, 0x63, 0x3e, 0x16, 0xb2, 0xaa, 0xce, 0x8a, 0xe8, 0xb0, 0xed, 0x9e, 0x32, 0x17, + 0x8e, 0xa3, 0x9f, 0xf4, 0x4e, 0x18, 0x1c, 0x8f, 0x06, 0xf2, 0x86, 0x2a, 0x74, 0xe8, 0x56, 0xbd, + 0xdd, 0xe2, 0x24, 0x45, 0x8a, 0x13, 0xdd, 0x09, 0xb7, 0x66, 0x99, 0x16, 0x5d, 0x7b, 0x06, 0x16, + 0x24, 0xde, 0xb4, 0x31, 0xcc, 0xa9, 0x4c, 0x34, 0x86, 0xfd, 0xe2, 0x83, 0x7d, 0x1f, 0x8a, 0x82, + 0x25, 0xbd, 0xfc, 0x1e, 0xf9, 0x81, 0x38, 0x8c, 0xf0, 0x7f, 0x0a, 0xa3, 0xbd, 0x8c, 0x8d, 0x9c, + 0x31, 0xf1, 0x7f, 0x94, 0x79, 0x46, 0x0e, 0xbd, 0xf5, 0xf6, 0x02, 0x7b, 0x80, 0x8f, 0x13, 0xc3, + 0x2b, 0x22, 0x85, 0xb7, 0x7b, 0x01, 0x7b, 0xb2, 0xc8, 0xbf, 0xf1, 0x57, 0xa1, 0xb0, 0x98, 0x50, + 0xb4, 0x4d, 0x3a, 0xdb, 0x63, 0xa2, 0x4d, 0x2e, 0x2d, 0xda, 0xb0, 0x50, 0x44, 0x9c, 0x92, 0x7d, + 0x19, 0x10, 0x86, 0xa2, 0x8d, 0x74, 0x82, 0x15, 0x62, 0x27, 0x98, 0xa4, 0x79, 0x8a, 0x46, 0x8f, + 0x49, 0x46, 0x42, 0xf3, 0x94, 0x3c, 0x4f, 0xdf, 0x0d, 0x67, 0x48, 0x4c, 0xd5, 0x47, 0xaf, 0x88, + 0xec, 0x7a, 0xc8, 0x13, 0x58, 0x27, 0x0e, 0xf2, 0xd3, 0x58, 0xc8, 0xd2, 0x5b, 0x85, 0x07, 0xfa, + 0xa3, 0x35, 0x2b, 0xe4, 0x79, 0x58, 0x0b, 0x53, 0xae, 0x06, 0x6f, 0x7a, 0x03, 0x1b, 0x93, 0xee, + 0x3e, 0xe4, 0x17, 0x37, 0x22, 0xca, 0xac, 0x37, 0xbd, 0xc1, 0x3e, 0x96, 0xf0, 0x6a, 0xfe, 0x59, + 0x4e, 0xe8, 0xeb, 0xb6, 0x7c, 0x7f, 0x14, 0x8c, 0x86, 0xce, 0x20, 0x66, 0xcc, 0x20, 0xc7, 0xf0, + 0x04, 0x56, 0xe9, 0x26, 0x26, 0xc1, 0xf1, 0x87, 0x22, 0x48, 0x4f, 0xb8, 0xc0, 0x16, 0x6e, 0x7e, + 0x22, 0x7e, 0xe1, 0xd6, 0x29, 0xb6, 0x2e, 0x23, 0xd3, 0x75, 0x25, 0x71, 0xdd, 0x3d, 0x65, 0xae, + 0x33, 0x9e, 0x29, 0x2c, 0xb2, 0x9b, 0xb1, 0xd7, 0x24, 0xad, 0x19, 0x5b, 0xd1, 0xc6, 0x13, 0xe7, + 0x2a, 0x6f, 0x49, 0xe4, 0x35, 0x98, 0xf7, 0xba, 0x72, 0xae, 0xd7, 0xa4, 0x1e, 0xbd, 0xda, 0x65, + 0xf1, 0xe6, 0x23, 0x1e, 0x74, 0x69, 0x78, 0x1c, 0xba, 0xb5, 0x14, 0x33, 0xfb, 0x68, 0x5b, 0x42, + 0x35, 0x94, 0x26, 0x23, 0xcb, 0xd1, 0x99, 0x83, 0xe7, 0x0b, 0xee, 0x02, 0x51, 0xc4, 0x7b, 0x93, + 0xff, 0xd2, 0xfe, 0x3f, 0x5c, 0x3b, 0x69, 0x1f, 0xd1, 0x1d, 0x63, 0x42, 0x87, 0xcf, 0xb3, 0x60, + 0xb3, 0xf1, 0x7e, 0xbb, 0x0c, 0x72, 0xc0, 0x6e, 0x4f, 0x4c, 0x11, 0x01, 0xdb, 0x1b, 0x7a, 0xda, + 0xbf, 0xe5, 0x61, 0x39, 0x6e, 0xe8, 0x22, 0xcf, 0x40, 0x41, 0xda, 0x28, 0xd7, 0x33, 0xac, 0x61, + 0xb8, 0x3d, 0x22, 0xd2, 0x89, 0x36, 0x46, 0x72, 0x1b, 0x96, 0xf1, 0xe9, 0x2d, 0x9e, 0xe6, 0x23, + 0x8f, 0x9b, 0x4f, 0xa7, 0x5b, 0xc0, 0x8b, 0x3f, 0x7a, 0xef, 0xd2, 0x29, 0x34, 0x76, 0x2f, 0x52, + 0x5a, 0x7a, 0x30, 0xd2, 0x42, 0xc9, 0x8e, 0x51, 0x98, 0x6c, 0xc7, 0xe0, 0x4d, 0x99, 0x60, 0xc7, + 0x98, 0x99, 0x62, 0xc7, 0x88, 0x28, 0x65, 0x3b, 0x06, 0x5a, 0xb3, 0xe6, 0x26, 0x59, 0xb3, 0x22, + 0x1a, 0x66, 0xcd, 0x8a, 0xec, 0x10, 0xc5, 0x89, 0x76, 0x88, 0x88, 0x86, 0xdb, 0x21, 0x22, 0xcb, + 0xc0, 0xfc, 0x44, 0xcb, 0x80, 0x44, 0xc4, 0x2c, 0x03, 0x57, 0x78, 0xc7, 0x0e, 0x9d, 0x07, 0x36, + 0xf6, 0x38, 0x17, 0x4d, 0xb1, 0xcb, 0x4c, 0xe7, 0x01, 0xbe, 0xa9, 0xa3, 0x82, 0x09, 0x7f, 0x88, + 0xa7, 0xfd, 0x20, 0xb1, 0x01, 0x89, 0x31, 0x7f, 0x1a, 0x96, 0xd9, 0x39, 0xcc, 0x83, 0x18, 0xb3, + 0x83, 0x78, 0xc9, 0x5c, 0x12, 0x50, 0xa6, 0x30, 0xfa, 0x18, 0xac, 0x84, 0x68, 0x5c, 0x67, 0x82, + 0xfe, 0xb9, 0x66, 0x48, 0xcd, 0xb5, 0x25, 0x32, 0xbf, 0x21, 0x0f, 0xe7, 0x14, 0xe3, 0xc7, 0x62, + 0xfd, 0x3c, 0x0b, 0x24, 0x42, 0x0b, 0x9f, 0x25, 0x17, 0x10, 0x75, 0x35, 0x44, 0x0d, 0xdf, 0x0e, + 0xff, 0x81, 0x92, 0xb0, 0x44, 0x7c, 0x54, 0xd5, 0x7f, 0x06, 0xc2, 0xaf, 0xdb, 0x5c, 0x9b, 0x2c, + 0x5a, 0xa0, 0x8a, 0x82, 0x16, 0x87, 0x6b, 0x87, 0x49, 0xdd, 0xc5, 0x47, 0x54, 0x2b, 0xed, 0x87, + 0xf9, 0x98, 0x96, 0x56, 0x7c, 0x86, 0xca, 0x37, 0x81, 0x6f, 0xf3, 0x21, 0xe6, 0xdb, 0xef, 0xe5, + 0x09, 0xd3, 0x94, 0x3f, 0xc4, 0xb4, 0xac, 0xa6, 0x09, 0x41, 0xe0, 0x8b, 0x77, 0x99, 0x36, 0xbb, + 0x93, 0x4b, 0x42, 0xb7, 0x60, 0xc7, 0xf6, 0xda, 0xd2, 0x74, 0x76, 0x42, 0x4d, 0x46, 0x57, 0x29, + 0xde, 0xcd, 0xc3, 0x5f, 0xe2, 0x03, 0x7b, 0x80, 0x46, 0x8d, 0x20, 0xce, 0x3c, 0x9f, 0xa1, 0x7d, + 0x49, 0x31, 0xc7, 0x5e, 0x42, 0xce, 0xea, 0x58, 0xfc, 0x2b, 0xd8, 0x1a, 0xb0, 0x88, 0x3a, 0x52, + 0xc1, 0xb0, 0x90, 0x61, 0x37, 0x4c, 0x37, 0xbe, 0x5c, 0xad, 0x9b, 0x0b, 0x94, 0x4e, 0xb0, 0x39, + 0x82, 0x27, 0x64, 0xcd, 0x66, 0xbc, 0x92, 0x33, 0x22, 0xf4, 0xf8, 0xd4, 0x1e, 0x88, 0x14, 0xa0, + 0x58, 0xd5, 0xb3, 0x4e, 0x1c, 0xc0, 0xd1, 0xb4, 0x23, 0xd8, 0x9c, 0x3c, 0x24, 0x53, 0xd2, 0xda, + 0x45, 0xa2, 0x4d, 0x4e, 0x16, 0x6d, 0x64, 0x3d, 0x67, 0x3e, 0xa6, 0xe7, 0xd4, 0xfe, 0x34, 0x0f, + 0x4f, 0x9d, 0x60, 0xb8, 0xa6, 0x7c, 0xf3, 0x33, 0x71, 0xc1, 0x39, 0x17, 0xd3, 0x2d, 0x51, 0xa6, + 0xfc, 0x4c, 0x78, 0xd8, 0xef, 0x4c, 0x10, 0x9b, 0xbf, 0x0c, 0x2b, 0x6c, 0xe3, 0x67, 0x6f, 0xa9, + 0x0f, 0xc6, 0xbd, 0x13, 0xec, 0xfc, 0xe7, 0x84, 0xe3, 0x67, 0x82, 0x14, 0x0f, 0x03, 0xdc, 0xef, + 0xac, 0x10, 0x46, 0xda, 0xb0, 0x80, 0x68, 0x07, 0x8e, 0xd7, 0x3b, 0x91, 0x07, 0xa2, 0x70, 0x2b, + 0x95, 0xc9, 0x98, 0x0b, 0x08, 0x05, 0x6c, 0xe3, 0x6f, 0x72, 0x15, 0x56, 0xfa, 0xe3, 0x63, 0x2a, + 0x12, 0xb2, 0xb9, 0xc0, 0x9f, 0xac, 0xcd, 0x98, 0x4b, 0xfd, 0xf1, 0xb1, 0x3e, 0x18, 0xe0, 0x90, + 0xe2, 0xdb, 0xb6, 0x55, 0x8a, 0xc7, 0x56, 0xad, 0xc0, 0x9c, 0x45, 0x4c, 0xca, 0x80, 0xad, 0x5b, + 0x8e, 0xbb, 0x06, 0xec, 0xa5, 0x33, 0x4f, 0xeb, 0xc7, 0x7e, 0x68, 0xff, 0x99, 0x13, 0x1a, 0xb3, + 0xc9, 0xf3, 0xfe, 0x57, 0x43, 0x94, 0x31, 0x44, 0xd7, 0x40, 0xa5, 0x5d, 0x1f, 0x6d, 0x2a, 0xe1, + 0x18, 0x2d, 0xf7, 0xc7, 0xc7, 0x61, 0xdf, 0xc9, 0x1d, 0x3f, 0x2b, 0x77, 0xfc, 0x4b, 0x42, 0xa3, + 0x96, 0xb9, 0x3d, 0x4c, 0xee, 0x72, 0x2a, 0x31, 0x5d, 0x3d, 0xd9, 0x26, 0xf0, 0xab, 0x71, 0xcb, + 0x18, 0xb7, 0x84, 0xe9, 0x66, 0x26, 0x65, 0xba, 0xc9, 0x58, 0x7b, 0xb3, 0x59, 0x6b, 0x2f, 0x65, + 0x28, 0x9a, 0xcb, 0x30, 0x14, 0x65, 0x2e, 0xd0, 0xe2, 0x23, 0x16, 0xe8, 0xbc, 0x3c, 0x4f, 0xfe, + 0x29, 0x27, 0x24, 0xa6, 0xf8, 0x15, 0xe8, 0x0d, 0x38, 0x2d, 0xae, 0x40, 0xec, 0xe4, 0x88, 0xec, + 0x7f, 0x0b, 0x37, 0xaf, 0x67, 0x5d, 0x7e, 0x10, 0x2d, 0xe3, 0x82, 0xb2, 0xca, 0xaf, 0x3d, 0x51, + 0xf9, 0xff, 0x9d, 0x0b, 0x0f, 0xb9, 0x07, 0x67, 0x31, 0x29, 0x46, 0x47, 0xb6, 0x5c, 0xda, 0x43, + 0xf7, 0x80, 0xcf, 0x87, 0xcb, 0xa9, 0xeb, 0x81, 0xd7, 0x91, 0xaa, 0x63, 0xba, 0x07, 0xbb, 0xa7, + 0xcc, 0xb5, 0x20, 0x03, 0x9e, 0xbc, 0x4b, 0x7d, 0x5f, 0x01, 0xed, 0xd1, 0xfd, 0x85, 0xd7, 0xde, + 0x64, 0x87, 0xd3, 0x6b, 0xaf, 0xd4, 0x7b, 0x4f, 0xc1, 0xd2, 0xd0, 0x3d, 0x18, 0xba, 0xc1, 0x51, + 0x4c, 0x37, 0xb5, 0xc8, 0x81, 0xa2, 0x63, 0x44, 0x24, 0xdd, 0xc7, 0xba, 0x8c, 0x08, 0x22, 0x6d, + 0x3b, 0xbc, 0x22, 0x67, 0x8e, 0x03, 0x9d, 0x4d, 0x72, 0x05, 0xd9, 0x8f, 0xdb, 0x85, 0x62, 0x4e, + 0xcd, 0x9b, 0x3c, 0xde, 0xef, 0x81, 0xd7, 0x73, 0xb5, 0xbf, 0x56, 0x84, 0x44, 0x90, 0xd5, 0x79, + 0xe4, 0x0d, 0xc9, 0x03, 0x21, 0x9f, 0x12, 0x43, 0xb2, 0x48, 0x4e, 0xa2, 0x38, 0xac, 0x7d, 0x48, + 0x8a, 0xc3, 0x5b, 0xe2, 0x19, 0x23, 0xdd, 0xf3, 0xf6, 0x6f, 0x90, 0xeb, 0x30, 0xc7, 0x5e, 0x2e, + 0x8a, 0xea, 0xae, 0xc4, 0xaa, 0xbb, 0x7f, 0xc3, 0x14, 0xe5, 0xda, 0x3b, 0xa1, 0x5d, 0x3d, 0xd5, + 0x88, 0xfd, 0x1b, 0xe4, 0xa5, 0x93, 0x79, 0x14, 0x14, 0x85, 0x47, 0x41, 0xe8, 0x4d, 0xf0, 0x72, + 0xcc, 0x9b, 0xe0, 0xca, 0xf4, 0xde, 0xe2, 0xaf, 0x21, 0x58, 0x0c, 0xd5, 0x28, 0xb6, 0xde, 0xcf, + 0x72, 0x70, 0x61, 0x2a, 0x05, 0x39, 0x0f, 0x45, 0xbd, 0x55, 0x6d, 0x47, 0xe3, 0x4b, 0xd7, 0x8c, + 0x80, 0x90, 0x1d, 0x98, 0xdf, 0x72, 0x02, 0xaf, 0x43, 0xa7, 0x71, 0xa6, 0x81, 0x31, 0xc5, 0x36, + 0x44, 0xdf, 0x3d, 0x65, 0x46, 0xb4, 0xc4, 0x86, 0x55, 0x5c, 0x0b, 0xb1, 0x7c, 0x79, 0xf9, 0x0c, + 0xf5, 0x4a, 0x8a, 0x61, 0x8a, 0x8c, 0xee, 0x33, 0x29, 0x20, 0xb9, 0x0f, 0xc4, 0xb2, 0x76, 0xcb, + 0xee, 0x70, 0xc4, 0xd5, 0x0e, 0x23, 0x2f, 0x7c, 0x9e, 0xfe, 0xfc, 0x23, 0xfa, 0x2e, 0x45, 0xb7, + 0x7b, 0xca, 0xcc, 0xe0, 0x96, 0x5c, 0xe6, 0x6f, 0x0b, 0x79, 0x67, 0x72, 0x27, 0x3c, 0x46, 0x7c, + 0xea, 0x6b, 0x50, 0x6c, 0x89, 0xb7, 0x50, 0x92, 0x9b, 0x8f, 0x78, 0xf7, 0x64, 0x86, 0xa5, 0xda, + 0x6f, 0x2b, 0x42, 0xcf, 0xf2, 0xe8, 0xce, 0x92, 0xd2, 0x19, 0x76, 0xa7, 0xa7, 0x33, 0xec, 0xfe, + 0x82, 0xe9, 0x0c, 0x35, 0x0f, 0xae, 0x9f, 0xb8, 0x63, 0xc9, 0xa7, 0x41, 0xc5, 0xcc, 0x6f, 0x8e, + 0x34, 0x48, 0x6c, 0x7d, 0xad, 0x86, 0x09, 0x0b, 0x76, 0x79, 0x7a, 0x4d, 0x73, 0xa5, 0x13, 0xa7, + 0xd6, 0xfe, 0x82, 0x27, 0xaa, 0xa8, 0x76, 0x5b, 0x09, 0x53, 0xd5, 0x07, 0xf5, 0x0c, 0x33, 0x62, + 0x8b, 0xed, 0x29, 0x29, 0xf3, 0x6e, 0xfa, 0x5b, 0x93, 0x1d, 0xc4, 0xa4, 0x95, 0xf7, 0xc7, 0x79, + 0x38, 0x3f, 0x8d, 0x3c, 0x33, 0xb7, 0xbf, 0xf2, 0x78, 0xb9, 0xfd, 0xaf, 0x43, 0x91, 0xc1, 0x42, + 0xb7, 0x27, 0x1c, 0x5b, 0x4e, 0x4a, 0xc7, 0x56, 0x14, 0x93, 0xa7, 0x60, 0x56, 0x2f, 0x5b, 0x51, + 0xba, 0x49, 0xf4, 0x4f, 0x70, 0x3a, 0x01, 0xbe, 0x7c, 0xe7, 0x45, 0xe4, 0x4b, 0xe9, 0x0c, 0xab, + 0x3c, 0xcf, 0xe4, 0x39, 0xa9, 0x43, 0x52, 0x39, 0x64, 0xb0, 0xbe, 0x51, 0xce, 0x13, 0x9e, 0x46, + 0xc0, 0x4c, 0x67, 0x6b, 0xd5, 0x60, 0xb6, 0x35, 0x74, 0x03, 0x77, 0x24, 0xfb, 0x0e, 0x0c, 0x10, + 0x62, 0xf2, 0x12, 0xfe, 0xb2, 0xdf, 0x79, 0xc8, 0x02, 0xb9, 0xcc, 0xca, 0xc1, 0xb5, 0xd0, 0x15, + 0x80, 0x82, 0x4d, 0x09, 0x85, 0x12, 0xd4, 0x9c, 0x71, 0xbf, 0x73, 0xb4, 0x67, 0xd6, 0xb8, 0xe4, + 0xc4, 0x08, 0x7a, 0x08, 0xa5, 0x0d, 0x0c, 0x4c, 0x09, 0x45, 0xfb, 0x96, 0x02, 0x6b, 0x59, 0xed, + 0x20, 0xe7, 0xa1, 0xd0, 0xcf, 0x4c, 0x26, 0xdb, 0x67, 0xf1, 0x27, 0x16, 0xd0, 0x7c, 0x76, 0xe0, + 0x0f, 0x8f, 0x9d, 0x91, 0xec, 0x61, 0x21, 0x81, 0x4d, 0x34, 0xbc, 0x6d, 0xe3, 0xff, 0xe4, 0x92, + 0x38, 0x72, 0xf2, 0xa9, 0xf4, 0xb3, 0xf8, 0x47, 0xd3, 0x01, 0xaa, 0xdd, 0x56, 0x73, 0xc0, 0x72, + 0x98, 0xbc, 0x00, 0x05, 0x5a, 0xad, 0xc4, 0xec, 0xa5, 0xf3, 0x47, 0xaf, 0xd7, 0x38, 0x12, 0xab, + 0x55, 0xe0, 0x1c, 0xf7, 0x4c, 0x44, 0xd6, 0xee, 0xc2, 0x72, 0x1c, 0x83, 0x18, 0xf1, 0x30, 0xd6, + 0x0b, 0x37, 0x55, 0xce, 0x69, 0xcb, 0xf7, 0x99, 0x97, 0xdf, 0xd6, 0x13, 0x3f, 0x7b, 0xef, 0x12, + 0xd0, 0x9f, 0x8c, 0x26, 0x2b, 0xcc, 0xb5, 0xf6, 0xed, 0x1c, 0xac, 0x45, 0x81, 0x45, 0xc4, 0x1a, + 0xfa, 0xa5, 0xf5, 0x72, 0xd7, 0x63, 0x5e, 0xd8, 0x42, 0x6e, 0x4c, 0x37, 0x70, 0x8a, 0xf3, 0xe7, + 0x0e, 0x6c, 0x4c, 0xc2, 0x27, 0xcf, 0xc0, 0x3c, 0xc6, 0xa2, 0x1b, 0x38, 0x1d, 0x57, 0xde, 0x66, + 0xfb, 0x02, 0x68, 0x46, 0xe5, 0xda, 0x4f, 0x14, 0xd8, 0xe4, 0xbe, 0x69, 0x75, 0xc7, 0xeb, 0xa3, + 0xfd, 0xa6, 0xe3, 0x7e, 0x38, 0x51, 0x1a, 0x76, 0x62, 0xfb, 0xd8, 0xd3, 0x71, 0x17, 0xc4, 0xd4, + 0xd7, 0x26, 0xb7, 0x96, 0x5c, 0xc7, 0xf8, 0x8a, 0xfc, 0x1d, 0x4e, 0x81, 0x45, 0xc5, 0xe9, 0x53, + 0x80, 0x1c, 0x15, 0x07, 0x31, 0xb4, 0x5f, 0x83, 0x8b, 0xd3, 0x3f, 0x40, 0xbe, 0x08, 0x4b, 0x98, + 0x30, 0x70, 0x6f, 0x70, 0x38, 0x74, 0xba, 0xae, 0xd0, 0xec, 0x09, 0x05, 0xb4, 0x5c, 0xc6, 0xc2, + 0x45, 0xf2, 0x28, 0x2d, 0x87, 0x98, 0x8a, 0x90, 0x13, 0xc5, 0x1c, 0x40, 0x65, 0x6e, 0xda, 0xd7, + 0x15, 0x20, 0x69, 0x1e, 0xe4, 0x93, 0xb0, 0xb8, 0xd7, 0x2e, 0x5b, 0x23, 0x67, 0x38, 0xda, 0xf5, + 0xc7, 0x43, 0x1e, 0xab, 0x91, 0x05, 0xed, 0x18, 0x75, 0x6c, 0x66, 0xa9, 0x3b, 0xf2, 0xc7, 0x43, + 0x33, 0x86, 0x87, 0x89, 0xe9, 0x5c, 0xf7, 0xcd, 0xae, 0xf3, 0x30, 0x9e, 0x98, 0x8e, 0xc3, 0x62, + 0x89, 0xe9, 0x38, 0x4c, 0x7b, 0x57, 0x81, 0x73, 0xe2, 0x71, 0x76, 0x37, 0xa3, 0x2e, 0x65, 0x0c, + 0x4d, 0x35, 0x14, 0xc1, 0xc1, 0xa7, 0x49, 0xe8, 0xab, 0x22, 0x7a, 0x1b, 0x56, 0x10, 0x45, 0x75, + 0x46, 0x4b, 0x3e, 0x03, 0x05, 0x6b, 0xe4, 0x0f, 0x4e, 0x10, 0xbe, 0x4d, 0x0d, 0x47, 0x74, 0xe4, + 0x0f, 0x90, 0x05, 0x52, 0x6a, 0x2e, 0xac, 0xc9, 0x95, 0x13, 0x35, 0x26, 0x75, 0x98, 0xe3, 0x71, + 0x3a, 0x13, 0x2f, 0x97, 0xa6, 0xb4, 0x69, 0x6b, 0x45, 0xc4, 0x88, 0xe3, 0xc1, 0xa9, 0x4d, 0xc1, + 0x43, 0xfb, 0x5d, 0x05, 0x16, 0xa8, 0x60, 0x83, 0x97, 0xd2, 0x0f, 0x3a, 0xa5, 0xe3, 0x72, 0xb0, + 0x78, 0x88, 0x17, 0xb2, 0x3f, 0xd1, 0x69, 0xfc, 0x22, 0xac, 0x24, 0x08, 0x88, 0x86, 0xd1, 0x81, + 0x7a, 0x5e, 0xc7, 0x61, 0x79, 0xae, 0xd8, 0x23, 0xb6, 0x18, 0x4c, 0xfb, 0x4d, 0x05, 0xd6, 0x9a, + 0x6f, 0x8e, 0x1c, 0x66, 0x50, 0x37, 0xc7, 0x3d, 0xb1, 0xde, 0xa9, 0xb0, 0x26, 0x5e, 0xf9, 0xb3, + 0xc8, 0x25, 0x4c, 0x58, 0xe3, 0x30, 0x33, 0x2c, 0x25, 0xbb, 0x50, 0xe4, 0xe7, 0x4b, 0xc0, 0x63, + 0x4a, 0x5f, 0x94, 0x74, 0x23, 0x11, 0x63, 0x8e, 0x44, 0x5b, 0x82, 0x5b, 0x18, 0xa7, 0x31, 0x43, + 0x6a, 0xed, 0xdf, 0x15, 0x58, 0x9f, 0x40, 0x43, 0x5e, 0x85, 0x19, 0xf4, 0xaa, 0xe6, 0xa3, 0x77, + 0x7e, 0xc2, 0x27, 0x46, 0x9d, 0xa3, 0xfd, 0x1b, 0xec, 0x20, 0x3a, 0xa6, 0x3f, 0x4c, 0x46, 0x45, + 0xde, 0x80, 0x79, 0xbd, 0xdb, 0xe5, 0xb7, 0xb3, 0x5c, 0xec, 0x76, 0x36, 0xe1, 0x8b, 0xcf, 0x85, + 0xf8, 0xec, 0x76, 0xc6, 0xfc, 0xfb, 0xba, 0x5d, 0x9b, 0x7b, 0x8c, 0x47, 0xfc, 0x36, 0x3f, 0x0d, + 0xcb, 0x71, 0xe4, 0xc7, 0x72, 0x72, 0x7d, 0x47, 0x01, 0x35, 0x5e, 0x87, 0x8f, 0x26, 0xba, 0x5d, + 0xd6, 0x30, 0x3f, 0x62, 0x52, 0xfd, 0x7e, 0x0e, 0xce, 0x64, 0xf6, 0x30, 0x79, 0x16, 0x66, 0xf5, + 0xc1, 0xa0, 0x5a, 0xe1, 0xb3, 0x8a, 0x4b, 0x48, 0xa8, 0xf4, 0x8e, 0x5d, 0x5e, 0x19, 0x12, 0x79, + 0x01, 0x8a, 0xec, 0xdd, 0x46, 0x45, 0x6c, 0x38, 0x18, 0xae, 0x8b, 0x3f, 0x2a, 0x89, 0x47, 0x77, + 0x16, 0x88, 0x64, 0x1b, 0x96, 0x79, 0xa0, 0x2b, 0x7c, 0xb9, 0x13, 0xa6, 0x19, 0xc1, 0x4c, 0x28, + 0x42, 0x93, 0xce, 0x1e, 0xfb, 0xc4, 0xf6, 0xce, 0x04, 0x15, 0xa9, 0x81, 0x8a, 0x3c, 0x65, 0x4e, + 0x2c, 0xc4, 0xb4, 0xf4, 0x78, 0x69, 0x02, 0xaf, 0x14, 0x65, 0x38, 0x5c, 0x7a, 0x10, 0x78, 0x87, + 0xfd, 0x63, 0xb7, 0x3f, 0xfa, 0xe8, 0x86, 0x2b, 0xfa, 0xc6, 0x89, 0x86, 0xeb, 0x0f, 0x0b, 0x6c, + 0x31, 0x27, 0xc9, 0xa8, 0x44, 0x23, 0x65, 0x15, 0x40, 0x89, 0x86, 0xde, 0xcf, 0x78, 0x28, 0xa7, + 0x0a, 0xcc, 0xb1, 0x10, 0x5b, 0x62, 0x65, 0x5c, 0xc8, 0xac, 0x02, 0xc3, 0xd9, 0xbf, 0xc1, 0xc4, + 0x17, 0xe6, 0xde, 0x1d, 0x98, 0x82, 0x94, 0xec, 0xc3, 0x42, 0xb9, 0xe7, 0x3a, 0xfd, 0xf1, 0xa0, + 0x7d, 0x32, 0xa3, 0xf1, 0x06, 0x6f, 0xcb, 0x62, 0x87, 0x91, 0xa1, 0xb1, 0x19, 0x77, 0x72, 0x99, + 0x11, 0x69, 0x87, 0x1e, 0x9f, 0x05, 0x54, 0xbc, 0x3e, 0x3f, 0xa5, 0x7f, 0x92, 0x40, 0xa4, 0x8b, + 0xbb, 0x33, 0x73, 0x97, 0x50, 0x1b, 0x96, 0x6b, 0x4e, 0x30, 0x6a, 0x0f, 0x9d, 0x7e, 0x80, 0xa1, + 0x79, 0x4f, 0x10, 0xba, 0xf0, 0x9c, 0x48, 0x3b, 0x8f, 0x2a, 0xd3, 0x51, 0x48, 0xca, 0x14, 0xb2, + 0x71, 0x76, 0x54, 0x5e, 0xda, 0xf6, 0xfa, 0x4e, 0xcf, 0xfb, 0x9a, 0x70, 0x8c, 0x67, 0xf2, 0xd2, + 0x81, 0x00, 0x9a, 0x51, 0xb9, 0xf6, 0x85, 0xd4, 0xb8, 0xb1, 0x5a, 0x2e, 0xc0, 0x1c, 0x0f, 0x9b, + 0xc2, 0xc2, 0x88, 0xb4, 0x8c, 0x46, 0xa5, 0xda, 0xd8, 0x51, 0x15, 0xb2, 0x0c, 0xd0, 0x32, 0x9b, + 0x65, 0xc3, 0xb2, 0xe8, 0xef, 0x1c, 0xfd, 0xcd, 0x63, 0x8c, 0x6c, 0xef, 0xd5, 0xd4, 0xbc, 0x14, + 0x66, 0xa4, 0xa0, 0xfd, 0x58, 0x81, 0xb3, 0xd9, 0x43, 0x49, 0xda, 0x80, 0x81, 0x66, 0xf8, 0xf3, + 0x81, 0x4f, 0x4e, 0x1d, 0xf7, 0x4c, 0x70, 0x32, 0x60, 0xcd, 0x88, 0x05, 0x42, 0xc9, 0x09, 0xdb, + 0x17, 0xf3, 0xac, 0xf6, 0xba, 0x66, 0xce, 0xeb, 0x6a, 0x65, 0xd8, 0x98, 0xc4, 0x23, 0xde, 0xd4, + 0x15, 0x58, 0xd0, 0x5b, 0xad, 0x5a, 0xb5, 0xac, 0xb7, 0xab, 0xcd, 0x86, 0xaa, 0x90, 0x79, 0x98, + 0xd9, 0x31, 0x9b, 0x7b, 0x2d, 0x35, 0xa7, 0x7d, 0x47, 0x81, 0xa5, 0x6a, 0xf4, 0x6e, 0xf5, 0x83, + 0x2e, 0xbe, 0x57, 0x62, 0x8b, 0x6f, 0x23, 0x0c, 0xc9, 0x14, 0x7e, 0xe0, 0x44, 0x2b, 0xef, 0xfd, + 0x1c, 0xac, 0xa6, 0x68, 0x88, 0x05, 0x73, 0xfa, 0x5d, 0xab, 0x59, 0xad, 0x94, 0x79, 0xcd, 0x2e, + 0x45, 0x0f, 0xd9, 0x30, 0x49, 0x5f, 0xea, 0x2b, 0x2c, 0x8c, 0xc1, 0x83, 0xc0, 0xf6, 0xbd, 0x6e, + 0x27, 0xf6, 0x82, 0x51, 0x70, 0xc2, 0x93, 0xec, 0x6b, 0xe3, 0xa1, 0x8b, 0x6c, 0x73, 0x31, 0xbd, + 0x6e, 0x08, 0x4f, 0x33, 0xc6, 0xc7, 0x91, 0x0e, 0x2d, 0x4f, 0xb3, 0x8e, 0xf8, 0x91, 0x06, 0xcc, + 0xee, 0x78, 0xa3, 0xdd, 0xf1, 0x7d, 0xbe, 0x7e, 0x2f, 0x46, 0x29, 0xdb, 0x76, 0xc7, 0xf7, 0xd3, + 0x6c, 0x51, 0x65, 0xc9, 0x42, 0x8e, 0xc5, 0x58, 0x72, 0x2e, 0x49, 0xcf, 0xeb, 0xc2, 0x63, 0x79, + 0x5e, 0x6f, 0x2d, 0xc1, 0x02, 0xbf, 0x43, 0xe1, 0xf5, 0xe4, 0x87, 0x0a, 0x6c, 0x4c, 0xea, 0x39, + 0x7a, 0x2d, 0x8b, 0x47, 0x58, 0x39, 0x1b, 0xe6, 0xf4, 0x89, 0x87, 0x56, 0x11, 0x68, 0xe4, 0x75, + 0x58, 0x60, 0xaf, 0xb4, 0xac, 0x17, 0xf6, 0xcc, 0x2a, 0x9f, 0xae, 0x17, 0xfe, 0xe5, 0xbd, 0x4b, + 0xeb, 0xfc, 0x61, 0x57, 0xf0, 0x82, 0x3d, 0x1e, 0x7a, 0xb1, 0xfc, 0x27, 0x32, 0x05, 0x95, 0xa2, + 0x9d, 0x71, 0xd7, 0x73, 0xc5, 0x1d, 0x42, 0x44, 0xa1, 0xe0, 0x30, 0xf9, 0x4c, 0x13, 0x30, 0xed, + 0x9b, 0x0a, 0x6c, 0x4e, 0x1e, 0x26, 0x7a, 0x4e, 0xb6, 0xd9, 0x63, 0x37, 0x11, 0x07, 0x02, 0xcf, + 0xc9, 0xf0, 0x45, 0x9c, 0xcc, 0x53, 0x20, 0x52, 0x22, 0xae, 0xe1, 0x12, 0x4a, 0x12, 0x39, 0x89, + 0x7f, 0x9c, 0x48, 0x20, 0x6a, 0xf7, 0x60, 0x7d, 0xc2, 0xa0, 0x92, 0xd7, 0x32, 0x33, 0x85, 0xa1, + 0x9b, 0xa4, 0x9c, 0x29, 0x2c, 0x96, 0x72, 0x52, 0x82, 0x6b, 0xff, 0x9a, 0x83, 0xb3, 0x74, 0x75, + 0xf5, 0xdc, 0x20, 0xd0, 0xa3, 0xa4, 0xda, 0x74, 0x57, 0x7c, 0x09, 0x66, 0x8f, 0x1e, 0x4f, 0x55, + 0xcc, 0xd0, 0x09, 0x01, 0x3c, 0xb1, 0x84, 0x73, 0x1e, 0xfd, 0x9f, 0x5c, 0x06, 0x90, 0xd2, 0xaa, + 0xe7, 0x31, 0x26, 0x73, 0x6e, 0x43, 0x31, 0xe7, 0x07, 0x61, 0xf2, 0xf4, 0x97, 0x61, 0x06, 0xf5, + 0x29, 0xfc, 0xec, 0x10, 0x32, 0x7f, 0x76, 0xed, 0x50, 0xdb, 0x62, 0x32, 0x02, 0xf2, 0x09, 0x80, + 0x28, 0x9d, 0x0d, 0x3f, 0x1c, 0x84, 0x9e, 0x21, 0xcc, 0x68, 0x63, 0xce, 0x1f, 0x1f, 0x38, 0x3c, + 0x47, 0x4c, 0x09, 0x56, 0x45, 0x8f, 0x0f, 0x44, 0x28, 0x57, 0x6e, 0xc5, 0x5c, 0x61, 0x05, 0xd5, + 0x81, 0x08, 0xe7, 0x7a, 0x25, 0x95, 0x55, 0x1e, 0x23, 0xba, 0x27, 0x52, 0xc7, 0x5f, 0x49, 0xa5, + 0x8e, 0x2f, 0x32, 0x2c, 0x39, 0x3f, 0xbc, 0xf6, 0x8f, 0x39, 0x98, 0xbf, 0x4b, 0xa5, 0x32, 0xd4, + 0x35, 0x4c, 0xd7, 0x5d, 0xdc, 0x84, 0x85, 0x9a, 0xef, 0x70, 0x73, 0x11, 0xf7, 0x69, 0x63, 0x6f, + 0xac, 0x7b, 0xbe, 0x23, 0x2c, 0x4f, 0x81, 0x29, 0x23, 0x3d, 0x22, 0x88, 0xc6, 0x6d, 0x98, 0x65, + 0xe6, 0x3b, 0xae, 0x46, 0x13, 0x72, 0x79, 0x58, 0xa3, 0xe7, 0x58, 0xb1, 0x64, 0xe1, 0x60, 0x26, + 0x40, 0x59, 0x48, 0xe4, 0x0f, 0xae, 0x25, 0xcd, 0xca, 0xcc, 0xc9, 0x34, 0x2b, 0x52, 0x00, 0xce, + 0xd9, 0x93, 0x04, 0xe0, 0xdc, 0xbc, 0x05, 0x0b, 0x52, 0x7d, 0x1e, 0x4b, 0x4c, 0xff, 0x46, 0x0e, + 0x96, 0xb0, 0x55, 0xe1, 0x5b, 0x9e, 0x5f, 0x4e, 0x3d, 0xd1, 0x2b, 0x31, 0x3d, 0xd1, 0x86, 0x3c, + 0x5e, 0xac, 0x65, 0x53, 0x14, 0x44, 0xb7, 0x61, 0x35, 0x85, 0x48, 0x5e, 0x84, 0x19, 0x5a, 0x7d, + 0x71, 0xaf, 0x56, 0x93, 0x33, 0x20, 0x0a, 0xd6, 0x4e, 0x1b, 0x1e, 0x98, 0x0c, 0x5b, 0xfb, 0x0f, + 0x05, 0x16, 0x79, 0xae, 0xa4, 0xfe, 0x81, 0xff, 0xc8, 0xee, 0xbc, 0x9a, 0xec, 0x4e, 0x16, 0x12, + 0x8a, 0x77, 0xe7, 0xff, 0x74, 0x27, 0xde, 0x8a, 0x75, 0xe2, 0x7a, 0x18, 0xba, 0x55, 0x34, 0x67, + 0x4a, 0x1f, 0xfe, 0x00, 0x83, 0x99, 0xc7, 0x11, 0xc9, 0x97, 0x60, 0xbe, 0xe1, 0x3e, 0x88, 0x5d, + 0x4f, 0xaf, 0x4e, 0x60, 0xfa, 0x5c, 0x88, 0xc8, 0xd6, 0x14, 0x73, 0x7b, 0x70, 0x1f, 0xd8, 0x29, + 0xcb, 0x61, 0xc4, 0x92, 0xde, 0x50, 0xe3, 0x64, 0x8f, 0x33, 0xf5, 0xb9, 0x83, 0x3d, 0x46, 0x39, + 0xfb, 0x56, 0x1e, 0x20, 0xf2, 0x4d, 0xa6, 0x0b, 0x30, 0xf6, 0x68, 0x42, 0x68, 0xf6, 0x11, 0x24, + 0xcf, 0x71, 0xf1, 0x96, 0xe2, 0x2a, 0xd7, 0x40, 0xe7, 0x26, 0x87, 0xd6, 0x45, 0x5d, 0x74, 0x99, + 0x3b, 0xc3, 0x76, 0xdd, 0x9e, 0xc3, 0xf6, 0xf6, 0xfc, 0xd6, 0x15, 0x8c, 0xa4, 0x1e, 0x42, 0x27, + 0xe4, 0xc8, 0x47, 0x97, 0xd9, 0x0a, 0x45, 0x48, 0xf9, 0xfb, 0x17, 0x1e, 0xcf, 0xdf, 0xbf, 0x05, + 0xf3, 0x5e, 0xff, 0x6d, 0xb7, 0x3f, 0xf2, 0x87, 0x0f, 0x51, 0xed, 0x1e, 0xe9, 0xf3, 0x68, 0x17, + 0x54, 0x45, 0x19, 0x1b, 0x07, 0x3c, 0x73, 0x43, 0x7c, 0x79, 0x18, 0x42, 0x60, 0x18, 0xaf, 0x60, + 0x46, 0x9d, 0xbd, 0x5d, 0x28, 0xce, 0xaa, 0x73, 0xb7, 0x0b, 0xc5, 0xa2, 0x3a, 0x7f, 0xbb, 0x50, + 0x9c, 0x57, 0xc1, 0x94, 0x6c, 0x66, 0xa1, 0x4d, 0x4c, 0x32, 0x63, 0xc5, 0x4d, 0x54, 0xda, 0xcf, + 0x73, 0x40, 0xd2, 0xd5, 0x20, 0xaf, 0xc0, 0x02, 0xdb, 0x60, 0xed, 0x61, 0xf0, 0x16, 0x77, 0x04, + 0x61, 0xb1, 0xe2, 0x24, 0xb0, 0x1c, 0x2b, 0x8e, 0x81, 0xcd, 0xe0, 0xad, 0x1e, 0xf9, 0x22, 0x9c, + 0xc6, 0xee, 0x1d, 0xb8, 0x43, 0xcf, 0xef, 0xda, 0x18, 0xd8, 0xdb, 0xe9, 0xf1, 0x7c, 0xb6, 0xcf, + 0x62, 0xe2, 0xf5, 0x74, 0xf1, 0x84, 0x61, 0x40, 0x17, 0xe4, 0x16, 0x62, 0xb6, 0x18, 0x22, 0x69, + 0x83, 0x2a, 0xd3, 0x1f, 0x8c, 0x7b, 0x3d, 0x3e, 0xb2, 0x25, 0x7a, 0xa3, 0x4f, 0x96, 0x4d, 0x60, + 0xbc, 0x1c, 0x31, 0xde, 0x1e, 0xf7, 0x7a, 0xe4, 0x25, 0x00, 0xbf, 0x6f, 0x1f, 0x7b, 0x41, 0xc0, + 0x8c, 0x39, 0xa1, 0x2b, 0x50, 0x04, 0x95, 0x07, 0xc3, 0xef, 0xd7, 0x19, 0x90, 0xfc, 0x3f, 0xc0, + 0x10, 0x33, 0x18, 0x7b, 0x89, 0xbd, 0x46, 0xe2, 0x29, 0xa7, 0x04, 0x30, 0x1e, 0x9c, 0xe1, 0xd0, + 0xb5, 0xbc, 0xaf, 0x09, 0x17, 0xbf, 0xcf, 0xc3, 0x2a, 0x7f, 0x2f, 0x7d, 0xd7, 0x1b, 0x1d, 0xf1, + 0xab, 0xc4, 0x07, 0xb9, 0x87, 0x48, 0x77, 0x89, 0xbf, 0x2d, 0x00, 0xe8, 0x77, 0x2d, 0x11, 0xd6, + 0xf0, 0x3a, 0xcc, 0xd0, 0x0b, 0x92, 0x50, 0xb4, 0xa0, 0x9a, 0x1a, 0xf9, 0xca, 0x6a, 0x6a, 0xc4, + 0xa0, 0xab, 0xd1, 0x44, 0x77, 0x07, 0xa1, 0x64, 0xc1, 0xd5, 0xc8, 0x3c, 0x20, 0x62, 0x61, 0xe5, + 0x39, 0x16, 0xa9, 0x01, 0x44, 0x81, 0x06, 0xb9, 0xc8, 0xbf, 0x1a, 0x45, 0xec, 0xe2, 0x05, 0x3c, + 0xb5, 0x4d, 0x14, 0xac, 0x50, 0x9e, 0x3e, 0x11, 0x1a, 0xb9, 0x03, 0x85, 0xb6, 0x13, 0xc6, 0x02, + 0x98, 0x10, 0x7e, 0xf1, 0x49, 0x9e, 0x6f, 0x38, 0x0a, 0xc1, 0xb8, 0x3c, 0x72, 0x62, 0x69, 0xd9, + 0x91, 0x09, 0x31, 0x60, 0xb6, 0xe5, 0x0c, 0x9d, 0xe3, 0x60, 0x52, 0xd8, 0x5e, 0x56, 0x2a, 0x82, + 0xf5, 0x23, 0x50, 0x96, 0x29, 0x58, 0x31, 0xb9, 0x09, 0x79, 0xcb, 0xaa, 0xf3, 0xa0, 0x43, 0x4b, + 0xd1, 0xf5, 0xcb, 0xb2, 0xea, 0xcc, 0xee, 0x1b, 0x04, 0xc7, 0x12, 0x19, 0x45, 0x26, 0x9f, 0x82, + 0x05, 0x49, 0x28, 0xe6, 0xe1, 0xba, 0xb0, 0x0f, 0x24, 0x7f, 0x49, 0x79, 0xd3, 0x90, 0xb0, 0x49, + 0x0d, 0xd4, 0x3b, 0xe3, 0xfb, 0xae, 0x3e, 0x18, 0xa0, 0x23, 0xf5, 0xdb, 0xee, 0x90, 0x89, 0x6d, + 0xc5, 0x28, 0xce, 0x3d, 0x7a, 0xaf, 0x74, 0x45, 0xa9, 0xac, 0x6c, 0x4a, 0x52, 0x92, 0x16, 0xac, + 0x5a, 0xee, 0x68, 0x3c, 0x60, 0xef, 0x6b, 0xb6, 0xfd, 0x21, 0xbd, 0xdf, 0xb0, 0xe0, 0x5e, 0x18, + 0x12, 0x3c, 0xa0, 0x85, 0xe2, 0x51, 0xd3, 0x81, 0x3f, 0x4c, 0xdc, 0x75, 0xd2, 0xc4, 0x9a, 0x2b, + 0x0f, 0x39, 0x3d, 0x55, 0xe3, 0xb7, 0x26, 0x3c, 0x55, 0xc5, 0xad, 0x29, 0xba, 0x2b, 0x7d, 0x22, + 0x23, 0x00, 0x25, 0x5a, 0x06, 0xa5, 0x00, 0x94, 0xb1, 0xb0, 0x93, 0xef, 0x16, 0xa4, 0x18, 0xc8, + 0x7c, 0x2c, 0x5e, 0x05, 0xb8, 0xed, 0x7b, 0xfd, 0xba, 0x3b, 0x3a, 0xf2, 0xbb, 0x52, 0x1c, 0xcc, + 0x85, 0xaf, 0xf8, 0x5e, 0xdf, 0x3e, 0x46, 0xf0, 0xcf, 0xdf, 0xbb, 0x24, 0x21, 0x99, 0xd2, 0xff, + 0xe4, 0xe3, 0x30, 0x4f, 0x7f, 0xb5, 0xa3, 0x57, 0x42, 0x4c, 0x27, 0x8b, 0xd4, 0x2c, 0x53, 0x50, + 0x84, 0x40, 0x6e, 0x61, 0x6e, 0x2c, 0x6f, 0x30, 0x92, 0x84, 0x57, 0x91, 0x08, 0xcb, 0x1b, 0x8c, + 0x92, 0x61, 0xed, 0x25, 0x64, 0xb2, 0x1b, 0x56, 0x5d, 0xa4, 0xb3, 0xe3, 0x29, 0xb8, 0x50, 0xf1, + 0xc8, 0xe7, 0x9a, 0x2d, 0xe2, 0x69, 0xcb, 0x2e, 0x9a, 0x09, 0x32, 0xac, 0x84, 0xb5, 0x5b, 0x61, + 0x96, 0x22, 0x2e, 0xd4, 0xb2, 0x4a, 0x04, 0x47, 0x5d, 0xbb, 0x83, 0xe0, 0x58, 0x25, 0x42, 0x64, + 0xb2, 0x05, 0x2b, 0x4c, 0xc6, 0x0f, 0xd3, 0xe2, 0x72, 0x11, 0x17, 0xf7, 0xb6, 0x28, 0x6f, 0xae, + 0xfc, 0xf9, 0x04, 0x01, 0xd9, 0x86, 0x19, 0xbc, 0x6b, 0x72, 0x6f, 0x88, 0x73, 0xb2, 0x9a, 0x20, + 0xb9, 0x8e, 0x70, 0x5f, 0x41, 0x05, 0x81, 0xbc, 0xaf, 0x20, 0x2a, 0xf9, 0x1c, 0x80, 0xd1, 0x1f, + 0xfa, 0xbd, 0x1e, 0x46, 0x7c, 0x2f, 0xc6, 0x1c, 0x63, 0x39, 0x1f, 0xe4, 0x12, 0x21, 0xf1, 0xe8, + 0xa4, 0xf8, 0xdb, 0x4e, 0xc4, 0x85, 0x97, 0x78, 0x69, 0x55, 0x98, 0x65, 0x8b, 0x11, 0xb3, 0x27, + 0xf0, 0x7c, 0x50, 0x52, 0xec, 0x7d, 0x96, 0x3d, 0x81, 0xc3, 0xd3, 0xd9, 0x13, 0x24, 0x02, 0xed, + 0x0e, 0xac, 0x65, 0x35, 0x2c, 0x76, 0x3b, 0x56, 0x4e, 0x7a, 0x3b, 0xfe, 0x5e, 0x1e, 0x16, 0x91, + 0x9b, 0xd8, 0x85, 0x75, 0x58, 0xb2, 0xc6, 0xf7, 0xc3, 0xd0, 0x82, 0x62, 0x37, 0xc6, 0xfa, 0x05, + 0x72, 0x81, 0x6c, 0xc3, 0x8b, 0x51, 0x10, 0x03, 0x96, 0xc5, 0x49, 0xb0, 0x23, 0x3c, 0x07, 0xc2, + 0xc4, 0x05, 0xc2, 0xa1, 0x22, 0x9d, 0x16, 0x3c, 0x41, 0x14, 0x9d, 0x07, 0xf9, 0xc7, 0x39, 0x0f, + 0x0a, 0x27, 0x3a, 0x0f, 0xde, 0x80, 0x45, 0xf1, 0x35, 0xdc, 0xc9, 0x67, 0x3e, 0xd8, 0x4e, 0x1e, + 0x63, 0x46, 0x6a, 0xe1, 0x8e, 0x3e, 0x3b, 0x75, 0x47, 0x47, 0xc3, 0xa8, 0x58, 0x65, 0x03, 0x84, + 0xa5, 0x37, 0x76, 0xcc, 0x9b, 0xbb, 0x53, 0x6e, 0xfd, 0x02, 0xa7, 0xe4, 0x8b, 0x30, 0x5f, 0xf3, + 0x85, 0x4d, 0x4c, 0x32, 0x46, 0xf4, 0x04, 0x50, 0x16, 0x17, 0x42, 0xcc, 0xf0, 0x74, 0xcb, 0x7f, + 0x18, 0xa7, 0xdb, 0x2d, 0x00, 0xee, 0x92, 0x12, 0xe5, 0xbb, 0xc4, 0x25, 0x23, 0x22, 0x24, 0xc5, + 0x6d, 0x22, 0x12, 0x32, 0xdd, 0x9d, 0xf8, 0x73, 0x1b, 0xe1, 0xc2, 0x2d, 0x27, 0x88, 0x17, 0x3e, + 0xf0, 0xc2, 0x2b, 0x5c, 0xde, 0x1e, 0x12, 0x64, 0x1f, 0xee, 0x80, 0x90, 0xcf, 0x86, 0x8f, 0x1f, + 0xe7, 0xa6, 0xf5, 0x90, 0x96, 0xea, 0xa1, 0x89, 0x4f, 0x1e, 0xb5, 0x1f, 0x2b, 0x72, 0xd6, 0x98, + 0x5f, 0x60, 0xa8, 0x5f, 0x06, 0x08, 0x1f, 0x25, 0x88, 0xb1, 0x0e, 0xdd, 0xc4, 0x19, 0x54, 0xee, + 0xe5, 0x08, 0x57, 0x6a, 0x4d, 0xfe, 0xc3, 0x6a, 0x4d, 0x1b, 0x16, 0x9a, 0x6f, 0x8e, 0x9c, 0xe8, + 0x15, 0x0b, 0x58, 0xa1, 0x24, 0x8b, 0x3b, 0x53, 0x7e, 0xeb, 0x69, 0x3c, 0x1b, 0x22, 0x39, 0x78, + 0x82, 0x08, 0x2c, 0x11, 0x6a, 0xff, 0xa5, 0xc0, 0x8a, 0x1c, 0xb8, 0xe3, 0x61, 0xbf, 0x43, 0x5e, + 0x63, 0x41, 0xac, 0x95, 0xd8, 0x95, 0x45, 0x42, 0xa2, 0x5b, 0xee, 0xc3, 0x7e, 0x87, 0x09, 0x40, + 0xce, 0x03, 0xb9, 0xb2, 0x94, 0x90, 0xdc, 0x87, 0xc5, 0x96, 0xdf, 0xeb, 0x51, 0xb1, 0x66, 0xf8, + 0x36, 0xbf, 0x00, 0x50, 0x46, 0x49, 0xd3, 0x88, 0xa8, 0xd0, 0xd6, 0x53, 0xfc, 0x9e, 0xbb, 0x3e, + 0xa0, 0xfb, 0xbd, 0xc7, 0xe9, 0x22, 0xb6, 0xef, 0xa0, 0x6b, 0xa0, 0xcc, 0x33, 0x3a, 0x9b, 0xe2, + 0xd9, 0x4f, 0xe4, 0x5a, 0xd2, 0x62, 0xac, 0xe7, 0x94, 0xb3, 0x49, 0xfb, 0xa9, 0x02, 0x24, 0xdd, + 0x34, 0x79, 0xeb, 0x53, 0xfe, 0x17, 0x44, 0xe1, 0x84, 0x08, 0x59, 0x78, 0x1c, 0x11, 0x52, 0xfb, + 0xae, 0x02, 0x6b, 0x59, 0xfd, 0x40, 0x4f, 0x10, 0xf9, 0x48, 0x09, 0x0f, 0x34, 0x3c, 0x41, 0xe4, + 0x53, 0x28, 0x7e, 0xac, 0x25, 0x88, 0x92, 0x95, 0xcb, 0x3d, 0x4e, 0xe5, 0x4a, 0xbf, 0xa7, 0xc0, + 0x4a, 0x55, 0xaf, 0xf3, 0x64, 0x39, 0xcc, 0x4c, 0x75, 0x19, 0x2e, 0x54, 0xf5, 0xba, 0xdd, 0x6a, + 0xd6, 0xaa, 0xe5, 0x7b, 0x76, 0x66, 0x0c, 0xfc, 0x0b, 0xf0, 0x44, 0x1a, 0x25, 0x32, 0x67, 0x9d, + 0x87, 0x8d, 0x74, 0xb1, 0x88, 0x93, 0x9f, 0x4d, 0x2c, 0x42, 0xea, 0xe7, 0x4b, 0xaf, 0xc3, 0x8a, + 0x88, 0x09, 0xdf, 0xae, 0x59, 0x98, 0x75, 0x66, 0x05, 0x16, 0xf6, 0x0d, 0xb3, 0xba, 0x7d, 0xcf, + 0xde, 0xde, 0xab, 0xd5, 0xd4, 0x53, 0x64, 0x09, 0xe6, 0x39, 0xa0, 0xac, 0xab, 0x0a, 0x59, 0x84, + 0x62, 0xb5, 0x61, 0x19, 0xe5, 0x3d, 0xd3, 0x50, 0x73, 0xa5, 0xd7, 0x61, 0xb9, 0x35, 0xf4, 0xde, + 0x76, 0x46, 0xee, 0x1d, 0xf7, 0x21, 0x5a, 0xa3, 0xe6, 0x20, 0x6f, 0xea, 0x77, 0xd5, 0x53, 0x04, + 0x60, 0xb6, 0x75, 0xa7, 0x6c, 0xdd, 0xb8, 0xa1, 0x2a, 0x64, 0x01, 0xe6, 0x76, 0xca, 0x2d, 0xfb, + 0x4e, 0xdd, 0x52, 0x73, 0xf4, 0x87, 0x7e, 0xd7, 0xc2, 0x1f, 0xf9, 0xd2, 0xf3, 0xb0, 0x8a, 0x52, + 0x57, 0xcd, 0x0b, 0x46, 0x6e, 0xdf, 0x1d, 0x62, 0x1d, 0x16, 0xa1, 0x68, 0xb9, 0x74, 0xbb, 0x1c, + 0xb9, 0xac, 0x02, 0xf5, 0x71, 0x6f, 0xe4, 0x0d, 0x7a, 0xee, 0x57, 0x55, 0xa5, 0x74, 0x0b, 0x56, + 0x4c, 0x7f, 0x3c, 0xf2, 0xfa, 0x87, 0xd6, 0x88, 0x62, 0x1c, 0x3e, 0x24, 0x67, 0x60, 0x75, 0xaf, + 0xa1, 0xd7, 0xb7, 0xaa, 0x3b, 0x7b, 0xcd, 0x3d, 0xcb, 0xae, 0xeb, 0xed, 0xf2, 0x2e, 0xb3, 0x85, + 0xd5, 0x9b, 0x56, 0xdb, 0x36, 0x8d, 0xb2, 0xd1, 0x68, 0xab, 0x4a, 0xe9, 0xdb, 0xa8, 0x40, 0xea, + 0xf8, 0xfd, 0xee, 0xb6, 0xd3, 0x19, 0xf9, 0x43, 0xac, 0xb0, 0x06, 0x17, 0x2d, 0xa3, 0xdc, 0x6c, + 0x54, 0xec, 0x6d, 0xbd, 0xdc, 0x6e, 0x9a, 0x59, 0x49, 0x18, 0x36, 0xe1, 0x6c, 0x06, 0x4e, 0xb3, + 0xdd, 0x52, 0x15, 0x72, 0x09, 0xce, 0x65, 0x94, 0xdd, 0x35, 0xb6, 0xf4, 0xbd, 0xf6, 0x6e, 0x43, + 0xcd, 0x4d, 0x20, 0xb6, 0xac, 0xa6, 0x9a, 0x2f, 0xfd, 0x96, 0x02, 0xcb, 0x7b, 0x01, 0x7f, 0x57, + 0xbf, 0x87, 0x5e, 0xc4, 0x4f, 0xc2, 0xf9, 0x3d, 0xcb, 0x30, 0xed, 0x76, 0xf3, 0x8e, 0xd1, 0xb0, + 0xf7, 0x2c, 0x7d, 0x27, 0x59, 0x9b, 0x4b, 0x70, 0x4e, 0xc2, 0x30, 0x8d, 0x72, 0x73, 0xdf, 0x30, + 0xed, 0x96, 0x6e, 0x59, 0x77, 0x9b, 0x66, 0x45, 0x55, 0xe8, 0x17, 0x33, 0x10, 0xea, 0xdb, 0x3a, + 0xab, 0x4d, 0xac, 0xac, 0x61, 0xdc, 0xd5, 0x6b, 0xf6, 0x56, 0xb3, 0xad, 0xe6, 0x4b, 0x75, 0x2a, + 0xc4, 0x60, 0x28, 0x74, 0xf6, 0x7c, 0xb2, 0x08, 0x85, 0x46, 0xb3, 0x61, 0x24, 0x2d, 0xa8, 0x8b, + 0x50, 0xd4, 0x5b, 0x2d, 0xb3, 0xb9, 0x8f, 0x53, 0x0c, 0x60, 0xb6, 0x62, 0x34, 0x68, 0xcd, 0xf2, + 0xb4, 0xa4, 0x65, 0x36, 0xeb, 0xcd, 0xb6, 0x51, 0x51, 0x0b, 0x25, 0x53, 0xec, 0x2f, 0x82, 0x69, + 0xc7, 0x67, 0xe6, 0xca, 0x8a, 0xb1, 0xad, 0xef, 0xd5, 0xda, 0x7c, 0x88, 0xee, 0xd9, 0xa6, 0xf1, + 0xd9, 0x3d, 0xc3, 0x6a, 0x5b, 0xaa, 0x42, 0x54, 0x58, 0x6c, 0x18, 0x46, 0xc5, 0xb2, 0x4d, 0x63, + 0xbf, 0x6a, 0xdc, 0x55, 0x73, 0x94, 0x27, 0xfb, 0x9f, 0x7e, 0xa1, 0xf4, 0xae, 0x02, 0x84, 0x85, + 0x91, 0x17, 0xb9, 0xc9, 0x70, 0xc6, 0x5c, 0x84, 0xcd, 0x5d, 0x3a, 0xd4, 0xd8, 0xb4, 0x7a, 0xb3, + 0x92, 0xec, 0xb2, 0xb3, 0x40, 0x12, 0xe5, 0xcd, 0xed, 0x6d, 0x55, 0x21, 0xe7, 0xe0, 0x74, 0x02, + 0x5e, 0x31, 0x9b, 0x2d, 0x35, 0xb7, 0x99, 0x2b, 0x2a, 0x64, 0x3d, 0x55, 0x78, 0xc7, 0x30, 0x5a, + 0x6a, 0x9e, 0x0e, 0x51, 0xa2, 0x40, 0x2c, 0x09, 0x46, 0x5e, 0x28, 0x7d, 0x53, 0x81, 0xb3, 0xac, + 0x9a, 0x62, 0x7d, 0x85, 0x55, 0x3d, 0x0f, 0x1b, 0x3c, 0x39, 0x46, 0x56, 0x45, 0xd7, 0x40, 0x8d, + 0x95, 0xb2, 0x6a, 0x9e, 0x81, 0xd5, 0x18, 0x14, 0xeb, 0x91, 0xa3, 0xbb, 0x47, 0x0c, 0xbc, 0x65, + 0x58, 0x6d, 0xdb, 0xd8, 0xde, 0x6e, 0x9a, 0x6d, 0x56, 0x91, 0x7c, 0x49, 0x83, 0xd5, 0xb2, 0x3b, + 0x1c, 0xd1, 0xfb, 0x65, 0x3f, 0xf0, 0xfc, 0x3e, 0x56, 0x61, 0x09, 0xe6, 0x8d, 0xcf, 0xb5, 0x8d, + 0x86, 0x55, 0x6d, 0x36, 0xd4, 0x53, 0xa5, 0xf3, 0x09, 0x1c, 0xb1, 0x8e, 0x2d, 0x6b, 0x57, 0x3d, + 0x55, 0x72, 0x60, 0x49, 0xbc, 0x2e, 0x67, 0xb3, 0xe2, 0x22, 0x6c, 0x8a, 0xb9, 0x86, 0x3b, 0x4a, + 0xb2, 0x09, 0x1b, 0xb0, 0x96, 0x2e, 0x37, 0xda, 0xaa, 0x42, 0x47, 0x21, 0x51, 0x42, 0xe1, 0xb9, + 0xd2, 0xaf, 0x2b, 0xb0, 0x14, 0x5a, 0x86, 0x50, 0x17, 0x7d, 0x09, 0xce, 0xd5, 0xb7, 0x75, 0xbb, + 0x62, 0xec, 0x57, 0xcb, 0x86, 0x7d, 0xa7, 0xda, 0xa8, 0x24, 0x3e, 0xf2, 0x04, 0x9c, 0xc9, 0x40, + 0xc0, 0xaf, 0x6c, 0xc0, 0x5a, 0xb2, 0xa8, 0x4d, 0x97, 0x6a, 0x8e, 0x76, 0x7d, 0xb2, 0x24, 0x5c, + 0xa7, 0xf9, 0xd2, 0x3e, 0x2c, 0x5b, 0x7a, 0xbd, 0xb6, 0xed, 0x0f, 0x3b, 0xae, 0x3e, 0x1e, 0x1d, + 0xf5, 0xc9, 0x39, 0x58, 0xdf, 0x6e, 0x9a, 0x65, 0xc3, 0x46, 0x94, 0x44, 0x0d, 0x4e, 0xc3, 0x8a, + 0x5c, 0x78, 0xcf, 0xa0, 0xd3, 0x97, 0xc0, 0xb2, 0x0c, 0x6c, 0x34, 0xd5, 0x5c, 0xe9, 0x0b, 0xb0, + 0x18, 0x4b, 0x51, 0xba, 0x0e, 0xa7, 0xe5, 0xdf, 0x2d, 0xb7, 0xdf, 0xf5, 0xfa, 0x87, 0xea, 0xa9, + 0x64, 0x81, 0x39, 0xee, 0xf7, 0x69, 0x01, 0xae, 0x67, 0xb9, 0xa0, 0xed, 0x0e, 0x8f, 0xbd, 0xbe, + 0x33, 0x72, 0xbb, 0x6a, 0xae, 0xf4, 0x1c, 0x2c, 0xc5, 0x12, 0x23, 0xd0, 0x81, 0xab, 0x35, 0xf9, + 0x06, 0x5c, 0x37, 0x2a, 0xd5, 0xbd, 0xba, 0x3a, 0x43, 0x57, 0xf2, 0x6e, 0x75, 0x67, 0x57, 0x85, + 0xd2, 0x77, 0x14, 0x7a, 0x99, 0xc2, 0x74, 0x67, 0xf5, 0x6d, 0x5d, 0x0c, 0x35, 0x9d, 0x66, 0x2c, + 0xdd, 0x8a, 0x61, 0x59, 0xec, 0xe1, 0xc0, 0x79, 0xd8, 0xe0, 0x3f, 0x6c, 0xbd, 0x51, 0xb1, 0x77, + 0x75, 0xb3, 0x72, 0x57, 0x37, 0xe9, 0xdc, 0xbb, 0xa7, 0xe6, 0x70, 0x41, 0x49, 0x10, 0xbb, 0xdd, + 0xdc, 0x2b, 0xef, 0xaa, 0x79, 0x3a, 0x7f, 0x63, 0xf0, 0x56, 0xb5, 0xa1, 0x16, 0x70, 0x79, 0xa6, + 0xb0, 0x91, 0x2d, 0x2d, 0x9f, 0x29, 0xbd, 0xaf, 0xc0, 0xba, 0xe5, 0x1d, 0xf6, 0x9d, 0xd1, 0x78, + 0xe8, 0xea, 0xbd, 0x43, 0x7f, 0xe8, 0x8d, 0x8e, 0x8e, 0xad, 0xb1, 0x37, 0x72, 0xc9, 0x75, 0x78, + 0xda, 0xaa, 0xee, 0x34, 0xf4, 0x36, 0x5d, 0x5e, 0x7a, 0x6d, 0xa7, 0x69, 0x56, 0xdb, 0xbb, 0x75, + 0xdb, 0xda, 0xab, 0xa6, 0x66, 0xde, 0x15, 0x78, 0x72, 0x32, 0x6a, 0xcd, 0xd8, 0xd1, 0xcb, 0xf7, + 0x54, 0x65, 0x3a, 0xc3, 0x2d, 0xbd, 0xa6, 0x37, 0xca, 0x46, 0xc5, 0xde, 0xbf, 0xa1, 0xe6, 0xc8, + 0xd3, 0x70, 0x79, 0x32, 0xea, 0x76, 0xb5, 0x65, 0x51, 0xb4, 0xfc, 0xf4, 0xef, 0xee, 0x5a, 0x75, + 0x8a, 0x55, 0x28, 0x7d, 0x57, 0x81, 0x8d, 0x49, 0xa1, 0xea, 0xc8, 0x55, 0xd0, 0x8c, 0x46, 0xdb, + 0xd4, 0xab, 0x15, 0xbb, 0x6c, 0x1a, 0x15, 0xa3, 0xd1, 0xae, 0xea, 0x35, 0xcb, 0xb6, 0x9a, 0x7b, + 0x74, 0x36, 0x45, 0xef, 0x3b, 0x9e, 0x82, 0x4b, 0x53, 0xf0, 0x9a, 0xd5, 0x4a, 0x59, 0x55, 0xc8, + 0x0d, 0x78, 0x76, 0x0a, 0x92, 0x75, 0xcf, 0x6a, 0x1b, 0x75, 0xb9, 0x44, 0xcd, 0xe1, 0x86, 0x95, + 0x1d, 0xa9, 0x8b, 0xb6, 0x0e, 0x4b, 0xa6, 0x57, 0xec, 0x32, 0x5c, 0x98, 0x88, 0xc5, 0xab, 0xf5, + 0x14, 0x5c, 0x9a, 0x88, 0xc2, 0x2a, 0xa5, 0xe6, 0x4a, 0x65, 0xd8, 0x9c, 0x1c, 0xac, 0x88, 0x9e, + 0x17, 0xf1, 0x21, 0x2f, 0x42, 0xa1, 0x42, 0x8f, 0xa8, 0x58, 0x7a, 0xa0, 0x92, 0x07, 0x6a, 0x32, + 0x90, 0x47, 0xea, 0x45, 0x90, 0xb9, 0xd7, 0x68, 0xb0, 0xf3, 0x6c, 0x05, 0x16, 0x9a, 0xed, 0x5d, + 0xc3, 0xe4, 0x09, 0x96, 0x30, 0xa3, 0xd2, 0x5e, 0x83, 0xae, 0xe0, 0xa6, 0x59, 0xfd, 0x3c, 0x1e, + 0x6c, 0x1b, 0xb0, 0x66, 0xd5, 0xf4, 0xf2, 0x1d, 0xbb, 0xd1, 0x6c, 0xdb, 0xd5, 0x86, 0x5d, 0xde, + 0xd5, 0x1b, 0x0d, 0xa3, 0xa6, 0x02, 0x8e, 0xea, 0x24, 0x4f, 0x56, 0xf2, 0x71, 0xb8, 0xd6, 0xbc, + 0xd3, 0xd6, 0xed, 0x56, 0x6d, 0x6f, 0xa7, 0xda, 0xb0, 0xad, 0x7b, 0x8d, 0xb2, 0x10, 0xc2, 0xca, + 0xe9, 0xbd, 0xff, 0x1a, 0x5c, 0x99, 0x8a, 0x1d, 0xa5, 0x42, 0xba, 0x0a, 0xda, 0x54, 0x4c, 0xde, + 0x90, 0xd2, 0x4f, 0x14, 0x38, 0x37, 0xc5, 0x62, 0x4f, 0x9e, 0x85, 0xeb, 0xbb, 0x86, 0x5e, 0xa9, + 0x19, 0x96, 0x85, 0x3b, 0x16, 0x1d, 0x14, 0xf6, 0x72, 0x28, 0x73, 0x67, 0xbf, 0x0e, 0x4f, 0x4f, + 0x47, 0x8f, 0x64, 0x84, 0x6b, 0x70, 0x65, 0x3a, 0x2a, 0x97, 0x19, 0x72, 0xa4, 0x04, 0x57, 0xa7, + 0x63, 0x86, 0xb2, 0x46, 0xbe, 0xf4, 0x3b, 0x0a, 0x9c, 0xcd, 0x56, 0x9b, 0xd1, 0xba, 0x55, 0x1b, + 0x56, 0x5b, 0xaf, 0xd5, 0xec, 0x96, 0x6e, 0xea, 0x75, 0xdb, 0x68, 0x98, 0xcd, 0x5a, 0x2d, 0xeb, + 0x8c, 0xbd, 0x02, 0x4f, 0x4e, 0x46, 0xb5, 0xca, 0x66, 0xb5, 0x45, 0x8f, 0x11, 0x0d, 0x2e, 0x4e, + 0xc6, 0x32, 0xaa, 0x65, 0x43, 0xcd, 0x6d, 0xbd, 0xfa, 0xa3, 0x7f, 0xb8, 0x78, 0xea, 0x47, 0xef, + 0x5f, 0x54, 0x7e, 0xfa, 0xfe, 0x45, 0xe5, 0xef, 0xdf, 0xbf, 0xa8, 0x7c, 0xfe, 0x99, 0x93, 0x65, + 0x11, 0xc4, 0xdb, 0xd1, 0xfd, 0x59, 0xbc, 0x0f, 0xbe, 0xf0, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, + 0x46, 0xfc, 0x79, 0x44, 0xea, 0xc7, 0x01, 0x00, } func (this *PluginSpecV1) Equal(that interface{}) bool { @@ -30142,6 +30248,20 @@ func (m *ProvisionTokenSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Oracle != nil { + { + size, err := m.Oracle.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } if m.Bitbucket != nil { { size, err := m.Bitbucket.MarshalToSizedBuffer(dAtA[:i]) @@ -31513,6 +31633,99 @@ func (m *ProvisionTokenSpecV2Bitbucket_Rule) MarshalToSizedBuffer(dAtA []byte) ( return len(dAtA) - i, nil } +func (m *ProvisionTokenSpecV2Oracle) 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 *ProvisionTokenSpecV2Oracle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProvisionTokenSpecV2Oracle) 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.Allow) > 0 { + for iNdEx := len(m.Allow) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Allow[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ProvisionTokenSpecV2Oracle_Rule) 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 *ProvisionTokenSpecV2Oracle_Rule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProvisionTokenSpecV2Oracle_Rule) 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.Regions) > 0 { + for iNdEx := len(m.Regions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Regions[iNdEx]) + copy(dAtA[i:], m.Regions[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Regions[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.ParentCompartments) > 0 { + for iNdEx := len(m.ParentCompartments) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ParentCompartments[iNdEx]) + copy(dAtA[i:], m.ParentCompartments[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ParentCompartments[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Tenancy) > 0 { + i -= len(m.Tenancy) + copy(dAtA[i:], m.Tenancy) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Tenancy))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *StaticTokensV2) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -32451,20 +32664,20 @@ func (m *AuthPreferenceSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xb2 } if len(m.SecondFactors) > 0 { - dAtA110 := make([]byte, len(m.SecondFactors)*10) - var j109 int + dAtA111 := make([]byte, len(m.SecondFactors)*10) + var j110 int for _, num := range m.SecondFactors { for num >= 1<<7 { - dAtA110[j109] = uint8(uint64(num)&0x7f | 0x80) + dAtA111[j110] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j109++ + j110++ } - dAtA110[j109] = uint8(num) - j109++ + dAtA111[j110] = uint8(num) + j110++ } - i -= j109 - copy(dAtA[i:], dAtA110[:j109]) - i = encodeVarintTypes(dAtA, i, uint64(j109)) + i -= j110 + copy(dAtA[i:], dAtA111[:j110]) + i = encodeVarintTypes(dAtA, i, uint64(j110)) i-- dAtA[i] = 0x1 i-- @@ -33132,12 +33345,12 @@ func (m *UserTokenSpecV3) 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.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err126 != nil { - return 0, err126 + n127, err127 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err127 != nil { + return 0, err127 } - i -= n126 - i = encodeVarintTypes(dAtA, i, uint64(n126)) + i -= n127 + i = encodeVarintTypes(dAtA, i, uint64(n127)) i-- dAtA[i] = 0x22 if m.Usage != 0 { @@ -33254,12 +33467,12 @@ func (m *UserTokenSecretsSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n129, err129 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err129 != nil { - return 0, err129 + n130, err130 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err130 != nil { + return 0, err130 } - i -= n129 - i = encodeVarintTypes(dAtA, i, uint64(n129)) + i -= n130 + i = encodeVarintTypes(dAtA, i, uint64(n130)) i-- dAtA[i] = 0x1a if len(m.QRCode) > 0 { @@ -33464,12 +33677,12 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if m.AssumeStartTime != nil { - n132, err132 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) - if err132 != nil { - return 0, err132 + n133, err133 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) + if err133 != nil { + return 0, err133 } - i -= n132 - i = encodeVarintTypes(dAtA, i, uint64(n132)) + i -= n133 + i = encodeVarintTypes(dAtA, i, uint64(n133)) i-- dAtA[i] = 0x52 } @@ -33486,20 +33699,20 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x4a } if len(m.ThresholdIndexes) > 0 { - dAtA135 := make([]byte, len(m.ThresholdIndexes)*10) - var j134 int + dAtA136 := make([]byte, len(m.ThresholdIndexes)*10) + var j135 int for _, num := range m.ThresholdIndexes { for num >= 1<<7 { - dAtA135[j134] = uint8(uint64(num)&0x7f | 0x80) + dAtA136[j135] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j134++ + j135++ } - dAtA135[j134] = uint8(num) - j134++ + dAtA136[j135] = uint8(num) + j135++ } - i -= j134 - copy(dAtA[i:], dAtA135[:j134]) - i = encodeVarintTypes(dAtA, i, uint64(j134)) + i -= j135 + copy(dAtA[i:], dAtA136[:j135]) + i = encodeVarintTypes(dAtA, i, uint64(j135)) i-- dAtA[i] = 0x3a } @@ -33513,12 +33726,12 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x32 - n137, err137 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err137 != nil { - return 0, err137 + n138, err138 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err138 != nil { + return 0, err138 } - i -= n137 - i = encodeVarintTypes(dAtA, i, uint64(n137)) + i -= n138 + i = encodeVarintTypes(dAtA, i, uint64(n138)) i-- dAtA[i] = 0x2a if len(m.Reason) > 0 { @@ -33621,20 +33834,20 @@ func (m *ThresholdIndexSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.Indexes) > 0 { - dAtA140 := make([]byte, len(m.Indexes)*10) - var j139 int + dAtA141 := make([]byte, len(m.Indexes)*10) + var j140 int for _, num := range m.Indexes { for num >= 1<<7 { - dAtA140[j139] = uint8(uint64(num)&0x7f | 0x80) + dAtA141[j140] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j139++ + j140++ } - dAtA140[j139] = uint8(num) - j139++ + dAtA141[j140] = uint8(num) + j140++ } - i -= j139 - copy(dAtA[i:], dAtA140[:j139]) - i = encodeVarintTypes(dAtA, i, uint64(j139)) + i -= j140 + copy(dAtA[i:], dAtA141[:j140]) + i = encodeVarintTypes(dAtA, i, uint64(j140)) i-- dAtA[i] = 0xa } @@ -33707,24 +33920,24 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if m.ResourceExpiry != nil { - n141, err141 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ResourceExpiry, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ResourceExpiry):]) - if err141 != nil { - return 0, err141 + n142, err142 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ResourceExpiry, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ResourceExpiry):]) + if err142 != nil { + return 0, err142 } - i -= n141 - i = encodeVarintTypes(dAtA, i, uint64(n141)) + i -= n142 + i = encodeVarintTypes(dAtA, i, uint64(n142)) i-- dAtA[i] = 0x1 i-- dAtA[i] = 0xb2 } if m.AssumeStartTime != nil { - n142, err142 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) - if err142 != nil { - return 0, err142 + n143, err143 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) + if err143 != nil { + return 0, err143 } - i -= n142 - i = encodeVarintTypes(dAtA, i, uint64(n142)) + i -= n143 + i = encodeVarintTypes(dAtA, i, uint64(n143)) i-- dAtA[i] = 0x1 i-- @@ -33744,22 +33957,22 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xa2 } - n144, err144 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SessionTTL, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SessionTTL):]) - if err144 != nil { - return 0, err144 + n145, err145 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SessionTTL, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SessionTTL):]) + if err145 != nil { + return 0, err145 } - i -= n144 - i = encodeVarintTypes(dAtA, i, uint64(n144)) + i -= n145 + i = encodeVarintTypes(dAtA, i, uint64(n145)) i-- dAtA[i] = 0x1 i-- dAtA[i] = 0x92 - n145, err145 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.MaxDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.MaxDuration):]) - if err145 != nil { - return 0, err145 + n146, err146 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.MaxDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.MaxDuration):]) + if err146 != nil { + return 0, err146 } - i -= n145 - i = encodeVarintTypes(dAtA, i, uint64(n145)) + i -= n146 + i = encodeVarintTypes(dAtA, i, uint64(n146)) i-- dAtA[i] = 0x1 i-- @@ -33892,21 +34105,21 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n149, err149 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err149 != nil { - return 0, err149 - } - i -= n149 - i = encodeVarintTypes(dAtA, i, uint64(n149)) - i-- - dAtA[i] = 0x2a - n150, err150 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + n150, err150 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) if err150 != nil { return 0, err150 } i -= n150 i = encodeVarintTypes(dAtA, i, uint64(n150)) i-- + dAtA[i] = 0x2a + n151, err151 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err151 != nil { + return 0, err151 + } + i -= n151 + i = encodeVarintTypes(dAtA, i, uint64(n151)) + i-- dAtA[i] = 0x22 if m.State != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.State)) @@ -34902,12 +35115,12 @@ func (m *RoleOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xfa } - n164, err164 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MFAVerificationInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MFAVerificationInterval):]) - if err164 != nil { - return 0, err164 + n165, err165 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MFAVerificationInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MFAVerificationInterval):]) + if err165 != nil { + return 0, err165 } - i -= n164 - i = encodeVarintTypes(dAtA, i, uint64(n164)) + i -= n165 + i = encodeVarintTypes(dAtA, i, uint64(n165)) i-- dAtA[i] = 0x1 i-- @@ -36921,12 +37134,12 @@ func (m *UserSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x42 - n195, err195 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err195 != nil { - return 0, err195 + n196, err196 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err196 != nil { + return 0, err196 } - i -= n195 - i = encodeVarintTypes(dAtA, i, uint64(n195)) + i -= n196 + i = encodeVarintTypes(dAtA, i, uint64(n196)) i-- dAtA[i] = 0x3a { @@ -37082,21 +37295,21 @@ func (m *LoginStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n198, err198 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires):]) - if err198 != nil { - return 0, err198 - } - i -= n198 - i = encodeVarintTypes(dAtA, i, uint64(n198)) - i-- - dAtA[i] = 0x22 - n199, err199 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime):]) + n199, err199 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires):]) if err199 != nil { return 0, err199 } i -= n199 i = encodeVarintTypes(dAtA, i, uint64(n199)) i-- + dAtA[i] = 0x22 + n200, err200 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime):]) + if err200 != nil { + return 0, err200 + } + i -= n200 + i = encodeVarintTypes(dAtA, i, uint64(n200)) + i-- dAtA[i] = 0x1a if len(m.LockedMessage) > 0 { i -= len(m.LockedMessage) @@ -37152,12 +37365,12 @@ func (m *CreatedBy) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - n201, err201 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err201 != nil { - return 0, err201 + n202, err202 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err202 != nil { + return 0, err202 } - i -= n201 - i = encodeVarintTypes(dAtA, i, uint64(n201)) + i -= n202 + i = encodeVarintTypes(dAtA, i, uint64(n202)) i-- dAtA[i] = 0x12 if m.Connector != nil { @@ -37275,21 +37488,21 @@ func (m *MFADevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } } - n204, err204 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUsed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUsed):]) - if err204 != nil { - return 0, err204 - } - i -= n204 - i = encodeVarintTypes(dAtA, i, uint64(n204)) - i-- - dAtA[i] = 0x3a - n205, err205 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AddedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AddedAt):]) + n205, err205 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUsed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUsed):]) if err205 != nil { return 0, err205 } i -= n205 i = encodeVarintTypes(dAtA, i, uint64(n205)) i-- + dAtA[i] = 0x3a + n206, err206 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AddedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AddedAt):]) + if err206 != nil { + return 0, err206 + } + i -= n206 + i = encodeVarintTypes(dAtA, i, uint64(n206)) + i-- dAtA[i] = 0x32 if len(m.Id) > 0 { i -= len(m.Id) @@ -37985,12 +38198,12 @@ func (m *TunnelConnectionSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x22 } - n217, err217 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) - if err217 != nil { - return 0, err217 + n218, err218 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) + if err218 != nil { + return 0, err218 } - i -= n217 - i = encodeVarintTypes(dAtA, i, uint64(n217)) + i -= n218 + i = encodeVarintTypes(dAtA, i, uint64(n218)) i-- dAtA[i] = 0x1a if len(m.ProxyName) > 0 { @@ -38082,12 +38295,12 @@ func (m *AcquireSemaphoreRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x2a } - n218, err218 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err218 != nil { - return 0, err218 + n219, err219 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err219 != nil { + return 0, err219 } - i -= n218 - i = encodeVarintTypes(dAtA, i, uint64(n218)) + i -= n219 + i = encodeVarintTypes(dAtA, i, uint64(n219)) i-- dAtA[i] = 0x22 if m.MaxLeases != 0 { @@ -38136,12 +38349,12 @@ func (m *SemaphoreLease) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n219, err219 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err219 != nil { - return 0, err219 + n220, err220 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err220 != nil { + return 0, err220 } - i -= n219 - i = encodeVarintTypes(dAtA, i, uint64(n219)) + i -= n220 + i = encodeVarintTypes(dAtA, i, uint64(n220)) i-- dAtA[i] = 0x2a if len(m.LeaseID) > 0 { @@ -38199,12 +38412,12 @@ func (m *SemaphoreLeaseRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - n220, err220 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err220 != nil { - return 0, err220 + n221, err221 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err221 != nil { + return 0, err221 } - i -= n220 - i = encodeVarintTypes(dAtA, i, uint64(n220)) + i -= n221 + i = encodeVarintTypes(dAtA, i, uint64(n221)) i-- dAtA[i] = 0x12 if len(m.LeaseID) > 0 { @@ -38476,29 +38689,29 @@ func (m *WebSessionSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x48 } - n227, err227 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LoginTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LoginTime):]) - if err227 != nil { - return 0, err227 - } - i -= n227 - i = encodeVarintTypes(dAtA, i, uint64(n227)) - i-- - dAtA[i] = 0x42 - n228, err228 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + n228, err228 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LoginTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LoginTime):]) if err228 != nil { return 0, err228 } i -= n228 i = encodeVarintTypes(dAtA, i, uint64(n228)) i-- - dAtA[i] = 0x3a - n229, err229 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.BearerTokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.BearerTokenExpires):]) + dAtA[i] = 0x42 + n229, err229 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) if err229 != nil { return 0, err229 } i -= n229 i = encodeVarintTypes(dAtA, i, uint64(n229)) i-- + dAtA[i] = 0x3a + n230, err230 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.BearerTokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.BearerTokenExpires):]) + if err230 != nil { + return 0, err230 + } + i -= n230 + i = encodeVarintTypes(dAtA, i, uint64(n230)) + i-- dAtA[i] = 0x32 if len(m.BearerToken) > 0 { i -= len(m.BearerToken) @@ -38730,21 +38943,21 @@ func (m *SAMLSessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n230, err230 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpireTime):]) - if err230 != nil { - return 0, err230 - } - i -= n230 - i = encodeVarintTypes(dAtA, i, uint64(n230)) - i-- - dAtA[i] = 0x1a - n231, err231 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateTime):]) + n231, err231 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpireTime):]) if err231 != nil { return 0, err231 } i -= n231 i = encodeVarintTypes(dAtA, i, uint64(n231)) i-- + dAtA[i] = 0x1a + n232, err232 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateTime):]) + if err232 != nil { + return 0, err232 + } + i -= n232 + i = encodeVarintTypes(dAtA, i, uint64(n232)) + i-- dAtA[i] = 0x12 if len(m.ID) > 0 { i -= len(m.ID) @@ -39025,12 +39238,12 @@ func (m *RemoteClusterStatusV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n235, err235 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) - if err235 != nil { - return 0, err235 + n236, err236 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) + if err236 != nil { + return 0, err236 } - i -= n235 - i = encodeVarintTypes(dAtA, i, uint64(n235)) + i -= n236 + i = encodeVarintTypes(dAtA, i, uint64(n236)) i-- dAtA[i] = 0x12 if len(m.Connection) > 0 { @@ -41808,12 +42021,12 @@ func (m *GithubAuthRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x62 } if m.Expires != nil { - n276, err276 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err276 != nil { - return 0, err276 + n277, err277 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err277 != nil { + return 0, err277 } - i -= n276 - i = encodeVarintTypes(dAtA, i, uint64(n276)) + i -= n277 + i = encodeVarintTypes(dAtA, i, uint64(n277)) i-- dAtA[i] = 0x5a } @@ -42832,21 +43045,21 @@ func (m *LockSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2a } - n294, err294 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):]) - if err294 != nil { - return 0, err294 + n295, err295 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):]) + if err295 != nil { + return 0, err295 } - i -= n294 - i = encodeVarintTypes(dAtA, i, uint64(n294)) + i -= n295 + i = encodeVarintTypes(dAtA, i, uint64(n295)) i-- dAtA[i] = 0x22 if m.Expires != nil { - n295, err295 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err295 != nil { - return 0, err295 + n296, err296 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err296 != nil { + return 0, err296 } - i -= n295 - i = encodeVarintTypes(dAtA, i, uint64(n295)) + i -= n296 + i = encodeVarintTypes(dAtA, i, uint64(n296)) i-- dAtA[i] = 0x1a } @@ -43563,12 +43776,12 @@ func (m *RegisterUsingTokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro dAtA[i] = 0x6a } if m.Expires != nil { - n307, err307 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err307 != nil { - return 0, err307 + n308, err308 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err308 != nil { + return 0, err308 } - i -= n307 - i = encodeVarintTypes(dAtA, i, uint64(n307)) + i -= n308 + i = encodeVarintTypes(dAtA, i, uint64(n308)) i-- dAtA[i] = 0x62 } @@ -43748,12 +43961,12 @@ func (m *RecoveryCodesSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n310, err310 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err310 != nil { - return 0, err310 + n311, err311 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err311 != nil { + return 0, err311 } - i -= n310 - i = encodeVarintTypes(dAtA, i, uint64(n310)) + i -= n311 + i = encodeVarintTypes(dAtA, i, uint64(n311)) i-- dAtA[i] = 0x12 if len(m.Codes) > 0 { @@ -44133,21 +44346,21 @@ func (m *SessionTrackerSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n314, err314 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err314 != nil { - return 0, err314 - } - i -= n314 - i = encodeVarintTypes(dAtA, i, uint64(n314)) - i-- - dAtA[i] = 0x2a - n315, err315 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + n315, err315 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) if err315 != nil { return 0, err315 } i -= n315 i = encodeVarintTypes(dAtA, i, uint64(n315)) i-- + dAtA[i] = 0x2a + n316, err316 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err316 != nil { + return 0, err316 + } + i -= n316 + i = encodeVarintTypes(dAtA, i, uint64(n316)) + i-- dAtA[i] = 0x22 if m.State != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.State)) @@ -44250,12 +44463,12 @@ func (m *Participant) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n316, err316 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) - if err316 != nil { - return 0, err316 + n317, err317 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) + if err317 != nil { + return 0, err317 } - i -= n316 - i = encodeVarintTypes(dAtA, i, uint64(n316)) + i -= n317 + i = encodeVarintTypes(dAtA, i, uint64(n317)) i-- dAtA[i] = 0x22 if len(m.Mode) > 0 { @@ -44967,12 +45180,12 @@ func (m *ClusterAlertSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n329, err329 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err329 != nil { - return 0, err329 + n330, err330 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err330 != nil { + return 0, err330 } - i -= n329 - i = encodeVarintTypes(dAtA, i, uint64(n329)) + i -= n330 + i = encodeVarintTypes(dAtA, i, uint64(n330)) i-- dAtA[i] = 0x1a if len(m.Message) > 0 { @@ -45102,12 +45315,12 @@ func (m *AlertAcknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n330, err330 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err330 != nil { - return 0, err330 + n331, err331 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err331 != nil { + return 0, err331 } - i -= n330 - i = encodeVarintTypes(dAtA, i, uint64(n330)) + i -= n331 + i = encodeVarintTypes(dAtA, i, uint64(n331)) i-- dAtA[i] = 0x22 if len(m.Reason) > 0 { @@ -47675,12 +47888,12 @@ func (m *PluginStatusV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n366, err366 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSyncTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSyncTime):]) - if err366 != nil { - return 0, err366 + n367, err367 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSyncTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSyncTime):]) + if err367 != nil { + return 0, err367 } - i -= n366 - i = encodeVarintTypes(dAtA, i, uint64(n366)) + i -= n367 + i = encodeVarintTypes(dAtA, i, uint64(n367)) i-- dAtA[i] = 0x1a if len(m.ErrorMessage) > 0 { @@ -48109,22 +48322,22 @@ func (m *PluginOktaStatusDetailsAppGroupSync) MarshalToSizedBuffer(dAtA []byte) dAtA[i] = 0x28 } if m.LastFailed != nil { - n377, err377 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err377 != nil { - return 0, err377 + n378, err378 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err378 != nil { + return 0, err378 } - i -= n377 - i = encodeVarintTypes(dAtA, i, uint64(n377)) + i -= n378 + i = encodeVarintTypes(dAtA, i, uint64(n378)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n378, err378 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err378 != nil { - return 0, err378 + n379, err379 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err379 != nil { + return 0, err379 } - i -= n378 - i = encodeVarintTypes(dAtA, i, uint64(n378)) + i -= n379 + i = encodeVarintTypes(dAtA, i, uint64(n379)) i-- dAtA[i] = 0x1a } @@ -48183,22 +48396,22 @@ func (m *PluginOktaStatusDetailsUsersSync) MarshalToSizedBuffer(dAtA []byte) (in dAtA[i] = 0x28 } if m.LastFailed != nil { - n379, err379 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err379 != nil { - return 0, err379 + n380, err380 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err380 != nil { + return 0, err380 } - i -= n379 - i = encodeVarintTypes(dAtA, i, uint64(n379)) + i -= n380 + i = encodeVarintTypes(dAtA, i, uint64(n380)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n380, err380 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err380 != nil { - return 0, err380 + n381, err381 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err381 != nil { + return 0, err381 } - i -= n380 - i = encodeVarintTypes(dAtA, i, uint64(n380)) + i -= n381 + i = encodeVarintTypes(dAtA, i, uint64(n381)) i-- dAtA[i] = 0x1a } @@ -48317,22 +48530,22 @@ func (m *PluginOktaStatusDetailsAccessListsSync) MarshalToSizedBuffer(dAtA []byt } } if m.LastFailed != nil { - n381, err381 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err381 != nil { - return 0, err381 + n382, err382 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err382 != nil { + return 0, err382 } - i -= n381 - i = encodeVarintTypes(dAtA, i, uint64(n381)) + i -= n382 + i = encodeVarintTypes(dAtA, i, uint64(n382)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n382, err382 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err382 != nil { - return 0, err382 + n383, err383 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err383 != nil { + return 0, err383 } - i -= n382 - i = encodeVarintTypes(dAtA, i, uint64(n382)) + i -= n383 + i = encodeVarintTypes(dAtA, i, uint64(n383)) i-- dAtA[i] = 0x1a } @@ -48498,12 +48711,12 @@ func (m *PluginOAuth2AccessTokenCredentials) MarshalToSizedBuffer(dAtA []byte) ( i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n387, err387 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err387 != nil { - return 0, err387 + n388, err388 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err388 != nil { + return 0, err388 } - i -= n387 - i = encodeVarintTypes(dAtA, i, uint64(n387)) + i -= n388 + i = encodeVarintTypes(dAtA, i, uint64(n388)) i-- dAtA[i] = 0x1a if len(m.RefreshToken) > 0 { @@ -49445,21 +49658,21 @@ func (m *ScheduledAgentUpgradeWindow) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n402, err402 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) - if err402 != nil { - return 0, err402 - } - i -= n402 - i = encodeVarintTypes(dAtA, i, uint64(n402)) - i-- - dAtA[i] = 0x12 - n403, err403 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) + n403, err403 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) if err403 != nil { return 0, err403 } i -= n403 i = encodeVarintTypes(dAtA, i, uint64(n403)) i-- + dAtA[i] = 0x12 + n404, err404 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) + if err404 != nil { + return 0, err404 + } + i -= n404 + i = encodeVarintTypes(dAtA, i, uint64(n404)) + i-- dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -49885,12 +50098,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x30 } - n410, err410 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) - if err410 != nil { - return 0, err410 + n411, err411 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) + if err411 != nil { + return 0, err411 } - i -= n410 - i = encodeVarintTypes(dAtA, i, uint64(n410)) + i -= n411 + i = encodeVarintTypes(dAtA, i, uint64(n411)) i-- dAtA[i] = 0x2a if m.Status != 0 { @@ -49898,12 +50111,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x20 } - n411, err411 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) - if err411 != nil { - return 0, err411 + n412, err412 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) + if err412 != nil { + return 0, err412 } - i -= n411 - i = encodeVarintTypes(dAtA, i, uint64(n411)) + i -= n412 + i = encodeVarintTypes(dAtA, i, uint64(n412)) i-- dAtA[i] = 0x1a if len(m.Targets) > 0 { @@ -51427,12 +51640,12 @@ func (m *AccessGraphSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } } - n436, err436 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) - if err436 != nil { - return 0, err436 + n437, err437 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) + if err437 != nil { + return 0, err437 } - i -= n436 - i = encodeVarintTypes(dAtA, i, uint64(n436)) + i -= n437 + i = encodeVarintTypes(dAtA, i, uint64(n437)) i-- dAtA[i] = 0x12 if len(m.AWS) > 0 { @@ -53487,6 +53700,10 @@ func (m *ProvisionTokenSpecV2) Size() (n int) { l = m.Bitbucket.Size() n += 2 + l + sovTypes(uint64(l)) } + if m.Oracle != nil { + l = m.Oracle.Size() + n += 2 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -54071,6 +54288,52 @@ func (m *ProvisionTokenSpecV2Bitbucket_Rule) Size() (n int) { return n } +func (m *ProvisionTokenSpecV2Oracle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Allow) > 0 { + for _, e := range m.Allow { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ProvisionTokenSpecV2Oracle_Rule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Tenancy) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.ParentCompartments) > 0 { + for _, s := range m.ParentCompartments { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Regions) > 0 { + for _, s := range m.Regions { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *StaticTokensV2) Size() (n int) { if m == nil { return 0 @@ -76310,6 +76573,42 @@ func (m *ProvisionTokenSpecV2) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Oracle", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Oracle == nil { + m.Oracle = &ProvisionTokenSpecV2Oracle{} + } + if err := m.Oracle.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -79803,6 +80102,238 @@ func (m *ProvisionTokenSpecV2Bitbucket_Rule) Unmarshal(dAtA []byte) error { } return nil } +func (m *ProvisionTokenSpecV2Oracle) 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 ErrIntOverflowTypes + } + 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: ProvisionTokenSpecV2Oracle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProvisionTokenSpecV2Oracle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allow", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allow = append(m.Allow, &ProvisionTokenSpecV2Oracle_Rule{}) + if err := m.Allow[len(m.Allow)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + 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 *ProvisionTokenSpecV2Oracle_Rule) 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 ErrIntOverflowTypes + } + 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: Rule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Rule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tenancy", 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.Tenancy = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentCompartments", 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.ParentCompartments = append(m.ParentCompartments, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Regions", 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.Regions = append(m.Regions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + 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 *StaticTokensV2) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/docs/pages/reference/operator-resources/resources-teleport-dev-provisiontokens.mdx b/docs/pages/reference/operator-resources/resources-teleport-dev-provisiontokens.mdx index 58bdd55eab002..d919d573db8c9 100644 --- a/docs/pages/reference/operator-resources/resources-teleport-dev-provisiontokens.mdx +++ b/docs/pages/reference/operator-resources/resources-teleport-dev-provisiontokens.mdx @@ -37,6 +37,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |gitlab|[object](#specgitlab)|GitLab allows the configuration of options specific to the "gitlab" join method.| |join_method|string|JoinMethod is the joining method required in order to use this token. Supported joining methods include: azure, circleci, ec2, gcp, github, gitlab, iam, kubernetes, spacelift, token, tpm| |kubernetes|[object](#speckubernetes)|Kubernetes allows the configuration of options specific to the "kubernetes" join method.| +|oracle|[object](#specoracle)|Oracle allows the configuration of options specific to the "oracle" join method.| |roles|[]string|Roles is a list of roles associated with the token, that will be converted to metadata in the SSH and X509 certificates issued to the user of the token| |spacelift|[object](#specspacelift)|Spacelift allows the configuration of options specific to the "spacelift" join method.| |suggested_agent_matcher_labels|object|SuggestedAgentMatcherLabels is a set of labels to be used by agents to match on resources. When an agent uses this token, the agent should monitor resources that match those labels. For databases, this means adding the labels to `db_service.resources.labels`. Currently, only node-join scripts create a configuration according to the suggestion.| @@ -181,6 +182,20 @@ resource, which you can apply after installing the Teleport Kubernetes operator. |---|---|---| |jwks|string|| +### spec.oracle + +|Field|Type|Description| +|---|---|---| +|allow|[][object](#specoracleallow-items)|Allow is a list of Rules, nodes using this token must match one allow rule to use this token.| + +### spec.oracle.allow items + +|Field|Type|Description| +|---|---|---| +|parent_compartments|[]string|| +|regions|[]string|| +|tenancy|string|| + ### spec.spacelift |Field|Type|Description| diff --git a/docs/pages/reference/operator-resources/resources-teleport-dev-trustedclustersv2.mdx b/docs/pages/reference/operator-resources/resources-teleport-dev-trustedclustersv2.mdx new file mode 100644 index 0000000000000..8728b51b2ab5c --- /dev/null +++ b/docs/pages/reference/operator-resources/resources-teleport-dev-trustedclustersv2.mdx @@ -0,0 +1,41 @@ +--- +title: TeleportTrustedClusterV2 +description: Provides a comprehensive list of fields in the TeleportTrustedClusterV2 resource available through the Teleport Kubernetes operator +tocDepth: 3 +--- + +{/*Auto-generated file. Do not edit.*/} +{/*To regenerate, navigate to integrations/operator and run "make crd-docs".*/} + +This guide is a comprehensive reference to the fields in the `TeleportTrustedClusterV2` +resource, which you can apply after installing the Teleport Kubernetes operator. + + +## resources.teleport.dev/v1 + +**apiVersion:** resources.teleport.dev/v1 + +|Field|Type|Description| +|---|---|---| +|apiVersion|string|APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources| +|kind|string|Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds| +|metadata|object|| +|spec|[object](#spec)|TrustedCluster resource definition v2 from Teleport| + +### spec + +|Field|Type|Description| +|---|---|---| +|enabled|boolean|Enabled is a bool that indicates if the TrustedCluster is enabled or disabled. Setting Enabled to false has a side effect of deleting the user and host certificate authority (CA).| +|role_map|[][object](#specrole_map-items)|RoleMap specifies role mappings to remote roles.| +|token|string|Token is the authorization token provided by another cluster needed by this cluster to join. This field supports secret lookup. See the operator documentation for more details.| +|tunnel_addr|string|ReverseTunnelAddress is the address of the SSH proxy server of the cluster to join. If not set, it is derived from `:`.| +|web_proxy_addr|string|ProxyAddress is the address of the web proxy server of the cluster to join. If not set, it is derived from `:`.| + +### spec.role_map items + +|Field|Type|Description| +|---|---|---| +|local|[]string|Local specifies local roles to map to| +|remote|string|Remote specifies remote role name to map from| + diff --git a/docs/pages/reference/terraform-provider/data-sources/provision_token.mdx b/docs/pages/reference/terraform-provider/data-sources/provision_token.mdx index 937be42adc350..250d9a32ee37d 100644 --- a/docs/pages/reference/terraform-provider/data-sources/provision_token.mdx +++ b/docs/pages/reference/terraform-provider/data-sources/provision_token.mdx @@ -43,6 +43,7 @@ Optional: - `gitlab` (Attributes) GitLab allows the configuration of options specific to the "gitlab" join method. (see [below for nested schema](#nested-schema-for-specgitlab)) - `join_method` (String) JoinMethod is the joining method required in order to use this token. Supported joining methods include: azure, circleci, ec2, gcp, github, gitlab, iam, kubernetes, spacelift, token, tpm - `kubernetes` (Attributes) Kubernetes allows the configuration of options specific to the "kubernetes" join method. (see [below for nested schema](#nested-schema-for-speckubernetes)) +- `oracle` (Attributes) Oracle allows the configuration of options specific to the "oracle" join method. (see [below for nested schema](#nested-schema-for-specoracle)) - `spacelift` (Attributes) Spacelift allows the configuration of options specific to the "spacelift" join method. (see [below for nested schema](#nested-schema-for-specspacelift)) - `suggested_agent_matcher_labels` (Map of List of String) SuggestedAgentMatcherLabels is a set of labels to be used by agents to match on resources. When an agent uses this token, the agent should monitor resources that match those labels. For databases, this means adding the labels to `db_service.resources.labels`. Currently, only node-join scripts create a configuration according to the suggestion. - `suggested_labels` (Map of List of String) SuggestedLabels is a set of labels that resources should set when using this token to enroll themselves in the cluster. Currently, only node-join scripts create a configuration according to the suggestion. @@ -202,6 +203,22 @@ Optional: +### Nested Schema for `spec.oracle` + +Optional: + +- `allow` (Attributes List) Allow is a list of Rules, nodes using this token must match one allow rule to use this token. (see [below for nested schema](#nested-schema-for-specoracleallow)) + +### Nested Schema for `spec.oracle.allow` + +Optional: + +- `parent_compartments` (List of String) ParentCompartments is a list of the OCIDs of compartments an instance is allowed to join from. Only direct parents are allowed, i.e. no nested compartments. If empty, any compartment is allowed. +- `regions` (List of String) Regions is a list of regions an instance is allowed to join from. Both full region names ("us-phoenix-1") and abbreviations ("phx") are allowed. If empty, any region is allowed. +- `tenancy` (String) Tenancy is the OCID of the instance's tenancy. Required. + + + ### Nested Schema for `spec.spacelift` Optional: diff --git a/docs/pages/reference/terraform-provider/resources/provision_token.mdx b/docs/pages/reference/terraform-provider/resources/provision_token.mdx index b42ddb363a9bf..a0a341cb34759 100644 --- a/docs/pages/reference/terraform-provider/resources/provision_token.mdx +++ b/docs/pages/reference/terraform-provider/resources/provision_token.mdx @@ -77,6 +77,7 @@ Optional: - `gitlab` (Attributes) GitLab allows the configuration of options specific to the "gitlab" join method. (see [below for nested schema](#nested-schema-for-specgitlab)) - `join_method` (String) JoinMethod is the joining method required in order to use this token. Supported joining methods include: azure, circleci, ec2, gcp, github, gitlab, iam, kubernetes, spacelift, token, tpm - `kubernetes` (Attributes) Kubernetes allows the configuration of options specific to the "kubernetes" join method. (see [below for nested schema](#nested-schema-for-speckubernetes)) +- `oracle` (Attributes) Oracle allows the configuration of options specific to the "oracle" join method. (see [below for nested schema](#nested-schema-for-specoracle)) - `spacelift` (Attributes) Spacelift allows the configuration of options specific to the "spacelift" join method. (see [below for nested schema](#nested-schema-for-specspacelift)) - `suggested_agent_matcher_labels` (Map of List of String) SuggestedAgentMatcherLabels is a set of labels to be used by agents to match on resources. When an agent uses this token, the agent should monitor resources that match those labels. For databases, this means adding the labels to `db_service.resources.labels`. Currently, only node-join scripts create a configuration according to the suggestion. - `suggested_labels` (Map of List of String) SuggestedLabels is a set of labels that resources should set when using this token to enroll themselves in the cluster. Currently, only node-join scripts create a configuration according to the suggestion. @@ -236,6 +237,22 @@ Optional: +### Nested Schema for `spec.oracle` + +Optional: + +- `allow` (Attributes List) Allow is a list of Rules, nodes using this token must match one allow rule to use this token. (see [below for nested schema](#nested-schema-for-specoracleallow)) + +### Nested Schema for `spec.oracle.allow` + +Optional: + +- `parent_compartments` (List of String) ParentCompartments is a list of the OCIDs of compartments an instance is allowed to join from. Only direct parents are allowed, i.e. no nested compartments. If empty, any compartment is allowed. +- `regions` (List of String) Regions is a list of regions an instance is allowed to join from. Both full region names ("us-phoenix-1") and abbreviations ("phx") are allowed. If empty, any region is allowed. +- `tenancy` (String) Tenancy is the OCID of the instance's tenancy. Required. + + + ### Nested Schema for `spec.spacelift` Optional: diff --git a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_provisiontokens.yaml b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_provisiontokens.yaml index e42dc48675faa..292fcee2ec787 100644 --- a/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_provisiontokens.yaml +++ b/examples/chart/teleport-cluster/charts/teleport-operator/operator-crds/resources.teleport.dev_provisiontokens.yaml @@ -330,6 +330,32 @@ spec: - `in_cluster` - `static_jwks` If unset, this defaults to `in_cluster`.' type: string type: object + oracle: + description: Oracle allows the configuration of options specific to + the "oracle" join method. + nullable: true + properties: + allow: + description: Allow is a list of Rules, nodes using this token + must match one allow rule to use this token. + items: + properties: + parent_compartments: + items: + type: string + nullable: true + type: array + regions: + items: + type: string + nullable: true + type: array + tenancy: + type: string + type: object + nullable: true + type: array + type: object roles: description: Roles is a list of roles associated with the token, that will be converted to metadata in the SSH and X509 certificates issued diff --git a/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml b/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml index e42dc48675faa..292fcee2ec787 100644 --- a/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml +++ b/integrations/operator/config/crd/bases/resources.teleport.dev_provisiontokens.yaml @@ -330,6 +330,32 @@ spec: - `in_cluster` - `static_jwks` If unset, this defaults to `in_cluster`.' type: string type: object + oracle: + description: Oracle allows the configuration of options specific to + the "oracle" join method. + nullable: true + properties: + allow: + description: Allow is a list of Rules, nodes using this token + must match one allow rule to use this token. + items: + properties: + parent_compartments: + items: + type: string + nullable: true + type: array + regions: + items: + type: string + nullable: true + type: array + tenancy: + type: string + type: object + nullable: true + type: array + type: object roles: description: Roles is a list of roles associated with the token, that will be converted to metadata in the SSH and X509 certificates issued diff --git a/integrations/terraform/tfschema/token/types_terraform.go b/integrations/terraform/tfschema/token/types_terraform.go index 64c3a61f7bc43..10d59da985e0e 100644 --- a/integrations/terraform/tfschema/token/types_terraform.go +++ b/integrations/terraform/tfschema/token/types_terraform.go @@ -454,6 +454,31 @@ func GenSchemaProvisionTokenV2(ctx context.Context) (github_com_hashicorp_terraf Description: "Kubernetes allows the configuration of options specific to the \"kubernetes\" join method.", Optional: true, }, + "oracle": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"allow": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "parent_compartments": { + Description: "ParentCompartments is a list of the OCIDs of compartments an instance is allowed to join from. Only direct parents are allowed, i.e. no nested compartments. If empty, any compartment is allowed.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.ListType{ElemType: github_com_hashicorp_terraform_plugin_framework_types.StringType}, + }, + "regions": { + Description: "Regions is a list of regions an instance is allowed to join from. Both full region names (\"us-phoenix-1\") and abbreviations (\"phx\") are allowed. If empty, any region is allowed.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.ListType{ElemType: github_com_hashicorp_terraform_plugin_framework_types.StringType}, + }, + "tenancy": { + Description: "Tenancy is the OCID of the instance's tenancy. Required.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Description: "Allow is a list of Rules, nodes using this token must match one allow rule to use this token.", + Optional: true, + }}), + Description: "Oracle allows the configuration of options specific to the \"oracle\" join method.", + Optional: true, + }, "roles": { Description: "Roles is a list of roles associated with the token, that will be converted to metadata in the SSH and X509 certificates issued to the user of the token", Required: true, @@ -2596,6 +2621,124 @@ func CopyProvisionTokenV2FromTerraform(_ context.Context, tf github_com_hashicor } } } + { + a, ok := tf.Attrs["oracle"] + if !ok { + diags.Append(attrReadMissingDiag{"ProvisionTokenV2.Spec.Oracle"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Oracle = nil + if !v.Null && !v.Unknown { + tf := v + obj.Oracle = &github_com_gravitational_teleport_api_types.ProvisionTokenSpecV2Oracle{} + obj := obj.Oracle + { + a, ok := tf.Attrs["allow"] + if !ok { + diags.Append(attrReadMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.Allow = make([]*github_com_gravitational_teleport_api_types.ProvisionTokenSpecV2Oracle_Rule, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow", "github_com_hashicorp_terraform_plugin_framework_types.Object"}) + } else { + var t *github_com_gravitational_teleport_api_types.ProvisionTokenSpecV2Oracle_Rule + if !v.Null && !v.Unknown { + tf := v + t = &github_com_gravitational_teleport_api_types.ProvisionTokenSpecV2Oracle_Rule{} + obj := t + { + a, ok := tf.Attrs["tenancy"] + if !ok { + diags.Append(attrReadMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Tenancy"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Tenancy", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Tenancy = t + } + } + } + { + a, ok := tf.Attrs["parent_compartments"] + if !ok { + diags.Append(attrReadMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.ParentCompartments = make([]string, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments", "github_com_hashicorp_terraform_plugin_framework_types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.ParentCompartments[k] = t + } + } + } + } + } + } + { + a, ok := tf.Attrs["regions"] + if !ok { + diags.Append(attrReadMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Regions"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Regions", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.Regions = make([]string, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Regions", "github_com_hashicorp_terraform_plugin_framework_types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Regions[k] = t + } + } + } + } + } + } + } + obj.Allow[k] = t + } + } + } + } + } + } + } + } + } + } } } } @@ -5657,6 +5800,224 @@ func CopyProvisionTokenV2ToTerraform(ctx context.Context, obj *github_com_gravit } } } + { + a, ok := tf.AttrTypes["oracle"] + if !ok { + diags.Append(attrWriteMissingDiag{"ProvisionTokenV2.Spec.Oracle"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["oracle"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Oracle == nil { + v.Null = true + } else { + obj := obj.Oracle + tf := &v + { + a, ok := tf.AttrTypes["allow"] + if !ok { + diags.Append(attrWriteMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["allow"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Allow)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Allow)) + } + } + if obj.Allow != nil { + o := o.ElemType.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if len(obj.Allow) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Allow)) + } + for k, a := range obj.Allow { + v, ok := tf.Attrs["allow"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if a == nil { + v.Null = true + } else { + obj := a + tf := &v + { + t, ok := tf.AttrTypes["tenancy"] + if !ok { + diags.Append(attrWriteMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Tenancy"}) + } else { + v, ok := tf.Attrs["tenancy"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"ProvisionTokenV2.Spec.Oracle.Allow.Tenancy", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Tenancy", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Tenancy) == "" + } + v.Value = string(obj.Tenancy) + v.Unknown = false + tf.Attrs["tenancy"] = v + } + } + { + a, ok := tf.AttrTypes["parent_compartments"] + if !ok { + diags.Append(attrWriteMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["parent_compartments"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.ParentCompartments)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.ParentCompartments)) + } + } + if obj.ParentCompartments != nil { + t := o.ElemType + if len(obj.ParentCompartments) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.ParentCompartments)) + } + for k, a := range obj.ParentCompartments { + v, ok := tf.Attrs["parent_compartments"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.ParentCompartments", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(a) == "" + } + v.Value = string(a) + v.Unknown = false + c.Elems[k] = v + } + if len(obj.ParentCompartments) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["parent_compartments"] = c + } + } + } + { + a, ok := tf.AttrTypes["regions"] + if !ok { + diags.Append(attrWriteMissingDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Regions"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Regions", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["regions"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Regions)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Regions)) + } + } + if obj.Regions != nil { + t := o.ElemType + if len(obj.Regions) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.Regions)) + } + for k, a := range obj.Regions { + v, ok := tf.Attrs["regions"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"ProvisionTokenV2.Spec.Oracle.Allow.Regions", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"ProvisionTokenV2.Spec.Oracle.Allow.Regions", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(a) == "" + } + v.Value = string(a) + v.Unknown = false + c.Elems[k] = v + } + if len(obj.Regions) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["regions"] = c + } + } + } + } + v.Unknown = false + c.Elems[k] = v + } + if len(obj.Allow) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["allow"] = c + } + } + } + } + v.Unknown = false + tf.Attrs["oracle"] = v + } + } + } } v.Unknown = false tf.Attrs["spec"] = v diff --git a/lib/auth/join.go b/lib/auth/join.go index ad92db5eb3a0d..3673b128b40db 100644 --- a/lib/auth/join.go +++ b/lib/auth/join.go @@ -238,8 +238,8 @@ func (a *Server) RegisterUsingToken(ctx context.Context, req *types.RegisterUsin if err := a.checkEC2JoinRequest(ctx, req); err != nil { return nil, trace.Wrap(err) } - case types.JoinMethodIAM, types.JoinMethodAzure, types.JoinMethodTPM: - // IAM and Azure join methods must use gRPC register methods + case types.JoinMethodIAM, types.JoinMethodAzure, types.JoinMethodTPM, types.JoinMethodOracle: + // These join methods must use gRPC register methods return nil, trace.AccessDenied("this token is only valid for the %s "+ "join method but the node has connected to the wrong endpoint, make "+ "sure your node is configured to use the %s join method", method, method) diff --git a/lib/auth/join/join.go b/lib/auth/join/join.go index 20a96aedd6d98..940cd3b211720 100644 --- a/lib/auth/join/join.go +++ b/lib/auth/join/join.go @@ -356,8 +356,11 @@ func registerThroughProxy( var certs *proto.Certs switch params.JoinMethod { - case types.JoinMethodIAM, types.JoinMethodAzure, types.JoinMethodTPM: - // IAM and Azure join methods require gRPC client + case types.JoinMethodIAM, + types.JoinMethodAzure, + types.JoinMethodTPM, + types.JoinMethodOracle: + // These join methods require gRPC client conn, err := proxyinsecureclient.NewConnection( ctx, proxyinsecureclient.ConnectionConfig{ @@ -381,6 +384,8 @@ func registerThroughProxy( certs, err = registerUsingAzureMethod(ctx, joinServiceClient, token, hostKeys, params) case types.JoinMethodTPM: certs, err = registerUsingTPMMethod(ctx, joinServiceClient, token, hostKeys, params) + case types.JoinMethodOracle: + certs, err = registerUsingOracleMethod(ctx, joinServiceClient, token, hostKeys, params) default: return nil, trace.BadParameter("unhandled join method %q", params.JoinMethod) } @@ -648,6 +653,11 @@ type joinServiceClient interface { initReq *proto.RegisterUsingTPMMethodInitialRequest, solveChallenge client.RegisterTPMChallengeResponseFunc, ) (*proto.Certs, error) + RegisterUsingOracleMethod( + ctx context.Context, + tokenReq *types.RegisterUsingTokenRequest, + challengeResponse client.RegisterOracleChallengeResponseFunc, + ) (*proto.Certs, error) } func registerUsingTokenRequestForParams(token string, hostKeys *newHostKeys, params RegisterParams) *types.RegisterUsingTokenRequest { @@ -801,6 +811,12 @@ func registerUsingTPMMethod( return certs, trace.Wrap(err) } +func registerUsingOracleMethod( + ctx context.Context, client joinServiceClient, token string, hostKeys *newHostKeys, params RegisterParams, +) (*proto.Certs, error) { + return nil, trace.NotImplemented("Not implemented") +} + // readCA will read in CA that will be used to validate the certificate that // the Auth Server presents. func readCA(path string) (*x509.Certificate, error) { diff --git a/lib/auth/join_oracle.go b/lib/auth/join_oracle.go new file mode 100644 index 0000000000000..5dd95e9e253ae --- /dev/null +++ b/lib/auth/join_oracle.go @@ -0,0 +1,37 @@ +// Teleport +// Copyright (C) 2025 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 auth + +import ( + "context" + + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/client" + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" +) + +// RegisterUsingOracleMethod registers the caller using the Oracle join method and +// returns signed certs to join the cluster. +func (a *Server) RegisterUsingOracleMethod( + ctx context.Context, + tokenReq *types.RegisterUsingTokenRequest, + challengeResponse client.RegisterOracleChallengeResponseFunc, +) (certs *proto.Certs, err error) { + return nil, trace.NotImplemented("Not implemented") +} diff --git a/lib/joinserver/joinserver.go b/lib/joinserver/joinserver.go index 2f16af283cfc5..b978bb8d61ef8 100644 --- a/lib/joinserver/joinserver.go +++ b/lib/joinserver/joinserver.go @@ -39,9 +39,7 @@ import ( ) const ( - iamJoinRequestTimeout = time.Minute - azureJoinRequestTimeout = time.Minute - tpmJoinRequestTimeout = time.Minute + joinRequestTimeout = time.Minute ) type joinServiceClient interface { @@ -52,6 +50,11 @@ type joinServiceClient interface { initReq *proto.RegisterUsingTPMMethodInitialRequest, solveChallenge client.RegisterTPMChallengeResponseFunc, ) (*proto.Certs, error) + RegisterUsingOracleMethod( + ctx context.Context, + tokenReq *types.RegisterUsingTokenRequest, + challengeResponse client.RegisterOracleChallengeResponseFunc, + ) (*proto.Certs, error) RegisterUsingToken( ctx context.Context, req *types.RegisterUsingTokenRequest, @@ -88,31 +91,9 @@ func NewJoinServiceGRPCServer(joinServiceClient joinServiceClient) *JoinServiceG // sts:GetCallerIdentity request with the challenge string. Finally, the signed // cluster certs are sent on the server stream. func (s *JoinServiceGRPCServer) RegisterUsingIAMMethod(srv proto.JoinService_RegisterUsingIAMMethodServer) error { - // Enforce a timeout on the entire RPC so that misbehaving clients cannot - // hold connections open indefinitely. - timeout := s.clock.NewTimer(iamJoinRequestTimeout) - defer timeout.Stop() - - // The only way to cancel a blocked Send or Recv on the server side without - // adding an interceptor to the entire gRPC service is to return from the - // handler https://github.com/grpc/grpc-go/issues/465#issuecomment-179414474 - errCh := make(chan error, 1) - go func() { - errCh <- s.registerUsingIAMMethod(srv) - }() - select { - case err := <-errCh: - // Completed before the deadline, return the error (may be nil). - return trace.Wrap(err) - case <-timeout.Chan(): - nodeAddr := "" - if peerInfo, ok := peer.FromContext(srv.Context()); ok { - nodeAddr = peerInfo.Addr.String() - } - slog.WarnContext(srv.Context(), "IAM join attempt timed out, agent is misbehaving or did not close the connection after encountering an error", "agent_addr", nodeAddr) - // Returning here should cancel any blocked Send or Recv operations. - return trace.LimitExceeded("RegisterUsingIAMMethod timed out after %s, terminating the stream on the server", iamJoinRequestTimeout) - } + return trace.Wrap(s.handleStreamingRegistration(srv.Context(), types.JoinMethodIAM, func() error { + return trace.Wrap(s.registerUsingIAMMethod(srv)) + })) } func (s *JoinServiceGRPCServer) registerUsingIAMMethod(srv proto.JoinService_RegisterUsingIAMMethodServer) error { @@ -159,31 +140,9 @@ func (s *JoinServiceGRPCServer) registerUsingIAMMethod(srv proto.JoinService_Reg // attested data document with the challenge string. Finally, the signed // cluster certs are sent on the server stream. func (s *JoinServiceGRPCServer) RegisterUsingAzureMethod(srv proto.JoinService_RegisterUsingAzureMethodServer) error { - // Enforce a timeout on the entire RPC so that misbehaving clients cannot - // hold connections open indefinitely. - timeout := s.clock.NewTimer(azureJoinRequestTimeout) - defer timeout.Stop() - - // The only way to cancel a blocked Send or Recv on the server side without - // adding an interceptor to the entire gRPC service is to return from the - // handler https://github.com/grpc/grpc-go/issues/465#issuecomment-179414474 - errCh := make(chan error, 1) - go func() { - errCh <- s.registerUsingAzureMethod(srv) - }() - select { - case err := <-errCh: - // Completed before the deadline, return the error (may be nil). - return trace.Wrap(err) - case <-timeout.Chan(): - nodeAddr := "" - if peerInfo, ok := peer.FromContext(srv.Context()); ok { - nodeAddr = peerInfo.Addr.String() - } - slog.WarnContext(srv.Context(), "Azure join attempt timed out, agent is misbehaving or did not close the connection after encountering an error", "agent_addr", nodeAddr) - // Returning here should cancel any blocked Send or Recv operations. - return trace.LimitExceeded("RegisterUsingAzureMethod timed out after %s, terminating the stream on the server", azureJoinRequestTimeout) - } + return trace.Wrap(s.handleStreamingRegistration(srv.Context(), types.JoinMethodAzure, func() error { + return trace.Wrap(s.registerUsingAzureMethod(srv)) + })) } func checkForProxyRole(identity tlsca.Identity) bool { @@ -281,41 +240,9 @@ func (s *JoinServiceGRPCServer) registerUsingAzureMethod(srv proto.JoinService_R // auth.ServerWithRoles's RegisterUsingTPMMethod method. When running on the // Proxy, this method will forward the request to the Auth server. func (s *JoinServiceGRPCServer) RegisterUsingTPMMethod(srv proto.JoinService_RegisterUsingTPMMethodServer) error { - ctx := srv.Context() - - // Enforce a timeout on the entire RPC so that misbehaving clients cannot - // hold connections open indefinitely. - timeout := s.clock.After(tpmJoinRequestTimeout) - - // The only way to cancel a blocked Send or Recv on the server side without - // adding an interceptor to the entire gRPC service is to return from the - // handler https://github.com/grpc/grpc-go/issues/465#issuecomment-179414474 - errCh := make(chan error, 1) - go func() { - errCh <- s.registerUsingTPMMethod(ctx, srv) - }() - select { - case err := <-errCh: - // Completed before the deadline, return the error (may be nil). - return trace.Wrap(err) - case <-timeout: - nodeAddr := "" - if peerInfo, ok := peer.FromContext(ctx); ok { - nodeAddr = peerInfo.Addr.String() - } - slog.WarnContext( - srv.Context(), - "TPM join attempt timed out, node is misbehaving or did not close the connection after encountering an error", - "node_addr", nodeAddr, - ) - // Returning here should cancel any blocked Send or Recv operations. - return trace.LimitExceeded( - "RegisterUsingTPMMethod timed out after %s, terminating the stream on the server", - tpmJoinRequestTimeout, - ) - case <-ctx.Done(): - return trace.Wrap(ctx.Err()) - } + return trace.Wrap(s.handleStreamingRegistration(srv.Context(), types.JoinMethodTPM, func() error { + return trace.Wrap(s.registerUsingTPMMethod(srv.Context(), srv)) + })) } func (s *JoinServiceGRPCServer) registerUsingTPMMethod( @@ -384,6 +311,64 @@ func (s *JoinServiceGRPCServer) registerUsingTPMMethod( })) } +// RegisterUsingOracleMethod registers the caller using the Oracle join method and +// returns signed certs to join the cluster. +func (s *JoinServiceGRPCServer) RegisterUsingOracleMethod( + srv proto.JoinService_RegisterUsingOracleMethodServer, +) error { + return trace.Wrap(s.handleStreamingRegistration(srv.Context(), types.JoinMethodOracle, func() error { + return trace.Wrap(s.registerUsingOracleMethod(srv)) + })) +} + +func (s *JoinServiceGRPCServer) registerUsingOracleMethod(srv proto.JoinService_RegisterUsingOracleMethodServer) error { + ctx := srv.Context() + tokenParamsReq, err := srv.Recv() + if err != nil { + return trace.Wrap(err) + } + tokenParams := tokenParamsReq.GetRegisterUsingTokenRequest() + if tokenParams == nil { + return trace.BadParameter("expected RegisterUsingTokenRequest, got %T", tokenParamsReq.Request) + } + if err := setClientRemoteAddr(ctx, tokenParams); err != nil { + return trace.Wrap(err) + } + setBotParameters(ctx, tokenParams) + + certs, err := s.joinServiceClient.RegisterUsingOracleMethod( + ctx, + tokenParams, + func(challenge string) (*proto.OracleSignedRequest, error) { + err = srv.Send(&proto.RegisterUsingOracleMethodResponse{ + Response: &proto.RegisterUsingOracleMethodResponse_Challenge{ + Challenge: challenge, + }, + }) + if err != nil { + return nil, trace.Wrap(err) + } + req, err := srv.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + oracleReq := req.GetOracleRequest() + if oracleReq == nil { + return nil, trace.BadParameter("expected signed Oracle request, got %T", req.Request) + } + return oracleReq, nil + }) + if err != nil { + return trace.Wrap(err) + } + + return trace.Wrap(srv.Send(&proto.RegisterUsingOracleMethodResponse{ + Response: &proto.RegisterUsingOracleMethodResponse_Certs{ + Certs: certs, + }, + })) +} + // RegisterUsingToken allows nodes and proxies to join the cluster using // legacy join methods which do not yet have their own RPC. // On the Auth server, this method will call the auth.Server's @@ -399,3 +384,37 @@ func (s *JoinServiceGRPCServer) RegisterUsingToken( return s.joinServiceClient.RegisterUsingToken(ctx, req) } + +func (s *JoinServiceGRPCServer) handleStreamingRegistration(ctx context.Context, joinMethod types.JoinMethod, register func() error) error { + // The only way to cancel a blocked Send or Recv on the server side without + // adding an interceptor to the entire gRPC service is to return from the + // handler https://github.com/grpc/grpc-go/issues/465#issuecomment-179414474 + errCh := make(chan error, 1) + go func() { + errCh <- register() + }() + select { + case err := <-errCh: + // Completed before the deadline, return the error (may be nil). + return trace.Wrap(err) + // Enforce a timeout on the entire RPC so that misbehaving clients cannot + // hold connections open indefinitely. + case <-s.clock.After(joinRequestTimeout): + nodeAddr := "" + if peerInfo, ok := peer.FromContext(ctx); ok { + nodeAddr = peerInfo.Addr.String() + } + slog.WarnContext( + ctx, + "Join attempt timed out, node is misbehaving or did not close the connection after encountering an error", + "join_method", joinMethod, "node_addr", nodeAddr, + ) + // Returning here should cancel any blocked Send or Recv operations. + return trace.LimitExceeded( + "%s join method timed out after %s, terminating the stream on the server", + joinMethod, joinRequestTimeout, + ) + case <-ctx.Done(): + return trace.Wrap(ctx.Err()) + } +} diff --git a/lib/joinserver/joinserver_test.go b/lib/joinserver/joinserver_test.go index 68c68757391ef..f9bd3e6d8e7dc 100644 --- a/lib/joinserver/joinserver_test.go +++ b/lib/joinserver/joinserver_test.go @@ -86,6 +86,14 @@ func (c *mockJoinServiceClient) RegisterUsingTPMMethod( return c.returnCerts, c.returnError } +func (c *mockJoinServiceClient) RegisterUsingOracleMethod( + ctx context.Context, + tokenReq *types.RegisterUsingTokenRequest, + challengeResponse client.RegisterOracleChallengeResponseFunc, +) (*proto.Certs, error) { + return c.returnCerts, c.returnError +} + func (c *mockJoinServiceClient) RegisterUsingToken( ctx context.Context, req *types.RegisterUsingTokenRequest, @@ -601,7 +609,7 @@ func TestTimeout(t *testing.T) { // // Make sure the request is automatically timed out on the server and all // connections are closed shortly after the timeout. - fakeClock.Advance(iamJoinRequestTimeout) + fakeClock.Advance(joinRequestTimeout) require.Eventually(t, func() bool { return testPack.streamConnectionCount.Load() == 0 }, 10*time.Second, 1*time.Millisecond) diff --git a/lib/service/service.go b/lib/service/service.go index 07427ae0157f6..a522f03491201 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -6680,7 +6680,8 @@ func readOrGenerateHostID(ctx context.Context, cfg *servicecfg.Config, kubeBacke types.JoinMethodAzure, types.JoinMethodGCP, types.JoinMethodTPM, - types.JoinMethodTerraformCloud: + types.JoinMethodTerraformCloud, + types.JoinMethodOracle: // Checking error instead of the usual uuid.New() in case uuid generation // fails due to not enough randomness. It's been known to happen happen when // Teleport starts very early in the node initialization cycle and /dev/urandom From 533202f18ce09052cbb4a759a751f9da257ec1b6 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Wed, 29 Jan 2025 18:15:12 -0300 Subject: [PATCH 04/28] fix: Randomly derive UUIDs from non-conformant session IDs (#51571) * Tests event with non-UUID session ID * Randomly derive UUIDs from non-conformant session IDs * nit: Use "" instead of `` * Link godoc references to Log.deriveSessionID * Mention UUIDv5 for derived IDs * Do not log the session ID * Rename test helper, move truncateEvents out of it --- lib/events/pgevents/pgevents.go | 65 +++++++++---- lib/events/pgevents/pgevents_test.go | 135 ++++++++++++++++++++++----- 2 files changed, 159 insertions(+), 41 deletions(-) diff --git a/lib/events/pgevents/pgevents.go b/lib/events/pgevents/pgevents.go index d0b18da2d3d73..0d30995927154 100644 --- a/lib/events/pgevents/pgevents.go +++ b/lib/events/pgevents/pgevents.go @@ -70,6 +70,14 @@ const ( ) const ( + // A note on "session_id uuid NOT NULL": + // + // Some session IDs aren't UUIDs. See [Log.deriveSessionID] for an example. + // The wiser choice of type would be "session_id text", ie, handling session + // IDs as an opaque identifier. + // + // If you are writing a new backend and stumbled on this comment, do not use + // a storage UUID type for session IDs. Use a string type. schemaV1Table = `CREATE TABLE events ( event_time timestamptz NOT NULL, event_id uuid NOT NULL, @@ -360,14 +368,6 @@ var _ events.AuditLogger = (*Log)(nil) // EmitAuditEvent implements [events.AuditLogger]. func (l *Log) EmitAuditEvent(ctx context.Context, event apievents.AuditEvent) error { ctx = context.WithoutCancel(ctx) - var sessionID uuid.UUID - if s := events.GetSessionID(event); s != "" { - u, err := uuid.Parse(s) - if err != nil { - return trace.Wrap(err) - } - sessionID = u - } eventJSON, err := utils.FastMarshal(event) if err != nil { @@ -375,6 +375,7 @@ func (l *Log) EmitAuditEvent(ctx context.Context, event apievents.AuditEvent) er } eventID := uuid.New() + sessionID := l.deriveSessionID(ctx, events.GetSessionID(event)) start := time.Now() // if an event with the same event_id exists, it means that we inserted it @@ -412,15 +413,6 @@ func (l *Log) searchEvents( eventTypes []string, cond *types.WhereExpr, sessionID string, limit int, order types.EventOrder, startKey string, ) ([]apievents.AuditEvent, string, error) { - var sessionUUID uuid.UUID - if sessionID != "" { - var err error - sessionUUID, err = uuid.Parse(sessionID) - if err != nil { - return nil, "", trace.Wrap(err) - } - } - if limit <= 0 { limit = defaults.EventsIterationLimit } @@ -447,6 +439,8 @@ func (l *Log) searchEvents( } } + sessionUUID := l.deriveSessionID(ctx, sessionID) + var qb strings.Builder qb.WriteString("DECLARE cur CURSOR FOR SELECT" + " events.event_time, events.event_id, events.event_data" + @@ -595,3 +589,40 @@ func (l *Log) GetEventExportChunks(ctx context.Context, req *auditlogpb.GetEvent func (l *Log) SearchSessionEvents(ctx context.Context, req events.SearchSessionEventsRequest) ([]apievents.AuditEvent, string, error) { return l.searchEvents(ctx, req.From, req.To, events.SessionRecordingEvents, req.Cond, req.SessionID, req.Limit, req.Order, req.StartKey) } + +// sessionIDBase is a randomly-generated UUID used as the basis for deriving +// an UUID from session IDs. See [Log.deriveSessionID]. +var sessionIDBase = uuid.MustParse("e481e221-77b0-4b9e-be98-bc2e486b751b") + +func (l *Log) deriveSessionID(ctx context.Context, sessionID string) uuid.UUID { + if sessionID == "" { + return uuid.Nil // return zero UUID for backwards compat + } + + u, err := uuid.Parse(sessionID) + if err == nil { + return u + } + + // Some session IDs aren't UUIDs. For example, App session IDs are 32-byte + // values encoded as hex. Whether the assumption of UUIDs is philosophically + // correct is immaterial, what matters is that we do not drop the audit + // event. + // + // To avoid dropping the event while conforming to the existing schema we + // deterministically derive an UUID from the session ID. + // + // Note that derived IDs are UUIDv5 (instead of the usual UUIDv4 from + // uuid.Parse), so that could be used as a hint to which UUIDs are original or + // derived. + // + // * https://github.com/gravitational/teleport/blob/63537e3da5a22b61d9218863f1ed535a31d229ea/lib/auth/sessions.go#L521 + derived := uuid.NewSHA1(sessionIDBase, []byte(sessionID)) + + l.log.DebugContext(ctx, + "Failed to parse event session ID, using derived ID", + "error", err, + "derived_id", derived, + ) + return derived +} diff --git a/lib/events/pgevents/pgevents_test.go b/lib/events/pgevents/pgevents_test.go index 05c4934d7b7ad..8aeb66ee5ca7e 100644 --- a/lib/events/pgevents/pgevents_test.go +++ b/lib/events/pgevents/pgevents_test.go @@ -25,10 +25,17 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + apidefaults "github.com/gravitational/teleport/api/defaults" + "github.com/gravitational/teleport/api/types" + apievents "github.com/gravitational/teleport/api/types/events" pgcommon "github.com/gravitational/teleport/lib/backend/pgbk/common" + "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/events/test" "github.com/gravitational/teleport/lib/utils" ) @@ -38,52 +45,132 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } +// TELEPORT_TEST_PGEVENTS_URL is a connection string similar to the one used by +// "audit_events_uri" (in teleport.yaml). +// For example: "postgresql://teleport@localhost:5432/teleport_test1?sslcert=/path/to/cert.pem&sslkey=/path/to/key.pem&sslrootcert=/path/to/ca.pem&sslmode=verify-full" const urlEnvVar = "TELEPORT_TEST_PGEVENTS_URL" func TestPostgresEvents(t *testing.T) { - s, ok := os.LookupEnv(urlEnvVar) - if !ok { - t.Skipf("Missing %v environment variable.", urlEnvVar) - } - - u, err := url.Parse(s) - require.NoError(t, err) - - var cfg Config - require.NoError(t, cfg.SetFromURL(u)) + // Don't t.Parallel(), relies on the database backed by urlEnvVar. + log := newLogForTesting(t) - ctx, cancel := context.WithCancel(context.Background()) - t.Cleanup(cancel) + ctx := context.Background() - log, err := New(ctx, cfg) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, log.Close()) }) + truncateEvents := func(t *testing.T) { + _, err := log.pool.Exec(ctx, "TRUNCATE events") + require.NoError(t, err, "truncate events") + } suite := test.EventsSuite{ Log: log, Clock: clockwork.NewRealClock(), } - // the tests in the suite expect a blank slate each time - setup := func(t *testing.T) { - _, err := log.pool.Exec(ctx, "TRUNCATE events") - require.NoError(t, err) - } - t.Run("SessionEventsCRUD", func(t *testing.T) { - setup(t) + // The tests in the suite expect a blank slate each time. + truncateEvents(t) suite.SessionEventsCRUD(t) }) t.Run("EventPagination", func(t *testing.T) { - setup(t) + truncateEvents(t) suite.EventPagination(t) }) t.Run("SearchSessionEventsBySessionID", func(t *testing.T) { - setup(t) + truncateEvents(t) suite.SearchSessionEventsBySessionID(t) }) } +// TestLog_nonStandardSessionID tests for +// https://github.com/gravitational/teleport/issues/46207. +func TestLog_nonStandardSessionID(t *testing.T) { + // Don't t.Parallel(), relies on the database backed by urlEnvVar. + eventsLog := newLogForTesting(t) + + // Example app event. Only the session ID matters for the test, everything + // else is realistic but irrelevant here. + eventTime := time.Now() + appStartEvent := &apievents.AppSessionStart{ + Metadata: apievents.Metadata{ + Type: events.AppSessionStartEvent, + Code: events.AppSessionStartCode, + ClusterName: "zarq", + Time: eventTime, + }, + ServerMetadata: apievents.ServerMetadata{ + ServerVersion: "17.2.2", + ServerID: "18d877c6-c8ab-46fc-9806-b638c0d6c556", + ServerNamespace: apidefaults.Namespace, + }, + SessionMetadata: apievents.SessionMetadata{ + // IMPORTANT: not an UUID! + SessionID: "f8571503d72f35938ce5001b792baebcce3183719ae947fde1ed685f7848facc", + }, + UserMetadata: apievents.UserMetadata{ + User: "alpaca", + UserKind: apievents.UserKind_USER_KIND_HUMAN, + }, + PublicAddr: "dumper.zarq.dev", + AppMetadata: apievents.AppMetadata{ + AppURI: "http://127.0.0.1:52932", + AppPublicAddr: "dumper.zarq.dev", + AppName: "dumper", + }, + } + + ctx := context.Background() + + // Emit event with non-standard session ID. + require.NoError(t, + eventsLog.EmitAuditEvent(ctx, appStartEvent), + "emit audit event", + ) + + // Search event by the same (non-standard) session ID. + // SearchSessionEvents has a hard-coded list of eventTypes that excludes App + // events, so we must use searchEvents instead. + before := eventTime.Add(-1 * time.Second) + after := eventTime.Add(1 * time.Second) + appEvents, _, err := eventsLog.searchEvents(ctx, + before, // fromTime + after, // toTime + []string{appStartEvent.Metadata.Type}, // eventTypes + nil, // cond + appStartEvent.SessionID, + 2, // limit + types.EventOrderAscending, + "", // startKey + ) + require.NoError(t, err, "search session events") + want := []apievents.AuditEvent{appStartEvent} + if diff := cmp.Diff(want, appEvents, protocmp.Transform()); diff != "" { + t.Errorf("searchEvents mismatch (-want +got)\n%s", diff) + } +} + +func newLogForTesting(t *testing.T) *Log { + t.Helper() + + connString, ok := os.LookupEnv(urlEnvVar) + if !ok { + t.Skipf("Missing %v environment variable.", urlEnvVar) + } + u, err := url.Parse(connString) + require.NoError(t, err, "parse Postgres connString from %s", urlEnvVar) + + var cfg Config + require.NoError(t, cfg.SetFromURL(u), "cfg.SetFromURL") + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + eventsLog, err := New(ctx, cfg) + require.NoError(t, err, "create new Log") + t.Cleanup(func() { assert.NoError(t, eventsLog.Close(), "close events log") }) + + return eventsLog +} + func TestConfig(t *testing.T) { configs := map[string]*Config{ "postgres://foo#auth_mode=azure": { From a9be7dbfbb9d1e36a77148d93f8a4446270bc0a1 Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Wed, 29 Jan 2025 13:16:56 -0800 Subject: [PATCH 05/28] Migrate AWS STS client to AWS SDK v2 (#51573) --- lib/cloud/clients.go | 20 ----- lib/cloud/mocks/aws.go | 2 +- lib/cloud/mocks/aws_sts.go | 17 ++++- lib/srv/app/aws/handler_test.go | 6 ++ lib/srv/db/cloud/iam.go | 6 +- lib/srv/db/cloud/iam_test.go | 73 ++++++++----------- lib/srv/db/cloud/meta.go | 11 +++ lib/srv/db/cloud/meta_test.go | 6 ++ lib/srv/db/cloud/resource_checker.go | 2 +- .../db/cloud/resource_checker_credentials.go | 30 +++++--- lib/srv/db/common/auth.go | 16 +++- lib/srv/db/common/auth_test.go | 59 +++++++++------ .../discovery/fetchers/aws-sync/aws-sync.go | 50 +++++-------- lib/srv/discovery/fetchers/aws-sync/ec2.go | 4 +- lib/srv/discovery/fetchers/aws-sync/eks.go | 2 +- lib/srv/discovery/fetchers/aws-sync/groups.go | 6 +- lib/srv/discovery/fetchers/aws-sync/idp.go | 4 +- .../discovery/fetchers/aws-sync/policies.go | 2 +- lib/srv/discovery/fetchers/aws-sync/rds.go | 2 +- .../discovery/fetchers/aws-sync/rds_test.go | 6 ++ lib/srv/discovery/fetchers/aws-sync/roles.go | 6 +- lib/srv/discovery/fetchers/aws-sync/s3.go | 4 +- lib/srv/discovery/fetchers/aws-sync/users.go | 8 +- 23 files changed, 185 insertions(+), 157 deletions(-) diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go index a9101dd1db977..0c8fe0306a63c 100644 --- a/lib/cloud/clients.go +++ b/lib/cloud/clients.go @@ -91,8 +91,6 @@ type GCPClients interface { type AWSClients interface { // GetAWSSession returns AWS session for the specified region and any role(s). GetAWSSession(ctx context.Context, region string, opts ...AWSOptionsFn) (*awssession.Session, error) - // GetAWSSTSClient returns AWS STS client for the specified region. - GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) } // AzureClients is an interface for Azure-specific API clients @@ -468,15 +466,6 @@ func (c *cloudClients) GetAWSSession(ctx context.Context, region string, opts .. return c.getAWSSessionForRole(ctx, region, options) } -// GetAWSSTSClient returns AWS STS client for the specified region. -func (c *cloudClients) GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) { - session, err := c.GetAWSSession(ctx, region, opts...) - if err != nil { - return nil, trace.Wrap(err) - } - return sts.New(session), nil -} - // GetGCPIAMClient returns GCP IAM client. func (c *cloudClients) GetGCPIAMClient(ctx context.Context) (*gcpcredentials.IamCredentialsClient, error) { c.mtx.RLock() @@ -964,15 +953,6 @@ func (c *TestCloudClients) getAWSSessionForRegion(region string) (*awssession.Se }) } -// GetAWSSTSClient returns AWS STS client for the specified region. -func (c *TestCloudClients) GetAWSSTSClient(ctx context.Context, region string, opts ...AWSOptionsFn) (stsiface.STSAPI, error) { - _, err := c.GetAWSSession(ctx, region, opts...) - if err != nil { - return nil, trace.Wrap(err) - } - return c.STS, nil -} - // GetGCPIAMClient returns GCP IAM client. func (c *TestCloudClients) GetGCPIAMClient(ctx context.Context) (*gcpcredentials.IamCredentialsClient, error) { return gcpcredentials.NewIamCredentialsClient(ctx, diff --git a/lib/cloud/mocks/aws.go b/lib/cloud/mocks/aws.go index f07981464c932..d48050dc5f373 100644 --- a/lib/cloud/mocks/aws.go +++ b/lib/cloud/mocks/aws.go @@ -81,7 +81,7 @@ func (m *STSClientV1) AssumeRoleWithContext(ctx aws.Context, in *sts.AssumeRoleI expiry := time.Now().Add(60 * time.Minute) return &sts.AssumeRoleOutput{ Credentials: &sts.Credentials{ - AccessKeyId: in.RoleArn, + AccessKeyId: aws.String("FAKEACCESSKEYID"), SecretAccessKey: aws.String("secret"), SessionToken: aws.String("token"), Expiration: &expiry, diff --git a/lib/cloud/mocks/aws_sts.go b/lib/cloud/mocks/aws_sts.go index cf117788e696f..09ae2796d194d 100644 --- a/lib/cloud/mocks/aws_sts.go +++ b/lib/cloud/mocks/aws_sts.go @@ -46,6 +46,7 @@ import ( type STSClient struct { STSClientV1 + Unauth bool // credentialProvider is only set when a chain of assumed roles is used. credentialProvider aws.CredentialsProvider // recordFn records the role and external ID when a role is assumed. @@ -55,17 +56,25 @@ type STSClient struct { } func (m *STSClient) GetCallerIdentity(ctx context.Context, params *sts.GetCallerIdentityInput, optFns ...func(*sts.Options)) (*sts.GetCallerIdentityOutput, error) { + if m.Unauth { + return nil, trace.AccessDenied("unauthorized") + } + return &sts.GetCallerIdentityOutput{ Arn: aws.String(m.ARN), }, nil } func (m *STSClient) AssumeRoleWithWebIdentity(ctx context.Context, in *sts.AssumeRoleWithWebIdentityInput, _ ...func(*sts.Options)) (*sts.AssumeRoleWithWebIdentityOutput, error) { + if m.Unauth { + return nil, trace.AccessDenied("unauthorized") + } + m.record(aws.ToString(in.RoleArn), "") expiry := time.Now().Add(60 * time.Minute) return &sts.AssumeRoleWithWebIdentityOutput{ Credentials: &ststypes.Credentials{ - AccessKeyId: in.RoleArn, + AccessKeyId: aws.String("WEBIDENTITYFAKEACCESSKEYID"), SecretAccessKey: aws.String("secret"), SessionToken: aws.String("token"), Expiration: &expiry, @@ -74,6 +83,10 @@ func (m *STSClient) AssumeRoleWithWebIdentity(ctx context.Context, in *sts.Assum } func (m *STSClient) AssumeRole(ctx context.Context, in *sts.AssumeRoleInput, _ ...func(*sts.Options)) (*sts.AssumeRoleOutput, error) { + if m.Unauth { + return nil, trace.AccessDenied("unauthorized") + } + // Retrieve credentials if we have a credential provider, so that all // assume-role providers in a role chain are triggered to call AssumeRole. if m.credentialProvider != nil { @@ -87,7 +100,7 @@ func (m *STSClient) AssumeRole(ctx context.Context, in *sts.AssumeRoleInput, _ . expiry := time.Now().Add(60 * time.Minute) return &sts.AssumeRoleOutput{ Credentials: &ststypes.Credentials{ - AccessKeyId: in.RoleArn, + AccessKeyId: aws.String("FAKEACCESSKEYID"), SecretAccessKey: aws.String("secret"), SessionToken: aws.String("token"), Expiration: &expiry, diff --git a/lib/srv/app/aws/handler_test.go b/lib/srv/app/aws/handler_test.go index 9189bb7e3e572..90dbd4ed46d21 100644 --- a/lib/srv/app/aws/handler_test.go +++ b/lib/srv/app/aws/handler_test.go @@ -26,6 +26,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "os" "strings" "testing" "time" @@ -57,6 +58,11 @@ import ( awsutils "github.com/gravitational/teleport/lib/utils/aws" ) +func TestMain(m *testing.M) { + utils.InitLoggerForTests() + os.Exit(m.Run()) +} + type makeRequest func(url string, provider client.ConfigProvider, awsHost string) error func s3Request(url string, provider client.ConfigProvider, awsHost string) error { diff --git a/lib/srv/db/cloud/iam.go b/lib/srv/db/cloud/iam.go index ef49e061e59b8..2cd2da23a354d 100644 --- a/lib/srv/db/cloud/iam.go +++ b/lib/srv/db/cloud/iam.go @@ -269,11 +269,13 @@ func (c *IAM) getAWSIdentity(ctx context.Context, database types.Database) (awsl return c.agentIdentity, nil } c.mu.RUnlock() - sts, err := c.cfg.Clients.GetAWSSTSClient(ctx, meta.Region, cloud.WithAmbientCredentials()) + + awsCfg, err := c.cfg.AWSConfigProvider.GetConfig(ctx, meta.Region, awsconfig.WithAmbientCredentials()) if err != nil { return nil, trace.Wrap(err) } - awsIdentity, err := awslib.GetIdentityWithClient(ctx, sts) + clt := c.cfg.awsClients.getSTSClient(awsCfg) + awsIdentity, err := awslib.GetIdentityWithClientV2(ctx, clt) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/db/cloud/iam_test.go b/lib/srv/db/cloud/iam_test.go index bbee3f9f35063..3c7e4c63f2888 100644 --- a/lib/srv/db/cloud/iam_test.go +++ b/lib/srv/db/cloud/iam_test.go @@ -156,16 +156,15 @@ func TestAWSIAM(t *testing.T) { AWSConfigProvider: &mocks.AWSConfigProvider{ STSClient: stsClient, }, - Clients: &clients.TestCloudClients{ - STS: &stsClient.STSClientV1, - }, - HostID: "host-id", + Clients: &clients.TestCloudClients{}, + HostID: "host-id", onProcessedTask: func(iamTask, error) { taskChan <- struct{}{} }, awsClients: fakeAWSClients{ iamClient: iamClient, rdsClient: clt, + stsClient: stsClient, }, }) require.NoError(t, err) @@ -291,8 +290,10 @@ func TestAWSIAMNoPermissions(t *testing.T) { t.Cleanup(cancel) // Create unauthorized mocks for AWS services. - stsClient := &mocks.STSClientV1{ - ARN: "arn:aws:iam::123456789012:role/test-role", + stsClient := &mocks.STSClient{ + STSClientV1: mocks.STSClientV1{ + ARN: "arn:aws:iam::123456789012:role/test-role", + }, } tests := []struct { name string @@ -301,70 +302,64 @@ func TestAWSIAMNoPermissions(t *testing.T) { awsClients awsClientProvider }{ { - name: "RDS database", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{InstanceID: "postgres-rds", ResourceID: "postgres-rds-resource-id"}}, - clients: &clients.TestCloudClients{ - STS: stsClient, - }, + name: "RDS database", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{InstanceID: "postgres-rds", ResourceID: "postgres-rds-resource-id"}}, + clients: &clients.TestCloudClients{}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, rdsClient: &mocks.RDSClient{Unauth: true}, + stsClient: stsClient, }, }, { - name: "Aurora cluster", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{ClusterID: "postgres-aurora", ResourceID: "postgres-aurora-resource-id"}}, - clients: &clients.TestCloudClients{ - STS: stsClient, - }, + name: "Aurora cluster", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{ClusterID: "postgres-aurora", ResourceID: "postgres-aurora-resource-id"}}, + clients: &clients.TestCloudClients{}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, rdsClient: &mocks.RDSClient{Unauth: true}, + stsClient: stsClient, }, }, { - name: "RDS database missing metadata", - meta: types.AWS{Region: "localhost", RDS: types.RDS{ClusterID: "postgres-aurora"}}, - clients: &clients.TestCloudClients{ - STS: stsClient, - }, + name: "RDS database missing metadata", + meta: types.AWS{Region: "localhost", RDS: types.RDS{ClusterID: "postgres-aurora"}}, + clients: &clients.TestCloudClients{}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, rdsClient: &mocks.RDSClient{Unauth: true}, + stsClient: stsClient, }, }, { - name: "Redshift cluster", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, - clients: &clients.TestCloudClients{ - STS: stsClient, - }, + name: "Redshift cluster", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, + clients: &clients.TestCloudClients{}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, + stsClient: stsClient, }, }, { - name: "ElastiCache", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", ElastiCache: types.ElastiCache{ReplicationGroupID: "some-group"}}, - clients: &clients.TestCloudClients{ - STS: stsClient, - }, + name: "ElastiCache", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", ElastiCache: types.ElastiCache{ReplicationGroupID: "some-group"}}, + clients: &clients.TestCloudClients{}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, + stsClient: stsClient, }, }, { - name: "IAM UnmodifiableEntityException", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, - clients: &clients.TestCloudClients{ - STS: stsClient, - }, + name: "IAM UnmodifiableEntityException", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, + clients: &clients.TestCloudClients{}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{ Error: &iamtypes.UnmodifiableEntityException{ Message: aws.String("Cannot perform the operation on the protected role"), }, }, + stsClient: stsClient, }, }, } @@ -377,11 +372,7 @@ func TestAWSIAMNoPermissions(t *testing.T) { Clients: test.clients, HostID: "host-id", AWSConfigProvider: &mocks.AWSConfigProvider{ - STSClient: &mocks.STSClient{ - STSClientV1: mocks.STSClientV1{ - ARN: "arn:aws:iam::123456789012:role/test-role", - }, - }, + STSClient: stsClient, }, awsClients: test.awsClients, }) diff --git a/lib/srv/db/cloud/meta.go b/lib/srv/db/cloud/meta.go index cfa0e75ed2484..ca84c8a0a6030 100644 --- a/lib/srv/db/cloud/meta.go +++ b/lib/srv/db/cloud/meta.go @@ -36,6 +36,7 @@ import ( redshifttypes "github.com/aws/aws-sdk-go-v2/service/redshift/types" rss "github.com/aws/aws-sdk-go-v2/service/redshiftserverless" rsstypes "github.com/aws/aws-sdk-go-v2/service/redshiftserverless/types" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/gravitational/trace" "github.com/gravitational/teleport" @@ -93,6 +94,11 @@ type rssClient interface { GetWorkgroup(ctx context.Context, params *rss.GetWorkgroupInput, optFns ...func(*rss.Options)) (*rss.GetWorkgroupOutput, error) } +// stsClient defines a subset of the AWS STS client API. +type stsClient interface { + GetCallerIdentity(ctx context.Context, params *sts.GetCallerIdentityInput, optFns ...func(*sts.Options)) (*sts.GetCallerIdentityOutput, error) +} + // awsClientProvider is an AWS SDK client provider. type awsClientProvider interface { getElastiCacheClient(cfg aws.Config, optFns ...func(*elasticache.Options)) elasticacheClient @@ -102,6 +108,7 @@ type awsClientProvider interface { getRDSClient(cfg aws.Config, optFns ...func(*rds.Options)) rdsClient getRedshiftClient(cfg aws.Config, optFns ...func(*redshift.Options)) redshiftClient getRedshiftServerlessClient(cfg aws.Config, optFns ...func(*rss.Options)) rssClient + getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient } type defaultAWSClients struct{} @@ -134,6 +141,10 @@ func (defaultAWSClients) getRedshiftServerlessClient(cfg aws.Config, optFns ...f return rss.NewFromConfig(cfg, optFns...) } +func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient { + return sts.NewFromConfig(cfg, optFns...) +} + // MetadataConfig is the cloud metadata service config. type MetadataConfig struct { // Clients is an interface for retrieving cloud clients. diff --git a/lib/srv/db/cloud/meta_test.go b/lib/srv/db/cloud/meta_test.go index 76c0668a62c07..1aea1d19e38db 100644 --- a/lib/srv/db/cloud/meta_test.go +++ b/lib/srv/db/cloud/meta_test.go @@ -35,6 +35,7 @@ import ( redshifttypes "github.com/aws/aws-sdk-go-v2/service/redshift/types" rss "github.com/aws/aws-sdk-go-v2/service/redshiftserverless" rsstypes "github.com/aws/aws-sdk-go-v2/service/redshiftserverless/types" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types" @@ -511,6 +512,7 @@ type fakeAWSClients struct { rdsClient rdsClient redshiftClient redshiftClient rssClient rssClient + stsClient stsClient } func (f fakeAWSClients) getElastiCacheClient(cfg aws.Config, optFns ...func(*elasticache.Options)) elasticacheClient { @@ -540,3 +542,7 @@ func (f fakeAWSClients) getRedshiftClient(aws.Config, ...func(*redshift.Options) func (f fakeAWSClients) getRedshiftServerlessClient(aws.Config, ...func(*rss.Options)) rssClient { return f.rssClient } + +func (f fakeAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient { + return f.stsClient +} diff --git a/lib/srv/db/cloud/resource_checker.go b/lib/srv/db/cloud/resource_checker.go index ea38c69abecf4..12fe017c3ca1b 100644 --- a/lib/srv/db/cloud/resource_checker.go +++ b/lib/srv/db/cloud/resource_checker.go @@ -80,7 +80,7 @@ func NewDiscoveryResourceChecker(cfg DiscoveryResourceCheckerConfig) (DiscoveryR return nil, trace.Wrap(err) } - credentialsChecker, err := newCrednentialsChecker(cfg) + credentialsChecker, err := newCredentialsChecker(cfg) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/db/cloud/resource_checker_credentials.go b/lib/srv/db/cloud/resource_checker_credentials.go index 3a35bd7614d30..0e6d5e7770d55 100644 --- a/lib/srv/db/cloud/resource_checker_credentials.go +++ b/lib/srv/db/cloud/resource_checker_credentials.go @@ -30,6 +30,7 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/aws" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/utils" ) @@ -40,13 +41,15 @@ import ( // Note that this checker warns the user with suggestions on how to configure // the credentials correctly instead of returning errors. type credentialsChecker struct { - cloudClients cloud.Clients - resourceMatchers []services.ResourceMatcher - logger *slog.Logger - cache *utils.FnCache + awsConfigProvider awsconfig.Provider + awsClients awsClientProvider + azureClients cloud.AzureClients + resourceMatchers []services.ResourceMatcher + logger *slog.Logger + cache *utils.FnCache } -func newCrednentialsChecker(cfg DiscoveryResourceCheckerConfig) (*credentialsChecker, error) { +func newCredentialsChecker(cfg DiscoveryResourceCheckerConfig) (*credentialsChecker, error) { cache, err := utils.NewFnCache(utils.FnCacheConfig{ TTL: 10 * time.Minute, Context: cfg.Context, @@ -56,10 +59,12 @@ func newCrednentialsChecker(cfg DiscoveryResourceCheckerConfig) (*credentialsChe } return &credentialsChecker{ - cloudClients: cfg.Clients, - resourceMatchers: cfg.ResourceMatchers, - logger: cfg.Logger, - cache: cache, + awsConfigProvider: cfg.AWSConfigProvider, + awsClients: defaultAWSClients{}, + azureClients: cfg.Clients, + resourceMatchers: cfg.ResourceMatchers, + logger: cfg.Logger, + cache: cache, }, nil } @@ -111,18 +116,19 @@ func (c *credentialsChecker) getAWSIdentity(ctx context.Context, meta *types.AWS } identity, err := utils.FnCacheGet(ctx, c.cache, types.CloudAWS, func(ctx context.Context) (aws.Identity, error) { - client, err := c.cloudClients.GetAWSSTSClient(ctx, "", cloud.WithAmbientCredentials()) + awsCfg, err := c.awsConfigProvider.GetConfig(ctx, meta.Region, awsconfig.WithAmbientCredentials()) if err != nil { return nil, trace.Wrap(err) } - return aws.GetIdentityWithClient(ctx, client) + client := c.awsClients.getSTSClient(awsCfg) + return aws.GetIdentityWithClientV2(ctx, client) }) return identity, trace.Wrap(err) } func (c *credentialsChecker) checkAzure(ctx context.Context, database types.Database) { allSubIDs, err := utils.FnCacheGet(ctx, c.cache, types.CloudAzure, func(ctx context.Context) ([]string, error) { - client, err := c.cloudClients.GetAzureSubscriptionClient() + client, err := c.azureClients.GetAzureSubscriptionClient() if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/db/common/auth.go b/lib/srv/db/common/auth.go index 375133b5905c0..d0347f3c6a6f6 100644 --- a/lib/srv/db/common/auth.go +++ b/lib/srv/db/common/auth.go @@ -38,6 +38,7 @@ import ( rdsauth "github.com/aws/aws-sdk-go-v2/feature/rds/auth" "github.com/aws/aws-sdk-go-v2/service/redshift" rss "github.com/aws/aws-sdk-go-v2/service/redshiftserverless" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/aws/aws-sdk-go/aws/credentials" v4 "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/gravitational/trace" @@ -135,10 +136,16 @@ type rssClient interface { GetCredentials(context.Context, *rss.GetCredentialsInput, ...func(*rss.Options)) (*rss.GetCredentialsOutput, error) } +// stsClient defines a subset of the AWS STS client API. +type stsClient interface { + GetCallerIdentity(ctx context.Context, params *sts.GetCallerIdentityInput, optFns ...func(*sts.Options)) (*sts.GetCallerIdentityOutput, error) +} + // awsClientProvider is an AWS SDK client provider. type awsClientProvider interface { getRedshiftClient(cfg aws.Config, optFns ...func(*redshift.Options)) redshiftClient getRedshiftServerlessClient(cfg aws.Config, optFns ...func(*rss.Options)) rssClient + getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient } type defaultAWSClients struct{} @@ -151,6 +158,10 @@ func (defaultAWSClients) getRedshiftServerlessClient(cfg aws.Config, optFns ...f return rss.NewFromConfig(cfg, optFns...) } +func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient { + return sts.NewFromConfig(cfg, optFns...) +} + // AuthConfig is the database access authenticator configuration. type AuthConfig struct { // AuthClient is the cluster auth client. @@ -1141,12 +1152,13 @@ func (a *dbAuth) buildAWSRoleARNFromDatabaseUser(ctx context.Context, database t awsAccountID = assumeRoleARN.AccountID default: a.cfg.Logger.DebugContext(ctx, "Fetching AWS Account ID to build role ARN") - stsClient, err := a.cfg.Clients.GetAWSSTSClient(ctx, dbAWS.Region, cloud.WithAmbientCredentials()) + awsCfg, err := a.cfg.AWSConfigProvider.GetConfig(ctx, dbAWS.Region, awsconfig.WithAmbientCredentials()) if err != nil { return "", trace.Wrap(err) } + clt := a.cfg.awsClients.getSTSClient(awsCfg) - identity, err := awslib.GetIdentityWithClient(ctx, stsClient) + identity, err := awslib.GetIdentityWithClientV2(ctx, clt) if err != nil { return "", trace.Wrap(err) } diff --git a/lib/srv/db/common/auth_test.go b/lib/srv/db/common/auth_test.go index f98de77911fe8..a1cfd04f16722 100644 --- a/lib/srv/db/common/auth_test.go +++ b/lib/srv/db/common/auth_test.go @@ -34,6 +34,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/redshift" rss "github.com/aws/aws-sdk-go-v2/service/redshiftserverless" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" @@ -591,7 +592,7 @@ func TestAuthGetAWSTokenWithAssumedRole(t *testing.T) { require.Equal(t, "some-user", query.Get("User")) require.Equal(t, "host", query.Get("X-Amz-SignedHeaders")) require.Equal(t, "token", query.Get("X-Amz-Security-Token")) - require.Equal(t, "arn:aws:iam::123456789012:role/RedisRole/20010203/ca-central-1/elasticache/aws4_request", + require.Equal(t, "FAKEACCESSKEYID/20010203/ca-central-1/elasticache/aws4_request", query.Get("X-Amz-Credential")) }, checkSTS: func(t *testing.T, stsMock *mocks.STSClient) { @@ -622,6 +623,7 @@ func TestAuthGetAWSTokenWithAssumedRole(t *testing.T) { rssClient: &mocks.RedshiftServerlessClient{ GetCredentialsOutput: mocks.RedshiftServerlessGetCredentialsOutput("IAM:some-user", "some-password", clock), }, + stsClient: fakeSTS, }, }) require.NoError(t, err) @@ -643,58 +645,55 @@ func TestGetAWSIAMCreds(t *testing.T) { for name, tt := range map[string]struct { db types.Database - stsMock *mocks.STSClientV1 + stsMock *mocks.STSClient username string - expectedKeyId string expectedAssumedRoles []string expectedExternalIDs []string - expectErr require.ErrorAssertionFunc + wantErrContains string }{ "username is full role ARN": { db: newMongoAtlasDatabase(t, types.AWS{}), - stsMock: &mocks.STSClientV1{}, + stsMock: &mocks.STSClient{}, username: "arn:aws:iam::123456789012:role/role-name", - expectedKeyId: "arn:aws:iam::123456789012:role/role-name", expectedAssumedRoles: []string{"arn:aws:iam::123456789012:role/role-name"}, expectedExternalIDs: []string{""}, - expectErr: require.NoError, }, "username is partial role ARN": { db: newMongoAtlasDatabase(t, types.AWS{}), - stsMock: &mocks.STSClientV1{ - // This is the role returned by the STS GetCallerIdentity. - ARN: "arn:aws:iam::222222222222:role/teleport-service-role", + stsMock: &mocks.STSClient{ + STSClientV1: mocks.STSClientV1{ + // This is the role returned by the STS GetCallerIdentity. + ARN: "arn:aws:iam::222222222222:role/teleport-service-role", + }, }, username: "role/role-name", - expectedKeyId: "arn:aws:iam::222222222222:role/role-name", expectedAssumedRoles: []string{"arn:aws:iam::222222222222:role/role-name"}, expectedExternalIDs: []string{""}, - expectErr: require.NoError, }, "unable to fetch account ID": { db: newMongoAtlasDatabase(t, types.AWS{}), - stsMock: &mocks.STSClientV1{ - ARN: "", + stsMock: &mocks.STSClient{ + Unauth: true, }, - username: "role/role-name", - expectErr: require.Error, + username: "role/role-name", + wantErrContains: "unauthorized", }, "chained IAM role": { db: newMongoAtlasDatabase(t, types.AWS{ ExternalID: "123123", AssumeRoleARN: "arn:aws:iam::222222222222:role/teleport-service-role-external", }), - stsMock: &mocks.STSClientV1{ - ARN: "arn:aws:iam::111111111111:role/teleport-service-role", + stsMock: &mocks.STSClient{ + STSClientV1: mocks.STSClientV1{ + ARN: "arn:aws:iam::111111111111:role/teleport-service-role", + }, }, - username: "role/role-name", - expectedKeyId: "arn:aws:iam::222222222222:role/role-name", + username: "role/role-name", expectedAssumedRoles: []string{ "arn:aws:iam::222222222222:role/teleport-service-role-external", "arn:aws:iam::222222222222:role/role-name", }, expectedExternalIDs: []string{"123123", ""}, - expectErr: require.NoError, }, } { t.Run(name, func(t *testing.T) { @@ -703,15 +702,22 @@ func TestGetAWSIAMCreds(t *testing.T) { AuthClient: new(authClientMock), AccessPoint: new(accessPointMock), Clients: &cloud.TestCloudClients{ - STS: tt.stsMock, + STS: &tt.stsMock.STSClientV1, }, AWSConfigProvider: &mocks.AWSConfigProvider{}, + awsClients: fakeAWSClients{ + stsClient: tt.stsMock, + }, }) require.NoError(t, err) keyId, _, _, err := auth.GetAWSIAMCreds(ctx, tt.db, tt.username) - tt.expectErr(t, err) - require.Equal(t, tt.expectedKeyId, keyId) + if tt.wantErrContains != "" { + require.Error(t, err) + require.ErrorContains(t, err, tt.wantErrContains) + return + } + require.Equal(t, "FAKEACCESSKEYID", keyId) require.ElementsMatch(t, tt.expectedAssumedRoles, tt.stsMock.GetAssumedRoleARNs()) require.ElementsMatch(t, tt.expectedExternalIDs, tt.stsMock.GetAssumedRoleExternalIDs()) }) @@ -1025,6 +1031,7 @@ func (m *imdsMock) GetType() types.InstanceMetadataType { type fakeAWSClients struct { redshiftClient redshiftClient rssClient rssClient + stsClient stsClient } func (f fakeAWSClients) getRedshiftClient(aws.Config, ...func(*redshift.Options)) redshiftClient { @@ -1034,3 +1041,7 @@ func (f fakeAWSClients) getRedshiftClient(aws.Config, ...func(*redshift.Options) func (f fakeAWSClients) getRedshiftServerlessClient(cfg aws.Config, optFns ...func(*rss.Options)) rssClient { return f.rssClient } + +func (f fakeAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient { + return f.stsClient +} diff --git a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go index eecc06b0ef218..21a5ca1af85e8 100644 --- a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go +++ b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go @@ -29,8 +29,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/iam" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/s3" - "github.com/aws/aws-sdk-go/aws/client" - "github.com/aws/aws-sdk-go/service/sts" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/gravitational/trace" "golang.org/x/sync/errgroup" @@ -106,6 +105,11 @@ type iamClient interface { ListSAMLProviders(context.Context, *iam.ListSAMLProvidersInput, ...func(*iam.Options)) (*iam.ListSAMLProvidersOutput, error) } +// stsClient defines a subset of the AWS STS client API. +type stsClient interface { + GetCallerIdentity(ctx context.Context, params *sts.GetCallerIdentityInput, optFns ...func(*sts.Options)) (*sts.GetCallerIdentityOutput, error) +} + // awsClientProvider provides AWS service API clients. type awsClientProvider interface { // getIAMClient provides an [iamClient]. @@ -114,6 +118,8 @@ type awsClientProvider interface { getRDSClient(cfg aws.Config, optFns ...func(*rds.Options)) rdsClient // getS3Client provides an [s3Client]. getS3Client(cfg aws.Config, optFns ...func(*s3.Options)) s3Client + // getSTSClient provides an [stsClient]. + getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient } type defaultAWSClients struct{} @@ -130,6 +136,10 @@ func (defaultAWSClients) getS3Client(cfg aws.Config, optFns ...func(*s3.Options) return s3.NewFromConfig(cfg, optFns...) } +func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient { + return sts.NewFromConfig(cfg, optFns...) +} + // AssumeRole is the configuration for assuming an AWS role. type AssumeRole struct { // RoleARN is the ARN of the role to assume. @@ -355,36 +365,9 @@ func (a *Fetcher) poll(ctx context.Context, features Features) (*Resources, erro return result, trace.NewAggregate(errs...) } -// getAWSOptions returns a list of AWSAssumeRoleOptionFn to be used when -// creating AWS clients. -func (a *Fetcher) getAWSOptions() []cloud.AWSOptionsFn { - opts := []cloud.AWSOptionsFn{ - cloud.WithCredentialsMaybeIntegration(a.Config.Integration), - } - - if a.Config.AssumeRole != nil { - opts = append(opts, cloud.WithAssumeRole(a.Config.AssumeRole.RoleARN, a.Config.AssumeRole.ExternalID)) - } - const maxRetries = 10 - opts = append(opts, - cloud.WithMaxRetries(maxRetries), - cloud.WithRetryer( - client.DefaultRetryer{ - NumMaxRetries: maxRetries, - MinRetryDelay: time.Second, - MinThrottleDelay: time.Second, - MaxRetryDelay: 300 * time.Second, - MaxThrottleDelay: 300 * time.Second, - }, - ), - ) - - return opts -} - -// getAWSV2Options returns a list of options to be used when +// getAWSOptions returns a list of options to be used when // creating AWS clients with the v2 sdk. -func (a *Fetcher) getAWSV2Options() []awsconfig.OptionsFn { +func (a *Fetcher) getAWSOptions() []awsconfig.OptionsFn { opts := []awsconfig.OptionsFn{ awsconfig.WithCredentialsMaybeIntegration(a.Config.Integration), } @@ -404,7 +387,7 @@ func (a *Fetcher) getAWSV2Options() []awsconfig.OptionsFn { } func (a *Fetcher) getAccountId(ctx context.Context) (string, error) { - stsClient, err := a.CloudClients.GetAWSSTSClient( + awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because groups are global */ a.getAWSOptions()..., @@ -412,9 +395,10 @@ func (a *Fetcher) getAccountId(ctx context.Context) (string, error) { if err != nil { return "", trace.Wrap(err) } + stsClient := a.awsClients.getSTSClient(awsCfg) input := &sts.GetCallerIdentityInput{} - req, err := stsClient.GetCallerIdentityWithContext(ctx, input) + req, err := stsClient.GetCallerIdentity(ctx, input) if err != nil { return "", trace.Wrap(err) } diff --git a/lib/srv/discovery/fetchers/aws-sync/ec2.go b/lib/srv/discovery/fetchers/aws-sync/ec2.go index 1ae520e743c38..1587ef6624679 100644 --- a/lib/srv/discovery/fetchers/aws-sync/ec2.go +++ b/lib/srv/discovery/fetchers/aws-sync/ec2.go @@ -89,7 +89,7 @@ func (a *Fetcher) fetchAWSEC2Instances(ctx context.Context) ([]*accessgraphv1alp return h.Region == region && h.AccountId == a.AccountID }, ) - ec2Client, err := a.GetEC2Client(ctx, region, a.getAWSV2Options()...) + ec2Client, err := a.GetEC2Client(ctx, region, a.getAWSOptions()...) if err != nil { collectHosts(prevIterationEc2, trace.Wrap(err)) return nil @@ -155,7 +155,7 @@ func (a *Fetcher) fetchInstanceProfiles(ctx context.Context) ([]*accessgraphv1al awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return existing, trace.Wrap(err) diff --git a/lib/srv/discovery/fetchers/aws-sync/eks.go b/lib/srv/discovery/fetchers/aws-sync/eks.go index beba3a5a9a3b3..1fec520ae96fe 100644 --- a/lib/srv/discovery/fetchers/aws-sync/eks.go +++ b/lib/srv/discovery/fetchers/aws-sync/eks.go @@ -103,7 +103,7 @@ func (a *Fetcher) fetchAWSSEKSClusters(ctx context.Context) (fetchAWSEKSClusters for _, region := range a.Regions { region := region eG.Go(func() error { - eksClient, err := a.GetEKSClient(ctx, region, a.getAWSV2Options()...) + eksClient, err := a.GetEKSClient(ctx, region, a.getAWSOptions()...) if err != nil { collectClusters(nil, nil, nil, trace.Wrap(err)) return nil diff --git a/lib/srv/discovery/fetchers/aws-sync/groups.go b/lib/srv/discovery/fetchers/aws-sync/groups.go index b212ee1629b5e..47be4da6b47bd 100644 --- a/lib/srv/discovery/fetchers/aws-sync/groups.go +++ b/lib/srv/discovery/fetchers/aws-sync/groups.go @@ -94,7 +94,7 @@ func (a *Fetcher) fetchGroups(ctx context.Context) ([]*accessgraphv1alpha.AWSGro awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return a.lastResult.Groups, trace.Wrap(err) @@ -144,7 +144,7 @@ func (a *Fetcher) fetchGroupInlinePolicies(ctx context.Context, group *accessgra awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) @@ -201,7 +201,7 @@ func (a *Fetcher) fetchGroupAttachedPolicies(ctx context.Context, group *accessg awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/discovery/fetchers/aws-sync/idp.go b/lib/srv/discovery/fetchers/aws-sync/idp.go index a564c5f02ebf8..f1aa70db6189a 100644 --- a/lib/srv/discovery/fetchers/aws-sync/idp.go +++ b/lib/srv/discovery/fetchers/aws-sync/idp.go @@ -37,7 +37,7 @@ func (a *Fetcher) pollAWSSAMLProviders(ctx context.Context, result *Resources, c awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because saml providers are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { collectErr(trace.Wrap(err, "failed to get AWS IAM client")) @@ -138,7 +138,7 @@ func (a *Fetcher) pollAWSOIDCProviders(ctx context.Context, result *Resources, c awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because oidc providers are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { collectErr(trace.Wrap(err, "failed to get AWS IAM client")) diff --git a/lib/srv/discovery/fetchers/aws-sync/policies.go b/lib/srv/discovery/fetchers/aws-sync/policies.go index 511245a4b732c..72dd185787089 100644 --- a/lib/srv/discovery/fetchers/aws-sync/policies.go +++ b/lib/srv/discovery/fetchers/aws-sync/policies.go @@ -53,7 +53,7 @@ func (a *Fetcher) fetchPolicies(ctx context.Context) ([]*accessgraphv1alpha.AWSP awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/discovery/fetchers/aws-sync/rds.go b/lib/srv/discovery/fetchers/aws-sync/rds.go index 3d7117425d6ab..849bd5c71df0f 100644 --- a/lib/srv/discovery/fetchers/aws-sync/rds.go +++ b/lib/srv/discovery/fetchers/aws-sync/rds.go @@ -81,7 +81,7 @@ func (a *Fetcher) fetchAWSRDSDatabases(ctx context.Context) ( for _, region := range a.Regions { region := region eG.Go(func() error { - awsCfg, err := a.AWSConfigProvider.GetConfig(ctx, region, a.getAWSV2Options()...) + awsCfg, err := a.AWSConfigProvider.GetConfig(ctx, region, a.getAWSOptions()...) if err != nil { collectDBs(nil, trace.Wrap(err)) return nil diff --git a/lib/srv/discovery/fetchers/aws-sync/rds_test.go b/lib/srv/discovery/fetchers/aws-sync/rds_test.go index 27940a1d4215f..330486aafc862 100644 --- a/lib/srv/discovery/fetchers/aws-sync/rds_test.go +++ b/lib/srv/discovery/fetchers/aws-sync/rds_test.go @@ -27,6 +27,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/rds" rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" "google.golang.org/protobuf/testing/protocmp" @@ -221,6 +222,7 @@ type fakeAWSClients struct { iamClient iamClient rdsClient rdsClient s3Client s3Client + stsClient stsClient } func (f fakeAWSClients) getIAMClient(cfg aws.Config, optFns ...func(*iam.Options)) iamClient { @@ -234,3 +236,7 @@ func (f fakeAWSClients) getRDSClient(cfg aws.Config, optFns ...func(*rds.Options func (f fakeAWSClients) getS3Client(cfg aws.Config, optFns ...func(*s3.Options)) s3Client { return f.s3Client } + +func (f fakeAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient { + return f.stsClient +} diff --git a/lib/srv/discovery/fetchers/aws-sync/roles.go b/lib/srv/discovery/fetchers/aws-sync/roles.go index 5f076f4b525c0..1770c7f8c310e 100644 --- a/lib/srv/discovery/fetchers/aws-sync/roles.go +++ b/lib/srv/discovery/fetchers/aws-sync/roles.go @@ -89,7 +89,7 @@ func (a *Fetcher) fetchRoles(ctx context.Context) ([]*accessgraphv1alpha.AWSRole awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because roles are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) @@ -126,7 +126,7 @@ func (a *Fetcher) fetchRoleInlinePolicies(ctx context.Context, role *accessgraph awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) @@ -175,7 +175,7 @@ func (a *Fetcher) fetchRoleAttachedPolicies(ctx context.Context, role *accessgra awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/discovery/fetchers/aws-sync/s3.go b/lib/srv/discovery/fetchers/aws-sync/s3.go index 20f749f6fd952..e318b9391e7f9 100644 --- a/lib/srv/discovery/fetchers/aws-sync/s3.go +++ b/lib/srv/discovery/fetchers/aws-sync/s3.go @@ -218,7 +218,7 @@ func (a *Fetcher) getS3BucketDetails(ctx context.Context, bucket s3types.Bucket, var errs []error var details s3Details - awsCfg, err := a.AWSConfigProvider.GetConfig(ctx, bucketRegion, a.getAWSV2Options()...) + awsCfg, err := a.AWSConfigProvider.GetConfig(ctx, bucketRegion, a.getAWSOptions()...) if err != nil { errs = append(errs, trace.Wrap(err, "failed to create s3 client for bucket %q", aws.ToString(bucket.Name)), @@ -300,7 +300,7 @@ func (a *Fetcher) listS3Buckets(ctx context.Context) ([]s3types.Bucket, func(*st } // use any region to list buckets - awsCfg, err := a.AWSConfigProvider.GetConfig(ctx, region, a.getAWSV2Options()...) + awsCfg, err := a.AWSConfigProvider.GetConfig(ctx, region, a.getAWSOptions()...) if err != nil { return nil, nil, trace.Wrap(err) } diff --git a/lib/srv/discovery/fetchers/aws-sync/users.go b/lib/srv/discovery/fetchers/aws-sync/users.go index 94f28cc9a3928..4f0c552eede61 100644 --- a/lib/srv/discovery/fetchers/aws-sync/users.go +++ b/lib/srv/discovery/fetchers/aws-sync/users.go @@ -108,7 +108,7 @@ func (a *Fetcher) fetchUsers(ctx context.Context) ([]*accessgraphv1alpha.AWSUser awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) @@ -174,7 +174,7 @@ func (a *Fetcher) fetchUserInlinePolicies(ctx context.Context, user *accessgraph awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) @@ -231,7 +231,7 @@ func (a *Fetcher) fetchUserAttachedPolicies(ctx context.Context, user *accessgra awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) @@ -280,7 +280,7 @@ func (a *Fetcher) fetchGroupsForUser(ctx context.Context, user *accessgraphv1alp awsCfg, err := a.AWSConfigProvider.GetConfig( ctx, "", /* region is empty because users and groups are global */ - a.getAWSV2Options()..., + a.getAWSOptions()..., ) if err != nil { return nil, trace.Wrap(err) From 08fcdd02affe16dff910f6629aaf47acfe448b1c Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Wed, 29 Jan 2025 15:20:58 -0700 Subject: [PATCH 06/28] docs: update CA import instructions for HSMs (#51530) Now that #51301 is merged, we have the ability to get all of the active user CA certificates. --- .../desktop-access/active-directory.mdx | 16 ++++++++++++++-- .../desktop-access/getting-started.mdx | 10 +++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/pages/enroll-resources/desktop-access/active-directory.mdx b/docs/pages/enroll-resources/desktop-access/active-directory.mdx index 26e11fd4291e3..73c9d00c285f3 100644 --- a/docs/pages/enroll-resources/desktop-access/active-directory.mdx +++ b/docs/pages/enroll-resources/desktop-access/active-directory.mdx @@ -237,7 +237,7 @@ You must repeat these steps if you rotate the Teleport user certificate authorit To export the Teleport user CA certificate: -1. Log on to a Windows domain controller where you can access **Group Policy Management**. +1. Log on to a Windows host where you can access **Group Policy Management**. 1. Open PowerShell and download the Teleport user certificate authority by running the following command and replacing `teleport.example.com` with the address of your Teleport cluster: @@ -246,7 +246,11 @@ To export the Teleport user CA certificate: $ curl.exe -fo user-ca.cer https:///webapi/auth/export?type=windows ``` -1. Take note of the path to the `user-ca.cer` file for use in a later step. + If you are using Teleport's support for HSM-backed keys, then your Teleport + cluster has multiple user CAs (one for each Auth Service instance). You can + download a bundle containing all CAs by appending `&format=zip` to the URL. + +1. Take note of the path to file you just downloaded for use in a later step. #### Create the GPO for the Teleport certificate @@ -289,6 +293,8 @@ To configure the group policy object: ![Import Teleport CA](../../../img/desktop-access/ca.png) + If you are using HSM-backed keys, you should repeat this step for each CA certificate. + 1. To ensure your GPO update takes effect immediately on this host, open PowerShell and run the following command (optional): @@ -314,6 +320,9 @@ To publish the Teleport certificate in the Active Directory domain: This command enables the domain controllers to trust the Teleport CA so that certificate-based smart card authentication through Teleport can succeed. + If you are using HSM-backed keys, you should repeat this step for each CA certificate + in the zip file you exported earlier in this guide. + #### Publish the Teleport CA to the NTAuth Store For authentication with Teleport-issued certificates to succeed, the @@ -322,6 +331,9 @@ Teleport periodically publishes its CA after it is able to authenticate, but this step must be performed manually the first time for Teleport to have LDAP access. +If you are using HSM-backed keys, you should repeat these steps for each CA certificate +in the bundle. + To publish the Teleport CA to LDAP: 1. Open PowerShell and run the following command using the path to the `user-ca.cer` diff --git a/docs/pages/enroll-resources/desktop-access/getting-started.mdx b/docs/pages/enroll-resources/desktop-access/getting-started.mdx index 520df5a97f79c..3170e6c05eaf4 100644 --- a/docs/pages/enroll-resources/desktop-access/getting-started.mdx +++ b/docs/pages/enroll-resources/desktop-access/getting-started.mdx @@ -48,6 +48,10 @@ To prepare a Windows computer: $ curl.exe -fo teleport.cer https:///webapi/auth/export?type=windows ``` + If you are using Teleport's support for HSM-backed keys, then your Teleport cluster + has multiple user CAs (one for each Auth Service instance). You can download a bundle + containing all CAs by appending `&format=zip` to the URL. + 3. Download the Teleport Windows Auth setup program: ```code @@ -55,7 +59,11 @@ $ curl.exe -fo teleport-windows-auth-setup-v(=teleport.version=)-amd64.exe https ``` 4. Double-click the executable you downloaded to run the Teleport Windows Auth Setup program -interactively and select the Teleport certificate that you exported when prompted. + interactively and select the Teleport certificate that you exported when prompted. + + If you are using Teleport's support for HSM-backed keys and you downloaded a zip file in step 2, + then you should extract the zip file and repeat the process below for each CA certificate. + You can defer the reboot until you have installed all of the certificates. The setup program: From b25252a39e6f606a0ee4772e5dd1c466bef8c35c Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:48:01 -0500 Subject: [PATCH 07/28] Prevent reauthentication for tilde prefix expansion errors (#51464) In https://github.com/gravitational/teleport/pull/24254 expansion of tilde prefixes(i.e. `tsh scp CHANGELOG.md root@host:~foo/`) was explicitly denied. However, because the error returned to the user is a trace.BadParameter error the reauthentication logic kicks in and attempts to resolve the issue with fresh credentials. This error is now caught and wrapped in a NonRetryableError to prevent the authentication logic from providing a weird UX. Updates https://github.com/gravitational/teleport/issues/22886. --- lib/client/client.go | 13 ++++++++++++- lib/sshutils/sftp/sftp.go | 16 +++++++++++++--- lib/sshutils/sftp/sftp_test.go | 3 +-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/client/client.go b/lib/client/client.go index 6d6d08f09f559..94284ed26494c 100644 --- a/lib/client/client.go +++ b/lib/client/client.go @@ -722,7 +722,18 @@ func (c *NodeClient) TransferFiles(ctx context.Context, cfg *sftp.Config) error ) defer span.End() - return trace.Wrap(cfg.TransferFiles(ctx, c.Client.Client)) + if err := cfg.TransferFiles(ctx, c.Client.Client); err != nil { + // TODO(tross): DELETE IN 19.0.0 - Older versions of Teleport would return + // a trace.BadParameter error when ~user path expansion was rejected, and + // reauthentication logic is attempted on BadParameter errors. + if trace.IsBadParameter(err) && strings.Contains(err.Error(), "expanding remote ~user paths is not supported") { + return trace.Wrap(&NonRetryableError{Err: err}) + } + + return trace.Wrap(err) + } + + return nil } type netDialer interface { diff --git a/lib/sshutils/sftp/sftp.go b/lib/sshutils/sftp/sftp.go index b16eb656a3557..28f053ad10d53 100644 --- a/lib/sshutils/sftp/sftp.go +++ b/lib/sshutils/sftp/sftp.go @@ -329,7 +329,7 @@ func (c *Config) expandPaths(srcIsRemote, dstIsRemote bool) (err error) { for i, srcPath := range c.srcPaths { c.srcPaths[i], err = expandPath(srcPath) if err != nil { - return trace.Wrap(err, "error expanding %q", srcPath) + return trace.Wrap(err) } } } @@ -337,13 +337,23 @@ func (c *Config) expandPaths(srcIsRemote, dstIsRemote bool) (err error) { if dstIsRemote { c.dstPath, err = expandPath(c.dstPath) if err != nil { - return trace.Wrap(err, "error expanding %q", c.dstPath) + return trace.Wrap(err) } } return nil } +// PathExpansionError is an [error] indicating that +// path expansion was rejected. +type PathExpansionError struct { + path string +} + +func (p PathExpansionError) Error() string { + return fmt.Sprintf("expanding remote ~user paths is not supported, specify an absolute path instead of %q", p.path) +} + func expandPath(pathStr string) (string, error) { pfxLen, ok := homeDirPrefixLen(pathStr) if !ok { @@ -358,7 +368,7 @@ func expandPath(pathStr string) (string, error) { return ".", nil } if pfxLen == 1 && len(pathStr) > 1 { - return "", trace.BadParameter("expanding remote ~user paths is not supported, specify an absolute path instead") + return "", trace.Wrap(PathExpansionError{path: pathStr}) } // if an SFTP path is not absolute, it is assumed to start at the user's diff --git a/lib/sshutils/sftp/sftp_test.go b/lib/sshutils/sftp/sftp_test.go index 7be2b5ae0f9ab..85e203d3cbdab 100644 --- a/lib/sshutils/sftp/sftp_test.go +++ b/lib/sshutils/sftp/sftp_test.go @@ -34,7 +34,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/gravitational/trace" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/lib/utils" @@ -585,7 +584,7 @@ func TestHomeDirExpansion(t *testing.T) { name: "~user path", path: "~user/foo", errCheck: func(t require.TestingT, err error, i ...interface{}) { - require.True(t, trace.IsBadParameter(err)) + require.ErrorIs(t, err, PathExpansionError{path: "~user/foo"}) }, }, } From 6a8c0b533008826d476e17f890466e85a635aad2 Mon Sep 17 00:00:00 2001 From: Stephen Levine Date: Wed, 29 Jan 2025 18:48:31 -0500 Subject: [PATCH 08/28] [teleport-update] Adjustments for SELinux (#51474) * selinux fixes * extra checks * lint * lint * cleanup * better cleanup * fix rebase --- lib/autoupdate/agent/installer.go | 13 ++- lib/autoupdate/agent/process.go | 12 +- lib/autoupdate/agent/setup.go | 15 ++- .../not_started_or_enabled.golden | 9 ++ ...enabled_now,_not_started_or_enabled.golden | 13 +++ lib/autoupdate/agent/updater.go | 94 ++++++++++++++-- lib/autoupdate/agent/updater_test.go | 103 ++++++++++++++++++ 7 files changed, 242 insertions(+), 17 deletions(-) create mode 100644 lib/autoupdate/agent/testdata/TestUpdater_Install/not_started_or_enabled.golden create mode 100644 lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now,_not_started_or_enabled.golden diff --git a/lib/autoupdate/agent/installer.go b/lib/autoupdate/agent/installer.go index 370dcb58ad3df..fcc34e822abde 100644 --- a/lib/autoupdate/agent/installer.go +++ b/lib/autoupdate/agent/installer.go @@ -515,7 +515,7 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string } } for _, f := range revertFiles { - err := renameio.WriteFile(f.name, f.data, f.mode) + err := writeFileAtomicWithinDir(f.name, f.data, f.mode) if err != nil { keepFiles = append(keepFiles, f) li.Log.ErrorContext(ctx, "Failed to revert files", "name", f.name, errorKey, err) @@ -650,13 +650,22 @@ func forceCopy(dst string, srcData []byte, n int64) (orig *smallFile, err error) return nil, trace.Wrap(os.ErrExist) } } - err = renameio.WriteFile(dst, srcData, configFileMode) + err = writeFileAtomicWithinDir(dst, srcData, configFileMode) if err != nil { return nil, trace.Wrap(err) } return orig, nil } +// writeFileAtomicWithinDir atomically creates a new file with renameio, while ensuring that temporary +// files use the same directory as the target file (with format: .[base][randints]). +// This ensures that SELinux contexts for important files are set correctly. +func writeFileAtomicWithinDir(filename string, data []byte, perm os.FileMode) error { + dir := filepath.Dir(filename) + err := renameio.WriteFile(filename, data, perm, renameio.WithTempDir(dir)) + return trace.Wrap(err) +} + // 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) diff --git a/lib/autoupdate/agent/process.go b/lib/autoupdate/agent/process.go index 75aa7cdbb9da0..4bf1bd2617e03 100644 --- a/lib/autoupdate/agent/process.go +++ b/lib/autoupdate/agent/process.go @@ -294,7 +294,7 @@ func (s SystemdService) Disable(ctx context.Context, now bool) error { return nil } -// IsEnabled returns true if the service is enabled, or if it's disabled but still active. +// IsEnabled returns true if the service is enabled. func (s SystemdService) IsEnabled(ctx context.Context) (bool, error) { if err := s.checkSystem(ctx); err != nil { return false, trace.Wrap(err) @@ -306,7 +306,15 @@ func (s SystemdService) IsEnabled(ctx context.Context) (bool, error) { case code == 0: return true, nil } - code = s.systemctl(ctx, slog.LevelDebug, "is-active", "--quiet", s.ServiceName) + return false, nil +} + +// IsActive returns true if the service is active. +func (s SystemdService) IsActive(ctx context.Context) (bool, error) { + if err := s.checkSystem(ctx); err != nil { + return false, trace.Wrap(err) + } + code := s.systemctl(ctx, slog.LevelDebug, "is-active", "--quiet", s.ServiceName) switch { case code < 0: return false, trace.Errorf("unable to determine if systemd service %s is active", s.ServiceName) diff --git a/lib/autoupdate/agent/setup.go b/lib/autoupdate/agent/setup.go index 163b8ea3171e2..b4aefe9b21425 100644 --- a/lib/autoupdate/agent/setup.go +++ b/lib/autoupdate/agent/setup.go @@ -233,7 +233,7 @@ func (ns *Namespace) Setup(ctx context.Context) error { } // If the old teleport-upgrade script is detected, disable it to ensure they do not interfere. // Note that the schedule is also set to nop by the Teleport agent -- this just prevents restarts. - enabled, err := oldTimer.IsEnabled(ctx) + enabled, err := isActiveOrEnabled(ctx, oldTimer) if err != nil { return trace.Wrap(err, "failed to determine if deprecated teleport-upgrade systemd timer is enabled") } @@ -305,15 +305,15 @@ func (ns *Namespace) writeConfigFiles(ctx context.Context) error { UpdaterCommand: ns.updaterBinFile + args + " update", UpdaterConfigFile: ns.updaterConfigFile, } - err := writeTemplate(ns.updaterServiceFile, updateServiceTemplate, params) + err := writeSystemTemplate(ns.updaterServiceFile, updateServiceTemplate, params) if err != nil { return trace.Wrap(err) } - err = writeTemplate(ns.updaterTimerFile, updateTimerTemplate, params) + err = writeSystemTemplate(ns.updaterTimerFile, updateTimerTemplate, params) if err != nil { return trace.Wrap(err) } - err = writeTemplate(ns.dropInFile, teleportDropInTemplate, params) + err = writeSystemTemplate(ns.dropInFile, teleportDropInTemplate, params) if err != nil { return trace.Wrap(err) } @@ -327,7 +327,7 @@ func (ns *Namespace) writeConfigFiles(ctx context.Context) error { return nil } ns.log.InfoContext(ctx, "Disabling needrestart.", unitKey, teleportService) - err = writeTemplate(ns.needrestartConfFile, needrestartConfTemplate, params) + err = writeSystemTemplate(ns.needrestartConfFile, needrestartConfTemplate, params) if err != nil { ns.log.ErrorContext(ctx, "Unable to disable needrestart.", errorKey, err) return nil @@ -335,7 +335,9 @@ func (ns *Namespace) writeConfigFiles(ctx context.Context) error { return nil } -func writeTemplate(path, t string, values any) error { +// writeSystemTemplate atomically writes a template to a system file, creating any needed directories. +// Temporarily files are stored in the target path to ensure the file has needed SELinux contexts. +func writeSystemTemplate(path, t string, values any) error { dir, file := filepath.Split(path) if err := os.MkdirAll(dir, systemDirMode); err != nil { return trace.Wrap(err) @@ -343,6 +345,7 @@ func writeTemplate(path, t string, values any) error { opts := []renameio.Option{ renameio.WithPermissions(configFileMode), renameio.WithExistingPermissions(), + renameio.WithTempDir(dir), } f, err := renameio.NewPendingFile(path, opts...) if err != nil { diff --git a/lib/autoupdate/agent/testdata/TestUpdater_Install/not_started_or_enabled.golden b/lib/autoupdate/agent/testdata/TestUpdater_Install/not_started_or_enabled.golden new file mode 100644 index 0000000000000..cfd3745bbd833 --- /dev/null +++ b/lib/autoupdate/agent/testdata/TestUpdater_Install/not_started_or_enabled.golden @@ -0,0 +1,9 @@ +version: v1 +kind: update_config +spec: + proxy: localhost + enabled: false + pinned: false +status: + active: + version: 16.3.0 diff --git a/lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now,_not_started_or_enabled.golden b/lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now,_not_started_or_enabled.golden new file mode 100644 index 0000000000000..490190b7416a0 --- /dev/null +++ b/lib/autoupdate/agent/testdata/TestUpdater_Update/updates_enabled_now,_not_started_or_enabled.golden @@ -0,0 +1,13 @@ +version: v1 +kind: update_config +spec: + proxy: localhost + group: group + base_url: 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 f9c2f2bb22d32..b558f1d6f3d58 100644 --- a/lib/autoupdate/agent/updater.go +++ b/lib/autoupdate/agent/updater.go @@ -247,14 +247,20 @@ type Process interface { // If the type implementing Process does not support the system process manager, // Sync must return ErrNotSupported. Sync(ctx context.Context) error - // IsEnabled must return true if the Process is running or is configured to run. + // IsEnabled must return true if the Process is configured to run on system boot. // If the type implementing Process does not support the system process manager, - // Sync must return ErrNotSupported. + // IsEnabled must return ErrNotSupported. IsEnabled(ctx context.Context) (bool, error) + // IsActive must return true if the Process is currently running. + // If the type implementing Process does not support the system process manager, + // IsActive must return ErrNotSupported. + IsActive(ctx context.Context) (bool, error) + // IsPresent must return true if the Process is installed on the system. + // If the type implementing Process does not support the system process manager, + // IsPresent must return ErrNotSupported. + IsPresent(ctx context.Context) (bool, error) } -// TODO(sclevine): add support for need_restart and selinux config - // OverrideConfig contains overrides for individual update operations. // If validated, these overrides may be persisted to disk. type OverrideConfig struct { @@ -331,7 +337,7 @@ func (u *Updater) Install(ctx context.Context, override OverrideConfig) error { return trace.Wrap(err, "failed to write %s", updateConfigName) } u.Log.InfoContext(ctx, "Configuration updated.") - return nil + return trace.Wrap(u.notices(ctx)) } // Remove removes everything created by the updater. @@ -358,12 +364,12 @@ func (u *Updater) Remove(ctx context.Context) error { revert, err := u.Installer.LinkSystem(ctx) if errors.Is(err, ErrNoBinaries) { u.Log.InfoContext(ctx, "Updater-managed installation of Teleport detected. Attempting to unlink and remove.") - ok, err := u.Process.IsEnabled(ctx) + ok, err := isActiveOrEnabled(ctx, u.Process) if err != nil && !errors.Is(err, ErrNotSupported) { return trace.Wrap(err) } if ok { - return trace.Errorf("refusing to remove active installation of Teleport, please disable Teleport first") + return trace.Errorf("refusing to remove active installation of Teleport, please stop and disable Teleport first") } if err := u.Installer.Unlink(ctx, active); err != nil { return trace.Wrap(err) @@ -439,6 +445,25 @@ func (u *Updater) Remove(ctx context.Context) error { return nil } +// isActiveOrEnabled returns true if the service is active or enabled. +func isActiveOrEnabled(ctx context.Context, s Process) (bool, error) { + enabled, err := s.IsEnabled(ctx) + if err != nil { + return false, trace.Wrap(err) + } + if enabled { + return true, nil + } + active, err := s.IsActive(ctx) + if err != nil { + return false, trace.Wrap(err) + } + if active { + return true, nil + } + return false, nil +} + // Status returns all available local and remote fields related to agent auto-updates. func (u *Updater) Status(ctx context.Context) (Status, error) { var out Status @@ -582,6 +607,10 @@ func (u *Updater) Update(ctx context.Context, now bool) error { } else { u.Log.InfoContext(ctx, "Configuration updated.") } + // Show notices last + if updateErr == nil && now { + updateErr = u.notices(ctx) + } return trace.NewAggregate(updateErr, writeErr) } @@ -695,6 +724,20 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision return trace.Wrap(err, "failed to validate configuration for new version %s of Teleport", target) } + present, err := u.Process.IsPresent(ctx) + if err != nil || !present { + u.Log.ErrorContext(ctx, "Reverting symlinks due to error reading Teleport service file.") + if ok := revertConfig(ctx); ok { + u.Log.WarnContext(ctx, "Teleport updater encountered an error reading the Teleport service file and successfully reverted the installation.") + } + } + if err != nil { + return trace.Wrap(err, "failed to determine if new version %s of Teleport has an installed systemd service", target) + } + if !present { + return trace.Errorf("cannot find systemd service for new version %s of Teleport, check SELinux settings", target) + } + // Restart Teleport if necessary. if cfg.Status.Active != target { @@ -718,6 +761,7 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision } return trace.Wrap(err, "failed to start new version %s of Teleport", target) } + if r := cfg.Status.Active; r.Version != "" { cfg.Status.Backup = toPtr(r) } @@ -734,6 +778,31 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision })) } +// notices displays final notices after install or update. +func (u *Updater) notices(ctx context.Context) error { + enabled, err := u.Process.IsEnabled(ctx) + if err != nil { + return trace.Wrap(err, "failed to query Teleport systemd enabled status") + } + active, err := u.Process.IsActive(ctx) + if err != nil { + return trace.Wrap(err, "failed to query Teleport systemd active status") + } + if !enabled && active { + u.Log.WarnContext(ctx, "Teleport is installed and started, but not configured to start on boot.") + u.Log.WarnContext(ctx, "After configuring teleport.yaml, you can enable it with: systemctl enable teleport") + } + if !active && enabled { + u.Log.WarnContext(ctx, "Teleport is installed and enabled at boot, but not running.") + u.Log.WarnContext(ctx, "After configuring teleport.yaml, you can start it with: systemctl start teleport") + } + if !active && !enabled { + u.Log.WarnContext(ctx, "Teleport is installed, but not running or enabled at boot.") + u.Log.WarnContext(ctx, "After configuring teleport.yaml, you can enable and start it with: systemctl enable teleport --now") + } + return nil +} + // cleanup orphan installations func (u *Updater) cleanup(ctx context.Context, keep []Revision) error { revs, err := u.Installer.List(ctx) @@ -793,10 +862,21 @@ func (u *Updater) LinkPackage(ctx context.Context) error { } else if err != nil { return trace.Wrap(err, "failed to link system package installation") } + + // If syncing succeeds, ensure the installed systemd service can be found via systemctl. + // SELinux contexts can interfere with systemctl's ability to read service files. if err := u.Process.Sync(ctx); errors.Is(err, ErrNotSupported) { u.Log.WarnContext(ctx, "Systemd is not installed. Skipping sync.") } else if err != nil { return trace.Wrap(err, "failed to sync systemd configuration") + } else { + present, err := u.Process.IsPresent(ctx) + if err != nil { + return trace.Wrap(err, "failed to determine if Teleport has an installed systemd service") + } + if !present { + return trace.Errorf("cannot find systemd service for Teleport, check SELinux settings") + } } u.Log.InfoContext(ctx, "Successfully linked system package installation.") return nil diff --git a/lib/autoupdate/agent/updater_test.go b/lib/autoupdate/agent/updater_test.go index f02c7773d5aa8..d0f36df0965b4 100644 --- a/lib/autoupdate/agent/updater_test.go +++ b/lib/autoupdate/agent/updater_test.go @@ -228,6 +228,8 @@ func TestUpdater_Update(t *testing.T) { installErr error setupErr error reloadErr error + notActive bool + notEnabled bool removedRevisions []Revision installedRevision Revision @@ -287,6 +289,32 @@ func TestUpdater_Update(t *testing.T) { reloadCalls: 1, setupCalls: 1, }, + { + name: "updates enabled now, not started or enabled", + cfg: &UpdateConfig{ + Version: updateConfigVersion, + Kind: updateConfigKind, + Spec: UpdateSpec{ + Group: "group", + BaseURL: "https://example.com", + Enabled: true, + }, + Status: UpdateStatus{ + Active: NewRevision("old-version", 0), + }, + }, + now: true, + notEnabled: true, + notActive: true, + + removedRevisions: []Revision{NewRevision("unknown-version", 0)}, + installedRevision: NewRevision("16.3.0", 0), + installedBaseURL: "https://example.com", + linkedRevision: NewRevision("16.3.0", 0), + requestGroup: "group", + reloadCalls: 1, + setupCalls: 1, + }, { name: "updates disabled during window", cfg: &UpdateConfig{ @@ -642,6 +670,15 @@ func TestUpdater_Update(t *testing.T) { reloadCalls++ return tt.reloadErr }, + FuncIsPresent: func(ctx context.Context) (bool, error) { + return true, nil + }, + FuncIsEnabled: func(ctx context.Context) (bool, error) { + return !tt.notEnabled, nil + }, + FuncIsActive: func(ctx context.Context) (bool, error) { + return !tt.notActive, nil + }, } updater.Setup = func(_ context.Context) error { setupCalls++ @@ -697,6 +734,7 @@ func TestUpdater_LinkPackage(t *testing.T) { cfg *UpdateConfig // nil -> file not present tryLinkSystemErr error syncErr error + notPresent bool syncCalls int tryLinkSystemCalls int @@ -794,6 +832,20 @@ func TestUpdater_LinkPackage(t *testing.T) { syncCalls: 1, syncErr: ErrNotSupported, }, + { + name: "SELinux blocks service from being read", + cfg: &UpdateConfig{ + Version: updateConfigVersion, + Kind: updateConfigKind, + Spec: UpdateSpec{ + Enabled: false, + }, + }, + tryLinkSystemCalls: 1, + syncCalls: 1, + notPresent: true, + errMatch: "cannot find systemd service", + }, } for _, tt := range tests { @@ -830,6 +882,9 @@ func TestUpdater_LinkPackage(t *testing.T) { syncCalls++ return tt.syncErr }, + FuncIsPresent: func(ctx context.Context) (bool, error) { + return !tt.notPresent, nil + }, } ctx := context.Background() @@ -1055,6 +1110,9 @@ func TestUpdater_Remove(t *testing.T) { FuncIsEnabled: func(_ context.Context) (bool, error) { return tt.processEnabled, tt.isEnabledErr }, + FuncIsActive: func(_ context.Context) (bool, error) { + return false, nil + }, } updater.Teardown = func(_ context.Context) error { teardownCalls++ @@ -1090,6 +1148,9 @@ func TestUpdater_Install(t *testing.T) { installErr error setupErr error reloadErr error + notPresent bool + notEnabled bool + notActive bool removedRevision Revision installedRevision Revision @@ -1322,6 +1383,29 @@ func TestUpdater_Install(t *testing.T) { name: "no need to reload", reloadErr: ErrNotNeeded, + installedRevision: NewRevision("16.3.0", 0), + installedBaseURL: autoupdate.DefaultBaseURL, + linkedRevision: NewRevision("16.3.0", 0), + reloadCalls: 1, + setupCalls: 1, + }, + { + name: "not present after install", + notPresent: true, + + installedRevision: NewRevision("16.3.0", 0), + installedBaseURL: autoupdate.DefaultBaseURL, + linkedRevision: NewRevision("16.3.0", 0), + reloadCalls: 0, + revertCalls: 1, + setupCalls: 1, + errMatch: "cannot find systemd service", + }, + { + name: "not started or enabled", + notEnabled: true, + notActive: true, + installedRevision: NewRevision("16.3.0", 0), installedBaseURL: autoupdate.DefaultBaseURL, linkedRevision: NewRevision("16.3.0", 0), @@ -1408,6 +1492,15 @@ func TestUpdater_Install(t *testing.T) { reloadCalls++ return tt.reloadErr }, + FuncIsPresent: func(ctx context.Context) (bool, error) { + return !tt.notPresent, nil + }, + FuncIsEnabled: func(ctx context.Context) (bool, error) { + return !tt.notEnabled, nil + }, + FuncIsActive: func(ctx context.Context) (bool, error) { + return !tt.notActive, nil + }, } updater.Setup = func(_ context.Context) error { setupCalls++ @@ -1513,6 +1606,8 @@ type testProcess struct { FuncReload func(ctx context.Context) error FuncSync func(ctx context.Context) error FuncIsEnabled func(ctx context.Context) (bool, error) + FuncIsActive func(ctx context.Context) (bool, error) + FuncIsPresent func(ctx context.Context) (bool, error) } func (tp *testProcess) Reload(ctx context.Context) error { @@ -1526,3 +1621,11 @@ func (tp *testProcess) Sync(ctx context.Context) error { func (tp *testProcess) IsEnabled(ctx context.Context) (bool, error) { return tp.FuncIsEnabled(ctx) } + +func (tp *testProcess) IsActive(ctx context.Context) (bool, error) { + return tp.FuncIsActive(ctx) +} + +func (tp *testProcess) IsPresent(ctx context.Context) (bool, error) { + return tp.FuncIsPresent(ctx) +} From ba65e79c6a1bf3a3f99ced6abee4d26081a096e7 Mon Sep 17 00:00:00 2001 From: Stephen Levine Date: Wed, 29 Jan 2025 19:35:37 -0500 Subject: [PATCH 09/28] [teleport-update] Add --overwrite flag to replace tarball installations (#51579) * add --overwrite flag * extra warning --- lib/autoupdate/agent/installer.go | 29 +++++++++------- lib/autoupdate/agent/installer_test.go | 46 +++++++++++++++++++++++--- lib/autoupdate/agent/updater.go | 22 +++++++++--- lib/autoupdate/agent/updater_test.go | 10 +++--- tool/teleport-update/main.go | 2 ++ 5 files changed, 83 insertions(+), 26 deletions(-) diff --git a/lib/autoupdate/agent/installer.go b/lib/autoupdate/agent/installer.go index fcc34e822abde..a25242bbc5d82 100644 --- a/lib/autoupdate/agent/installer.go +++ b/lib/autoupdate/agent/installer.go @@ -413,7 +413,7 @@ func (li *LocalInstaller) List(ctx context.Context) (revs []Revision, err error) // Link the specified version into the system LinkBinDir and CopyServiceFile. // The revert function restores the previous linking. // See Installer interface for additional specs. -func (li *LocalInstaller) Link(ctx context.Context, rev Revision) (revert func(context.Context) bool, err error) { +func (li *LocalInstaller) Link(ctx context.Context, rev Revision, force bool) (revert func(context.Context) bool, err error) { revert = func(context.Context) bool { return true } versionDir, err := li.revisionDir(rev) if err != nil { @@ -422,6 +422,7 @@ func (li *LocalInstaller) Link(ctx context.Context, rev Revision) (revert func(c revert, err = li.forceLinks(ctx, filepath.Join(versionDir, "bin"), filepath.Join(versionDir, serviceDir, serviceName), + force, ) if err != nil { return revert, trace.Wrap(err) @@ -430,10 +431,11 @@ func (li *LocalInstaller) Link(ctx context.Context, rev Revision) (revert func(c } // LinkSystem links the system (package) version into LinkBinDir and CopyServiceFile. +// LinkSystem returns ErrInvalid if LinkBinDir is not DefaultLinkDir. // The revert function restores the previous linking. // See Installer interface for additional specs. func (li *LocalInstaller) LinkSystem(ctx context.Context) (revert func(context.Context) bool, err error) { - revert, err = li.forceLinks(ctx, li.SystemBinDir, li.SystemServiceFile) + revert, err = li.forceLinks(ctx, li.SystemBinDir, li.SystemServiceFile, false) return revert, trace.Wrap(err) } @@ -453,6 +455,7 @@ func (li *LocalInstaller) TryLink(ctx context.Context, revision Revision) error // TryLinkSystem links the system installation, but only in the case that // no installation of Teleport is already linked or partially linked. +// TryLinkSystem returns ErrInvalid if LinkBinDir is not DefaultLinkDir. // See Installer interface for additional specs. func (li *LocalInstaller) TryLinkSystem(ctx context.Context) error { return trace.Wrap(li.tryLinks(ctx, li.SystemBinDir, li.SystemServiceFile)) @@ -494,7 +497,7 @@ type smallFile struct { // forceLinks will revert any overridden links or files if it hits an error. // If successful, forceLinks may also be reverted after it returns by calling revert. // The revert function returns true if reverting succeeds. -func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string) (revert func(context.Context) bool, err error) { +func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string, force bool) (revert func(context.Context) bool, err error) { // setup revert function var ( revertLinks []symlink @@ -562,7 +565,7 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string if !exec { continue } - orig, err := forceLink(oldname, newname) + orig, err := forceLink(oldname, newname, force) if err != nil && !errors.Is(err, os.ErrExist) { return revert, trace.Wrap(err, "failed to create symlink for %s", entry.Name()) } @@ -602,16 +605,18 @@ func (li *LocalInstaller) forceCopyService(dst, src string, n int64) (orig *smal } // forceLink attempts to create a symlink, atomically replacing an existing link if already present. -// If a non-symlink file or directory exists in newname already, forceLink errors. +// If a non-symlink file or directory exists in newname already, forceLink errors with ErrFilePresent. // If the link is already present with the desired oldname, forceLink returns os.ErrExist. -func forceLink(oldname, newname string) (orig string, err error) { +func forceLink(oldname, newname string, force bool) (orig string, err error) { orig, err = os.Readlink(newname) if errors.Is(err, os.ErrInvalid) || errors.Is(err, syscall.EINVAL) { // workaround missing ErrInvalid wrapper - // important: do not attempt to replace a non-linked install of Teleport - return "", trace.Errorf("refusing to replace file at %s", newname) - } - if err != nil && !errors.Is(err, os.ErrNotExist) { + if force { + return "", trace.Wrap(renameio.Symlink(oldname, newname)) + } + // important: do not attempt to replace a non-linked install of Teleport without force + return "", trace.Wrap(ErrFilePresent, "refusing to replace file at %s", newname) + } else if err != nil && !errors.Is(err, os.ErrNotExist) { return "", trace.Wrap(err) } if orig == oldname { @@ -805,14 +810,14 @@ func (li *LocalInstaller) tryLinks(ctx context.Context, binDir, svcPath string) } // needsLink returns true when a symlink from oldname to newname needs to be created, or false if it exists. -// If a non-symlink file or directory exists at newname, needsLink errors. +// If a non-symlink file or directory exists at newname, needsLink errors with ErrFilePresent. // If a symlink to a different location exists, needsLink errors with ErrLinked. func needsLink(oldname, newname string) (ok bool, err error) { orig, err := os.Readlink(newname) if errors.Is(err, os.ErrInvalid) || errors.Is(err, syscall.EINVAL) { // workaround missing ErrInvalid wrapper // important: do not attempt to replace a non-linked install of Teleport - return false, trace.Errorf("refusing to replace file at %s", newname) + return false, trace.Wrap(ErrFilePresent, "refusing to replace file at %s", newname) } if errors.Is(err, os.ErrNotExist) { return true, nil diff --git a/lib/autoupdate/agent/installer_test.go b/lib/autoupdate/agent/installer_test.go index ddc950eabcfde..fa614f4a20705 100644 --- a/lib/autoupdate/agent/installer_test.go +++ b/lib/autoupdate/agent/installer_test.go @@ -206,6 +206,7 @@ func TestLocalInstaller_Link(t *testing.T) { installFileMode os.FileMode existingLinks []string existingFiles []string + force bool resultLinks []string resultServices []string @@ -344,13 +345,50 @@ func TestLocalInstaller_Link(t *testing.T) { existingLinks: []string{ "bin/teleport", "bin/tbot", + }, + existingFiles: []string{ "lib/systemd/system/teleport.service", + "bin/tsh", + }, + + errMatch: ErrFilePresent.Error(), + }, + { + name: "overwriting bin files", + installDirs: []string{ + "bin", + "bin/somedir", + "lib", + "lib/systemd", + "lib/systemd/system", + "somedir", + }, + installFiles: []string{ + "bin/teleport", + "bin/tsh", + "bin/tbot", + servicePath, + "README", + }, + installFileMode: os.ModePerm, + existingLinks: []string{ + "bin/teleport", + "bin/tbot", }, existingFiles: []string{ + "lib/systemd/system/teleport.service", "bin/tsh", }, + force: true, - errMatch: "refusing", + resultLinks: []string{ + "bin/teleport", + "bin/tsh", + "bin/tbot", + }, + resultServices: []string{ + "lib/systemd/system/teleport.service", + }, }, { name: "no links", @@ -412,7 +450,7 @@ func TestLocalInstaller_Link(t *testing.T) { Template: autoupdate.DefaultCDNURITemplate, } ctx := context.Background() - revert, err := installer.Link(ctx, NewRevision(version, 0)) + revert, err := installer.Link(ctx, NewRevision(version, 0), tt.force) if tt.errMatch != "" { require.Error(t, err) assert.Contains(t, err.Error(), tt.errMatch) @@ -606,7 +644,7 @@ func TestLocalInstaller_TryLink(t *testing.T) { "bin/tsh", }, - errMatch: "replace file", + errMatch: ErrFilePresent.Error(), }, { name: "no links", @@ -819,7 +857,7 @@ func TestLocalInstaller_Remove(t *testing.T) { ctx := context.Background() if tt.linkedVersion != "" { - _, err = installer.Link(ctx, NewRevision(tt.linkedVersion, 0)) + _, err = installer.Link(ctx, NewRevision(tt.linkedVersion, 0), false) require.NoError(t, err) } err = installer.Remove(ctx, NewRevision(tt.removeVersion, 0)) diff --git a/lib/autoupdate/agent/updater.go b/lib/autoupdate/agent/updater.go index b558f1d6f3d58..08dddc27b285d 100644 --- a/lib/autoupdate/agent/updater.go +++ b/lib/autoupdate/agent/updater.go @@ -189,7 +189,7 @@ type Installer interface { // Link the Teleport agent at the specified revision of Teleport into the linking locations. // The revert function must restore the previous linking, returning false on any failure. // Link must be idempotent. Link's revert function must be idempotent. - Link(ctx context.Context, rev Revision) (revert func(context.Context) bool, err error) + Link(ctx context.Context, rev Revision, force bool) (revert func(context.Context) bool, err error) // LinkSystem links the system installation of Teleport into the linking locations. // The revert function must restore the previous linking, returning false on any failure. // LinkSystem must be idempotent. LinkSystem's revert function must be idempotent. @@ -225,6 +225,8 @@ var ( ErrNotSupported = errors.New("not supported on this platform") // ErrNoBinaries is returned when no binaries are available to be linked. ErrNoBinaries = errors.New("no binaries available to link") + // ErrFilePresent is returned when a file is present. + ErrFilePresent = errors.New("file present") ) const ( @@ -269,6 +271,8 @@ type OverrideConfig struct { ForceVersion string // ForceFlags in installed Teleport. ForceFlags autoupdate.InstallFlags + // AllowOverwrite of installed binaries. + AllowOverwrite bool } func deref[T any](ptr *T) T { @@ -323,7 +327,11 @@ func (u *Updater) Install(ctx context.Context, override OverrideConfig) error { u.Log.InfoContext(ctx, "Initiating installation.", targetKey, target, activeKey, active) } - if err := u.update(ctx, cfg, target); err != nil { + if err := u.update(ctx, cfg, target, override.AllowOverwrite); err != nil { + if errors.Is(err, ErrFilePresent) && !override.AllowOverwrite { + u.Log.WarnContext(ctx, "Use --overwrite to force removal of existing binaries installed via script.") + u.Log.WarnContext(ctx, "If a teleport rpm or deb package is installed, upgrade it to the latest version and retry. DO NOT USE --overwrite.") + } return trace.Wrap(err) } if target.Version == skip.Version { @@ -600,7 +608,7 @@ func (u *Updater) Update(ctx context.Context, now bool) error { time.Sleep(resp.Jitter) } - updateErr := u.update(ctx, cfg, target) + updateErr := u.update(ctx, cfg, target, false) writeErr := writeConfig(u.ConfigPath, cfg) if writeErr != nil { writeErr = trace.Wrap(writeErr, "failed to write %s", updateConfigName) @@ -652,7 +660,7 @@ func (u *Updater) find(ctx context.Context, cfg *UpdateConfig) (FindResp, error) }, nil } -func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision) error { +func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision, force bool) error { active := cfg.Status.Active backup := deref(cfg.Status.Backup) switch backup { @@ -685,7 +693,7 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision // Cleanup logic at the end of this function will ensure that they are removed // eventually. - revert, err := u.Installer.Link(ctx, target) + revert, err := u.Installer.Link(ctx, target, force) if err != nil { return trace.Wrap(err, "failed to link") } @@ -697,6 +705,10 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, target Revision if target.Version != "" { cfg.Status.Skip = toPtr(target) } + if force { + u.Log.ErrorContext(ctx, "Unable to revert Teleport symlinks in overwrite mode. Installation likely broken.") + return false + } if ok := revert(ctx); !ok { u.Log.ErrorContext(ctx, "Failed to revert Teleport symlinks. Installation likely broken.") return false diff --git a/lib/autoupdate/agent/updater_test.go b/lib/autoupdate/agent/updater_test.go index d0f36df0965b4..2faf2dbd13e31 100644 --- a/lib/autoupdate/agent/updater_test.go +++ b/lib/autoupdate/agent/updater_test.go @@ -646,7 +646,7 @@ func TestUpdater_Update(t *testing.T) { installedBaseURL = baseURL return tt.installErr }, - FuncLink: func(_ context.Context, rev Revision) (revert func(context.Context) bool, err error) { + FuncLink: func(_ context.Context, rev Revision, force bool) (revert func(context.Context) bool, err error) { linkedRevision = rev return func(_ context.Context) bool { revertFuncCalls++ @@ -1472,7 +1472,7 @@ func TestUpdater_Install(t *testing.T) { installedBaseURL = baseURL return tt.installErr }, - FuncLink: func(_ context.Context, rev Revision) (revert func(context.Context) bool, err error) { + FuncLink: func(_ context.Context, rev Revision, force bool) (revert func(context.Context) bool, err error) { linkedRevision = rev return func(_ context.Context) bool { revertFuncCalls++ @@ -1557,7 +1557,7 @@ func blankTestAddr(s []byte) []byte { type testInstaller struct { FuncInstall func(ctx context.Context, rev Revision, baseURL string) error FuncRemove func(ctx context.Context, rev Revision) error - FuncLink func(ctx context.Context, rev Revision) (revert func(context.Context) bool, err error) + FuncLink func(ctx context.Context, rev Revision, force bool) (revert func(context.Context) bool, err error) FuncLinkSystem func(ctx context.Context) (revert func(context.Context) bool, err error) FuncTryLink func(ctx context.Context, rev Revision) error FuncTryLinkSystem func(ctx context.Context) error @@ -1574,8 +1574,8 @@ func (ti *testInstaller) Remove(ctx context.Context, rev Revision) error { return ti.FuncRemove(ctx, rev) } -func (ti *testInstaller) Link(ctx context.Context, rev Revision) (revert func(context.Context) bool, err error) { - return ti.FuncLink(ctx, rev) +func (ti *testInstaller) Link(ctx context.Context, rev Revision, force bool) (revert func(context.Context) bool, err error) { + return ti.FuncLink(ctx, rev, force) } func (ti *testInstaller) LinkSystem(ctx context.Context) (revert func(context.Context) bool, err error) { diff --git a/tool/teleport-update/main.go b/tool/teleport-update/main.go index 6bcb1deb9d1f0..fb0104012bc52 100644 --- a/tool/teleport-update/main.go +++ b/tool/teleport-update/main.go @@ -115,6 +115,8 @@ func Run(args []string) int { Short('g').Envar(updateGroupEnvVar).StringVar(&ccfg.Group) enableCmd.Flag("base-url", "Base URL used to override the Teleport download URL."). Short('b').Envar(common.BaseURLEnvVar).StringVar(&ccfg.BaseURL) + enableCmd.Flag("overwrite", "Allow existing installed Teleport binaries to be overwritten."). + Short('o').BoolVar(&ccfg.AllowOverwrite) enableCmd.Flag("force-version", "Force the provided version instead of using the version provided by the Teleport cluster."). Short('f').Envar(updateVersionEnvVar).Hidden().StringVar(&ccfg.ForceVersion) enableCmd.Flag("self-setup", "Use the current teleport-update binary to create systemd service config for auto-updates."). From 9c5f8f7481be27d1e20bc4ce41cb5f3b591ad13a Mon Sep 17 00:00:00 2001 From: Noah Stride Date: Thu, 30 Jan 2025 13:28:07 +0000 Subject: [PATCH 10/28] Track usage by BotInstanceID (#51540) * Add BotInstanceActivitySupport to usage reporting * Wire BotInstanceActivityReport into submitter * Share userActivityLock * Add test for bot instance * TestBotInstanceActivityReportSplitting * Use 15minute interval rather than hourly * Switch to compound key for botInstanceActivity map * ADjust lolck name --- gen/proto/go/prehog/v1/teleport.pb.go | 400 ++- gen/proto/go/prehog/v1alpha/teleport.pb.go | 3014 +++++++++-------- gen/proto/ts/prehog/v1/teleport_pb.ts | 265 +- gen/proto/ts/prehog/v1alpha/teleport_pb.ts | 50 +- lib/auth/auth.go | 1 + .../teleport/aggregating/reporter.go | 109 +- .../teleport/aggregating/reporter_test.go | 111 + .../teleport/aggregating/service.go | 125 +- .../teleport/aggregating/service_test.go | 31 +- .../teleport/aggregating/submitter.go | 36 +- lib/usagereporter/teleport/audit.go | 14 +- lib/usagereporter/teleport/types.go | 45 +- proto/prehog/v1/teleport.proto | 53 + proto/prehog/v1alpha/teleport.proto | 10 + 14 files changed, 2645 insertions(+), 1619 deletions(-) diff --git a/gen/proto/go/prehog/v1/teleport.pb.go b/gen/proto/go/prehog/v1/teleport.pb.go index 2c69caaa5da06..7ccaf3202682b 100644 --- a/gen/proto/go/prehog/v1/teleport.pb.go +++ b/gen/proto/go/prehog/v1/teleport.pb.go @@ -616,6 +616,188 @@ func (x *ResourceKindPresenceReport) GetResourceIds() []uint64 { return nil } +// counters for bot instance activity coming from a specific auth server from a +// specific cluster. +// +// PostHog event: tp.bot_instance.activity +type BotInstanceActivityReport struct { + state protoimpl.MessageState `protogen:"open.v1"` + // randomly generated UUID for this specific report, 16 bytes (in string order) + // + // PostHog property: tp.report_uuid (in 8-4-4-4-12 string form) + ReportUuid []byte `protobuf:"bytes,1,opt,name=report_uuid,json=reportUuid,proto3" json:"report_uuid,omitempty"` + // cluster name, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.cluster_name (in base64) + ClusterName []byte `protobuf:"bytes,2,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` + // hostid of the auth that collected this report, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.reporter_hostid (in base64) + ReporterHostid []byte `protobuf:"bytes,3,opt,name=reporter_hostid,json=reporterHostid,proto3" json:"reporter_hostid,omitempty"` + // beginning of the time window for this data; ending is not specified but is + // intended to be at most 15 minutes + // + // PostHog timestamp (not a property, the ingest time is tp.report_time instead) + StartTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + // one set of counters for each bot instance + // + // PostHog property: tp.records (encoded as a map keyed by anonymized bot + // instance id, not as a list) + Records []*BotInstanceActivityRecord `protobuf:"bytes,5,rep,name=records,proto3" json:"records,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BotInstanceActivityReport) Reset() { + *x = BotInstanceActivityReport{} + mi := &file_prehog_v1_teleport_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BotInstanceActivityReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BotInstanceActivityReport) ProtoMessage() {} + +func (x *BotInstanceActivityReport) ProtoReflect() protoreflect.Message { + mi := &file_prehog_v1_teleport_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 BotInstanceActivityReport.ProtoReflect.Descriptor instead. +func (*BotInstanceActivityReport) Descriptor() ([]byte, []int) { + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{4} +} + +func (x *BotInstanceActivityReport) GetReportUuid() []byte { + if x != nil { + return x.ReportUuid + } + return nil +} + +func (x *BotInstanceActivityReport) GetClusterName() []byte { + if x != nil { + return x.ClusterName + } + return nil +} + +func (x *BotInstanceActivityReport) GetReporterHostid() []byte { + if x != nil { + return x.ReporterHostid + } + return nil +} + +func (x *BotInstanceActivityReport) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *BotInstanceActivityReport) GetRecords() []*BotInstanceActivityRecord { + if x != nil { + return x.Records + } + return nil +} + +// Records the activity for a single bot instance against a specific auth server +// from a specific cluster. +type BotInstanceActivityRecord struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The UUID of the BotInstance, anonymized using HMAC-SHA-256. + BotInstanceId []byte `protobuf:"bytes,1,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` + // The name of the user associated with the BotInstance, + // anonymized using HMAC-SHA-256. + // Enables correlation with the UserActivityRecord for the Bot. + BotUserName []byte `protobuf:"bytes,2,opt,name=bot_user_name,json=botUserName,proto3" json:"bot_user_name,omitempty"` + // counter of bot joins + BotJoins uint64 `protobuf:"varint,3,opt,name=bot_joins,json=botJoins,proto3" json:"bot_joins,omitempty"` + // counter of SPIFFE SVIDs issued + SpiffeSvidsIssued uint64 `protobuf:"varint,4,opt,name=spiffe_svids_issued,json=spiffeSvidsIssued,proto3" json:"spiffe_svids_issued,omitempty"` + // counter of certificates issued for this user + CertificatesIssued uint64 `protobuf:"varint,5,opt,name=certificates_issued,json=certificatesIssued,proto3" json:"certificates_issued,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BotInstanceActivityRecord) Reset() { + *x = BotInstanceActivityRecord{} + mi := &file_prehog_v1_teleport_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BotInstanceActivityRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BotInstanceActivityRecord) ProtoMessage() {} + +func (x *BotInstanceActivityRecord) ProtoReflect() protoreflect.Message { + mi := &file_prehog_v1_teleport_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 BotInstanceActivityRecord.ProtoReflect.Descriptor instead. +func (*BotInstanceActivityRecord) Descriptor() ([]byte, []int) { + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{5} +} + +func (x *BotInstanceActivityRecord) GetBotInstanceId() []byte { + if x != nil { + return x.BotInstanceId + } + return nil +} + +func (x *BotInstanceActivityRecord) GetBotUserName() []byte { + if x != nil { + return x.BotUserName + } + return nil +} + +func (x *BotInstanceActivityRecord) GetBotJoins() uint64 { + if x != nil { + return x.BotJoins + } + return 0 +} + +func (x *BotInstanceActivityRecord) GetSpiffeSvidsIssued() uint64 { + if x != nil { + return x.SpiffeSvidsIssued + } + return 0 +} + +func (x *BotInstanceActivityRecord) GetCertificatesIssued() uint64 { + if x != nil { + return x.CertificatesIssued + } + return 0 +} + type SubmitUsageReportsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // at most 10 reports of all kinds in a single RPC, each shouldn't exceed 128KiB or so @@ -624,13 +806,15 @@ type SubmitUsageReportsRequest struct { UserActivity []*UserActivityReport `protobuf:"bytes,1,rep,name=user_activity,json=userActivity,proto3" json:"user_activity,omitempty"` // encoded as a separate tp.resource.counts PostHog event ResourcePresence []*ResourcePresenceReport `protobuf:"bytes,2,rep,name=resource_presence,json=resourcePresence,proto3" json:"resource_presence,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // encoded as a seperate tp.bot_instance.activity PostHog event + BotInstanceActivity []*BotInstanceActivityReport `protobuf:"bytes,3,rep,name=bot_instance_activity,json=botInstanceActivity,proto3" json:"bot_instance_activity,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SubmitUsageReportsRequest) Reset() { *x = SubmitUsageReportsRequest{} - mi := &file_prehog_v1_teleport_proto_msgTypes[4] + mi := &file_prehog_v1_teleport_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -642,7 +826,7 @@ func (x *SubmitUsageReportsRequest) String() string { func (*SubmitUsageReportsRequest) ProtoMessage() {} func (x *SubmitUsageReportsRequest) ProtoReflect() protoreflect.Message { - mi := &file_prehog_v1_teleport_proto_msgTypes[4] + mi := &file_prehog_v1_teleport_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -655,7 +839,7 @@ func (x *SubmitUsageReportsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitUsageReportsRequest.ProtoReflect.Descriptor instead. func (*SubmitUsageReportsRequest) Descriptor() ([]byte, []int) { - return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{4} + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{6} } func (x *SubmitUsageReportsRequest) GetUserActivity() []*UserActivityReport { @@ -672,6 +856,13 @@ func (x *SubmitUsageReportsRequest) GetResourcePresence() []*ResourcePresenceRep return nil } +func (x *SubmitUsageReportsRequest) GetBotInstanceActivity() []*BotInstanceActivityReport { + if x != nil { + return x.BotInstanceActivity + } + return nil +} + type SubmitUsageReportsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // randomly generated UUID for this specific batch, 16 bytes (in string order) @@ -684,7 +875,7 @@ type SubmitUsageReportsResponse struct { func (x *SubmitUsageReportsResponse) Reset() { *x = SubmitUsageReportsResponse{} - mi := &file_prehog_v1_teleport_proto_msgTypes[5] + mi := &file_prehog_v1_teleport_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -696,7 +887,7 @@ func (x *SubmitUsageReportsResponse) String() string { func (*SubmitUsageReportsResponse) ProtoMessage() {} func (x *SubmitUsageReportsResponse) ProtoReflect() protoreflect.Message { - mi := &file_prehog_v1_teleport_proto_msgTypes[5] + mi := &file_prehog_v1_teleport_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -709,7 +900,7 @@ func (x *SubmitUsageReportsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitUsageReportsResponse.ProtoReflect.Descriptor instead. func (*SubmitUsageReportsResponse) Descriptor() ([]byte, []int) { - return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{5} + return file_prehog_v1_teleport_proto_rawDescGZIP(), []int{7} } func (x *SubmitUsageReportsResponse) GetBatchUuid() []byte { @@ -810,63 +1001,99 @@ var file_prehog_v1_teleport_proto_rawDesc = string([]byte{ 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x06, - 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0xaf, 0x01, - 0x0a, 0x19, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0d, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, - 0x4e, 0x0a, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x73, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, - 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x10, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x22, - 0x3b, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x55, 0x75, 0x69, 0x64, 0x2a, 0x4d, 0x0a, 0x08, - 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, + 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0x83, 0x02, + 0x0a, 0x19, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x75, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x73, 0x74, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x2e, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x19, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6f, 0x74, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x62, 0x6f, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x62, 0x6f, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x62, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x70, + 0x69, 0x66, 0x66, 0x65, 0x5f, 0x73, 0x76, 0x69, 0x64, 0x73, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x53, + 0x76, 0x69, 0x64, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x73, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x22, 0x89, 0x02, 0x0a, 0x19, + 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0d, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x0c, 0x75, 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x4e, 0x0a, + 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, + 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x10, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x58, 0x0a, + 0x15, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x13, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x22, 0x3b, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x75, + 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x55, 0x75, 0x69, 0x64, 0x2a, 0x4d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, + 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x48, 0x55, 0x4d, 0x41, 0x4e, 0x10, 0x01, + 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x42, 0x4f, + 0x54, 0x10, 0x02, 0x2a, 0x87, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x48, 0x55, 0x4d, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x42, 0x4f, 0x54, 0x10, 0x02, 0x2a, 0x87, 0x02, 0x0a, 0x0c, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, - 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, - 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, - 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x03, - 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x21, 0x0a, - 0x1d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x57, - 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x05, - 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x10, 0x06, - 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x5f, 0x45, - 0x49, 0x43, 0x45, 0x10, 0x07, 0x32, 0x7f, 0x0a, 0x18, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x63, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, - 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xa6, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 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, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, - 0x58, 0x58, 0xaa, 0x02, 0x09, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, - 0x09, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x15, 0x50, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0a, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, + 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, + 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x5f, + 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, + 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, + 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, + 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x5f, 0x45, 0x49, 0x43, 0x45, 0x10, 0x07, 0x32, 0x7f, 0x0a, + 0x18, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x12, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, + 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, + 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xa6, + 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x41, 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, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x50, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x09, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x15, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0a, 0x50, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( @@ -882,7 +1109,7 @@ func file_prehog_v1_teleport_proto_rawDescGZIP() []byte { } var file_prehog_v1_teleport_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_prehog_v1_teleport_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_prehog_v1_teleport_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_prehog_v1_teleport_proto_goTypes = []any{ (UserKind)(0), // 0: prehog.v1.UserKind (ResourceKind)(0), // 1: prehog.v1.ResourceKind @@ -890,26 +1117,31 @@ var file_prehog_v1_teleport_proto_goTypes = []any{ (*UserActivityRecord)(nil), // 3: prehog.v1.UserActivityRecord (*ResourcePresenceReport)(nil), // 4: prehog.v1.ResourcePresenceReport (*ResourceKindPresenceReport)(nil), // 5: prehog.v1.ResourceKindPresenceReport - (*SubmitUsageReportsRequest)(nil), // 6: prehog.v1.SubmitUsageReportsRequest - (*SubmitUsageReportsResponse)(nil), // 7: prehog.v1.SubmitUsageReportsResponse - (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp + (*BotInstanceActivityReport)(nil), // 6: prehog.v1.BotInstanceActivityReport + (*BotInstanceActivityRecord)(nil), // 7: prehog.v1.BotInstanceActivityRecord + (*SubmitUsageReportsRequest)(nil), // 8: prehog.v1.SubmitUsageReportsRequest + (*SubmitUsageReportsResponse)(nil), // 9: prehog.v1.SubmitUsageReportsResponse + (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp } var file_prehog_v1_teleport_proto_depIdxs = []int32{ - 8, // 0: prehog.v1.UserActivityReport.start_time:type_name -> google.protobuf.Timestamp - 3, // 1: prehog.v1.UserActivityReport.records:type_name -> prehog.v1.UserActivityRecord - 0, // 2: prehog.v1.UserActivityRecord.user_kind:type_name -> prehog.v1.UserKind - 8, // 3: prehog.v1.ResourcePresenceReport.start_time:type_name -> google.protobuf.Timestamp - 5, // 4: prehog.v1.ResourcePresenceReport.resource_kind_reports:type_name -> prehog.v1.ResourceKindPresenceReport - 1, // 5: prehog.v1.ResourceKindPresenceReport.resource_kind:type_name -> prehog.v1.ResourceKind - 2, // 6: prehog.v1.SubmitUsageReportsRequest.user_activity:type_name -> prehog.v1.UserActivityReport - 4, // 7: prehog.v1.SubmitUsageReportsRequest.resource_presence:type_name -> prehog.v1.ResourcePresenceReport - 6, // 8: prehog.v1.TeleportReportingService.SubmitUsageReports:input_type -> prehog.v1.SubmitUsageReportsRequest - 7, // 9: prehog.v1.TeleportReportingService.SubmitUsageReports:output_type -> prehog.v1.SubmitUsageReportsResponse - 9, // [9:10] is the sub-list for method output_type - 8, // [8:9] 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 + 10, // 0: prehog.v1.UserActivityReport.start_time:type_name -> google.protobuf.Timestamp + 3, // 1: prehog.v1.UserActivityReport.records:type_name -> prehog.v1.UserActivityRecord + 0, // 2: prehog.v1.UserActivityRecord.user_kind:type_name -> prehog.v1.UserKind + 10, // 3: prehog.v1.ResourcePresenceReport.start_time:type_name -> google.protobuf.Timestamp + 5, // 4: prehog.v1.ResourcePresenceReport.resource_kind_reports:type_name -> prehog.v1.ResourceKindPresenceReport + 1, // 5: prehog.v1.ResourceKindPresenceReport.resource_kind:type_name -> prehog.v1.ResourceKind + 10, // 6: prehog.v1.BotInstanceActivityReport.start_time:type_name -> google.protobuf.Timestamp + 7, // 7: prehog.v1.BotInstanceActivityReport.records:type_name -> prehog.v1.BotInstanceActivityRecord + 2, // 8: prehog.v1.SubmitUsageReportsRequest.user_activity:type_name -> prehog.v1.UserActivityReport + 4, // 9: prehog.v1.SubmitUsageReportsRequest.resource_presence:type_name -> prehog.v1.ResourcePresenceReport + 6, // 10: prehog.v1.SubmitUsageReportsRequest.bot_instance_activity:type_name -> prehog.v1.BotInstanceActivityReport + 8, // 11: prehog.v1.TeleportReportingService.SubmitUsageReports:input_type -> prehog.v1.SubmitUsageReportsRequest + 9, // 12: prehog.v1.TeleportReportingService.SubmitUsageReports:output_type -> prehog.v1.SubmitUsageReportsResponse + 12, // [12:13] is the sub-list for method output_type + 11, // [11:12] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_prehog_v1_teleport_proto_init() } @@ -923,7 +1155,7 @@ func file_prehog_v1_teleport_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_prehog_v1_teleport_proto_rawDesc), len(file_prehog_v1_teleport_proto_rawDesc)), NumEnums: 2, - NumMessages: 6, + NumMessages: 8, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/proto/go/prehog/v1alpha/teleport.pb.go b/gen/proto/go/prehog/v1alpha/teleport.pb.go index 1221c8345eac8..36a5f82ab0db7 100644 --- a/gen/proto/go/prehog/v1alpha/teleport.pb.go +++ b/gen/proto/go/prehog/v1alpha/teleport.pb.go @@ -1886,8 +1886,11 @@ type UserCertificateIssuedEvent struct { UsageDesktop bool `protobuf:"varint,7,opt,name=usage_desktop,json=usageDesktop,proto3" json:"usage_desktop,omitempty"` // the private key policy associated with these user certificates. PrivateKeyPolicy string `protobuf:"bytes,8,opt,name=private_key_policy,json=privateKeyPolicy,proto3" json:"private_key_policy,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + BotInstanceId string `protobuf:"bytes,9,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UserCertificateIssuedEvent) Reset() { @@ -1976,6 +1979,13 @@ func (x *UserCertificateIssuedEvent) GetPrivateKeyPolicy() string { return "" } +func (x *UserCertificateIssuedEvent) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + // the issuance of a SPIFFE SVID // // PostHog event: tp.spiffe.svid.issued @@ -2001,7 +2011,10 @@ type SPIFFESVIDIssuedEvent struct { DnsSansCount int32 `protobuf:"varint,5,opt,name=dns_sans_count,json=dnsSansCount,proto3" json:"dns_sans_count,omitempty"` // Type of SVID issued. `x509` or `jwt` // PostHog property: tp.spiffe.svid_type - SvidType string `protobuf:"bytes,6,opt,name=svid_type,json=svidType,proto3" json:"svid_type,omitempty"` + SvidType string `protobuf:"bytes,6,opt,name=svid_type,json=svidType,proto3" json:"svid_type,omitempty"` + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + BotInstanceId string `protobuf:"bytes,7,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2078,6 +2091,13 @@ func (x *SPIFFESVIDIssuedEvent) GetSvidType() string { return "" } +func (x *SPIFFESVIDIssuedEvent) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + // UIBannerClickEvent is a usage event sent by the UI when the upgrade // banner is clicked. type UIBannerClickEvent struct { @@ -4166,7 +4186,9 @@ type BotJoinEvent struct { // the cluster. JoinTokenName string `protobuf:"bytes,3,opt,name=join_token_name,json=joinTokenName,proto3" json:"join_token_name,omitempty"` // user_name is the anonymised name of the Bot user. - UserName string `protobuf:"bytes,4,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + UserName string `protobuf:"bytes,4,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + // bot_instance_id is the anonymized instance id of the bot. + BotInstanceId string `protobuf:"bytes,5,opt,name=bot_instance_id,json=botInstanceId,proto3" json:"bot_instance_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4229,6 +4251,13 @@ func (x *BotJoinEvent) GetUserName() string { return "" } +func (x *BotJoinEvent) GetBotInstanceId() string { + if x != nil { + return x.BotInstanceId + } + return "" +} + // UICreateNewRoleClickEvent is an event that can be triggered during custom role creation type UICreateNewRoleClickEvent struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -9618,7 +9647,7 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = string([]byte{ 0x0a, 0x17, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x41, 0x70, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xbf, 0x02, + 0x52, 0x0b, 0x69, 0x73, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xe7, 0x02, 0x0a, 0x1a, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -9638,23 +9667,28 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = string([]byte{ 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, - 0xef, 0x01, 0x0a, 0x15, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, 0x73, - 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, - 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, - 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x70, - 0x5f, 0x73, 0x61, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0b, 0x69, 0x70, 0x53, 0x61, 0x6e, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, - 0x0a, 0x0e, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x61, 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x64, 0x6e, 0x73, 0x53, 0x61, 0x6e, 0x73, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x76, 0x69, 0x64, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x76, 0x69, 0x64, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x47, 0x0a, 0x12, 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x97, 0x02, 0x0a, 0x15, 0x53, 0x50, 0x49, 0x46, + 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, + 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x70, 0x5f, 0x73, 0x61, 0x6e, 0x73, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x69, 0x70, 0x53, 0x61, 0x6e, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x61, + 0x6e, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, + 0x64, 0x6e, 0x73, 0x53, 0x61, 0x6e, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x76, 0x69, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x76, 0x69, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, + 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x22, 0x47, 0x0a, 0x12, 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, @@ -10065,7 +10099,7 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = string([]byte{ 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6a, 0x6f, 0x69, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, - 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x0c, 0x42, 0x6f, 0x74, 0x4a, 0x6f, + 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x0c, 0x42, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, @@ -10074,1520 +10108,1522 @@ var file_prehog_v1alpha_teleport_proto_rawDesc = string([]byte{ 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x55, 0x49, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x1d, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, - 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x3e, 0x0a, 0x1f, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, - 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x49, 0x0a, 0x2a, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, - 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x5e, 0x0a, 0x18, 0x55, - 0x49, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, - 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, 0x63, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x43, 0x54, 0x41, 0x52, 0x03, 0x63, 0x74, 0x61, 0x22, 0x66, 0x0a, 0x10, 0x4b, - 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6f, 0x74, 0x5f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x62, 0x6f, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x22, 0x38, 0x0a, 0x19, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, + 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x1d, 0x55, 0x49, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, + 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x0a, 0x1f, 0x55, 0x49, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x49, 0x0a, 0x2a, 0x55, 0x49, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, + 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x5e, 0x0a, 0x18, 0x55, 0x49, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, - 0x69, 0x6e, 0x64, 0x22, 0x77, 0x0a, 0x09, 0x53, 0x46, 0x54, 0x50, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, + 0x63, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x43, 0x54, 0x41, 0x52, 0x03, + 0x63, 0x74, 0x61, 0x22, 0x66, 0x0a, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, + 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x77, 0x0a, 0x09, 0x53, + 0x46, 0x54, 0x50, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xcb, 0x03, 0x0a, 0x12, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x68, 0x6f, 0x73, + 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x68, 0x6f, 0x73, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, + 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x6c, 0x69, 0x62, 0x63, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, + 0x6c, 0x69, 0x62, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x12, 0x35, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, + 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x72, 0x63, 0x68, + 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x5f, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, + 0x65, 0x72, 0x22, 0xd2, 0x01, 0x0a, 0x15, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, + 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xf0, 0x01, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x69, + 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6b, 0x69, - 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, - 0x6e, 0x64, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xcb, 0x03, 0x0a, - 0x12, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, - 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x6f, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, - 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x68, 0x6f, - 0x73, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x67, 0x6c, 0x69, 0x62, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x6c, 0x69, 0x62, 0x63, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x11, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x16, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, - 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x72, 0x22, 0xd2, 0x01, 0x0a, 0x15, 0x41, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, - 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, - 0xf0, 0x01, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, + 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x55, 0x0a, 0x1a, 0x41, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x22, 0x55, 0x0a, 0x1a, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x18, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x11, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x24, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x15, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x18, 0x41, 0x73, - 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xbd, 0x01, - 0x0a, 0x11, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x24, 0x0a, - 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x74, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9b, 0x01, + 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, + 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0xa4, 0x02, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, + 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x6f, + 0x6c, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x72, + 0x61, 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x12, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x1d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1a, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x6c, + 0x65, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, + 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x1b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, + 0x64, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x22, 0xaf, + 0x03, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x19, 0x64, + 0x61, 0x79, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, + 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, + 0x64, 0x61, 0x79, 0x73, 0x50, 0x61, 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x38, 0x0a, + 0x18, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x16, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x72, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x39, 0x0a, 0x19, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, + 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x16, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x4f, 0x66, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x22, 0xad, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, + 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x49, 0x64, + 0x22, 0x88, 0x01, 0x0a, 0x1f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, + 0x74, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, + 0x74, 0x73, 0x5f, 0x6e, 0x65, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x73, 0x4e, 0x65, 0x65, 0x64, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x22, 0x83, 0x01, 0x0a, 0x19, + 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x66, 0x0a, 0x1d, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x69, 0x0a, 0x20, 0x55, 0x49, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x1b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x3f, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xe5, 0x01, 0x0a, 0x1c, 0x55, + 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x39, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x43, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x6c, 0x0a, 0x11, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x79, 0x0a, 0x17, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x11, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0xdd, 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, - 0x69, 0x6e, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x07, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x6f, 0x0a, 0x1d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x1b, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, 0x0a, 0x11, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, + 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0d, 0x6c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x52, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x7a, + 0x0a, 0x1a, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, + 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x4e, 0x0a, 0x15, 0x44, 0x65, + 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x0a, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x14, 0x54, + 0x41, 0x47, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, - 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, - 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1f, - 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x22, - 0xa4, 0x02, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, - 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x41, - 0x0a, 0x1d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, - 0x64, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65, - 0x72, 0x69, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, - 0x64, 0x12, 0x43, 0x0a, 0x1e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, - 0x69, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1b, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x69, 0x74, 0x73, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x22, 0xaf, 0x03, 0x0a, 0x1b, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x19, 0x64, 0x61, 0x79, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x74, - 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x64, 0x61, 0x79, 0x73, 0x50, 0x61, 0x73, 0x74, - 0x4e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, - 0x1f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, - 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, - 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x3c, 0x0a, 0x1b, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, - 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, - 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x39, 0x0a, - 0x19, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x16, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4f, 0x66, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x1b, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x49, 0x64, 0x22, 0x88, 0x01, 0x0a, 0x1f, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x5f, 0x6e, 0x65, 0x65, 0x64, 0x5f, - 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4e, 0x65, 0x65, 0x64, 0x52, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x22, 0x83, 0x01, 0x0a, 0x19, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x39, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x66, 0x0a, 0x1d, 0x55, 0x49, 0x49, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x22, 0x69, 0x0a, 0x20, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x74, 0x0a, 0x1b, - 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3f, 0x0a, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0xe5, 0x01, 0x0a, 0x1c, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x04, 0x73, 0x74, - 0x65, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x52, - 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x6c, 0x0a, 0x11, 0x45, 0x64, - 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, - 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x79, 0x0a, 0x17, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, - 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0xdd, - 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x66, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x52, 0x07, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x6f, 0x0a, - 0x1d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x1b, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, - 0x0a, 0x11, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0d, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, - 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, - 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x7a, 0x0a, 0x1a, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, - 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, - 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x4e, 0x0a, 0x15, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, - 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, - 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, - 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x63, 0x0a, 0x29, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, - 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, - 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x8d, - 0x01, 0x0a, 0x29, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x87, - 0x01, 0x0a, 0x1a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, - 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, - 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0xe8, 0x03, 0x0a, 0x17, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x57, 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x63, - 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x63, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x45, 0x6b, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, - 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x52, 0x64, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x28, - 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x33, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, - 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, - 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x61, 0x6d, - 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, - 0x69, 0x64, 0x63, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x21, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x24, 0x55, 0x49, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, - 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, - 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x22, 0x0a, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x27, 0x0a, 0x25, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, - 0x63, 0x0a, 0x1c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, - 0x64, 0x61, 0x79, 0x73, 0x22, 0x64, 0x0a, 0x12, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x61, 0x0a, 0x13, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x75, 0x64, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x02, - 0x0a, 0x17, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, - 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x41, 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6e, 0x75, - 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, - 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x07, 0x6e, 0x75, 0x6d, 0x41, 0x70, 0x70, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, - 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x72, - 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x52, - 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, - 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x35, - 0x0a, 0x17, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x14, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x18, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, - 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, - 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0xe0, 0x01, 0x0a, 0x22, 0x44, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, - 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x14, 0x6e, 0x75, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x75, 0x0a, 0x1b, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0xa7, 0x50, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, - 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x73, 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x53, 0x4f, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x73, 0x73, 0x6f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x4e, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x4c, 0x0a, - 0x0f, 0x75, 0x69, 0x5f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x69, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, 0x0a, 0x29, - 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x5f, 0x67, 0x6f, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x47, 0x6f, 0x54, 0x6f, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, - 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, 0x69, 0x4f, - 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x6f, - 0x54, 0x6f, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6c, 0x69, 0x63, 0x6b, - 0x12, 0x82, 0x01, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, - 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, + 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, + 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x63, 0x0a, 0x29, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x17, + 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x29, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, + 0x6e, 0x53, 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x73, + 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x73, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x1a, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x22, 0xe8, 0x03, 0x0a, 0x17, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x41, 0x57, 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x63, 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x45, 0x63, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x6f, 0x6c, 0x65, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x6b, 0x73, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x72, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x64, 0x73, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x73, 0x33, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x33, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, + 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x61, 0x6d, 0x6c, 0x5f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x61, 0x6d, 0x6c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6f, 0x69, 0x64, 0x63, + 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4f, 0x69, 0x64, 0x63, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x21, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x96, 0x01, 0x0a, 0x24, 0x55, 0x49, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x44, 0x69, 0x66, + 0x66, 0x56, 0x69, 0x65, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x22, 0x0a, 0x20, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, + 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x27, + 0x0a, 0x25, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x63, 0x0a, 0x1c, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x61, 0x79, 0x73, 0x22, 0x64, 0x0a, 0x12, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, + 0x61, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x22, 0x61, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, + 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, + 0x75, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x02, 0x0a, 0x17, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x41, + 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x75, 0x6d, + 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6e, 0x75, 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x70, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6e, 0x75, 0x6d, 0x41, 0x70, 0x70, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x10, + 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x17, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x9e, 0x01, + 0x0a, 0x18, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0xe0, + 0x01, 0x0a, 0x22, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x6e, + 0x75, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x6e, 0x75, 0x6d, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x75, 0x0a, 0x1b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x55, 0x73, 0x65, + 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x69, 0x73, 0x73, 0x75, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa7, 0x50, 0x0a, 0x12, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x29, + 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x5f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x73, + 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, - 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, - 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, - 0x69, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, - 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4c, 0x61, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, - 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x72, 0x65, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x53, - 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x87, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x6f, - 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, - 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, + 0x53, 0x53, 0x4f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x09, 0x73, 0x73, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x4e, 0x0a, 0x0f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x0d, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x4c, 0x0a, 0x0f, 0x75, 0x69, 0x5f, 0x62, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x69, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, + 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x67, 0x6f, 0x5f, 0x74, + 0x6f, 0x5f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x6f, 0x54, 0x6f, 0x44, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x6f, 0x54, 0x6f, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x82, 0x01, 0x0a, 0x23, 0x75, 0x69, 0x5f, + 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, - 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x20, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, - 0x74, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, - 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, - 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, - 0x69, 0x6e, 0x75, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x1c, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x6f, - 0x0a, 0x1c, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x70, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, - 0x72, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, 0x69, 0x63, - 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x19, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, - 0x69, 0x63, 0x6b, 0x12, 0x63, 0x0a, 0x19, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x16, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6f, 0x0a, - 0x1d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x13, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x1a, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x4d, - 0x0a, 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, - 0x76, 0x32, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x56, 0x32, 0x12, 0x76, 0x0a, - 0x20, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7f, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x8f, 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, + 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, + 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x92, 0x01, + 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x64, 0x64, + 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x6c, 0x61, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, + 0x69, 0x72, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x74, 0x65, + 0x72, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x23, 0x75, + 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x41, 0x64, 0x64, 0x46, 0x69, 0x72, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x69, + 0x63, 0x6b, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, + 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, + 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x74, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, + 0x87, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x7b, 0x0a, 0x20, 0x75, 0x69, 0x5f, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, + 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x43, 0x6c, 0x69, 0x63, + 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x6f, 0x0a, 0x1c, 0x75, 0x69, 0x5f, 0x72, 0x65, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x79, + 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, + 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x70, + 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, + 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, + 0x70, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x72, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x72, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x50, + 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x19, 0x75, 0x69, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, + 0x73, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x63, 0x0a, 0x19, 0x75, + 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6f, 0x0a, 0x1d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, + 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x75, 0x73, 0x65, 0x72, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x49, 0x73, 0x73, 0x75, 0x65, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x76, 0x32, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x56, 0x32, 0x12, 0x76, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7f, 0x0a, + 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x4d, 0x54, 0x4c, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x24, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x8f, + 0x01, 0x0a, 0x29, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x65, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x4d, - 0x74, 0x6c, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0xb8, 0x01, 0x0a, 0x38, 0x75, 0x69, 0x5f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, - 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x6f, - 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x31, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, - 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0xae, 0x01, 0x0a, 0x34, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x2e, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x95, 0x01, 0x0a, 0x2b, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x70, 0x72, 0x65, + 0x54, 0x4c, 0x53, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x75, 0x69, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x4d, 0x74, 0x6c, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0xb8, 0x01, 0x0a, 0x38, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, + 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x31, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0xae, 0x01, 0x0a, 0x34, + 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x6b, + 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x41, 0x75, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x26, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x41, 0x75, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x9f, 0x01, 0x0a, - 0x2f, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, - 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x65, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x29, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, - 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x88, - 0x01, 0x0a, 0x26, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x70, - 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, - 0x69, 0x70, 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x22, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x79, 0x0a, 0x21, 0x75, 0x69, 0x5f, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x69, 0x0a, 0x1b, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x42, 0x0a, 0x0b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x1f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x63, 0x0a, 0x18, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, - 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, - 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, - 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x70, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x73, - 0x61, 0x76, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, - 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x18, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, - 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x76, 0x0a, 0x1f, 0x75, 0x69, - 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, - 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x22, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, - 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, - 0x63, 0x6b, 0x12, 0x98, 0x01, 0x0a, 0x2b, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, - 0x63, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x25, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x45, 0x0a, - 0x0c, 0x6b, 0x75, 0x62, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x24, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x66, 0x74, 0x70, 0x18, 0x25, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x53, 0x46, 0x54, 0x50, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x04, 0x73, 0x66, 0x74, 0x70, 0x12, 0x56, 0x0a, 0x14, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x26, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x57, 0x0a, - 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, - 0x65, 0x61, 0x74, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, - 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x9c, 0x01, 0x0a, 0x2e, 0x75, 0x69, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x57, 0x53, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x28, 0x75, 0x69, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x41, 0x77, 0x73, 0x4f, 0x69, 0x64, 0x63, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x83, 0x01, 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, - 0x64, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, - 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x44, 0x53, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x64, 0x73, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6b, 0x0a, 0x1d, 0x75, - 0x69, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, - 0x75, 0x69, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, - 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x54, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, - 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2b, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x73, - 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x79, - 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x75, 0x69, 0x49, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, - 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, - 0x0a, 0x13, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x69, - 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x11, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x62, 0x6f, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x42, 0x6f, 0x74, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x74, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x12, 0x7a, 0x0a, 0x1f, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, - 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x2e, 0x75, 0x69, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x95, 0x01, 0x0a, + 0x2b, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x75, 0x74, + 0x6f, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x41, 0x75, + 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x26, 0x75, 0x69, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x41, 0x75, 0x74, 0x6f, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x9f, 0x01, 0x0a, 0x2f, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x49, 0x41, 0x4d, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x29, 0x75, 0x69, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x88, 0x01, 0x0a, 0x26, 0x75, 0x69, 0x5f, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, + 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x22, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, + 0x61, 0x6c, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x79, 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x5f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1d, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x69, 0x0a, 0x1b, + 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, + 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x0b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x6f, + 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0a, 0x72, 0x6f, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x63, 0x0a, 0x18, 0x75, + 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, - 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, - 0x6e, 0x61, 0x69, 0x72, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x51, 0x75, 0x65, - 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x12, 0x39, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x31, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x42, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x51, 0x0a, 0x10, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x64, - 0x0a, 0x17, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x19, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x17, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x6e, 0x0a, 0x1c, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1a, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x5e, 0x0a, 0x15, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, + 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, + 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x6c, 0x69, 0x63, 0x6b, + 0x12, 0x70, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, + 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x73, 0x61, 0x76, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, 0x63, + 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x43, 0x6c, 0x69, + 0x63, 0x6b, 0x12, 0x76, 0x0a, 0x1f, 0x75, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, + 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, + 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x43, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x98, 0x01, 0x0a, 0x2b, 0x75, + 0x69, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, + 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x55, 0x49, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, + 0x65, 0x56, 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x25, + 0x75, 0x69, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x56, + 0x69, 0x65, 0x77, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x12, 0x45, 0x0a, 0x0c, 0x6b, 0x75, 0x62, 0x65, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4b, 0x75, 0x62, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0b, 0x6b, 0x75, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x04, + 0x73, 0x66, 0x74, 0x70, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x46, 0x54, 0x50, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x66, 0x74, 0x70, 0x12, 0x56, 0x0a, + 0x14, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x12, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x57, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x27, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, + 0x62, 0x65, 0x61, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x9c, + 0x01, 0x0a, 0x2e, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x6f, + 0x69, 0x64, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x57, + 0x53, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x28, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x77, 0x73, 0x4f, 0x69, 0x64, + 0x63, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x83, 0x01, + 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x64, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, + 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x52, 0x44, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x20, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x64, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x6b, 0x0a, 0x1d, 0x75, 0x69, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x74, + 0x6f, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x43, 0x61, + 0x6c, 0x6c, 0x54, 0x6f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x75, 0x69, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x6f, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x54, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x79, 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2c, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x1d, 0x75, 0x69, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x75, 0x69, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x13, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x2e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x62, + 0x6f, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x42, 0x6f, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x09, 0x62, 0x6f, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x7a, 0x0a, 0x1f, + 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x18, + 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, 0x72, 0x65, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x4f, 0x6e, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x61, 0x69, + 0x72, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x39, 0x0a, 0x08, 0x62, 0x6f, 0x74, 0x5f, + 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x31, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x42, 0x6f, 0x74, 0x4a, + 0x6f, 0x69, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x74, 0x4a, + 0x6f, 0x69, 0x6e, 0x12, 0x51, 0x0a, 0x10, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x64, 0x0a, 0x17, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, + 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x19, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x6e, 0x0a, 0x1c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, + 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x5e, 0x0a, 0x15, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x36, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x37, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, - 0x73, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x37, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x13, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, - 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x38, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x13, 0x6c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x6c, 0x69, - 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x3b, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x55, 0x0a, - 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x0c, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, + 0x13, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x53, 0x0a, 0x13, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x3a, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x55, + 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x55, 0x0a, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x68, - 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x3e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x3f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x12, 0x69, 0x0a, 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x73, 0x65, 0x72, - 0x18, 0x40, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x12, 0x81, 0x01, - 0x0a, 0x22, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x63, - 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x41, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x72, 0x65, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x3f, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x69, 0x0a, 0x1a, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x40, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x54, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x54, + 0x6f, 0x55, 0x73, 0x65, 0x72, 0x12, 0x81, 0x01, 0x0a, 0x22, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x63, 0x32, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x41, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x43, + 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x63, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x62, 0x0a, 0x17, 0x75, 0x69, 0x5f, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, + 0x65, 0x69, 0x63, 0x65, 0x18, 0x42, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x43, 0x32, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x1e, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x63, 0x32, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x62, 0x0a, 0x17, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x65, 0x69, 0x63, 0x65, 0x18, 0x42, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x45, 0x49, 0x43, 0x45, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x14, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x45, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x17, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, - 0x18, 0x43, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x64, 0x0a, 0x17, 0x64, 0x65, 0x73, - 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, - 0x68, 0x61, 0x72, 0x65, 0x18, 0x44, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x6b, - 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, - 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, - 0x65, 0x0a, 0x1a, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x45, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, - 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x64, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x11, 0x74, 0x61, 0x67, 0x5f, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x46, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x54, 0x41, 0x47, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x74, 0x61, 0x67, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x86, 0x01, 0x0a, 0x23, 0x65, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x18, 0x47, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x6b, 0x0a, 0x1a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x18, 0x48, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x17, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x12, 0x4c, 0x0a, 0x0f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x18, 0x49, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0d, 0x61, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x59, - 0x0a, 0x15, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x66, 0x65, 0x74, 0x63, - 0x68, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x4a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, - 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x4b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x18, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x74, 0x0a, - 0x1d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x4d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x18, 0x6d, 0x66, 0x61, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, - 0x4e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4d, 0x46, 0x41, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, - 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x16, 0x6d, 0x66, 0x61, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x55, 0x0a, 0x12, 0x73, 0x70, 0x69, 0x66, 0x66, - 0x65, 0x5f, 0x73, 0x76, 0x69, 0x64, 0x5f, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x18, 0x4f, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, - 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x73, 0x70, - 0x69, 0x66, 0x66, 0x65, 0x53, 0x76, 0x69, 0x64, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x5c, - 0x0a, 0x15, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4f, - 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, - 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x5e, 0x0a, 0x15, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x51, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x7f, 0x0a, 0x21, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x52, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x84, 0x01, - 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x53, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x77, 0x0a, 0x21, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x65, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x54, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x45, 0x49, 0x43, 0x45, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x45, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, + 0x17, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x43, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x14, 0x75, 0x69, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x12, 0x64, 0x0a, 0x17, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x44, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x15, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, 0x65, 0x0a, 0x1a, 0x64, 0x65, 0x73, 0x6b, 0x74, + 0x6f, 0x70, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x45, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x65, 0x73, + 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x18, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x43, 0x6c, 0x69, + 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x52, + 0x0a, 0x11, 0x74, 0x61, 0x67, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x54, 0x41, 0x47, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x0f, 0x74, 0x61, 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x86, 0x01, 0x0a, 0x23, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, + 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x61, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x47, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x35, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x64, 0x69, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x6b, 0x0a, 0x1a, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x67, + 0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x48, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, - 0x4b, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, - 0x6b, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7d, 0x0a, - 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x18, 0x55, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x18, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x67, 0x69, 0x74, - 0x6c, 0x61, 0x62, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x18, 0x56, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, + 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x17, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x4c, 0x0a, 0x0f, 0x61, 0x75, 0x64, 0x69, + 0x74, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x49, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x59, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, + 0x4a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x13, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x68, 0x0a, 0x19, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x4b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, - 0x62, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, - 0x63, 0x61, 0x6e, 0x12, 0x94, 0x01, 0x0a, 0x29, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, - 0x6e, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x57, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x2a, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x74, 0x0a, 0x1d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x4d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, + 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x18, 0x6d, + 0x66, 0x61, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x4e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4d, + 0x46, 0x41, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x6d, 0x66, 0x61, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x55, 0x0a, 0x12, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x73, 0x76, 0x69, 0x64, 0x5f, 0x69, + 0x73, 0x73, 0x75, 0x65, 0x64, 0x18, 0x4f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x50, 0x49, + 0x46, 0x46, 0x45, 0x53, 0x56, 0x49, 0x44, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x10, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x53, 0x76, 0x69, 0x64, + 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x15, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, + 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x12, 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x79, 0x6e, 0x63, 0x12, 0x5e, 0x0a, 0x15, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x51, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, + 0x13, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x7f, 0x0a, 0x21, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x52, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x32, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x84, 0x01, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x53, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x77, 0x0a, 0x21, + 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x75, 0x62, 0x65, + 0x5f, 0x65, 0x6b, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x54, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, 0x4b, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x4b, 0x75, 0x62, 0x65, 0x45, 0x6b, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x7d, 0x0a, 0x23, 0x75, 0x69, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x70, 0x70, 0x5f, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x55, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1e, 0x75, 0x69, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x65, 0x0a, 0x18, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x5f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x5f, 0x73, 0x63, 0x61, 0x6e, + 0x18, 0x56, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x94, 0x01, 0x0a, 0x29, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x57, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, + 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x64, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, - 0x53, 0x63, 0x61, 0x6e, 0x53, 0x73, 0x68, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x5c, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x18, 0x59, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x57, - 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x77, 0x73, 0x53, 0x63, 0x61, 0x6e, - 0x12, 0x7b, 0x0a, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, - 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x78, 0x0a, - 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, - 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1b, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, - 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, 0x6f, 0x77, - 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x76, 0x69, 0x65, - 0x77, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, - 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x1f, 0x75, 0x69, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, + 0x53, 0x63, 0x61, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, + 0x79, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x2a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, + 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x18, 0x58, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, + 0x53, 0x48, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x24, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x73, 0x68, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x5c, 0x0a, 0x15, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x61, 0x77, 0x73, 0x5f, 0x73, + 0x63, 0x61, 0x6e, 0x18, 0x59, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, 0x57, 0x53, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x41, 0x77, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x7b, 0x0a, 0x20, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x5a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x78, 0x0a, 0x1f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, + 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, + 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, + 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x1b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, + 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, + 0x86, 0x01, 0x0a, 0x25, 0x75, 0x69, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x5f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x5f, + 0x64, 0x69, 0x66, 0x66, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x34, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x55, 0x49, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, - 0x12, 0x67, 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x5d, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a, 0x0f, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x5e, 0x20, 0x01, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x69, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, + 0x44, 0x69, 0x66, 0x66, 0x56, 0x69, 0x65, 0x77, 0x12, 0x67, 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x4c, 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, + 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x76, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x18, 0x60, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, + 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x75, 0x69, 0x49, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, + 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x52, 0x1c, 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x13, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x54, 0x61, - 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x76, 0x0a, 0x20, 0x75, 0x69, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x60, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x55, 0x49, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x1c, 0x75, 0x69, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, - 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x52, 0x1c, - 0x75, 0x69, 0x5f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x15, 0x0a, 0x13, - 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, - 0x0a, 0x14, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, - 0x87, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, - 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x50, 0x5f, 0x53, 0x45, 0x52, - 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, - 0x45, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, - 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, - 0x4f, 0x50, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, - 0x53, 0x48, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, - 0x53, 0x48, 0x5f, 0x45, 0x49, 0x43, 0x45, 0x10, 0x07, 0x2a, 0x4d, 0x0a, 0x08, 0x55, 0x73, 0x65, - 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x48, 0x55, - 0x4d, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x42, 0x4f, 0x54, 0x10, 0x02, 0x2a, 0xc0, 0x0f, 0x0a, 0x10, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x0a, - 0x1d, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, - 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x01, 0x12, 0x20, - 0x0a, 0x1c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x02, - 0x12, 0x33, 0x0a, 0x2f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, - 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, - 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, - 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, - 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, - 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x53, 0x45, - 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x05, 0x12, 0x2b, 0x0a, 0x27, 0x44, - 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, - 0x45, 0x53, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x06, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, + 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x16, + 0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, + 0x0a, 0x15, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x87, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, + 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x41, 0x50, 0x50, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, + 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4b, + 0x55, 0x42, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x42, + 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, + 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, + 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x10, 0x06, 0x12, 0x23, 0x0a, 0x1f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, + 0x44, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x53, 0x53, 0x48, 0x5f, 0x45, 0x49, 0x43, 0x45, 0x10, + 0x07, 0x2a, 0x4d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, + 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x48, 0x55, 0x4d, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x11, 0x0a, + 0x0d, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x42, 0x4f, 0x54, 0x10, 0x02, + 0x2a, 0xc0, 0x0f, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, + 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, + 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x02, 0x12, 0x33, 0x0a, 0x2f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x52, 0x44, 0x53, - 0x10, 0x07, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x08, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, + 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x30, 0x0a, + 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, + 0x4c, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, + 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x4f, + 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, + 0x44, 0x10, 0x05, 0x12, 0x2b, 0x0a, 0x27, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, + 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x06, + 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, + 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x07, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x43, 0x50, 0x10, - 0x09, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, - 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x0a, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x52, 0x44, 0x53, 0x10, 0x0b, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x54, 0x54, 0x50, + 0x10, 0x08, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x09, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, + 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x10, 0x0a, + 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, + 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x44, 0x53, 0x10, 0x0b, 0x12, 0x30, + 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, + 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x44, 0x53, 0x48, 0x49, 0x46, 0x54, 0x10, 0x0c, + 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, + 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, + 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, - 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, - 0x44, 0x53, 0x48, 0x49, 0x46, 0x54, 0x10, 0x0c, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, + 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x2b, 0x0a, 0x27, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, - 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x30, - 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, - 0x49, 0x53, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0e, - 0x12, 0x2b, 0x0a, 0x27, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, - 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x0f, 0x12, 0x28, 0x0a, - 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, - 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, - 0x4c, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x10, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, - 0x47, 0x43, 0x50, 0x10, 0x11, 0x12, 0x3b, 0x0a, 0x37, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, + 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, + 0x47, 0x43, 0x50, 0x10, 0x0f, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, - 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x44, - 0x53, 0x48, 0x49, 0x46, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, - 0x10, 0x12, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, - 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, - 0x13, 0x12, 0x27, 0x0a, 0x23, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x4f, 0x44, 0x42, 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, + 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x10, 0x12, + 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, + 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x11, 0x12, 0x3b, 0x0a, + 0x37, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, + 0x47, 0x52, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x44, 0x53, 0x48, 0x49, 0x46, 0x54, 0x5f, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x12, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x53, 0x53, 0x41, 0x4e, 0x44, - 0x52, 0x41, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x50, 0x41, 0x43, 0x45, 0x53, 0x10, 0x15, 0x12, 0x34, - 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x53, - 0x53, 0x41, 0x4e, 0x44, 0x52, 0x41, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, - 0x45, 0x44, 0x10, 0x16, 0x12, 0x38, 0x0a, 0x34, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, - 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, - 0x53, 0x45, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, 0x49, 0x43, 0x53, 0x45, 0x41, 0x52, 0x43, 0x48, - 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x17, 0x12, 0x30, - 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, - 0x49, 0x53, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, 0x49, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x18, - 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, - 0x45, 0x44, 0x49, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x44, 0x42, 0x10, 0x19, 0x12, - 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, - 0x44, 0x49, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, - 0x1a, 0x12, 0x38, 0x0a, 0x34, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, - 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x2a, 0x0a, 0x26, 0x44, - 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, - 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1c, 0x12, 0x2e, 0x0a, 0x2a, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, - 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1d, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, + 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x13, 0x12, 0x27, 0x0a, 0x23, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x4f, 0x44, 0x42, + 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, + 0x5f, 0x43, 0x41, 0x53, 0x53, 0x41, 0x4e, 0x44, 0x52, 0x41, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x50, + 0x41, 0x43, 0x45, 0x53, 0x10, 0x15, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x53, 0x53, 0x41, 0x4e, 0x44, 0x52, 0x41, 0x5f, 0x53, + 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x16, 0x12, 0x38, 0x0a, 0x34, + 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, + 0x49, 0x43, 0x53, 0x45, 0x41, 0x52, 0x43, 0x48, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, + 0x53, 0x54, 0x45, 0x44, 0x10, 0x17, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x45, 0x4c, 0x41, 0x53, 0x54, + 0x49, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x18, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, + 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x4d, 0x45, 0x4d, + 0x4f, 0x52, 0x59, 0x44, 0x42, 0x10, 0x19, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, - 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x10, 0x1e, 0x12, 0x36, 0x0a, 0x32, 0x44, - 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x43, 0x4b, 0x52, 0x4f, - 0x41, 0x43, 0x48, 0x44, 0x42, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, - 0x44, 0x10, 0x1f, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x41, 0x5a, 0x55, 0x52, + 0x45, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x1a, 0x12, 0x38, 0x0a, 0x34, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x44, 0x49, 0x53, 0x5f, 0x43, 0x4c, + 0x55, 0x53, 0x54, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, + 0x44, 0x10, 0x1b, 0x12, 0x2a, 0x0a, 0x26, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, + 0x45, 0x5f, 0x4d, 0x59, 0x53, 0x51, 0x4c, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1c, 0x12, + 0x2e, 0x0a, 0x2a, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, + 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x1d, 0x12, + 0x32, 0x0a, 0x2e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x51, + 0x4c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, + 0x54, 0x10, 0x1e, 0x12, 0x36, 0x0a, 0x32, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, - 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, 0x42, 0x5f, 0x41, 0x54, 0x4c, 0x41, 0x53, 0x10, - 0x20, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x53, 0x4e, 0x4f, 0x57, 0x46, 0x4c, 0x41, 0x4b, 0x45, 0x10, 0x21, 0x12, 0x2c, 0x0a, 0x28, 0x44, + 0x45, 0x5f, 0x43, 0x4f, 0x43, 0x4b, 0x52, 0x4f, 0x41, 0x43, 0x48, 0x44, 0x42, 0x5f, 0x53, 0x45, + 0x4c, 0x46, 0x5f, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x1f, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x44, - 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, 0x22, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x47, 0x4f, 0x44, + 0x42, 0x5f, 0x41, 0x54, 0x4c, 0x41, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, - 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, - 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x23, 0x12, - 0x37, 0x0a, 0x33, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, - 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, - 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x24, 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x41, - 0x4d, 0x4c, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x25, - 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x43, 0x32, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, - 0x43, 0x45, 0x10, 0x26, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, - 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x57, 0x49, - 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x5f, 0x4e, 0x4f, - 0x4e, 0x5f, 0x41, 0x44, 0x10, 0x27, 0x12, 0x24, 0x0a, 0x20, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, - 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, - 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x5f, 0x45, 0x4b, 0x53, 0x10, 0x28, 0x12, 0x2d, 0x0a, 0x29, + 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x46, 0x4c, 0x41, 0x4b, + 0x45, 0x10, 0x21, 0x12, 0x2c, 0x0a, 0x28, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x52, 0x44, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, + 0x22, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, + 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, + 0x41, 0x53, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, + 0x49, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x23, 0x12, 0x37, 0x0a, 0x33, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x4f, 0x43, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, + 0x43, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x24, + 0x12, 0x26, 0x0a, 0x22, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x41, 0x4d, 0x4c, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x25, 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x49, 0x53, 0x43, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x43, + 0x32, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x26, 0x12, 0x30, 0x0a, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x57, - 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x10, 0x29, 0x2a, 0xa3, 0x01, 0x0a, 0x0e, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, - 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, + 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, + 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x10, 0x27, 0x12, 0x24, + 0x0a, 0x20, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x5f, 0x45, + 0x4b, 0x53, 0x10, 0x28, 0x12, 0x2d, 0x0a, 0x29, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, + 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, + 0x45, 0x10, 0x29, 0x2a, 0xa3, 0x01, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, + 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, + 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, - 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, - 0x04, 0x2a, 0xd4, 0x02, 0x0a, 0x03, 0x43, 0x54, 0x41, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x54, 0x41, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, - 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, - 0x43, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, - 0x54, 0x49, 0x56, 0x45, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x02, 0x12, - 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x52, 0x45, - 0x51, 0x55, 0x45, 0x53, 0x54, 0x53, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, - 0x50, 0x52, 0x45, 0x4d, 0x49, 0x55, 0x4d, 0x5f, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x10, - 0x04, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, - 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, - 0x41, 0x5f, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, 0x45, 0x5f, 0x42, 0x41, 0x4e, 0x4e, 0x45, 0x52, - 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, - 0x47, 0x5f, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x43, - 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, - 0x12, 0x19, 0x0a, 0x15, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4d, - 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x1e, 0x0a, 0x1a, 0x43, - 0x54, 0x41, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x41, 0x55, 0x44, 0x49, - 0x54, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x43, - 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x59, 0x4e, - 0x43, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x54, 0x41, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, - 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, - 0x41, 0x5f, 0x53, 0x43, 0x49, 0x4d, 0x10, 0x0d, 0x2a, 0x94, 0x09, 0x0a, 0x15, 0x49, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4b, 0x69, - 0x6e, 0x64, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x10, 0x01, 0x12, 0x24, - 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, - 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x4f, 0x49, - 0x44, 0x43, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x50, 0x41, 0x47, 0x45, 0x52, 0x44, 0x55, 0x54, 0x59, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x45, 0x4d, 0x41, 0x49, 0x4c, 0x10, 0x04, 0x12, 0x20, - 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, - 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4a, 0x49, 0x52, 0x41, 0x10, 0x05, - 0x12, 0x23, 0x0a, 0x1f, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x49, 0x53, 0x43, - 0x4f, 0x52, 0x44, 0x10, 0x06, 0x12, 0x26, 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, 0xd4, 0x02, 0x0a, 0x03, 0x43, 0x54, + 0x41, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x54, 0x41, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x55, + 0x54, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x53, 0x45, 0x53, + 0x53, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x41, + 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x53, 0x10, 0x03, + 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x55, 0x4d, 0x5f, + 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, 0x41, + 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, + 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, + 0x45, 0x5f, 0x42, 0x41, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x54, + 0x41, 0x5f, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, + 0x59, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x54, 0x41, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, + 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x54, 0x41, 0x5f, + 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, + 0x47, 0x10, 0x09, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x54, 0x41, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, + 0x4e, 0x41, 0x4c, 0x5f, 0x41, 0x55, 0x44, 0x49, 0x54, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, + 0x45, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x5f, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, + 0x54, 0x41, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x11, 0x0a, + 0x0d, 0x43, 0x54, 0x41, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x5f, 0x53, 0x43, 0x49, 0x4d, 0x10, 0x0d, + 0x2a, 0x94, 0x09, 0x0a, 0x15, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, + 0x4c, 0x41, 0x43, 0x4b, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, + 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, + 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, + 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x52, 0x44, 0x55, 0x54, + 0x59, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x45, + 0x4d, 0x41, 0x49, 0x4c, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, + 0x44, 0x5f, 0x4a, 0x49, 0x52, 0x41, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x49, 0x4e, 0x54, 0x45, + 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, + 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x52, 0x44, 0x10, 0x06, 0x12, 0x26, 0x0a, + 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, + 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4d, + 0x4f, 0x53, 0x54, 0x10, 0x07, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x4d, 0x4f, 0x53, 0x54, 0x10, 0x07, 0x12, 0x24, 0x0a, - 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, - 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x53, 0x5f, 0x54, 0x45, 0x41, 0x4d, - 0x53, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, - 0x50, 0x53, 0x47, 0x45, 0x4e, 0x49, 0x45, 0x10, 0x09, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, 0x4b, 0x54, 0x41, 0x10, 0x0a, 0x12, 0x20, 0x0a, 0x1c, 0x49, + 0x5f, 0x4d, 0x53, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4a, 0x41, 0x4d, 0x46, 0x10, 0x0b, 0x12, 0x26, 0x0a, - 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, - 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, - 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x35, 0x0a, 0x31, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, 0x50, 0x53, 0x47, 0x45, 0x4e, 0x49, 0x45, 0x10, + 0x09, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4f, 0x4b, 0x54, + 0x41, 0x10, 0x0a, 0x12, 0x20, 0x0a, 0x1c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4a, + 0x41, 0x4d, 0x46, 0x10, 0x0b, 0x12, 0x26, 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x48, - 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x0d, 0x12, 0x2f, 0x0a, 0x2b, - 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, - 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45, 0x43, 0x49, 0x10, 0x0e, 0x12, 0x2d, 0x0a, - 0x29, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, + 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x10, 0x0c, 0x12, 0x35, 0x0a, + 0x31, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, - 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x10, 0x0f, 0x12, 0x2e, 0x0a, 0x2a, - 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, - 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x4a, 0x45, 0x4e, 0x4b, 0x49, 0x4e, 0x53, 0x10, 0x10, 0x12, 0x2e, 0x0a, 0x2a, + 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x53, 0x10, 0x0d, 0x12, 0x2f, 0x0a, 0x2b, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, + 0x45, 0x43, 0x49, 0x10, 0x0e, 0x12, 0x2d, 0x0a, 0x29, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x49, 0x54, 0x4c, + 0x41, 0x42, 0x10, 0x0f, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x4a, 0x45, 0x4e, 0x4b, 0x49, + 0x4e, 0x53, 0x10, 0x10, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x4e, 0x53, 0x49, 0x42, + 0x4c, 0x45, 0x10, 0x11, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x10, 0x12, + 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, + 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, 0x43, 0x50, 0x10, 0x13, 0x12, 0x2c, 0x0a, 0x28, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x41, 0x4e, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x11, 0x12, 0x2a, 0x0a, 0x26, + 0x49, 0x44, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x10, 0x14, 0x12, 0x30, 0x0a, 0x2c, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, + 0x5f, 0x53, 0x50, 0x41, 0x43, 0x45, 0x4c, 0x49, 0x46, 0x54, 0x10, 0x15, 0x12, 0x31, 0x0a, 0x2d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, - 0x49, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x10, 0x12, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, - 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, - 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x47, - 0x43, 0x50, 0x10, 0x13, 0x12, 0x2c, 0x0a, 0x28, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, - 0x10, 0x14, 0x12, 0x30, 0x0a, 0x2c, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, - 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x50, 0x41, 0x43, 0x45, 0x4c, 0x49, - 0x46, 0x54, 0x10, 0x15, 0x12, 0x31, 0x0a, 0x2d, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x4d, 0x41, 0x43, 0x48, 0x49, 0x4e, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, - 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x16, 0x12, 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, - 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, - 0x4e, 0x44, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, 0x5f, 0x49, 0x44, 0x10, 0x17, 0x12, 0x37, 0x0a, - 0x33, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, - 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x44, 0x4f, 0x47, - 0x5f, 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, - 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, + 0x49, 0x44, 0x5f, 0x4b, 0x55, 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x16, 0x12, + 0x24, 0x0a, 0x20, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, + 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x41, + 0x5f, 0x49, 0x44, 0x10, 0x17, 0x12, 0x37, 0x0a, 0x33, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x44, 0x4f, 0x47, 0x5f, 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, + 0x54, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x18, 0x12, 0x26, + 0x0a, 0x22, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, + 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, + 0x45, 0x4e, 0x4f, 0x57, 0x10, 0x19, 0x12, 0x2f, 0x0a, 0x2b, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, - 0x44, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x4e, 0x4f, 0x57, 0x10, 0x19, 0x12, 0x2f, - 0x0a, 0x2b, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, - 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x49, 0x44, - 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x1a, 0x2a, - 0xa7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x53, 0x54, 0x45, 0x50, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, - 0x53, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x49, 0x44, 0x43, - 0x10, 0x01, 0x12, 0x3e, 0x0a, 0x3a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, - 0x53, 0x49, 0x43, 0x5f, 0x53, 0x45, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x4c, 0x49, - 0x53, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, - 0x10, 0x02, 0x12, 0x3d, 0x0a, 0x39, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, - 0x53, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x53, - 0x41, 0x4d, 0x4c, 0x5f, 0x53, 0x50, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x10, - 0x03, 0x12, 0x36, 0x0a, 0x32, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, - 0x49, 0x43, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x43, 0x49, 0x4d, 0x5f, 0x43, 0x4f, 0x4e, - 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x2a, 0xfb, 0x01, 0x0a, 0x1b, 0x49, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, + 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x43, + 0x45, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x1a, 0x2a, 0xa7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x65, + 0x70, 0x12, 0x27, 0x0a, 0x23, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x5f, 0x4f, 0x49, 0x44, 0x43, 0x10, 0x01, 0x12, 0x3e, 0x0a, 0x3a, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x53, 0x45, 0x54, 0x5f, + 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, + 0x4c, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x02, 0x12, 0x3d, 0x0a, 0x39, 0x49, 0x4e, + 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x4c, 0x4f, + 0x41, 0x44, 0x5f, 0x41, 0x57, 0x53, 0x5f, 0x53, 0x41, 0x4d, 0x4c, 0x5f, 0x53, 0x50, 0x5f, 0x4d, + 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x10, 0x03, 0x12, 0x36, 0x0a, 0x32, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, - 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, - 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, - 0x02, 0x12, 0x28, 0x0a, 0x24, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x53, 0x54, 0x45, 0x50, 0x5f, 0x41, 0x57, 0x53, 0x49, 0x43, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, + 0x53, 0x43, 0x49, 0x4d, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x04, 0x2a, 0xfb, 0x01, 0x0a, 0x1b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x2e, 0x0a, 0x2a, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, - 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x2a, 0x0a, 0x26, 0x49, - 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, - 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x42, - 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, 0x88, 0x01, 0x0a, 0x12, 0x45, 0x64, 0x69, 0x74, - 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, - 0x0a, 0x20, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, - 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, - 0x45, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x45, - 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, - 0x10, 0x02, 0x2a, 0x3f, 0x0a, 0x07, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, - 0x13, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, - 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, - 0x53, 0x10, 0x01, 0x2a, 0xa0, 0x01, 0x0a, 0x1b, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, - 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x29, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, - 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, - 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x26, - 0x0a, 0x22, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, - 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x44, 0x4f, 0x4e, 0x45, 0x10, 0x02, 0x2a, 0x82, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x63, 0x65, 0x6e, - 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x19, 0x4c, 0x49, 0x43, 0x45, 0x4e, - 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x28, 0x0a, 0x24, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, - 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, - 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x5f, 0x4a, 0x41, 0x4d, 0x46, 0x10, 0x01, - 0x12, 0x29, 0x0a, 0x25, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, - 0x54, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, - 0x45, 0x41, 0x4d, 0x5f, 0x55, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x32, 0xb4, 0x02, 0x0a, 0x18, - 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, - 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, - 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x5b, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x65, - 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0d, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, - 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, - 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0xc9, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 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, 0x70, 0x72, 0x65, 0x68, 0x6f, - 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, - 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xca, 0x02, - 0x0e, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xe2, - 0x02, 0x1a, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, - 0x72, 0x65, 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, + 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x2a, 0x0a, + 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, + 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, + 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x12, 0x28, 0x0a, 0x24, 0x49, 0x4e, 0x54, + 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x03, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x2a, + 0x88, 0x01, 0x0a, 0x12, 0x45, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, + 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x44, 0x49, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x48, + 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, + 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x3f, 0x0a, 0x07, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, + 0x0a, 0x17, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, + 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x10, 0x01, 0x2a, 0xa0, 0x01, 0x0a, 0x1b, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x29, 0x46, + 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26, 0x46, 0x45, + 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, + 0x45, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x4e, 0x45, 0x10, 0x02, 0x2a, 0x82, + 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, + 0x1d, 0x0a, 0x19, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x28, + 0x0a, 0x24, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, + 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, 0x45, 0x41, + 0x4d, 0x5f, 0x4a, 0x41, 0x4d, 0x46, 0x10, 0x01, 0x12, 0x29, 0x0a, 0x25, 0x4c, 0x49, 0x43, 0x45, + 0x4e, 0x53, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, + 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x5f, 0x55, 0x53, 0x41, 0x47, + 0x45, 0x10, 0x02, 0x32, 0xb4, 0x02, 0x0a, 0x18, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x5b, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x22, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x12, 0x5b, 0x0a, + 0x0c, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x2e, + 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0d, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x2e, 0x70, 0x72, + 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, + 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xc9, 0x01, 0x0a, 0x12, 0x63, + 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x42, 0x0d, 0x54, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x4b, 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, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x3b, 0x70, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xa2, + 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0e, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x2e, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xca, 0x02, 0x0e, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x5c, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0xe2, 0x02, 0x1a, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, + 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x72, 0x65, 0x68, 0x6f, 0x67, 0x3a, 0x3a, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( diff --git a/gen/proto/ts/prehog/v1/teleport_pb.ts b/gen/proto/ts/prehog/v1/teleport_pb.ts index 79f489dabd77c..aa3d941baaad4 100644 --- a/gen/proto/ts/prehog/v1/teleport_pb.ts +++ b/gen/proto/ts/prehog/v1/teleport_pb.ts @@ -253,6 +253,98 @@ export interface ResourceKindPresenceReport { */ resourceIds: bigint[]; } +/** + * counters for bot instance activity coming from a specific auth server from a + * specific cluster. + * + * PostHog event: tp.bot_instance.activity + * + * @generated from protobuf message prehog.v1.BotInstanceActivityReport + */ +export interface BotInstanceActivityReport { + /** + * randomly generated UUID for this specific report, 16 bytes (in string order) + * + * PostHog property: tp.report_uuid (in 8-4-4-4-12 string form) + * + * @generated from protobuf field: bytes report_uuid = 1; + */ + reportUuid: Uint8Array; + /** + * cluster name, anonymized, 32 bytes (HMAC-SHA-256) + * + * PostHog property: tp.cluster_name (in base64) + * + * @generated from protobuf field: bytes cluster_name = 2; + */ + clusterName: Uint8Array; + /** + * hostid of the auth that collected this report, anonymized, 32 bytes (HMAC-SHA-256) + * + * PostHog property: tp.reporter_hostid (in base64) + * + * @generated from protobuf field: bytes reporter_hostid = 3; + */ + reporterHostid: Uint8Array; + /** + * beginning of the time window for this data; ending is not specified but is + * intended to be at most 15 minutes + * + * PostHog timestamp (not a property, the ingest time is tp.report_time instead) + * + * @generated from protobuf field: google.protobuf.Timestamp start_time = 4; + */ + startTime?: Timestamp; + /** + * one set of counters for each bot instance + * + * PostHog property: tp.records (encoded as a map keyed by anonymized bot + * instance id, not as a list) + * + * @generated from protobuf field: repeated prehog.v1.BotInstanceActivityRecord records = 5; + */ + records: BotInstanceActivityRecord[]; +} +/** + * Records the activity for a single bot instance against a specific auth server + * from a specific cluster. + * + * @generated from protobuf message prehog.v1.BotInstanceActivityRecord + */ +export interface BotInstanceActivityRecord { + /** + * The UUID of the BotInstance, anonymized using HMAC-SHA-256. + * + * @generated from protobuf field: bytes bot_instance_id = 1; + */ + botInstanceId: Uint8Array; + /** + * The name of the user associated with the BotInstance, + * anonymized using HMAC-SHA-256. + * Enables correlation with the UserActivityRecord for the Bot. + * + * @generated from protobuf field: bytes bot_user_name = 2; + */ + botUserName: Uint8Array; + /** + * counter of bot joins + * + * @generated from protobuf field: uint64 bot_joins = 3; + */ + botJoins: bigint; + /** + * counter of SPIFFE SVIDs issued + * + * @generated from protobuf field: uint64 spiffe_svids_issued = 4; + */ + spiffeSvidsIssued: bigint; + /** + * counter of certificates issued for this user + * + * @generated from protobuf field: uint64 certificates_issued = 5; + */ + certificatesIssued: bigint; +} /** * @generated from protobuf message prehog.v1.SubmitUsageReportsRequest */ @@ -271,6 +363,12 @@ export interface SubmitUsageReportsRequest { * @generated from protobuf field: repeated prehog.v1.ResourcePresenceReport resource_presence = 2; */ resourcePresence: ResourcePresenceReport[]; + /** + * encoded as a seperate tp.bot_instance.activity PostHog event + * + * @generated from protobuf field: repeated prehog.v1.BotInstanceActivityReport bot_instance_activity = 3; + */ + botInstanceActivity: BotInstanceActivityReport[]; } /** * @generated from protobuf message prehog.v1.SubmitUsageReportsResponse @@ -778,17 +876,176 @@ class ResourceKindPresenceReport$Type extends MessageType { + constructor() { + super("prehog.v1.BotInstanceActivityReport", [ + { no: 1, name: "report_uuid", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 2, name: "cluster_name", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 3, name: "reporter_hostid", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 4, name: "start_time", kind: "message", T: () => Timestamp }, + { no: 5, name: "records", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => BotInstanceActivityRecord } + ]); + } + create(value?: PartialMessage): BotInstanceActivityReport { + const message = globalThis.Object.create((this.messagePrototype!)); + message.reportUuid = new Uint8Array(0); + message.clusterName = new Uint8Array(0); + message.reporterHostid = new Uint8Array(0); + message.records = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BotInstanceActivityReport): BotInstanceActivityReport { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes report_uuid */ 1: + message.reportUuid = reader.bytes(); + break; + case /* bytes cluster_name */ 2: + message.clusterName = reader.bytes(); + break; + case /* bytes reporter_hostid */ 3: + message.reporterHostid = reader.bytes(); + break; + case /* google.protobuf.Timestamp start_time */ 4: + message.startTime = Timestamp.internalBinaryRead(reader, reader.uint32(), options, message.startTime); + break; + case /* repeated prehog.v1.BotInstanceActivityRecord records */ 5: + message.records.push(BotInstanceActivityRecord.internalBinaryRead(reader, reader.uint32(), options)); + 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: BotInstanceActivityReport, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes report_uuid = 1; */ + if (message.reportUuid.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.reportUuid); + /* bytes cluster_name = 2; */ + if (message.clusterName.length) + writer.tag(2, WireType.LengthDelimited).bytes(message.clusterName); + /* bytes reporter_hostid = 3; */ + if (message.reporterHostid.length) + writer.tag(3, WireType.LengthDelimited).bytes(message.reporterHostid); + /* google.protobuf.Timestamp start_time = 4; */ + if (message.startTime) + Timestamp.internalBinaryWrite(message.startTime, writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + /* repeated prehog.v1.BotInstanceActivityRecord records = 5; */ + for (let i = 0; i < message.records.length; i++) + BotInstanceActivityRecord.internalBinaryWrite(message.records[i], writer.tag(5, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message prehog.v1.BotInstanceActivityReport + */ +export const BotInstanceActivityReport = new BotInstanceActivityReport$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class BotInstanceActivityRecord$Type extends MessageType { + constructor() { + super("prehog.v1.BotInstanceActivityRecord", [ + { no: 1, name: "bot_instance_id", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 2, name: "bot_user_name", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 3, name: "bot_joins", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 4, name: "spiffe_svids_issued", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 5, name: "certificates_issued", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ } + ]); + } + create(value?: PartialMessage): BotInstanceActivityRecord { + const message = globalThis.Object.create((this.messagePrototype!)); + message.botInstanceId = new Uint8Array(0); + message.botUserName = new Uint8Array(0); + message.botJoins = 0n; + message.spiffeSvidsIssued = 0n; + message.certificatesIssued = 0n; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: BotInstanceActivityRecord): BotInstanceActivityRecord { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes bot_instance_id */ 1: + message.botInstanceId = reader.bytes(); + break; + case /* bytes bot_user_name */ 2: + message.botUserName = reader.bytes(); + break; + case /* uint64 bot_joins */ 3: + message.botJoins = reader.uint64().toBigInt(); + break; + case /* uint64 spiffe_svids_issued */ 4: + message.spiffeSvidsIssued = reader.uint64().toBigInt(); + break; + case /* uint64 certificates_issued */ 5: + message.certificatesIssued = reader.uint64().toBigInt(); + 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: BotInstanceActivityRecord, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes bot_instance_id = 1; */ + if (message.botInstanceId.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.botInstanceId); + /* bytes bot_user_name = 2; */ + if (message.botUserName.length) + writer.tag(2, WireType.LengthDelimited).bytes(message.botUserName); + /* uint64 bot_joins = 3; */ + if (message.botJoins !== 0n) + writer.tag(3, WireType.Varint).uint64(message.botJoins); + /* uint64 spiffe_svids_issued = 4; */ + if (message.spiffeSvidsIssued !== 0n) + writer.tag(4, WireType.Varint).uint64(message.spiffeSvidsIssued); + /* uint64 certificates_issued = 5; */ + if (message.certificatesIssued !== 0n) + writer.tag(5, WireType.Varint).uint64(message.certificatesIssued); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message prehog.v1.BotInstanceActivityRecord + */ +export const BotInstanceActivityRecord = new BotInstanceActivityRecord$Type(); +// @generated message type with reflection information, may provide speed optimized methods class SubmitUsageReportsRequest$Type extends MessageType { constructor() { super("prehog.v1.SubmitUsageReportsRequest", [ { no: 1, name: "user_activity", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => UserActivityReport }, - { no: 2, name: "resource_presence", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ResourcePresenceReport } + { no: 2, name: "resource_presence", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ResourcePresenceReport }, + { no: 3, name: "bot_instance_activity", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => BotInstanceActivityReport } ]); } create(value?: PartialMessage): SubmitUsageReportsRequest { const message = globalThis.Object.create((this.messagePrototype!)); message.userActivity = []; message.resourcePresence = []; + message.botInstanceActivity = []; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -804,6 +1061,9 @@ class SubmitUsageReportsRequest$Type extends MessageType): UserCertificateIssuedEvent { @@ -4678,6 +4699,7 @@ class UserCertificateIssuedEvent$Type extends MessageType(this, message, value); return message; @@ -4711,6 +4733,9 @@ class UserCertificateIssuedEvent$Type extends MessageType { { no: 3, name: "spiffe_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 4, name: "ip_sans_count", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, { no: 5, name: "dns_sans_count", kind: "scalar", T: 5 /*ScalarType.INT32*/ }, - { no: 6, name: "svid_type", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 6, name: "svid_type", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 7, name: "bot_instance_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): SPIFFESVIDIssuedEvent { @@ -4777,6 +4806,7 @@ class SPIFFESVIDIssuedEvent$Type extends MessageType { message.ipSansCount = 0; message.dnsSansCount = 0; message.svidType = ""; + message.botInstanceId = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -4804,6 +4834,9 @@ class SPIFFESVIDIssuedEvent$Type extends MessageType { case /* string svid_type */ 6: message.svidType = reader.string(); break; + case /* string bot_instance_id */ 7: + message.botInstanceId = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -4834,6 +4867,9 @@ class SPIFFESVIDIssuedEvent$Type extends MessageType { /* string svid_type = 6; */ if (message.svidType !== "") writer.tag(6, WireType.LengthDelimited).string(message.svidType); + /* string bot_instance_id = 7; */ + if (message.botInstanceId !== "") + writer.tag(7, WireType.LengthDelimited).string(message.botInstanceId); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -6885,7 +6921,8 @@ class BotJoinEvent$Type extends MessageType { { no: 1, name: "bot_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 2, name: "join_method", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 3, name: "join_token_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 4, name: "user_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 4, name: "user_name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: "bot_instance_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): BotJoinEvent { @@ -6894,6 +6931,7 @@ class BotJoinEvent$Type extends MessageType { message.joinMethod = ""; message.joinTokenName = ""; message.userName = ""; + message.botInstanceId = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -6915,6 +6953,9 @@ class BotJoinEvent$Type extends MessageType { case /* string user_name */ 4: message.userName = reader.string(); break; + case /* string bot_instance_id */ 5: + message.botInstanceId = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -6939,6 +6980,9 @@ class BotJoinEvent$Type extends MessageType { /* string user_name = 4; */ if (message.userName !== "") writer.tag(4, WireType.LengthDelimited).string(message.userName); + /* string bot_instance_id = 5; */ + if (message.botInstanceId !== "") + writer.tag(5, WireType.LengthDelimited).string(message.botInstanceId); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/lib/auth/auth.go b/lib/auth/auth.go index b21ca73523ff2..5a1dfcbf796b2 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -3058,6 +3058,7 @@ func (a *Server) submitCertificateIssuedEvent(req *certRequest, attestedKeyPolic UsageKubernetes: kubernetes, UsageDesktop: desktop, PrivateKeyPolicy: string(attestedKeyPolicy), + BotInstanceId: req.botInstanceID, }) } diff --git a/lib/usagereporter/teleport/aggregating/reporter.go b/lib/usagereporter/teleport/aggregating/reporter.go index 7dc288411b92a..dad1471158bf7 100644 --- a/lib/usagereporter/teleport/aggregating/reporter.go +++ b/lib/usagereporter/teleport/aggregating/reporter.go @@ -39,10 +39,11 @@ import ( ) const ( - userActivityReportGranularity = 15 * time.Minute - resourceReportGranularity = time.Hour - rollbackGrace = time.Minute - reportTTL = 60 * 24 * time.Hour + userActivityReportGranularity = 15 * time.Minute + resourceReportGranularity = time.Hour + botInstanceActivityReportGranularity = 15 * time.Minute + rollbackGrace = time.Minute + reportTTL = 60 * 24 * time.Hour checkInterval = time.Minute ) @@ -272,6 +273,23 @@ func (r *Reporter) run(ctx context.Context) { return record } + botInstanceActivityStartTime := r.clock.Now().UTC().Truncate(botInstanceActivityReportGranularity) + botInstanceActivityWindowStart := botInstanceActivityStartTime.Add(-rollbackGrace) + botInstanceActivityWindowEnd := botInstanceActivityStartTime.Add(botInstanceActivityReportGranularity) + botInstanceActivity := make(map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord) + botInstanceRecord := func(botUserName string, botInstanceID string) *prehogv1.BotInstanceActivityRecord { + key := botInstanceActivityKey{ + botUserName: botUserName, + botInstanceID: botInstanceID, + } + record := botInstanceActivity[key] + if record == nil { + record = &prehogv1.BotInstanceActivityRecord{} + botInstanceActivity[key] = record + } + return record + } + resourceUsageStartTime := r.clock.Now().UTC().Truncate(resourceReportGranularity) resourceUsageWindowStart := resourceUsageStartTime.Add(-rollbackGrace) resourceUsageWindowEnd := resourceUsageStartTime.Add(resourceReportGranularity) @@ -317,6 +335,25 @@ Ingest: userActivity = make(map[string]*prehogv1.UserActivityRecord, len(userActivity)) } + if now := r.clock.Now().UTC(); now.Before(botInstanceActivityWindowStart) || !now.Before(botInstanceActivityWindowEnd) { + if len(botInstanceActivity) > 0 { + wg.Add(1) + go func( + ctx context.Context, + startTime time.Time, + botInstanceActivity map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord, + ) { + defer wg.Done() + r.persistBotInstanceActivity(ctx, startTime, botInstanceActivity) + }(ctx, botInstanceActivityStartTime, botInstanceActivity) + } + + botInstanceActivityStartTime = now.Truncate(botInstanceActivityReportGranularity) + botInstanceActivityWindowStart = botInstanceActivityStartTime.Add(-rollbackGrace) + botInstanceActivityWindowEnd = botInstanceActivityStartTime.Add(botInstanceActivityReportGranularity) + botInstanceActivity = make(map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord, len(botInstanceActivity)) + } + if now := r.clock.Now().UTC(); now.Before(resourceUsageWindowStart) || !now.Before(resourceUsageWindowEnd) { if len(resourcePresences) > 0 { wg.Add(1) @@ -364,9 +401,15 @@ Ingest: resourcePresence(prehogv1.ResourceKind(te.Kind))[te.Name] = struct{}{} case *usagereporter.SPIFFESVIDIssuedEvent: userRecord(te.UserName, te.UserKind).SpiffeSvidsIssued++ + if te.BotInstanceId != "" { + botInstanceRecord(te.UserName, te.BotInstanceId).SpiffeSvidsIssued++ + } case *usagereporter.BotJoinEvent: botUserName := machineidv1.BotResourceName(te.BotName) userRecord(botUserName, prehogv1alpha.UserKind_USER_KIND_BOT).BotJoins++ + if te.BotInstanceId != "" { + botInstanceRecord(botUserName, te.BotInstanceId).BotJoins++ + } case *usagereporter.UserCertificateIssuedEvent: // Note: kind is poorly defined for this event type, so we'll assume // unspecified even though non-bot users are almost certainly human. @@ -376,6 +419,9 @@ Ingest: } userRecord(te.UserName, kind).CertificatesIssued++ + if te.BotInstanceId != "" { + botInstanceRecord(te.UserName, te.BotInstanceId).CertificatesIssued++ + } } if ae != nil && r.ingested != nil { @@ -387,6 +433,10 @@ Ingest: r.persistUserActivity(ctx, userActivityStartTime, userActivity) } + if len(botInstanceActivity) > 0 { + r.persistBotInstanceActivity(ctx, botInstanceActivityStartTime, botInstanceActivity) + } + if len(resourcePresences) > 0 { r.persistResourcePresence(ctx, resourceUsageStartTime, resourcePresences) } @@ -394,6 +444,57 @@ Ingest: wg.Wait() } +type botInstanceActivityKey struct { + botUserName string + botInstanceID string +} + +func (r *Reporter) persistBotInstanceActivity( + ctx context.Context, + startTime time.Time, + botInstanceActivity map[botInstanceActivityKey]*prehogv1.BotInstanceActivityRecord, +) { + records := make([]*prehogv1.BotInstanceActivityRecord, 0, len(botInstanceActivity)) + for key, record := range botInstanceActivity { + record.BotUserName = r.anonymizer.AnonymizeNonEmpty(key.botUserName) + record.BotInstanceId = r.anonymizer.AnonymizeNonEmpty(key.botInstanceID) + records = append(records, record) + } + + anonymizedClusterName := r.anonymizer.AnonymizeNonEmpty(r.clusterName) + anonymizedHostID := r.anonymizer.AnonymizeNonEmpty(r.hostID) + + reports, err := prepareBotInstanceActivityReports( + anonymizedClusterName, anonymizedHostID, startTime, records, + ) + if err != nil { + r.logger.ErrorContext(ctx, "Failed to prepare bot instance activity report, dropping data.", + "start_time", startTime, + "lost_records", len(records), + "error", err, + ) + return + } + + for _, report := range reports { + if err := r.svc.upsertBotInstanceActivityReport(ctx, report, reportTTL); err != nil { + r.logger.ErrorContext(ctx, "Failed to persist bot instance activity report, dropping data.", + "start_time", startTime, + "lost_records", len(report.Records), + "error", err, + ) + continue + } + + reportUUID, _ := uuid.FromBytes(report.ReportUuid) + r.logger.DebugContext(ctx, "Persisted bot instance activity report.", + "report_uuid", reportUUID, + "start_time", startTime, + "records", len(report.Records), + ) + } +} + func (r *Reporter) persistUserActivity(ctx context.Context, startTime time.Time, userActivity map[string]*prehogv1.UserActivityRecord) { records := make([]*prehogv1.UserActivityRecord, 0, len(userActivity)) for userName, record := range userActivity { diff --git a/lib/usagereporter/teleport/aggregating/reporter_test.go b/lib/usagereporter/teleport/aggregating/reporter_test.go index 0c82a51fbd938..d860d04c24180 100644 --- a/lib/usagereporter/teleport/aggregating/reporter_test.go +++ b/lib/usagereporter/teleport/aggregating/reporter_test.go @@ -21,6 +21,7 @@ package aggregating import ( "bytes" "context" + "slices" "testing" "time" @@ -181,3 +182,113 @@ func TestReporter(t *testing.T) { require.Equal(t, uint64(0), rec1.KubeSessions) require.Equal(t, uint64(1), rec2.KubeSessions) } + +func TestReporterBotInstanceActivity(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + clk := clockwork.NewFakeClock() + bk, err := memory.New(memory.Config{ + Clock: clk, + }) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, bk.Close()) }) + // we set up a watcher to not have to poll the backend for newly added items + // we expect + w, err := bk.NewWatcher(ctx, backend.Watch{}) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, w.Close()) }) + recvBackendEvent := func() backend.Event { + select { + case e := <-w.Events(): + return e + case <-time.After(time.Second): + t.Fatal("failed to get backend event") + return backend.Event{} + } + } + require.Equal(t, types.OpInit, recvBackendEvent().Type) + + clusterName, err := services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ + ClusterName: "clustername", + }) + require.NoError(t, err) + + anonymizer, err := utils.NewHMACAnonymizer("0123456789abcdef") + require.NoError(t, err) + + r, err := NewReporter(ctx, ReporterConfig{ + Backend: bk, + Clock: clk, + ClusterName: clusterName, + HostID: uuid.NewString(), + Anonymizer: anonymizer, + }) + require.NoError(t, err) + + svc := reportService{bk} + + r.ingested = make(chan usagereporter.Anonymizable, 4) + recvIngested := func() { + select { + case <-r.ingested: + case <-time.After(time.Second): + t.Fatal("failed to receive ingested event") + } + } + + r.AnonymizeAndSubmit(&usagereporter.UserCertificateIssuedEvent{ + UserName: "bot-bob", + BotInstanceId: "0000-01", + IsBot: true, + }) + r.AnonymizeAndSubmit(&usagereporter.BotJoinEvent{ + BotName: "bob", + BotInstanceId: "0000-01", + }) + // Submit for two different bot instances, we expect a useractivity record + // with a value of two, and two bot instance activity records with a single + // value of 1. + r.AnonymizeAndSubmit(&usagereporter.SPIFFESVIDIssuedEvent{ + UserName: "bot-bob", + BotInstanceId: "0000-01", + UserKind: prehogv1a.UserKind_USER_KIND_BOT, + }) + r.AnonymizeAndSubmit(&usagereporter.SPIFFESVIDIssuedEvent{ + UserName: "bot-bob", + BotInstanceId: "0000-02", + UserKind: prehogv1a.UserKind_USER_KIND_BOT, + }) + recvIngested() + recvIngested() + recvIngested() + recvIngested() + + clk.BlockUntil(1) + clk.Advance(botInstanceActivityReportGranularity) + + require.Equal(t, types.OpPut, recvBackendEvent().Type) + require.Equal(t, types.OpPut, recvBackendEvent().Type) + + userActivityReports, err := svc.listUserActivityReports(ctx, 10) + require.NoError(t, err) + require.Len(t, userActivityReports, 1) + require.Len(t, userActivityReports[0].Records, 1) + userActivityRecord := userActivityReports[0].Records[0] + require.Equal(t, uint64(1), userActivityRecord.BotJoins) + require.Equal(t, uint64(2), userActivityRecord.SpiffeSvidsIssued) + require.Equal(t, uint64(1), userActivityRecord.CertificatesIssued) + + botInstanceActivityReports, err := svc.listBotInstanceActivityReports(ctx, 10) + require.NoError(t, err) + require.Len(t, botInstanceActivityReports, 1) + require.Len(t, botInstanceActivityReports[0].Records, 2) + for _, record := range botInstanceActivityReports[0].Records { + require.Equal(t, userActivityRecord.UserName, record.BotUserName) + } + require.True(t, slices.ContainsFunc(botInstanceActivityReports[0].Records, func(record *prehogv1.BotInstanceActivityRecord) bool { + return record.BotJoins == 1 && record.CertificatesIssued == 1 && record.SpiffeSvidsIssued == 1 + })) + require.True(t, slices.ContainsFunc(botInstanceActivityReports[0].Records, func(record *prehogv1.BotInstanceActivityRecord) bool { + return record.BotJoins == 0 && record.CertificatesIssued == 0 && record.SpiffeSvidsIssued == 1 + })) +} diff --git a/lib/usagereporter/teleport/aggregating/service.go b/lib/usagereporter/teleport/aggregating/service.go index 586688826cc12..c215b2fa9b976 100644 --- a/lib/usagereporter/teleport/aggregating/service.go +++ b/lib/usagereporter/teleport/aggregating/service.go @@ -39,8 +39,12 @@ const ( ) const ( - userActivityReportsPrefix = "userActivityReports" - userActivityReportsLock = "userActivityReportsLock" + botInstanceActivityReportsPrefix = "botInstanceActivityReports" + userActivityReportsPrefix = "userActivityReports" + // usageReportingLock is a lock that should be held when submitting usage + // reports to the upstream service. Whilst the underlying key refers + // specifically to "userActivityReports", this is inaccurate. + usageReportingLock = "userActivityReportsLock" ResourcePresenceReportsPrefix = "resourcePresenceReports" ) @@ -164,6 +168,42 @@ func prepareResourcePresenceReports( return reports, nil } +// botInstanceActivityReportKey returns the backend key for a bot instance +// activity report with a given UUID and start time, such that reports with +// an earlier start time will appear earlier in lexicographic ordering. +func botInstanceActivityReportKey(reportUUID uuid.UUID, startTime time.Time) backend.Key { + return backend.NewKey(botInstanceActivityReportsPrefix, startTime.Format(time.RFC3339), reportUUID.String()) +} + +func prepareBotInstanceActivityReports( + clusterName, reporterHostID []byte, + startTime time.Time, records []*prehogv1.BotInstanceActivityRecord, +) (reports []*prehogv1.BotInstanceActivityReport, err error) { + for len(records) > 0 { + reportUUID := uuid.New() + report := &prehogv1.BotInstanceActivityReport{ + ReportUuid: reportUUID[:], + ClusterName: clusterName, + ReporterHostid: reporterHostID, + StartTime: timestamppb.New(startTime), + Records: records, + } + + for proto.Size(report) > maxItemSize { + if len(report.Records) <= 1 { + return nil, trace.LimitExceeded("failed to marshal bot instance activity report within size limit (this is a bug)") + } + + report.Records = report.Records[:len(report.Records)/2] + } + + records = records[len(report.Records):] + reports = append(reports, report) + } + + return reports, nil +} + // reportService is a [backend.Backend] wrapper that handles usage reports. type reportService struct { b backend.Backend @@ -236,16 +276,18 @@ func (r reportService) listUserActivityReports(ctx context.Context, count int) ( return reports, nil } -func (r reportService) createUserActivityReportsLock(ctx context.Context, ttl time.Duration, payload []byte) error { +// createUsageReportingLock creates a lock that should be held when reading +// reports and submitting them to the upstream service. +func (r reportService) createUsageReportingLock(ctx context.Context, ttl time.Duration, payload []byte) error { if len(payload) == 0 { payload = []byte("null") } - lockKey := backend.NewKey(userActivityReportsLock) + lockKey := backend.NewKey(usageReportingLock) // HACK(espadolini): dynamodbbk doesn't let you Create over an expired item // but it will explicitly delete expired items on a Get; in addition, reads // are cheaper than writes in most backends, so we do a Get here first if _, err := r.b.Get(ctx, lockKey); err == nil { - return trace.AlreadyExists(userActivityReportsLock + " already exists") + return trace.AlreadyExists(usageReportingLock + " already exists") } else if !trace.IsNotFound(err) { return trace.Wrap(err) } @@ -326,3 +368,76 @@ func (r reportService) listResourcePresenceReports(ctx context.Context, count in return reports, nil } + +func (r reportService) upsertBotInstanceActivityReport( + ctx context.Context, report *prehogv1.BotInstanceActivityReport, ttl time.Duration, +) error { + wire, err := proto.Marshal(report) + if err != nil { + return trace.Wrap(err) + } + + reportUUID, err := uuid.FromBytes(report.GetReportUuid()) + if err != nil { + return trace.Wrap(err) + } + + startTime := report.GetStartTime().AsTime() + if startTime.IsZero() { + return trace.BadParameter("missing start_time") + } + + if _, err := r.b.Put(ctx, backend.Item{ + Key: botInstanceActivityReportKey(reportUUID, startTime), + Value: wire, + Expires: startTime.Add(ttl), + }); err != nil { + return trace.Wrap(err) + } + + return nil +} + +func (r reportService) deleteBotInstanceActivityReport( + ctx context.Context, report *prehogv1.BotInstanceActivityReport, +) error { + reportUUID, err := uuid.FromBytes(report.GetReportUuid()) + if err != nil { + return trace.Wrap(err) + } + + startTime := report.GetStartTime().AsTime() + if startTime.IsZero() { + return trace.BadParameter("missing start_time") + } + + if err := r.b.Delete(ctx, botInstanceActivityReportKey(reportUUID, startTime)); err != nil { + return trace.Wrap(err) + } + + return nil +} + +// listBotInstanceActivityReports returns the first `count` user activity reports +// according to the key order; as we store them with time and uuid in the key, +// this results in returning earlier reports first. +func (r reportService) listBotInstanceActivityReports( + ctx context.Context, count int, +) ([]*prehogv1.BotInstanceActivityReport, error) { + rangeStart := backend.ExactKey(botInstanceActivityReportsPrefix) + result, err := r.b.GetRange(ctx, rangeStart, backend.RangeEnd(rangeStart), count) + if err != nil { + return nil, trace.Wrap(err) + } + + reports := make([]*prehogv1.BotInstanceActivityReport, 0, len(result.Items)) + for _, item := range result.Items { + report := &prehogv1.BotInstanceActivityReport{} + if err := proto.Unmarshal(item.Value, report); err != nil { + return nil, trace.Wrap(err) + } + reports = append(reports, report) + } + + return reports, nil +} diff --git a/lib/usagereporter/teleport/aggregating/service_test.go b/lib/usagereporter/teleport/aggregating/service_test.go index 9d075743b0779..6bccb56432b17 100644 --- a/lib/usagereporter/teleport/aggregating/service_test.go +++ b/lib/usagereporter/teleport/aggregating/service_test.go @@ -125,13 +125,13 @@ func TestLock(t *testing.T) { svc := reportService{bk} - require.NoError(t, svc.createUserActivityReportsLock(ctx, 2*time.Minute, nil)) + require.NoError(t, svc.createUsageReportingLock(ctx, 2*time.Minute, nil)) clk.Advance(time.Minute) - err = svc.createUserActivityReportsLock(ctx, 2*time.Minute, nil) + err = svc.createUsageReportingLock(ctx, 2*time.Minute, nil) require.Error(t, err) require.True(t, trace.IsAlreadyExists(err)) clk.Advance(time.Minute) - require.NoError(t, svc.createUserActivityReportsLock(ctx, 2*time.Minute, nil)) + require.NoError(t, svc.createUsageReportingLock(ctx, 2*time.Minute, nil)) } func newResourcePresenceReport(startTime time.Time) *prehogv1.ResourcePresenceReport { @@ -210,3 +210,28 @@ func TestResourcePresenceReportSplitting(t *testing.T) { "resource ids for resource kind %v do not match", resKindReport.ResourceKind) } } + +func TestBotInstanceActivityReportSplitting(t *testing.T) { + recordCount := 10000 + records := make([]*prehogv1.BotInstanceActivityRecord, 0, recordCount) + for i := 0; i < recordCount; i++ { + records = append(records, &prehogv1.BotInstanceActivityRecord{ + BotUserName: []byte("user"), + BotInstanceId: []byte("foo"), + BotJoins: 1000, + }) + } + reports, err := prepareBotInstanceActivityReports( + []byte("clusterName"), []byte("reporterHostID"), time.Now(), records, + ) + require.NoError(t, err) + require.GreaterOrEqual(t, len(reports), 2) // some reports were split into two + require.GreaterOrEqual(t, len(reports[0].Records), 2) // first report was able to contain a few user activity records + + // reassemble records and ensure that nothing was lost + recordsCopy := make([]*prehogv1.BotInstanceActivityRecord, 0, recordCount) + for _, report := range reports { + recordsCopy = append(recordsCopy, report.Records...) + } + require.Equal(t, records, recordsCopy, "some bot instance activity records have been lost during splitting") +} diff --git a/lib/usagereporter/teleport/aggregating/submitter.go b/lib/usagereporter/teleport/aggregating/submitter.go index ebb43942da2f4..4d4e9dae1b118 100644 --- a/lib/usagereporter/teleport/aggregating/submitter.go +++ b/lib/usagereporter/teleport/aggregating/submitter.go @@ -140,7 +140,17 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { } } - totalReportCount := len(userActivityReports) + len(resourcePresenceReports) + freeBatchSize = submitBatchSize - len(userActivityReports) - len(resourcePresenceReports) + var botInstanceActivityReports []*prehogv1.BotInstanceActivityReport + if freeBatchSize > 0 { + botInstanceActivityReports, err = svc.listBotInstanceActivityReports(ctx, freeBatchSize) + if err != nil { + c.Logger.ErrorContext(ctx, "Failed to load bot instance activity reports for submission.", "error", err) + return + } + } + + totalReportCount := len(userActivityReports) + len(resourcePresenceReports) + len(botInstanceActivityReports) if totalReportCount < 1 { err := ClearAlert(ctx, c.Status) @@ -170,13 +180,21 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { newest = t } } + if len(botInstanceActivityReports) > 0 { + if t := botInstanceActivityReports[0].GetStartTime().AsTime(); t.Before(oldest) { + oldest = t + } + if t := botInstanceActivityReports[len(botInstanceActivityReports)-1].GetStartTime().AsTime(); t.After(newest) { + newest = t + } + } debugPayload := fmt.Sprintf("%v %q", time.Now().Round(0), c.HostID) - if err := svc.createUserActivityReportsLock(ctx, submitLockDuration, []byte(debugPayload)); err != nil { + if err := svc.createUsageReportingLock(ctx, submitLockDuration, []byte(debugPayload)); err != nil { if trace.IsAlreadyExists(err) { - c.Logger.DebugContext(ctx, "Failed to acquire lock, already held.", "lock", userActivityReportsLock) + c.Logger.DebugContext(ctx, "Failed to acquire lock, already held.", "lock", usageReportingLock) } else { - c.Logger.ErrorContext(ctx, "Failed to acquire lock.", "lock", userActivityReportsLock, "error", err) + c.Logger.ErrorContext(ctx, "Failed to acquire lock.", "lock", usageReportingLock, "error", err) } return } @@ -185,8 +203,9 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { defer cancel() batchUUID, err := c.Submitter(lockCtx, &prehogv1.SubmitUsageReportsRequest{ - UserActivity: userActivityReports, - ResourcePresence: resourcePresenceReports, + UserActivity: userActivityReports, + ResourcePresence: resourcePresenceReports, + BotInstanceActivity: botInstanceActivityReports, }) if err != nil { c.Logger.ErrorContext(ctx, "Failed to send usage reports.", @@ -236,6 +255,11 @@ func submitOnce(ctx context.Context, c SubmitterConfig) { lastErr = err } } + for _, report := range botInstanceActivityReports { + if err := svc.deleteBotInstanceActivityReport(ctx, report); err != nil { + lastErr = err + } + } if lastErr != nil { c.Logger.WarnContext(ctx, "Failed to delete some usage reports after successful send.", "last_error", lastErr) } diff --git a/lib/usagereporter/teleport/audit.go b/lib/usagereporter/teleport/audit.go index b846472521564..a1108374bb3fc 100644 --- a/lib/usagereporter/teleport/audit.go +++ b/lib/usagereporter/teleport/audit.go @@ -194,6 +194,7 @@ func ConvertAuditEvent(event apievents.AuditEvent) Anonymizable { JoinMethod: e.Method, JoinTokenName: e.TokenName, UserName: e.UserName, + BotInstanceId: e.BotInstanceID, } case *apievents.DeviceEvent2: @@ -269,12 +270,13 @@ func ConvertAuditEvent(event apievents.AuditEvent) Anonymizable { } case *apievents.SPIFFESVIDIssued: return &SPIFFESVIDIssuedEvent{ - UserName: e.User, - UserKind: prehogUserKindFromEventKind(e.UserKind), - SpiffeId: e.SPIFFEID, - IpSansCount: int32(len(e.IPSANs)), - DnsSansCount: int32(len(e.DNSSANs)), - SvidType: e.SVIDType, + UserName: e.User, + UserKind: prehogUserKindFromEventKind(e.UserKind), + SpiffeId: e.SPIFFEID, + IpSansCount: int32(len(e.IPSANs)), + DnsSansCount: int32(len(e.DNSSANs)), + SvidType: e.SVIDType, + BotInstanceId: e.BotInstanceID, } case *apievents.DatabaseUserCreate: return &DatabaseUserCreatedEvent{ diff --git a/lib/usagereporter/teleport/types.go b/lib/usagereporter/teleport/types.go index 43729db3baed4..3b783f73b55e1 100644 --- a/lib/usagereporter/teleport/types.go +++ b/lib/usagereporter/teleport/types.go @@ -71,6 +71,7 @@ func (u *BotJoinEvent) Anonymize(a utils.Anonymizer) prehogv1a.SubmitEventReques JoinTokenName: a.AnonymizeString(u.JoinTokenName), JoinMethod: u.JoinMethod, UserName: a.AnonymizeString(u.UserName), + BotInstanceId: a.AnonymizeString(u.BotInstanceId), }, }, } @@ -516,18 +517,22 @@ func (u *UICallToActionClickEvent) Anonymize(a utils.Anonymizer) prehogv1a.Submi type UserCertificateIssuedEvent prehogv1a.UserCertificateIssuedEvent func (u *UserCertificateIssuedEvent) Anonymize(a utils.Anonymizer) prehogv1a.SubmitEventRequest { + e := &prehogv1a.UserCertificateIssuedEvent{ + UserName: a.AnonymizeString(u.UserName), + Ttl: u.Ttl, + IsBot: u.IsBot, + UsageDatabase: u.UsageDatabase, + UsageApp: u.UsageApp, + UsageKubernetes: u.UsageKubernetes, + UsageDesktop: u.UsageDesktop, + PrivateKeyPolicy: u.PrivateKeyPolicy, + } + if u.BotInstanceId != "" { + e.BotInstanceId = a.AnonymizeString(u.BotInstanceId) + } return prehogv1a.SubmitEventRequest{ Event: &prehogv1a.SubmitEventRequest_UserCertificateIssuedEvent{ - UserCertificateIssuedEvent: &prehogv1a.UserCertificateIssuedEvent{ - UserName: a.AnonymizeString(u.UserName), - Ttl: u.Ttl, - IsBot: u.IsBot, - UsageDatabase: u.UsageDatabase, - UsageApp: u.UsageApp, - UsageKubernetes: u.UsageKubernetes, - UsageDesktop: u.UsageDesktop, - PrivateKeyPolicy: u.PrivateKeyPolicy, - }, + UserCertificateIssuedEvent: e, }, } } @@ -1274,16 +1279,20 @@ func (u *DatabaseUserPermissionsUpdateEvent) Anonymize(a utils.Anonymizer) preho type SPIFFESVIDIssuedEvent prehogv1a.SPIFFESVIDIssuedEvent func (u *SPIFFESVIDIssuedEvent) Anonymize(a utils.Anonymizer) prehogv1a.SubmitEventRequest { + e := &prehogv1a.SPIFFESVIDIssuedEvent{ + UserName: a.AnonymizeString(u.UserName), + UserKind: u.UserKind, + SpiffeId: a.AnonymizeString(u.SpiffeId), + IpSansCount: u.IpSansCount, + DnsSansCount: u.DnsSansCount, + SvidType: u.SvidType, + } + if u.BotInstanceId != "" { + e.BotInstanceId = a.AnonymizeString(u.BotInstanceId) + } return prehogv1a.SubmitEventRequest{ Event: &prehogv1a.SubmitEventRequest_SpiffeSvidIssued{ - SpiffeSvidIssued: &prehogv1a.SPIFFESVIDIssuedEvent{ - UserName: a.AnonymizeString(u.UserName), - UserKind: u.UserKind, - SpiffeId: a.AnonymizeString(u.SpiffeId), - IpSansCount: u.IpSansCount, - DnsSansCount: u.DnsSansCount, - SvidType: u.SvidType, - }, + SpiffeSvidIssued: e, }, } } diff --git a/proto/prehog/v1/teleport.proto b/proto/prehog/v1/teleport.proto index 2afb47fb95f72..821e8f1c1e8ad 100644 --- a/proto/prehog/v1/teleport.proto +++ b/proto/prehog/v1/teleport.proto @@ -182,6 +182,57 @@ message ResourceKindPresenceReport { repeated fixed64 resource_ids = 2; } +// counters for bot instance activity coming from a specific auth server from a +// specific cluster. +// +// PostHog event: tp.bot_instance.activity +message BotInstanceActivityReport { + // randomly generated UUID for this specific report, 16 bytes (in string order) + // + // PostHog property: tp.report_uuid (in 8-4-4-4-12 string form) + bytes report_uuid = 1; + + // cluster name, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.cluster_name (in base64) + bytes cluster_name = 2; + + // hostid of the auth that collected this report, anonymized, 32 bytes (HMAC-SHA-256) + // + // PostHog property: tp.reporter_hostid (in base64) + bytes reporter_hostid = 3; + + // beginning of the time window for this data; ending is not specified but is + // intended to be at most 15 minutes + // + // PostHog timestamp (not a property, the ingest time is tp.report_time instead) + google.protobuf.Timestamp start_time = 4; + + // one set of counters for each bot instance + // + // PostHog property: tp.records (encoded as a map keyed by anonymized bot + // instance id, not as a list) + repeated BotInstanceActivityRecord records = 5; +} + +// Records the activity for a single bot instance against a specific auth server +// from a specific cluster. +message BotInstanceActivityRecord { + // The UUID of the BotInstance, anonymized using HMAC-SHA-256. + bytes bot_instance_id = 1; + // The name of the user associated with the BotInstance, + // anonymized using HMAC-SHA-256. + // Enables correlation with the UserActivityRecord for the Bot. + bytes bot_user_name = 2; + + // counter of bot joins + uint64 bot_joins = 3; + // counter of SPIFFE SVIDs issued + uint64 spiffe_svids_issued = 4; + // counter of certificates issued for this user + uint64 certificates_issued = 5; +} + message SubmitUsageReportsRequest { // at most 10 reports of all kinds in a single RPC, each shouldn't exceed 128KiB or so // @@ -189,6 +240,8 @@ message SubmitUsageReportsRequest { repeated UserActivityReport user_activity = 1; // encoded as a separate tp.resource.counts PostHog event repeated ResourcePresenceReport resource_presence = 2; + // encoded as a seperate tp.bot_instance.activity PostHog event + repeated BotInstanceActivityReport bot_instance_activity = 3; } message SubmitUsageReportsResponse { // randomly generated UUID for this specific batch, 16 bytes (in string order) diff --git a/proto/prehog/v1alpha/teleport.proto b/proto/prehog/v1alpha/teleport.proto index 9d2d2b78282d3..2c83c29946388 100644 --- a/proto/prehog/v1alpha/teleport.proto +++ b/proto/prehog/v1alpha/teleport.proto @@ -300,6 +300,10 @@ message UserCertificateIssuedEvent { // the private key policy associated with these user certificates. string private_key_policy = 8; + + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + string bot_instance_id = 9; } // the issuance of a SPIFFE SVID @@ -332,6 +336,10 @@ message SPIFFESVIDIssuedEvent { // Type of SVID issued. `x509` or `jwt` // PostHog property: tp.spiffe.svid_type string svid_type = 6; + + // bot_instance_id is the anonymized instance id of the bot, if the user is + // a Bot. + string bot_instance_id = 7; } // UIBannerClickEvent is a usage event sent by the UI when the upgrade @@ -743,6 +751,8 @@ message BotJoinEvent { string join_token_name = 3; // user_name is the anonymised name of the Bot user. string user_name = 4; + // bot_instance_id is the anonymized instance id of the bot. + string bot_instance_id = 5; } // UICreateNewRoleClickEvent is an event that can be triggered during custom role creation From 86773c1109a0e652c4dc822a34bf02aaec636568 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 30 Jan 2025 14:51:47 +0000 Subject: [PATCH 11/28] kube: fix race when unregistering kube cluster (#51641) PR #51448 replaced the `x/exp/maps` with stdlib `maps` but there is a subtle change, the `x/exp/maps` automatically collects the map values when `maps.Values` and the stdlib package returns an iterator. Since we were collecting the values under a lock, the iterator approach doesn't held the lock during actual map range causing a datarace with other code. This PR fixes that by collecting the iterator values while holding the lock. Fixes #51572 Signed-off-by: Tiago Silva --- lib/kube/proxy/watcher.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/kube/proxy/watcher.go b/lib/kube/proxy/watcher.go index 8b46dce5240e7..0c8587ff6e0d9 100644 --- a/lib/kube/proxy/watcher.go +++ b/lib/kube/proxy/watcher.go @@ -21,6 +21,7 @@ package proxy import ( "context" "maps" + "slices" "sync" "time" @@ -238,10 +239,11 @@ func (s *TLSServer) unregisterKubeCluster(ctx context.Context, name string) erro // close active sessions before returning. s.fwd.mu.Lock() - sessions := maps.Values(s.fwd.sessions) + // collect all sessions to avoid holding the lock while closing them + sessions := slices.Collect(maps.Values(s.fwd.sessions)) s.fwd.mu.Unlock() // close active sessions - for sess := range sessions { + for _, sess := range sessions { if sess.ctx.kubeClusterName == name { // TODO(tigrato): check if we should send errors to each client errs = append(errs, sess.Close()) From 0380866cb322045764f84259d57d059c8ad20bd8 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 30 Jan 2025 14:51:51 +0000 Subject: [PATCH 12/28] kube: fix transport being incorrectly cached by kube service (#51640) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #46899 introduced a subtle change in Kubernetes service behavior, where the direct transport—kube agent to Kubernetes API—is now cached for five hours. This disrupts auto-discovery because tokens are only valid for 15 minutes, while the HTTP transport that applies them remains valid for five hours. As a result, the Kubernetes service continues using the same expired token for 4 hours and 45 minutes. This PR resolves the issue by preventing token caching altogether. Fixes #51639 Signed-off-by: Tiago Silva --- lib/kube/proxy/kube_creds.go | 2 +- lib/kube/proxy/transport.go | 13 +++++++--- lib/kube/proxy/transport_test.go | 44 ++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/lib/kube/proxy/kube_creds.go b/lib/kube/proxy/kube_creds.go index fd7e367d5f8cf..e646920563a99 100644 --- a/lib/kube/proxy/kube_creds.go +++ b/lib/kube/proxy/kube_creds.go @@ -236,7 +236,7 @@ func newDynamicKubeCreds(ctx context.Context, cfg dynamicCredsConfig) (*dynamicK func (d *dynamicKubeCreds) getTLSConfig() *tls.Config { d.RLock() defer d.RUnlock() - return d.staticCreds.tlsConfig + return d.staticCreds.getTLSConfig() } func (d *dynamicKubeCreds) getTransportConfig() *transport.Config { diff --git a/lib/kube/proxy/transport.go b/lib/kube/proxy/transport.go index 87217b39a0a4b..5821bbd229553 100644 --- a/lib/kube/proxy/transport.go +++ b/lib/kube/proxy/transport.go @@ -59,6 +59,15 @@ type dialContextFunc func(context.Context, string, string) (net.Conn, error) // The transport is cached in the forwarder so that it can be reused for future // requests. If the transport is not cached, a new one is created and cached. func (f *Forwarder) transportForRequestWithImpersonation(sess *clusterSession) (http.RoundTripper, *tls.Config, error) { + // If the session has a kube API credentials, it means that the next hop is + // a Kubernetes API server. In this case, we can use the provided credentials + // to dial the next hop directly and never cache the transport. + if sess.kubeAPICreds != nil { + // If agent is running in agent mode, get the transport from the configured cluster + // credentials. + return sess.kubeAPICreds.getTransport(), sess.kubeAPICreds.getTLSConfig(), nil + } + // If the cluster is remote, the key is the teleport cluster name. // If the cluster is local, the key is the teleport cluster name and the kubernetes // cluster name: /. @@ -73,10 +82,6 @@ func (f *Forwarder) transportForRequestWithImpersonation(sess *clusterSession) ( if sess.teleportCluster.isRemote { // If the cluster is remote, create a new transport for the remote cluster. httpTransport, tlsConfig, err = f.newRemoteClusterTransport(sess.teleportCluster.name) - } else if sess.kubeAPICreds != nil { - // If agent is running in agent mode, get the transport from the configured cluster - // credentials. - httpTransport, tlsConfig = sess.kubeAPICreds.getTransport(), sess.kubeAPICreds.getTLSConfig() } else if f.cfg.ReverseTunnelSrv != nil { // If agent is running in proxy mode, create a new transport for the local cluster. httpTransport, tlsConfig, err = f.newLocalClusterTransport(sess.kubeClusterName) diff --git a/lib/kube/proxy/transport_test.go b/lib/kube/proxy/transport_test.go index 88af58d7649c4..2f057a74a263a 100644 --- a/lib/kube/proxy/transport_test.go +++ b/lib/kube/proxy/transport_test.go @@ -20,10 +20,12 @@ package proxy import ( "context" + "crypto/tls" "fmt" "net" "testing" + "github.com/jonboulle/clockwork" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" @@ -137,3 +139,45 @@ func newKubeServerWithProxyIDs(t *testing.T, hostname, hostID string, proxyIds [ ks.Spec.ProxyIDs = proxyIds return ks } + +func TestDirectTransportNotCached(t *testing.T) { + t.Parallel() + + transportClients, err := utils.NewFnCache(utils.FnCacheConfig{ + TTL: transportCacheTTL, + Clock: clockwork.NewFakeClock(), + }) + require.NoError(t, err) + + forwarder := &Forwarder{ + ctx: context.Background(), + cachedTransport: transportClients, + } + + kubeAPICreds := &dynamicKubeCreds{ + staticCreds: &staticKubeCreds{ + tlsConfig: &tls.Config{ + ServerName: "localhost", + }, + }, + } + + clusterSess := &clusterSession{ + kubeAPICreds: kubeAPICreds, + authContext: authContext{ + kubeClusterName: "b", + teleportCluster: teleportClusterClient{ + name: "a", + }, + }, + } + + _, tlsConfig, err := forwarder.transportForRequestWithImpersonation(clusterSess) + require.NoError(t, err) + require.Equal(t, "localhost", tlsConfig.ServerName) + + kubeAPICreds.staticCreds.tlsConfig.ServerName = "example.com" + _, tlsConfig, err = forwarder.transportForRequestWithImpersonation(clusterSess) + require.NoError(t, err) + require.Equal(t, "example.com", tlsConfig.ServerName) +} From 3b1c68947da83f8128e11a14f34e6a5c46f12c41 Mon Sep 17 00:00:00 2001 From: Grzegorz Zdunek Date: Thu, 30 Jan 2025 16:28:05 +0100 Subject: [PATCH 13/28] Store profile color in workspace (#51417) * Adjust workspace tests to accept persisted workspace type * Store profile color in workspace * Replace manual workspace creation in stories/tests with `addRootClusterWithDoc` * Fix checking if all colors are taken * Add DELETE IN comment * `ProfileColor` -> `WorkspaceColor` * Lint * Prettier * Add TODO about creating workspaces in `setActiveWorkspace` --- .../jest/jest-environment-patched-jsdom.js | 14 ++ .../useAssumedRolesBar.test.tsx | 10 +- .../ClusterConnect/ClusterAdd/ClusterAdd.tsx | 3 +- .../DocumentConnectMyComputer/Setup.story.tsx | 14 +- .../DocumentConnectMyComputer/Setup.test.tsx | 11 +- .../Status.story.tsx | 16 +-- .../NavigationMenu.story.tsx | 13 +- .../connectMyComputerContext.test.tsx | 14 +- .../DocumentAccessRequests.story.tsx | 72 ++-------- .../DocumentAuthorizeWebSession.test.tsx | 12 +- .../DocumentCluster/DocumentCluster.story.tsx | 124 +++++------------ .../DocumentCluster/DocumentCluster.test.tsx | 105 +++++---------- .../DocumentCluster/UnifiedResources.test.tsx | 68 +++------- .../ui/DocumentGateway/useGateway.test.tsx | 13 +- .../DocumentGatewayApp.story.tsx | 18 +-- .../DocumentGatewayKube.story.tsx | 21 +-- .../teleterm/src/ui/Search/SearchBar.test.tsx | 19 +-- .../src/ui/Search/SearchContext.test.tsx | 20 +-- .../Search/pickers/useDisplayResults.test.tsx | 43 ++---- .../teleterm/src/ui/TabHost/TabHost.test.tsx | 22 +-- .../src/ui/TabHost/useTabShortcuts.test.tsx | 11 +- .../src/ui/TopBar/Identity/Identity.test.tsx | 28 +--- .../teleterm/src/ui/fixtures/mocks.ts | 12 +- .../connectionTrackerService.legacy.test.ts | 1 + .../statePersistenceService.ts | 19 ++- .../ui/services/workspacesService/color.ts | 69 ++++++++++ .../ui/services/workspacesService/index.ts | 1 + .../workspacesService.test.ts | 125 +++++++++++++++--- .../workspacesService/workspacesService.ts | 42 +++++- 29 files changed, 401 insertions(+), 539 deletions(-) create mode 100644 web/packages/teleterm/src/ui/services/workspacesService/color.ts diff --git a/web/packages/build/jest/jest-environment-patched-jsdom.js b/web/packages/build/jest/jest-environment-patched-jsdom.js index c5d45a7bdc92b..2f27f8a302450 100644 --- a/web/packages/build/jest/jest-environment-patched-jsdom.js +++ b/web/packages/build/jest/jest-environment-patched-jsdom.js @@ -66,6 +66,20 @@ export default class PatchedJSDOMEnvironment extends JSDOMEnvironment { global.AbortSignal = AbortSignal; global.AbortController = AbortController; } + // TODO(gzdunek): Remove when JSDOM supports Set.prototype.difference. + // After the update to Node.js 22, we can replace the implementation with + // global.Set.prototype.difference = Set.prototype.difference. + if (!global.Set.difference) { + global.Set.prototype.difference = function (otherSet) { + const result = new Set(); + for (const value of this) { + if (!otherSet.has(value)) { + result.add(value); + } + } + return result; + }; + } } } export const TestEnvironment = PatchedJSDOMEnvironment; diff --git a/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx b/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx index d0bcc2dcba6f0..0cf1cd9cfd0dc 100644 --- a/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx +++ b/web/packages/teleterm/src/ui/AccessRequestCheckout/useAssumedRolesBar.test.tsx @@ -33,15 +33,7 @@ import { useAssumedRolesBar } from './useAssumedRolesBar'; test('dropping a request refreshes resources', async () => { const appContext = new MockAppContext(); const cluster = makeRootCluster(); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); jest.spyOn(appContext.clustersService, 'dropRoles'); const refreshListener = jest.fn(); diff --git a/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx b/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx index 68d96c1c0bb95..e2d6303bb7313 100644 --- a/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx +++ b/web/packages/teleterm/src/ui/ClusterConnect/ClusterAdd/ClusterAdd.tsx @@ -35,11 +35,12 @@ export function ClusterAdd(props: { onSuccess(clusterUri: string): void; prefill: { clusterAddress: string }; }) { - const { clustersService } = useAppContext(); + const { clustersService, workspacesService } = useAppContext(); const [{ status, statusText }, addCluster] = useAsync( async (addr: string) => { const proxyAddr = parseClusterProxyWebAddr(addr); const cluster = await clustersService.addRootCluster(proxyAddr); + workspacesService.addWorkspace(cluster.uri); return props.onSuccess(cluster.uri); } ); diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx index 4d1ab55176e3a..d41968fef69ec 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.story.tsx @@ -27,7 +27,6 @@ import { ResourcesContextProvider } from 'teleterm/ui/DocumentCluster/resourcesC import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { IAppContext } from 'teleterm/ui/types'; import { ConnectMyComputerContextProvider } from '../connectMyComputerContext'; import { Setup } from './Setup'; @@ -153,20 +152,11 @@ function ShowState({ clickStartSetup = true, }: { cluster: Cluster; - appContext: IAppContext; + appContext: MockAppContext; clickStartSetup?: boolean; }) { if (!appContext.clustersService.state.clusters.get(cluster.uri)) { - appContext.clustersService.state.clusters.set(cluster.uri, cluster); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); } useLayoutEffect(() => { 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 41912c9b4adc6..e8e96e1e49c6b 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Setup.test.tsx @@ -131,16 +131,7 @@ function setupAppContext(): { const appContext = new MockAppContext({ appVersion: cluster.proxyVersion, }); - appContext.clustersService.state.clusters.set(cluster.uri, cluster); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); jest .spyOn(appContext.mainProcessClient, 'isAgentConfigFileCreated') diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx index fe659cd9ee305..84aa769bd2a80 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/DocumentConnectMyComputer/Status.story.tsx @@ -25,7 +25,6 @@ import { makeRootCluster, makeServer, } from 'teleterm/services/tshd/testHelpers'; -import AppContext from 'teleterm/ui/appContext'; import { ResourcesContextProvider } from 'teleterm/ui/DocumentCluster/resourcesContext'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; @@ -236,7 +235,7 @@ export function UpgradeAgentSuggestion() { function ShowState(props: { agentProcessState: AgentProcessState; - appContext?: AppContext; + appContext?: MockAppContext; proxyVersion?: string; autoStart?: boolean; }) { @@ -248,18 +247,7 @@ function ShowState(props: { new MockAppContext({ appVersion: cluster.proxyVersion }); appContext.mainProcessClient.getAgentState = () => props.agentProcessState; - appContext.clustersService.state.clusters.set(cluster.uri, cluster); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces = { - [cluster.uri]: { - localClusterUri: cluster.uri, - documents: [], - location: '/docs/1234', - accessRequests: undefined, - }, - }; - }); + appContext.addRootCluster(cluster); if (props.autoStart) { appContext.workspacesService.setConnectMyComputerAutoStart( diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx index c3f037e9151f4..b0d85e60b53b0 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.story.tsx @@ -32,7 +32,7 @@ export default { title: 'Teleterm/ConnectMyComputer/NavigationMenu', }; -export function AgenNotConfigured() { +export function AgentNotConfigured() { return ( { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - localClusterUri: cluster.uri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(cluster); appContext.mainProcessClient.getAgentState = () => agentProcessState; appContext.connectMyComputerService.isAgentConfigFileCreated = diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx index ee0a84a9272c2..86674bb9d8a49 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/connectMyComputerContext.test.tsx @@ -65,19 +65,7 @@ function getMocks() { const appContext = new MockAppContext({ appVersion: rootCluster.proxyVersion, }); - - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, rootCluster); - }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - documents: [], - location: undefined, - localClusterUri: rootCluster.uri, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(rootCluster); return { appContext, rootCluster }; } diff --git a/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx b/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx index fc0c623198ae0..c9325fb5ce68e 100644 --- a/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentAccessRequests/DocumentAccessRequests.story.tsx @@ -27,7 +27,6 @@ import { ResourcesContextProvider } from 'teleterm/ui/DocumentCluster/resourcesC import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; import * as types from 'teleterm/ui/services/workspacesService'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; const rootCluster = makeRootCluster(); @@ -89,18 +88,7 @@ export function Browsing() { startKey: '', requests: [mockedAccessRequest], }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, [doc]); return ( @@ -117,21 +105,7 @@ export function BrowsingError() { const appContext = new MockAppContext(); appContext.tshd.getAccessRequests = () => new MockedUnaryCall(null, new Error('network error')); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, rootCluster); - }); + appContext.addRootClusterWithDoc(rootCluster, [doc]); return ( @@ -156,24 +130,13 @@ export function CreatingWhenUnifiedResourcesShowOnlyAccessibleResources() { startKey: '', requests: [mockedAccessRequest], }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: docCreating.clusterUri, - documents: [docCreating], - location: docCreating.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, { + appContext.addRootClusterWithDoc( + { ...rootCluster, showResources: ShowResources.ACCESSIBLE_ONLY, - }); - }); + }, + [doc] + ); return ( @@ -198,24 +161,13 @@ export function CreatingWhenUnifiedResourcesShowRequestableAndAccessibleResource startKey: '', requests: [mockedAccessRequest], }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: docCreating.clusterUri, - documents: [docCreating], - location: docCreating.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - appContext.clustersService.setState(draftState => { - draftState.clusters.set(rootCluster.uri, { + appContext.addRootClusterWithDoc( + { ...rootCluster, showResources: ShowResources.REQUESTABLE, - }); - }); + }, + [doc] + ); return ( diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx index 59246adf0cf32..df3af448a8d04 100644 --- a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx @@ -95,17 +95,7 @@ test('authorizing a session opens its URL and closes document', async () => { 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, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, doc); render( diff --git a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx index b1043c9600789..2ad72ab0e928d 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.story.tsx @@ -35,16 +35,10 @@ import AppContextProvider from 'teleterm/ui/appContextProvider'; import { ConnectMyComputerContextProvider } from 'teleterm/ui/ConnectMyComputer'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { - ClustersServiceState, - createClusterServiceState, -} from 'teleterm/ui/services/clusters'; import { ResourcesService } from 'teleterm/ui/services/resources'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; import * as docTypes from 'teleterm/ui/services/workspacesService/documentsService/types'; import { ConnectionsContextProvider } from 'teleterm/ui/TopBar/Connections/connectionsContext'; -import { routing } from 'teleterm/ui/uri'; import { VnetContextProvider } from 'teleterm/ui/Vnet'; import DocumentCluster from './DocumentCluster'; @@ -65,16 +59,10 @@ const leafClusterDoc = makeDocumentCluster({ }); export const OnlineLoadedResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ - uri: rootClusterDoc.clusterUri, - }) - ); - return renderState({ - state, + cluster: makeRootCluster({ + uri: rootClusterDoc.clusterUri, + }), doc: rootClusterDoc, listUnifiedResources: () => Promise.resolve({ @@ -161,10 +149,8 @@ export const OnlineLoadedResources = () => { }; export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.LOCAL, @@ -179,11 +165,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { }, }), }), - }) - ); - - return renderState({ - state, + }), doc: rootClusterDoc, platform: 'darwin', listUnifiedResources: () => @@ -197,10 +179,8 @@ export const OnlineEmptyResourcesAndCanAddResourcesAndConnectComputer = () => { export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ userType: tsh.LoggedInUser_UserType.SSO, @@ -215,11 +195,7 @@ export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = }, }), }), - }) - ); - - return renderState({ - state, + }), doc: rootClusterDoc, platform: 'win32', listUnifiedResources: () => @@ -232,10 +208,8 @@ export const OnlineEmptyResourcesAndCanAddResourcesButCannotConnectComputer = }; export const OnlineEmptyResourcesAndCannotAddResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, loggedInUser: makeLoggedInUser({ acl: makeAcl({ @@ -249,11 +223,7 @@ export const OnlineEmptyResourcesAndCannotAddResources = () => { }, }), }), - }) - ); - - return renderState({ - state, + }), doc: rootClusterDoc, listUnifiedResources: () => Promise.resolve({ @@ -265,14 +235,6 @@ export const OnlineEmptyResourcesAndCannotAddResources = () => { }; export const OnlineLoadingResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ - uri: rootClusterDoc.clusterUri, - }) - ); - let rejectPromise: (error: Error) => void; const promiseRejectedOnUnmount = new Promise((resolve, reject) => { rejectPromise = reject; @@ -285,23 +247,19 @@ export const OnlineLoadingResources = () => { }, [rejectPromise]); return renderState({ - state, + cluster: makeRootCluster({ + uri: rootClusterDoc.clusterUri, + }), doc: rootClusterDoc, listUnifiedResources: () => promiseRejectedOnUnmount, }); }; export const OnlineErrorLoadingResources = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ - uri: rootClusterDoc.clusterUri, - }) - ); - return renderState({ - state, + cluster: makeRootCluster({ + uri: rootClusterDoc.clusterUri, + }), doc: rootClusterDoc, listUnifiedResources: () => Promise.reject(new Error('Whoops, something went wrong, sorry!')), @@ -309,58 +267,38 @@ export const OnlineErrorLoadingResources = () => { }; export const Offline = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ connected: false, uri: rootClusterDoc.clusterUri, - }) - ); - - return renderState({ state, doc: rootClusterDoc }); + }), + doc: rootClusterDoc, + }); }; export const Notfound = () => { - const state = createClusterServiceState(); - state.clusters.set( - rootClusterDoc.clusterUri, - makeRootCluster({ + return renderState({ + cluster: makeRootCluster({ uri: rootClusterDoc.clusterUri, - }) - ); - return renderState({ state, doc: leafClusterDoc }); + }), + doc: leafClusterDoc, + }); }; function renderState({ - state, + cluster, doc, listUnifiedResources, platform = 'darwin', }: { - state: ClustersServiceState; + cluster: tsh.Cluster; doc: docTypes.DocumentCluster; listUnifiedResources?: ResourcesService['listUnifiedResources']; platform?: NodeJS.Platform; userType?: tsh.LoggedInUser_UserType; }) { const appContext = new MockAppContext({ platform }); - appContext.clustersService.state = state; - - const rootClusterUri = routing.ensureRootClusterUri(doc.clusterUri); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); - + appContext.addRootClusterWithDoc(cluster, doc); appContext.resourcesService.listUnifiedResources = (params, abortSignal) => listUnifiedResources ? listUnifiedResources(params, abortSignal) diff --git a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx index 02d89810e9b47..0c3ac10a61fbe 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/DocumentCluster.test.tsx @@ -31,7 +31,6 @@ import { ConnectMyComputerContextProvider } from 'teleterm/ui/ConnectMyComputer' import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; import DocumentCluster from './DocumentCluster'; @@ -43,41 +42,25 @@ it('displays a button for Connect My Computer in the empty state if the user can const doc = makeDocumentCluster(); const appContext = new MockAppContext({ platform: 'darwin' }); - appContext.clustersService.setState(draft => { - draft.clusters.set( - doc.clusterUri, - makeRootCluster({ - uri: doc.clusterUri, - loggedInUser: makeLoggedInUser({ - userType: tsh.LoggedInUser_UserType.LOCAL, - acl: makeAcl({ - tokens: { - create: true, - list: true, - edit: true, - delete: true, - read: true, - use: true, - }, - }), + appContext.addRootClusterWithDoc( + makeRootCluster({ + uri: doc.clusterUri, + loggedInUser: makeLoggedInUser({ + userType: tsh.LoggedInUser_UserType.LOCAL, + acl: makeAcl({ + tokens: { + create: true, + list: true, + edit: true, + delete: true, + read: true, + use: true, + }, }), - }) - ); - }); - - appContext.workspacesService.setState(draftState => { - const rootClusterUri = doc.clusterUri; - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + }), + }), + doc + ); const emptyResponse = { resources: [], @@ -116,41 +99,25 @@ it('does not display a button for Connect My Computer in the empty state if the }); const appContext = new MockAppContext({ platform: 'linux' }); - appContext.clustersService.setState(draft => { - draft.clusters.set( - doc.clusterUri, - makeRootCluster({ - uri: doc.clusterUri, - loggedInUser: makeLoggedInUser({ - userType: tsh.LoggedInUser_UserType.LOCAL, - acl: makeAcl({ - tokens: { - create: false, - list: true, - edit: true, - delete: true, - read: true, - use: true, - }, - }), + appContext.addRootClusterWithDoc( + makeRootCluster({ + uri: doc.clusterUri, + loggedInUser: makeLoggedInUser({ + userType: tsh.LoggedInUser_UserType.LOCAL, + acl: makeAcl({ + tokens: { + create: false, + list: true, + edit: true, + delete: true, + read: true, + use: true, + }, }), - }) - ); - }); - - appContext.workspacesService.setState(draftState => { - const rootClusterUri = doc.clusterUri; - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + }), + }), + doc + ); const emptyResponse = { resources: [], diff --git a/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx b/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx index c6d81570b11c2..d2d9dab4483dd 100644 --- a/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentCluster/UnifiedResources.test.tsx @@ -44,7 +44,6 @@ import { UnifiedResources } from 'teleterm/ui/DocumentCluster/UnifiedResources'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; -import { getEmptyPendingAccessRequest } from 'teleterm/ui/services/workspacesService/accessRequestsService'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; import * as uri from 'teleterm/ui/uri'; @@ -175,39 +174,25 @@ test.each([ const doc = makeDocumentCluster(); const appContext = new MockAppContext({ platform: 'darwin' }); - appContext.clustersService.setState(draft => { - draft.clusters.set( - doc.clusterUri, - makeRootCluster({ - uri: doc.clusterUri, - features: { - advancedAccessWorkflows: - testCase.conditions.isClusterSupportingAccessRequests, - isUsageBasedBilling: false, - }, - showResources: testCase.conditions.showResources, - }) - ); - }); - - appContext.workspacesService.setState(draftState => { - const rootClusterUri = doc.clusterUri; - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: doc.clusterUri, - documents: [doc], - location: doc.uri, - unifiedResourcePreferences: { - defaultTab: DefaultTab.ALL, - viewMode: ViewMode.CARD, - labelsViewMode: LabelsViewMode.COLLAPSED, - availableResourceMode: - testCase.conditions.availableResourceModePreference, - }, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, + appContext.addRootClusterWithDoc( + makeRootCluster({ + uri: doc.clusterUri, + features: { + advancedAccessWorkflows: + testCase.conditions.isClusterSupportingAccessRequests, + isUsageBasedBilling: false, }, + showResources: testCase.conditions.showResources, + }), + doc + ); + appContext.workspacesService.setState(draftState => { + draftState.workspaces[doc.clusterUri].unifiedResourcePreferences = { + defaultTab: DefaultTab.ALL, + viewMode: ViewMode.CARD, + labelsViewMode: LabelsViewMode.COLLAPSED, + availableResourceMode: + testCase.conditions.availableResourceModePreference, }; }); @@ -302,22 +287,7 @@ test.each([ }); const serverResource = makeServer(); const appContext = new MockAppContext(); - appContext.clustersService.setState(draft => { - draft.clusters.set(rootCluster.uri, rootCluster); - }); - - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootCluster.uri; - draftState.workspaces[rootCluster.uri] = { - localClusterUri: rootCluster.uri, - documents: [doc], - location: doc.uri, - accessRequests: { - pending: getEmptyPendingAccessRequest(), - isBarCollapsed: true, - }, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, doc); jest .spyOn(appContext.resourcesService, 'listUnifiedResources') diff --git a/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx b/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx index 5f7cef9704cfd..503171d4735a6 100644 --- a/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx +++ b/web/packages/teleterm/src/ui/DocumentGateway/useGateway.test.tsx @@ -126,18 +126,7 @@ const testSetup = () => { title: '', status: '', }; - appContext.clustersService.setState(draftState => { - draftState.clusters.set(cluster.uri, cluster); - }); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - documents: [doc], - location: doc.uri, - localClusterUri: cluster.uri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(cluster, doc); const workspaceContext = { rootClusterUri: cluster.uri, localClusterUri: cluster.uri, diff --git a/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx b/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx index b140fe1aac5c8..47144e12f1011 100644 --- a/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentGatewayApp/DocumentGatewayApp.story.tsx @@ -22,7 +22,11 @@ import { Flex } from 'design'; import { usePromiseRejectedOnUnmount, wait } from 'shared/utils/wait'; import { MockedUnaryCall } from 'teleterm/services/tshd/cloneableClient'; -import { makeApp, makeAppGateway } from 'teleterm/services/tshd/testHelpers'; +import { + makeApp, + makeAppGateway, + makeRootCluster, +} from 'teleterm/services/tshd/testHelpers'; import { DocumentGatewayApp } from 'teleterm/ui/DocumentGatewayApp/DocumentGatewayApp'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; @@ -80,7 +84,7 @@ const meta: Meta = { export default meta; export function Story(props: StoryProps) { - const rootClusterUri = '/clusters/bar'; + const rootCluster = makeRootCluster({ uri: '/clusters/bar' }); const gateway = makeAppGateway(); if (props.appType === 'tcp') { gateway.protocol = 'TCP'; @@ -111,15 +115,7 @@ export function Story(props: StoryProps) { const infinitePromise = usePromiseRejectedOnUnmount(); const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [documentGateway], - location: documentGateway.uri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, documentGateway); if (props.online) { appContext.clustersService.createGateway = () => Promise.resolve(gateway); appContext.clustersService.setState(draftState => { diff --git a/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx b/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx index 15a68c41e2c9c..c6ef7ec2bc5cf 100644 --- a/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx +++ b/web/packages/teleterm/src/ui/DocumentGatewayKube/DocumentGatewayKube.story.tsx @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { MockWorkspaceContextProvider } from 'teleterm/ui/fixtures/MockWorkspaceContextProvider'; @@ -27,38 +28,28 @@ export default { title: 'Teleterm/DocumentGatewayKube', }; -const offlineDocumentGatewayProps: types.DocumentGatewayKube = { +const rootCluster = makeRootCluster(); +const offlineDocumentGateway: types.DocumentGatewayKube = { kind: 'doc.gateway_kube', rootClusterId: '', leafClusterId: '', - targetUri: '/clusters/bar/kubes/quux', + targetUri: `${rootCluster.uri}/kubes/quux`, origin: 'resource_table', status: '', uri: '/docs/123', title: 'quux', }; -const rootClusterUri = '/clusters/bar'; - export function Offline() { const appContext = new MockAppContext(); appContext.clustersService.createGateway = () => Promise.reject(new Error('failed to create gateway')); - - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [offlineDocumentGatewayProps], - location: offlineDocumentGatewayProps.uri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(rootCluster, offlineDocumentGateway); return ( - + ); diff --git a/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx b/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx index 412d39a8be931..8d063772cddf8 100644 --- a/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx +++ b/web/packages/teleterm/src/ui/Search/SearchBar.test.tsx @@ -31,7 +31,7 @@ import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import ModalsHost from 'teleterm/ui/ModalsHost'; import { ResourceSearchError } from 'teleterm/ui/services/resources'; import { ConnectionsContextProvider } from 'teleterm/ui/TopBar/Connections/connectionsContext'; -import { ClusterUri } from 'teleterm/ui/uri'; +import { ClusterUri, routing } from 'teleterm/ui/uri'; import { VnetContextProvider } from 'teleterm/ui/Vnet'; import { SearchAction } from './actions'; @@ -411,16 +411,11 @@ const getMockedSearchContext = (): SearchContext.SearchContext => ({ const setUpContext = (clusterUri: ClusterUri) => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = clusterUri; - draft.workspaces = { - [clusterUri]: { - documents: [], - location: undefined, - localClusterUri: clusterUri, - accessRequests: undefined, - }, - }; - }); + appContext.addRootCluster( + makeRootCluster({ + uri: clusterUri, + name: routing.parseClusterUri(clusterUri).params.rootClusterId, + }) + ); return appContext; }; diff --git a/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx b/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx index 841eafe91fadb..ef30cd17b26c7 100644 --- a/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx +++ b/web/packages/teleterm/src/ui/Search/SearchContext.test.tsx @@ -29,6 +29,7 @@ import { screen, } from '@testing-library/react'; +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { IAppContext } from 'teleterm/ui/types'; @@ -233,17 +234,10 @@ describe('closeWithoutRestoringFocus', () => { }); test('search bar state is adjusted to the active document', () => { - const rootClusterUri = '/clusters/localhost'; + const rootCluster = makeRootCluster({ uri: '/clusters/localhost' }); const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.rootClusterUri = rootClusterUri; - draftState.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [], - location: undefined, - accessRequests: undefined, - }; - }); + appContext.addRootCluster(rootCluster); + const docService = appContext.workspacesService.getActiveWorkspaceDocumentService(); const { result } = renderHook(() => useSearchContext(), { @@ -260,7 +254,7 @@ test('search bar state is adjusted to the active document', () => { // document changes to the cluster document act(() => { const clusterDoc = docService.createClusterDocument({ - clusterUri: rootClusterUri, + clusterUri: rootCluster.uri, queryParams: { search: 'foo', resourceKinds: ['db'], @@ -281,7 +275,7 @@ test('search bar state is adjusted to the active document', () => { // document changes to another cluster document act(() => { const clusterDoc = docService.createClusterDocument({ - clusterUri: rootClusterUri, + clusterUri: rootCluster.uri, queryParams: { search: 'bar', resourceKinds: ['kube_cluster'], @@ -316,7 +310,7 @@ test('search bar state is adjusted to the active document', () => { // document changes to a cluster document act(() => { const clusterDoc = docService.createClusterDocument({ - clusterUri: rootClusterUri, + clusterUri: rootCluster.uri, queryParams: { search: 'bar', resourceKinds: ['kube_cluster'], diff --git a/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx b/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx index 0d60c80125215..30a2fb11c2ffd 100644 --- a/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx +++ b/web/packages/teleterm/src/ui/Search/pickers/useDisplayResults.test.tsx @@ -18,6 +18,7 @@ import { renderHook } from '@testing-library/react'; +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/documentsService/testHelpers'; @@ -30,17 +31,10 @@ const documentCluster = makeDocumentCluster({ test('if the cluster document is active, the search results should be shown in it', () => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.workspaces = { - '/clusters/teleport-a': { - localClusterUri: '/clusters/teleport-a', - location: documentCluster.uri, - accessRequests: undefined, - documents: [documentCluster], - }, - }; - draftState.rootClusterUri = '/clusters/teleport-a'; - }); + appContext.addRootClusterWithDoc( + makeRootCluster({ uri: '/clusters/teleport-a' }), + documentCluster + ); const { result } = renderHook( () => @@ -65,17 +59,10 @@ test('if the cluster document is active, the search results should be shown in i test('if the cluster filter does not match the document cluster, the results should be opened in a new document', () => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.workspaces = { - '/clusters/teleport-a': { - localClusterUri: '/clusters/teleport-a', - location: '/docs/abc', - accessRequests: undefined, - documents: [documentCluster], - }, - }; - draftState.rootClusterUri = '/clusters/teleport-a'; - }); + appContext.addRootClusterWithDoc( + makeRootCluster({ uri: '/clusters/teleport-a' }), + documentCluster + ); const { result } = renderHook( () => @@ -101,17 +88,7 @@ test('if the cluster filter does not match the document cluster, the results sho test('if the cluster document is not active, the results should be opened in a new document', () => { const appContext = new MockAppContext(); - appContext.workspacesService.setState(draftState => { - draftState.workspaces = { - '/clusters/teleport-a': { - localClusterUri: '/clusters/teleport-a', - location: '/docs/abc', - accessRequests: undefined, - documents: [], - }, - }; - draftState.rootClusterUri = '/clusters/teleport-a'; - }); + appContext.addRootCluster(makeRootCluster({ uri: '/clusters/teleport-a' })); const { result } = renderHook( () => diff --git a/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx b/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx index a224cfb3221cc..5a8db6c1cd294 100644 --- a/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx +++ b/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx @@ -54,27 +54,7 @@ async function getTestSetup({ documents }: { documents: Document[] }) { const appContext = new MockAppContext(); jest.spyOn(appContext.mainProcessClient, 'openTabContextMenu'); - appContext.clustersService.setState(draft => { - draft.clusters.set( - rootClusterUri, - makeRootCluster({ - uri: rootClusterUri, - }) - ); - }); - - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = rootClusterUri; - draft.workspaces[rootClusterUri] = { - documents, - location: documents[0]?.uri, - localClusterUri: rootClusterUri, - accessRequests: { - isBarCollapsed: true, - pending: { kind: 'resource', resources: new Map() }, - }, - }; - }); + appContext.addRootClusterWithDoc(makeRootCluster(), documents); const docsService = appContext.workspacesService.getActiveWorkspaceDocumentService(); diff --git a/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx b/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx index b8fe467178b54..e459582fd54ae 100644 --- a/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx +++ b/web/packages/teleterm/src/ui/TabHost/useTabShortcuts.test.tsx @@ -20,6 +20,7 @@ import { PropsWithChildren } from 'react'; import renderHook from 'design/utils/renderHook'; +import { makeRootCluster } from 'teleterm/services/tshd/testHelpers'; import AppContextProvider from 'teleterm/ui/appContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; import { @@ -107,15 +108,7 @@ function getTestSetup({ documents }: { documents: Document[] }) { eventEmitter = null; }); - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = rootClusterUri; - draft.workspaces[rootClusterUri] = { - documents, - location: documents[0]?.uri, - localClusterUri: rootClusterUri, - accessRequests: undefined, - }; - }); + appContext.addRootClusterWithDoc(makeRootCluster(), documents); const docsService = appContext.workspacesService.getActiveWorkspaceDocumentService(); diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx index ba52b2a9a872c..d9ae5e88962b9 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.test.tsx @@ -25,7 +25,6 @@ import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/tru import { makeLoggedInUser, makeRootCluster, - rootClusterUri, } from 'teleterm/services/tshd/testHelpers'; import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; @@ -73,28 +72,11 @@ test.each([ }, ])('$name', async testCase => { const appContext = new MockAppContext(); - appContext.clustersService.setState(draft => { - draft.clusters.set( - rootClusterUri, - makeRootCluster({ - uri: rootClusterUri, - loggedInUser: testCase.user, - }) - ); - }); - - appContext.workspacesService.setState(draft => { - draft.rootClusterUri = rootClusterUri; - draft.workspaces[rootClusterUri] = { - localClusterUri: rootClusterUri, - documents: [], - location: undefined, - accessRequests: { - isBarCollapsed: true, - pending: { kind: 'resource', resources: new Map() }, - }, - }; - }); + appContext.addRootCluster( + makeRootCluster({ + loggedInUser: testCase.user, + }) + ); render( diff --git a/web/packages/teleterm/src/ui/fixtures/mocks.ts b/web/packages/teleterm/src/ui/fixtures/mocks.ts index f746eead52eb5..2c2d0a7b5d980 100644 --- a/web/packages/teleterm/src/ui/fixtures/mocks.ts +++ b/web/packages/teleterm/src/ui/fixtures/mocks.ts @@ -53,17 +53,11 @@ export class MockAppContext extends AppContext { draftState.clusters.set(cluster.uri, cluster); }); const docs = Array.isArray(doc) ? doc : [doc]; + this.workspacesService.addWorkspace(cluster.uri); this.workspacesService.setState(draftState => { draftState.rootClusterUri = cluster.uri; - draftState.workspaces[cluster.uri] = { - documents: docs.filter(Boolean), - location: docs[0]?.uri, - localClusterUri: cluster.uri, - accessRequests: { - isBarCollapsed: true, - pending: { kind: 'role', roles: new Set() }, - }, - }; + draftState.workspaces[cluster.uri].documents = docs.filter(Boolean); + draftState.workspaces[cluster.uri].location = docs[0]?.uri; }); } diff --git a/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts b/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts index c7a4c9c0795e4..16c29c9251631 100644 --- a/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts +++ b/web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.legacy.test.ts @@ -272,6 +272,7 @@ function getTestSetupWithMockedDocuments(documents: Document[]) { // Insert the documents. workspacesService.setState(draftState => { draftState.workspaces['/clusters/localhost'] = { + color: 'purple', accessRequests: { pending: getEmptyPendingAccessRequest(), isBarCollapsed: false, diff --git a/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts b/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts index 75caa7cbc5cf5..074255002bd52 100644 --- a/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts +++ b/web/packages/teleterm/src/ui/services/statePersistence/statePersistenceService.ts @@ -20,6 +20,7 @@ import { FileStorage } from 'teleterm/types'; import { ConnectionTrackerState } from 'teleterm/ui/services/connectionTracker'; import { Workspace, + WorkspaceColor, WorkspacesState, } from 'teleterm/ui/services/workspacesService'; @@ -31,14 +32,24 @@ interface UsageReportingState { askedForUserJobRole: boolean; } +/** + * Expected shape of the persisted workspaces. + * In the future, it should come from zod. + */ +export type PersistedWorkspace = Omit< + Workspace, + 'accessRequests' | 'documentsRestoredOrDiscarded' | 'color' +> & { + // TODO(gzdunek) DELETE IN v19.0.0: Make the field required by removing the 'color' type below and the omitted 'color' above. + // This only expresses that existing persisted state from older versions might not have color defined. + color?: WorkspaceColor; +}; + export type WorkspacesPersistedState = Omit< WorkspacesState, 'workspaces' | 'isInitialized' > & { - workspaces: Record< - string, - Omit - >; + workspaces: Record; }; export interface StatePersistenceState { diff --git a/web/packages/teleterm/src/ui/services/workspacesService/color.ts b/web/packages/teleterm/src/ui/services/workspacesService/color.ts new file mode 100644 index 0000000000000..d6627fc0b6c5f --- /dev/null +++ b/web/packages/teleterm/src/ui/services/workspacesService/color.ts @@ -0,0 +1,69 @@ +/** + * Teleport + * Copyright (C) 2025 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 { z } from 'zod'; + +import Logger from 'teleterm/logger'; + +export type WorkspaceColor = z.infer; + +export const workspaceColors = z.enum([ + 'purple', + 'green', + 'yellow', + 'red', + 'cyan', + 'pink', + 'blue', +]); + +// TODO(gzdunek): Parse the entire workspace state read from disk like below. +export function parseWorkspaceColor( + color: unknown, + workspaces: Record< + string, + { + color: WorkspaceColor; + } + > +): WorkspaceColor { + const getDefault = () => getNextWorkspaceColor(workspaces); + return workspaceColors + .default(getDefault) + .catch(ctx => { + new Logger('WorkspacesService').error( + 'Failed to read workspace color preference', + ctx.error + ); + return getDefault(); + }) + .parse(color); +} + +/** + * Determines the next available unused color across all workspaces. + * If all colors are already in use, it defaults to returning purple. + */ +function getNextWorkspaceColor( + workspaces: Record +): WorkspaceColor { + const takenColors = new Set(Object.values(workspaces).map(w => w.color)); + const allColors = new Set(workspaceColors.options); + const unusedColors = allColors.difference(takenColors); + return unusedColors.size > 0 ? [...unusedColors][0] : 'purple'; +} diff --git a/web/packages/teleterm/src/ui/services/workspacesService/index.ts b/web/packages/teleterm/src/ui/services/workspacesService/index.ts index 23a5a63930c83..abf5d27d23ddb 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/index.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/index.ts @@ -18,3 +18,4 @@ export * from './workspacesService'; export * from './documentsService'; +export * from './color'; diff --git a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts index 8fd108779e9c7..399321bae23b5 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts @@ -31,14 +31,14 @@ import { makeDocumentCluster } from 'teleterm/ui/services/workspacesService/docu import { ClustersService } from '../clusters'; import { ModalsService } from '../modals'; import { NotificationsService } from '../notifications'; -import { StatePersistenceService } from '../statePersistence'; +import { + PersistedWorkspace, + StatePersistenceService, + WorkspacesPersistedState, +} from '../statePersistence'; import { getEmptyPendingAccessRequest } from './accessRequestsService'; import { DocumentCluster, DocumentsService } from './documentsService'; -import { - Workspace, - WorkspacesService, - WorkspacesState, -} from './workspacesService'; +import { WorkspacesService, WorkspacesState } from './workspacesService'; beforeAll(() => { Logger.init(new NullService()); @@ -51,11 +51,7 @@ beforeEach(() => { describe('restoring workspace', () => { it('restores the workspace if there is a persisted state for given clusterUri', () => { const cluster = makeRootCluster(); - const testWorkspace: Workspace = { - accessRequests: { - isBarCollapsed: true, - pending: getEmptyPendingAccessRequest(), - }, + const testWorkspace: PersistedWorkspace = { localClusterUri: cluster.uri, documents: [ { @@ -85,6 +81,7 @@ describe('restoring workspace', () => { }, isBarCollapsed: false, }, + color: 'purple', localClusterUri: testWorkspace.localClusterUri, documents: [expect.objectContaining({ kind: 'doc.cluster' })], location: expect.any(String), @@ -121,6 +118,7 @@ describe('restoring workspace', () => { resources: new Map(), }, }, + color: 'purple', localClusterUri: cluster.uri, documents: [expect.objectContaining({ kind: 'doc.cluster' })], location: expect.any(String), @@ -136,6 +134,96 @@ describe('restoring workspace', () => { }); expect(workspacesService.getRestoredState().workspaces).toStrictEqual({}); }); + + it('restores profile color from state or assigns if empty', async () => { + const clusterFoo = makeRootCluster({ uri: '/clusters/foo' }); + const workspaceFoo: PersistedWorkspace = { + color: 'blue', + localClusterUri: clusterFoo.uri, + documents: [], + location: undefined, + }; + const clusterBar = makeRootCluster({ uri: '/clusters/bar' }); + const workspaceBar: PersistedWorkspace = { + localClusterUri: clusterBar.uri, + documents: [], + location: undefined, + }; + const clusterBaz = makeRootCluster({ uri: '/clusters/baz' }); + const workspaceBaz: PersistedWorkspace = { + localClusterUri: clusterBaz.uri, + documents: [], + location: undefined, + }; + const clusterQux = makeRootCluster({ uri: '/clusters/qux' }); + const workspaceQux: PersistedWorkspace = { + localClusterUri: clusterQux.uri, + documents: [], + location: undefined, + }; + const clusterWaldo = makeRootCluster({ uri: '/clusters/waldo' }); + const workspaceWaldo: PersistedWorkspace = { + localClusterUri: clusterWaldo.uri, + documents: [], + location: undefined, + }; + const clusterFred = makeRootCluster({ uri: '/clusters/fred' }); + const workspaceFred: PersistedWorkspace = { + localClusterUri: clusterFred.uri, + documents: [], + location: undefined, + }; + const clusterGrault = makeRootCluster({ uri: '/clusters/grault' }); + const workspaceGrault: PersistedWorkspace = { + localClusterUri: clusterGrault.uri, + documents: [], + location: undefined, + }; + const clusterPlugh = makeRootCluster({ uri: '/clusters/plugh' }); + const workspacePlugh: PersistedWorkspace = { + localClusterUri: clusterPlugh.uri, + documents: [], + location: undefined, + }; + + const { workspacesService } = getTestSetup({ + cluster: [ + clusterFoo, + clusterBar, + clusterBaz, + clusterQux, + clusterWaldo, + clusterFred, + clusterGrault, + clusterPlugh, + ], + persistedWorkspaces: { + [clusterFoo.uri]: workspaceFoo, + [clusterBar.uri]: workspaceBar, + [clusterBaz.uri]: workspaceBaz, + [clusterQux.uri]: workspaceQux, + [clusterWaldo.uri]: workspaceWaldo, + [clusterFred.uri]: workspaceFred, + [clusterGrault.uri]: workspaceGrault, + [clusterPlugh.uri]: workspacePlugh, + }, + }); + + workspacesService.restorePersistedState(); + + expect(workspacesService.getWorkspace(clusterFoo.uri).color).toBe('blue'); // read from disk + expect(workspacesService.getWorkspace(clusterBar.uri).color).toBe('purple'); // the first unused color + expect(workspacesService.getWorkspace(clusterBaz.uri).color).toBe('green'); + expect(workspacesService.getWorkspace(clusterQux.uri).color).toBe('yellow'); + expect(workspacesService.getWorkspace(clusterWaldo.uri).color).toBe('red'); + expect(workspacesService.getWorkspace(clusterFred.uri).color).toBe('cyan'); + expect(workspacesService.getWorkspace(clusterGrault.uri).color).toBe( + 'pink' + ); + expect(workspacesService.getWorkspace(clusterPlugh.uri).color).toBe( + 'purple' + ); // we have run out of colors, assign the default purple color + }); }); describe('state persistence', () => { @@ -150,6 +238,7 @@ describe('state persistence', () => { isBarCollapsed: true, pending: getEmptyPendingAccessRequest(), }, + color: 'purple', localClusterUri: cluster.uri, documents: [ { @@ -309,11 +398,7 @@ describe('setActiveWorkspace', () => { it('sets location to first document if location points to non-existing document when reopening documents', async () => { const cluster = makeRootCluster(); - const testWorkspace: Workspace = { - accessRequests: { - isBarCollapsed: true, - pending: getEmptyPendingAccessRequest(), - }, + const testWorkspace: PersistedWorkspace = { localClusterUri: cluster.uri, documents: [ { @@ -374,11 +459,7 @@ describe('setActiveWorkspace', () => { it('ongoing setActive call is canceled when the method is called again', async () => { const clusterFoo = makeRootCluster({ uri: '/clusters/foo' }); const clusterBar = makeRootCluster({ uri: '/clusters/bar' }); - const workspace1: Workspace = { - accessRequests: { - isBarCollapsed: true, - pending: getEmptyPendingAccessRequest(), - }, + const workspace1: PersistedWorkspace = { localClusterUri: clusterFoo.uri, documents: [ { @@ -410,7 +491,7 @@ describe('setActiveWorkspace', () => { function getTestSetup(options: { cluster: tshd.Cluster | tshd.Cluster[] | undefined; - persistedWorkspaces: Record; + persistedWorkspaces: WorkspacesPersistedState['workspaces']; }) { const { cluster } = options; diff --git a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts index 6173dcb02881b..d7a1f6d55afe2 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.ts @@ -38,6 +38,7 @@ import { ImmutableStore } from 'teleterm/ui/services/immutableStore'; import { ModalsService } from 'teleterm/ui/services/modals'; import { NotificationsService } from 'teleterm/ui/services/notifications'; import { + PersistedWorkspace, StatePersistenceService, WorkspacesPersistedState, } from 'teleterm/ui/services/statePersistence'; @@ -54,6 +55,7 @@ import { getEmptyPendingAccessRequest, PendingAccessRequest, } from './accessRequestsService'; +import { parseWorkspaceColor, WorkspaceColor } from './color'; import { createClusterDocument, Document, @@ -82,6 +84,7 @@ export interface WorkspacesState { export interface Workspace { localClusterUri: ClusterUri; + color: WorkspaceColor; documents: Document[]; location: DocumentUri | undefined; accessRequests: { @@ -176,6 +179,15 @@ export class WorkspacesService extends ImmutableStore { }); } + changeWorkspaceColor( + rootClusterUri: RootClusterUri, + color: WorkspaceColor + ): void { + this.setState(draftState => { + draftState.workspaces[rootClusterUri].color = color; + }); + } + getWorkspaceDocumentService( clusterUri: RootClusterUri ): DocumentsService | undefined { @@ -373,10 +385,14 @@ export class WorkspacesService extends ImmutableStore { } } // If we don't have a workspace for this cluster, add it. + // TODO(gzdunek): Creating a workspace here might not be necessary + // after we started calling workspacesService.addWorkspace in ClusterAdd. this.setState(draftState => { if (!draftState.workspaces[clusterUri]) { - draftState.workspaces[clusterUri] = - getWorkspaceDefaultState(clusterUri); + draftState.workspaces[clusterUri] = getWorkspaceDefaultState( + clusterUri, + draftState.workspaces + ); } draftState.rootClusterUri = clusterUri; }); @@ -421,6 +437,18 @@ export class WorkspacesService extends ImmutableStore { return { isAtDesiredWorkspace: true }; } + addWorkspace(clusterUri: RootClusterUri): void { + if (this.state.workspaces[clusterUri]) { + return; + } + this.setState(draftState => { + draftState.workspaces[clusterUri] = getWorkspaceDefaultState( + clusterUri, + draftState.workspaces + ); + }); + } + removeWorkspace(clusterUri: RootClusterUri): void { this.setState(draftState => { delete draftState.workspaces[clusterUri]; @@ -459,6 +487,7 @@ export class WorkspacesService extends ImmutableStore { const restoredWorkspace = this.restoredState.workspaces[cluster.uri]; workspaces[cluster.uri] = getWorkspaceDefaultState( cluster.uri, + workspaces, restoredWorkspace ); return workspaces; @@ -558,6 +587,7 @@ export class WorkspacesService extends ImmutableStore { stateToSave.workspaces[w] = { localClusterUri: workspace.localClusterUri, location: workspace.location, + color: workspace.color, documents: documentsToPersist, connectMyComputer: workspace.connectMyComputer, unifiedResourcePreferences: workspace.unifiedResourcePreferences, @@ -633,7 +663,8 @@ function getLocationToRestore( function getWorkspaceDefaultState( rootClusterUri: RootClusterUri, - restoredWorkspace?: Immutable> + workspaces: Record, + restoredWorkspace?: Immutable ): Workspace { const defaultDocument = createClusterDocument({ clusterUri: rootClusterUri }); const defaultWorkspace: Workspace = { @@ -647,6 +678,7 @@ function getWorkspaceDefaultState( hasDocumentsToReopen: false, localClusterUri: rootClusterUri, unifiedResourcePreferences: parseUnifiedResourcePreferences(undefined), + color: parseWorkspaceColor(undefined, workspaces), }; if (!restoredWorkspace) { return defaultWorkspace; @@ -656,6 +688,10 @@ function getWorkspaceDefaultState( defaultWorkspace.unifiedResourcePreferences = parseUnifiedResourcePreferences( restoredWorkspace.unifiedResourcePreferences ); + defaultWorkspace.color = parseWorkspaceColor( + restoredWorkspace.color, + workspaces + ); defaultWorkspace.connectMyComputer = restoredWorkspace.connectMyComputer; defaultWorkspace.hasDocumentsToReopen = hasDocumentsToReopen({ previousDocuments: restoredWorkspace.documents, From 937e4a9ac9f85b2c3501168fd509693fea2e218e Mon Sep 17 00:00:00 2001 From: Grzegorz Zdunek Date: Thu, 30 Jan 2025 16:48:05 +0100 Subject: [PATCH 14/28] Redesign profile switcher (#51419) * Add mapping of profile color to theme color * Prepare UserIcon to display colors, make it slightly larger * Rewrite single identity item to show icon and user/cluster in separate lines * Render single cluster items in a list * Add color picker * Render active cluster separately, above inactive clusters * Put the new identity components together * Refactor `Identity` story, render the container component instead of "presentational" one * Refresh startup page * Minor style fixes * Add comment about `dataVisualisationColors` * Bring back the original styling of `StaticListItem` * Make the pencil icon hoverable and clickable * Increase min-width from 200 px to 300 px, simplify active cluster layout * Show logout button when any part of `ListItem` is hovered * Remove text from logout button, improve titles * Pass correct index number to `AddClusterItem` * Update comment for `focusGrabber` * Use `useStoreSelector` correctly * Improve accessibility of color picker * Replace Pam icon with plus symbol * Remove unnecessary optional chaining * Align profile status error with user icon * Add story for cluster connect panel * Make user icon letter follow active theme This was suggested by Kenny, and I think it looks good. * Change gap from 11 px to 10 px * Rename profile color -> workspace color --- .../design/src/theme/themes/darkTheme.ts | 6 +- .../ClusterConnectPanel.story.tsx | 83 ++++ .../ClusterConnectPanel.tsx | 90 +++- .../ClusterConnectPanel/RecentClusters.tsx | 94 ---- .../EmptyIdentityList/EmptyIdentityList.tsx | 43 -- .../src/ui/TopBar/Identity/Identity.story.tsx | 429 +++++------------- .../src/ui/TopBar/Identity/Identity.tsx | 205 ++++----- .../IdentityList/AddNewClusterItem.tsx | 51 --- .../Identity/IdentityList/ColorPicker.tsx | 130 ++++++ .../Identity/IdentityList/IdentityList.tsx | 168 ++++--- .../IdentityList/IdentityListItem.tsx | 178 +++++--- .../IdentitySelector/IdentitySelector.tsx | 41 +- .../Identity/IdentitySelector/PamIcon.tsx | 41 -- .../Identity/IdentitySelector/UserIcon.tsx | 66 ++- .../TopBar/Identity/IdentitySelector/pam.svg | 65 --- .../src/ui/TopBar/Identity/useIdentity.ts | 53 +-- .../KeyboardArrowsNavigation.tsx | 18 + .../teleterm/src/ui/components/ListItem.tsx | 23 +- .../src/ui/components/ProfileStatusError.tsx | 16 +- .../ui/services/workspacesService/color.ts | 20 +- .../workspacesService.test.ts | 2 +- 21 files changed, 901 insertions(+), 921 deletions(-) create mode 100644 web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx delete mode 100644 web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx create mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx delete mode 100644 web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg diff --git a/web/packages/design/src/theme/themes/darkTheme.ts b/web/packages/design/src/theme/themes/darkTheme.ts index eb0f044ee51c2..d4158282b3d5f 100644 --- a/web/packages/design/src/theme/themes/darkTheme.ts +++ b/web/packages/design/src/theme/themes/darkTheme.ts @@ -32,7 +32,11 @@ import { lighten } from '../utils/colorManipulator'; import { sharedColors, sharedStyles } from './sharedStyles'; import { DataVisualisationColors, Theme, ThemeColors } from './types'; -const dataVisualisationColors: DataVisualisationColors = { +/** + * Used for the user icon in Connect (the top-right one). + * In both the light and dark mode, the dark version of dataVisualisationColors is used. + */ +export const dataVisualisationColors: DataVisualisationColors = { primary: { purple: '#9F85FF', wednesdays: '#F74DFF', diff --git a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx new file mode 100644 index 0000000000000..8a4d827e6e4b0 --- /dev/null +++ b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.story.tsx @@ -0,0 +1,83 @@ +/** + * Teleport + * Copyright (C) 2025 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 { + makeLoggedInUser, + makeRootCluster, +} from 'teleterm/services/tshd/testHelpers'; +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; + +import { ClusterConnectPanel } from './ClusterConnectPanel'; + +export default { + title: 'Teleterm/ClusterConnectPanel', +}; + +const profileStatusError = + 'No YubiKey device connected with serial number 14358031. Connect the device and try again.'; +const clusterOrange = makeRootCluster({ + name: 'orange', + loggedInUser: makeLoggedInUser({ + name: 'bob', + roles: ['access', 'editor'], + sshLogins: ['root'], + }), + uri: '/clusters/orange', +}); +const clusterViolet = makeRootCluster({ + name: 'violet', + loggedInUser: makeLoggedInUser({ name: 'sammy' }), + uri: '/clusters/violet', +}); + +export const Empty = () => { + return ( + + + + ); +}; + +export const WithClusters = () => { + const ctx = new MockAppContext(); + ctx.addRootCluster(clusterOrange); + ctx.addRootCluster(clusterViolet); + + return ( + + ; + + ); +}; + +export const WithErrors = () => { + const ctx = new MockAppContext(); + ctx.addRootCluster( + makeRootCluster({ + ...clusterOrange, + profileStatusError, + }) + ); + ctx.addRootCluster(clusterViolet); + return ( + + ; + + ); +}; diff --git a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx index 773f5808cc6e6..b8eda061b186f 100644 --- a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx +++ b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/ClusterConnectPanel.tsx @@ -16,21 +16,51 @@ * along with this program. If not, see . */ +import { useCallback, useEffect, useRef } from 'react'; import styled from 'styled-components'; -import { Box, ButtonPrimary, Flex, H1, ResourceIcon, Text } from 'design'; +import { + Box, + ButtonPrimary, + Flex, + H1, + H2, + P2, + ResourceIcon, + Text, +} from 'design'; import { useAppContext } from 'teleterm/ui/appContextProvider'; - -import { RecentClusters } from './RecentClusters'; +import { NullKeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation'; +import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; +import { ClusterList } from 'teleterm/ui/TopBar/Identity/IdentityList/IdentityList'; +import { RootClusterUri } from 'teleterm/ui/uri'; export function ClusterConnectPanel() { const ctx = useAppContext(); - - function handleConnect() { + const clusters = useStoreSelector( + 'clustersService', + useCallback(state => state.clusters, []) + ); + const rootClusters = [...clusters.values()].filter(c => !c.leaf); + function add(): void { ctx.commandLauncher.executeCommand('cluster-connect', {}); } + function connect(clusterUri: RootClusterUri): void { + ctx.workspacesService.setActiveWorkspace(clusterUri); + } + + const containerRef = useRef(); + + // Focus the first item. + const hasCluster = !!rootClusters.length; + useEffect(() => { + if (hasCluster) { + containerRef.current.querySelector('li').focus(); + } + }, [hasCluster]); + return ( @@ -41,16 +71,48 @@ export function ClusterConnectPanel() { alignItems="center" > -

Connect a Cluster

- - Connect an existing Teleport cluster
to start using Teleport - Connect. -
- - Connect - + {hasCluster ? ( + +

Clusters

+ + Log in to a cluster to use Teleport Connect. + + {/*Disable arrows navigation, it doesn't work well here,*/} + {/*since it requires the container to be focused.*/} + {/*The user can navigate with Tab.*/} + + p.theme.radii[2]}px; + padding: ${p => p.theme.space[2]}px; + } + `} + > + + + +
+ ) : ( + <> +

Connect a Cluster

+ + Connect an existing Teleport cluster
to start using + Teleport Connect. +
+ + Connect + + + )} -
); diff --git a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx b/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx deleted file mode 100644 index c1b7264633c6d..0000000000000 --- a/web/packages/teleterm/src/ui/TabHost/ClusterConnectPanel/RecentClusters.tsx +++ /dev/null @@ -1,94 +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 { Box, ButtonBorder, Card, Flex, Text } from 'design'; - -import { useAppContext } from 'teleterm/ui/appContextProvider'; -import { ProfileStatusError } from 'teleterm/ui/components/ProfileStatusError'; -import { RootClusterUri } from 'teleterm/ui/uri'; -import { getUserWithClusterName } from 'teleterm/ui/utils'; - -export function RecentClusters() { - const ctx = useAppContext(); - - ctx.clustersService.useState(); - - const rootClusters = ctx.clustersService - .getClusters() - .filter(c => !c.leaf) - .map(cluster => ({ - userWithClusterName: getUserWithClusterName({ - userName: cluster.loggedInUser?.name, - clusterName: cluster.name, - }), - connectionProblemError: cluster.profileStatusError, - uri: cluster.uri, - })); - - function connect(clusterUri: RootClusterUri): void { - ctx.workspacesService.setActiveWorkspace(clusterUri); - } - - if (!rootClusters.length) { - return null; - } - - return ( - - - Recent clusters - - - {rootClusters.map((cluster, index) => ( - - - - {cluster.userWithClusterName} - - {cluster.connectionProblemError && ( - - )} - - connect(cluster.uri)} - title={`Connect to ${cluster.userWithClusterName}`} - > - Connect - - - ))} - - - ); -} diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx deleted file mode 100644 index 1824054ebdfce..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/EmptyIdentityList/EmptyIdentityList.tsx +++ /dev/null @@ -1,43 +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 { ButtonPrimary, Flex, ResourceIcon, Text } from 'design'; - -interface EmptyIdentityListProps { - onConnect(): void; -} - -export function EmptyIdentityList(props: EmptyIdentityListProps) { - return ( - - - - No cluster connected - - - Connect - - - ); -} diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx index 9abacf8a59480..43eb4967ef282 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.story.tsx @@ -16,91 +16,104 @@ * along with this program. If not, see . */ -import { useEffect, useRef } from 'react'; +import { useLayoutEffect } from 'react'; import Flex from 'design/Flex'; import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/trusted_device_requirement_pb'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; import { makeLoggedInUser, makeRootCluster, } from 'teleterm/services/tshd/testHelpers'; +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; +import { RootClusterUri } from 'teleterm/ui/uri'; -import { Identity, IdentityHandler, IdentityProps } from './Identity'; -import { IdentityRootCluster } from './useIdentity'; +import { IdentityContainer } from './Identity'; export default { title: 'Teleterm/Identity', }; -const makeTitle = (userWithClusterName: string) => userWithClusterName; +const clusterOrange = makeRootCluster({ + name: 'orange', + loggedInUser: makeLoggedInUser({ + name: 'bob', + roles: ['access', 'editor'], + sshLogins: ['root'], + }), + uri: '/clusters/orange', +}); +const clusterViolet = makeRootCluster({ + name: 'violet', + loggedInUser: makeLoggedInUser({ name: 'sammy' }), + uri: '/clusters/violet', +}); +const clusterGreen = makeRootCluster({ + name: 'green', + loggedInUser: undefined, + uri: '/clusters/green', +}); + const profileStatusError = 'No YubiKey device connected with serial number 14358031. Connect the device and try again.'; -const OpenedIdentity = (props: IdentityProps) => { - const ref = useRef(); - useEffect(() => { - if (ref.current) { - ref.current.togglePopover(); - } - }, [ref.current]); +const OpenIdentityPopover = (props: { + clusters: Cluster[]; + activeClusterUri: RootClusterUri | undefined; +}) => { + const ctx = new MockAppContext(); + props.clusters.forEach(c => { + ctx.addRootCluster(c); + }); + ctx.workspacesService.setState(draftState => { + draftState.rootClusterUri = props.activeClusterUri; + }); + useOpenPopover(); return ( - + + + ); }; +const useOpenPopover = () => { + useLayoutEffect(() => { + const isProfileSelectorOpen = !!document.querySelector( + 'button[title~="logout"i]' + ); + + if (isProfileSelectorOpen) { + return; + } + + const button = document.querySelector( + 'button[title~="profiles"i]' + ) as HTMLButtonElement; + + button?.click(); + }, []); +}; + export function NoRootClusters() { - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} - /> - ); + return ; } export function OneClusterWithNoActiveCluster() { - const identityRootCluster: IdentityRootCluster = { - active: false, - clusterName: 'teleport-localhost', - userName: '', - uri: '/clusters/localhost', - connected: false, - profileStatusError: '', - }; - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function OneClusterWithActiveCluster() { - const identityRootCluster: IdentityRootCluster = { - active: true, - clusterName: 'Teleport-Localhost', - userName: 'alice', - uri: '/clusters/localhost', - connected: true, - profileStatusError: '', - }; - const cluster = makeRootCluster({ - uri: '/clusters/localhost', - name: 'teleport-localhost', - proxyHost: 'localhost:3080', loggedInUser: makeLoggedInUser({ name: 'alice', roles: ['access', 'editor'], @@ -109,297 +122,105 @@ export function OneClusterWithActiveCluster() { }); return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} - /> + ); } export function ManyClustersWithNoActiveCluster() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - const identityRootCluster2: IdentityRootCluster = { - active: false, - clusterName: 'violet', - userName: 'sammy', - uri: '/clusters/violet', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: true, - profileStatusError: '', - }; - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function ManyClustersWithActiveCluster() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - const identityRootCluster2: IdentityRootCluster = { - active: true, - clusterName: 'violet', - userName: 'sammy', - uri: '/clusters/violet', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster2; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - name: activeIdentityRootCluster.userName, - roles: ['access', 'editor'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function ManyClustersWithProfileErrorsAndActiveCluster() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: false, - profileStatusError: profileStatusError, - }; - const identityRootCluster2: IdentityRootCluster = { - active: true, - clusterName: 'violet', - userName: 'sammy', - uri: '/clusters/violet', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: false, - profileStatusError: profileStatusError, - }; - - const activeIdentityRootCluster = identityRootCluster2; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - name: activeIdentityRootCluster.userName, - roles: ['access', 'editor'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + activeClusterUri={clusterOrange.uri} /> ); } export function LongNamesWithManyRoles() { - const identityRootCluster1: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - const identityRootCluster2: IdentityRootCluster = { - active: true, - clusterName: 'psv-eindhoven-eredivisie-production-lorem-ipsum', - userName: 'ruud-van-nistelrooy-van-der-sar', - uri: '/clusters/psv', - connected: true, - profileStatusError: '', - }; - const identityRootCluster3: IdentityRootCluster = { - active: false, - clusterName: 'green', - userName: '', - uri: '/clusters/green', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster2; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - name: activeIdentityRootCluster.userName, - roles: [ - 'circle-mark-app-access', - 'grafana-lite-app-access', - 'grafana-gold-app-access', - 'release-lion-app-access', - 'release-fox-app-access', - 'sales-center-lorem-app-access', - 'sales-center-ipsum-db-access', - 'sales-center-shop-app-access', - 'sales-center-floor-db-access', - ], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + activeClusterUri={clusterViolet.uri} /> ); } export function TrustedDeviceEnrolled() { - const identityRootCluster: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - isDeviceTrusted: true, - name: activeIdentityRootCluster.userName, - roles: ['circle-mark-app-access', 'grafana-lite-app-access'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } export function TrustedDeviceRequiredButNotEnrolled() { - const identityRootCluster: IdentityRootCluster = { - active: false, - clusterName: 'orange', - userName: 'bob', - uri: '/clusters/orange', - connected: true, - profileStatusError: '', - }; - - const activeIdentityRootCluster = identityRootCluster; - const activeCluster = makeRootCluster({ - uri: activeIdentityRootCluster.uri, - name: activeIdentityRootCluster.clusterName, - proxyHost: 'localhost:3080', - loggedInUser: makeLoggedInUser({ - trustedDeviceRequirement: TrustedDeviceRequirement.REQUIRED, - name: activeIdentityRootCluster.userName, - roles: ['circle-mark-app-access'], - sshLogins: ['root'], - }), - }); - return ( - Promise.resolve()} - logout={() => {}} - addCluster={() => {}} + ); } diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx index f5c7cd25cbc1f..e15db0888d35d 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/Identity.tsx @@ -16,14 +16,7 @@ * along with this program. If not, see . */ -import { - forwardRef, - useCallback, - useImperativeHandle, - useMemo, - useRef, - useState, -} from 'react'; +import { useCallback, useMemo, useRef, useState } from 'react'; import styled from 'styled-components'; import { Box } from 'design'; @@ -31,15 +24,16 @@ import Popover from 'design/Popover'; import { TrustedDeviceRequirement } from 'gen-proto-ts/teleport/legacy/types/trusted_device_requirement_pb'; import * as tshd from 'teleterm/services/tshd/types'; +import { KeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; +import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; import { useKeyboardShortcutFormatters, useKeyboardShortcuts, } from 'teleterm/ui/services/keyboardShortcuts'; -import { EmptyIdentityList } from './EmptyIdentityList/EmptyIdentityList'; -import { IdentityList } from './IdentityList/IdentityList'; +import { ActiveCluster, ClusterList } from './IdentityList/IdentityList'; import { IdentitySelector } from './IdentitySelector/IdentitySelector'; -import { IdentityRootCluster, useIdentity } from './useIdentity'; +import { useIdentity } from './useIdentity'; export function IdentityContainer() { const { @@ -48,17 +42,27 @@ export function IdentityContainer() { changeRootCluster, logout, addCluster, + refreshCluster, + changeColor, } = useIdentity(); + const selectorRef = useRef(); + const [open, setOpen] = useState(false); const { getLabelWithAccelerator } = useKeyboardShortcutFormatters(); - - const presenterRef = useRef(); + const hasClusters = activeRootCluster || rootClusters.length; + const togglePopoverOrAddCluster = useCallback(() => { + if (hasClusters) { + setOpen(o => !o); + } else { + addCluster(); + } + }, [addCluster, hasClusters]); useKeyboardShortcuts( useMemo( () => ({ - openProfiles: presenterRef.current?.togglePopover, + openProfiles: togglePopoverOrAddCluster, }), - [presenterRef.current?.togglePopover] + [togglePopoverOrAddCluster] ) ); @@ -68,109 +72,71 @@ export function IdentityContainer() { 'openProfiles' ); + function withClose any>( + fn: T + ): (...args: Parameters) => ReturnType { + return (...args) => { + setOpen(false); + return fn(...args); + }; + } + + const deviceTrustStatus = calculateDeviceTrustStatus( + activeRootCluster?.loggedInUser + ); + const activeColor = useStoreSelector( + 'workspacesService', + useCallback(state => state.workspaces[state.rootClusterUri]?.color, []) + ); + return ( - + <> + + setOpen(false)} + popoverCss={() => `max-width: min(450px, 90%)`} + > + + {activeRootCluster && ( + logout(activeRootCluster.uri))} + onRefresh={withClose(() => refreshCluster(activeRootCluster.uri))} + deviceTrustStatus={deviceTrustStatus} + /> + )} + + {focusGrabber} + + + + + ); } -export type IdentityHandler = { togglePopover: () => void }; - -export type IdentityProps = { - activeRootCluster: tshd.Cluster | undefined; - rootClusters: IdentityRootCluster[]; - changeRootCluster: (clusterUri: string) => Promise; - logout: (clusterUri: string) => void; - addCluster: () => void; - makeTitle: (userWithClusterName: string | undefined) => string; -}; - -export const Identity = forwardRef( - ( - { - activeRootCluster, - rootClusters, - changeRootCluster, - logout, - addCluster, - makeTitle, - }, - ref - ) => { - const selectorRef = useRef(); - const [isPopoverOpened, setIsPopoverOpened] = useState(false); - - const togglePopover = useCallback(() => { - setIsPopoverOpened(wasOpened => !wasOpened); - }, [setIsPopoverOpened]); - - function withClose any>( - fn: T - ): (...args: Parameters) => ReturnType { - return (...args) => { - setIsPopoverOpened(false); - return fn(...args); - }; - } - - useImperativeHandle(ref, () => ({ - togglePopover: () => { - togglePopover(); - }, - })); - - const loggedInUser = activeRootCluster?.loggedInUser; - - const deviceTrustStatus = calculateDeviceTrustStatus(loggedInUser); - - return ( - <> - - setIsPopoverOpened(false)} - popoverCss={() => `max-width: min(560px, 90%)`} - > - - {rootClusters.length ? ( - - ) : ( - - )} - - - - ); - } -); - const Container = styled(Box)` background: ${props => props.theme.colors.levels.elevated}; + min-width: 300px; width: 100%; `; @@ -192,3 +158,18 @@ function calculateDeviceTrustStatus( } return 'none'; } + +// Hack - for some reason xterm.js doesn't allow moving focus to the Identity popover +// when it is focused using element.focus(). +// It used to restore focus after the popover was closed, but this no longer seems to work. +const focusGrabber = ( + +); diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx deleted file mode 100644 index 71755da3d4a21..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/AddNewClusterItem.tsx +++ /dev/null @@ -1,51 +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 styled from 'styled-components'; - -import { Add } from 'design/Icon'; - -import { useKeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; -import { ListItem } from 'teleterm/ui/components/ListItem'; - -interface AddNewClusterItemProps { - index: number; - - onClick(): void; -} - -export function AddNewClusterItem(props: AddNewClusterItemProps) { - const { isActive } = useKeyboardArrowsNavigation({ - index: props.index, - onRun: props.onClick, - }); - - return ( - - - Add another cluster - - ); -} - -const StyledListItem = styled(ListItem)` - border-radius: 0; - height: 38px; - justify-content: center; - color: ${props => props.theme.colors.text.slightlyMuted}; -`; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx new file mode 100644 index 0000000000000..479b852d6b60f --- /dev/null +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/ColorPicker.tsx @@ -0,0 +1,130 @@ +/** + * Teleport + * Copyright (C) 2025 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 { useState } from 'react'; +import styled from 'styled-components'; + +import { Box, Flex } from 'design'; +import { Pencil } from 'design/Icon'; +import { useRefClickOutside } from 'shared/hooks/useRefClickOutside'; + +import { + WorkspaceColor, + workspaceColorMapping, + workspaceColors, +} from 'teleterm/ui/services/workspacesService'; + +import { UserIcon } from '../IdentitySelector/UserIcon'; + +export function ColorPicker(props: { + letter: string; + color: WorkspaceColor; + setColor(color: WorkspaceColor): void; +}) { + const [open, setOpen] = useState(false); + const [hoveredColor, setHoveredColor] = useState< + WorkspaceColor | undefined + >(); + const ref = useRefClickOutside({ open, setOpen }); + + const userIconProps = { + size: 'big' as const, + onClick: () => setOpen(o => !o), + letter: props.letter, + }; + + return ( + + + + + {open && ( + + + + {workspaceColors.options.map(color => ( + setHoveredColor(color)} + onMouseLeave={() => setHoveredColor(undefined)} + onClick={() => { + props.setColor(color); + setOpen(false); + }} + /> + ))} + + + )} + + ); +} + +const Circle = styled.button<{ color?: string }>` + border-radius: 50%; + background: ${props => props.color}; + height: 16px; + width: 16px; + border: none; + cursor: pointer; + box-shadow: rgba(0, 0, 0, 0.15) 0 1px 3px; + + &:focus-visible { + outline: 1px solid ${props => props.theme.colors.text.muted}; + } + + &:hover { + opacity: 0.9; + } +`; + +const AbsolutePencilIcon = styled(Pencil).attrs({ size: 11 })` + position: absolute; + bottom: -1px; + left: 21px; + border-radius: 50%; + color: black; + background: rgb(240, 240, 240); + box-shadow: rgba(0, 0, 0, 0.15) 0 1px 3px; + height: 16px; + width: 16px; +`; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx index 9f2d023272023..86158707c1200 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityList.tsx @@ -19,68 +19,117 @@ import { JSX } from 'react'; import styled from 'styled-components'; -import { Box, Flex, Label, P3, Text } from 'design'; -import { ShieldCheck, ShieldWarning } from 'design/Icon'; +import { ButtonText, Flex, Label, P3 } from 'design'; +import { Logout, Refresh, ShieldCheck, ShieldWarning } from 'design/Icon'; import Link from 'design/Link'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; -import { LoggedInUser } from 'teleterm/services/tshd/types'; -import { KeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; +import { ProfileStatusError } from 'teleterm/ui/components/ProfileStatusError'; +import { WorkspaceColor } from 'teleterm/ui/services/workspacesService'; import { DeviceTrustStatus } from 'teleterm/ui/TopBar/Identity/Identity'; +import { RootClusterUri } from 'teleterm/ui/uri'; -import { IdentityRootCluster } from '../useIdentity'; -import { AddNewClusterItem } from './AddNewClusterItem'; -import { IdentityListItem } from './IdentityListItem'; +import { ColorPicker } from './ColorPicker'; +import { + AddClusterItem, + getClusterLetter, + IdentityListItem, + TitleAndSubtitle, +} from './IdentityListItem'; -export function IdentityList(props: { - loggedInUser: LoggedInUser; - clusters: IdentityRootCluster[]; - onSelectCluster(clusterUri: string): void; - onAddCluster(): void; - onLogout(clusterUri: string): void; +export function ActiveCluster(props: { + activeCluster: Cluster | undefined; + activeColor: WorkspaceColor; deviceTrustStatus: DeviceTrustStatus; + onChangeColor(color: WorkspaceColor): void; + onRefresh(): void; + onLogout(): void; }) { return ( - - {props.loggedInUser && ( - <> - - - {props.loggedInUser.name} - - {props.loggedInUser.roles.map(role => ( - - ))} - - - - - - - )} - - {focusGrabber} - - {props.clusters.map((cluster, index) => ( - props.onSelectCluster(cluster.uri)} - onLogout={() => props.onLogout(cluster.uri)} + <> + + + + - ))} - - - - + + + + props.onRefresh()} + > + + + props.onLogout()} + intent="danger" + size="small" + > + + + + + {props.activeCluster.profileStatusError && ( + props.theme.space[2]}px; + gap: 14px; + `} /> - - - + )} + + {props.activeCluster.loggedInUser?.roles.map(role => ( + + ))} + + + + + + ); +} + +export function ClusterList(props: { + clusters: Cluster[]; + onSelect(clusterUri: RootClusterUri): void; + onLogout?(clusterUri: RootClusterUri): void; + onAdd(): void; +}) { + return ( + <> + {props.clusters.map((cluster, index) => ( + props.onSelect(cluster.uri)} + onLogout={ + props.onLogout ? () => props.onLogout(cluster.uri) : undefined + } + /> + ))} + + ); } @@ -126,21 +175,6 @@ function DeviceTrustMessage(props: { status: DeviceTrustStatus }) { } } -// Hack - for some reason xterm.js doesn't allow moving a focus to the Identity popover -// when it is focused using element.focus(). Moreover, it looks like this solution has a benefit -// of returning the focus to the previously focused element when popover is closed. -const focusGrabber = ( - -); - const Separator = styled.div` background: ${props => props.theme.colors.spotBackground[1]}; height: 1px; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx index d1d053612d1dd..bc3a8b2f6248a 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentityList/IdentityListItem.tsx @@ -15,85 +15,157 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +import { useCallback } from 'react'; +import styled from 'styled-components'; -import { useState } from 'react'; - -import { ButtonIcon, Flex, Label, Text } from 'design'; +import { ButtonText, Flex, P3, Text } from 'design'; import { Logout } from 'design/Icon'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; import { useKeyboardArrowsNavigation } from 'teleterm/ui/components/KeyboardArrowsNavigation'; import { ListItem } from 'teleterm/ui/components/ListItem'; import { ProfileStatusError } from 'teleterm/ui/components/ProfileStatusError'; -import { getUserWithClusterName } from 'teleterm/ui/utils'; +import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; +import { WorkspaceColor } from 'teleterm/ui/services/workspacesService'; -import { IdentityRootCluster } from '../useIdentity'; +import { UserIcon } from '../IdentitySelector/UserIcon'; export function IdentityListItem(props: { index: number; - cluster: IdentityRootCluster; + cluster: Cluster; onSelect(): void; - onLogout(): void; + /** If defined, the logout button is rendered. */ + onLogout?(): void; }) { - const [isHovered, setIsHovered] = useState(false); const { isActive } = useKeyboardArrowsNavigation({ index: props.index, onRun: props.onSelect, }); - - const userWithClusterName = getUserWithClusterName(props.cluster); + const workspaceColor = useStoreSelector( + 'workspacesService', + useCallback( + state => state.workspaces[props.cluster.uri]?.color, + [props.cluster.uri] + ) + ); return ( - + (e.key === 'Enter' || e.key === 'Space') && props.onSelect() + } isActive={isActive} - onMouseEnter={() => { - setIsHovered(true); - }} - onMouseLeave={() => { - setIsHovered(false); - }} + title={`Switch to ${props.cluster.name}`} > - - - - {userWithClusterName} - - {props.cluster.profileStatusError && ( - - )} - - - {props.cluster.active ? ( - - ) : null} - + + {props.onLogout && ( + { e.stopPropagation(); props.onLogout(); }} > - {/* Due to the icon shape it appears to be not centered, so a small margin is added */} - - - + + + )} - + {props.cluster.profileStatusError && ( + props.theme.space[2]}px; + gap: 10px; + `} + /> + )} + ); } + +export function AddClusterItem(props: { index: number; onClick(): void }) { + const { isActive } = useKeyboardArrowsNavigation({ + index: props.index, + onRun: props.onClick, + }); + + return ( + + + + ); +} + +const StyledListItem = styled(ListItem)` + padding: ${props => props.theme.space[2]}px ${props => props.theme.space[3]}px; + flex-direction: column; + align-items: start; + gap: ${props => props.theme.space[1]}px; + border-radius: 0; + height: 100%; + &:hover .logout { + visibility: visible; + } +`; + +function WithIconItem(props: { + letter: string; + title: string; + subtitle?: string; + color?: WorkspaceColor; +}) { + return ( + + + + + ); +} + +export function TitleAndSubtitle(props: { title: string; subtitle?: string }) { + return ( + + + {props.title} + + + {props.subtitle && ( + + {props.subtitle} + + )} + + ); +} + +export function getClusterLetter(cluster: Cluster): string { + return cluster.name.at(0); +} diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx index c99d3f20ff729..df1d83ac0d7ee 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/IdentitySelector.tsx @@ -19,35 +19,39 @@ import { forwardRef } from 'react'; import { Box } from 'design'; +import { Cluster } from 'gen-proto-ts/teleport/lib/teleterm/v1/cluster_pb'; +import { WorkspaceColor } from 'teleterm/ui/services/workspacesService'; import { ConnectionStatusIndicator } from 'teleterm/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator'; import { DeviceTrustStatus } from 'teleterm/ui/TopBar/Identity/Identity'; import { TopBarButton } from 'teleterm/ui/TopBar/TopBarButton'; import { getUserWithClusterName } from 'teleterm/ui/utils'; -import { PamIcon } from './PamIcon'; +import { getClusterLetter } from '../IdentityList/IdentityListItem'; import { UserIcon } from './UserIcon'; -interface IdentitySelectorProps { - isOpened: boolean; - userName: string; - clusterName: string; - onClick(): void; - makeTitle: (userWithClusterName: string | undefined) => string; - deviceTrustStatus: DeviceTrustStatus; -} - export const IdentitySelector = forwardRef< HTMLButtonElement, - IdentitySelectorProps + { + open: boolean; + activeCluster: Cluster | undefined; + onClick(): void; + makeTitle(userWithClusterName: string | undefined): string; + deviceTrustStatus: DeviceTrustStatus; + activeColor: WorkspaceColor; + } >((props, ref) => { - const isSelected = props.userName && props.clusterName; - const selectorText = isSelected && getUserWithClusterName(props); + const selectorText = + props.activeCluster && + getUserWithClusterName({ + clusterName: props.activeCluster.name, + userName: props.activeCluster.loggedInUser?.name, + }); const title = props.makeTitle(selectorText); return ( - {isSelected ? ( + {props.activeCluster ? ( - + {props.deviceTrustStatus === 'requires-enrollment' && ( ) : ( - + )} ); diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx deleted file mode 100644 index a7a4c9d4dc282..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/PamIcon.tsx +++ /dev/null @@ -1,41 +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 styled from 'styled-components'; - -import { Image } from 'design'; - -import pam from './pam.svg'; - -export function PamIcon() { - return ( - - - - ); -} - -const PamCircle = styled.div` - height: 24px; - width: 24px; - display: flex; - align-content: center; - justify-content: center; - border-radius: 50%; - background: ${props => props.theme.colors.spotBackground[0]}; -`; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx index 4807171195940..a71c1b3f571cf 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/UserIcon.tsx @@ -16,25 +16,67 @@ * along with this program. If not, see . */ +import { MouseEvent, ReactNode } from 'react'; import styled from 'styled-components'; -interface UserIconProps { - letter: string; -} +import { + WorkspaceColor, + workspaceColorMapping, +} from 'teleterm/ui/services/workspacesService'; -export function UserIcon(props: UserIconProps) { - return {props.letter.toLocaleUpperCase()}; +export function UserIcon(props: { + letter: string; + /** If not provided, a default neutral color is rendered. */ + color?: WorkspaceColor; + onClick?(e: MouseEvent): void; + children?: ReactNode; + interactive?: boolean; + size?: 'regular' | 'big'; +}) { + return ( + + {props.letter?.toLocaleUpperCase()} + {props.children} + + ); } -const Circle = styled.span` +const Circle = styled.span<{ + color?: string; + interactive?: boolean; + size: string; +}>` + position: relative; border-radius: 50%; - color: ${props => props.theme.colors.buttons.primary.text}; - background: ${props => props.theme.colors.buttons.primary.default}; - height: 24px; - width: 24px; + color: ${props => + props.color + ? props.theme.colors.text.primaryInverse + : props.theme.colors.text.main}; + background: ${props => + props.color || props.theme.colors.interactive.tonal.neutral[1]}; + height: ${props => props.size}; + width: ${props => props.size}; display: flex; - flex-shrink: 0; + font-weight: 500; justify-content: center; align-items: center; - overflow: hidden; + box-shadow: rgba(0, 0, 0, 0.15) 0 1px 3px; + border: none; + &:focus-visible { + outline: 2px solid ${props => props.theme.colors.text.muted}; + } + ${props => + props.interactive && + ` + &:hover { + opacity: 0.9; + } + cursor: pointer; + `} `; diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg b/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg deleted file mode 100644 index 8ae4aed3b0686..0000000000000 --- a/web/packages/teleterm/src/ui/TopBar/Identity/IdentitySelector/pam.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts b/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts index a19e5201b3322..95e111e175594 100644 --- a/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts +++ b/web/packages/teleterm/src/ui/TopBar/Identity/useIdentity.ts @@ -16,9 +16,14 @@ * along with this program. If not, see . */ -import { Cluster, LoggedInUser } from 'teleterm/services/tshd/types'; +import { useCallback } from 'react'; + +import { Cluster } from 'teleterm/services/tshd/types'; import { useAppContext } from 'teleterm/ui/appContextProvider'; -import { useWorkspaceServiceState } from 'teleterm/ui/services/workspacesService'; +import { + useWorkspaceServiceState, + WorkspaceColor, +} from 'teleterm/ui/services/workspacesService'; import { RootClusterUri } from 'teleterm/ui/uri'; export function useIdentity() { @@ -31,61 +36,43 @@ export function useIdentity() { await ctx.workspacesService.setActiveWorkspace(clusterUri); } - function addCluster(): void { + const addCluster = useCallback(() => { ctx.commandLauncher.executeCommand('cluster-connect', {}); + }, [ctx.commandLauncher]); + + function refreshCluster(clusterUri: RootClusterUri): void { + ctx.commandLauncher.executeCommand('cluster-connect', { clusterUri }); } function logout(clusterUri: RootClusterUri): void { ctx.commandLauncher.executeCommand('cluster-logout', { clusterUri }); } + const activeClusterUri = ctx.workspacesService.getRootClusterUri(); function getActiveRootCluster(): Cluster | undefined { - const clusterUri = ctx.workspacesService.getRootClusterUri(); - if (!clusterUri) { - return; - } - return ctx.clustersService.findCluster(clusterUri); + return ctx.clustersService.findCluster(activeClusterUri); } - function getLoggedInUser(): LoggedInUser | undefined { + function changeColor(color: WorkspaceColor): undefined { const clusterUri = ctx.workspacesService.getRootClusterUri(); if (!clusterUri) { return; } - const cluster = ctx.clustersService.findCluster(clusterUri); - if (!cluster) { - return; - } - return cluster.loggedInUser; + ctx.workspacesService.changeWorkspaceColor(clusterUri, color); } - const rootClusters: IdentityRootCluster[] = ctx.clustersService + const rootClusters = ctx.clustersService .getClusters() .filter(c => !c.leaf) - .map(cluster => ({ - active: cluster.uri === ctx.workspacesService.getRootClusterUri(), - clusterName: cluster.name, - userName: cluster.loggedInUser?.name, - uri: cluster.uri, - connected: cluster.connected, - profileStatusError: cluster.profileStatusError, - })); + .filter(c => c.uri !== activeClusterUri); return { changeRootCluster, addCluster, + refreshCluster, logout, - loggedInUser: getLoggedInUser(), + changeColor, activeRootCluster: getActiveRootCluster(), rootClusters, }; } - -export interface IdentityRootCluster { - active: boolean; - clusterName: string; - userName: string; - uri: RootClusterUri; - connected: boolean; - profileStatusError: string; -} diff --git a/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx b/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx index 7ea02bdc193bf..1ee0d43115751 100644 --- a/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx +++ b/web/packages/teleterm/src/ui/components/KeyboardArrowsNavigation/KeyboardArrowsNavigation.tsx @@ -106,6 +106,24 @@ export const KeyboardArrowsNavigation: FC = props => { ); }; +export const NullKeyboardArrowsNavigation: FC = props => { + const value = useMemo( + () => ({ + addItem: () => {}, + removeItem: () => {}, + activeIndex: -1, + setActiveIndex: () => {}, + }), + [] + ); + + return ( + +
{props.children}
+
+ ); +}; + function getNextIndex( items: RunActiveItemHandler[], currentIndex: number diff --git a/web/packages/teleterm/src/ui/components/ListItem.tsx b/web/packages/teleterm/src/ui/components/ListItem.tsx index 59b9ce56f70bc..44c2326f5bdc2 100644 --- a/web/packages/teleterm/src/ui/components/ListItem.tsx +++ b/web/packages/teleterm/src/ui/components/ListItem.tsx @@ -24,26 +24,33 @@ export const StaticListItem = styled.li` display: flex; align-items: center; justify-content: flex-start; - width: 100%; - position: relative; - font-size: 14px; - padding: 0 16px; + outline: none; font-weight: ${props => props.theme.regular}; font-family: ${props => props.theme.font}; color: ${props => props.theme.colors.text.main}; + position: relative; + font-size: 14px; + padding: 0 16px; height: 34px; background: inherit; border: none; border-radius: 4px; `; -export const ListItem = styled(StaticListItem)<{ isActive?: boolean }>` +export const ListItem = styled(StaticListItem).attrs({ tabIndex: 0 })<{ + isActive?: boolean; +}>` cursor: pointer; background: ${props => - props.isActive ? props.theme.colors.spotBackground[0] : null}; + props.isActive ? props.theme.colors.interactive.tonal.neutral[0] : null}; - &:focus, + &:focus-visible { + outline: 1px solid ${props => props.theme.colors.text.muted}; + background: ${props => props.theme.colors.interactive.tonal.neutral[0]}; + } &:hover { - background: ${props => props.theme.colors.spotBackground[0]}; + outline: 1px solid + ${props => props.theme.colors.interactive.tonal.neutral[0]}; + background: ${props => props.theme.colors.interactive.tonal.neutral[0]}; } `; diff --git a/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx b/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx index dfc6be8684823..de97f6432e863 100644 --- a/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx +++ b/web/packages/teleterm/src/ui/components/ProfileStatusError.tsx @@ -21,12 +21,20 @@ import { Warning } from 'design/Icon'; export function ProfileStatusError(props: { error: string; - mb?: number | string; -}) { + className?: string; +}): JSX.Element { return ( - + - {toWellFormattedConnectionError(props.error)} + + {toWellFormattedConnectionError(props.error)} + ); } diff --git a/web/packages/teleterm/src/ui/services/workspacesService/color.ts b/web/packages/teleterm/src/ui/services/workspacesService/color.ts index d6627fc0b6c5f..8c1333aa68ab6 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/color.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/color.ts @@ -18,6 +18,8 @@ import { z } from 'zod'; +import { dataVisualisationColors } from 'design/theme/themes/darkTheme'; + import Logger from 'teleterm/logger'; export type WorkspaceColor = z.infer; @@ -57,7 +59,7 @@ export function parseWorkspaceColor( /** * Determines the next available unused color across all workspaces. - * If all colors are already in use, it defaults to returning purple. + * If all colors are already in use, it returns purple. */ function getNextWorkspaceColor( workspaces: Record @@ -67,3 +69,19 @@ function getNextWorkspaceColor( const unusedColors = allColors.difference(takenColors); return unusedColors.size > 0 ? [...unusedColors][0] : 'purple'; } + +/** + * Maps workspace colors to the theme colors. + * We always use dark theme colors. + * They look good in both light and dark modes, + * and we avoid confusing users with different shades of the same color. + */ +export const workspaceColorMapping: Record = { + purple: dataVisualisationColors.primary.purple, + red: dataVisualisationColors.primary.abbey, + green: dataVisualisationColors.primary.caribbean, + yellow: dataVisualisationColors.primary.sunflower, + blue: dataVisualisationColors.primary.picton, + cyan: dataVisualisationColors.primary.cyan, + pink: dataVisualisationColors.primary.wednesdays, +}; diff --git a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts index 399321bae23b5..48a18aff66d29 100644 --- a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts +++ b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts @@ -135,7 +135,7 @@ describe('restoring workspace', () => { expect(workspacesService.getRestoredState().workspaces).toStrictEqual({}); }); - it('restores profile color from state or assigns if empty', async () => { + it('restores workspace color from state or assigns if empty', async () => { const clusterFoo = makeRootCluster({ uri: '/clusters/foo' }); const workspaceFoo: PersistedWorkspace = { color: 'blue', From a5131a09eb459e605b978a7b67186a090309b5f2 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:03:00 -0500 Subject: [PATCH 15/28] Add Audit Log tab to tctl top (#51620) The new tab consumes `audit_failed_emit_events`, `teleport_audit_stored_trimmed_events`, and `teleport_audit_emitted_event_sizes` to help troubleshoot issues related to audit log backends. The metrics are displayed in graphs which illustrate the change in metrics over the sampling period. --- tool/tctl/common/top/model.go | 59 ++++++++++++++++- tool/tctl/common/top/report.go | 118 ++++++++++++++++++++++++++++++++- tool/tsh/common/latency.go | 1 + 3 files changed, 176 insertions(+), 2 deletions(-) diff --git a/tool/tctl/common/top/model.go b/tool/tctl/common/top/model.go index be7debcd6105e..dd4668a197d64 100644 --- a/tool/tctl/common/top/model.go +++ b/tool/tctl/common/top/model.go @@ -103,6 +103,8 @@ func (m *topModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.selected = 2 case "4": m.selected = 3 + case "5": + m.selected = 4 case "right": m.selected = min(m.selected+1, len(tabs)-1) case "left": @@ -218,6 +220,8 @@ func (m *topModel) contentView() string { return renderCache(m.report, m.height, m.width) case 3: return renderWatcher(m.report, m.height, m.width) + case 4: + return renderAudit(m.report, m.height, m.width) default: return "" } @@ -412,6 +416,7 @@ func renderWatcher(report *Report, height, width int) string { eventData, asciigraph.Height(graphHeight), asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), ) eventCountContent := boxedView("Events/Sec", countPlot, graphWidth) @@ -423,6 +428,7 @@ func renderWatcher(report *Report, height, width int) string { sizeData, asciigraph.Height(graphHeight), asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), ) eventSizeContent := boxedView("Bytes/Sec", sizePlot, graphWidth) @@ -449,6 +455,54 @@ func renderWatcher(report *Report, height, width int) string { ) } +// renderAudit generates the view for the audit stats tab. +func renderAudit(report *Report, height, width int) string { + graphHeight := height / 3 + graphWidth := width + + eventsLegend := lipgloss.JoinHorizontal( + lipgloss.Left, + "- Emitted", + failedEventStyle.Render(" - Failed"), + trimmedEventStyle.Render(" - Trimmed"), + ) + + eventsPlot := asciigraph.PlotMany( + [][]float64{ + report.Audit.EmittedEventsBuffer.Data(graphWidth - 15), + report.Audit.FailedEventsBuffer.Data(graphWidth - 15), + report.Audit.TrimmedEventsBuffer.Data(graphWidth - 15), + }, + asciigraph.Height(graphHeight), + asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), + asciigraph.SeriesColors(asciigraph.Default, asciigraph.Red, asciigraph.Goldenrod), + asciigraph.Caption(eventsLegend), + ) + eventGraph := boxedView("Events Emitted", eventsPlot, graphWidth) + + eventSizePlot := asciigraph.Plot( + report.Audit.EventSizeBuffer.Data(graphWidth-15), + asciigraph.Height(graphHeight), + asciigraph.Width(graphWidth-15), + asciigraph.UpperBound(1), + ) + sizeGraph := boxedView("Event Sizes", eventSizePlot, graphWidth) + + graphStyle := lipgloss.NewStyle(). + Width(graphWidth). + Padding(0). + Margin(0). + Align(lipgloss.Left) + + return lipgloss.JoinVertical(lipgloss.Left, + graphStyle.Render( + eventGraph, + sizeGraph, + ), + ) +} + // tabView renders the tabbed content in the header. func tabView(selectedTab int) string { output := lipgloss.NewStyle(). @@ -520,5 +574,8 @@ var ( selectedColor = lipgloss.Color("4") - tabs = []string{"Common", "Backend", "Cache", "Watcher"} + failedEventStyle = lipgloss.NewStyle().Foreground(lipgloss.Color(fmt.Sprintf("%d", asciigraph.Red))) + trimmedEventStyle = lipgloss.NewStyle().Foreground(lipgloss.Color(fmt.Sprintf("%d", asciigraph.Goldenrod))) + + tabs = []string{"Common", "Backend", "Cache", "Watcher", "Audit"} ) diff --git a/tool/tctl/common/top/report.go b/tool/tctl/common/top/report.go index 95ff68382804f..b185daf9958e9 100644 --- a/tool/tctl/common/top/report.go +++ b/tool/tctl/common/top/report.go @@ -59,6 +59,32 @@ type Report struct { Cluster ClusterStats // Watcher is watcher stats Watcher *WatcherStats + // Audit contains stats for audit event backends. + Audit *AuditStats +} + +// AuditStats contains metrics related to the audit log. +type AuditStats struct { + // FailedEventsCounter tallies the frequency of failed events. + FailedEventsCounter *Counter + // FailedEventsBuffer contains the historical frequencies of + // the FailedEventsCounter. + FailedEventsBuffer *utils.CircularBuffer + // EmittedEventsCounter tallies the frequency of all emitted events. + EmittedEventsCounter *Counter + // EmittedEventsBuffer contains the historical frequencies of + // the EmittedEventsCounter. + EmittedEventsBuffer *utils.CircularBuffer + // EventSizeCounter tallies the frequency of all events. + EventSizeCounter *Counter + // EventSizeBuffer contains the historical sizes of + // the EventSizeCounter. + EventSizeBuffer *utils.CircularBuffer + // EventsCounter tallies the frequency of trimmed events. + TrimmedEventsCounter *Counter + // TrimmedEventsBuffer contains the historical sizes of + // the TrimmedEventsCounter. + TrimmedEventsBuffer *utils.CircularBuffer } // WatcherStats contains watcher stats @@ -256,7 +282,8 @@ type Counter struct { } // SetFreq sets counter frequency based on the previous value -// and the time period +// and the time period. SetFreq should be preffered over UpdateFreq +// when initializing a Counter from previous statistics. func (c *Counter) SetFreq(prevCount Counter, period time.Duration) { if period == 0 { return @@ -265,6 +292,25 @@ func (c *Counter) SetFreq(prevCount Counter, period time.Duration) { c.Freq = &freq } +// UpdateFreq sets counter frequency based on the previous value +// and the time period. UpdateFreq should be preferred over SetFreq +// if the Counter is reused. +func (c *Counter) UpdateFreq(currentCount int64, period time.Duration) { + if period == 0 { + return + } + + // Do not calculate the frequency until there are two data points. + if c.Count == 0 && c.Freq == nil { + c.Count = currentCount + return + } + + freq := float64(currentCount-c.Count) / float64(period/time.Second) + c.Freq = &freq + c.Count = currentCount +} + // GetFreq returns frequency of the request func (c Counter) GetFreq() float64 { if c.Freq == nil { @@ -424,6 +470,13 @@ func generateReport(metrics map[string]*dto.MetricFamily, prev *Report, period t Roles: getGaugeValue(metrics[prometheus.BuildFQName(teleport.MetricNamespace, "", "roles_total")]), } + var auditStats *AuditStats + if prev != nil { + auditStats = prev.Audit + } + + re.Audit = getAuditStats(metrics, auditStats, period) + if prev != nil { re.Cluster.GenerateRequestsCount.SetFreq(prev.Cluster.GenerateRequestsCount, period) re.Cluster.GenerateRequestsThrottledCount.SetFreq(prev.Cluster.GenerateRequestsThrottledCount, period) @@ -548,6 +601,69 @@ func getWatcherStats(metrics map[string]*dto.MetricFamily, prev *WatcherStats, p return stats } +func getAuditStats(metrics map[string]*dto.MetricFamily, prev *AuditStats, period time.Duration) *AuditStats { + if prev == nil { + failed, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + events, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + trimmed, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + sizes, err := utils.NewCircularBuffer(150) + if err != nil { + return nil + } + + prev = &AuditStats{ + FailedEventsBuffer: failed, + FailedEventsCounter: &Counter{}, + EmittedEventsBuffer: events, + EmittedEventsCounter: &Counter{}, + TrimmedEventsBuffer: trimmed, + TrimmedEventsCounter: &Counter{}, + EventSizeBuffer: sizes, + EventSizeCounter: &Counter{}, + } + } + + updateCounter := func(metrics map[string]*dto.MetricFamily, metric string, counter *Counter, buf *utils.CircularBuffer) { + current := getCounterValue(metrics[metric]) + counter.UpdateFreq(current, period) + buf.Add(counter.GetFreq()) + } + + updateCounter(metrics, prometheus.BuildFQName("", "audit", "failed_emit_events"), prev.FailedEventsCounter, prev.FailedEventsBuffer) + updateCounter(metrics, prometheus.BuildFQName(teleport.MetricNamespace, "audit", "stored_trimmed_events"), prev.TrimmedEventsCounter, prev.TrimmedEventsBuffer) + + histogram := getHistogram(metrics[prometheus.BuildFQName(teleport.MetricNamespace, "", "audit_emitted_event_sizes")], atIndex(0)) + + prev.EmittedEventsCounter.UpdateFreq(histogram.Count, period) + prev.EmittedEventsBuffer.Add(prev.EmittedEventsCounter.GetFreq()) + + prev.EventSizeCounter.UpdateFreq(int64(histogram.Sum), period) + prev.EventSizeBuffer.Add(prev.EventSizeCounter.GetFreq()) + + return &AuditStats{ + FailedEventsBuffer: prev.FailedEventsBuffer, + FailedEventsCounter: prev.FailedEventsCounter, + EmittedEventsBuffer: prev.EmittedEventsBuffer, + EmittedEventsCounter: prev.EmittedEventsCounter, + TrimmedEventsBuffer: prev.TrimmedEventsBuffer, + TrimmedEventsCounter: prev.TrimmedEventsCounter, + EventSizeBuffer: prev.EventSizeBuffer, + EventSizeCounter: prev.EventSizeCounter, + } +} + func getRemoteClusters(metric *dto.MetricFamily) []RemoteCluster { if metric == nil || metric.GetType() != dto.MetricType_GAUGE || len(metric.Metric) == 0 { return nil diff --git a/tool/tsh/common/latency.go b/tool/tsh/common/latency.go index 6089f58c7bd44..6c73bd73d623b 100644 --- a/tool/tsh/common/latency.go +++ b/tool/tsh/common/latency.go @@ -151,6 +151,7 @@ func (m *latencyModel) View() string { [][]float64{clientData, serverData}, asciigraph.Height(m.h-4), asciigraph.Width(m.w), + asciigraph.UpperBound(1), asciigraph.SeriesColors(clientColor, serverColor), asciigraph.Caption(legend), ) From 476c9e40f1fd428009fab9869c6ec6e99276c7e6 Mon Sep 17 00:00:00 2001 From: Marco Dinis Date: Thu, 30 Jan 2025 16:27:14 +0000 Subject: [PATCH 16/28] DiscoveryConfigStatus: update counters once per iteration (#51647) DiscoveryService can process DiscoveryConfig matchers and will update its Status field depending on the number of found resources. Currently, it was updating them in real-time-ish: every time it found a new resource, it would update the counter in memory and propagate that change into the cluster shared storage. However, this resulted in counters flutuating a lot and causing confusion from the user's point of view (being at 0 every couple of minutes). Instead, this PR, ensures we update the values only once per iteration cycle (happens at discovery_service.poll_interval - defaults to 5 miunutes). This means we lose real-time observation of the counters, but we gain stability on the values which should help UX. --- lib/srv/discovery/database_watcher.go | 14 ++--- lib/srv/discovery/discovery.go | 29 ++-------- lib/srv/discovery/discovery_test.go | 55 +++++++++++++------ lib/srv/discovery/kube_integration_watcher.go | 16 ++---- lib/srv/discovery/status.go | 2 - lib/srv/server/azure_watcher.go | 2 + lib/srv/server/ec2_watcher.go | 2 + lib/srv/server/gcp_watcher.go | 2 + lib/srv/server/watcher.go | 15 ++++- 9 files changed, 71 insertions(+), 66 deletions(-) diff --git a/lib/srv/discovery/database_watcher.go b/lib/srv/discovery/database_watcher.go index 75c306c9a6306..d9b52d3671081 100644 --- a/lib/srv/discovery/database_watcher.go +++ b/lib/srv/discovery/database_watcher.go @@ -85,7 +85,6 @@ func (s *Server) startDatabaseWatchers() error { go func() { for { - discoveryConfigsChanged := map[string]struct{}{} resourcesFoundByGroup := make(map[awsResourceGroup]int) select { @@ -99,7 +98,6 @@ func (s *Server) startDatabaseWatchers() error { resourceGroup := awsResourceGroupFromLabels(db.GetStaticLabels()) resourcesFoundByGroup[resourceGroup] += 1 - discoveryConfigsChanged[resourceGroup.discoveryConfigName] = struct{}{} dbs = append(dbs, db) @@ -136,9 +134,6 @@ func (s *Server) startDatabaseWatchers() error { return } - for dc := range discoveryConfigsChanged { - s.updateDiscoveryConfigStatus(dc) - } s.upsertTasksForAWSRDSFailedEnrollments() } }() @@ -203,16 +198,15 @@ func (s *Server) databaseWatcherIterationStarted() { }, ) - for _, g := range awsResultGroups { - s.awsRDSResourcesStatus.iterationStarted(g) - } - discoveryConfigs := slices.FilterMapUnique(awsResultGroups, func(g awsResourceGroup) (s string, include bool) { return g.discoveryConfigName, true }) s.updateDiscoveryConfigStatus(discoveryConfigs...) - s.awsRDSResourcesStatus.reset() + for _, g := range awsResultGroups { + s.awsRDSResourcesStatus.iterationStarted(g) + } + s.awsRDSTasks.reset() } diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index 0f2617fb3f140..b5c9b14df95ec 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -584,6 +584,7 @@ func (s *Server) initAWSWatchers(matchers []types.AWSMatcher) error { server.WithPollInterval(s.PollInterval), server.WithTriggerFetchC(s.newDiscoveryConfigChangedSub()), server.WithPreFetchHookFn(s.ec2WatcherIterationStarted), + server.WithClock(s.clock), ) if err != nil { return trace.Wrap(err) @@ -643,15 +644,14 @@ func (s *Server) ec2WatcherIterationStarted() { return resourceGroup, include }, ) - for _, g := range awsResultGroups { - s.awsEC2ResourcesStatus.iterationStarted(g) - } - discoveryConfigs := libslices.FilterMapUnique(awsResultGroups, func(g awsResourceGroup) (s string, include bool) { return g.discoveryConfigName, true }) s.updateDiscoveryConfigStatus(discoveryConfigs...) s.awsEC2ResourcesStatus.reset() + for _, g := range awsResultGroups { + s.awsEC2ResourcesStatus.iterationStarted(g) + } s.awsEC2Tasks.reset() } @@ -799,15 +799,7 @@ func (s *Server) initAzureWatchers(ctx context.Context, matchers []types.AzureMa s.ctx, s.getAllAzureServerFetchers, server.WithPollInterval(s.PollInterval), server.WithTriggerFetchC(s.newDiscoveryConfigChangedSub()), - server.WithPreFetchHookFn(func() { - discoveryConfigs := libslices.FilterMapUnique( - s.getAllAzureServerFetchers(), - func(f server.Fetcher) (s string, include bool) { - return f.GetDiscoveryConfigName(), f.GetDiscoveryConfigName() != "" - }, - ) - s.updateDiscoveryConfigStatus(discoveryConfigs...) - }), + server.WithClock(s.clock), ) if err != nil { return trace.Wrap(err) @@ -866,15 +858,7 @@ func (s *Server) initGCPServerWatcher(ctx context.Context, vmMatchers []types.GC s.ctx, s.getAllGCPServerFetchers, server.WithPollInterval(s.PollInterval), server.WithTriggerFetchC(s.newDiscoveryConfigChangedSub()), - server.WithPreFetchHookFn(func() { - discoveryConfigs := libslices.FilterMapUnique( - s.getAllGCPServerFetchers(), - func(f server.Fetcher) (s string, include bool) { - return f.GetDiscoveryConfigName(), f.GetDiscoveryConfigName() != "" - }, - ) - s.updateDiscoveryConfigStatus(discoveryConfigs...) - }), + server.WithClock(s.clock), ) if err != nil { return trace.Wrap(err) @@ -1302,7 +1286,6 @@ func (s *Server) handleEC2Discovery() { s.logHandleInstancesErr(err) } - s.updateDiscoveryConfigStatus(instances.EC2.DiscoveryConfigName) s.upsertTasksForAWSEC2FailedEnrollments() case <-s.ctx.Done(): s.ec2Watcher.Stop() diff --git a/lib/srv/discovery/discovery_test.go b/lib/srv/discovery/discovery_test.go index 40c3ed6615e0e..dcde4aa6d386b 100644 --- a/lib/srv/discovery/discovery_test.go +++ b/lib/srv/discovery/discovery_test.go @@ -976,12 +976,22 @@ func TestDiscoveryServer(t *testing.T) { if tc.wantDiscoveryConfigStatus != nil { // It can take a while for the status to be updated. require.Eventually(t, func() bool { + fakeClock.Advance(server.PollInterval) storedDiscoveryConfig, err := tlsServer.Auth().DiscoveryConfigs.GetDiscoveryConfig(ctx, tc.discoveryConfig.GetName()) require.NoError(t, err) if len(storedDiscoveryConfig.Status.IntegrationDiscoveredResources) == 0 { return false } - require.Equal(t, *tc.wantDiscoveryConfigStatus, storedDiscoveryConfig.Status) + want := *tc.wantDiscoveryConfigStatus + got := storedDiscoveryConfig.Status + + require.Equal(t, want.State, got.State) + require.Equal(t, want.DiscoveredResources, got.DiscoveredResources) + require.Equal(t, want.ErrorMessage, got.ErrorMessage) + for expectedKey, expectedValue := range want.IntegrationDiscoveredResources { + require.Contains(t, got.IntegrationDiscoveredResources, expectedKey) + require.Equal(t, expectedValue, got.IntegrationDiscoveredResources[expectedKey]) + } return true }, 500*time.Millisecond, 50*time.Millisecond) } @@ -2175,16 +2185,17 @@ func TestDiscoveryDatabase(t *testing.T) { } tcs := []struct { - name string - existingDatabases []types.Database - integrationsOnlyCredentials bool - awsMatchers []types.AWSMatcher - azureMatchers []types.AzureMatcher - expectDatabases []types.Database - discoveryConfigs func(*testing.T) []*discoveryconfig.DiscoveryConfig - discoveryConfigStatusCheck func(*testing.T, discoveryconfig.Status) - userTasksCheck func(*testing.T, []*usertasksv1.UserTask) - wantEvents int + name string + existingDatabases []types.Database + integrationsOnlyCredentials bool + awsMatchers []types.AWSMatcher + azureMatchers []types.AzureMatcher + expectDatabases []types.Database + discoveryConfigs func(*testing.T) []*discoveryconfig.DiscoveryConfig + discoveryConfigStatusCheck func(*testing.T, discoveryconfig.Status) + discoveryConfigStatusExpectedResources int + userTasksCheck func(*testing.T, []*usertasksv1.UserTask) + wantEvents int }{ { name: "discover AWS database", @@ -2383,11 +2394,11 @@ func TestDiscoveryDatabase(t *testing.T) { }, wantEvents: 1, discoveryConfigStatusCheck: func(t *testing.T, s discoveryconfig.Status) { - require.Equal(t, uint64(1), s.DiscoveredResources) require.Equal(t, uint64(1), s.IntegrationDiscoveredResources[integrationName].AwsRds.Enrolled) require.Equal(t, uint64(1), s.IntegrationDiscoveredResources[integrationName].AwsRds.Found) require.Zero(t, s.IntegrationDiscoveredResources[integrationName].AwsRds.Failed) }, + discoveryConfigStatusExpectedResources: 1, }, { name: "running in integrations-only-mode with a matcher without an integration, must find 1 database", @@ -2417,10 +2428,10 @@ func TestDiscoveryDatabase(t *testing.T) { expectDatabases: []types.Database{}, wantEvents: 0, discoveryConfigStatusCheck: func(t *testing.T, s discoveryconfig.Status) { - require.Equal(t, uint64(1), s.DiscoveredResources) require.Equal(t, uint64(1), s.IntegrationDiscoveredResources[integrationName].AwsEks.Found) require.Zero(t, s.IntegrationDiscoveredResources[integrationName].AwsEks.Enrolled) }, + discoveryConfigStatusExpectedResources: 1, }, { name: "discovery config status must be updated even when there are no resources", @@ -2439,9 +2450,9 @@ func TestDiscoveryDatabase(t *testing.T) { expectDatabases: []types.Database{}, wantEvents: 0, discoveryConfigStatusCheck: func(t *testing.T, s discoveryconfig.Status) { - require.Equal(t, uint64(0), s.DiscoveredResources) require.Equal(t, "DISCOVERY_CONFIG_STATE_SYNCING", s.State) }, + discoveryConfigStatusExpectedResources: 0, }, { name: "discover-rds user task must be created when database is not configured to allow IAM DB Authentication", @@ -2485,6 +2496,7 @@ func TestDiscoveryDatabase(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { t.Parallel() + fakeClock := clockwork.NewFakeClock() ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) @@ -2578,6 +2590,7 @@ func TestDiscoveryDatabase(t *testing.T) { waitForReconcile <- struct{}{} }, DiscoveryGroup: mainDiscoveryGroup, + clock: fakeClock, }) require.NoError(t, err) @@ -2627,10 +2640,18 @@ func TestDiscoveryDatabase(t *testing.T) { } if tc.discoveryConfigStatusCheck != nil { - dc, err := tlsServer.Auth().GetDiscoveryConfig(ctx, discoveryConfigName) - require.NoError(t, err) + require.Eventually(t, func() bool { + fakeClock.Advance(srv.PollInterval * 2) + dc, err := tlsServer.Auth().GetDiscoveryConfig(ctx, discoveryConfigName) + require.NoError(t, err) + if tc.discoveryConfigStatusExpectedResources != int(dc.Status.DiscoveredResources) { + return false + } + + tc.discoveryConfigStatusCheck(t, dc.Status) + return true + }, time.Second, 100*time.Millisecond) - tc.discoveryConfigStatusCheck(t, dc.Status) } if tc.userTasksCheck != nil { var userTasks []*usertasksv1.UserTask diff --git a/lib/srv/discovery/kube_integration_watcher.go b/lib/srv/discovery/kube_integration_watcher.go index 88d89f258f8c4..c1332af68c81a 100644 --- a/lib/srv/discovery/kube_integration_watcher.go +++ b/lib/srv/discovery/kube_integration_watcher.go @@ -78,6 +78,7 @@ func (s *Server) startKubeIntegrationWatchers() error { Origin: types.OriginCloud, TriggerFetchC: s.newDiscoveryConfigChangedSub(), PreFetchHookFn: s.kubernetesIntegrationWatcherIterationStarted, + Clock: s.clock, }) if err != nil { return trace.Wrap(err) @@ -86,7 +87,6 @@ func (s *Server) startKubeIntegrationWatchers() error { go func() { for { - discoveryConfigsChanged := map[string]struct{}{} resourcesFoundByGroup := make(map[awsResourceGroup]int) resourcesEnrolledByGroup := make(map[awsResourceGroup]int) @@ -124,7 +124,6 @@ func (s *Server) startKubeIntegrationWatchers() error { resourceGroup := awsResourceGroupFromLabels(newCluster.GetStaticLabels()) resourcesFoundByGroup[resourceGroup] += 1 - discoveryConfigsChanged[resourceGroup.discoveryConfigName] = struct{}{} if enrollingClusters[newCluster.GetAWSConfig().Name] || slices.ContainsFunc(existingServers, func(c types.KubeServer) bool { return c.GetName() == newCluster.GetName() }) || @@ -175,10 +174,6 @@ func (s *Server) startKubeIntegrationWatchers() error { for group, count := range resourcesEnrolledByGroup { s.awsEKSResourcesStatus.incrementEnrolled(group, count) } - - for dc := range discoveryConfigsChanged { - s.updateDiscoveryConfigStatus(dc) - } } }() return nil @@ -203,16 +198,16 @@ func (s *Server) kubernetesIntegrationWatcherIterationStarted() { return resourceGroup, include }, ) - for _, g := range awsResultGroups { - s.awsEKSResourcesStatus.iterationStarted(g) - } discoveryConfigs := libslices.FilterMapUnique(awsResultGroups, func(g awsResourceGroup) (s string, include bool) { return g.discoveryConfigName, true }) s.updateDiscoveryConfigStatus(discoveryConfigs...) - s.awsEKSResourcesStatus.reset() + for _, g := range awsResultGroups { + s.awsEKSResourcesStatus.iterationStarted(g) + } + s.awsEKSTasks.reset() } @@ -232,7 +227,6 @@ func (s *Server) enrollEKSClusters(region, integration, discoveryConfigName stri } mu.Unlock() - s.updateDiscoveryConfigStatus(discoveryConfigName) s.upsertTasksForAWSEKSFailedEnrollments() }() diff --git a/lib/srv/discovery/status.go b/lib/srv/discovery/status.go index 4b25bff187540..642deb7244c85 100644 --- a/lib/srv/discovery/status.go +++ b/lib/srv/discovery/status.go @@ -355,8 +355,6 @@ func (s *Server) ReportEC2SSMInstallationResult(ctx context.Context, result *ser integration: result.IntegrationName, }, 1) - s.updateDiscoveryConfigStatus(result.DiscoveryConfigName) - s.awsEC2Tasks.addFailedEnrollment( awsEC2TaskKey{ integration: result.IntegrationName, diff --git a/lib/srv/server/azure_watcher.go b/lib/srv/server/azure_watcher.go index fb1110247dc0f..3ebca31e2710f 100644 --- a/lib/srv/server/azure_watcher.go +++ b/lib/srv/server/azure_watcher.go @@ -25,6 +25,7 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" usageeventsv1 "github.com/gravitational/teleport/api/gen/proto/go/usageevents/v1" "github.com/gravitational/teleport/api/types" @@ -86,6 +87,7 @@ func NewAzureWatcher(ctx context.Context, fetchersFn func() []Fetcher, opts ...O ctx: cancelCtx, cancel: cancelFn, pollInterval: time.Minute, + clock: clockwork.NewRealClock(), triggerFetchC: make(<-chan struct{}), InstancesC: make(chan Instances), } diff --git a/lib/srv/server/ec2_watcher.go b/lib/srv/server/ec2_watcher.go index 1f81fb3d6952a..d189f628aa11c 100644 --- a/lib/srv/server/ec2_watcher.go +++ b/lib/srv/server/ec2_watcher.go @@ -28,6 +28,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ec2" ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" usageeventsv1 "github.com/gravitational/teleport/api/gen/proto/go/usageevents/v1" "github.com/gravitational/teleport/api/types" @@ -177,6 +178,7 @@ func NewEC2Watcher(ctx context.Context, fetchersFn func() []Fetcher, missedRotat fetchersFn: fetchersFn, ctx: cancelCtx, cancel: cancelFn, + clock: clockwork.NewRealClock(), pollInterval: time.Minute, triggerFetchC: make(<-chan struct{}), InstancesC: make(chan Instances), diff --git a/lib/srv/server/gcp_watcher.go b/lib/srv/server/gcp_watcher.go index e3cf33c591d49..8c4396c856610 100644 --- a/lib/srv/server/gcp_watcher.go +++ b/lib/srv/server/gcp_watcher.go @@ -25,6 +25,7 @@ import ( "time" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" usageeventsv1 "github.com/gravitational/teleport/api/gen/proto/go/usageevents/v1" "github.com/gravitational/teleport/api/types" @@ -78,6 +79,7 @@ func NewGCPWatcher(ctx context.Context, fetchersFn func() []Fetcher, opts ...Opt fetchersFn: fetchersFn, ctx: cancelCtx, cancel: cancelFn, + clock: clockwork.NewRealClock(), pollInterval: time.Minute, triggerFetchC: make(<-chan struct{}), InstancesC: make(chan Instances), diff --git a/lib/srv/server/watcher.go b/lib/srv/server/watcher.go index 5b10097b0e045..53409171c2ba0 100644 --- a/lib/srv/server/watcher.go +++ b/lib/srv/server/watcher.go @@ -24,6 +24,7 @@ import ( "time" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" "github.com/gravitational/teleport/api/types" ) @@ -64,6 +65,13 @@ func WithPreFetchHookFn(f func()) Option { } } +// WithClock sets a clock that is used to periodically fetch new resources. +func WithClock(clock clockwork.Clock) Option { + return func(w *Watcher) { + w.clock = clock + } +} + // Watcher allows callers to discover cloud instances matching specified filters. type Watcher struct { // InstancesC can be used to consume newly discovered instances. @@ -72,6 +80,7 @@ type Watcher struct { fetchersFn func() []Fetcher pollInterval time.Duration + clock clockwork.Clock triggerFetchC <-chan struct{} ctx context.Context cancel context.CancelFunc @@ -107,7 +116,7 @@ func (w *Watcher) fetchAndSubmit() { // Run starts the watcher's main watch loop. func (w *Watcher) Run() { - pollTimer := time.NewTimer(w.pollInterval) + pollTimer := w.clock.NewTimer(w.pollInterval) defer pollTimer.Stop() if w.triggerFetchC == nil { @@ -123,7 +132,7 @@ func (w *Watcher) Run() { w.sendInstancesOrLogError(fetcher.GetMatchingInstances(insts, true)) } - case <-pollTimer.C: + case <-pollTimer.Chan(): w.fetchAndSubmit() pollTimer.Reset(w.pollInterval) @@ -132,7 +141,7 @@ func (w *Watcher) Run() { // stop and drain timer if !pollTimer.Stop() { - <-pollTimer.C + <-pollTimer.Chan() } pollTimer.Reset(w.pollInterval) From 5fb00a4aeed215225505e23f2d812157af4976f2 Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Thu, 30 Jan 2025 08:51:33 -0800 Subject: [PATCH 17/28] Migrate AWS session to SDK v2 (#51626) Only DynamoDB and AWS MongoDB Atlas depended on GetAWSSession, and the migration for these packages was trivial. Since this was the last AWS method in lib/cloud/clients, the vast majority of the changes are to remove dead code. --- lib/auth/auth.go | 7 - lib/auth/init.go | 4 - lib/cloud/clients.go | 388 +----------------- lib/cloud/clients_test.go | 114 ----- lib/cloud/mocks/aws_config.go | 5 +- lib/service/service.go | 6 - lib/srv/db/access_test.go | 2 - lib/srv/db/cloud/aws.go | 6 - lib/srv/db/cloud/iam.go | 11 - lib/srv/db/cloud/iam_test.go | 36 +- lib/srv/db/cloud/meta.go | 10 - lib/srv/db/cloud/meta_test.go | 7 - lib/srv/db/cloud/resource_checker.go | 8 +- .../db/cloud/resource_checker_credentials.go | 2 +- lib/srv/db/cloud/resource_checker_url.go | 3 - .../db/cloud/resource_checker_url_aws_test.go | 13 - lib/srv/db/cloud/users/users.go | 10 - lib/srv/db/cloud/users/users_test.go | 2 - lib/srv/db/common/auth.go | 22 +- lib/srv/db/common/auth_test.go | 10 +- lib/srv/db/common/engines.go | 8 +- lib/srv/db/common/engines_test.go | 2 +- lib/srv/db/dynamodb/engine.go | 28 +- lib/srv/db/dynamodb/test.go | 4 +- lib/srv/db/dynamodb_test.go | 38 +- lib/srv/db/mysql/engine.go | 2 +- lib/srv/db/objects/fetcher.go | 8 +- lib/srv/db/objects/importer.go | 8 +- lib/srv/db/objects/objects.go | 6 +- lib/srv/db/postgres/connector.go | 8 +- lib/srv/db/postgres/engine.go | 9 +- lib/srv/db/postgres/objects.go | 6 +- lib/srv/db/postgres/users.go | 8 +- lib/srv/db/server.go | 10 +- lib/srv/db/watcher_test.go | 8 - lib/srv/discovery/access_graph_aws.go | 1 - lib/srv/discovery/access_graph_test.go | 4 +- lib/srv/discovery/discovery.go | 10 +- lib/srv/discovery/discovery_test.go | 9 - .../discovery/fetchers/aws-sync/aws-sync.go | 3 - lib/srv/discovery/fetchers/db/aws.go | 6 - .../db/aws_redshift_serverless_test.go | 4 +- lib/srv/discovery/fetchers/db/db.go | 6 - lib/srv/discovery/fetchers/db/helpers_test.go | 6 - lib/srv/server/azure_watcher_test.go | 2 +- 45 files changed, 99 insertions(+), 771 deletions(-) delete mode 100644 lib/cloud/clients_test.go diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 5a1dfcbf796b2..ef4ad7b892e17 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -92,7 +92,6 @@ import ( "github.com/gravitational/teleport/lib/bitbucket" "github.com/gravitational/teleport/lib/cache" "github.com/gravitational/teleport/lib/circleci" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/devicetrust/assertserver" @@ -373,12 +372,6 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { return nil, trace.Wrap(err) } } - if cfg.CloudClients == nil { - cfg.CloudClients, err = cloud.NewClients() - if err != nil { - return nil, trace.Wrap(err) - } - } if cfg.Notifications == nil { cfg.Notifications, err = local.NewNotificationsService(cfg.Backend, cfg.Clock) if err != nil { diff --git a/lib/auth/init.go b/lib/auth/init.go index 2e78c94f4a91c..97a82ac403434 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -57,7 +57,6 @@ import ( "github.com/gravitational/teleport/lib/auth/migration" "github.com/gravitational/teleport/lib/auth/state" "github.com/gravitational/teleport/lib/backend" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/modules" @@ -302,9 +301,6 @@ type InitConfig struct { // AccessMonitoringRules is a service that manages access monitoring rules. AccessMonitoringRules services.AccessMonitoringRules - // CloudClients provides clients for various cloud providers. - CloudClients cloud.Clients - // KubeWaitingContainers is a service that manages // Kubernetes ephemeral containers that are waiting // to be created until moderated session conditions are met. diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go index 0c8fe0306a63c..1dbe9539acefe 100644 --- a/lib/cloud/clients.go +++ b/lib/cloud/clients.go @@ -21,9 +21,7 @@ package cloud import ( "context" "io" - "log/slog" "sync" - "time" gcpcredentials "cloud.google.com/go/iam/credentials/apiv1" "github.com/Azure/azure-sdk-for-go/sdk/azcore" @@ -33,29 +31,17 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/mysql/armmysql" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/postgresql/armpostgresql" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" - "github.com/aws/aws-sdk-go/aws/endpoints" - "github.com/aws/aws-sdk-go/aws/request" - awssession "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/sts" - "github.com/aws/aws-sdk-go/service/sts/stsiface" "github.com/gravitational/trace" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "github.com/gravitational/teleport/api/types" - libcloudaws "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/teleport/lib/cloud/azure" "github.com/gravitational/teleport/lib/cloud/gcp" "github.com/gravitational/teleport/lib/cloud/imds" awsimds "github.com/gravitational/teleport/lib/cloud/imds/aws" azureimds "github.com/gravitational/teleport/lib/cloud/imds/azure" gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp" - "github.com/gravitational/teleport/lib/modules" - "github.com/gravitational/teleport/lib/utils" ) // Clients provides interface for obtaining cloud provider clients. @@ -65,8 +51,6 @@ type Clients interface { GetInstanceMetadataClient(ctx context.Context) (imds.Client, error) // GCPClients is an interface for providing GCP API clients. GCPClients - // AWSClients is an interface for providing AWS API clients. - AWSClients // AzureClients is an interface for Azure-specific API clients AzureClients // Closer closes all initialized clients. @@ -87,12 +71,6 @@ type GCPClients interface { GetGCPInstancesClient(context.Context) (gcp.InstancesClient, error) } -// AWSClients is an interface for providing AWS API clients. -type AWSClients interface { - // GetAWSSession returns AWS session for the specified region and any role(s). - GetAWSSession(ctx context.Context, region string, opts ...AWSOptionsFn) (*awssession.Session, error) -} - // AzureClients is an interface for Azure-specific API clients type AzureClients interface { // GetAzureCredential returns Azure default token credential chain. @@ -199,23 +177,16 @@ type ClientsOption func(cfg *cloudClients) // NewClients returns a new instance of cloud clients retriever. func NewClients(opts ...ClientsOption) (Clients, error) { - awsSessionsCache, err := utils.NewFnCache(utils.FnCacheConfig{ - TTL: 15 * time.Minute, - }) - if err != nil { - return nil, trace.Wrap(err) - } azClients, err := newAzureClients() if err != nil { return nil, trace.Wrap(err) } cloudClients := &cloudClients{ - awsSessionsCache: awsSessionsCache, gcpClients: gcpClients{ - gcpSQLAdmin: newClientCache[gcp.SQLAdminClient](gcp.NewSQLAdminClient), - gcpGKE: newClientCache[gcp.GKEClient](gcp.NewGKEClient), - gcpProjects: newClientCache[gcp.ProjectsClient](gcp.NewProjectsClient), - gcpInstances: newClientCache[gcp.InstancesClient](gcp.NewInstancesClient), + gcpSQLAdmin: newClientCache(gcp.NewSQLAdminClient), + gcpGKE: newClientCache(gcp.NewGKEClient), + gcpProjects: newClientCache(gcp.NewProjectsClient), + gcpInstances: newClientCache(gcp.NewInstancesClient), }, azureClients: azClients, } @@ -230,31 +201,7 @@ func NewClients(opts ...ClientsOption) (Clients, error) { // cloudClients implements Clients var _ Clients = (*cloudClients)(nil) -// WithAWSIntegrationSessionProvider sets an integration session generator for AWS apis. -// If a client is requested for a specific Integration, instead of using the ambient credentials, this generator is used to fetch the AWS Session. -func WithAWSIntegrationSessionProvider(sessionProvider AWSIntegrationSessionProvider) func(*cloudClients) { - return func(cc *cloudClients) { - cc.awsIntegrationSessionProviderFn = sessionProvider - } -} - -// AWSIntegrationSessionProvider defines a function that creates an [awssession.Session] from a Region and an Integration. -// This is used to generate aws sessions for clients that must use an Integration instead of ambient credentials. -type AWSIntegrationSessionProvider func(ctx context.Context, region string, integration string) (*awssession.Session, error) - -type awsSessionCacheKey struct { - region string - integration string - roleARN string - externalID string -} - type cloudClients struct { - // awsSessionsCache is a cache of AWS sessions, where the cache key is - // an instance of awsSessionCacheKey. - awsSessionsCache *utils.FnCache - // awsIntegrationSessionProviderFn is a AWS Session Generator that uses an Integration to generate an AWS Session. - awsIntegrationSessionProviderFn AWSIntegrationSessionProvider // instanceMetadata is the cached instance metadata client. instanceMetadata imds.Client // gcpClients contains GCP-specific clients. @@ -316,156 +263,6 @@ type azureClients struct { azureRoleAssignmentsClients azure.ClientMap[azure.RoleAssignmentsClient] } -// credentialsSource defines where the credentials must come from. -type credentialsSource int - -const ( - // credentialsSourceAmbient uses the default Cloud SDK method to load the credentials. - credentialsSourceAmbient = iota + 1 - // credentialsSourceIntegration uses an Integration to load the credentials. - credentialsSourceIntegration -) - -// awsOptions a struct of additional options for assuming an AWS role -// when construction an underlying AWS session. -type awsOptions struct { - // baseSession is a session to use instead of the default session for an - // AWS region, which is used to enable role chaining. - baseSession *awssession.Session - // assumeRoleARN is the AWS IAM Role ARN to assume. - assumeRoleARN string - // assumeRoleExternalID is used to assume an external AWS IAM Role. - assumeRoleExternalID string - - // credentialsSource describes which source to use to fetch credentials. - credentialsSource credentialsSource - - // integration is the name of the integration to be used to fetch the credentials. - integration string - - // customRetryer is a custom retryer to use for the session. - customRetryer request.Retryer - - // maxRetries is the maximum number of retries to use for the session. - maxRetries *int - - // withoutSessionCache disables the session cache for the AWS session. - withoutSessionCache bool -} - -func (a *awsOptions) checkAndSetDefaults() error { - switch a.credentialsSource { - case credentialsSourceAmbient: - if a.integration != "" { - return trace.BadParameter("integration and ambient credentials cannot be used at the same time") - } - case credentialsSourceIntegration: - if a.integration == "" { - return trace.BadParameter("missing integration name") - } - default: - return trace.BadParameter("missing credentials source (ambient or integration)") - } - - return nil -} - -// AWSOptionsFn is an option function for setting additional options -// when getting an AWS session. -type AWSOptionsFn func(*awsOptions) - -// WithAssumeRole configures options needed for assuming an AWS role. -func WithAssumeRole(roleARN, externalID string) AWSOptionsFn { - return func(options *awsOptions) { - options.assumeRoleARN = roleARN - options.assumeRoleExternalID = externalID - } -} - -// WithoutSessionCache disables the session cache for the AWS session. -func WithoutSessionCache() AWSOptionsFn { - return func(options *awsOptions) { - options.withoutSessionCache = true - } -} - -// WithAssumeRoleFromAWSMeta extracts options needed from AWS metadata for -// assuming an AWS role. -func WithAssumeRoleFromAWSMeta(meta types.AWS) AWSOptionsFn { - return WithAssumeRole(meta.AssumeRoleARN, meta.ExternalID) -} - -// WithChainedAssumeRole sets a role to assume with a base session to use -// for assuming the role, which enables role chaining. -func WithChainedAssumeRole(session *awssession.Session, roleARN, externalID string) AWSOptionsFn { - return func(options *awsOptions) { - options.baseSession = session - options.assumeRoleARN = roleARN - options.assumeRoleExternalID = externalID - } -} - -// WithRetryer sets a custom retryer for the session. -func WithRetryer(retryer request.Retryer) AWSOptionsFn { - return func(options *awsOptions) { - options.customRetryer = retryer - } -} - -// WithMaxRetries sets the maximum allowed value for the sdk to keep retrying. -func WithMaxRetries(maxRetries int) AWSOptionsFn { - return func(options *awsOptions) { - options.maxRetries = &maxRetries - } -} - -// WithCredentialsMaybeIntegration sets the credential source to be -// - ambient if the integration is an empty string -// - integration, otherwise -func WithCredentialsMaybeIntegration(integration string) AWSOptionsFn { - if integration != "" { - return withIntegrationCredentials(integration) - } - - return WithAmbientCredentials() -} - -// withIntegrationCredentials configures options with an Integration that must be used to fetch Credentials to assume a role. -// This prevents the usage of AWS environment credentials. -func withIntegrationCredentials(integration string) AWSOptionsFn { - return func(options *awsOptions) { - options.credentialsSource = credentialsSourceIntegration - options.integration = integration - } -} - -// WithAmbientCredentials configures options to use the ambient credentials. -func WithAmbientCredentials() AWSOptionsFn { - return func(options *awsOptions) { - options.credentialsSource = credentialsSourceAmbient - } -} - -// GetAWSSession returns AWS session for the specified region, optionally -// assuming AWS IAM Roles. -func (c *cloudClients) GetAWSSession(ctx context.Context, region string, opts ...AWSOptionsFn) (*awssession.Session, error) { - var options awsOptions - for _, opt := range opts { - opt(&options) - } - var err error - if options.baseSession == nil { - options.baseSession, err = c.getAWSSessionForRegion(ctx, region, options) - if err != nil { - return nil, trace.Wrap(err) - } - } - if options.assumeRoleARN == "" { - return options.baseSession, nil - } - return c.getAWSSessionForRole(ctx, region, options) -} - // GetGCPIAMClient returns GCP IAM client. func (c *cloudClients) GetGCPIAMClient(ctx context.Context) (*gcpcredentials.IamCredentialsClient, error) { c.mtx.RLock() @@ -627,105 +424,6 @@ func (c *cloudClients) Close() (err error) { return trace.Wrap(err) } -// awsAmbientSessionProvider loads a new session using the environment variables. -// Describe in detail here: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials -func awsAmbientSessionProvider(ctx context.Context, region string) (*awssession.Session, error) { - awsSessionOptions := buildAWSSessionOptions(region, nil /* credentials */) - - session, err := awssession.NewSessionWithOptions(awsSessionOptions) - return session, trace.Wrap(err) -} - -// getAWSSessionForRegion returns AWS session for the specified region. -func (c *cloudClients) getAWSSessionForRegion(ctx context.Context, region string, opts awsOptions) (*awssession.Session, error) { - if err := opts.checkAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - - createSession := func(ctx context.Context) (*awssession.Session, error) { - if opts.credentialsSource == credentialsSourceIntegration { - if c.awsIntegrationSessionProviderFn == nil { - return nil, trace.BadParameter("missing aws integration session provider") - } - - slog.DebugContext(ctx, "Initializing AWS session", - "region", region, - "integration", opts.integration, - ) - session, err := c.awsIntegrationSessionProviderFn(ctx, region, opts.integration) - return session, trace.Wrap(err) - } - - slog.DebugContext(ctx, "Initializing AWS session using environment credentials", - "region", region, - ) - session, err := awsAmbientSessionProvider(ctx, region) - return session, trace.Wrap(err) - } - - if opts.withoutSessionCache { - sess, err := createSession(ctx) - if err != nil { - return nil, trace.Wrap(err) - } - if opts.customRetryer != nil || opts.maxRetries != nil { - return sess.Copy(&aws.Config{ - Retryer: opts.customRetryer, - MaxRetries: opts.maxRetries, - }), nil - } - return sess, trace.Wrap(err) - } - - cacheKey := awsSessionCacheKey{ - region: region, - integration: opts.integration, - } - - sess, err := utils.FnCacheGet(ctx, c.awsSessionsCache, cacheKey, func(ctx context.Context) (*awssession.Session, error) { - session, err := createSession(ctx) - return session, trace.Wrap(err) - }) - if err != nil { - return nil, trace.Wrap(err) - } - if opts.customRetryer != nil || opts.maxRetries != nil { - return sess.Copy(&aws.Config{ - Retryer: opts.customRetryer, - MaxRetries: opts.maxRetries, - }), nil - } - return sess, err -} - -// getAWSSessionForRole returns AWS session for the specified region and role. -func (c *cloudClients) getAWSSessionForRole(ctx context.Context, region string, options awsOptions) (*awssession.Session, error) { - if err := options.checkAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - - createSession := func(ctx context.Context) (*awssession.Session, error) { - stsClient := sts.New(options.baseSession) - return newSessionWithRole(ctx, stsClient, region, options.assumeRoleARN, options.assumeRoleExternalID) - } - - if options.withoutSessionCache { - session, err := createSession(ctx) - return session, trace.Wrap(err) - } - - cacheKey := awsSessionCacheKey{ - region: region, - integration: options.integration, - roleARN: options.assumeRoleARN, - externalID: options.assumeRoleExternalID, - } - return utils.FnCacheGet(ctx, c.awsSessionsCache, cacheKey, func(ctx context.Context) (*awssession.Session, error) { - session, err := createSession(ctx) - return session, trace.Wrap(err) - }) -} - func (c *cloudClients) initGCPIAMClient(ctx context.Context) (*gcpcredentials.IamCredentialsClient, error) { c.mtx.Lock() defer c.mtx.Unlock() @@ -891,7 +589,6 @@ var _ Clients = (*TestCloudClients)(nil) // TestCloudClients are used in tests. type TestCloudClients struct { - STS stsiface.STSAPI GCPSQL gcp.SQLAdminClient GCPGKE gcp.GKEClient GCPProjects gcp.ProjectsClient @@ -916,43 +613,6 @@ type TestCloudClients struct { AzureRoleAssignments azure.RoleAssignmentsClient } -// GetAWSSession returns AWS session for the specified region, optionally -// assuming AWS IAM Roles. -func (c *TestCloudClients) GetAWSSession(ctx context.Context, region string, opts ...AWSOptionsFn) (*awssession.Session, error) { - var options awsOptions - for _, opt := range opts { - opt(&options) - } - var err error - if options.baseSession == nil { - options.baseSession, err = c.getAWSSessionForRegion(region) - if err != nil { - return nil, trace.Wrap(err) - } - } - if options.assumeRoleARN == "" { - return options.baseSession, nil - } - return newSessionWithRole(ctx, c.STS, region, options.assumeRoleARN, options.assumeRoleExternalID) -} - -// GetAWSSession returns AWS session for the specified region. -func (c *TestCloudClients) getAWSSessionForRegion(region string) (*awssession.Session, error) { - useFIPSEndpoint := endpoints.FIPSEndpointStateUnset - if modules.GetModules().IsBoringBinary() { - useFIPSEndpoint = endpoints.FIPSEndpointStateEnabled - } - - return awssession.NewSession(&aws.Config{ - Credentials: credentials.NewCredentials(&credentials.StaticProvider{Value: credentials.Value{ - AccessKeyID: "fakeClientKeyID", - SecretAccessKey: "fakeClientSecret", - }}), - Region: aws.String(region), - UseFIPSEndpoint: useFIPSEndpoint, - }) -} - // GetGCPIAMClient returns GCP IAM client. func (c *TestCloudClients) GetGCPIAMClient(ctx context.Context) (*gcpcredentials.IamCredentialsClient, error) { return gcpcredentials.NewIamCredentialsClient(ctx, @@ -1075,43 +735,3 @@ func (c *TestCloudClients) GetAzureRoleAssignmentsClient(subscription string) (a func (c *TestCloudClients) Close() error { return nil } - -// newSessionWithRole assumes a given AWS IAM Role, passing an external ID if given, -// and returns a new AWS session with the assumed role in the given region. -func newSessionWithRole(ctx context.Context, svc stscreds.AssumeRoler, region, roleARN, externalID string) (*awssession.Session, error) { - slog.DebugContext(ctx, "Initializing AWS session for assumed role", - "assumed_role", roleARN, - "region", region, - ) - // Make a credentials with AssumeRoleProvider and test it out. - cred := stscreds.NewCredentialsWithClient(svc, roleARN, func(p *stscreds.AssumeRoleProvider) { - if externalID != "" { - p.ExternalID = aws.String(externalID) - } - }) - if _, err := cred.GetWithContext(ctx); err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) - } - - awsSessionOptions := buildAWSSessionOptions(region, cred) - - // Create a new session with the credentials. - roleSession, err := awssession.NewSessionWithOptions(awsSessionOptions) - return roleSession, trace.Wrap(err) -} - -func buildAWSSessionOptions(region string, cred *credentials.Credentials) awssession.Options { - useFIPSEndpoint := endpoints.FIPSEndpointStateUnset - if modules.GetModules().IsBoringBinary() { - useFIPSEndpoint = endpoints.FIPSEndpointStateEnabled - } - - return awssession.Options{ - SharedConfigState: awssession.SharedConfigEnable, - Config: aws.Config{ - Region: aws.String(region), - Credentials: cred, - UseFIPSEndpoint: useFIPSEndpoint, - }, - } -} diff --git a/lib/cloud/clients_test.go b/lib/cloud/clients_test.go deleted file mode 100644 index 483b7bd5c5f0e..0000000000000 --- a/lib/cloud/clients_test.go +++ /dev/null @@ -1,114 +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 . - */ - -package cloud - -import ( - "context" - "testing" - - "github.com/aws/aws-sdk-go/aws" - awssession "github.com/aws/aws-sdk-go/aws/session" - "github.com/gravitational/trace" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestClientGetAWSSessionIntegration(t *testing.T) { - dummyIntegration := "integration-test" - dummyRegion := "test-region-123" - - t.Run("without an integration session provider, must return a missing aws integration session provider error", func(t *testing.T) { - ctx := context.Background() - - clients, err := NewClients() - require.NoError(t, err) - - t.Cleanup(func() { require.NoError(t, clients.Close()) }) - - _, err = clients.GetAWSSession(ctx, "us-region-2", WithCredentialsMaybeIntegration("integration-test")) - require.True(t, trace.IsBadParameter(err), "expected err to be BadParameter, got %+v", err) - require.ErrorContains(t, err, "missing aws integration session provider") - }) - - t.Run("with an integration session provider, must return the session", func(t *testing.T) { - ctx := context.Background() - dummySession := &awssession.Session{ - Config: &aws.Config{ - Region: &dummyRegion, - }, - } - - clients, err := NewClients(WithAWSIntegrationSessionProvider(func(ctx context.Context, region, integration string) (*awssession.Session, error) { - assert.Equal(t, dummyIntegration, integration) - assert.Equal(t, dummyRegion, region) - return dummySession, nil - })) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, clients.Close()) }) - - sess, err := clients.GetAWSSession(ctx, dummyRegion, WithCredentialsMaybeIntegration("integration-test")) - require.NoError(t, err) - require.Equal(t, dummySession, sess) - }) - - t.Run("with an integration session provider, but using an empty integration falls back to ambient credentials, must not call the integration session provider", func(t *testing.T) { - ctx := context.Background() - - clients, err := NewClients(WithAWSIntegrationSessionProvider(func(ctx context.Context, region, integration string) (*awssession.Session, error) { - assert.Fail(t, "should not be called") - return nil, nil - })) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, clients.Close()) }) - - sess, err := clients.GetAWSSession(ctx, dummyRegion, WithCredentialsMaybeIntegration("")) - require.NoError(t, err) - require.NotNil(t, sess) - }) - - t.Run("with an integration session provider, but using ambient credentials, must not call the integration session provider", func(t *testing.T) { - ctx := context.Background() - - clients, err := NewClients(WithAWSIntegrationSessionProvider(func(ctx context.Context, region, integration string) (*awssession.Session, error) { - assert.Fail(t, "should not be called") - return nil, nil - })) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, clients.Close()) }) - - sess, err := clients.GetAWSSession(ctx, dummyRegion, WithAmbientCredentials()) - require.NoError(t, err) - require.NotNil(t, sess) - }) - - t.Run("with an integration session provider, but no credential source defined", func(t *testing.T) { - ctx := context.Background() - - clients, err := NewClients(WithAWSIntegrationSessionProvider(func(ctx context.Context, region, integration string) (*awssession.Session, error) { - assert.Fail(t, "should not be called") - return nil, nil - })) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, clients.Close()) }) - - _, err = clients.GetAWSSession(ctx, dummyRegion) - require.Error(t, err) - require.ErrorContains(t, err, "missing credentials source") - }) -} diff --git a/lib/cloud/mocks/aws_config.go b/lib/cloud/mocks/aws_config.go index d148e9512c8d4..e56804bbde803 100644 --- a/lib/cloud/mocks/aws_config.go +++ b/lib/cloud/mocks/aws_config.go @@ -63,7 +63,10 @@ func (f *FakeOIDCIntegrationClient) GetIntegration(ctx context.Context, name str if f.Unauth { return nil, trace.AccessDenied("unauthorized") } - return f.Integration, nil + if f.Integration.GetName() == name { + return f.Integration, nil + } + return nil, trace.NotFound("integration %q not found", name) } func (f *FakeOIDCIntegrationClient) GenerateAWSOIDCToken(ctx context.Context, integrationName string) (string, error) { diff --git a/lib/service/service.go b/lib/service/service.go index a522f03491201..7003d108b9843 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -2136,11 +2136,6 @@ func (process *TeleportProcess) initAuthService() error { return trace.Wrap(err) } - cloudClients, err := cloud.NewClients() - if err != nil { - return trace.Wrap(err) - } - logger := process.logger.With(teleport.ComponentKey, teleport.Component(teleport.ComponentAuth, process.id)) // first, create the AuthServer @@ -2187,7 +2182,6 @@ func (process *TeleportProcess) initAuthService() error { Clock: cfg.Clock, HTTPClientForAWSSTS: cfg.Auth.HTTPClientForAWSSTS, Tracer: process.TracingProvider.Tracer(teleport.ComponentAuth), - CloudClients: cloudClients, Logger: logger, }, func(as *auth.Server) error { if !process.Config.CachePolicy.Enabled { diff --git a/lib/srv/db/access_test.go b/lib/srv/db/access_test.go index 6da256f8b2654..87b4254bc310c 100644 --- a/lib/srv/db/access_test.go +++ b/lib/srv/db/access_test.go @@ -107,7 +107,6 @@ func TestMain(m *testing.M) { registerTestSnowflakeEngine() registerTestElasticsearchEngine() registerTestSQLServerEngine() - registerTestDynamoDBEngine() os.Exit(m.Run()) } @@ -2483,7 +2482,6 @@ func (p *agentParams) setDefaults(c *testContext) { if p.CloudClients == nil { p.CloudClients = &clients.TestCloudClients{ - STS: &mocks.STSClientV1{}, GCPSQL: p.GCPSQL, } } diff --git a/lib/srv/db/cloud/aws.go b/lib/srv/db/cloud/aws.go index 5ec00224d045b..091f066cebe47 100644 --- a/lib/srv/db/cloud/aws.go +++ b/lib/srv/db/cloud/aws.go @@ -30,7 +30,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/cloud" awslib "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/teleport/lib/cloud/awsconfig" dbiam "github.com/gravitational/teleport/lib/srv/db/common/iam" @@ -40,8 +39,6 @@ import ( type awsConfig struct { // awsConfigProvider provides [aws.Config] for AWS SDK service clients. awsConfigProvider awsconfig.Provider - // clients is an interface for creating AWS clients. - clients cloud.Clients // identity is AWS identity this database agent is running as. identity awslib.Identity // database is the database instance to configure. @@ -55,9 +52,6 @@ type awsConfig struct { // Check validates the config. func (c *awsConfig) Check() error { - if c.clients == nil { - return trace.BadParameter("missing parameter clients") - } if c.identity == nil { return trace.BadParameter("missing parameter identity") } diff --git a/lib/srv/db/cloud/iam.go b/lib/srv/db/cloud/iam.go index 2cd2da23a354d..dfea3893469bc 100644 --- a/lib/srv/db/cloud/iam.go +++ b/lib/srv/db/cloud/iam.go @@ -33,7 +33,6 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/retryutils" "github.com/gravitational/teleport/lib/auth/authclient" - "github.com/gravitational/teleport/lib/cloud" awslib "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/services" @@ -48,8 +47,6 @@ type IAMConfig struct { AccessPoint authclient.DatabaseAccessPoint // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. AWSConfigProvider awsconfig.Provider - // Clients is an interface for retrieving cloud clients. - Clients cloud.Clients // HostID is the host identified where this agent is running. // DELETE IN 11.0. HostID string @@ -70,13 +67,6 @@ func (c *IAMConfig) Check() error { if c.AWSConfigProvider == nil { return trace.BadParameter("missing AWSConfigProvider") } - if c.Clients == nil { - cloudClients, err := cloud.NewClients() - if err != nil { - return trace.Wrap(err) - } - c.Clients = cloudClients - } if c.HostID == "" { return trace.BadParameter("missing HostID") } @@ -245,7 +235,6 @@ func (c *IAM) getAWSConfigurator(ctx context.Context, database types.Database) ( } return newAWS(ctx, awsConfig{ awsConfigProvider: c.cfg.AWSConfigProvider, - clients: c.cfg.Clients, database: database, identity: identity, policyName: policyName, diff --git a/lib/srv/db/cloud/iam_test.go b/lib/srv/db/cloud/iam_test.go index 3c7e4c63f2888..cae979ddaa360 100644 --- a/lib/srv/db/cloud/iam_test.go +++ b/lib/srv/db/cloud/iam_test.go @@ -33,7 +33,6 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/auth/authclient" - clients "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/services" @@ -156,8 +155,7 @@ func TestAWSIAM(t *testing.T) { AWSConfigProvider: &mocks.AWSConfigProvider{ STSClient: stsClient, }, - Clients: &clients.TestCloudClients{}, - HostID: "host-id", + HostID: "host-id", onProcessedTask: func(iamTask, error) { taskChan <- struct{}{} }, @@ -298,13 +296,11 @@ func TestAWSIAMNoPermissions(t *testing.T) { tests := []struct { name string meta types.AWS - clients clients.Clients awsClients awsClientProvider }{ { - name: "RDS database", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{InstanceID: "postgres-rds", ResourceID: "postgres-rds-resource-id"}}, - clients: &clients.TestCloudClients{}, + name: "RDS database", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{InstanceID: "postgres-rds", ResourceID: "postgres-rds-resource-id"}}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, rdsClient: &mocks.RDSClient{Unauth: true}, @@ -312,9 +308,8 @@ func TestAWSIAMNoPermissions(t *testing.T) { }, }, { - name: "Aurora cluster", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{ClusterID: "postgres-aurora", ResourceID: "postgres-aurora-resource-id"}}, - clients: &clients.TestCloudClients{}, + name: "Aurora cluster", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", RDS: types.RDS{ClusterID: "postgres-aurora", ResourceID: "postgres-aurora-resource-id"}}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, rdsClient: &mocks.RDSClient{Unauth: true}, @@ -322,9 +317,8 @@ func TestAWSIAMNoPermissions(t *testing.T) { }, }, { - name: "RDS database missing metadata", - meta: types.AWS{Region: "localhost", RDS: types.RDS{ClusterID: "postgres-aurora"}}, - clients: &clients.TestCloudClients{}, + name: "RDS database missing metadata", + meta: types.AWS{Region: "localhost", RDS: types.RDS{ClusterID: "postgres-aurora"}}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, rdsClient: &mocks.RDSClient{Unauth: true}, @@ -332,27 +326,24 @@ func TestAWSIAMNoPermissions(t *testing.T) { }, }, { - name: "Redshift cluster", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, - clients: &clients.TestCloudClients{}, + name: "Redshift cluster", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, stsClient: stsClient, }, }, { - name: "ElastiCache", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", ElastiCache: types.ElastiCache{ReplicationGroupID: "some-group"}}, - clients: &clients.TestCloudClients{}, + name: "ElastiCache", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", ElastiCache: types.ElastiCache{ReplicationGroupID: "some-group"}}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{Unauth: true}, stsClient: stsClient, }, }, { - name: "IAM UnmodifiableEntityException", - meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, - clients: &clients.TestCloudClients{}, + name: "IAM UnmodifiableEntityException", + meta: types.AWS{Region: "localhost", AccountID: "123456789012", Redshift: types.Redshift{ClusterID: "redshift-cluster-1"}}, awsClients: fakeAWSClients{ iamClient: &mocks.IAMMock{ Error: &iamtypes.UnmodifiableEntityException{ @@ -369,7 +360,6 @@ func TestAWSIAMNoPermissions(t *testing.T) { // Make configurator. configurator, err := NewIAM(ctx, IAMConfig{ AccessPoint: &mockAccessPoint{}, - Clients: test.clients, HostID: "host-id", AWSConfigProvider: &mocks.AWSConfigProvider{ STSClient: stsClient, diff --git a/lib/srv/db/cloud/meta.go b/lib/srv/db/cloud/meta.go index ca84c8a0a6030..9a1de680d9ed6 100644 --- a/lib/srv/db/cloud/meta.go +++ b/lib/srv/db/cloud/meta.go @@ -41,7 +41,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/srv/db/common" discoverycommon "github.com/gravitational/teleport/lib/srv/discovery/common" @@ -147,8 +146,6 @@ func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Option // MetadataConfig is the cloud metadata service config. type MetadataConfig struct { - // Clients is an interface for retrieving cloud clients. - Clients cloud.Clients // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. AWSConfigProvider awsconfig.Provider @@ -158,13 +155,6 @@ type MetadataConfig struct { // Check validates the metadata service config. func (c *MetadataConfig) Check() error { - if c.Clients == nil { - cloudClients, err := cloud.NewClients() - if err != nil { - return trace.Wrap(err) - } - c.Clients = cloudClients - } if c.AWSConfigProvider == nil { return trace.BadParameter("missing AWSConfigProvider") } diff --git a/lib/srv/db/cloud/meta_test.go b/lib/srv/db/cloud/meta_test.go index 1aea1d19e38db..46ef553afb297 100644 --- a/lib/srv/db/cloud/meta_test.go +++ b/lib/srv/db/cloud/meta_test.go @@ -39,7 +39,6 @@ import ( "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/defaults" ) @@ -137,9 +136,6 @@ func TestAWSMetadata(t *testing.T) { // Create metadata fetcher. metadata, err := NewMetadata(MetadataConfig{ - Clients: &cloud.TestCloudClients{ - STS: &fakeSTS.STSClientV1, - }, AWSConfigProvider: &mocks.AWSConfigProvider{ STSClient: fakeSTS, }, @@ -420,9 +416,6 @@ func TestAWSMetadataNoPermissions(t *testing.T) { // Create metadata fetcher. metadata, err := NewMetadata(MetadataConfig{ - Clients: &cloud.TestCloudClients{ - STS: &fakeSTS.STSClientV1, - }, AWSConfigProvider: &mocks.AWSConfigProvider{ STSClient: fakeSTS, }, diff --git a/lib/srv/db/cloud/resource_checker.go b/lib/srv/db/cloud/resource_checker.go index 12fe017c3ca1b..85cd9df8a47fc 100644 --- a/lib/srv/db/cloud/resource_checker.go +++ b/lib/srv/db/cloud/resource_checker.go @@ -45,8 +45,8 @@ type DiscoveryResourceCheckerConfig struct { AWSConfigProvider awsconfig.Provider // ResourceMatchers is a list of database resource matchers. ResourceMatchers []services.ResourceMatcher - // Clients is an interface for retrieving cloud clients. - Clients cloud.Clients + // AzureClients is an interface for retrieving Azure cloud clients. + AzureClients cloud.AzureClients // Context is the database server close context. Context context.Context // Logger is used for logging. @@ -55,12 +55,12 @@ type DiscoveryResourceCheckerConfig struct { // CheckAndSetDefaults validates the config and sets default values. func (c *DiscoveryResourceCheckerConfig) CheckAndSetDefaults() error { - if c.Clients == nil { + if c.AzureClients == nil { cloudClients, err := cloud.NewClients() if err != nil { return trace.Wrap(err) } - c.Clients = cloudClients + c.AzureClients = cloudClients } if c.AWSConfigProvider == nil { return trace.BadParameter("missing AWSConfigProvider") diff --git a/lib/srv/db/cloud/resource_checker_credentials.go b/lib/srv/db/cloud/resource_checker_credentials.go index 0e6d5e7770d55..1902a2d886ffe 100644 --- a/lib/srv/db/cloud/resource_checker_credentials.go +++ b/lib/srv/db/cloud/resource_checker_credentials.go @@ -61,7 +61,7 @@ func newCredentialsChecker(cfg DiscoveryResourceCheckerConfig) (*credentialsChec return &credentialsChecker{ awsConfigProvider: cfg.AWSConfigProvider, awsClients: defaultAWSClients{}, - azureClients: cfg.Clients, + azureClients: cfg.AzureClients, resourceMatchers: cfg.ResourceMatchers, logger: cfg.Logger, cache: cache, diff --git a/lib/srv/db/cloud/resource_checker_url.go b/lib/srv/db/cloud/resource_checker_url.go index b9c3cd59d9c86..947b86b537ea5 100644 --- a/lib/srv/db/cloud/resource_checker_url.go +++ b/lib/srv/db/cloud/resource_checker_url.go @@ -33,7 +33,6 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils" apiawsutils "github.com/gravitational/teleport/api/utils/aws" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" ) @@ -44,7 +43,6 @@ type urlChecker struct { // awsClients is an SDK client provider. awsClients awsClientProvider - clients cloud.Clients logger *slog.Logger warnOnError bool @@ -60,7 +58,6 @@ func newURLChecker(cfg DiscoveryResourceCheckerConfig) *urlChecker { return &urlChecker{ awsConfigProvider: cfg.AWSConfigProvider, awsClients: defaultAWSClients{}, - clients: cfg.Clients, logger: cfg.Logger, warnOnError: getWarnOnError(), } diff --git a/lib/srv/db/cloud/resource_checker_url_aws_test.go b/lib/srv/db/cloud/resource_checker_url_aws_test.go index 7af30ae2fe7c3..754879b78eb47 100644 --- a/lib/srv/db/cloud/resource_checker_url_aws_test.go +++ b/lib/srv/db/cloud/resource_checker_url_aws_test.go @@ -32,7 +32,6 @@ import ( "github.com/gravitational/teleport/api/types" apiawsutils "github.com/gravitational/teleport/api/utils/aws" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/srv/discovery/common" @@ -119,26 +118,16 @@ func TestURLChecker_AWS(t *testing.T) { require.Len(t, docdbClusterDBs, 2) // Primary, reader. testCases = append(testCases, docdbClusterDBs...) - // Mock cloud clients. - mockClients := &cloud.TestCloudClients{ - STS: &mocks.STSClientV1{}, - } - mockClientsUnauth := &cloud.TestCloudClients{ - STS: &mocks.STSClientV1{}, - } - // Test both check methods. // Note that "No permissions" logs should only be printed during the second // group ("basic endpoint check"). methods := []struct { name string - clients cloud.Clients awsConfigProvider awsconfig.Provider awsClients awsClientProvider }{ { name: "API check", - clients: mockClients, awsConfigProvider: &mocks.AWSConfigProvider{}, awsClients: fakeAWSClients{ ecClient: &mocks.ElastiCacheClient{ @@ -167,7 +156,6 @@ func TestURLChecker_AWS(t *testing.T) { }, { name: "basic endpoint check", - clients: mockClientsUnauth, awsConfigProvider: &mocks.AWSConfigProvider{}, awsClients: fakeAWSClients{ ecClient: &mocks.ElastiCacheClient{Unauth: true}, @@ -183,7 +171,6 @@ func TestURLChecker_AWS(t *testing.T) { for _, method := range methods { t.Run(method.name, func(t *testing.T) { c := newURLChecker(DiscoveryResourceCheckerConfig{ - Clients: method.clients, AWSConfigProvider: method.awsConfigProvider, Logger: utils.NewSlogLoggerForTests(), }) diff --git a/lib/srv/db/cloud/users/users.go b/lib/srv/db/cloud/users/users.go index 45eeba3c3bd7d..95a511b865095 100644 --- a/lib/srv/db/cloud/users/users.go +++ b/lib/srv/db/cloud/users/users.go @@ -33,7 +33,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/retryutils" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/srv/db/secrets" "github.com/gravitational/teleport/lib/utils/interval" @@ -43,8 +42,6 @@ import ( type Config struct { // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. AWSConfigProvider awsconfig.Provider - // Clients is an interface for retrieving cloud clients. - Clients cloud.Clients // Clock is used to control time. Clock clockwork.Clock // Interval is the interval between user updates. Interval is also used as @@ -93,13 +90,6 @@ func (c *Config) CheckAndSetDefaults() error { if c.UpdateMeta == nil { return trace.BadParameter("missing UpdateMeta") } - if c.Clients == nil { - cloudClients, err := cloud.NewClients() - if err != nil { - return trace.Wrap(err) - } - c.Clients = cloudClients - } if c.Clock == nil { c.Clock = clockwork.NewRealClock() } diff --git a/lib/srv/db/cloud/users/users_test.go b/lib/srv/db/cloud/users/users_test.go index 9d817db844884..937e85f267225 100644 --- a/lib/srv/db/cloud/users/users_test.go +++ b/lib/srv/db/cloud/users/users_test.go @@ -36,7 +36,6 @@ import ( "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types" - clients "github.com/gravitational/teleport/lib/cloud" libaws "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/defaults" @@ -85,7 +84,6 @@ func TestUsers(t *testing.T) { users, err := NewUsers(Config{ AWSConfigProvider: &mocks.AWSConfigProvider{}, - Clients: &clients.TestCloudClients{}, Clock: clock, UpdateMeta: func(_ context.Context, database types.Database) error { // Update db1 to group3 when setupAllDatabases. diff --git a/lib/srv/db/common/auth.go b/lib/srv/db/common/auth.go index d0347f3c6a6f6..92b5c7a785c89 100644 --- a/lib/srv/db/common/auth.go +++ b/lib/srv/db/common/auth.go @@ -1180,26 +1180,18 @@ func (a *dbAuth) GetAWSIAMCreds(ctx context.Context, database types.Database, da return "", "", "", trace.Wrap(err) } - baseSession, err := a.cfg.Clients.GetAWSSession(ctx, dbAWS.Region, - cloud.WithAssumeRoleFromAWSMeta(dbAWS), - cloud.WithAmbientCredentials(), - ) - if err != nil { - return "", "", "", trace.Wrap(err) - } - - // ExternalID should only be used once. If the baseSession assumes a role, - // the chained sessions should have an empty external ID. - - sess, err := a.cfg.Clients.GetAWSSession(ctx, dbAWS.Region, - cloud.WithChainedAssumeRole(baseSession, arn, externalIDForChainedAssumeRole(dbAWS)), - cloud.WithAmbientCredentials(), + awsCfg, err := a.cfg.AWSConfigProvider.GetConfig(ctx, dbAWS.Region, + awsconfig.WithAssumeRole(dbAWS.AssumeRoleARN, dbAWS.ExternalID), + // ExternalID should only be used once. If the baseSession assumes a role, + // the chained sessions should have an empty external ID. + awsconfig.WithAssumeRole(arn, externalIDForChainedAssumeRole(dbAWS)), + awsconfig.WithAmbientCredentials(), ) if err != nil { return "", "", "", trace.Wrap(err) } - creds, err := sess.Config.Credentials.Get() + creds, err := awsCfg.Credentials.Retrieve(ctx) if err != nil { return "", "", "", trace.Wrap(err) } diff --git a/lib/srv/db/common/auth_test.go b/lib/srv/db/common/auth_test.go index a1cfd04f16722..3fb9645b9dddf 100644 --- a/lib/srv/db/common/auth_test.go +++ b/lib/srv/db/common/auth_test.go @@ -609,9 +609,7 @@ func TestAuthGetAWSTokenWithAssumedRole(t *testing.T) { Clock: clock, AuthClient: new(authClientMock), AccessPoint: new(accessPointMock), - Clients: &cloud.TestCloudClients{ - STS: &fakeSTS.STSClientV1, - }, + Clients: &cloud.TestCloudClients{}, AWSConfigProvider: &mocks.AWSConfigProvider{ STSClient: fakeSTS, }, @@ -701,10 +699,10 @@ func TestGetAWSIAMCreds(t *testing.T) { Clock: clock, AuthClient: new(authClientMock), AccessPoint: new(accessPointMock), - Clients: &cloud.TestCloudClients{ - STS: &tt.stsMock.STSClientV1, + Clients: &cloud.TestCloudClients{}, + AWSConfigProvider: &mocks.AWSConfigProvider{ + STSClient: tt.stsMock, }, - AWSConfigProvider: &mocks.AWSConfigProvider{}, awsClients: fakeAWSClients{ stsClient: tt.stsMock, }, diff --git a/lib/srv/db/common/engines.go b/lib/srv/db/common/engines.go index d7a5da72dec37..b989b93462716 100644 --- a/lib/srv/db/common/engines.go +++ b/lib/srv/db/common/engines.go @@ -106,8 +106,8 @@ type EngineConfig struct { AuthClient *authclient.Client // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. AWSConfigProvider awsconfig.Provider - // CloudClients provides access to cloud API clients. - CloudClients cloud.Clients + // GCPClients provides access to Google Cloud API clients. + GCPClients cloud.GCPClients // Context is the database server close context. Context context.Context // Clock is the clock interface. @@ -141,8 +141,8 @@ func (c *EngineConfig) CheckAndSetDefaults() error { if c.AWSConfigProvider == nil { return trace.BadParameter("missing AWSConfigProvider") } - if c.CloudClients == nil { - return trace.BadParameter("engine config CloudClients are missing") + if c.GCPClients == nil { + return trace.BadParameter("engine config GCPClients are missing") } if c.Context == nil { c.Context = context.Background() diff --git a/lib/srv/db/common/engines_test.go b/lib/srv/db/common/engines_test.go index 8ef522db8ded5..14a56c4fc4cd7 100644 --- a/lib/srv/db/common/engines_test.go +++ b/lib/srv/db/common/engines_test.go @@ -51,7 +51,7 @@ func TestRegisterEngine(t *testing.T) { Audit: &testAudit{}, AuthClient: &authclient.Client{}, AWSConfigProvider: &mocks.AWSConfigProvider{}, - CloudClients: cloudClients, + GCPClients: cloudClients, } require.NoError(t, ec.CheckAndSetDefaults()) diff --git a/lib/srv/db/dynamodb/engine.go b/lib/srv/db/dynamodb/engine.go index d877741dc628b..734ff51568f2c 100644 --- a/lib/srv/db/dynamodb/engine.go +++ b/lib/srv/db/dynamodb/engine.go @@ -40,7 +40,6 @@ import ( "github.com/gravitational/teleport" apievents "github.com/gravitational/teleport/api/types/events" apiaws "github.com/gravitational/teleport/api/utils/aws" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/modules" @@ -71,8 +70,6 @@ type Engine struct { // RoundTrippers is a cache of RoundTrippers, mapped by service endpoint. // It is not guarded by a mutex, since requests are processed serially. RoundTrippers map[string]http.RoundTripper - // CredentialsGetter is used to obtain STS credentials. - CredentialsGetter libaws.CredentialsGetter // UseFIPS will ensure FIPS endpoint resolution. UseFIPS bool } @@ -141,18 +138,9 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error } defer e.Audit.OnSessionEnd(e.Context, e.sessionCtx) - meta := e.sessionCtx.Database.GetAWS() - awsSession, err := e.CloudClients.GetAWSSession(ctx, meta.Region, - cloud.WithAssumeRoleFromAWSMeta(meta), - cloud.WithAmbientCredentials(), - ) - if err != nil { - return trace.Wrap(err) - } signer, err := libaws.NewSigningService(libaws.SigningServiceConfig{ Clock: e.Clock, - SessionProvider: libaws.StaticAWSSessionProvider(awsSession), - CredentialsGetter: e.CredentialsGetter, + AWSConfigProvider: e.AWSConfigProvider, }) if err != nil { return trace.Wrap(err) @@ -223,12 +211,14 @@ func (e *Engine) process(ctx context.Context, req *http.Request, signer *libaws. return trace.Wrap(err) } signingCtx := &libaws.SigningCtx{ - SigningName: re.SigningName, - SigningRegion: re.SigningRegion, - Expiry: e.sessionCtx.Identity.Expires, - SessionName: e.sessionCtx.Identity.Username, - AWSRoleArn: roleArn, - SessionTags: e.sessionCtx.Database.GetAWS().SessionTags, + SigningName: re.SigningName, + SigningRegion: re.SigningRegion, + Expiry: e.sessionCtx.Identity.Expires, + SessionName: e.sessionCtx.Identity.Username, + BaseAWSRoleARN: meta.AssumeRoleARN, + BaseAWSExternalID: meta.ExternalID, + AWSRoleArn: roleArn, + SessionTags: e.sessionCtx.Database.GetAWS().SessionTags, } if meta.AssumeRoleARN == "" { signingCtx.AWSExternalID = meta.ExternalID diff --git a/lib/srv/db/dynamodb/test.go b/lib/srv/db/dynamodb/test.go index 92e57e4915c60..b12d0493ea75e 100644 --- a/lib/srv/db/dynamodb/test.go +++ b/lib/srv/db/dynamodb/test.go @@ -101,7 +101,9 @@ func NewTestServer(config common.TestServerConfig, opts ...TestServerOption) (*T mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - err := awsutils.VerifyAWSSignatureV2(r, credentials.NewStaticCredentialsProvider("AKIDl", "SECRET", "SESSION")) + err := awsutils.VerifyAWSSignatureV2(r, + credentials.NewStaticCredentialsProvider("FAKEACCESSKEYID", "secret", "token"), + ) if err != nil { code := trace.ErrorToCode(err) body, _ := json.Marshal(jsonErr{ diff --git a/lib/srv/db/dynamodb_test.go b/lib/srv/db/dynamodb_test.go index f7a2b259e110b..16ee32af42315 100644 --- a/lib/srv/db/dynamodb_test.go +++ b/lib/srv/db/dynamodb_test.go @@ -22,48 +22,29 @@ import ( "context" "crypto/tls" "net" - "net/http" "testing" - "github.com/aws/aws-sdk-go-v2/credentials" awsdynamodb "github.com/aws/aws-sdk-go-v2/service/dynamodb" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/defaults" libevents "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/srv/db/common" "github.com/gravitational/teleport/lib/srv/db/dynamodb" - awsutils "github.com/gravitational/teleport/lib/utils/aws" - "github.com/gravitational/teleport/lib/utils/aws/migration" ) -func registerTestDynamoDBEngine() { - // Override DynamoDB engine that is used normally with the test one - // with custom HTTP client. - common.RegisterEngine(newTestDynamoDBEngine, defaults.ProtocolDynamoDB) -} - -func newTestDynamoDBEngine(ec common.EngineConfig) common.Engine { - return &dynamodb.Engine{ - EngineConfig: ec, - RoundTrippers: make(map[string]http.RoundTripper), - // inject mock AWS credentials. - CredentialsGetter: awsutils.NewStaticCredentialsGetter( - migration.NewCredentialsAdapter( - credentials.NewStaticCredentialsProvider("AKIDl", "SECRET", "SESSION"), - ), - ), - } -} - func TestAccessDynamoDB(t *testing.T) { t.Parallel() ctx := context.Background() mockTables := []string{"table-one", "table-two"} - testCtx := setupTestContext(ctx, t, - withDynamoDB("DynamoDB")) + testCtx := setupTestContext(ctx, t) + testCtx.server = testCtx.setupDatabaseServer(ctx, t, agentParams{ + AWSConfigProvider: &mocks.AWSConfigProvider{}, + Databases: []types.Database{withDynamoDB("DynamoDB")(t, ctx, testCtx)}, + }) go testCtx.startHandlingConnections() tests := []struct { @@ -143,8 +124,11 @@ func TestAccessDynamoDB(t *testing.T) { func TestAuditDynamoDB(t *testing.T) { ctx := context.Background() - testCtx := setupTestContext(ctx, t, - withDynamoDB("DynamoDB")) + testCtx := setupTestContext(ctx, t) + testCtx.server = testCtx.setupDatabaseServer(ctx, t, agentParams{ + AWSConfigProvider: &mocks.AWSConfigProvider{}, + Databases: []types.Database{withDynamoDB("DynamoDB")(t, ctx, testCtx)}, + }) go testCtx.startHandlingConnections() testCtx.createUserAndRole(ctx, t, "alice", "admin", []string{"admin"}, []string{types.Wildcard}) diff --git a/lib/srv/db/mysql/engine.go b/lib/srv/db/mysql/engine.go index 9828d484b7bba..369e4a832ab86 100644 --- a/lib/srv/db/mysql/engine.go +++ b/lib/srv/db/mysql/engine.go @@ -237,7 +237,7 @@ func (e *Engine) connect(ctx context.Context, sessionCtx *common.Session) (*clie } case sessionCtx.Database.IsCloudSQL(): // Get the client once for subsequent calls (it acquires a read lock). - gcpClient, err := e.CloudClients.GetGCPSQLAdminClient(ctx) + gcpClient, err := e.GCPClients.GetGCPSQLAdminClient(ctx) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/db/objects/fetcher.go b/lib/srv/db/objects/fetcher.go index 676c2b822b320..af1887e021794 100644 --- a/lib/srv/db/objects/fetcher.go +++ b/lib/srv/db/objects/fetcher.go @@ -38,10 +38,10 @@ type ImportRulesReader interface { // ObjectFetcherConfig provides static object fetcher configuration. type ObjectFetcherConfig struct { - ImportRules ImportRulesReader - Auth common.Auth - CloudClients libcloud.Clients - Log *slog.Logger + ImportRules ImportRulesReader + Auth common.Auth + GCPClients libcloud.GCPClients + Log *slog.Logger } // ObjectFetcher defines an interface for retrieving database objects. diff --git a/lib/srv/db/objects/importer.go b/lib/srv/db/objects/importer.go index b5c3d6d5a3a9a..295bd0e99cb14 100644 --- a/lib/srv/db/objects/importer.go +++ b/lib/srv/db/objects/importer.go @@ -51,10 +51,10 @@ func startDatabaseImporter(ctx context.Context, cfg Config, database types.Datab cfg.Log = cfg.Log.With("database", database.GetName(), "protocol", database.GetProtocol()) fetcher, err := GetObjectFetcher(ctx, database, ObjectFetcherConfig{ - ImportRules: cfg.ImportRules, - Auth: cfg.Auth, - CloudClients: cfg.CloudClients, - Log: cfg.Log, + ImportRules: cfg.ImportRules, + Auth: cfg.Auth, + GCPClients: cfg.GCPClients, + Log: cfg.Log, }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/db/objects/objects.go b/lib/srv/db/objects/objects.go index ae292ed13b52d..248a388264062 100644 --- a/lib/srv/db/objects/objects.go +++ b/lib/srv/db/objects/objects.go @@ -42,7 +42,7 @@ type Config struct { DatabaseObjectClient *databaseobject.Client ImportRules ImportRulesReader Auth common.Auth - CloudClients cloud.Clients + GCPClients cloud.GCPClients // ScanInterval specifies how often the database is scanned. // A higher ScanInterval reduces the load on the database and database agent, @@ -113,8 +113,8 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) error { if c.Auth == nil { return trace.BadParameter("missing parameter Auth") } - if c.CloudClients == nil { - return trace.BadParameter("missing parameter CloudClients") + if c.GCPClients == nil { + return trace.BadParameter("missing parameter GCPClients") } if c.Log == nil { c.Log = slog.Default().With(teleport.ComponentKey, "db:obj_importer") diff --git a/lib/srv/db/postgres/connector.go b/lib/srv/db/postgres/connector.go index 81873b6afd7b2..3a73d9e58b017 100644 --- a/lib/srv/db/postgres/connector.go +++ b/lib/srv/db/postgres/connector.go @@ -34,9 +34,9 @@ import ( ) type connector struct { - auth common.Auth - cloudClients libcloud.Clients - log *slog.Logger + auth common.Auth + gcpClients libcloud.GCPClients + log *slog.Logger certExpiry time.Time database types.Database @@ -91,7 +91,7 @@ func (c *connector) getConnectConfig(ctx context.Context) (*pgconn.Config, error return nil, trace.Wrap(err) } // Get the client once for subsequent calls (it acquires a read lock). - gcpClient, err := c.cloudClients.GetGCPSQLAdminClient(ctx) + gcpClient, err := c.gcpClients.GetGCPSQLAdminClient(ctx) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/srv/db/postgres/engine.go b/lib/srv/db/postgres/engine.go index ec1f95d5fa121..f7b581b65792b 100644 --- a/lib/srv/db/postgres/engine.go +++ b/lib/srv/db/postgres/engine.go @@ -505,9 +505,9 @@ func (e *Engine) receiveFromServer(serverConn *pgconn.PgConn, serverErrCh chan<- func (e *Engine) newConnector(sessionCtx *common.Session) *connector { conn := &connector{ - auth: e.Auth, - cloudClients: e.CloudClients, - log: e.Log, + auth: e.Auth, + gcpClients: e.GCPClients, + log: e.Log, certExpiry: sessionCtx.GetExpiry(), database: sessionCtx.Database, @@ -533,9 +533,6 @@ func (e *Engine) handleCancelRequest(ctx context.Context, sessionCtx *common.Ses // Instead, use the pgconn config string parser for convenience and dial // db host:port ourselves. network, address := pgconn.NetworkAddress(config.Host, config.Port) - if err != nil { - return trace.Wrap(err) - } dialer := net.Dialer{Timeout: defaults.DefaultIOTimeout} conn, err := dialer.DialContext(ctx, network, address) if err != nil { diff --git a/lib/srv/db/postgres/objects.go b/lib/srv/db/postgres/objects.go index f965baf5cf05c..67d2a37e98465 100644 --- a/lib/srv/db/postgres/objects.go +++ b/lib/srv/db/postgres/objects.go @@ -119,9 +119,9 @@ func (f *objectFetcher) getDatabaseNames(ctx context.Context) ([]string, error) func (f *objectFetcher) connectAsAdmin(ctx context.Context, databaseName string) (*pgx.Conn, error) { conn := &connector{ - auth: f.cfg.Auth, - cloudClients: f.cfg.CloudClients, - log: f.cfg.Log, + auth: f.cfg.Auth, + gcpClients: f.cfg.GCPClients, + log: f.cfg.Log, certExpiry: time.Now().Add(time.Hour), database: f.db, diff --git a/lib/srv/db/postgres/users.go b/lib/srv/db/postgres/users.go index 56fb14a2dd9d8..1e49614bb7224 100644 --- a/lib/srv/db/postgres/users.go +++ b/lib/srv/db/postgres/users.go @@ -204,10 +204,10 @@ func (e *Engine) applyPermissions(ctx context.Context, sessionCtx *common.Sessio } fetcher, err := objects.GetObjectFetcher(ctx, sessionCtx.Database, objects.ObjectFetcherConfig{ - ImportRules: e.AuthClient, - Auth: e.Auth, - CloudClients: e.CloudClients, - Log: e.Log, + ImportRules: e.AuthClient, + Auth: e.Auth, + GCPClients: e.GCPClients, + Log: e.Log, }) if err != nil { return trace.Wrap(err) diff --git a/lib/srv/db/server.go b/lib/srv/db/server.go index 223744173ae7d..b4a122b376502 100644 --- a/lib/srv/db/server.go +++ b/lib/srv/db/server.go @@ -210,7 +210,6 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) (err error) { } if c.AWSDatabaseFetcherFactory == nil { factory, err := db.NewAWSFetcherFactory(db.AWSFetcherFactoryConfig{ - CloudClients: c.CloudClients, AWSConfigProvider: c.AWSConfigProvider, }) if err != nil { @@ -253,7 +252,6 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) (err error) { } if c.CloudMeta == nil { c.CloudMeta, err = cloud.NewMetadata(cloud.MetadataConfig{ - Clients: c.CloudClients, AWSConfigProvider: c.AWSConfigProvider, }) if err != nil { @@ -264,7 +262,6 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) (err error) { c.CloudIAM, err = cloud.NewIAM(ctx, cloud.IAMConfig{ AccessPoint: c.AccessPoint, AWSConfigProvider: c.AWSConfigProvider, - Clients: c.CloudClients, HostID: c.HostID, }) if err != nil { @@ -289,7 +286,6 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) (err error) { } c.CloudUsers, err = users.NewUsers(users.Config{ AWSConfigProvider: c.AWSConfigProvider, - Clients: c.CloudClients, UpdateMeta: c.CloudMeta.Update, ClusterName: clusterName.GetClusterName(), }) @@ -303,7 +299,7 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) (err error) { DatabaseObjectClient: c.AuthClient.DatabaseObjectsClient(), ImportRules: c.AuthClient, Auth: c.Auth, - CloudClients: c.CloudClients, + GCPClients: c.CloudClients, }) if err != nil { return trace.Wrap(err) @@ -313,7 +309,7 @@ func (c *Config) CheckAndSetDefaults(ctx context.Context) (err error) { if c.discoveryResourceChecker == nil { c.discoveryResourceChecker, err = cloud.NewDiscoveryResourceChecker(cloud.DiscoveryResourceCheckerConfig{ ResourceMatchers: c.ResourceMatchers, - Clients: c.CloudClients, + AzureClients: c.CloudClients, AWSConfigProvider: c.AWSConfigProvider, Context: ctx, }) @@ -1204,7 +1200,7 @@ func (s *Server) createEngine(sessionCtx *common.Session, audit common.Audit) (c Audit: audit, AuthClient: s.cfg.AuthClient, AWSConfigProvider: s.cfg.AWSConfigProvider, - CloudClients: s.cfg.CloudClients, + GCPClients: s.cfg.CloudClients, Context: s.connContext, Clock: s.cfg.Clock, Log: sessionCtx.Log, diff --git a/lib/srv/db/watcher_test.go b/lib/srv/db/watcher_test.go index 8e35120eddfa9..e6e06ff35202b 100644 --- a/lib/srv/db/watcher_test.go +++ b/lib/srv/db/watcher_test.go @@ -335,15 +335,8 @@ func TestWatcherCloudFetchers(t *testing.T) { ctx := context.Background() testCtx := setupTestContext(ctx, t) - testCloudClients := &clients.TestCloudClients{ - AzureSQLServer: azure.NewSQLClientByAPI(&azure.ARMSQLServerMock{ - AllServers: []*armsql.Server{azSQLServer}, - }), - AzureManagedSQLServer: azure.NewManagedSQLClientByAPI(&azure.ARMSQLManagedServerMock{}), - } dbFetcherFactory, err := db.NewAWSFetcherFactory(db.AWSFetcherFactoryConfig{ AWSConfigProvider: &mocks.AWSConfigProvider{}, - CloudClients: testCloudClients, AWSClients: fakeAWSClients{ rdsClient: &mocks.RDSClient{Unauth: true}, // Access denied error should not affect other fetchers. rssClient: &mocks.RedshiftServerlessClient{ @@ -376,7 +369,6 @@ func TestWatcherCloudFetchers(t *testing.T) { }, }}, CloudClients: &clients.TestCloudClients{ - STS: &mocks.STSClientV1{}, AzureSQLServer: azure.NewSQLClientByAPI(&azure.ARMSQLServerMock{ AllServers: []*armsql.Server{azSQLServer}, }), diff --git a/lib/srv/discovery/access_graph_aws.go b/lib/srv/discovery/access_graph_aws.go index 185dd3f908a68..9b17be7fd3dc4 100644 --- a/lib/srv/discovery/access_graph_aws.go +++ b/lib/srv/discovery/access_graph_aws.go @@ -505,7 +505,6 @@ func (s *Server) accessGraphAWSFetchersFromMatchers(ctx context.Context, matcher ctx, aws_sync.Config{ AWSConfigProvider: s.AWSConfigProvider, - CloudClients: s.CloudClients, GetEKSClient: s.GetAWSSyncEKSClient, GetEC2Client: s.GetEC2Client, AssumeRole: assumeRole, diff --git a/lib/srv/discovery/access_graph_test.go b/lib/srv/discovery/access_graph_test.go index c6efe1064cbfc..633770bce7dd3 100644 --- a/lib/srv/discovery/access_graph_test.go +++ b/lib/srv/discovery/access_graph_test.go @@ -190,11 +190,11 @@ func TestServer_updateDiscoveryConfigStatus(t *testing.T) { name: "merge two errors", args: args{ fetchers: []*fakeFetcher{ - &fakeFetcher{ + { discoveryConfigName: "test1", err: fmt.Errorf("error in fetcher 1"), }, - &fakeFetcher{ + { discoveryConfigName: "test1", err: fmt.Errorf("error in fetcher 2"), }, diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go index b5c9b14df95ec..b29cef50e2cc9 100644 --- a/lib/srv/discovery/discovery.go +++ b/lib/srv/discovery/discovery.go @@ -36,7 +36,6 @@ 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/aws-sdk-go/aws/session" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "google.golang.org/protobuf/types/known/timestamppb" @@ -57,7 +56,6 @@ import ( "github.com/gravitational/teleport/lib/cloud/awsconfig" gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp" "github.com/gravitational/teleport/lib/cryptosuites" - "github.com/gravitational/teleport/lib/integrations/awsoidc" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/readonly" "github.com/gravitational/teleport/lib/srv/discovery/common" @@ -240,12 +238,7 @@ func (c *Config) CheckAndSetDefaults() error { kubernetes matchers are present.`) } if c.CloudClients == nil { - awsIntegrationSessionProvider := func(ctx context.Context, region, integration string) (*session.Session, error) { - return awsoidc.NewSessionV1(ctx, c.AccessPoint, region, integration) - } - cloudClients, err := cloud.NewClients( - cloud.WithAWSIntegrationSessionProvider(awsIntegrationSessionProvider), - ) + cloudClients, err := cloud.NewClients() if err != nil { return trace.Wrap(err, "unable to create cloud clients") } @@ -264,7 +257,6 @@ kubernetes matchers are present.`) } if c.AWSDatabaseFetcherFactory == nil { factory, err := db.NewAWSFetcherFactory(db.AWSFetcherFactoryConfig{ - CloudClients: c.CloudClients, AWSConfigProvider: c.AWSConfigProvider, }) if err != nil { diff --git a/lib/srv/discovery/discovery_test.go b/lib/srv/discovery/discovery_test.go index dcde4aa6d386b..bc397e4e717be 100644 --- a/lib/srv/discovery/discovery_test.go +++ b/lib/srv/discovery/discovery_test.go @@ -365,7 +365,6 @@ func TestDiscoveryServer(t *testing.T) { wantInstalledInstances []string wantDiscoveryConfigStatus *discoveryconfig.Status userTasksDiscoverCheck require.ValueAssertionFunc - cloudClients cloud.Clients ssmRunError error }{ { @@ -947,7 +946,6 @@ func TestDiscoveryServer(t *testing.T) { Emitter: tc.emitter, Log: logger, DiscoveryGroup: defaultDiscoveryGroup, - CloudClients: tc.cloudClients, clock: fakeClock, }) require.NoError(t, err) @@ -2174,7 +2172,6 @@ func TestDiscoveryDatabase(t *testing.T) { } testCloudClients := &cloud.TestCloudClients{ - STS: &mocks.STSClientV1{}, AzureRedis: azure.NewRedisClientByAPI(&azure.ARMRedisMock{ Servers: []*armredis.ResourceInfo{azRedisResource}, }), @@ -2550,7 +2547,6 @@ func TestDiscoveryDatabase(t *testing.T) { } dbFetcherFactory, err := db.NewAWSFetcherFactory(db.AWSFetcherFactoryConfig{ AWSConfigProvider: fakeConfigProvider, - CloudClients: testCloudClients, AWSClients: fakeAWSClients{ ecClient: &mocks.ElastiCacheClient{}, mdbClient: &mocks.MemoryDBClient{}, @@ -2685,12 +2681,8 @@ func TestDiscoveryDatabaseRemovingDiscoveryConfigs(t *testing.T) { fakeConfigProvider := &mocks.AWSConfigProvider{ STSClient: &mocks.STSClient{}, } - testCloudClients := &cloud.TestCloudClients{ - STS: &fakeConfigProvider.STSClient.STSClientV1, - } dbFetcherFactory, err := db.NewAWSFetcherFactory(db.AWSFetcherFactoryConfig{ AWSConfigProvider: fakeConfigProvider, - CloudClients: testCloudClients, AWSClients: fakeAWSClients{ rdsClient: &mocks.RDSClient{ DBInstances: []rdstypes.DBInstance{*awsRDSInstance}, @@ -2730,7 +2722,6 @@ func TestDiscoveryDatabaseRemovingDiscoveryConfigs(t *testing.T) { &Config{ AWSConfigProvider: fakeConfigProvider, AWSDatabaseFetcherFactory: dbFetcherFactory, - CloudClients: testCloudClients, ClusterFeatures: func() proto.Features { return proto.Features{} }, KubernetesClient: fake.NewSimpleClientset(), AccessPoint: getDiscoveryAccessPoint(tlsServer.Auth(), authClient), diff --git a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go index 21a5ca1af85e8..146637659bba7 100644 --- a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go +++ b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go @@ -35,7 +35,6 @@ import ( usageeventsv1 "github.com/gravitational/teleport/api/gen/proto/go/usageevents/v1" accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/srv/server" ) @@ -48,8 +47,6 @@ const pageSize int32 = 500 type Config struct { // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. AWSConfigProvider awsconfig.Provider - // CloudClients is the cloud clients to use when fetching AWS resources. - CloudClients cloud.Clients // GetEKSClient gets an AWS EKS client for the given region. GetEKSClient EKSClientGetter // GetEC2Client gets an AWS EC2 client for the given region. diff --git a/lib/srv/discovery/fetchers/db/aws.go b/lib/srv/discovery/fetchers/db/aws.go index 24de91e83e309..10a49173a5a3a 100644 --- a/lib/srv/discovery/fetchers/db/aws.go +++ b/lib/srv/discovery/fetchers/db/aws.go @@ -27,7 +27,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/srv/discovery/common" ) @@ -49,8 +48,6 @@ type awsFetcherPlugin interface { // awsFetcherConfig is the AWS database fetcher configuration. type awsFetcherConfig struct { - // AWSClients are the AWS API clients. - AWSClients cloud.AWSClients // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. AWSConfigProvider awsconfig.Provider // Type is the type of DB matcher, for example "rds", "redshift", etc. @@ -78,9 +75,6 @@ type awsFetcherConfig struct { // CheckAndSetDefaults validates the config and sets defaults. func (cfg *awsFetcherConfig) CheckAndSetDefaults(component string) error { - if cfg.AWSClients == nil { - return trace.BadParameter("missing parameter AWSClients") - } if cfg.AWSConfigProvider == nil { return trace.BadParameter("missing AWSConfigProvider") } diff --git a/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go b/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go index dd64dcdade45f..bf657836520c6 100644 --- a/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go +++ b/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go @@ -26,7 +26,6 @@ import ( "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/cloud/awstesthelpers" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/srv/discovery/common" @@ -51,8 +50,7 @@ func TestRedshiftServerlessFetcher(t *testing.T) { tests := []awsFetcherTest{ { - name: "fetch all", - inputClients: &cloud.TestCloudClients{}, + name: "fetch all", fetcherCfg: AWSFetcherFactoryConfig{ AWSClients: fakeAWSClients{ rssClient: &mocks.RedshiftServerlessClient{ diff --git a/lib/srv/discovery/fetchers/db/db.go b/lib/srv/discovery/fetchers/db/db.go index d7cca43f75dfe..eca656ca067a9 100644 --- a/lib/srv/discovery/fetchers/db/db.go +++ b/lib/srv/discovery/fetchers/db/db.go @@ -121,14 +121,9 @@ type AWSFetcherFactoryConfig struct { AWSConfigProvider awsconfig.Provider // AWSClients provides AWS SDK clients. AWSClients AWSClientProvider - // CloudClients is an interface for retrieving AWS SDK v1 cloud clients. - CloudClients cloud.AWSClients } func (c *AWSFetcherFactoryConfig) checkAndSetDefaults() error { - if c.CloudClients == nil { - return trace.BadParameter("missing CloudClients") - } if c.AWSConfigProvider == nil { return trace.BadParameter("missing AWSConfigProvider") } @@ -173,7 +168,6 @@ func (f *AWSFetcherFactory) MakeFetchers(ctx context.Context, matchers []types.A for _, makeFetcher := range makeFetchers { for _, region := range matcher.Regions { fetcher, err := makeFetcher(awsFetcherConfig{ - AWSClients: f.cfg.CloudClients, Type: matcherType, AssumeRole: assumeRole, Labels: matcher.Tags, diff --git a/lib/srv/discovery/fetchers/db/helpers_test.go b/lib/srv/discovery/fetchers/db/helpers_test.go index 5feae42c7b367..69b94ff9b0896 100644 --- a/lib/srv/discovery/fetchers/db/helpers_test.go +++ b/lib/srv/discovery/fetchers/db/helpers_test.go @@ -112,7 +112,6 @@ var testAssumeRole = types.AssumeRole{ // awsFetcherTest is a common test struct for AWS fetchers. type awsFetcherTest struct { name string - inputClients *cloud.TestCloudClients fetcherCfg AWSFetcherFactoryConfig inputMatchers []types.AWSMatcher wantDatabases types.Databases @@ -125,11 +124,6 @@ func testAWSFetchers(t *testing.T, tests ...awsFetcherTest) { for _, test := range tests { test := test fakeSTS := &mocks.STSClient{} - if test.inputClients != nil { - require.Nil(t, test.inputClients.STS, "testAWSFetchers injects an STS mock itself, but test input had already configured it. This is a test configuration error.") - test.inputClients.STS = &fakeSTS.STSClientV1 - } - test.fetcherCfg.CloudClients = test.inputClients require.Nil(t, test.fetcherCfg.AWSConfigProvider, "testAWSFetchers injects a fake AWSConfigProvider, but the test input had already configured it. This is a test configuration error.") test.fetcherCfg.AWSConfigProvider = &mocks.AWSConfigProvider{ STSClient: fakeSTS, diff --git a/lib/srv/server/azure_watcher_test.go b/lib/srv/server/azure_watcher_test.go index 0c9a183b1fc89..3ff11436ebc06 100644 --- a/lib/srv/server/azure_watcher_test.go +++ b/lib/srv/server/azure_watcher_test.go @@ -33,7 +33,7 @@ import ( ) type mockClients struct { - cloud.Clients + cloud.AzureClients azureClient azure.VirtualMachinesClient } From 7d042c15b4e3bcf5e9916de2806e2fd35cc6efc3 Mon Sep 17 00:00:00 2001 From: Paul Gottschling Date: Thu, 30 Jan 2025 12:03:21 -0500 Subject: [PATCH 18/28] Upgrade Vale in the prose check workflow (#51619) --- .github/workflows/doc-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-tests.yaml b/.github/workflows/doc-tests.yaml index 54df4b0743ef2..60685a0b8295e 100644 --- a/.github/workflows/doc-tests.yaml +++ b/.github/workflows/doc-tests.yaml @@ -134,7 +134,7 @@ jobs: - name: Run the linter uses: errata-ai/vale-action@d89dee975228ae261d22c15adcd03578634d429c # v2.1.1 with: - version: 2.30.0 + version: 3.9.4 # Take the comma-separated list of files returned by the "Check for # relevant changes" job. separator: "," From f4514b4d34d6189f6b356dd860b10e4de99df358 Mon Sep 17 00:00:00 2001 From: Brian Joerger Date: Thu, 30 Jan 2025 09:40:46 -0800 Subject: [PATCH 19/28] Address todos. (#50417) --- .../wizards/AddAuthDeviceWizard.tsx | 7 --- .../teleport/src/services/auth/auth.ts | 59 ------------------- 2 files changed, 66 deletions(-) diff --git a/web/packages/teleport/src/Account/ManageDevices/wizards/AddAuthDeviceWizard.tsx b/web/packages/teleport/src/Account/ManageDevices/wizards/AddAuthDeviceWizard.tsx index be291c660f55a..d161d8db54b93 100644 --- a/web/packages/teleport/src/Account/ManageDevices/wizards/AddAuthDeviceWizard.tsx +++ b/web/packages/teleport/src/Account/ManageDevices/wizards/AddAuthDeviceWizard.tsx @@ -73,12 +73,6 @@ export function AddAuthDeviceWizard({ const reauthState = useReAuthenticate({ challengeScope: MfaChallengeScope.MANAGE_DEVICES, onMfaResponse: mfaResponse => - // TODO(Joerger): Instead of getting a privilege token, we should get - // // a register challenge with the mfa response directly. For good UX, this would - // // require some refactoring to the flow so the user can choose a device type before - // // completing an mfa check and getting an otp/webauthn register challenge, or - // // allowing the backend to return a flexible register challenge - // await auth.createPrivilegeToken(mfaResponse).then(setPrivilegeToken); auth.createPrivilegeToken(mfaResponse).then(setPrivilegeToken), }); @@ -188,7 +182,6 @@ export function CreateDeviceStep({ if (usage === 'passwordless' || newMfaDeviceType === 'webauthn') { createPasskeyAttempt.run(async () => { const credential = await auth.createNewWebAuthnDevice({ - // TODO(Joerger): Skip privilege token step, just pass in mfa response. tokenId: privilegeToken, deviceUsage: usage, }); diff --git a/web/packages/teleport/src/services/auth/auth.ts b/web/packages/teleport/src/services/auth/auth.ts index 3e58e9f5f5f4b..4d1e978f2f64c 100644 --- a/web/packages/teleport/src/services/auth/auth.ts +++ b/web/packages/teleport/src/services/auth/auth.ts @@ -341,7 +341,6 @@ const auth = { }); }, - // TODO(Joerger): Delete once no longer used by /e async getSsoChallengeResponse( challenge: SsoChallenge ): Promise { @@ -386,63 +385,10 @@ const auth = { }; }, - // TODO(Joerger): Delete once no longer used by /e - createPrivilegeTokenWithWebauthn() { - return auth - .getMfaChallenge({ scope: MfaChallengeScope.MANAGE_DEVICES }) - .then(auth.getMfaChallengeResponse) - .then(mfaResp => auth.createPrivilegeToken(mfaResp)); - }, - - // TODO(Joerger): Delete once no longer used by /e - createPrivilegeTokenWithTotp(secondFactorToken: string) { - return api.post(cfg.api.createPrivilegeTokenPath, { secondFactorToken }); - }, - createRestrictedPrivilegeToken() { return api.post(cfg.api.createPrivilegeTokenPath, {}); }, - // TODO(Joerger): Remove once /e is no longer using it. - async getWebauthnResponse( - scope: MfaChallengeScope, - allowReuse?: boolean, - isMfaRequiredRequest?: IsMfaRequiredRequest, - abortSignal?: AbortSignal - ) { - // TODO(Joerger): DELETE IN 16.0.0 - // the create mfa challenge endpoint below supports - // MFARequired requests without the extra roundtrip. - if (isMfaRequiredRequest) { - try { - const isMFARequired = await checkMfaRequired( - isMfaRequiredRequest, - abortSignal - ); - if (!isMFARequired.required) { - return; - } - } catch (err) { - if ( - err?.response?.status === 400 && - err?.message.includes('missing target for MFA check') - ) { - // checking MFA requirement for admin actions is not supported by old - // auth servers, we expect an error instead. In this case, assume MFA is - // not required. Callers should fallback to retrying with MFA if needed. - return; - } - - throw err; - } - } - - return auth - .getMfaChallenge({ scope, allowReuse, isMfaRequiredRequest }, abortSignal) - .then(challenge => auth.getMfaChallengeResponse(challenge, 'webauthn')) - .then(res => res.webauthn_response); - }, - getMfaChallengeResponseForAdminAction(allowReuse?: boolean) { // If the client is checking if MFA is required for an admin action, // but we know admin action MFA is not enforced, return early. @@ -460,11 +406,6 @@ const auth = { }) .then(auth.getMfaChallengeResponse); }, - - // TODO(Joerger): Delete in favor of getMfaChallengeResponseForAdminAction once /e is updated. - getWebauthnResponseForAdminAction(allowReuse?: boolean) { - return auth.getMfaChallengeResponseForAdminAction(allowReuse); - }, }; function checkMfaRequired( From f44af9b61d33495784fb9589016baed335209e0d Mon Sep 17 00:00:00 2001 From: "STeve (Xin) Huang" Date: Thu, 30 Jan 2025 12:52:43 -0500 Subject: [PATCH 20/28] [docs] PostgreSQL auto-user provisioning guide minor edits (#48897) * [docs] PostgreSQL auto-user provisioning guide minor edits * remove admin option from rds_superuser and add note on admin option for each role --- .../auto-user-provisioning/postgres.mdx | 36 ++++++++++++++----- .../postgres15-grant-create.mdx | 11 ------ 2 files changed, 27 insertions(+), 20 deletions(-) delete mode 100644 docs/pages/includes/database-access/auto-user-provisioning/postgres15-grant-create.mdx diff --git a/docs/pages/enroll-resources/database-access/auto-user-provisioning/postgres.mdx b/docs/pages/enroll-resources/database-access/auto-user-provisioning/postgres.mdx index 2fb8c7c1aac83..46f44bf3306ca 100644 --- a/docs/pages/enroll-resources/database-access/auto-user-provisioning/postgres.mdx +++ b/docs/pages/enroll-resources/database-access/auto-user-provisioning/postgres.mdx @@ -41,6 +41,19 @@ Note that the RDS database must have IAM authentication enabled. Refer to the [AWS documentation](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html) to make sure you are using the `rds_iam` role correctly. for more information. + +If the admin user needs to grant the `rds_superuser` role to auto-provisioned +users, the admin user must also be a `rds_superuser`: +```sql +GRANT rds_superuser TO "teleport-admin"; +``` + +For PostgreSQL 16+, you must grant the `ADMIN` option to the admin user for each +PostgreSQL role that Teleport will assign to your Teleport user. For example, to +allow the admin user to grant and revoke role `reader`: +```sql +GRANT reader TO "teleport-admin" WITH ADMIN OPTION; +``` The self-hosted PostgreSQL admin user must have X.509 authentication configured. @@ -49,6 +62,13 @@ The self-hosted PostgreSQL admin user must have X.509 authentication configured. CREATE USER "teleport-admin" login createrole; ``` +For PostgreSQL 16+, you must grant the `ADMIN` option to the admin user for each +PostgreSQL role that Teleport will assign to your Teleport user. For example, to +allow the admin user to grant and revoke role `reader`: +```sql +GRANT reader TO "teleport-admin" WITH ADMIN OPTION; +``` + Note that the database must be configured to accept client certificate auth for the admin user by having the following entries in `pg_hba.conf`: @@ -63,7 +83,13 @@ to ensure that your configuration is correct. -When [Database Access Controls](../rbac.mdx) feature is in use, the `teleport-admin` should have permissions to relevant database objects. For example: +When [Database Access Controls](../rbac.mdx) feature is in use, the +`teleport-admin` should have permissions to relevant database objects. You can +grant `teleport-admin` the `SUPERUSER` option for self-hosted databases, or the +`rds_superuser` role for RDS databases. + +For improved security through the principle of least privilege, you can also +assign permissions directly to specific database objects. For example: ```sql GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA schema1, schema2, schema3 TO "teleport-admin"; @@ -75,10 +101,6 @@ the database, which will be created automatically if it doesn't exist. (!docs/pages/includes/database-access/auto-user-provisioning/db-definition-default-dbname.mdx protocol="postgres" uri="localhost:5432" default="the same database that the user is accessing" !) - -(!docs/pages/includes/database-access/auto-user-provisioning/postgres15-grant-create.mdx!) - - ## Step 2/3. Configure a Teleport role Database permissions are associated with a Teleport role, which can either allocate predefined database roles (configured in each database) or define specific database object permissions directly. Teleport grants these permissions for the duration of the connection. @@ -169,10 +191,6 @@ Users created within the database will: ## Troubleshooting -### Permission denied for schema public error - -(!docs/pages/includes/database-access/auto-user-provisioning/postgres15-grant-create.mdx!) - ### User does not have CONNECT privilege error You may encounter the following error when the admin user or the roles assigned diff --git a/docs/pages/includes/database-access/auto-user-provisioning/postgres15-grant-create.mdx b/docs/pages/includes/database-access/auto-user-provisioning/postgres15-grant-create.mdx deleted file mode 100644 index 012fe0e585848..0000000000000 --- a/docs/pages/includes/database-access/auto-user-provisioning/postgres15-grant-create.mdx +++ /dev/null @@ -1,11 +0,0 @@ -PostgreSQL 15 revokes the `CREATE` permission from all users except a database -owner from the public (or default) schema. - -Grant the admin user `CREATE` privilege so the admin user can create procedures: -```sql -GRANT CREATE ON SCHEMA public TO "teleport-admin"; -``` - -If `admin_user.default_database` is specified, the `CREATE` privilege is only -required for the database specified in the `default_database`. Otherwise, you -have to repeat the privilege grant for every database Teleport will access. From 176488fa3bbc1c05a4d3cf8df33e5c920fab818a Mon Sep 17 00:00:00 2001 From: "STeve (Xin) Huang" Date: Thu, 30 Jan 2025 12:52:51 -0500 Subject: [PATCH 21/28] add MongoDB auto-user provisioning prereq (#49478) * add MongoDB auto-user provisioning prereq * try without Admonition --- .../database-access/auto-user-provisioning/mongodb.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/pages/enroll-resources/database-access/auto-user-provisioning/mongodb.mdx b/docs/pages/enroll-resources/database-access/auto-user-provisioning/mongodb.mdx index 32b58386d39a5..97bff21317697 100644 --- a/docs/pages/enroll-resources/database-access/auto-user-provisioning/mongodb.mdx +++ b/docs/pages/enroll-resources/database-access/auto-user-provisioning/mongodb.mdx @@ -11,6 +11,10 @@ description: Configure automatic user provisioning for MongoDB. - A self-hosted MongoDB database enrolled with your Teleport cluster. Follow the [Teleport documentation](../enroll-self-hosted-databases/mongodb-self-hosted.mdx) to learn how to enroll your database. + Your MongoDB database must have Role-Based Access Control (RBAC) enabled by + setting + [`security.authorization`](https://www.mongodb.com/docs/manual/reference/configuration-options/#mongodb-setting-security.authorization) + to `enabled` in the configuration file. - Ability to connect to and create user accounts in the target database. From f14c4c75aa081a7deaefb0d4f95456dbbd338b45 Mon Sep 17 00:00:00 2001 From: Zac Bergquist Date: Thu, 30 Jan 2025 11:01:56 -0700 Subject: [PATCH 22/28] Don't emit SSO failures to audit log for illegitimate requests (#51614) SSO flows are initiated via unauthenticated APIs, so it's not uncommon to see spam from security tools or malicious bots probing. If we can tell that these are not legitimate SSO attempts then we avoid emitting falures that clutter the audit log. --- lib/auth/auth_with_roles.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index 379467800318d..ba7b73c1a5e5a 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -4175,7 +4175,14 @@ func (a *ServerWithRoles) CreateGithubAuthRequest(ctx context.Context, req types githubReq, err := a.authServer.CreateGithubAuthRequest(ctx, req) if err != nil { - emitSSOLoginFailureEvent(a.authServer.closeCtx, a.authServer.emitter, events.LoginMethodGithub, err, req.SSOTestFlow) + if trace.IsNotFound(err) { + // This flow is triggered via an unauthenticated endpoint, so it's not unusual to see + // attempts to hit this API with an invalid connector ID. These are not legitimate SSO + // attempts, so avoid cluttering the audit log with them. + a.authServer.logger.InfoContext(ctx, "rejecting invalid GitHub auth request", "connector", req.ConnectorID) + } else { + emitSSOLoginFailureEvent(a.authServer.closeCtx, a.authServer.emitter, events.LoginMethodGithub, err, req.SSOTestFlow) + } return nil, trace.Wrap(err) } From c0b3e62f25301d17859ed05a4d34f5d34af6f75b Mon Sep 17 00:00:00 2001 From: Nic Klaassen Date: Thu, 30 Jan 2025 10:55:32 -0800 Subject: [PATCH 23/28] [vnet] refactor osconfig (#51577) * [vnet] refactor osconfig This PR refactors VNet's OS configuration code. There is now a `osConfigurator` struct that runs the OS configuration loop and calls out to a `targetOSConfigProvider` which determines the current target OS configuration. This `targetOSConfigProvider` can be implemented for the MacOS daemon process by moving some of the existing code around. In a following PR I will implement it for Windows which will call out to the user process to get the current target OS configuration. This PR doesn't really change any of the logic that runs on MacOS, it just refactors things so that we can swap in a different implementation for Windows. FYI, after I get the Windows code fully working, I plan to migrate the MacOS code to follow the new way Windows handles things, where the admin process handles all networking and calls out to the user process for everything that uses a Teleport client. This will unify multiple codepaths and eliminate the profileOSConfigProvider added here. * fix lint on linux * use ip-aware function to compute TUN address --- lib/vnet/admin_process_darwin.go | 57 +--- lib/vnet/osconfig.go | 262 ++++------------- lib/vnet/osconfig_darwin.go | 48 +--- lib/vnet/osconfig_windows.go | 31 +++ lib/vnet/profile_osconfig_provider_darwin.go | 278 +++++++++++++++++++ lib/vnet/unsupported_os.go | 19 ++ 6 files changed, 400 insertions(+), 295 deletions(-) create mode 100644 lib/vnet/osconfig_windows.go create mode 100644 lib/vnet/profile_osconfig_provider_darwin.go diff --git a/lib/vnet/admin_process_darwin.go b/lib/vnet/admin_process_darwin.go index f9ee788327842..b2aec9952f3d1 100644 --- a/lib/vnet/admin_process_darwin.go +++ b/lib/vnet/admin_process_darwin.go @@ -48,9 +48,15 @@ func RunDarwinAdminProcess(ctx context.Context, config daemon.Config) error { return trace.Wrap(err) } + osConfigProvider, err := newProfileOSConfigProvider(tunName, config.IPv6Prefix, config.DNSAddr, config.HomePath, config.ClientCred) + if err != nil { + return trace.Wrap(err, "creating profileOSConfigProvider") + } + osConfigurator := newOSConfigurator(osConfigProvider) + errCh := make(chan error) go func() { - errCh <- trace.Wrap(osConfigurationLoop(ctx, tunName, config.IPv6Prefix, config.DNSAddr, config.HomePath, config.ClientCred)) + errCh <- trace.Wrap(osConfigurator.runOSConfigurationLoop(ctx)) }() // Stay alive until we get an error on errCh, indicating that the osConfig loop exited. @@ -105,52 +111,3 @@ func createTUNDevice(ctx context.Context) (tun.Device, string, error) { } return dev, name, nil } - -// osConfigurationLoop will keep running until ctx is canceled or an unrecoverable error is encountered, in -// order to keep the host OS configuration up to date. -func osConfigurationLoop(ctx context.Context, tunName, ipv6Prefix, dnsAddr, homePath string, clientCred daemon.ClientCred) error { - osConfigurator, err := newOSConfigurator(tunName, ipv6Prefix, dnsAddr, homePath, clientCred) - if err != nil { - return trace.Wrap(err, "creating OS configurator") - } - defer func() { - if err := osConfigurator.close(); err != nil { - log.ErrorContext(ctx, "Error while closing OS configurator", "error", err) - } - }() - - // Clean up any stale configuration left by a previous VNet instance that may have failed to clean up. - // This is necessary in case any stale /etc/resolver/ entries are still present, we need to - // be able to reach the proxy in order to fetch the vnet_config. - if err := osConfigurator.deconfigureOS(ctx); err != nil { - return trace.Wrap(err, "cleaning up OS configuration on startup") - } - - defer func() { - // Shutting down, deconfigure OS. Pass context.Background because ctx has likely been canceled - // already but we still need to clean up. - if err := osConfigurator.deconfigureOS(context.Background()); err != nil { - log.ErrorContext(ctx, "Error deconfiguring host OS before shutting down.", "error", err) - } - }() - - if err := osConfigurator.updateOSConfiguration(ctx); err != nil { - return trace.Wrap(err, "applying initial OS configuration") - } - - // Re-configure the host OS every 10 seconds. This will pick up any newly logged-in clusters by - // reading profiles from TELEPORT_HOME. - const osConfigurationInterval = 10 * time.Second - ticker := time.NewTicker(osConfigurationInterval) - defer ticker.Stop() - for { - select { - case <-ticker.C: - if err := osConfigurator.updateOSConfiguration(ctx); err != nil { - return trace.Wrap(err, "updating OS configuration") - } - case <-ctx.Done(): - return ctx.Err() - } - } -} diff --git a/lib/vnet/osconfig.go b/lib/vnet/osconfig.go index 05ac1dcb3a688..1cbe009963ea9 100644 --- a/lib/vnet/osconfig.go +++ b/lib/vnet/osconfig.go @@ -14,25 +14,14 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -// TODO(nklaassen): refactor OS configuration so this file isn't -// platform-specific. -//go:build darwin -// +build darwin - package vnet import ( "context" - "net" + "net/netip" + "time" "github.com/gravitational/trace" - "github.com/jonboulle/clockwork" - - "github.com/gravitational/teleport/api/profile" - "github.com/gravitational/teleport/api/utils" - "github.com/gravitational/teleport/lib/client" - "github.com/gravitational/teleport/lib/client/clientcache" - "github.com/gravitational/teleport/lib/vnet/daemon" ) type osConfig struct { @@ -44,182 +33,33 @@ type osConfig struct { dnsZones []string } -type osConfigurator struct { - clientStore *client.Store - clientCache *clientcache.Cache - clusterConfigCache *ClusterConfigCache - // daemonClientCred are the credentials of the process that contacted the daemon. - daemonClientCred daemon.ClientCred - tunName string - tunIPv6 string - dnsAddr string - homePath string - tunIPv4 string +func configureOS(ctx context.Context, osConfig *osConfig) error { + return trace.Wrap(platformConfigureOS(ctx, osConfig)) } -func newOSConfigurator(tunName, ipv6Prefix, dnsAddr, homePath string, daemonClientCred daemon.ClientCred) (*osConfigurator, error) { - if homePath == "" { - // This runs as root so we need to be configured with the user's home path. - return nil, trace.BadParameter("homePath must be passed from unprivileged process") - } - - // ipv6Prefix always looks like "fdxx:xxxx:xxxx::" - // Set the IPv6 address for the TUN to "fdxx:xxxx:xxxx::1", the first valid address in the range. - tunIPv6 := ipv6Prefix + "1" - - configurator := &osConfigurator{ - tunName: tunName, - tunIPv6: tunIPv6, - dnsAddr: dnsAddr, - homePath: homePath, - clientStore: client.NewFSClientStore(homePath), - daemonClientCred: daemonClientCred, - } - configurator.clusterConfigCache = NewClusterConfigCache(clockwork.NewRealClock()) - - clientCache, err := clientcache.New(clientcache.Config{ - NewClientFunc: configurator.getClient, - RetryWithReloginFunc: func(ctx context.Context, tc *client.TeleportClient, fn func() error, opts ...client.RetryWithReloginOption) error { - // osConfigurator is ran from a root process, so there's no way for it to relogin. - // Instead, osConfigurator depends on the user performing a relogin from another process. - return trace.Wrap(fn()) - }, - }) - if err != nil { - return nil, trace.Wrap(err) - } - configurator.clientCache = clientCache - - return configurator, nil +type targetOSConfigProvider interface { + targetOSConfig(context.Context) (*osConfig, error) } -func (c *osConfigurator) close() error { - return trace.Wrap(c.clientCache.Clear()) +type osConfigurator struct { + targetOSConfigProvider targetOSConfigProvider } -// updateOSConfiguration reads tsh profiles out of [c.homePath]. For each profile, it reads the VNet -// config of the root cluster and of each leaf cluster. Then it proceeds to update the OS based on -// information from that config. -// -// For the duration of reading data from clusters, it drops the root privileges, only to regain them -// before configuring the OS. -func (c *osConfigurator) updateOSConfiguration(ctx context.Context) error { - var dnsZones []string - var cidrRanges []string - - // Drop privileges to ensure that the user who spawned the daemon client has privileges necessary - // to access c.homePath that it sent when starting the daemon. - // Otherwise a client could make the daemon read a profile out of any directory. - if err := c.doWithDroppedRootPrivileges(ctx, func() error { - profileNames, err := profile.ListProfileNames(c.homePath) - if err != nil { - return trace.Wrap(err, "listing user profiles") - } - for _, profileName := range profileNames { - profileDNSZones, profileCIDRRanges := c.getDNSZonesAndCIDRRangesForProfile(ctx, profileName) - dnsZones = append(dnsZones, profileDNSZones...) - cidrRanges = append(cidrRanges, profileCIDRRanges...) - } - return nil - }); err != nil { - return trace.Wrap(err) - } - - dnsZones = utils.Deduplicate(dnsZones) - cidrRanges = utils.Deduplicate(cidrRanges) - - if c.tunIPv4 == "" && len(cidrRanges) > 0 { - // Choose an IPv4 address for the TUN interface from the CIDR range of one arbitrary currently - // logged-in cluster. Only one IPv4 address is needed. - if err := c.setTunIPv4FromCIDR(cidrRanges[0]); err != nil { - return trace.Wrap(err, "setting TUN IPv4 address") - } +func newOSConfigurator(targetOSConfigProvider targetOSConfigProvider) *osConfigurator { + return &osConfigurator{ + targetOSConfigProvider: targetOSConfigProvider, } - - err := configureOS(ctx, &osConfig{ - tunName: c.tunName, - tunIPv6: c.tunIPv6, - tunIPv4: c.tunIPv4, - dnsAddr: c.dnsAddr, - dnsZones: dnsZones, - cidrRanges: cidrRanges, - }) - return trace.Wrap(err, "configuring OS") } -// getDNSZonesAndCIDRRangesForProfile returns DNS zones and CIDR ranges for the root cluster and its -// leaf clusters. -// -// It's important for this function to return any data it manages to collect. For example, if it -// manages to grab DNS zones and CIDR ranges of the root cluster but it fails to list leaf clusters, -// it should still return the zones and ranges of the root cluster. Hence the use of named return -// values. -func (c *osConfigurator) getDNSZonesAndCIDRRangesForProfile(ctx context.Context, profileName string) (dnsZones []string, cidrRanges []string) { - shouldClearCacheForRoot := true - defer func() { - if shouldClearCacheForRoot { - if err := c.clientCache.ClearForRoot(profileName); err != nil { - log.ErrorContext(ctx, "Error while clearing client cache", "profile", profileName, "error", err) - } - } - }() - - rootClient, err := c.clientCache.Get(ctx, profileName, "" /*leafClusterName*/) - if err != nil { - log.WarnContext(ctx, - "Failed to get root cluster client from cache, profile may be expired, not configuring VNet for this cluster", - "profile", profileName, "error", err) - - return - } - clusterConfig, err := c.clusterConfigCache.GetClusterConfig(ctx, rootClient) +func (c *osConfigurator) updateOSConfiguration(ctx context.Context) error { + desiredOSConfig, err := c.targetOSConfigProvider.targetOSConfig(ctx) if err != nil { - log.WarnContext(ctx, - "Failed to load VNet configuration, profile may be expired, not configuring VNet for this cluster", - "profile", profileName, "error", err) - - return + return trace.Wrap(err) } - - dnsZones = append(dnsZones, clusterConfig.DNSZones...) - cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) - - leafClusters, err := getLeafClusters(ctx, rootClient) - if err != nil { - log.WarnContext(ctx, - "Failed to list leaf clusters, profile may be expired, not configuring VNet for leaf clusters of this cluster", - "profile", profileName, "error", err) - - return + if err := configureOS(ctx, desiredOSConfig); err != nil { + return trace.Wrap(err, "configuring OS") } - - // getLeafClusters was the last call using the root client. Do not clear cache if any call to - // a leaf cluster fails – it might fail because of a problem with the leaf cluster, not because of - // an expired cert. - shouldClearCacheForRoot = false - - for _, leafClusterName := range leafClusters { - clusterClient, err := c.clientCache.Get(ctx, profileName, leafClusterName) - if err != nil { - log.WarnContext(ctx, - "Failed to create leaf cluster client, not configuring VNet for this cluster", - "profile", profileName, "leaf_cluster", leafClusterName, "error", err) - continue - } - - clusterConfig, err := c.clusterConfigCache.GetClusterConfig(ctx, clusterClient) - if err != nil { - log.WarnContext(ctx, - "Failed to load VNet configuration, not configuring VNet for this cluster", - "profile", profileName, "leaf_cluster", leafClusterName, "error", err) - continue - } - - dnsZones = append(dnsZones, clusterConfig.DNSZones...) - cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) - } - - return + return nil } func (c *osConfigurator) deconfigureOS(ctx context.Context) error { @@ -227,36 +67,56 @@ func (c *osConfigurator) deconfigureOS(ctx context.Context) error { return trace.Wrap(configureOS(ctx, &osConfig{})) } -func (c *osConfigurator) setTunIPv4FromCIDR(cidrRange string) error { - if c.tunIPv4 != "" { - return nil +// runOSConfigurationLoop will keep running until ctx is canceled or an +// unrecoverable error is encountered, in order to keep the host OS +// configuration up to date. +func (c *osConfigurator) runOSConfigurationLoop(ctx context.Context) error { + // Clean up any stale configuration left by a previous VNet instance that + // may have failed to clean up. This is necessary in case any stale DNS + // configuration is still present, we need to make sure the proxy is + // reachable without hitting the VNet DNS resolver which is not ready yet. + if err := c.deconfigureOS(ctx); err != nil { + return trace.Wrap(err, "cleaning up OS configuration on startup") } - _, ipnet, err := net.ParseCIDR(cidrRange) - if err != nil { - return trace.Wrap(err, "parsing CIDR %q", cidrRange) + if err := c.updateOSConfiguration(ctx); err != nil { + return trace.Wrap(err, "applying initial OS configuration") } - // ipnet.IP is the network address, ending in 0s, like 100.64.0.0 - // Add 1 to assign the TUN address, like 100.64.0.1 - tunAddress := ipnet.IP - tunAddress[len(tunAddress)-1]++ - c.tunIPv4 = tunAddress.String() - return nil -} + defer func() { + // Shutting down, deconfigure OS. Pass context.Background because ctx has likely been canceled + // already but we still need to clean up. + if err := c.deconfigureOS(context.Background()); err != nil { + log.ErrorContext(ctx, "Error deconfiguring host OS before shutting down.", "error", err) + } + }() -func (c *osConfigurator) getClient(ctx context.Context, profileName, leafClusterName string) (*client.TeleportClient, error) { - // This runs in the root process, so obviously we don't have access to the client cache in the user - // process. This loads cluster profiles and credentials from TELEPORT_HOME. - clientConfig := &client.Config{ - ClientStore: c.clientStore, + // Re-configure the host OS every 10 seconds to pick up any newly logged-in + // clusters or updated DNS zones or CIDR ranges. + const osConfigurationInterval = 10 * time.Second + tick := time.Tick(osConfigurationInterval) + for { + select { + case <-tick: + if err := c.updateOSConfiguration(ctx); err != nil { + return trace.Wrap(err, "updating OS configuration") + } + case <-ctx.Done(): + return trace.Wrap(ctx.Err(), "context canceled, shutting down os configuration loop") + } } - if err := clientConfig.LoadProfile(c.clientStore, profileName); err != nil { - return nil, trace.Wrap(err, "loading client profile") +} + +// tunIPv6ForPrefix returns the IPv6 address to assign to the TUN interface under +// ipv6Prefix. It always returns the second address in the range because the +// first address (ending with all zeros) is the subnet router anycast address. +func tunIPv6ForPrefix(ipv6Prefix string) (string, error) { + addr, err := netip.ParseAddr(ipv6Prefix) + if err != nil { + return "", trace.Wrap(err, "parsing IPv6 prefix %s", ipv6Prefix) } - if leafClusterName != "" { - clientConfig.SiteName = leafClusterName + if !addr.Is6() { + return "", trace.BadParameter("IPv6 prefix %s is not an IPv6 address", ipv6Prefix) } - tc, err := client.NewClient(clientConfig) - return tc, trace.Wrap(err) + return addr.Next().String(), nil } diff --git a/lib/vnet/osconfig_darwin.go b/lib/vnet/osconfig_darwin.go index 27864c80bb400..1fd257a7886c4 100644 --- a/lib/vnet/osconfig_darwin.go +++ b/lib/vnet/osconfig_darwin.go @@ -22,15 +22,14 @@ import ( "os" "os/exec" "path/filepath" - "sync/atomic" - "syscall" "github.com/gravitational/trace" ) -// configureOS configures the host OS according to [cfg]. It is safe to call repeatedly, and it is meant to be -// called with an empty [osConfig] to deconfigure anything necessary before exiting. -func configureOS(ctx context.Context, cfg *osConfig) error { +// platformConfigureOS configures the host OS according to cfg. It is safe to +// call repeatedly, and it is meant to be called with an empty osConfig to +// deconfigure anything necessary before exiting. +func platformConfigureOS(ctx context.Context, cfg *osConfig) error { // There is no need to remove IP addresses or routes, they will automatically be cleaned up when the // process exits and the TUN is deleted. @@ -141,42 +140,3 @@ func vnetManagedResolverFiles() (map[string]struct{}, error) { } return matchingFiles, nil } - -var hasDroppedPrivileges atomic.Bool - -// doWithDroppedRootPrivileges drops the privileges of the current process to those of the client -// process that called the VNet daemon. -func (c *osConfigurator) doWithDroppedRootPrivileges(ctx context.Context, fn func() error) (err error) { - if !hasDroppedPrivileges.CompareAndSwap(false, true) { - // At the moment of writing, the VNet daemon wasn't expected to do multiple things in parallel - // with dropped privileges. If you run into this error, consider if employing a mutex is going - // to be enough or if a more elaborate refactoring is required. - return trace.CompareFailed("privileges are being temporarily dropped already") - } - defer hasDroppedPrivileges.Store(false) - - rootEgid := os.Getegid() - rootEuid := os.Geteuid() - - log.InfoContext(ctx, "Temporarily dropping root privileges.", "egid", c.daemonClientCred.Egid, "euid", c.daemonClientCred.Euid) - - if err := syscall.Setegid(c.daemonClientCred.Egid); err != nil { - panic(trace.Wrap(err, "setting egid")) - } - if err := syscall.Seteuid(c.daemonClientCred.Euid); err != nil { - panic(trace.Wrap(err, "setting euid")) - } - - defer func() { - if err := syscall.Seteuid(rootEuid); err != nil { - panic(trace.Wrap(err, "reverting euid")) - } - if err := syscall.Setegid(rootEgid); err != nil { - panic(trace.Wrap(err, "reverting egid")) - } - - log.InfoContext(ctx, "Restored root privileges.", "egid", rootEgid, "euid", rootEuid) - }() - - return trace.Wrap(fn()) -} diff --git a/lib/vnet/osconfig_windows.go b/lib/vnet/osconfig_windows.go new file mode 100644 index 0000000000000..aa47ec43804bb --- /dev/null +++ b/lib/vnet/osconfig_windows.go @@ -0,0 +1,31 @@ +// Teleport +// Copyright (C) 2025 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 vnet + +import ( + "context" + + "github.com/gravitational/trace" +) + +// platformConfigureOS configures the host OS according to cfg. It is safe to +// call repeatedly, and it is meant to be called with an empty osConfig to +// deconfigure anything necessary before exiting. +func platformConfigureOS(ctx context.Context, cfg *osConfig) error { + // TODO(nklaassen): implement platformConfigureOS for Windows. + return trace.NotImplemented("platformConfigureOS is not implemented on Windows") +} diff --git a/lib/vnet/profile_osconfig_provider_darwin.go b/lib/vnet/profile_osconfig_provider_darwin.go new file mode 100644 index 0000000000000..8aea54d0175fd --- /dev/null +++ b/lib/vnet/profile_osconfig_provider_darwin.go @@ -0,0 +1,278 @@ +// Teleport +// Copyright (C) 2025 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 vnet + +import ( + "context" + "net" + "os" + "sync/atomic" + "syscall" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + + "github.com/gravitational/teleport/api/profile" + "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/client/clientcache" + "github.com/gravitational/teleport/lib/vnet/daemon" +) + +// profileOSConfigProvider implements targetOSConfigProvider for the MacOS +// daemon process. It reads all active profiles from the user's TELEPORT_HOME +// and uses the user certs found there to dial to each cluster to find the +// current vnet_config resource to compute the current target OS configuration. +type profileOSConfigProvider struct { + clientStore *client.Store + clientCache *clientcache.Cache + clusterConfigCache *ClusterConfigCache + // daemonClientCred are the credentials of the process that contacted the daemon. + daemonClientCred daemon.ClientCred + tunName string + tunIPv6 string + dnsAddr string + homePath string + tunIPv4 string +} + +func newProfileOSConfigProvider(tunName, ipv6Prefix, dnsAddr, homePath string, daemonClientCred daemon.ClientCred) (*profileOSConfigProvider, error) { + if homePath == "" { + // This runs as root so we need to be configured with the user's home path. + return nil, trace.BadParameter("homePath must be passed from unprivileged process") + } + tunIP, err := tunIPv6ForPrefix(ipv6Prefix) + if err != nil { + return nil, trace.Wrap(err) + } + + p := &profileOSConfigProvider{ + clientStore: client.NewFSClientStore(homePath), + clusterConfigCache: NewClusterConfigCache(clockwork.NewRealClock()), + daemonClientCred: daemonClientCred, + tunName: tunName, + tunIPv6: tunIP, + dnsAddr: dnsAddr, + homePath: homePath, + } + clientCache, err := clientcache.New(clientcache.Config{ + NewClientFunc: p.getClient, + RetryWithReloginFunc: func(ctx context.Context, tc *client.TeleportClient, fn func() error, opts ...client.RetryWithReloginOption) error { + // profileOSConfigProvider runs in the MacOS daemon process, there's no way for it to relogin. + // Instead, osConfigurator depends on the user performing a relogin from another process. + return trace.Wrap(fn()) + }, + }) + if err != nil { + return nil, trace.Wrap(err) + } + p.clientCache = clientCache + return p, nil +} + +func (p *profileOSConfigProvider) targetOSConfig(ctx context.Context) (*osConfig, error) { + var ( + dnsZones []string + cidrRanges []string + ) + + // Drop privileges to ensure that the user who spawned the daemon client has privileges necessary + // to access p.homePath that it sent when starting the daemon. + // Otherwise a client could make the daemon read a profile out of any directory. + if err := doWithDroppedRootPrivileges(ctx, p.daemonClientCred, func() error { + profileNames, err := profile.ListProfileNames(p.homePath) + if err != nil { + return trace.Wrap(err, "listing user profiles") + } + for _, profileName := range profileNames { + profileDNSZones, profileCIDRRanges := p.getDNSZonesAndCIDRRangesForProfile(ctx, profileName) + dnsZones = append(dnsZones, profileDNSZones...) + cidrRanges = append(cidrRanges, profileCIDRRanges...) + } + return nil + }); err != nil { + return nil, trace.Wrap(err) + } + + dnsZones = utils.Deduplicate(dnsZones) + cidrRanges = utils.Deduplicate(cidrRanges) + + if p.tunIPv4 == "" && len(cidrRanges) > 0 { + // Choose an IPv4 address for the TUN interface from the CIDR range of one arbitrary currently + // logged-in cluster. Only one IPv4 address is needed. + if err := p.setTunIPv4FromCIDR(cidrRanges[0]); err != nil { + return nil, trace.Wrap(err, "setting TUN IPv4 address") + } + } + + return &osConfig{ + tunName: p.tunName, + tunIPv6: p.tunIPv6, + tunIPv4: p.tunIPv4, + dnsAddr: p.dnsAddr, + dnsZones: dnsZones, + cidrRanges: cidrRanges, + }, nil +} + +// getDNSZonesAndCIDRRangesForProfile returns DNS zones and CIDR ranges for the root cluster and its +// leaf clusters. +// +// It's important for this function to return any data it manages to collect. For example, if it +// manages to grab DNS zones and CIDR ranges of the root cluster but it fails to list leaf clusters, +// it should still return the zones and ranges of the root cluster. Hence the use of named return +// values. +func (p *profileOSConfigProvider) getDNSZonesAndCIDRRangesForProfile(ctx context.Context, profileName string) (dnsZones []string, cidrRanges []string) { + shouldClearCacheForRoot := true + defer func() { + if shouldClearCacheForRoot { + if err := p.clientCache.ClearForRoot(profileName); err != nil { + log.ErrorContext(ctx, "Error while clearing client cache", "profile", profileName, "error", err) + } + } + }() + + rootClient, err := p.clientCache.Get(ctx, profileName, "" /*leafClusterName*/) + if err != nil { + log.WarnContext(ctx, + "Failed to get root cluster client from cache, profile may be expired, not configuring VNet for this cluster", + "profile", profileName, "error", err) + + return + } + clusterConfig, err := p.clusterConfigCache.GetClusterConfig(ctx, rootClient) + if err != nil { + log.WarnContext(ctx, + "Failed to load VNet configuration, profile may be expired, not configuring VNet for this cluster", + "profile", profileName, "error", err) + + return + } + + dnsZones = append(dnsZones, clusterConfig.DNSZones...) + cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) + + leafClusters, err := getLeafClusters(ctx, rootClient) + if err != nil { + log.WarnContext(ctx, + "Failed to list leaf clusters, profile may be expired, not configuring VNet for leaf clusters of this cluster", + "profile", profileName, "error", err) + + return + } + + // getLeafClusters was the last call using the root client. Do not clear cache if any call to + // a leaf cluster fails – it might fail because of a problem with the leaf cluster, not because of + // an expired cert. + shouldClearCacheForRoot = false + + for _, leafClusterName := range leafClusters { + clusterClient, err := p.clientCache.Get(ctx, profileName, leafClusterName) + if err != nil { + log.WarnContext(ctx, + "Failed to create leaf cluster client, not configuring VNet for this cluster", + "profile", profileName, "leaf_cluster", leafClusterName, "error", err) + continue + } + + clusterConfig, err := p.clusterConfigCache.GetClusterConfig(ctx, clusterClient) + if err != nil { + log.WarnContext(ctx, + "Failed to load VNet configuration, not configuring VNet for this cluster", + "profile", profileName, "leaf_cluster", leafClusterName, "error", err) + continue + } + + dnsZones = append(dnsZones, clusterConfig.DNSZones...) + cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) + } + + return +} + +func (p *profileOSConfigProvider) setTunIPv4FromCIDR(cidrRange string) error { + if p.tunIPv4 != "" { + return nil + } + + _, ipnet, err := net.ParseCIDR(cidrRange) + if err != nil { + return trace.Wrap(err, "parsing CIDR %q", cidrRange) + } + + // ipnet.IP is the network address, ending in 0s, like 100.64.0.0 + // Add 1 to assign the TUN address, like 100.64.0.1 + tunAddress := ipnet.IP + tunAddress[len(tunAddress)-1]++ + p.tunIPv4 = tunAddress.String() + return nil +} + +func (p *profileOSConfigProvider) getClient(ctx context.Context, profileName, leafClusterName string) (*client.TeleportClient, error) { + // This runs in the root process, so obviously we don't have access to the client cache in the user + // process. This loads cluster profiles and credentials from TELEPORT_HOME. + clientConfig := &client.Config{ + ClientStore: p.clientStore, + } + if err := clientConfig.LoadProfile(p.clientStore, profileName); err != nil { + return nil, trace.Wrap(err, "loading client profile") + } + if leafClusterName != "" { + clientConfig.SiteName = leafClusterName + } + tc, err := client.NewClient(clientConfig) + return tc, trace.Wrap(err) +} + +var hasDroppedPrivileges atomic.Bool + +// doWithDroppedRootPrivileges drops the privileges of the current process to those of the client +// process that called the VNet daemon. +func doWithDroppedRootPrivileges(ctx context.Context, clientCred daemon.ClientCred, fn func() error) (err error) { + if !hasDroppedPrivileges.CompareAndSwap(false, true) { + // At the moment of writing, the VNet daemon wasn't expected to do multiple things in parallel + // with dropped privileges. If you run into this error, consider if employing a mutex is going + // to be enough or if a more elaborate refactoring is required. + return trace.CompareFailed("privileges are being temporarily dropped already") + } + defer hasDroppedPrivileges.Store(false) + + rootEgid := os.Getegid() + rootEuid := os.Geteuid() + + log.InfoContext(ctx, "Temporarily dropping root privileges.", "egid", clientCred.Egid, "euid", clientCred.Euid) + + if err := syscall.Setegid(clientCred.Egid); err != nil { + panic(trace.Wrap(err, "setting egid")) + } + if err := syscall.Seteuid(clientCred.Euid); err != nil { + panic(trace.Wrap(err, "setting euid")) + } + + defer func() { + if err := syscall.Seteuid(rootEuid); err != nil { + panic(trace.Wrap(err, "reverting euid")) + } + if err := syscall.Setegid(rootEgid); err != nil { + panic(trace.Wrap(err, "reverting egid")) + } + + log.InfoContext(ctx, "Restored root privileges.", "egid", rootEgid, "euid", rootEuid) + }() + + return trace.Wrap(fn()) +} diff --git a/lib/vnet/unsupported_os.go b/lib/vnet/unsupported_os.go index a807101f88801..1b65e366ee44c 100644 --- a/lib/vnet/unsupported_os.go +++ b/lib/vnet/unsupported_os.go @@ -32,3 +32,22 @@ var ErrVnetNotImplemented = &trace.NotImplementedError{Message: "VNet is not imp func runPlatformUserProcess(_ context.Context, _ *UserProcessConfig) (*ProcessManager, error) { return nil, trace.Wrap(ErrVnetNotImplemented) } + +func platformConfigureOS(_ context.Context, _ *osConfig) error { + return trace.Wrap(ErrVnetNotImplemented) +} + +// Satisfy unused linter. +var ( + _ = osConfig{ + tunName: "", + tunIPv4: "", + tunIPv6: "", + dnsAddr: "", + cidrRanges: nil, + dnsZones: nil, + } + _ = tunIPv6ForPrefix + _ = newOSConfigurator + _ = (*osConfigurator).runOSConfigurationLoop +) From e3c36a0dbf9db39667bbec076fc9a2d74a321d37 Mon Sep 17 00:00:00 2001 From: Vadym Popov Date: Thu, 30 Jan 2025 12:07:49 -0800 Subject: [PATCH 24/28] Remove timeout for TestUpdate (#51666) --- integration/autoupdate/tools/updater_test.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/integration/autoupdate/tools/updater_test.go b/integration/autoupdate/tools/updater_test.go index a64ec9a1f9d0f..0c05f2524caf0 100644 --- a/integration/autoupdate/tools/updater_test.go +++ b/integration/autoupdate/tools/updater_test.go @@ -46,8 +46,7 @@ var ( // an update to a newer version, expecting it to re-execute with the updated version. func TestUpdate(t *testing.T) { t.Setenv(types.HomeEnvVar, t.TempDir()) - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() + ctx := context.Background() // Fetch compiled test binary with updater logic and install to $TELEPORT_HOME. updater := tools.NewUpdater( @@ -88,8 +87,7 @@ func TestUpdate(t *testing.T) { // the command with the updated version without any new downloads. func TestParallelUpdate(t *testing.T) { t.Setenv(types.HomeEnvVar, t.TempDir()) - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() + ctx := context.Background() // Initial fetch the updater binary un-archive and replace. updater := tools.NewUpdater( @@ -162,8 +160,7 @@ func TestParallelUpdate(t *testing.T) { // TestUpdateInterruptSignal verifies the interrupt signal send to the process must stop downloading. func TestUpdateInterruptSignal(t *testing.T) { t.Setenv(types.HomeEnvVar, t.TempDir()) - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() + ctx := context.Background() // Initial fetch the updater binary un-archive and replace. updater := tools.NewUpdater( From b69d49b2a223dd1833bdd0861831c87dc77dc66f Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Thu, 30 Jan 2025 12:14:45 -0800 Subject: [PATCH 25/28] Simplify lib/utils/aws (#51627) This eliminates the SigningService in favor of a free function SignRequest, which eliminates AWS credential loading and simplifies the AWS utils package. In the process of doing this refactor, the AWS app handler has been changed to use AWS SDK v2 to load its credentials as well. --- integration/proxy/proxy_helpers.go | 8 +- integration/proxy/proxy_test.go | 4 +- lib/cloud/awsconfig/awsconfig.go | 65 ++++++++- lib/cloud/awsconfig/awsconfig_test.go | 4 +- lib/service/service.go | 13 ++ lib/srv/alpnproxy/aws_local_proxy.go | 4 +- lib/srv/app/aws/handler.go | 30 ++-- lib/srv/app/aws/handler_test.go | 74 +++++----- lib/srv/app/connections_handler.go | 18 +-- lib/srv/app/server_test.go | 2 + lib/srv/db/dynamodb/engine.go | 47 ++++--- lib/srv/db/dynamodb/test.go | 2 +- lib/srv/db/opensearch/engine.go | 49 +++---- lib/utils/aws/aws.go | 11 +- lib/utils/aws/credentials.go | 172 ----------------------- lib/utils/aws/credentials_test.go | 189 -------------------------- lib/utils/aws/signing.go | 140 ++----------------- 17 files changed, 219 insertions(+), 613 deletions(-) delete mode 100644 lib/utils/aws/credentials_test.go diff --git a/integration/proxy/proxy_helpers.go b/integration/proxy/proxy_helpers.go index 3ce8a4f17657e..f41a6f4513b4e 100644 --- a/integration/proxy/proxy_helpers.go +++ b/integration/proxy/proxy_helpers.go @@ -33,7 +33,7 @@ import ( "testing" "time" - "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jackc/pgconn" @@ -605,7 +605,7 @@ func mustParseURL(t *testing.T, rawURL string) *url.URL { type fakeSTSClient struct { accountID string arn string - credentials *credentials.Credentials + credentials aws.CredentialsProvider } func (f fakeSTSClient) Do(req *http.Request) (*http.Response, error) { @@ -640,10 +640,10 @@ func mustCreateIAMJoinProvisionToken(t *testing.T, name, awsAccountID, allowedAR return provisionToken } -func mustRegisterUsingIAMMethod(t *testing.T, proxyAddr utils.NetAddr, token string, credentials *credentials.Credentials) { +func mustRegisterUsingIAMMethod(t *testing.T, proxyAddr utils.NetAddr, token string, credentials aws.CredentialsProvider) { t.Helper() - cred, err := credentials.Get() + cred, err := credentials.Retrieve(context.Background()) require.NoError(t, err) t.Setenv("AWS_ACCESS_KEY_ID", cred.AccessKeyID) diff --git a/integration/proxy/proxy_test.go b/integration/proxy/proxy_test.go index 262b8c1046726..b230a04c0e549 100644 --- a/integration/proxy/proxy_test.go +++ b/integration/proxy/proxy_test.go @@ -31,7 +31,7 @@ import ( "testing" "time" - "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go-v2/credentials" "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" @@ -1739,7 +1739,7 @@ func TestALPNSNIProxyGRPCInsecure(t *testing.T) { nodeAccount := "123456789012" nodeRoleARN := "arn:aws:iam::123456789012:role/test" - nodeCredentials := credentials.NewStaticCredentials("FAKE_ID", "FAKE_KEY", "FAKE_TOKEN") + nodeCredentials := credentials.NewStaticCredentialsProvider("FAKE_ID", "FAKE_KEY", "FAKE_TOKEN") provisionToken := mustCreateIAMJoinProvisionToken(t, "iam-join-token", nodeAccount, nodeRoleARN) suite := newSuite(t, diff --git a/lib/cloud/awsconfig/awsconfig.go b/lib/cloud/awsconfig/awsconfig.go index 245fe8a9a6b23..5e6967d2d4909 100644 --- a/lib/cloud/awsconfig/awsconfig.go +++ b/lib/cloud/awsconfig/awsconfig.go @@ -18,12 +18,16 @@ package awsconfig import ( "context" + "crypto/sha1" + "encoding/hex" + "fmt" "log/slog" "github.com/aws/aws-sdk-go-v2/aws" "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" + ststypes "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/tracing/smithyoteltracing" "github.com/gravitational/trace" "go.opentelemetry.io/otel" @@ -69,7 +73,12 @@ type AssumeRole struct { // RoleARN is the ARN of the role to assume. RoleARN string `json:"role_arn"` // ExternalID is an optional ID to include when assuming the role. - ExternalID string `json:"external_id"` + ExternalID string `json:"external_id,omitempty"` + // SessionName is an optional session name to use when assuming the role. + SessionName string `json:"session_name,omitempty"` + // Tags is a list of STS session tags to pass when assuming the role. + // https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + Tags map[string]string `json:"tags,omitempty"` } // options is a struct of additional options for assuming an AWS role @@ -153,6 +162,18 @@ func WithAssumeRole(roleARN, externalID string) OptionsFn { } } +// WithDetailedAssumeRole configures options needed for assuming an AWS role, +// including optional details like session name, duration, and tags. +func WithDetailedAssumeRole(ar AssumeRole) OptionsFn { + return func(options *options) { + if ar.RoleARN == "" { + // ignore empty role ARN for caller convenience. + return + } + options.assumeRoles = append(options.assumeRoles, ar) + } +} + // WithRetryer sets a custom retryer for the config. func WithRetryer(retryer func() aws.Retryer) OptionsFn { return func(options *options) { @@ -302,6 +323,13 @@ func getAssumeRoleProvider(ctx context.Context, clt stscreds.AssumeRoleAPIClient if role.ExternalID != "" { aro.ExternalID = aws.String(role.ExternalID) } + aro.RoleSessionName = maybeHashRoleSessionName(role.SessionName) + for k, v := range role.Tags { + aro.Tags = append(aro.Tags, ststypes.Tag{ + Key: aws.String(k), + Value: aws.String(v), + }) + } }) } @@ -342,3 +370,38 @@ func (p *integrationCredentialsProvider) Retrieve(ctx context.Context) (aws.Cred ).Retrieve(ctx) return cred, trace.Wrap(err) } + +// maybeHashRoleSessionName truncates the role session name and adds a hash +// when the original role session name is greater than AWS character limit +// (64). +func maybeHashRoleSessionName(roleSessionName string) (ret string) { + // maxRoleSessionNameLength is the maximum length of the role session name + // used by the AssumeRole call. + // https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html + const maxRoleSessionNameLength = 64 + if len(roleSessionName) <= maxRoleSessionNameLength { + return roleSessionName + } + + const hashLen = 16 + hash := sha1.New() + hash.Write([]byte(roleSessionName)) + hex := hex.EncodeToString(hash.Sum(nil))[:hashLen] + + // "1" for the delimiter. + keepPrefixIndex := maxRoleSessionNameLength - len(hex) - 1 + + // Sanity check. This should never happen since hash length and + // MaxRoleSessionNameLength are both constant. + if keepPrefixIndex < 0 { + keepPrefixIndex = 0 + } + + ret = fmt.Sprintf("%s-%s", roleSessionName[:keepPrefixIndex], hex) + slog.DebugContext(context.Background(), + "AWS role session name is too long. Using a hash instead.", + "hashed", ret, + "original", roleSessionName, + ) + return ret +} diff --git a/lib/cloud/awsconfig/awsconfig_test.go b/lib/cloud/awsconfig/awsconfig_test.go index 2de624fe86c54..ca6d5a1576976 100644 --- a/lib/cloud/awsconfig/awsconfig_test.go +++ b/lib/cloud/awsconfig/awsconfig_test.go @@ -251,12 +251,12 @@ func testGetConfigIntegration(t *testing.T, provider Provider) { func TestNewCacheKey(t *testing.T) { roleChain := []AssumeRole{ {RoleARN: "roleA"}, - {RoleARN: "roleB", ExternalID: "abc123"}, + {RoleARN: "roleB", ExternalID: "abc123", SessionName: "alice", Tags: map[string]string{"AKey": "AValue"}}, } got, err := newCacheKey("integration-name", roleChain...) require.NoError(t, err) want := strings.TrimSpace(` -{"integration":"integration-name","role_chain":[{"role_arn":"roleA","external_id":""},{"role_arn":"roleB","external_id":"abc123"}]} +{"integration":"integration-name","role_chain":[{"role_arn":"roleA"},{"role_arn":"roleB","external_id":"abc123","session_name":"alice","tags":{"AKey":"AValue"}}]} `) require.Equal(t, want, got) } diff --git a/lib/service/service.go b/lib/service/service.go index 7003d108b9843..4d43026364c50 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -112,6 +112,7 @@ import ( pgrepl "github.com/gravitational/teleport/lib/client/db/postgres/repl" dbrepl "github.com/gravitational/teleport/lib/client/db/repl" "github.com/gravitational/teleport/lib/cloud" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/cloud/gcp" "github.com/gravitational/teleport/lib/cloud/imds" awsimds "github.com/gravitational/teleport/lib/cloud/imds/aws" @@ -4889,6 +4890,12 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { return awsoidc.NewSessionV1(ctx, conn.Client, region, integration) } + awsConfigProvider, err := awsconfig.NewCache(awsconfig.WithDefaults( + awsconfig.WithOIDCIntegrationClient(conn.Client), + )) + if err != nil { + return trace.Wrap(err, "unable to create AWS config provider cache") + } connectionsHandler, err := app.NewConnectionsHandler(process.GracefulExitContext(), &app.ConnectionsHandlerConfig{ Clock: process.Clock, @@ -4903,6 +4910,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { CipherSuites: cfg.CipherSuites, ServiceComponent: teleport.ComponentWebProxy, AWSSessionProvider: awsSessionGetter, + AWSConfigProvider: awsConfigProvider, }) if err != nil { return trace.Wrap(err) @@ -6218,6 +6226,10 @@ func (process *TeleportProcess) initApps() { return trace.Wrap(err) } + awsConfigProvider, err := awsconfig.NewCache() + if err != nil { + return trace.Wrap(err, "unable to create AWS config provider cache") + } connectionsHandler, err := app.NewConnectionsHandler(process.ExitContext(), &app.ConnectionsHandlerConfig{ Clock: process.Config.Clock, DataDir: process.Config.DataDir, @@ -6232,6 +6244,7 @@ func (process *TeleportProcess) initApps() { ServiceComponent: teleport.ComponentApp, Logger: logger, AWSSessionProvider: awsutils.SessionProviderUsingAmbientCredentials(), + AWSConfigProvider: awsConfigProvider, }) if err != nil { return trace.Wrap(err) diff --git a/lib/srv/alpnproxy/aws_local_proxy.go b/lib/srv/alpnproxy/aws_local_proxy.go index 77980930b2f37..2498058e927d1 100644 --- a/lib/srv/alpnproxy/aws_local_proxy.go +++ b/lib/srv/alpnproxy/aws_local_proxy.go @@ -134,7 +134,7 @@ func (m *AWSAccessMiddleware) HandleRequest(rw http.ResponseWriter, req *http.Re } func (m *AWSAccessMiddleware) handleCommonRequest(rw http.ResponseWriter, req *http.Request) bool { - if err := awsutils.VerifyAWSSignatureV2(req, m.AWSCredentialsProvider); err != nil { + if err := awsutils.VerifyAWSSignature(req, m.AWSCredentialsProvider); err != nil { m.Log.ErrorContext(req.Context(), "AWS signature verification failed", "error", err) rw.WriteHeader(http.StatusForbidden) return true @@ -149,7 +149,7 @@ func (m *AWSAccessMiddleware) handleRequestByAssumedRole(rw http.ResponseWriter, aws.ToString(assumedRole.Credentials.SessionToken), ) - if err := awsutils.VerifyAWSSignatureV2(req, credentials); err != nil { + if err := awsutils.VerifyAWSSignature(req, credentials); err != nil { m.Log.ErrorContext(req.Context(), "AWS signature verification failed", "error", err) rw.WriteHeader(http.StatusForbidden) return true diff --git a/lib/srv/app/aws/handler.go b/lib/srv/app/aws/handler.go index 8bd04ea356e89..f7d95e0badf74 100644 --- a/lib/srv/app/aws/handler.go +++ b/lib/srv/app/aws/handler.go @@ -33,6 +33,7 @@ import ( "github.com/jonboulle/clockwork" "github.com/gravitational/teleport" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/httplib" "github.com/gravitational/teleport/lib/httplib/reverseproxy" @@ -53,12 +54,12 @@ type signerHandler struct { // SignerHandlerConfig is the awsSignerHandler configuration. type SignerHandlerConfig struct { + // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. + AWSConfigProvider awsconfig.Provider // Log is a logger for the handler. Log *slog.Logger // RoundTripper is an http.RoundTripper instance used for requests. RoundTripper http.RoundTripper - // SigningService is used to sign requests before forwarding them. - *awsutils.SigningService // Clock is used to override time in tests. Clock clockwork.Clock // MaxHTTPRequestBodySize is the limit on how big a request body can be. @@ -67,8 +68,8 @@ type SignerHandlerConfig struct { // CheckAndSetDefaults validates the AwsSignerHandlerConfig. func (cfg *SignerHandlerConfig) CheckAndSetDefaults() error { - if cfg.SigningService == nil { - return trace.BadParameter("missing SigningService") + if cfg.AWSConfigProvider == nil { + return trace.BadParameter("aws config provider missing") } if cfg.RoundTripper == nil { tr, err := defaults.Transport() @@ -165,15 +166,24 @@ func (s *signerHandler) serveCommonRequest(sessCtx *common.SessionContext, w htt return trace.Wrap(err) } - signedReq, err := s.SignRequest(s.closeContext, unsignedReq, + awsCfg, err := s.AWSConfigProvider.GetConfig(s.closeContext, re.SigningRegion, + awsconfig.WithDetailedAssumeRole(awsconfig.AssumeRole{ + RoleARN: sessCtx.Identity.RouteToApp.AWSRoleARN, + ExternalID: sessCtx.App.GetAWSExternalID(), + SessionName: sessCtx.Identity.Username, + }), + awsconfig.WithCredentialsMaybeIntegration(sessCtx.App.GetIntegration()), + ) + if err != nil { + return trace.Wrap(err) + } + + signedReq, err := awsutils.SignRequest(s.closeContext, unsignedReq, &awsutils.SigningCtx{ + Clock: s.Clock, + Credentials: awsCfg.Credentials, SigningName: re.SigningName, SigningRegion: re.SigningRegion, - Expiry: sessCtx.Identity.Expires, - SessionName: sessCtx.Identity.Username, - AWSRoleArn: sessCtx.Identity.RouteToApp.AWSRoleARN, - AWSExternalID: sessCtx.App.GetAWSExternalID(), - Integration: sessCtx.App.GetIntegration(), }) if err != nil { return trace.Wrap(err) diff --git a/lib/srv/app/aws/handler_test.go b/lib/srv/app/aws/handler_test.go index 90dbd4ed46d21..4f19b9fb18a95 100644 --- a/lib/srv/app/aws/handler_test.go +++ b/lib/srv/app/aws/handler_test.go @@ -31,6 +31,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/awserr" "github.com/aws/aws-sdk-go/aws/client" @@ -50,6 +51,8 @@ import ( "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/events" + "github.com/gravitational/teleport/lib/cloud/awsconfig" + "github.com/gravitational/teleport/lib/cloud/mocks" libevents "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/events/eventstest" "github.com/gravitational/teleport/lib/srv/app/common" @@ -191,12 +194,19 @@ func TestAWSSignerHandler(t *testing.T) { }) require.NoError(t, err) + awsOIDCIntegration, err := types.NewIntegrationAWSOIDC( + types.Metadata{Name: "my-integration"}, + &types.AWSOIDCIntegrationSpecV1{ + RoleARN: "arn:aws:sts::123456789012:role/TestRole", + }, + ) + require.NoError(t, err) consoleAppWithIntegration, err := types.NewAppV3(types.Metadata{ Name: "awsconsole", }, types.AppSpecV3{ URI: constants.AWSConsoleURL, PublicAddr: "test.local", - Integration: "my-integration", + Integration: awsOIDCIntegration.GetName(), }) require.NoError(t, err) @@ -204,7 +214,7 @@ func TestAWSSignerHandler(t *testing.T) { name string app types.Application awsClientSession *session.Session - awsSessionProvider awsutils.AWSSessionProvider + awsConfigProvider awsconfig.Provider request makeRequest advanceClock time.Duration wantHost string @@ -226,7 +236,7 @@ func TestAWSSignerHandler(t *testing.T) { })), request: s3Request, wantHost: "s3.us-west-2.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "s3", wantAuthCredRegion: "us-west-2", wantEventType: &events.AppSessionRequest{}, @@ -242,14 +252,14 @@ func TestAWSSignerHandler(t *testing.T) { Region: aws.String("us-west-2"), })), request: s3Request, - awsSessionProvider: func(ctx context.Context, region, integration string) (*session.Session, error) { - if integration != "my-integration" { - return nil, trace.BadParameter("") - } - return nil, nil + awsConfigProvider: &mocks.AWSConfigProvider{ + OIDCIntegrationClient: &mocks.FakeOIDCIntegrationClient{ + Integration: awsOIDCIntegration, + Token: "fake-oidc-token", + }, }, wantHost: "s3.us-west-2.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "s3", wantAuthCredRegion: "us-west-2", wantEventType: &events.AppSessionRequest{}, @@ -266,7 +276,7 @@ func TestAWSSignerHandler(t *testing.T) { })), request: s3Request, wantHost: "s3.us-west-1.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "s3", wantAuthCredRegion: "us-west-1", wantEventType: &events.AppSessionRequest{}, @@ -314,7 +324,7 @@ func TestAWSSignerHandler(t *testing.T) { })), request: dynamoRequest, wantHost: "dynamodb.us-east-1.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "dynamodb", wantAuthCredRegion: "us-east-1", wantEventType: &events.AppSessionDynamoDBRequest{}, @@ -331,7 +341,7 @@ func TestAWSSignerHandler(t *testing.T) { })), request: dynamoRequest, wantHost: "dynamodb.us-west-1.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "dynamodb", wantAuthCredRegion: "us-west-1", wantEventType: &events.AppSessionDynamoDBRequest{}, @@ -379,7 +389,7 @@ func TestAWSSignerHandler(t *testing.T) { })), request: lambdaRequest, wantHost: "lambda.us-east-1.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "lambda", wantAuthCredRegion: "us-east-1", wantEventType: &events.AppSessionRequest{}, @@ -411,7 +421,7 @@ func TestAWSSignerHandler(t *testing.T) { request: assumeRoleRequest(2 * time.Hour), advanceClock: 10 * time.Minute, wantHost: "sts.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "sts", wantAuthCredRegion: "us-east-1", wantEventType: &events.AppSessionRequest{}, @@ -429,7 +439,7 @@ func TestAWSSignerHandler(t *testing.T) { })), request: assumeRoleRequest(32 * time.Minute), wantHost: "sts.amazonaws.com", - wantAuthCredKeyID: "AKIDl", + wantAuthCredKeyID: "FAKEACCESSKEYID", wantAuthCredService: "sts", wantAuthCredRegion: "us-east-1", wantEventType: &events.AppSessionRequest{}, @@ -445,14 +455,10 @@ func TestAWSSignerHandler(t *testing.T) { Credentials: staticAWSCredentialsForClient, Region: aws.String("us-east-1"), })), - request: assumeRoleRequest(2 * time.Hour), - advanceClock: 50 * time.Minute, // identity is expiring in 10m which is less than minimum - wantHost: "sts.amazonaws.com", - wantAuthCredKeyID: "AKIDl", - wantAuthCredService: "sts", - wantAuthCredRegion: "us-east-1", - wantEventType: &events.AppSessionRequest{}, + request: assumeRoleRequest(2 * time.Hour), + advanceClock: 50 * time.Minute, // identity is expiring in 10m which is less than minimum errAssertionFns: []require.ErrorAssertionFunc{ + // the request is 403 forbidden by Teleport, so the mock AWS handler won't be sent anything. hasStatusCode(http.StatusForbidden), }, }, @@ -476,7 +482,9 @@ func TestAWSSignerHandler(t *testing.T) { // check that the signature is valid. if !tc.skipVerifySignature { - err = awsutils.VerifyAWSSignature(r, staticAWSCredentials) + err := awsutils.VerifyAWSSignature(r, + credentialsv2.NewStaticCredentialsProvider(tc.wantAuthCredKeyID, "secret", "token"), + ) if !assert.NoError(t, err) { http.Error(w, err.Error(), trace.ErrorToCode(err)) return @@ -490,12 +498,12 @@ func TestAWSSignerHandler(t *testing.T) { w.WriteHeader(http.StatusOK) } - sessionProvider := awsutils.SessionProviderUsingAmbientCredentials() - if tc.awsSessionProvider != nil { - sessionProvider = tc.awsSessionProvider + awsCfgProvider := tc.awsConfigProvider + if awsCfgProvider == nil { + awsCfgProvider = &mocks.AWSConfigProvider{} } - suite := createSuite(t, mockAwsHandler, tc.app, fakeClock, sessionProvider) + suite := createSuite(t, mockAwsHandler, tc.app, fakeClock, awsCfgProvider) fakeClock.Advance(tc.advanceClock) err := tc.request(suite.URL, tc.awsClientSession, tc.wantHost) @@ -603,7 +611,6 @@ const assumedRoleKeyID = "assumedRoleKeyID" var ( staticAWSCredentialsForAssumedRole = credentials.NewStaticCredentials(assumedRoleKeyID, "assumedRoleKeySecret", "") - staticAWSCredentials = credentials.NewStaticCredentials("AKIDl", "SECRET", "SESSION") staticAWSCredentialsForClient = credentials.NewStaticCredentials("fakeClientKeyID", "fakeClientSecret", "") ) @@ -614,7 +621,7 @@ type suite struct { recorder *eventstest.ChannelRecorder } -func createSuite(t *testing.T, mockAWSHandler http.HandlerFunc, app types.Application, clock clockwork.Clock, awsSessionProvider awsutils.AWSSessionProvider) *suite { +func createSuite(t *testing.T, mockAWSHandler http.HandlerFunc, app types.Application, clock clockwork.Clock, acp awsconfig.Provider) *suite { recorder := eventstest.NewChannelRecorder(1) identity := tlsca.Identity{ Username: "user", @@ -630,13 +637,6 @@ func createSuite(t *testing.T, mockAWSHandler http.HandlerFunc, app types.Applic awsAPIMock.Close() }) - svc, err := awsutils.NewSigningService(awsutils.SigningServiceConfig{ - SessionProvider: awsSessionProvider, - CredentialsGetter: awsutils.NewStaticCredentialsGetter(staticAWSCredentials), - Clock: clock, - }) - require.NoError(t, err) - audit, err := common.NewAudit(common.AuditConfig{ Emitter: libevents.NewDiscardEmitter(), Recorder: libevents.WithNoOpPreparer(recorder), @@ -644,7 +644,7 @@ func createSuite(t *testing.T, mockAWSHandler http.HandlerFunc, app types.Applic require.NoError(t, err) signerHandler, err := NewAWSSignerHandler(context.Background(), SignerHandlerConfig{ - SigningService: svc, + AWSConfigProvider: acp, RoundTripper: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, diff --git a/lib/srv/app/connections_handler.go b/lib/srv/app/connections_handler.go index 3fad12e54eaaa..f5a583fc05c77 100644 --- a/lib/srv/app/connections_handler.go +++ b/lib/srv/app/connections_handler.go @@ -45,6 +45,7 @@ import ( "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/authz" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/httplib" "github.com/gravitational/teleport/lib/services" @@ -93,6 +94,9 @@ type ConnectionsHandlerConfig struct { // AWSSessionProvider is used to provide AWS Sessions. AWSSessionProvider awsutils.AWSSessionProvider + // AWSConfigProvider provides [aws.Config] for AWS SDK service clients. + AWSConfigProvider awsconfig.Provider + // TLSConfig is the *tls.Config for this server. TLSConfig *tls.Config @@ -142,6 +146,9 @@ func (c *ConnectionsHandlerConfig) CheckAndSetDefaults() error { if c.AWSSessionProvider == nil { return trace.BadParameter("aws session provider missing") } + if c.AWSConfigProvider == nil { + return trace.BadParameter("aws config provider missing") + } if c.Cloud == nil { cloud, err := NewCloud(CloudConfig{ Clock: c.Clock, @@ -206,16 +213,9 @@ func NewConnectionsHandler(closeContext context.Context, cfg *ConnectionsHandler return nil, trace.Wrap(err) } - awsSigner, err := awsutils.NewSigningService(awsutils.SigningServiceConfig{ - Clock: cfg.Clock, - SessionProvider: cfg.AWSSessionProvider, - }) - if err != nil { - return nil, trace.Wrap(err) - } awsHandler, err := appaws.NewAWSSignerHandler(closeContext, appaws.SignerHandlerConfig{ - SigningService: awsSigner, - Clock: cfg.Clock, + AWSConfigProvider: cfg.AWSConfigProvider, + Clock: cfg.Clock, }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/srv/app/server_test.go b/lib/srv/app/server_test.go index 1c0c8b4f322b3..3f0da8abda9b6 100644 --- a/lib/srv/app/server_test.go +++ b/lib/srv/app/server_test.go @@ -56,6 +56,7 @@ import ( "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/authz" + "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/httplib/reverseproxy" @@ -365,6 +366,7 @@ func SetUpSuiteWithConfig(t *testing.T, config suiteConfig) *Suite { CipherSuites: utils.DefaultCipherSuites(), ServiceComponent: teleport.ComponentApp, AWSSessionProvider: aws.SessionProviderUsingAmbientCredentials(), + AWSConfigProvider: &mocks.AWSConfigProvider{}, }) require.NoError(t, err) diff --git a/lib/srv/db/dynamodb/engine.go b/lib/srv/db/dynamodb/engine.go index 734ff51568f2c..165d856677f9d 100644 --- a/lib/srv/db/dynamodb/engine.go +++ b/lib/srv/db/dynamodb/engine.go @@ -40,6 +40,7 @@ import ( "github.com/gravitational/teleport" apievents "github.com/gravitational/teleport/api/types/events" apiaws "github.com/gravitational/teleport/api/utils/aws" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/modules" @@ -138,14 +139,6 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error } defer e.Audit.OnSessionEnd(e.Context, e.sessionCtx) - signer, err := libaws.NewSigningService(libaws.SigningServiceConfig{ - Clock: e.Clock, - AWSConfigProvider: e.AWSConfigProvider, - }) - if err != nil { - return trace.Wrap(err) - } - clientConnReader := bufio.NewReader(e.clientConn) observe() @@ -159,7 +152,7 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error return trace.Wrap(err) } - if err := e.process(ctx, req, signer, msgFromClient, msgFromServer); err != nil { + if err := e.process(ctx, req, msgFromClient, msgFromServer); err != nil { return trace.Wrap(err) } } @@ -167,7 +160,7 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error // process reads request from connected dynamodb client, processes the requests/responses and sends data back // to the client. -func (e *Engine) process(ctx context.Context, req *http.Request, signer *libaws.SigningService, msgFromClient prometheus.Counter, msgFromServer prometheus.Counter) (err error) { +func (e *Engine) process(ctx context.Context, req *http.Request, msgFromClient prometheus.Counter, msgFromServer prometheus.Counter) (err error) { msgFromClient.Inc() if req.Body != nil { @@ -210,20 +203,32 @@ func (e *Engine) process(ctx context.Context, req *http.Request, signer *libaws. if err != nil { return trace.Wrap(err) } - signingCtx := &libaws.SigningCtx{ - SigningName: re.SigningName, - SigningRegion: re.SigningRegion, - Expiry: e.sessionCtx.Identity.Expires, - SessionName: e.sessionCtx.Identity.Username, - BaseAWSRoleARN: meta.AssumeRoleARN, - BaseAWSExternalID: meta.ExternalID, - AWSRoleArn: roleArn, - SessionTags: e.sessionCtx.Database.GetAWS().SessionTags, + + ar := awsconfig.AssumeRole{ + RoleARN: roleArn, + SessionName: e.sessionCtx.Identity.Username, + Tags: meta.SessionTags, } if meta.AssumeRoleARN == "" { - signingCtx.AWSExternalID = meta.ExternalID + ar.ExternalID = meta.ExternalID } - signedReq, err := signer.SignRequest(e.Context, outReq, signingCtx) + awsCfg, err := e.AWSConfigProvider.GetConfig(ctx, meta.Region, + awsconfig.WithAssumeRole(meta.AssumeRoleARN, meta.ExternalID), + awsconfig.WithDetailedAssumeRole(ar), + awsconfig.WithAmbientCredentials(), + ) + if err != nil { + return trace.Wrap(err) + } + + signingCtx := &libaws.SigningCtx{ + Clock: e.Clock, + Credentials: awsCfg.Credentials, + SigningName: re.SigningName, + SigningRegion: re.SigningRegion, + } + + signedReq, err := libaws.SignRequest(e.Context, outReq, signingCtx) if err != nil { return trace.Wrap(err) } diff --git a/lib/srv/db/dynamodb/test.go b/lib/srv/db/dynamodb/test.go index b12d0493ea75e..e91125dff69f8 100644 --- a/lib/srv/db/dynamodb/test.go +++ b/lib/srv/db/dynamodb/test.go @@ -101,7 +101,7 @@ func NewTestServer(config common.TestServerConfig, opts ...TestServerOption) (*T mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - err := awsutils.VerifyAWSSignatureV2(r, + err := awsutils.VerifyAWSSignature(r, credentials.NewStaticCredentialsProvider("FAKEACCESSKEYID", "secret", "token"), ) if err != nil { diff --git a/lib/srv/db/opensearch/engine.go b/lib/srv/db/opensearch/engine.go index 4f54f4b5a282d..f017f5c7a8369 100644 --- a/lib/srv/db/opensearch/engine.go +++ b/lib/srv/db/opensearch/engine.go @@ -34,6 +34,7 @@ import ( "github.com/gravitational/teleport" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/types/wrappers" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/srv/db/common" @@ -133,14 +134,6 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error e.Audit.OnSessionStart(e.Context, e.sessionCtx, err) return trace.Wrap(err) } - signer, err := libaws.NewSigningService(libaws.SigningServiceConfig{ - Clock: e.Clock, - AWSConfigProvider: e.AWSConfigProvider, - }) - if err != nil { - return trace.Wrap(err) - } - // TODO(Tener): // Consider rewriting to support HTTP2 clients. // Ideally we should have shared middleware for DB clients using HTTP, instead of separate per-engine implementations. @@ -166,7 +159,7 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error return trace.Wrap(err) } - if err := e.process(ctx, tr, signer, req, msgFromClient, msgFromServer); err != nil { + if err := e.process(ctx, tr, req, msgFromClient, msgFromServer); err != nil { return trace.Wrap(err) } } @@ -174,7 +167,7 @@ func (e *Engine) HandleConnection(ctx context.Context, _ *common.Session) error // process reads request from connected OpenSearch client, processes the requests/responses and send data back // to the client. -func (e *Engine) process(ctx context.Context, tr *http.Transport, signer *libaws.SigningService, req *http.Request, msgFromClient prometheus.Counter, msgFromServer prometheus.Counter) error { +func (e *Engine) process(ctx context.Context, tr *http.Transport, req *http.Request, msgFromClient prometheus.Counter, msgFromServer prometheus.Counter) error { msgFromClient.Inc() if req.Body != nil { @@ -193,7 +186,7 @@ func (e *Engine) process(ctx context.Context, tr *http.Transport, signer *libaws e.emitAuditEvent(reqCopy, payload, responseStatusCode, err == nil) }() - signedReq, err := e.getSignedRequest(signer, reqCopy) + signedReq, err := e.getSignedRequest(reqCopy) if err != nil { return trace.Wrap(err) } @@ -225,31 +218,33 @@ func (e *Engine) getTransport(ctx context.Context) (*http.Transport, error) { return tr, nil } -func (e *Engine) getSignedRequest(signer *libaws.SigningService, reqCopy *http.Request) (*http.Request, error) { +func (e *Engine) getSignedRequest(reqCopy *http.Request) (*http.Request, error) { roleArn, err := libaws.BuildRoleARN(e.sessionCtx.DatabaseUser, e.sessionCtx.Database.GetAWS().Region, e.sessionCtx.Database.GetAWS().AccountID) if err != nil { return nil, trace.Wrap(err) } meta := e.sessionCtx.Database.GetAWS() - signCtx := &libaws.SigningCtx{ - SigningName: "es", - SigningRegion: meta.Region, - Expiry: e.sessionCtx.Identity.Expires, - SessionName: e.sessionCtx.Identity.Username, - BaseAWSRoleARN: meta.AssumeRoleARN, - BaseAWSExternalID: meta.ExternalID, - AWSRoleArn: roleArn, - // OpenSearch uses meta.ExternalID for both the base role and the - // assumed role. - AWSExternalID: meta.ExternalID, + awsCfg, err := e.AWSConfigProvider.GetConfig(e.Context, meta.Region, + awsconfig.WithAssumeRole(meta.AssumeRoleARN, meta.ExternalID), + awsconfig.WithDetailedAssumeRole(awsconfig.AssumeRole{ + RoleARN: roleArn, + ExternalID: meta.ExternalID, + SessionName: e.sessionCtx.Identity.Username, + }), + awsconfig.WithAmbientCredentials(), + ) + if err != nil { + return nil, trace.Wrap(err) } - - if meta.AssumeRoleARN == "" { - signCtx.AWSExternalID = meta.ExternalID + signCtx := &libaws.SigningCtx{ + Clock: e.Clock, + Credentials: awsCfg.Credentials, + SigningName: "es", + SigningRegion: e.sessionCtx.Database.GetAWS().Region, } - signedReq, err := signer.SignRequest(e.Context, reqCopy, signCtx) + signedReq, err := libaws.SignRequest(e.Context, reqCopy, signCtx) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/utils/aws/aws.go b/lib/utils/aws/aws.go index c06636c109150..084a6383e80f7 100644 --- a/lib/utils/aws/aws.go +++ b/lib/utils/aws/aws.go @@ -159,22 +159,17 @@ func IsSignedByAWSSigV4(r *http.Request) bool { return strings.HasPrefix(r.Header.Get(AuthorizationHeader), AmazonSigV4AuthorizationPrefix) } -// VerifyAWSSignatureV2 is a temporary AWS SDK migration helper. -func VerifyAWSSignatureV2(req *http.Request, provider aws.CredentialsProvider) error { - return VerifyAWSSignature(req, migration.NewCredentialsAdapter(provider)) -} - // VerifyAWSSignature verifies the request signature ensuring that the request originates from tsh aws command execution // AWS CLI signs the request with random generated credentials that are passed to LocalProxy by // the AWSCredentials LocalProxyConfig configuration. -func VerifyAWSSignature(req *http.Request, credentials *credentials.Credentials) error { +func VerifyAWSSignature(req *http.Request, credProvider aws.CredentialsProvider) error { sigV4, err := ParseSigV4(req.Header.Get("Authorization")) if err != nil { return trace.BadParameter(err.Error()) } // Verifies the request is signed by the expected access key ID. - credValue, err := credentials.Get() + credValue, err := credProvider.Retrieve(req.Context()) if err != nil { return trace.Wrap(err) } @@ -212,7 +207,7 @@ func VerifyAWSSignature(req *http.Request, credentials *credentials.Credentials) return trace.BadParameter(err.Error()) } - signer := NewSigner(credentials, sigV4.Service) + signer := NewSignerV2(credProvider, sigV4.Service) _, err = signer.Sign(reqCopy, bytes.NewReader(payload), sigV4.Service, sigV4.Region, t) if err != nil { return trace.Wrap(err) diff --git a/lib/utils/aws/credentials.go b/lib/utils/aws/credentials.go index 47c3105174943..8be99d898e5f7 100644 --- a/lib/utils/aws/credentials.go +++ b/lib/utils/aws/credentials.go @@ -20,187 +20,15 @@ package aws import ( "context" - "log/slog" - "sort" - "strings" - "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/client" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/sts" "github.com/gravitational/trace" - "github.com/jonboulle/clockwork" "github.com/gravitational/teleport/lib/modules" - "github.com/gravitational/teleport/lib/utils" ) -// GetCredentialsRequest is the request for obtaining STS credentials. -type GetCredentialsRequest struct { - // Provider is the user session used to create the STS client. - Provider client.ConfigProvider - // Expiry is session expiry to be requested. - Expiry time.Time - // SessionName is the session name to be requested. - SessionName string - // RoleARN is the role ARN to be requested. - RoleARN string - // ExternalID is the external ID to be requested, if not empty. - ExternalID string - // Tags is a list of AWS STS session tags. - Tags map[string]string -} - -// CredentialsGetter defines an interface for obtaining STS credentials. -type CredentialsGetter interface { - // Get obtains STS credentials. - Get(ctx context.Context, request GetCredentialsRequest) (*credentials.Credentials, error) -} - -type credentialsGetter struct { -} - -// NewCredentialsGetter returns a new CredentialsGetter. -func NewCredentialsGetter() CredentialsGetter { - return &credentialsGetter{} -} - -// Get obtains STS credentials. -func (g *credentialsGetter) Get(ctx context.Context, request GetCredentialsRequest) (*credentials.Credentials, error) { - slog.DebugContext(ctx, "Creating STS session", - "session_name", request.SessionName, - "role_arn", request.RoleARN, - ) - return stscreds.NewCredentials(request.Provider, request.RoleARN, - func(cred *stscreds.AssumeRoleProvider) { - cred.RoleSessionName = MaybeHashRoleSessionName(request.SessionName) - cred.Expiry.SetExpiration(request.Expiry, 0) - - if request.ExternalID != "" { - cred.ExternalID = aws.String(request.ExternalID) - } - - cred.Tags = make([]*sts.Tag, 0, len(request.Tags)) - for key, value := range request.Tags { - cred.Tags = append(cred.Tags, &sts.Tag{Key: aws.String(key), Value: aws.String(value)}) - } - }, - ), nil -} - -// CachedCredentialsGetterConfig is the config for creating a CredentialsGetter that caches credentials. -type CachedCredentialsGetterConfig struct { - // Getter is the CredentialsGetter for obtaining the STS credentials. - Getter CredentialsGetter - // CacheTTL is the cache TTL. - CacheTTL time.Duration - // Clock is used to control time. - Clock clockwork.Clock -} - -// SetDefaults sets default values for CachedCredentialsGetterConfig. -func (c *CachedCredentialsGetterConfig) SetDefaults() { - if c.Getter == nil { - c.Getter = NewCredentialsGetter() - } - if c.CacheTTL <= 0 { - c.CacheTTL = time.Minute - } - if c.Clock == nil { - c.Clock = clockwork.NewRealClock() - } -} - -// credentialRequestCacheKey credentials request cache key. -type credentialRequestCacheKey struct { - provider client.ConfigProvider - expiry time.Time - sessionName string - roleARN string - externalID string - tags string -} - -// newCredentialRequestCacheKey creates a new cache key for the credentials -// request. -func newCredentialRequestCacheKey(req GetCredentialsRequest) credentialRequestCacheKey { - k := credentialRequestCacheKey{ - provider: req.Provider, - expiry: req.Expiry, - sessionName: req.SessionName, - roleARN: req.RoleARN, - externalID: req.ExternalID, - } - - tags := make([]string, 0, len(req.Tags)) - for key, value := range req.Tags { - tags = append(tags, key+"="+value+",") - } - sort.Strings(tags) - k.tags = strings.Join(tags, ",") - - return k -} - -type cachedCredentialsGetter struct { - config CachedCredentialsGetterConfig - cache *utils.FnCache -} - -// NewCachedCredentialsGetter returns a CredentialsGetter that caches credentials. -func NewCachedCredentialsGetter(config CachedCredentialsGetterConfig) (CredentialsGetter, error) { - config.SetDefaults() - - cache, err := utils.NewFnCache(utils.FnCacheConfig{ - TTL: config.CacheTTL, - Clock: config.Clock, - }) - if err != nil { - return nil, trace.Wrap(err) - } - - return &cachedCredentialsGetter{ - config: config, - cache: cache, - }, nil -} - -// Get returns cached credentials if found, or fetch it from the configured -// getter. -func (g *cachedCredentialsGetter) Get(ctx context.Context, request GetCredentialsRequest) (*credentials.Credentials, error) { - credentials, err := utils.FnCacheGet(ctx, g.cache, newCredentialRequestCacheKey(request), func(ctx context.Context) (*credentials.Credentials, error) { - credentials, err := g.config.Getter.Get(ctx, request) - return credentials, trace.Wrap(err) - }) - return credentials, trace.Wrap(err) -} - -type staticCredentialsGetter struct { - credentials *credentials.Credentials -} - -// NewStaticCredentialsGetter returns a CredentialsGetter that always returns -// the same provided credentials. -// -// Used in testing to mock CredentialsGetter. -func NewStaticCredentialsGetter(credentials *credentials.Credentials) CredentialsGetter { - return &staticCredentialsGetter{ - credentials: credentials, - } -} - -// Get returns the credentials provided to NewStaticCredentialsGetter. -func (g *staticCredentialsGetter) Get(_ context.Context, _ GetCredentialsRequest) (*credentials.Credentials, error) { - if g.credentials == nil { - return nil, trace.NotFound("no credentials found") - } - return g.credentials, nil -} - // AWSSessionProvider defines a function that creates an AWS Session. // It must use ambient credentials if Integration is empty. // It must use Integration credentials otherwise. diff --git a/lib/utils/aws/credentials_test.go b/lib/utils/aws/credentials_test.go deleted file mode 100644 index 3f682f3462cc5..0000000000000 --- a/lib/utils/aws/credentials_test.go +++ /dev/null @@ -1,189 +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 . - */ - -package aws - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/google/uuid" - "github.com/jonboulle/clockwork" - "github.com/stretchr/testify/require" -) - -type fakeCredentialsGetter struct { -} - -func (f *fakeCredentialsGetter) Get(ctx context.Context, request GetCredentialsRequest) (*credentials.Credentials, error) { - return credentials.NewStaticCredentials( - fmt.Sprintf("%s-%s-%s", request.SessionName, request.RoleARN, request.ExternalID), - uuid.NewString(), - uuid.NewString(), - ), nil -} - -func TestCachedCredentialsGetter(t *testing.T) { - t.Parallel() - - hostSession := session.Must(session.NewSession(&aws.Config{ - Credentials: credentials.AnonymousCredentials, - Region: aws.String("us-west-2"), - })) - fakeClock := clockwork.NewFakeClock() - - getter, err := NewCachedCredentialsGetter(CachedCredentialsGetterConfig{ - Getter: &fakeCredentialsGetter{}, - CacheTTL: time.Minute, - Clock: fakeClock, - }) - require.NoError(t, err) - - cred1, err := getter.Get(context.Background(), GetCredentialsRequest{ - Provider: hostSession, - Expiry: fakeClock.Now().Add(time.Hour), - SessionName: "test-session", - RoleARN: "test-role", - Tags: map[string]string{ - "one": "1", - "two": "2", - "three": "3", - }, - }) - require.NoError(t, err) - checkCredentialsAccessKeyID(t, cred1, "test-session-test-role-") - - tests := []struct { - name string - sessionName string - roleARN string - externalID string - tags map[string]string - advanceClock time.Duration - compareCred1 require.ComparisonAssertionFunc - }{ - { - name: "cached", - sessionName: "test-session", - roleARN: "test-role", - tags: map[string]string{ - "one": "1", - "two": "2", - "three": "3", - }, - compareCred1: require.Same, - }, - { - name: "cached different tags order", - sessionName: "test-session", - roleARN: "test-role", - tags: map[string]string{ - "three": "3", - "two": "2", - "one": "1", - }, - compareCred1: require.Same, - }, - { - name: "different session name", - sessionName: "test-session-2", - roleARN: "test-role", - tags: map[string]string{ - "one": "1", - "two": "2", - "three": "3", - }, - compareCred1: require.NotSame, - }, - { - name: "different role ARN", - sessionName: "test-session", - roleARN: "test-role-2", - tags: map[string]string{ - "one": "1", - "two": "2", - "three": "3", - }, - compareCred1: require.NotSame, - }, - { - name: "different external ID", - sessionName: "test-session", - roleARN: "test-role", - externalID: "test-id", - tags: map[string]string{ - "one": "1", - "two": "2", - "three": "3", - }, - compareCred1: require.NotSame, - }, - { - name: "different tags", - sessionName: "test-session", - roleARN: "test-role", - tags: map[string]string{ - "four": "4", - "five": "5", - }, - compareCred1: require.NotSame, - }, - { - name: "cache expired", - sessionName: "test-session", - roleARN: "test-role", - tags: map[string]string{ - "one": "1", - "two": "2", - "three": "3", - }, - advanceClock: time.Hour, - compareCred1: require.NotSame, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - fakeClock.Advance(test.advanceClock) - - cred, err := getter.Get(context.Background(), GetCredentialsRequest{ - Provider: hostSession, - Expiry: fakeClock.Now().Add(time.Hour), - SessionName: test.sessionName, - RoleARN: test.roleARN, - ExternalID: test.externalID, - Tags: test.tags, - }) - require.NoError(t, err) - checkCredentialsAccessKeyID(t, cred, fmt.Sprintf("%s-%s-%s", test.sessionName, test.roleARN, test.externalID)) - test.compareCred1(t, cred1, cred) - }) - } -} - -func checkCredentialsAccessKeyID(t *testing.T, cred *credentials.Credentials, wantAccessKeyID string) { - t.Helper() - value, err := cred.Get() - require.NoError(t, err) - require.Equal(t, wantAccessKeyID, value.AccessKeyID) -} diff --git a/lib/utils/aws/signing.go b/lib/utils/aws/signing.go index 6549265aed676..31d29532c20d8 100644 --- a/lib/utils/aws/signing.go +++ b/lib/utils/aws/signing.go @@ -23,114 +23,35 @@ import ( "context" "io" "net/http" - "time" - v4 "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/utils" ) -// NewSigningService creates a new instance of SigningService. -func NewSigningService(config SigningServiceConfig) (*SigningService, error) { - if err := config.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - return &SigningService{ - SigningServiceConfig: config, - }, nil -} - -// SigningService is an AWS CLI proxy service that signs AWS requests -// based on user identity. -type SigningService struct { - // SigningServiceConfig is the SigningService configuration. - SigningServiceConfig -} - -// SigningServiceConfig is the SigningService configuration. -type SigningServiceConfig struct { - // SessionProvider is a provider for AWS Sessions. - SessionProvider AWSSessionProvider - // Clock is used to override time in tests. - Clock clockwork.Clock - // CredentialsGetter is used to obtain STS credentials. - CredentialsGetter CredentialsGetter - // AWSConfigProvider is a provider for AWS configs. - AWSConfigProvider awsconfig.Provider -} - -// CheckAndSetDefaults validates the SigningServiceConfig config. -func (s *SigningServiceConfig) CheckAndSetDefaults() error { - if s.Clock == nil { - s.Clock = clockwork.NewRealClock() - } - - if s.AWSConfigProvider == nil { - if s.SessionProvider == nil { - return trace.BadParameter("session provider or config provider is required") - } - if s.CredentialsGetter == nil { - // Use cachedCredentialsGetter by default. cachedCredentialsGetter - // caches the credentials for one minute. - cachedGetter, err := NewCachedCredentialsGetter(CachedCredentialsGetterConfig{ - Clock: s.Clock, - }) - if err != nil { - return trace.Wrap(err) - } - - s.CredentialsGetter = cachedGetter - } - } - return nil -} - // SigningCtx contains AWS SigV4 signing context parameters. type SigningCtx struct { + // Clock is used to override time in tests. + Clock clockwork.Clock + // Credentials provides AWS credentials. + Credentials aws.CredentialsProvider // SigningName is the AWS signing service name. SigningName string // SigningRegion is the AWS region to sign a request for. SigningRegion string - // Expiry is the expiration of the AWS credentials used to sign requests. - Expiry time.Time - // SessionName is role session name of AWS credentials used to sign requests. - SessionName string - // BaseAWSRoleARN is the AWS ARN of the role as a base to the assumed roles. - BaseAWSRoleARN string - // BaseAWSRoleARN is an optional external ID used on base assumed role. - BaseAWSExternalID string - // AWSRoleArn is the AWS ARN of the role to assume for signing requests, - // chained with BaseAWSRoleARN. - AWSRoleArn string - // AWSExternalID is an optional external ID used when getting sts credentials. - AWSExternalID string - // SessionTags is a list of AWS STS session tags. - SessionTags map[string]string - // Integration is the Integration name to use to generate credentials. - // If empty, it will use ambient credentials - Integration string } // Check checks signing context parameters. -func (sc *SigningCtx) Check(clock clockwork.Clock) error { +func (sc *SigningCtx) Check() error { switch { + case sc.Credentials == nil: + return trace.BadParameter("missing AWS credentials") case sc.SigningName == "": return trace.BadParameter("missing AWS signing name") case sc.SigningRegion == "": return trace.BadParameter("missing AWS signing region") - case sc.SessionName == "": - return trace.BadParameter("missing AWS session name") - case sc.AWSRoleArn == "": - return trace.BadParameter("missing AWS Role ARN") - case sc.Expiry.Before(clock.Now()): - return trace.BadParameter("AWS SigV4 expiry has already expired") - } - _, err := ParseRoleARN(sc.AWSRoleArn) - if err != nil { - return trace.Wrap(err) } return nil } @@ -151,11 +72,11 @@ func (sc *SigningCtx) Check(clock clockwork.Clock) error { // Not that for endpoint resolving the https://github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go // package is used and when Amazon releases a new API the dependency update is needed. // 5. Sign HTTP request. -func (s *SigningService) SignRequest(ctx context.Context, req *http.Request, signCtx *SigningCtx) (*http.Request, error) { +func SignRequest(ctx context.Context, req *http.Request, signCtx *SigningCtx) (*http.Request, error) { if signCtx == nil { return nil, trace.BadParameter("missing signing context") } - if err := signCtx.Check(s.Clock); err != nil { + if err := signCtx.Check(); err != nil { return nil, trace.Wrap(err) } payload, err := utils.GetAndReplaceRequestBody(req) @@ -173,11 +94,8 @@ func (s *SigningService) SignRequest(ctx context.Context, req *http.Request, sig // 100-continue" headers without being signed, otherwise the Athena service // would reject the requests. unsignedHeaders := removeUnsignedHeaders(reqCopy) - signer, err := s.newSigner(ctx, signCtx) - if err != nil { - return nil, trace.Wrap(err) - } - _, err = signer.Sign(reqCopy, bytes.NewReader(payload), signCtx.SigningName, signCtx.SigningRegion, s.Clock.Now()) + signer := NewSignerV2(signCtx.Credentials, signCtx.SigningName) + _, err = signer.Sign(reqCopy, bytes.NewReader(payload), signCtx.SigningName, signCtx.SigningRegion, signCtx.Clock.Now()) if err != nil { return nil, trace.Wrap(err) } @@ -187,40 +105,6 @@ func (s *SigningService) SignRequest(ctx context.Context, req *http.Request, sig return reqCopy, nil } -// TODO(gabrielcorado): once all service callers are updated to use -// AWSConfigProvider, make it required and remove session provider and -// credentials getter fallback. -func (s *SigningService) newSigner(ctx context.Context, signCtx *SigningCtx) (*v4.Signer, error) { - if s.AWSConfigProvider != nil { - awsCfg, err := s.AWSConfigProvider.GetConfig(ctx, signCtx.SigningRegion, - awsconfig.WithAssumeRole(signCtx.BaseAWSRoleARN, signCtx.BaseAWSExternalID), - awsconfig.WithAssumeRole(signCtx.AWSRoleArn, signCtx.AWSExternalID), - awsconfig.WithCredentialsMaybeIntegration(signCtx.Integration), - ) - if err != nil { - return nil, trace.Wrap(err) - } - return NewSignerV2(awsCfg.Credentials, signCtx.SigningName), nil - } - - session, err := s.SessionProvider(ctx, signCtx.SigningRegion, signCtx.Integration) - if err != nil { - return nil, trace.Wrap(err) - } - credentials, err := s.CredentialsGetter.Get(ctx, GetCredentialsRequest{ - Provider: session, - Expiry: signCtx.Expiry, - SessionName: signCtx.SessionName, - RoleARN: signCtx.AWSRoleArn, - ExternalID: signCtx.AWSExternalID, - Tags: signCtx.SessionTags, - }) - if err != nil { - return nil, trace.Wrap(err) - } - return NewSigner(credentials, signCtx.SigningName), nil -} - // removeUnsignedHeaders removes and returns header keys that are not included in SigV4 SignedHeaders. // If the request is not already signed, then no headers are removed. func removeUnsignedHeaders(reqCopy *http.Request) []string { From a24fe3e258fa6db164b797e64e2fed2dd567a652 Mon Sep 17 00:00:00 2001 From: Pawel Kopiczko Date: Thu, 30 Jan 2025 20:46:15 +0000 Subject: [PATCH 26/28] Okta API: Remove unused fields and update docs (#51637) * Okta API: Remove unused fields and update docs * Add temporary protobuf liter exception --- .../go/teleport/okta/v1/okta_service.pb.go | 535 +++++++++--------- api/proto/teleport/legacy/types/types.proto | 6 +- api/proto/teleport/okta/v1/okta_service.proto | 6 +- api/types/types.pb.go | 6 +- buf.yaml | 2 + 5 files changed, 267 insertions(+), 288 deletions(-) diff --git a/api/gen/proto/go/teleport/okta/v1/okta_service.pb.go b/api/gen/proto/go/teleport/okta/v1/okta_service.pb.go index 341c409e2ccaa..7f14369fd18df 100644 --- a/api/gen/proto/go/teleport/okta/v1/okta_service.pb.go +++ b/api/gen/proto/go/teleport/okta/v1/okta_service.pb.go @@ -402,14 +402,10 @@ type UpdateIntegrationRequest struct { EnableAppGroupSync bool `protobuf:"varint,6,opt,name=enable_app_group_sync,json=enableAppGroupSync,proto3" json:"enable_app_group_sync,omitempty"` // Settings related to access list synchronization. AccessListSettings *AccessListSettings `protobuf:"bytes,7,opt,name=access_list_settings,json=accessListSettings,proto3" json:"access_list_settings,omitempty"` - // Option to reuse an existing connector. - ReuseConnector string `protobuf:"bytes,8,opt,name=reuse_connector,json=reuseConnector,proto3" json:"reuse_connector,omitempty"` - // SSO metadata URL for integration. - SsoMetadataUrl string `protobuf:"bytes,9,opt,name=sso_metadata_url,json=ssoMetadataUrl,proto3" json:"sso_metadata_url,omitempty"` // Enable sync from Teleport to Okta. If disabled it will prevent creating Okta assignments which // in turn will disable JIT Access Requests. Makes sense only when apps and groups sync is // enabled. - EnableBidirectionalSync bool `protobuf:"varint,10,opt,name=enable_bidirectional_sync,json=enableBidirectionalSync,proto3" json:"enable_bidirectional_sync,omitempty"` + EnableBidirectionalSync bool `protobuf:"varint,8,opt,name=enable_bidirectional_sync,json=enableBidirectionalSync,proto3" json:"enable_bidirectional_sync,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -486,20 +482,6 @@ func (x *UpdateIntegrationRequest) GetAccessListSettings() *AccessListSettings { return nil } -func (x *UpdateIntegrationRequest) GetReuseConnector() string { - if x != nil { - return x.ReuseConnector - } - return "" -} - -func (x *UpdateIntegrationRequest) GetSsoMetadataUrl() string { - if x != nil { - return x.SsoMetadataUrl - } - return "" -} - func (x *UpdateIntegrationRequest) GetEnableBidirectionalSync() bool { if x != nil { return x.EnableBidirectionalSync @@ -1856,7 +1838,7 @@ var file_teleport_okta_v1_okta_service_proto_rawDesc = string([]byte{ 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x83, 0x04, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, + 0x6e, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x22, 0xb0, 0x03, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, @@ -1879,272 +1861,267 @@ var file_teleport_okta_v1_okta_service_proto_rawDesc = string([]byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x12, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x27, - 0x0a, 0x0f, 0x72, 0x65, 0x75, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x75, 0x73, 0x65, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x73, 0x6f, 0x5f, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x73, 0x73, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x72, - 0x6c, 0x12, 0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x64, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, 0x64, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x7f, 0x0a, - 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, - 0x70, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x67, - 0x0a, 0x12, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x50, 0x49, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x73, 0x12, 0x1b, 0x0a, 0x08, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x49, - 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x73, 0x77, 0x73, 0x5f, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, - 0x73, 0x73, 0x77, 0x73, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, - 0x06, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x8c, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x56, 0x31, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x46, - 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x8c, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x56, 0x31, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x46, 0x0a, - 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0b, 0x6f, 0x6b, 0x74, 0x61, 0x5f, - 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x6b, - 0x74, 0x61, 0x41, 0x70, 0x70, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x6b, 0x74, 0x61, 0x5f, - 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6f, - 0x6b, 0x74, 0x61, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x70, 0x70, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x20, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x32, 0x0a, 0x15, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x13, 0x6f, 0x6b, 0x74, 0x61, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, - 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x50, 0x49, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x73, 0x52, 0x0e, 0x61, 0x70, 0x69, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x73, 0x22, 0x23, 0x0a, 0x21, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x58, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, - 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 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, 0x81, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 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, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 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, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, + 0x0a, 0x19, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x7f, 0x0a, 0x12, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x67, 0x0a, 0x12, 0x4f, + 0x6b, 0x74, 0x61, 0x41, 0x50, 0x49, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, + 0x73, 0x12, 0x1b, 0x0a, 0x08, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x49, 0x64, 0x12, 0x2c, + 0x0a, 0x11, 0x73, 0x73, 0x77, 0x73, 0x5f, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x73, 0x77, + 0x73, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x06, 0x0a, 0x04, + 0x61, 0x75, 0x74, 0x68, 0x22, 0x8c, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x56, 0x31, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x46, 0x0a, 0x0e, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, + 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, + 0x6e, 0x66, 0x6f, 0x22, 0x8c, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x27, 0x0a, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x56, 0x31, 0x52, 0x06, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x46, 0x0a, 0x0e, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, + 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, + 0x66, 0x6f, 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0b, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x61, 0x70, 0x70, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x6b, 0x74, 0x61, 0x41, + 0x70, 0x70, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x61, 0x70, 0x70, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x6b, 0x74, + 0x61, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x6f, 0x6b, 0x74, 0x61, + 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6f, 0x6b, 0x74, 0x61, 0x41, 0x70, 0x70, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x20, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, + 0x15, 0x6f, 0x6b, 0x74, 0x61, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x6f, 0x6b, + 0x74, 0x61, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, + 0x6c, 0x12, 0x4d, 0x0a, 0x0f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6b, + 0x74, 0x61, 0x41, 0x50, 0x49, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x52, 0x0e, 0x61, 0x70, 0x69, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x22, 0x23, 0x0a, 0x21, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x58, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, + 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 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, + 0x81, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3a, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 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, 0x52, 0x0b, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 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, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 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, 0x57, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 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, 0x57, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, - 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 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, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x22, - 0x57, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, - 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, + 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x18, 0x01, 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, + 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x57, 0x0a, 0x1b, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 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, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x31, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, + 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 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, 0x21, 0x0a, 0x1f, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x58, 0x0a, 0x1a, 0x4c, + 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 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, 0x80, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, + 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 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, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4f, + 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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, 0x56, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 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, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x22, 0x56, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x37, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 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, 0x52, 0x0a, 0x69, 0x6d, - 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x31, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, - 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, 0x21, 0x0a, 0x1f, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x58, - 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x6d, 0x65, 0x6e, 0x74, 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, 0x80, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, - 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x69, - 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 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, 0x52, 0x0b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 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, 0x22, 0x2e, 0x0a, 0x18, 0x47, - 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, - 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, 0x56, 0x0a, 0x1b, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 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, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x22, 0x56, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, - 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, - 0x18, 0x01, 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, 0x52, - 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xc4, 0x01, 0x0a, 0x21, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x12, 0x48, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, - 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, - 0x56, 0x31, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x41, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x73, - 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x73, 0x50, 0x61, 0x73, 0x73, - 0x65, 0x64, 0x22, 0x31, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, - 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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, 0x21, 0x0a, 0x1f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, - 0x6c, 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0xa9, 0x0e, 0x0a, 0x0b, 0x4f, 0x6b, 0x74, - 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, - 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, - 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x11, - 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, - 0x65, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, - 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x75, 0x6c, 0x65, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2d, + 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x52, 0x0a, 0x61, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xc4, 0x01, 0x0a, 0x21, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x12, 0x48, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x56, 0x31, 0x2e, + 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x41, 0x0a, 0x0f, + 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x73, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64, 0x22, + 0x31, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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, 0x21, 0x0a, 0x1f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, + 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, 0xa9, 0x0e, 0x0a, 0x0b, 0x4f, 0x6b, 0x74, 0x61, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, + 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x11, 0x47, 0x65, 0x74, + 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x75, 0x6c, 0x65, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2d, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, + 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, + 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x56, 0x31, 0x12, 0x5d, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, + 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x75, 0x6c, 0x65, 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, 0x65, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, + 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x75, 0x6c, 0x65, 0x56, 0x31, 0x12, 0x5d, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x2d, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 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, 0x72, 0x0a, 0x13, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 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, 0x65, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, - 0x6c, 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, - 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, - 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, - 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 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, 0x72, 0x0a, 0x13, - 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, - 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, - 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x58, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, - 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, - 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, - 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, - 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, - 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x12, 0x69, 0x0a, 0x1a, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x5d, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, - 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, + 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x12, 0x5e, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x12, 0x69, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, + 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 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, 0x5d, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, + 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 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, 0x65, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, + 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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, 0x65, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, - 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, 0x74, - 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 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, 0x84, 0x01, 0x0a, 0x19, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 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, 0x84, 0x01, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, - 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, - 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x6c, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, - 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, - 0x0a, 0x07, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, - 0x0a, 0x09, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x22, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 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, 0x6f, 0x6b, 0x74, 0x61, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x6b, 0x74, 0x61, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x6c, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, + 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, + 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x70, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x70, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x47, + 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x6b, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x4c, 0x5a, 0x4a, 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, 0x6f, 0x6b, 0x74, 0x61, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x6b, 0x74, 0x61, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 5ef26f33d3b05..b09cb788a1675 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -6711,7 +6711,7 @@ message PluginOktaSyncSettings { // AppName is the Okta-assigned unique name of the Okta App that Teleport uses // as a gateway to interact with Okta for SAML login, SCIM provisioning and user - // sync. May be missing for old Okta integration installs. + // sync. string app_name = 8; // DisableSyncAppGroups disables syncing of app groups from Okta. @@ -7180,7 +7180,9 @@ message PluginOktaStatusDetailsSSO { // SSO login. string app_id = 2; - // AppName is the human-readable name of the Okta Applicaion used for SSO. + // AppName is the Okta-assigned unique name of the Okta App that Teleport uses + // as a gateway to interact with Okta for SAML login, SCIM provisioning and user + // sync. string app_name = 3; } diff --git a/api/proto/teleport/okta/v1/okta_service.proto b/api/proto/teleport/okta/v1/okta_service.proto index 1be540f43ab85..bb346eece44a5 100644 --- a/api/proto/teleport/okta/v1/okta_service.proto +++ b/api/proto/teleport/okta/v1/okta_service.proto @@ -150,14 +150,10 @@ message UpdateIntegrationRequest { bool enable_app_group_sync = 6; // Settings related to access list synchronization. AccessListSettings access_list_settings = 7; - // Option to reuse an existing connector. - string reuse_connector = 8; - // SSO metadata URL for integration. - string sso_metadata_url = 9; // Enable sync from Teleport to Okta. If disabled it will prevent creating Okta assignments which // in turn will disable JIT Access Requests. Makes sense only when apps and groups sync is // enabled. - bool enable_bidirectional_sync = 10; + bool enable_bidirectional_sync = 8; } // AccessListSettings contains the settings for access list synchronization. diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 8b7501b928414..c88f3b1c957cc 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -17239,7 +17239,7 @@ type PluginOktaSyncSettings struct { AppFilters []string `protobuf:"bytes,7,rep,name=app_filters,json=appFilters,proto3" json:"app_filters,omitempty"` // AppName is the Okta-assigned unique name of the Okta App that Teleport uses // as a gateway to interact with Okta for SAML login, SCIM provisioning and user - // sync. May be missing for old Okta integration installs. + // sync. AppName string `protobuf:"bytes,8,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` // DisableSyncAppGroups disables syncing of app groups from Okta. // This is useful when the app groups are not needed in Teleport. @@ -18816,7 +18816,9 @@ type PluginOktaStatusDetailsSSO struct { // AppId is the unique Okta application ID of the Okta Applicaion used for // SSO login. AppId string `protobuf:"bytes,2,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` - // AppName is the human-readable name of the Okta Applicaion used for SSO. + // AppName is the Okta-assigned unique name of the Okta App that Teleport uses + // as a gateway to interact with Okta for SAML login, SCIM provisioning and user + // sync. AppName string `protobuf:"bytes,3,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` diff --git a/buf.yaml b/buf.yaml index 8f01bbe2dea21..ccdcedcce111e 100644 --- a/buf.yaml +++ b/buf.yaml @@ -84,6 +84,8 @@ breaking: ignore: # TODO(codingllama): Remove ignore once the PDP API is stable. - api/proto/teleport/decision/v1alpha1 + # TODO(kopiczko) remove after https://github.com/gravitational/teleport/pull/51637 is merged + - api/proto/teleport/okta/v1/okta_service.proto ignore_only: RESERVED_ENUM_NO_DELETE: - api/proto/teleport/legacy/types/types.proto From 32d2aa9515da134904db25e19e6b1b049f36e63f Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 30 Jan 2025 17:06:58 -0500 Subject: [PATCH 27/28] Remove aws-sdk-go depdenency in bot tests (#51680) The use of static credentials in the test was unnecessary and the same result can be achieved using static strings. --- lib/auth/bot_test.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/auth/bot_test.go b/lib/auth/bot_test.go index 3b09c041721a6..ee1cf22358e8c 100644 --- a/lib/auth/bot_test.go +++ b/lib/auth/bot_test.go @@ -32,7 +32,6 @@ import ( "testing" "time" - "github.com/aws/aws-sdk-go/aws/credentials" "github.com/digitorus/pkcs7" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -923,16 +922,14 @@ func TestRegisterBot_BotInstanceRejoin(t *testing.T) { }), } - nodeCredentials, err := credentials.NewStaticCredentials("FAKE_ID", "FAKE_KEY", "FAKE_TOKEN").Get() - require.NoError(t, err) - t.Setenv("AWS_ACCESS_KEY_ID", nodeCredentials.AccessKeyID) - t.Setenv("AWS_SECRET_ACCESS_KEY", nodeCredentials.SecretAccessKey) - t.Setenv("AWS_SESSION_TOKEN", nodeCredentials.SessionToken) + t.Setenv("AWS_ACCESS_KEY_ID", "FAKE_ID") + t.Setenv("AWS_SECRET_ACCESS_KEY", "FAKE_KEY") + t.Setenv("AWS_SESSION_TOKEN", "FAKE_TOKEN") t.Setenv("AWS_REGION", "us-west-2") // Create a bot roleName := "test-role" - _, err = CreateRole(ctx, a, roleName, types.RoleSpecV6{}) + _, err := CreateRole(ctx, a, roleName, types.RoleSpecV6{}) require.NoError(t, err) botName := "bot" From ee119ea6d68045124d82b2b99cad5e308d8d19c8 Mon Sep 17 00:00:00 2001 From: Gavin Frazar Date: Thu, 30 Jan 2025 15:06:09 -0800 Subject: [PATCH 28/28] Remove remaining db and discovery AWS SDK imports (#51628) This eliminates all remaining references to AWS SDK v1 in the lib/srv/db/... and lib/srv/discovery/... packages. Most of the changes are simply to remove dead code. --- lib/cloud/aws/errors.go | 22 +- lib/cloud/aws/errors_test.go | 48 ++-- lib/cloud/aws/identity.go | 22 +- lib/cloud/aws/identity_test.go | 19 +- lib/cloud/aws/policy_statements.go | 2 +- lib/cloud/aws/policy_test.go | 2 +- lib/cloud/mocks/aws.go | 105 -------- lib/cloud/mocks/aws_rds.go | 58 ++-- lib/cloud/mocks/aws_redshift_serverless.go | 12 +- lib/cloud/mocks/aws_sts.go | 43 ++- lib/configurators/aws/aws.go | 2 +- .../awsoidc/eks_enroll_clusters.go | 2 +- .../awsoidc/listdeployeddatabaseservice.go | 2 +- lib/srv/db/cloud/aws.go | 4 +- lib/srv/db/cloud/iam.go | 14 +- lib/srv/db/cloud/iam_test.go | 36 ++- .../db/cloud/resource_checker_credentials.go | 2 +- lib/srv/db/cloud/users/elasticache.go | 6 +- lib/srv/db/cloud/users/memorydb.go | 6 +- lib/srv/db/common/auth.go | 74 ++--- lib/srv/db/common/auth_test.go | 10 +- lib/srv/db/common/errors.go | 6 +- lib/srv/db/redis/engine.go | 4 +- lib/srv/db/secrets/aws_secrets_manager.go | 2 +- lib/srv/discovery/common/renaming_test.go | 4 +- lib/srv/discovery/common/server.go | 28 -- lib/srv/discovery/common/server_test.go | 252 ------------------ .../discovery/fetchers/aws-sync/aws-sync.go | 4 +- lib/srv/discovery/fetchers/db/aws_docdb.go | 14 +- .../discovery/fetchers/db/aws_elasticache.go | 8 +- lib/srv/discovery/fetchers/db/aws_memorydb.go | 4 +- .../discovery/fetchers/db/aws_opensearch.go | 4 +- lib/srv/discovery/fetchers/db/aws_rds.go | 4 +- .../discovery/fetchers/db/aws_rds_proxy.go | 6 +- lib/srv/discovery/fetchers/db/aws_redshift.go | 2 +- .../fetchers/db/aws_redshift_serverless.go | 4 +- .../db/aws_redshift_serverless_test.go | 6 +- 37 files changed, 226 insertions(+), 617 deletions(-) delete mode 100644 lib/cloud/mocks/aws.go diff --git a/lib/cloud/aws/errors.go b/lib/cloud/aws/errors.go index 7722e7515bc1f..6daaea372c061 100644 --- a/lib/cloud/aws/errors.go +++ b/lib/cloud/aws/errors.go @@ -26,30 +26,16 @@ import ( awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" ecstypes "github.com/aws/aws-sdk-go-v2/service/ecs/types" iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/gravitational/trace" ) -// ConvertRequestFailureError converts `err` into AWS errors to trace errors. -// If the provided error is not a [awserr.RequestFailure] it delegates -// error conversion to [ConvertRequestFailureErrorV2] for SDK v2 compatibility. -// Prefer using [ConvertRequestFailureErrorV2] directly for AWS SDK v2 client -// errors. -func ConvertRequestFailureError(err error) error { - var requestErr awserr.RequestFailure - if errors.As(err, &requestErr) { - return convertRequestFailureErrorFromStatusCode(requestErr.StatusCode(), requestErr) - } - return ConvertRequestFailureErrorV2(err) -} - -// ConvertRequestFailureErrorV2 converts AWS SDK v2 errors to trace errors. +// ConvertRequestFailureError converts AWS SDK v2 errors to trace errors. // If the provided error is not a [awshttp.ResponseError] it returns the error // without modifying it. -func ConvertRequestFailureErrorV2(err error) error { +func ConvertRequestFailureError(err error) error { var re *awshttp.ResponseError if errors.As(err, &re) { - return convertRequestFailureErrorFromStatusCode(re.HTTPStatusCode(), re.Err) + return convertRequestFailureErrorFromStatusCode(re.HTTPStatusCode(), re) } return err } @@ -107,5 +93,5 @@ func ConvertIAMError(err error) error { return trace.BadParameter(*malformedPolicyDocument.Message) } - return ConvertRequestFailureErrorV2(err) + return ConvertRequestFailureError(err) } diff --git a/lib/cloud/aws/errors_test.go b/lib/cloud/aws/errors_test.go index 8e28e6cb0cf64..eb666ef477ccd 100644 --- a/lib/cloud/aws/errors_test.go +++ b/lib/cloud/aws/errors_test.go @@ -23,10 +23,9 @@ import ( "net/http" "testing" + "github.com/aws/aws-sdk-go-v2/aws" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" smithyhttp "github.com/aws/smithy-go/transport/http" "github.com/gravitational/trace" "github.com/stretchr/testify/require" @@ -37,6 +36,18 @@ func TestConvertRequestFailureError(t *testing.T) { fakeRequestID := "11111111-2222-3333-3333-333333333334" + newResponseError := func(code int) error { + return &awshttp.ResponseError{ + RequestID: fakeRequestID, + ResponseError: &smithyhttp.ResponseError{ + Response: &smithyhttp.Response{Response: &http.Response{ + StatusCode: code, + }}, + Err: trace.Errorf("inner"), + }, + } + } + tests := []struct { name string inputError error @@ -45,49 +56,46 @@ func TestConvertRequestFailureError(t *testing.T) { }{ { name: "StatusForbidden", - inputError: awserr.NewRequestFailure(awserr.New("code", "message", nil), http.StatusForbidden, fakeRequestID), + inputError: newResponseError(http.StatusForbidden), wantIsError: trace.IsAccessDenied, }, { name: "StatusConflict", - inputError: awserr.NewRequestFailure(awserr.New("code", "message", nil), http.StatusConflict, fakeRequestID), + inputError: newResponseError(http.StatusConflict), wantIsError: trace.IsAlreadyExists, }, { name: "StatusNotFound", - inputError: awserr.NewRequestFailure(awserr.New("code", "message", nil), http.StatusNotFound, fakeRequestID), + inputError: newResponseError(http.StatusNotFound), wantIsError: trace.IsNotFound, }, { name: "StatusBadRequest", - inputError: awserr.NewRequestFailure(awserr.New("code", "message", nil), http.StatusBadRequest, fakeRequestID), - wantUnmodified: true, - }, - { - name: "StatusBadRequest with AccessDeniedException", - inputError: awserr.NewRequestFailure(awserr.New("AccessDeniedException", "message", nil), http.StatusBadRequest, fakeRequestID), - wantIsError: trace.IsAccessDenied, - }, - { - name: "not AWS error", - inputError: errors.New("not-aws-error"), + inputError: newResponseError(http.StatusBadRequest), wantUnmodified: true, }, { - name: "v2 sdk error", + name: "StatusBadRequest with AccessDeniedException", inputError: &awshttp.ResponseError{ + RequestID: fakeRequestID, ResponseError: &smithyhttp.ResponseError{ Response: &smithyhttp.Response{Response: &http.Response{ - StatusCode: http.StatusNotFound, + StatusCode: http.StatusBadRequest, }}, - Err: trace.Errorf(""), + Err: trace.Errorf("AccessDeniedException"), }, }, - wantIsError: trace.IsNotFound, + wantIsError: trace.IsAccessDenied, + }, + { + name: "not AWS error", + inputError: errors.New("not-aws-error"), + wantUnmodified: true, }, { name: "v2 sdk error for ecs ClusterNotFoundException", inputError: &awshttp.ResponseError{ + RequestID: fakeRequestID, ResponseError: &smithyhttp.ResponseError{ Response: &smithyhttp.Response{Response: &http.Response{ StatusCode: http.StatusBadRequest, diff --git a/lib/cloud/aws/identity.go b/lib/cloud/aws/identity.go index 8ecad2747887e..05d36b7aceb46 100644 --- a/lib/cloud/aws/identity.go +++ b/lib/cloud/aws/identity.go @@ -24,11 +24,8 @@ import ( "strings" awsv2 "github.com/aws/aws-sdk-go-v2/aws" - stsv2 "github.com/aws/aws-sdk-go-v2/service/sts" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" - "github.com/aws/aws-sdk-go/service/sts" - "github.com/aws/aws-sdk-go/service/sts/stsiface" + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/gravitational/trace" ) @@ -109,23 +106,12 @@ func (i identityBase) String() string { } type callerIdentityGetter interface { - GetCallerIdentity(ctx context.Context, params *stsv2.GetCallerIdentityInput, optFns ...func(*stsv2.Options)) (*stsv2.GetCallerIdentityOutput, error) + GetCallerIdentity(ctx context.Context, params *sts.GetCallerIdentityInput, optFns ...func(*sts.Options)) (*sts.GetCallerIdentityOutput, error) } // GetIdentityWithClient determines AWS identity of this Teleport process // using the provided STS API client. -func GetIdentityWithClient(ctx context.Context, stsClient stsiface.STSAPI) (Identity, error) { - out, err := stsClient.GetCallerIdentityWithContext(ctx, &sts.GetCallerIdentityInput{}) - if err != nil { - return nil, trace.Wrap(err) - } - - return IdentityFromArn(aws.StringValue(out.Arn)) -} - -// GetIdentityWithClient determines AWS identity of this Teleport process -// using the provided STS API client. -func GetIdentityWithClientV2(ctx context.Context, clt callerIdentityGetter) (Identity, error) { +func GetIdentityWithClient(ctx context.Context, clt callerIdentityGetter) (Identity, error) { out, err := clt.GetCallerIdentity(ctx, nil) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/cloud/aws/identity_test.go b/lib/cloud/aws/identity_test.go index 20f11f04204dd..747ef265b5daf 100644 --- a/lib/cloud/aws/identity_test.go +++ b/lib/cloud/aws/identity_test.go @@ -22,11 +22,9 @@ import ( "context" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/sts" - "github.com/aws/aws-sdk-go/service/sts/stsiface" "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/lib/cloud/mocks" ) // TestGetIdentity verifies parsing of AWS identity received from STS API. @@ -79,7 +77,7 @@ func TestGetIdentity(t *testing.T) { } for _, test := range tests { t.Run(test.description, func(t *testing.T) { - identity, err := GetIdentityWithClient(context.Background(), &stsMock{arn: test.inARN}) + identity, err := GetIdentityWithClient(context.Background(), &mocks.STSClient{ARN: test.inARN}) require.NoError(t, err) require.IsType(t, test.outIdentity, identity) require.Equal(t, test.outName, identity.GetName()) @@ -89,14 +87,3 @@ func TestGetIdentity(t *testing.T) { }) } } - -type stsMock struct { - stsiface.STSAPI - arn string -} - -func (m *stsMock) GetCallerIdentityWithContext(aws.Context, *sts.GetCallerIdentityInput, ...request.Option) (*sts.GetCallerIdentityOutput, error) { - return &sts.GetCallerIdentityOutput{ - Arn: aws.String(m.arn), - }, nil -} diff --git a/lib/cloud/aws/policy_statements.go b/lib/cloud/aws/policy_statements.go index d266bed81a088..4289774a70a26 100644 --- a/lib/cloud/aws/policy_statements.go +++ b/lib/cloud/aws/policy_statements.go @@ -21,7 +21,7 @@ package aws import ( "fmt" - "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/gravitational/trace" "github.com/gravitational/teleport/api/types" diff --git a/lib/cloud/aws/policy_test.go b/lib/cloud/aws/policy_test.go index d9085a7f586a3..2efa2d0fcd3be 100644 --- a/lib/cloud/aws/policy_test.go +++ b/lib/cloud/aws/policy_test.go @@ -26,9 +26,9 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/iam" iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types" - "github.com/aws/aws-sdk-go/aws/arn" "github.com/google/go-cmp/cmp" "github.com/gravitational/trace" "github.com/stretchr/testify/require" diff --git a/lib/cloud/mocks/aws.go b/lib/cloud/mocks/aws.go deleted file mode 100644 index d48050dc5f373..0000000000000 --- a/lib/cloud/mocks/aws.go +++ /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 . - */ - -package mocks - -import ( - "context" - "net/http" - "net/url" - "slices" - "sync" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/sts" - "github.com/aws/aws-sdk-go/service/sts/stsiface" -) - -// STSClientV1 mocks AWS STS API for AWS SDK v1. -type STSClientV1 struct { - stsiface.STSAPI - ARN string - URL *url.URL - assumedRoleARNs []string - assumedRoleExternalIDs []string - mu sync.Mutex -} - -func (m *STSClientV1) GetAssumedRoleARNs() []string { - m.mu.Lock() - defer m.mu.Unlock() - return m.assumedRoleARNs -} - -func (m *STSClientV1) GetAssumedRoleExternalIDs() []string { - m.mu.Lock() - defer m.mu.Unlock() - return m.assumedRoleExternalIDs -} - -func (m *STSClientV1) ResetAssumeRoleHistory() { - m.mu.Lock() - defer m.mu.Unlock() - m.assumedRoleARNs = nil - m.assumedRoleExternalIDs = nil -} - -func (m *STSClientV1) GetCallerIdentityWithContext(aws.Context, *sts.GetCallerIdentityInput, ...request.Option) (*sts.GetCallerIdentityOutput, error) { - return &sts.GetCallerIdentityOutput{ - Arn: aws.String(m.ARN), - }, nil -} - -func (m *STSClientV1) AssumeRole(in *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) { - return m.AssumeRoleWithContext(context.Background(), in) -} - -func (m *STSClientV1) AssumeRoleWithContext(ctx aws.Context, in *sts.AssumeRoleInput, _ ...request.Option) (*sts.AssumeRoleOutput, error) { - m.mu.Lock() - defer m.mu.Unlock() - if !slices.Contains(m.assumedRoleARNs, aws.StringValue(in.RoleArn)) { - m.assumedRoleARNs = append(m.assumedRoleARNs, aws.StringValue(in.RoleArn)) - m.assumedRoleExternalIDs = append(m.assumedRoleExternalIDs, aws.StringValue(in.ExternalId)) - } - expiry := time.Now().Add(60 * time.Minute) - return &sts.AssumeRoleOutput{ - Credentials: &sts.Credentials{ - AccessKeyId: aws.String("FAKEACCESSKEYID"), - SecretAccessKey: aws.String("secret"), - SessionToken: aws.String("token"), - Expiration: &expiry, - }, - }, nil -} - -func (m *STSClientV1) GetCallerIdentityRequest(req *sts.GetCallerIdentityInput) (*request.Request, *sts.GetCallerIdentityOutput) { - return &request.Request{ - HTTPRequest: &http.Request{ - Header: http.Header{}, - URL: m.URL, - }, - Operation: &request.Operation{ - Name: "GetCallerIdentity", - HTTPMethod: "POST", - HTTPPath: "/", - }, - Handlers: request.Handlers{}, - }, nil -} diff --git a/lib/cloud/mocks/aws_rds.go b/lib/cloud/mocks/aws_rds.go index 9338b8330dc5f..ae023e1db787a 100644 --- a/lib/cloud/mocks/aws_rds.go +++ b/lib/cloud/mocks/aws_rds.go @@ -22,11 +22,11 @@ import ( "context" "fmt" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/rds" rdsv2 "github.com/aws/aws-sdk-go-v2/service/rds" rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" "github.com/google/uuid" "github.com/gravitational/trace" @@ -55,19 +55,19 @@ func (c *RDSClient) DescribeDBInstances(_ context.Context, input *rdsv2.Describe if err != nil { return nil, trace.Wrap(err) } - if aws.StringValue(input.DBInstanceIdentifier) == "" { + if aws.ToString(input.DBInstanceIdentifier) == "" { return &rdsv2.DescribeDBInstancesOutput{ DBInstances: instances, }, nil } for _, instance := range instances { - if aws.StringValue(instance.DBInstanceIdentifier) == aws.StringValue(input.DBInstanceIdentifier) { + if aws.ToString(instance.DBInstanceIdentifier) == aws.ToString(input.DBInstanceIdentifier) { return &rdsv2.DescribeDBInstancesOutput{ DBInstances: []rdstypes.DBInstance{instance}, }, nil } } - return nil, trace.NotFound("instance %v not found", aws.StringValue(input.DBInstanceIdentifier)) + return nil, trace.NotFound("instance %v not found", aws.ToString(input.DBInstanceIdentifier)) } func (c *RDSClient) DescribeDBClusters(_ context.Context, input *rdsv2.DescribeDBClustersInput, _ ...func(*rdsv2.Options)) (*rdsv2.DescribeDBClustersOutput, error) { @@ -82,19 +82,19 @@ func (c *RDSClient) DescribeDBClusters(_ context.Context, input *rdsv2.DescribeD if err != nil { return nil, trace.Wrap(err) } - if aws.StringValue(input.DBClusterIdentifier) == "" { + if aws.ToString(input.DBClusterIdentifier) == "" { return &rdsv2.DescribeDBClustersOutput{ DBClusters: clusters, }, nil } for _, cluster := range clusters { - if aws.StringValue(cluster.DBClusterIdentifier) == aws.StringValue(input.DBClusterIdentifier) { + if aws.ToString(cluster.DBClusterIdentifier) == aws.ToString(input.DBClusterIdentifier) { return &rdsv2.DescribeDBClustersOutput{ DBClusters: []rdstypes.DBCluster{cluster}, }, nil } } - return nil, trace.NotFound("cluster %v not found", aws.StringValue(input.DBClusterIdentifier)) + return nil, trace.NotFound("cluster %v not found", aws.ToString(input.DBClusterIdentifier)) } func (c *RDSClient) ModifyDBInstance(ctx context.Context, input *rdsv2.ModifyDBInstanceInput, optFns ...func(*rdsv2.Options)) (*rdsv2.ModifyDBInstanceOutput, error) { @@ -103,8 +103,8 @@ func (c *RDSClient) ModifyDBInstance(ctx context.Context, input *rdsv2.ModifyDBI } for i, instance := range c.DBInstances { - if aws.StringValue(instance.DBInstanceIdentifier) == aws.StringValue(input.DBInstanceIdentifier) { - if aws.BoolValue(input.EnableIAMDatabaseAuthentication) { + if aws.ToString(instance.DBInstanceIdentifier) == aws.ToString(input.DBInstanceIdentifier) { + if aws.ToBool(input.EnableIAMDatabaseAuthentication) { c.DBInstances[i].IAMDatabaseAuthenticationEnabled = aws.Bool(true) } return &rdsv2.ModifyDBInstanceOutput{ @@ -112,7 +112,7 @@ func (c *RDSClient) ModifyDBInstance(ctx context.Context, input *rdsv2.ModifyDBI }, nil } } - return nil, trace.NotFound("instance %v not found", aws.StringValue(input.DBInstanceIdentifier)) + return nil, trace.NotFound("instance %v not found", aws.ToString(input.DBInstanceIdentifier)) } func (c *RDSClient) ModifyDBCluster(ctx context.Context, input *rdsv2.ModifyDBClusterInput, optFns ...func(*rdsv2.Options)) (*rdsv2.ModifyDBClusterOutput, error) { @@ -121,8 +121,8 @@ func (c *RDSClient) ModifyDBCluster(ctx context.Context, input *rdsv2.ModifyDBCl } for i, cluster := range c.DBClusters { - if aws.StringValue(cluster.DBClusterIdentifier) == aws.StringValue(input.DBClusterIdentifier) { - if aws.BoolValue(input.EnableIAMDatabaseAuthentication) { + if aws.ToString(cluster.DBClusterIdentifier) == aws.ToString(input.DBClusterIdentifier) { + if aws.ToBool(input.EnableIAMDatabaseAuthentication) { c.DBClusters[i].IAMDatabaseAuthenticationEnabled = aws.Bool(true) } return &rdsv2.ModifyDBClusterOutput{ @@ -130,7 +130,7 @@ func (c *RDSClient) ModifyDBCluster(ctx context.Context, input *rdsv2.ModifyDBCl }, nil } } - return nil, trace.NotFound("cluster %v not found", aws.StringValue(input.DBClusterIdentifier)) + return nil, trace.NotFound("cluster %v not found", aws.ToString(input.DBClusterIdentifier)) } func (c *RDSClient) DescribeDBProxies(_ context.Context, input *rdsv2.DescribeDBProxiesInput, _ ...func(*rdsv2.Options)) (*rdsv2.DescribeDBProxiesOutput, error) { @@ -138,19 +138,19 @@ func (c *RDSClient) DescribeDBProxies(_ context.Context, input *rdsv2.DescribeDB return nil, trace.AccessDenied("unauthorized") } - if aws.StringValue(input.DBProxyName) == "" { + if aws.ToString(input.DBProxyName) == "" { return &rdsv2.DescribeDBProxiesOutput{ DBProxies: c.DBProxies, }, nil } for _, dbProxy := range c.DBProxies { - if aws.StringValue(dbProxy.DBProxyName) == aws.StringValue(input.DBProxyName) { + if aws.ToString(dbProxy.DBProxyName) == aws.ToString(input.DBProxyName) { return &rdsv2.DescribeDBProxiesOutput{ DBProxies: []rdstypes.DBProxy{dbProxy}, }, nil } } - return nil, trace.NotFound("proxy %v not found", aws.StringValue(input.DBProxyName)) + return nil, trace.NotFound("proxy %v not found", aws.ToString(input.DBProxyName)) } func (c *RDSClient) DescribeDBProxyEndpoints(_ context.Context, input *rdsv2.DescribeDBProxyEndpointsInput, _ ...func(*rdsv2.Options)) (*rdsv2.DescribeDBProxyEndpointsOutput, error) { @@ -158,8 +158,8 @@ func (c *RDSClient) DescribeDBProxyEndpoints(_ context.Context, input *rdsv2.Des return nil, trace.AccessDenied("unauthorized") } - inputProxyName := aws.StringValue(input.DBProxyName) - inputProxyEndpointName := aws.StringValue(input.DBProxyEndpointName) + inputProxyName := aws.ToString(input.DBProxyName) + inputProxyEndpointName := aws.ToString(input.DBProxyEndpointName) if inputProxyName == "" && inputProxyEndpointName == "" { return &rdsv2.DescribeDBProxyEndpointsOutput{ @@ -170,19 +170,19 @@ func (c *RDSClient) DescribeDBProxyEndpoints(_ context.Context, input *rdsv2.Des var endpoints []rdstypes.DBProxyEndpoint for _, dbProxyEndpoiont := range c.DBProxyEndpoints { if inputProxyEndpointName != "" && - inputProxyEndpointName != aws.StringValue(dbProxyEndpoiont.DBProxyEndpointName) { + inputProxyEndpointName != aws.ToString(dbProxyEndpoiont.DBProxyEndpointName) { continue } if inputProxyName != "" && - inputProxyName != aws.StringValue(dbProxyEndpoiont.DBProxyName) { + inputProxyName != aws.ToString(dbProxyEndpoiont.DBProxyName) { continue } endpoints = append(endpoints, dbProxyEndpoiont) } if len(endpoints) == 0 { - return nil, trace.NotFound("proxy endpoint %v not found", aws.StringValue(input.DBProxyEndpointName)) + return nil, trace.NotFound("proxy endpoint %v not found", aws.ToString(input.DBProxyEndpointName)) } return &rdsv2.DescribeDBProxyEndpointsOutput{DBProxyEndpoints: endpoints}, nil } @@ -198,10 +198,10 @@ func checkEngineFilters(filters []rdstypes.Filter, engineVersions []rdstypes.DBE } recognizedEngines := make(map[string]struct{}) for _, e := range engineVersions { - recognizedEngines[aws.StringValue(e.Engine)] = struct{}{} + recognizedEngines[aws.ToString(e.Engine)] = struct{}{} } for _, f := range filters { - if aws.StringValue(f.Name) != "engine" { + if aws.ToString(f.Name) != "engine" { continue } for _, v := range f.Values { @@ -261,7 +261,7 @@ func clusterIdentifierFilterSet(filters []rdstypes.Filter) map[string]struct{} { func filterValues(filters []rdstypes.Filter, filterKey string) map[string]struct{} { out := make(map[string]struct{}) for _, f := range filters { - if aws.StringValue(f.Name) != filterKey { + if aws.ToString(f.Name) != filterKey { continue } for _, v := range f.Values { @@ -273,19 +273,19 @@ func filterValues(filters []rdstypes.Filter, filterKey string) map[string]struct // instanceEngineMatches returns whether an RDS DBInstance engine matches any engine name in a filter set. func instanceEngineMatches(instance rdstypes.DBInstance, filterSet map[string]struct{}) bool { - _, ok := filterSet[aws.StringValue(instance.Engine)] + _, ok := filterSet[aws.ToString(instance.Engine)] return ok } // instanceClusterIDMatches returns whether an RDS DBInstance ClusterID matches any ClusterID in a filter set. func instanceClusterIDMatches(instance rdstypes.DBInstance, filterSet map[string]struct{}) bool { - _, ok := filterSet[aws.StringValue(instance.DBClusterIdentifier)] + _, ok := filterSet[aws.ToString(instance.DBClusterIdentifier)] return ok } // clusterEngineMatches returns whether an RDS DBCluster engine matches any engine name in a filter set. func clusterEngineMatches(cluster rdstypes.DBCluster, filterSet map[string]struct{}) bool { - _, ok := filterSet[aws.StringValue(cluster.Engine)] + _, ok := filterSet[aws.ToString(cluster.Engine)] return ok } @@ -340,7 +340,7 @@ func WithRDSClusterReader(cluster *rdstypes.DBCluster) { func WithRDSClusterCustomEndpoint(name string) func(*rdstypes.DBCluster) { return func(cluster *rdstypes.DBCluster) { - parsed, _ := arn.Parse(aws.StringValue(cluster.DBClusterArn)) + parsed, _ := arn.Parse(aws.ToString(cluster.DBClusterArn)) cluster.CustomEndpoints = append(cluster.CustomEndpoints, fmt.Sprintf("%v.cluster-custom-aabbccdd.%v.rds.amazonaws.com", name, parsed.Region), ) diff --git a/lib/cloud/mocks/aws_redshift_serverless.go b/lib/cloud/mocks/aws_redshift_serverless.go index c22afed51af4c..3720f5c0e9302 100644 --- a/lib/cloud/mocks/aws_redshift_serverless.go +++ b/lib/cloud/mocks/aws_redshift_serverless.go @@ -23,9 +23,9 @@ import ( "fmt" "time" + "github.com/aws/aws-sdk-go-v2/aws" rss "github.com/aws/aws-sdk-go-v2/service/redshiftserverless" rsstypes "github.com/aws/aws-sdk-go-v2/service/redshiftserverless/types" - "github.com/aws/aws-sdk-go/aws" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" ) @@ -44,13 +44,13 @@ func (m RedshiftServerlessClient) GetWorkgroup(_ context.Context, input *rss.Get } for _, workgroup := range m.Workgroups { - if aws.StringValue(workgroup.WorkgroupName) == aws.StringValue(input.WorkgroupName) { + if aws.ToString(workgroup.WorkgroupName) == aws.ToString(input.WorkgroupName) { return &rss.GetWorkgroupOutput{ Workgroup: &workgroup, }, nil } } - return nil, trace.NotFound("workgroup %q not found", aws.StringValue(input.WorkgroupName)) + return nil, trace.NotFound("workgroup %q not found", aws.ToString(input.WorkgroupName)) } func (m RedshiftServerlessClient) GetEndpointAccess(_ context.Context, input *rss.GetEndpointAccessInput, _ ...func(*rss.Options)) (*rss.GetEndpointAccessOutput, error) { @@ -58,13 +58,13 @@ func (m RedshiftServerlessClient) GetEndpointAccess(_ context.Context, input *rs return nil, trace.AccessDenied("unauthorized") } for _, endpoint := range m.Endpoints { - if aws.StringValue(endpoint.EndpointName) == aws.StringValue(input.EndpointName) { + if aws.ToString(endpoint.EndpointName) == aws.ToString(input.EndpointName) { return &rss.GetEndpointAccessOutput{ Endpoint: &endpoint, }, nil } } - return nil, trace.NotFound("endpoint %q not found", aws.StringValue(input.EndpointName)) + return nil, trace.NotFound("endpoint %q not found", aws.ToString(input.EndpointName)) } func (m RedshiftServerlessClient) ListWorkgroups(_ context.Context, input *rss.ListWorkgroupsInput, _ ...func(*rss.Options)) (*rss.ListWorkgroupsOutput, error) { @@ -93,7 +93,7 @@ func (m RedshiftServerlessClient) ListTagsForResource(_ context.Context, input * return &rss.ListTagsForResourceOutput{}, nil } return &rss.ListTagsForResourceOutput{ - Tags: m.TagsByARN[aws.StringValue(input.ResourceArn)], + Tags: m.TagsByARN[aws.ToString(input.ResourceArn)], }, nil } diff --git a/lib/cloud/mocks/aws_sts.go b/lib/cloud/mocks/aws_sts.go index 09ae2796d194d..56a5e8459cfd3 100644 --- a/lib/cloud/mocks/aws_sts.go +++ b/lib/cloud/mocks/aws_sts.go @@ -20,7 +20,9 @@ package mocks import ( "context" + "net/url" "slices" + "sync" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -32,19 +34,13 @@ import ( "github.com/gravitational/teleport/lib/cloud/awsconfig" ) -// STSClient mocks the AWS STS API for AWS SDK v1 and v2. -// Callers can use it in tests for both the v1 and v2 interfaces. -// This is useful when some services still use SDK v1 while others use v2 SDK, -// so that all assumed roles can be recorded in one place. -// For example: -// -// clt := &STSClient{} -// a.stsClientV1 = &clt.STSClientV1 -// b.stsClientV2 = clt -// ... -// gotRoles := clt.GetAssumedRoleARNs() // returns roles that were assumed with either v1 or v2 client. +// STSClient mocks the AWS STS API for AWS SDK v2. type STSClient struct { - STSClientV1 + ARN string + URL *url.URL + assumedRoleARNs []string + assumedRoleExternalIDs []string + mu sync.Mutex Unauth bool // credentialProvider is only set when a chain of assumed roles is used. @@ -117,8 +113,8 @@ func (m *STSClient) record(roleARN, externalID string) { m.recordFn(roleARN, externalID) return } - m.STSClientV1.mu.Lock() - defer m.STSClientV1.mu.Unlock() + m.mu.Lock() + defer m.mu.Unlock() if !slices.Contains(m.assumedRoleARNs, roleARN) { m.assumedRoleARNs = append(m.assumedRoleARNs, roleARN) m.assumedRoleExternalIDs = append(m.assumedRoleExternalIDs, externalID) @@ -141,3 +137,22 @@ func newAssumeRoleClientProviderFunc(base *STSClient) awsconfig.STSClientProvide return base } } + +func (m *STSClient) GetAssumedRoleARNs() []string { + m.mu.Lock() + defer m.mu.Unlock() + return m.assumedRoleARNs +} + +func (m *STSClient) GetAssumedRoleExternalIDs() []string { + m.mu.Lock() + defer m.mu.Unlock() + return m.assumedRoleExternalIDs +} + +func (m *STSClient) ResetAssumeRoleHistory() { + m.mu.Lock() + defer m.mu.Unlock() + m.assumedRoleARNs = nil + m.assumedRoleExternalIDs = nil +} diff --git a/lib/configurators/aws/aws.go b/lib/configurators/aws/aws.go index 6673b1fbe8519..c6ec812ded8ac 100644 --- a/lib/configurators/aws/aws.go +++ b/lib/configurators/aws/aws.go @@ -400,7 +400,7 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error { }) } if c.Identity == nil { - c.Identity, err = awslib.GetIdentityWithClientV2(context.Background(), c.stsClient) + c.Identity, err = awslib.GetIdentityWithClient(context.Background(), c.stsClient) if err != nil { return trace.Wrap(err) } diff --git a/lib/integrations/awsoidc/eks_enroll_clusters.go b/lib/integrations/awsoidc/eks_enroll_clusters.go index 66f647e7c1248..a38acf38360cf 100644 --- a/lib/integrations/awsoidc/eks_enroll_clusters.go +++ b/lib/integrations/awsoidc/eks_enroll_clusters.go @@ -539,7 +539,7 @@ func maybeAddAccessEntry(ctx context.Context, log *slog.Logger, clusterName, rol _, err = clt.CreateAccessEntry(ctx, createAccessEntryReq) if err != nil { - convertedError := awslib.ConvertRequestFailureErrorV2(err) + convertedError := awslib.ConvertRequestFailureError(err) if !trace.IsAccessDenied(convertedError) { return false, trace.Wrap(err) } diff --git a/lib/integrations/awsoidc/listdeployeddatabaseservice.go b/lib/integrations/awsoidc/listdeployeddatabaseservice.go index 4ac05bdbe2c3b..c15138a64a1e4 100644 --- a/lib/integrations/awsoidc/listdeployeddatabaseservice.go +++ b/lib/integrations/awsoidc/listdeployeddatabaseservice.go @@ -140,7 +140,7 @@ func ListDeployedDatabaseServices(ctx context.Context, clt ListDeployedDatabaseS listServicesOutput, err := clt.ListServices(ctx, listServicesInput) if err != nil { - convertedError := awslib.ConvertRequestFailureErrorV2(err) + convertedError := awslib.ConvertRequestFailureError(err) if trace.IsNotFound(convertedError) { return &ListDeployedDatabaseServicesResponse{}, nil } diff --git a/lib/srv/db/cloud/aws.go b/lib/srv/db/cloud/aws.go index 091f066cebe47..fe303654f7933 100644 --- a/lib/srv/db/cloud/aws.go +++ b/lib/srv/db/cloud/aws.go @@ -351,7 +351,7 @@ func (r *rdsDBConfigurator) enableIAMAuth(ctx context.Context, db types.Database EnableIAMDatabaseAuthentication: aws.Bool(true), ApplyImmediately: aws.Bool(true), }) - return awslib.ConvertRequestFailureErrorV2(err) + return awslib.ConvertRequestFailureError(err) } if meta.RDS.InstanceID != "" { _, err = clt.ModifyDBInstance(ctx, &rds.ModifyDBInstanceInput{ @@ -359,7 +359,7 @@ func (r *rdsDBConfigurator) enableIAMAuth(ctx context.Context, db types.Database EnableIAMDatabaseAuthentication: aws.Bool(true), ApplyImmediately: aws.Bool(true), }) - return awslib.ConvertRequestFailureErrorV2(err) + return awslib.ConvertRequestFailureError(err) } return nil } diff --git a/lib/srv/db/cloud/iam.go b/lib/srv/db/cloud/iam.go index dfea3893469bc..7baf562101e1f 100644 --- a/lib/srv/db/cloud/iam.go +++ b/lib/srv/db/cloud/iam.go @@ -20,12 +20,11 @@ package cloud import ( "context" - "errors" "log/slog" + "strings" "sync" "time" - "github.com/aws/aws-sdk-go/aws/credentials" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" @@ -264,7 +263,11 @@ func (c *IAM) getAWSIdentity(ctx context.Context, database types.Database) (awsl return nil, trace.Wrap(err) } clt := c.cfg.awsClients.getSTSClient(awsCfg) - awsIdentity, err := awslib.GetIdentityWithClientV2(ctx, clt) + _, err = awsCfg.Credentials.Retrieve(ctx) + if err != nil { + return nil, trace.Wrap(err, "failed to retrieve credentials") + } + awsIdentity, err := awslib.GetIdentityWithClient(ctx, clt) if err != nil { return nil, trace.Wrap(err) } @@ -298,9 +301,10 @@ func (c *IAM) processTask(ctx context.Context, task iamTask) error { configurator, err := c.getAWSConfigurator(ctx, task.database) if err != nil { c.iamPolicyStatus.Store(task.database.GetName(), types.IAMPolicyStatus_IAM_POLICY_STATUS_FAILED) - if errors.Is(trace.Unwrap(err), credentials.ErrNoValidProvidersFoundInChain) { - c.logger.WarnContext(ctx, "No AWS credentials provider, Skipping IAM task for database", + if strings.Contains(err.Error(), "failed to retrieve credentials") { + c.logger.WarnContext(ctx, "Failed to load AWS IAM configurator, skipping IAM task for database", "database", task.database.GetName(), + "error", err, ) return nil } diff --git a/lib/srv/db/cloud/iam_test.go b/lib/srv/db/cloud/iam_test.go index cae979ddaa360..23fd39378f060 100644 --- a/lib/srv/db/cloud/iam_test.go +++ b/lib/srv/db/cloud/iam_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/iam" iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types" rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" @@ -33,6 +34,7 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/auth/authclient" + "github.com/gravitational/teleport/lib/cloud/awsconfig" "github.com/gravitational/teleport/lib/cloud/mocks" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/services" @@ -58,9 +60,7 @@ func TestAWSIAM(t *testing.T) { // Configure mocks. stsClient := &mocks.STSClient{ - STSClientV1: mocks.STSClientV1{ - ARN: "arn:aws:iam::123456789012:role/test-role", - }, + ARN: "arn:aws:iam::123456789012:role/test-role", } clt := &mocks.RDSClient{ @@ -152,9 +152,10 @@ func TestAWSIAM(t *testing.T) { } configurator, err := NewIAM(ctx, IAMConfig{ AccessPoint: &mockAccessPoint{}, - AWSConfigProvider: &mocks.AWSConfigProvider{ - STSClient: stsClient, - }, + AWSConfigProvider: withStaticCredentials( + &mocks.AWSConfigProvider{ + STSClient: stsClient, + }), HostID: "host-id", onProcessedTask: func(iamTask, error) { taskChan <- struct{}{} @@ -289,9 +290,7 @@ func TestAWSIAMNoPermissions(t *testing.T) { // Create unauthorized mocks for AWS services. stsClient := &mocks.STSClient{ - STSClientV1: mocks.STSClientV1{ - ARN: "arn:aws:iam::123456789012:role/test-role", - }, + ARN: "arn:aws:iam::123456789012:role/test-role", } tests := []struct { name string @@ -361,9 +360,10 @@ func TestAWSIAMNoPermissions(t *testing.T) { configurator, err := NewIAM(ctx, IAMConfig{ AccessPoint: &mockAccessPoint{}, HostID: "host-id", - AWSConfigProvider: &mocks.AWSConfigProvider{ - STSClient: stsClient, - }, + AWSConfigProvider: withStaticCredentials( + &mocks.AWSConfigProvider{ + STSClient: stsClient, + }), awsClients: test.awsClients, }) require.NoError(t, err) @@ -425,3 +425,15 @@ func (m *mockAccessPoint) AcquireSemaphore(ctx context.Context, params types.Acq func (m *mockAccessPoint) CancelSemaphoreLease(ctx context.Context, lease types.SemaphoreLease) error { return nil } + +func withStaticCredentials(p awsconfig.Provider) awsconfig.Provider { + return awsconfig.ProviderFunc( + func(ctx context.Context, region string, optFns ...awsconfig.OptionsFn) (aws.Config, error) { + cfg, err := p.GetConfig(ctx, region, optFns...) + if err != nil { + return aws.Config{}, trace.Wrap(err) + } + cfg.Credentials = credentials.NewStaticCredentialsProvider("FAKE_ID", "FAKE_KEY", "FAKE_TOKEN") + return cfg, nil + }) +} diff --git a/lib/srv/db/cloud/resource_checker_credentials.go b/lib/srv/db/cloud/resource_checker_credentials.go index 1902a2d886ffe..1e3854d32bd97 100644 --- a/lib/srv/db/cloud/resource_checker_credentials.go +++ b/lib/srv/db/cloud/resource_checker_credentials.go @@ -121,7 +121,7 @@ func (c *credentialsChecker) getAWSIdentity(ctx context.Context, meta *types.AWS return nil, trace.Wrap(err) } client := c.awsClients.getSTSClient(awsCfg) - return aws.GetIdentityWithClientV2(ctx, client) + return aws.GetIdentityWithClient(ctx, client) }) return identity, trace.Wrap(err) } diff --git a/lib/srv/db/cloud/users/elasticache.go b/lib/srv/db/cloud/users/elasticache.go index 4e46bb5e4ab3d..6bbc2ecd27659 100644 --- a/lib/srv/db/cloud/users/elasticache.go +++ b/lib/srv/db/cloud/users/elasticache.go @@ -164,7 +164,7 @@ func (f *elastiCacheFetcher) getUsersForRegion(ctx context.Context, region strin for pager.HasMorePages() { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libaws.ConvertRequestFailureError(err)) } users = append(users, page.Users...) } @@ -185,7 +185,7 @@ func (f *elastiCacheFetcher) getUserTags(ctx context.Context, user *ectypes.User ResourceName: user.ARN, }) if err != nil { - return nil, trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libaws.ConvertRequestFailureError(err)) } return output.TagList, nil } @@ -256,7 +256,7 @@ func (r *elastiCacheUserResource) ModifyUserPassword(ctx context.Context, oldPas NoPasswordRequired: aws.Bool(len(passwords) == 0), } if _, err := r.client.ModifyUser(ctx, input); err != nil { - return trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return trace.Wrap(libaws.ConvertRequestFailureError(err)) } return nil } diff --git a/lib/srv/db/cloud/users/memorydb.go b/lib/srv/db/cloud/users/memorydb.go index 6b4c09b3561a7..ee41122c497cd 100644 --- a/lib/srv/db/cloud/users/memorydb.go +++ b/lib/srv/db/cloud/users/memorydb.go @@ -163,7 +163,7 @@ func (f *memoryDBFetcher) getUsersForRegion(ctx context.Context, region string, for i := 0; i < common.MaxPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libaws.ConvertRequestFailureError(err)) } users = append(users, page.Users...) } @@ -185,7 +185,7 @@ func (f *memoryDBFetcher) getUserTags(ctx context.Context, user *memorydbtypes.U ResourceArn: user.ARN, }) if err != nil { - return nil, trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libaws.ConvertRequestFailureError(err)) } return output.TagList, nil } @@ -245,7 +245,7 @@ func (r *memoryDBUserResource) ModifyUserPassword(ctx context.Context, oldPasswo input.AuthenticationMode.Passwords = append(input.AuthenticationMode.Passwords, newPassword) if _, err := r.client.UpdateUser(ctx, input); err != nil { - return trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return trace.Wrap(libaws.ConvertRequestFailureError(err)) } return nil } diff --git a/lib/srv/db/common/auth.go b/lib/srv/db/common/auth.go index 92b5c7a785c89..9fdd254521bca 100644 --- a/lib/srv/db/common/auth.go +++ b/lib/srv/db/common/auth.go @@ -35,12 +35,11 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/aws/aws-sdk-go-v2/aws" + v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" rdsauth "github.com/aws/aws-sdk-go-v2/feature/rds/auth" "github.com/aws/aws-sdk-go-v2/service/redshift" rss "github.com/aws/aws-sdk-go-v2/service/redshiftserverless" "github.com/aws/aws-sdk-go-v2/service/sts" - "github.com/aws/aws-sdk-go/aws/credentials" - v4 "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "golang.org/x/oauth2" @@ -63,12 +62,18 @@ import ( "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" awsutils "github.com/gravitational/teleport/lib/utils/aws" - "github.com/gravitational/teleport/lib/utils/aws/migration" ) -// azureVirtualMachineCacheTTL is the default TTL for Azure virtual machine -// cache entries. -const azureVirtualMachineCacheTTL = 5 * time.Minute +const ( + // azureVirtualMachineCacheTTL is the default TTL for Azure virtual machine + // cache entries. + azureVirtualMachineCacheTTL = 5 * time.Minute + + // emptyPayloadHash is the SHA-256 for an empty element (as in echo -n | sha256sum). + // PresignHTTP requires the hash of the body, but when there is no body we hash the empty string. + // https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html + emptyPayloadHash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +) // Auth defines interface for creating auth tokens and TLS configurations. type Auth interface { @@ -659,14 +664,14 @@ func (a *dbAuth) GetElastiCacheRedisToken(ctx context.Context, database types.Da tokenReq := &awsRedisIAMTokenRequest{ // For IAM-enabled ElastiCache users, the username and user id properties must be identical. // https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth-iam.html#auth-iam-limits - userID: databaseUser, - targetID: meta.ElastiCache.ReplicationGroupID, - serviceName: "elasticache", - region: meta.Region, - credentials: migration.NewCredentialsAdapter(awsCfg.Credentials), - clock: a.cfg.Clock, - } - token, err := tokenReq.toSignedRequestURI() + userID: databaseUser, + targetID: meta.ElastiCache.ReplicationGroupID, + serviceName: "elasticache", + region: meta.Region, + credProvider: awsCfg.Credentials, + clock: a.cfg.Clock, + } + token, err := tokenReq.toSignedRequestURI(ctx) return token, trace.Wrap(err) } @@ -685,14 +690,14 @@ func (a *dbAuth) GetMemoryDBToken(ctx context.Context, database types.Database, "database_user", databaseUser, ) tokenReq := &awsRedisIAMTokenRequest{ - userID: databaseUser, - targetID: meta.MemoryDB.ClusterName, - serviceName: "memorydb", - region: meta.Region, - credentials: migration.NewCredentialsAdapter(awsCfg.Credentials), - clock: a.cfg.Clock, - } - token, err := tokenReq.toSignedRequestURI() + userID: databaseUser, + targetID: meta.MemoryDB.ClusterName, + serviceName: "memorydb", + region: meta.Region, + credProvider: awsCfg.Credentials, + clock: a.cfg.Clock, + } + token, err := tokenReq.toSignedRequestURI(ctx) return token, trace.Wrap(err) } @@ -1158,7 +1163,7 @@ func (a *dbAuth) buildAWSRoleARNFromDatabaseUser(ctx context.Context, database t } clt := a.cfg.awsClients.getSTSClient(awsCfg) - identity, err := awslib.GetIdentityWithClientV2(ctx, clt) + identity, err := awslib.GetIdentityWithClient(ctx, clt) if err != nil { return "", trace.Wrap(err) } @@ -1270,8 +1275,8 @@ type awsRedisIAMTokenRequest struct { targetID string // region is the AWS region. region string - // credentials are used to presign with AWS SigV4. - credentials *credentials.Credentials + // credProvider are used to presign with AWS SigV4. + credProvider aws.CredentialsProvider // clock is the clock implementation. clock clockwork.Clock // serviceName is the AWS service name used for signing. @@ -1289,8 +1294,8 @@ func (r *awsRedisIAMTokenRequest) checkAndSetDefaults() error { if r.region == "" { return trace.BadParameter("missing region") } - if r.credentials == nil { - return trace.BadParameter("missing credentials") + if r.credProvider == nil { + return trace.BadParameter("missing credentials provider") } if r.serviceName == "" { return trace.BadParameter("missing service name") @@ -1304,7 +1309,7 @@ func (r *awsRedisIAMTokenRequest) checkAndSetDefaults() error { // toSignedRequestURI creates a new AWS SigV4 pre-signed request URI. // This pre-signed request URI can then be used to authenticate as an // ElastiCache Redis or MemoryDB user. -func (r *awsRedisIAMTokenRequest) toSignedRequestURI() (string, error) { +func (r *awsRedisIAMTokenRequest) toSignedRequestURI(ctx context.Context) (string, error) { if err := r.checkAndSetDefaults(); err != nil { return "", trace.Wrap(err) } @@ -1312,17 +1317,16 @@ func (r *awsRedisIAMTokenRequest) toSignedRequestURI() (string, error) { if err != nil { return "", trace.Wrap(err) } - s := v4.NewSigner(r.credentials) - _, err = s.Presign(req, nil, r.serviceName, r.region, time.Minute*15, r.clock.Now()) + signer := v4.NewSigner() + creds, err := r.credProvider.Retrieve(ctx) if err != nil { return "", trace.Wrap(err) } - res := url.URL{ - Host: req.URL.Host, - Path: "/", - RawQuery: req.URL.RawQuery, + signedURI, _, err := signer.PresignHTTP(ctx, creds, req, emptyPayloadHash, r.serviceName, r.region, r.clock.Now()) + if err != nil { + return "", trace.Wrap(err) } - return strings.TrimPrefix(res.String(), "//"), nil + return strings.TrimPrefix(signedURI, "http://"), nil } // getSignableRequest creates a new request suitable for pre-signing with SigV4. diff --git a/lib/srv/db/common/auth_test.go b/lib/srv/db/common/auth_test.go index 3fb9645b9dddf..499e2737f4f0f 100644 --- a/lib/srv/db/common/auth_test.go +++ b/lib/srv/db/common/auth_test.go @@ -659,10 +659,8 @@ func TestGetAWSIAMCreds(t *testing.T) { "username is partial role ARN": { db: newMongoAtlasDatabase(t, types.AWS{}), stsMock: &mocks.STSClient{ - STSClientV1: mocks.STSClientV1{ - // This is the role returned by the STS GetCallerIdentity. - ARN: "arn:aws:iam::222222222222:role/teleport-service-role", - }, + // This is the role returned by the STS GetCallerIdentity. + ARN: "arn:aws:iam::222222222222:role/teleport-service-role", }, username: "role/role-name", expectedAssumedRoles: []string{"arn:aws:iam::222222222222:role/role-name"}, @@ -682,9 +680,7 @@ func TestGetAWSIAMCreds(t *testing.T) { AssumeRoleARN: "arn:aws:iam::222222222222:role/teleport-service-role-external", }), stsMock: &mocks.STSClient{ - STSClientV1: mocks.STSClientV1{ - ARN: "arn:aws:iam::111111111111:role/teleport-service-role", - }, + ARN: "arn:aws:iam::111111111111:role/teleport-service-role", }, username: "role/role-name", expectedAssumedRoles: []string{ diff --git a/lib/srv/db/common/errors.go b/lib/srv/db/common/errors.go index 64d2980d65c1b..ef3bbb79f87a3 100644 --- a/lib/srv/db/common/errors.go +++ b/lib/srv/db/common/errors.go @@ -26,7 +26,6 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/go-mysql-org/go-mysql/mysql" "github.com/gravitational/trace" "github.com/jackc/pgconn" @@ -66,16 +65,13 @@ func ConvertError(err error) error { } var googleAPIErr *googleapi.Error - var awsRequestFailureErr awserr.RequestFailure - var awsRequestFailureErrV2 *awshttp.ResponseError + var awsRequestFailureErr *awshttp.ResponseError var azResponseErr *azcore.ResponseError var pgError *pgconn.PgError var myError *mysql.MyError switch err := trace.Unwrap(err); { case errors.As(err, &googleAPIErr): return convertGCPError(googleAPIErr) - case errors.As(err, &awsRequestFailureErrV2): - return awslib.ConvertRequestFailureErrorV2(awsRequestFailureErrV2) case errors.As(err, &awsRequestFailureErr): return awslib.ConvertRequestFailureError(awsRequestFailureErr) case errors.As(err, &azResponseErr): diff --git a/lib/srv/db/redis/engine.go b/lib/srv/db/redis/engine.go index 00142a4fdd92d..5644c452a0fe0 100644 --- a/lib/srv/db/redis/engine.go +++ b/lib/srv/db/redis/engine.go @@ -456,7 +456,7 @@ func (e *Engine) checkElastiCacheUserIAMAuthIsEnabled(ctx context.Context, awsMe input := elasticache.DescribeUsersInput{UserId: aws.String(username)} out, err := client.DescribeUsers(ctx, &input) if err != nil { - return false, trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return false, trace.Wrap(libaws.ConvertRequestFailureError(err)) } if len(out.Users) < 1 || out.Users[0].Authentication == nil { return false, nil @@ -477,7 +477,7 @@ func (e *Engine) checkMemoryDBUserIAMAuthIsEnabled(ctx context.Context, awsMeta input := memorydb.DescribeUsersInput{UserName: aws.String(username)} out, err := client.DescribeUsers(ctx, &input) if err != nil { - return false, trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return false, trace.Wrap(libaws.ConvertRequestFailureError(err)) } if len(out.Users) < 1 || out.Users[0].Authentication == nil { return false, nil diff --git a/lib/srv/db/secrets/aws_secrets_manager.go b/lib/srv/db/secrets/aws_secrets_manager.go index 70c96a326370d..81c1b867a768a 100644 --- a/lib/srv/db/secrets/aws_secrets_manager.go +++ b/lib/srv/db/secrets/aws_secrets_manager.go @@ -325,7 +325,7 @@ func convertSecretsManagerError(err error) error { } // Match by status code. - return trace.Wrap(libaws.ConvertRequestFailureErrorV2(err)) + return trace.Wrap(libaws.ConvertRequestFailureError(err)) } const ( diff --git a/lib/srv/discovery/common/renaming_test.go b/lib/srv/discovery/common/renaming_test.go index 7bb64f9f01bab..ae24023554742 100644 --- a/lib/srv/discovery/common/renaming_test.go +++ b/lib/srv/discovery/common/renaming_test.go @@ -27,9 +27,9 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/mysql/armmysqlflexibleservers" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/redis/armredis/v3" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/redisenterprise/armredisenterprise" + "github.com/aws/aws-sdk-go-v2/aws" ekstypes "github.com/aws/aws-sdk-go-v2/service/eks/types" rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" - "github.com/aws/aws-sdk-go/aws" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -505,7 +505,7 @@ func makeEKSKubeCluster(t *testing.T, name, region, accountID, overrideLabel str overrideLabel: name, }, } - kubeCluster, err := NewKubeClusterFromAWSEKS(aws.StringValue(eksCluster.Name), aws.StringValue(eksCluster.Arn), eksCluster.Tags) + kubeCluster, err := NewKubeClusterFromAWSEKS(aws.ToString(eksCluster.Name), aws.ToString(eksCluster.Arn), eksCluster.Tags) require.NoError(t, err) require.True(t, kubeCluster.IsAWS()) return kubeCluster diff --git a/lib/srv/discovery/common/server.go b/lib/srv/discovery/common/server.go index 78893f88aed5a..a13db6f29217a 100644 --- a/lib/srv/discovery/common/server.go +++ b/lib/srv/discovery/common/server.go @@ -21,7 +21,6 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" - ec2v1 "github.com/aws/aws-sdk-go/service/ec2" "github.com/gravitational/trace" "github.com/gravitational/teleport/api/types" @@ -76,30 +75,3 @@ func NewAWSNodeFromEC2Instance(instance ec2types.Instance, awsCloudMetadata *typ return server, nil } - -// NewAWSNodeFromEC2v1Instance creates a Node resource from an EC2 Instance. -// It has a pre-populated spec which contains info that is not available in the ec2.Instance object. -// Uses AWS SDK Go V1 -func NewAWSNodeFromEC2v1Instance(instance ec2v1.Instance, awsCloudMetadata *types.AWSInfo) (types.Server, error) { - server, err := NewAWSNodeFromEC2Instance(ec2InstanceV1ToV2(instance), awsCloudMetadata) - return server, trace.Wrap(err) -} - -func ec2InstanceV1ToV2(instance ec2v1.Instance) ec2types.Instance { - tags := make([]ec2types.Tag, 0, len(instance.Tags)) - for _, tag := range instance.Tags { - tags = append(tags, ec2types.Tag{ - Key: tag.Key, - Value: tag.Value, - }) - } - - return ec2types.Instance{ - InstanceId: instance.InstanceId, - VpcId: instance.VpcId, - SubnetId: instance.SubnetId, - PrivateIpAddress: instance.PrivateIpAddress, - PrivateDnsName: instance.PrivateDnsName, - Tags: tags, - } -} diff --git a/lib/srv/discovery/common/server_test.go b/lib/srv/discovery/common/server_test.go index 77eaa89ccddca..95de601ff95a6 100644 --- a/lib/srv/discovery/common/server_test.go +++ b/lib/srv/discovery/common/server_test.go @@ -23,7 +23,6 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" - ec2v1 "github.com/aws/aws-sdk-go/service/ec2" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/gravitational/trace" @@ -281,254 +280,3 @@ func TestNewAWSNodeFromEC2Instance(t *testing.T) { }) } } - -func TestNewAWSNodeFromEC2v1Instance(t *testing.T) { - isBadParameterErr := func(tt require.TestingT, err error, i ...any) { - require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) - } - - makeEC2Instance := func(fn func(*ec2v1.Instance)) ec2v1.Instance { - s := ec2v1.Instance{ - PrivateDnsName: aws.String("my-private-dns.compute.aws"), - InstanceId: aws.String("i-123456789abcedf"), - VpcId: aws.String("vpc-abcd"), - SubnetId: aws.String("subnet-123"), - PrivateIpAddress: aws.String("172.31.1.1"), - Tags: []*ec2v1.Tag{ - { - Key: aws.String("MyTag"), - Value: aws.String("MyTagValue"), - }, - }, - } - fn(&s) - return s - } - - for _, tt := range []struct { - name string - ec2Instance ec2v1.Instance - awsCloudMetadata *types.AWSInfo - errCheck require.ErrorAssertionFunc - expectedServer types.Server - }{ - { - name: "valid", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) {}), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: require.NoError, - expectedServer: &types.ServerV2{ - Kind: "node", - Version: "v2", - SubKind: "openssh-ec2-ice", - Metadata: types.Metadata{ - Labels: map[string]string{ - "account-id": "123456789012", - "region": "us-east-1", - "MyTag": "MyTagValue", - "teleport.dev/instance-id": "i-123456789abcedf", - "teleport.dev/account-id": "123456789012", - }, - Namespace: "default", - }, - Spec: types.ServerSpecV2{ - Addr: "172.31.1.1:22", - Hostname: "my-private-dns.compute.aws", - CloudMetadata: &types.CloudMetadata{ - AWS: &types.AWSInfo{ - AccountID: "123456789012", - InstanceID: "i-123456789abcedf", - Region: "us-east-1", - VPCID: "vpc-abcd", - SubnetID: "subnet-123", - Integration: "myintegration", - }, - }, - }, - }, - }, - - { - name: "valid with hostname override by tag", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) { - i.Tags = append(i.Tags, &ec2v1.Tag{ - Key: aws.String("TeleportHostname"), - Value: aws.String("my-custom-hostname"), - }) - }), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: require.NoError, - expectedServer: &types.ServerV2{ - Kind: "node", - Version: "v2", - SubKind: "openssh-ec2-ice", - Metadata: types.Metadata{ - Labels: map[string]string{ - "account-id": "123456789012", - "region": "us-east-1", - "MyTag": "MyTagValue", - "TeleportHostname": "my-custom-hostname", - "teleport.dev/instance-id": "i-123456789abcedf", - "teleport.dev/account-id": "123456789012", - }, - Namespace: "default", - }, - Spec: types.ServerSpecV2{ - Addr: "172.31.1.1:22", - Hostname: "my-custom-hostname", - CloudMetadata: &types.CloudMetadata{ - AWS: &types.AWSInfo{ - AccountID: "123456789012", - InstanceID: "i-123456789abcedf", - Region: "us-east-1", - VPCID: "vpc-abcd", - SubnetID: "subnet-123", - Integration: "myintegration", - }, - }, - }, - }, - }, - { - name: "instance metadata generated labels are not replaced by instance tags", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) { - i.Tags = append(i.Tags, &ec2v1.Tag{ - Key: aws.String("region"), - Value: aws.String("evil"), - }) - i.Tags = append(i.Tags, &ec2v1.Tag{ - Key: aws.String("account-id"), - Value: aws.String("evil"), - }) - }), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: require.NoError, - expectedServer: &types.ServerV2{ - Kind: "node", - Version: "v2", - SubKind: "openssh-ec2-ice", - Metadata: types.Metadata{ - Labels: map[string]string{ - "account-id": "123456789012", - "region": "us-east-1", - "MyTag": "MyTagValue", - "teleport.dev/instance-id": "i-123456789abcedf", - "teleport.dev/account-id": "123456789012", - }, - Namespace: "default", - }, - Spec: types.ServerSpecV2{ - Addr: "172.31.1.1:22", - Hostname: "my-private-dns.compute.aws", - CloudMetadata: &types.CloudMetadata{ - AWS: &types.AWSInfo{ - AccountID: "123456789012", - InstanceID: "i-123456789abcedf", - Region: "us-east-1", - VPCID: "vpc-abcd", - SubnetID: "subnet-123", - Integration: "myintegration", - }, - }, - }, - }, - }, - { - name: "missing ec2 private dns name", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) { - i.PrivateDnsName = nil - }), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: isBadParameterErr, - }, - { - name: "missing ec2 instance id", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) { - i.InstanceId = nil - }), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: isBadParameterErr, - }, - { - name: "missing ec2 vpc id", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) { - i.VpcId = nil - }), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: isBadParameterErr, - }, - { - name: "missing ec2 private ip address", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) { - i.PrivateDnsName = nil - }), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: isBadParameterErr, - }, - { - name: "missing account id", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) {}), - awsCloudMetadata: &types.AWSInfo{ - Region: "us-east-1", - Integration: "myintegration", - }, - errCheck: isBadParameterErr, - }, - { - name: "missing region", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) {}), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Integration: "myintegration", - }, - errCheck: isBadParameterErr, - }, - { - name: "missing integration name", - ec2Instance: makeEC2Instance(func(i *ec2v1.Instance) {}), - awsCloudMetadata: &types.AWSInfo{ - AccountID: "123456789012", - Region: "us-east-1", - }, - errCheck: isBadParameterErr, - }, - } { - t.Run(tt.name, func(t *testing.T) { - s, err := NewAWSNodeFromEC2v1Instance(tt.ec2Instance, tt.awsCloudMetadata) - tt.errCheck(t, err) - if err != nil { - return - } - - require.Empty(t, cmp.Diff(tt.expectedServer, s, cmpopts.IgnoreFields(types.ServerV2{}, "Metadata.Name"))) - }) - } -} diff --git a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go index 146637659bba7..6567158fbbe9a 100644 --- a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go +++ b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go @@ -362,8 +362,8 @@ func (a *Fetcher) poll(ctx context.Context, features Features) (*Resources, erro return result, trace.NewAggregate(errs...) } -// getAWSOptions returns a list of options to be used when -// creating AWS clients with the v2 sdk. +// getAWSOptions returns a list of options to be used when creating AWS clients +// with the v2 sdk. func (a *Fetcher) getAWSOptions() []awsconfig.OptionsFn { opts := []awsconfig.OptionsFn{ awsconfig.WithCredentialsMaybeIntegration(a.Config.Integration), diff --git a/lib/srv/discovery/fetchers/db/aws_docdb.go b/lib/srv/discovery/fetchers/db/aws_docdb.go index ef1920d83d6b8..8632df542d7fb 100644 --- a/lib/srv/discovery/fetchers/db/aws_docdb.go +++ b/lib/srv/discovery/fetchers/db/aws_docdb.go @@ -21,9 +21,9 @@ package db import ( "context" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/rds" rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types" - "github.com/aws/aws-sdk-go/aws" "github.com/gravitational/trace" "github.com/gravitational/teleport/api/types" @@ -64,22 +64,22 @@ func (f *rdsDocumentDBFetcher) GetDatabases(ctx context.Context, cfg *awsFetcher for _, cluster := range clusters { if !libcloudaws.IsDocumentDBClusterSupported(&cluster) { cfg.Logger.DebugContext(ctx, "DocumentDB cluster doesn't support IAM authentication. Skipping.", - "cluster", aws.StringValue(cluster.DBClusterIdentifier), - "engine_version", aws.StringValue(cluster.EngineVersion)) + "cluster", aws.ToString(cluster.DBClusterIdentifier), + "engine_version", aws.ToString(cluster.EngineVersion)) continue } if !libcloudaws.IsDBClusterAvailable(cluster.Status, cluster.DBClusterIdentifier) { cfg.Logger.DebugContext(ctx, "DocumentDB cluster is not available. Skipping.", - "cluster", aws.StringValue(cluster.DBClusterIdentifier), - "status", aws.StringValue(cluster.Status)) + "cluster", aws.ToString(cluster.DBClusterIdentifier), + "status", aws.ToString(cluster.Status)) continue } dbs, err := common.NewDatabasesFromDocumentDBCluster(&cluster) if err != nil { cfg.Logger.WarnContext(ctx, "Could not convert DocumentDB cluster to database resources.", - "cluster", aws.StringValue(cluster.DBClusterIdentifier), + "cluster", aws.ToString(cluster.DBClusterIdentifier), "error", err) } databases = append(databases, dbs...) @@ -101,7 +101,7 @@ func (f *rdsDocumentDBFetcher) getAllDBClusters(ctx context.Context, clt RDSClie for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } clusters = append(clusters, page.DBClusters...) } diff --git a/lib/srv/discovery/fetchers/db/aws_elasticache.go b/lib/srv/discovery/fetchers/db/aws_elasticache.go index b200e732e9b79..c5e417ed7c0f4 100644 --- a/lib/srv/discovery/fetchers/db/aws_elasticache.go +++ b/lib/srv/discovery/fetchers/db/aws_elasticache.go @@ -156,7 +156,7 @@ func getElastiCacheClusters(ctx context.Context, client ElastiCacheClient) ([]ec for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } out = append(out, page.ReplicationGroups...) } @@ -176,7 +176,7 @@ func getElastiCacheNodes(ctx context.Context, client ElastiCacheClient) ([]ectyp for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } // There are three types of ectypes.CacheCluster: // 1) a Memcache cluster. @@ -204,7 +204,7 @@ func getElastiCacheSubnetGroups(ctx context.Context, client ElastiCacheClient) ( for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } out = append(out, page.CacheSubnetGroups...) } @@ -219,7 +219,7 @@ func getElastiCacheResourceTags(ctx context.Context, client ElastiCacheClient, r } output, err := client.ListTagsForResource(ctx, input) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } return output.TagList, nil diff --git a/lib/srv/discovery/fetchers/db/aws_memorydb.go b/lib/srv/discovery/fetchers/db/aws_memorydb.go index d4ab6189c1e9b..92398f3191b74 100644 --- a/lib/srv/discovery/fetchers/db/aws_memorydb.go +++ b/lib/srv/discovery/fetchers/db/aws_memorydb.go @@ -140,7 +140,7 @@ func getMemoryDBClusters(ctx context.Context, client MemoryDBClient) ([]memorydb for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } out = append(out, page.Clusters...) } @@ -157,7 +157,7 @@ func getMemoryDBSubnetGroups(ctx context.Context, client MemoryDBClient) ([]memo for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } out = append(out, page.SubnetGroups...) } diff --git a/lib/srv/discovery/fetchers/db/aws_opensearch.go b/lib/srv/discovery/fetchers/db/aws_opensearch.go index cb92f78da8b61..cd9db40b4dfc1 100644 --- a/lib/srv/discovery/fetchers/db/aws_opensearch.go +++ b/lib/srv/discovery/fetchers/db/aws_opensearch.go @@ -111,7 +111,7 @@ func (f *openSearchPlugin) GetDatabases(ctx context.Context, cfg *awsFetcherConf func getOpenSearchDomains(ctx context.Context, client OpenSearchClient) ([]opensearchtypes.DomainStatus, error) { names, err := client.ListDomainNames(ctx, &opensearch.ListDomainNamesInput{}) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } req := &opensearch.DescribeDomainsInput{} @@ -132,7 +132,7 @@ func getOpenSearchDomains(ctx context.Context, client OpenSearchClient) ([]opens func getOpenSearchResourceTags(ctx context.Context, client OpenSearchClient, resourceARN *string) ([]opensearchtypes.Tag, error) { output, err := client.ListTags(ctx, &opensearch.ListTagsInput{ARN: resourceARN}) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } return output.TagList, nil diff --git a/lib/srv/discovery/fetchers/db/aws_rds.go b/lib/srv/discovery/fetchers/db/aws_rds.go index 1b438873c8726..1dbe6c0380da1 100644 --- a/lib/srv/discovery/fetchers/db/aws_rds.go +++ b/lib/srv/discovery/fetchers/db/aws_rds.go @@ -137,7 +137,7 @@ func getAllDBInstancesWithFilters(ctx context.Context, clt RDSClient, maxPages i out = instances return nil }) - return out, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return out, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } // newRDSAuroraClustersFetcher returns a new AWS fetcher for RDS Aurora @@ -231,7 +231,7 @@ func getAllDBClusters(ctx context.Context, clt RDSClient, maxPages int, logger * out = clusters return nil }) - return out, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return out, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } // rdsInstanceEngines returns engines to make sure DescribeDBInstances call returns diff --git a/lib/srv/discovery/fetchers/db/aws_rds_proxy.go b/lib/srv/discovery/fetchers/db/aws_rds_proxy.go index 59adf7f7f5b88..d297434e17200 100644 --- a/lib/srv/discovery/fetchers/db/aws_rds_proxy.go +++ b/lib/srv/discovery/fetchers/db/aws_rds_proxy.go @@ -145,7 +145,7 @@ func getRDSProxies(ctx context.Context, clt RDSClient, maxPages int) ([]rdstypes for i := 0; i < maxPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } rdsProxies = append(rdsProxies, page.DBProxies...) } @@ -165,7 +165,7 @@ func getRDSProxyCustomEndpoints(ctx context.Context, clt RDSClient, maxPages int for i := 0; i < maxPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } for _, customEndpoint := range page.DBProxyEndpoints { customEndpointsByProxyName[aws.ToString(customEndpoint.DBProxyName)] = append(customEndpointsByProxyName[aws.ToString(customEndpoint.DBProxyName)], customEndpoint) @@ -180,7 +180,7 @@ func listRDSResourceTags(ctx context.Context, clt RDSClient, resourceName *strin ResourceName: resourceName, }) if err != nil { - return nil, trace.Wrap(libcloudaws.ConvertRequestFailureErrorV2(err)) + return nil, trace.Wrap(libcloudaws.ConvertRequestFailureError(err)) } return output.TagList, nil } diff --git a/lib/srv/discovery/fetchers/db/aws_redshift.go b/lib/srv/discovery/fetchers/db/aws_redshift.go index ccfa726e36e9e..351d438bf68e1 100644 --- a/lib/srv/discovery/fetchers/db/aws_redshift.go +++ b/lib/srv/discovery/fetchers/db/aws_redshift.go @@ -100,7 +100,7 @@ func getRedshiftClusters(ctx context.Context, clt RedshiftClient) ([]redshifttyp for pageNum := 0; pageNum < maxAWSPages && pager.HasMorePages(); pageNum++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, libcloudaws.ConvertRequestFailureErrorV2(err) + return nil, libcloudaws.ConvertRequestFailureError(err) } clusters = append(clusters, page.Clusters...) } diff --git a/lib/srv/discovery/fetchers/db/aws_redshift_serverless.go b/lib/srv/discovery/fetchers/db/aws_redshift_serverless.go index 81dfb6cc27468..02cc5528e9683 100644 --- a/lib/srv/discovery/fetchers/db/aws_redshift_serverless.go +++ b/lib/srv/discovery/fetchers/db/aws_redshift_serverless.go @@ -197,7 +197,7 @@ func getRSSWorkgroups(ctx context.Context, clt RSSClient) ([]rsstypes.Workgroup, for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, libcloudaws.ConvertRequestFailureErrorV2(err) + return nil, libcloudaws.ConvertRequestFailureError(err) } out = append(out, page.Workgroups...) } @@ -215,7 +215,7 @@ func getRSSVPCEndpoints(ctx context.Context, clt RSSClient) ([]rsstypes.Endpoint for i := 0; i < maxAWSPages && pager.HasMorePages(); i++ { page, err := pager.NextPage(ctx) if err != nil { - return nil, libcloudaws.ConvertRequestFailureErrorV2(err) + return nil, libcloudaws.ConvertRequestFailureError(err) } out = append(out, page.Endpoints...) } diff --git a/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go b/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go index bf657836520c6..1f1261b9e7491 100644 --- a/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go +++ b/lib/srv/discovery/fetchers/db/aws_redshift_serverless_test.go @@ -21,8 +21,8 @@ package db import ( "testing" + "github.com/aws/aws-sdk-go-v2/aws" rsstypes "github.com/aws/aws-sdk-go-v2/service/redshiftserverless/types" - "github.com/aws/aws-sdk-go/aws" "github.com/stretchr/testify/require" "github.com/gravitational/teleport/api/types" @@ -39,8 +39,8 @@ func TestRedshiftServerlessFetcher(t *testing.T) { endpointProd, endpointProdDB := makeRedshiftServerlessEndpoint(t, workgroupProd, "endpoint1", "us-east-1", envProdLabels) endpointDev, endpointProdDev := makeRedshiftServerlessEndpoint(t, workgroupDev, "endpoint2", "us-east-1", envDevLabels) tagsByARN := map[string][]rsstypes.Tag{ - aws.StringValue(workgroupProd.WorkgroupArn): awstesthelpers.LabelsToRedshiftServerlessTags(envProdLabels), - aws.StringValue(workgroupDev.WorkgroupArn): awstesthelpers.LabelsToRedshiftServerlessTags(envDevLabels), + aws.ToString(workgroupProd.WorkgroupArn): awstesthelpers.LabelsToRedshiftServerlessTags(envProdLabels), + aws.ToString(workgroupDev.WorkgroupArn): awstesthelpers.LabelsToRedshiftServerlessTags(envDevLabels), } workgroupNotAvailable := mocks.RedshiftServerlessWorkgroup("wg-creating", "us-east-1")