From a25800b1a1e32c62dcc74587a2dbf7503e977211 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Fri, 4 Oct 2024 18:06:14 -0500 Subject: [PATCH] Include log text in snapshots (#597) --- go.mod | 4 +- grant/logs.go | 57 -- input/system/heroku/logs.go | 3 +- logs/analyze.go | 3 +- logs/querysample/tracing.go | 4 +- logs/replace.go | 63 +-- logs/replace_test.go | 32 +- main.go | 6 +- output/compact_logs.go | 12 +- grant/default.go => output/grant.go | 4 +- .../compact_log_snapshot.pb.go | 500 +++++++++--------- output/transform/logs.go | 1 + output/upload_logfile.go | 140 ----- output/upload_logfile_util.go | 136 ----- protobuf/compact_log_snapshot.proto | 2 + runner/activity.go | 3 +- runner/full.go | 3 +- runner/logs.go | 62 ++- 18 files changed, 334 insertions(+), 701 deletions(-) delete mode 100644 grant/logs.go rename grant/default.go => output/grant.go (93%) delete mode 100644 output/upload_logfile.go delete mode 100644 output/upload_logfile_util.go diff --git a/go.mod b/go.mod index e6a0ea70f..e8ca656f5 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -// +heroku goVersion go1.20 +// +heroku goVersion go1.21 module github.com/pganalyze/collector @@ -98,4 +98,4 @@ require ( google.golang.org/grpc v1.58.3 // indirect ) -go 1.20 +go 1.21 diff --git a/grant/logs.go b/grant/logs.go deleted file mode 100644 index cffa04905..000000000 --- a/grant/logs.go +++ /dev/null @@ -1,57 +0,0 @@ -package grant - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/pganalyze/collector/state" - "github.com/pganalyze/collector/util" -) - -func GetLogsGrant(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger) (state.GrantLogs, error) { - req, err := http.NewRequestWithContext(ctx, "GET", server.Config.APIBaseURL+"/v2/snapshots/grant_logs", nil) - if err != nil { - return state.GrantLogs{}, err - } - - req.Header.Set("Pganalyze-Api-Key", server.Config.APIKey) - req.Header.Set("Pganalyze-System-Id", server.Config.SystemID) - req.Header.Set("Pganalyze-System-Type", server.Config.SystemType) - req.Header.Set("Pganalyze-System-Scope", server.Config.SystemScope) - req.Header.Set("Pganalyze-System-Id-Fallback", server.Config.SystemIDFallback) - req.Header.Set("Pganalyze-System-Type-Fallback", server.Config.SystemTypeFallback) - req.Header.Set("Pganalyze-System-Scope-Fallback", server.Config.SystemScopeFallback) - req.Header.Set("User-Agent", util.CollectorNameAndVersion) - req.Header.Add("Accept", "application/json") - - resp, err := server.Config.HTTPClientWithRetry.Do(req) - if err != nil { - return state.GrantLogs{}, util.CleanHTTPError(err) - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return state.GrantLogs{}, err - } - - if resp.StatusCode == http.StatusForbidden { - return state.GrantLogs{}, nil - } - - if resp.StatusCode != http.StatusOK || len(body) == 0 { - return state.GrantLogs{}, fmt.Errorf("Error when getting grant: %s", body) - } - - grant := state.GrantLogs{} - err = json.Unmarshal(body, &grant) - if err != nil { - return state.GrantLogs{}, err - } - grant.Valid = true - - return grant, nil -} diff --git a/input/system/heroku/logs.go b/input/system/heroku/logs.go index e08a0dcd1..f51aad60d 100644 --- a/input/system/heroku/logs.go +++ b/input/system/heroku/logs.go @@ -10,7 +10,6 @@ import ( "time" "github.com/kr/logfmt" - "github.com/pganalyze/collector/grant" "github.com/pganalyze/collector/logs" "github.com/pganalyze/collector/output" "github.com/pganalyze/collector/state" @@ -69,7 +68,7 @@ func processSystemMetrics(ctx context.Context, timestamp time.Time, content []by prefixedLogger := logger.WithPrefix(server.Config.SectionName) - grant, err := grant.GetDefaultGrant(ctx, server, globalCollectionOpts, prefixedLogger) + grant, err := output.GetGrant(ctx, server, globalCollectionOpts, prefixedLogger) if err != nil { prefixedLogger.PrintError("Could not get default grant for system snapshot: %s", err) return diff --git a/logs/analyze.go b/logs/analyze.go index 7561aec85..e4997046f 100644 --- a/logs/analyze.go +++ b/logs/analyze.go @@ -2266,8 +2266,7 @@ func AnalyzeBackendLogLines(logLines []state.LogLine) (logLinesOut []state.LogLi logLinesOut = append(logLinesOut, logLine) } - // Ensure no other part of the system accidentally sends log line contents, as - // they should be considered opaque from here on + // Remove log line content. Note that ReplaceSecrets adds it back after secrets have been removed. for idx := range logLinesOut { logLinesOut[idx].Content = "" } diff --git a/logs/querysample/tracing.go b/logs/querysample/tracing.go index 50bb14bdf..a3bb0e92d 100644 --- a/logs/querysample/tracing.go +++ b/logs/querysample/tracing.go @@ -18,7 +18,7 @@ import ( const otelSpanName = "EXPLAIN Plan" -func urlToSample(server *state.Server, grant state.GrantLogs, sample state.PostgresQuerySample) string { +func urlToSample(server *state.Server, grant state.Grant, sample state.PostgresQuerySample) string { fp := util.FingerprintQuery(sample.Query, server.Config.FilterQueryText, -1) fpBin := make([]byte, 8) binary.BigEndian.PutUint64(fpBin, fp) @@ -66,7 +66,7 @@ func startAndEndTime(traceState trace.TraceState, sample state.PostgresQuerySamp return } -func ExportQuerySamplesAsTraceSpans(ctx context.Context, server *state.Server, logger *util.Logger, grant state.GrantLogs, samples []state.PostgresQuerySample) { +func ExportQuerySamplesAsTraceSpans(ctx context.Context, server *state.Server, logger *util.Logger, grant state.Grant, samples []state.PostgresQuerySample) { exportCount := 0 for _, sample := range samples { if !sample.HasExplain { diff --git a/logs/replace.go b/logs/replace.go index f6e03c3f1..c28d8c35e 100644 --- a/logs/replace.go +++ b/logs/replace.go @@ -1,74 +1,41 @@ package logs import ( + "slices" "sort" "github.com/pganalyze/collector/state" ) -type logRange struct { - start int64 - end int64 // When working with this range, the character at the index of end is *excluded* -} - -const replacementChar = 'X' - -// ReplaceSecrets - Replaces the secrets of the specified kind with the replacement character in the text -func ReplaceSecrets(input []byte, logLines []state.LogLine, filterLogSecret []state.LogSecretKind) []byte { - var goodRanges []logRange +const replacement = "[redacted]" +func ReplaceSecrets(input []byte, logLines []state.LogLine, filterLogSecret []state.LogSecretKind) { filterUnidentified := false for _, k := range filterLogSecret { if k == state.UnidentifiedLogSecret { filterUnidentified = true } } - - for _, logLine := range logLines { - goodRanges = append(goodRanges, logRange{start: logLine.ByteStart, end: logLine.ByteContentStart}) - if logLine.ReviewedForSecrets { + for idx, logLine := range logLines { + if filterUnidentified && logLines[idx].Classification == 0 { + logLines[idx].Content = replacement + "\n" + } else { + content := input[logLines[idx].ByteContentStart:logLines[idx].ByteEnd] sort.Slice(logLine.SecretMarkers, func(i, j int) bool { return logLine.SecretMarkers[i].ByteStart < logLine.SecretMarkers[j].ByteEnd }) - - // We're creating a good range when we find a filtered secret or the end (everything before is marked as good) - nextIdxToEvaluate := logLine.ByteContentStart + bytesChecked := 0 + offset := 0 for _, m := range logLine.SecretMarkers { - filter := false for _, k := range filterLogSecret { - if m.Kind == k { - filter = true + if m.Kind == k && m.ByteStart > bytesChecked { + content = slices.Replace(content, m.ByteStart-offset, m.ByteEnd-offset, []byte(replacement)...) + bytesChecked = m.ByteEnd + offset += (m.ByteEnd - m.ByteStart) - len(replacement) } } - if filter { - firstFilteredIdx := logLine.ByteContentStart + int64(m.ByteStart) - goodRanges = append(goodRanges, logRange{start: nextIdxToEvaluate, end: firstFilteredIdx}) - nextIdxToEvaluate = logLine.ByteContentStart + int64(m.ByteEnd) - } } - // No more markers means the rest of the line is safe - if nextIdxToEvaluate < logLine.ByteEnd { - goodRanges = append(goodRanges, logRange{start: nextIdxToEvaluate, end: logLine.ByteEnd}) - } - } else if !filterUnidentified { - goodRanges = append(goodRanges, logRange{start: logLine.ByteContentStart, end: logLine.ByteEnd}) - } - } - sort.Slice(goodRanges, func(i, j int) bool { - return goodRanges[i].start < goodRanges[j].start - }) - - lastGood := int64(0) - for _, r := range goodRanges { - for i := lastGood; i < r.start; i++ { - input[i] = replacementChar - } - lastGood = r.end - } - if len(goodRanges) > 0 || filterUnidentified { - for i := lastGood; i < int64(len(input)); i++ { - input[i] = replacementChar + logLines[idx].Content = string(content) } } - return input } diff --git a/logs/replace_test.go b/logs/replace_test.go index f6406c5dd..2478b1d24 100644 --- a/logs/replace_test.go +++ b/logs/replace_test.go @@ -22,42 +22,32 @@ var replaceTests = []replaceTestpair{ { filterLogSecret: "all", input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 1242.570 ms statement: SELECT 1\n", - output: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 1242.570 ms statement: XXXXXXXX\n", + output: "duration: 1242.570 ms statement: [redacted]\n", }, { filterLogSecret: "statement_text", input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 1242.570 ms statement: SELECT 1\n", - output: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 1242.570 ms statement: XXXXXXXX\n", + output: "duration: 1242.570 ms statement: [redacted]\n", }, { filterLogSecret: "statement_parameter", - input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 4079.697 ms execute : \nSELECT * FROM x WHERE y = $1 LIMIT $2\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:DETAIL: parameters: $1 = 'long string', $2 = '1'\n", - output: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 4079.697 ms execute : \nSELECT * FROM x WHERE y = $1 LIMIT $2\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:DETAIL: parameters: $1 = 'XXXXXXXXXXX', $2 = 'X'\n", + input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 4079.697 ms execute : \nSELECT * FROM x WHERE y = $1 LIMIT $2\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:DETAIL: parameters: $1 = 'long string', $2 = '1', $3 = 'long string'\n", + output: "duration: 4079.697 ms execute : \nSELECT * FROM x WHERE y = $1 LIMIT $2\nparameters: $1 = '[redacted]', $2 = '[redacted]', $3 = '[redacted]'\n", }, { filterLogSecret: "none", input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: division by zero\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: Unknown Data\n", - output: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: division by zero\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: Unknown Data\n", + output: "division by zero\nUnknown Data\n", }, { filterLogSecret: "unidentified", input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: division by zero\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: Unknown Data\n", - output: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: division by zero\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:ERROR: XXXXXXXXXXXXX", - }, - { - filterLogSecret: "none", - input: "Unknown Data\n", - output: "Unknown Data\n", - }, - { - filterLogSecret: "unidentified", - input: "Unknown Data\n", - output: "XXXXXXXXXXXXX", + output: "division by zero\n[redacted]\n", }, { filterLogSecret: "statement_text, statement_parameter, unidentified", input: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 4079.697 ms execute : \nSELECT * FROM x WHERE y = $1 LIMIT $2\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:DETAIL: parameters: $1 = 'long string', $2 = '1'\n", - output: "2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:LOG: duration: 4079.697 ms execute : \nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n2018-03-11 20:00:02 UTC:1.1.1.1(2):a@b:[3]:DETAIL: parameters: $1 = 'XXXXXXXXXXX', $2 = 'X'\n", + output: "duration: 4079.697 ms execute : \n[redacted]\n[redacted]\n", }, } @@ -67,12 +57,16 @@ func TestReplaceSecrets(t *testing.T) { server := state.MakeServer(config.ServerConfig{}, false) server.LogParser = logs.NewLogParser(logs.LogPrefixAmazonRds, nil, false) logLines, _ := logs.ParseAndAnalyzeBuffer(reader, time.Time{}, server) - output := logs.ReplaceSecrets([]byte(pair.input), logLines, state.ParseFilterLogSecret(pair.filterLogSecret)) + logs.ReplaceSecrets([]byte(pair.input), logLines, state.ParseFilterLogSecret(pair.filterLogSecret)) cfg := pretty.CompareConfig cfg.SkipZeroFields = true - if diff := cfg.Compare(pair.output, string(output)); diff != "" { + output := "" + for _, logLine := range logLines { + output += logLine.Content + } + if diff := cfg.Compare(pair.output, output); diff != "" { t.Errorf("For filter \"%s\", text:\n%vdiff: (-want +got)\n%s", pair.filterLogSecret, pair.input, diff) } } diff --git a/main.go b/main.go index f0851adfc..7c60bd766 100644 --- a/main.go +++ b/main.go @@ -478,7 +478,11 @@ func main() { reader := strings.NewReader(content) logReader := logs.NewMaybeHerokuLogReader(reader) logLines, _ := logs.ParseAndAnalyzeBuffer(logReader, time.Time{}, state.MakeServer(config.ServerConfig{}, false)) - output := logs.ReplaceSecrets(contentBytes, logLines, state.ParseFilterLogSecret(filterLogSecret)) + logs.ReplaceSecrets(contentBytes, logLines, state.ParseFilterLogSecret(filterLogSecret)) + output := "" + for _, logLine := range logLines { + output += logLine.Content + } fmt.Printf("%s", output) return } diff --git a/output/compact_logs.go b/output/compact_logs.go index cbc419a66..a90921603 100644 --- a/output/compact_logs.go +++ b/output/compact_logs.go @@ -9,19 +9,13 @@ import ( "github.com/pganalyze/collector/util" ) -// UploadAndSendLogs - Filters the log file, then uploads it to the storage and sends the metadata to the API -func UploadAndSendLogs(ctx context.Context, server *state.Server, grant state.GrantLogs, collectionOpts state.CollectionOpts, logger *util.Logger, logState state.TransientLogState) error { - if collectionOpts.SubmitCollectedData && grant.EncryptionKey.CiphertextBlob != "" { - logState.LogFiles = EncryptAndUploadLogfiles(ctx, server.Config.HTTPClientWithRetry, grant.Logdata, grant.EncryptionKey, logger, logState.LogFiles) - } - +// UploadAndSendLogs - Filters the log file, then uploads it +func UploadAndSendLogs(ctx context.Context, server *state.Server, grant state.Grant, collectionOpts state.CollectionOpts, logger *util.Logger, logState state.TransientLogState) error { ls, r := transform.LogStateToLogSnapshot(server, logState) s := pganalyze_collector.CompactSnapshot{ BaseRefs: &r, Data: &pganalyze_collector.CompactSnapshot_LogSnapshot{LogSnapshot: &ls}, } - - snapshotGrant := state.Grant{Valid: true, S3URL: grant.Snapshot.S3URL, S3Fields: grant.Snapshot.S3Fields} - + snapshotGrant := state.Grant{Valid: true, S3URL: grant.S3URL, S3Fields: grant.S3Fields} return uploadAndSubmitCompactSnapshot(ctx, s, snapshotGrant, server, collectionOpts, logger, logState.CollectedAt, false, "logs") } diff --git a/grant/default.go b/output/grant.go similarity index 93% rename from grant/default.go rename to output/grant.go index 2d6eab669..33079a1a0 100644 --- a/grant/default.go +++ b/output/grant.go @@ -1,4 +1,4 @@ -package grant +package output import ( "context" @@ -12,7 +12,7 @@ import ( "github.com/pganalyze/collector/util" ) -func GetDefaultGrant(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger) (state.Grant, error) { +func GetGrant(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger) (state.Grant, error) { grant := state.Grant{Config: pganalyze_collector.ServerMessage_Config{Features: &pganalyze_collector.ServerMessage_Features{}}} req, err := http.NewRequestWithContext(ctx, "GET", server.Config.APIBaseURL+"/v2/snapshots/grant", nil) if err != nil { diff --git a/output/pganalyze_collector/compact_log_snapshot.pb.go b/output/pganalyze_collector/compact_log_snapshot.pb.go index 02dc91e6d..e0de001d8 100644 --- a/output/pganalyze_collector/compact_log_snapshot.pb.go +++ b/output/pganalyze_collector/compact_log_snapshot.pb.go @@ -795,6 +795,7 @@ type LogLineInformation struct { HasRelationIdx bool `protobuf:"varint,18,opt,name=has_relation_idx,json=hasRelationIdx,proto3" json:"has_relation_idx,omitempty"` RelationIdx int32 `protobuf:"varint,19,opt,name=relation_idx,json=relationIdx,proto3" json:"relation_idx,omitempty"` RelatedPids []int32 `protobuf:"varint,20,rep,packed,name=related_pids,json=relatedPids,proto3" json:"related_pids,omitempty"` // Other PIDs that are related to this log line (mentioned in some way) + Content string `protobuf:"bytes,21,opt,name=content,proto3" json:"content,omitempty"` } func (x *LogLineInformation) Reset() { @@ -969,6 +970,13 @@ func (x *LogLineInformation) GetRelatedPids() []int32 { return nil } +func (x *LogLineInformation) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + type QuerySample struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1163,7 +1171,7 @@ var file_compact_log_snapshot_proto_rawDesc = []byte{ 0x4f, 0x47, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x50, 0x53, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x4e, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, - 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x06, 0x22, 0xa1, 0x1e, 0x0a, + 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x06, 0x22, 0xbb, 0x1e, 0x0a, 0x12, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0c, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x46, 0x69, @@ -1215,252 +1223,254 @@ var file_compact_log_snapshot_proto_rawDesc = []byte{ 0x69, 0x64, 0x78, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x78, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x69, 0x64, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0b, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x69, 0x64, 0x73, 0x22, 0xac, 0x01, 0x0a, 0x08, 0x4c, 0x6f, - 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, - 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, - 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, - 0x43, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, - 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, - 0x4c, 0x4f, 0x47, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, - 0x12, 0x09, 0x0a, 0x05, 0x50, 0x41, 0x4e, 0x49, 0x43, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, - 0x45, 0x54, 0x41, 0x49, 0x4c, 0x10, 0x09, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x4e, 0x54, 0x10, - 0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x10, 0x0b, 0x12, 0x0d, - 0x0a, 0x09, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, 0x09, 0x0a, - 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, 0x0d, 0x22, 0xb5, 0x16, 0x0a, 0x11, 0x4c, 0x6f, 0x67, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, - 0x0a, 0x1a, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x43, 0x4c, - 0x41, 0x53, 0x53, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x12, - 0x0a, 0x0e, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x43, 0x52, 0x41, 0x53, 0x48, 0x45, 0x44, - 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, - 0x52, 0x54, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, - 0x54, 0x41, 0x52, 0x54, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x49, 0x4e, 0x47, 0x10, - 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x55, 0x54, - 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, - 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x10, 0x05, - 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x53, 0x55, 0x4d, 0x10, 0x06, 0x12, 0x1c, 0x0a, - 0x18, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x5f, 0x46, 0x49, 0x4c, - 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x53, - 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x43, 0x10, 0x08, 0x12, 0x11, 0x0a, 0x0d, - 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x09, 0x12, - 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, - 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x45, - 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, - 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x0b, 0x12, 0x17, - 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x43, - 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, 0x14, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x4e, 0x45, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, - 0x10, 0x15, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x16, 0x12, 0x1b, 0x0a, 0x17, 0x43, - 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, - 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x43, 0x4f, 0x4e, 0x4e, - 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x41, - 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, - 0x18, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x4c, 0x4f, 0x53, 0x54, 0x10, 0x19, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x54, - 0x58, 0x10, 0x1a, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x16, - 0x0a, 0x12, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, - 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x1c, 0x12, 0x1d, 0x0a, 0x19, 0x54, 0x4f, 0x4f, 0x5f, 0x4d, 0x41, - 0x4e, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x52, - 0x4f, 0x4c, 0x45, 0x10, 0x1d, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4c, 0x44, 0x5f, 0x4e, - 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x43, 0x4f, - 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x1e, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, - 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, - 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, - 0x10, 0x1f, 0x12, 0x25, 0x0a, 0x21, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x5f, - 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x20, 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x4f, 0x4f, - 0x5f, 0x4d, 0x41, 0x4e, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x10, 0x21, 0x12, 0x17, 0x0a, 0x13, - 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, - 0x49, 0x4e, 0x47, 0x10, 0x28, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, 0x4f, - 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x29, 0x12, 0x1b, - 0x0a, 0x17, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x4f, 0x4f, - 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x54, 0x10, 0x2a, 0x12, 0x19, 0x0a, 0x15, 0x52, - 0x45, 0x53, 0x54, 0x41, 0x52, 0x54, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, - 0x54, 0x49, 0x4e, 0x47, 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x54, 0x41, 0x52, - 0x54, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x2c, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x53, 0x54, 0x41, 0x52, 0x54, 0x50, 0x4f, 0x49, 0x4e, - 0x54, 0x5f, 0x41, 0x54, 0x10, 0x2d, 0x12, 0x1d, 0x0a, 0x19, 0x57, 0x41, 0x4c, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x4c, 0x45, 0x4e, - 0x47, 0x54, 0x48, 0x10, 0x32, 0x12, 0x0c, 0x0a, 0x08, 0x57, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x44, - 0x4f, 0x10, 0x33, 0x12, 0x1e, 0x0a, 0x1a, 0x57, 0x41, 0x4c, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, - 0x56, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, - 0x44, 0x10, 0x34, 0x12, 0x1c, 0x0a, 0x18, 0x57, 0x41, 0x4c, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x5f, - 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x35, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x55, 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, - 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x3c, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x58, 0x49, 0x44, - 0x5f, 0x57, 0x52, 0x41, 0x50, 0x41, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x57, 0x41, 0x52, 0x4e, - 0x49, 0x4e, 0x47, 0x10, 0x3d, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x58, 0x49, 0x44, 0x5f, 0x57, 0x52, - 0x41, 0x50, 0x41, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x3e, - 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, 0x4c, - 0x41, 0x55, 0x4e, 0x43, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, - 0x3f, 0x12, 0x25, 0x0a, 0x21, 0x41, 0x55, 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, - 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, - 0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x40, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, - 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, - 0x10, 0x41, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x41, 0x4e, 0x41, 0x4c, 0x59, 0x5a, - 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x42, 0x12, 0x26, 0x0a, - 0x22, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, - 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, - 0x42, 0x4c, 0x45, 0x10, 0x43, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x49, 0x4e, - 0x47, 0x5f, 0x41, 0x4e, 0x41, 0x4c, 0x59, 0x5a, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x4e, - 0x4f, 0x54, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x44, 0x12, 0x11, - 0x0a, 0x0d, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x41, 0x43, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, - 0x46, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x47, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x54, 0x49, 0x4d, 0x45, - 0x4f, 0x55, 0x54, 0x10, 0x48, 0x12, 0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, - 0x41, 0x44, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, - 0x49, 0x12, 0x19, 0x0a, 0x15, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x4f, - 0x43, 0x4b, 0x5f, 0x41, 0x56, 0x4f, 0x49, 0x44, 0x45, 0x44, 0x10, 0x4a, 0x12, 0x16, 0x0a, 0x12, - 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x10, 0x50, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, - 0x55, 0x54, 0x10, 0x51, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, - 0x52, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4c, - 0x4f, 0x47, 0x10, 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x54, - 0x12, 0x25, 0x0a, 0x21, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x52, 0x45, 0x53, 0x54, - 0x4f, 0x52, 0x45, 0x44, 0x5f, 0x57, 0x41, 0x4c, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x41, 0x52, - 0x43, 0x48, 0x49, 0x56, 0x45, 0x10, 0x5a, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x54, 0x41, 0x4e, 0x44, - 0x42, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, - 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x5b, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, - 0x59, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x49, 0x4e, 0x54, 0x45, - 0x52, 0x52, 0x55, 0x50, 0x54, 0x45, 0x44, 0x10, 0x5c, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x54, 0x41, - 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x52, - 0x45, 0x41, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x5d, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x54, 0x41, 0x4e, - 0x44, 0x42, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x52, - 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x5e, 0x12, - 0x1e, 0x0a, 0x1a, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x5f, 0x12, - 0x1c, 0x0a, 0x18, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x60, 0x12, 0x1f, 0x0a, - 0x1b, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, - 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x64, 0x12, 0x24, - 0x0a, 0x20, 0x46, 0x4f, 0x52, 0x45, 0x49, 0x47, 0x4e, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x43, 0x4f, - 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x10, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x4e, 0x4f, 0x54, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, - 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x66, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x48, 0x45, 0x43, 0x4b, - 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x67, 0x12, 0x22, 0x0a, 0x1e, 0x45, 0x58, 0x43, 0x4c, 0x55, - 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, - 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x68, 0x12, 0x10, 0x0a, 0x0c, 0x53, - 0x59, 0x4e, 0x54, 0x41, 0x58, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x6e, 0x12, 0x18, 0x0a, - 0x14, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x53, - 0x59, 0x4e, 0x54, 0x41, 0x58, 0x10, 0x6f, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x41, 0x4c, 0x55, 0x45, - 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x4c, 0x4f, 0x4e, 0x47, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x10, 0x70, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x71, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x4c, 0x46, 0x4f, - 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, - 0x41, 0x4c, 0x10, 0x72, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x55, 0x42, 0x51, 0x55, 0x45, 0x52, 0x59, - 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x4c, 0x49, 0x41, 0x53, 0x10, 0x73, - 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, - 0x54, 0x5f, 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x74, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x4e, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x5f, 0x52, - 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x75, 0x12, - 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, - 0x47, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x42, 0x59, 0x10, - 0x76, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, - 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x77, 0x12, 0x19, - 0x0a, 0x15, 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x78, 0x12, 0x1b, 0x0a, 0x17, 0x4f, 0x50, 0x45, - 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, - 0x58, 0x49, 0x53, 0x54, 0x10, 0x79, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, - 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x41, 0x4d, 0x42, 0x49, 0x47, - 0x55, 0x4f, 0x55, 0x53, 0x10, 0x7a, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, - 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x7b, 0x12, 0x1a, 0x0a, - 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x53, 0x5f, - 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x7c, 0x12, 0x23, 0x0a, 0x1f, 0x4f, 0x4e, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x53, - 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x7d, 0x12, 0x22, - 0x0a, 0x1e, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x5f, 0x52, 0x4f, - 0x57, 0x5f, 0x41, 0x46, 0x46, 0x45, 0x43, 0x54, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, - 0x10, 0x7e, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, 0x5f, 0x43, 0x41, 0x4e, - 0x4e, 0x4f, 0x54, 0x5f, 0x42, 0x45, 0x5f, 0x43, 0x41, 0x53, 0x54, 0x10, 0x7f, 0x12, 0x15, 0x0a, - 0x10, 0x44, 0x49, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, - 0x4f, 0x10, 0x80, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x44, - 0x52, 0x4f, 0x50, 0x10, 0x81, 0x01, 0x12, 0x19, 0x0a, 0x14, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, - 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x82, - 0x01, 0x12, 0x13, 0x0a, 0x0e, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x47, - 0x45, 0x58, 0x50, 0x10, 0x83, 0x01, 0x12, 0x12, 0x0a, 0x0d, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, - 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x84, 0x01, 0x12, 0x1c, 0x0a, 0x17, 0x46, 0x55, - 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, - 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x85, 0x01, 0x12, 0x16, 0x0a, 0x11, 0x4e, 0x4f, 0x5f, 0x53, - 0x55, 0x43, 0x48, 0x5f, 0x53, 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x86, 0x01, - 0x12, 0x1f, 0x0a, 0x1a, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, - 0x5f, 0x51, 0x55, 0x4f, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x87, - 0x01, 0x12, 0x23, 0x0a, 0x1e, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, - 0x44, 0x5f, 0x51, 0x55, 0x4f, 0x54, 0x45, 0x44, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, - 0x49, 0x45, 0x52, 0x10, 0x88, 0x01, 0x12, 0x1a, 0x0a, 0x15, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, - 0x89, 0x01, 0x12, 0x28, 0x0a, 0x23, 0x43, 0x4f, 0x55, 0x4c, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, - 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, - 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x8a, 0x01, 0x12, 0x25, 0x0a, 0x20, + 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x69, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x22, 0xac, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, + 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, + 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x0b, + 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x47, 0x10, 0x06, 0x12, + 0x09, 0x0a, 0x05, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x41, + 0x4e, 0x49, 0x43, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x10, + 0x09, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x43, + 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x10, 0x0b, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, 0x09, 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, + 0x10, 0x0d, 0x22, 0xb5, 0x16, 0x0a, 0x11, 0x4c, 0x6f, 0x67, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x49, 0x46, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x45, 0x52, 0x56, + 0x45, 0x52, 0x5f, 0x43, 0x52, 0x41, 0x53, 0x48, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, + 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x02, 0x12, 0x1b, + 0x0a, 0x17, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x52, + 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x04, + 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, + 0x46, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x45, + 0x43, 0x4b, 0x53, 0x55, 0x4d, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, + 0x4d, 0x49, 0x53, 0x43, 0x10, 0x08, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, + 0x5f, 0x52, 0x45, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x45, 0x58, 0x49, 0x54, + 0x45, 0x44, 0x10, 0x0a, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x54, + 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x0b, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x44, 0x10, + 0x14, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x15, 0x12, 0x17, 0x0a, 0x13, + 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, + 0x54, 0x45, 0x44, 0x10, 0x16, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, + 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x54, + 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x18, 0x12, 0x13, 0x0a, 0x0f, 0x43, + 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0x19, + 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, + 0x4f, 0x53, 0x54, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x54, 0x58, 0x10, 0x1a, 0x12, 0x19, 0x0a, + 0x15, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x52, 0x4d, + 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x16, 0x0a, 0x12, 0x4f, 0x55, 0x54, 0x5f, + 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x1c, + 0x12, 0x1d, 0x0a, 0x19, 0x54, 0x4f, 0x4f, 0x5f, 0x4d, 0x41, 0x4e, 0x59, 0x5f, 0x43, 0x4f, 0x4e, + 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x10, 0x1d, 0x12, + 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x55, 0x4c, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x43, + 0x45, 0x50, 0x54, 0x5f, 0x53, 0x53, 0x4c, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x10, 0x1e, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, + 0x45, 0x44, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x1f, 0x12, 0x25, 0x0a, 0x21, + 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, + 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, + 0x45, 0x10, 0x20, 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x4f, 0x4f, 0x5f, 0x4d, 0x41, 0x4e, 0x59, 0x5f, + 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x42, 0x41, 0x53, 0x45, 0x10, 0x21, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, + 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x28, 0x12, + 0x17, 0x0a, 0x13, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x43, 0x4f, + 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x29, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x48, 0x45, 0x43, + 0x4b, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, + 0x45, 0x4e, 0x54, 0x10, 0x2a, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x54, 0x41, 0x52, 0x54, + 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x2b, + 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x54, 0x41, 0x52, 0x54, 0x50, 0x4f, 0x49, 0x4e, 0x54, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2c, 0x12, 0x13, 0x0a, 0x0f, 0x52, + 0x45, 0x53, 0x54, 0x41, 0x52, 0x54, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x5f, 0x41, 0x54, 0x10, 0x2d, + 0x12, 0x1d, 0x0a, 0x19, 0x57, 0x41, 0x4c, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x10, 0x32, 0x12, + 0x0c, 0x0a, 0x08, 0x57, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x44, 0x4f, 0x10, 0x33, 0x12, 0x1e, 0x0a, + 0x1a, 0x57, 0x41, 0x4c, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x5f, 0x43, 0x4f, 0x4d, + 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x34, 0x12, 0x1c, 0x0a, + 0x18, 0x57, 0x41, 0x4c, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x35, 0x12, 0x15, 0x0a, 0x11, 0x41, + 0x55, 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, + 0x10, 0x3c, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x58, 0x49, 0x44, 0x5f, 0x57, 0x52, 0x41, 0x50, 0x41, + 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x3d, 0x12, + 0x19, 0x0a, 0x15, 0x54, 0x58, 0x49, 0x44, 0x5f, 0x57, 0x52, 0x41, 0x50, 0x41, 0x52, 0x4f, 0x55, + 0x4e, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x3e, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, + 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x45, + 0x52, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x3f, 0x12, 0x25, 0x0a, 0x21, 0x41, + 0x55, 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, + 0x45, 0x52, 0x5f, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, + 0x10, 0x40, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x41, 0x12, 0x19, 0x0a, 0x15, + 0x41, 0x55, 0x54, 0x4f, 0x41, 0x4e, 0x41, 0x4c, 0x59, 0x5a, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, + 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x42, 0x12, 0x26, 0x0a, 0x22, 0x53, 0x4b, 0x49, 0x50, 0x50, + 0x49, 0x4e, 0x47, 0x5f, 0x56, 0x41, 0x43, 0x55, 0x55, 0x4d, 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x43, 0x12, + 0x27, 0x0a, 0x23, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x4e, 0x41, 0x4c, + 0x59, 0x5a, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x56, 0x41, + 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x44, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x43, 0x4b, + 0x5f, 0x41, 0x43, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x46, 0x12, 0x10, 0x0a, 0x0c, 0x4c, + 0x4f, 0x43, 0x4b, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x47, 0x12, 0x10, 0x0a, + 0x0c, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x48, 0x12, + 0x1a, 0x0a, 0x16, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x4f, 0x43, 0x4b, + 0x5f, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x49, 0x12, 0x19, 0x0a, 0x15, 0x4c, + 0x4f, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x41, 0x56, 0x4f, + 0x49, 0x44, 0x45, 0x44, 0x10, 0x4a, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, + 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x50, 0x12, 0x1e, + 0x0a, 0x1a, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, + 0x45, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x51, 0x12, 0x1b, + 0x0a, 0x17, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, + 0x45, 0x4c, 0x45, 0x44, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x10, 0x52, 0x12, 0x11, 0x0a, 0x0d, 0x53, + 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x4f, 0x47, 0x10, 0x53, 0x12, 0x1a, + 0x0a, 0x16, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x55, 0x54, 0x4f, + 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x54, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x54, + 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x52, 0x45, 0x53, 0x54, 0x4f, 0x52, 0x45, 0x44, 0x5f, 0x57, + 0x41, 0x4c, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x10, + 0x5a, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x53, 0x54, 0x41, + 0x52, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x5b, + 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x53, 0x54, 0x52, 0x45, + 0x41, 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x55, 0x50, 0x54, 0x45, + 0x44, 0x10, 0x5c, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x53, + 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x49, 0x4e, 0x47, + 0x10, 0x5d, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x54, 0x41, 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x43, 0x4f, + 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, + 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x5e, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x54, 0x41, + 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, + 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x5f, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x54, 0x41, + 0x4e, 0x44, 0x42, 0x59, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x49, 0x4d, + 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x60, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x4e, 0x49, 0x51, 0x55, + 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, + 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x64, 0x12, 0x24, 0x0a, 0x20, 0x46, 0x4f, 0x52, 0x45, + 0x49, 0x47, 0x4e, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, + 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x65, 0x12, 0x21, + 0x0a, 0x1d, 0x4e, 0x4f, 0x54, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, + 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x66, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, + 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x67, 0x12, 0x22, 0x0a, 0x1e, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, + 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, 0x5f, 0x56, 0x49, 0x4f, 0x4c, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x68, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x6e, 0x12, 0x18, 0x0a, 0x14, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x53, 0x59, 0x4e, 0x54, 0x41, 0x58, 0x10, + 0x6f, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x4c, + 0x4f, 0x4e, 0x47, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x70, 0x12, 0x11, + 0x0a, 0x0d, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, + 0x71, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x41, 0x4c, 0x46, 0x4f, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x41, + 0x52, 0x52, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x54, 0x45, 0x52, 0x41, 0x4c, 0x10, 0x72, 0x12, 0x1a, + 0x0a, 0x16, 0x53, 0x55, 0x42, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, + 0x4e, 0x47, 0x5f, 0x41, 0x4c, 0x49, 0x41, 0x53, 0x10, 0x73, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, + 0x53, 0x45, 0x52, 0x54, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x43, 0x4f, 0x4c, 0x55, + 0x4d, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x74, 0x12, 0x1a, 0x0a, + 0x16, 0x41, 0x4e, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, + 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x10, 0x75, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4c, + 0x55, 0x4d, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x52, 0x4f, 0x4d, + 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x42, 0x59, 0x10, 0x76, 0x12, 0x1b, 0x0a, 0x17, 0x52, + 0x45, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x77, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4c, 0x55, + 0x4d, 0x4e, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, + 0x54, 0x10, 0x78, 0x12, 0x1b, 0x0a, 0x17, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, + 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, 0x79, + 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, + 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x41, 0x4d, 0x42, 0x49, 0x47, 0x55, 0x4f, 0x55, 0x53, 0x10, 0x7a, + 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, + 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x7b, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x41, 0x4e, 0x53, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, + 0x44, 0x10, 0x7c, 0x12, 0x23, 0x0a, 0x1f, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x49, + 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x41, 0x49, 0x4e, 0x54, + 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x7d, 0x12, 0x22, 0x0a, 0x1e, 0x4f, 0x4e, 0x5f, 0x43, + 0x4f, 0x4e, 0x46, 0x4c, 0x49, 0x43, 0x54, 0x5f, 0x52, 0x4f, 0x57, 0x5f, 0x41, 0x46, 0x46, 0x45, + 0x43, 0x54, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x7e, 0x12, 0x19, 0x0a, 0x15, + 0x43, 0x4f, 0x4c, 0x55, 0x4d, 0x4e, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x42, 0x45, + 0x5f, 0x43, 0x41, 0x53, 0x54, 0x10, 0x7f, 0x12, 0x15, 0x0a, 0x10, 0x44, 0x49, 0x56, 0x49, 0x53, + 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x80, 0x01, 0x12, 0x10, + 0x0a, 0x0b, 0x43, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x81, 0x01, + 0x12, 0x19, 0x0a, 0x14, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x45, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, + 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x82, 0x01, 0x12, 0x13, 0x0a, 0x0e, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x50, 0x10, 0x83, 0x01, + 0x12, 0x12, 0x0a, 0x0d, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, + 0x47, 0x10, 0x84, 0x01, 0x12, 0x1c, 0x0a, 0x17, 0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x10, + 0x85, 0x01, 0x12, 0x16, 0x0a, 0x11, 0x4e, 0x4f, 0x5f, 0x53, 0x55, 0x43, 0x48, 0x5f, 0x53, 0x41, + 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x86, 0x01, 0x12, 0x1f, 0x0a, 0x1a, 0x55, 0x4e, + 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x51, 0x55, 0x4f, 0x54, 0x45, + 0x44, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x87, 0x01, 0x12, 0x23, 0x0a, 0x1e, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x51, 0x55, 0x4f, 0x54, + 0x45, 0x44, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, 0x49, 0x45, 0x52, 0x10, 0x88, 0x01, + 0x12, 0x1a, 0x0a, 0x15, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x59, 0x54, 0x45, + 0x5f, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x89, 0x01, 0x12, 0x28, 0x0a, 0x23, 0x43, 0x4f, 0x55, 0x4c, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, - 0x49, 0x5a, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, - 0x10, 0x8b, 0x01, 0x12, 0x1e, 0x0a, 0x19, 0x49, 0x4e, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, - 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x53, - 0x10, 0x8c, 0x01, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x47, 0x41, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, - 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, 0x59, 0x10, 0xe8, 0x07, - 0x22, 0xa3, 0x06, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x78, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x65, 0x72, 0x79, 0x49, 0x64, 0x78, 0x12, 0x3b, 0x0a, - 0x0b, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x74, 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, 0x0a, - 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x54, 0x65, 0x78, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x4c, - 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x3f, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x67, 0x61, 0x6e, + 0x49, 0x5a, 0x45, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x52, + 0x45, 0x41, 0x44, 0x10, 0x8a, 0x01, 0x12, 0x25, 0x0a, 0x20, 0x43, 0x4f, 0x55, 0x4c, 0x44, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x5f, 0x53, 0x45, + 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x8b, 0x01, 0x12, 0x1e, 0x0a, + 0x19, 0x49, 0x4e, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x41, + 0x4e, 0x47, 0x45, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x53, 0x10, 0x8c, 0x01, 0x12, 0x1b, 0x0a, + 0x16, 0x50, 0x47, 0x41, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x49, + 0x44, 0x45, 0x4e, 0x54, 0x49, 0x46, 0x59, 0x10, 0xe8, 0x07, 0x22, 0xa3, 0x06, 0x0a, 0x0b, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x49, 0x64, 0x78, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x63, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x64, 0x5f, 0x61, 0x74, 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, 0x0a, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x54, 0x65, + 0x78, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, + 0x3f, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x2e, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x75, 0x75, 0x69, + 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, + 0x55, 0x75, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x61, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6c, + 0x61, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x68, 0x61, 0x73, 0x45, 0x78, + 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, + 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, + 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x55, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, - 0x4e, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, - 0x6e, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, - 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x61, - 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0a, 0x68, 0x61, 0x73, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x65, - 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x15, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x4f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x55, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2e, 0x2e, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, - 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x55, - 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, - 0x7a, 0x65, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, - 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x45, - 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x00, 0x12, - 0x17, 0x0a, 0x13, 0x4a, 0x53, 0x4f, 0x4e, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, - 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x01, 0x22, 0x8b, 0x01, 0x0a, 0x0d, 0x45, 0x78, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x45, 0x58, 0x50, 0x4c, - 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, - 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x45, 0x58, 0x50, - 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x1b, 0x0a, - 0x17, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, - 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x47, 0x45, - 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x10, 0x03, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x2f, 0x63, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2f, - 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6c, + 0x61, 0x69, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x61, + 0x69, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x55, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x6c, + 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2e, 0x2e, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x2e, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, + 0x41, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, + 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4a, 0x53, 0x4f, + 0x4e, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, + 0x10, 0x01, 0x22, 0x8b, 0x01, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x54, 0x41, 0x54, 0x45, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x4c, 0x4f, 0x47, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x45, + 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x54, 0x45, 0x52, + 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, + 0x45, 0x58, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x03, + 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x67, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x2f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2f, 0x70, 0x67, 0x61, 0x6e, 0x61, 0x6c, + 0x79, 0x7a, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/output/transform/logs.go b/output/transform/logs.go index 9639e0f9d..a018e974d 100644 --- a/output/transform/logs.go +++ b/output/transform/logs.go @@ -148,6 +148,7 @@ func transformSystemLogLine(server *state.Server, r *snapshot.CompactSnapshot_Ba Level: logLineIn.LogLevel, Classification: logLineIn.Classification, RelatedPids: logLineIn.RelatedPids, + Content: logLineIn.Content, } if logLineIn.ParentUUID != uuid.Nil { diff --git a/output/upload_logfile.go b/output/upload_logfile.go deleted file mode 100644 index 468855987..000000000 --- a/output/upload_logfile.go +++ /dev/null @@ -1,140 +0,0 @@ -package output - -import ( - "bytes" - "context" - "crypto/rand" - "encoding/base64" - "fmt" - "io" - "io/ioutil" - "net/http" - - "github.com/aws/aws-sdk-go/service/s3/s3crypto" - "github.com/pganalyze/collector/logs" - "github.com/pganalyze/collector/state" - "github.com/pganalyze/collector/util" -) - -type keyHandler struct { - plaintextKey []byte - ciphertextKey []byte - cmkID string - - CipherData s3crypto.CipherData -} - -func generateBytes(n int) []byte { - b := make([]byte, n) - rand.Read(b) - return b -} - -func (kh *keyHandler) GenerateCipherData(keySize, ivSize int) (s3crypto.CipherData, error) { - if keySize != len(kh.plaintextKey) { - return s3crypto.CipherData{}, fmt.Errorf("Stored key size (%d) does not match requested (%d)", len(kh.plaintextKey), keySize) - } - - matdesc := s3crypto.MaterialDescription{} - matdesc["kms_cmk_id"] = &kh.cmkID - - cd := s3crypto.CipherData{ - Key: kh.plaintextKey, - IV: generateBytes(ivSize), - WrapAlgorithm: s3crypto.KMSWrap, - MaterialDescription: matdesc, - EncryptedKey: kh.ciphertextKey, - } - return cd, nil -} - -func EncryptAndUploadLogfiles(ctx context.Context, httpClient *http.Client, s3 state.GrantS3, encryptionKey state.GrantLogsEncryptionKey, logger *util.Logger, logFiles []state.LogFile) []state.LogFile { - if len(logFiles) == 0 { - return logFiles - } - - plaintextKey, err := base64.StdEncoding.DecodeString(encryptionKey.Plaintext) - if err != nil { - logger.PrintError("Could not decode log encryption key (plaintext)") - return logFiles - } - ciphertextKey, err := base64.StdEncoding.DecodeString(encryptionKey.CiphertextBlob) - if err != nil { - logger.PrintError("Could not decode log encryption key (encrypted)") - return logFiles - } - - kh := keyHandler{plaintextKey: plaintextKey, ciphertextKey: ciphertextKey, cmkID: encryptionKey.KeyId} - builder := s3crypto.AESGCMContentCipherBuilder(&kh) - - encryptor, err := builder.ContentCipher() - if err != nil { - logger.PrintError("Could not load content cipher: %s", err) - return logFiles - } - - for idx, logFile := range logFiles { - content, _ := ioutil.ReadFile(logFile.TmpFile.Name()) - - if len(logFile.FilterLogSecret) > 0 { - content = logs.ReplaceSecrets(content, logFile.LogLines, logFile.FilterLogSecret) - } - - dst := &bytesReadWriteSeeker{} - md5 := newMD5Reader(bytes.NewReader(content)) - reader, err := encryptor.EncryptContents(md5) - if err != nil { - logger.PrintError("%s", err) - return logFiles - } - - _, err = io.Copy(dst, reader) - if err != nil { - logger.PrintError("%s", err) - return logFiles - } - - data := encryptor.GetCipherData() - env, err := encodeMeta(md5, data) - if err != nil { - logger.PrintError("%s", err) - return logFiles - } - - dst.Seek(0, 0) - encryptedContent, err := ioutil.ReadAll(dst) - if err != nil { - logger.PrintError("%s", err) - return logFiles - } - - formFields := make(map[string]string) - for k, v := range s3.S3Fields { - formFields[k] = v - } - - formFields["x-amz-meta-x-amz-key-v2"] = env.CipherKey - formFields["x-amz-meta-x-amz-iv"] = env.IV - formFields["x-amz-meta-x-amz-matdesc"] = env.MatDesc - formFields["x-amz-meta-x-amz-wrap-alg"] = env.WrapAlg - formFields["x-amz-meta-x-amz-cek-alg"] = env.CEKAlg - formFields["x-amz-meta-x-amz-tag-len"] = env.TagLen - formFields["x-amz-meta-x-amz-unencrypted-content-md5"] = env.UnencryptedMD5 - formFields["x-amz-meta-x-amz-unencrypted-content-length"] = env.UnencryptedContentLen - - s3Location, err := uploadToS3(ctx, httpClient, s3.S3URL, formFields, logger, encryptedContent, logFile.UUID.String()) - if err != nil { - logger.PrintError("Log S3 upload failed: %s", err) - return logFiles - } - - logFile.S3Location = s3Location - logFile.S3CekAlgo = env.CEKAlg - logFile.S3CmkKeyID = encryptionKey.KeyId - logFile.ByteSize = int64(len(content)) - - logFiles[idx] = logFile - } - - return logFiles -} diff --git a/output/upload_logfile_util.go b/output/upload_logfile_util.go deleted file mode 100644 index e37bf9894..000000000 --- a/output/upload_logfile_util.go +++ /dev/null @@ -1,136 +0,0 @@ -package output - -import ( - "crypto/md5" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "hash" - "io" - "strconv" - - "github.com/aws/aws-sdk-go/service/s3/s3crypto" -) - -// hashReader is used for calculating SHA256 when following the sigv4 specification. -// Additionally this used for calculating the unencrypted MD5. -type hashReader interface { - GetValue() []byte - GetContentLength() int64 -} - -type sha256Writer struct { - sha256 []byte - hash hash.Hash - out io.Writer -} - -func newSHA256Writer(f io.Writer) *sha256Writer { - return &sha256Writer{hash: sha256.New(), out: f} -} -func (r *sha256Writer) Write(b []byte) (int, error) { - r.hash.Write(b) - return r.out.Write(b) -} - -func (r *sha256Writer) GetValue() []byte { - return r.hash.Sum(nil) -} - -type md5Reader struct { - contentLength int64 - hash hash.Hash - body io.Reader -} - -func newMD5Reader(body io.Reader) *md5Reader { - return &md5Reader{hash: md5.New(), body: body} -} - -func (w *md5Reader) Read(b []byte) (int, error) { - n, err := w.body.Read(b) - if err != nil && err != io.EOF { - return n, err - } - w.contentLength += int64(n) - w.hash.Write(b[:n]) - return n, err -} - -func (w *md5Reader) GetValue() []byte { - return w.hash.Sum(nil) -} - -func (w *md5Reader) GetContentLength() int64 { - return w.contentLength -} - -// --- - -func encodeMeta(reader hashReader, cd s3crypto.CipherData) (s3crypto.Envelope, error) { - iv := base64.StdEncoding.EncodeToString(cd.IV) - key := base64.StdEncoding.EncodeToString(cd.EncryptedKey) - - md5 := reader.GetValue() - contentLength := reader.GetContentLength() - - md5Str := base64.StdEncoding.EncodeToString(md5) - matdesc, err := json.Marshal(&cd.MaterialDescription) - if err != nil { - return s3crypto.Envelope{}, err - } - - return s3crypto.Envelope{ - CipherKey: key, - IV: iv, - MatDesc: string(matdesc), - WrapAlg: cd.WrapAlgorithm, - CEKAlg: cd.CEKAlgorithm, - TagLen: cd.TagLength, - UnencryptedMD5: md5Str, - UnencryptedContentLen: strconv.FormatInt(contentLength, 10), - }, nil -} - -// --- - -type bytesReadWriteSeeker struct { - buf []byte - i int64 -} - -// Copied from Go stdlib bytes.Reader -func (ws *bytesReadWriteSeeker) Read(b []byte) (int, error) { - if ws.i >= int64(len(ws.buf)) { - return 0, io.EOF - } - n := copy(b, ws.buf[ws.i:]) - ws.i += int64(n) - return n, nil -} - -func (ws *bytesReadWriteSeeker) Write(b []byte) (int, error) { - ws.buf = append(ws.buf, b...) - return len(b), nil -} - -// Copied from Go stdlib bytes.Reader -func (ws *bytesReadWriteSeeker) Seek(offset int64, whence int) (int64, error) { - var abs int64 - switch whence { - case 0: - abs = offset - case 1: - abs = int64(ws.i) + offset - case 2: - abs = int64(len(ws.buf)) + offset - default: - return 0, errors.New("bytes.Reader.Seek: invalid whence") - } - if abs < 0 { - return 0, errors.New("bytes.Reader.Seek: negative position") - } - ws.i = abs - return abs, nil -} diff --git a/protobuf/compact_log_snapshot.proto b/protobuf/compact_log_snapshot.proto index 35ddd1001..a5511a84b 100644 --- a/protobuf/compact_log_snapshot.proto +++ b/protobuf/compact_log_snapshot.proto @@ -211,6 +211,8 @@ message LogLineInformation { int32 relation_idx = 19; repeated int32 related_pids = 20; // Other PIDs that are related to this log line (mentioned in some way) + + string content = 21; } message QuerySample { diff --git a/runner/activity.go b/runner/activity.go index 428d8463e..aa3b5e021 100644 --- a/runner/activity.go +++ b/runner/activity.go @@ -8,7 +8,6 @@ import ( "sync" "time" - "github.com/pganalyze/collector/grant" "github.com/pganalyze/collector/input/postgres" "github.com/pganalyze/collector/output" "github.com/pganalyze/collector/selftest" @@ -51,7 +50,7 @@ func processActivityForServer(ctx context.Context, server *state.Server, globalC } if !newGrant.Valid && !globalCollectionOpts.ForceEmptyGrant { - newGrant, err = grant.GetDefaultGrant(ctx, server, globalCollectionOpts, logger) + newGrant, err = output.GetGrant(ctx, server, globalCollectionOpts, logger) if err != nil { return newState, false, errors.Wrap(err, "could not get default grant for activity snapshot") } diff --git a/runner/full.go b/runner/full.go index 84084f887..14fd5e375 100644 --- a/runner/full.go +++ b/runner/full.go @@ -10,7 +10,6 @@ import ( "time" raven "github.com/getsentry/raven-go" - "github.com/pganalyze/collector/grant" "github.com/pganalyze/collector/input" "github.com/pganalyze/collector/input/postgres" "github.com/pganalyze/collector/logs" @@ -104,7 +103,7 @@ func processServer(ctx context.Context, server *state.Server, globalCollectionOp if server.WebSocket.Load() != nil { newGrant = *server.Grant.Load() } else if !globalCollectionOpts.ForceEmptyGrant { - newGrant, err = grant.GetDefaultGrant(ctx, server, globalCollectionOpts, logger) + newGrant, err = output.GetGrant(ctx, server, globalCollectionOpts, logger) if err != nil { if server.Grant.Load().Valid { logger.PrintVerbose("Could not acquire snapshot grant, reusing previous grant: %s", err) diff --git a/runner/logs.go b/runner/logs.go index faa1e2b1c..ab356b84d 100644 --- a/runner/logs.go +++ b/runner/logs.go @@ -8,23 +8,21 @@ import ( "sync" "time" - "github.com/pganalyze/collector/input/system/tembo" - "github.com/pganalyze/collector/selftest" - "github.com/google/uuid" "github.com/guregu/null" "github.com/pganalyze/collector/config" - "github.com/pganalyze/collector/grant" "github.com/pganalyze/collector/input/postgres" "github.com/pganalyze/collector/input/system" "github.com/pganalyze/collector/input/system/azure" "github.com/pganalyze/collector/input/system/google_cloudsql" "github.com/pganalyze/collector/input/system/heroku" "github.com/pganalyze/collector/input/system/selfhosted" + "github.com/pganalyze/collector/input/system/tembo" "github.com/pganalyze/collector/logs" "github.com/pganalyze/collector/logs/querysample" "github.com/pganalyze/collector/logs/stream" "github.com/pganalyze/collector/output" + "github.com/pganalyze/collector/selftest" "github.com/pganalyze/collector/state" "github.com/pganalyze/collector/util" "github.com/pkg/errors" @@ -148,7 +146,7 @@ func downloadLogsForServerWithLocksAndCallbacks(ctx context.Context, wg *sync.Wa } func downloadLogsForServer(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger) (state.PersistedLogState, bool, error) { - grant, err := getLogsGrant(ctx, server, globalCollectionOpts, logger) + grant, err := output.GetGrant(ctx, server, globalCollectionOpts, logger) if err != nil || !grant.Valid { return server.LogPrevState, false, err } @@ -254,13 +252,19 @@ func processLogStream(ctx context.Context, server *state.Server, logLines []stat } if globalCollectionOpts.TestRun { - server.SelfTest.MarkCollectionAspectOk(state.CollectionAspectLogs) - logTestFunc(server, logFile, logTestSucceeded) - + grant := server.Grant.Load() + if !grant.Valid || grant.Config.EnableLogs { + server.SelfTest.MarkCollectionAspectOk(state.CollectionAspectLogs) + logTestFunc(server, logFile, logTestSucceeded) + } else { + server.SelfTest.MarkCollectionAspectError(state.CollectionAspectLogs, "Log Insights not available on this plan") + server.SelfTest.HintCollectionAspect(state.CollectionAspectLogs, "You may need to upgrade, see %s", selftest.URLPrinter.Sprint("https://pganalyze.com/pricing")) + logger.PrintError(" Failed - Log Insights feature not available on this pganalyze plan. You may need to upgrade, see https://pganalyze.com/pricing") + } return tooFreshLogLines } - grant, err := getLogsGrant(ctx, server, globalCollectionOpts, logger) + grant, err := output.GetGrant(ctx, server, globalCollectionOpts, logger) if err != nil { // Note we intentionally discard log lines here (and in the other // error case below), because the HTTP client already retries to work @@ -282,28 +286,7 @@ func processLogStream(ctx context.Context, server *state.Server, logLines []stat return tooFreshLogLines } -func getLogsGrant(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger) (logGrant state.GrantLogs, err error) { - logGrant, err = grant.GetLogsGrant(ctx, server, globalCollectionOpts, logger) - if err != nil { - server.SelfTest.MarkCollectionAspectError(state.CollectionAspectLogs, "error getting log grant: %s", err) - return state.GrantLogs{Valid: false}, errors.Wrap(err, "could not get log grant") - } - - if !logGrant.Valid { - if globalCollectionOpts.TestRun { - server.SelfTest.MarkCollectionAspectError(state.CollectionAspectLogs, "Log Insights not available on this plan") - server.SelfTest.HintCollectionAspect(state.CollectionAspectLogs, "You may need to upgrade, see %s", selftest.URLPrinter.Sprint("https://pganalyze.com/pricing")) - logger.PrintError(" Failed - Log Insights feature not available on this pganalyze plan, or log data limit exceeded. You may need to upgrade, see https://pganalyze.com/pricing") - } else { - logger.PrintVerbose("Skipping log data: Feature not available on this pganalyze plan, or log data limit exceeded") - } - return state.GrantLogs{Valid: false}, nil - } - - return logGrant, nil -} - -func postprocessAndSendLogs(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger, transientLogState state.TransientLogState, grant state.GrantLogs) (err error) { +func postprocessAndSendLogs(ctx context.Context, server *state.Server, globalCollectionOpts state.CollectionOpts, logger *util.Logger, transientLogState state.TransientLogState, grant state.Grant) (err error) { if server.Config.EnableLogExplain && len(transientLogState.QuerySamples) != 0 { transientLogState.QuerySamples = postgres.RunExplain(ctx, server, transientLogState.QuerySamples, globalCollectionOpts, logger) } @@ -347,10 +330,25 @@ func postprocessAndSendLogs(ctx context.Context, server *state.Server, globalCol transientLogState.LogFiles[idx].FilterLogSecret = state.ParseFilterLogSecret(server.Config.FilterLogSecret) } + for idx := range transientLogState.LogFiles { + logFile := &transientLogState.LogFiles[idx] + if len(logFile.FilterLogSecret) > 0 { + content, err := ioutil.ReadFile(logFile.TmpFile.Name()) + if err != nil { + return err + } + logFile.ByteSize = int64(len(content)) + logs.ReplaceSecrets(content, logFile.LogLines, logFile.FilterLogSecret) + } + } + if globalCollectionOpts.DebugLogs { logger.PrintInfo("Would have sent log state:\n") for _, logFile := range transientLogState.LogFiles { - content, _ := ioutil.ReadFile(logFile.TmpFile.Name()) + content, err := ioutil.ReadFile(logFile.TmpFile.Name()) + if err != nil { + return err + } logs.PrintDebugInfo(string(content), logFile.LogLines, transientLogState.QuerySamples) } return nil