diff --git a/proto/gen/rill/runtime/v1/resources.pb.go b/proto/gen/rill/runtime/v1/resources.pb.go index 700fba627fd..0e61693153f 100644 --- a/proto/gen/rill/runtime/v1/resources.pb.go +++ b/proto/gen/rill/runtime/v1/resources.pb.go @@ -126,6 +126,119 @@ func (ExploreComparisonMode) EnumDescriptor() ([]byte, []int) { return file_rill_runtime_v1_resources_proto_rawDescGZIP(), []int{1} } +type ExploreWebView int32 + +const ( + ExploreWebView_EXPLORE_WEB_VIEW_UNSPECIFIED ExploreWebView = 0 + ExploreWebView_EXPLORE_WEB_VIEW_EXPLORE ExploreWebView = 1 + ExploreWebView_EXPLORE_WEB_VIEW_TIME_DIMENSION ExploreWebView = 2 + ExploreWebView_EXPLORE_WEB_VIEW_PIVOT ExploreWebView = 3 + ExploreWebView_EXPLORE_WEB_VIEW_CANVAS ExploreWebView = 4 +) + +// Enum value maps for ExploreWebView. +var ( + ExploreWebView_name = map[int32]string{ + 0: "EXPLORE_WEB_VIEW_UNSPECIFIED", + 1: "EXPLORE_WEB_VIEW_EXPLORE", + 2: "EXPLORE_WEB_VIEW_TIME_DIMENSION", + 3: "EXPLORE_WEB_VIEW_PIVOT", + 4: "EXPLORE_WEB_VIEW_CANVAS", + } + ExploreWebView_value = map[string]int32{ + "EXPLORE_WEB_VIEW_UNSPECIFIED": 0, + "EXPLORE_WEB_VIEW_EXPLORE": 1, + "EXPLORE_WEB_VIEW_TIME_DIMENSION": 2, + "EXPLORE_WEB_VIEW_PIVOT": 3, + "EXPLORE_WEB_VIEW_CANVAS": 4, + } +) + +func (x ExploreWebView) Enum() *ExploreWebView { + p := new(ExploreWebView) + *p = x + return p +} + +func (x ExploreWebView) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExploreWebView) Descriptor() protoreflect.EnumDescriptor { + return file_rill_runtime_v1_resources_proto_enumTypes[2].Descriptor() +} + +func (ExploreWebView) Type() protoreflect.EnumType { + return &file_rill_runtime_v1_resources_proto_enumTypes[2] +} + +func (x ExploreWebView) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExploreWebView.Descriptor instead. +func (ExploreWebView) EnumDescriptor() ([]byte, []int) { + return file_rill_runtime_v1_resources_proto_rawDescGZIP(), []int{2} +} + +type ExploreSortType int32 + +const ( + ExploreSortType_EXPLORE_SORT_TYPE_UNSPECIFIED ExploreSortType = 0 + ExploreSortType_EXPLORE_SORT_TYPE_VALUE ExploreSortType = 1 + ExploreSortType_EXPLORE_SORT_TYPE_PERCENT ExploreSortType = 2 + ExploreSortType_EXPLORE_SORT_TYPE_DELTA_PERCENT ExploreSortType = 3 + ExploreSortType_EXPLORE_SORT_TYPE_DELTA_ABSOLUTE ExploreSortType = 4 + ExploreSortType_EXPLORE_SORT_TYPE_DIMENSION ExploreSortType = 5 +) + +// Enum value maps for ExploreSortType. +var ( + ExploreSortType_name = map[int32]string{ + 0: "EXPLORE_SORT_TYPE_UNSPECIFIED", + 1: "EXPLORE_SORT_TYPE_VALUE", + 2: "EXPLORE_SORT_TYPE_PERCENT", + 3: "EXPLORE_SORT_TYPE_DELTA_PERCENT", + 4: "EXPLORE_SORT_TYPE_DELTA_ABSOLUTE", + 5: "EXPLORE_SORT_TYPE_DIMENSION", + } + ExploreSortType_value = map[string]int32{ + "EXPLORE_SORT_TYPE_UNSPECIFIED": 0, + "EXPLORE_SORT_TYPE_VALUE": 1, + "EXPLORE_SORT_TYPE_PERCENT": 2, + "EXPLORE_SORT_TYPE_DELTA_PERCENT": 3, + "EXPLORE_SORT_TYPE_DELTA_ABSOLUTE": 4, + "EXPLORE_SORT_TYPE_DIMENSION": 5, + } +) + +func (x ExploreSortType) Enum() *ExploreSortType { + p := new(ExploreSortType) + *p = x + return p +} + +func (x ExploreSortType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExploreSortType) Descriptor() protoreflect.EnumDescriptor { + return file_rill_runtime_v1_resources_proto_enumTypes[3].Descriptor() +} + +func (ExploreSortType) Type() protoreflect.EnumType { + return &file_rill_runtime_v1_resources_proto_enumTypes[3] +} + +func (x ExploreSortType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExploreSortType.Descriptor instead. +func (ExploreSortType) EnumDescriptor() ([]byte, []int) { + return file_rill_runtime_v1_resources_proto_rawDescGZIP(), []int{3} +} + type AssertionStatus int32 const ( @@ -162,11 +275,11 @@ func (x AssertionStatus) String() string { } func (AssertionStatus) Descriptor() protoreflect.EnumDescriptor { - return file_rill_runtime_v1_resources_proto_enumTypes[2].Descriptor() + return file_rill_runtime_v1_resources_proto_enumTypes[4].Descriptor() } func (AssertionStatus) Type() protoreflect.EnumType { - return &file_rill_runtime_v1_resources_proto_enumTypes[2] + return &file_rill_runtime_v1_resources_proto_enumTypes[4] } func (x AssertionStatus) Number() protoreflect.EnumNumber { @@ -175,7 +288,7 @@ func (x AssertionStatus) Number() protoreflect.EnumNumber { // Deprecated: Use AssertionStatus.Descriptor instead. func (AssertionStatus) EnumDescriptor() ([]byte, []int) { - return file_rill_runtime_v1_resources_proto_rawDescGZIP(), []int{2} + return file_rill_runtime_v1_resources_proto_rawDescGZIP(), []int{4} } // Type of measure query to generate @@ -215,11 +328,11 @@ func (x MetricsViewSpec_MeasureType) String() string { } func (MetricsViewSpec_MeasureType) Descriptor() protoreflect.EnumDescriptor { - return file_rill_runtime_v1_resources_proto_enumTypes[3].Descriptor() + return file_rill_runtime_v1_resources_proto_enumTypes[5].Descriptor() } func (MetricsViewSpec_MeasureType) Type() protoreflect.EnumType { - return &file_rill_runtime_v1_resources_proto_enumTypes[3] + return &file_rill_runtime_v1_resources_proto_enumTypes[5] } func (x MetricsViewSpec_MeasureType) Number() protoreflect.EnumNumber { @@ -269,11 +382,11 @@ func (x MetricsViewSpec_ComparisonMode) String() string { } func (MetricsViewSpec_ComparisonMode) Descriptor() protoreflect.EnumDescriptor { - return file_rill_runtime_v1_resources_proto_enumTypes[4].Descriptor() + return file_rill_runtime_v1_resources_proto_enumTypes[6].Descriptor() } func (MetricsViewSpec_ComparisonMode) Type() protoreflect.EnumType { - return &file_rill_runtime_v1_resources_proto_enumTypes[4] + return &file_rill_runtime_v1_resources_proto_enumTypes[6] } func (x MetricsViewSpec_ComparisonMode) Number() protoreflect.EnumNumber { @@ -318,11 +431,11 @@ func (x BucketExtractPolicy_Strategy) String() string { } func (BucketExtractPolicy_Strategy) Descriptor() protoreflect.EnumDescriptor { - return file_rill_runtime_v1_resources_proto_enumTypes[5].Descriptor() + return file_rill_runtime_v1_resources_proto_enumTypes[7].Descriptor() } func (BucketExtractPolicy_Strategy) Type() protoreflect.EnumType { - return &file_rill_runtime_v1_resources_proto_enumTypes[5] + return &file_rill_runtime_v1_resources_proto_enumTypes[7] } func (x BucketExtractPolicy_Strategy) Number() protoreflect.EnumNumber { @@ -2647,14 +2760,31 @@ type ExplorePreset struct { Measures []string `protobuf:"bytes,4,rep,name=measures,proto3" json:"measures,omitempty"` // Dynamic selector for `measures`. Will be processed during validation, so it will always be empty in `state.valid_spec`. MeasuresSelector *FieldSelector `protobuf:"bytes,10,opt,name=measures_selector,json=measuresSelector,proto3" json:"measures_selector,omitempty"` + Where *Expression `protobuf:"bytes,11,opt,name=where,proto3,oneof" json:"where,omitempty"` // Time range for the explore. // It corresponds to the `range` property of the explore's `time_ranges`. // If not found in `time_ranges`, it should be added to the list. - TimeRange string `protobuf:"bytes,6,opt,name=time_range,json=timeRange,proto3" json:"time_range,omitempty"` + TimeRange *string `protobuf:"bytes,6,opt,name=time_range,json=timeRange,proto3,oneof" json:"time_range,omitempty"` + Timezone *string `protobuf:"bytes,12,opt,name=timezone,proto3,oneof" json:"timezone,omitempty"` + TimeGrain *string `protobuf:"bytes,13,opt,name=time_grain,json=timeGrain,proto3,oneof" json:"time_grain,omitempty"` + SelectTimeRange *string `protobuf:"bytes,14,opt,name=select_time_range,json=selectTimeRange,proto3,oneof" json:"select_time_range,omitempty"` // Comparison mode. - ComparisonMode ExploreComparisonMode `protobuf:"varint,7,opt,name=comparison_mode,json=comparisonMode,proto3,enum=rill.runtime.v1.ExploreComparisonMode" json:"comparison_mode,omitempty"` + ComparisonMode ExploreComparisonMode `protobuf:"varint,7,opt,name=comparison_mode,json=comparisonMode,proto3,enum=rill.runtime.v1.ExploreComparisonMode" json:"comparison_mode,omitempty"` + CompareTimeRange *string `protobuf:"bytes,15,opt,name=compare_time_range,json=compareTimeRange,proto3,oneof" json:"compare_time_range,omitempty"` // If comparison_mode is EXPLORE_COMPARISON_MODE_DIMENSION, this indicates the dimension to use. - ComparisonDimension string `protobuf:"bytes,8,opt,name=comparison_dimension,json=comparisonDimension,proto3" json:"comparison_dimension,omitempty"` + ComparisonDimension *string `protobuf:"bytes,8,opt,name=comparison_dimension,json=comparisonDimension,proto3,oneof" json:"comparison_dimension,omitempty"` + View *ExploreWebView `protobuf:"varint,16,opt,name=view,proto3,enum=rill.runtime.v1.ExploreWebView,oneof" json:"view,omitempty"` + ExploreSortBy *string `protobuf:"bytes,17,opt,name=explore_sort_by,json=exploreSortBy,proto3,oneof" json:"explore_sort_by,omitempty"` + ExploreSortAsc *bool `protobuf:"varint,18,opt,name=explore_sort_asc,json=exploreSortAsc,proto3,oneof" json:"explore_sort_asc,omitempty"` + ExploreSortType *ExploreSortType `protobuf:"varint,19,opt,name=explore_sort_type,json=exploreSortType,proto3,enum=rill.runtime.v1.ExploreSortType,oneof" json:"explore_sort_type,omitempty"` + ExploreExpandedDimension *string `protobuf:"bytes,20,opt,name=explore_expanded_dimension,json=exploreExpandedDimension,proto3,oneof" json:"explore_expanded_dimension,omitempty"` + TimeDimensionMeasure *string `protobuf:"bytes,21,opt,name=time_dimension_measure,json=timeDimensionMeasure,proto3,oneof" json:"time_dimension_measure,omitempty"` + TimeDimensionChartType *string `protobuf:"bytes,22,opt,name=time_dimension_chart_type,json=timeDimensionChartType,proto3,oneof" json:"time_dimension_chart_type,omitempty"` + TimeDimensionPin *bool `protobuf:"varint,23,opt,name=time_dimension_pin,json=timeDimensionPin,proto3,oneof" json:"time_dimension_pin,omitempty"` + PivotRows []string `protobuf:"bytes,24,rep,name=pivot_rows,json=pivotRows,proto3" json:"pivot_rows,omitempty"` + PivotCols []string `protobuf:"bytes,25,rep,name=pivot_cols,json=pivotCols,proto3" json:"pivot_cols,omitempty"` + PivotSortBy *string `protobuf:"bytes,26,opt,name=pivot_sort_by,json=pivotSortBy,proto3,oneof" json:"pivot_sort_by,omitempty"` + PivotSortAsc *bool `protobuf:"varint,27,opt,name=pivot_sort_asc,json=pivotSortAsc,proto3,oneof" json:"pivot_sort_asc,omitempty"` } func (x *ExplorePreset) Reset() { @@ -2717,9 +2847,37 @@ func (x *ExplorePreset) GetMeasuresSelector() *FieldSelector { return nil } -func (x *ExplorePreset) GetTimeRange() string { +func (x *ExplorePreset) GetWhere() *Expression { if x != nil { - return x.TimeRange + return x.Where + } + return nil +} + +func (x *ExplorePreset) GetTimeRange() string { + if x != nil && x.TimeRange != nil { + return *x.TimeRange + } + return "" +} + +func (x *ExplorePreset) GetTimezone() string { + if x != nil && x.Timezone != nil { + return *x.Timezone + } + return "" +} + +func (x *ExplorePreset) GetTimeGrain() string { + if x != nil && x.TimeGrain != nil { + return *x.TimeGrain + } + return "" +} + +func (x *ExplorePreset) GetSelectTimeRange() string { + if x != nil && x.SelectTimeRange != nil { + return *x.SelectTimeRange } return "" } @@ -2731,13 +2889,104 @@ func (x *ExplorePreset) GetComparisonMode() ExploreComparisonMode { return ExploreComparisonMode_EXPLORE_COMPARISON_MODE_UNSPECIFIED } +func (x *ExplorePreset) GetCompareTimeRange() string { + if x != nil && x.CompareTimeRange != nil { + return *x.CompareTimeRange + } + return "" +} + func (x *ExplorePreset) GetComparisonDimension() string { + if x != nil && x.ComparisonDimension != nil { + return *x.ComparisonDimension + } + return "" +} + +func (x *ExplorePreset) GetView() ExploreWebView { + if x != nil && x.View != nil { + return *x.View + } + return ExploreWebView_EXPLORE_WEB_VIEW_UNSPECIFIED +} + +func (x *ExplorePreset) GetExploreSortBy() string { + if x != nil && x.ExploreSortBy != nil { + return *x.ExploreSortBy + } + return "" +} + +func (x *ExplorePreset) GetExploreSortAsc() bool { + if x != nil && x.ExploreSortAsc != nil { + return *x.ExploreSortAsc + } + return false +} + +func (x *ExplorePreset) GetExploreSortType() ExploreSortType { + if x != nil && x.ExploreSortType != nil { + return *x.ExploreSortType + } + return ExploreSortType_EXPLORE_SORT_TYPE_UNSPECIFIED +} + +func (x *ExplorePreset) GetExploreExpandedDimension() string { + if x != nil && x.ExploreExpandedDimension != nil { + return *x.ExploreExpandedDimension + } + return "" +} + +func (x *ExplorePreset) GetTimeDimensionMeasure() string { + if x != nil && x.TimeDimensionMeasure != nil { + return *x.TimeDimensionMeasure + } + return "" +} + +func (x *ExplorePreset) GetTimeDimensionChartType() string { + if x != nil && x.TimeDimensionChartType != nil { + return *x.TimeDimensionChartType + } + return "" +} + +func (x *ExplorePreset) GetTimeDimensionPin() bool { + if x != nil && x.TimeDimensionPin != nil { + return *x.TimeDimensionPin + } + return false +} + +func (x *ExplorePreset) GetPivotRows() []string { + if x != nil { + return x.PivotRows + } + return nil +} + +func (x *ExplorePreset) GetPivotCols() []string { if x != nil { - return x.ComparisonDimension + return x.PivotCols + } + return nil +} + +func (x *ExplorePreset) GetPivotSortBy() string { + if x != nil && x.PivotSortBy != nil { + return *x.PivotSortBy } return "" } +func (x *ExplorePreset) GetPivotSortAsc() bool { + if x != nil && x.PivotSortAsc != nil { + return *x.PivotSortAsc + } + return false +} + // FieldSelector describes logic for selecting a list of fields. // It is useful for dynamically evaluating fields when the list of potential fields is not known at parse time. type FieldSelector struct { @@ -7136,7 +7385,7 @@ var file_rill_runtime_v1_resources_proto_rawDesc = []byte{ 0x73, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x8c, 0x03, 0x0a, 0x0d, 0x45, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0xba, 0x0c, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x13, @@ -7151,613 +7400,713 @@ var file_rill_runtime_v1_resources_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x10, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, - 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, - 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, - 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, - 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, - 0x69, 0x73, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, - 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xca, 0x01, 0x0a, 0x0d, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x69, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, - 0x65, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x48, 0x00, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x11, 0x64, - 0x75, 0x63, 0x6b, 0x64, 0x62, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x64, 0x75, 0x63, 0x6b, 0x64, 0x62, - 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x29, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x22, 0x76, 0x0a, 0x09, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, - 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x59, 0x0a, 0x0d, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x2a, 0x0a, 0x0e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x6d, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x32, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, - 0xf5, 0x05, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, - 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x10, 0x72, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x52, 0x0f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x73, 0x4a, 0x73, 0x6f, - 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, - 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x73, 0x12, 0x4e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x88, 0x01, 0x01, 0x12, 0x22, + 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x01, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x88, + 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x69, + 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x47, + 0x72, 0x61, 0x69, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x04, 0x52, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x4f, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x31, 0x0a, 0x12, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x09, 0x48, 0x05, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x14, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x13, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x88, 0x01, 0x01, 0x12, 0x38, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x56, + 0x69, 0x65, 0x77, 0x48, 0x07, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x88, 0x01, 0x01, 0x12, 0x2b, + 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, + 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x48, 0x08, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x53, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x10, 0x65, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x61, 0x73, 0x63, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x08, 0x48, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, + 0x53, 0x6f, 0x72, 0x74, 0x41, 0x73, 0x63, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, 0x11, 0x65, 0x78, + 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x53, + 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x0a, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x53, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, + 0x1a, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, + 0x64, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x0b, 0x52, 0x18, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x45, 0x78, 0x70, 0x61, + 0x6e, 0x64, 0x65, 0x64, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, + 0x12, 0x39, 0x0a, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x0c, 0x52, 0x14, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x19, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0d, + 0x52, 0x16, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x43, + 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x12, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x69, + 0x6e, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x48, 0x0e, 0x52, 0x10, 0x74, 0x69, 0x6d, 0x65, 0x44, + 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x69, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1d, + 0x0a, 0x0a, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x18, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x19, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x09, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x43, 0x6f, 0x6c, 0x73, 0x12, 0x27, 0x0a, 0x0d, + 0x70, 0x69, 0x76, 0x6f, 0x74, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x18, 0x1a, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x0f, 0x52, 0x0b, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x6f, 0x72, 0x74, + 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x5f, 0x73, + 0x6f, 0x72, 0x74, 0x5f, 0x61, 0x73, 0x63, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x48, 0x10, 0x52, + 0x0c, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x53, 0x6f, 0x72, 0x74, 0x41, 0x73, 0x63, 0x88, 0x01, 0x01, + 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x77, 0x68, 0x65, 0x72, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x67, 0x72, 0x61, 0x69, 0x6e, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x15, 0x0a, 0x13, 0x5f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, + 0x6e, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x5f, + 0x76, 0x69, 0x65, 0x77, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, + 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x65, 0x78, 0x70, + 0x6c, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x61, 0x73, 0x63, 0x42, 0x14, 0x0a, + 0x12, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x42, 0x1d, 0x0a, 0x1b, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x5f, + 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x42, 0x19, 0x0a, 0x17, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x42, 0x1c, 0x0a, + 0x1a, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x15, 0x0a, 0x13, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x69, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x5f, 0x73, 0x6f, 0x72, + 0x74, 0x5f, 0x62, 0x79, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x70, 0x69, 0x76, 0x6f, 0x74, 0x5f, 0x73, + 0x6f, 0x72, 0x74, 0x5f, 0x61, 0x73, 0x63, 0x22, 0xca, 0x01, 0x0a, 0x0d, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x12, 0x12, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, + 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x3a, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x12, 0x16, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x11, 0x64, 0x75, 0x63, + 0x6b, 0x64, 0x62, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x64, 0x75, 0x63, 0x6b, 0x64, 0x62, 0x45, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x22, 0x29, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, + 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, + 0x76, 0x0a, 0x09, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x59, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x22, 0x2a, 0x0a, 0x0e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x6d, + 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, - 0x70, 0x65, 0x63, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x69, - 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x77, 0x61, - 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x12, 0x34, - 0x0a, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x69, 0x73, 0x6f, 0x5f, - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x49, 0x73, 0x6f, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, - 0x18, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x5f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, - 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x90, 0x02, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x6e, 0x65, 0x78, 0x74, 0x5f, - 0x72, 0x75, 0x6e, 0x5f, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xf5, 0x05, + 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x10, 0x72, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x0f, + 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, + 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x42, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, + 0x4e, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x2b, 0x0a, 0x11, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x68, + 0x65, 0x72, 0x69, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x77, 0x61, 0x74, 0x65, + 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x12, 0x34, 0x0a, 0x16, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x69, 0x73, 0x6f, 0x5f, 0x64, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x49, 0x73, 0x6f, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, + 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x6e, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x90, 0x02, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0b, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x75, + 0x6e, 0x5f, 0x6f, 0x6e, 0x18, 0x01, 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, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x75, 0x6e, 0x4f, + 0x6e, 0x12, 0x4d, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x4d, 0x0a, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x69, + 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x81, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x61, 0x64, 0x68, 0x6f, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x68, + 0x6f, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 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, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x75, - 0x6e, 0x4f, 0x6e, 0x12, 0x4d, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, + 0x6f, 0x6e, 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, 0x65, 0x64, 0x4f, 0x6e, 0x12, + 0x3b, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x05, + 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, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x6e, 0x22, 0x6a, 0x0a, 0x05, + 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, + 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xf8, 0x08, 0x0a, 0x09, 0x41, 0x6c, 0x65, + 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x10, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, - 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x81, 0x02, 0x0a, 0x0f, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, - 0x0a, 0x05, 0x61, 0x64, 0x68, 0x6f, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, - 0x64, 0x68, 0x6f, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 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, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x6f, 0x6e, 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, 0x65, 0x64, 0x4f, - 0x6e, 0x12, 0x3b, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x6f, 0x6e, - 0x18, 0x05, 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, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x6e, 0x22, 0x6a, - 0x0a, 0x05, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xf8, 0x08, 0x0a, 0x09, 0x41, - 0x6c, 0x65, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, - 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, - 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x10, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x0f, 0x72, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x77, - 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, - 0x6b, 0x49, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x69, 0x73, 0x6f, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x73, 0x49, 0x73, 0x6f, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, - 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, - 0x73, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, - 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x73, 0x4a, 0x73, 0x6f, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x16, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, - 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, - 0x74, 0x69, 0x65, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x55, 0x73, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x14, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x66, 0x6f, - 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x11, 0x71, 0x75, 0x65, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x55, 0x73, - 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4b, 0x0a, 0x14, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, - 0x52, 0x12, 0x71, 0x75, 0x65, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6f, - 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6f, 0x6e, 0x5f, 0x66, 0x61, - 0x69, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x4f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x5f, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x72, 0x65, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x72, 0x65, 0x6e, 0x6f, - 0x74, 0x69, 0x66, 0x79, 0x41, 0x66, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x12, 0x37, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x18, 0x15, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x5f, 0x66, 0x6f, 0x72, 0x22, 0x61, 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, - 0x37, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x0f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x77, 0x61, 0x74, + 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x49, + 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x73, 0x5f, 0x69, 0x73, 0x6f, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x73, 0x49, 0x73, 0x6f, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x73, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x41, 0x72, 0x67, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x16, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x66, + 0x6f, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x31, 0x0a, 0x14, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x66, 0x6f, 0x72, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x11, 0x71, 0x75, 0x65, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, + 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4b, 0x0a, 0x14, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x66, + 0x6f, 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x70, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x0a, 0x41, 0x6c, 0x65, - 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x5f, - 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x65, 0x63, - 0x48, 0x61, 0x73, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x73, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x66, 0x73, 0x48, 0x61, 0x73, - 0x68, 0x12, 0x3a, 0x0a, 0x0b, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x6f, 0x6e, - 0x18, 0x03, 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, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x6e, 0x12, 0x4c, 0x0a, - 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x11, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x12, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6f, 0x6e, 0x5f, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x24, + 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x69, 0x6c, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, + 0x46, 0x61, 0x69, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6f, + 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x72, 0x65, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x72, 0x65, 0x6e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x41, 0x66, 0x74, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x37, + 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x6c, 0x65, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, + 0x66, 0x6f, 0x72, 0x22, 0x61, 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x37, 0x0a, + 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x0a, 0x41, 0x6c, 0x65, 0x72, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x65, 0x63, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x66, 0x73, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x3a, 0x0a, 0x0b, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x6f, 0x6e, 0x18, 0x03, + 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, 0x6e, 0x65, 0x78, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x6e, 0x12, 0x4c, 0x0a, 0x11, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x91, 0x03, 0x0a, 0x0e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x68, 0x6f, 0x63, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x68, 0x6f, 0x63, 0x12, 0x38, 0x0a, 0x06, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, - 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x6f, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x11, 0x73, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 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, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x05, 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, 0x65, 0x64, - 0x4f, 0x6e, 0x12, 0x3b, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x6f, - 0x6e, 0x18, 0x06, 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, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x6e, 0x12, - 0x45, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73, 0x69, - 0x6e, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x11, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0x91, 0x03, 0x0a, 0x0e, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x68, 0x6f, 0x63, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x68, 0x6f, 0x63, 0x12, 0x38, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, + 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x11, 0x73, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 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, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, + 0x5f, 0x6f, 0x6e, 0x18, 0x05, 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, 0x0f, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, - 0x64, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x72, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, - 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x72, 0x6f, 0x77, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, - 0x07, 0x66, 0x61, 0x69, 0x6c, 0x52, 0x6f, 0x77, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7c, 0x0a, - 0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x04, - 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, - 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x12, 0x37, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x50, - 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x22, 0x12, - 0x0a, 0x10, 0x50, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x22, 0x85, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, - 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3a, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x52, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, - 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x22, 0x15, 0x0a, 0x13, - 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, - 0x6f, 0x64, 0x65, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, - 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x04, 0x66, 0x75, 0x6c, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x65, - 0x64, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x82, 0x01, 0x0a, 0x0d, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x36, 0x0a, - 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x4f, 0x6e, + 0x12, 0x3b, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, + 0x06, 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, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x45, 0x0a, + 0x10, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x6e, 0x63, + 0x65, 0x18, 0x07, 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, 0x0f, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, + 0x69, 0x6e, 0x63, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x72, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x72, 0x6f, 0x77, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x66, + 0x61, 0x69, 0x6c, 0x52, 0x6f, 0x77, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7c, 0x0a, 0x0b, 0x50, + 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x54, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x12, 0x37, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x50, 0x75, 0x6c, + 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x22, 0x12, 0x0a, 0x10, + 0x50, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x22, 0x85, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, + 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x06, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, + 0x65, 0x72, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x22, 0x95, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x66, + 0x75, 0x6c, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x50, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x82, 0x01, 0x0a, 0x0d, 0x42, 0x75, + 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, + 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x60, + 0x0a, 0x11, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x4b, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, - 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, - 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x22, 0x60, 0x0a, 0x11, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, - 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4b, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x22, 0x2c, 0x0a, 0x12, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x22, 0xd6, + 0x02, 0x0a, 0x13, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x22, 0x2c, 0x0a, 0x12, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x6c, 0x61, 0x6e, - 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, - 0x22, 0xd6, 0x02, 0x0a, 0x13, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x6f, 0x77, 0x73, - 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0c, - 0x72, 0x6f, 0x77, 0x73, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x10, - 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x4c, 0x69, 0x6d, 0x69, - 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, - 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, + 0x69, 0x63, 0x79, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0c, 0x72, 0x6f, + 0x77, 0x73, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x6f, + 0x77, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x72, 0x6f, 0x77, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x4a, 0x0a, 0x08, 0x53, + 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x54, 0x52, 0x41, 0x54, + 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x48, 0x45, + 0x41, 0x44, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, + 0x5f, 0x54, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x22, 0x6a, 0x0a, 0x05, 0x54, 0x68, 0x65, 0x6d, 0x65, + 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x1f, 0x0a, 0x0b, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x4a, 0x0a, - 0x08, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x54, 0x52, - 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, 0x47, 0x59, 0x5f, - 0x48, 0x45, 0x41, 0x44, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x52, 0x41, 0x54, 0x45, - 0x47, 0x59, 0x5f, 0x54, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x22, 0x6a, 0x0a, 0x05, 0x54, 0x68, 0x65, - 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x95, 0x02, 0x0a, 0x09, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x40, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, - 0x6f, 0x72, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6c, - 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, - 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x22, 0x95, 0x02, 0x0a, 0x09, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x40, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x48, 0x00, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, + 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6c, 0x6f, 0x72, 0x48, 0x01, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, + 0x79, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, 0x11, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x52, 0x61, 0x77, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, + 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x52, 0x61, 0x77, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x0c, 0x0a, 0x0a, 0x54, + 0x68, 0x65, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x76, 0x0a, 0x09, 0x43, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x22, 0xd6, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, + 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x52, 0x12, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x3a, + 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x48, 0x01, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, 0x11, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x72, 0x61, 0x77, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, - 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x61, 0x77, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x72, 0x61, 0x77, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x43, - 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x61, 0x77, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x73, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x0c, 0x0a, - 0x0a, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x76, 0x0a, 0x09, 0x43, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, - 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x35, 0x0a, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x22, 0xd6, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, - 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, - 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, - 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x68, + 0x6f, 0x77, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x2a, + 0x0a, 0x11, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e, + 0x76, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x22, 0x4f, 0x0a, 0x0e, 0x43, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x0a, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0x78, 0x0a, 0x11, 0x43, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6d, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, + 0x2f, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x22, 0x96, 0x02, 0x0a, 0x0a, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, + 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x67, + 0x61, 0x70, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x12, 0x3a, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x68, 0x6f, 0x77, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x68, 0x6f, 0x77, - 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x63, - 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x65, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x22, 0x4f, 0x0a, 0x0e, - 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3d, - 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x70, - 0x65, 0x63, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0x78, 0x0a, - 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x0d, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6d, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x76, 0x61, - 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x96, 0x02, 0x0a, 0x0a, 0x43, 0x61, 0x6e, 0x76, 0x61, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, - 0x6d, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, - 0x6e, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x03, 0x67, 0x61, 0x70, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x09, 0x76, 0x61, 0x72, - 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x49, 0x74, - 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x73, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, - 0x52, 0x0d, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, - 0x49, 0x0a, 0x0b, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, - 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x52, - 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0xd5, 0x01, 0x0a, 0x0a, 0x43, - 0x61, 0x6e, 0x76, 0x61, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x69, 0x6e, - 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x6e, - 0x76, 0x61, 0x73, 0x12, 0x11, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, - 0x52, 0x01, 0x78, 0x88, 0x01, 0x01, 0x12, 0x11, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0d, 0x48, 0x01, 0x52, 0x01, 0x79, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0d, 0x48, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, - 0x01, 0x42, 0x04, 0x0a, 0x02, 0x5f, 0x78, 0x42, 0x04, 0x0a, 0x02, 0x5f, 0x79, 0x42, 0x08, 0x0a, - 0x06, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x22, 0x64, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2c, 0x0a, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xb1, 0x02, 0x0a, 0x07, 0x41, 0x50, 0x49, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, - 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x49, 0x74, 0x65, 0x6d, + 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x49, 0x0a, + 0x0b, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x0a, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x53, 0x70, 0x65, 0x63, 0x22, 0xd5, 0x01, 0x0a, 0x0a, 0x43, 0x61, 0x6e, + 0x76, 0x61, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, + 0x5f, 0x69, 0x6e, 0x5f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x49, 0x6e, 0x43, 0x61, 0x6e, 0x76, 0x61, + 0x73, 0x12, 0x11, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x01, + 0x78, 0x88, 0x01, 0x01, 0x12, 0x11, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, + 0x01, 0x52, 0x01, 0x79, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x88, + 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x48, 0x03, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, + 0x04, 0x0a, 0x02, 0x5f, 0x78, 0x42, 0x04, 0x0a, 0x02, 0x5f, 0x79, 0x42, 0x08, 0x0a, 0x06, 0x5f, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x22, 0x64, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2c, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x70, 0x65, 0x63, 0x52, + 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xb1, 0x02, 0x0a, 0x07, 0x41, 0x50, 0x49, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, + 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x6e, + 0x61, 0x70, 0x69, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x12, 0x46, 0x0a, 0x12, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, - 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x70, - 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x12, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x11, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, - 0x69, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x17, 0x6f, - 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x15, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x0a, 0x0a, 0x08, - 0x41, 0x50, 0x49, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x5f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x66, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72, - 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x69, 0x63, 0x6b, - 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, - 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x0e, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22, 0x50, - 0x0a, 0x0f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x50, 0x61, 0x74, 0x68, - 0x22, 0x4b, 0x0a, 0x0f, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x45, 0x72, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x11, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x17, 0x6f, 0x70, 0x65, + 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x52, 0x15, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x0a, 0x0a, 0x08, 0x41, 0x50, + 0x49, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x66, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, + 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, + 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, - 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x2a, 0x0a, - 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x0e, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22, 0x50, 0x0a, 0x0f, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x43, 0x68, 0x61, - 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0xae, 0x03, - 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x72, 0x69, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x50, 0x61, 0x74, 0x68, 0x22, 0x4b, + 0x0a, 0x0f, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, + 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x2a, 0x0a, 0x0e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x72, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0xae, 0x03, 0x0a, 0x0d, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, + 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x13, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x77, 0x0a, 0x19, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x70, - 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x64, - 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x77, 0x0a, 0x19, 0x70, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x76, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x17, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2d, - 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x65, 0x63, 0x48, 0x61, 0x73, 0x68, 0x22, 0x78, 0x0a, - 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x12, 0x32, 0x0a, 0x04, - 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, - 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x8a, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x6f, - 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x52, + 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x17, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x4a, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x46, 0x72, + 0x6f, 0x6d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2d, 0x0a, 0x0e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x70, 0x65, 0x63, 0x48, 0x61, 0x73, 0x68, 0x22, 0x78, 0x0a, 0x0b, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x12, 0x32, 0x0a, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x35, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x8a, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, + 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x43, + 0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, - 0x15, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, - 0x4e, 0x43, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, - 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, - 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, - 0x4e, 0x47, 0x10, 0x03, 0x2a, 0xab, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, - 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27, - 0x0a, 0x23, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, - 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, + 0x49, 0x44, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, + 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, + 0x4e, 0x47, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x43, 0x49, 0x4c, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, + 0x10, 0x03, 0x2a, 0xab, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x43, 0x6f, + 0x6d, 0x70, 0x61, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27, 0x0a, 0x23, + 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, + 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, + 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, - 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, + 0x44, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, 0x4e, 0x5f, - 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x25, 0x0a, 0x21, 0x45, - 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x52, 0x49, 0x53, 0x4f, - 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, - 0x10, 0x03, 0x2a, 0x85, 0x01, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x53, 0x53, 0x45, 0x52, 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, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, - 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, - 0x53, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x1a, - 0x0a, 0x16, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x42, 0xc1, 0x01, 0x0a, 0x13, 0x63, - 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x42, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x2e, - 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x52, 0x69, 0x6c, - 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x52, - 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x52, 0x69, 0x6c, - 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x03, + 0x2a, 0xae, 0x01, 0x0a, 0x0e, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x56, + 0x69, 0x65, 0x77, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57, + 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, + 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, + 0x45, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x57, + 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x44, 0x49, 0x4d, + 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x50, 0x4c, + 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x50, 0x49, 0x56, + 0x4f, 0x54, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, + 0x57, 0x45, 0x42, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x43, 0x41, 0x4e, 0x56, 0x41, 0x53, 0x10, + 0x04, 0x2a, 0xdc, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x72, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, + 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x50, 0x4c, + 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x41, + 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, + 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, + 0x4e, 0x54, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, + 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x4c, 0x54, 0x41, 0x5f, + 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x58, 0x50, + 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, + 0x45, 0x4c, 0x54, 0x41, 0x5f, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45, 0x10, 0x04, 0x12, + 0x1f, 0x0a, 0x1b, 0x45, 0x58, 0x50, 0x4c, 0x4f, 0x52, 0x45, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x49, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x05, + 0x2a, 0x85, 0x01, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x53, 0x53, 0x45, 0x52, 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, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x10, + 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, + 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x42, 0xc1, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x42, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, + 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, + 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, + 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, + 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -7772,267 +8121,272 @@ func file_rill_runtime_v1_resources_proto_rawDescGZIP() []byte { return file_rill_runtime_v1_resources_proto_rawDescData } -var file_rill_runtime_v1_resources_proto_enumTypes = make([]protoimpl.EnumInfo, 6) +var file_rill_runtime_v1_resources_proto_enumTypes = make([]protoimpl.EnumInfo, 8) var file_rill_runtime_v1_resources_proto_msgTypes = make([]protoimpl.MessageInfo, 84) var file_rill_runtime_v1_resources_proto_goTypes = []any{ (ReconcileStatus)(0), // 0: rill.runtime.v1.ReconcileStatus (ExploreComparisonMode)(0), // 1: rill.runtime.v1.ExploreComparisonMode - (AssertionStatus)(0), // 2: rill.runtime.v1.AssertionStatus - (MetricsViewSpec_MeasureType)(0), // 3: rill.runtime.v1.MetricsViewSpec.MeasureType - (MetricsViewSpec_ComparisonMode)(0), // 4: rill.runtime.v1.MetricsViewSpec.ComparisonMode - (BucketExtractPolicy_Strategy)(0), // 5: rill.runtime.v1.BucketExtractPolicy.Strategy - (*Resource)(nil), // 6: rill.runtime.v1.Resource - (*ResourceMeta)(nil), // 7: rill.runtime.v1.ResourceMeta - (*ResourceName)(nil), // 8: rill.runtime.v1.ResourceName - (*ProjectParser)(nil), // 9: rill.runtime.v1.ProjectParser - (*ProjectParserSpec)(nil), // 10: rill.runtime.v1.ProjectParserSpec - (*ProjectParserState)(nil), // 11: rill.runtime.v1.ProjectParserState - (*SourceV2)(nil), // 12: rill.runtime.v1.SourceV2 - (*SourceSpec)(nil), // 13: rill.runtime.v1.SourceSpec - (*SourceState)(nil), // 14: rill.runtime.v1.SourceState - (*ModelV2)(nil), // 15: rill.runtime.v1.ModelV2 - (*ModelSpec)(nil), // 16: rill.runtime.v1.ModelSpec - (*ModelState)(nil), // 17: rill.runtime.v1.ModelState - (*MetricsViewV2)(nil), // 18: rill.runtime.v1.MetricsViewV2 - (*MetricsViewSpec)(nil), // 19: rill.runtime.v1.MetricsViewSpec - (*SecurityRule)(nil), // 20: rill.runtime.v1.SecurityRule - (*SecurityRuleAccess)(nil), // 21: rill.runtime.v1.SecurityRuleAccess - (*SecurityRuleFieldAccess)(nil), // 22: rill.runtime.v1.SecurityRuleFieldAccess - (*SecurityRuleRowFilter)(nil), // 23: rill.runtime.v1.SecurityRuleRowFilter - (*MetricsViewState)(nil), // 24: rill.runtime.v1.MetricsViewState - (*Explore)(nil), // 25: rill.runtime.v1.Explore - (*ExploreSpec)(nil), // 26: rill.runtime.v1.ExploreSpec - (*ExploreState)(nil), // 27: rill.runtime.v1.ExploreState - (*ExploreTimeRange)(nil), // 28: rill.runtime.v1.ExploreTimeRange - (*ExploreComparisonTimeRange)(nil), // 29: rill.runtime.v1.ExploreComparisonTimeRange - (*ExplorePreset)(nil), // 30: rill.runtime.v1.ExplorePreset - (*FieldSelector)(nil), // 31: rill.runtime.v1.FieldSelector - (*StringListValue)(nil), // 32: rill.runtime.v1.StringListValue - (*Migration)(nil), // 33: rill.runtime.v1.Migration - (*MigrationSpec)(nil), // 34: rill.runtime.v1.MigrationSpec - (*MigrationState)(nil), // 35: rill.runtime.v1.MigrationState - (*Report)(nil), // 36: rill.runtime.v1.Report - (*ReportSpec)(nil), // 37: rill.runtime.v1.ReportSpec - (*ReportState)(nil), // 38: rill.runtime.v1.ReportState - (*ReportExecution)(nil), // 39: rill.runtime.v1.ReportExecution - (*Alert)(nil), // 40: rill.runtime.v1.Alert - (*AlertSpec)(nil), // 41: rill.runtime.v1.AlertSpec - (*Notifier)(nil), // 42: rill.runtime.v1.Notifier - (*AlertState)(nil), // 43: rill.runtime.v1.AlertState - (*AlertExecution)(nil), // 44: rill.runtime.v1.AlertExecution - (*AssertionResult)(nil), // 45: rill.runtime.v1.AssertionResult - (*PullTrigger)(nil), // 46: rill.runtime.v1.PullTrigger - (*PullTriggerSpec)(nil), // 47: rill.runtime.v1.PullTriggerSpec - (*PullTriggerState)(nil), // 48: rill.runtime.v1.PullTriggerState - (*RefreshTrigger)(nil), // 49: rill.runtime.v1.RefreshTrigger - (*RefreshTriggerSpec)(nil), // 50: rill.runtime.v1.RefreshTriggerSpec - (*RefreshTriggerState)(nil), // 51: rill.runtime.v1.RefreshTriggerState - (*RefreshModelTrigger)(nil), // 52: rill.runtime.v1.RefreshModelTrigger - (*BucketPlanner)(nil), // 53: rill.runtime.v1.BucketPlanner - (*BucketPlannerSpec)(nil), // 54: rill.runtime.v1.BucketPlannerSpec - (*BucketPlannerState)(nil), // 55: rill.runtime.v1.BucketPlannerState - (*BucketExtractPolicy)(nil), // 56: rill.runtime.v1.BucketExtractPolicy - (*Theme)(nil), // 57: rill.runtime.v1.Theme - (*ThemeSpec)(nil), // 58: rill.runtime.v1.ThemeSpec - (*ThemeState)(nil), // 59: rill.runtime.v1.ThemeState - (*Component)(nil), // 60: rill.runtime.v1.Component - (*ComponentSpec)(nil), // 61: rill.runtime.v1.ComponentSpec - (*ComponentState)(nil), // 62: rill.runtime.v1.ComponentState - (*ComponentVariable)(nil), // 63: rill.runtime.v1.ComponentVariable - (*Canvas)(nil), // 64: rill.runtime.v1.Canvas - (*CanvasSpec)(nil), // 65: rill.runtime.v1.CanvasSpec - (*CanvasState)(nil), // 66: rill.runtime.v1.CanvasState - (*CanvasItem)(nil), // 67: rill.runtime.v1.CanvasItem - (*API)(nil), // 68: rill.runtime.v1.API - (*APISpec)(nil), // 69: rill.runtime.v1.APISpec - (*APIState)(nil), // 70: rill.runtime.v1.APIState - (*Schedule)(nil), // 71: rill.runtime.v1.Schedule - (*ParseError)(nil), // 72: rill.runtime.v1.ParseError - (*ValidationError)(nil), // 73: rill.runtime.v1.ValidationError - (*DependencyError)(nil), // 74: rill.runtime.v1.DependencyError - (*ExecutionError)(nil), // 75: rill.runtime.v1.ExecutionError - (*CharLocation)(nil), // 76: rill.runtime.v1.CharLocation - (*ConnectorSpec)(nil), // 77: rill.runtime.v1.ConnectorSpec - (*ConnectorState)(nil), // 78: rill.runtime.v1.ConnectorState - (*ConnectorV2)(nil), // 79: rill.runtime.v1.ConnectorV2 - (*MetricsViewSpec_DimensionV2)(nil), // 80: rill.runtime.v1.MetricsViewSpec.DimensionV2 - (*MetricsViewSpec_DimensionSelector)(nil), // 81: rill.runtime.v1.MetricsViewSpec.DimensionSelector - (*MetricsViewSpec_MeasureWindow)(nil), // 82: rill.runtime.v1.MetricsViewSpec.MeasureWindow - (*MetricsViewSpec_MeasureV2)(nil), // 83: rill.runtime.v1.MetricsViewSpec.MeasureV2 - (*MetricsViewSpec_AvailableComparisonOffset)(nil), // 84: rill.runtime.v1.MetricsViewSpec.AvailableComparisonOffset - (*MetricsViewSpec_AvailableTimeRange)(nil), // 85: rill.runtime.v1.MetricsViewSpec.AvailableTimeRange - nil, // 86: rill.runtime.v1.ReportSpec.AnnotationsEntry - nil, // 87: rill.runtime.v1.AlertSpec.AnnotationsEntry - nil, // 88: rill.runtime.v1.ConnectorSpec.PropertiesEntry - nil, // 89: rill.runtime.v1.ConnectorSpec.PropertiesFromVariablesEntry - (*timestamppb.Timestamp)(nil), // 90: google.protobuf.Timestamp - (*structpb.Struct)(nil), // 91: google.protobuf.Struct - (*StructType)(nil), // 92: rill.runtime.v1.StructType - (TimeGrain)(0), // 93: rill.runtime.v1.TimeGrain - (*Expression)(nil), // 94: rill.runtime.v1.Expression - (ExportFormat)(0), // 95: rill.runtime.v1.ExportFormat - (*Color)(nil), // 96: rill.runtime.v1.Color - (*structpb.Value)(nil), // 97: google.protobuf.Value + (ExploreWebView)(0), // 2: rill.runtime.v1.ExploreWebView + (ExploreSortType)(0), // 3: rill.runtime.v1.ExploreSortType + (AssertionStatus)(0), // 4: rill.runtime.v1.AssertionStatus + (MetricsViewSpec_MeasureType)(0), // 5: rill.runtime.v1.MetricsViewSpec.MeasureType + (MetricsViewSpec_ComparisonMode)(0), // 6: rill.runtime.v1.MetricsViewSpec.ComparisonMode + (BucketExtractPolicy_Strategy)(0), // 7: rill.runtime.v1.BucketExtractPolicy.Strategy + (*Resource)(nil), // 8: rill.runtime.v1.Resource + (*ResourceMeta)(nil), // 9: rill.runtime.v1.ResourceMeta + (*ResourceName)(nil), // 10: rill.runtime.v1.ResourceName + (*ProjectParser)(nil), // 11: rill.runtime.v1.ProjectParser + (*ProjectParserSpec)(nil), // 12: rill.runtime.v1.ProjectParserSpec + (*ProjectParserState)(nil), // 13: rill.runtime.v1.ProjectParserState + (*SourceV2)(nil), // 14: rill.runtime.v1.SourceV2 + (*SourceSpec)(nil), // 15: rill.runtime.v1.SourceSpec + (*SourceState)(nil), // 16: rill.runtime.v1.SourceState + (*ModelV2)(nil), // 17: rill.runtime.v1.ModelV2 + (*ModelSpec)(nil), // 18: rill.runtime.v1.ModelSpec + (*ModelState)(nil), // 19: rill.runtime.v1.ModelState + (*MetricsViewV2)(nil), // 20: rill.runtime.v1.MetricsViewV2 + (*MetricsViewSpec)(nil), // 21: rill.runtime.v1.MetricsViewSpec + (*SecurityRule)(nil), // 22: rill.runtime.v1.SecurityRule + (*SecurityRuleAccess)(nil), // 23: rill.runtime.v1.SecurityRuleAccess + (*SecurityRuleFieldAccess)(nil), // 24: rill.runtime.v1.SecurityRuleFieldAccess + (*SecurityRuleRowFilter)(nil), // 25: rill.runtime.v1.SecurityRuleRowFilter + (*MetricsViewState)(nil), // 26: rill.runtime.v1.MetricsViewState + (*Explore)(nil), // 27: rill.runtime.v1.Explore + (*ExploreSpec)(nil), // 28: rill.runtime.v1.ExploreSpec + (*ExploreState)(nil), // 29: rill.runtime.v1.ExploreState + (*ExploreTimeRange)(nil), // 30: rill.runtime.v1.ExploreTimeRange + (*ExploreComparisonTimeRange)(nil), // 31: rill.runtime.v1.ExploreComparisonTimeRange + (*ExplorePreset)(nil), // 32: rill.runtime.v1.ExplorePreset + (*FieldSelector)(nil), // 33: rill.runtime.v1.FieldSelector + (*StringListValue)(nil), // 34: rill.runtime.v1.StringListValue + (*Migration)(nil), // 35: rill.runtime.v1.Migration + (*MigrationSpec)(nil), // 36: rill.runtime.v1.MigrationSpec + (*MigrationState)(nil), // 37: rill.runtime.v1.MigrationState + (*Report)(nil), // 38: rill.runtime.v1.Report + (*ReportSpec)(nil), // 39: rill.runtime.v1.ReportSpec + (*ReportState)(nil), // 40: rill.runtime.v1.ReportState + (*ReportExecution)(nil), // 41: rill.runtime.v1.ReportExecution + (*Alert)(nil), // 42: rill.runtime.v1.Alert + (*AlertSpec)(nil), // 43: rill.runtime.v1.AlertSpec + (*Notifier)(nil), // 44: rill.runtime.v1.Notifier + (*AlertState)(nil), // 45: rill.runtime.v1.AlertState + (*AlertExecution)(nil), // 46: rill.runtime.v1.AlertExecution + (*AssertionResult)(nil), // 47: rill.runtime.v1.AssertionResult + (*PullTrigger)(nil), // 48: rill.runtime.v1.PullTrigger + (*PullTriggerSpec)(nil), // 49: rill.runtime.v1.PullTriggerSpec + (*PullTriggerState)(nil), // 50: rill.runtime.v1.PullTriggerState + (*RefreshTrigger)(nil), // 51: rill.runtime.v1.RefreshTrigger + (*RefreshTriggerSpec)(nil), // 52: rill.runtime.v1.RefreshTriggerSpec + (*RefreshTriggerState)(nil), // 53: rill.runtime.v1.RefreshTriggerState + (*RefreshModelTrigger)(nil), // 54: rill.runtime.v1.RefreshModelTrigger + (*BucketPlanner)(nil), // 55: rill.runtime.v1.BucketPlanner + (*BucketPlannerSpec)(nil), // 56: rill.runtime.v1.BucketPlannerSpec + (*BucketPlannerState)(nil), // 57: rill.runtime.v1.BucketPlannerState + (*BucketExtractPolicy)(nil), // 58: rill.runtime.v1.BucketExtractPolicy + (*Theme)(nil), // 59: rill.runtime.v1.Theme + (*ThemeSpec)(nil), // 60: rill.runtime.v1.ThemeSpec + (*ThemeState)(nil), // 61: rill.runtime.v1.ThemeState + (*Component)(nil), // 62: rill.runtime.v1.Component + (*ComponentSpec)(nil), // 63: rill.runtime.v1.ComponentSpec + (*ComponentState)(nil), // 64: rill.runtime.v1.ComponentState + (*ComponentVariable)(nil), // 65: rill.runtime.v1.ComponentVariable + (*Canvas)(nil), // 66: rill.runtime.v1.Canvas + (*CanvasSpec)(nil), // 67: rill.runtime.v1.CanvasSpec + (*CanvasState)(nil), // 68: rill.runtime.v1.CanvasState + (*CanvasItem)(nil), // 69: rill.runtime.v1.CanvasItem + (*API)(nil), // 70: rill.runtime.v1.API + (*APISpec)(nil), // 71: rill.runtime.v1.APISpec + (*APIState)(nil), // 72: rill.runtime.v1.APIState + (*Schedule)(nil), // 73: rill.runtime.v1.Schedule + (*ParseError)(nil), // 74: rill.runtime.v1.ParseError + (*ValidationError)(nil), // 75: rill.runtime.v1.ValidationError + (*DependencyError)(nil), // 76: rill.runtime.v1.DependencyError + (*ExecutionError)(nil), // 77: rill.runtime.v1.ExecutionError + (*CharLocation)(nil), // 78: rill.runtime.v1.CharLocation + (*ConnectorSpec)(nil), // 79: rill.runtime.v1.ConnectorSpec + (*ConnectorState)(nil), // 80: rill.runtime.v1.ConnectorState + (*ConnectorV2)(nil), // 81: rill.runtime.v1.ConnectorV2 + (*MetricsViewSpec_DimensionV2)(nil), // 82: rill.runtime.v1.MetricsViewSpec.DimensionV2 + (*MetricsViewSpec_DimensionSelector)(nil), // 83: rill.runtime.v1.MetricsViewSpec.DimensionSelector + (*MetricsViewSpec_MeasureWindow)(nil), // 84: rill.runtime.v1.MetricsViewSpec.MeasureWindow + (*MetricsViewSpec_MeasureV2)(nil), // 85: rill.runtime.v1.MetricsViewSpec.MeasureV2 + (*MetricsViewSpec_AvailableComparisonOffset)(nil), // 86: rill.runtime.v1.MetricsViewSpec.AvailableComparisonOffset + (*MetricsViewSpec_AvailableTimeRange)(nil), // 87: rill.runtime.v1.MetricsViewSpec.AvailableTimeRange + nil, // 88: rill.runtime.v1.ReportSpec.AnnotationsEntry + nil, // 89: rill.runtime.v1.AlertSpec.AnnotationsEntry + nil, // 90: rill.runtime.v1.ConnectorSpec.PropertiesEntry + nil, // 91: rill.runtime.v1.ConnectorSpec.PropertiesFromVariablesEntry + (*timestamppb.Timestamp)(nil), // 92: google.protobuf.Timestamp + (*structpb.Struct)(nil), // 93: google.protobuf.Struct + (*StructType)(nil), // 94: rill.runtime.v1.StructType + (TimeGrain)(0), // 95: rill.runtime.v1.TimeGrain + (*Expression)(nil), // 96: rill.runtime.v1.Expression + (ExportFormat)(0), // 97: rill.runtime.v1.ExportFormat + (*Color)(nil), // 98: rill.runtime.v1.Color + (*structpb.Value)(nil), // 99: google.protobuf.Value } var file_rill_runtime_v1_resources_proto_depIdxs = []int32{ - 7, // 0: rill.runtime.v1.Resource.meta:type_name -> rill.runtime.v1.ResourceMeta - 9, // 1: rill.runtime.v1.Resource.project_parser:type_name -> rill.runtime.v1.ProjectParser - 12, // 2: rill.runtime.v1.Resource.source:type_name -> rill.runtime.v1.SourceV2 - 15, // 3: rill.runtime.v1.Resource.model:type_name -> rill.runtime.v1.ModelV2 - 18, // 4: rill.runtime.v1.Resource.metrics_view:type_name -> rill.runtime.v1.MetricsViewV2 - 25, // 5: rill.runtime.v1.Resource.explore:type_name -> rill.runtime.v1.Explore - 33, // 6: rill.runtime.v1.Resource.migration:type_name -> rill.runtime.v1.Migration - 36, // 7: rill.runtime.v1.Resource.report:type_name -> rill.runtime.v1.Report - 40, // 8: rill.runtime.v1.Resource.alert:type_name -> rill.runtime.v1.Alert - 46, // 9: rill.runtime.v1.Resource.pull_trigger:type_name -> rill.runtime.v1.PullTrigger - 49, // 10: rill.runtime.v1.Resource.refresh_trigger:type_name -> rill.runtime.v1.RefreshTrigger - 53, // 11: rill.runtime.v1.Resource.bucket_planner:type_name -> rill.runtime.v1.BucketPlanner - 57, // 12: rill.runtime.v1.Resource.theme:type_name -> rill.runtime.v1.Theme - 60, // 13: rill.runtime.v1.Resource.component:type_name -> rill.runtime.v1.Component - 64, // 14: rill.runtime.v1.Resource.canvas:type_name -> rill.runtime.v1.Canvas - 68, // 15: rill.runtime.v1.Resource.api:type_name -> rill.runtime.v1.API - 79, // 16: rill.runtime.v1.Resource.connector:type_name -> rill.runtime.v1.ConnectorV2 - 8, // 17: rill.runtime.v1.ResourceMeta.name:type_name -> rill.runtime.v1.ResourceName - 8, // 18: rill.runtime.v1.ResourceMeta.refs:type_name -> rill.runtime.v1.ResourceName - 8, // 19: rill.runtime.v1.ResourceMeta.owner:type_name -> rill.runtime.v1.ResourceName - 90, // 20: rill.runtime.v1.ResourceMeta.created_on:type_name -> google.protobuf.Timestamp - 90, // 21: rill.runtime.v1.ResourceMeta.spec_updated_on:type_name -> google.protobuf.Timestamp - 90, // 22: rill.runtime.v1.ResourceMeta.state_updated_on:type_name -> google.protobuf.Timestamp - 90, // 23: rill.runtime.v1.ResourceMeta.deleted_on:type_name -> google.protobuf.Timestamp + 9, // 0: rill.runtime.v1.Resource.meta:type_name -> rill.runtime.v1.ResourceMeta + 11, // 1: rill.runtime.v1.Resource.project_parser:type_name -> rill.runtime.v1.ProjectParser + 14, // 2: rill.runtime.v1.Resource.source:type_name -> rill.runtime.v1.SourceV2 + 17, // 3: rill.runtime.v1.Resource.model:type_name -> rill.runtime.v1.ModelV2 + 20, // 4: rill.runtime.v1.Resource.metrics_view:type_name -> rill.runtime.v1.MetricsViewV2 + 27, // 5: rill.runtime.v1.Resource.explore:type_name -> rill.runtime.v1.Explore + 35, // 6: rill.runtime.v1.Resource.migration:type_name -> rill.runtime.v1.Migration + 38, // 7: rill.runtime.v1.Resource.report:type_name -> rill.runtime.v1.Report + 42, // 8: rill.runtime.v1.Resource.alert:type_name -> rill.runtime.v1.Alert + 48, // 9: rill.runtime.v1.Resource.pull_trigger:type_name -> rill.runtime.v1.PullTrigger + 51, // 10: rill.runtime.v1.Resource.refresh_trigger:type_name -> rill.runtime.v1.RefreshTrigger + 55, // 11: rill.runtime.v1.Resource.bucket_planner:type_name -> rill.runtime.v1.BucketPlanner + 59, // 12: rill.runtime.v1.Resource.theme:type_name -> rill.runtime.v1.Theme + 62, // 13: rill.runtime.v1.Resource.component:type_name -> rill.runtime.v1.Component + 66, // 14: rill.runtime.v1.Resource.canvas:type_name -> rill.runtime.v1.Canvas + 70, // 15: rill.runtime.v1.Resource.api:type_name -> rill.runtime.v1.API + 81, // 16: rill.runtime.v1.Resource.connector:type_name -> rill.runtime.v1.ConnectorV2 + 10, // 17: rill.runtime.v1.ResourceMeta.name:type_name -> rill.runtime.v1.ResourceName + 10, // 18: rill.runtime.v1.ResourceMeta.refs:type_name -> rill.runtime.v1.ResourceName + 10, // 19: rill.runtime.v1.ResourceMeta.owner:type_name -> rill.runtime.v1.ResourceName + 92, // 20: rill.runtime.v1.ResourceMeta.created_on:type_name -> google.protobuf.Timestamp + 92, // 21: rill.runtime.v1.ResourceMeta.spec_updated_on:type_name -> google.protobuf.Timestamp + 92, // 22: rill.runtime.v1.ResourceMeta.state_updated_on:type_name -> google.protobuf.Timestamp + 92, // 23: rill.runtime.v1.ResourceMeta.deleted_on:type_name -> google.protobuf.Timestamp 0, // 24: rill.runtime.v1.ResourceMeta.reconcile_status:type_name -> rill.runtime.v1.ReconcileStatus - 90, // 25: rill.runtime.v1.ResourceMeta.reconcile_on:type_name -> google.protobuf.Timestamp - 8, // 26: rill.runtime.v1.ResourceMeta.renamed_from:type_name -> rill.runtime.v1.ResourceName - 10, // 27: rill.runtime.v1.ProjectParser.spec:type_name -> rill.runtime.v1.ProjectParserSpec - 11, // 28: rill.runtime.v1.ProjectParser.state:type_name -> rill.runtime.v1.ProjectParserState - 72, // 29: rill.runtime.v1.ProjectParserState.parse_errors:type_name -> rill.runtime.v1.ParseError - 13, // 30: rill.runtime.v1.SourceV2.spec:type_name -> rill.runtime.v1.SourceSpec - 14, // 31: rill.runtime.v1.SourceV2.state:type_name -> rill.runtime.v1.SourceState - 91, // 32: rill.runtime.v1.SourceSpec.properties:type_name -> google.protobuf.Struct - 71, // 33: rill.runtime.v1.SourceSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule - 90, // 34: rill.runtime.v1.SourceState.refreshed_on:type_name -> google.protobuf.Timestamp - 16, // 35: rill.runtime.v1.ModelV2.spec:type_name -> rill.runtime.v1.ModelSpec - 17, // 36: rill.runtime.v1.ModelV2.state:type_name -> rill.runtime.v1.ModelState - 71, // 37: rill.runtime.v1.ModelSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule - 91, // 38: rill.runtime.v1.ModelSpec.incremental_state_resolver_properties:type_name -> google.protobuf.Struct - 91, // 39: rill.runtime.v1.ModelSpec.partitions_resolver_properties:type_name -> google.protobuf.Struct - 91, // 40: rill.runtime.v1.ModelSpec.input_properties:type_name -> google.protobuf.Struct - 91, // 41: rill.runtime.v1.ModelSpec.stage_properties:type_name -> google.protobuf.Struct - 91, // 42: rill.runtime.v1.ModelSpec.output_properties:type_name -> google.protobuf.Struct - 91, // 43: rill.runtime.v1.ModelState.result_properties:type_name -> google.protobuf.Struct - 90, // 44: rill.runtime.v1.ModelState.refreshed_on:type_name -> google.protobuf.Timestamp - 91, // 45: rill.runtime.v1.ModelState.incremental_state:type_name -> google.protobuf.Struct - 92, // 46: rill.runtime.v1.ModelState.incremental_state_schema:type_name -> rill.runtime.v1.StructType - 19, // 47: rill.runtime.v1.MetricsViewV2.spec:type_name -> rill.runtime.v1.MetricsViewSpec - 24, // 48: rill.runtime.v1.MetricsViewV2.state:type_name -> rill.runtime.v1.MetricsViewState - 93, // 49: rill.runtime.v1.MetricsViewSpec.smallest_time_grain:type_name -> rill.runtime.v1.TimeGrain - 80, // 50: rill.runtime.v1.MetricsViewSpec.dimensions:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionV2 - 83, // 51: rill.runtime.v1.MetricsViewSpec.measures:type_name -> rill.runtime.v1.MetricsViewSpec.MeasureV2 - 20, // 52: rill.runtime.v1.MetricsViewSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule - 4, // 53: rill.runtime.v1.MetricsViewSpec.default_comparison_mode:type_name -> rill.runtime.v1.MetricsViewSpec.ComparisonMode - 85, // 54: rill.runtime.v1.MetricsViewSpec.available_time_ranges:type_name -> rill.runtime.v1.MetricsViewSpec.AvailableTimeRange - 21, // 55: rill.runtime.v1.SecurityRule.access:type_name -> rill.runtime.v1.SecurityRuleAccess - 22, // 56: rill.runtime.v1.SecurityRule.field_access:type_name -> rill.runtime.v1.SecurityRuleFieldAccess - 23, // 57: rill.runtime.v1.SecurityRule.row_filter:type_name -> rill.runtime.v1.SecurityRuleRowFilter - 94, // 58: rill.runtime.v1.SecurityRuleRowFilter.expression:type_name -> rill.runtime.v1.Expression - 19, // 59: rill.runtime.v1.MetricsViewState.valid_spec:type_name -> rill.runtime.v1.MetricsViewSpec - 26, // 60: rill.runtime.v1.Explore.spec:type_name -> rill.runtime.v1.ExploreSpec - 27, // 61: rill.runtime.v1.Explore.state:type_name -> rill.runtime.v1.ExploreState - 31, // 62: rill.runtime.v1.ExploreSpec.dimensions_selector:type_name -> rill.runtime.v1.FieldSelector - 31, // 63: rill.runtime.v1.ExploreSpec.measures_selector:type_name -> rill.runtime.v1.FieldSelector - 58, // 64: rill.runtime.v1.ExploreSpec.embedded_theme:type_name -> rill.runtime.v1.ThemeSpec - 28, // 65: rill.runtime.v1.ExploreSpec.time_ranges:type_name -> rill.runtime.v1.ExploreTimeRange - 30, // 66: rill.runtime.v1.ExploreSpec.default_preset:type_name -> rill.runtime.v1.ExplorePreset - 20, // 67: rill.runtime.v1.ExploreSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule - 26, // 68: rill.runtime.v1.ExploreState.valid_spec:type_name -> rill.runtime.v1.ExploreSpec - 29, // 69: rill.runtime.v1.ExploreTimeRange.comparison_time_ranges:type_name -> rill.runtime.v1.ExploreComparisonTimeRange - 31, // 70: rill.runtime.v1.ExplorePreset.dimensions_selector:type_name -> rill.runtime.v1.FieldSelector - 31, // 71: rill.runtime.v1.ExplorePreset.measures_selector:type_name -> rill.runtime.v1.FieldSelector - 1, // 72: rill.runtime.v1.ExplorePreset.comparison_mode:type_name -> rill.runtime.v1.ExploreComparisonMode - 32, // 73: rill.runtime.v1.FieldSelector.fields:type_name -> rill.runtime.v1.StringListValue - 34, // 74: rill.runtime.v1.Migration.spec:type_name -> rill.runtime.v1.MigrationSpec - 35, // 75: rill.runtime.v1.Migration.state:type_name -> rill.runtime.v1.MigrationState - 37, // 76: rill.runtime.v1.Report.spec:type_name -> rill.runtime.v1.ReportSpec - 38, // 77: rill.runtime.v1.Report.state:type_name -> rill.runtime.v1.ReportState - 71, // 78: rill.runtime.v1.ReportSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule - 95, // 79: rill.runtime.v1.ReportSpec.export_format:type_name -> rill.runtime.v1.ExportFormat - 42, // 80: rill.runtime.v1.ReportSpec.notifiers:type_name -> rill.runtime.v1.Notifier - 86, // 81: rill.runtime.v1.ReportSpec.annotations:type_name -> rill.runtime.v1.ReportSpec.AnnotationsEntry - 90, // 82: rill.runtime.v1.ReportState.next_run_on:type_name -> google.protobuf.Timestamp - 39, // 83: rill.runtime.v1.ReportState.current_execution:type_name -> rill.runtime.v1.ReportExecution - 39, // 84: rill.runtime.v1.ReportState.execution_history:type_name -> rill.runtime.v1.ReportExecution - 90, // 85: rill.runtime.v1.ReportExecution.report_time:type_name -> google.protobuf.Timestamp - 90, // 86: rill.runtime.v1.ReportExecution.started_on:type_name -> google.protobuf.Timestamp - 90, // 87: rill.runtime.v1.ReportExecution.finished_on:type_name -> google.protobuf.Timestamp - 41, // 88: rill.runtime.v1.Alert.spec:type_name -> rill.runtime.v1.AlertSpec - 43, // 89: rill.runtime.v1.Alert.state:type_name -> rill.runtime.v1.AlertState - 71, // 90: rill.runtime.v1.AlertSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule - 91, // 91: rill.runtime.v1.AlertSpec.resolver_properties:type_name -> google.protobuf.Struct - 91, // 92: rill.runtime.v1.AlertSpec.query_for_attributes:type_name -> google.protobuf.Struct - 42, // 93: rill.runtime.v1.AlertSpec.notifiers:type_name -> rill.runtime.v1.Notifier - 87, // 94: rill.runtime.v1.AlertSpec.annotations:type_name -> rill.runtime.v1.AlertSpec.AnnotationsEntry - 91, // 95: rill.runtime.v1.Notifier.properties:type_name -> google.protobuf.Struct - 90, // 96: rill.runtime.v1.AlertState.next_run_on:type_name -> google.protobuf.Timestamp - 44, // 97: rill.runtime.v1.AlertState.current_execution:type_name -> rill.runtime.v1.AlertExecution - 44, // 98: rill.runtime.v1.AlertState.execution_history:type_name -> rill.runtime.v1.AlertExecution - 45, // 99: rill.runtime.v1.AlertExecution.result:type_name -> rill.runtime.v1.AssertionResult - 90, // 100: rill.runtime.v1.AlertExecution.execution_time:type_name -> google.protobuf.Timestamp - 90, // 101: rill.runtime.v1.AlertExecution.started_on:type_name -> google.protobuf.Timestamp - 90, // 102: rill.runtime.v1.AlertExecution.finished_on:type_name -> google.protobuf.Timestamp - 90, // 103: rill.runtime.v1.AlertExecution.suppressed_since:type_name -> google.protobuf.Timestamp - 2, // 104: rill.runtime.v1.AssertionResult.status:type_name -> rill.runtime.v1.AssertionStatus - 91, // 105: rill.runtime.v1.AssertionResult.fail_row:type_name -> google.protobuf.Struct - 47, // 106: rill.runtime.v1.PullTrigger.spec:type_name -> rill.runtime.v1.PullTriggerSpec - 48, // 107: rill.runtime.v1.PullTrigger.state:type_name -> rill.runtime.v1.PullTriggerState - 50, // 108: rill.runtime.v1.RefreshTrigger.spec:type_name -> rill.runtime.v1.RefreshTriggerSpec - 51, // 109: rill.runtime.v1.RefreshTrigger.state:type_name -> rill.runtime.v1.RefreshTriggerState - 8, // 110: rill.runtime.v1.RefreshTriggerSpec.resources:type_name -> rill.runtime.v1.ResourceName - 52, // 111: rill.runtime.v1.RefreshTriggerSpec.models:type_name -> rill.runtime.v1.RefreshModelTrigger - 54, // 112: rill.runtime.v1.BucketPlanner.spec:type_name -> rill.runtime.v1.BucketPlannerSpec - 55, // 113: rill.runtime.v1.BucketPlanner.state:type_name -> rill.runtime.v1.BucketPlannerState - 56, // 114: rill.runtime.v1.BucketPlannerSpec.extract_policy:type_name -> rill.runtime.v1.BucketExtractPolicy - 5, // 115: rill.runtime.v1.BucketExtractPolicy.rows_strategy:type_name -> rill.runtime.v1.BucketExtractPolicy.Strategy - 5, // 116: rill.runtime.v1.BucketExtractPolicy.files_strategy:type_name -> rill.runtime.v1.BucketExtractPolicy.Strategy - 58, // 117: rill.runtime.v1.Theme.spec:type_name -> rill.runtime.v1.ThemeSpec - 59, // 118: rill.runtime.v1.Theme.state:type_name -> rill.runtime.v1.ThemeState - 96, // 119: rill.runtime.v1.ThemeSpec.primary_color:type_name -> rill.runtime.v1.Color - 96, // 120: rill.runtime.v1.ThemeSpec.secondary_color:type_name -> rill.runtime.v1.Color - 61, // 121: rill.runtime.v1.Component.spec:type_name -> rill.runtime.v1.ComponentSpec - 62, // 122: rill.runtime.v1.Component.state:type_name -> rill.runtime.v1.ComponentState - 91, // 123: rill.runtime.v1.ComponentSpec.resolver_properties:type_name -> google.protobuf.Struct - 91, // 124: rill.runtime.v1.ComponentSpec.renderer_properties:type_name -> google.protobuf.Struct - 63, // 125: rill.runtime.v1.ComponentSpec.input:type_name -> rill.runtime.v1.ComponentVariable - 63, // 126: rill.runtime.v1.ComponentSpec.output:type_name -> rill.runtime.v1.ComponentVariable - 61, // 127: rill.runtime.v1.ComponentState.valid_spec:type_name -> rill.runtime.v1.ComponentSpec - 97, // 128: rill.runtime.v1.ComponentVariable.default_value:type_name -> google.protobuf.Value - 65, // 129: rill.runtime.v1.Canvas.spec:type_name -> rill.runtime.v1.CanvasSpec - 66, // 130: rill.runtime.v1.Canvas.state:type_name -> rill.runtime.v1.CanvasState - 63, // 131: rill.runtime.v1.CanvasSpec.variables:type_name -> rill.runtime.v1.ComponentVariable - 67, // 132: rill.runtime.v1.CanvasSpec.items:type_name -> rill.runtime.v1.CanvasItem - 20, // 133: rill.runtime.v1.CanvasSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule - 65, // 134: rill.runtime.v1.CanvasState.valid_spec:type_name -> rill.runtime.v1.CanvasSpec - 69, // 135: rill.runtime.v1.API.spec:type_name -> rill.runtime.v1.APISpec - 70, // 136: rill.runtime.v1.API.state:type_name -> rill.runtime.v1.APIState - 91, // 137: rill.runtime.v1.APISpec.resolver_properties:type_name -> google.protobuf.Struct - 91, // 138: rill.runtime.v1.APISpec.openapi_parameters:type_name -> google.protobuf.Struct - 91, // 139: rill.runtime.v1.APISpec.openapi_response_schema:type_name -> google.protobuf.Struct - 76, // 140: rill.runtime.v1.ParseError.start_location:type_name -> rill.runtime.v1.CharLocation - 88, // 141: rill.runtime.v1.ConnectorSpec.properties:type_name -> rill.runtime.v1.ConnectorSpec.PropertiesEntry - 89, // 142: rill.runtime.v1.ConnectorSpec.properties_from_variables:type_name -> rill.runtime.v1.ConnectorSpec.PropertiesFromVariablesEntry - 77, // 143: rill.runtime.v1.ConnectorV2.spec:type_name -> rill.runtime.v1.ConnectorSpec - 78, // 144: rill.runtime.v1.ConnectorV2.state:type_name -> rill.runtime.v1.ConnectorState - 93, // 145: rill.runtime.v1.MetricsViewSpec.DimensionSelector.time_grain:type_name -> rill.runtime.v1.TimeGrain - 81, // 146: rill.runtime.v1.MetricsViewSpec.MeasureWindow.order_by:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionSelector - 3, // 147: rill.runtime.v1.MetricsViewSpec.MeasureV2.type:type_name -> rill.runtime.v1.MetricsViewSpec.MeasureType - 82, // 148: rill.runtime.v1.MetricsViewSpec.MeasureV2.window:type_name -> rill.runtime.v1.MetricsViewSpec.MeasureWindow - 81, // 149: rill.runtime.v1.MetricsViewSpec.MeasureV2.per_dimensions:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionSelector - 81, // 150: rill.runtime.v1.MetricsViewSpec.MeasureV2.required_dimensions:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionSelector - 91, // 151: rill.runtime.v1.MetricsViewSpec.MeasureV2.format_d3_locale:type_name -> google.protobuf.Struct - 84, // 152: rill.runtime.v1.MetricsViewSpec.AvailableTimeRange.comparison_offsets:type_name -> rill.runtime.v1.MetricsViewSpec.AvailableComparisonOffset - 153, // [153:153] is the sub-list for method output_type - 153, // [153:153] is the sub-list for method input_type - 153, // [153:153] is the sub-list for extension type_name - 153, // [153:153] is the sub-list for extension extendee - 0, // [0:153] is the sub-list for field type_name + 92, // 25: rill.runtime.v1.ResourceMeta.reconcile_on:type_name -> google.protobuf.Timestamp + 10, // 26: rill.runtime.v1.ResourceMeta.renamed_from:type_name -> rill.runtime.v1.ResourceName + 12, // 27: rill.runtime.v1.ProjectParser.spec:type_name -> rill.runtime.v1.ProjectParserSpec + 13, // 28: rill.runtime.v1.ProjectParser.state:type_name -> rill.runtime.v1.ProjectParserState + 74, // 29: rill.runtime.v1.ProjectParserState.parse_errors:type_name -> rill.runtime.v1.ParseError + 15, // 30: rill.runtime.v1.SourceV2.spec:type_name -> rill.runtime.v1.SourceSpec + 16, // 31: rill.runtime.v1.SourceV2.state:type_name -> rill.runtime.v1.SourceState + 93, // 32: rill.runtime.v1.SourceSpec.properties:type_name -> google.protobuf.Struct + 73, // 33: rill.runtime.v1.SourceSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule + 92, // 34: rill.runtime.v1.SourceState.refreshed_on:type_name -> google.protobuf.Timestamp + 18, // 35: rill.runtime.v1.ModelV2.spec:type_name -> rill.runtime.v1.ModelSpec + 19, // 36: rill.runtime.v1.ModelV2.state:type_name -> rill.runtime.v1.ModelState + 73, // 37: rill.runtime.v1.ModelSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule + 93, // 38: rill.runtime.v1.ModelSpec.incremental_state_resolver_properties:type_name -> google.protobuf.Struct + 93, // 39: rill.runtime.v1.ModelSpec.partitions_resolver_properties:type_name -> google.protobuf.Struct + 93, // 40: rill.runtime.v1.ModelSpec.input_properties:type_name -> google.protobuf.Struct + 93, // 41: rill.runtime.v1.ModelSpec.stage_properties:type_name -> google.protobuf.Struct + 93, // 42: rill.runtime.v1.ModelSpec.output_properties:type_name -> google.protobuf.Struct + 93, // 43: rill.runtime.v1.ModelState.result_properties:type_name -> google.protobuf.Struct + 92, // 44: rill.runtime.v1.ModelState.refreshed_on:type_name -> google.protobuf.Timestamp + 93, // 45: rill.runtime.v1.ModelState.incremental_state:type_name -> google.protobuf.Struct + 94, // 46: rill.runtime.v1.ModelState.incremental_state_schema:type_name -> rill.runtime.v1.StructType + 21, // 47: rill.runtime.v1.MetricsViewV2.spec:type_name -> rill.runtime.v1.MetricsViewSpec + 26, // 48: rill.runtime.v1.MetricsViewV2.state:type_name -> rill.runtime.v1.MetricsViewState + 95, // 49: rill.runtime.v1.MetricsViewSpec.smallest_time_grain:type_name -> rill.runtime.v1.TimeGrain + 82, // 50: rill.runtime.v1.MetricsViewSpec.dimensions:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionV2 + 85, // 51: rill.runtime.v1.MetricsViewSpec.measures:type_name -> rill.runtime.v1.MetricsViewSpec.MeasureV2 + 22, // 52: rill.runtime.v1.MetricsViewSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule + 6, // 53: rill.runtime.v1.MetricsViewSpec.default_comparison_mode:type_name -> rill.runtime.v1.MetricsViewSpec.ComparisonMode + 87, // 54: rill.runtime.v1.MetricsViewSpec.available_time_ranges:type_name -> rill.runtime.v1.MetricsViewSpec.AvailableTimeRange + 23, // 55: rill.runtime.v1.SecurityRule.access:type_name -> rill.runtime.v1.SecurityRuleAccess + 24, // 56: rill.runtime.v1.SecurityRule.field_access:type_name -> rill.runtime.v1.SecurityRuleFieldAccess + 25, // 57: rill.runtime.v1.SecurityRule.row_filter:type_name -> rill.runtime.v1.SecurityRuleRowFilter + 96, // 58: rill.runtime.v1.SecurityRuleRowFilter.expression:type_name -> rill.runtime.v1.Expression + 21, // 59: rill.runtime.v1.MetricsViewState.valid_spec:type_name -> rill.runtime.v1.MetricsViewSpec + 28, // 60: rill.runtime.v1.Explore.spec:type_name -> rill.runtime.v1.ExploreSpec + 29, // 61: rill.runtime.v1.Explore.state:type_name -> rill.runtime.v1.ExploreState + 33, // 62: rill.runtime.v1.ExploreSpec.dimensions_selector:type_name -> rill.runtime.v1.FieldSelector + 33, // 63: rill.runtime.v1.ExploreSpec.measures_selector:type_name -> rill.runtime.v1.FieldSelector + 60, // 64: rill.runtime.v1.ExploreSpec.embedded_theme:type_name -> rill.runtime.v1.ThemeSpec + 30, // 65: rill.runtime.v1.ExploreSpec.time_ranges:type_name -> rill.runtime.v1.ExploreTimeRange + 32, // 66: rill.runtime.v1.ExploreSpec.default_preset:type_name -> rill.runtime.v1.ExplorePreset + 22, // 67: rill.runtime.v1.ExploreSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule + 28, // 68: rill.runtime.v1.ExploreState.valid_spec:type_name -> rill.runtime.v1.ExploreSpec + 31, // 69: rill.runtime.v1.ExploreTimeRange.comparison_time_ranges:type_name -> rill.runtime.v1.ExploreComparisonTimeRange + 33, // 70: rill.runtime.v1.ExplorePreset.dimensions_selector:type_name -> rill.runtime.v1.FieldSelector + 33, // 71: rill.runtime.v1.ExplorePreset.measures_selector:type_name -> rill.runtime.v1.FieldSelector + 96, // 72: rill.runtime.v1.ExplorePreset.where:type_name -> rill.runtime.v1.Expression + 1, // 73: rill.runtime.v1.ExplorePreset.comparison_mode:type_name -> rill.runtime.v1.ExploreComparisonMode + 2, // 74: rill.runtime.v1.ExplorePreset.view:type_name -> rill.runtime.v1.ExploreWebView + 3, // 75: rill.runtime.v1.ExplorePreset.explore_sort_type:type_name -> rill.runtime.v1.ExploreSortType + 34, // 76: rill.runtime.v1.FieldSelector.fields:type_name -> rill.runtime.v1.StringListValue + 36, // 77: rill.runtime.v1.Migration.spec:type_name -> rill.runtime.v1.MigrationSpec + 37, // 78: rill.runtime.v1.Migration.state:type_name -> rill.runtime.v1.MigrationState + 39, // 79: rill.runtime.v1.Report.spec:type_name -> rill.runtime.v1.ReportSpec + 40, // 80: rill.runtime.v1.Report.state:type_name -> rill.runtime.v1.ReportState + 73, // 81: rill.runtime.v1.ReportSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule + 97, // 82: rill.runtime.v1.ReportSpec.export_format:type_name -> rill.runtime.v1.ExportFormat + 44, // 83: rill.runtime.v1.ReportSpec.notifiers:type_name -> rill.runtime.v1.Notifier + 88, // 84: rill.runtime.v1.ReportSpec.annotations:type_name -> rill.runtime.v1.ReportSpec.AnnotationsEntry + 92, // 85: rill.runtime.v1.ReportState.next_run_on:type_name -> google.protobuf.Timestamp + 41, // 86: rill.runtime.v1.ReportState.current_execution:type_name -> rill.runtime.v1.ReportExecution + 41, // 87: rill.runtime.v1.ReportState.execution_history:type_name -> rill.runtime.v1.ReportExecution + 92, // 88: rill.runtime.v1.ReportExecution.report_time:type_name -> google.protobuf.Timestamp + 92, // 89: rill.runtime.v1.ReportExecution.started_on:type_name -> google.protobuf.Timestamp + 92, // 90: rill.runtime.v1.ReportExecution.finished_on:type_name -> google.protobuf.Timestamp + 43, // 91: rill.runtime.v1.Alert.spec:type_name -> rill.runtime.v1.AlertSpec + 45, // 92: rill.runtime.v1.Alert.state:type_name -> rill.runtime.v1.AlertState + 73, // 93: rill.runtime.v1.AlertSpec.refresh_schedule:type_name -> rill.runtime.v1.Schedule + 93, // 94: rill.runtime.v1.AlertSpec.resolver_properties:type_name -> google.protobuf.Struct + 93, // 95: rill.runtime.v1.AlertSpec.query_for_attributes:type_name -> google.protobuf.Struct + 44, // 96: rill.runtime.v1.AlertSpec.notifiers:type_name -> rill.runtime.v1.Notifier + 89, // 97: rill.runtime.v1.AlertSpec.annotations:type_name -> rill.runtime.v1.AlertSpec.AnnotationsEntry + 93, // 98: rill.runtime.v1.Notifier.properties:type_name -> google.protobuf.Struct + 92, // 99: rill.runtime.v1.AlertState.next_run_on:type_name -> google.protobuf.Timestamp + 46, // 100: rill.runtime.v1.AlertState.current_execution:type_name -> rill.runtime.v1.AlertExecution + 46, // 101: rill.runtime.v1.AlertState.execution_history:type_name -> rill.runtime.v1.AlertExecution + 47, // 102: rill.runtime.v1.AlertExecution.result:type_name -> rill.runtime.v1.AssertionResult + 92, // 103: rill.runtime.v1.AlertExecution.execution_time:type_name -> google.protobuf.Timestamp + 92, // 104: rill.runtime.v1.AlertExecution.started_on:type_name -> google.protobuf.Timestamp + 92, // 105: rill.runtime.v1.AlertExecution.finished_on:type_name -> google.protobuf.Timestamp + 92, // 106: rill.runtime.v1.AlertExecution.suppressed_since:type_name -> google.protobuf.Timestamp + 4, // 107: rill.runtime.v1.AssertionResult.status:type_name -> rill.runtime.v1.AssertionStatus + 93, // 108: rill.runtime.v1.AssertionResult.fail_row:type_name -> google.protobuf.Struct + 49, // 109: rill.runtime.v1.PullTrigger.spec:type_name -> rill.runtime.v1.PullTriggerSpec + 50, // 110: rill.runtime.v1.PullTrigger.state:type_name -> rill.runtime.v1.PullTriggerState + 52, // 111: rill.runtime.v1.RefreshTrigger.spec:type_name -> rill.runtime.v1.RefreshTriggerSpec + 53, // 112: rill.runtime.v1.RefreshTrigger.state:type_name -> rill.runtime.v1.RefreshTriggerState + 10, // 113: rill.runtime.v1.RefreshTriggerSpec.resources:type_name -> rill.runtime.v1.ResourceName + 54, // 114: rill.runtime.v1.RefreshTriggerSpec.models:type_name -> rill.runtime.v1.RefreshModelTrigger + 56, // 115: rill.runtime.v1.BucketPlanner.spec:type_name -> rill.runtime.v1.BucketPlannerSpec + 57, // 116: rill.runtime.v1.BucketPlanner.state:type_name -> rill.runtime.v1.BucketPlannerState + 58, // 117: rill.runtime.v1.BucketPlannerSpec.extract_policy:type_name -> rill.runtime.v1.BucketExtractPolicy + 7, // 118: rill.runtime.v1.BucketExtractPolicy.rows_strategy:type_name -> rill.runtime.v1.BucketExtractPolicy.Strategy + 7, // 119: rill.runtime.v1.BucketExtractPolicy.files_strategy:type_name -> rill.runtime.v1.BucketExtractPolicy.Strategy + 60, // 120: rill.runtime.v1.Theme.spec:type_name -> rill.runtime.v1.ThemeSpec + 61, // 121: rill.runtime.v1.Theme.state:type_name -> rill.runtime.v1.ThemeState + 98, // 122: rill.runtime.v1.ThemeSpec.primary_color:type_name -> rill.runtime.v1.Color + 98, // 123: rill.runtime.v1.ThemeSpec.secondary_color:type_name -> rill.runtime.v1.Color + 63, // 124: rill.runtime.v1.Component.spec:type_name -> rill.runtime.v1.ComponentSpec + 64, // 125: rill.runtime.v1.Component.state:type_name -> rill.runtime.v1.ComponentState + 93, // 126: rill.runtime.v1.ComponentSpec.resolver_properties:type_name -> google.protobuf.Struct + 93, // 127: rill.runtime.v1.ComponentSpec.renderer_properties:type_name -> google.protobuf.Struct + 65, // 128: rill.runtime.v1.ComponentSpec.input:type_name -> rill.runtime.v1.ComponentVariable + 65, // 129: rill.runtime.v1.ComponentSpec.output:type_name -> rill.runtime.v1.ComponentVariable + 63, // 130: rill.runtime.v1.ComponentState.valid_spec:type_name -> rill.runtime.v1.ComponentSpec + 99, // 131: rill.runtime.v1.ComponentVariable.default_value:type_name -> google.protobuf.Value + 67, // 132: rill.runtime.v1.Canvas.spec:type_name -> rill.runtime.v1.CanvasSpec + 68, // 133: rill.runtime.v1.Canvas.state:type_name -> rill.runtime.v1.CanvasState + 65, // 134: rill.runtime.v1.CanvasSpec.variables:type_name -> rill.runtime.v1.ComponentVariable + 69, // 135: rill.runtime.v1.CanvasSpec.items:type_name -> rill.runtime.v1.CanvasItem + 22, // 136: rill.runtime.v1.CanvasSpec.security_rules:type_name -> rill.runtime.v1.SecurityRule + 67, // 137: rill.runtime.v1.CanvasState.valid_spec:type_name -> rill.runtime.v1.CanvasSpec + 71, // 138: rill.runtime.v1.API.spec:type_name -> rill.runtime.v1.APISpec + 72, // 139: rill.runtime.v1.API.state:type_name -> rill.runtime.v1.APIState + 93, // 140: rill.runtime.v1.APISpec.resolver_properties:type_name -> google.protobuf.Struct + 93, // 141: rill.runtime.v1.APISpec.openapi_parameters:type_name -> google.protobuf.Struct + 93, // 142: rill.runtime.v1.APISpec.openapi_response_schema:type_name -> google.protobuf.Struct + 78, // 143: rill.runtime.v1.ParseError.start_location:type_name -> rill.runtime.v1.CharLocation + 90, // 144: rill.runtime.v1.ConnectorSpec.properties:type_name -> rill.runtime.v1.ConnectorSpec.PropertiesEntry + 91, // 145: rill.runtime.v1.ConnectorSpec.properties_from_variables:type_name -> rill.runtime.v1.ConnectorSpec.PropertiesFromVariablesEntry + 79, // 146: rill.runtime.v1.ConnectorV2.spec:type_name -> rill.runtime.v1.ConnectorSpec + 80, // 147: rill.runtime.v1.ConnectorV2.state:type_name -> rill.runtime.v1.ConnectorState + 95, // 148: rill.runtime.v1.MetricsViewSpec.DimensionSelector.time_grain:type_name -> rill.runtime.v1.TimeGrain + 83, // 149: rill.runtime.v1.MetricsViewSpec.MeasureWindow.order_by:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionSelector + 5, // 150: rill.runtime.v1.MetricsViewSpec.MeasureV2.type:type_name -> rill.runtime.v1.MetricsViewSpec.MeasureType + 84, // 151: rill.runtime.v1.MetricsViewSpec.MeasureV2.window:type_name -> rill.runtime.v1.MetricsViewSpec.MeasureWindow + 83, // 152: rill.runtime.v1.MetricsViewSpec.MeasureV2.per_dimensions:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionSelector + 83, // 153: rill.runtime.v1.MetricsViewSpec.MeasureV2.required_dimensions:type_name -> rill.runtime.v1.MetricsViewSpec.DimensionSelector + 93, // 154: rill.runtime.v1.MetricsViewSpec.MeasureV2.format_d3_locale:type_name -> google.protobuf.Struct + 86, // 155: rill.runtime.v1.MetricsViewSpec.AvailableTimeRange.comparison_offsets:type_name -> rill.runtime.v1.MetricsViewSpec.AvailableComparisonOffset + 156, // [156:156] is the sub-list for method output_type + 156, // [156:156] is the sub-list for method input_type + 156, // [156:156] is the sub-list for extension type_name + 156, // [156:156] is the sub-list for extension extendee + 0, // [0:156] is the sub-list for field type_name } func init() { file_rill_runtime_v1_resources_proto_init() } @@ -9031,6 +9385,7 @@ func file_rill_runtime_v1_resources_proto_init() { (*SecurityRule_FieldAccess)(nil), (*SecurityRule_RowFilter)(nil), } + file_rill_runtime_v1_resources_proto_msgTypes[24].OneofWrappers = []any{} file_rill_runtime_v1_resources_proto_msgTypes[25].OneofWrappers = []any{ (*FieldSelector_All)(nil), (*FieldSelector_Fields)(nil), @@ -9049,7 +9404,7 @@ func file_rill_runtime_v1_resources_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rill_runtime_v1_resources_proto_rawDesc, - NumEnums: 6, + NumEnums: 8, NumMessages: 84, NumExtensions: 0, NumServices: 0, diff --git a/proto/gen/rill/runtime/v1/resources.pb.validate.go b/proto/gen/rill/runtime/v1/resources.pb.validate.go index 0b3dfd330d1..27b3719e279 100644 --- a/proto/gen/rill/runtime/v1/resources.pb.validate.go +++ b/proto/gen/rill/runtime/v1/resources.pb.validate.go @@ -4888,11 +4888,104 @@ func (m *ExplorePreset) validate(all bool) error { } } - // no validation rules for TimeRange - // no validation rules for ComparisonMode - // no validation rules for ComparisonDimension + if m.Where != nil { + + if all { + switch v := interface{}(m.GetWhere()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ExplorePresetValidationError{ + field: "Where", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ExplorePresetValidationError{ + field: "Where", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetWhere()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ExplorePresetValidationError{ + field: "Where", + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if m.TimeRange != nil { + // no validation rules for TimeRange + } + + if m.Timezone != nil { + // no validation rules for Timezone + } + + if m.TimeGrain != nil { + // no validation rules for TimeGrain + } + + if m.SelectTimeRange != nil { + // no validation rules for SelectTimeRange + } + + if m.CompareTimeRange != nil { + // no validation rules for CompareTimeRange + } + + if m.ComparisonDimension != nil { + // no validation rules for ComparisonDimension + } + + if m.View != nil { + // no validation rules for View + } + + if m.ExploreSortBy != nil { + // no validation rules for ExploreSortBy + } + + if m.ExploreSortAsc != nil { + // no validation rules for ExploreSortAsc + } + + if m.ExploreSortType != nil { + // no validation rules for ExploreSortType + } + + if m.ExploreExpandedDimension != nil { + // no validation rules for ExploreExpandedDimension + } + + if m.TimeDimensionMeasure != nil { + // no validation rules for TimeDimensionMeasure + } + + if m.TimeDimensionChartType != nil { + // no validation rules for TimeDimensionChartType + } + + if m.TimeDimensionPin != nil { + // no validation rules for TimeDimensionPin + } + + if m.PivotSortBy != nil { + // no validation rules for PivotSortBy + } + + if m.PivotSortAsc != nil { + // no validation rules for PivotSortAsc + } if len(errors) > 0 { return ExplorePresetMultiError(errors) diff --git a/proto/gen/rill/runtime/v1/runtime.swagger.yaml b/proto/gen/rill/runtime/v1/runtime.swagger.yaml index 592c1abe7b8..d5578f954af 100644 --- a/proto/gen/rill/runtime/v1/runtime.swagger.yaml +++ b/proto/gen/rill/runtime/v1/runtime.swagger.yaml @@ -4092,18 +4092,66 @@ definitions: measuresSelector: $ref: '#/definitions/v1FieldSelector' description: Dynamic selector for `measures`. Will be processed during validation, so it will always be empty in `state.valid_spec`. + where: + $ref: '#/definitions/v1Expression' timeRange: type: string description: |- Time range for the explore. It corresponds to the `range` property of the explore's `time_ranges`. If not found in `time_ranges`, it should be added to the list. + timezone: + type: string + timeGrain: + type: string + selectTimeRange: + type: string comparisonMode: $ref: '#/definitions/v1ExploreComparisonMode' description: Comparison mode. + compareTimeRange: + type: string comparisonDimension: type: string description: If comparison_mode is EXPLORE_COMPARISON_MODE_DIMENSION, this indicates the dimension to use. + view: + $ref: '#/definitions/v1ExploreWebView' + exploreSortBy: + type: string + exploreSortAsc: + type: boolean + exploreSortType: + $ref: '#/definitions/v1ExploreSortType' + exploreExpandedDimension: + type: string + timeDimensionMeasure: + type: string + timeDimensionChartType: + type: string + timeDimensionPin: + type: boolean + pivotRows: + type: array + items: + type: string + pivotCols: + type: array + items: + type: string + pivotSortBy: + type: string + pivotSortAsc: + type: boolean + v1ExploreSortType: + type: string + enum: + - EXPLORE_SORT_TYPE_UNSPECIFIED + - EXPLORE_SORT_TYPE_VALUE + - EXPLORE_SORT_TYPE_PERCENT + - EXPLORE_SORT_TYPE_DELTA_PERCENT + - EXPLORE_SORT_TYPE_DELTA_ABSOLUTE + - EXPLORE_SORT_TYPE_DIMENSION + default: EXPLORE_SORT_TYPE_UNSPECIFIED v1ExploreSpec: type: object properties: @@ -4184,6 +4232,15 @@ definitions: type: object $ref: '#/definitions/v1ExploreComparisonTimeRange' title: Comparison time ranges available for this time range + v1ExploreWebView: + type: string + enum: + - EXPLORE_WEB_VIEW_UNSPECIFIED + - EXPLORE_WEB_VIEW_EXPLORE + - EXPLORE_WEB_VIEW_TIME_DIMENSION + - EXPLORE_WEB_VIEW_PIVOT + - EXPLORE_WEB_VIEW_CANVAS + default: EXPLORE_WEB_VIEW_UNSPECIFIED v1ExportFormat: type: string enum: diff --git a/proto/rill/runtime/v1/resources.proto b/proto/rill/runtime/v1/resources.proto index 0760b25633b..e1993e75069 100644 --- a/proto/rill/runtime/v1/resources.proto +++ b/proto/rill/runtime/v1/resources.proto @@ -385,14 +385,38 @@ message ExplorePreset { repeated string measures = 4; // Dynamic selector for `measures`. Will be processed during validation, so it will always be empty in `state.valid_spec`. FieldSelector measures_selector = 10; + + optional Expression where = 11; + // Time range for the explore. // It corresponds to the `range` property of the explore's `time_ranges`. // If not found in `time_ranges`, it should be added to the list. - string time_range = 6; + optional string time_range = 6; + optional string timezone = 12; + optional string time_grain = 13; + optional string select_time_range = 14; + // Comparison mode. ExploreComparisonMode comparison_mode = 7; + optional string compare_time_range = 15; // If comparison_mode is EXPLORE_COMPARISON_MODE_DIMENSION, this indicates the dimension to use. - string comparison_dimension = 8; + optional string comparison_dimension = 8; + + optional ExploreWebView view = 16; + + optional string explore_sort_by = 17; + optional bool explore_sort_asc = 18; + optional ExploreSortType explore_sort_type = 19; + optional string explore_expanded_dimension = 20; + + optional string time_dimension_measure = 21; + optional string time_dimension_chart_type = 22; + optional bool time_dimension_pin = 23; + + repeated string pivot_rows = 24; + repeated string pivot_cols = 25; + optional string pivot_sort_by = 26; + optional bool pivot_sort_asc = 27; } enum ExploreComparisonMode { @@ -402,6 +426,23 @@ enum ExploreComparisonMode { EXPLORE_COMPARISON_MODE_DIMENSION = 3; } +enum ExploreWebView { + EXPLORE_WEB_VIEW_UNSPECIFIED = 0; + EXPLORE_WEB_VIEW_EXPLORE = 1; + EXPLORE_WEB_VIEW_TIME_DIMENSION = 2; + EXPLORE_WEB_VIEW_PIVOT = 3; + EXPLORE_WEB_VIEW_CANVAS = 4; +} + +enum ExploreSortType { + EXPLORE_SORT_TYPE_UNSPECIFIED = 0; + EXPLORE_SORT_TYPE_VALUE = 1; + EXPLORE_SORT_TYPE_PERCENT = 2; + EXPLORE_SORT_TYPE_DELTA_PERCENT = 3; + EXPLORE_SORT_TYPE_DELTA_ABSOLUTE = 4; + EXPLORE_SORT_TYPE_DIMENSION = 5; +} + // FieldSelector describes logic for selecting a list of fields. // It is useful for dynamically evaluating fields when the list of potential fields is not known at parse time. message FieldSelector { diff --git a/runtime/compilers/rillv1/parse_explore.go b/runtime/compilers/rillv1/parse_explore.go index 38a10fc4222..fa9fc7941df 100644 --- a/runtime/compilers/rillv1/parse_explore.go +++ b/runtime/compilers/rillv1/parse_explore.go @@ -228,14 +228,22 @@ func (p *Parser) parseExplore(node *Node) error { presetMeasuresSelector = tmp.Defaults.Measures.Proto() } + var tr *string + if tmp.Defaults.TimeRange != "" { + tr = &tmp.Defaults.TimeRange + } + var compareDim *string + if tmp.Defaults.ComparisonDimension != "" { + compareDim = &tmp.Defaults.ComparisonDimension + } defaultPreset = &runtimev1.ExplorePreset{ Dimensions: presetDimensions, DimensionsSelector: presetDimensionsSelector, Measures: presetMeasures, MeasuresSelector: presetMeasuresSelector, - TimeRange: tmp.Defaults.TimeRange, + TimeRange: tr, ComparisonMode: mode, - ComparisonDimension: tmp.Defaults.ComparisonDimension, + ComparisonDimension: compareDim, } } diff --git a/runtime/compilers/rillv1/parse_metrics_view.go b/runtime/compilers/rillv1/parse_metrics_view.go index 4085dbfe25a..7039beb4f03 100644 --- a/runtime/compilers/rillv1/parse_metrics_view.go +++ b/runtime/compilers/rillv1/parse_metrics_view.go @@ -899,14 +899,22 @@ func (p *Parser) parseMetricsView(node *Node) error { if len(spec.DefaultMeasures) == 0 { presetMeasuresSelector = &runtimev1.FieldSelector{Selector: &runtimev1.FieldSelector_All{All: true}} } + var tr *string + if spec.DefaultTimeRange != "" { + tr = &spec.DefaultTimeRange + } + var compareDim *string + if spec.DefaultComparisonDimension != "" { + compareDim = &spec.DefaultComparisonDimension + } e.ExploreSpec.DefaultPreset = &runtimev1.ExplorePreset{ Dimensions: spec.DefaultDimensions, DimensionsSelector: presetDimensionsSelector, Measures: spec.DefaultMeasures, MeasuresSelector: presetMeasuresSelector, - TimeRange: spec.DefaultTimeRange, + TimeRange: tr, ComparisonMode: exploreComparisonMode, - ComparisonDimension: spec.DefaultComparisonDimension, + ComparisonDimension: compareDim, } return nil diff --git a/runtime/compilers/rillv1/parser_test.go b/runtime/compilers/rillv1/parser_test.go index 9014167a0de..47442823359 100644 --- a/runtime/compilers/rillv1/parser_test.go +++ b/runtime/compilers/rillv1/parser_test.go @@ -212,6 +212,7 @@ schema: default `, } + timeRange := "P4W" resources := []*Resource{ // init.sql { @@ -317,7 +318,7 @@ schema: default DefaultPreset: &runtimev1.ExplorePreset{ DimensionsSelector: &runtimev1.FieldSelector{Selector: &runtimev1.FieldSelector_All{All: true}}, MeasuresSelector: &runtimev1.FieldSelector{Selector: &runtimev1.FieldSelector_All{All: true}}, - TimeRange: "P4W", + TimeRange: &timeRange, ComparisonMode: runtimev1.ExploreComparisonMode_EXPLORE_COMPARISON_MODE_NONE, }, }, diff --git a/scripts/tsc-with-whitelist.sh b/scripts/tsc-with-whitelist.sh index 4a67159656d..5a975eb91cb 100755 --- a/scripts/tsc-with-whitelist.sh +++ b/scripts/tsc-with-whitelist.sh @@ -22,6 +22,7 @@ web-admin/src/routes/[organization]/-/settings/billing/payment/+page.ts: error T web-admin/src/routes/[organization]/-/settings/billing/upgrade/+page.ts: error TS2307 web-admin/src/routes/[organization]/-/settings/usage/+page.ts: error TS2307 web-admin/src/routes/[organization]/-/upgrade-callback/+page.ts: error TS2307 +web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts: error TS2345 web-common/src/components/data-graphic/actions/mouse-position-to-domain-action-factory.ts: error TS2322 web-common/src/components/data-graphic/actions/outline.ts: error TS18047 web-common/src/components/data-graphic/actions/outline.ts: error TS2345 diff --git a/web-admin/src/features/bookmarks/BaseBookmarkForm.svelte b/web-admin/src/features/bookmarks/BaseBookmarkForm.svelte index 32e5c7d6fc8..8ab436deed1 100644 --- a/web-admin/src/features/bookmarks/BaseBookmarkForm.svelte +++ b/web-admin/src/features/bookmarks/BaseBookmarkForm.svelte @@ -10,7 +10,7 @@ import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte"; import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte"; import FilterChipsReadOnly from "@rilldata/web-common/features/dashboards/filters/FilterChipsReadOnly.svelte"; - import { useExploreStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; + import { useExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient"; import type { V1TimeRange } from "@rilldata/web-common/runtime-client"; import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; @@ -21,13 +21,13 @@ export let exploreName: string; export let formState: ReturnType>; - $: exploreStore = useExploreStore(exploreName); + $: exploreState = useExploreState(exploreName); let timeRange: V1TimeRange; $: timeRange = { - isoDuration: $exploreStore.selectedTimeRange?.name, - start: $exploreStore.selectedTimeRange?.start?.toISOString() ?? "", - end: $exploreStore.selectedTimeRange?.end?.toISOString() ?? "", + isoDuration: $exploreState.selectedTimeRange?.name, + start: $exploreState.selectedTimeRange?.start?.toISOString() ?? "", + end: $exploreState.selectedTimeRange?.end?.toISOString() ?? "", }; $: selectedTimeRange = getPrettySelectedTimeRange( @@ -70,8 +70,8 @@ Managed bookmarks will be available to all viewers of this dashboard.`;
Inherited from underlying dashboard view.
diff --git a/web-admin/src/features/bookmarks/BookmarkDialog.svelte b/web-admin/src/features/bookmarks/BookmarkDialog.svelte index 153fdbc34e1..f87659b51fa 100644 --- a/web-admin/src/features/bookmarks/BookmarkDialog.svelte +++ b/web-admin/src/features/bookmarks/BookmarkDialog.svelte @@ -13,7 +13,7 @@ import { Button } from "@rilldata/web-common/components/button"; import * as Dialog from "@rilldata/web-common/components/dialog-v2"; import { getStateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers"; - import { useExploreStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; + import { useExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; import { useTimeControlStore } from "@rilldata/web-common/features/dashboards/time-controls/time-control-store"; import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; import { eventBus } from "@rilldata/web-common/lib/event-bus/event-bus"; @@ -53,7 +53,7 @@ description: values.description, shared: values.shared === "true", data: getBookmarkDataForDashboard( - $exploreStore, + $exploreState, values.filtersOnly, values.absoluteTimeRange, $timeControlsStore, @@ -70,7 +70,7 @@ resourceName: exploreName, shared: values.shared === "true", data: getBookmarkDataForDashboard( - $exploreStore, + $exploreState, values.filtersOnly, values.absoluteTimeRange, $timeControlsStore, @@ -97,7 +97,7 @@ const { handleSubmit, handleReset } = formState; $: ({ params } = $page); - $: exploreStore = useExploreStore(exploreName); + $: exploreState = useExploreState(exploreName); $: projectId = useProjectId(params.organization, params.project); diff --git a/web-admin/src/features/bookmarks/BookmarkFiltersFormSection.svelte b/web-admin/src/features/bookmarks/BookmarkFiltersFormSection.svelte index f995128825a..e20992de24c 100644 --- a/web-admin/src/features/bookmarks/BookmarkFiltersFormSection.svelte +++ b/web-admin/src/features/bookmarks/BookmarkFiltersFormSection.svelte @@ -1,18 +1,18 @@ @@ -22,8 +22,8 @@ title="Filters" > diff --git a/web-admin/src/features/bookmarks/Bookmarks.svelte b/web-admin/src/features/bookmarks/Bookmarks.svelte index 6033533e159..5d5cded278f 100644 --- a/web-admin/src/features/bookmarks/Bookmarks.svelte +++ b/web-admin/src/features/bookmarks/Bookmarks.svelte @@ -1,12 +1,13 @@ - -{#if $dashboardStoreReady} - -{:else} -
- -
-{/if} diff --git a/web-admin/src/features/dashboards/query-mappers/getDashboardFromAggregationRequest.ts b/web-admin/src/features/dashboards/query-mappers/getDashboardFromAggregationRequest.ts index c46174a728b..81f1f371cf0 100644 --- a/web-admin/src/features/dashboards/query-mappers/getDashboardFromAggregationRequest.ts +++ b/web-admin/src/features/dashboards/query-mappers/getDashboardFromAggregationRequest.ts @@ -1,8 +1,5 @@ import type { QueryMapperArgs } from "@rilldata/web-admin/features/dashboards/query-mappers/types"; -import { - convertExprToToplist, - fillTimeRange, -} from "@rilldata/web-admin/features/dashboards/query-mappers/utils"; +import { fillTimeRange } from "@rilldata/web-admin/features/dashboards/query-mappers/utils"; import { ComparisonDeltaAbsoluteSuffix, ComparisonDeltaRelativeSuffix, @@ -10,7 +7,6 @@ import { mapExprToMeasureFilter, } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-entry"; import { splitWhereFilter } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-utils"; -import { mergeFilters } from "@rilldata/web-common/features/dashboards/pivot/pivot-merge-filters"; import { SortDirection, SortType, @@ -18,7 +14,9 @@ import { import { getDashboardStateFromUrl } from "@rilldata/web-common/features/dashboards/proto-state/fromProto"; import { createAndExpression, + createSubQueryExpression, forEachIdentifier, + getAllIdentifiers, } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; import { TDDChart } from "@rilldata/web-common/features/dashboards/time-dimension-details/types"; @@ -79,24 +77,18 @@ export async function getDashboardFromAggregationRequest({ exprHasComparison(req.having) || dashboard.dimensionThresholdFilters.length > 0 ) { - const expr = await convertExprToToplist( - queryClient, - instanceId, - dashboard.name, + const extraFilter = createSubQueryExpression( dimension, - req.measures?.[0]?.name ?? "", - req.timeRange, - req.comparisonTimeRange, - executionTime, - req.where, + getAllIdentifiers(req.having), req.having, ); - if (expr) { - dashboard.whereFilter = - mergeFilters( - dashboard.whereFilter ?? createAndExpression([]), - createAndExpression([expr]), - ) ?? createAndExpression([]); + if (dashboard.whereFilter?.cond?.exprs?.length) { + dashboard.whereFilter = createAndExpression([ + dashboard.whereFilter, + extraFilter, + ]); + } else { + dashboard.whereFilter = extraFilter; } } else { dashboard.dimensionThresholdFilters = [ diff --git a/web-admin/src/features/dashboards/query-mappers/mapQueryToDashboard.ts b/web-admin/src/features/dashboards/query-mappers/mapQueryToDashboard.ts index dc743b9f6e5..4a65ce3d724 100644 --- a/web-admin/src/features/dashboards/query-mappers/mapQueryToDashboard.ts +++ b/web-admin/src/features/dashboards/query-mappers/mapQueryToDashboard.ts @@ -5,8 +5,7 @@ import type { QueryRequests, } from "@rilldata/web-admin/features/dashboards/query-mappers/types"; import type { CompoundQueryResult } from "@rilldata/web-common/features/compound-query-result"; -import { getProtoFromDashboardState } from "@rilldata/web-common/features/dashboards/proto-state/toProto"; -import { getDefaultMetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; +import { getDefaultExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; import { initLocalUserPreferenceStore } from "@rilldata/web-common/features/dashboards/user-preferences"; import { useExploreValidSpec } from "@rilldata/web-common/features/explores/selectors"; @@ -20,7 +19,7 @@ import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import { derived, get, readable } from "svelte/store"; type DashboardStateForQuery = { - state?: string; + exploreState?: MetricsExplorerEntity; exploreName?: string; }; @@ -118,7 +117,7 @@ export function mapQueryToDashboard( const { metricsView, explore } = validSpecResp.data; initLocalUserPreferenceStore(metricsViewName); - const defaultDashboard = getDefaultMetricsExplorerEntity( + const defaultExploreState = getDefaultExploreState( metricsViewName, metricsView, explore, @@ -127,7 +126,7 @@ export function mapQueryToDashboard( getDashboardState({ queryClient, instanceId, - dashboard: defaultDashboard, + dashboard: defaultExploreState, req, metricsView, explore, @@ -135,12 +134,12 @@ export function mapQueryToDashboard( executionTime, annotations, }) - .then((newDashboard) => { + .then((newExploreState) => { set({ isFetching: false, error: "", data: { - state: getProtoFromDashboardState(newDashboard), + exploreState: newExploreState, exploreName, }, }); diff --git a/web-admin/src/features/dashboards/query-mappers/utils.ts b/web-admin/src/features/dashboards/query-mappers/utils.ts index e8e0466b51d..4fe74dca587 100644 --- a/web-admin/src/features/dashboards/query-mappers/utils.ts +++ b/web-admin/src/features/dashboards/query-mappers/utils.ts @@ -9,6 +9,8 @@ import { } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; import { PreviousCompleteRangeMap } from "@rilldata/web-common/features/dashboards/time-controls/time-range-mappers"; +import { convertExploreStateToURLSearchParams } from "@rilldata/web-common/features/dashboards/url-state/convertExploreStateToURLSearchParams"; +import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient"; import { isoDurationToFullTimeRange } from "@rilldata/web-common/lib/time/ranges/iso-ranges"; import { type DashboardTimeControls, @@ -17,13 +19,17 @@ import { } from "@rilldata/web-common/lib/time/types"; import { getQueryServiceMetricsViewAggregationQueryKey, + getRuntimeServiceGetExploreQueryKey, queryServiceMetricsViewAggregation, type QueryServiceMetricsViewAggregationBody, + runtimeServiceGetExplore, type V1Expression, type V1TimeRange, type V1TimeRangeSummary, } from "@rilldata/web-common/runtime-client"; +import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import type { QueryClient } from "@tanstack/svelte-query"; +import { get } from "svelte/store"; // We are manually sending in duration, offset and round to grain for previous complete ranges. // This is to map back that split @@ -217,15 +223,39 @@ export function getExploreName(webOpenPath: string) { return matches[1]; } -export function getExplorePageUrl( +export async function getExplorePageUrl( curPageUrl: URL, organization: string, project: string, exploreName: string, - state: string, + exploreState: MetricsExplorerEntity, ) { + const instanceId = get(runtime).instanceId; + const { explore } = await queryClient.fetchQuery({ + queryFn: ({ signal }) => + runtimeServiceGetExplore( + instanceId, + { + name: exploreName, + }, + signal, + ), + queryKey: getRuntimeServiceGetExploreQueryKey(instanceId, { + name: exploreName, + }), + // this loader function is run for every param change in url. + // so to avoid re-fetching explore everytime we set this so that it hits cache. + staleTime: Infinity, + }); + const url = new URL(`${curPageUrl.protocol}//${curPageUrl.host}`); url.pathname = `/${organization}/${project}/explore/${exploreName}`; - url.searchParams.set("state", state); + + const exploreSpec = explore?.explore?.state?.validSpec; + url.search = convertExploreStateToURLSearchParams( + exploreState, + exploreSpec ?? {}, + exploreSpec?.defaultPreset ?? {}, + ); return url.toString(); } diff --git a/web-admin/src/features/embeds/ExploreEmbed.svelte b/web-admin/src/features/embeds/ExploreEmbed.svelte index cb218482f98..3e5db6dcde5 100644 --- a/web-admin/src/features/embeds/ExploreEmbed.svelte +++ b/web-admin/src/features/embeds/ExploreEmbed.svelte @@ -1,9 +1,8 @@ - -{#if $dashboardStoreReady} - -{:else} -
- -
-{/if} diff --git a/web-admin/src/features/public-urls/form-utils.ts b/web-admin/src/features/public-urls/form-utils.ts index 350f800b5d3..6a777cd339a 100644 --- a/web-admin/src/features/public-urls/form-utils.ts +++ b/web-admin/src/features/public-urls/form-utils.ts @@ -86,7 +86,6 @@ export function getSanitizedDashboardStateParam( sortDirection: dashboard.sortDirection, // Remove the where filter // whereFilter: dashboard.whereFilter, - havingFilter: dashboard.havingFilter, dimensionThresholdFilters: dashboard.dimensionThresholdFilters, dimensionFilterExcludeMode: dashboard.dimensionFilterExcludeMode, // There's no need to share filters-in-progress diff --git a/web-admin/src/routes/+layout.ts b/web-admin/src/routes/+layout.ts index 6362a8a5427..3e066ff3d58 100644 --- a/web-admin/src/routes/+layout.ts +++ b/web-admin/src/routes/+layout.ts @@ -7,21 +7,17 @@ export const ssr = false; import { dev } from "$app/environment"; import { - adminServiceGetProject, - getAdminServiceGetProjectQueryKey, type V1OrganizationPermissions, type V1ProjectPermissions, } from "@rilldata/web-admin/client"; import { redirectToLoginOrRequestAccess } from "@rilldata/web-admin/features/authentication/checkUserAccess"; import { fetchOrganizationPermissions } from "@rilldata/web-admin/features/organizations/selectors"; +import { fetchProjectDeploymentDetails } from "@rilldata/web-admin/features/projects/selectors"; import { initPosthog } from "@rilldata/web-common/lib/analytics/posthog"; import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient.js"; +import { fixLocalhostRuntimePort } from "@rilldata/web-common/runtime-client/fix-localhost-runtime-port"; +import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import { error, redirect, type Page } from "@sveltejs/kit"; -import type { QueryFunction, QueryKey } from "@tanstack/svelte-query"; -import { - adminServiceGetProjectWithBearerToken, - getAdminServiceGetProjectWithBearerTokenQueryKey, -} from "../features/public-urls/get-project-with-bearer-token.js"; export const load = async ({ params, url, route }) => { // Route params @@ -34,7 +30,7 @@ export const load = async ({ params, url, route }) => { let searchParamToken: string | undefined; if (url.searchParams.has("token")) { - searchParamToken = url.searchParams.get("token"); + searchParamToken = url.searchParams.get("token") ?? undefined; } const token = searchParamToken ?? routeToken; @@ -74,46 +70,26 @@ export const load = async ({ params, url, route }) => { } } - // Get project permissions - let queryKey: QueryKey; - let queryFn: QueryFunction< - Awaited> - >; - - if (token) { - queryKey = getAdminServiceGetProjectWithBearerTokenQueryKey( - organization, - project, - token, - {}, - ); - - queryFn = ({ signal }) => - adminServiceGetProjectWithBearerToken( - organization, - project, - token, - {}, - signal, - ); - } else { - queryKey = getAdminServiceGetProjectQueryKey(organization, project); - - queryFn = ({ signal }) => - adminServiceGetProject(organization, project, {}, signal); - } - try { - const response = await queryClient.fetchQuery({ - queryFn, - queryKey, - }); + const { + projectPermissions, + project: proj, + runtime: runtimeData, + } = await fetchProjectDeploymentDetails(organization, project, token); - const { projectPermissions } = response; + await runtime.setRuntime( + queryClient, + fixLocalhostRuntimePort(runtimeData.host), + runtimeData.instanceId, + runtimeData.jwt?.token, + runtimeData.jwt?.authContext, + ); return { organizationPermissions, projectPermissions, + project: proj, + runtime: runtimeData, }; } catch (e) { if (e.response?.status !== 403) { diff --git a/web-admin/src/routes/[organization]/[project]/-/alerts/[alert]/open/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/alerts/[alert]/open/+page.svelte index 5b957edd53a..85ea997ff11 100644 --- a/web-admin/src/routes/[organization]/[project]/-/alerts/[alert]/open/+page.svelte +++ b/web-admin/src/routes/[organization]/[project]/-/alerts/[alert]/open/+page.svelte @@ -47,15 +47,18 @@ } $: if ($dashboardStateForAlert.data) { - void goto( - getExplorePageUrl( - $page.url, - organization, - project, - $dashboardStateForAlert.data.exploreName, - $dashboardStateForAlert.data.state, - ), + void gotoExplorePage(); + } + + async function gotoExplorePage() { + const explorePageUrl = await getExplorePageUrl( + $page.url, + organization, + project, + $dashboardStateForAlert.data.exploreName, + $dashboardStateForAlert.data.exploreState, ); + return goto(explorePageUrl); } diff --git a/web-admin/src/routes/[organization]/[project]/-/reports/[report]/open/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/reports/[report]/open/+page.svelte index 25cb4aa905a..f9af86ca92d 100644 --- a/web-admin/src/routes/[organization]/[project]/-/reports/[report]/open/+page.svelte +++ b/web-admin/src/routes/[organization]/[project]/-/reports/[report]/open/+page.svelte @@ -35,15 +35,18 @@ ); $: if ($dashboardStateForReport?.data) { - void goto( - getExplorePageUrl( - $page.url, - organization, - project, - $dashboardStateForReport.data.exploreName, - $dashboardStateForReport.data.state, - ), + void gotoExplorePage(); + } + + async function gotoExplorePage() { + const explorePageUrl = await getExplorePageUrl( + $page.url, + organization, + project, + $dashboardStateForReport.data.exploreName, + $dashboardStateForReport.data.exploreState, ); + return goto(explorePageUrl); } // TODO: error handling diff --git a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+layout.ts b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+layout.ts new file mode 100644 index 00000000000..86058fe4b0f --- /dev/null +++ b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+layout.ts @@ -0,0 +1,31 @@ +import { fetchMagicAuthToken } from "@rilldata/web-admin/features/projects/selectors"; +import { fetchExploreSpec } from "@rilldata/web-common/features/explores/selectors"; +import { error } from "@sveltejs/kit"; + +export const load = async ({ params: { token }, parent }) => { + const { runtime } = await parent(); + + try { + const tokenData = await fetchMagicAuthToken(token); + + if (!tokenData.token?.resourceName) { + throw new Error("Token does not have an associated resource name"); + } + + const { explore, metricsView, defaultExplorePreset } = + await fetchExploreSpec( + runtime.instanceId as string, + tokenData.token.resourceName, + ); + + return { + explore, + metricsView, + defaultExplorePreset, + token: tokenData?.token, + }; + } catch (e) { + console.error(e); + throw error(404, "Unable to find token"); + } +}; diff --git a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.svelte index 769b94f8612..d84646ce3c7 100644 --- a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.svelte +++ b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.svelte @@ -2,10 +2,9 @@ import { onNavigate } from "$app/navigation"; import { page } from "$app/stores"; import { createAdminServiceGetProject } from "@rilldata/web-admin/client"; - import DashboardPublicURLStateProvider from "@rilldata/web-admin/features/public-urls/DashboardPublicURLStateProvider.svelte"; import { Dashboard } from "@rilldata/web-common/features/dashboards"; import DashboardThemeProvider from "@rilldata/web-common/features/dashboards/DashboardThemeProvider.svelte"; - import DashboardURLStateProvider from "@rilldata/web-common/features/dashboards/proto-state/DashboardURLStateProvider.svelte"; + import DashboardURLStateSync from "@rilldata/web-common/features/dashboards/url-state/DashboardURLStateSync.svelte"; import StateManagersProvider from "@rilldata/web-common/features/dashboards/state-managers/StateManagersProvider.svelte"; import { eventBus } from "@rilldata/web-common/lib/event-bus/event-bus"; import { createRuntimeServiceGetExplore } from "@rilldata/web-common/runtime-client"; @@ -14,7 +13,11 @@ export let data: PageData; - $: ({ resourceName } = data.token); + $: ({ + defaultExplorePreset, + partialExploreState, + token: { resourceName }, + } = data); $: ({ organization, project } = $page.params); // Query the `GetProject` API with cookie-based auth to determine if the user has access to the original dashboard @@ -52,21 +55,14 @@ metricsViewName={explore.metricsView.meta.name.name} exploreName={resourceName} > - - - - - - - + + + + + {/if} {/key} diff --git a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts index 6b061042194..9db3b59c398 100644 --- a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts +++ b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts @@ -1,35 +1,57 @@ -import { - adminServiceGetMagicAuthToken, - getAdminServiceGetMagicAuthTokenQueryKey, -} from "@rilldata/web-admin/features/public-urls/get-magic-auth-token"; -import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient"; -import { error } from "@sveltejs/kit"; -import { type QueryFunction } from "@tanstack/svelte-query"; +import { getDashboardStateFromUrl } from "@rilldata/web-common/features/dashboards/proto-state/fromProto"; +import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; +import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; +import { convertExploreStateToURLSearchParams } from "@rilldata/web-common/features/dashboards/url-state/convertExploreStateToURLSearchParams"; +import { convertURLToExploreState } from "@rilldata/web-common/features/dashboards/url-state/convertPresetToExploreState"; +import { redirect } from "@sveltejs/kit"; +import { get } from "svelte/store"; -export const load = async ({ params: { token }, url: { searchParams } }) => { - const queryKey = getAdminServiceGetMagicAuthTokenQueryKey(token); - const queryFunction: QueryFunction< - Awaited> - > = ({ signal }) => adminServiceGetMagicAuthToken(token, signal); +export const load = async ({ url, parent }) => { + const { explore, metricsView, defaultExplorePreset, token } = await parent(); + const exploreName = token.resourceName; + const metricsViewSpec = metricsView.metricsView?.state?.validSpec; + const exploreSpec = explore.explore?.state?.validSpec; - try { - const tokenData = await queryClient.fetchQuery({ - queryKey, - queryFn: queryFunction, - }); - - const state = searchParams.get("state"); - - // Add the token's `state` to the URL (only if there's no existing URL `state`) - if (tokenData?.token?.state && !state) { - searchParams.set("state", tokenData.token.state); - } + // On the first dashboard load, if there are no URL params, append the token's state (in human-readable format) to the URL. + if ( + token.state && + ![...url.searchParams.keys()].length && + !(exploreName in get(metricsExplorerStore).entities) + ) { + const exploreState = getDashboardStateFromUrl( + token.state, + metricsViewSpec, + exploreSpec, + {}, // TODO + ); + const newUrl = new URL(url); + newUrl.search = convertExploreStateToURLSearchParams( + exploreState as MetricsExplorerEntity, + exploreSpec, + defaultExplorePreset, + ); + throw redirect(307, `${newUrl.pathname}${newUrl.search}`); + } - return { - token: tokenData?.token, - }; - } catch (e) { - console.error(e); - throw error(404, "Unable to find token"); + // Get Explore state from URL params + let partialExploreState: Partial = {}; + const errors: Error[] = []; + if (metricsViewSpec && exploreSpec) { + const { + partialExploreState: partialExploreStateFromUrl, + errors: errorsFromConvert, + } = convertURLToExploreState( + url.searchParams, + metricsViewSpec, + exploreSpec, + defaultExplorePreset, + ); + partialExploreState = partialExploreStateFromUrl; + errors.push(...errorsFromConvert); } + + return { + partialExploreState, + errors, + }; }; diff --git a/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+layout.ts b/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+layout.ts new file mode 100644 index 00000000000..914f498f0b8 --- /dev/null +++ b/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+layout.ts @@ -0,0 +1,41 @@ +import { + fetchBookmarks, + isHomeBookmark, +} from "@rilldata/web-admin/features/bookmarks/selectors"; +import { fetchExploreSpec } from "@rilldata/web-common/features/explores/selectors"; +import { + type V1ExplorePreset, + type V1Resource, +} from "@rilldata/web-common/runtime-client"; + +export const load = async ({ params, depends, parent }) => { + const { project, runtime } = await parent(); + + const exploreName = params.dashboard; + + depends(exploreName, "explore"); + + try { + const { explore, metricsView, defaultExplorePreset } = + await fetchExploreSpec(runtime?.instanceId, exploreName); + + // used to merge home bookmark to url state + const bookmarks = await fetchBookmarks(project.id, exploreName); + + return { + explore, + metricsView, + defaultExplorePreset, + homeBookmark: bookmarks.find(isHomeBookmark), + }; + } catch { + // error handled in +page.svelte for now + // TODO: move it here + return { + explore: {}, + metricsView: {}, + defaultExplorePreset: {}, + homeBookmark: undefined, + }; + } +}; diff --git a/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+page.svelte b/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+page.svelte index a1ebe555737..93f22dd32c6 100644 --- a/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+page.svelte +++ b/web-admin/src/routes/[organization]/[project]/explore/[dashboard]/+page.svelte @@ -1,26 +1,36 @@ @@ -112,7 +122,7 @@ />

+ import * as Tooltip from "@rilldata/web-common/components/tooltip-v2"; + import { convertExpressionToFilterParam } from "@rilldata/web-common/features/dashboards/url-state/filters/converters"; + import type { V1Expression } from "@rilldata/web-common/runtime-client"; + + export let advancedFilter: V1Expression; + + $: filterText = convertExpressionToFilterParam(advancedFilter); + + +
+ + + Advanced (BETA) + {filterText} + + + Advanced filters are a bleeding edge feature! There may be bugs. + + +
diff --git a/web-common/src/features/dashboards/filters/Filters.svelte b/web-common/src/features/dashboards/filters/Filters.svelte index d60d78bdd76..982f8763e69 100644 --- a/web-common/src/features/dashboards/filters/Filters.svelte +++ b/web-common/src/features/dashboards/filters/Filters.svelte @@ -2,20 +2,22 @@ import Button from "@rilldata/web-common/components/button/Button.svelte"; import Calendar from "@rilldata/web-common/components/icons/Calendar.svelte"; import Filter from "@rilldata/web-common/components/icons/Filter.svelte"; - import type { MeasureFilterEntry } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-entry"; + import AdvancedFilter from "@rilldata/web-common/features/dashboards/filters/AdvancedFilter.svelte"; import MeasureFilter from "@rilldata/web-common/features/dashboards/filters/measure-filters/MeasureFilter.svelte"; + import type { MeasureFilterEntry } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-entry"; + import { isExpressionUnsupported } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import { getMapFromArray } from "@rilldata/web-common/lib/arrayUtils"; import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import { flip } from "svelte/animate"; import { fly } from "svelte/transition"; import { useModelHasTimeSeries } from "../selectors"; import { getStateManagers } from "../state-managers/state-managers"; + import TimeGrainSelector from "../time-controls/TimeGrainSelector.svelte"; import ComparisonPill from "../time-controls/comparison-pill/ComparisonPill.svelte"; import SuperPill from "../time-controls/super-pill/SuperPill.svelte"; import { useTimeControlStore } from "../time-controls/time-control-store"; - import DimensionFilter from "./dimension-filters/DimensionFilter.svelte"; import FilterButton from "./FilterButton.svelte"; - import TimeGrainSelector from "../time-controls/TimeGrainSelector.svelte"; + import DimensionFilter from "./dimension-filters/DimensionFilter.svelte"; export let readOnly = false; @@ -46,6 +48,7 @@ measureFilters: { getMeasureFilterItems, getAllMeasureFilterItems }, pivot: { showPivot }, }, + dashboardStore, } = StateManagers; const timeControlsStore = useTimeControlStore(StateManagers); @@ -87,6 +90,8 @@ $: metricTimeSeries = useModelHasTimeSeries(instanceId, $metricsViewName); $: hasTimeSeries = $metricTimeSeries.data; + $: isComplexFilter = isExpressionUnsupported($dashboardStore.whereFilter); + function handleMeasureFilterApply( dimension: string, measureName: string, @@ -124,7 +129,9 @@ {/if}
- {#if !allDimensionFilters.length && !allMeasureFilters.length} + {#if isComplexFilter} + + {:else if !allDimensionFilters.length && !allMeasureFilters.length}
+ import Input from "@rilldata/web-common/components/forms/Input.svelte"; + import { + convertExpressionToFilterParam, + convertFilterParamToExpression, + stripParserError, + } from "@rilldata/web-common/features/dashboards/url-state/filters/converters"; + import type { V1Expression } from "@rilldata/web-common/runtime-client"; + import * as Tooltip from "@rilldata/web-common/components/tooltip-v2"; + import { InfoIcon } from "lucide-svelte"; + + export let filter: V1Expression; + export let onChange: (newFilter: V1Expression) => void; + + let filterText = convertExpressionToFilterParam(filter); + let error = ""; + + function handleFilterChange() { + try { + const newFilter = convertFilterParamToExpression(filterText); + if (newFilter) { + onChange(newFilter); + error = ""; + } + } catch (e) { + error = stripParserError(e); + } + } + + +
+ + {#if error} + + + + + + {error} + + + {/if} +
diff --git a/web-common/src/features/dashboards/filters/measure-filters/MeasureFilterMenu.svelte b/web-common/src/features/dashboards/filters/measure-filters/MeasureFilterMenu.svelte index 89a0f4b7cca..2ad734fd78a 100644 --- a/web-common/src/features/dashboards/filters/measure-filters/MeasureFilterMenu.svelte +++ b/web-common/src/features/dashboards/filters/measure-filters/MeasureFilterMenu.svelte @@ -123,6 +123,7 @@ errors={$errors["value1"]} id="value1" onBlur={handleSubmit} + onEnter={handleSubmit} placeholder={isBetweenExpression ? "Lower Value" : "Enter a Number"} /> {#if isBetweenExpression} @@ -132,6 +133,7 @@ id="value2" placeholder="Higher Value" onBlur={handleSubmit} + onEnter={handleSubmit} /> {/if} diff --git a/web-common/src/features/dashboards/filters/measure-filters/measure-filter-utils.ts b/web-common/src/features/dashboards/filters/measure-filters/measure-filter-utils.ts index 25c16b48de2..3753d55d232 100644 --- a/web-common/src/features/dashboards/filters/measure-filters/measure-filter-utils.ts +++ b/web-common/src/features/dashboards/filters/measure-filters/measure-filter-utils.ts @@ -7,6 +7,8 @@ import { createAndExpression, createSubQueryExpression, filterExpressions, + isExpressionUnsupported, + isJoinerExpression, } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import type { DimensionThresholdFilter, @@ -42,17 +44,24 @@ export function mergeDimensionAndMeasureFilter( * Measure filters will be sub-queries */ export function splitWhereFilter(whereFilter: V1Expression | undefined) { + if (whereFilter && isExpressionUnsupported(whereFilter)) { + return { dimensionFilters: whereFilter, dimensionThresholdFilters: [] }; + } + const dimensionFilters = createAndExpression([]); const dimensionThresholdFilters: DimensionThresholdFilter[] = []; whereFilter?.cond?.exprs?.filter((e) => { const subqueryExpr = e.cond?.exprs?.[1]; if (subqueryExpr?.subquery) { + const filters = isJoinerExpression(subqueryExpr.subquery.having) + ? (subqueryExpr.subquery.having?.cond?.exprs + ?.map(mapExprToMeasureFilter) + .filter(Boolean) as MeasureFilterEntry[]) + : [mapExprToMeasureFilter(subqueryExpr.subquery.having)]; + dimensionThresholdFilters.push({ name: subqueryExpr.subquery.dimension ?? "", - filters: - (subqueryExpr.subquery.having?.cond?.exprs - ?.map(mapExprToMeasureFilter) - .filter(Boolean) as MeasureFilterEntry[]) ?? [], + filters: filters.filter(Boolean) as MeasureFilterEntry[], }); return; } diff --git a/web-common/src/features/dashboards/leaderboard/Leaderboard.svelte b/web-common/src/features/dashboards/leaderboard/Leaderboard.svelte index 613c8f236dc..f933e822f6d 100644 --- a/web-common/src/features/dashboards/leaderboard/Leaderboard.svelte +++ b/web-common/src/features/dashboards/leaderboard/Leaderboard.svelte @@ -14,30 +14,31 @@ V1Operation, } from "@rilldata/web-common/runtime-client"; import { onMount } from "svelte"; + import { + cleanUpComparisonValue, + compareLeaderboardValues, + getSort, + type LeaderboardItemData, + prepareLeaderboardItemData, + } from "./leaderboard-utils"; + import type { DimensionThresholdFilter } from "../stores/metrics-explorer-entity"; + import { SortType } from "../proto-state/derived-types"; + import { + createAndExpression, + createOrExpression, + isExpressionUnsupported, + sanitiseExpression, + } from "../stores/filter-utils"; import { getComparisonRequestMeasures, getURIRequestMeasure, } from "../dashboard-utils"; import { mergeDimensionAndMeasureFilter } from "../filters/measure-filters/measure-filter-utils"; - import { SortType } from "../proto-state/derived-types"; import { additionalMeasures, getFiltersForOtherDimensions, } from "../selectors"; import { getIndependentMeasures } from "../state-managers/selectors/measures"; - import { - createAndExpression, - createOrExpression, - sanitiseExpression, - } from "../stores/filter-utils"; - import type { DimensionThresholdFilter } from "../stores/metrics-explorer-entity"; - import { - cleanUpComparisonValue, - compareLeaderboardValues, - getSort, - prepareLeaderboardItemData, - type LeaderboardItemData, - } from "./leaderboard-utils"; import { LEADERBOARD_DEFAULT_COLUMN_WIDTHS, type ColumnWidths, @@ -113,13 +114,16 @@ uri, } = dimension); - $: where = sanitiseExpression( - mergeDimensionAndMeasureFilter( - getFiltersForOtherDimensions(whereFilter, dimensionName), - dimensionThresholdFilters, - ), - undefined, - ); + $: isComplexFilter = isExpressionUnsupported(whereFilter); + $: where = isComplexFilter + ? whereFilter + : sanitiseExpression( + mergeDimensionAndMeasureFilter( + getFiltersForOtherDimensions(whereFilter, dimensionName), + dimensionThresholdFilters, + ), + undefined, + ); $: measures = getIndependentMeasures( metricsView, diff --git a/web-common/src/features/dashboards/proto-state/DashboardURLStateProvider.svelte b/web-common/src/features/dashboards/proto-state/DashboardURLStateProvider.svelte deleted file mode 100644 index 2e688ac315b..00000000000 --- a/web-common/src/features/dashboards/proto-state/DashboardURLStateProvider.svelte +++ /dev/null @@ -1,67 +0,0 @@ - - -{#if schemaError} - -{:else if timeRangeSummaryError} - -{:else if timeRangeSummaryIsNull} - -{:else if $dashboardStore} - -{/if} diff --git a/web-common/src/features/dashboards/proto-state/dashboard-url-state.spec.ts b/web-common/src/features/dashboards/proto-state/dashboard-url-state.spec.ts deleted file mode 100644 index b8aad0d3931..00000000000 --- a/web-common/src/features/dashboards/proto-state/dashboard-url-state.spec.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { DashboardFetchMocks } from "@rilldata/web-common/features/dashboards/dashboard-fetch-mocks"; -import { - useDashboardDefaultProto, - useDashboardUrlSync, -} from "@rilldata/web-common/features/dashboards/proto-state/dashboard-url-state"; -import { getProtoFromDashboardState } from "@rilldata/web-common/features/dashboards/proto-state/toProto"; -import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; -import { - AD_BIDS_BID_PRICE_MEASURE, - AD_BIDS_DEFAULT_URL_TIME_RANGE, - AD_BIDS_EXCLUDE_FILTER, - AD_BIDS_IMPRESSIONS_MEASURE, - AD_BIDS_METRICS_INIT, - AD_BIDS_METRICS_INIT_WITH_TIME, - AD_BIDS_NAME, - AD_BIDS_PUBLISHER_DIMENSION, - AD_BIDS_SCHEMA, - AD_BIDS_TIMESTAMP_DIMENSION, - AD_BIDS_METRICS_WITH_DELETED_MEASURE, - TestTimeConstants, - AD_BIDS_EXPLORE_INIT, - AD_BIDS_EXPLORE_NAME, - AD_BIDS_EXPLORE_WITH_DELETED_MEASURE, -} from "@rilldata/web-common/features/dashboards/stores/test-data/data"; -import DashboardTestComponent from "@rilldata/web-common/features/dashboards/stores/DashboardTestComponent.svelte"; -import { - createAndExpression, - createInExpression, -} from "@rilldata/web-common/features/dashboards/stores/filter-utils"; -import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; -import { - assertMetricsView, - createDashboardState, - initStateManagers, - resetDashboardStore, -} from "@rilldata/web-common/features/dashboards/stores/test-data/helpers"; -import { initLocalUserPreferenceStore } from "@rilldata/web-common/features/dashboards/user-preferences"; -import type { DashboardTimeControls } from "@rilldata/web-common/lib/time/types"; -import { waitUntil } from "@rilldata/web-common/lib/waitUtils"; -import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; -import type { Page } from "@sveltejs/kit"; -import { render } from "@testing-library/svelte"; -import { get, type Readable, writable } from "svelte/store"; -import { - beforeAll, - beforeEach, - describe, - expect, - it, - type MockInstance, - vi, -} from "vitest"; - -const pageMock: PageMock = vi.hoisted(() => ({}) as any); - -vi.mock("$app/navigation", () => { - return { - goto: (url) => pageMock.goto(url), - }; -}); -vi.mock("$app/stores", () => { - return { - page: pageMock, - }; -}); - -describe("useDashboardUrlSync", () => { - runtime.set({ - host: "http://localhost", - instanceId: "default", - }); - const dashboardFetchMocks = DashboardFetchMocks.useDashboardFetchMocks(); - - beforeAll(() => { - createPageMock(); - initLocalUserPreferenceStore(AD_BIDS_EXPLORE_NAME); - }); - - beforeEach(() => { - resetDashboardStore(); - pageMock.goto(`/explore/${AD_BIDS_EXPLORE_NAME}`); - pageMock.gotoSpy.mockClear(); - }); - - it("Changes to dashboard through interactions", async () => { - const { teardown, defaultProtoStore, stateManagers } = - await initDashboardUrlState(); - const { - actions: { - dimensionsFilter: { toggleDimensionValueSelection }, - }, - } = stateManagers; - - expect(pageMock.gotoSpy).toBeCalledTimes(0); - - toggleDimensionValueSelection(AD_BIDS_PUBLISHER_DIMENSION, "Google"); - await wait(); - assertUrlState( - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].proto!, - ); - const protoWithFilter = - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].proto!; - expect(pageMock.gotoSpy).toBeCalledTimes(1); - - pageMock.goto("/dashboard/AdBids"); - expect( - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].proto, - ).toEqual(get(defaultProtoStore).proto); - expect( - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].whereFilter, - ).toEqual(createAndExpression([])); - expect(pageMock.gotoSpy).toBeCalledTimes(2); - - pageMock.updateState(protoWithFilter); - await wait(); - assertUrlState( - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].proto!, - ); - expect( - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].whereFilter, - ).toEqual( - createAndExpression([ - createInExpression(AD_BIDS_PUBLISHER_DIMENSION, ["Google"]), - ]), - ); - expect(pageMock.gotoSpy).toBeCalledTimes(2); - - teardown(); - }); - - it("Changes to dashboard config", async () => { - const { teardown, queryClient } = await initDashboardUrlState(); - expect(pageMock.gotoSpy).toBeCalledTimes(0); - - dashboardFetchMocks.mockMetricsExplore( - AD_BIDS_EXPLORE_NAME, - { - ...AD_BIDS_METRICS_WITH_DELETED_MEASURE, - timeDimension: AD_BIDS_TIMESTAMP_DIMENSION, - }, - AD_BIDS_EXPLORE_WITH_DELETED_MEASURE, - ); - await queryClient.refetchQueries({ - type: "active", - }); - await wait(); - // Goto not called still since defaultProto has changed - expect(pageMock.gotoSpy).toBeCalledTimes(0); - expect(get(pageMock).url.searchParams.has("state")).toBeFalsy(); - // This is not updated since the sync is called in a component - // TODO: We should add tests for the sync component - expect([ - ...get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME] - .visibleMeasureKeys, - ]).toEqual([AD_BIDS_IMPRESSIONS_MEASURE, AD_BIDS_BID_PRICE_MEASURE]); - - teardown(); - }); - - it("Init load from url", async () => { - gotoDashboardState( - createDashboardState( - AD_BIDS_EXPLORE_NAME, - AD_BIDS_METRICS_INIT, - AD_BIDS_EXPLORE_INIT, - AD_BIDS_EXCLUDE_FILTER, - ), - ); - const { teardown } = await initDashboardUrlState(); - - assertUrlState( - get(metricsExplorerStore).entities[AD_BIDS_EXPLORE_NAME].proto!, - ); - assertMetricsView( - AD_BIDS_EXPLORE_NAME, - AD_BIDS_EXCLUDE_FILTER, - AD_BIDS_DEFAULT_URL_TIME_RANGE as DashboardTimeControls, - ); - - teardown(); - }); - - async function initDashboardUrlState() { - dashboardFetchMocks.mockMetricsExplore( - AD_BIDS_EXPLORE_NAME, - AD_BIDS_METRICS_INIT_WITH_TIME, - AD_BIDS_EXPLORE_INIT, - ); - const { queryClient, stateManagers } = initStateManagers(); - dashboardFetchMocks.mockTimeRangeSummary(AD_BIDS_NAME, { - min: TestTimeConstants.LAST_DAY.toISOString(), - max: TestTimeConstants.NOW.toISOString(), - }); - - const { unmount } = render(DashboardTestComponent, { - ctx: stateManagers, - }); - - const defaultProtoStore = useDashboardDefaultProto(stateManagers); - await waitUntil(() => !get(defaultProtoStore).isFetching, 1000, 5); - - const unsubscribe = useDashboardUrlSync(stateManagers, AD_BIDS_SCHEMA); - await wait(); - - return { - teardown: () => { - unmount(); - unsubscribe(); - }, - stateManagers, - queryClient, - defaultProtoStore, - }; - } -}); - -type PageMock = Readable & { - updateState: (state: string) => void; - goto: (path: string) => void; - gotoSpy: MockInstance; -}; -function createPageMock() { - const { update, subscribe } = writable({ - url: new URL("http://localhost/explore/AdBids_explore"), - params: { name: "AdBids_explore" }, - } as any); - - pageMock.subscribe = subscribe; - pageMock.updateState = (state: string) => { - update((page) => { - if (state) { - page.url = new URL( - `http://localhost/explore/AdBids_explore?state=${encodeURIComponent( - state, - )}`, - ); - } else { - page.url = new URL("http://localhost/explore/AdBids_explore"); - } - return page; - }); - }; - pageMock.goto = (path: string) => { - update((page) => { - page.url = new URL(`http://localhost${path}`); - return page; - }); - }; - pageMock.gotoSpy = vi.spyOn(pageMock, "goto"); -} - -function assertUrlState(expected: string) { - const actual = decodeURIComponent( - get(pageMock).url.searchParams.get("state")!, - ); - expect(actual).toEqual(expected); -} - -function wait() { - return new Promise((resolve) => setTimeout(resolve, 10)); -} - -function gotoDashboardState(state: MetricsExplorerEntity) { - pageMock.goto( - `/dashboard/${state.name}?state=${encodeURIComponent( - getProtoFromDashboardState(state), - )}`, - ); -} diff --git a/web-common/src/features/dashboards/proto-state/dashboard-url-state.ts b/web-common/src/features/dashboards/proto-state/dashboard-url-state.ts deleted file mode 100644 index ab609efb626..00000000000 --- a/web-common/src/features/dashboards/proto-state/dashboard-url-state.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { goto } from "$app/navigation"; -import { page } from "$app/stores"; -import { getProtoFromDashboardState } from "@rilldata/web-common/features/dashboards/proto-state/toProto"; -import { createTimeRangeSummary } from "@rilldata/web-common/features/dashboards/selectors/index"; -import type { StateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers"; -import { getDefaultMetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; -import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; -import { getUrlForPath } from "@rilldata/web-common/lib/url-utils"; -import type { V1StructType } from "@rilldata/web-common/runtime-client"; -import { type Readable, derived, get } from "svelte/store"; - -export type DashboardUrlState = { - isReady: boolean; - proto?: string; - defaultProto?: string; - urlName?: string; - urlProto?: string; - isPublicUrl?: boolean; -}; -export type DashboardUrlStore = Readable; - -/** - * Creates a derived store that has the current proto and default proto of a dashboard along with the proto in the url. - */ -export function useDashboardUrlState(ctx: StateManagers): DashboardUrlStore { - return derived( - [useDashboardProto(ctx), useDashboardDefaultProto(ctx), page], - ([proto, defaultProtoState, page], set) => { - if (defaultProtoState.isFetching) { - set({ isReady: false }); - return; - } - - const defaultProto = defaultProtoState.proto; - const urlProto = page.url.searchParams.get("state"); - const decodedUrlProto = urlProto - ? decodeURIComponent(urlProto) - : defaultProto; - - const urlName = getMetricsViewNameFromParams(page.params); - set({ - isReady: true, - proto, - defaultProto, - urlName, - urlProto: decodedUrlProto, - isPublicUrl: !urlName, - }); - }, - ); -} - -/** - * Code that looks at dashboard state and url state and decides which one to sync with. - * This depends on the fact that the same dashboard state results in the same proto and vice-versa. - * - * Case 1 - * 1. The dashboard state changes due to user interactions. - * 2. Proto in the state is updated to match the new state. - * 3. `lastKnownProto` is now different from the proto in state. - * 4. This triggers a goto to the url with the correct proto. - * 5. After navigation `urlProto` changes. Since this will be equal to `lastKnownProto` there will be no more operations. - * - * Case 2 - * 1. The url is changed by using the back button (or any other way). - * 2. `urlProto` changes to reflect the one in the new url. - * 3. `lastKnownProto` is now different to the `urlProto`. - * 4. This triggers a sync of state in the url to the dashboard store. - * 5. After updating the store proto in the state will be the same as `lastKnownProto`. No navigations happen. - */ -export function useDashboardUrlSync(ctx: StateManagers, schema: V1StructType) { - const dashboardUrlState = useDashboardUrlState(ctx); - - let lastKnownProto = get(dashboardUrlState)?.defaultProto; - return dashboardUrlState.subscribe((state) => { - const exploreName = get(ctx.exploreName); - - // Avoid a race condition when switching between metrics views - // (It's not necessary for Public URLs because there's no UI flow for switching from one Public URL to another) - if ( - !state.isPublicUrl && - state?.urlName?.toLowerCase() !== exploreName.toLowerCase() - ) - return; - - if (!state.isReady || !state.proto) return; - - if (state.proto !== lastKnownProto) { - // changed when filters etc are changed on the dashboard - gotoNewDashboardUrl(get(page).url, state.proto, state.defaultProto!); - - lastKnownProto = state.proto; - } else if (state.urlProto !== lastKnownProto) { - // changed when user updated the url manually - metricsExplorerStore.syncFromUrl( - exploreName, - state.urlProto!, - get(ctx.validSpecStore).data?.metricsView ?? {}, - get(ctx.validSpecStore).data?.explore ?? {}, - schema, - ); - lastKnownProto = state.urlProto; - } - }); -} - -function gotoNewDashboardUrl(url: URL, newState: string, defaultState: string) { - // this store the actual state. for default state it will be empty - let newStateInUrl = ""; - // changed when filters etc are changed on the dashboard - - const newUrl = getUrlForPath(url.pathname, ["features", "theme"]); - - if (newState !== defaultState) { - newStateInUrl = newState; - newUrl.searchParams.set("state", newStateInUrl); - } - - const currentStateInUrl = url.searchParams.get("state") ?? ""; - - if (newStateInUrl === currentStateInUrl) return; - goto(newUrl.toString()); -} - -/** - * Pulls data from dashboard to create the url state. - * Any subsections in the future would be added here to build the final url state. - */ -export function useDashboardProto(ctx: StateManagers) { - return derived([ctx.dashboardStore], ([dashboard]) => - getProtoFromDashboardState(dashboard), - ); -} - -// NOTE: the data here can be stale when metricsViewName changes in ctx, along with the metricsView. -// but the time range summary is yet to be triggered to change causing it to have data from previous active dashboard -// Above issue is currently fixed in useDashboardUrlSync and DashboardURLStateProvider by create a new instance when the url is changed. -// TODO: we need to update the architecture to perhaps recreate all derived stores when the metricsViewName changes -export function useDashboardDefaultProto(ctx: StateManagers) { - return derived( - [ctx.validSpecStore, createTimeRangeSummary(ctx)], - ([validSpec, timeRangeSummary]) => { - const hasTimeSeries = Boolean(validSpec.data?.metricsView?.timeDimension); - if ( - !validSpec.data?.metricsView || - !validSpec.data?.explore || - (hasTimeSeries && !timeRangeSummary.data) - ) - return { - isFetching: true, - proto: "", - }; - - const metricsExplorer = getDefaultMetricsExplorerEntity( - get(ctx.metricsViewName), - validSpec.data.metricsView, - validSpec.data.explore, - timeRangeSummary.data, - ); - return { - isFetching: false, - proto: getProtoFromDashboardState(metricsExplorer), - }; - }, - ); -} -/** - * We have different ways of getting the metrics view name, depending on the context: - * - The `dashboard` URL param is used in Cloud - * - The `name` URL param is used in Ril Developer - * - The `token` URL param is used in Public URLs. The metrics view name is embedded in the token. - */ -function getMetricsViewNameFromParams( - params: Record, -): string | undefined { - const { dashboard, name } = params; - - if (dashboard) return dashboard; - if (name) return name; - // TODO: Add support for public urls' `token` param - - return undefined; -} diff --git a/web-common/src/features/dashboards/proto-state/fromProto.ts b/web-common/src/features/dashboards/proto-state/fromProto.ts index f49a164ea93..3084b27fb22 100644 --- a/web-common/src/features/dashboards/proto-state/fromProto.ts +++ b/web-common/src/features/dashboards/proto-state/fromProto.ts @@ -134,7 +134,9 @@ export function getDashboardStateFromProto( dashboard.compareTimeRange, ); // backwards compatibility - correctComparisonTimeRange(entity.selectedComparisonTimeRange); + entity.selectedComparisonTimeRange.name = correctComparisonTimeRange( + entity.selectedComparisonTimeRange.name as string, + ) as TimeComparisonOption; } if (dashboard.showTimeComparison !== undefined) { entity.showTimeComparison = Boolean(dashboard.showTimeComparison); @@ -166,7 +168,7 @@ export function getDashboardStateFromProto( if (dashboard.comparisonDimension) { entity.selectedComparisonDimension = dashboard.comparisonDimension; } else { - entity.selectedComparisonDimension = undefined; + entity.selectedComparisonDimension = ""; } if (dashboard.expandedMeasure) { entity.tdd = { @@ -223,7 +225,9 @@ export function base64ToProto(message: string) { return protoBase64.dec(message); } -function fromExpressionProto(expression: Expression): V1Expression | undefined { +export function fromExpressionProto( + expression: Expression, +): V1Expression | undefined { switch (expression.expression.case) { case "ident": return { @@ -422,29 +426,22 @@ function fromPivotProto( }; } -function correctComparisonTimeRange( - comparisonTimeRange: DashboardTimeControls, -) { - switch (comparisonTimeRange.name as string) { +export function correctComparisonTimeRange(name: string) { + switch (name) { case "CONTIGUOUS": - comparisonTimeRange.name = TimeComparisonOption.CONTIGUOUS; - break; + return TimeComparisonOption.CONTIGUOUS; case "P1D": - comparisonTimeRange.name = TimeComparisonOption.DAY; - break; + return TimeComparisonOption.DAY; case "P1W": - comparisonTimeRange.name = TimeComparisonOption.WEEK; - break; + return TimeComparisonOption.WEEK; case "P1M": - comparisonTimeRange.name = TimeComparisonOption.MONTH; - break; + return TimeComparisonOption.MONTH; case "P3M": - comparisonTimeRange.name = TimeComparisonOption.QUARTER; - break; + return TimeComparisonOption.QUARTER; case "P1Y": - comparisonTimeRange.name = TimeComparisonOption.YEAR; - break; + return TimeComparisonOption.YEAR; } + return name; } function chartTypeMap(chartType: string | undefined): TDDChart { @@ -474,7 +471,7 @@ function fromActivePageProto( } else if (dashboard.expandedMeasure) { return { activePage: DashboardState_ActivePage.TIME_DIMENSIONAL_DETAIL, - selectedDimensionName: undefined, + selectedDimensionName: "", }; } // return empty so that nothing is overridden @@ -486,7 +483,7 @@ function fromActivePageProto( case DashboardState_ActivePage.TIME_DIMENSIONAL_DETAIL: return { activePage: dashboard.activePage, - selectedDimensionName: undefined, + selectedDimensionName: "", }; case DashboardState_ActivePage.DIMENSION_TABLE: diff --git a/web-common/src/features/dashboards/proto-state/proto.spec.ts b/web-common/src/features/dashboards/proto-state/proto.spec.ts index e99c97c4dce..e8afc3f26e6 100644 --- a/web-common/src/features/dashboards/proto-state/proto.spec.ts +++ b/web-common/src/features/dashboards/proto-state/proto.spec.ts @@ -1,22 +1,22 @@ import { protoBase64, Value } from "@bufbuild/protobuf"; import { getDashboardStateFromUrl } from "@rilldata/web-common/features/dashboards/proto-state/fromProto"; import { getProtoFromDashboardState } from "@rilldata/web-common/features/dashboards/proto-state/toProto"; -import { getDefaultMetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; +import { getDefaultExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; import { + createAndExpression, + createInExpression, +} from "@rilldata/web-common/features/dashboards/stores/filter-utils"; +import { + AD_BIDS_EXPLORE_INIT, + AD_BIDS_EXPLORE_WITH_BOOL_DIMENSION, AD_BIDS_METRICS_INIT_WITH_TIME, + AD_BIDS_METRICS_WITH_BOOL_DIMENSION, AD_BIDS_NAME, AD_BIDS_PUBLISHER_DIMENSION, AD_BIDS_PUBLISHER_IS_NULL_DOMAIN, AD_BIDS_SCHEMA, - AD_BIDS_METRICS_WITH_BOOL_DIMENSION, TestTimeConstants, - AD_BIDS_EXPLORE_INIT, - AD_BIDS_EXPLORE_WITH_BOOL_DIMENSION, } from "@rilldata/web-common/features/dashboards/stores/test-data/data"; -import { - createAndExpression, - createInExpression, -} from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import { getLocalUserPreferences, initLocalUserPreferenceStore, @@ -39,7 +39,7 @@ describe("toProto/fromProto", () => { }); it("backwards compatibility for time controls", () => { - const metricsExplorer = getDefaultMetricsExplorerEntity( + const metricsExplorer = getDefaultExploreState( AD_BIDS_NAME, AD_BIDS_METRICS_INIT_WITH_TIME, AD_BIDS_EXPLORE_INIT, diff --git a/web-common/src/features/dashboards/proto-state/sparse-proto.spec.ts b/web-common/src/features/dashboards/proto-state/sparse-proto.spec.ts index 087c5054d6d..45bc03e7ee4 100644 --- a/web-common/src/features/dashboards/proto-state/sparse-proto.spec.ts +++ b/web-common/src/features/dashboards/proto-state/sparse-proto.spec.ts @@ -1,6 +1,7 @@ import { getProtoFromDashboardState } from "@rilldata/web-common/features/dashboards/proto-state/toProto"; -import { getDefaultMetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; +import { getDefaultExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; +import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; import { AD_BIDS_EXPLORE_INIT, AD_BIDS_EXPLORE_NAME, @@ -9,32 +10,31 @@ import { AD_BIDS_TIME_RANGE_SUMMARY, } from "@rilldata/web-common/features/dashboards/stores/test-data/data"; import { - AD_BIDS_APPLY_PUB_DIMENSION_FILTER, + getPartialDashboard, + resetDashboardStore, +} from "@rilldata/web-common/features/dashboards/stores/test-data/helpers"; +import { + AD_BIDS_APPLY_BP_MEASURE_FILTER, + AD_BIDS_APPLY_DOM_DIMENSION_FILTER, AD_BIDS_APPLY_IMP_MEASURE_FILTER, + AD_BIDS_APPLY_PUB_DIMENSION_FILTER, + AD_BIDS_OPEN_BP_TDD, + AD_BIDS_OPEN_DOM_BP_PIVOT, + AD_BIDS_OPEN_DOM_DIMENSION_TABLE, + AD_BIDS_OPEN_IMP_TDD, AD_BIDS_OPEN_PUB_DIMENSION_TABLE, AD_BIDS_OPEN_PUB_IMP_PIVOT, - AD_BIDS_OPEN_IMP_TDD, + AD_BIDS_REMOVE_IMP_MEASURE_FILTER, + AD_BIDS_REMOVE_PUB_DIMENSION_FILTER, + AD_BIDS_SET_P4W_TIME_RANGE_FILTER, AD_BIDS_SET_P7D_TIME_RANGE_FILTER, applyMutationsToDashboard, type TestDashboardMutation, - AD_BIDS_APPLY_DOM_DIMENSION_FILTER, - AD_BIDS_APPLY_BP_MEASURE_FILTER, - AD_BIDS_SET_P4W_TIME_RANGE_FILTER, - AD_BIDS_OPEN_DOM_DIMENSION_TABLE, - AD_BIDS_OPEN_BP_TDD, - AD_BIDS_OPEN_DOM_BP_PIVOT, - AD_BIDS_REMOVE_PUB_DIMENSION_FILTER, - AD_BIDS_REMOVE_IMP_MEASURE_FILTER, } from "@rilldata/web-common/features/dashboards/stores/test-data/store-mutations"; -import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; -import { - getPartialDashboard, - resetDashboardStore, -} from "@rilldata/web-common/features/dashboards/stores/test-data/helpers"; import { initLocalUserPreferenceStore } from "@rilldata/web-common/features/dashboards/user-preferences"; import { deepClone } from "@vitest/utils"; import { get } from "svelte/store"; -import { beforeAll, it, describe, beforeEach, expect } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it } from "vitest"; const TestCases: { title: string; @@ -94,7 +94,7 @@ describe("sparse proto", () => { describe("should reset dashboard store", () => { for (const { title, mutations } of TestCases) { it(`from ${title}`, () => { - const dashboard = getDefaultMetricsExplorerEntity( + const dashboard = getDefaultExploreState( AD_BIDS_EXPLORE_NAME, AD_BIDS_METRICS_INIT, AD_BIDS_EXPLORE_INIT, diff --git a/web-common/src/features/dashboards/rows-viewer/RowsViewer.svelte b/web-common/src/features/dashboards/rows-viewer/RowsViewer.svelte index c6ff0b5b2ff..31451929244 100644 --- a/web-common/src/features/dashboards/rows-viewer/RowsViewer.svelte +++ b/web-common/src/features/dashboards/rows-viewer/RowsViewer.svelte @@ -9,7 +9,7 @@ } from "@rilldata/web-common/runtime-client"; import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import { writable } from "svelte/store"; - import { useExploreStore } from "web-common/src/features/dashboards/stores/dashboard-stores"; + import { useExploreState } from "web-common/src/features/dashboards/stores/dashboard-stores"; import { PreviewTable } from "../../../components/preview-table"; import ReconcilingSpinner from "../../entity-management/ReconcilingSpinner.svelte"; @@ -22,7 +22,7 @@ const SAMPLE_SIZE = 10000; const FALLBACK_SAMPLE_SIZE = 1000; - $: exploreStore = useExploreStore(exploreName); + $: exploreState = useExploreState(exploreName); const timeControlsStore = useTimeControlStore(getStateManagers()); let limit = writable(SAMPLE_SIZE); @@ -38,7 +38,7 @@ }, { query: { - enabled: $timeControlsStore.ready && !!$exploreStore?.whereFilter, + enabled: $timeControlsStore.ready && !!$exploreState?.whereFilter, }, }, ); diff --git a/web-common/src/features/dashboards/rows-viewer/RowsViewerAccordion.svelte b/web-common/src/features/dashboards/rows-viewer/RowsViewerAccordion.svelte index f4a36be7e3d..c5953e13187 100644 --- a/web-common/src/features/dashboards/rows-viewer/RowsViewerAccordion.svelte +++ b/web-common/src/features/dashboards/rows-viewer/RowsViewerAccordion.svelte @@ -9,16 +9,16 @@ import type { TimeRangeString } from "@rilldata/web-common/lib/time/types"; import { V1ExportFormat, - type V1Expression, - type V1MetricsViewAggregationResponseDataItem, createQueryServiceExport, createQueryServiceMetricsViewAggregation, + type V1Expression, + type V1MetricsViewAggregationResponseDataItem, } from "@rilldata/web-common/runtime-client"; import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; - import { useExploreStore } from "web-common/src/features/dashboards/stores/dashboard-stores"; + import { useExploreState } from "web-common/src/features/dashboards/stores/dashboard-stores"; + import ExportMenu from "../../exports/ExportMenu.svelte"; import { featureFlags } from "../../feature-flags"; import RowsViewer from "./RowsViewer.svelte"; - import ExportMenu from "../../exports/ExportMenu.svelte"; import exportMetrics from "./export-metrics"; const exportDash = createQueryServiceExport(); @@ -44,9 +44,9 @@ const stateManagers = getStateManagers(); - $: exploreStore = useExploreStore(exploreName); + $: exploreState = useExploreState(exploreName); $: pivotDataStore = usePivotDataStore(stateManagers); - $: showPivot = $exploreStore.pivot.active; + $: showPivot = $exploreState.pivot.active; $: activeCellFilters = $pivotDataStore.activeCellFilters; let filters: V1Expression | undefined; @@ -68,7 +68,7 @@ if (maybeEnd) { timeRange.end = new Date(new Date(maybeEnd).valueOf() + 1).toISOString(); } - filters = sanitiseExpression($exploreStore.whereFilter, undefined); + filters = sanitiseExpression($exploreState.whereFilter, undefined); label = DEFAULT_LABEL; } @@ -92,7 +92,7 @@ where: filters, }, ], - enabled: $timeControlsStore.ready && !!$exploreStore?.whereFilter, + enabled: $timeControlsStore.ready && !!$exploreState?.whereFilter, }, }, ); diff --git a/web-common/src/features/dashboards/selectors.ts b/web-common/src/features/dashboards/selectors.ts index fd088216ef3..3444b1f69d8 100644 --- a/web-common/src/features/dashboards/selectors.ts +++ b/web-common/src/features/dashboards/selectors.ts @@ -8,6 +8,7 @@ import { useFilteredResources, useResource, } from "@rilldata/web-common/features/entity-management/resource-selectors"; +import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient"; import type { RpcStatus, V1Expression, @@ -124,6 +125,7 @@ export function useMetricsViewTimeRange( query: { ...queryOptions, enabled: !!metricsView.data?.timeDimension && queryOptions?.enabled, + queryClient, }, }, ).subscribe(set), diff --git a/web-common/src/features/dashboards/state-managers/StateManagersProvider.svelte b/web-common/src/features/dashboards/state-managers/StateManagersProvider.svelte index 69d1790ef6e..2fe6884fe3c 100644 --- a/web-common/src/features/dashboards/state-managers/StateManagersProvider.svelte +++ b/web-common/src/features/dashboards/state-managers/StateManagersProvider.svelte @@ -8,8 +8,8 @@ export let exploreName: string; export let visualEditing = false; - $: orgName = $page.params.organization; - $: projectName = $page.params.project; + const orgName = $page.params.organization; + const projectName = $page.params.project; const queryClient = useQueryClient(); const stateManagers = createStateManagers({ diff --git a/web-common/src/features/dashboards/state-managers/actions/dimension-filters.ts b/web-common/src/features/dashboards/state-managers/actions/dimension-filters.ts index da2176a70fa..054e748cca5 100644 --- a/web-common/src/features/dashboards/state-managers/actions/dimension-filters.ts +++ b/web-common/src/features/dashboards/state-managers/actions/dimension-filters.ts @@ -1,3 +1,4 @@ +import { splitWhereFilter } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-utils"; import { createInExpression, getValueIndexInExpression, @@ -156,6 +157,16 @@ export function deselectItemsInFilter( } } +export function setFilters( + { dashboard }: DashboardMutables, + filter: V1Expression, +) { + const { dimensionFilters, dimensionThresholdFilters } = + splitWhereFilter(filter); + dashboard.whereFilter = dimensionFilters; + dashboard.dimensionThresholdFilters = dimensionThresholdFilters; +} + export const dimensionFilterActions = { /** * Toggles whether the given dimension value is selected in the @@ -170,4 +181,5 @@ export const dimensionFilterActions = { removeDimensionFilter, selectItemsInFilter, deselectItemsInFilter, + setFilters, }; diff --git a/web-common/src/features/dashboards/state-managers/actions/filters.ts b/web-common/src/features/dashboards/state-managers/actions/filters.ts index f55769b1f56..32749c48449 100644 --- a/web-common/src/features/dashboards/state-managers/actions/filters.ts +++ b/web-common/src/features/dashboards/state-managers/actions/filters.ts @@ -4,14 +4,12 @@ import { createAndExpression } from "@rilldata/web-common/features/dashboards/st export function clearAllFilters({ dashboard }: DashboardMutables) { const hasFilters = dashboard.whereFilter.cond?.exprs?.length || - dashboard.havingFilter.cond?.exprs?.length || dashboard.dimensionThresholdFilters?.length; if (!hasFilters) { return; } dashboard.whereFilter = createAndExpression([]); - dashboard.havingFilter = createAndExpression([]); dashboard.dimensionThresholdFilters = []; dashboard.temporaryFilterName = null; dashboard.dimensionFilterExcludeMode.clear(); diff --git a/web-common/src/features/dashboards/state-managers/actions/sorting.ts b/web-common/src/features/dashboards/state-managers/actions/sorting.ts index 057cd81eb44..9ca7c278a2d 100644 --- a/web-common/src/features/dashboards/state-managers/actions/sorting.ts +++ b/web-common/src/features/dashboards/state-managers/actions/sorting.ts @@ -37,6 +37,14 @@ export const toggleSortByActiveContextColumn = (args: DashboardMutables) => { toggleSort(args, contextColumnSortType); }; +export const setSortDescending = ({ + dashboard, + persistentDashboardStore, +}: DashboardMutables) => { + dashboard.sortDirection = SortDirection.DESCENDING; + persistentDashboardStore.updateSortDirection(dashboard.sortDirection); +}; + export const sortActions = { /** * Sets the sort type for the dashboard (value, percent, delta, etc.) @@ -58,11 +66,5 @@ export const sortActions = { /** * Sets the sort direction to descending. */ - setSortDescending: ({ - dashboard, - persistentDashboardStore, - }: DashboardMutables) => { - dashboard.sortDirection = SortDirection.DESCENDING; - persistentDashboardStore.updateSortDirection(dashboard.sortDirection); - }, + setSortDescending, }; diff --git a/web-common/src/features/dashboards/state-managers/selectors/dimension-filters.ts b/web-common/src/features/dashboards/state-managers/selectors/dimension-filters.ts index ab53b79055f..4a409f38a40 100644 --- a/web-common/src/features/dashboards/state-managers/selectors/dimension-filters.ts +++ b/web-common/src/features/dashboards/state-managers/selectors/dimension-filters.ts @@ -3,6 +3,7 @@ import { filterItemsSortFunction } from "@rilldata/web-common/features/dashboard import { forEachIdentifier, getValuesInExpression, + isExpressionUnsupported, matchExpressionByName, } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import type { @@ -17,6 +18,9 @@ export const selectedDimensionValues = ( dashData: AtLeast, ): ((dimName: string) => string[]) => { return (dimName: string) => { + // if it is a complex filter unsupported by UI then no values are selected + if (isExpressionUnsupported(dashData.dashboard.whereFilter)) return []; + // FIXME: it is possible for this way of accessing the filters // to return the same value twice, which would seem to indicate // a bug in the way we're setting the filters / active values. diff --git a/web-common/src/features/dashboards/state-managers/state-managers.ts b/web-common/src/features/dashboards/state-managers/state-managers.ts index fa6e38fee59..5b56aed69d6 100644 --- a/web-common/src/features/dashboards/state-managers/state-managers.ts +++ b/web-common/src/features/dashboards/state-managers/state-managers.ts @@ -1,20 +1,27 @@ import { - contextColWidthDefaults, type ContextColWidths, type MetricsExplorerEntity, + contextColWidthDefaults, } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; import { getPersistentDashboardStore, initPersistentDashboardStore, } from "@rilldata/web-common/features/dashboards/stores/persistent-dashboard-state"; +import { updateExploreSessionStore } from "@rilldata/web-common/features/dashboards/url-state/explore-web-view-store"; +import { getDefaultExplorePreset } from "@rilldata/web-common/features/dashboards/url-state/getDefaultExplorePreset"; +import { + getLocalUserPreferencesState, + initLocalUserPreferenceStore, +} from "@rilldata/web-common/features/dashboards/user-preferences"; import { type ExploreValidSpecResponse, useExploreValidSpec, } from "@rilldata/web-common/features/explores/selectors"; import { + type RpcStatus, + type V1ExplorePreset, type V1MetricsViewTimeRangeResponse, createQueryServiceMetricsViewTimeRange, - type RpcStatus, } from "@rilldata/web-common/runtime-client"; import type { Runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; @@ -31,9 +38,9 @@ import { type MetricsExplorerStoreType, metricsExplorerStore, updateMetricsExplorerByName, - useExploreStore, + useExploreState, } from "web-common/src/features/dashboards/stores/dashboard-stores"; -import { createStateManagerActions, type StateManagerActions } from "./actions"; +import { type StateManagerActions, createStateManagerActions } from "./actions"; import type { DashboardCallbackExecutor } from "./actions/types"; import { type StateManagerReadables, @@ -69,6 +76,7 @@ export type StateManagers = { * it's a one-off solution that introduces another new pattern. */ contextColumnWidths: Writable; + defaultExploreState: Readable; }; export const DEFAULT_STORE_KEY = Symbol("state-managers"); @@ -94,8 +102,8 @@ export function createStateManagers({ const dashboardStore: Readable = derived( [exploreNameStore], ([name], set) => { - const store = useExploreStore(name); - return store.subscribe(set); + const exploreState = useExploreState(name); + return exploreState.subscribe(set); }, ); @@ -137,8 +145,33 @@ export function createStateManagers({ contextColWidthDefaults, ); + const defaultExploreState = derived( + [validSpecStore, timeRangeSummaryStore], + ([validSpec, timeRangeSummary]) => { + if (!validSpec.data?.explore) { + return {}; + } + return getDefaultExplorePreset( + validSpec.data?.explore ?? {}, + getLocalUserPreferencesState(exploreName), + timeRangeSummary.data, + ); + }, + ); + dashboardStore.subscribe((dashState) => { + const exploreState = get(validSpecStore).data?.explore; + if (!dashState || !exploreState) return; + updateExploreSessionStore( + exploreName, + extraKeyPrefix, + dashState, + exploreState, + ); + }); + // TODO: once we move everything from dashboard-stores to here, we can get rid of the global initPersistentDashboardStore((extraKeyPrefix || "") + exploreName); + initLocalUserPreferenceStore(exploreName); const persistentDashboardStore = getPersistentDashboardStore(); return { @@ -169,5 +202,6 @@ export function createStateManagers({ persistentDashboardStore, }), contextColumnWidths, + defaultExploreState, }; } diff --git a/web-common/src/features/dashboards/stores/AdvancedMeasureCorrector.spec.ts b/web-common/src/features/dashboards/stores/AdvancedMeasureCorrector.spec.ts index 892441d33d1..566c8273cb9 100644 --- a/web-common/src/features/dashboards/stores/AdvancedMeasureCorrector.spec.ts +++ b/web-common/src/features/dashboards/stores/AdvancedMeasureCorrector.spec.ts @@ -3,7 +3,14 @@ import { MeasureFilterType, } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-options"; import { AdvancedMeasureCorrector } from "@rilldata/web-common/features/dashboards/stores/AdvancedMeasureCorrector"; -import { getDefaultMetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; +import { getDefaultExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; +import type { DashboardTimeControls } from "@rilldata/web-common/lib/time/types"; +import { + V1TimeGrain, + type V1ExploreSpec, + type V1MetricsViewSpec, +} from "@rilldata/web-common/runtime-client"; +import { describe, expect, it } from "vitest"; import { AD_BIDS_ADVANCED_MEASURES, AD_BIDS_EXPLORE_INIT, @@ -15,13 +22,6 @@ import { AD_BIDS_PUBLISHER_DIMENSION, AD_BIDS_TIMESTAMP_DIMENSION, } from "./test-data/data"; -import type { DashboardTimeControls } from "@rilldata/web-common/lib/time/types"; -import { - type V1MetricsViewSpec, - V1TimeGrain, - type V1ExploreSpec, -} from "@rilldata/web-common/runtime-client"; -import { describe, expect, it } from "vitest"; describe("AdvancedMeasureCorrector", () => { const MetricsView = { @@ -34,7 +34,7 @@ describe("AdvancedMeasureCorrector", () => { } as V1ExploreSpec; it("changing grain while in TDD for measure based on timestamp", () => { - const dashboard = getDefaultMetricsExplorerEntity( + const dashboard = getDefaultExploreState( "AdBids", MetricsView, Explore, @@ -71,7 +71,7 @@ describe("AdvancedMeasureCorrector", () => { }); it("metrics view spec changed converting a measure to an advanced measure", () => { - const dashboard = getDefaultMetricsExplorerEntity( + const dashboard = getDefaultExploreState( "AdBids", MetricsView, Explore, diff --git a/web-common/src/features/dashboards/stores/dashboard-store-defaults.ts b/web-common/src/features/dashboards/stores/dashboard-store-defaults.ts index 088b76dae5e..4fb751bfa60 100644 --- a/web-common/src/features/dashboards/stores/dashboard-store-defaults.ts +++ b/web-common/src/features/dashboards/stores/dashboard-store-defaults.ts @@ -1,212 +1,52 @@ import { LeaderboardContextColumn } from "@rilldata/web-common/features/dashboards/leaderboard-context-column"; -import { - SortDirection, - SortType, -} from "@rilldata/web-common/features/dashboards/proto-state/derived-types"; -import { createAndExpression } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import { contextColWidthDefaults, type MetricsExplorerEntity, } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; import { getPersistentDashboardState } from "@rilldata/web-common/features/dashboards/stores/persistent-dashboard-state"; -import { TDDChart } from "@rilldata/web-common/features/dashboards/time-dimension-details/types"; -import { getLocalUserPreferences } from "@rilldata/web-common/features/dashboards/user-preferences"; -import { getTimeComparisonParametersForComponent } from "@rilldata/web-common/lib/time/comparisons"; -import { DEFAULT_TIME_RANGES } from "@rilldata/web-common/lib/time/config"; -import { getDefaultTimeGrain } from "@rilldata/web-common/lib/time/grains"; -import { ISODurationToTimePreset } from "@rilldata/web-common/lib/time/ranges"; -import { isoDurationToFullTimeRange } from "@rilldata/web-common/lib/time/ranges/iso-ranges"; -import type { TimeComparisonOption } from "@rilldata/web-common/lib/time/types"; -import { DashboardState_ActivePage } from "@rilldata/web-common/proto/gen/rill/ui/v1/dashboard_pb"; +import { convertPresetToExploreState } from "@rilldata/web-common/features/dashboards/url-state/convertPresetToExploreState"; +import { getDefaultExplorePreset } from "@rilldata/web-common/features/dashboards/url-state/getDefaultExplorePreset"; +import { getLocalUserPreferencesState } from "@rilldata/web-common/features/dashboards/user-preferences"; import type { - MetricsViewSpecDimensionV2, - MetricsViewSpecMeasureV2, - V1ExplorePreset, V1ExploreSpec, V1MetricsViewSpec, V1MetricsViewTimeRangeResponse, } from "@rilldata/web-common/runtime-client"; -import { V1ExploreComparisonMode } from "@rilldata/web-common/runtime-client"; -import { get } from "svelte/store"; - -export function setDefaultTimeRange( - explorePreset: V1ExplorePreset | undefined, - metricsExplorer: MetricsExplorerEntity, - fullTimeRange: V1MetricsViewTimeRangeResponse | undefined, -) { - // This function implementation mirrors some code in the metricsExplorer.init() function - if ( - !fullTimeRange || - !fullTimeRange.timeRangeSummary?.min || - !fullTimeRange.timeRangeSummary?.max - ) - return; - const timeZone = get(getLocalUserPreferences()).timeZone; - const fullTimeStart = new Date(fullTimeRange.timeRangeSummary.min); - const fullTimeEnd = new Date(fullTimeRange.timeRangeSummary.max); - const timeRange = isoDurationToFullTimeRange( - explorePreset?.timeRange, - fullTimeStart, - fullTimeEnd, - timeZone, - ); - - const timeGrain = getDefaultTimeGrain(timeRange.start, timeRange.end); - metricsExplorer.selectedTimeRange = { - ...timeRange, - interval: timeGrain.grain, - }; - metricsExplorer.selectedTimezone = timeZone ?? "UTC"; - // TODO: refactor all sub methods and call setSelectedScrubRange here - metricsExplorer.selectedScrubRange = undefined; - metricsExplorer.lastDefinedScrubRange = undefined; -} - -function setDefaultComparison( - metricsViewSpec: V1MetricsViewSpec, - exploreSpec: V1ExploreSpec, - metricsExplorer: MetricsExplorerEntity, - fullTimeRange: V1MetricsViewTimeRangeResponse | undefined, -) { - switch (exploreSpec?.defaultPreset?.comparisonMode) { - case V1ExploreComparisonMode.EXPLORE_COMPARISON_MODE_DIMENSION: - metricsExplorer.selectedComparisonDimension = - normaliseName( - exploreSpec?.defaultPreset?.comparisonDimension, - metricsViewSpec.dimensions, - ) || exploreSpec.dimensions?.[0]; - break; - - case V1ExploreComparisonMode.EXPLORE_COMPARISON_MODE_TIME: - setDefaultComparisonTimeRange( - exploreSpec?.defaultPreset, - metricsExplorer, - fullTimeRange, - ); - break; - - // if default_comparison is not specified it defaults to no comparison - case V1ExploreComparisonMode.EXPLORE_COMPARISON_MODE_UNSPECIFIED: - } -} - -function setDefaultComparisonTimeRange( - explorePreset: V1ExplorePreset | undefined, - metricsExplorer: MetricsExplorerEntity, - fullTimeRange: V1MetricsViewTimeRangeResponse | undefined, -) { - if ( - !fullTimeRange || - !fullTimeRange.timeRangeSummary?.min || - !fullTimeRange.timeRangeSummary?.max - ) - return; - metricsExplorer.showTimeComparison = true; - const preset = ISODurationToTimePreset(explorePreset?.timeRange, true); - if (!preset) return; - const comparisonOption = DEFAULT_TIME_RANGES[preset] - ?.defaultComparison as TimeComparisonOption; - if (!comparisonOption) return; - - const fullTimeStart = new Date(fullTimeRange.timeRangeSummary.min); - const fullTimeEnd = new Date(fullTimeRange.timeRangeSummary.max); - const comparisonRange = getTimeComparisonParametersForComponent( - comparisonOption, - fullTimeStart, - fullTimeEnd, - metricsExplorer.selectedTimeRange?.start, - metricsExplorer.selectedTimeRange?.end, - ); - if ( - !comparisonRange.isComparisonRangeAvailable || - !comparisonRange.start || - !comparisonRange.end - ) - return; - - metricsExplorer.selectedComparisonTimeRange = { - name: comparisonOption, - start: comparisonRange.start, - end: comparisonRange.end, - }; - metricsExplorer.leaderboardContextColumn = - LeaderboardContextColumn.DELTA_PERCENT; -} - -export function getDefaultMetricsExplorerEntity( +// TODO: Remove this in favour of just `getBasePreset` +export function getDefaultExploreState( name: string, metricsView: V1MetricsViewSpec, explore: V1ExploreSpec, fullTimeRange: V1MetricsViewTimeRangeResponse | undefined, + defaultExplorePreset = getDefaultExplorePreset( + explore, + getLocalUserPreferencesState(name), + fullTimeRange, + ), ): MetricsExplorerEntity { - const defaultMeasureNames = - explore?.defaultPreset?.measures ?? explore?.measures ?? []; - - const defaultDimNames = - explore?.defaultPreset?.dimensions ?? explore?.dimensions ?? []; - - const metricsExplorer: MetricsExplorerEntity = { + const { partialExploreState } = convertPresetToExploreState( + metricsView, + explore, + defaultExplorePreset, + ); + return { + // fields filled here are the ones that are not stored and loaded to/from URL name, - visibleMeasureKeys: new Set( - defaultMeasureNames - .map((dm) => normaliseName(dm, metricsView.measures)) - .filter((dm) => !!dm) as string[], - ), - allMeasuresVisible: defaultMeasureNames.length === explore.measures?.length, - visibleDimensionKeys: new Set( - defaultDimNames - .map((dd) => normaliseName(dd, metricsView.dimensions)) - .filter((dd) => !!dd) as string[], - ), - allDimensionsVisible: defaultDimNames.length === explore.dimensions?.length, - leaderboardMeasureName: defaultMeasureNames[0], - whereFilter: createAndExpression([]), - havingFilter: createAndExpression([]), - dimensionThresholdFilters: [], dimensionFilterExcludeMode: new Map(), leaderboardContextColumn: LeaderboardContextColumn.HIDDEN, - dashboardSortType: SortType.VALUE, - sortDirection: SortDirection.DESCENDING, - selectedTimezone: "UTC", - selectedTimeRange: undefined, - activePage: DashboardState_ActivePage.DEFAULT, - selectedComparisonDimension: undefined, - selectedDimensionName: undefined, - - showTimeComparison: false, temporaryFilterName: null, - tdd: { - chartType: TDDChart.DEFAULT, - expandedMeasureName: "", - pinIndex: -1, - }, - pivot: { - active: false, - rows: { - dimension: [], - }, - columns: { - dimension: [], - measure: [], - }, - rowJoinType: "nest", - expanded: {}, - sorting: [], - rowPage: 1, - enableComparison: true, - columnPage: 1, - activeCell: null, - }, contextColumnWidths: { ...contextColWidthDefaults }, - }; - // set time range related stuff - setDefaultTimeRange(explore?.defaultPreset, metricsExplorer, fullTimeRange); - setDefaultComparison(metricsView, explore, metricsExplorer, fullTimeRange); - return metricsExplorer; + + lastDefinedScrubRange: undefined, + + ...partialExploreState, + } as MetricsExplorerEntity; } +// TODO: move this to the same place where we load from session store. +// also move the type to V1ExplorePreset similar to session store. export function restorePersistedDashboardState( metricsExplorer: MetricsExplorerEntity, ) { @@ -239,14 +79,3 @@ export function restorePersistedDashboardState( } return metricsExplorer; } - -function normaliseName( - name: string | undefined, - entities: - | MetricsViewSpecMeasureV2[] - | MetricsViewSpecDimensionV2[] - | undefined, -): string | undefined { - return entities?.find((e) => e.name?.toLowerCase() === name?.toLowerCase()) - ?.name; -} diff --git a/web-common/src/features/dashboards/stores/dashboard-stores.ts b/web-common/src/features/dashboards/stores/dashboard-stores.ts index f8e37f6d5ae..dfb82049709 100644 --- a/web-common/src/features/dashboards/stores/dashboard-stores.ts +++ b/web-common/src/features/dashboards/stores/dashboard-stores.ts @@ -4,7 +4,7 @@ import { getProtoFromDashboardState } from "@rilldata/web-common/features/dashbo import { getWhereFilterExpressionIndex } from "@rilldata/web-common/features/dashboards/state-managers/selectors/dimension-filters"; import { AdvancedMeasureCorrector } from "@rilldata/web-common/features/dashboards/stores/AdvancedMeasureCorrector"; import { - getDefaultMetricsExplorerEntity, + getDefaultExploreState, restorePersistedDashboardState, } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; import { @@ -32,7 +32,7 @@ import { type V1StructType, } from "@rilldata/web-common/runtime-client"; import type { ExpandedState, SortingState } from "@tanstack/svelte-table"; -import { type Readable, derived, writable } from "svelte/store"; +import { derived, writable, type Readable } from "svelte/store"; import { SortType } from "web-common/src/features/dashboards/proto-state/derived-types"; import type { PivotColumns, PivotRows } from "../pivot/types"; import { PivotChipType, type PivotChipData } from "../pivot/types"; @@ -174,17 +174,15 @@ const metricsViewReducers = { metricsView: V1MetricsViewSpec, explore: V1ExploreSpec, fullTimeRange: V1MetricsViewTimeRangeResponse | undefined, + initState: Partial = {}, ) { update((state) => { if (state.entities[name]) return state; - state.entities[name] = getDefaultMetricsExplorerEntity( - name, - metricsView, - explore, - fullTimeRange, - ); - + state.entities[name] = { + ...getDefaultExploreState(name, metricsView, explore, fullTimeRange), + ...initState, + }; state.entities[name] = restorePersistedDashboardState( state.entities[name], ); @@ -228,6 +226,26 @@ const metricsViewReducers = { }); }, + mergePartialExplorerEntity( + name: string, + partialExploreState: Partial, + metricsView: V1MetricsViewSpec, + ) { + updateMetricsExplorerByName(name, (metricsExplorer) => { + for (const key in partialExploreState) { + metricsExplorer[key] = partialExploreState[key]; + } + // this hack is needed since what is shown for comparison is not a single source + // TODO: use an enum and get rid of this + if (!partialExploreState.showTimeComparison) { + metricsExplorer.showTimeComparison = false; + } + metricsExplorer.dimensionFilterExcludeMode = + includeExcludeModeFromFilters(partialExploreState.whereFilter); + AdvancedMeasureCorrector.correct(metricsExplorer, metricsView); + }); + }, + sync(name: string, explore: V1ExploreSpec) { if (!name || !explore || !explore.measures) return; updateMetricsExplorerByName(name, (metricsExplorer) => { @@ -386,6 +404,7 @@ const metricsViewReducers = { createPivot(name: string, rows: PivotRows, columns: PivotColumns) { updateMetricsExplorerByName(name, (metricsExplorer) => { + metricsExplorer.activePage = DashboardState_ActivePage.PIVOT; metricsExplorer.pivot = { ...metricsExplorer.pivot, active: true, @@ -537,7 +556,7 @@ export const metricsExplorerStore: Readable & ...metricsViewReducers, }; -export function useExploreStore(name: string): Readable { +export function useExploreState(name: string): Readable { return derived(metricsExplorerStore, ($store) => { return $store.entities[name]; }); diff --git a/web-common/src/features/dashboards/stores/filter-utils.ts b/web-common/src/features/dashboards/stores/filter-utils.ts index 132b85214a1..740f6b4520a 100644 --- a/web-common/src/features/dashboards/stores/filter-utils.ts +++ b/web-common/src/features/dashboards/stores/filter-utils.ts @@ -2,6 +2,7 @@ import { type V1Condition, V1Operation, type V1Expression, + type V1Subquery, } from "@rilldata/web-common/runtime-client"; export function createLikeExpression( @@ -183,6 +184,12 @@ export function filterExpressions( expr: V1Expression, checker: (e: V1Expression) => boolean, ): V1Expression | undefined { + if (expr.subquery) { + return { + subquery: filterSubQuery(expr.subquery, checker), + }; + } + if (!expr.cond?.exprs) { return { ...expr, @@ -205,15 +212,49 @@ export function filterExpressions( if (newExpr.cond?.exprs?.length === 0) return undefined; break; - // other types will have identifier as 1st expression default: - if (!newExpr.cond?.exprs?.length || !("ident" in newExpr.cond.exprs[0])) + // other types should have at least 2 expressions + if (newExpr.cond?.exprs?.length && newExpr.cond.exprs.length <= 1) return undefined; break; } return newExpr; } +function filterSubQuery( + subQuery: V1Subquery, + checker: (e: V1Expression) => boolean, +) { + if (subQuery.having?.cond?.exprs?.length) { + if (checker(subQuery.having)) { + subQuery.having = filterExpressions(subQuery.having, checker); + } else { + subQuery.having = undefined; + } + } else if (subQuery.having) { + subQuery.having = { + ...subQuery.having, + }; + } + if (subQuery.where?.cond?.exprs?.length) { + if (checker(subQuery.where)) { + subQuery.where = filterExpressions(subQuery.where, checker); + } else { + subQuery.where = undefined; + } + } else if (subQuery.where) { + subQuery.where = { + ...subQuery.where, + }; + } + + return { + dimension: subQuery.dimension, + measures: [...(subQuery.measures ?? [])], + where: subQuery.where, + having: subQuery.having, + }; +} export function copyFilterExpression(expr: V1Expression) { return filterExpressions(expr, () => true) ?? createAndExpression([]); @@ -224,6 +265,9 @@ export function filterIdentifiers( cb: (e: V1Expression, ident: string) => boolean, ) { return filterExpressions(expr, (e) => { + if (e.subquery?.dimension) { + return cb(e, e.subquery.dimension); + } const ident = e.cond?.exprs?.[0].ident; if (ident === undefined) { return true; @@ -305,3 +349,40 @@ export function isExpressionIncomplete(expression: V1Expression): boolean { // If the operation is specified and a defined, non-empty val is found, the expression is complete return false; } + +export function isJoinerExpression(expression: V1Expression | undefined) { + return ( + expression?.cond?.op && + (expression.cond.op === V1Operation.OPERATION_AND || + expression.cond.op === V1Operation.OPERATION_OR) + ); +} + +export function isExpressionUnsupported(expression: V1Expression) { + if ( + !expression.cond || + !expression.cond.exprs || + expression.cond?.op !== V1Operation.OPERATION_AND + ) { + return true; + } + + for (const expr of expression.cond.exprs) { + if ( + expr.cond?.op !== V1Operation.OPERATION_IN && + expr.cond?.op !== V1Operation.OPERATION_NIN + ) + return true; + + const subqueryExpr = expr.cond?.exprs?.[1]; + if ( + subqueryExpr?.subquery?.having?.cond?.exprs?.length && + isJoinerExpression(subqueryExpr.subquery.having) && + subqueryExpr.subquery.having.cond.exprs.length > 1 + ) { + return true; + } + } + + return false; +} diff --git a/web-common/src/features/dashboards/stores/metrics-explorer-entity.ts b/web-common/src/features/dashboards/stores/metrics-explorer-entity.ts index a7641904583..c23bf40564d 100644 --- a/web-common/src/features/dashboards/stores/metrics-explorer-entity.ts +++ b/web-common/src/features/dashboards/stores/metrics-explorer-entity.ts @@ -74,7 +74,6 @@ export interface MetricsExplorerEntity { sortDirection: SortDirection; whereFilter: V1Expression; - havingFilter: V1Expression; dimensionThresholdFilters: Array; /** diff --git a/web-common/src/features/dashboards/stores/syncDashboardState.ts b/web-common/src/features/dashboards/stores/syncDashboardState.ts index 5dc9ab6cd2d..b2febc4adc9 100644 --- a/web-common/src/features/dashboards/stores/syncDashboardState.ts +++ b/web-common/src/features/dashboards/stores/syncDashboardState.ts @@ -66,7 +66,7 @@ export function createDashboardStateSync( const exploreName = get(ctx.exploreName); if (exploreName in get(metricsExplorerStore).entities) { // Successive syncs with metrics view spec - metricsExplorerStore.sync(exploreName, explore); + // metricsExplorerStore.sync(exploreName, explore); } else { // Running for the 1st time. Initialise the dashboard store. metricsExplorerStore.init( @@ -79,13 +79,13 @@ export function createDashboardStateSync( get(page).url.searchParams.get("state") ?? initialUrlStateRes?.data; if (initialUrlState) { // If there is data to be loaded, load it during the init - metricsExplorerStore.syncFromUrl( - exploreName, - initialUrlState, - metricsView, - explore, - metricsViewSchemaRes.data.schema, - ); + // metricsExplorerStore.syncFromUrl( + // exploreName, + // initialUrlState, + // metricsView, + // explore, + // metricsViewSchemaRes.data.schema, + // ); // Call sync to make sure changes in dashboard are honoured metricsExplorerStore.sync(exploreName, explore); } diff --git a/web-common/src/features/dashboards/stores/test-data/data.ts b/web-common/src/features/dashboards/stores/test-data/data.ts index 21c9faf69c3..405b3fa2001 100644 --- a/web-common/src/features/dashboards/stores/test-data/data.ts +++ b/web-common/src/features/dashboards/stores/test-data/data.ts @@ -1,7 +1,10 @@ +import { PivotChipType } from "@rilldata/web-common/features/dashboards/pivot/types"; import { createAndExpression, createInExpression, } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; +import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; +import { getDefaultExplorePreset } from "@rilldata/web-common/features/dashboards/url-state/getDefaultExplorePreset"; import { getLocalIANA } from "@rilldata/web-common/lib/time/timezone"; import { getOffset, @@ -13,15 +16,20 @@ import { TimeOffsetType, TimeRangePreset, } from "@rilldata/web-common/lib/time/types"; -import type { - MetricsViewSpecDimensionV2, - MetricsViewSpecMeasureV2, - V1ExploreSpec, - V1MetricsViewSpec, - V1MetricsViewTimeRangeResponse, - V1StructType, +import { DashboardState_ActivePage } from "@rilldata/web-common/proto/gen/rill/ui/v1/dashboard_pb"; +import { + type MetricsViewSpecDimensionV2, + type MetricsViewSpecMeasureV2, + TypeCode, + type V1ExplorePreset, + V1ExploreSortType, + type V1ExploreSpec, + V1ExploreWebView, + type V1MetricsViewSpec, + type V1MetricsViewTimeRangeResponse, + type V1StructType, + V1TimeGrain, } from "@rilldata/web-common/runtime-client"; -import { TypeCode, V1TimeGrain } from "@rilldata/web-common/runtime-client"; export const AD_BIDS_NAME = "AdBids"; export const AD_BIDS_EXPLORE_NAME = AD_BIDS_NAME + "_explore"; @@ -180,6 +188,12 @@ export const AD_BIDS_METRICS_WITH_BOOL_DIMENSION: V1MetricsViewSpec = { }, ], }; +export const AD_BIDS_METRICS_3_MEASURES_DIMENSIONS: V1MetricsViewSpec = { + displayName: AD_BIDS_NAME, + table: AD_BIDS_SOURCE_NAME, + measures: AD_BIDS_THREE_MEASURES, + dimensions: AD_BIDS_THREE_DIMENSIONS, +}; export const AD_BIDS_EXPLORE_INIT: V1ExploreSpec = { displayName: AD_BIDS_EXPLORE_NAME, @@ -221,6 +235,40 @@ export const AD_BIDS_EXPLORE_WITH_BOOL_DIMENSION: V1ExploreSpec = { ], }; +export const AD_BIDS_PRESET: V1ExplorePreset = { + timeRange: "P7D", + timezone: "Asia/Kathmandu", + compareTimeRange: "rill-PP", + measures: [AD_BIDS_IMPRESSIONS_MEASURE], + dimensions: [AD_BIDS_PUBLISHER_DIMENSION], + exploreSortBy: AD_BIDS_BID_PRICE_MEASURE, + exploreSortAsc: true, + exploreSortType: V1ExploreSortType.EXPLORE_SORT_TYPE_PERCENT, +}; +export const AD_BIDS_DIMENSION_TABLE_PRESET: V1ExplorePreset = { + exploreExpandedDimension: AD_BIDS_DOMAIN_DIMENSION, +}; +export const AD_BIDS_TIME_DIMENSION_DETAILS_PRESET: V1ExplorePreset = { + view: V1ExploreWebView.EXPLORE_WEB_VIEW_TIME_DIMENSION, + timeDimensionMeasure: AD_BIDS_IMPRESSIONS_MEASURE, + timeDimensionChartType: "stacked_bar", +}; +export const AD_BIDS_PIVOT_PRESET: V1ExplorePreset = { + view: V1ExploreWebView.EXPLORE_WEB_VIEW_PIVOT, + pivotRows: ["publisher", "time.hour"], + pivotCols: ["domain", "time.day", "impressions"], + pivotSortBy: "time.day", + pivotSortAsc: true, +}; + +export const AD_BIDS_BASE_PRESET = getDefaultExplorePreset( + AD_BIDS_EXPLORE_INIT, + { + timeZone: "UTC", + }, + undefined, +); + export const AD_BIDS_SCHEMA: V1StructType = { fields: [ { @@ -310,3 +358,52 @@ export const CUSTOM_TEST_CONTROLS = { start: TestTimeConstants.LAST_18_HOURS, end: TestTimeConstants.LAST_12_HOURS, } as DashboardTimeControls; + +export const AD_BIDS_PIVOT_ENTITY: Partial = { + activePage: DashboardState_ActivePage.PIVOT, + pivot: { + active: true, + rows: { + dimension: [ + { + id: AD_BIDS_PUBLISHER_DIMENSION, + type: PivotChipType.Dimension, + title: AD_BIDS_PUBLISHER_DIMENSION, + }, + { + id: V1TimeGrain.TIME_GRAIN_HOUR, + type: PivotChipType.Time, + title: "hour", + }, + ], + }, + columns: { + measure: [ + { + id: AD_BIDS_IMPRESSIONS_MEASURE, + type: PivotChipType.Measure, + title: AD_BIDS_IMPRESSIONS_MEASURE, + }, + ], + dimension: [ + { + id: AD_BIDS_DOMAIN_DIMENSION, + type: PivotChipType.Dimension, + title: AD_BIDS_DOMAIN_DIMENSION, + }, + { + id: V1TimeGrain.TIME_GRAIN_DAY, + type: PivotChipType.Time, + title: "day", + }, + ], + }, + expanded: {}, + sorting: [], + columnPage: 1, + rowPage: 1, + enableComparison: true, + activeCell: null, + rowJoinType: "nest", + }, +}; diff --git a/web-common/src/features/dashboards/stores/test-data/helpers.ts b/web-common/src/features/dashboards/stores/test-data/helpers.ts index 5d01bfd39d9..d382dcca79a 100644 --- a/web-common/src/features/dashboards/stores/test-data/helpers.ts +++ b/web-common/src/features/dashboards/stores/test-data/helpers.ts @@ -1,6 +1,6 @@ import { QueryClient } from "@rilldata/svelte-query"; import { createStateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers"; -import { getDefaultMetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; +import { getDefaultExploreState } from "@rilldata/web-common/features/dashboards/stores/dashboard-store-defaults"; import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; import { createAndExpression } from "@rilldata/web-common/features/dashboards/stores/filter-utils"; import type { MetricsExplorerEntity } from "@rilldata/web-common/features/dashboards/stores/metrics-explorer-entity"; @@ -17,10 +17,10 @@ import { } from "@rilldata/web-common/features/dashboards/stores/test-data/data"; import type { ExploreValidSpecResponse } from "@rilldata/web-common/features/explores/selectors"; import type { DashboardTimeControls } from "@rilldata/web-common/lib/time/types"; -import type { - V1ExploreSpec, - V1Expression, - V1MetricsViewSpec, +import { + type V1ExploreSpec, + type V1Expression, + type V1MetricsViewSpec, } from "@rilldata/web-common/runtime-client"; import { deepClone } from "@vitest/utils"; import { get } from "svelte/store"; @@ -58,12 +58,7 @@ export function createDashboardState( whereFilter: V1Expression = createAndExpression([]), timeRange: DashboardTimeControls = AD_BIDS_DEFAULT_TIME_RANGE, ): MetricsExplorerEntity { - const explorer = getDefaultMetricsExplorerEntity( - name, - metrics, - explore, - undefined, - ); + const explorer = getDefaultExploreState(name, metrics, explore, undefined); explorer.whereFilter = whereFilter; explorer.selectedTimeRange = timeRange; return explorer; @@ -89,7 +84,10 @@ export function createAdBidsMirrorInStore({ export function assertMetricsView( name: string, filters: V1Expression = createAndExpression([]), - timeRange: DashboardTimeControls = AD_BIDS_DEFAULT_TIME_RANGE, + timeRange = { + name: AD_BIDS_DEFAULT_TIME_RANGE.name, + interval: AD_BIDS_DEFAULT_TIME_RANGE.interval, + } as DashboardTimeControls, selectedMeasure = AD_BIDS_IMPRESSIONS_MEASURE, ) { assertMetricsViewRaw(name, filters, timeRange, selectedMeasure); @@ -110,20 +108,6 @@ export function assertMetricsViewRaw( expect(metricsView.leaderboardMeasureName).toEqual(selectedMeasure); } -export function assertVisiblePartsOfMetricsView( - name: string, - measures: Array | undefined, - dimensions: Array | undefined, -) { - const metricsView = get(metricsExplorerStore).entities[name]; - if (measures) - expect([...metricsView.visibleMeasureKeys].sort()).toEqual(measures.sort()); - if (dimensions) - expect([...metricsView.visibleDimensionKeys].sort()).toEqual( - dimensions.sort(), - ); -} - export function initStateManagers(metricsViewName?: string) { metricsViewName ??= AD_BIDS_NAME; const exploreName = metricsViewName + "_explore"; diff --git a/web-common/src/features/dashboards/stores/test-data/query-mocks.ts b/web-common/src/features/dashboards/stores/test-data/query-mocks.ts index abf5a320d06..dbdf83b7ce2 100644 --- a/web-common/src/features/dashboards/stores/test-data/query-mocks.ts +++ b/web-common/src/features/dashboards/stores/test-data/query-mocks.ts @@ -2,6 +2,7 @@ import type { CreateQueryResult } from "@rilldata/svelte-query"; import { AD_BIDS_INIT_DIMENSIONS, AD_BIDS_INIT_MEASURES, + AD_BIDS_METRICS_INIT, AD_BIDS_NAME, } from "@rilldata/web-common/features/dashboards/stores/test-data/data"; import type { ExploreValidSpecResponse } from "@rilldata/web-common/features/explores/selectors"; @@ -63,6 +64,7 @@ export function createMetricsMetaQueryMock( export function createValidSpecQueryMock( metricsView = AD_BIDS_NAME, shouldInit = true, + initMetrics: V1MetricsViewSpec = AD_BIDS_METRICS_INIT, ): CreateQueryResult & { setMeasures: (measures: Array) => void; setDimensions: (dimensions: Array) => void; @@ -120,8 +122,8 @@ export function createValidSpecQueryMock( }; if (shouldInit) { - mock.setMeasures(AD_BIDS_INIT_MEASURES); - mock.setDimensions(AD_BIDS_INIT_DIMENSIONS); + mock.setMeasures(initMetrics.measures!); + mock.setDimensions(initMetrics.dimensions!); } return mock; diff --git a/web-common/src/features/dashboards/stores/test-data/store-mutations.ts b/web-common/src/features/dashboards/stores/test-data/store-mutations.ts index b8b009f127d..d42319cb9cd 100644 --- a/web-common/src/features/dashboards/stores/test-data/store-mutations.ts +++ b/web-common/src/features/dashboards/stores/test-data/store-mutations.ts @@ -3,28 +3,43 @@ import { MeasureFilterType, } from "@rilldata/web-common/features/dashboards/filters/measure-filters/measure-filter-options"; import { PivotChipType } from "@rilldata/web-common/features/dashboards/pivot/types"; +import { setLeaderboardMeasureName } from "@rilldata/web-common/features/dashboards/state-managers/actions/core-actions"; import { removeDimensionFilter, toggleDimensionValueSelection, } from "@rilldata/web-common/features/dashboards/state-managers/actions/dimension-filters"; -import { setPrimaryDimension } from "@rilldata/web-common/features/dashboards/state-managers/actions/dimensions"; +import { + setPrimaryDimension, + toggleDimensionVisibility, +} from "@rilldata/web-common/features/dashboards/state-managers/actions/dimensions"; import { removeMeasureFilter, setMeasureFilter, } from "@rilldata/web-common/features/dashboards/state-managers/actions/measure-filters"; +import { toggleMeasureVisibility } from "@rilldata/web-common/features/dashboards/state-managers/actions/measures"; +import { + setSortDescending, + toggleSort, +} from "@rilldata/web-common/features/dashboards/state-managers/actions/sorting"; import type { DashboardMutables } from "@rilldata/web-common/features/dashboards/state-managers/actions/types"; -import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; +import { + metricsExplorerStore, + updateMetricsExplorerByName, +} from "@rilldata/web-common/features/dashboards/stores/dashboard-stores"; +import { createPersistentDashboardStore } from "@rilldata/web-common/features/dashboards/stores/persistent-dashboard-state"; import { AD_BIDS_BID_PRICE_MEASURE, AD_BIDS_DOMAIN_DIMENSION, + AD_BIDS_EXPLORE_INIT, + AD_BIDS_EXPLORE_NAME, AD_BIDS_IMPRESSIONS_MEASURE, AD_BIDS_METRICS_INIT, - AD_BIDS_NAME, AD_BIDS_PUBLISHER_DIMENSION, } from "@rilldata/web-common/features/dashboards/stores/test-data/data"; +import { TDDChart } from "@rilldata/web-common/features/dashboards/time-dimension-details/types"; import { TimeRangePreset } from "@rilldata/web-common/lib/time/types"; +import { DashboardState_LeaderboardSortType } from "@rilldata/web-common/proto/gen/rill/ui/v1/dashboard_pb"; import { V1TimeGrain } from "@rilldata/web-common/runtime-client"; -import { get } from "svelte/store"; export type TestDashboardMutation = (mut: DashboardMutables) => void; export const AD_BIDS_APPLY_PUB_DIMENSION_FILTER: TestDashboardMutation = ( @@ -62,7 +77,7 @@ export const AD_BIDS_APPLY_BP_MEASURE_FILTER: TestDashboardMutation = (mut) => export const AD_BIDS_SET_P7D_TIME_RANGE_FILTER: TestDashboardMutation = () => metricsExplorerStore.selectTimeRange( - AD_BIDS_NAME, + AD_BIDS_EXPLORE_NAME, { name: TimeRangePreset.LAST_7_DAYS } as any, V1TimeGrain.TIME_GRAIN_DAY, undefined, @@ -70,34 +85,202 @@ export const AD_BIDS_SET_P7D_TIME_RANGE_FILTER: TestDashboardMutation = () => ); export const AD_BIDS_SET_P4W_TIME_RANGE_FILTER: TestDashboardMutation = () => metricsExplorerStore.selectTimeRange( - AD_BIDS_NAME, + AD_BIDS_EXPLORE_NAME, { name: TimeRangePreset.LAST_4_WEEKS } as any, V1TimeGrain.TIME_GRAIN_WEEK, undefined, AD_BIDS_METRICS_INIT, ); +export const AD_BIDS_SET_ALL_TIME_RANGE_FILTER: TestDashboardMutation = () => + metricsExplorerStore.selectTimeRange( + AD_BIDS_EXPLORE_NAME, + { name: TimeRangePreset.ALL_TIME } as any, + V1TimeGrain.TIME_GRAIN_DAY, + undefined, + AD_BIDS_METRICS_INIT, + ); +export const AD_BIDS_SET_KATHMANDU_TIMEZONE: TestDashboardMutation = () => + metricsExplorerStore.setTimeZone(AD_BIDS_EXPLORE_NAME, "Asia/Kathmandu"); +export const AD_BIDS_SET_LA_TIMEZONE: TestDashboardMutation = () => + metricsExplorerStore.setTimeZone(AD_BIDS_EXPLORE_NAME, "America/Los_Angeles"); +export const AD_BIDS_SET_PREVIOUS_PERIOD_COMPARE_TIME_RANGE_FILTER: TestDashboardMutation = + () => { + metricsExplorerStore.displayTimeComparison(AD_BIDS_EXPLORE_NAME, true); + metricsExplorerStore.setSelectedComparisonRange( + AD_BIDS_EXPLORE_NAME, + { name: "rill-PP" } as any, + AD_BIDS_METRICS_INIT, + ); + }; +export const AD_BIDS_SET_PREVIOUS_WEEK_COMPARE_TIME_RANGE_FILTER: TestDashboardMutation = + () => { + metricsExplorerStore.displayTimeComparison(AD_BIDS_EXPLORE_NAME, true); + metricsExplorerStore.setSelectedComparisonRange( + AD_BIDS_EXPLORE_NAME, + { name: "rill-PW" } as any, + AD_BIDS_METRICS_INIT, + ); + }; +export const AD_BIDS_DISABLE_COMPARE_TIME_RANGE_FILTER: TestDashboardMutation = + () => metricsExplorerStore.displayTimeComparison(AD_BIDS_EXPLORE_NAME, false); + +export const AD_BIDS_TOGGLE_BID_PRICE_MEASURE_VISIBILITY: TestDashboardMutation = + (mut) => { + toggleMeasureVisibility( + mut, + AD_BIDS_EXPLORE_INIT.measures!, + AD_BIDS_BID_PRICE_MEASURE, + ); + }; +export const AD_BIDS_TOGGLE_BID_DOMAIN_DIMENSION_VISIBILITY: TestDashboardMutation = + (mut) => { + toggleDimensionVisibility( + mut, + AD_BIDS_EXPLORE_INIT.dimensions!, + AD_BIDS_DOMAIN_DIMENSION, + ); + }; + +export const AD_BIDS_SORT_DESC_BY_IMPRESSIONS: TestDashboardMutation = ( + mut, +) => { + setLeaderboardMeasureName(mut, AD_BIDS_IMPRESSIONS_MEASURE); + setSortDescending(mut); +}; +export const AD_BIDS_SORT_ASC_BY_BID_PRICE: TestDashboardMutation = (mut) => { + setLeaderboardMeasureName(mut, AD_BIDS_BID_PRICE_MEASURE); + setSortDescending(mut); + toggleSort(mut, mut.dashboard.dashboardSortType); +}; +export const AD_BIDS_SORT_BY_VALUE: TestDashboardMutation = (mut) => { + toggleSort(mut, DashboardState_LeaderboardSortType.VALUE); +}; +export const AD_BIDS_SORT_BY_PERCENT_VALUE: TestDashboardMutation = (mut) => { + toggleSort(mut, DashboardState_LeaderboardSortType.PERCENT); +}; +export const AD_BIDS_SORT_BY_DELTA_ABS_VALUE: TestDashboardMutation = (mut) => { + toggleSort(mut, DashboardState_LeaderboardSortType.DELTA_ABSOLUTE); +}; export const AD_BIDS_OPEN_PUB_DIMENSION_TABLE: TestDashboardMutation = (mut) => setPrimaryDimension(mut, AD_BIDS_PUBLISHER_DIMENSION); export const AD_BIDS_OPEN_DOM_DIMENSION_TABLE: TestDashboardMutation = (mut) => setPrimaryDimension(mut, AD_BIDS_DOMAIN_DIMENSION); +export const AD_BIDS_CLOSE_DIMENSION_TABLE: TestDashboardMutation = (mut) => + setPrimaryDimension(mut, ""); export const AD_BIDS_OPEN_IMP_TDD: TestDashboardMutation = () => metricsExplorerStore.setExpandedMeasureName( - AD_BIDS_NAME, + AD_BIDS_EXPLORE_NAME, AD_BIDS_IMPRESSIONS_MEASURE, ); +export const AD_BIDS_SWITCH_TO_STACKED_BAR_IN_TDD: TestDashboardMutation = () => + metricsExplorerStore.setTDDChartType( + AD_BIDS_EXPLORE_NAME, + TDDChart.STACKED_BAR, + ); + export const AD_BIDS_OPEN_BP_TDD: TestDashboardMutation = () => metricsExplorerStore.setExpandedMeasureName( - AD_BIDS_NAME, + AD_BIDS_EXPLORE_NAME, AD_BIDS_BID_PRICE_MEASURE, ); +export const AD_BIDS_CLOSE_TDD: TestDashboardMutation = () => + metricsExplorerStore.setExpandedMeasureName(AD_BIDS_EXPLORE_NAME, ""); + +export const AD_BIDS_OPEN_PIVOT_WITH_ALL_FIELDS: TestDashboardMutation = () => + metricsExplorerStore.createPivot( + AD_BIDS_EXPLORE_NAME, + { + dimension: [ + { + id: AD_BIDS_PUBLISHER_DIMENSION, + title: AD_BIDS_PUBLISHER_DIMENSION, + type: PivotChipType.Dimension, + }, + { + id: V1TimeGrain.TIME_GRAIN_HOUR, + title: "hour", + type: PivotChipType.Time, + }, + ], + }, + { + dimension: [ + { + id: AD_BIDS_DOMAIN_DIMENSION, + title: AD_BIDS_DOMAIN_DIMENSION, + type: PivotChipType.Dimension, + }, + { + id: V1TimeGrain.TIME_GRAIN_DAY, + title: "day", + type: PivotChipType.Time, + }, + ], + measure: [ + { + id: AD_BIDS_IMPRESSIONS_MEASURE, + title: AD_BIDS_IMPRESSIONS_MEASURE, + type: PivotChipType.Measure, + }, + ], + }, + ); +export const AD_BIDS_OPEN_DOMAIN_BID_PRICE_PIVOT: TestDashboardMutation = () => + metricsExplorerStore.createPivot( + AD_BIDS_EXPLORE_NAME, + { + dimension: [ + { + id: AD_BIDS_DOMAIN_DIMENSION, + title: AD_BIDS_DOMAIN_DIMENSION, + type: PivotChipType.Dimension, + }, + { + id: V1TimeGrain.TIME_GRAIN_DAY, + title: "day", + type: PivotChipType.Time, + }, + ], + }, + { + dimension: [], + measure: [ + { + id: AD_BIDS_IMPRESSIONS_MEASURE, + title: AD_BIDS_IMPRESSIONS_MEASURE, + type: PivotChipType.Measure, + }, + ], + }, + ); +export const AD_BIDS_TOGGLE_PIVOT: TestDashboardMutation = () => + metricsExplorerStore.setPivotMode(AD_BIDS_EXPLORE_NAME, false); +export const AD_BIDS_SORT_PIVOT_BY_DOMAIN_DESC: TestDashboardMutation = () => + metricsExplorerStore.setPivotSort(AD_BIDS_EXPLORE_NAME, [ + { id: AD_BIDS_DOMAIN_DIMENSION, desc: true }, + ]); +export const AD_BIDS_SORT_PIVOT_BY_TIME_DAY_ASC: TestDashboardMutation = () => + metricsExplorerStore.setPivotSort(AD_BIDS_EXPLORE_NAME, [ + { id: V1TimeGrain.TIME_GRAIN_DAY, desc: false }, + ]); +export const AD_BIDS_SORT_PIVOT_BY_IMPRESSIONS_DESC: TestDashboardMutation = + () => + metricsExplorerStore.setPivotSort(AD_BIDS_EXPLORE_NAME, [ + { id: AD_BIDS_IMPRESSIONS_MEASURE, desc: true }, + ]); export const AD_BIDS_OPEN_PUB_IMP_PIVOT: TestDashboardMutation = () => metricsExplorerStore.createPivot( - AD_BIDS_NAME, + AD_BIDS_EXPLORE_NAME, { dimension: [ + { + id: V1TimeGrain.TIME_GRAIN_HOUR, + title: "hour", + type: PivotChipType.Time, + }, { id: AD_BIDS_PUBLISHER_DIMENSION, title: AD_BIDS_PUBLISHER_DIMENSION, @@ -118,7 +301,7 @@ export const AD_BIDS_OPEN_PUB_IMP_PIVOT: TestDashboardMutation = () => ); export const AD_BIDS_OPEN_DOM_BP_PIVOT: TestDashboardMutation = () => metricsExplorerStore.createPivot( - AD_BIDS_NAME, + AD_BIDS_EXPLORE_NAME, { dimension: [ { @@ -144,8 +327,11 @@ export function applyMutationsToDashboard( name: string, mutations: TestDashboardMutation[], ) { - const dashboard = get(metricsExplorerStore).entities[name]; - const dashboardMutables = { dashboard } as DashboardMutables; - - mutations.forEach((mutation) => mutation(dashboardMutables)); + updateMetricsExplorerByName(name, (dashboard) => { + const dashboardMutables = { + dashboard, + persistentDashboardStore: createPersistentDashboardStore("dummy"), + } as DashboardMutables; + mutations.forEach((mutation) => mutation(dashboardMutables)); + }); } diff --git a/web-common/src/features/dashboards/tab-bar/Tab.svelte b/web-common/src/features/dashboards/tab-bar/Tab.svelte index 7806cf510e4..5e71d0a6738 100644 --- a/web-common/src/features/dashboards/tab-bar/Tab.svelte +++ b/web-common/src/features/dashboards/tab-bar/Tab.svelte @@ -3,9 +3,10 @@ export let disabled = false; export let selected = false; + export let href: string; - +