Repository: akuity/kargo

Issue:
AnalysisRun phase changes don't trigger stage controller reconcile
# Checklist

* [x] I've searched the issue queue to verify this is not a duplicate bug report.
* [x] I've included steps to reproduce the bug.
* [x] I've pasted the output of `kargo version`.
* [x] I've pasted logs, if applicable.

# Description

AnalysisRun phase changes doesn't trigger stage controller reconcile. AnalysisRun are shown as "Verifying" until the stage gets requeued automatically by the defaultRequeue of 5min.

# Screenshots

![Image](https://github.com/user-attachments/assets/7e5c1187-fd0c-46d6-9e71-fd0dec0e344a)

# Steps to Reproduce

- Use a sharded kargo controller
- We're using a ClusterAnalysisTemplate based on a metric provider
- Launching through the UI or automated by promotion makes no difference on our side

# Version

Using kargo helm chart without overrides (1.5.1)

# Logs

In the logs the EventSource is started correctly, however we don't see the [handler](https://github.com/akuity/kargo/blob/main/internal/controller/stages/event_handlers.go#L489) getting called at all (with debug logs).

```
time="2025-06-02T15:11:48Z" level=info msg="Starting EventSource" controller=stage controllerGroup=kargo.akuity.io controllerKind=Stage source="kind source: *v1alpha1.AnalysisRun"
```

Our hypothesis revolves around this [predicate](https://github.com/akuity/kargo/blob/main/internal/controller/stages/regular_stages.go#L180) masking the phase status change because the generation didn't change but that might be something else.




Discussion:
@hiddeco: Have been unable to reproduce this, and can see the reconciliation of the Stage getting queued in the logs:

```
time="2025-06-03T10:16:06Z" level=debug msg="enqueued Stage for reconciliation" analysisRun=test.01jwtmh6jvcgsngse8j1r94gcr.1a2e85b namespace=kargo-demo-01 stage=test
```

Could you provide a minimal viable example that I can use to attempt to reproduce it?@AlanLonguet: Oo, well I'll post the Stage and ClusterAnalysisTemplate we're using below, maybe this is a setup issue on our side, is there anything on argo-rollouts or on kargo (e.g. RBAC) that would not permit the events to be properly received ?

```
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
  annotations:
    kargo.akuity.io/color: '#882255'
  labels:
    argocd.argoproj.io/instance: demo-domain-kargo-promotion
  name: dev-colorapp1
  namespace: demo-domain
spec:
  promotionTemplate:
    spec:
      steps:
        - task:
            kind: ClusterPromotionTask
            name: ecr
          vars:
            - name: environment
              value: dev
            - name: application
              value: colorapp1
            - name: imageURL
              value: XXX
            - name: gitOpsRepoURL
              value: XXX
  requestedFreight:
    - origin:
        kind: Warehouse
        name: colorapp1
      sources:
        direct: true
  shard: dev
  verification:
    analysisTemplates:
      - kind: ClusterAnalysisTemplate
        name: metrics-analysis
    args:
      - name: application
        value: colorapp1
      - name: env
        value: dev
      - name: version
        value: >-
          ${{
          imageFrom('XXX').Tag
          }}
```

```
apiVersion: argoproj.io/v1alpha1
kind: ClusterAnalysisTemplate
metadata:
  name: metrics-analysis
spec:
  args:
  - name: application
  - name: env
  - name: version
  metrics:
  - name: deployment-status
    count: 3
    interval: 20s
    successCondition: result > 0.9
    failureLimit: 3
    provider:
      datadog:
        apiVersion: v2
        interval: 1m
        query: |
          max:kubernetes_state.deployment.condition{status:true,condition:available, env:{{args.env}}, kube_app_name:{{args.application}}, version:{{args.version}}}
```



@AlanLonguet: @hiddeco On a sharded kargo setup (which is our case) would that [line](https://github.com/akuity/kargo/blob/main/internal/controller/stages/regular_stages.go#L280) not lead to issues as we're checking the shardName is equal to the rollout controller ID instead of the kargo controller shard name ? If the indexer is not working correctly I'd say the EventSource wouldn't too but I'm not that knowledgeable with Indexers.

Solution patch:
diff --git a/README.md b/README.md
index e31d6939..5a937e45 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ technologies, like [Argo CD](https://argoproj.github.io/cd/), to streamline and
 automate the progressive rollout of changes across the many stages of an
 application's lifecycle.
 
-![Kargo Dashboard](https://github.com/user-attachments/assets/8e8ab1db-7857-4d3c-ab0f-6f579fe5c403)
+![Kargo Dashboard](./docs/static/img/kargo-ui.png)
 
 ## Getting Started
 
diff --git a/api/service/v1alpha1/service.pb.go b/api/service/v1alpha1/service.pb.go
index 126c8ae9..a8b35ab1 100644
--- a/api/service/v1alpha1/service.pb.go
+++ b/api/service/v1alpha1/service.pb.go
@@ -2173,17 +2173,16 @@ func (x *RefreshStageResponse) GetStage() *v1alpha1.Stage {
 	return nil
 }
 
-type ListPromotionsRequest struct {
+type GetClusterConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string  `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage   *string `protobuf:"bytes,2,opt,name=stage,proto3,oneof" json:"stage,omitempty"`
+	Format RawFormat `protobuf:"varint,1,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *ListPromotionsRequest) Reset() {
-	*x = ListPromotionsRequest{}
+func (x *GetClusterConfigRequest) Reset() {
+	*x = GetClusterConfigRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[38]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2191,13 +2190,13 @@ func (x *ListPromotionsRequest) Reset() {
 	}
 }
 
-func (x *ListPromotionsRequest) String() string {
+func (x *GetClusterConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListPromotionsRequest) ProtoMessage() {}
+func (*GetClusterConfigRequest) ProtoMessage() {}
 
-func (x *ListPromotionsRequest) ProtoReflect() protoreflect.Message {
+func (x *GetClusterConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[38]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2209,35 +2208,32 @@ func (x *ListPromotionsRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListPromotionsRequest.ProtoReflect.Descriptor instead.
-func (*ListPromotionsRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetClusterConfigRequest.ProtoReflect.Descriptor instead.
+func (*GetClusterConfigRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{38}
 }
 
-func (x *ListPromotionsRequest) GetProject() string {
+func (x *GetClusterConfigRequest) GetFormat() RawFormat {
 	if x != nil {
-		return x.Project
-	}
-	return ""
-}
-
-func (x *ListPromotionsRequest) GetStage() string {
-	if x != nil && x.Stage != nil {
-		return *x.Stage
+		return x.Format
 	}
-	return ""
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-type ListPromotionsResponse struct {
+type GetClusterConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Promotions []*v1alpha1.Promotion `protobuf:"bytes,1,rep,name=promotions,proto3" json:"promotions,omitempty"`
+	// Types that are assignable to Result:
+	//
+	//	*GetClusterConfigResponse_ClusterConfig
+	//	*GetClusterConfigResponse_Raw
+	Result isGetClusterConfigResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *ListPromotionsResponse) Reset() {
-	*x = ListPromotionsResponse{}
+func (x *GetClusterConfigResponse) Reset() {
+	*x = GetClusterConfigResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[39]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2245,13 +2241,13 @@ func (x *ListPromotionsResponse) Reset() {
 	}
 }
 
-func (x *ListPromotionsResponse) String() string {
+func (x *GetClusterConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListPromotionsResponse) ProtoMessage() {}
+func (*GetClusterConfigResponse) ProtoMessage() {}
 
-func (x *ListPromotionsResponse) ProtoReflect() protoreflect.Message {
+func (x *GetClusterConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[39]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2263,29 +2259,56 @@ func (x *ListPromotionsResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListPromotionsResponse.ProtoReflect.Descriptor instead.
-func (*ListPromotionsResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetClusterConfigResponse.ProtoReflect.Descriptor instead.
+func (*GetClusterConfigResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{39}
 }
 
-func (x *ListPromotionsResponse) GetPromotions() []*v1alpha1.Promotion {
-	if x != nil {
-		return x.Promotions
+func (m *GetClusterConfigResponse) GetResult() isGetClusterConfigResponse_Result {
+	if m != nil {
+		return m.Result
 	}
 	return nil
 }
 
-type WatchPromotionsRequest struct {
+func (x *GetClusterConfigResponse) GetClusterConfig() *v1alpha1.ClusterConfig {
+	if x, ok := x.GetResult().(*GetClusterConfigResponse_ClusterConfig); ok {
+		return x.ClusterConfig
+	}
+	return nil
+}
+
+func (x *GetClusterConfigResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetClusterConfigResponse_Raw); ok {
+		return x.Raw
+	}
+	return nil
+}
+
+type isGetClusterConfigResponse_Result interface {
+	isGetClusterConfigResponse_Result()
+}
+
+type GetClusterConfigResponse_ClusterConfig struct {
+	ClusterConfig *v1alpha1.ClusterConfig `protobuf:"bytes,1,opt,name=cluster_config,json=clusterConfig,proto3,oneof"`
+}
+
+type GetClusterConfigResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+}
+
+func (*GetClusterConfigResponse_ClusterConfig) isGetClusterConfigResponse_Result() {}
+
+func (*GetClusterConfigResponse_Raw) isGetClusterConfigResponse_Result() {}
+
+type DeleteClusterConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Project string  `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage   *string `protobuf:"bytes,2,opt,name=stage,proto3,oneof" json:"stage,omitempty"`
 }
 
-func (x *WatchPromotionsRequest) Reset() {
-	*x = WatchPromotionsRequest{}
+func (x *DeleteClusterConfigRequest) Reset() {
+	*x = DeleteClusterConfigRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[40]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2293,13 +2316,13 @@ func (x *WatchPromotionsRequest) Reset() {
 	}
 }
 
-func (x *WatchPromotionsRequest) String() string {
+func (x *DeleteClusterConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchPromotionsRequest) ProtoMessage() {}
+func (*DeleteClusterConfigRequest) ProtoMessage() {}
 
-func (x *WatchPromotionsRequest) ProtoReflect() protoreflect.Message {
+func (x *DeleteClusterConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[40]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2311,36 +2334,19 @@ func (x *WatchPromotionsRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchPromotionsRequest.ProtoReflect.Descriptor instead.
-func (*WatchPromotionsRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use DeleteClusterConfigRequest.ProtoReflect.Descriptor instead.
+func (*DeleteClusterConfigRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{40}
 }
 
-func (x *WatchPromotionsRequest) GetProject() string {
-	if x != nil {
-		return x.Project
-	}
-	return ""
-}
-
-func (x *WatchPromotionsRequest) GetStage() string {
-	if x != nil && x.Stage != nil {
-		return *x.Stage
-	}
-	return ""
-}
-
-type WatchPromotionsResponse struct {
+type DeleteClusterConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3" json:"promotion,omitempty"`
-	Type      string              `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
 }
 
-func (x *WatchPromotionsResponse) Reset() {
-	*x = WatchPromotionsResponse{}
+func (x *DeleteClusterConfigResponse) Reset() {
+	*x = DeleteClusterConfigResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[41]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2348,13 +2354,13 @@ func (x *WatchPromotionsResponse) Reset() {
 	}
 }
 
-func (x *WatchPromotionsResponse) String() string {
+func (x *DeleteClusterConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchPromotionsResponse) ProtoMessage() {}
+func (*DeleteClusterConfigResponse) ProtoMessage() {}
 
-func (x *WatchPromotionsResponse) ProtoReflect() protoreflect.Message {
+func (x *DeleteClusterConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[41]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2366,37 +2372,19 @@ func (x *WatchPromotionsResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchPromotionsResponse.ProtoReflect.Descriptor instead.
-func (*WatchPromotionsResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use DeleteClusterConfigResponse.ProtoReflect.Descriptor instead.
+func (*DeleteClusterConfigResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{41}
 }
 
-func (x *WatchPromotionsResponse) GetPromotion() *v1alpha1.Promotion {
-	if x != nil {
-		return x.Promotion
-	}
-	return nil
-}
-
-func (x *WatchPromotionsResponse) GetType() string {
-	if x != nil {
-		return x.Type
-	}
-	return ""
-}
-
-type GetPromotionRequest struct {
+type WatchClusterConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *GetPromotionRequest) Reset() {
-	*x = GetPromotionRequest{}
+func (x *WatchClusterConfigRequest) Reset() {
+	*x = WatchClusterConfigRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[42]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2404,13 +2392,13 @@ func (x *GetPromotionRequest) Reset() {
 	}
 }
 
-func (x *GetPromotionRequest) String() string {
+func (x *WatchClusterConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetPromotionRequest) ProtoMessage() {}
+func (*WatchClusterConfigRequest) ProtoMessage() {}
 
-func (x *GetPromotionRequest) ProtoReflect() protoreflect.Message {
+func (x *WatchClusterConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[42]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2422,46 +2410,22 @@ func (x *GetPromotionRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetPromotionRequest.ProtoReflect.Descriptor instead.
-func (*GetPromotionRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use WatchClusterConfigRequest.ProtoReflect.Descriptor instead.
+func (*WatchClusterConfigRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{42}
 }
 
-func (x *GetPromotionRequest) GetProject() string {
-	if x != nil {
-		return x.Project
-	}
-	return ""
-}
-
-func (x *GetPromotionRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *GetPromotionRequest) GetFormat() RawFormat {
-	if x != nil {
-		return x.Format
-	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
-}
-
-type GetPromotionResponse struct {
+type WatchClusterConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// Types that are assignable to Result:
-	//
-	//	*GetPromotionResponse_Promotion
-	//	*GetPromotionResponse_Raw
-	Result isGetPromotionResponse_Result `protobuf_oneof:"result"`
+	ClusterConfig *v1alpha1.ClusterConfig `protobuf:"bytes,1,opt,name=cluster_config,json=clusterConfig,proto3" json:"cluster_config,omitempty"`
+	Type          string                  `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // ADDED / MODIFIED / DELETED
 }
 
-func (x *GetPromotionResponse) Reset() {
-	*x = GetPromotionResponse{}
+func (x *WatchClusterConfigResponse) Reset() {
+	*x = WatchClusterConfigResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[43]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2469,13 +2433,13 @@ func (x *GetPromotionResponse) Reset() {
 	}
 }
 
-func (x *GetPromotionResponse) String() string {
+func (x *WatchClusterConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetPromotionResponse) ProtoMessage() {}
+func (*WatchClusterConfigResponse) ProtoMessage() {}
 
-func (x *GetPromotionResponse) ProtoReflect() protoreflect.Message {
+func (x *WatchClusterConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[43]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2487,59 +2451,33 @@ func (x *GetPromotionResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetPromotionResponse.ProtoReflect.Descriptor instead.
-func (*GetPromotionResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use WatchClusterConfigResponse.ProtoReflect.Descriptor instead.
+func (*WatchClusterConfigResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{43}
 }
 
-func (m *GetPromotionResponse) GetResult() isGetPromotionResponse_Result {
-	if m != nil {
-		return m.Result
-	}
-	return nil
-}
-
-func (x *GetPromotionResponse) GetPromotion() *v1alpha1.Promotion {
-	if x, ok := x.GetResult().(*GetPromotionResponse_Promotion); ok {
-		return x.Promotion
+func (x *WatchClusterConfigResponse) GetClusterConfig() *v1alpha1.ClusterConfig {
+	if x != nil {
+		return x.ClusterConfig
 	}
 	return nil
 }
 
-func (x *GetPromotionResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetPromotionResponse_Raw); ok {
-		return x.Raw
+func (x *WatchClusterConfigResponse) GetType() string {
+	if x != nil {
+		return x.Type
 	}
-	return nil
-}
-
-type isGetPromotionResponse_Result interface {
-	isGetPromotionResponse_Result()
-}
-
-type GetPromotionResponse_Promotion struct {
-	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3,oneof"`
-}
-
-type GetPromotionResponse_Raw struct {
-	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+	return ""
 }
 
-func (*GetPromotionResponse_Promotion) isGetPromotionResponse_Result() {}
-
-func (*GetPromotionResponse_Raw) isGetPromotionResponse_Result() {}
-
-type WatchPromotionRequest struct {
+type RefreshClusterConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *WatchPromotionRequest) Reset() {
-	*x = WatchPromotionRequest{}
+func (x *RefreshClusterConfigRequest) Reset() {
+	*x = RefreshClusterConfigRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[44]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2547,13 +2485,13 @@ func (x *WatchPromotionRequest) Reset() {
 	}
 }
 
-func (x *WatchPromotionRequest) String() string {
+func (x *RefreshClusterConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchPromotionRequest) ProtoMessage() {}
+func (*RefreshClusterConfigRequest) ProtoMessage() {}
 
-func (x *WatchPromotionRequest) ProtoReflect() protoreflect.Message {
+func (x *RefreshClusterConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[44]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2565,36 +2503,21 @@ func (x *WatchPromotionRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchPromotionRequest.ProtoReflect.Descriptor instead.
-func (*WatchPromotionRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use RefreshClusterConfigRequest.ProtoReflect.Descriptor instead.
+func (*RefreshClusterConfigRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{44}
 }
 
-func (x *WatchPromotionRequest) GetProject() string {
-	if x != nil {
-		return x.Project
-	}
-	return ""
-}
-
-func (x *WatchPromotionRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-type WatchPromotionResponse struct {
+type RefreshClusterConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3" json:"promotion,omitempty"`
-	Type      string              `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
+	ClusterConfig *v1alpha1.ClusterConfig `protobuf:"bytes,1,opt,name=cluster_config,json=clusterConfig,proto3" json:"cluster_config,omitempty"`
 }
 
-func (x *WatchPromotionResponse) Reset() {
-	*x = WatchPromotionResponse{}
+func (x *RefreshClusterConfigResponse) Reset() {
+	*x = RefreshClusterConfigResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[45]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2602,13 +2525,13 @@ func (x *WatchPromotionResponse) Reset() {
 	}
 }
 
-func (x *WatchPromotionResponse) String() string {
+func (x *RefreshClusterConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchPromotionResponse) ProtoMessage() {}
+func (*RefreshClusterConfigResponse) ProtoMessage() {}
 
-func (x *WatchPromotionResponse) ProtoReflect() protoreflect.Message {
+func (x *RefreshClusterConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[45]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2620,36 +2543,29 @@ func (x *WatchPromotionResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchPromotionResponse.ProtoReflect.Descriptor instead.
-func (*WatchPromotionResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use RefreshClusterConfigResponse.ProtoReflect.Descriptor instead.
+func (*RefreshClusterConfigResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{45}
 }
 
-func (x *WatchPromotionResponse) GetPromotion() *v1alpha1.Promotion {
+func (x *RefreshClusterConfigResponse) GetClusterConfig() *v1alpha1.ClusterConfig {
 	if x != nil {
-		return x.Promotion
+		return x.ClusterConfig
 	}
 	return nil
 }
 
-func (x *WatchPromotionResponse) GetType() string {
-	if x != nil {
-		return x.Type
-	}
-	return ""
-}
-
-type AbortPromotionRequest struct {
+type ListPromotionsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Project string  `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Stage   *string `protobuf:"bytes,2,opt,name=stage,proto3,oneof" json:"stage,omitempty"`
 }
 
-func (x *AbortPromotionRequest) Reset() {
-	*x = AbortPromotionRequest{}
+func (x *ListPromotionsRequest) Reset() {
+	*x = ListPromotionsRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[46]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2657,13 +2573,13 @@ func (x *AbortPromotionRequest) Reset() {
 	}
 }
 
-func (x *AbortPromotionRequest) String() string {
+func (x *ListPromotionsRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*AbortPromotionRequest) ProtoMessage() {}
+func (*ListPromotionsRequest) ProtoMessage() {}
 
-func (x *AbortPromotionRequest) ProtoReflect() protoreflect.Message {
+func (x *ListPromotionsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[46]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2675,33 +2591,35 @@ func (x *AbortPromotionRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use AbortPromotionRequest.ProtoReflect.Descriptor instead.
-func (*AbortPromotionRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use ListPromotionsRequest.ProtoReflect.Descriptor instead.
+func (*ListPromotionsRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{46}
 }
 
-func (x *AbortPromotionRequest) GetProject() string {
+func (x *ListPromotionsRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *AbortPromotionRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
+func (x *ListPromotionsRequest) GetStage() string {
+	if x != nil && x.Stage != nil {
+		return *x.Stage
+	}
 	return ""
 }
 
-type AbortPromotionResponse struct {
+type ListPromotionsResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Promotions []*v1alpha1.Promotion `protobuf:"bytes,1,rep,name=promotions,proto3" json:"promotions,omitempty"`
 }
 
-func (x *AbortPromotionResponse) Reset() {
-	*x = AbortPromotionResponse{}
+func (x *ListPromotionsResponse) Reset() {
+	*x = ListPromotionsResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[47]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2709,13 +2627,13 @@ func (x *AbortPromotionResponse) Reset() {
 	}
 }
 
-func (x *AbortPromotionResponse) String() string {
+func (x *ListPromotionsResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*AbortPromotionResponse) ProtoMessage() {}
+func (*ListPromotionsResponse) ProtoMessage() {}
 
-func (x *AbortPromotionResponse) ProtoReflect() protoreflect.Message {
+func (x *ListPromotionsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[47]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2727,21 +2645,29 @@ func (x *AbortPromotionResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use AbortPromotionResponse.ProtoReflect.Descriptor instead.
-func (*AbortPromotionResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use ListPromotionsResponse.ProtoReflect.Descriptor instead.
+func (*ListPromotionsResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{47}
 }
 
-type DeleteProjectRequest struct {
+func (x *ListPromotionsResponse) GetPromotions() []*v1alpha1.Promotion {
+	if x != nil {
+		return x.Promotions
+	}
+	return nil
+}
+
+type WatchPromotionsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Project string  `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Stage   *string `protobuf:"bytes,2,opt,name=stage,proto3,oneof" json:"stage,omitempty"`
 }
 
-func (x *DeleteProjectRequest) Reset() {
-	*x = DeleteProjectRequest{}
+func (x *WatchPromotionsRequest) Reset() {
+	*x = WatchPromotionsRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[48]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2749,13 +2675,13 @@ func (x *DeleteProjectRequest) Reset() {
 	}
 }
 
-func (x *DeleteProjectRequest) String() string {
+func (x *WatchPromotionsRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteProjectRequest) ProtoMessage() {}
+func (*WatchPromotionsRequest) ProtoMessage() {}
 
-func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message {
+func (x *WatchPromotionsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[48]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2767,26 +2693,36 @@ func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteProjectRequest.ProtoReflect.Descriptor instead.
-func (*DeleteProjectRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use WatchPromotionsRequest.ProtoReflect.Descriptor instead.
+func (*WatchPromotionsRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{48}
 }
 
-func (x *DeleteProjectRequest) GetName() string {
+func (x *WatchPromotionsRequest) GetProject() string {
 	if x != nil {
-		return x.Name
+		return x.Project
 	}
 	return ""
 }
 
-type DeleteProjectResponse struct {
+func (x *WatchPromotionsRequest) GetStage() string {
+	if x != nil && x.Stage != nil {
+		return *x.Stage
+	}
+	return ""
+}
+
+type WatchPromotionsResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3" json:"promotion,omitempty"`
+	Type      string              `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
 }
 
-func (x *DeleteProjectResponse) Reset() {
-	*x = DeleteProjectResponse{}
+func (x *WatchPromotionsResponse) Reset() {
+	*x = WatchPromotionsResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[49]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2794,13 +2730,13 @@ func (x *DeleteProjectResponse) Reset() {
 	}
 }
 
-func (x *DeleteProjectResponse) String() string {
+func (x *WatchPromotionsResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteProjectResponse) ProtoMessage() {}
+func (*WatchPromotionsResponse) ProtoMessage() {}
 
-func (x *DeleteProjectResponse) ProtoReflect() protoreflect.Message {
+func (x *WatchPromotionsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[49]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2812,21 +2748,37 @@ func (x *DeleteProjectResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteProjectResponse.ProtoReflect.Descriptor instead.
-func (*DeleteProjectResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use WatchPromotionsResponse.ProtoReflect.Descriptor instead.
+func (*WatchPromotionsResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{49}
 }
 
-type DeleteProjectConfigRequest struct {
+func (x *WatchPromotionsResponse) GetPromotion() *v1alpha1.Promotion {
+	if x != nil {
+		return x.Promotion
+	}
+	return nil
+}
+
+func (x *WatchPromotionsResponse) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+type GetPromotionRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *DeleteProjectConfigRequest) Reset() {
-	*x = DeleteProjectConfigRequest{}
+func (x *GetPromotionRequest) Reset() {
+	*x = GetPromotionRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[50]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2834,13 +2786,13 @@ func (x *DeleteProjectConfigRequest) Reset() {
 	}
 }
 
-func (x *DeleteProjectConfigRequest) String() string {
+func (x *GetPromotionRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteProjectConfigRequest) ProtoMessage() {}
+func (*GetPromotionRequest) ProtoMessage() {}
 
-func (x *DeleteProjectConfigRequest) ProtoReflect() protoreflect.Message {
+func (x *GetPromotionRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[50]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2852,26 +2804,46 @@ func (x *DeleteProjectConfigRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteProjectConfigRequest.ProtoReflect.Descriptor instead.
-func (*DeleteProjectConfigRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetPromotionRequest.ProtoReflect.Descriptor instead.
+func (*GetPromotionRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{50}
 }
 
-func (x *DeleteProjectConfigRequest) GetName() string {
+func (x *GetPromotionRequest) GetProject() string {
+	if x != nil {
+		return x.Project
+	}
+	return ""
+}
+
+func (x *GetPromotionRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-type DeleteProjectConfigResponse struct {
+func (x *GetPromotionRequest) GetFormat() RawFormat {
+	if x != nil {
+		return x.Format
+	}
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
+}
+
+type GetPromotionResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Result:
+	//
+	//	*GetPromotionResponse_Promotion
+	//	*GetPromotionResponse_Raw
+	Result isGetPromotionResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *DeleteProjectConfigResponse) Reset() {
-	*x = DeleteProjectConfigResponse{}
+func (x *GetPromotionResponse) Reset() {
+	*x = GetPromotionResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[51]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2879,13 +2851,13 @@ func (x *DeleteProjectConfigResponse) Reset() {
 	}
 }
 
-func (x *DeleteProjectConfigResponse) String() string {
+func (x *GetPromotionResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteProjectConfigResponse) ProtoMessage() {}
+func (*GetPromotionResponse) ProtoMessage() {}
 
-func (x *DeleteProjectConfigResponse) ProtoReflect() protoreflect.Message {
+func (x *GetPromotionResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[51]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2897,22 +2869,59 @@ func (x *DeleteProjectConfigResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteProjectConfigResponse.ProtoReflect.Descriptor instead.
-func (*DeleteProjectConfigResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetPromotionResponse.ProtoReflect.Descriptor instead.
+func (*GetPromotionResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{51}
 }
 
-type GetProjectConfigRequest struct {
+func (m *GetPromotionResponse) GetResult() isGetPromotionResponse_Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+func (x *GetPromotionResponse) GetPromotion() *v1alpha1.Promotion {
+	if x, ok := x.GetResult().(*GetPromotionResponse_Promotion); ok {
+		return x.Promotion
+	}
+	return nil
+}
+
+func (x *GetPromotionResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetPromotionResponse_Raw); ok {
+		return x.Raw
+	}
+	return nil
+}
+
+type isGetPromotionResponse_Result interface {
+	isGetPromotionResponse_Result()
+}
+
+type GetPromotionResponse_Promotion struct {
+	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3,oneof"`
+}
+
+type GetPromotionResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+}
+
+func (*GetPromotionResponse_Promotion) isGetPromotionResponse_Result() {}
+
+func (*GetPromotionResponse_Raw) isGetPromotionResponse_Result() {}
+
+type WatchPromotionRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Name   string    `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Format RawFormat `protobuf:"varint,2,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *GetProjectConfigRequest) Reset() {
-	*x = GetProjectConfigRequest{}
+func (x *WatchPromotionRequest) Reset() {
+	*x = WatchPromotionRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[52]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2920,13 +2929,13 @@ func (x *GetProjectConfigRequest) Reset() {
 	}
 }
 
-func (x *GetProjectConfigRequest) String() string {
+func (x *WatchPromotionRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetProjectConfigRequest) ProtoMessage() {}
+func (*WatchPromotionRequest) ProtoMessage() {}
 
-func (x *GetProjectConfigRequest) ProtoReflect() protoreflect.Message {
+func (x *WatchPromotionRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[52]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2938,39 +2947,36 @@ func (x *GetProjectConfigRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetProjectConfigRequest.ProtoReflect.Descriptor instead.
-func (*GetProjectConfigRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use WatchPromotionRequest.ProtoReflect.Descriptor instead.
+func (*WatchPromotionRequest) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{52}
 }
 
-func (x *GetProjectConfigRequest) GetName() string {
+func (x *WatchPromotionRequest) GetProject() string {
 	if x != nil {
-		return x.Name
+		return x.Project
 	}
 	return ""
 }
 
-func (x *GetProjectConfigRequest) GetFormat() RawFormat {
+func (x *WatchPromotionRequest) GetName() string {
 	if x != nil {
-		return x.Format
+		return x.Name
 	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
+	return ""
 }
 
-type GetProjectConfigResponse struct {
+type WatchPromotionResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// Types that are assignable to Result:
-	//
-	//	*GetProjectConfigResponse_ProjectConfig
-	//	*GetProjectConfigResponse_Raw
-	Result isGetProjectConfigResponse_Result `protobuf_oneof:"result"`
+	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3" json:"promotion,omitempty"`
+	Type      string              `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
 }
 
-func (x *GetProjectConfigResponse) Reset() {
-	*x = GetProjectConfigResponse{}
+func (x *WatchPromotionResponse) Reset() {
+	*x = WatchPromotionResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_service_v1alpha1_service_proto_msgTypes[53]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2978,13 +2984,13 @@ func (x *GetProjectConfigResponse) Reset() {
 	}
 }
 
-func (x *GetProjectConfigResponse) String() string {
+func (x *WatchPromotionResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetProjectConfigResponse) ProtoMessage() {}
+func (*WatchPromotionResponse) ProtoMessage() {}
 
-func (x *GetProjectConfigResponse) ProtoReflect() protoreflect.Message {
+func (x *WatchPromotionResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_service_v1alpha1_service_proto_msgTypes[53]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -2996,47 +3002,202 @@ func (x *GetProjectConfigResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetProjectConfigResponse.ProtoReflect.Descriptor instead.
-func (*GetProjectConfigResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use WatchPromotionResponse.ProtoReflect.Descriptor instead.
+func (*WatchPromotionResponse) Descriptor() ([]byte, []int) {
 	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{53}
 }
 
-func (m *GetProjectConfigResponse) GetResult() isGetProjectConfigResponse_Result {
-	if m != nil {
-		return m.Result
+func (x *WatchPromotionResponse) GetPromotion() *v1alpha1.Promotion {
+	if x != nil {
+		return x.Promotion
 	}
 	return nil
 }
 
-func (x *GetProjectConfigResponse) GetProjectConfig() *v1alpha1.ProjectConfig {
-	if x, ok := x.GetResult().(*GetProjectConfigResponse_ProjectConfig); ok {
-		return x.ProjectConfig
+func (x *WatchPromotionResponse) GetType() string {
+	if x != nil {
+		return x.Type
 	}
-	return nil
+	return ""
 }
 
-func (x *GetProjectConfigResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetProjectConfigResponse_Raw); ok {
-		return x.Raw
-	}
-	return nil
+type AbortPromotionRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-type isGetProjectConfigResponse_Result interface {
-	isGetProjectConfigResponse_Result()
+func (x *AbortPromotionRequest) Reset() {
+	*x = AbortPromotionRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[54]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
-type GetProjectConfigResponse_ProjectConfig struct {
-	ProjectConfig *v1alpha1.ProjectConfig `protobuf:"bytes,1,opt,name=project_config,json=projectConfig,proto3,oneof"`
+func (x *AbortPromotionRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
 }
 
-type GetProjectConfigResponse_Raw struct {
-	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+func (*AbortPromotionRequest) ProtoMessage() {}
+
+func (x *AbortPromotionRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[54]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (*GetProjectConfigResponse_ProjectConfig) isGetProjectConfigResponse_Result() {}
+// Deprecated: Use AbortPromotionRequest.ProtoReflect.Descriptor instead.
+func (*AbortPromotionRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{54}
+}
 
-func (*GetProjectConfigResponse_Raw) isGetProjectConfigResponse_Result() {}
+func (x *AbortPromotionRequest) GetProject() string {
+	if x != nil {
+		return x.Project
+	}
+	return ""
+}
+
+func (x *AbortPromotionRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type AbortPromotionResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *AbortPromotionResponse) Reset() {
+	*x = AbortPromotionResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[55]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AbortPromotionResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AbortPromotionResponse) ProtoMessage() {}
+
+func (x *AbortPromotionResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[55]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AbortPromotionResponse.ProtoReflect.Descriptor instead.
+func (*AbortPromotionResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{55}
+}
+
+type DeleteProjectRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *DeleteProjectRequest) Reset() {
+	*x = DeleteProjectRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[56]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteProjectRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteProjectRequest) ProtoMessage() {}
+
+func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[56]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteProjectRequest.ProtoReflect.Descriptor instead.
+func (*DeleteProjectRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{56}
+}
+
+func (x *DeleteProjectRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type DeleteProjectResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DeleteProjectResponse) Reset() {
+	*x = DeleteProjectResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[57]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteProjectResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteProjectResponse) ProtoMessage() {}
+
+func (x *DeleteProjectResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[57]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteProjectResponse.ProtoReflect.Descriptor instead.
+func (*DeleteProjectResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{57}
+}
 
 type GetProjectRequest struct {
 	state         protoimpl.MessageState
@@ -3050,7 +3211,7 @@ type GetProjectRequest struct {
 func (x *GetProjectRequest) Reset() {
 	*x = GetProjectRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[54]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[58]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3063,7 +3224,7 @@ func (x *GetProjectRequest) String() string {
 func (*GetProjectRequest) ProtoMessage() {}
 
 func (x *GetProjectRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[54]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[58]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3076,7 +3237,7 @@ func (x *GetProjectRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetProjectRequest.ProtoReflect.Descriptor instead.
 func (*GetProjectRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{54}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{58}
 }
 
 func (x *GetProjectRequest) GetName() string {
@@ -3108,7 +3269,7 @@ type GetProjectResponse struct {
 func (x *GetProjectResponse) Reset() {
 	*x = GetProjectResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[55]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[59]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3121,7 +3282,7 @@ func (x *GetProjectResponse) String() string {
 func (*GetProjectResponse) ProtoMessage() {}
 
 func (x *GetProjectResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[55]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[59]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3134,7 +3295,7 @@ func (x *GetProjectResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetProjectResponse.ProtoReflect.Descriptor instead.
 func (*GetProjectResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{55}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{59}
 }
 
 func (m *GetProjectResponse) GetResult() isGetProjectResponse_Result {
@@ -3187,7 +3348,7 @@ type ListProjectsRequest struct {
 func (x *ListProjectsRequest) Reset() {
 	*x = ListProjectsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[56]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[60]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3200,7 +3361,7 @@ func (x *ListProjectsRequest) String() string {
 func (*ListProjectsRequest) ProtoMessage() {}
 
 func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[56]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[60]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3213,7 +3374,7 @@ func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectsRequest.ProtoReflect.Descriptor instead.
 func (*ListProjectsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{56}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{60}
 }
 
 func (x *ListProjectsRequest) GetPageSize() int32 {
@@ -3249,7 +3410,7 @@ type ListProjectsResponse struct {
 func (x *ListProjectsResponse) Reset() {
 	*x = ListProjectsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[57]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[61]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3262,7 +3423,7 @@ func (x *ListProjectsResponse) String() string {
 func (*ListProjectsResponse) ProtoMessage() {}
 
 func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[57]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[61]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3275,7 +3436,7 @@ func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectsResponse.ProtoReflect.Descriptor instead.
 func (*ListProjectsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{57}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{61}
 }
 
 func (x *ListProjectsResponse) GetProjects() []*v1alpha1.Project {
@@ -3292,34 +3453,32 @@ func (x *ListProjectsResponse) GetTotal() int32 {
 	return 0
 }
 
-type ApproveFreightRequest struct {
+type GetProjectConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Alias   string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
-	Stage   string `protobuf:"bytes,4,opt,name=stage,proto3" json:"stage,omitempty"`
+	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Format  RawFormat `protobuf:"varint,2,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *ApproveFreightRequest) Reset() {
-	*x = ApproveFreightRequest{}
+func (x *GetProjectConfigRequest) Reset() {
+	*x = GetProjectConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[58]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[62]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ApproveFreightRequest) String() string {
+func (x *GetProjectConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ApproveFreightRequest) ProtoMessage() {}
+func (*GetProjectConfigRequest) ProtoMessage() {}
 
-func (x *ApproveFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[58]
+func (x *GetProjectConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[62]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3330,62 +3489,54 @@ func (x *ApproveFreightRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ApproveFreightRequest.ProtoReflect.Descriptor instead.
-func (*ApproveFreightRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{58}
+// Deprecated: Use GetProjectConfigRequest.ProtoReflect.Descriptor instead.
+func (*GetProjectConfigRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{62}
 }
 
-func (x *ApproveFreightRequest) GetProject() string {
+func (x *GetProjectConfigRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *ApproveFreightRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *ApproveFreightRequest) GetAlias() string {
-	if x != nil {
-		return x.Alias
-	}
-	return ""
-}
-
-func (x *ApproveFreightRequest) GetStage() string {
+func (x *GetProjectConfigRequest) GetFormat() RawFormat {
 	if x != nil {
-		return x.Stage
+		return x.Format
 	}
-	return ""
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-type ApproveFreightResponse struct {
+type GetProjectConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-}
 
-func (x *ApproveFreightResponse) Reset() {
-	*x = ApproveFreightResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[59]
+	// Types that are assignable to Result:
+	//
+	//	*GetProjectConfigResponse_ProjectConfig
+	//	*GetProjectConfigResponse_Raw
+	Result isGetProjectConfigResponse_Result `protobuf_oneof:"result"`
+}
+
+func (x *GetProjectConfigResponse) Reset() {
+	*x = GetProjectConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[63]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ApproveFreightResponse) String() string {
+func (x *GetProjectConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ApproveFreightResponse) ProtoMessage() {}
+func (*GetProjectConfigResponse) ProtoMessage() {}
 
-func (x *ApproveFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[59]
+func (x *GetProjectConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[63]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3396,38 +3547,73 @@ func (x *ApproveFreightResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ApproveFreightResponse.ProtoReflect.Descriptor instead.
-func (*ApproveFreightResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{59}
+// Deprecated: Use GetProjectConfigResponse.ProtoReflect.Descriptor instead.
+func (*GetProjectConfigResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{63}
 }
 
-type DeleteFreightRequest struct {
+func (m *GetProjectConfigResponse) GetResult() isGetProjectConfigResponse_Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+func (x *GetProjectConfigResponse) GetProjectConfig() *v1alpha1.ProjectConfig {
+	if x, ok := x.GetResult().(*GetProjectConfigResponse_ProjectConfig); ok {
+		return x.ProjectConfig
+	}
+	return nil
+}
+
+func (x *GetProjectConfigResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetProjectConfigResponse_Raw); ok {
+		return x.Raw
+	}
+	return nil
+}
+
+type isGetProjectConfigResponse_Result interface {
+	isGetProjectConfigResponse_Result()
+}
+
+type GetProjectConfigResponse_ProjectConfig struct {
+	ProjectConfig *v1alpha1.ProjectConfig `protobuf:"bytes,1,opt,name=project_config,json=projectConfig,proto3,oneof"`
+}
+
+type GetProjectConfigResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+}
+
+func (*GetProjectConfigResponse_ProjectConfig) isGetProjectConfigResponse_Result() {}
+
+func (*GetProjectConfigResponse_Raw) isGetProjectConfigResponse_Result() {}
+
+type DeleteProjectConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Alias   string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
 }
 
-func (x *DeleteFreightRequest) Reset() {
-	*x = DeleteFreightRequest{}
+func (x *DeleteProjectConfigRequest) Reset() {
+	*x = DeleteProjectConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[60]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[64]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteFreightRequest) String() string {
+func (x *DeleteProjectConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteFreightRequest) ProtoMessage() {}
+func (*DeleteProjectConfigRequest) ProtoMessage() {}
 
-func (x *DeleteFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[60]
+func (x *DeleteProjectConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[64]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3438,55 +3624,41 @@ func (x *DeleteFreightRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteFreightRequest.ProtoReflect.Descriptor instead.
-func (*DeleteFreightRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{60}
+// Deprecated: Use DeleteProjectConfigRequest.ProtoReflect.Descriptor instead.
+func (*DeleteProjectConfigRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{64}
 }
 
-func (x *DeleteFreightRequest) GetProject() string {
+func (x *DeleteProjectConfigRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *DeleteFreightRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *DeleteFreightRequest) GetAlias() string {
-	if x != nil {
-		return x.Alias
-	}
-	return ""
-}
-
-type DeleteFreightResponse struct {
+type DeleteProjectConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
 
-func (x *DeleteFreightResponse) Reset() {
-	*x = DeleteFreightResponse{}
+func (x *DeleteProjectConfigResponse) Reset() {
+	*x = DeleteProjectConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[61]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[65]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteFreightResponse) String() string {
+func (x *DeleteProjectConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteFreightResponse) ProtoMessage() {}
+func (*DeleteProjectConfigResponse) ProtoMessage() {}
 
-func (x *DeleteFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[61]
+func (x *DeleteProjectConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[65]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3497,39 +3669,36 @@ func (x *DeleteFreightResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteFreightResponse.ProtoReflect.Descriptor instead.
-func (*DeleteFreightResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{61}
+// Deprecated: Use DeleteProjectConfigResponse.ProtoReflect.Descriptor instead.
+func (*DeleteProjectConfigResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{65}
 }
 
-type GetFreightRequest struct {
+type WatchProjectConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Alias   string    `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
-	Format  RawFormat `protobuf:"varint,4,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
 }
 
-func (x *GetFreightRequest) Reset() {
-	*x = GetFreightRequest{}
+func (x *WatchProjectConfigRequest) Reset() {
+	*x = WatchProjectConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[62]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[66]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetFreightRequest) String() string {
+func (x *WatchProjectConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetFreightRequest) ProtoMessage() {}
+func (*WatchProjectConfigRequest) ProtoMessage() {}
 
-func (x *GetFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[62]
+func (x *WatchProjectConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[66]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3540,68 +3709,44 @@ func (x *GetFreightRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetFreightRequest.ProtoReflect.Descriptor instead.
-func (*GetFreightRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{62}
+// Deprecated: Use WatchProjectConfigRequest.ProtoReflect.Descriptor instead.
+func (*WatchProjectConfigRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{66}
 }
 
-func (x *GetFreightRequest) GetProject() string {
+func (x *WatchProjectConfigRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *GetFreightRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *GetFreightRequest) GetAlias() string {
-	if x != nil {
-		return x.Alias
-	}
-	return ""
-}
-
-func (x *GetFreightRequest) GetFormat() RawFormat {
-	if x != nil {
-		return x.Format
-	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
-}
-
-type GetFreightResponse struct {
+type WatchProjectConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// Types that are assignable to Result:
-	//
-	//	*GetFreightResponse_Freight
-	//	*GetFreightResponse_Raw
-	Result isGetFreightResponse_Result `protobuf_oneof:"result"`
+	ProjectConfig *v1alpha1.ProjectConfig `protobuf:"bytes,1,opt,name=project_config,json=projectConfig,proto3" json:"project_config,omitempty"`
+	Type          string                  `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // ADDED / MODIFIED / DELETED
 }
 
-func (x *GetFreightResponse) Reset() {
-	*x = GetFreightResponse{}
+func (x *WatchProjectConfigResponse) Reset() {
+	*x = WatchProjectConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[63]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[67]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetFreightResponse) String() string {
+func (x *WatchProjectConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetFreightResponse) ProtoMessage() {}
+func (*WatchProjectConfigResponse) ProtoMessage() {}
 
-func (x *GetFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[63]
+func (x *WatchProjectConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[67]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3612,49 +3757,26 @@ func (x *GetFreightResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetFreightResponse.ProtoReflect.Descriptor instead.
-func (*GetFreightResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{63}
-}
-
-func (m *GetFreightResponse) GetResult() isGetFreightResponse_Result {
-	if m != nil {
-		return m.Result
-	}
-	return nil
+// Deprecated: Use WatchProjectConfigResponse.ProtoReflect.Descriptor instead.
+func (*WatchProjectConfigResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{67}
 }
 
-func (x *GetFreightResponse) GetFreight() *v1alpha1.Freight {
-	if x, ok := x.GetResult().(*GetFreightResponse_Freight); ok {
-		return x.Freight
+func (x *WatchProjectConfigResponse) GetProjectConfig() *v1alpha1.ProjectConfig {
+	if x != nil {
+		return x.ProjectConfig
 	}
 	return nil
 }
 
-func (x *GetFreightResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetFreightResponse_Raw); ok {
-		return x.Raw
+func (x *WatchProjectConfigResponse) GetType() string {
+	if x != nil {
+		return x.Type
 	}
-	return nil
-}
-
-type isGetFreightResponse_Result interface {
-	isGetFreightResponse_Result()
-}
-
-type GetFreightResponse_Freight struct {
-	Freight *v1alpha1.Freight `protobuf:"bytes,1,opt,name=freight,proto3,oneof"`
-}
-
-type GetFreightResponse_Raw struct {
-	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+	return ""
 }
 
-func (*GetFreightResponse_Freight) isGetFreightResponse_Result() {}
-
-func (*GetFreightResponse_Raw) isGetFreightResponse_Result() {}
-
-type WatchFreightRequest struct {
+type RefreshProjectConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -3662,23 +3784,23 @@ type WatchFreightRequest struct {
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
 }
 
-func (x *WatchFreightRequest) Reset() {
-	*x = WatchFreightRequest{}
+func (x *RefreshProjectConfigRequest) Reset() {
+	*x = RefreshProjectConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[64]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[68]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *WatchFreightRequest) String() string {
+func (x *RefreshProjectConfigRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchFreightRequest) ProtoMessage() {}
+func (*RefreshProjectConfigRequest) ProtoMessage() {}
 
-func (x *WatchFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[64]
+func (x *RefreshProjectConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[68]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3689,44 +3811,43 @@ func (x *WatchFreightRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchFreightRequest.ProtoReflect.Descriptor instead.
-func (*WatchFreightRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{64}
+// Deprecated: Use RefreshProjectConfigRequest.ProtoReflect.Descriptor instead.
+func (*RefreshProjectConfigRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{68}
 }
 
-func (x *WatchFreightRequest) GetProject() string {
+func (x *RefreshProjectConfigRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-type WatchFreightResponse struct {
+type RefreshProjectConfigResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Freight *v1alpha1.Freight `protobuf:"bytes,1,opt,name=freight,proto3" json:"freight,omitempty"`
-	Type    string            `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // ADDED / MODIFIED / DELETED
+	ProjectConfig *v1alpha1.ProjectConfig `protobuf:"bytes,1,opt,name=project_config,json=projectConfig,proto3" json:"project_config,omitempty"`
 }
 
-func (x *WatchFreightResponse) Reset() {
-	*x = WatchFreightResponse{}
+func (x *RefreshProjectConfigResponse) Reset() {
+	*x = RefreshProjectConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[65]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[69]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *WatchFreightResponse) String() string {
+func (x *RefreshProjectConfigResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchFreightResponse) ProtoMessage() {}
+func (*RefreshProjectConfigResponse) ProtoMessage() {}
 
-func (x *WatchFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[65]
+func (x *RefreshProjectConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[69]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3737,53 +3858,46 @@ func (x *WatchFreightResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchFreightResponse.ProtoReflect.Descriptor instead.
-func (*WatchFreightResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{65}
+// Deprecated: Use RefreshProjectConfigResponse.ProtoReflect.Descriptor instead.
+func (*RefreshProjectConfigResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{69}
 }
 
-func (x *WatchFreightResponse) GetFreight() *v1alpha1.Freight {
+func (x *RefreshProjectConfigResponse) GetProjectConfig() *v1alpha1.ProjectConfig {
 	if x != nil {
-		return x.Freight
+		return x.ProjectConfig
 	}
 	return nil
 }
 
-func (x *WatchFreightResponse) GetType() string {
-	if x != nil {
-		return x.Type
-	}
-	return ""
-}
-
-type PromoteToStageRequest struct {
+type ApproveFreightRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project      string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage        string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
-	Freight      string `protobuf:"bytes,3,opt,name=freight,proto3" json:"freight,omitempty"`
-	FreightAlias string `protobuf:"bytes,4,opt,name=freight_alias,json=freightAlias,proto3" json:"freight_alias,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Alias   string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
+	Stage   string `protobuf:"bytes,4,opt,name=stage,proto3" json:"stage,omitempty"`
 }
 
-func (x *PromoteToStageRequest) Reset() {
-	*x = PromoteToStageRequest{}
+func (x *ApproveFreightRequest) Reset() {
+	*x = ApproveFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[66]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[70]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *PromoteToStageRequest) String() string {
+func (x *ApproveFreightRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*PromoteToStageRequest) ProtoMessage() {}
+func (*ApproveFreightRequest) ProtoMessage() {}
 
-func (x *PromoteToStageRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[66]
+func (x *ApproveFreightRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[70]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3794,64 +3908,62 @@ func (x *PromoteToStageRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use PromoteToStageRequest.ProtoReflect.Descriptor instead.
-func (*PromoteToStageRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{66}
+// Deprecated: Use ApproveFreightRequest.ProtoReflect.Descriptor instead.
+func (*ApproveFreightRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{70}
 }
 
-func (x *PromoteToStageRequest) GetProject() string {
+func (x *ApproveFreightRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *PromoteToStageRequest) GetStage() string {
+func (x *ApproveFreightRequest) GetName() string {
 	if x != nil {
-		return x.Stage
+		return x.Name
 	}
 	return ""
 }
 
-func (x *PromoteToStageRequest) GetFreight() string {
+func (x *ApproveFreightRequest) GetAlias() string {
 	if x != nil {
-		return x.Freight
+		return x.Alias
 	}
 	return ""
 }
 
-func (x *PromoteToStageRequest) GetFreightAlias() string {
+func (x *ApproveFreightRequest) GetStage() string {
 	if x != nil {
-		return x.FreightAlias
+		return x.Stage
 	}
 	return ""
 }
 
-type PromoteToStageResponse struct {
+type ApproveFreightResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3" json:"promotion,omitempty"`
 }
 
-func (x *PromoteToStageResponse) Reset() {
-	*x = PromoteToStageResponse{}
+func (x *ApproveFreightResponse) Reset() {
+	*x = ApproveFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[67]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[71]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *PromoteToStageResponse) String() string {
+func (x *ApproveFreightResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*PromoteToStageResponse) ProtoMessage() {}
+func (*ApproveFreightResponse) ProtoMessage() {}
 
-func (x *PromoteToStageResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[67]
+func (x *ApproveFreightResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[71]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3862,46 +3974,38 @@ func (x *PromoteToStageResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use PromoteToStageResponse.ProtoReflect.Descriptor instead.
-func (*PromoteToStageResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{67}
-}
-
-func (x *PromoteToStageResponse) GetPromotion() *v1alpha1.Promotion {
-	if x != nil {
-		return x.Promotion
-	}
-	return nil
+// Deprecated: Use ApproveFreightResponse.ProtoReflect.Descriptor instead.
+func (*ApproveFreightResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{71}
 }
 
-type PromoteDownstreamRequest struct {
+type DeleteFreightRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project      string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage        string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
-	Freight      string `protobuf:"bytes,3,opt,name=freight,proto3" json:"freight,omitempty"`
-	FreightAlias string `protobuf:"bytes,4,opt,name=freight_alias,json=freightAlias,proto3" json:"freight_alias,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Alias   string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
 }
 
-func (x *PromoteDownstreamRequest) Reset() {
-	*x = PromoteDownstreamRequest{}
+func (x *DeleteFreightRequest) Reset() {
+	*x = DeleteFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[68]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[72]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *PromoteDownstreamRequest) String() string {
+func (x *DeleteFreightRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*PromoteDownstreamRequest) ProtoMessage() {}
+func (*DeleteFreightRequest) ProtoMessage() {}
 
-func (x *PromoteDownstreamRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[68]
+func (x *DeleteFreightRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[72]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3912,64 +4016,55 @@ func (x *PromoteDownstreamRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use PromoteDownstreamRequest.ProtoReflect.Descriptor instead.
-func (*PromoteDownstreamRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{68}
+// Deprecated: Use DeleteFreightRequest.ProtoReflect.Descriptor instead.
+func (*DeleteFreightRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{72}
 }
 
-func (x *PromoteDownstreamRequest) GetProject() string {
+func (x *DeleteFreightRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *PromoteDownstreamRequest) GetStage() string {
-	if x != nil {
-		return x.Stage
-	}
-	return ""
-}
-
-func (x *PromoteDownstreamRequest) GetFreight() string {
+func (x *DeleteFreightRequest) GetName() string {
 	if x != nil {
-		return x.Freight
+		return x.Name
 	}
 	return ""
 }
 
-func (x *PromoteDownstreamRequest) GetFreightAlias() string {
+func (x *DeleteFreightRequest) GetAlias() string {
 	if x != nil {
-		return x.FreightAlias
+		return x.Alias
 	}
 	return ""
 }
 
-type PromoteDownstreamResponse struct {
+type DeleteFreightResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Promotions []*v1alpha1.Promotion `protobuf:"bytes,1,rep,name=promotions,proto3" json:"promotions,omitempty"`
 }
 
-func (x *PromoteDownstreamResponse) Reset() {
-	*x = PromoteDownstreamResponse{}
+func (x *DeleteFreightResponse) Reset() {
+	*x = DeleteFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[69]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[73]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *PromoteDownstreamResponse) String() string {
+func (x *DeleteFreightResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*PromoteDownstreamResponse) ProtoMessage() {}
+func (*DeleteFreightResponse) ProtoMessage() {}
 
-func (x *PromoteDownstreamResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[69]
+func (x *DeleteFreightResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[73]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3980,49 +4075,39 @@ func (x *PromoteDownstreamResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use PromoteDownstreamResponse.ProtoReflect.Descriptor instead.
-func (*PromoteDownstreamResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{69}
-}
-
-func (x *PromoteDownstreamResponse) GetPromotions() []*v1alpha1.Promotion {
-	if x != nil {
-		return x.Promotions
-	}
-	return nil
+// Deprecated: Use DeleteFreightResponse.ProtoReflect.Descriptor instead.
+func (*DeleteFreightResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{73}
 }
 
-type QueryFreightRequest struct {
+type GetFreightRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string   `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage   string   `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
-	GroupBy string   `protobuf:"bytes,3,opt,name=group_by,json=groupBy,proto3" json:"group_by,omitempty"`
-	Group   string   `protobuf:"bytes,4,opt,name=group,proto3" json:"group,omitempty"`
-	OrderBy string   `protobuf:"bytes,5,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
-	Reverse bool     `protobuf:"varint,6,opt,name=reverse,proto3" json:"reverse,omitempty"`
-	Origins []string `protobuf:"bytes,7,rep,name=origins,proto3" json:"origins,omitempty"`
+	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Alias   string    `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
+	Format  RawFormat `protobuf:"varint,4,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *QueryFreightRequest) Reset() {
-	*x = QueryFreightRequest{}
+func (x *GetFreightRequest) Reset() {
+	*x = GetFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[70]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[74]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *QueryFreightRequest) String() string {
+func (x *GetFreightRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*QueryFreightRequest) ProtoMessage() {}
+func (*GetFreightRequest) ProtoMessage() {}
 
-func (x *QueryFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[70]
+func (x *GetFreightRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[74]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4033,85 +4118,68 @@ func (x *QueryFreightRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use QueryFreightRequest.ProtoReflect.Descriptor instead.
-func (*QueryFreightRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{70}
+// Deprecated: Use GetFreightRequest.ProtoReflect.Descriptor instead.
+func (*GetFreightRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{74}
 }
 
-func (x *QueryFreightRequest) GetProject() string {
+func (x *GetFreightRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *QueryFreightRequest) GetStage() string {
-	if x != nil {
-		return x.Stage
-	}
-	return ""
-}
-
-func (x *QueryFreightRequest) GetGroupBy() string {
-	if x != nil {
-		return x.GroupBy
-	}
-	return ""
-}
-
-func (x *QueryFreightRequest) GetGroup() string {
+func (x *GetFreightRequest) GetName() string {
 	if x != nil {
-		return x.Group
+		return x.Name
 	}
 	return ""
 }
 
-func (x *QueryFreightRequest) GetOrderBy() string {
+func (x *GetFreightRequest) GetAlias() string {
 	if x != nil {
-		return x.OrderBy
+		return x.Alias
 	}
 	return ""
 }
 
-func (x *QueryFreightRequest) GetReverse() bool {
-	if x != nil {
-		return x.Reverse
-	}
-	return false
-}
-
-func (x *QueryFreightRequest) GetOrigins() []string {
+func (x *GetFreightRequest) GetFormat() RawFormat {
 	if x != nil {
-		return x.Origins
+		return x.Format
 	}
-	return nil
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-type QueryFreightResponse struct {
+type GetFreightResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Groups map[string]*FreightList `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	// Types that are assignable to Result:
+	//
+	//	*GetFreightResponse_Freight
+	//	*GetFreightResponse_Raw
+	Result isGetFreightResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *QueryFreightResponse) Reset() {
-	*x = QueryFreightResponse{}
+func (x *GetFreightResponse) Reset() {
+	*x = GetFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[71]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[75]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *QueryFreightResponse) String() string {
+func (x *GetFreightResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*QueryFreightResponse) ProtoMessage() {}
+func (*GetFreightResponse) ProtoMessage() {}
 
-func (x *QueryFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[71]
+func (x *GetFreightResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[75]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4122,93 +4190,73 @@ func (x *QueryFreightResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use QueryFreightResponse.ProtoReflect.Descriptor instead.
-func (*QueryFreightResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{71}
+// Deprecated: Use GetFreightResponse.ProtoReflect.Descriptor instead.
+func (*GetFreightResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{75}
 }
 
-func (x *QueryFreightResponse) GetGroups() map[string]*FreightList {
-	if x != nil {
-		return x.Groups
+func (m *GetFreightResponse) GetResult() isGetFreightResponse_Result {
+	if m != nil {
+		return m.Result
 	}
 	return nil
 }
 
-type FreightList struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Freight []*v1alpha1.Freight `protobuf:"bytes,1,rep,name=freight,proto3" json:"freight,omitempty"`
+func (x *GetFreightResponse) GetFreight() *v1alpha1.Freight {
+	if x, ok := x.GetResult().(*GetFreightResponse_Freight); ok {
+		return x.Freight
+	}
+	return nil
 }
 
-func (x *FreightList) Reset() {
-	*x = FreightList{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[72]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
+func (x *GetFreightResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetFreightResponse_Raw); ok {
+		return x.Raw
 	}
+	return nil
 }
 
-func (x *FreightList) String() string {
-	return protoimpl.X.MessageStringOf(x)
+type isGetFreightResponse_Result interface {
+	isGetFreightResponse_Result()
 }
 
-func (*FreightList) ProtoMessage() {}
-
-func (x *FreightList) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[72]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
+type GetFreightResponse_Freight struct {
+	Freight *v1alpha1.Freight `protobuf:"bytes,1,opt,name=freight,proto3,oneof"`
 }
 
-// Deprecated: Use FreightList.ProtoReflect.Descriptor instead.
-func (*FreightList) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{72}
+type GetFreightResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
 }
 
-func (x *FreightList) GetFreight() []*v1alpha1.Freight {
-	if x != nil {
-		return x.Freight
-	}
-	return nil
-}
+func (*GetFreightResponse_Freight) isGetFreightResponse_Result() {}
 
-type UpdateFreightAliasRequest struct {
+func (*GetFreightResponse_Raw) isGetFreightResponse_Result() {}
+
+type WatchFreightRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project  string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name     string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	OldAlias string `protobuf:"bytes,3,opt,name=old_alias,json=oldAlias,proto3" json:"old_alias,omitempty"`
-	NewAlias string `protobuf:"bytes,4,opt,name=new_alias,json=newAlias,proto3" json:"new_alias,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
 }
 
-func (x *UpdateFreightAliasRequest) Reset() {
-	*x = UpdateFreightAliasRequest{}
+func (x *WatchFreightRequest) Reset() {
+	*x = WatchFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[73]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[76]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *UpdateFreightAliasRequest) String() string {
+func (x *WatchFreightRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*UpdateFreightAliasRequest) ProtoMessage() {}
+func (*WatchFreightRequest) ProtoMessage() {}
 
-func (x *UpdateFreightAliasRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[73]
+func (x *WatchFreightRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[76]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4219,62 +4267,44 @@ func (x *UpdateFreightAliasRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use UpdateFreightAliasRequest.ProtoReflect.Descriptor instead.
-func (*UpdateFreightAliasRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{73}
+// Deprecated: Use WatchFreightRequest.ProtoReflect.Descriptor instead.
+func (*WatchFreightRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{76}
 }
 
-func (x *UpdateFreightAliasRequest) GetProject() string {
+func (x *WatchFreightRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *UpdateFreightAliasRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *UpdateFreightAliasRequest) GetOldAlias() string {
-	if x != nil {
-		return x.OldAlias
-	}
-	return ""
-}
-
-func (x *UpdateFreightAliasRequest) GetNewAlias() string {
-	if x != nil {
-		return x.NewAlias
-	}
-	return ""
-}
-
-type UpdateFreightAliasResponse struct {
+type WatchFreightResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Freight *v1alpha1.Freight `protobuf:"bytes,1,opt,name=freight,proto3" json:"freight,omitempty"`
+	Type    string            `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // ADDED / MODIFIED / DELETED
 }
 
-func (x *UpdateFreightAliasResponse) Reset() {
-	*x = UpdateFreightAliasResponse{}
+func (x *WatchFreightResponse) Reset() {
+	*x = WatchFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[74]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[77]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *UpdateFreightAliasResponse) String() string {
+func (x *WatchFreightResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*UpdateFreightAliasResponse) ProtoMessage() {}
+func (*WatchFreightResponse) ProtoMessage() {}
 
-func (x *UpdateFreightAliasResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[74]
+func (x *WatchFreightResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[77]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4285,37 +4315,53 @@ func (x *UpdateFreightAliasResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use UpdateFreightAliasResponse.ProtoReflect.Descriptor instead.
-func (*UpdateFreightAliasResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{74}
+// Deprecated: Use WatchFreightResponse.ProtoReflect.Descriptor instead.
+func (*WatchFreightResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{77}
 }
 
-type ReverifyRequest struct {
+func (x *WatchFreightResponse) GetFreight() *v1alpha1.Freight {
+	if x != nil {
+		return x.Freight
+	}
+	return nil
+}
+
+func (x *WatchFreightResponse) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+type PromoteToStageRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage   string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
+	Project      string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Stage        string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
+	Freight      string `protobuf:"bytes,3,opt,name=freight,proto3" json:"freight,omitempty"`
+	FreightAlias string `protobuf:"bytes,4,opt,name=freight_alias,json=freightAlias,proto3" json:"freight_alias,omitempty"`
 }
 
-func (x *ReverifyRequest) Reset() {
-	*x = ReverifyRequest{}
+func (x *PromoteToStageRequest) Reset() {
+	*x = PromoteToStageRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[75]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[78]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ReverifyRequest) String() string {
+func (x *PromoteToStageRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ReverifyRequest) ProtoMessage() {}
+func (*PromoteToStageRequest) ProtoMessage() {}
 
-func (x *ReverifyRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[75]
+func (x *PromoteToStageRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[78]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4326,48 +4372,64 @@ func (x *ReverifyRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ReverifyRequest.ProtoReflect.Descriptor instead.
-func (*ReverifyRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{75}
+// Deprecated: Use PromoteToStageRequest.ProtoReflect.Descriptor instead.
+func (*PromoteToStageRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{78}
 }
 
-func (x *ReverifyRequest) GetProject() string {
+func (x *PromoteToStageRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *ReverifyRequest) GetStage() string {
+func (x *PromoteToStageRequest) GetStage() string {
 	if x != nil {
 		return x.Stage
 	}
 	return ""
 }
 
-type ReverifyResponse struct {
+func (x *PromoteToStageRequest) GetFreight() string {
+	if x != nil {
+		return x.Freight
+	}
+	return ""
+}
+
+func (x *PromoteToStageRequest) GetFreightAlias() string {
+	if x != nil {
+		return x.FreightAlias
+	}
+	return ""
+}
+
+type PromoteToStageResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Promotion *v1alpha1.Promotion `protobuf:"bytes,1,opt,name=promotion,proto3" json:"promotion,omitempty"`
 }
 
-func (x *ReverifyResponse) Reset() {
-	*x = ReverifyResponse{}
+func (x *PromoteToStageResponse) Reset() {
+	*x = PromoteToStageResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[76]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[79]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ReverifyResponse) String() string {
+func (x *PromoteToStageResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ReverifyResponse) ProtoMessage() {}
+func (*PromoteToStageResponse) ProtoMessage() {}
 
-func (x *ReverifyResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[76]
+func (x *PromoteToStageResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[79]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4378,37 +4440,46 @@ func (x *ReverifyResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ReverifyResponse.ProtoReflect.Descriptor instead.
-func (*ReverifyResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{76}
+// Deprecated: Use PromoteToStageResponse.ProtoReflect.Descriptor instead.
+func (*PromoteToStageResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{79}
 }
 
-type AbortVerificationRequest struct {
+func (x *PromoteToStageResponse) GetPromotion() *v1alpha1.Promotion {
+	if x != nil {
+		return x.Promotion
+	}
+	return nil
+}
+
+type PromoteDownstreamRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Stage   string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
+	Project      string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Stage        string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
+	Freight      string `protobuf:"bytes,3,opt,name=freight,proto3" json:"freight,omitempty"`
+	FreightAlias string `protobuf:"bytes,4,opt,name=freight_alias,json=freightAlias,proto3" json:"freight_alias,omitempty"`
 }
 
-func (x *AbortVerificationRequest) Reset() {
-	*x = AbortVerificationRequest{}
+func (x *PromoteDownstreamRequest) Reset() {
+	*x = PromoteDownstreamRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[77]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[80]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *AbortVerificationRequest) String() string {
+func (x *PromoteDownstreamRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*AbortVerificationRequest) ProtoMessage() {}
+func (*PromoteDownstreamRequest) ProtoMessage() {}
 
-func (x *AbortVerificationRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[77]
+func (x *PromoteDownstreamRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[80]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4419,48 +4490,64 @@ func (x *AbortVerificationRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use AbortVerificationRequest.ProtoReflect.Descriptor instead.
-func (*AbortVerificationRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{77}
+// Deprecated: Use PromoteDownstreamRequest.ProtoReflect.Descriptor instead.
+func (*PromoteDownstreamRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{80}
 }
 
-func (x *AbortVerificationRequest) GetProject() string {
+func (x *PromoteDownstreamRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *AbortVerificationRequest) GetStage() string {
+func (x *PromoteDownstreamRequest) GetStage() string {
 	if x != nil {
 		return x.Stage
 	}
 	return ""
 }
 
-type AbortVerificationResponse struct {
-	state         protoimpl.MessageState
+func (x *PromoteDownstreamRequest) GetFreight() string {
+	if x != nil {
+		return x.Freight
+	}
+	return ""
+}
+
+func (x *PromoteDownstreamRequest) GetFreightAlias() string {
+	if x != nil {
+		return x.FreightAlias
+	}
+	return ""
+}
+
+type PromoteDownstreamResponse struct {
+	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Promotions []*v1alpha1.Promotion `protobuf:"bytes,1,rep,name=promotions,proto3" json:"promotions,omitempty"`
 }
 
-func (x *AbortVerificationResponse) Reset() {
-	*x = AbortVerificationResponse{}
+func (x *PromoteDownstreamResponse) Reset() {
+	*x = PromoteDownstreamResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[78]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[81]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *AbortVerificationResponse) String() string {
+func (x *PromoteDownstreamResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*AbortVerificationResponse) ProtoMessage() {}
+func (*PromoteDownstreamResponse) ProtoMessage() {}
 
-func (x *AbortVerificationResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[78]
+func (x *PromoteDownstreamResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[81]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4471,36 +4558,49 @@ func (x *AbortVerificationResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use AbortVerificationResponse.ProtoReflect.Descriptor instead.
-func (*AbortVerificationResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{78}
+// Deprecated: Use PromoteDownstreamResponse.ProtoReflect.Descriptor instead.
+func (*PromoteDownstreamResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{81}
 }
 
-type ListWarehousesRequest struct {
+func (x *PromoteDownstreamResponse) GetPromotions() []*v1alpha1.Promotion {
+	if x != nil {
+		return x.Promotions
+	}
+	return nil
+}
+
+type QueryFreightRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Project string   `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Stage   string   `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
+	GroupBy string   `protobuf:"bytes,3,opt,name=group_by,json=groupBy,proto3" json:"group_by,omitempty"`
+	Group   string   `protobuf:"bytes,4,opt,name=group,proto3" json:"group,omitempty"`
+	OrderBy string   `protobuf:"bytes,5,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
+	Reverse bool     `protobuf:"varint,6,opt,name=reverse,proto3" json:"reverse,omitempty"`
+	Origins []string `protobuf:"bytes,7,rep,name=origins,proto3" json:"origins,omitempty"`
 }
 
-func (x *ListWarehousesRequest) Reset() {
-	*x = ListWarehousesRequest{}
+func (x *QueryFreightRequest) Reset() {
+	*x = QueryFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[79]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[82]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListWarehousesRequest) String() string {
+func (x *QueryFreightRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListWarehousesRequest) ProtoMessage() {}
+func (*QueryFreightRequest) ProtoMessage() {}
 
-func (x *ListWarehousesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[79]
+func (x *QueryFreightRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[82]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4511,43 +4611,85 @@ func (x *ListWarehousesRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListWarehousesRequest.ProtoReflect.Descriptor instead.
-func (*ListWarehousesRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{79}
+// Deprecated: Use QueryFreightRequest.ProtoReflect.Descriptor instead.
+func (*QueryFreightRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{82}
 }
 
-func (x *ListWarehousesRequest) GetProject() string {
+func (x *QueryFreightRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-type ListWarehousesResponse struct {
+func (x *QueryFreightRequest) GetStage() string {
+	if x != nil {
+		return x.Stage
+	}
+	return ""
+}
+
+func (x *QueryFreightRequest) GetGroupBy() string {
+	if x != nil {
+		return x.GroupBy
+	}
+	return ""
+}
+
+func (x *QueryFreightRequest) GetGroup() string {
+	if x != nil {
+		return x.Group
+	}
+	return ""
+}
+
+func (x *QueryFreightRequest) GetOrderBy() string {
+	if x != nil {
+		return x.OrderBy
+	}
+	return ""
+}
+
+func (x *QueryFreightRequest) GetReverse() bool {
+	if x != nil {
+		return x.Reverse
+	}
+	return false
+}
+
+func (x *QueryFreightRequest) GetOrigins() []string {
+	if x != nil {
+		return x.Origins
+	}
+	return nil
+}
+
+type QueryFreightResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Warehouses []*v1alpha1.Warehouse `protobuf:"bytes,1,rep,name=warehouses,proto3" json:"warehouses,omitempty"`
+	Groups map[string]*FreightList `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 }
 
-func (x *ListWarehousesResponse) Reset() {
-	*x = ListWarehousesResponse{}
+func (x *QueryFreightResponse) Reset() {
+	*x = QueryFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[80]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[83]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListWarehousesResponse) String() string {
+func (x *QueryFreightResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListWarehousesResponse) ProtoMessage() {}
+func (*QueryFreightResponse) ProtoMessage() {}
 
-func (x *ListWarehousesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[80]
+func (x *QueryFreightResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[83]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4558,45 +4700,43 @@ func (x *ListWarehousesResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListWarehousesResponse.ProtoReflect.Descriptor instead.
-func (*ListWarehousesResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{80}
+// Deprecated: Use QueryFreightResponse.ProtoReflect.Descriptor instead.
+func (*QueryFreightResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{83}
 }
 
-func (x *ListWarehousesResponse) GetWarehouses() []*v1alpha1.Warehouse {
+func (x *QueryFreightResponse) GetGroups() map[string]*FreightList {
 	if x != nil {
-		return x.Warehouses
+		return x.Groups
 	}
 	return nil
 }
 
-type GetWarehouseRequest struct {
+type FreightList struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+	Freight []*v1alpha1.Freight `protobuf:"bytes,1,rep,name=freight,proto3" json:"freight,omitempty"`
 }
 
-func (x *GetWarehouseRequest) Reset() {
-	*x = GetWarehouseRequest{}
+func (x *FreightList) Reset() {
+	*x = FreightList{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[81]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[84]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetWarehouseRequest) String() string {
+func (x *FreightList) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetWarehouseRequest) ProtoMessage() {}
+func (*FreightList) ProtoMessage() {}
 
-func (x *GetWarehouseRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[81]
+func (x *FreightList) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[84]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4607,61 +4747,46 @@ func (x *GetWarehouseRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetWarehouseRequest.ProtoReflect.Descriptor instead.
-func (*GetWarehouseRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{81}
-}
-
-func (x *GetWarehouseRequest) GetProject() string {
-	if x != nil {
-		return x.Project
-	}
-	return ""
-}
-
-func (x *GetWarehouseRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
+// Deprecated: Use FreightList.ProtoReflect.Descriptor instead.
+func (*FreightList) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{84}
 }
 
-func (x *GetWarehouseRequest) GetFormat() RawFormat {
+func (x *FreightList) GetFreight() []*v1alpha1.Freight {
 	if x != nil {
-		return x.Format
+		return x.Freight
 	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
+	return nil
 }
 
-type GetWarehouseResponse struct {
+type UpdateFreightAliasRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// Types that are assignable to Result:
-	//
-	//	*GetWarehouseResponse_Warehouse
-	//	*GetWarehouseResponse_Raw
-	Result isGetWarehouseResponse_Result `protobuf_oneof:"result"`
+	Project  string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name     string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	OldAlias string `protobuf:"bytes,3,opt,name=old_alias,json=oldAlias,proto3" json:"old_alias,omitempty"`
+	NewAlias string `protobuf:"bytes,4,opt,name=new_alias,json=newAlias,proto3" json:"new_alias,omitempty"`
 }
 
-func (x *GetWarehouseResponse) Reset() {
-	*x = GetWarehouseResponse{}
+func (x *UpdateFreightAliasRequest) Reset() {
+	*x = UpdateFreightAliasRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[82]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[85]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetWarehouseResponse) String() string {
+func (x *UpdateFreightAliasRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetWarehouseResponse) ProtoMessage() {}
+func (*UpdateFreightAliasRequest) ProtoMessage() {}
 
-func (x *GetWarehouseResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[82]
+func (x *UpdateFreightAliasRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[85]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4672,74 +4797,103 @@ func (x *GetWarehouseResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetWarehouseResponse.ProtoReflect.Descriptor instead.
-func (*GetWarehouseResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{82}
+// Deprecated: Use UpdateFreightAliasRequest.ProtoReflect.Descriptor instead.
+func (*UpdateFreightAliasRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{85}
 }
 
-func (m *GetWarehouseResponse) GetResult() isGetWarehouseResponse_Result {
-	if m != nil {
-		return m.Result
+func (x *UpdateFreightAliasRequest) GetProject() string {
+	if x != nil {
+		return x.Project
 	}
-	return nil
+	return ""
 }
 
-func (x *GetWarehouseResponse) GetWarehouse() *v1alpha1.Warehouse {
-	if x, ok := x.GetResult().(*GetWarehouseResponse_Warehouse); ok {
-		return x.Warehouse
+func (x *UpdateFreightAliasRequest) GetName() string {
+	if x != nil {
+		return x.Name
 	}
-	return nil
+	return ""
 }
 
-func (x *GetWarehouseResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetWarehouseResponse_Raw); ok {
-		return x.Raw
+func (x *UpdateFreightAliasRequest) GetOldAlias() string {
+	if x != nil {
+		return x.OldAlias
 	}
-	return nil
+	return ""
 }
 
-type isGetWarehouseResponse_Result interface {
-	isGetWarehouseResponse_Result()
+func (x *UpdateFreightAliasRequest) GetNewAlias() string {
+	if x != nil {
+		return x.NewAlias
+	}
+	return ""
 }
 
-type GetWarehouseResponse_Warehouse struct {
-	Warehouse *v1alpha1.Warehouse `protobuf:"bytes,1,opt,name=warehouse,proto3,oneof"`
+type UpdateFreightAliasResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
 }
 
-type GetWarehouseResponse_Raw struct {
-	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+func (x *UpdateFreightAliasResponse) Reset() {
+	*x = UpdateFreightAliasResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[86]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
 }
 
-func (*GetWarehouseResponse_Warehouse) isGetWarehouseResponse_Result() {}
+func (x *UpdateFreightAliasResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
 
-func (*GetWarehouseResponse_Raw) isGetWarehouseResponse_Result() {}
+func (*UpdateFreightAliasResponse) ProtoMessage() {}
 
-type WatchWarehousesRequest struct {
+func (x *UpdateFreightAliasResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[86]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateFreightAliasResponse.ProtoReflect.Descriptor instead.
+func (*UpdateFreightAliasResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{86}
+}
+
+type ReverifyRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Stage   string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
 }
 
-func (x *WatchWarehousesRequest) Reset() {
-	*x = WatchWarehousesRequest{}
+func (x *ReverifyRequest) Reset() {
+	*x = ReverifyRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[83]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[87]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *WatchWarehousesRequest) String() string {
+func (x *ReverifyRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchWarehousesRequest) ProtoMessage() {}
+func (*ReverifyRequest) ProtoMessage() {}
 
-func (x *WatchWarehousesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[83]
+func (x *ReverifyRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[87]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4750,51 +4904,48 @@ func (x *WatchWarehousesRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchWarehousesRequest.ProtoReflect.Descriptor instead.
-func (*WatchWarehousesRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{83}
+// Deprecated: Use ReverifyRequest.ProtoReflect.Descriptor instead.
+func (*ReverifyRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{87}
 }
 
-func (x *WatchWarehousesRequest) GetProject() string {
+func (x *ReverifyRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *WatchWarehousesRequest) GetName() string {
+func (x *ReverifyRequest) GetStage() string {
 	if x != nil {
-		return x.Name
+		return x.Stage
 	}
 	return ""
 }
 
-type WatchWarehousesResponse struct {
+type ReverifyResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Warehouse *v1alpha1.Warehouse `protobuf:"bytes,1,opt,name=warehouse,proto3" json:"warehouse,omitempty"`
-	Type      string              `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
 }
 
-func (x *WatchWarehousesResponse) Reset() {
-	*x = WatchWarehousesResponse{}
+func (x *ReverifyResponse) Reset() {
+	*x = ReverifyResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[84]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[88]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *WatchWarehousesResponse) String() string {
+func (x *ReverifyResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*WatchWarehousesResponse) ProtoMessage() {}
+func (*ReverifyResponse) ProtoMessage() {}
 
-func (x *WatchWarehousesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[84]
+func (x *ReverifyResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[88]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4805,51 +4956,37 @@ func (x *WatchWarehousesResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use WatchWarehousesResponse.ProtoReflect.Descriptor instead.
-func (*WatchWarehousesResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{84}
-}
-
-func (x *WatchWarehousesResponse) GetWarehouse() *v1alpha1.Warehouse {
-	if x != nil {
-		return x.Warehouse
-	}
-	return nil
-}
-
-func (x *WatchWarehousesResponse) GetType() string {
-	if x != nil {
-		return x.Type
-	}
-	return ""
+// Deprecated: Use ReverifyResponse.ProtoReflect.Descriptor instead.
+func (*ReverifyResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{88}
 }
 
-type DeleteWarehouseRequest struct {
+type AbortVerificationRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Stage   string `protobuf:"bytes,2,opt,name=stage,proto3" json:"stage,omitempty"`
 }
 
-func (x *DeleteWarehouseRequest) Reset() {
-	*x = DeleteWarehouseRequest{}
+func (x *AbortVerificationRequest) Reset() {
+	*x = AbortVerificationRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[85]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[89]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteWarehouseRequest) String() string {
+func (x *AbortVerificationRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteWarehouseRequest) ProtoMessage() {}
+func (*AbortVerificationRequest) ProtoMessage() {}
 
-func (x *DeleteWarehouseRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[85]
+func (x *AbortVerificationRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[89]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4860,48 +4997,48 @@ func (x *DeleteWarehouseRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteWarehouseRequest.ProtoReflect.Descriptor instead.
-func (*DeleteWarehouseRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{85}
+// Deprecated: Use AbortVerificationRequest.ProtoReflect.Descriptor instead.
+func (*AbortVerificationRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{89}
 }
 
-func (x *DeleteWarehouseRequest) GetProject() string {
+func (x *AbortVerificationRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *DeleteWarehouseRequest) GetName() string {
+func (x *AbortVerificationRequest) GetStage() string {
 	if x != nil {
-		return x.Name
+		return x.Stage
 	}
 	return ""
 }
 
-type DeleteWarehouseResponse struct {
+type AbortVerificationResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 }
 
-func (x *DeleteWarehouseResponse) Reset() {
-	*x = DeleteWarehouseResponse{}
+func (x *AbortVerificationResponse) Reset() {
+	*x = AbortVerificationResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[86]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[90]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteWarehouseResponse) String() string {
+func (x *AbortVerificationResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteWarehouseResponse) ProtoMessage() {}
+func (*AbortVerificationResponse) ProtoMessage() {}
 
-func (x *DeleteWarehouseResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[86]
+func (x *AbortVerificationResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[90]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4912,37 +5049,36 @@ func (x *DeleteWarehouseResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteWarehouseResponse.ProtoReflect.Descriptor instead.
-func (*DeleteWarehouseResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{86}
+// Deprecated: Use AbortVerificationResponse.ProtoReflect.Descriptor instead.
+func (*AbortVerificationResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{90}
 }
 
-type RefreshWarehouseRequest struct {
+type ListWarehousesRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *RefreshWarehouseRequest) Reset() {
-	*x = RefreshWarehouseRequest{}
+func (x *ListWarehousesRequest) Reset() {
+	*x = ListWarehousesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[87]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[91]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *RefreshWarehouseRequest) String() string {
+func (x *ListWarehousesRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*RefreshWarehouseRequest) ProtoMessage() {}
+func (*ListWarehousesRequest) ProtoMessage() {}
 
-func (x *RefreshWarehouseRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[87]
+func (x *ListWarehousesRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[91]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -4953,50 +5089,43 @@ func (x *RefreshWarehouseRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use RefreshWarehouseRequest.ProtoReflect.Descriptor instead.
-func (*RefreshWarehouseRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{87}
+// Deprecated: Use ListWarehousesRequest.ProtoReflect.Descriptor instead.
+func (*ListWarehousesRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{91}
 }
 
-func (x *RefreshWarehouseRequest) GetProject() string {
+func (x *ListWarehousesRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *RefreshWarehouseRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-type RefreshWarehouseResponse struct {
+type ListWarehousesResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Warehouse *v1alpha1.Warehouse `protobuf:"bytes,1,opt,name=warehouse,proto3" json:"warehouse,omitempty"`
+	Warehouses []*v1alpha1.Warehouse `protobuf:"bytes,1,rep,name=warehouses,proto3" json:"warehouses,omitempty"`
 }
 
-func (x *RefreshWarehouseResponse) Reset() {
-	*x = RefreshWarehouseResponse{}
+func (x *ListWarehousesResponse) Reset() {
+	*x = ListWarehousesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[88]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[92]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *RefreshWarehouseResponse) String() string {
+func (x *ListWarehousesResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*RefreshWarehouseResponse) ProtoMessage() {}
+func (*ListWarehousesResponse) ProtoMessage() {}
 
-func (x *RefreshWarehouseResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[88]
+func (x *ListWarehousesResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[92]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5007,43 +5136,45 @@ func (x *RefreshWarehouseResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use RefreshWarehouseResponse.ProtoReflect.Descriptor instead.
-func (*RefreshWarehouseResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{88}
+// Deprecated: Use ListWarehousesResponse.ProtoReflect.Descriptor instead.
+func (*ListWarehousesResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{92}
 }
 
-func (x *RefreshWarehouseResponse) GetWarehouse() *v1alpha1.Warehouse {
+func (x *ListWarehousesResponse) GetWarehouses() []*v1alpha1.Warehouse {
 	if x != nil {
-		return x.Warehouse
+		return x.Warehouses
 	}
 	return nil
 }
 
-type ListProjectSecretsRequest struct {
+type GetWarehouseRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *ListProjectSecretsRequest) Reset() {
-	*x = ListProjectSecretsRequest{}
+func (x *GetWarehouseRequest) Reset() {
+	*x = GetWarehouseRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[89]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[93]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListProjectSecretsRequest) String() string {
+func (x *GetWarehouseRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListProjectSecretsRequest) ProtoMessage() {}
+func (*GetWarehouseRequest) ProtoMessage() {}
 
-func (x *ListProjectSecretsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[89]
+func (x *GetWarehouseRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[93]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5054,43 +5185,61 @@ func (x *ListProjectSecretsRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListProjectSecretsRequest.ProtoReflect.Descriptor instead.
-func (*ListProjectSecretsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{89}
+// Deprecated: Use GetWarehouseRequest.ProtoReflect.Descriptor instead.
+func (*GetWarehouseRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{93}
 }
 
-func (x *ListProjectSecretsRequest) GetProject() string {
+func (x *GetWarehouseRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-type ListProjectSecretsResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
+func (x *GetWarehouseRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
 
-	Secrets []*v1.Secret `protobuf:"bytes,1,rep,name=secrets,proto3" json:"secrets,omitempty"`
+func (x *GetWarehouseRequest) GetFormat() RawFormat {
+	if x != nil {
+		return x.Format
+	}
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-func (x *ListProjectSecretsResponse) Reset() {
-	*x = ListProjectSecretsResponse{}
+type GetWarehouseResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Result:
+	//
+	//	*GetWarehouseResponse_Warehouse
+	//	*GetWarehouseResponse_Raw
+	Result isGetWarehouseResponse_Result `protobuf_oneof:"result"`
+}
+
+func (x *GetWarehouseResponse) Reset() {
+	*x = GetWarehouseResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[90]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[94]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListProjectSecretsResponse) String() string {
+func (x *GetWarehouseResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListProjectSecretsResponse) ProtoMessage() {}
+func (*GetWarehouseResponse) ProtoMessage() {}
 
-func (x *ListProjectSecretsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[90]
+func (x *GetWarehouseResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[94]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5101,46 +5250,74 @@ func (x *ListProjectSecretsResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListProjectSecretsResponse.ProtoReflect.Descriptor instead.
-func (*ListProjectSecretsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{90}
+// Deprecated: Use GetWarehouseResponse.ProtoReflect.Descriptor instead.
+func (*GetWarehouseResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{94}
 }
 
-func (x *ListProjectSecretsResponse) GetSecrets() []*v1.Secret {
-	if x != nil {
-		return x.Secrets
+func (m *GetWarehouseResponse) GetResult() isGetWarehouseResponse_Result {
+	if m != nil {
+		return m.Result
 	}
 	return nil
 }
 
-type CreateProjectSecretRequest struct {
+func (x *GetWarehouseResponse) GetWarehouse() *v1alpha1.Warehouse {
+	if x, ok := x.GetResult().(*GetWarehouseResponse_Warehouse); ok {
+		return x.Warehouse
+	}
+	return nil
+}
+
+func (x *GetWarehouseResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetWarehouseResponse_Raw); ok {
+		return x.Raw
+	}
+	return nil
+}
+
+type isGetWarehouseResponse_Result interface {
+	isGetWarehouseResponse_Result()
+}
+
+type GetWarehouseResponse_Warehouse struct {
+	Warehouse *v1alpha1.Warehouse `protobuf:"bytes,1,opt,name=warehouse,proto3,oneof"`
+}
+
+type GetWarehouseResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+}
+
+func (*GetWarehouseResponse_Warehouse) isGetWarehouseResponse_Result() {}
+
+func (*GetWarehouseResponse_Raw) isGetWarehouseResponse_Result() {}
+
+type WatchWarehousesRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project     string            `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name        string            `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Description string            `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
-	Data        map[string]string `protobuf:"bytes,4,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *CreateProjectSecretRequest) Reset() {
-	*x = CreateProjectSecretRequest{}
+func (x *WatchWarehousesRequest) Reset() {
+	*x = WatchWarehousesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[91]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[95]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *CreateProjectSecretRequest) String() string {
+func (x *WatchWarehousesRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*CreateProjectSecretRequest) ProtoMessage() {}
+func (*WatchWarehousesRequest) ProtoMessage() {}
 
-func (x *CreateProjectSecretRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[91]
+func (x *WatchWarehousesRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[95]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5151,64 +5328,51 @@ func (x *CreateProjectSecretRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use CreateProjectSecretRequest.ProtoReflect.Descriptor instead.
-func (*CreateProjectSecretRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{91}
+// Deprecated: Use WatchWarehousesRequest.ProtoReflect.Descriptor instead.
+func (*WatchWarehousesRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{95}
 }
 
-func (x *CreateProjectSecretRequest) GetProject() string {
+func (x *WatchWarehousesRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *CreateProjectSecretRequest) GetName() string {
+func (x *WatchWarehousesRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-func (x *CreateProjectSecretRequest) GetDescription() string {
-	if x != nil {
-		return x.Description
-	}
-	return ""
-}
-
-func (x *CreateProjectSecretRequest) GetData() map[string]string {
-	if x != nil {
-		return x.Data
-	}
-	return nil
-}
-
-type CreateProjectSecretResponse struct {
+type WatchWarehousesResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Secret *v1.Secret `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"`
+	Warehouse *v1alpha1.Warehouse `protobuf:"bytes,1,opt,name=warehouse,proto3" json:"warehouse,omitempty"`
+	Type      string              `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
 }
 
-func (x *CreateProjectSecretResponse) Reset() {
-	*x = CreateProjectSecretResponse{}
+func (x *WatchWarehousesResponse) Reset() {
+	*x = WatchWarehousesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[92]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[96]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *CreateProjectSecretResponse) String() string {
+func (x *WatchWarehousesResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*CreateProjectSecretResponse) ProtoMessage() {}
+func (*WatchWarehousesResponse) ProtoMessage() {}
 
-func (x *CreateProjectSecretResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[92]
+func (x *WatchWarehousesResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[96]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5219,46 +5383,51 @@ func (x *CreateProjectSecretResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use CreateProjectSecretResponse.ProtoReflect.Descriptor instead.
-func (*CreateProjectSecretResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{92}
+// Deprecated: Use WatchWarehousesResponse.ProtoReflect.Descriptor instead.
+func (*WatchWarehousesResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{96}
 }
 
-func (x *CreateProjectSecretResponse) GetSecret() *v1.Secret {
+func (x *WatchWarehousesResponse) GetWarehouse() *v1alpha1.Warehouse {
 	if x != nil {
-		return x.Secret
+		return x.Warehouse
 	}
 	return nil
 }
 
-type UpdateProjectSecretRequest struct {
+func (x *WatchWarehousesResponse) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+type DeleteWarehouseRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project     string            `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name        string            `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Description string            `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
-	Data        map[string]string `protobuf:"bytes,4,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *UpdateProjectSecretRequest) Reset() {
-	*x = UpdateProjectSecretRequest{}
+func (x *DeleteWarehouseRequest) Reset() {
+	*x = DeleteWarehouseRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[93]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[97]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *UpdateProjectSecretRequest) String() string {
+func (x *DeleteWarehouseRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*UpdateProjectSecretRequest) ProtoMessage() {}
+func (*DeleteWarehouseRequest) ProtoMessage() {}
 
-func (x *UpdateProjectSecretRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[93]
+func (x *DeleteWarehouseRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[97]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5269,64 +5438,48 @@ func (x *UpdateProjectSecretRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use UpdateProjectSecretRequest.ProtoReflect.Descriptor instead.
-func (*UpdateProjectSecretRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{93}
+// Deprecated: Use DeleteWarehouseRequest.ProtoReflect.Descriptor instead.
+func (*DeleteWarehouseRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{97}
 }
 
-func (x *UpdateProjectSecretRequest) GetProject() string {
+func (x *DeleteWarehouseRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *UpdateProjectSecretRequest) GetName() string {
+func (x *DeleteWarehouseRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-func (x *UpdateProjectSecretRequest) GetDescription() string {
-	if x != nil {
-		return x.Description
-	}
-	return ""
-}
-
-func (x *UpdateProjectSecretRequest) GetData() map[string]string {
-	if x != nil {
-		return x.Data
-	}
-	return nil
-}
-
-type UpdateProjectSecretResponse struct {
+type DeleteWarehouseResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Secret *v1.Secret `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"`
 }
 
-func (x *UpdateProjectSecretResponse) Reset() {
-	*x = UpdateProjectSecretResponse{}
+func (x *DeleteWarehouseResponse) Reset() {
+	*x = DeleteWarehouseResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[94]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[98]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *UpdateProjectSecretResponse) String() string {
+func (x *DeleteWarehouseResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*UpdateProjectSecretResponse) ProtoMessage() {}
+func (*DeleteWarehouseResponse) ProtoMessage() {}
 
-func (x *UpdateProjectSecretResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[94]
+func (x *DeleteWarehouseResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[98]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5337,19 +5490,12 @@ func (x *UpdateProjectSecretResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use UpdateProjectSecretResponse.ProtoReflect.Descriptor instead.
-func (*UpdateProjectSecretResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{94}
-}
-
-func (x *UpdateProjectSecretResponse) GetSecret() *v1.Secret {
-	if x != nil {
-		return x.Secret
-	}
-	return nil
+// Deprecated: Use DeleteWarehouseResponse.ProtoReflect.Descriptor instead.
+func (*DeleteWarehouseResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{98}
 }
 
-type DeleteProjectSecretRequest struct {
+type RefreshWarehouseRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -5358,23 +5504,23 @@ type DeleteProjectSecretRequest struct {
 	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *DeleteProjectSecretRequest) Reset() {
-	*x = DeleteProjectSecretRequest{}
+func (x *RefreshWarehouseRequest) Reset() {
+	*x = RefreshWarehouseRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[95]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[99]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteProjectSecretRequest) String() string {
+func (x *RefreshWarehouseRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteProjectSecretRequest) ProtoMessage() {}
+func (*RefreshWarehouseRequest) ProtoMessage() {}
 
-func (x *DeleteProjectSecretRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[95]
+func (x *RefreshWarehouseRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[99]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5385,48 +5531,50 @@ func (x *DeleteProjectSecretRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteProjectSecretRequest.ProtoReflect.Descriptor instead.
-func (*DeleteProjectSecretRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{95}
+// Deprecated: Use RefreshWarehouseRequest.ProtoReflect.Descriptor instead.
+func (*RefreshWarehouseRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{99}
 }
 
-func (x *DeleteProjectSecretRequest) GetProject() string {
+func (x *RefreshWarehouseRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *DeleteProjectSecretRequest) GetName() string {
+func (x *RefreshWarehouseRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-type DeleteProjectSecretResponse struct {
+type RefreshWarehouseResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Warehouse *v1alpha1.Warehouse `protobuf:"bytes,1,opt,name=warehouse,proto3" json:"warehouse,omitempty"`
 }
 
-func (x *DeleteProjectSecretResponse) Reset() {
-	*x = DeleteProjectSecretResponse{}
+func (x *RefreshWarehouseResponse) Reset() {
+	*x = RefreshWarehouseResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[96]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[100]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteProjectSecretResponse) String() string {
+func (x *RefreshWarehouseResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteProjectSecretResponse) ProtoMessage() {}
+func (*RefreshWarehouseResponse) ProtoMessage() {}
 
-func (x *DeleteProjectSecretResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[96]
+func (x *RefreshWarehouseResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[100]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5437,9 +5585,16 @@ func (x *DeleteProjectSecretResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteProjectSecretResponse.ProtoReflect.Descriptor instead.
-func (*DeleteProjectSecretResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{96}
+// Deprecated: Use RefreshWarehouseResponse.ProtoReflect.Descriptor instead.
+func (*RefreshWarehouseResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{100}
+}
+
+func (x *RefreshWarehouseResponse) GetWarehouse() *v1alpha1.Warehouse {
+	if x != nil {
+		return x.Warehouse
+	}
+	return nil
 }
 
 type CreateCredentialsRequest struct {
@@ -5461,7 +5616,7 @@ type CreateCredentialsRequest struct {
 func (x *CreateCredentialsRequest) Reset() {
 	*x = CreateCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[97]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[101]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5474,7 +5629,7 @@ func (x *CreateCredentialsRequest) String() string {
 func (*CreateCredentialsRequest) ProtoMessage() {}
 
 func (x *CreateCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[97]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[101]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5487,7 +5642,7 @@ func (x *CreateCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*CreateCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{97}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{101}
 }
 
 func (x *CreateCredentialsRequest) GetProject() string {
@@ -5557,7 +5712,7 @@ type CreateCredentialsResponse struct {
 func (x *CreateCredentialsResponse) Reset() {
 	*x = CreateCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[98]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[102]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5570,7 +5725,7 @@ func (x *CreateCredentialsResponse) String() string {
 func (*CreateCredentialsResponse) ProtoMessage() {}
 
 func (x *CreateCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[98]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[102]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5583,7 +5738,7 @@ func (x *CreateCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*CreateCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{98}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{102}
 }
 
 func (x *CreateCredentialsResponse) GetCredentials() *v1.Secret {
@@ -5605,7 +5760,7 @@ type DeleteCredentialsRequest struct {
 func (x *DeleteCredentialsRequest) Reset() {
 	*x = DeleteCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[99]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[103]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5618,7 +5773,7 @@ func (x *DeleteCredentialsRequest) String() string {
 func (*DeleteCredentialsRequest) ProtoMessage() {}
 
 func (x *DeleteCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[99]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[103]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5631,7 +5786,7 @@ func (x *DeleteCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*DeleteCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{99}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{103}
 }
 
 func (x *DeleteCredentialsRequest) GetProject() string {
@@ -5657,7 +5812,7 @@ type DeleteCredentialsResponse struct {
 func (x *DeleteCredentialsResponse) Reset() {
 	*x = DeleteCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[100]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[104]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5670,7 +5825,7 @@ func (x *DeleteCredentialsResponse) String() string {
 func (*DeleteCredentialsResponse) ProtoMessage() {}
 
 func (x *DeleteCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[100]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[104]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5683,7 +5838,7 @@ func (x *DeleteCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*DeleteCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{100}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{104}
 }
 
 type GetCredentialsRequest struct {
@@ -5699,7 +5854,7 @@ type GetCredentialsRequest struct {
 func (x *GetCredentialsRequest) Reset() {
 	*x = GetCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[101]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[105]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5712,7 +5867,7 @@ func (x *GetCredentialsRequest) String() string {
 func (*GetCredentialsRequest) ProtoMessage() {}
 
 func (x *GetCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[101]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[105]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5725,7 +5880,7 @@ func (x *GetCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*GetCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{101}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{105}
 }
 
 func (x *GetCredentialsRequest) GetProject() string {
@@ -5764,7 +5919,7 @@ type GetCredentialsResponse struct {
 func (x *GetCredentialsResponse) Reset() {
 	*x = GetCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[102]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[106]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5777,7 +5932,7 @@ func (x *GetCredentialsResponse) String() string {
 func (*GetCredentialsResponse) ProtoMessage() {}
 
 func (x *GetCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[102]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[106]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5790,7 +5945,7 @@ func (x *GetCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*GetCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{102}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{106}
 }
 
 func (m *GetCredentialsResponse) GetResult() isGetCredentialsResponse_Result {
@@ -5841,7 +5996,7 @@ type ListCredentialsRequest struct {
 func (x *ListCredentialsRequest) Reset() {
 	*x = ListCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[103]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[107]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5854,7 +6009,7 @@ func (x *ListCredentialsRequest) String() string {
 func (*ListCredentialsRequest) ProtoMessage() {}
 
 func (x *ListCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[103]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[107]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5867,7 +6022,7 @@ func (x *ListCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*ListCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{103}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{107}
 }
 
 func (x *ListCredentialsRequest) GetProject() string {
@@ -5888,7 +6043,7 @@ type ListCredentialsResponse struct {
 func (x *ListCredentialsResponse) Reset() {
 	*x = ListCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[104]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[108]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5901,7 +6056,7 @@ func (x *ListCredentialsResponse) String() string {
 func (*ListCredentialsResponse) ProtoMessage() {}
 
 func (x *ListCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[104]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[108]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5914,7 +6069,7 @@ func (x *ListCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*ListCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{104}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{108}
 }
 
 func (x *ListCredentialsResponse) GetCredentials() []*v1.Secret {
@@ -5942,7 +6097,7 @@ type UpdateCredentialsRequest struct {
 func (x *UpdateCredentialsRequest) Reset() {
 	*x = UpdateCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[105]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[109]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5955,7 +6110,7 @@ func (x *UpdateCredentialsRequest) String() string {
 func (*UpdateCredentialsRequest) ProtoMessage() {}
 
 func (x *UpdateCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[105]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[109]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -5968,7 +6123,7 @@ func (x *UpdateCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*UpdateCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{105}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{109}
 }
 
 func (x *UpdateCredentialsRequest) GetProject() string {
@@ -6038,7 +6193,7 @@ type UpdateCredentialsResponse struct {
 func (x *UpdateCredentialsResponse) Reset() {
 	*x = UpdateCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[106]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[110]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6051,7 +6206,7 @@ func (x *UpdateCredentialsResponse) String() string {
 func (*UpdateCredentialsResponse) ProtoMessage() {}
 
 func (x *UpdateCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[106]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[110]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6064,7 +6219,7 @@ func (x *UpdateCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*UpdateCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{106}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{110}
 }
 
 func (x *UpdateCredentialsResponse) GetCredentials() *v1.Secret {
@@ -6074,7 +6229,7 @@ func (x *UpdateCredentialsResponse) GetCredentials() *v1.Secret {
 	return nil
 }
 
-type ListAnalysisTemplatesRequest struct {
+type ListProjectSecretsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -6082,23 +6237,23 @@ type ListAnalysisTemplatesRequest struct {
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
 }
 
-func (x *ListAnalysisTemplatesRequest) Reset() {
-	*x = ListAnalysisTemplatesRequest{}
+func (x *ListProjectSecretsRequest) Reset() {
+	*x = ListProjectSecretsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[107]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[111]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListAnalysisTemplatesRequest) String() string {
+func (x *ListProjectSecretsRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListAnalysisTemplatesRequest) ProtoMessage() {}
+func (*ListProjectSecretsRequest) ProtoMessage() {}
 
-func (x *ListAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[107]
+func (x *ListProjectSecretsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[111]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6109,43 +6264,43 @@ func (x *ListAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListAnalysisTemplatesRequest.ProtoReflect.Descriptor instead.
-func (*ListAnalysisTemplatesRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{107}
+// Deprecated: Use ListProjectSecretsRequest.ProtoReflect.Descriptor instead.
+func (*ListProjectSecretsRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{111}
 }
 
-func (x *ListAnalysisTemplatesRequest) GetProject() string {
+func (x *ListProjectSecretsRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-type ListAnalysisTemplatesResponse struct {
+type ListProjectSecretsResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	AnalysisTemplates []*v1alpha11.AnalysisTemplate `protobuf:"bytes,1,rep,name=analysis_templates,json=analysisTemplates,proto3" json:"analysis_templates,omitempty"`
+	Secrets []*v1.Secret `protobuf:"bytes,1,rep,name=secrets,proto3" json:"secrets,omitempty"`
 }
 
-func (x *ListAnalysisTemplatesResponse) Reset() {
-	*x = ListAnalysisTemplatesResponse{}
+func (x *ListProjectSecretsResponse) Reset() {
+	*x = ListProjectSecretsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[108]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[112]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListAnalysisTemplatesResponse) String() string {
+func (x *ListProjectSecretsResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListAnalysisTemplatesResponse) ProtoMessage() {}
+func (*ListProjectSecretsResponse) ProtoMessage() {}
 
-func (x *ListAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[108]
+func (x *ListProjectSecretsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[112]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6156,43 +6311,46 @@ func (x *ListAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListAnalysisTemplatesResponse.ProtoReflect.Descriptor instead.
-func (*ListAnalysisTemplatesResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{108}
+// Deprecated: Use ListProjectSecretsResponse.ProtoReflect.Descriptor instead.
+func (*ListProjectSecretsResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{112}
 }
 
-func (x *ListAnalysisTemplatesResponse) GetAnalysisTemplates() []*v1alpha11.AnalysisTemplate {
+func (x *ListProjectSecretsResponse) GetSecrets() []*v1.Secret {
 	if x != nil {
-		return x.AnalysisTemplates
+		return x.Secrets
 	}
 	return nil
 }
 
-type ListPromotionTasksRequest struct {
+type CreateProjectSecretRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Project     string            `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name        string            `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Description string            `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	Data        map[string]string `protobuf:"bytes,4,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 }
 
-func (x *ListPromotionTasksRequest) Reset() {
-	*x = ListPromotionTasksRequest{}
+func (x *CreateProjectSecretRequest) Reset() {
+	*x = CreateProjectSecretRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[109]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[113]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListPromotionTasksRequest) String() string {
+func (x *CreateProjectSecretRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListPromotionTasksRequest) ProtoMessage() {}
+func (*CreateProjectSecretRequest) ProtoMessage() {}
 
-func (x *ListPromotionTasksRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[109]
+func (x *CreateProjectSecretRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[113]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6203,43 +6361,64 @@ func (x *ListPromotionTasksRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListPromotionTasksRequest.ProtoReflect.Descriptor instead.
-func (*ListPromotionTasksRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{109}
+// Deprecated: Use CreateProjectSecretRequest.ProtoReflect.Descriptor instead.
+func (*CreateProjectSecretRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{113}
 }
 
-func (x *ListPromotionTasksRequest) GetProject() string {
+func (x *CreateProjectSecretRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-type ListPromotionTasksResponse struct {
+func (x *CreateProjectSecretRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *CreateProjectSecretRequest) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *CreateProjectSecretRequest) GetData() map[string]string {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type CreateProjectSecretResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	PromotionTasks []*v1alpha1.PromotionTask `protobuf:"bytes,1,rep,name=promotion_tasks,json=promotionTasks,proto3" json:"promotion_tasks,omitempty"`
+	Secret *v1.Secret `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"`
 }
 
-func (x *ListPromotionTasksResponse) Reset() {
-	*x = ListPromotionTasksResponse{}
+func (x *CreateProjectSecretResponse) Reset() {
+	*x = CreateProjectSecretResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[110]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[114]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListPromotionTasksResponse) String() string {
+func (x *CreateProjectSecretResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListPromotionTasksResponse) ProtoMessage() {}
+func (*CreateProjectSecretResponse) ProtoMessage() {}
 
-func (x *ListPromotionTasksResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[110]
+func (x *CreateProjectSecretResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[114]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6250,41 +6429,46 @@ func (x *ListPromotionTasksResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListPromotionTasksResponse.ProtoReflect.Descriptor instead.
-func (*ListPromotionTasksResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{110}
+// Deprecated: Use CreateProjectSecretResponse.ProtoReflect.Descriptor instead.
+func (*CreateProjectSecretResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{114}
 }
 
-func (x *ListPromotionTasksResponse) GetPromotionTasks() []*v1alpha1.PromotionTask {
+func (x *CreateProjectSecretResponse) GetSecret() *v1.Secret {
 	if x != nil {
-		return x.PromotionTasks
+		return x.Secret
 	}
 	return nil
 }
 
-type ListClusterPromotionTasksRequest struct {
+type UpdateProjectSecretRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Project     string            `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name        string            `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Description string            `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	Data        map[string]string `protobuf:"bytes,4,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 }
 
-func (x *ListClusterPromotionTasksRequest) Reset() {
-	*x = ListClusterPromotionTasksRequest{}
+func (x *UpdateProjectSecretRequest) Reset() {
+	*x = UpdateProjectSecretRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[111]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[115]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListClusterPromotionTasksRequest) String() string {
+func (x *UpdateProjectSecretRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListClusterPromotionTasksRequest) ProtoMessage() {}
+func (*UpdateProjectSecretRequest) ProtoMessage() {}
 
-func (x *ListClusterPromotionTasksRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[111]
+func (x *UpdateProjectSecretRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[115]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6295,36 +6479,64 @@ func (x *ListClusterPromotionTasksRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListClusterPromotionTasksRequest.ProtoReflect.Descriptor instead.
-func (*ListClusterPromotionTasksRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{111}
+// Deprecated: Use UpdateProjectSecretRequest.ProtoReflect.Descriptor instead.
+func (*UpdateProjectSecretRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{115}
 }
 
-type ListClusterPromotionTasksResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	ClusterPromotionTasks []*v1alpha1.ClusterPromotionTask `protobuf:"bytes,1,rep,name=cluster_promotion_tasks,json=clusterPromotionTasks,proto3" json:"cluster_promotion_tasks,omitempty"`
+func (x *UpdateProjectSecretRequest) GetProject() string {
+	if x != nil {
+		return x.Project
+	}
+	return ""
 }
 
-func (x *ListClusterPromotionTasksResponse) Reset() {
-	*x = ListClusterPromotionTasksResponse{}
+func (x *UpdateProjectSecretRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *UpdateProjectSecretRequest) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *UpdateProjectSecretRequest) GetData() map[string]string {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type UpdateProjectSecretResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Secret *v1.Secret `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"`
+}
+
+func (x *UpdateProjectSecretResponse) Reset() {
+	*x = UpdateProjectSecretResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[112]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[116]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListClusterPromotionTasksResponse) String() string {
+func (x *UpdateProjectSecretResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListClusterPromotionTasksResponse) ProtoMessage() {}
+func (*UpdateProjectSecretResponse) ProtoMessage() {}
 
-func (x *ListClusterPromotionTasksResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[112]
+func (x *UpdateProjectSecretResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[116]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6335,45 +6547,44 @@ func (x *ListClusterPromotionTasksResponse) ProtoReflect() protoreflect.Message
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListClusterPromotionTasksResponse.ProtoReflect.Descriptor instead.
-func (*ListClusterPromotionTasksResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{112}
+// Deprecated: Use UpdateProjectSecretResponse.ProtoReflect.Descriptor instead.
+func (*UpdateProjectSecretResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{116}
 }
 
-func (x *ListClusterPromotionTasksResponse) GetClusterPromotionTasks() []*v1alpha1.ClusterPromotionTask {
+func (x *UpdateProjectSecretResponse) GetSecret() *v1.Secret {
 	if x != nil {
-		return x.ClusterPromotionTasks
+		return x.Secret
 	}
 	return nil
 }
 
-type GetAnalysisTemplateRequest struct {
+type DeleteProjectSecretRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *GetAnalysisTemplateRequest) Reset() {
-	*x = GetAnalysisTemplateRequest{}
+func (x *DeleteProjectSecretRequest) Reset() {
+	*x = DeleteProjectSecretRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[113]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[117]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetAnalysisTemplateRequest) String() string {
+func (x *DeleteProjectSecretRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetAnalysisTemplateRequest) ProtoMessage() {}
+func (*DeleteProjectSecretRequest) ProtoMessage() {}
 
-func (x *GetAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[113]
+func (x *DeleteProjectSecretRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[117]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6384,61 +6595,88 @@ func (x *GetAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
-func (*GetAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{113}
+// Deprecated: Use DeleteProjectSecretRequest.ProtoReflect.Descriptor instead.
+func (*DeleteProjectSecretRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{117}
 }
 
-func (x *GetAnalysisTemplateRequest) GetProject() string {
+func (x *DeleteProjectSecretRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *GetAnalysisTemplateRequest) GetName() string {
+func (x *DeleteProjectSecretRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-func (x *GetAnalysisTemplateRequest) GetFormat() RawFormat {
-	if x != nil {
-		return x.Format
+type DeleteProjectSecretResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DeleteProjectSecretResponse) Reset() {
+	*x = DeleteProjectSecretResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[118]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
 	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-type GetAnalysisTemplateResponse struct {
+func (x *DeleteProjectSecretResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteProjectSecretResponse) ProtoMessage() {}
+
+func (x *DeleteProjectSecretResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[118]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteProjectSecretResponse.ProtoReflect.Descriptor instead.
+func (*DeleteProjectSecretResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{118}
+}
+
+type ListAnalysisTemplatesRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	// Types that are assignable to Result:
-	//
-	//	*GetAnalysisTemplateResponse_AnalysisTemplate
-	//	*GetAnalysisTemplateResponse_Raw
-	Result isGetAnalysisTemplateResponse_Result `protobuf_oneof:"result"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
 }
 
-func (x *GetAnalysisTemplateResponse) Reset() {
-	*x = GetAnalysisTemplateResponse{}
+func (x *ListAnalysisTemplatesRequest) Reset() {
+	*x = ListAnalysisTemplatesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[114]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[119]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetAnalysisTemplateResponse) String() string {
+func (x *ListAnalysisTemplatesRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetAnalysisTemplateResponse) ProtoMessage() {}
+func (*ListAnalysisTemplatesRequest) ProtoMessage() {}
 
-func (x *GetAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[114]
+func (x *ListAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[119]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6449,49 +6687,66 @@ func (x *GetAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
-func (*GetAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{114}
+// Deprecated: Use ListAnalysisTemplatesRequest.ProtoReflect.Descriptor instead.
+func (*ListAnalysisTemplatesRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{119}
 }
 
-func (m *GetAnalysisTemplateResponse) GetResult() isGetAnalysisTemplateResponse_Result {
-	if m != nil {
-		return m.Result
+func (x *ListAnalysisTemplatesRequest) GetProject() string {
+	if x != nil {
+		return x.Project
 	}
-	return nil
+	return ""
 }
 
-func (x *GetAnalysisTemplateResponse) GetAnalysisTemplate() *v1alpha11.AnalysisTemplate {
-	if x, ok := x.GetResult().(*GetAnalysisTemplateResponse_AnalysisTemplate); ok {
-		return x.AnalysisTemplate
-	}
-	return nil
+type ListAnalysisTemplatesResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	AnalysisTemplates []*v1alpha11.AnalysisTemplate `protobuf:"bytes,1,rep,name=analysis_templates,json=analysisTemplates,proto3" json:"analysis_templates,omitempty"`
 }
 
-func (x *GetAnalysisTemplateResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetAnalysisTemplateResponse_Raw); ok {
-		return x.Raw
+func (x *ListAnalysisTemplatesResponse) Reset() {
+	*x = ListAnalysisTemplatesResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[120]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
 	}
-	return nil
 }
 
-type isGetAnalysisTemplateResponse_Result interface {
-	isGetAnalysisTemplateResponse_Result()
+func (x *ListAnalysisTemplatesResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
 }
 
-type GetAnalysisTemplateResponse_AnalysisTemplate struct {
-	AnalysisTemplate *v1alpha11.AnalysisTemplate `protobuf:"bytes,1,opt,name=analysis_template,json=analysisTemplate,proto3,oneof"`
-}
+func (*ListAnalysisTemplatesResponse) ProtoMessage() {}
 
-type GetAnalysisTemplateResponse_Raw struct {
-	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+func (x *ListAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[120]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
 }
 
-func (*GetAnalysisTemplateResponse_AnalysisTemplate) isGetAnalysisTemplateResponse_Result() {}
+// Deprecated: Use ListAnalysisTemplatesResponse.ProtoReflect.Descriptor instead.
+func (*ListAnalysisTemplatesResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{120}
+}
 
-func (*GetAnalysisTemplateResponse_Raw) isGetAnalysisTemplateResponse_Result() {}
+func (x *ListAnalysisTemplatesResponse) GetAnalysisTemplates() []*v1alpha11.AnalysisTemplate {
+	if x != nil {
+		return x.AnalysisTemplates
+	}
+	return nil
+}
 
-type GetPromotionTaskRequest struct {
+type GetAnalysisTemplateRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -6501,23 +6756,23 @@ type GetPromotionTaskRequest struct {
 	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *GetPromotionTaskRequest) Reset() {
-	*x = GetPromotionTaskRequest{}
+func (x *GetAnalysisTemplateRequest) Reset() {
+	*x = GetAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[115]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[121]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetPromotionTaskRequest) String() string {
+func (x *GetAnalysisTemplateRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetPromotionTaskRequest) ProtoMessage() {}
+func (*GetAnalysisTemplateRequest) ProtoMessage() {}
 
-func (x *GetPromotionTaskRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[115]
+func (x *GetAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[121]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6528,61 +6783,61 @@ func (x *GetPromotionTaskRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetPromotionTaskRequest.ProtoReflect.Descriptor instead.
-func (*GetPromotionTaskRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{115}
+// Deprecated: Use GetAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
+func (*GetAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{121}
 }
 
-func (x *GetPromotionTaskRequest) GetProject() string {
+func (x *GetAnalysisTemplateRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *GetPromotionTaskRequest) GetName() string {
+func (x *GetAnalysisTemplateRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-func (x *GetPromotionTaskRequest) GetFormat() RawFormat {
+func (x *GetAnalysisTemplateRequest) GetFormat() RawFormat {
 	if x != nil {
 		return x.Format
 	}
 	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-type GetPromotionTaskResponse struct {
+type GetAnalysisTemplateResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	// Types that are assignable to Result:
 	//
-	//	*GetPromotionTaskResponse_PromotionTask
-	//	*GetPromotionTaskResponse_Raw
-	Result isGetPromotionTaskResponse_Result `protobuf_oneof:"result"`
+	//	*GetAnalysisTemplateResponse_AnalysisTemplate
+	//	*GetAnalysisTemplateResponse_Raw
+	Result isGetAnalysisTemplateResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *GetPromotionTaskResponse) Reset() {
-	*x = GetPromotionTaskResponse{}
+func (x *GetAnalysisTemplateResponse) Reset() {
+	*x = GetAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[116]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[122]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetPromotionTaskResponse) String() string {
+func (x *GetAnalysisTemplateResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetPromotionTaskResponse) ProtoMessage() {}
+func (*GetAnalysisTemplateResponse) ProtoMessage() {}
 
-func (x *GetPromotionTaskResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[116]
+func (x *GetAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[122]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6593,74 +6848,74 @@ func (x *GetPromotionTaskResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetPromotionTaskResponse.ProtoReflect.Descriptor instead.
-func (*GetPromotionTaskResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{116}
+// Deprecated: Use GetAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
+func (*GetAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{122}
 }
 
-func (m *GetPromotionTaskResponse) GetResult() isGetPromotionTaskResponse_Result {
+func (m *GetAnalysisTemplateResponse) GetResult() isGetAnalysisTemplateResponse_Result {
 	if m != nil {
 		return m.Result
 	}
 	return nil
 }
 
-func (x *GetPromotionTaskResponse) GetPromotionTask() *v1alpha1.PromotionTask {
-	if x, ok := x.GetResult().(*GetPromotionTaskResponse_PromotionTask); ok {
-		return x.PromotionTask
+func (x *GetAnalysisTemplateResponse) GetAnalysisTemplate() *v1alpha11.AnalysisTemplate {
+	if x, ok := x.GetResult().(*GetAnalysisTemplateResponse_AnalysisTemplate); ok {
+		return x.AnalysisTemplate
 	}
 	return nil
 }
 
-func (x *GetPromotionTaskResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetPromotionTaskResponse_Raw); ok {
+func (x *GetAnalysisTemplateResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetAnalysisTemplateResponse_Raw); ok {
 		return x.Raw
 	}
 	return nil
 }
 
-type isGetPromotionTaskResponse_Result interface {
-	isGetPromotionTaskResponse_Result()
+type isGetAnalysisTemplateResponse_Result interface {
+	isGetAnalysisTemplateResponse_Result()
 }
 
-type GetPromotionTaskResponse_PromotionTask struct {
-	PromotionTask *v1alpha1.PromotionTask `protobuf:"bytes,1,opt,name=promotion_task,json=promotionTask,proto3,oneof"`
+type GetAnalysisTemplateResponse_AnalysisTemplate struct {
+	AnalysisTemplate *v1alpha11.AnalysisTemplate `protobuf:"bytes,1,opt,name=analysis_template,json=analysisTemplate,proto3,oneof"`
 }
 
-type GetPromotionTaskResponse_Raw struct {
+type GetAnalysisTemplateResponse_Raw struct {
 	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
 }
 
-func (*GetPromotionTaskResponse_PromotionTask) isGetPromotionTaskResponse_Result() {}
+func (*GetAnalysisTemplateResponse_AnalysisTemplate) isGetAnalysisTemplateResponse_Result() {}
 
-func (*GetPromotionTaskResponse_Raw) isGetPromotionTaskResponse_Result() {}
+func (*GetAnalysisTemplateResponse_Raw) isGetAnalysisTemplateResponse_Result() {}
 
-type GetClusterPromotionTaskRequest struct {
+type DeleteAnalysisTemplateRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Name   string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Format RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *GetClusterPromotionTaskRequest) Reset() {
-	*x = GetClusterPromotionTaskRequest{}
+func (x *DeleteAnalysisTemplateRequest) Reset() {
+	*x = DeleteAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[117]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[123]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetClusterPromotionTaskRequest) String() string {
+func (x *DeleteAnalysisTemplateRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetClusterPromotionTaskRequest) ProtoMessage() {}
+func (*DeleteAnalysisTemplateRequest) ProtoMessage() {}
 
-func (x *GetClusterPromotionTaskRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[117]
+func (x *DeleteAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[123]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6671,54 +6926,48 @@ func (x *GetClusterPromotionTaskRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetClusterPromotionTaskRequest.ProtoReflect.Descriptor instead.
-func (*GetClusterPromotionTaskRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{117}
+// Deprecated: Use DeleteAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
+func (*DeleteAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{123}
 }
 
-func (x *GetClusterPromotionTaskRequest) GetName() string {
+func (x *DeleteAnalysisTemplateRequest) GetProject() string {
 	if x != nil {
-		return x.Name
+		return x.Project
 	}
 	return ""
 }
 
-func (x *GetClusterPromotionTaskRequest) GetFormat() RawFormat {
+func (x *DeleteAnalysisTemplateRequest) GetName() string {
 	if x != nil {
-		return x.Format
+		return x.Name
 	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
+	return ""
 }
 
-type GetClusterPromotionTaskResponse struct {
+type DeleteAnalysisTemplateResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	// Types that are assignable to Result:
-	//
-	//	*GetClusterPromotionTaskResponse_PromotionTask
-	//	*GetClusterPromotionTaskResponse_Raw
-	Result isGetClusterPromotionTaskResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *GetClusterPromotionTaskResponse) Reset() {
-	*x = GetClusterPromotionTaskResponse{}
+func (x *DeleteAnalysisTemplateResponse) Reset() {
+	*x = DeleteAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[118]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[124]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetClusterPromotionTaskResponse) String() string {
+func (x *DeleteAnalysisTemplateResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetClusterPromotionTaskResponse) ProtoMessage() {}
+func (*DeleteAnalysisTemplateResponse) ProtoMessage() {}
 
-func (x *GetClusterPromotionTaskResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[118]
+func (x *DeleteAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[124]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6729,48 +6978,11 @@ func (x *GetClusterPromotionTaskResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetClusterPromotionTaskResponse.ProtoReflect.Descriptor instead.
-func (*GetClusterPromotionTaskResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{118}
-}
-
-func (m *GetClusterPromotionTaskResponse) GetResult() isGetClusterPromotionTaskResponse_Result {
-	if m != nil {
-		return m.Result
-	}
-	return nil
-}
-
-func (x *GetClusterPromotionTaskResponse) GetPromotionTask() *v1alpha1.ClusterPromotionTask {
-	if x, ok := x.GetResult().(*GetClusterPromotionTaskResponse_PromotionTask); ok {
-		return x.PromotionTask
-	}
-	return nil
-}
-
-func (x *GetClusterPromotionTaskResponse) GetRaw() []byte {
-	if x, ok := x.GetResult().(*GetClusterPromotionTaskResponse_Raw); ok {
-		return x.Raw
-	}
-	return nil
-}
-
-type isGetClusterPromotionTaskResponse_Result interface {
-	isGetClusterPromotionTaskResponse_Result()
-}
-
-type GetClusterPromotionTaskResponse_PromotionTask struct {
-	PromotionTask *v1alpha1.ClusterPromotionTask `protobuf:"bytes,1,opt,name=promotion_task,json=clusterPromotionTask,proto3,oneof"`
-}
-
-type GetClusterPromotionTaskResponse_Raw struct {
-	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+// Deprecated: Use DeleteAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
+func (*DeleteAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{124}
 }
 
-func (*GetClusterPromotionTaskResponse_PromotionTask) isGetClusterPromotionTaskResponse_Result() {}
-
-func (*GetClusterPromotionTaskResponse_Raw) isGetClusterPromotionTaskResponse_Result() {}
-
 type ListClusterAnalysisTemplatesRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -6780,7 +6992,7 @@ type ListClusterAnalysisTemplatesRequest struct {
 func (x *ListClusterAnalysisTemplatesRequest) Reset() {
 	*x = ListClusterAnalysisTemplatesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[119]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[125]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6793,7 +7005,7 @@ func (x *ListClusterAnalysisTemplatesRequest) String() string {
 func (*ListClusterAnalysisTemplatesRequest) ProtoMessage() {}
 
 func (x *ListClusterAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[119]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[125]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6806,7 +7018,7 @@ func (x *ListClusterAnalysisTemplatesRequest) ProtoReflect() protoreflect.Messag
 
 // Deprecated: Use ListClusterAnalysisTemplatesRequest.ProtoReflect.Descriptor instead.
 func (*ListClusterAnalysisTemplatesRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{119}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{125}
 }
 
 type ListClusterAnalysisTemplatesResponse struct {
@@ -6820,7 +7032,7 @@ type ListClusterAnalysisTemplatesResponse struct {
 func (x *ListClusterAnalysisTemplatesResponse) Reset() {
 	*x = ListClusterAnalysisTemplatesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[120]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[126]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6833,7 +7045,7 @@ func (x *ListClusterAnalysisTemplatesResponse) String() string {
 func (*ListClusterAnalysisTemplatesResponse) ProtoMessage() {}
 
 func (x *ListClusterAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[120]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[126]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6846,7 +7058,7 @@ func (x *ListClusterAnalysisTemplatesResponse) ProtoReflect() protoreflect.Messa
 
 // Deprecated: Use ListClusterAnalysisTemplatesResponse.ProtoReflect.Descriptor instead.
 func (*ListClusterAnalysisTemplatesResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{120}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{126}
 }
 
 func (x *ListClusterAnalysisTemplatesResponse) GetClusterAnalysisTemplates() []*v1alpha11.ClusterAnalysisTemplate {
@@ -6868,7 +7080,7 @@ type GetClusterAnalysisTemplateRequest struct {
 func (x *GetClusterAnalysisTemplateRequest) Reset() {
 	*x = GetClusterAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[121]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[127]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6881,7 +7093,7 @@ func (x *GetClusterAnalysisTemplateRequest) String() string {
 func (*GetClusterAnalysisTemplateRequest) ProtoMessage() {}
 
 func (x *GetClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[121]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[127]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6894,7 +7106,7 @@ func (x *GetClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use GetClusterAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
 func (*GetClusterAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{121}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{127}
 }
 
 func (x *GetClusterAnalysisTemplateRequest) GetName() string {
@@ -6926,7 +7138,7 @@ type GetClusterAnalysisTemplateResponse struct {
 func (x *GetClusterAnalysisTemplateResponse) Reset() {
 	*x = GetClusterAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[122]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[128]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6939,7 +7151,7 @@ func (x *GetClusterAnalysisTemplateResponse) String() string {
 func (*GetClusterAnalysisTemplateResponse) ProtoMessage() {}
 
 func (x *GetClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[122]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[128]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -6952,7 +7164,7 @@ func (x *GetClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use GetClusterAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
 func (*GetClusterAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{122}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{128}
 }
 
 func (m *GetClusterAnalysisTemplateResponse) GetResult() isGetClusterAnalysisTemplateResponse_Result {
@@ -6993,33 +7205,31 @@ func (*GetClusterAnalysisTemplateResponse_ClusterAnalysisTemplate) isGetClusterA
 
 func (*GetClusterAnalysisTemplateResponse_Raw) isGetClusterAnalysisTemplateResponse_Result() {}
 
-type GetAnalysisRunRequest struct {
+type DeleteClusterAnalysisTemplateRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Namespace string    `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
-	Name      string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Format    RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *GetAnalysisRunRequest) Reset() {
-	*x = GetAnalysisRunRequest{}
+func (x *DeleteClusterAnalysisTemplateRequest) Reset() {
+	*x = DeleteClusterAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[123]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[129]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetAnalysisRunRequest) String() string {
+func (x *DeleteClusterAnalysisTemplateRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetAnalysisRunRequest) ProtoMessage() {}
+func (*DeleteClusterAnalysisTemplateRequest) ProtoMessage() {}
 
-func (x *GetAnalysisRunRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[123]
+func (x *DeleteClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[129]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7030,61 +7240,41 @@ func (x *GetAnalysisRunRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetAnalysisRunRequest.ProtoReflect.Descriptor instead.
-func (*GetAnalysisRunRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{123}
-}
-
-func (x *GetAnalysisRunRequest) GetNamespace() string {
-	if x != nil {
-		return x.Namespace
-	}
-	return ""
+// Deprecated: Use DeleteClusterAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
+func (*DeleteClusterAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{129}
 }
 
-func (x *GetAnalysisRunRequest) GetName() string {
+func (x *DeleteClusterAnalysisTemplateRequest) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-func (x *GetAnalysisRunRequest) GetFormat() RawFormat {
-	if x != nil {
-		return x.Format
-	}
-	return RawFormat_RAW_FORMAT_UNSPECIFIED
-}
-
-type GetAnalysisRunResponse struct {
+type DeleteClusterAnalysisTemplateResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	// Types that are assignable to Result:
-	//
-	//	*GetAnalysisRunResponse_AnalysisRun
-	//	*GetAnalysisRunResponse_Raw
-	Result isGetAnalysisRunResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *GetAnalysisRunResponse) Reset() {
-	*x = GetAnalysisRunResponse{}
+func (x *DeleteClusterAnalysisTemplateResponse) Reset() {
+	*x = DeleteClusterAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[124]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[130]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetAnalysisRunResponse) String() string {
+func (x *DeleteClusterAnalysisTemplateResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetAnalysisRunResponse) ProtoMessage() {}
+func (*DeleteClusterAnalysisTemplateResponse) ProtoMessage() {}
 
-func (x *GetAnalysisRunResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[124]
+func (x *DeleteClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[130]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7095,22 +7285,129 @@ func (x *GetAnalysisRunResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetAnalysisRunResponse.ProtoReflect.Descriptor instead.
-func (*GetAnalysisRunResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{124}
+// Deprecated: Use DeleteClusterAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
+func (*DeleteClusterAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{130}
 }
 
-func (m *GetAnalysisRunResponse) GetResult() isGetAnalysisRunResponse_Result {
-	if m != nil {
-		return m.Result
-	}
-	return nil
+type GetAnalysisRunRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Namespace string    `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
+	Name      string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Format    RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *GetAnalysisRunResponse) GetAnalysisRun() *v1alpha11.AnalysisRun {
-	if x, ok := x.GetResult().(*GetAnalysisRunResponse_AnalysisRun); ok {
-		return x.AnalysisRun
-	}
+func (x *GetAnalysisRunRequest) Reset() {
+	*x = GetAnalysisRunRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[131]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAnalysisRunRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAnalysisRunRequest) ProtoMessage() {}
+
+func (x *GetAnalysisRunRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[131]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAnalysisRunRequest.ProtoReflect.Descriptor instead.
+func (*GetAnalysisRunRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{131}
+}
+
+func (x *GetAnalysisRunRequest) GetNamespace() string {
+	if x != nil {
+		return x.Namespace
+	}
+	return ""
+}
+
+func (x *GetAnalysisRunRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *GetAnalysisRunRequest) GetFormat() RawFormat {
+	if x != nil {
+		return x.Format
+	}
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
+}
+
+type GetAnalysisRunResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Result:
+	//
+	//	*GetAnalysisRunResponse_AnalysisRun
+	//	*GetAnalysisRunResponse_Raw
+	Result isGetAnalysisRunResponse_Result `protobuf_oneof:"result"`
+}
+
+func (x *GetAnalysisRunResponse) Reset() {
+	*x = GetAnalysisRunResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[132]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAnalysisRunResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAnalysisRunResponse) ProtoMessage() {}
+
+func (x *GetAnalysisRunResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[132]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAnalysisRunResponse.ProtoReflect.Descriptor instead.
+func (*GetAnalysisRunResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{132}
+}
+
+func (m *GetAnalysisRunResponse) GetResult() isGetAnalysisRunResponse_Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+func (x *GetAnalysisRunResponse) GetAnalysisRun() *v1alpha11.AnalysisRun {
+	if x, ok := x.GetResult().(*GetAnalysisRunResponse_AnalysisRun); ok {
+		return x.AnalysisRun
+	}
 	return nil
 }
 
@@ -7151,7 +7448,7 @@ type GetAnalysisRunLogsRequest struct {
 func (x *GetAnalysisRunLogsRequest) Reset() {
 	*x = GetAnalysisRunLogsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[125]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[133]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7164,7 +7461,7 @@ func (x *GetAnalysisRunLogsRequest) String() string {
 func (*GetAnalysisRunLogsRequest) ProtoMessage() {}
 
 func (x *GetAnalysisRunLogsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[125]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[133]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7177,7 +7474,7 @@ func (x *GetAnalysisRunLogsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAnalysisRunLogsRequest.ProtoReflect.Descriptor instead.
 func (*GetAnalysisRunLogsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{125}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{133}
 }
 
 func (x *GetAnalysisRunLogsRequest) GetNamespace() string {
@@ -7219,7 +7516,7 @@ type GetAnalysisRunLogsResponse struct {
 func (x *GetAnalysisRunLogsResponse) Reset() {
 	*x = GetAnalysisRunLogsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[126]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[134]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7232,7 +7529,7 @@ func (x *GetAnalysisRunLogsResponse) String() string {
 func (*GetAnalysisRunLogsResponse) ProtoMessage() {}
 
 func (x *GetAnalysisRunLogsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[126]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[134]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7245,7 +7542,7 @@ func (x *GetAnalysisRunLogsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAnalysisRunLogsResponse.ProtoReflect.Descriptor instead.
 func (*GetAnalysisRunLogsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{126}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{134}
 }
 
 func (x *GetAnalysisRunLogsResponse) GetChunk() string {
@@ -7255,32 +7552,31 @@ func (x *GetAnalysisRunLogsResponse) GetChunk() string {
 	return ""
 }
 
-type DeleteAnalysisTemplateRequest struct {
+type ListProjectEventsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 }
 
-func (x *DeleteAnalysisTemplateRequest) Reset() {
-	*x = DeleteAnalysisTemplateRequest{}
+func (x *ListProjectEventsRequest) Reset() {
+	*x = ListProjectEventsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[127]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[135]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteAnalysisTemplateRequest) String() string {
+func (x *ListProjectEventsRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteAnalysisTemplateRequest) ProtoMessage() {}
+func (*ListProjectEventsRequest) ProtoMessage() {}
 
-func (x *DeleteAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[127]
+func (x *ListProjectEventsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[135]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7291,48 +7587,43 @@ func (x *DeleteAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
-func (*DeleteAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{127}
+// Deprecated: Use ListProjectEventsRequest.ProtoReflect.Descriptor instead.
+func (*ListProjectEventsRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{135}
 }
 
-func (x *DeleteAnalysisTemplateRequest) GetProject() string {
+func (x *ListProjectEventsRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-func (x *DeleteAnalysisTemplateRequest) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-type DeleteAnalysisTemplateResponse struct {
+type ListProjectEventsResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Events []*v1.Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
 }
 
-func (x *DeleteAnalysisTemplateResponse) Reset() {
-	*x = DeleteAnalysisTemplateResponse{}
+func (x *ListProjectEventsResponse) Reset() {
+	*x = ListProjectEventsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[128]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[136]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteAnalysisTemplateResponse) String() string {
+func (x *ListProjectEventsResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteAnalysisTemplateResponse) ProtoMessage() {}
+func (*ListProjectEventsResponse) ProtoMessage() {}
 
-func (x *DeleteAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[128]
+func (x *ListProjectEventsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[136]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7343,36 +7634,43 @@ func (x *DeleteAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
-func (*DeleteAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{128}
+// Deprecated: Use ListProjectEventsResponse.ProtoReflect.Descriptor instead.
+func (*ListProjectEventsResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{136}
 }
 
-type DeleteClusterAnalysisTemplateRequest struct {
+func (x *ListProjectEventsResponse) GetEvents() []*v1.Event {
+	if x != nil {
+		return x.Events
+	}
+	return nil
+}
+
+type ListPromotionTasksRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
 }
 
-func (x *DeleteClusterAnalysisTemplateRequest) Reset() {
-	*x = DeleteClusterAnalysisTemplateRequest{}
+func (x *ListPromotionTasksRequest) Reset() {
+	*x = ListPromotionTasksRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[129]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[137]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteClusterAnalysisTemplateRequest) String() string {
+func (x *ListPromotionTasksRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteClusterAnalysisTemplateRequest) ProtoMessage() {}
+func (*ListPromotionTasksRequest) ProtoMessage() {}
 
-func (x *DeleteClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[129]
+func (x *ListPromotionTasksRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[137]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7383,41 +7681,43 @@ func (x *DeleteClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Messa
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteClusterAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
-func (*DeleteClusterAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{129}
+// Deprecated: Use ListPromotionTasksRequest.ProtoReflect.Descriptor instead.
+func (*ListPromotionTasksRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{137}
 }
 
-func (x *DeleteClusterAnalysisTemplateRequest) GetName() string {
+func (x *ListPromotionTasksRequest) GetProject() string {
 	if x != nil {
-		return x.Name
+		return x.Project
 	}
 	return ""
 }
 
-type DeleteClusterAnalysisTemplateResponse struct {
+type ListPromotionTasksResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	PromotionTasks []*v1alpha1.PromotionTask `protobuf:"bytes,1,rep,name=promotion_tasks,json=promotionTasks,proto3" json:"promotion_tasks,omitempty"`
 }
 
-func (x *DeleteClusterAnalysisTemplateResponse) Reset() {
-	*x = DeleteClusterAnalysisTemplateResponse{}
+func (x *ListPromotionTasksResponse) Reset() {
+	*x = ListPromotionTasksResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[130]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[138]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteClusterAnalysisTemplateResponse) String() string {
+func (x *ListPromotionTasksResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteClusterAnalysisTemplateResponse) ProtoMessage() {}
+func (*ListPromotionTasksResponse) ProtoMessage() {}
 
-func (x *DeleteClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[130]
+func (x *ListPromotionTasksResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[138]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7428,36 +7728,45 @@ func (x *DeleteClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Mess
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteClusterAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
-func (*DeleteClusterAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{130}
+// Deprecated: Use ListPromotionTasksResponse.ProtoReflect.Descriptor instead.
+func (*ListPromotionTasksResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{138}
 }
 
-type ListProjectEventsRequest struct {
+func (x *ListPromotionTasksResponse) GetPromotionTasks() []*v1alpha1.PromotionTask {
+	if x != nil {
+		return x.PromotionTasks
+	}
+	return nil
+}
+
+type GetPromotionTaskRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Project string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Format  RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *ListProjectEventsRequest) Reset() {
-	*x = ListProjectEventsRequest{}
+func (x *GetPromotionTaskRequest) Reset() {
+	*x = GetPromotionTaskRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[131]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[139]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListProjectEventsRequest) String() string {
+func (x *GetPromotionTaskRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListProjectEventsRequest) ProtoMessage() {}
+func (*GetPromotionTaskRequest) ProtoMessage() {}
 
-func (x *ListProjectEventsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[131]
+func (x *GetPromotionTaskRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[139]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7468,43 +7777,61 @@ func (x *ListProjectEventsRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListProjectEventsRequest.ProtoReflect.Descriptor instead.
-func (*ListProjectEventsRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{131}
+// Deprecated: Use GetPromotionTaskRequest.ProtoReflect.Descriptor instead.
+func (*GetPromotionTaskRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{139}
 }
 
-func (x *ListProjectEventsRequest) GetProject() string {
+func (x *GetPromotionTaskRequest) GetProject() string {
 	if x != nil {
 		return x.Project
 	}
 	return ""
 }
 
-type ListProjectEventsResponse struct {
+func (x *GetPromotionTaskRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *GetPromotionTaskRequest) GetFormat() RawFormat {
+	if x != nil {
+		return x.Format
+	}
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
+}
+
+type GetPromotionTaskResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Events []*v1.Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
+	// Types that are assignable to Result:
+	//
+	//	*GetPromotionTaskResponse_PromotionTask
+	//	*GetPromotionTaskResponse_Raw
+	Result isGetPromotionTaskResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *ListProjectEventsResponse) Reset() {
-	*x = ListProjectEventsResponse{}
+func (x *GetPromotionTaskResponse) Reset() {
+	*x = GetPromotionTaskResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[132]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[140]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *ListProjectEventsResponse) String() string {
+func (x *GetPromotionTaskResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ListProjectEventsResponse) ProtoMessage() {}
+func (*GetPromotionTaskResponse) ProtoMessage() {}
 
-func (x *ListProjectEventsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[132]
+func (x *GetPromotionTaskResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[140]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7515,43 +7842,71 @@ func (x *ListProjectEventsResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ListProjectEventsResponse.ProtoReflect.Descriptor instead.
-func (*ListProjectEventsResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{132}
+// Deprecated: Use GetPromotionTaskResponse.ProtoReflect.Descriptor instead.
+func (*GetPromotionTaskResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{140}
 }
 
-func (x *ListProjectEventsResponse) GetEvents() []*v1.Event {
-	if x != nil {
-		return x.Events
+func (m *GetPromotionTaskResponse) GetResult() isGetPromotionTaskResponse_Result {
+	if m != nil {
+		return m.Result
 	}
 	return nil
 }
 
-type CreateRoleRequest struct {
+func (x *GetPromotionTaskResponse) GetPromotionTask() *v1alpha1.PromotionTask {
+	if x, ok := x.GetResult().(*GetPromotionTaskResponse_PromotionTask); ok {
+		return x.PromotionTask
+	}
+	return nil
+}
+
+func (x *GetPromotionTaskResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetPromotionTaskResponse_Raw); ok {
+		return x.Raw
+	}
+	return nil
+}
+
+type isGetPromotionTaskResponse_Result interface {
+	isGetPromotionTaskResponse_Result()
+}
+
+type GetPromotionTaskResponse_PromotionTask struct {
+	PromotionTask *v1alpha1.PromotionTask `protobuf:"bytes,1,opt,name=promotion_task,json=promotionTask,proto3,oneof"`
+}
+
+type GetPromotionTaskResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+}
+
+func (*GetPromotionTaskResponse_PromotionTask) isGetPromotionTaskResponse_Result() {}
+
+func (*GetPromotionTaskResponse_Raw) isGetPromotionTaskResponse_Result() {}
+
+type ListClusterPromotionTasksRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
-
-	Role *v1alpha12.Role `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
 }
 
-func (x *CreateRoleRequest) Reset() {
-	*x = CreateRoleRequest{}
+func (x *ListClusterPromotionTasksRequest) Reset() {
+	*x = ListClusterPromotionTasksRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[133]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[141]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *CreateRoleRequest) String() string {
+func (x *ListClusterPromotionTasksRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*CreateRoleRequest) ProtoMessage() {}
+func (*ListClusterPromotionTasksRequest) ProtoMessage() {}
 
-func (x *CreateRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[133]
+func (x *ListClusterPromotionTasksRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[141]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7562,43 +7917,36 @@ func (x *CreateRoleRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use CreateRoleRequest.ProtoReflect.Descriptor instead.
-func (*CreateRoleRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{133}
-}
-
-func (x *CreateRoleRequest) GetRole() *v1alpha12.Role {
-	if x != nil {
-		return x.Role
-	}
-	return nil
+// Deprecated: Use ListClusterPromotionTasksRequest.ProtoReflect.Descriptor instead.
+func (*ListClusterPromotionTasksRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{141}
 }
 
-type CreateRoleResponse struct {
+type ListClusterPromotionTasksResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Role *v1alpha12.Role `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
+	ClusterPromotionTasks []*v1alpha1.ClusterPromotionTask `protobuf:"bytes,1,rep,name=cluster_promotion_tasks,json=clusterPromotionTasks,proto3" json:"cluster_promotion_tasks,omitempty"`
 }
 
-func (x *CreateRoleResponse) Reset() {
-	*x = CreateRoleResponse{}
+func (x *ListClusterPromotionTasksResponse) Reset() {
+	*x = ListClusterPromotionTasksResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[134]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[142]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *CreateRoleResponse) String() string {
+func (x *ListClusterPromotionTasksResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*CreateRoleResponse) ProtoMessage() {}
+func (*ListClusterPromotionTasksResponse) ProtoMessage() {}
 
-func (x *CreateRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[134]
+func (x *ListClusterPromotionTasksResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[142]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7609,44 +7957,44 @@ func (x *CreateRoleResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use CreateRoleResponse.ProtoReflect.Descriptor instead.
-func (*CreateRoleResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{134}
+// Deprecated: Use ListClusterPromotionTasksResponse.ProtoReflect.Descriptor instead.
+func (*ListClusterPromotionTasksResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{142}
 }
 
-func (x *CreateRoleResponse) GetRole() *v1alpha12.Role {
+func (x *ListClusterPromotionTasksResponse) GetClusterPromotionTasks() []*v1alpha1.ClusterPromotionTask {
 	if x != nil {
-		return x.Role
+		return x.ClusterPromotionTasks
 	}
 	return nil
 }
 
-type DeleteRoleRequest struct {
+type GetClusterPromotionTaskRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Name   string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Format RawFormat `protobuf:"varint,3,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
 }
 
-func (x *DeleteRoleRequest) Reset() {
-	*x = DeleteRoleRequest{}
+func (x *GetClusterPromotionTaskRequest) Reset() {
+	*x = GetClusterPromotionTaskRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[135]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[143]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteRoleRequest) String() string {
+func (x *GetClusterPromotionTaskRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteRoleRequest) ProtoMessage() {}
+func (*GetClusterPromotionTaskRequest) ProtoMessage() {}
 
-func (x *DeleteRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[135]
+func (x *GetClusterPromotionTaskRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[143]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7657,48 +8005,54 @@ func (x *DeleteRoleRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteRoleRequest.ProtoReflect.Descriptor instead.
-func (*DeleteRoleRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{135}
+// Deprecated: Use GetClusterPromotionTaskRequest.ProtoReflect.Descriptor instead.
+func (*GetClusterPromotionTaskRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{143}
 }
 
-func (x *DeleteRoleRequest) GetProject() string {
+func (x *GetClusterPromotionTaskRequest) GetName() string {
 	if x != nil {
-		return x.Project
+		return x.Name
 	}
 	return ""
 }
 
-func (x *DeleteRoleRequest) GetName() string {
+func (x *GetClusterPromotionTaskRequest) GetFormat() RawFormat {
 	if x != nil {
-		return x.Name
+		return x.Format
 	}
-	return ""
+	return RawFormat_RAW_FORMAT_UNSPECIFIED
 }
 
-type DeleteRoleResponse struct {
+type GetClusterPromotionTaskResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Result:
+	//
+	//	*GetClusterPromotionTaskResponse_PromotionTask
+	//	*GetClusterPromotionTaskResponse_Raw
+	Result isGetClusterPromotionTaskResponse_Result `protobuf_oneof:"result"`
 }
 
-func (x *DeleteRoleResponse) Reset() {
-	*x = DeleteRoleResponse{}
+func (x *GetClusterPromotionTaskResponse) Reset() {
+	*x = GetClusterPromotionTaskResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[136]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[144]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *DeleteRoleResponse) String() string {
+func (x *GetClusterPromotionTaskResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*DeleteRoleResponse) ProtoMessage() {}
+func (*GetClusterPromotionTaskResponse) ProtoMessage() {}
 
-func (x *DeleteRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[136]
+func (x *GetClusterPromotionTaskResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[144]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7709,41 +8063,265 @@ func (x *DeleteRoleResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteRoleResponse.ProtoReflect.Descriptor instead.
-func (*DeleteRoleResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{136}
+// Deprecated: Use GetClusterPromotionTaskResponse.ProtoReflect.Descriptor instead.
+func (*GetClusterPromotionTaskResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{144}
 }
 
-type GetRoleRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
+func (m *GetClusterPromotionTaskResponse) GetResult() isGetClusterPromotionTaskResponse_Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
 
-	Project     string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
-	Name        string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	AsResources bool      `protobuf:"varint,3,opt,name=as_resources,json=asResources,proto3" json:"as_resources,omitempty"`
-	Format      RawFormat `protobuf:"varint,4,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+func (x *GetClusterPromotionTaskResponse) GetPromotionTask() *v1alpha1.ClusterPromotionTask {
+	if x, ok := x.GetResult().(*GetClusterPromotionTaskResponse_PromotionTask); ok {
+		return x.PromotionTask
+	}
+	return nil
 }
 
-func (x *GetRoleRequest) Reset() {
-	*x = GetRoleRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[137]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
+func (x *GetClusterPromotionTaskResponse) GetRaw() []byte {
+	if x, ok := x.GetResult().(*GetClusterPromotionTaskResponse_Raw); ok {
+		return x.Raw
 	}
+	return nil
 }
 
-func (x *GetRoleRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
+type isGetClusterPromotionTaskResponse_Result interface {
+	isGetClusterPromotionTaskResponse_Result()
 }
 
-func (*GetRoleRequest) ProtoMessage() {}
+type GetClusterPromotionTaskResponse_PromotionTask struct {
+	PromotionTask *v1alpha1.ClusterPromotionTask `protobuf:"bytes,1,opt,name=promotion_task,json=clusterPromotionTask,proto3,oneof"`
+}
 
-func (x *GetRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[137]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+type GetClusterPromotionTaskResponse_Raw struct {
+	Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3,oneof"`
+}
+
+func (*GetClusterPromotionTaskResponse_PromotionTask) isGetClusterPromotionTaskResponse_Result() {}
+
+func (*GetClusterPromotionTaskResponse_Raw) isGetClusterPromotionTaskResponse_Result() {}
+
+type CreateRoleRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Role *v1alpha12.Role `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
+}
+
+func (x *CreateRoleRequest) Reset() {
+	*x = CreateRoleRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[145]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateRoleRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateRoleRequest) ProtoMessage() {}
+
+func (x *CreateRoleRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[145]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateRoleRequest.ProtoReflect.Descriptor instead.
+func (*CreateRoleRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{145}
+}
+
+func (x *CreateRoleRequest) GetRole() *v1alpha12.Role {
+	if x != nil {
+		return x.Role
+	}
+	return nil
+}
+
+type CreateRoleResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Role *v1alpha12.Role `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
+}
+
+func (x *CreateRoleResponse) Reset() {
+	*x = CreateRoleResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[146]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateRoleResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateRoleResponse) ProtoMessage() {}
+
+func (x *CreateRoleResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[146]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateRoleResponse.ProtoReflect.Descriptor instead.
+func (*CreateRoleResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{146}
+}
+
+func (x *CreateRoleResponse) GetRole() *v1alpha12.Role {
+	if x != nil {
+		return x.Role
+	}
+	return nil
+}
+
+type DeleteRoleRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *DeleteRoleRequest) Reset() {
+	*x = DeleteRoleRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[147]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteRoleRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteRoleRequest) ProtoMessage() {}
+
+func (x *DeleteRoleRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[147]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteRoleRequest.ProtoReflect.Descriptor instead.
+func (*DeleteRoleRequest) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{147}
+}
+
+func (x *DeleteRoleRequest) GetProject() string {
+	if x != nil {
+		return x.Project
+	}
+	return ""
+}
+
+func (x *DeleteRoleRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type DeleteRoleResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DeleteRoleResponse) Reset() {
+	*x = DeleteRoleResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[148]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteRoleResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteRoleResponse) ProtoMessage() {}
+
+func (x *DeleteRoleResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[148]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteRoleResponse.ProtoReflect.Descriptor instead.
+func (*DeleteRoleResponse) Descriptor() ([]byte, []int) {
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{148}
+}
+
+type GetRoleRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Project     string    `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
+	Name        string    `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	AsResources bool      `protobuf:"varint,3,opt,name=as_resources,json=asResources,proto3" json:"as_resources,omitempty"`
+	Format      RawFormat `protobuf:"varint,4,opt,name=format,proto3,enum=akuity.io.kargo.service.v1alpha1.RawFormat" json:"format,omitempty"`
+}
+
+func (x *GetRoleRequest) Reset() {
+	*x = GetRoleRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[149]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetRoleRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetRoleRequest) ProtoMessage() {}
+
+func (x *GetRoleRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[149]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
 		}
@@ -7754,7 +8332,7 @@ func (x *GetRoleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRoleRequest.ProtoReflect.Descriptor instead.
 func (*GetRoleRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{137}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{149}
 }
 
 func (x *GetRoleRequest) GetProject() string {
@@ -7801,7 +8379,7 @@ type GetRoleResponse struct {
 func (x *GetRoleResponse) Reset() {
 	*x = GetRoleResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[138]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[150]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7814,7 +8392,7 @@ func (x *GetRoleResponse) String() string {
 func (*GetRoleResponse) ProtoMessage() {}
 
 func (x *GetRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[138]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[150]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7827,7 +8405,7 @@ func (x *GetRoleResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRoleResponse.ProtoReflect.Descriptor instead.
 func (*GetRoleResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{138}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{150}
 }
 
 func (m *GetRoleResponse) GetResult() isGetRoleResponse_Result {
@@ -7892,7 +8470,7 @@ type Claims struct {
 func (x *Claims) Reset() {
 	*x = Claims{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[139]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[151]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7905,7 +8483,7 @@ func (x *Claims) String() string {
 func (*Claims) ProtoMessage() {}
 
 func (x *Claims) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[139]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[151]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7918,7 +8496,7 @@ func (x *Claims) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Claims.ProtoReflect.Descriptor instead.
 func (*Claims) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{139}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{151}
 }
 
 func (x *Claims) GetClaims() []*v1alpha12.Claim {
@@ -7945,7 +8523,7 @@ type GrantRequest struct {
 func (x *GrantRequest) Reset() {
 	*x = GrantRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[140]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[152]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7958,7 +8536,7 @@ func (x *GrantRequest) String() string {
 func (*GrantRequest) ProtoMessage() {}
 
 func (x *GrantRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[140]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[152]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -7971,7 +8549,7 @@ func (x *GrantRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GrantRequest.ProtoReflect.Descriptor instead.
 func (*GrantRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{140}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{152}
 }
 
 func (x *GrantRequest) GetProject() string {
@@ -8036,7 +8614,7 @@ type GrantResponse struct {
 func (x *GrantResponse) Reset() {
 	*x = GrantResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[141]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[153]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8049,7 +8627,7 @@ func (x *GrantResponse) String() string {
 func (*GrantResponse) ProtoMessage() {}
 
 func (x *GrantResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[141]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[153]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8062,7 +8640,7 @@ func (x *GrantResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GrantResponse.ProtoReflect.Descriptor instead.
 func (*GrantResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{141}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{153}
 }
 
 func (x *GrantResponse) GetRole() *v1alpha12.Role {
@@ -8084,7 +8662,7 @@ type ListRolesRequest struct {
 func (x *ListRolesRequest) Reset() {
 	*x = ListRolesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[142]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[154]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8097,7 +8675,7 @@ func (x *ListRolesRequest) String() string {
 func (*ListRolesRequest) ProtoMessage() {}
 
 func (x *ListRolesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[142]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[154]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8110,7 +8688,7 @@ func (x *ListRolesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListRolesRequest.ProtoReflect.Descriptor instead.
 func (*ListRolesRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{142}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{154}
 }
 
 func (x *ListRolesRequest) GetProject() string {
@@ -8140,7 +8718,7 @@ type ListRolesResponse struct {
 func (x *ListRolesResponse) Reset() {
 	*x = ListRolesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[143]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[155]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8153,7 +8731,7 @@ func (x *ListRolesResponse) String() string {
 func (*ListRolesResponse) ProtoMessage() {}
 
 func (x *ListRolesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[143]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[155]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8166,7 +8744,7 @@ func (x *ListRolesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListRolesResponse.ProtoReflect.Descriptor instead.
 func (*ListRolesResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{143}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{155}
 }
 
 func (x *ListRolesResponse) GetRoles() []*v1alpha12.Role {
@@ -8200,7 +8778,7 @@ type RevokeRequest struct {
 func (x *RevokeRequest) Reset() {
 	*x = RevokeRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[144]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[156]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8213,7 +8791,7 @@ func (x *RevokeRequest) String() string {
 func (*RevokeRequest) ProtoMessage() {}
 
 func (x *RevokeRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[144]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[156]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8226,7 +8804,7 @@ func (x *RevokeRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RevokeRequest.ProtoReflect.Descriptor instead.
 func (*RevokeRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{144}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{156}
 }
 
 func (x *RevokeRequest) GetProject() string {
@@ -8291,7 +8869,7 @@ type RevokeResponse struct {
 func (x *RevokeResponse) Reset() {
 	*x = RevokeResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[145]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[157]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8304,7 +8882,7 @@ func (x *RevokeResponse) String() string {
 func (*RevokeResponse) ProtoMessage() {}
 
 func (x *RevokeResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[145]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[157]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8317,7 +8895,7 @@ func (x *RevokeResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RevokeResponse.ProtoReflect.Descriptor instead.
 func (*RevokeResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{145}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{157}
 }
 
 func (x *RevokeResponse) GetRole() *v1alpha12.Role {
@@ -8338,7 +8916,7 @@ type UpdateRoleRequest struct {
 func (x *UpdateRoleRequest) Reset() {
 	*x = UpdateRoleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[146]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[158]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8351,7 +8929,7 @@ func (x *UpdateRoleRequest) String() string {
 func (*UpdateRoleRequest) ProtoMessage() {}
 
 func (x *UpdateRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[146]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[158]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8364,7 +8942,7 @@ func (x *UpdateRoleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateRoleRequest.ProtoReflect.Descriptor instead.
 func (*UpdateRoleRequest) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{146}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{158}
 }
 
 func (x *UpdateRoleRequest) GetRole() *v1alpha12.Role {
@@ -8385,7 +8963,7 @@ type UpdateRoleResponse struct {
 func (x *UpdateRoleResponse) Reset() {
 	*x = UpdateRoleResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_service_v1alpha1_service_proto_msgTypes[147]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[159]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -8398,7 +8976,7 @@ func (x *UpdateRoleResponse) String() string {
 func (*UpdateRoleResponse) ProtoMessage() {}
 
 func (x *UpdateRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_api_service_v1alpha1_service_proto_msgTypes[147]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[159]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -8411,7 +8989,7 @@ func (x *UpdateRoleResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateRoleResponse.ProtoReflect.Descriptor instead.
 func (*UpdateRoleResponse) Descriptor() ([]byte, []int) {
-	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{147}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{159}
 }
 
 func (x *UpdateRoleResponse) GetRole() *v1alpha12.Role {
@@ -8693,370 +9271,376 @@ var file_api_service_v1alpha1_service_proto_rawDesc = []byte{
 	0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e,
 	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69,
 	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52,
-	0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x56, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72,
-	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x05, 0x73, 0x74, 0x61,
-	0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67,
-	0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x69,
-	0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6d,
-	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67,
-	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70,
-	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x57, 0x0a, 0x16, 0x57, 0x61, 0x74,
-	0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x19, 0x0a,
-	0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05,
-	0x73, 0x74, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61,
-	0x67, 0x65, 0x22, 0x7c, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a,
-	0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04,
-	0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
-	0x22, 0x88, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72,
-	0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x14,
-	0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
-	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d,
-	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x22, 0x45, 0x0a, 0x15, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d,
-	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7b, 0x0a, 0x16, 0x57, 0x61,
-	0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
-	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
-	0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x45, 0x0a, 0x15, 0x41, 0x62, 0x6f, 0x72, 0x74,
-	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x18,
-	0x0a, 0x16, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x0a,
-	0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
-	0x1d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72,
-	0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a,
-	0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d,
-	0x61, 0x74, 0x22, 0x96, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
-	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x5c, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0d,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a,
-	0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61,
-	0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x6c, 0x0a, 0x11, 0x47,
-	0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61,
-	0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x7d, 0x0a, 0x12, 0x47, 0x65, 0x74,
-	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x49, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x48,
-	0x00, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61,
-	0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08,
-	0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73,
-	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x88,
-	0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
-	0x48, 0x01, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x66,
-	0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x06, 0x66,
-	0x69, 0x6c, 0x74, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x67,
-	0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x42,
-	0x09, 0x0a, 0x07, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x77, 0x0a, 0x14, 0x4c, 0x69,
-	0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x49, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x14, 0x0a,
-	0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f,
-	0x74, 0x61, 0x6c, 0x22, 0x71, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x46, 0x72,
-	0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c,
-	0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73,
-	0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76,
-	0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x5a, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
-	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x17, 0x0a, 0x15,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65,
-	0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69,
-	0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12,
-	0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f,
-	0x72, 0x6d, 0x61, 0x74, 0x22, 0x7d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67,
-	0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x66, 0x72,
-	0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x69,
+	0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x5e, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75,
+	0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
+	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06,
+	0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x96, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x6c,
+	0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x0e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69,
 	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x48, 0x00, 0x52, 0x07, 0x66, 0x72,
-	0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x13, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x72, 0x65, 0x69,
-	0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f,
-	0x6a, 0x65, 0x63, 0x74, 0x22, 0x73, 0x0a, 0x14, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x72, 0x65,
-	0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x07,
-	0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e,
-	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x07, 0x66, 0x72,
-	0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x15, 0x50, 0x72,
-	0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a,
-	0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74,
-	0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x23, 0x0a,
-	0x0d, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69,
-	0x61, 0x73, 0x22, 0x67, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53,
-	0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09,
-	0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x61, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x48, 0x00, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00,
+	0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
+	0x1c, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1d, 0x0a,
+	0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19,
+	0x57, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x1a, 0x57, 0x61,
+	0x74, 0x63, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0e, 0x63, 0x6c, 0x75, 0x73,
+	0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72,
+	0x65, 0x73, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x7a, 0x0a, 0x1c, 0x52, 0x65, 0x66, 0x72, 0x65,
+	0x73, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0e, 0x63, 0x6c, 0x75, 0x73, 0x74,
+	0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x89, 0x01, 0x0a, 0x18,
-	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61,
-	0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x72, 0x65, 0x69,
-	0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67,
-	0x68, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x61, 0x6c,
-	0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x69, 0x67,
-	0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x6c, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75,
-	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46,
-	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
-	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x19, 0x0a,
-	0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x19,
-	0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x76,
-	0x65, 0x72, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x76, 0x65,
-	0x72, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x07,
-	0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x73, 0x22, 0xdc, 0x01,
-	0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73,
-	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46,
-	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47,
-	0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x73, 0x1a, 0x68, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 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, 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73,
-	0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x0b,
-	0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x07, 0x66,
-	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67,
-	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x07, 0x66, 0x72, 0x65,
-	0x69, 0x67, 0x68, 0x74, 0x22, 0x83, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46,
-	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x1b, 0x0a,
-	0x09, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x6e, 0x65, 0x77, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x55, 0x70,
-	0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x65,
-	0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x52,
-	0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x4a, 0x0a, 0x18, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x41,
-	0x62, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74,
-	0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x69, 0x0a, 0x16, 0x4c,
-	0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75,
-	0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x22, 0x56, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x88, 0x01,
+	0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x69, 0x0a, 0x16, 0x4c,
+	0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68,
 	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61,
 	0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x0a, 0x77, 0x61, 0x72, 0x65,
-	0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x61,
-	0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18,
-	0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06,
-	0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61,
-	0x74, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75,
-	0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x09, 0x77, 0x61,
-	0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e,
+	0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x57, 0x0a, 0x16, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x05, 0x73, 0x74,
+	0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61,
+	0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22,
+	0x7c, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09, 0x70, 0x72,
+	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e,
 	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
 	0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x48, 0x00,
-	0x52, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x72,
-	0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42,
-	0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x46, 0x0a, 0x16, 0x57, 0x61, 0x74,
-	0x63, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a,
-	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x22, 0x7c, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f,
-	0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09,
-	0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65,
-	0x52, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74,
-	0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22,
-	0x46, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75,
-	0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09,
+	0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x88, 0x01,
+	0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+	0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74,
+	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x4f, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48,
+	0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
+	0x22, 0x45, 0x0a, 0x15, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f,
 	0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a,
 	0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x47, 0x0a, 0x17, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72,
-	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7b, 0x0a, 0x16, 0x57, 0x61, 0x74, 0x63, 0x68,
+	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x4d, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
+	0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+	0x74, 0x79, 0x70, 0x65, 0x22, 0x45, 0x0a, 0x15, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f,
+	0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
 	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
 	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x69, 0x0a, 0x18, 0x52,
-	0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68,
-	0x6f, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x41,
+	0x62, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6c, 0x0a, 0x11, 0x47, 0x65,
+	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+	0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x7d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49,
+	0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00,
+	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74,
+	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x88, 0x01,
+	0x01, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48,
+	0x01, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69,
+	0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x06, 0x66, 0x69,
+	0x6c, 0x74, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x67, 0x65,
+	0x5f, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x42, 0x09,
+	0x0a, 0x07, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x77, 0x0a, 0x14, 0x4c, 0x69, 0x73,
+	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x49, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05,
+	0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74,
+	0x61, 0x6c, 0x22, 0x78, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61,
+	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f,
+	0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x96, 0x01, 0x0a,
+	0x18, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x0e, 0x70, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x36, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x1d, 0x0a,
+	0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x19,
+	0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a,
+	0x65, 0x63, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x1a, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74,
 	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b,
 	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x09, 0x77, 0x61, 0x72,
-	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x52, 0x0a,
-	0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72,
-	0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x73,
-	0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b,
-	0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76,
-	0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74,
-	0x73, 0x22, 0x81, 0x02, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
+	0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12,
+	0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79,
+	0x70, 0x65, 0x22, 0x37, 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x50, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x7a, 0x0a, 0x1c, 0x52,
+	0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x0e, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x71, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x72, 0x6f,
+	0x76, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 	0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
 	0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20,
-	0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-	0x12, 0x5a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46,
-	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53,
-	0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74,
-	0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09,
-	0x44, 0x61, 0x74, 0x61, 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, 0x51, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70,
-	0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
-	0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x81, 0x02, 0x0a, 0x1a, 0x55, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14,
+	0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61,
+	0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x70,
+	0x70, 0x72, 0x6f, 0x76, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72,
+	0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c,
+	0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73,
+	0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9c, 0x01, 0x0a, 0x11, 0x47, 0x65,
+	0x74, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c,
+	0x69, 0x61, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+	0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x7d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x46,
+	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49,
+	0x0a, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x48, 0x00,
+	0x52, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x13, 0x57, 0x61, 0x74, 0x63, 0x68,
+	0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18,
+	0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x73, 0x0a, 0x14, 0x57, 0x61, 0x74, 0x63,
+	0x68, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x47, 0x0a, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74,
+	0x52, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x86, 0x01,
+	0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67,
+	0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68,
+	0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x61, 0x6c, 0x69,
+	0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68,
+	0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x67, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
+	0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x4d, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x22,
+	0x89, 0x01, 0x0a, 0x18, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
+	0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07,
+	0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66,
+	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68,
+	0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66,
+	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x6c, 0x0a, 0x19, 0x50,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x13, 0x51, 0x75,
+	0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73,
+	0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67,
+	0x65, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x79, 0x12, 0x14, 0x0a, 0x05,
+	0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x18, 0x0a,
+	0x07, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
+	0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x69, 0x67, 0x69,
+	0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
+	0x73, 0x22, 0xdc, 0x01, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67,
+	0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x06, 0x67, 0x72,
+	0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x51, 0x75,
+	0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06,
+	0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x68, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 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, 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
+	0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+	0x22, 0x56, 0x0a, 0x0b, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12,
+	0x47, 0x0a, 0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52,
+	0x07, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x83, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x5f, 0x61, 0x6c, 0x69, 0x61,
+	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x41, 0x6c, 0x69, 0x61,
+	0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x1c,
+	0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41,
+	0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0x0a, 0x0f,
+	0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
+	0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22,
+	0x12, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x4a, 0x0a, 0x18, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69,
+	0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
+	0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x22,
+	0x1b, 0x0a, 0x19, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x0a, 0x15,
+	0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22,
+	0x69, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0a, 0x77, 0x61, 0x72,
+	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e,
+	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x0a,
+	0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x13, 0x47,
+	0x65, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04,
+	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66,
+	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x61, 0x72,
+	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f,
+	0x0a, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75,
+	0x73, 0x65, 0x48, 0x00, 0x52, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12,
+	0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03,
+	0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x46, 0x0a,
+	0x16, 0x57, 0x61, 0x74, 0x63, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
 	0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
 	0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
-	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
-	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64,
-	0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 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, 0x51, 0x0a, 0x1b,
-	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63,
-	0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x73,
-	0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x38,
-	0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31,
-	0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22,
-	0x4a, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7c, 0x0a, 0x17, 0x57, 0x61, 0x74, 0x63, 0x68, 0x57, 0x61,
+	0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x4d, 0x0a, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68,
+	0x6f, 0x75, 0x73, 0x65, 0x52, 0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12,
+	0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
+	0x79, 0x70, 0x65, 0x22, 0x46, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61, 0x72,
+	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
 	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
 	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x44,
-	0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72,
-	0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x43,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x0a, 0x17, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
+	0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
+	0x69, 0x0a, 0x18, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f,
+	0x75, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x09, 0x77,
+	0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f,
+	0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52,
+	0x09, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x43,
 	0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
 	0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
@@ -9131,65 +9715,80 @@ var file_api_service_v1alpha1_service_proto_rawDesc = []byte{
 	0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
 	0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65,
 	0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x64,
-	0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x38, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x41,
-	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
-	0x74, 0x22, 0x95, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73,
-	0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x12, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f,
-	0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x45, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74,
-	0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65,
-	0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x11, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
-	0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x19, 0x4c, 0x69, 0x73,
-	0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
-	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x22, 0x7a, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c,
-	0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b,
-	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
-	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x0e, 0x70, 0x72,
-	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x22, 0x0a, 0x20,
-	0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x22, 0x97, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
-	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x17, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
-	0x72, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b,
-	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43,
-	0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54,
-	0x61, 0x73, 0x6b, 0x52, 0x15, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d,
-	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x8f, 0x01, 0x0a, 0x1a, 0x47,
-	0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
-	0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f,
-	0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61,
-	0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f,
-	0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xb1, 0x01, 0x0a,
-	0x1b, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70,
-	0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x11,
-	0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x6c,
-	0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x6e,
-	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00,
-	0x52, 0x10, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
-	0x74, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48,
-	0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
-	0x22, 0x8c, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
+	0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x35, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x52,
+	0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63,
+	0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07,
+	0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+	0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65,
+	0x74, 0x73, 0x22, 0x81, 0x02, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+	0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x12, 0x5a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x46, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
+	0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61,
+	0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a,
+	0x09, 0x44, 0x61, 0x74, 0x61, 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, 0x51, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65,
+	0x74, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x81, 0x02, 0x0a, 0x1a, 0x55, 0x70,
+	0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65,
+	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a,
+	0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04,
+	0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 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, 0x51, 0x0a,
+	0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65,
+	0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x06,
+	0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b,
+	0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76,
+	0x31, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74,
+	0x22, 0x4a, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18,
+	0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1d, 0x0a, 0x1b,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63,
+	0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x0a, 0x1c, 0x4c,
+	0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c,
+	0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x95, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x12, 0x61, 0x6e, 0x61, 0x6c, 0x79,
+	0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73,
+	0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x11, 0x61, 0x6e, 0x61, 0x6c,
+	0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x22, 0x8f, 0x01,
+	0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
+	0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
 	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
 	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f,
@@ -9197,843 +9796,942 @@ var file_api_service_v1alpha1_service_proto_rawDesc = []byte{
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
 	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61,
 	0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22,
-	0x96, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
-	0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x0e,
-	0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d,
-	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f,
-	0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61,
-	0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08,
-	0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x79, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x43,
-	0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54,
-	0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43,
-	0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b,
-	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72,
-	0x6d, 0x61, 0x74, 0x22, 0xab, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74,
-	0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x3a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72,
-	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x14, 0x63,
-	0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54,
-	0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
-	0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
-	0x74, 0x22, 0x25, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
-	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
-	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, 0x01, 0x0a, 0x24, 0x4c, 0x69, 0x73,
-	0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
-	0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x8a, 0x01, 0x0a, 0x1a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x6e,
-	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73,
-	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
-	0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f,
-	0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x75,
-	0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70,
-	0x6c, 0x61, 0x74, 0x65, 0x52, 0x18, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x61,
-	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x22, 0x7c,
-	0x0a, 0x21, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c,
-	0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61,
-	0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f,
-	0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xcf, 0x01, 0x0a,
-	0x22, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79,
-	0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x8a, 0x01, 0x0a, 0x19, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f,
-	0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x6c,
-	0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c,
-	0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
-	0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x17, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
-	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
-	0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52,
-	0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x8e,
-	0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75,
-	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65,
-	0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d,
-	0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0xb1, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x74, 0x0a, 0x11, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70,
+	0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x69, 0x74,
+	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b,
+	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72,
+	0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
+	0x65, 0x48, 0x00, 0x52, 0x10, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
+	0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73,
+	0x75, 0x6c, 0x74, 0x22, 0x4d, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61,
+	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c,
+	0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73,
+	0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c,
+	0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, 0x01, 0x0a, 0x24,
+	0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79,
+	0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8a, 0x01, 0x0a, 0x1a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+	0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61,
+	0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f,
+	0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
+	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x18, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
+	0x73, 0x22, 0x7c, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41,
+	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f,
 	0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
 	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61,
 	0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22,
-	0x9d, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52,
-	0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x0c, 0x61, 0x6e,
-	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x40, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
-	0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52,
-	0x75, 0x6e, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75,
-	0x6e, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00,
-	0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
-	0x95, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52,
-	0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a,
-	0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
-	0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65,
-	0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
-	0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x6e,
-	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x22, 0x4d, 0x0a, 0x1d, 0x44,
-	0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
-	0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65,
-	0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70,
-	0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x24,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61,
-	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x25, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69,
-	0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0x34, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
-	0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x4e, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x50,
-	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e, 0x61, 0x70,
-	0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52,
-	0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x58, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x04,
-	0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74,
+	0xcf, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8a, 0x01, 0x0a, 0x19, 0x63, 0x6c, 0x75, 0x73, 0x74,
+	0x65, 0x72, 0x5f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x65, 0x6d, 0x70,
+	0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x69, 0x74,
 	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c,
-	0x65, 0x22, 0x59, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
-	0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x41, 0x0a, 0x11,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
-	0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa6, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a,
-	0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x73,
-	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72,
-	0x6d, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69,
-	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77,
-	0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xd0,
-	0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72,
-	0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c,
-	0x65, 0x48, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x58, 0x0a, 0x09, 0x72, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67,
-	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
+	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72,
+	0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
+	0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x17, 0x63, 0x6c, 0x75, 0x73,
+	0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c,
+	0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
 	0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
-	0x74, 0x22, 0x52, 0x0a, 0x06, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x48, 0x0a, 0x06, 0x63,
-	0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x52, 0x06, 0x63,
-	0x6c, 0x61, 0x69, 0x6d, 0x73, 0x22, 0xfd, 0x01, 0x0a, 0x0c, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52,
+	0x74, 0x22, 0x3a, 0x0a, 0x24, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74,
+	0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+	0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a,
+	0x25, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52,
+	0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x9d, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41,
+	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x65, 0x0a, 0x0c, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x72,
+	0x75, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75,
+	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x75, 0x62, 0x73, 0x2e, 0x72, 0x6f, 0x6c,
+	0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41,
+	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x95, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41,
+	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
+	0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
+	0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74,
+	0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22,
+	0x32, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75,
+	0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x68,
+	0x75, 0x6e, 0x6b, 0x22, 0x34, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x4e, 0x0a, 0x19, 0x4c, 0x69, 0x73,
+	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73,
+	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e,
+	0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x35, 0x0a, 0x19, 0x4c, 0x69, 0x73,
+	0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52,
 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
 	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x72, 0x6f, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x61,
-	0x69, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6b, 0x75, 0x69,
-	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x61,
-	0x69, 0x6d, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x69, 0x6d,
-	0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x54, 0x0a, 0x0d, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x4f, 0x0a, 0x10, 0x4c,
-	0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x73, 0x5f,
-	0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x0b, 0x61, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xb2, 0x01, 0x0a,
-	0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e,
-	0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f,
-	0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x09, 0x72, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67,
-	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x73, 0x22, 0xfe, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a,
-	0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c,
-	0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x22, 0x7a, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c,
+	0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x0e, 0x70, 0x72,
+	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x8c, 0x01, 0x0a,
+	0x17, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73,
+	0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a,
+	0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73,
-	0x48, 0x00, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x67,
-	0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72,
+	0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x96, 0x01, 0x0a, 0x18,
+	0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x33, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x22, 0x22, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73,
+	0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x97, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73,
+	0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72,
+	0x0a, 0x17, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
+	0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x3a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72,
+	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x15, 0x63, 0x6c, 0x75,
+	0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73,
+	0x6b, 0x73, 0x22, 0x79, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d,
+	0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x46,
+	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xab, 0x01,
+	0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x6a, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74,
+	0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61,
+	0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x14, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a,
+	0x03, 0x72, 0x61, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61,
+	0x77, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x58, 0x0a, 0x11, 0x43,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f,
+	0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61,
+	0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52,
+	0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
+	0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72,
+	0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61,
+	0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65,
+	0x22, 0x41, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c,
+	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa6, 0x01, 0x0a, 0x0e, 0x47, 0x65,
+	0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x73,
+	0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
+	0x52, 0x0b, 0x61, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a,
+	0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d,
+	0x61, 0x74, 0x22, 0xd0, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x58, 0x0a,
+	0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x38, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72,
+	0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c,
+	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65,
+	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x42, 0x08, 0x0a, 0x06, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x52, 0x0a, 0x06, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12,
+	0x48, 0x0a, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x30, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62,
+	0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69,
+	0x6d, 0x52, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x22, 0xfd, 0x01, 0x0a, 0x0c, 0x47, 0x72,
+	0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72,
+	0x5f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x43,
+	0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x3a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62,
+	0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x72,
+	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x09,
+	0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x54, 0x0a, 0x0d, 0x47, 0x72, 0x61,
+	0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f,
+	0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75,
 	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72,
 	0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x22, 0x55, 0x0a, 0x0e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69,
-	0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52,
-	0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x58, 0x0a, 0x11, 0x55, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43,
-	0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22,
+	0x4f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a,
+	0x0c, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
+	0x22, 0xb2, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18,
+	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x56, 0x0a,
+	0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x38, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72,
+	0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c,
+	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6c,
+	0x61, 0x69, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c,
+	0x61, 0x69, 0x6d, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x69,
+	0x6d, 0x73, 0x12, 0x67, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64,
+	0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67,
 	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
 	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72,
-	0x6f, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c,
-	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x2a, 0x51,
-	0x0a, 0x09, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1a, 0x0a, 0x16, 0x52,
-	0x41, 0x57, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
-	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x41, 0x57, 0x5f, 0x46,
-	0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f,
-	0x52, 0x41, 0x57, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x59, 0x41, 0x4d, 0x4c, 0x10,
-	0x02, 0x32, 0xc3, 0x48, 0x0a, 0x0c, 0x4b, 0x61, 0x72, 0x67, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
-	0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
-	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73,
-	0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38,
-	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
-	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, 0x0e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
+	0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x58, 0x0a,
+	0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x43, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x2f, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72,
+	0x62, 0x61, 0x63, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c,
+	0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x59, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a,
+	0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x69,
+	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f,
+	0x6c, 0x65, 0x2a, 0x51, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12,
+	0x1a, 0x0a, 0x16, 0x52, 0x41, 0x57, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e,
+	0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52,
+	0x41, 0x57, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x01,
+	0x12, 0x13, 0x0a, 0x0f, 0x52, 0x41, 0x57, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x59,
+	0x41, 0x4d, 0x4c, 0x10, 0x02, 0x32, 0xbc, 0x4f, 0x0a, 0x0c, 0x4b, 0x61, 0x72, 0x67, 0x6f, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x56, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69,
 	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
 	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x86,
-	0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e,
-	0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
-	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x4c, 0x6f,
-	0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64,
-	0x6d, 0x69, 0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x83, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
-	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
-	0x65, 0x12, 0x3f, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x40, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
 	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70,
-	0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
-	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x44,
-	0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x09,
+	0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e,
 	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
 	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x77, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x12, 0x33,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62,
+	0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x41,
+	0x64, 0x6d, 0x69, 0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x6d,
+	0x69, 0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34,
 	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
 	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
-	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x4c, 0x69, 0x73,
-	0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x31, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
+	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
 	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49,
-	0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x71, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x31,
-	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74,
-	0x61, 0x67, 0x65, 0x73, 0x12, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61,
-	0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61,
-	0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x30, 0x01, 0x12, 0x7a, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61,
-	0x67, 0x65, 0x12, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x7d, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12,
-	0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
+	0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x16, 0x43,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3f, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f,
+	0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x40, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
-	0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83,
-	0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x4f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83,
+	0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
 	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69,
-	0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72,
-	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63,
-	0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65,
+	0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67,
+	0x65, 0x73, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
 	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12,
-	0x7d, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12,
-	0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f,
-	0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x85,
-	0x01, 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
-	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61,
-	0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x41, 0x62, 0x6f, 0x72, 0x74,
-	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69,
-	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62, 0x6f,
-	0x72, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53,
+	0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a,
+	0x0a, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x33, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c,
+	0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61,
+	0x67, 0x65, 0x12, 0x31, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
 	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a,
-	0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x36,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67,
+	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x57, 0x61, 0x74,
+	0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x12, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63,
+	0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35,
 	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
 	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x7a, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74,
+	0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
 	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x33, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74,
-	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
-	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
-	0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a,
-	0x10, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x12, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x61,
+	0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x61,
 	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
 	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x41, 0x70, 0x70,
-	0x72, 0x6f, 0x76, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x37, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41,
-	0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x46,
-	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80,
-	0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74,
-	0x12, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
-	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12,
-	0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74,
+	0x61, 0x67, 0x65, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74,
+	0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65,
+	0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
+	0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c,
+	0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92,
+	0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
 	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67,
-	0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x0c, 0x57, 0x61,
-	0x74, 0x63, 0x68, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c,
+	0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x12, 0x57, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x75,
+	0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
 	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61,
-	0x74, 0x63, 0x68, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
-	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x83, 0x01, 0x0a, 0x0e,
-	0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x37,
-	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x74, 0x63, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
 	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f, 0x77,
-	0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68,
+	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x72,
+	0x65, 0x73, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x12, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74,
+	0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x3e, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
+	0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
+	0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x83, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c,
+	0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74,
+	0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
 	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f,
-	0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x7d, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01,
+	0x12, 0x7d, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
 	0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
 	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74,
+	0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
 	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79,
-	0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x8f, 0x01, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
-	0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
-	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65,
-	0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x71, 0x0a, 0x08, 0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x31, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56, 0x65,
-	0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72,
+	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x85, 0x01, 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
+	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57,
+	0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x41, 0x62, 0x6f, 0x72,
+	0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
 	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62,
-	0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56,
-	0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65,
-	0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61,
-	0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6d,
+	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01,
+	0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12,
+	0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
 	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0c, 0x47, 0x65, 0x74,
-	0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
+	0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x33,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0c, 0x4c, 0x69, 0x73,
+	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69,
 	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
-	0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73,
+	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 	0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
 	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x57, 0x61, 0x74,
-	0x63, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x12, 0x38, 0x2e, 0x61,
+	0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74,
+	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x2e, 0x61,
 	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
 	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x57, 0x61, 0x74, 0x63, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65,
+	0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x12, 0x57, 0x61,
+	0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x95, 0x01,
+	0x0a, 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x57,
-	0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x30, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61,
-	0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61, 0x72, 0x65, 0x68,
-	0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a,
-	0x10, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73,
-	0x65, 0x12, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
+	0x68, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
+	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76,
+	0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x72,
+	0x6f, 0x76, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
 	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65,
-	0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x61,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x46, 0x72, 0x65, 0x69,
+	0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x0d,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x36, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46,
+	0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77,
+	0x0a, 0x0a, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x33, 0x2e, 0x61,
 	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
 	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65,
-	0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x3a,
+	0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
+	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x0c, 0x57, 0x61, 0x74, 0x63, 0x68,
+	0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68,
+	0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36,
 	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
 	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
-	0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75,
+	0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f,
+	0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x37, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x54,
+	0x6f, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c,
+	0x01, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x74,
+	0x72, 0x65, 0x61, 0x6d, 0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44,
+	0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
+	0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a,
+	0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x35, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x46, 0x72, 0x65,
+	0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8f, 0x01, 0x0a,
+	0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x41, 0x6c,
+	0x69, 0x61, 0x73, 0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65,
+	0x69, 0x67, 0x68, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68,
+	0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71,
+	0x0a, 0x08, 0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x31, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72,
-	0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x3a, 0x2e,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65,
+	0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66,
+	0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74,
+	0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x56, 0x65, 0x72, 0x69,
+	0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x83, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75,
+	0x73, 0x65, 0x73, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68,
+	0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61,
+	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
+	0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x57, 0x61, 0x72,
+	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x35, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x72,
+	0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e,
 	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
 	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
-	0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x2e, 0x47, 0x65, 0x74, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x57, 0x61, 0x74, 0x63, 0x68, 0x57,
+	0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69,
 	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c,
-	0x65, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x72,
-	0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74,
+	0x63, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x57, 0x61, 0x72, 0x65,
+	0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01,
+	0x12, 0x86, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61, 0x72, 0x65, 0x68,
+	0x6f, 0x75, 0x73, 0x65, 0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61,
+	0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73,
+	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x10, 0x52, 0x65,
+	0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x39,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75,
+	0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69,
 	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
-	0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
-	0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x86, 0x01, 0x0a,
-	0x0f, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
-	0x12, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
-	0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69,
-	0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66,
+	0x72, 0x65, 0x73, 0x68, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
 	0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x3a, 0x2e, 0x61, 0x6b,
 	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55,
-	0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
 	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
 	0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f,
-	0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x3b, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c,
-	0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
-	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43,
+	0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65,
+	0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
+	0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x0f, 0x4c, 0x69,
+	0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x38, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43,
+	0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x65,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72,
+	0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x8f, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
 	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
 	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
 	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x3c,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x3c, 0x2e, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72,
+	0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x13, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
+	0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
+	0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d,
 	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
 	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53,
-	0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61,
+	0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53,
+	0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01,
+	0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53,
+	0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79,
+	0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x2e, 0x61,
 	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
 	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63,
-	0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x13,
-	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63,
-	0x72, 0x65, 0x74, 0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70,
+	0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x61,
+	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70,
+	0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x92, 0x01,
+	0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
+	0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c,
+	0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
 	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f,
-	0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x92, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65,
-	0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e,
-	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x12,
-	0x3e, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54,
-	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x3f, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54,
-	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x92, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
-	0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
-	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41,
-	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
-	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61,
-	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73,
+	0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61,
+	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x2e,
+	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x40,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
+	0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0xad, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
 	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
-	0x12, 0x3f, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73,
-	0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x40, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
+	0x73, 0x12, 0x45, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
 	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6e, 0x61, 0x6c, 0x79,
-	0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0xad, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73,
-	0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c,
-	0x61, 0x74, 0x65, 0x73, 0x12, 0x45, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73,
-	0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c,
-	0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x46, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c,
-	0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73,
-	0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0xa7, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74,
-	0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
-	0x74, 0x65, 0x12, 0x43, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
 	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x44, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c,
-	0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
-	0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xb0, 0x01,
-	0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x46, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
+	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0xa7, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41,
 	0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12,
-	0x46, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x43, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
 	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
-	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x47, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
-	0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x83, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73,
-	0x52, 0x75, 0x6e, 0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
-	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
-	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73,
-	0x69, 0x73, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x6e,
-	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x3b, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c,
-	0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65,
-	0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x4c,
-	0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
-	0x12, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
-	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45,
-	0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61,
+	0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61,
+	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x44, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74,
+	0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+	0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xb0, 0x01, 0x0a, 0x1d, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c,
+	0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x46, 0x2e, 0x61,
 	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
 	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x12, 0x4c, 0x69,
-	0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73,
-	0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61,
+	0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x47, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c,
+	0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x54, 0x65, 0x6d,
+	0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01,
+	0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e,
+	0x12, 0x37, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72,
 	0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e,
+	0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52,
+	0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
+	0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79,
+	0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x3b, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65,
+	0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e,
+	0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x52, 0x75, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74,
+	0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x2e,
 	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
 	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61,
-	0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa4, 0x01, 0x0a, 0x19,
-	0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
-	0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x42, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e,
+	0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x61, 0x6b, 0x75, 0x69,
 	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
 	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73,
-	0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e,
+	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x50,
+	0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x3b, 0x2e,
 	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
 	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d,
-	0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
-	0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72,
-	0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
-	0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9e,
-	0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f,
-	0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x40, 0x2e, 0x61, 0x6b, 0x75,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61,
+	0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69,
+	0x73, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa4, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73,
 	0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
-	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
-	0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x77, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x33, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b,
-	0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61,
-	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x42, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
 	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b,
-	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44,
-	0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x6e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31,
-	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
-	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
-	0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x68, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x61, 0x6b, 0x75,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c,
+	0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61,
+	0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x72,
-	0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x61, 0x6b, 0x75,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69,
+	0x73, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69,
+	0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x89, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
+	0x54, 0x61, 0x73, 0x6b, 0x12, 0x39, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
+	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x3a, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
+	0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54,
+	0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x17,
+	0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74,
+	0x69, 0x6f, 0x6e, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x40, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c,
+	0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61,
+	0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
+	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e,
+	0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a,
+	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75,
 	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x72,
-	0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x09, 0x4c,
-	0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
+	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
+	0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
+	0x6f, 0x6c, 0x65, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
 	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
-	0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x6b, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x2f, 0x2e, 0x61, 0x6b,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65,
+	0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e,
+	0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74,
+	0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x61, 0x6b,
 	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52,
-	0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77,
-	0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x33, 0x2e, 0x61,
-	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
-	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x34, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x93, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e,
-	0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
-	0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
-	0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6b, 0x75,
-	0x69, 0x74, 0x79, 0x2f, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x73,
-	0x76, 0x63, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x04, 0x41, 0x49, 0x4b,
-	0x53, 0xaa, 0x02, 0x20, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x49, 0x6f, 0x2e, 0x4b, 0x61,
-	0x72, 0x67, 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x20, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x5c, 0x49, 0x6f,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47,
+	0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68,
+	0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74,
+	0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69,
+	0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c,
+	0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73,
+	0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b,
+	0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x2f, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74,
+	0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f,
+	0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76,
+	0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x33, 0x2e, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34,
+	0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x42, 0x93, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6b, 0x75,
+	0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0c, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x38, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79,
+	0x2f, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x73, 0x76, 0x63, 0x76,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x04, 0x41, 0x49, 0x4b, 0x53, 0xaa, 0x02,
+	0x20, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x49, 0x6f, 0x2e, 0x4b, 0x61, 0x72, 0x67, 0x6f,
+	0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0xca, 0x02, 0x20, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x5c, 0x49, 0x6f, 0x5c, 0x4b, 0x61,
+	0x72, 0x67, 0x6f, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56, 0x31, 0x61, 0x6c,
+	0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x5c, 0x49, 0x6f,
 	0x5c, 0x4b, 0x61, 0x72, 0x67, 0x6f, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x56,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79,
-	0x5c, 0x49, 0x6f, 0x5c, 0x4b, 0x61, 0x72, 0x67, 0x6f, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
-	0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x3a,
-	0x3a, 0x49, 0x6f, 0x3a, 0x3a, 0x4b, 0x61, 0x72, 0x67, 0x6f, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64,
+	0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x41, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x3a, 0x3a, 0x49, 0x6f,
+	0x3a, 0x3a, 0x4b, 0x61, 0x72, 0x67, 0x6f, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x33,
 }
 
 var (
@@ -10049,7 +10747,7 @@ func file_api_service_v1alpha1_service_proto_rawDescGZIP() []byte {
 }
 
 var file_api_service_v1alpha1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_api_service_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 155)
+var file_api_service_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 167)
 var file_api_service_v1alpha1_service_proto_goTypes = []interface{}{
 	(RawFormat)(0),                                // 0: akuity.io.kargo.service.v1alpha1.RawFormat
 	(*ComponentVersions)(nil),                     // 1: akuity.io.kargo.service.v1alpha1.ComponentVersions
@@ -10090,369 +10788,400 @@ var file_api_service_v1alpha1_service_proto_goTypes = []interface{}{
 	(*DeleteStageResponse)(nil),                   // 36: akuity.io.kargo.service.v1alpha1.DeleteStageResponse
 	(*RefreshStageRequest)(nil),                   // 37: akuity.io.kargo.service.v1alpha1.RefreshStageRequest
 	(*RefreshStageResponse)(nil),                  // 38: akuity.io.kargo.service.v1alpha1.RefreshStageResponse
-	(*ListPromotionsRequest)(nil),                 // 39: akuity.io.kargo.service.v1alpha1.ListPromotionsRequest
-	(*ListPromotionsResponse)(nil),                // 40: akuity.io.kargo.service.v1alpha1.ListPromotionsResponse
-	(*WatchPromotionsRequest)(nil),                // 41: akuity.io.kargo.service.v1alpha1.WatchPromotionsRequest
-	(*WatchPromotionsResponse)(nil),               // 42: akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse
-	(*GetPromotionRequest)(nil),                   // 43: akuity.io.kargo.service.v1alpha1.GetPromotionRequest
-	(*GetPromotionResponse)(nil),                  // 44: akuity.io.kargo.service.v1alpha1.GetPromotionResponse
-	(*WatchPromotionRequest)(nil),                 // 45: akuity.io.kargo.service.v1alpha1.WatchPromotionRequest
-	(*WatchPromotionResponse)(nil),                // 46: akuity.io.kargo.service.v1alpha1.WatchPromotionResponse
-	(*AbortPromotionRequest)(nil),                 // 47: akuity.io.kargo.service.v1alpha1.AbortPromotionRequest
-	(*AbortPromotionResponse)(nil),                // 48: akuity.io.kargo.service.v1alpha1.AbortPromotionResponse
-	(*DeleteProjectRequest)(nil),                  // 49: akuity.io.kargo.service.v1alpha1.DeleteProjectRequest
-	(*DeleteProjectResponse)(nil),                 // 50: akuity.io.kargo.service.v1alpha1.DeleteProjectResponse
-	(*DeleteProjectConfigRequest)(nil),            // 51: akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest
-	(*DeleteProjectConfigResponse)(nil),           // 52: akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse
-	(*GetProjectConfigRequest)(nil),               // 53: akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest
-	(*GetProjectConfigResponse)(nil),              // 54: akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse
-	(*GetProjectRequest)(nil),                     // 55: akuity.io.kargo.service.v1alpha1.GetProjectRequest
-	(*GetProjectResponse)(nil),                    // 56: akuity.io.kargo.service.v1alpha1.GetProjectResponse
-	(*ListProjectsRequest)(nil),                   // 57: akuity.io.kargo.service.v1alpha1.ListProjectsRequest
-	(*ListProjectsResponse)(nil),                  // 58: akuity.io.kargo.service.v1alpha1.ListProjectsResponse
-	(*ApproveFreightRequest)(nil),                 // 59: akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
-	(*ApproveFreightResponse)(nil),                // 60: akuity.io.kargo.service.v1alpha1.ApproveFreightResponse
-	(*DeleteFreightRequest)(nil),                  // 61: akuity.io.kargo.service.v1alpha1.DeleteFreightRequest
-	(*DeleteFreightResponse)(nil),                 // 62: akuity.io.kargo.service.v1alpha1.DeleteFreightResponse
-	(*GetFreightRequest)(nil),                     // 63: akuity.io.kargo.service.v1alpha1.GetFreightRequest
-	(*GetFreightResponse)(nil),                    // 64: akuity.io.kargo.service.v1alpha1.GetFreightResponse
-	(*WatchFreightRequest)(nil),                   // 65: akuity.io.kargo.service.v1alpha1.WatchFreightRequest
-	(*WatchFreightResponse)(nil),                  // 66: akuity.io.kargo.service.v1alpha1.WatchFreightResponse
-	(*PromoteToStageRequest)(nil),                 // 67: akuity.io.kargo.service.v1alpha1.PromoteToStageRequest
-	(*PromoteToStageResponse)(nil),                // 68: akuity.io.kargo.service.v1alpha1.PromoteToStageResponse
-	(*PromoteDownstreamRequest)(nil),              // 69: akuity.io.kargo.service.v1alpha1.PromoteDownstreamRequest
-	(*PromoteDownstreamResponse)(nil),             // 70: akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse
-	(*QueryFreightRequest)(nil),                   // 71: akuity.io.kargo.service.v1alpha1.QueryFreightRequest
-	(*QueryFreightResponse)(nil),                  // 72: akuity.io.kargo.service.v1alpha1.QueryFreightResponse
-	(*FreightList)(nil),                           // 73: akuity.io.kargo.service.v1alpha1.FreightList
-	(*UpdateFreightAliasRequest)(nil),             // 74: akuity.io.kargo.service.v1alpha1.UpdateFreightAliasRequest
-	(*UpdateFreightAliasResponse)(nil),            // 75: akuity.io.kargo.service.v1alpha1.UpdateFreightAliasResponse
-	(*ReverifyRequest)(nil),                       // 76: akuity.io.kargo.service.v1alpha1.ReverifyRequest
-	(*ReverifyResponse)(nil),                      // 77: akuity.io.kargo.service.v1alpha1.ReverifyResponse
-	(*AbortVerificationRequest)(nil),              // 78: akuity.io.kargo.service.v1alpha1.AbortVerificationRequest
-	(*AbortVerificationResponse)(nil),             // 79: akuity.io.kargo.service.v1alpha1.AbortVerificationResponse
-	(*ListWarehousesRequest)(nil),                 // 80: akuity.io.kargo.service.v1alpha1.ListWarehousesRequest
-	(*ListWarehousesResponse)(nil),                // 81: akuity.io.kargo.service.v1alpha1.ListWarehousesResponse
-	(*GetWarehouseRequest)(nil),                   // 82: akuity.io.kargo.service.v1alpha1.GetWarehouseRequest
-	(*GetWarehouseResponse)(nil),                  // 83: akuity.io.kargo.service.v1alpha1.GetWarehouseResponse
-	(*WatchWarehousesRequest)(nil),                // 84: akuity.io.kargo.service.v1alpha1.WatchWarehousesRequest
-	(*WatchWarehousesResponse)(nil),               // 85: akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse
-	(*DeleteWarehouseRequest)(nil),                // 86: akuity.io.kargo.service.v1alpha1.DeleteWarehouseRequest
-	(*DeleteWarehouseResponse)(nil),               // 87: akuity.io.kargo.service.v1alpha1.DeleteWarehouseResponse
-	(*RefreshWarehouseRequest)(nil),               // 88: akuity.io.kargo.service.v1alpha1.RefreshWarehouseRequest
-	(*RefreshWarehouseResponse)(nil),              // 89: akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse
-	(*ListProjectSecretsRequest)(nil),             // 90: akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
-	(*ListProjectSecretsResponse)(nil),            // 91: akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
-	(*CreateProjectSecretRequest)(nil),            // 92: akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
-	(*CreateProjectSecretResponse)(nil),           // 93: akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
-	(*UpdateProjectSecretRequest)(nil),            // 94: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
-	(*UpdateProjectSecretResponse)(nil),           // 95: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
-	(*DeleteProjectSecretRequest)(nil),            // 96: akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
-	(*DeleteProjectSecretResponse)(nil),           // 97: akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse
-	(*CreateCredentialsRequest)(nil),              // 98: akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
-	(*CreateCredentialsResponse)(nil),             // 99: akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
-	(*DeleteCredentialsRequest)(nil),              // 100: akuity.io.kargo.service.v1alpha1.DeleteCredentialsRequest
-	(*DeleteCredentialsResponse)(nil),             // 101: akuity.io.kargo.service.v1alpha1.DeleteCredentialsResponse
-	(*GetCredentialsRequest)(nil),                 // 102: akuity.io.kargo.service.v1alpha1.GetCredentialsRequest
-	(*GetCredentialsResponse)(nil),                // 103: akuity.io.kargo.service.v1alpha1.GetCredentialsResponse
-	(*ListCredentialsRequest)(nil),                // 104: akuity.io.kargo.service.v1alpha1.ListCredentialsRequest
-	(*ListCredentialsResponse)(nil),               // 105: akuity.io.kargo.service.v1alpha1.ListCredentialsResponse
-	(*UpdateCredentialsRequest)(nil),              // 106: akuity.io.kargo.service.v1alpha1.UpdateCredentialsRequest
-	(*UpdateCredentialsResponse)(nil),             // 107: akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse
-	(*ListAnalysisTemplatesRequest)(nil),          // 108: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
-	(*ListAnalysisTemplatesResponse)(nil),         // 109: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
-	(*ListPromotionTasksRequest)(nil),             // 110: akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest
-	(*ListPromotionTasksResponse)(nil),            // 111: akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse
-	(*ListClusterPromotionTasksRequest)(nil),      // 112: akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest
-	(*ListClusterPromotionTasksResponse)(nil),     // 113: akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse
-	(*GetAnalysisTemplateRequest)(nil),            // 114: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
-	(*GetAnalysisTemplateResponse)(nil),           // 115: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
-	(*GetPromotionTaskRequest)(nil),               // 116: akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest
-	(*GetPromotionTaskResponse)(nil),              // 117: akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse
-	(*GetClusterPromotionTaskRequest)(nil),        // 118: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest
-	(*GetClusterPromotionTaskResponse)(nil),       // 119: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse
-	(*ListClusterAnalysisTemplatesRequest)(nil),   // 120: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesRequest
-	(*ListClusterAnalysisTemplatesResponse)(nil),  // 121: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse
-	(*GetClusterAnalysisTemplateRequest)(nil),     // 122: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest
-	(*GetClusterAnalysisTemplateResponse)(nil),    // 123: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse
-	(*GetAnalysisRunRequest)(nil),                 // 124: akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest
-	(*GetAnalysisRunResponse)(nil),                // 125: akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse
-	(*GetAnalysisRunLogsRequest)(nil),             // 126: akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsRequest
-	(*GetAnalysisRunLogsResponse)(nil),            // 127: akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsResponse
-	(*DeleteAnalysisTemplateRequest)(nil),         // 128: akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
-	(*DeleteAnalysisTemplateResponse)(nil),        // 129: akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse
+	(*GetClusterConfigRequest)(nil),               // 39: akuity.io.kargo.service.v1alpha1.GetClusterConfigRequest
+	(*GetClusterConfigResponse)(nil),              // 40: akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse
+	(*DeleteClusterConfigRequest)(nil),            // 41: akuity.io.kargo.service.v1alpha1.DeleteClusterConfigRequest
+	(*DeleteClusterConfigResponse)(nil),           // 42: akuity.io.kargo.service.v1alpha1.DeleteClusterConfigResponse
+	(*WatchClusterConfigRequest)(nil),             // 43: akuity.io.kargo.service.v1alpha1.WatchClusterConfigRequest
+	(*WatchClusterConfigResponse)(nil),            // 44: akuity.io.kargo.service.v1alpha1.WatchClusterConfigResponse
+	(*RefreshClusterConfigRequest)(nil),           // 45: akuity.io.kargo.service.v1alpha1.RefreshClusterConfigRequest
+	(*RefreshClusterConfigResponse)(nil),          // 46: akuity.io.kargo.service.v1alpha1.RefreshClusterConfigResponse
+	(*ListPromotionsRequest)(nil),                 // 47: akuity.io.kargo.service.v1alpha1.ListPromotionsRequest
+	(*ListPromotionsResponse)(nil),                // 48: akuity.io.kargo.service.v1alpha1.ListPromotionsResponse
+	(*WatchPromotionsRequest)(nil),                // 49: akuity.io.kargo.service.v1alpha1.WatchPromotionsRequest
+	(*WatchPromotionsResponse)(nil),               // 50: akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse
+	(*GetPromotionRequest)(nil),                   // 51: akuity.io.kargo.service.v1alpha1.GetPromotionRequest
+	(*GetPromotionResponse)(nil),                  // 52: akuity.io.kargo.service.v1alpha1.GetPromotionResponse
+	(*WatchPromotionRequest)(nil),                 // 53: akuity.io.kargo.service.v1alpha1.WatchPromotionRequest
+	(*WatchPromotionResponse)(nil),                // 54: akuity.io.kargo.service.v1alpha1.WatchPromotionResponse
+	(*AbortPromotionRequest)(nil),                 // 55: akuity.io.kargo.service.v1alpha1.AbortPromotionRequest
+	(*AbortPromotionResponse)(nil),                // 56: akuity.io.kargo.service.v1alpha1.AbortPromotionResponse
+	(*DeleteProjectRequest)(nil),                  // 57: akuity.io.kargo.service.v1alpha1.DeleteProjectRequest
+	(*DeleteProjectResponse)(nil),                 // 58: akuity.io.kargo.service.v1alpha1.DeleteProjectResponse
+	(*GetProjectRequest)(nil),                     // 59: akuity.io.kargo.service.v1alpha1.GetProjectRequest
+	(*GetProjectResponse)(nil),                    // 60: akuity.io.kargo.service.v1alpha1.GetProjectResponse
+	(*ListProjectsRequest)(nil),                   // 61: akuity.io.kargo.service.v1alpha1.ListProjectsRequest
+	(*ListProjectsResponse)(nil),                  // 62: akuity.io.kargo.service.v1alpha1.ListProjectsResponse
+	(*GetProjectConfigRequest)(nil),               // 63: akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest
+	(*GetProjectConfigResponse)(nil),              // 64: akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse
+	(*DeleteProjectConfigRequest)(nil),            // 65: akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest
+	(*DeleteProjectConfigResponse)(nil),           // 66: akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse
+	(*WatchProjectConfigRequest)(nil),             // 67: akuity.io.kargo.service.v1alpha1.WatchProjectConfigRequest
+	(*WatchProjectConfigResponse)(nil),            // 68: akuity.io.kargo.service.v1alpha1.WatchProjectConfigResponse
+	(*RefreshProjectConfigRequest)(nil),           // 69: akuity.io.kargo.service.v1alpha1.RefreshProjectConfigRequest
+	(*RefreshProjectConfigResponse)(nil),          // 70: akuity.io.kargo.service.v1alpha1.RefreshProjectConfigResponse
+	(*ApproveFreightRequest)(nil),                 // 71: akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
+	(*ApproveFreightResponse)(nil),                // 72: akuity.io.kargo.service.v1alpha1.ApproveFreightResponse
+	(*DeleteFreightRequest)(nil),                  // 73: akuity.io.kargo.service.v1alpha1.DeleteFreightRequest
+	(*DeleteFreightResponse)(nil),                 // 74: akuity.io.kargo.service.v1alpha1.DeleteFreightResponse
+	(*GetFreightRequest)(nil),                     // 75: akuity.io.kargo.service.v1alpha1.GetFreightRequest
+	(*GetFreightResponse)(nil),                    // 76: akuity.io.kargo.service.v1alpha1.GetFreightResponse
+	(*WatchFreightRequest)(nil),                   // 77: akuity.io.kargo.service.v1alpha1.WatchFreightRequest
+	(*WatchFreightResponse)(nil),                  // 78: akuity.io.kargo.service.v1alpha1.WatchFreightResponse
+	(*PromoteToStageRequest)(nil),                 // 79: akuity.io.kargo.service.v1alpha1.PromoteToStageRequest
+	(*PromoteToStageResponse)(nil),                // 80: akuity.io.kargo.service.v1alpha1.PromoteToStageResponse
+	(*PromoteDownstreamRequest)(nil),              // 81: akuity.io.kargo.service.v1alpha1.PromoteDownstreamRequest
+	(*PromoteDownstreamResponse)(nil),             // 82: akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse
+	(*QueryFreightRequest)(nil),                   // 83: akuity.io.kargo.service.v1alpha1.QueryFreightRequest
+	(*QueryFreightResponse)(nil),                  // 84: akuity.io.kargo.service.v1alpha1.QueryFreightResponse
+	(*FreightList)(nil),                           // 85: akuity.io.kargo.service.v1alpha1.FreightList
+	(*UpdateFreightAliasRequest)(nil),             // 86: akuity.io.kargo.service.v1alpha1.UpdateFreightAliasRequest
+	(*UpdateFreightAliasResponse)(nil),            // 87: akuity.io.kargo.service.v1alpha1.UpdateFreightAliasResponse
+	(*ReverifyRequest)(nil),                       // 88: akuity.io.kargo.service.v1alpha1.ReverifyRequest
+	(*ReverifyResponse)(nil),                      // 89: akuity.io.kargo.service.v1alpha1.ReverifyResponse
+	(*AbortVerificationRequest)(nil),              // 90: akuity.io.kargo.service.v1alpha1.AbortVerificationRequest
+	(*AbortVerificationResponse)(nil),             // 91: akuity.io.kargo.service.v1alpha1.AbortVerificationResponse
+	(*ListWarehousesRequest)(nil),                 // 92: akuity.io.kargo.service.v1alpha1.ListWarehousesRequest
+	(*ListWarehousesResponse)(nil),                // 93: akuity.io.kargo.service.v1alpha1.ListWarehousesResponse
+	(*GetWarehouseRequest)(nil),                   // 94: akuity.io.kargo.service.v1alpha1.GetWarehouseRequest
+	(*GetWarehouseResponse)(nil),                  // 95: akuity.io.kargo.service.v1alpha1.GetWarehouseResponse
+	(*WatchWarehousesRequest)(nil),                // 96: akuity.io.kargo.service.v1alpha1.WatchWarehousesRequest
+	(*WatchWarehousesResponse)(nil),               // 97: akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse
+	(*DeleteWarehouseRequest)(nil),                // 98: akuity.io.kargo.service.v1alpha1.DeleteWarehouseRequest
+	(*DeleteWarehouseResponse)(nil),               // 99: akuity.io.kargo.service.v1alpha1.DeleteWarehouseResponse
+	(*RefreshWarehouseRequest)(nil),               // 100: akuity.io.kargo.service.v1alpha1.RefreshWarehouseRequest
+	(*RefreshWarehouseResponse)(nil),              // 101: akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse
+	(*CreateCredentialsRequest)(nil),              // 102: akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
+	(*CreateCredentialsResponse)(nil),             // 103: akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
+	(*DeleteCredentialsRequest)(nil),              // 104: akuity.io.kargo.service.v1alpha1.DeleteCredentialsRequest
+	(*DeleteCredentialsResponse)(nil),             // 105: akuity.io.kargo.service.v1alpha1.DeleteCredentialsResponse
+	(*GetCredentialsRequest)(nil),                 // 106: akuity.io.kargo.service.v1alpha1.GetCredentialsRequest
+	(*GetCredentialsResponse)(nil),                // 107: akuity.io.kargo.service.v1alpha1.GetCredentialsResponse
+	(*ListCredentialsRequest)(nil),                // 108: akuity.io.kargo.service.v1alpha1.ListCredentialsRequest
+	(*ListCredentialsResponse)(nil),               // 109: akuity.io.kargo.service.v1alpha1.ListCredentialsResponse
+	(*UpdateCredentialsRequest)(nil),              // 110: akuity.io.kargo.service.v1alpha1.UpdateCredentialsRequest
+	(*UpdateCredentialsResponse)(nil),             // 111: akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse
+	(*ListProjectSecretsRequest)(nil),             // 112: akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
+	(*ListProjectSecretsResponse)(nil),            // 113: akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
+	(*CreateProjectSecretRequest)(nil),            // 114: akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
+	(*CreateProjectSecretResponse)(nil),           // 115: akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
+	(*UpdateProjectSecretRequest)(nil),            // 116: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
+	(*UpdateProjectSecretResponse)(nil),           // 117: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
+	(*DeleteProjectSecretRequest)(nil),            // 118: akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
+	(*DeleteProjectSecretResponse)(nil),           // 119: akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse
+	(*ListAnalysisTemplatesRequest)(nil),          // 120: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
+	(*ListAnalysisTemplatesResponse)(nil),         // 121: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
+	(*GetAnalysisTemplateRequest)(nil),            // 122: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
+	(*GetAnalysisTemplateResponse)(nil),           // 123: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
+	(*DeleteAnalysisTemplateRequest)(nil),         // 124: akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
+	(*DeleteAnalysisTemplateResponse)(nil),        // 125: akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse
+	(*ListClusterAnalysisTemplatesRequest)(nil),   // 126: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesRequest
+	(*ListClusterAnalysisTemplatesResponse)(nil),  // 127: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse
+	(*GetClusterAnalysisTemplateRequest)(nil),     // 128: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest
+	(*GetClusterAnalysisTemplateResponse)(nil),    // 129: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse
 	(*DeleteClusterAnalysisTemplateRequest)(nil),  // 130: akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest
 	(*DeleteClusterAnalysisTemplateResponse)(nil), // 131: akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse
-	(*ListProjectEventsRequest)(nil),              // 132: akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
-	(*ListProjectEventsResponse)(nil),             // 133: akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
-	(*CreateRoleRequest)(nil),                     // 134: akuity.io.kargo.service.v1alpha1.CreateRoleRequest
-	(*CreateRoleResponse)(nil),                    // 135: akuity.io.kargo.service.v1alpha1.CreateRoleResponse
-	(*DeleteRoleRequest)(nil),                     // 136: akuity.io.kargo.service.v1alpha1.DeleteRoleRequest
-	(*DeleteRoleResponse)(nil),                    // 137: akuity.io.kargo.service.v1alpha1.DeleteRoleResponse
-	(*GetRoleRequest)(nil),                        // 138: akuity.io.kargo.service.v1alpha1.GetRoleRequest
-	(*GetRoleResponse)(nil),                       // 139: akuity.io.kargo.service.v1alpha1.GetRoleResponse
-	(*Claims)(nil),                                // 140: akuity.io.kargo.service.v1alpha1.Claims
-	(*GrantRequest)(nil),                          // 141: akuity.io.kargo.service.v1alpha1.GrantRequest
-	(*GrantResponse)(nil),                         // 142: akuity.io.kargo.service.v1alpha1.GrantResponse
-	(*ListRolesRequest)(nil),                      // 143: akuity.io.kargo.service.v1alpha1.ListRolesRequest
-	(*ListRolesResponse)(nil),                     // 144: akuity.io.kargo.service.v1alpha1.ListRolesResponse
-	(*RevokeRequest)(nil),                         // 145: akuity.io.kargo.service.v1alpha1.RevokeRequest
-	(*RevokeResponse)(nil),                        // 146: akuity.io.kargo.service.v1alpha1.RevokeResponse
-	(*UpdateRoleRequest)(nil),                     // 147: akuity.io.kargo.service.v1alpha1.UpdateRoleRequest
-	(*UpdateRoleResponse)(nil),                    // 148: akuity.io.kargo.service.v1alpha1.UpdateRoleResponse
-	nil,                                           // 149: akuity.io.kargo.service.v1alpha1.GetConfigResponse.ArgocdShardsEntry
-	nil,                                           // 150: akuity.io.kargo.service.v1alpha1.ListImagesResponse.ImagesEntry
-	nil,                                           // 151: akuity.io.kargo.service.v1alpha1.TagMap.TagsEntry
-	nil,                                           // 152: akuity.io.kargo.service.v1alpha1.ImageStageMap.StagesEntry
-	nil,                                           // 153: akuity.io.kargo.service.v1alpha1.QueryFreightResponse.GroupsEntry
-	nil,                                           // 154: akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.DataEntry
-	nil,                                           // 155: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.DataEntry
-	(*timestamppb.Timestamp)(nil),                 // 156: google.protobuf.Timestamp
-	(*v1alpha1.Stage)(nil),                        // 157: github.com.akuity.kargo.api.v1alpha1.Stage
-	(*v1alpha1.Promotion)(nil),                    // 158: github.com.akuity.kargo.api.v1alpha1.Promotion
-	(*v1alpha1.ProjectConfig)(nil),                // 159: github.com.akuity.kargo.api.v1alpha1.ProjectConfig
-	(*v1alpha1.Project)(nil),                      // 160: github.com.akuity.kargo.api.v1alpha1.Project
-	(*v1alpha1.Freight)(nil),                      // 161: github.com.akuity.kargo.api.v1alpha1.Freight
-	(*v1alpha1.Warehouse)(nil),                    // 162: github.com.akuity.kargo.api.v1alpha1.Warehouse
-	(*v1.Secret)(nil),                             // 163: k8s.io.api.core.v1.Secret
-	(*v1alpha11.AnalysisTemplate)(nil),            // 164: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
-	(*v1alpha1.PromotionTask)(nil),                // 165: github.com.akuity.kargo.api.v1alpha1.PromotionTask
-	(*v1alpha1.ClusterPromotionTask)(nil),         // 166: github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
-	(*v1alpha11.ClusterAnalysisTemplate)(nil),     // 167: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
-	(*v1alpha11.AnalysisRun)(nil),                 // 168: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
-	(*v1.Event)(nil),                              // 169: k8s.io.api.core.v1.Event
-	(*v1alpha12.Role)(nil),                        // 170: github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	(*v1alpha12.RoleResources)(nil),               // 171: github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
-	(*v1alpha12.Claim)(nil),                       // 172: github.com.akuity.kargo.api.rbac.v1alpha1.Claim
-	(*v1alpha12.ResourceDetails)(nil),             // 173: github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
+	(*GetAnalysisRunRequest)(nil),                 // 132: akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest
+	(*GetAnalysisRunResponse)(nil),                // 133: akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse
+	(*GetAnalysisRunLogsRequest)(nil),             // 134: akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsRequest
+	(*GetAnalysisRunLogsResponse)(nil),            // 135: akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsResponse
+	(*ListProjectEventsRequest)(nil),              // 136: akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
+	(*ListProjectEventsResponse)(nil),             // 137: akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
+	(*ListPromotionTasksRequest)(nil),             // 138: akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest
+	(*ListPromotionTasksResponse)(nil),            // 139: akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse
+	(*GetPromotionTaskRequest)(nil),               // 140: akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest
+	(*GetPromotionTaskResponse)(nil),              // 141: akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse
+	(*ListClusterPromotionTasksRequest)(nil),      // 142: akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest
+	(*ListClusterPromotionTasksResponse)(nil),     // 143: akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse
+	(*GetClusterPromotionTaskRequest)(nil),        // 144: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest
+	(*GetClusterPromotionTaskResponse)(nil),       // 145: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse
+	(*CreateRoleRequest)(nil),                     // 146: akuity.io.kargo.service.v1alpha1.CreateRoleRequest
+	(*CreateRoleResponse)(nil),                    // 147: akuity.io.kargo.service.v1alpha1.CreateRoleResponse
+	(*DeleteRoleRequest)(nil),                     // 148: akuity.io.kargo.service.v1alpha1.DeleteRoleRequest
+	(*DeleteRoleResponse)(nil),                    // 149: akuity.io.kargo.service.v1alpha1.DeleteRoleResponse
+	(*GetRoleRequest)(nil),                        // 150: akuity.io.kargo.service.v1alpha1.GetRoleRequest
+	(*GetRoleResponse)(nil),                       // 151: akuity.io.kargo.service.v1alpha1.GetRoleResponse
+	(*Claims)(nil),                                // 152: akuity.io.kargo.service.v1alpha1.Claims
+	(*GrantRequest)(nil),                          // 153: akuity.io.kargo.service.v1alpha1.GrantRequest
+	(*GrantResponse)(nil),                         // 154: akuity.io.kargo.service.v1alpha1.GrantResponse
+	(*ListRolesRequest)(nil),                      // 155: akuity.io.kargo.service.v1alpha1.ListRolesRequest
+	(*ListRolesResponse)(nil),                     // 156: akuity.io.kargo.service.v1alpha1.ListRolesResponse
+	(*RevokeRequest)(nil),                         // 157: akuity.io.kargo.service.v1alpha1.RevokeRequest
+	(*RevokeResponse)(nil),                        // 158: akuity.io.kargo.service.v1alpha1.RevokeResponse
+	(*UpdateRoleRequest)(nil),                     // 159: akuity.io.kargo.service.v1alpha1.UpdateRoleRequest
+	(*UpdateRoleResponse)(nil),                    // 160: akuity.io.kargo.service.v1alpha1.UpdateRoleResponse
+	nil,                                           // 161: akuity.io.kargo.service.v1alpha1.GetConfigResponse.ArgocdShardsEntry
+	nil,                                           // 162: akuity.io.kargo.service.v1alpha1.ListImagesResponse.ImagesEntry
+	nil,                                           // 163: akuity.io.kargo.service.v1alpha1.TagMap.TagsEntry
+	nil,                                           // 164: akuity.io.kargo.service.v1alpha1.ImageStageMap.StagesEntry
+	nil,                                           // 165: akuity.io.kargo.service.v1alpha1.QueryFreightResponse.GroupsEntry
+	nil,                                           // 166: akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.DataEntry
+	nil,                                           // 167: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.DataEntry
+	(*timestamppb.Timestamp)(nil),                 // 168: google.protobuf.Timestamp
+	(*v1alpha1.Stage)(nil),                        // 169: github.com.akuity.kargo.api.v1alpha1.Stage
+	(*v1alpha1.ClusterConfig)(nil),                // 170: github.com.akuity.kargo.api.v1alpha1.ClusterConfig
+	(*v1alpha1.Promotion)(nil),                    // 171: github.com.akuity.kargo.api.v1alpha1.Promotion
+	(*v1alpha1.Project)(nil),                      // 172: github.com.akuity.kargo.api.v1alpha1.Project
+	(*v1alpha1.ProjectConfig)(nil),                // 173: github.com.akuity.kargo.api.v1alpha1.ProjectConfig
+	(*v1alpha1.Freight)(nil),                      // 174: github.com.akuity.kargo.api.v1alpha1.Freight
+	(*v1alpha1.Warehouse)(nil),                    // 175: github.com.akuity.kargo.api.v1alpha1.Warehouse
+	(*v1.Secret)(nil),                             // 176: k8s.io.api.core.v1.Secret
+	(*v1alpha11.AnalysisTemplate)(nil),            // 177: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
+	(*v1alpha11.ClusterAnalysisTemplate)(nil),     // 178: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
+	(*v1alpha11.AnalysisRun)(nil),                 // 179: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
+	(*v1.Event)(nil),                              // 180: k8s.io.api.core.v1.Event
+	(*v1alpha1.PromotionTask)(nil),                // 181: github.com.akuity.kargo.api.v1alpha1.PromotionTask
+	(*v1alpha1.ClusterPromotionTask)(nil),         // 182: github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
+	(*v1alpha12.Role)(nil),                        // 183: github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	(*v1alpha12.RoleResources)(nil),               // 184: github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
+	(*v1alpha12.Claim)(nil),                       // 185: github.com.akuity.kargo.api.rbac.v1alpha1.Claim
+	(*v1alpha12.ResourceDetails)(nil),             // 186: github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
 }
 var file_api_service_v1alpha1_service_proto_depIdxs = []int32{
 	2,   // 0: akuity.io.kargo.service.v1alpha1.ComponentVersions.server:type_name -> akuity.io.kargo.service.v1alpha1.VersionInfo
 	2,   // 1: akuity.io.kargo.service.v1alpha1.ComponentVersions.cli:type_name -> akuity.io.kargo.service.v1alpha1.VersionInfo
-	156, // 2: akuity.io.kargo.service.v1alpha1.VersionInfo.build_time:type_name -> google.protobuf.Timestamp
+	168, // 2: akuity.io.kargo.service.v1alpha1.VersionInfo.build_time:type_name -> google.protobuf.Timestamp
 	2,   // 3: akuity.io.kargo.service.v1alpha1.GetVersionInfoResponse.version_info:type_name -> akuity.io.kargo.service.v1alpha1.VersionInfo
-	149, // 4: akuity.io.kargo.service.v1alpha1.GetConfigResponse.argocd_shards:type_name -> akuity.io.kargo.service.v1alpha1.GetConfigResponse.ArgocdShardsEntry
+	161, // 4: akuity.io.kargo.service.v1alpha1.GetConfigResponse.argocd_shards:type_name -> akuity.io.kargo.service.v1alpha1.GetConfigResponse.ArgocdShardsEntry
 	10,  // 5: akuity.io.kargo.service.v1alpha1.GetPublicConfigResponse.oidc_config:type_name -> akuity.io.kargo.service.v1alpha1.OIDCConfig
 	14,  // 6: akuity.io.kargo.service.v1alpha1.CreateResourceResponse.results:type_name -> akuity.io.kargo.service.v1alpha1.CreateResourceResult
 	17,  // 7: akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceResponse.results:type_name -> akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceResult
 	20,  // 8: akuity.io.kargo.service.v1alpha1.UpdateResourceResponse.results:type_name -> akuity.io.kargo.service.v1alpha1.UpdateResourceResult
 	23,  // 9: akuity.io.kargo.service.v1alpha1.DeleteResourceResponse.results:type_name -> akuity.io.kargo.service.v1alpha1.DeleteResourceResult
-	157, // 10: akuity.io.kargo.service.v1alpha1.ListStagesResponse.stages:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
-	150, // 11: akuity.io.kargo.service.v1alpha1.ListImagesResponse.images:type_name -> akuity.io.kargo.service.v1alpha1.ListImagesResponse.ImagesEntry
-	151, // 12: akuity.io.kargo.service.v1alpha1.TagMap.tags:type_name -> akuity.io.kargo.service.v1alpha1.TagMap.TagsEntry
-	152, // 13: akuity.io.kargo.service.v1alpha1.ImageStageMap.stages:type_name -> akuity.io.kargo.service.v1alpha1.ImageStageMap.StagesEntry
+	169, // 10: akuity.io.kargo.service.v1alpha1.ListStagesResponse.stages:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
+	162, // 11: akuity.io.kargo.service.v1alpha1.ListImagesResponse.images:type_name -> akuity.io.kargo.service.v1alpha1.ListImagesResponse.ImagesEntry
+	163, // 12: akuity.io.kargo.service.v1alpha1.TagMap.tags:type_name -> akuity.io.kargo.service.v1alpha1.TagMap.TagsEntry
+	164, // 13: akuity.io.kargo.service.v1alpha1.ImageStageMap.stages:type_name -> akuity.io.kargo.service.v1alpha1.ImageStageMap.StagesEntry
 	0,   // 14: akuity.io.kargo.service.v1alpha1.GetStageRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	157, // 15: akuity.io.kargo.service.v1alpha1.GetStageResponse.stage:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
-	157, // 16: akuity.io.kargo.service.v1alpha1.WatchStagesResponse.stage:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
-	157, // 17: akuity.io.kargo.service.v1alpha1.RefreshStageResponse.stage:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
-	158, // 18: akuity.io.kargo.service.v1alpha1.ListPromotionsResponse.promotions:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
-	158, // 19: akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
-	0,   // 20: akuity.io.kargo.service.v1alpha1.GetPromotionRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	158, // 21: akuity.io.kargo.service.v1alpha1.GetPromotionResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
-	158, // 22: akuity.io.kargo.service.v1alpha1.WatchPromotionResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
-	0,   // 23: akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	159, // 24: akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse.project_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ProjectConfig
-	0,   // 25: akuity.io.kargo.service.v1alpha1.GetProjectRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	160, // 26: akuity.io.kargo.service.v1alpha1.GetProjectResponse.project:type_name -> github.com.akuity.kargo.api.v1alpha1.Project
-	160, // 27: akuity.io.kargo.service.v1alpha1.ListProjectsResponse.projects:type_name -> github.com.akuity.kargo.api.v1alpha1.Project
-	0,   // 28: akuity.io.kargo.service.v1alpha1.GetFreightRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	161, // 29: akuity.io.kargo.service.v1alpha1.GetFreightResponse.freight:type_name -> github.com.akuity.kargo.api.v1alpha1.Freight
-	161, // 30: akuity.io.kargo.service.v1alpha1.WatchFreightResponse.freight:type_name -> github.com.akuity.kargo.api.v1alpha1.Freight
-	158, // 31: akuity.io.kargo.service.v1alpha1.PromoteToStageResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
-	158, // 32: akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse.promotions:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
-	153, // 33: akuity.io.kargo.service.v1alpha1.QueryFreightResponse.groups:type_name -> akuity.io.kargo.service.v1alpha1.QueryFreightResponse.GroupsEntry
-	161, // 34: akuity.io.kargo.service.v1alpha1.FreightList.freight:type_name -> github.com.akuity.kargo.api.v1alpha1.Freight
-	162, // 35: akuity.io.kargo.service.v1alpha1.ListWarehousesResponse.warehouses:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
-	0,   // 36: akuity.io.kargo.service.v1alpha1.GetWarehouseRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	162, // 37: akuity.io.kargo.service.v1alpha1.GetWarehouseResponse.warehouse:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
-	162, // 38: akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse.warehouse:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
-	162, // 39: akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse.warehouse:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
-	163, // 40: akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse.secrets:type_name -> k8s.io.api.core.v1.Secret
-	154, // 41: akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.data:type_name -> akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.DataEntry
-	163, // 42: akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse.secret:type_name -> k8s.io.api.core.v1.Secret
-	155, // 43: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.data:type_name -> akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.DataEntry
-	163, // 44: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse.secret:type_name -> k8s.io.api.core.v1.Secret
-	163, // 45: akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
-	0,   // 46: akuity.io.kargo.service.v1alpha1.GetCredentialsRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	163, // 47: akuity.io.kargo.service.v1alpha1.GetCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
-	163, // 48: akuity.io.kargo.service.v1alpha1.ListCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
-	163, // 49: akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
-	164, // 50: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse.analysis_templates:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
-	165, // 51: akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse.promotion_tasks:type_name -> github.com.akuity.kargo.api.v1alpha1.PromotionTask
-	166, // 52: akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse.cluster_promotion_tasks:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
-	0,   // 53: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	164, // 54: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.analysis_template:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
-	0,   // 55: akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	165, // 56: akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse.promotion_task:type_name -> github.com.akuity.kargo.api.v1alpha1.PromotionTask
-	0,   // 57: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	166, // 58: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse.promotion_task:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
-	167, // 59: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse.cluster_analysis_templates:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
+	169, // 15: akuity.io.kargo.service.v1alpha1.GetStageResponse.stage:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
+	169, // 16: akuity.io.kargo.service.v1alpha1.WatchStagesResponse.stage:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
+	169, // 17: akuity.io.kargo.service.v1alpha1.RefreshStageResponse.stage:type_name -> github.com.akuity.kargo.api.v1alpha1.Stage
+	0,   // 18: akuity.io.kargo.service.v1alpha1.GetClusterConfigRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	170, // 19: akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse.cluster_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterConfig
+	170, // 20: akuity.io.kargo.service.v1alpha1.WatchClusterConfigResponse.cluster_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterConfig
+	170, // 21: akuity.io.kargo.service.v1alpha1.RefreshClusterConfigResponse.cluster_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterConfig
+	171, // 22: akuity.io.kargo.service.v1alpha1.ListPromotionsResponse.promotions:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
+	171, // 23: akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
+	0,   // 24: akuity.io.kargo.service.v1alpha1.GetPromotionRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	171, // 25: akuity.io.kargo.service.v1alpha1.GetPromotionResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
+	171, // 26: akuity.io.kargo.service.v1alpha1.WatchPromotionResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
+	0,   // 27: akuity.io.kargo.service.v1alpha1.GetProjectRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	172, // 28: akuity.io.kargo.service.v1alpha1.GetProjectResponse.project:type_name -> github.com.akuity.kargo.api.v1alpha1.Project
+	172, // 29: akuity.io.kargo.service.v1alpha1.ListProjectsResponse.projects:type_name -> github.com.akuity.kargo.api.v1alpha1.Project
+	0,   // 30: akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	173, // 31: akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse.project_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ProjectConfig
+	173, // 32: akuity.io.kargo.service.v1alpha1.WatchProjectConfigResponse.project_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ProjectConfig
+	173, // 33: akuity.io.kargo.service.v1alpha1.RefreshProjectConfigResponse.project_config:type_name -> github.com.akuity.kargo.api.v1alpha1.ProjectConfig
+	0,   // 34: akuity.io.kargo.service.v1alpha1.GetFreightRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	174, // 35: akuity.io.kargo.service.v1alpha1.GetFreightResponse.freight:type_name -> github.com.akuity.kargo.api.v1alpha1.Freight
+	174, // 36: akuity.io.kargo.service.v1alpha1.WatchFreightResponse.freight:type_name -> github.com.akuity.kargo.api.v1alpha1.Freight
+	171, // 37: akuity.io.kargo.service.v1alpha1.PromoteToStageResponse.promotion:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
+	171, // 38: akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse.promotions:type_name -> github.com.akuity.kargo.api.v1alpha1.Promotion
+	165, // 39: akuity.io.kargo.service.v1alpha1.QueryFreightResponse.groups:type_name -> akuity.io.kargo.service.v1alpha1.QueryFreightResponse.GroupsEntry
+	174, // 40: akuity.io.kargo.service.v1alpha1.FreightList.freight:type_name -> github.com.akuity.kargo.api.v1alpha1.Freight
+	175, // 41: akuity.io.kargo.service.v1alpha1.ListWarehousesResponse.warehouses:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
+	0,   // 42: akuity.io.kargo.service.v1alpha1.GetWarehouseRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	175, // 43: akuity.io.kargo.service.v1alpha1.GetWarehouseResponse.warehouse:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
+	175, // 44: akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse.warehouse:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
+	175, // 45: akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse.warehouse:type_name -> github.com.akuity.kargo.api.v1alpha1.Warehouse
+	176, // 46: akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
+	0,   // 47: akuity.io.kargo.service.v1alpha1.GetCredentialsRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	176, // 48: akuity.io.kargo.service.v1alpha1.GetCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
+	176, // 49: akuity.io.kargo.service.v1alpha1.ListCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
+	176, // 50: akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
+	176, // 51: akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse.secrets:type_name -> k8s.io.api.core.v1.Secret
+	166, // 52: akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.data:type_name -> akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.DataEntry
+	176, // 53: akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse.secret:type_name -> k8s.io.api.core.v1.Secret
+	167, // 54: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.data:type_name -> akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.DataEntry
+	176, // 55: akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse.secret:type_name -> k8s.io.api.core.v1.Secret
+	177, // 56: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse.analysis_templates:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
+	0,   // 57: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	177, // 58: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.analysis_template:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
+	178, // 59: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse.cluster_analysis_templates:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
 	0,   // 60: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	167, // 61: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse.cluster_analysis_template:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
+	178, // 61: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse.cluster_analysis_template:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
 	0,   // 62: akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	168, // 63: akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse.analysis_run:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
-	169, // 64: akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse.events:type_name -> k8s.io.api.core.v1.Event
-	170, // 65: akuity.io.kargo.service.v1alpha1.CreateRoleRequest.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	170, // 66: akuity.io.kargo.service.v1alpha1.CreateRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	0,   // 67: akuity.io.kargo.service.v1alpha1.GetRoleRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	170, // 68: akuity.io.kargo.service.v1alpha1.GetRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	171, // 69: akuity.io.kargo.service.v1alpha1.GetRoleResponse.resources:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
-	172, // 70: akuity.io.kargo.service.v1alpha1.Claims.claims:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Claim
-	140, // 71: akuity.io.kargo.service.v1alpha1.GrantRequest.user_claims:type_name -> akuity.io.kargo.service.v1alpha1.Claims
-	173, // 72: akuity.io.kargo.service.v1alpha1.GrantRequest.resource_details:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
-	170, // 73: akuity.io.kargo.service.v1alpha1.GrantResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	170, // 74: akuity.io.kargo.service.v1alpha1.ListRolesResponse.roles:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	171, // 75: akuity.io.kargo.service.v1alpha1.ListRolesResponse.resources:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
-	140, // 76: akuity.io.kargo.service.v1alpha1.RevokeRequest.user_claims:type_name -> akuity.io.kargo.service.v1alpha1.Claims
-	173, // 77: akuity.io.kargo.service.v1alpha1.RevokeRequest.resource_details:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
-	170, // 78: akuity.io.kargo.service.v1alpha1.RevokeResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	170, // 79: akuity.io.kargo.service.v1alpha1.UpdateRoleRequest.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	170, // 80: akuity.io.kargo.service.v1alpha1.UpdateRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
-	6,   // 81: akuity.io.kargo.service.v1alpha1.GetConfigResponse.ArgocdShardsEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.ArgoCDShard
-	29,  // 82: akuity.io.kargo.service.v1alpha1.ListImagesResponse.ImagesEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.TagMap
-	30,  // 83: akuity.io.kargo.service.v1alpha1.TagMap.TagsEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.ImageStageMap
-	73,  // 84: akuity.io.kargo.service.v1alpha1.QueryFreightResponse.GroupsEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.FreightList
-	3,   // 85: akuity.io.kargo.service.v1alpha1.KargoService.GetVersionInfo:input_type -> akuity.io.kargo.service.v1alpha1.GetVersionInfoRequest
-	5,   // 86: akuity.io.kargo.service.v1alpha1.KargoService.GetConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetConfigRequest
-	8,   // 87: akuity.io.kargo.service.v1alpha1.KargoService.GetPublicConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetPublicConfigRequest
-	11,  // 88: akuity.io.kargo.service.v1alpha1.KargoService.AdminLogin:input_type -> akuity.io.kargo.service.v1alpha1.AdminLoginRequest
-	13,  // 89: akuity.io.kargo.service.v1alpha1.KargoService.CreateResource:input_type -> akuity.io.kargo.service.v1alpha1.CreateResourceRequest
-	16,  // 90: akuity.io.kargo.service.v1alpha1.KargoService.CreateOrUpdateResource:input_type -> akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceRequest
-	19,  // 91: akuity.io.kargo.service.v1alpha1.KargoService.UpdateResource:input_type -> akuity.io.kargo.service.v1alpha1.UpdateResourceRequest
-	22,  // 92: akuity.io.kargo.service.v1alpha1.KargoService.DeleteResource:input_type -> akuity.io.kargo.service.v1alpha1.DeleteResourceRequest
-	25,  // 93: akuity.io.kargo.service.v1alpha1.KargoService.ListStages:input_type -> akuity.io.kargo.service.v1alpha1.ListStagesRequest
-	27,  // 94: akuity.io.kargo.service.v1alpha1.KargoService.ListImages:input_type -> akuity.io.kargo.service.v1alpha1.ListImagesRequest
-	31,  // 95: akuity.io.kargo.service.v1alpha1.KargoService.GetStage:input_type -> akuity.io.kargo.service.v1alpha1.GetStageRequest
-	33,  // 96: akuity.io.kargo.service.v1alpha1.KargoService.WatchStages:input_type -> akuity.io.kargo.service.v1alpha1.WatchStagesRequest
-	35,  // 97: akuity.io.kargo.service.v1alpha1.KargoService.DeleteStage:input_type -> akuity.io.kargo.service.v1alpha1.DeleteStageRequest
-	37,  // 98: akuity.io.kargo.service.v1alpha1.KargoService.RefreshStage:input_type -> akuity.io.kargo.service.v1alpha1.RefreshStageRequest
-	39,  // 99: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions:input_type -> akuity.io.kargo.service.v1alpha1.ListPromotionsRequest
-	41,  // 100: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotions:input_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionsRequest
-	43,  // 101: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotion:input_type -> akuity.io.kargo.service.v1alpha1.GetPromotionRequest
-	45,  // 102: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotion:input_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionRequest
-	47,  // 103: akuity.io.kargo.service.v1alpha1.KargoService.AbortPromotion:input_type -> akuity.io.kargo.service.v1alpha1.AbortPromotionRequest
-	49,  // 104: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProject:input_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectRequest
-	55,  // 105: akuity.io.kargo.service.v1alpha1.KargoService.GetProject:input_type -> akuity.io.kargo.service.v1alpha1.GetProjectRequest
-	57,  // 106: akuity.io.kargo.service.v1alpha1.KargoService.ListProjects:input_type -> akuity.io.kargo.service.v1alpha1.ListProjectsRequest
-	51,  // 107: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig:input_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest
-	53,  // 108: akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest
-	59,  // 109: akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight:input_type -> akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
-	61,  // 110: akuity.io.kargo.service.v1alpha1.KargoService.DeleteFreight:input_type -> akuity.io.kargo.service.v1alpha1.DeleteFreightRequest
-	63,  // 111: akuity.io.kargo.service.v1alpha1.KargoService.GetFreight:input_type -> akuity.io.kargo.service.v1alpha1.GetFreightRequest
-	65,  // 112: akuity.io.kargo.service.v1alpha1.KargoService.WatchFreight:input_type -> akuity.io.kargo.service.v1alpha1.WatchFreightRequest
-	67,  // 113: akuity.io.kargo.service.v1alpha1.KargoService.PromoteToStage:input_type -> akuity.io.kargo.service.v1alpha1.PromoteToStageRequest
-	69,  // 114: akuity.io.kargo.service.v1alpha1.KargoService.PromoteDownstream:input_type -> akuity.io.kargo.service.v1alpha1.PromoteDownstreamRequest
-	71,  // 115: akuity.io.kargo.service.v1alpha1.KargoService.QueryFreight:input_type -> akuity.io.kargo.service.v1alpha1.QueryFreightRequest
-	74,  // 116: akuity.io.kargo.service.v1alpha1.KargoService.UpdateFreightAlias:input_type -> akuity.io.kargo.service.v1alpha1.UpdateFreightAliasRequest
-	76,  // 117: akuity.io.kargo.service.v1alpha1.KargoService.Reverify:input_type -> akuity.io.kargo.service.v1alpha1.ReverifyRequest
-	78,  // 118: akuity.io.kargo.service.v1alpha1.KargoService.AbortVerification:input_type -> akuity.io.kargo.service.v1alpha1.AbortVerificationRequest
-	80,  // 119: akuity.io.kargo.service.v1alpha1.KargoService.ListWarehouses:input_type -> akuity.io.kargo.service.v1alpha1.ListWarehousesRequest
-	82,  // 120: akuity.io.kargo.service.v1alpha1.KargoService.GetWarehouse:input_type -> akuity.io.kargo.service.v1alpha1.GetWarehouseRequest
-	84,  // 121: akuity.io.kargo.service.v1alpha1.KargoService.WatchWarehouses:input_type -> akuity.io.kargo.service.v1alpha1.WatchWarehousesRequest
-	86,  // 122: akuity.io.kargo.service.v1alpha1.KargoService.DeleteWarehouse:input_type -> akuity.io.kargo.service.v1alpha1.DeleteWarehouseRequest
-	88,  // 123: akuity.io.kargo.service.v1alpha1.KargoService.RefreshWarehouse:input_type -> akuity.io.kargo.service.v1alpha1.RefreshWarehouseRequest
-	98,  // 124: akuity.io.kargo.service.v1alpha1.KargoService.CreateCredentials:input_type -> akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
-	100, // 125: akuity.io.kargo.service.v1alpha1.KargoService.DeleteCredentials:input_type -> akuity.io.kargo.service.v1alpha1.DeleteCredentialsRequest
-	102, // 126: akuity.io.kargo.service.v1alpha1.KargoService.GetCredentials:input_type -> akuity.io.kargo.service.v1alpha1.GetCredentialsRequest
-	104, // 127: akuity.io.kargo.service.v1alpha1.KargoService.ListCredentials:input_type -> akuity.io.kargo.service.v1alpha1.ListCredentialsRequest
-	106, // 128: akuity.io.kargo.service.v1alpha1.KargoService.UpdateCredentials:input_type -> akuity.io.kargo.service.v1alpha1.UpdateCredentialsRequest
-	90,  // 129: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectSecrets:input_type -> akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
-	92,  // 130: akuity.io.kargo.service.v1alpha1.KargoService.CreateProjectSecret:input_type -> akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
-	94,  // 131: akuity.io.kargo.service.v1alpha1.KargoService.UpdateProjectSecret:input_type -> akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
-	96,  // 132: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectSecret:input_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
-	108, // 133: akuity.io.kargo.service.v1alpha1.KargoService.ListAnalysisTemplates:input_type -> akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
-	114, // 134: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
-	128, // 135: akuity.io.kargo.service.v1alpha1.KargoService.DeleteAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
-	120, // 136: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterAnalysisTemplates:input_type -> akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesRequest
-	122, // 137: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest
-	130, // 138: akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest
-	124, // 139: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRun:input_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest
-	126, // 140: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRunLogs:input_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsRequest
-	132, // 141: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectEvents:input_type -> akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
-	110, // 142: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotionTasks:input_type -> akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest
-	112, // 143: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterPromotionTasks:input_type -> akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest
-	116, // 144: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotionTask:input_type -> akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest
-	118, // 145: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterPromotionTask:input_type -> akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest
-	134, // 146: akuity.io.kargo.service.v1alpha1.KargoService.CreateRole:input_type -> akuity.io.kargo.service.v1alpha1.CreateRoleRequest
-	136, // 147: akuity.io.kargo.service.v1alpha1.KargoService.DeleteRole:input_type -> akuity.io.kargo.service.v1alpha1.DeleteRoleRequest
-	138, // 148: akuity.io.kargo.service.v1alpha1.KargoService.GetRole:input_type -> akuity.io.kargo.service.v1alpha1.GetRoleRequest
-	141, // 149: akuity.io.kargo.service.v1alpha1.KargoService.Grant:input_type -> akuity.io.kargo.service.v1alpha1.GrantRequest
-	143, // 150: akuity.io.kargo.service.v1alpha1.KargoService.ListRoles:input_type -> akuity.io.kargo.service.v1alpha1.ListRolesRequest
-	145, // 151: akuity.io.kargo.service.v1alpha1.KargoService.Revoke:input_type -> akuity.io.kargo.service.v1alpha1.RevokeRequest
-	147, // 152: akuity.io.kargo.service.v1alpha1.KargoService.UpdateRole:input_type -> akuity.io.kargo.service.v1alpha1.UpdateRoleRequest
-	4,   // 153: akuity.io.kargo.service.v1alpha1.KargoService.GetVersionInfo:output_type -> akuity.io.kargo.service.v1alpha1.GetVersionInfoResponse
-	7,   // 154: akuity.io.kargo.service.v1alpha1.KargoService.GetConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetConfigResponse
-	9,   // 155: akuity.io.kargo.service.v1alpha1.KargoService.GetPublicConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetPublicConfigResponse
-	12,  // 156: akuity.io.kargo.service.v1alpha1.KargoService.AdminLogin:output_type -> akuity.io.kargo.service.v1alpha1.AdminLoginResponse
-	15,  // 157: akuity.io.kargo.service.v1alpha1.KargoService.CreateResource:output_type -> akuity.io.kargo.service.v1alpha1.CreateResourceResponse
-	18,  // 158: akuity.io.kargo.service.v1alpha1.KargoService.CreateOrUpdateResource:output_type -> akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceResponse
-	21,  // 159: akuity.io.kargo.service.v1alpha1.KargoService.UpdateResource:output_type -> akuity.io.kargo.service.v1alpha1.UpdateResourceResponse
-	24,  // 160: akuity.io.kargo.service.v1alpha1.KargoService.DeleteResource:output_type -> akuity.io.kargo.service.v1alpha1.DeleteResourceResponse
-	26,  // 161: akuity.io.kargo.service.v1alpha1.KargoService.ListStages:output_type -> akuity.io.kargo.service.v1alpha1.ListStagesResponse
-	28,  // 162: akuity.io.kargo.service.v1alpha1.KargoService.ListImages:output_type -> akuity.io.kargo.service.v1alpha1.ListImagesResponse
-	32,  // 163: akuity.io.kargo.service.v1alpha1.KargoService.GetStage:output_type -> akuity.io.kargo.service.v1alpha1.GetStageResponse
-	34,  // 164: akuity.io.kargo.service.v1alpha1.KargoService.WatchStages:output_type -> akuity.io.kargo.service.v1alpha1.WatchStagesResponse
-	36,  // 165: akuity.io.kargo.service.v1alpha1.KargoService.DeleteStage:output_type -> akuity.io.kargo.service.v1alpha1.DeleteStageResponse
-	38,  // 166: akuity.io.kargo.service.v1alpha1.KargoService.RefreshStage:output_type -> akuity.io.kargo.service.v1alpha1.RefreshStageResponse
-	40,  // 167: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions:output_type -> akuity.io.kargo.service.v1alpha1.ListPromotionsResponse
-	42,  // 168: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotions:output_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse
-	44,  // 169: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotion:output_type -> akuity.io.kargo.service.v1alpha1.GetPromotionResponse
-	46,  // 170: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotion:output_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionResponse
-	48,  // 171: akuity.io.kargo.service.v1alpha1.KargoService.AbortPromotion:output_type -> akuity.io.kargo.service.v1alpha1.AbortPromotionResponse
-	50,  // 172: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProject:output_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectResponse
-	56,  // 173: akuity.io.kargo.service.v1alpha1.KargoService.GetProject:output_type -> akuity.io.kargo.service.v1alpha1.GetProjectResponse
-	58,  // 174: akuity.io.kargo.service.v1alpha1.KargoService.ListProjects:output_type -> akuity.io.kargo.service.v1alpha1.ListProjectsResponse
-	52,  // 175: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig:output_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse
-	54,  // 176: akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse
-	60,  // 177: akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight:output_type -> akuity.io.kargo.service.v1alpha1.ApproveFreightResponse
-	62,  // 178: akuity.io.kargo.service.v1alpha1.KargoService.DeleteFreight:output_type -> akuity.io.kargo.service.v1alpha1.DeleteFreightResponse
-	64,  // 179: akuity.io.kargo.service.v1alpha1.KargoService.GetFreight:output_type -> akuity.io.kargo.service.v1alpha1.GetFreightResponse
-	66,  // 180: akuity.io.kargo.service.v1alpha1.KargoService.WatchFreight:output_type -> akuity.io.kargo.service.v1alpha1.WatchFreightResponse
-	68,  // 181: akuity.io.kargo.service.v1alpha1.KargoService.PromoteToStage:output_type -> akuity.io.kargo.service.v1alpha1.PromoteToStageResponse
-	70,  // 182: akuity.io.kargo.service.v1alpha1.KargoService.PromoteDownstream:output_type -> akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse
-	72,  // 183: akuity.io.kargo.service.v1alpha1.KargoService.QueryFreight:output_type -> akuity.io.kargo.service.v1alpha1.QueryFreightResponse
-	75,  // 184: akuity.io.kargo.service.v1alpha1.KargoService.UpdateFreightAlias:output_type -> akuity.io.kargo.service.v1alpha1.UpdateFreightAliasResponse
-	77,  // 185: akuity.io.kargo.service.v1alpha1.KargoService.Reverify:output_type -> akuity.io.kargo.service.v1alpha1.ReverifyResponse
-	79,  // 186: akuity.io.kargo.service.v1alpha1.KargoService.AbortVerification:output_type -> akuity.io.kargo.service.v1alpha1.AbortVerificationResponse
-	81,  // 187: akuity.io.kargo.service.v1alpha1.KargoService.ListWarehouses:output_type -> akuity.io.kargo.service.v1alpha1.ListWarehousesResponse
-	83,  // 188: akuity.io.kargo.service.v1alpha1.KargoService.GetWarehouse:output_type -> akuity.io.kargo.service.v1alpha1.GetWarehouseResponse
-	85,  // 189: akuity.io.kargo.service.v1alpha1.KargoService.WatchWarehouses:output_type -> akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse
-	87,  // 190: akuity.io.kargo.service.v1alpha1.KargoService.DeleteWarehouse:output_type -> akuity.io.kargo.service.v1alpha1.DeleteWarehouseResponse
-	89,  // 191: akuity.io.kargo.service.v1alpha1.KargoService.RefreshWarehouse:output_type -> akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse
-	99,  // 192: akuity.io.kargo.service.v1alpha1.KargoService.CreateCredentials:output_type -> akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
-	101, // 193: akuity.io.kargo.service.v1alpha1.KargoService.DeleteCredentials:output_type -> akuity.io.kargo.service.v1alpha1.DeleteCredentialsResponse
-	103, // 194: akuity.io.kargo.service.v1alpha1.KargoService.GetCredentials:output_type -> akuity.io.kargo.service.v1alpha1.GetCredentialsResponse
-	105, // 195: akuity.io.kargo.service.v1alpha1.KargoService.ListCredentials:output_type -> akuity.io.kargo.service.v1alpha1.ListCredentialsResponse
-	107, // 196: akuity.io.kargo.service.v1alpha1.KargoService.UpdateCredentials:output_type -> akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse
-	91,  // 197: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectSecrets:output_type -> akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
-	93,  // 198: akuity.io.kargo.service.v1alpha1.KargoService.CreateProjectSecret:output_type -> akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
-	95,  // 199: akuity.io.kargo.service.v1alpha1.KargoService.UpdateProjectSecret:output_type -> akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
-	97,  // 200: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectSecret:output_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse
-	109, // 201: akuity.io.kargo.service.v1alpha1.KargoService.ListAnalysisTemplates:output_type -> akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
-	115, // 202: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
-	129, // 203: akuity.io.kargo.service.v1alpha1.KargoService.DeleteAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse
-	121, // 204: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterAnalysisTemplates:output_type -> akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse
-	123, // 205: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse
-	131, // 206: akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse
-	125, // 207: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRun:output_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse
-	127, // 208: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRunLogs:output_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsResponse
-	133, // 209: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectEvents:output_type -> akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
-	111, // 210: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotionTasks:output_type -> akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse
-	113, // 211: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterPromotionTasks:output_type -> akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse
-	117, // 212: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotionTask:output_type -> akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse
-	119, // 213: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterPromotionTask:output_type -> akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse
-	135, // 214: akuity.io.kargo.service.v1alpha1.KargoService.CreateRole:output_type -> akuity.io.kargo.service.v1alpha1.CreateRoleResponse
-	137, // 215: akuity.io.kargo.service.v1alpha1.KargoService.DeleteRole:output_type -> akuity.io.kargo.service.v1alpha1.DeleteRoleResponse
-	139, // 216: akuity.io.kargo.service.v1alpha1.KargoService.GetRole:output_type -> akuity.io.kargo.service.v1alpha1.GetRoleResponse
-	142, // 217: akuity.io.kargo.service.v1alpha1.KargoService.Grant:output_type -> akuity.io.kargo.service.v1alpha1.GrantResponse
-	144, // 218: akuity.io.kargo.service.v1alpha1.KargoService.ListRoles:output_type -> akuity.io.kargo.service.v1alpha1.ListRolesResponse
-	146, // 219: akuity.io.kargo.service.v1alpha1.KargoService.Revoke:output_type -> akuity.io.kargo.service.v1alpha1.RevokeResponse
-	148, // 220: akuity.io.kargo.service.v1alpha1.KargoService.UpdateRole:output_type -> akuity.io.kargo.service.v1alpha1.UpdateRoleResponse
-	153, // [153:221] is the sub-list for method output_type
-	85,  // [85:153] is the sub-list for method input_type
-	85,  // [85:85] is the sub-list for extension type_name
-	85,  // [85:85] is the sub-list for extension extendee
-	0,   // [0:85] is the sub-list for field type_name
+	179, // 63: akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse.analysis_run:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
+	180, // 64: akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse.events:type_name -> k8s.io.api.core.v1.Event
+	181, // 65: akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse.promotion_tasks:type_name -> github.com.akuity.kargo.api.v1alpha1.PromotionTask
+	0,   // 66: akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	181, // 67: akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse.promotion_task:type_name -> github.com.akuity.kargo.api.v1alpha1.PromotionTask
+	182, // 68: akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse.cluster_promotion_tasks:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
+	0,   // 69: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	182, // 70: akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse.promotion_task:type_name -> github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
+	183, // 71: akuity.io.kargo.service.v1alpha1.CreateRoleRequest.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	183, // 72: akuity.io.kargo.service.v1alpha1.CreateRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	0,   // 73: akuity.io.kargo.service.v1alpha1.GetRoleRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
+	183, // 74: akuity.io.kargo.service.v1alpha1.GetRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	184, // 75: akuity.io.kargo.service.v1alpha1.GetRoleResponse.resources:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
+	185, // 76: akuity.io.kargo.service.v1alpha1.Claims.claims:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Claim
+	152, // 77: akuity.io.kargo.service.v1alpha1.GrantRequest.user_claims:type_name -> akuity.io.kargo.service.v1alpha1.Claims
+	186, // 78: akuity.io.kargo.service.v1alpha1.GrantRequest.resource_details:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
+	183, // 79: akuity.io.kargo.service.v1alpha1.GrantResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	183, // 80: akuity.io.kargo.service.v1alpha1.ListRolesResponse.roles:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	184, // 81: akuity.io.kargo.service.v1alpha1.ListRolesResponse.resources:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
+	152, // 82: akuity.io.kargo.service.v1alpha1.RevokeRequest.user_claims:type_name -> akuity.io.kargo.service.v1alpha1.Claims
+	186, // 83: akuity.io.kargo.service.v1alpha1.RevokeRequest.resource_details:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
+	183, // 84: akuity.io.kargo.service.v1alpha1.RevokeResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	183, // 85: akuity.io.kargo.service.v1alpha1.UpdateRoleRequest.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	183, // 86: akuity.io.kargo.service.v1alpha1.UpdateRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
+	6,   // 87: akuity.io.kargo.service.v1alpha1.GetConfigResponse.ArgocdShardsEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.ArgoCDShard
+	29,  // 88: akuity.io.kargo.service.v1alpha1.ListImagesResponse.ImagesEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.TagMap
+	30,  // 89: akuity.io.kargo.service.v1alpha1.TagMap.TagsEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.ImageStageMap
+	85,  // 90: akuity.io.kargo.service.v1alpha1.QueryFreightResponse.GroupsEntry.value:type_name -> akuity.io.kargo.service.v1alpha1.FreightList
+	3,   // 91: akuity.io.kargo.service.v1alpha1.KargoService.GetVersionInfo:input_type -> akuity.io.kargo.service.v1alpha1.GetVersionInfoRequest
+	5,   // 92: akuity.io.kargo.service.v1alpha1.KargoService.GetConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetConfigRequest
+	8,   // 93: akuity.io.kargo.service.v1alpha1.KargoService.GetPublicConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetPublicConfigRequest
+	11,  // 94: akuity.io.kargo.service.v1alpha1.KargoService.AdminLogin:input_type -> akuity.io.kargo.service.v1alpha1.AdminLoginRequest
+	13,  // 95: akuity.io.kargo.service.v1alpha1.KargoService.CreateResource:input_type -> akuity.io.kargo.service.v1alpha1.CreateResourceRequest
+	16,  // 96: akuity.io.kargo.service.v1alpha1.KargoService.CreateOrUpdateResource:input_type -> akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceRequest
+	19,  // 97: akuity.io.kargo.service.v1alpha1.KargoService.UpdateResource:input_type -> akuity.io.kargo.service.v1alpha1.UpdateResourceRequest
+	22,  // 98: akuity.io.kargo.service.v1alpha1.KargoService.DeleteResource:input_type -> akuity.io.kargo.service.v1alpha1.DeleteResourceRequest
+	25,  // 99: akuity.io.kargo.service.v1alpha1.KargoService.ListStages:input_type -> akuity.io.kargo.service.v1alpha1.ListStagesRequest
+	27,  // 100: akuity.io.kargo.service.v1alpha1.KargoService.ListImages:input_type -> akuity.io.kargo.service.v1alpha1.ListImagesRequest
+	31,  // 101: akuity.io.kargo.service.v1alpha1.KargoService.GetStage:input_type -> akuity.io.kargo.service.v1alpha1.GetStageRequest
+	33,  // 102: akuity.io.kargo.service.v1alpha1.KargoService.WatchStages:input_type -> akuity.io.kargo.service.v1alpha1.WatchStagesRequest
+	35,  // 103: akuity.io.kargo.service.v1alpha1.KargoService.DeleteStage:input_type -> akuity.io.kargo.service.v1alpha1.DeleteStageRequest
+	37,  // 104: akuity.io.kargo.service.v1alpha1.KargoService.RefreshStage:input_type -> akuity.io.kargo.service.v1alpha1.RefreshStageRequest
+	39,  // 105: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetClusterConfigRequest
+	41,  // 106: akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterConfig:input_type -> akuity.io.kargo.service.v1alpha1.DeleteClusterConfigRequest
+	43,  // 107: akuity.io.kargo.service.v1alpha1.KargoService.WatchClusterConfig:input_type -> akuity.io.kargo.service.v1alpha1.WatchClusterConfigRequest
+	45,  // 108: akuity.io.kargo.service.v1alpha1.KargoService.RefreshClusterConfig:input_type -> akuity.io.kargo.service.v1alpha1.RefreshClusterConfigRequest
+	47,  // 109: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions:input_type -> akuity.io.kargo.service.v1alpha1.ListPromotionsRequest
+	49,  // 110: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotions:input_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionsRequest
+	51,  // 111: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotion:input_type -> akuity.io.kargo.service.v1alpha1.GetPromotionRequest
+	53,  // 112: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotion:input_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionRequest
+	55,  // 113: akuity.io.kargo.service.v1alpha1.KargoService.AbortPromotion:input_type -> akuity.io.kargo.service.v1alpha1.AbortPromotionRequest
+	57,  // 114: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProject:input_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectRequest
+	59,  // 115: akuity.io.kargo.service.v1alpha1.KargoService.GetProject:input_type -> akuity.io.kargo.service.v1alpha1.GetProjectRequest
+	61,  // 116: akuity.io.kargo.service.v1alpha1.KargoService.ListProjects:input_type -> akuity.io.kargo.service.v1alpha1.ListProjectsRequest
+	63,  // 117: akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig:input_type -> akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest
+	65,  // 118: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig:input_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest
+	67,  // 119: akuity.io.kargo.service.v1alpha1.KargoService.WatchProjectConfig:input_type -> akuity.io.kargo.service.v1alpha1.WatchProjectConfigRequest
+	69,  // 120: akuity.io.kargo.service.v1alpha1.KargoService.RefreshProjectConfig:input_type -> akuity.io.kargo.service.v1alpha1.RefreshProjectConfigRequest
+	71,  // 121: akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight:input_type -> akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
+	73,  // 122: akuity.io.kargo.service.v1alpha1.KargoService.DeleteFreight:input_type -> akuity.io.kargo.service.v1alpha1.DeleteFreightRequest
+	75,  // 123: akuity.io.kargo.service.v1alpha1.KargoService.GetFreight:input_type -> akuity.io.kargo.service.v1alpha1.GetFreightRequest
+	77,  // 124: akuity.io.kargo.service.v1alpha1.KargoService.WatchFreight:input_type -> akuity.io.kargo.service.v1alpha1.WatchFreightRequest
+	79,  // 125: akuity.io.kargo.service.v1alpha1.KargoService.PromoteToStage:input_type -> akuity.io.kargo.service.v1alpha1.PromoteToStageRequest
+	81,  // 126: akuity.io.kargo.service.v1alpha1.KargoService.PromoteDownstream:input_type -> akuity.io.kargo.service.v1alpha1.PromoteDownstreamRequest
+	83,  // 127: akuity.io.kargo.service.v1alpha1.KargoService.QueryFreight:input_type -> akuity.io.kargo.service.v1alpha1.QueryFreightRequest
+	86,  // 128: akuity.io.kargo.service.v1alpha1.KargoService.UpdateFreightAlias:input_type -> akuity.io.kargo.service.v1alpha1.UpdateFreightAliasRequest
+	88,  // 129: akuity.io.kargo.service.v1alpha1.KargoService.Reverify:input_type -> akuity.io.kargo.service.v1alpha1.ReverifyRequest
+	90,  // 130: akuity.io.kargo.service.v1alpha1.KargoService.AbortVerification:input_type -> akuity.io.kargo.service.v1alpha1.AbortVerificationRequest
+	92,  // 131: akuity.io.kargo.service.v1alpha1.KargoService.ListWarehouses:input_type -> akuity.io.kargo.service.v1alpha1.ListWarehousesRequest
+	94,  // 132: akuity.io.kargo.service.v1alpha1.KargoService.GetWarehouse:input_type -> akuity.io.kargo.service.v1alpha1.GetWarehouseRequest
+	96,  // 133: akuity.io.kargo.service.v1alpha1.KargoService.WatchWarehouses:input_type -> akuity.io.kargo.service.v1alpha1.WatchWarehousesRequest
+	98,  // 134: akuity.io.kargo.service.v1alpha1.KargoService.DeleteWarehouse:input_type -> akuity.io.kargo.service.v1alpha1.DeleteWarehouseRequest
+	100, // 135: akuity.io.kargo.service.v1alpha1.KargoService.RefreshWarehouse:input_type -> akuity.io.kargo.service.v1alpha1.RefreshWarehouseRequest
+	102, // 136: akuity.io.kargo.service.v1alpha1.KargoService.CreateCredentials:input_type -> akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
+	104, // 137: akuity.io.kargo.service.v1alpha1.KargoService.DeleteCredentials:input_type -> akuity.io.kargo.service.v1alpha1.DeleteCredentialsRequest
+	106, // 138: akuity.io.kargo.service.v1alpha1.KargoService.GetCredentials:input_type -> akuity.io.kargo.service.v1alpha1.GetCredentialsRequest
+	108, // 139: akuity.io.kargo.service.v1alpha1.KargoService.ListCredentials:input_type -> akuity.io.kargo.service.v1alpha1.ListCredentialsRequest
+	110, // 140: akuity.io.kargo.service.v1alpha1.KargoService.UpdateCredentials:input_type -> akuity.io.kargo.service.v1alpha1.UpdateCredentialsRequest
+	112, // 141: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectSecrets:input_type -> akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
+	114, // 142: akuity.io.kargo.service.v1alpha1.KargoService.CreateProjectSecret:input_type -> akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
+	116, // 143: akuity.io.kargo.service.v1alpha1.KargoService.UpdateProjectSecret:input_type -> akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
+	118, // 144: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectSecret:input_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
+	120, // 145: akuity.io.kargo.service.v1alpha1.KargoService.ListAnalysisTemplates:input_type -> akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
+	122, // 146: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
+	124, // 147: akuity.io.kargo.service.v1alpha1.KargoService.DeleteAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
+	126, // 148: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterAnalysisTemplates:input_type -> akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesRequest
+	128, // 149: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest
+	130, // 150: akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterAnalysisTemplate:input_type -> akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest
+	132, // 151: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRun:input_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest
+	134, // 152: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRunLogs:input_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsRequest
+	136, // 153: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectEvents:input_type -> akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
+	138, // 154: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotionTasks:input_type -> akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest
+	142, // 155: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterPromotionTasks:input_type -> akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest
+	140, // 156: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotionTask:input_type -> akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest
+	144, // 157: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterPromotionTask:input_type -> akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest
+	146, // 158: akuity.io.kargo.service.v1alpha1.KargoService.CreateRole:input_type -> akuity.io.kargo.service.v1alpha1.CreateRoleRequest
+	148, // 159: akuity.io.kargo.service.v1alpha1.KargoService.DeleteRole:input_type -> akuity.io.kargo.service.v1alpha1.DeleteRoleRequest
+	150, // 160: akuity.io.kargo.service.v1alpha1.KargoService.GetRole:input_type -> akuity.io.kargo.service.v1alpha1.GetRoleRequest
+	153, // 161: akuity.io.kargo.service.v1alpha1.KargoService.Grant:input_type -> akuity.io.kargo.service.v1alpha1.GrantRequest
+	155, // 162: akuity.io.kargo.service.v1alpha1.KargoService.ListRoles:input_type -> akuity.io.kargo.service.v1alpha1.ListRolesRequest
+	157, // 163: akuity.io.kargo.service.v1alpha1.KargoService.Revoke:input_type -> akuity.io.kargo.service.v1alpha1.RevokeRequest
+	159, // 164: akuity.io.kargo.service.v1alpha1.KargoService.UpdateRole:input_type -> akuity.io.kargo.service.v1alpha1.UpdateRoleRequest
+	4,   // 165: akuity.io.kargo.service.v1alpha1.KargoService.GetVersionInfo:output_type -> akuity.io.kargo.service.v1alpha1.GetVersionInfoResponse
+	7,   // 166: akuity.io.kargo.service.v1alpha1.KargoService.GetConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetConfigResponse
+	9,   // 167: akuity.io.kargo.service.v1alpha1.KargoService.GetPublicConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetPublicConfigResponse
+	12,  // 168: akuity.io.kargo.service.v1alpha1.KargoService.AdminLogin:output_type -> akuity.io.kargo.service.v1alpha1.AdminLoginResponse
+	15,  // 169: akuity.io.kargo.service.v1alpha1.KargoService.CreateResource:output_type -> akuity.io.kargo.service.v1alpha1.CreateResourceResponse
+	18,  // 170: akuity.io.kargo.service.v1alpha1.KargoService.CreateOrUpdateResource:output_type -> akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceResponse
+	21,  // 171: akuity.io.kargo.service.v1alpha1.KargoService.UpdateResource:output_type -> akuity.io.kargo.service.v1alpha1.UpdateResourceResponse
+	24,  // 172: akuity.io.kargo.service.v1alpha1.KargoService.DeleteResource:output_type -> akuity.io.kargo.service.v1alpha1.DeleteResourceResponse
+	26,  // 173: akuity.io.kargo.service.v1alpha1.KargoService.ListStages:output_type -> akuity.io.kargo.service.v1alpha1.ListStagesResponse
+	28,  // 174: akuity.io.kargo.service.v1alpha1.KargoService.ListImages:output_type -> akuity.io.kargo.service.v1alpha1.ListImagesResponse
+	32,  // 175: akuity.io.kargo.service.v1alpha1.KargoService.GetStage:output_type -> akuity.io.kargo.service.v1alpha1.GetStageResponse
+	34,  // 176: akuity.io.kargo.service.v1alpha1.KargoService.WatchStages:output_type -> akuity.io.kargo.service.v1alpha1.WatchStagesResponse
+	36,  // 177: akuity.io.kargo.service.v1alpha1.KargoService.DeleteStage:output_type -> akuity.io.kargo.service.v1alpha1.DeleteStageResponse
+	38,  // 178: akuity.io.kargo.service.v1alpha1.KargoService.RefreshStage:output_type -> akuity.io.kargo.service.v1alpha1.RefreshStageResponse
+	40,  // 179: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse
+	42,  // 180: akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterConfig:output_type -> akuity.io.kargo.service.v1alpha1.DeleteClusterConfigResponse
+	44,  // 181: akuity.io.kargo.service.v1alpha1.KargoService.WatchClusterConfig:output_type -> akuity.io.kargo.service.v1alpha1.WatchClusterConfigResponse
+	46,  // 182: akuity.io.kargo.service.v1alpha1.KargoService.RefreshClusterConfig:output_type -> akuity.io.kargo.service.v1alpha1.RefreshClusterConfigResponse
+	48,  // 183: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions:output_type -> akuity.io.kargo.service.v1alpha1.ListPromotionsResponse
+	50,  // 184: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotions:output_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse
+	52,  // 185: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotion:output_type -> akuity.io.kargo.service.v1alpha1.GetPromotionResponse
+	54,  // 186: akuity.io.kargo.service.v1alpha1.KargoService.WatchPromotion:output_type -> akuity.io.kargo.service.v1alpha1.WatchPromotionResponse
+	56,  // 187: akuity.io.kargo.service.v1alpha1.KargoService.AbortPromotion:output_type -> akuity.io.kargo.service.v1alpha1.AbortPromotionResponse
+	58,  // 188: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProject:output_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectResponse
+	60,  // 189: akuity.io.kargo.service.v1alpha1.KargoService.GetProject:output_type -> akuity.io.kargo.service.v1alpha1.GetProjectResponse
+	62,  // 190: akuity.io.kargo.service.v1alpha1.KargoService.ListProjects:output_type -> akuity.io.kargo.service.v1alpha1.ListProjectsResponse
+	64,  // 191: akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig:output_type -> akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse
+	66,  // 192: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig:output_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse
+	68,  // 193: akuity.io.kargo.service.v1alpha1.KargoService.WatchProjectConfig:output_type -> akuity.io.kargo.service.v1alpha1.WatchProjectConfigResponse
+	70,  // 194: akuity.io.kargo.service.v1alpha1.KargoService.RefreshProjectConfig:output_type -> akuity.io.kargo.service.v1alpha1.RefreshProjectConfigResponse
+	72,  // 195: akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight:output_type -> akuity.io.kargo.service.v1alpha1.ApproveFreightResponse
+	74,  // 196: akuity.io.kargo.service.v1alpha1.KargoService.DeleteFreight:output_type -> akuity.io.kargo.service.v1alpha1.DeleteFreightResponse
+	76,  // 197: akuity.io.kargo.service.v1alpha1.KargoService.GetFreight:output_type -> akuity.io.kargo.service.v1alpha1.GetFreightResponse
+	78,  // 198: akuity.io.kargo.service.v1alpha1.KargoService.WatchFreight:output_type -> akuity.io.kargo.service.v1alpha1.WatchFreightResponse
+	80,  // 199: akuity.io.kargo.service.v1alpha1.KargoService.PromoteToStage:output_type -> akuity.io.kargo.service.v1alpha1.PromoteToStageResponse
+	82,  // 200: akuity.io.kargo.service.v1alpha1.KargoService.PromoteDownstream:output_type -> akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse
+	84,  // 201: akuity.io.kargo.service.v1alpha1.KargoService.QueryFreight:output_type -> akuity.io.kargo.service.v1alpha1.QueryFreightResponse
+	87,  // 202: akuity.io.kargo.service.v1alpha1.KargoService.UpdateFreightAlias:output_type -> akuity.io.kargo.service.v1alpha1.UpdateFreightAliasResponse
+	89,  // 203: akuity.io.kargo.service.v1alpha1.KargoService.Reverify:output_type -> akuity.io.kargo.service.v1alpha1.ReverifyResponse
+	91,  // 204: akuity.io.kargo.service.v1alpha1.KargoService.AbortVerification:output_type -> akuity.io.kargo.service.v1alpha1.AbortVerificationResponse
+	93,  // 205: akuity.io.kargo.service.v1alpha1.KargoService.ListWarehouses:output_type -> akuity.io.kargo.service.v1alpha1.ListWarehousesResponse
+	95,  // 206: akuity.io.kargo.service.v1alpha1.KargoService.GetWarehouse:output_type -> akuity.io.kargo.service.v1alpha1.GetWarehouseResponse
+	97,  // 207: akuity.io.kargo.service.v1alpha1.KargoService.WatchWarehouses:output_type -> akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse
+	99,  // 208: akuity.io.kargo.service.v1alpha1.KargoService.DeleteWarehouse:output_type -> akuity.io.kargo.service.v1alpha1.DeleteWarehouseResponse
+	101, // 209: akuity.io.kargo.service.v1alpha1.KargoService.RefreshWarehouse:output_type -> akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse
+	103, // 210: akuity.io.kargo.service.v1alpha1.KargoService.CreateCredentials:output_type -> akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
+	105, // 211: akuity.io.kargo.service.v1alpha1.KargoService.DeleteCredentials:output_type -> akuity.io.kargo.service.v1alpha1.DeleteCredentialsResponse
+	107, // 212: akuity.io.kargo.service.v1alpha1.KargoService.GetCredentials:output_type -> akuity.io.kargo.service.v1alpha1.GetCredentialsResponse
+	109, // 213: akuity.io.kargo.service.v1alpha1.KargoService.ListCredentials:output_type -> akuity.io.kargo.service.v1alpha1.ListCredentialsResponse
+	111, // 214: akuity.io.kargo.service.v1alpha1.KargoService.UpdateCredentials:output_type -> akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse
+	113, // 215: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectSecrets:output_type -> akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
+	115, // 216: akuity.io.kargo.service.v1alpha1.KargoService.CreateProjectSecret:output_type -> akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
+	117, // 217: akuity.io.kargo.service.v1alpha1.KargoService.UpdateProjectSecret:output_type -> akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
+	119, // 218: akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectSecret:output_type -> akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse
+	121, // 219: akuity.io.kargo.service.v1alpha1.KargoService.ListAnalysisTemplates:output_type -> akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
+	123, // 220: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
+	125, // 221: akuity.io.kargo.service.v1alpha1.KargoService.DeleteAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse
+	127, // 222: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterAnalysisTemplates:output_type -> akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse
+	129, // 223: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse
+	131, // 224: akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterAnalysisTemplate:output_type -> akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse
+	133, // 225: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRun:output_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse
+	135, // 226: akuity.io.kargo.service.v1alpha1.KargoService.GetAnalysisRunLogs:output_type -> akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsResponse
+	137, // 227: akuity.io.kargo.service.v1alpha1.KargoService.ListProjectEvents:output_type -> akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
+	139, // 228: akuity.io.kargo.service.v1alpha1.KargoService.ListPromotionTasks:output_type -> akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse
+	143, // 229: akuity.io.kargo.service.v1alpha1.KargoService.ListClusterPromotionTasks:output_type -> akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse
+	141, // 230: akuity.io.kargo.service.v1alpha1.KargoService.GetPromotionTask:output_type -> akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse
+	145, // 231: akuity.io.kargo.service.v1alpha1.KargoService.GetClusterPromotionTask:output_type -> akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse
+	147, // 232: akuity.io.kargo.service.v1alpha1.KargoService.CreateRole:output_type -> akuity.io.kargo.service.v1alpha1.CreateRoleResponse
+	149, // 233: akuity.io.kargo.service.v1alpha1.KargoService.DeleteRole:output_type -> akuity.io.kargo.service.v1alpha1.DeleteRoleResponse
+	151, // 234: akuity.io.kargo.service.v1alpha1.KargoService.GetRole:output_type -> akuity.io.kargo.service.v1alpha1.GetRoleResponse
+	154, // 235: akuity.io.kargo.service.v1alpha1.KargoService.Grant:output_type -> akuity.io.kargo.service.v1alpha1.GrantResponse
+	156, // 236: akuity.io.kargo.service.v1alpha1.KargoService.ListRoles:output_type -> akuity.io.kargo.service.v1alpha1.ListRolesResponse
+	158, // 237: akuity.io.kargo.service.v1alpha1.KargoService.Revoke:output_type -> akuity.io.kargo.service.v1alpha1.RevokeResponse
+	160, // 238: akuity.io.kargo.service.v1alpha1.KargoService.UpdateRole:output_type -> akuity.io.kargo.service.v1alpha1.UpdateRoleResponse
+	165, // [165:239] is the sub-list for method output_type
+	91,  // [91:165] is the sub-list for method input_type
+	91,  // [91:91] is the sub-list for extension type_name
+	91,  // [91:91] is the sub-list for extension extendee
+	0,   // [0:91] is the sub-list for field type_name
 }
 
 func init() { file_api_service_v1alpha1_service_proto_init() }
@@ -10918,7 +11647,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListPromotionsRequest); i {
+			switch v := v.(*GetClusterConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -10930,7 +11659,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListPromotionsResponse); i {
+			switch v := v.(*GetClusterConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -10942,7 +11671,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*WatchPromotionsRequest); i {
+			switch v := v.(*DeleteClusterConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -10954,7 +11683,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*WatchPromotionsResponse); i {
+			switch v := v.(*DeleteClusterConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -10966,7 +11695,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetPromotionRequest); i {
+			switch v := v.(*WatchClusterConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -10978,7 +11707,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetPromotionResponse); i {
+			switch v := v.(*WatchClusterConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -10990,7 +11719,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*WatchPromotionRequest); i {
+			switch v := v.(*RefreshClusterConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11002,7 +11731,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*WatchPromotionResponse); i {
+			switch v := v.(*RefreshClusterConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11014,7 +11743,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AbortPromotionRequest); i {
+			switch v := v.(*ListPromotionsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11026,7 +11755,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AbortPromotionResponse); i {
+			switch v := v.(*ListPromotionsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11038,7 +11767,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteProjectRequest); i {
+			switch v := v.(*WatchPromotionsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11050,7 +11779,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteProjectResponse); i {
+			switch v := v.(*WatchPromotionsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11062,7 +11791,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteProjectConfigRequest); i {
+			switch v := v.(*GetPromotionRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11074,7 +11803,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteProjectConfigResponse); i {
+			switch v := v.(*GetPromotionResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11086,7 +11815,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetProjectConfigRequest); i {
+			switch v := v.(*WatchPromotionRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11098,7 +11827,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetProjectConfigResponse); i {
+			switch v := v.(*WatchPromotionResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11110,7 +11839,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetProjectRequest); i {
+			switch v := v.(*AbortPromotionRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11122,7 +11851,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetProjectResponse); i {
+			switch v := v.(*AbortPromotionResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11134,7 +11863,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListProjectsRequest); i {
+			switch v := v.(*DeleteProjectRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11146,7 +11875,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListProjectsResponse); i {
+			switch v := v.(*DeleteProjectResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11158,7 +11887,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApproveFreightRequest); i {
+			switch v := v.(*GetProjectRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11170,7 +11899,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApproveFreightResponse); i {
+			switch v := v.(*GetProjectResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11182,7 +11911,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteFreightRequest); i {
+			switch v := v.(*ListProjectsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11194,7 +11923,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteFreightResponse); i {
+			switch v := v.(*ListProjectsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11206,7 +11935,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetFreightRequest); i {
+			switch v := v.(*GetProjectConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11218,7 +11947,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetFreightResponse); i {
+			switch v := v.(*GetProjectConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11230,7 +11959,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*WatchFreightRequest); i {
+			switch v := v.(*DeleteProjectConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11242,7 +11971,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*WatchFreightResponse); i {
+			switch v := v.(*DeleteProjectConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11254,7 +11983,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PromoteToStageRequest); i {
+			switch v := v.(*WatchProjectConfigRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11266,7 +11995,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PromoteToStageResponse); i {
+			switch v := v.(*WatchProjectConfigResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11278,6 +12007,150 @@ func file_api_service_v1alpha1_service_proto_init() {
 			}
 		}
 		file_api_service_v1alpha1_service_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RefreshProjectConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RefreshProjectConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ApproveFreightRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ApproveFreightResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteFreightRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteFreightResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetFreightRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetFreightResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*WatchFreightRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*WatchFreightResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PromoteToStageRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PromoteToStageResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_service_v1alpha1_service_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PromoteDownstreamRequest); i {
 			case 0:
 				return &v.state
@@ -11289,7 +12162,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PromoteDownstreamResponse); i {
 			case 0:
 				return &v.state
@@ -11301,7 +12174,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*QueryFreightRequest); i {
 			case 0:
 				return &v.state
@@ -11313,7 +12186,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*QueryFreightResponse); i {
 			case 0:
 				return &v.state
@@ -11325,7 +12198,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FreightList); i {
 			case 0:
 				return &v.state
@@ -11337,7 +12210,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateFreightAliasRequest); i {
 			case 0:
 				return &v.state
@@ -11349,7 +12222,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateFreightAliasResponse); i {
 			case 0:
 				return &v.state
@@ -11361,7 +12234,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ReverifyRequest); i {
 			case 0:
 				return &v.state
@@ -11373,7 +12246,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ReverifyResponse); i {
 			case 0:
 				return &v.state
@@ -11385,7 +12258,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AbortVerificationRequest); i {
 			case 0:
 				return &v.state
@@ -11397,7 +12270,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AbortVerificationResponse); i {
 			case 0:
 				return &v.state
@@ -11409,7 +12282,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListWarehousesRequest); i {
 			case 0:
 				return &v.state
@@ -11421,7 +12294,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListWarehousesResponse); i {
 			case 0:
 				return &v.state
@@ -11433,7 +12306,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetWarehouseRequest); i {
 			case 0:
 				return &v.state
@@ -11445,7 +12318,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetWarehouseResponse); i {
 			case 0:
 				return &v.state
@@ -11457,7 +12330,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchWarehousesRequest); i {
 			case 0:
 				return &v.state
@@ -11469,7 +12342,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchWarehousesResponse); i {
 			case 0:
 				return &v.state
@@ -11481,7 +12354,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[97].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteWarehouseRequest); i {
 			case 0:
 				return &v.state
@@ -11493,7 +12366,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[98].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteWarehouseResponse); i {
 			case 0:
 				return &v.state
@@ -11505,7 +12378,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RefreshWarehouseRequest); i {
 			case 0:
 				return &v.state
@@ -11517,7 +12390,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RefreshWarehouseResponse); i {
 			case 0:
 				return &v.state
@@ -11529,8 +12402,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListProjectSecretsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateCredentialsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11541,8 +12414,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListProjectSecretsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateCredentialsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11553,8 +12426,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*CreateProjectSecretRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteCredentialsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11565,8 +12438,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*CreateProjectSecretResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteCredentialsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11577,8 +12450,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*UpdateProjectSecretRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetCredentialsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11589,8 +12462,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*UpdateProjectSecretResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetCredentialsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11601,8 +12474,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteProjectSecretRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListCredentialsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11613,8 +12486,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteProjectSecretResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListCredentialsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11625,8 +12498,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[97].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*CreateCredentialsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateCredentialsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11637,8 +12510,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[98].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*CreateCredentialsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateCredentialsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11649,8 +12522,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteCredentialsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListProjectSecretsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11661,8 +12534,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteCredentialsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListProjectSecretsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11673,8 +12546,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetCredentialsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateProjectSecretRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11685,8 +12558,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetCredentialsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateProjectSecretResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11697,8 +12570,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListCredentialsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateProjectSecretRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11709,8 +12582,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListCredentialsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateProjectSecretResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11721,8 +12594,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*UpdateCredentialsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteProjectSecretRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11733,8 +12606,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*UpdateCredentialsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteProjectSecretResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11745,7 +12618,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[119].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListAnalysisTemplatesRequest); i {
 			case 0:
 				return &v.state
@@ -11757,7 +12630,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[120].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListAnalysisTemplatesResponse); i {
 			case 0:
 				return &v.state
@@ -11769,8 +12642,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListPromotionTasksRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11781,8 +12654,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListPromotionTasksResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11793,8 +12666,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListClusterPromotionTasksRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11805,8 +12678,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListClusterPromotionTasksResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11817,8 +12690,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetAnalysisTemplateRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[125].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListClusterAnalysisTemplatesRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11829,8 +12702,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetAnalysisTemplateResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[126].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListClusterAnalysisTemplatesResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11841,8 +12714,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetPromotionTaskRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[127].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetClusterAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11853,8 +12726,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetPromotionTaskResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[128].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetClusterAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11865,8 +12738,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetClusterPromotionTaskRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[129].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteClusterAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11877,8 +12750,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetClusterPromotionTaskResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteClusterAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11889,8 +12762,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[119].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListClusterAnalysisTemplatesRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[131].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAnalysisRunRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11901,8 +12774,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[120].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListClusterAnalysisTemplatesResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[132].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAnalysisRunResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11913,8 +12786,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetClusterAnalysisTemplateRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[133].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAnalysisRunLogsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11925,8 +12798,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetClusterAnalysisTemplateResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[134].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAnalysisRunLogsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11937,8 +12810,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetAnalysisRunRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[135].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListProjectEventsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11949,8 +12822,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetAnalysisRunResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[136].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListProjectEventsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11961,8 +12834,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[125].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetAnalysisRunLogsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[137].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListPromotionTasksRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11973,8 +12846,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[126].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetAnalysisRunLogsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[138].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListPromotionTasksResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11985,8 +12858,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[127].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteAnalysisTemplateRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[139].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetPromotionTaskRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -11997,8 +12870,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[128].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteAnalysisTemplateResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[140].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetPromotionTaskResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -12009,8 +12882,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[129].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteClusterAnalysisTemplateRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[141].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListClusterPromotionTasksRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -12021,8 +12894,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DeleteClusterAnalysisTemplateResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[142].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListClusterPromotionTasksResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -12033,8 +12906,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[131].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListProjectEventsRequest); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[143].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetClusterPromotionTaskRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -12045,8 +12918,8 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[132].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ListProjectEventsResponse); i {
+		file_api_service_v1alpha1_service_proto_msgTypes[144].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetClusterPromotionTaskResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -12057,7 +12930,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[133].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[145].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateRoleRequest); i {
 			case 0:
 				return &v.state
@@ -12069,7 +12942,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[134].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[146].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateRoleResponse); i {
 			case 0:
 				return &v.state
@@ -12081,7 +12954,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[135].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[147].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteRoleRequest); i {
 			case 0:
 				return &v.state
@@ -12093,7 +12966,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[136].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[148].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteRoleResponse); i {
 			case 0:
 				return &v.state
@@ -12105,7 +12978,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[137].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[149].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetRoleRequest); i {
 			case 0:
 				return &v.state
@@ -12117,7 +12990,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[138].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[150].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetRoleResponse); i {
 			case 0:
 				return &v.state
@@ -12129,7 +13002,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[139].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[151].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Claims); i {
 			case 0:
 				return &v.state
@@ -12141,7 +13014,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[140].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[152].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GrantRequest); i {
 			case 0:
 				return &v.state
@@ -12153,7 +13026,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[141].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[153].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GrantResponse); i {
 			case 0:
 				return &v.state
@@ -12165,7 +13038,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[142].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[154].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListRolesRequest); i {
 			case 0:
 				return &v.state
@@ -12177,7 +13050,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[143].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[155].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListRolesResponse); i {
 			case 0:
 				return &v.state
@@ -12189,7 +13062,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[144].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[156].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RevokeRequest); i {
 			case 0:
 				return &v.state
@@ -12201,7 +13074,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[145].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[157].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RevokeResponse); i {
 			case 0:
 				return &v.state
@@ -12213,7 +13086,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[146].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[158].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateRoleRequest); i {
 			case 0:
 				return &v.state
@@ -12225,7 +13098,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_api_service_v1alpha1_service_proto_msgTypes[147].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[159].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateRoleResponse); i {
 			case 0:
 				return &v.state
@@ -12260,63 +13133,67 @@ func file_api_service_v1alpha1_service_proto_init() {
 		(*GetStageResponse_Stage)(nil),
 		(*GetStageResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[38].OneofWrappers = []interface{}{}
-	file_api_service_v1alpha1_service_proto_msgTypes[40].OneofWrappers = []interface{}{}
-	file_api_service_v1alpha1_service_proto_msgTypes[43].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[39].OneofWrappers = []interface{}{
+		(*GetClusterConfigResponse_ClusterConfig)(nil),
+		(*GetClusterConfigResponse_Raw)(nil),
+	}
+	file_api_service_v1alpha1_service_proto_msgTypes[46].OneofWrappers = []interface{}{}
+	file_api_service_v1alpha1_service_proto_msgTypes[48].OneofWrappers = []interface{}{}
+	file_api_service_v1alpha1_service_proto_msgTypes[51].OneofWrappers = []interface{}{
 		(*GetPromotionResponse_Promotion)(nil),
 		(*GetPromotionResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[53].OneofWrappers = []interface{}{
-		(*GetProjectConfigResponse_ProjectConfig)(nil),
-		(*GetProjectConfigResponse_Raw)(nil),
-	}
-	file_api_service_v1alpha1_service_proto_msgTypes[55].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[59].OneofWrappers = []interface{}{
 		(*GetProjectResponse_Project)(nil),
 		(*GetProjectResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[56].OneofWrappers = []interface{}{}
+	file_api_service_v1alpha1_service_proto_msgTypes[60].OneofWrappers = []interface{}{}
 	file_api_service_v1alpha1_service_proto_msgTypes[63].OneofWrappers = []interface{}{
+		(*GetProjectConfigResponse_ProjectConfig)(nil),
+		(*GetProjectConfigResponse_Raw)(nil),
+	}
+	file_api_service_v1alpha1_service_proto_msgTypes[75].OneofWrappers = []interface{}{
 		(*GetFreightResponse_Freight)(nil),
 		(*GetFreightResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[82].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[94].OneofWrappers = []interface{}{
 		(*GetWarehouseResponse_Warehouse)(nil),
 		(*GetWarehouseResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[102].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[106].OneofWrappers = []interface{}{
 		(*GetCredentialsResponse_Credentials)(nil),
 		(*GetCredentialsResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[114].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[122].OneofWrappers = []interface{}{
 		(*GetAnalysisTemplateResponse_AnalysisTemplate)(nil),
 		(*GetAnalysisTemplateResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[116].OneofWrappers = []interface{}{
-		(*GetPromotionTaskResponse_PromotionTask)(nil),
-		(*GetPromotionTaskResponse_Raw)(nil),
-	}
-	file_api_service_v1alpha1_service_proto_msgTypes[118].OneofWrappers = []interface{}{
-		(*GetClusterPromotionTaskResponse_PromotionTask)(nil),
-		(*GetClusterPromotionTaskResponse_Raw)(nil),
-	}
-	file_api_service_v1alpha1_service_proto_msgTypes[122].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[128].OneofWrappers = []interface{}{
 		(*GetClusterAnalysisTemplateResponse_ClusterAnalysisTemplate)(nil),
 		(*GetClusterAnalysisTemplateResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[124].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[132].OneofWrappers = []interface{}{
 		(*GetAnalysisRunResponse_AnalysisRun)(nil),
 		(*GetAnalysisRunResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[138].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[140].OneofWrappers = []interface{}{
+		(*GetPromotionTaskResponse_PromotionTask)(nil),
+		(*GetPromotionTaskResponse_Raw)(nil),
+	}
+	file_api_service_v1alpha1_service_proto_msgTypes[144].OneofWrappers = []interface{}{
+		(*GetClusterPromotionTaskResponse_PromotionTask)(nil),
+		(*GetClusterPromotionTaskResponse_Raw)(nil),
+	}
+	file_api_service_v1alpha1_service_proto_msgTypes[150].OneofWrappers = []interface{}{
 		(*GetRoleResponse_Role)(nil),
 		(*GetRoleResponse_Resources)(nil),
 		(*GetRoleResponse_Raw)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[140].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[152].OneofWrappers = []interface{}{
 		(*GrantRequest_UserClaims)(nil),
 		(*GrantRequest_ResourceDetails)(nil),
 	}
-	file_api_service_v1alpha1_service_proto_msgTypes[144].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[156].OneofWrappers = []interface{}{
 		(*RevokeRequest_UserClaims)(nil),
 		(*RevokeRequest_ResourceDetails)(nil),
 	}
@@ -12326,7 +13203,7 @@ func file_api_service_v1alpha1_service_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_api_service_v1alpha1_service_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   155,
+			NumMessages:   167,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/api/service/v1alpha1/service.proto b/api/service/v1alpha1/service.proto
index a421a0a5..75bc734e 100644
--- a/api/service/v1alpha1/service.proto
+++ b/api/service/v1alpha1/service.proto
@@ -40,6 +40,13 @@ service KargoService {
   rpc DeleteStage(DeleteStageRequest) returns (DeleteStageResponse);
   rpc RefreshStage(RefreshStageRequest) returns (RefreshStageResponse);
 
+  /* ClusterConfig APIs */
+
+  rpc GetClusterConfig(GetClusterConfigRequest) returns (GetClusterConfigResponse);
+  rpc DeleteClusterConfig(DeleteClusterConfigRequest) returns (DeleteClusterConfigResponse);
+  rpc WatchClusterConfig(WatchClusterConfigRequest) returns (stream WatchClusterConfigResponse);
+  rpc RefreshClusterConfig(RefreshClusterConfigRequest) returns (RefreshClusterConfigResponse);
+
   /* Promotion APIs */
 
   rpc ListPromotions(ListPromotionsRequest) returns (ListPromotionsResponse);
@@ -53,8 +60,12 @@ service KargoService {
   rpc DeleteProject(DeleteProjectRequest) returns (DeleteProjectResponse);
   rpc GetProject(GetProjectRequest) returns (GetProjectResponse);
   rpc ListProjects(ListProjectsRequest) returns (ListProjectsResponse);
-  rpc DeleteProjectConfig(DeleteProjectConfigRequest) returns (DeleteProjectConfigResponse);
+
+  /* ProjectConfig APIs */
   rpc GetProjectConfig(GetProjectConfigRequest) returns (GetProjectConfigResponse);
+  rpc DeleteProjectConfig(DeleteProjectConfigRequest) returns (DeleteProjectConfigResponse);
+  rpc WatchProjectConfig(WatchProjectConfigRequest) returns (stream WatchProjectConfigResponse);
+  rpc RefreshProjectConfig(RefreshProjectConfigRequest) returns (RefreshProjectConfigResponse);
 
   /* Freight APIs */
 
@@ -128,6 +139,8 @@ service KargoService {
   rpc UpdateRole(UpdateRoleRequest) returns (UpdateRoleResponse);
 }
 
+/* Version and Configuration Messages */
+
 message ComponentVersions {
   optional VersionInfo server = 1;
   optional VersionInfo cli = 2;
@@ -184,6 +197,8 @@ message AdminLoginResponse {
   string id_token = 1;
 }
 
+/* Resource Management Messages */
+
 message CreateResourceRequest {
   bytes manifest = 1;
 }
@@ -245,6 +260,8 @@ message DeleteResourceResponse {
   repeated DeleteResourceResult results = 1;
 }
 
+/* Stage Messages */
+
 message ListStagesRequest {
   string project = 1;
 }
@@ -313,6 +330,46 @@ message RefreshStageResponse {
   github.com.akuity.kargo.api.v1alpha1.Stage stage = 1;
 }
 
+/* ClusterConfig Messages */
+
+message GetClusterConfigRequest {
+  RawFormat format = 1;
+}
+
+message GetClusterConfigResponse {
+  oneof result {
+    github.com.akuity.kargo.api.v1alpha1.ClusterConfig cluster_config = 1;
+    bytes raw = 2;
+  }
+}
+
+message DeleteClusterConfigRequest {
+  /* explicitly empty */
+}
+
+message DeleteClusterConfigResponse {
+  /* explicitly empty */
+}
+
+message WatchClusterConfigRequest {
+  /* explicitly empty */
+}
+
+message WatchClusterConfigResponse {
+  github.com.akuity.kargo.api.v1alpha1.ClusterConfig cluster_config = 1;
+  string type = 2; // ADDED / MODIFIED / DELETED
+}
+
+message RefreshClusterConfigRequest {
+  /* explicitly empty */
+}
+
+message RefreshClusterConfigResponse {
+  github.com.akuity.kargo.api.v1alpha1.ClusterConfig cluster_config = 1;
+}
+
+/* Promotion Messages */
+
 message ListPromotionsRequest {
   string project = 1;
   optional string stage = 2;
@@ -364,6 +421,8 @@ message AbortPromotionResponse {
   /* explicitly empty */
 }
 
+/* Project Messages */
+
 message DeleteProjectRequest {
   string name = 1;
 }
@@ -372,16 +431,33 @@ message DeleteProjectResponse {
   /* explicitly empty */
 }
 
-message DeleteProjectConfigRequest {
+message GetProjectRequest {
   string name = 1;
+  RawFormat format = 2;
 }
 
-message DeleteProjectConfigResponse {
-  /* explicitly empty */
+message GetProjectResponse {
+  oneof result {
+    github.com.akuity.kargo.api.v1alpha1.Project project = 1;
+    bytes raw = 2;
+  }
+}
+
+message ListProjectsRequest {
+  optional int32 page_size = 1;
+  optional int32 page = 2;
+  optional string filter = 3;
 }
 
+message ListProjectsResponse {
+  repeated github.com.akuity.kargo.api.v1alpha1.Project projects = 1;
+  int32 total = 2;
+}
+
+/* ProjectConfig Messages */
+
 message GetProjectConfigRequest {
-  string name = 1;
+  string project = 1;
   RawFormat format = 2;
 }
 
@@ -392,29 +468,33 @@ message GetProjectConfigResponse {
   }
 }
 
-message GetProjectRequest {
-  string name = 1;
-  RawFormat format = 2;
+message DeleteProjectConfigRequest {
+  string project = 1;
 }
 
-message GetProjectResponse {
-  oneof result {
-    github.com.akuity.kargo.api.v1alpha1.Project project = 1;
-    bytes raw = 2;
-  }
+message DeleteProjectConfigResponse {
+  /* explicitly empty */
 }
 
-message ListProjectsRequest {
-  optional int32 page_size = 1;
-  optional int32 page = 2;
-  optional string filter = 3;
+message WatchProjectConfigRequest {
+  string project = 1;
 }
 
-message ListProjectsResponse {
-  repeated github.com.akuity.kargo.api.v1alpha1.Project projects = 1;
-  int32 total = 2;
+message WatchProjectConfigResponse {
+  github.com.akuity.kargo.api.v1alpha1.ProjectConfig project_config = 1;
+  string type = 2; // ADDED / MODIFIED / DELETED
+}
+
+message RefreshProjectConfigRequest {
+  string project = 1;
+}
+
+message RefreshProjectConfigResponse {
+  github.com.akuity.kargo.api.v1alpha1.ProjectConfig project_config = 1;
 }
 
+/* Freight Messages */
+
 message ApproveFreightRequest {
   string project = 1;
   string name = 2;
@@ -510,6 +590,8 @@ message UpdateFreightAliasResponse {
   /* explicitly empty */
 }
 
+/* Verification Messages */
+
 message ReverifyRequest {
   string project = 1;
   string stage = 2;
@@ -528,6 +610,8 @@ message AbortVerificationResponse {
   /* explicitly empty */
 }
 
+/* Warehouse Messages */
+
 message ListWarehousesRequest {
   string project = 1;
 }
@@ -577,44 +661,7 @@ message RefreshWarehouseResponse {
   github.com.akuity.kargo.api.v1alpha1.Warehouse warehouse = 1;
 }
 
-message ListProjectSecretsRequest {
-  string project = 1;
-}
-
-message ListProjectSecretsResponse {
-  repeated k8s.io.api.core.v1.Secret secrets = 1;
-}
-
-message CreateProjectSecretRequest {
-  string project = 1;
-  string name = 2;
-  string description = 3;
-  map<string, string> data = 4;
-}
-
-message CreateProjectSecretResponse {
-  k8s.io.api.core.v1.Secret secret = 1;
-}
-
-message UpdateProjectSecretRequest {
-  string project = 1;
-  string name = 2;
-  string description = 3;
-  map<string, string> data = 4;
-}
-
-message UpdateProjectSecretResponse {
-  k8s.io.api.core.v1.Secret secret = 1;
-}
-
-message DeleteProjectSecretRequest {
-  string project = 1;
-  string name = 2;
-}
-
-message DeleteProjectSecretResponse {
-  /* explicitly empty */
-}
+/* Credential Messages */
 
 message CreateCredentialsRequest {
   string project = 1;
@@ -677,64 +724,77 @@ message UpdateCredentialsResponse {
   k8s.io.api.core.v1.Secret credentials = 1;
 }
 
-message ListAnalysisTemplatesRequest {
+/* Project Secrets Messages */
+
+message ListProjectSecretsRequest {
   string project = 1;
 }
 
-message ListAnalysisTemplatesResponse {
-  repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_templates = 1 [json_name = "analysisTemplates"];
+message ListProjectSecretsResponse {
+  repeated k8s.io.api.core.v1.Secret secrets = 1;
 }
 
-message ListPromotionTasksRequest {
+message CreateProjectSecretRequest {
   string project = 1;
+  string name = 2;
+  string description = 3;
+  map<string, string> data = 4;
 }
 
-message ListPromotionTasksResponse {
-  repeated github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_tasks = 1;
+message CreateProjectSecretResponse {
+  k8s.io.api.core.v1.Secret secret = 1;
 }
 
-message ListClusterPromotionTasksRequest {}
+message UpdateProjectSecretRequest {
+  string project = 1;
+  string name = 2;
+  string description = 3;
+  map<string, string> data = 4;
+}
 
-message ListClusterPromotionTasksResponse {
-  repeated github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask cluster_promotion_tasks = 1;
+message UpdateProjectSecretResponse {
+  k8s.io.api.core.v1.Secret secret = 1;
 }
 
-message GetAnalysisTemplateRequest {
+message DeleteProjectSecretRequest {
   string project = 1;
   string name = 2;
-  RawFormat format = 3;
 }
 
-message GetAnalysisTemplateResponse {
-  oneof result {
-    github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_template = 1 [json_name = "analysisTemplate"];
-    bytes raw = 2;
-  }
+message DeleteProjectSecretResponse {
+  /* explicitly empty */
 }
 
-message GetPromotionTaskRequest {
+/* Analysis Messages */
+
+message ListAnalysisTemplatesRequest {
+  string project = 1;
+}
+
+message ListAnalysisTemplatesResponse {
+  repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_templates = 1 [json_name = "analysisTemplates"];
+}
+
+message GetAnalysisTemplateRequest {
   string project = 1;
   string name = 2;
   RawFormat format = 3;
 }
 
-message GetPromotionTaskResponse {
+message GetAnalysisTemplateResponse {
   oneof result {
-    github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_task = 1 [json_name = "promotionTask"];
+    github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_template = 1 [json_name = "analysisTemplate"];
     bytes raw = 2;
   }
 }
 
-message GetClusterPromotionTaskRequest {
+message DeleteAnalysisTemplateRequest {
+  string project = 1;
   string name = 2;
-  RawFormat format = 3;
 }
 
-message GetClusterPromotionTaskResponse {
-  oneof result {
-    github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask promotion_task = 1 [json_name = "clusterPromotionTask"];
-    bytes raw = 2;
-  }
+message DeleteAnalysisTemplateResponse {
+  /* explicitly empty */
 }
 
 message ListClusterAnalysisTemplatesRequest {}
@@ -755,6 +815,14 @@ message GetClusterAnalysisTemplateResponse {
   }
 }
 
+message DeleteClusterAnalysisTemplateRequest {
+  string name = 2;
+}
+
+message DeleteClusterAnalysisTemplateResponse {
+  /* explicitly empty */
+}
+
 message GetAnalysisRunRequest {
   string namespace = 1;
   string name = 2;
@@ -779,31 +847,59 @@ message GetAnalysisRunLogsResponse {
   string chunk = 1;
 }
 
-message DeleteAnalysisTemplateRequest {
+/* Event Messages */
+
+message ListProjectEventsRequest {
   string project = 1;
-  string name = 2;
 }
 
-message DeleteAnalysisTemplateResponse {
-  /* explicitly empty */
+message ListProjectEventsResponse {
+  repeated k8s.io.api.core.v1.Event events = 1;
 }
 
-message DeleteClusterAnalysisTemplateRequest {
-  string name = 2;
+/* Promotion Task Messages */
+
+message ListPromotionTasksRequest {
+  string project = 1;
 }
 
-message DeleteClusterAnalysisTemplateResponse {
-  /* explicitly empty */
+message ListPromotionTasksResponse {
+  repeated github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_tasks = 1;
 }
 
-message ListProjectEventsRequest {
+message GetPromotionTaskRequest {
   string project = 1;
+  string name = 2;
+  RawFormat format = 3;
 }
 
-message ListProjectEventsResponse {
-  repeated k8s.io.api.core.v1.Event events = 1;
+message GetPromotionTaskResponse {
+  oneof result {
+    github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_task = 1 [json_name = "promotionTask"];
+    bytes raw = 2;
+  }
+}
+
+message ListClusterPromotionTasksRequest {}
+
+message ListClusterPromotionTasksResponse {
+  repeated github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask cluster_promotion_tasks = 1;
+}
+
+message GetClusterPromotionTaskRequest {
+  string name = 2;
+  RawFormat format = 3;
 }
 
+message GetClusterPromotionTaskResponse {
+  oneof result {
+    github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask promotion_task = 1 [json_name = "clusterPromotionTask"];
+    bytes raw = 2;
+  }
+}
+
+/* Role Messages */
+
 message CreateRoleRequest {
   github.com.akuity.kargo.api.rbac.v1alpha1.Role role = 1;
 }
diff --git a/api/service/v1alpha1/svcv1alpha1connect/service.connect.go b/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
index 1f2021a0..695c10a7 100644
--- a/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
+++ b/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
@@ -70,6 +70,18 @@ const (
 	// KargoServiceRefreshStageProcedure is the fully-qualified name of the KargoService's RefreshStage
 	// RPC.
 	KargoServiceRefreshStageProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/RefreshStage"
+	// KargoServiceGetClusterConfigProcedure is the fully-qualified name of the KargoService's
+	// GetClusterConfig RPC.
+	KargoServiceGetClusterConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/GetClusterConfig"
+	// KargoServiceDeleteClusterConfigProcedure is the fully-qualified name of the KargoService's
+	// DeleteClusterConfig RPC.
+	KargoServiceDeleteClusterConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/DeleteClusterConfig"
+	// KargoServiceWatchClusterConfigProcedure is the fully-qualified name of the KargoService's
+	// WatchClusterConfig RPC.
+	KargoServiceWatchClusterConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/WatchClusterConfig"
+	// KargoServiceRefreshClusterConfigProcedure is the fully-qualified name of the KargoService's
+	// RefreshClusterConfig RPC.
+	KargoServiceRefreshClusterConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/RefreshClusterConfig"
 	// KargoServiceListPromotionsProcedure is the fully-qualified name of the KargoService's
 	// ListPromotions RPC.
 	KargoServiceListPromotionsProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/ListPromotions"
@@ -93,12 +105,18 @@ const (
 	// KargoServiceListProjectsProcedure is the fully-qualified name of the KargoService's ListProjects
 	// RPC.
 	KargoServiceListProjectsProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/ListProjects"
-	// KargoServiceDeleteProjectConfigProcedure is the fully-qualified name of the KargoService's
-	// DeleteProjectConfig RPC.
-	KargoServiceDeleteProjectConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/DeleteProjectConfig"
 	// KargoServiceGetProjectConfigProcedure is the fully-qualified name of the KargoService's
 	// GetProjectConfig RPC.
 	KargoServiceGetProjectConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/GetProjectConfig"
+	// KargoServiceDeleteProjectConfigProcedure is the fully-qualified name of the KargoService's
+	// DeleteProjectConfig RPC.
+	KargoServiceDeleteProjectConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/DeleteProjectConfig"
+	// KargoServiceWatchProjectConfigProcedure is the fully-qualified name of the KargoService's
+	// WatchProjectConfig RPC.
+	KargoServiceWatchProjectConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/WatchProjectConfig"
+	// KargoServiceRefreshProjectConfigProcedure is the fully-qualified name of the KargoService's
+	// RefreshProjectConfig RPC.
+	KargoServiceRefreshProjectConfigProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/RefreshProjectConfig"
 	// KargoServiceApproveFreightProcedure is the fully-qualified name of the KargoService's
 	// ApproveFreight RPC.
 	KargoServiceApproveFreightProcedure = "/akuity.io.kargo.service.v1alpha1.KargoService/ApproveFreight"
@@ -241,6 +259,10 @@ var (
 	kargoServiceWatchStagesMethodDescriptor                   = kargoServiceServiceDescriptor.Methods().ByName("WatchStages")
 	kargoServiceDeleteStageMethodDescriptor                   = kargoServiceServiceDescriptor.Methods().ByName("DeleteStage")
 	kargoServiceRefreshStageMethodDescriptor                  = kargoServiceServiceDescriptor.Methods().ByName("RefreshStage")
+	kargoServiceGetClusterConfigMethodDescriptor              = kargoServiceServiceDescriptor.Methods().ByName("GetClusterConfig")
+	kargoServiceDeleteClusterConfigMethodDescriptor           = kargoServiceServiceDescriptor.Methods().ByName("DeleteClusterConfig")
+	kargoServiceWatchClusterConfigMethodDescriptor            = kargoServiceServiceDescriptor.Methods().ByName("WatchClusterConfig")
+	kargoServiceRefreshClusterConfigMethodDescriptor          = kargoServiceServiceDescriptor.Methods().ByName("RefreshClusterConfig")
 	kargoServiceListPromotionsMethodDescriptor                = kargoServiceServiceDescriptor.Methods().ByName("ListPromotions")
 	kargoServiceWatchPromotionsMethodDescriptor               = kargoServiceServiceDescriptor.Methods().ByName("WatchPromotions")
 	kargoServiceGetPromotionMethodDescriptor                  = kargoServiceServiceDescriptor.Methods().ByName("GetPromotion")
@@ -249,8 +271,10 @@ var (
 	kargoServiceDeleteProjectMethodDescriptor                 = kargoServiceServiceDescriptor.Methods().ByName("DeleteProject")
 	kargoServiceGetProjectMethodDescriptor                    = kargoServiceServiceDescriptor.Methods().ByName("GetProject")
 	kargoServiceListProjectsMethodDescriptor                  = kargoServiceServiceDescriptor.Methods().ByName("ListProjects")
-	kargoServiceDeleteProjectConfigMethodDescriptor           = kargoServiceServiceDescriptor.Methods().ByName("DeleteProjectConfig")
 	kargoServiceGetProjectConfigMethodDescriptor              = kargoServiceServiceDescriptor.Methods().ByName("GetProjectConfig")
+	kargoServiceDeleteProjectConfigMethodDescriptor           = kargoServiceServiceDescriptor.Methods().ByName("DeleteProjectConfig")
+	kargoServiceWatchProjectConfigMethodDescriptor            = kargoServiceServiceDescriptor.Methods().ByName("WatchProjectConfig")
+	kargoServiceRefreshProjectConfigMethodDescriptor          = kargoServiceServiceDescriptor.Methods().ByName("RefreshProjectConfig")
 	kargoServiceApproveFreightMethodDescriptor                = kargoServiceServiceDescriptor.Methods().ByName("ApproveFreight")
 	kargoServiceDeleteFreightMethodDescriptor                 = kargoServiceServiceDescriptor.Methods().ByName("DeleteFreight")
 	kargoServiceGetFreightMethodDescriptor                    = kargoServiceServiceDescriptor.Methods().ByName("GetFreight")
@@ -315,6 +339,10 @@ type KargoServiceClient interface {
 	WatchStages(context.Context, *connect.Request[v1alpha1.WatchStagesRequest]) (*connect.ServerStreamForClient[v1alpha1.WatchStagesResponse], error)
 	DeleteStage(context.Context, *connect.Request[v1alpha1.DeleteStageRequest]) (*connect.Response[v1alpha1.DeleteStageResponse], error)
 	RefreshStage(context.Context, *connect.Request[v1alpha1.RefreshStageRequest]) (*connect.Response[v1alpha1.RefreshStageResponse], error)
+	GetClusterConfig(context.Context, *connect.Request[v1alpha1.GetClusterConfigRequest]) (*connect.Response[v1alpha1.GetClusterConfigResponse], error)
+	DeleteClusterConfig(context.Context, *connect.Request[v1alpha1.DeleteClusterConfigRequest]) (*connect.Response[v1alpha1.DeleteClusterConfigResponse], error)
+	WatchClusterConfig(context.Context, *connect.Request[v1alpha1.WatchClusterConfigRequest]) (*connect.ServerStreamForClient[v1alpha1.WatchClusterConfigResponse], error)
+	RefreshClusterConfig(context.Context, *connect.Request[v1alpha1.RefreshClusterConfigRequest]) (*connect.Response[v1alpha1.RefreshClusterConfigResponse], error)
 	ListPromotions(context.Context, *connect.Request[v1alpha1.ListPromotionsRequest]) (*connect.Response[v1alpha1.ListPromotionsResponse], error)
 	WatchPromotions(context.Context, *connect.Request[v1alpha1.WatchPromotionsRequest]) (*connect.ServerStreamForClient[v1alpha1.WatchPromotionsResponse], error)
 	GetPromotion(context.Context, *connect.Request[v1alpha1.GetPromotionRequest]) (*connect.Response[v1alpha1.GetPromotionResponse], error)
@@ -323,8 +351,11 @@ type KargoServiceClient interface {
 	DeleteProject(context.Context, *connect.Request[v1alpha1.DeleteProjectRequest]) (*connect.Response[v1alpha1.DeleteProjectResponse], error)
 	GetProject(context.Context, *connect.Request[v1alpha1.GetProjectRequest]) (*connect.Response[v1alpha1.GetProjectResponse], error)
 	ListProjects(context.Context, *connect.Request[v1alpha1.ListProjectsRequest]) (*connect.Response[v1alpha1.ListProjectsResponse], error)
-	DeleteProjectConfig(context.Context, *connect.Request[v1alpha1.DeleteProjectConfigRequest]) (*connect.Response[v1alpha1.DeleteProjectConfigResponse], error)
+	// ProjectConfig APIs
 	GetProjectConfig(context.Context, *connect.Request[v1alpha1.GetProjectConfigRequest]) (*connect.Response[v1alpha1.GetProjectConfigResponse], error)
+	DeleteProjectConfig(context.Context, *connect.Request[v1alpha1.DeleteProjectConfigRequest]) (*connect.Response[v1alpha1.DeleteProjectConfigResponse], error)
+	WatchProjectConfig(context.Context, *connect.Request[v1alpha1.WatchProjectConfigRequest]) (*connect.ServerStreamForClient[v1alpha1.WatchProjectConfigResponse], error)
+	RefreshProjectConfig(context.Context, *connect.Request[v1alpha1.RefreshProjectConfigRequest]) (*connect.Response[v1alpha1.RefreshProjectConfigResponse], error)
 	ApproveFreight(context.Context, *connect.Request[v1alpha1.ApproveFreightRequest]) (*connect.Response[v1alpha1.ApproveFreightResponse], error)
 	DeleteFreight(context.Context, *connect.Request[v1alpha1.DeleteFreightRequest]) (*connect.Response[v1alpha1.DeleteFreightResponse], error)
 	GetFreight(context.Context, *connect.Request[v1alpha1.GetFreightRequest]) (*connect.Response[v1alpha1.GetFreightResponse], error)
@@ -465,6 +496,30 @@ func NewKargoServiceClient(httpClient connect.HTTPClient, baseURL string, opts .
 			connect.WithSchema(kargoServiceRefreshStageMethodDescriptor),
 			connect.WithClientOptions(opts...),
 		),
+		getClusterConfig: connect.NewClient[v1alpha1.GetClusterConfigRequest, v1alpha1.GetClusterConfigResponse](
+			httpClient,
+			baseURL+KargoServiceGetClusterConfigProcedure,
+			connect.WithSchema(kargoServiceGetClusterConfigMethodDescriptor),
+			connect.WithClientOptions(opts...),
+		),
+		deleteClusterConfig: connect.NewClient[v1alpha1.DeleteClusterConfigRequest, v1alpha1.DeleteClusterConfigResponse](
+			httpClient,
+			baseURL+KargoServiceDeleteClusterConfigProcedure,
+			connect.WithSchema(kargoServiceDeleteClusterConfigMethodDescriptor),
+			connect.WithClientOptions(opts...),
+		),
+		watchClusterConfig: connect.NewClient[v1alpha1.WatchClusterConfigRequest, v1alpha1.WatchClusterConfigResponse](
+			httpClient,
+			baseURL+KargoServiceWatchClusterConfigProcedure,
+			connect.WithSchema(kargoServiceWatchClusterConfigMethodDescriptor),
+			connect.WithClientOptions(opts...),
+		),
+		refreshClusterConfig: connect.NewClient[v1alpha1.RefreshClusterConfigRequest, v1alpha1.RefreshClusterConfigResponse](
+			httpClient,
+			baseURL+KargoServiceRefreshClusterConfigProcedure,
+			connect.WithSchema(kargoServiceRefreshClusterConfigMethodDescriptor),
+			connect.WithClientOptions(opts...),
+		),
 		listPromotions: connect.NewClient[v1alpha1.ListPromotionsRequest, v1alpha1.ListPromotionsResponse](
 			httpClient,
 			baseURL+KargoServiceListPromotionsProcedure,
@@ -513,16 +568,28 @@ func NewKargoServiceClient(httpClient connect.HTTPClient, baseURL string, opts .
 			connect.WithSchema(kargoServiceListProjectsMethodDescriptor),
 			connect.WithClientOptions(opts...),
 		),
+		getProjectConfig: connect.NewClient[v1alpha1.GetProjectConfigRequest, v1alpha1.GetProjectConfigResponse](
+			httpClient,
+			baseURL+KargoServiceGetProjectConfigProcedure,
+			connect.WithSchema(kargoServiceGetProjectConfigMethodDescriptor),
+			connect.WithClientOptions(opts...),
+		),
 		deleteProjectConfig: connect.NewClient[v1alpha1.DeleteProjectConfigRequest, v1alpha1.DeleteProjectConfigResponse](
 			httpClient,
 			baseURL+KargoServiceDeleteProjectConfigProcedure,
 			connect.WithSchema(kargoServiceDeleteProjectConfigMethodDescriptor),
 			connect.WithClientOptions(opts...),
 		),
-		getProjectConfig: connect.NewClient[v1alpha1.GetProjectConfigRequest, v1alpha1.GetProjectConfigResponse](
+		watchProjectConfig: connect.NewClient[v1alpha1.WatchProjectConfigRequest, v1alpha1.WatchProjectConfigResponse](
 			httpClient,
-			baseURL+KargoServiceGetProjectConfigProcedure,
-			connect.WithSchema(kargoServiceGetProjectConfigMethodDescriptor),
+			baseURL+KargoServiceWatchProjectConfigProcedure,
+			connect.WithSchema(kargoServiceWatchProjectConfigMethodDescriptor),
+			connect.WithClientOptions(opts...),
+		),
+		refreshProjectConfig: connect.NewClient[v1alpha1.RefreshProjectConfigRequest, v1alpha1.RefreshProjectConfigResponse](
+			httpClient,
+			baseURL+KargoServiceRefreshProjectConfigProcedure,
+			connect.WithSchema(kargoServiceRefreshProjectConfigMethodDescriptor),
 			connect.WithClientOptions(opts...),
 		),
 		approveFreight: connect.NewClient[v1alpha1.ApproveFreightRequest, v1alpha1.ApproveFreightResponse](
@@ -808,6 +875,10 @@ type kargoServiceClient struct {
 	watchStages                   *connect.Client[v1alpha1.WatchStagesRequest, v1alpha1.WatchStagesResponse]
 	deleteStage                   *connect.Client[v1alpha1.DeleteStageRequest, v1alpha1.DeleteStageResponse]
 	refreshStage                  *connect.Client[v1alpha1.RefreshStageRequest, v1alpha1.RefreshStageResponse]
+	getClusterConfig              *connect.Client[v1alpha1.GetClusterConfigRequest, v1alpha1.GetClusterConfigResponse]
+	deleteClusterConfig           *connect.Client[v1alpha1.DeleteClusterConfigRequest, v1alpha1.DeleteClusterConfigResponse]
+	watchClusterConfig            *connect.Client[v1alpha1.WatchClusterConfigRequest, v1alpha1.WatchClusterConfigResponse]
+	refreshClusterConfig          *connect.Client[v1alpha1.RefreshClusterConfigRequest, v1alpha1.RefreshClusterConfigResponse]
 	listPromotions                *connect.Client[v1alpha1.ListPromotionsRequest, v1alpha1.ListPromotionsResponse]
 	watchPromotions               *connect.Client[v1alpha1.WatchPromotionsRequest, v1alpha1.WatchPromotionsResponse]
 	getPromotion                  *connect.Client[v1alpha1.GetPromotionRequest, v1alpha1.GetPromotionResponse]
@@ -816,8 +887,10 @@ type kargoServiceClient struct {
 	deleteProject                 *connect.Client[v1alpha1.DeleteProjectRequest, v1alpha1.DeleteProjectResponse]
 	getProject                    *connect.Client[v1alpha1.GetProjectRequest, v1alpha1.GetProjectResponse]
 	listProjects                  *connect.Client[v1alpha1.ListProjectsRequest, v1alpha1.ListProjectsResponse]
-	deleteProjectConfig           *connect.Client[v1alpha1.DeleteProjectConfigRequest, v1alpha1.DeleteProjectConfigResponse]
 	getProjectConfig              *connect.Client[v1alpha1.GetProjectConfigRequest, v1alpha1.GetProjectConfigResponse]
+	deleteProjectConfig           *connect.Client[v1alpha1.DeleteProjectConfigRequest, v1alpha1.DeleteProjectConfigResponse]
+	watchProjectConfig            *connect.Client[v1alpha1.WatchProjectConfigRequest, v1alpha1.WatchProjectConfigResponse]
+	refreshProjectConfig          *connect.Client[v1alpha1.RefreshProjectConfigRequest, v1alpha1.RefreshProjectConfigResponse]
 	approveFreight                *connect.Client[v1alpha1.ApproveFreightRequest, v1alpha1.ApproveFreightResponse]
 	deleteFreight                 *connect.Client[v1alpha1.DeleteFreightRequest, v1alpha1.DeleteFreightResponse]
 	getFreight                    *connect.Client[v1alpha1.GetFreightRequest, v1alpha1.GetFreightResponse]
@@ -935,6 +1008,26 @@ func (c *kargoServiceClient) RefreshStage(ctx context.Context, req *connect.Requ
 	return c.refreshStage.CallUnary(ctx, req)
 }
 
+// GetClusterConfig calls akuity.io.kargo.service.v1alpha1.KargoService.GetClusterConfig.
+func (c *kargoServiceClient) GetClusterConfig(ctx context.Context, req *connect.Request[v1alpha1.GetClusterConfigRequest]) (*connect.Response[v1alpha1.GetClusterConfigResponse], error) {
+	return c.getClusterConfig.CallUnary(ctx, req)
+}
+
+// DeleteClusterConfig calls akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterConfig.
+func (c *kargoServiceClient) DeleteClusterConfig(ctx context.Context, req *connect.Request[v1alpha1.DeleteClusterConfigRequest]) (*connect.Response[v1alpha1.DeleteClusterConfigResponse], error) {
+	return c.deleteClusterConfig.CallUnary(ctx, req)
+}
+
+// WatchClusterConfig calls akuity.io.kargo.service.v1alpha1.KargoService.WatchClusterConfig.
+func (c *kargoServiceClient) WatchClusterConfig(ctx context.Context, req *connect.Request[v1alpha1.WatchClusterConfigRequest]) (*connect.ServerStreamForClient[v1alpha1.WatchClusterConfigResponse], error) {
+	return c.watchClusterConfig.CallServerStream(ctx, req)
+}
+
+// RefreshClusterConfig calls akuity.io.kargo.service.v1alpha1.KargoService.RefreshClusterConfig.
+func (c *kargoServiceClient) RefreshClusterConfig(ctx context.Context, req *connect.Request[v1alpha1.RefreshClusterConfigRequest]) (*connect.Response[v1alpha1.RefreshClusterConfigResponse], error) {
+	return c.refreshClusterConfig.CallUnary(ctx, req)
+}
+
 // ListPromotions calls akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions.
 func (c *kargoServiceClient) ListPromotions(ctx context.Context, req *connect.Request[v1alpha1.ListPromotionsRequest]) (*connect.Response[v1alpha1.ListPromotionsResponse], error) {
 	return c.listPromotions.CallUnary(ctx, req)
@@ -975,14 +1068,24 @@ func (c *kargoServiceClient) ListProjects(ctx context.Context, req *connect.Requ
 	return c.listProjects.CallUnary(ctx, req)
 }
 
+// GetProjectConfig calls akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig.
+func (c *kargoServiceClient) GetProjectConfig(ctx context.Context, req *connect.Request[v1alpha1.GetProjectConfigRequest]) (*connect.Response[v1alpha1.GetProjectConfigResponse], error) {
+	return c.getProjectConfig.CallUnary(ctx, req)
+}
+
 // DeleteProjectConfig calls akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig.
 func (c *kargoServiceClient) DeleteProjectConfig(ctx context.Context, req *connect.Request[v1alpha1.DeleteProjectConfigRequest]) (*connect.Response[v1alpha1.DeleteProjectConfigResponse], error) {
 	return c.deleteProjectConfig.CallUnary(ctx, req)
 }
 
-// GetProjectConfig calls akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig.
-func (c *kargoServiceClient) GetProjectConfig(ctx context.Context, req *connect.Request[v1alpha1.GetProjectConfigRequest]) (*connect.Response[v1alpha1.GetProjectConfigResponse], error) {
-	return c.getProjectConfig.CallUnary(ctx, req)
+// WatchProjectConfig calls akuity.io.kargo.service.v1alpha1.KargoService.WatchProjectConfig.
+func (c *kargoServiceClient) WatchProjectConfig(ctx context.Context, req *connect.Request[v1alpha1.WatchProjectConfigRequest]) (*connect.ServerStreamForClient[v1alpha1.WatchProjectConfigResponse], error) {
+	return c.watchProjectConfig.CallServerStream(ctx, req)
+}
+
+// RefreshProjectConfig calls akuity.io.kargo.service.v1alpha1.KargoService.RefreshProjectConfig.
+func (c *kargoServiceClient) RefreshProjectConfig(ctx context.Context, req *connect.Request[v1alpha1.RefreshProjectConfigRequest]) (*connect.Response[v1alpha1.RefreshProjectConfigResponse], error) {
+	return c.refreshProjectConfig.CallUnary(ctx, req)
 }
 
 // ApproveFreight calls akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight.
@@ -1230,6 +1333,10 @@ type KargoServiceHandler interface {
 	WatchStages(context.Context, *connect.Request[v1alpha1.WatchStagesRequest], *connect.ServerStream[v1alpha1.WatchStagesResponse]) error
 	DeleteStage(context.Context, *connect.Request[v1alpha1.DeleteStageRequest]) (*connect.Response[v1alpha1.DeleteStageResponse], error)
 	RefreshStage(context.Context, *connect.Request[v1alpha1.RefreshStageRequest]) (*connect.Response[v1alpha1.RefreshStageResponse], error)
+	GetClusterConfig(context.Context, *connect.Request[v1alpha1.GetClusterConfigRequest]) (*connect.Response[v1alpha1.GetClusterConfigResponse], error)
+	DeleteClusterConfig(context.Context, *connect.Request[v1alpha1.DeleteClusterConfigRequest]) (*connect.Response[v1alpha1.DeleteClusterConfigResponse], error)
+	WatchClusterConfig(context.Context, *connect.Request[v1alpha1.WatchClusterConfigRequest], *connect.ServerStream[v1alpha1.WatchClusterConfigResponse]) error
+	RefreshClusterConfig(context.Context, *connect.Request[v1alpha1.RefreshClusterConfigRequest]) (*connect.Response[v1alpha1.RefreshClusterConfigResponse], error)
 	ListPromotions(context.Context, *connect.Request[v1alpha1.ListPromotionsRequest]) (*connect.Response[v1alpha1.ListPromotionsResponse], error)
 	WatchPromotions(context.Context, *connect.Request[v1alpha1.WatchPromotionsRequest], *connect.ServerStream[v1alpha1.WatchPromotionsResponse]) error
 	GetPromotion(context.Context, *connect.Request[v1alpha1.GetPromotionRequest]) (*connect.Response[v1alpha1.GetPromotionResponse], error)
@@ -1238,8 +1345,11 @@ type KargoServiceHandler interface {
 	DeleteProject(context.Context, *connect.Request[v1alpha1.DeleteProjectRequest]) (*connect.Response[v1alpha1.DeleteProjectResponse], error)
 	GetProject(context.Context, *connect.Request[v1alpha1.GetProjectRequest]) (*connect.Response[v1alpha1.GetProjectResponse], error)
 	ListProjects(context.Context, *connect.Request[v1alpha1.ListProjectsRequest]) (*connect.Response[v1alpha1.ListProjectsResponse], error)
-	DeleteProjectConfig(context.Context, *connect.Request[v1alpha1.DeleteProjectConfigRequest]) (*connect.Response[v1alpha1.DeleteProjectConfigResponse], error)
+	// ProjectConfig APIs
 	GetProjectConfig(context.Context, *connect.Request[v1alpha1.GetProjectConfigRequest]) (*connect.Response[v1alpha1.GetProjectConfigResponse], error)
+	DeleteProjectConfig(context.Context, *connect.Request[v1alpha1.DeleteProjectConfigRequest]) (*connect.Response[v1alpha1.DeleteProjectConfigResponse], error)
+	WatchProjectConfig(context.Context, *connect.Request[v1alpha1.WatchProjectConfigRequest], *connect.ServerStream[v1alpha1.WatchProjectConfigResponse]) error
+	RefreshProjectConfig(context.Context, *connect.Request[v1alpha1.RefreshProjectConfigRequest]) (*connect.Response[v1alpha1.RefreshProjectConfigResponse], error)
 	ApproveFreight(context.Context, *connect.Request[v1alpha1.ApproveFreightRequest]) (*connect.Response[v1alpha1.ApproveFreightResponse], error)
 	DeleteFreight(context.Context, *connect.Request[v1alpha1.DeleteFreightRequest]) (*connect.Response[v1alpha1.DeleteFreightResponse], error)
 	GetFreight(context.Context, *connect.Request[v1alpha1.GetFreightRequest]) (*connect.Response[v1alpha1.GetFreightResponse], error)
@@ -1376,6 +1486,30 @@ func NewKargoServiceHandler(svc KargoServiceHandler, opts ...connect.HandlerOpti
 		connect.WithSchema(kargoServiceRefreshStageMethodDescriptor),
 		connect.WithHandlerOptions(opts...),
 	)
+	kargoServiceGetClusterConfigHandler := connect.NewUnaryHandler(
+		KargoServiceGetClusterConfigProcedure,
+		svc.GetClusterConfig,
+		connect.WithSchema(kargoServiceGetClusterConfigMethodDescriptor),
+		connect.WithHandlerOptions(opts...),
+	)
+	kargoServiceDeleteClusterConfigHandler := connect.NewUnaryHandler(
+		KargoServiceDeleteClusterConfigProcedure,
+		svc.DeleteClusterConfig,
+		connect.WithSchema(kargoServiceDeleteClusterConfigMethodDescriptor),
+		connect.WithHandlerOptions(opts...),
+	)
+	kargoServiceWatchClusterConfigHandler := connect.NewServerStreamHandler(
+		KargoServiceWatchClusterConfigProcedure,
+		svc.WatchClusterConfig,
+		connect.WithSchema(kargoServiceWatchClusterConfigMethodDescriptor),
+		connect.WithHandlerOptions(opts...),
+	)
+	kargoServiceRefreshClusterConfigHandler := connect.NewUnaryHandler(
+		KargoServiceRefreshClusterConfigProcedure,
+		svc.RefreshClusterConfig,
+		connect.WithSchema(kargoServiceRefreshClusterConfigMethodDescriptor),
+		connect.WithHandlerOptions(opts...),
+	)
 	kargoServiceListPromotionsHandler := connect.NewUnaryHandler(
 		KargoServiceListPromotionsProcedure,
 		svc.ListPromotions,
@@ -1424,16 +1558,28 @@ func NewKargoServiceHandler(svc KargoServiceHandler, opts ...connect.HandlerOpti
 		connect.WithSchema(kargoServiceListProjectsMethodDescriptor),
 		connect.WithHandlerOptions(opts...),
 	)
+	kargoServiceGetProjectConfigHandler := connect.NewUnaryHandler(
+		KargoServiceGetProjectConfigProcedure,
+		svc.GetProjectConfig,
+		connect.WithSchema(kargoServiceGetProjectConfigMethodDescriptor),
+		connect.WithHandlerOptions(opts...),
+	)
 	kargoServiceDeleteProjectConfigHandler := connect.NewUnaryHandler(
 		KargoServiceDeleteProjectConfigProcedure,
 		svc.DeleteProjectConfig,
 		connect.WithSchema(kargoServiceDeleteProjectConfigMethodDescriptor),
 		connect.WithHandlerOptions(opts...),
 	)
-	kargoServiceGetProjectConfigHandler := connect.NewUnaryHandler(
-		KargoServiceGetProjectConfigProcedure,
-		svc.GetProjectConfig,
-		connect.WithSchema(kargoServiceGetProjectConfigMethodDescriptor),
+	kargoServiceWatchProjectConfigHandler := connect.NewServerStreamHandler(
+		KargoServiceWatchProjectConfigProcedure,
+		svc.WatchProjectConfig,
+		connect.WithSchema(kargoServiceWatchProjectConfigMethodDescriptor),
+		connect.WithHandlerOptions(opts...),
+	)
+	kargoServiceRefreshProjectConfigHandler := connect.NewUnaryHandler(
+		KargoServiceRefreshProjectConfigProcedure,
+		svc.RefreshProjectConfig,
+		connect.WithSchema(kargoServiceRefreshProjectConfigMethodDescriptor),
 		connect.WithHandlerOptions(opts...),
 	)
 	kargoServiceApproveFreightHandler := connect.NewUnaryHandler(
@@ -1730,6 +1876,14 @@ func NewKargoServiceHandler(svc KargoServiceHandler, opts ...connect.HandlerOpti
 			kargoServiceDeleteStageHandler.ServeHTTP(w, r)
 		case KargoServiceRefreshStageProcedure:
 			kargoServiceRefreshStageHandler.ServeHTTP(w, r)
+		case KargoServiceGetClusterConfigProcedure:
+			kargoServiceGetClusterConfigHandler.ServeHTTP(w, r)
+		case KargoServiceDeleteClusterConfigProcedure:
+			kargoServiceDeleteClusterConfigHandler.ServeHTTP(w, r)
+		case KargoServiceWatchClusterConfigProcedure:
+			kargoServiceWatchClusterConfigHandler.ServeHTTP(w, r)
+		case KargoServiceRefreshClusterConfigProcedure:
+			kargoServiceRefreshClusterConfigHandler.ServeHTTP(w, r)
 		case KargoServiceListPromotionsProcedure:
 			kargoServiceListPromotionsHandler.ServeHTTP(w, r)
 		case KargoServiceWatchPromotionsProcedure:
@@ -1746,10 +1900,14 @@ func NewKargoServiceHandler(svc KargoServiceHandler, opts ...connect.HandlerOpti
 			kargoServiceGetProjectHandler.ServeHTTP(w, r)
 		case KargoServiceListProjectsProcedure:
 			kargoServiceListProjectsHandler.ServeHTTP(w, r)
-		case KargoServiceDeleteProjectConfigProcedure:
-			kargoServiceDeleteProjectConfigHandler.ServeHTTP(w, r)
 		case KargoServiceGetProjectConfigProcedure:
 			kargoServiceGetProjectConfigHandler.ServeHTTP(w, r)
+		case KargoServiceDeleteProjectConfigProcedure:
+			kargoServiceDeleteProjectConfigHandler.ServeHTTP(w, r)
+		case KargoServiceWatchProjectConfigProcedure:
+			kargoServiceWatchProjectConfigHandler.ServeHTTP(w, r)
+		case KargoServiceRefreshProjectConfigProcedure:
+			kargoServiceRefreshProjectConfigHandler.ServeHTTP(w, r)
 		case KargoServiceApproveFreightProcedure:
 			kargoServiceApproveFreightHandler.ServeHTTP(w, r)
 		case KargoServiceDeleteFreightProcedure:
@@ -1903,6 +2061,22 @@ func (UnimplementedKargoServiceHandler) RefreshStage(context.Context, *connect.R
 	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.RefreshStage is not implemented"))
 }
 
+func (UnimplementedKargoServiceHandler) GetClusterConfig(context.Context, *connect.Request[v1alpha1.GetClusterConfigRequest]) (*connect.Response[v1alpha1.GetClusterConfigResponse], error) {
+	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.GetClusterConfig is not implemented"))
+}
+
+func (UnimplementedKargoServiceHandler) DeleteClusterConfig(context.Context, *connect.Request[v1alpha1.DeleteClusterConfigRequest]) (*connect.Response[v1alpha1.DeleteClusterConfigResponse], error) {
+	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterConfig is not implemented"))
+}
+
+func (UnimplementedKargoServiceHandler) WatchClusterConfig(context.Context, *connect.Request[v1alpha1.WatchClusterConfigRequest], *connect.ServerStream[v1alpha1.WatchClusterConfigResponse]) error {
+	return connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.WatchClusterConfig is not implemented"))
+}
+
+func (UnimplementedKargoServiceHandler) RefreshClusterConfig(context.Context, *connect.Request[v1alpha1.RefreshClusterConfigRequest]) (*connect.Response[v1alpha1.RefreshClusterConfigResponse], error) {
+	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.RefreshClusterConfig is not implemented"))
+}
+
 func (UnimplementedKargoServiceHandler) ListPromotions(context.Context, *connect.Request[v1alpha1.ListPromotionsRequest]) (*connect.Response[v1alpha1.ListPromotionsResponse], error) {
 	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions is not implemented"))
 }
@@ -1935,12 +2109,20 @@ func (UnimplementedKargoServiceHandler) ListProjects(context.Context, *connect.R
 	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.ListProjects is not implemented"))
 }
 
+func (UnimplementedKargoServiceHandler) GetProjectConfig(context.Context, *connect.Request[v1alpha1.GetProjectConfigRequest]) (*connect.Response[v1alpha1.GetProjectConfigResponse], error) {
+	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig is not implemented"))
+}
+
 func (UnimplementedKargoServiceHandler) DeleteProjectConfig(context.Context, *connect.Request[v1alpha1.DeleteProjectConfigRequest]) (*connect.Response[v1alpha1.DeleteProjectConfigResponse], error) {
 	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig is not implemented"))
 }
 
-func (UnimplementedKargoServiceHandler) GetProjectConfig(context.Context, *connect.Request[v1alpha1.GetProjectConfigRequest]) (*connect.Response[v1alpha1.GetProjectConfigResponse], error) {
-	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig is not implemented"))
+func (UnimplementedKargoServiceHandler) WatchProjectConfig(context.Context, *connect.Request[v1alpha1.WatchProjectConfigRequest], *connect.ServerStream[v1alpha1.WatchProjectConfigResponse]) error {
+	return connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.WatchProjectConfig is not implemented"))
+}
+
+func (UnimplementedKargoServiceHandler) RefreshProjectConfig(context.Context, *connect.Request[v1alpha1.RefreshProjectConfigRequest]) (*connect.Response[v1alpha1.RefreshProjectConfigResponse], error) {
+	return nil, connect.NewError(connect.CodeUnimplemented, errors.New("akuity.io.kargo.service.v1alpha1.KargoService.RefreshProjectConfig is not implemented"))
 }
 
 func (UnimplementedKargoServiceHandler) ApproveFreight(context.Context, *connect.Request[v1alpha1.ApproveFreightRequest]) (*connect.Response[v1alpha1.ApproveFreightResponse], error) {
diff --git a/api/v1alpha1/cluster_config_types.go b/api/v1alpha1/cluster_config_types.go
index 7c3f0b9f..1e014922 100644
--- a/api/v1alpha1/cluster_config_types.go
+++ b/api/v1alpha1/cluster_config_types.go
@@ -41,6 +41,14 @@ type ClusterConfigStatus struct {
 	// +listType=map
 	// +listMapKey=type
 	Conditions []metav1.Condition `json:"conditions,omitempty" patchMergeKey:"type" patchStrategy:"merge" protobuf:"bytes,1,rep,name=conditions"`
+	// ObservedGeneration represents the .metadata.generation that this
+	// ClusterConfig was reconciled against.
+	ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"`
+	// LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+	// annotation that was handled by the controller. This field can be used to
+	// determine whether the request to refresh the resource has been handled.
+	// +optional
+	LastHandledRefresh string `json:"lastHandledRefresh,omitempty" protobuf:"bytes,4,opt,name=lastHandledRefresh"`
 	// WebhookReceivers describes the status of cluster-scoped webhook receivers.
 	WebhookReceivers []WebhookReceiverDetails `json:"webhookReceivers,omitempty" protobuf:"bytes,2,rep,name=webhookReceivers"`
 }
diff --git a/api/v1alpha1/generated.pb.go b/api/v1alpha1/generated.pb.go
index e495a679..b216dc0c 100644
--- a/api/v1alpha1/generated.pb.go
+++ b/api/v1alpha1/generated.pb.go
@@ -646,10 +646,38 @@ func (m *DiscoveredImageReference) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_DiscoveredImageReference proto.InternalMessageInfo
 
+func (m *DockerHubWebhookReceiverConfig) Reset()      { *m = DockerHubWebhookReceiverConfig{} }
+func (*DockerHubWebhookReceiverConfig) ProtoMessage() {}
+func (*DockerHubWebhookReceiverConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e26b7f7bbc391025, []int{22}
+}
+func (m *DockerHubWebhookReceiverConfig) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *DockerHubWebhookReceiverConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	b = b[:cap(b)]
+	n, err := m.MarshalToSizedBuffer(b)
+	if err != nil {
+		return nil, err
+	}
+	return b[:n], nil
+}
+func (m *DockerHubWebhookReceiverConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DockerHubWebhookReceiverConfig.Merge(m, src)
+}
+func (m *DockerHubWebhookReceiverConfig) XXX_Size() int {
+	return m.Size()
+}
+func (m *DockerHubWebhookReceiverConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_DockerHubWebhookReceiverConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DockerHubWebhookReceiverConfig proto.InternalMessageInfo
+
 func (m *ExpressionVariable) Reset()      { *m = ExpressionVariable{} }
 func (*ExpressionVariable) ProtoMessage() {}
 func (*ExpressionVariable) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{22}
+	return fileDescriptor_e26b7f7bbc391025, []int{23}
 }
 func (m *ExpressionVariable) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -677,7 +705,7 @@ var xxx_messageInfo_ExpressionVariable proto.InternalMessageInfo
 func (m *Freight) Reset()      { *m = Freight{} }
 func (*Freight) ProtoMessage() {}
 func (*Freight) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{23}
+	return fileDescriptor_e26b7f7bbc391025, []int{24}
 }
 func (m *Freight) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -705,7 +733,7 @@ var xxx_messageInfo_Freight proto.InternalMessageInfo
 func (m *FreightCollection) Reset()      { *m = FreightCollection{} }
 func (*FreightCollection) ProtoMessage() {}
 func (*FreightCollection) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{24}
+	return fileDescriptor_e26b7f7bbc391025, []int{25}
 }
 func (m *FreightCollection) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -733,7 +761,7 @@ var xxx_messageInfo_FreightCollection proto.InternalMessageInfo
 func (m *FreightList) Reset()      { *m = FreightList{} }
 func (*FreightList) ProtoMessage() {}
 func (*FreightList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{25}
+	return fileDescriptor_e26b7f7bbc391025, []int{26}
 }
 func (m *FreightList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -761,7 +789,7 @@ var xxx_messageInfo_FreightList proto.InternalMessageInfo
 func (m *FreightOrigin) Reset()      { *m = FreightOrigin{} }
 func (*FreightOrigin) ProtoMessage() {}
 func (*FreightOrigin) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{26}
+	return fileDescriptor_e26b7f7bbc391025, []int{27}
 }
 func (m *FreightOrigin) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -789,7 +817,7 @@ var xxx_messageInfo_FreightOrigin proto.InternalMessageInfo
 func (m *FreightReference) Reset()      { *m = FreightReference{} }
 func (*FreightReference) ProtoMessage() {}
 func (*FreightReference) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{27}
+	return fileDescriptor_e26b7f7bbc391025, []int{28}
 }
 func (m *FreightReference) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -817,7 +845,7 @@ var xxx_messageInfo_FreightReference proto.InternalMessageInfo
 func (m *FreightRequest) Reset()      { *m = FreightRequest{} }
 func (*FreightRequest) ProtoMessage() {}
 func (*FreightRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{28}
+	return fileDescriptor_e26b7f7bbc391025, []int{29}
 }
 func (m *FreightRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -845,7 +873,7 @@ var xxx_messageInfo_FreightRequest proto.InternalMessageInfo
 func (m *FreightSources) Reset()      { *m = FreightSources{} }
 func (*FreightSources) ProtoMessage() {}
 func (*FreightSources) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{29}
+	return fileDescriptor_e26b7f7bbc391025, []int{30}
 }
 func (m *FreightSources) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -873,7 +901,7 @@ var xxx_messageInfo_FreightSources proto.InternalMessageInfo
 func (m *FreightStatus) Reset()      { *m = FreightStatus{} }
 func (*FreightStatus) ProtoMessage() {}
 func (*FreightStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{30}
+	return fileDescriptor_e26b7f7bbc391025, []int{31}
 }
 func (m *FreightStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -901,7 +929,7 @@ var xxx_messageInfo_FreightStatus proto.InternalMessageInfo
 func (m *GitCommit) Reset()      { *m = GitCommit{} }
 func (*GitCommit) ProtoMessage() {}
 func (*GitCommit) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{31}
+	return fileDescriptor_e26b7f7bbc391025, []int{32}
 }
 func (m *GitCommit) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -929,7 +957,7 @@ var xxx_messageInfo_GitCommit proto.InternalMessageInfo
 func (m *GitDiscoveryResult) Reset()      { *m = GitDiscoveryResult{} }
 func (*GitDiscoveryResult) ProtoMessage() {}
 func (*GitDiscoveryResult) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{32}
+	return fileDescriptor_e26b7f7bbc391025, []int{33}
 }
 func (m *GitDiscoveryResult) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -957,7 +985,7 @@ var xxx_messageInfo_GitDiscoveryResult proto.InternalMessageInfo
 func (m *GitHubWebhookReceiverConfig) Reset()      { *m = GitHubWebhookReceiverConfig{} }
 func (*GitHubWebhookReceiverConfig) ProtoMessage() {}
 func (*GitHubWebhookReceiverConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{33}
+	return fileDescriptor_e26b7f7bbc391025, []int{34}
 }
 func (m *GitHubWebhookReceiverConfig) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -985,7 +1013,7 @@ var xxx_messageInfo_GitHubWebhookReceiverConfig proto.InternalMessageInfo
 func (m *GitLabWebhookReceiverConfig) Reset()      { *m = GitLabWebhookReceiverConfig{} }
 func (*GitLabWebhookReceiverConfig) ProtoMessage() {}
 func (*GitLabWebhookReceiverConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{34}
+	return fileDescriptor_e26b7f7bbc391025, []int{35}
 }
 func (m *GitLabWebhookReceiverConfig) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1013,7 +1041,7 @@ var xxx_messageInfo_GitLabWebhookReceiverConfig proto.InternalMessageInfo
 func (m *GitSubscription) Reset()      { *m = GitSubscription{} }
 func (*GitSubscription) ProtoMessage() {}
 func (*GitSubscription) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{35}
+	return fileDescriptor_e26b7f7bbc391025, []int{36}
 }
 func (m *GitSubscription) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1041,7 +1069,7 @@ var xxx_messageInfo_GitSubscription proto.InternalMessageInfo
 func (m *Health) Reset()      { *m = Health{} }
 func (*Health) ProtoMessage() {}
 func (*Health) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{36}
+	return fileDescriptor_e26b7f7bbc391025, []int{37}
 }
 func (m *Health) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1069,7 +1097,7 @@ var xxx_messageInfo_Health proto.InternalMessageInfo
 func (m *HealthCheckStep) Reset()      { *m = HealthCheckStep{} }
 func (*HealthCheckStep) ProtoMessage() {}
 func (*HealthCheckStep) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{37}
+	return fileDescriptor_e26b7f7bbc391025, []int{38}
 }
 func (m *HealthCheckStep) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1097,7 +1125,7 @@ var xxx_messageInfo_HealthCheckStep proto.InternalMessageInfo
 func (m *HealthStats) Reset()      { *m = HealthStats{} }
 func (*HealthStats) ProtoMessage() {}
 func (*HealthStats) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{38}
+	return fileDescriptor_e26b7f7bbc391025, []int{39}
 }
 func (m *HealthStats) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1125,7 +1153,7 @@ var xxx_messageInfo_HealthStats proto.InternalMessageInfo
 func (m *Image) Reset()      { *m = Image{} }
 func (*Image) ProtoMessage() {}
 func (*Image) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{39}
+	return fileDescriptor_e26b7f7bbc391025, []int{40}
 }
 func (m *Image) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1153,7 +1181,7 @@ var xxx_messageInfo_Image proto.InternalMessageInfo
 func (m *ImageDiscoveryResult) Reset()      { *m = ImageDiscoveryResult{} }
 func (*ImageDiscoveryResult) ProtoMessage() {}
 func (*ImageDiscoveryResult) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{40}
+	return fileDescriptor_e26b7f7bbc391025, []int{41}
 }
 func (m *ImageDiscoveryResult) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1181,7 +1209,7 @@ var xxx_messageInfo_ImageDiscoveryResult proto.InternalMessageInfo
 func (m *ImageSubscription) Reset()      { *m = ImageSubscription{} }
 func (*ImageSubscription) ProtoMessage() {}
 func (*ImageSubscription) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{41}
+	return fileDescriptor_e26b7f7bbc391025, []int{42}
 }
 func (m *ImageSubscription) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1209,7 +1237,7 @@ var xxx_messageInfo_ImageSubscription proto.InternalMessageInfo
 func (m *Project) Reset()      { *m = Project{} }
 func (*Project) ProtoMessage() {}
 func (*Project) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{42}
+	return fileDescriptor_e26b7f7bbc391025, []int{43}
 }
 func (m *Project) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1237,7 +1265,7 @@ var xxx_messageInfo_Project proto.InternalMessageInfo
 func (m *ProjectConfig) Reset()      { *m = ProjectConfig{} }
 func (*ProjectConfig) ProtoMessage() {}
 func (*ProjectConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{43}
+	return fileDescriptor_e26b7f7bbc391025, []int{44}
 }
 func (m *ProjectConfig) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1265,7 +1293,7 @@ var xxx_messageInfo_ProjectConfig proto.InternalMessageInfo
 func (m *ProjectConfigList) Reset()      { *m = ProjectConfigList{} }
 func (*ProjectConfigList) ProtoMessage() {}
 func (*ProjectConfigList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{44}
+	return fileDescriptor_e26b7f7bbc391025, []int{45}
 }
 func (m *ProjectConfigList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1293,7 +1321,7 @@ var xxx_messageInfo_ProjectConfigList proto.InternalMessageInfo
 func (m *ProjectConfigSpec) Reset()      { *m = ProjectConfigSpec{} }
 func (*ProjectConfigSpec) ProtoMessage() {}
 func (*ProjectConfigSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{45}
+	return fileDescriptor_e26b7f7bbc391025, []int{46}
 }
 func (m *ProjectConfigSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1321,7 +1349,7 @@ var xxx_messageInfo_ProjectConfigSpec proto.InternalMessageInfo
 func (m *ProjectConfigStatus) Reset()      { *m = ProjectConfigStatus{} }
 func (*ProjectConfigStatus) ProtoMessage() {}
 func (*ProjectConfigStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{46}
+	return fileDescriptor_e26b7f7bbc391025, []int{47}
 }
 func (m *ProjectConfigStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1349,7 +1377,7 @@ var xxx_messageInfo_ProjectConfigStatus proto.InternalMessageInfo
 func (m *ProjectList) Reset()      { *m = ProjectList{} }
 func (*ProjectList) ProtoMessage() {}
 func (*ProjectList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{47}
+	return fileDescriptor_e26b7f7bbc391025, []int{48}
 }
 func (m *ProjectList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1377,7 +1405,7 @@ var xxx_messageInfo_ProjectList proto.InternalMessageInfo
 func (m *ProjectStats) Reset()      { *m = ProjectStats{} }
 func (*ProjectStats) ProtoMessage() {}
 func (*ProjectStats) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{48}
+	return fileDescriptor_e26b7f7bbc391025, []int{49}
 }
 func (m *ProjectStats) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1405,7 +1433,7 @@ var xxx_messageInfo_ProjectStats proto.InternalMessageInfo
 func (m *ProjectStatus) Reset()      { *m = ProjectStatus{} }
 func (*ProjectStatus) ProtoMessage() {}
 func (*ProjectStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{49}
+	return fileDescriptor_e26b7f7bbc391025, []int{50}
 }
 func (m *ProjectStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1433,7 +1461,7 @@ var xxx_messageInfo_ProjectStatus proto.InternalMessageInfo
 func (m *Promotion) Reset()      { *m = Promotion{} }
 func (*Promotion) ProtoMessage() {}
 func (*Promotion) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{50}
+	return fileDescriptor_e26b7f7bbc391025, []int{51}
 }
 func (m *Promotion) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1461,7 +1489,7 @@ var xxx_messageInfo_Promotion proto.InternalMessageInfo
 func (m *PromotionList) Reset()      { *m = PromotionList{} }
 func (*PromotionList) ProtoMessage() {}
 func (*PromotionList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{51}
+	return fileDescriptor_e26b7f7bbc391025, []int{52}
 }
 func (m *PromotionList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1489,7 +1517,7 @@ var xxx_messageInfo_PromotionList proto.InternalMessageInfo
 func (m *PromotionPolicy) Reset()      { *m = PromotionPolicy{} }
 func (*PromotionPolicy) ProtoMessage() {}
 func (*PromotionPolicy) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{52}
+	return fileDescriptor_e26b7f7bbc391025, []int{53}
 }
 func (m *PromotionPolicy) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1517,7 +1545,7 @@ var xxx_messageInfo_PromotionPolicy proto.InternalMessageInfo
 func (m *PromotionPolicySelector) Reset()      { *m = PromotionPolicySelector{} }
 func (*PromotionPolicySelector) ProtoMessage() {}
 func (*PromotionPolicySelector) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{53}
+	return fileDescriptor_e26b7f7bbc391025, []int{54}
 }
 func (m *PromotionPolicySelector) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1545,7 +1573,7 @@ var xxx_messageInfo_PromotionPolicySelector proto.InternalMessageInfo
 func (m *PromotionReference) Reset()      { *m = PromotionReference{} }
 func (*PromotionReference) ProtoMessage() {}
 func (*PromotionReference) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{54}
+	return fileDescriptor_e26b7f7bbc391025, []int{55}
 }
 func (m *PromotionReference) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1573,7 +1601,7 @@ var xxx_messageInfo_PromotionReference proto.InternalMessageInfo
 func (m *PromotionSpec) Reset()      { *m = PromotionSpec{} }
 func (*PromotionSpec) ProtoMessage() {}
 func (*PromotionSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{55}
+	return fileDescriptor_e26b7f7bbc391025, []int{56}
 }
 func (m *PromotionSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1601,7 +1629,7 @@ var xxx_messageInfo_PromotionSpec proto.InternalMessageInfo
 func (m *PromotionStatus) Reset()      { *m = PromotionStatus{} }
 func (*PromotionStatus) ProtoMessage() {}
 func (*PromotionStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{56}
+	return fileDescriptor_e26b7f7bbc391025, []int{57}
 }
 func (m *PromotionStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1629,7 +1657,7 @@ var xxx_messageInfo_PromotionStatus proto.InternalMessageInfo
 func (m *PromotionStep) Reset()      { *m = PromotionStep{} }
 func (*PromotionStep) ProtoMessage() {}
 func (*PromotionStep) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{57}
+	return fileDescriptor_e26b7f7bbc391025, []int{58}
 }
 func (m *PromotionStep) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1657,7 +1685,7 @@ var xxx_messageInfo_PromotionStep proto.InternalMessageInfo
 func (m *PromotionStepRetry) Reset()      { *m = PromotionStepRetry{} }
 func (*PromotionStepRetry) ProtoMessage() {}
 func (*PromotionStepRetry) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{58}
+	return fileDescriptor_e26b7f7bbc391025, []int{59}
 }
 func (m *PromotionStepRetry) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1685,7 +1713,7 @@ var xxx_messageInfo_PromotionStepRetry proto.InternalMessageInfo
 func (m *PromotionTask) Reset()      { *m = PromotionTask{} }
 func (*PromotionTask) ProtoMessage() {}
 func (*PromotionTask) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{59}
+	return fileDescriptor_e26b7f7bbc391025, []int{60}
 }
 func (m *PromotionTask) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1713,7 +1741,7 @@ var xxx_messageInfo_PromotionTask proto.InternalMessageInfo
 func (m *PromotionTaskList) Reset()      { *m = PromotionTaskList{} }
 func (*PromotionTaskList) ProtoMessage() {}
 func (*PromotionTaskList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{60}
+	return fileDescriptor_e26b7f7bbc391025, []int{61}
 }
 func (m *PromotionTaskList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1741,7 +1769,7 @@ var xxx_messageInfo_PromotionTaskList proto.InternalMessageInfo
 func (m *PromotionTaskReference) Reset()      { *m = PromotionTaskReference{} }
 func (*PromotionTaskReference) ProtoMessage() {}
 func (*PromotionTaskReference) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{61}
+	return fileDescriptor_e26b7f7bbc391025, []int{62}
 }
 func (m *PromotionTaskReference) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1769,7 +1797,7 @@ var xxx_messageInfo_PromotionTaskReference proto.InternalMessageInfo
 func (m *PromotionTaskSpec) Reset()      { *m = PromotionTaskSpec{} }
 func (*PromotionTaskSpec) ProtoMessage() {}
 func (*PromotionTaskSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{62}
+	return fileDescriptor_e26b7f7bbc391025, []int{63}
 }
 func (m *PromotionTaskSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1797,7 +1825,7 @@ var xxx_messageInfo_PromotionTaskSpec proto.InternalMessageInfo
 func (m *PromotionTemplate) Reset()      { *m = PromotionTemplate{} }
 func (*PromotionTemplate) ProtoMessage() {}
 func (*PromotionTemplate) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{63}
+	return fileDescriptor_e26b7f7bbc391025, []int{64}
 }
 func (m *PromotionTemplate) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1825,7 +1853,7 @@ var xxx_messageInfo_PromotionTemplate proto.InternalMessageInfo
 func (m *PromotionTemplateSpec) Reset()      { *m = PromotionTemplateSpec{} }
 func (*PromotionTemplateSpec) ProtoMessage() {}
 func (*PromotionTemplateSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{64}
+	return fileDescriptor_e26b7f7bbc391025, []int{65}
 }
 func (m *PromotionTemplateSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1853,7 +1881,7 @@ var xxx_messageInfo_PromotionTemplateSpec proto.InternalMessageInfo
 func (m *QuayWebhookReceiverConfig) Reset()      { *m = QuayWebhookReceiverConfig{} }
 func (*QuayWebhookReceiverConfig) ProtoMessage() {}
 func (*QuayWebhookReceiverConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{65}
+	return fileDescriptor_e26b7f7bbc391025, []int{66}
 }
 func (m *QuayWebhookReceiverConfig) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1881,7 +1909,7 @@ var xxx_messageInfo_QuayWebhookReceiverConfig proto.InternalMessageInfo
 func (m *RepoSubscription) Reset()      { *m = RepoSubscription{} }
 func (*RepoSubscription) ProtoMessage() {}
 func (*RepoSubscription) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{66}
+	return fileDescriptor_e26b7f7bbc391025, []int{67}
 }
 func (m *RepoSubscription) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1909,7 +1937,7 @@ var xxx_messageInfo_RepoSubscription proto.InternalMessageInfo
 func (m *Stage) Reset()      { *m = Stage{} }
 func (*Stage) ProtoMessage() {}
 func (*Stage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{67}
+	return fileDescriptor_e26b7f7bbc391025, []int{68}
 }
 func (m *Stage) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1937,7 +1965,7 @@ var xxx_messageInfo_Stage proto.InternalMessageInfo
 func (m *StageList) Reset()      { *m = StageList{} }
 func (*StageList) ProtoMessage() {}
 func (*StageList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{68}
+	return fileDescriptor_e26b7f7bbc391025, []int{69}
 }
 func (m *StageList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1965,7 +1993,7 @@ var xxx_messageInfo_StageList proto.InternalMessageInfo
 func (m *StageSpec) Reset()      { *m = StageSpec{} }
 func (*StageSpec) ProtoMessage() {}
 func (*StageSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{69}
+	return fileDescriptor_e26b7f7bbc391025, []int{70}
 }
 func (m *StageSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1993,7 +2021,7 @@ var xxx_messageInfo_StageSpec proto.InternalMessageInfo
 func (m *StageStats) Reset()      { *m = StageStats{} }
 func (*StageStats) ProtoMessage() {}
 func (*StageStats) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{70}
+	return fileDescriptor_e26b7f7bbc391025, []int{71}
 }
 func (m *StageStats) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2021,7 +2049,7 @@ var xxx_messageInfo_StageStats proto.InternalMessageInfo
 func (m *StageStatus) Reset()      { *m = StageStatus{} }
 func (*StageStatus) ProtoMessage() {}
 func (*StageStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{71}
+	return fileDescriptor_e26b7f7bbc391025, []int{72}
 }
 func (m *StageStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2049,7 +2077,7 @@ var xxx_messageInfo_StageStatus proto.InternalMessageInfo
 func (m *StepExecutionMetadata) Reset()      { *m = StepExecutionMetadata{} }
 func (*StepExecutionMetadata) ProtoMessage() {}
 func (*StepExecutionMetadata) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{72}
+	return fileDescriptor_e26b7f7bbc391025, []int{73}
 }
 func (m *StepExecutionMetadata) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2077,7 +2105,7 @@ var xxx_messageInfo_StepExecutionMetadata proto.InternalMessageInfo
 func (m *Verification) Reset()      { *m = Verification{} }
 func (*Verification) ProtoMessage() {}
 func (*Verification) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{73}
+	return fileDescriptor_e26b7f7bbc391025, []int{74}
 }
 func (m *Verification) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2105,7 +2133,7 @@ var xxx_messageInfo_Verification proto.InternalMessageInfo
 func (m *VerificationInfo) Reset()      { *m = VerificationInfo{} }
 func (*VerificationInfo) ProtoMessage() {}
 func (*VerificationInfo) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{74}
+	return fileDescriptor_e26b7f7bbc391025, []int{75}
 }
 func (m *VerificationInfo) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2133,7 +2161,7 @@ var xxx_messageInfo_VerificationInfo proto.InternalMessageInfo
 func (m *VerifiedStage) Reset()      { *m = VerifiedStage{} }
 func (*VerifiedStage) ProtoMessage() {}
 func (*VerifiedStage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{75}
+	return fileDescriptor_e26b7f7bbc391025, []int{76}
 }
 func (m *VerifiedStage) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2161,7 +2189,7 @@ var xxx_messageInfo_VerifiedStage proto.InternalMessageInfo
 func (m *Warehouse) Reset()      { *m = Warehouse{} }
 func (*Warehouse) ProtoMessage() {}
 func (*Warehouse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{76}
+	return fileDescriptor_e26b7f7bbc391025, []int{77}
 }
 func (m *Warehouse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2189,7 +2217,7 @@ var xxx_messageInfo_Warehouse proto.InternalMessageInfo
 func (m *WarehouseList) Reset()      { *m = WarehouseList{} }
 func (*WarehouseList) ProtoMessage() {}
 func (*WarehouseList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{77}
+	return fileDescriptor_e26b7f7bbc391025, []int{78}
 }
 func (m *WarehouseList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2217,7 +2245,7 @@ var xxx_messageInfo_WarehouseList proto.InternalMessageInfo
 func (m *WarehouseSpec) Reset()      { *m = WarehouseSpec{} }
 func (*WarehouseSpec) ProtoMessage() {}
 func (*WarehouseSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{78}
+	return fileDescriptor_e26b7f7bbc391025, []int{79}
 }
 func (m *WarehouseSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2245,7 +2273,7 @@ var xxx_messageInfo_WarehouseSpec proto.InternalMessageInfo
 func (m *WarehouseStats) Reset()      { *m = WarehouseStats{} }
 func (*WarehouseStats) ProtoMessage() {}
 func (*WarehouseStats) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{79}
+	return fileDescriptor_e26b7f7bbc391025, []int{80}
 }
 func (m *WarehouseStats) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2273,7 +2301,7 @@ var xxx_messageInfo_WarehouseStats proto.InternalMessageInfo
 func (m *WarehouseStatus) Reset()      { *m = WarehouseStatus{} }
 func (*WarehouseStatus) ProtoMessage() {}
 func (*WarehouseStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{80}
+	return fileDescriptor_e26b7f7bbc391025, []int{81}
 }
 func (m *WarehouseStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2301,7 +2329,7 @@ var xxx_messageInfo_WarehouseStatus proto.InternalMessageInfo
 func (m *WebhookReceiverConfig) Reset()      { *m = WebhookReceiverConfig{} }
 func (*WebhookReceiverConfig) ProtoMessage() {}
 func (*WebhookReceiverConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{81}
+	return fileDescriptor_e26b7f7bbc391025, []int{82}
 }
 func (m *WebhookReceiverConfig) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2329,7 +2357,7 @@ var xxx_messageInfo_WebhookReceiverConfig proto.InternalMessageInfo
 func (m *WebhookReceiverDetails) Reset()      { *m = WebhookReceiverDetails{} }
 func (*WebhookReceiverDetails) ProtoMessage() {}
 func (*WebhookReceiverDetails) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e26b7f7bbc391025, []int{82}
+	return fileDescriptor_e26b7f7bbc391025, []int{83}
 }
 func (m *WebhookReceiverDetails) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2380,6 +2408,7 @@ func init() {
 	proto.RegisterType((*DiscoveredCommit)(nil), "github.com.akuity.kargo.api.v1alpha1.DiscoveredCommit")
 	proto.RegisterType((*DiscoveredImageReference)(nil), "github.com.akuity.kargo.api.v1alpha1.DiscoveredImageReference")
 	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.api.v1alpha1.DiscoveredImageReference.AnnotationsEntry")
+	proto.RegisterType((*DockerHubWebhookReceiverConfig)(nil), "github.com.akuity.kargo.api.v1alpha1.DockerHubWebhookReceiverConfig")
 	proto.RegisterType((*ExpressionVariable)(nil), "github.com.akuity.kargo.api.v1alpha1.ExpressionVariable")
 	proto.RegisterType((*Freight)(nil), "github.com.akuity.kargo.api.v1alpha1.Freight")
 	proto.RegisterType((*FreightCollection)(nil), "github.com.akuity.kargo.api.v1alpha1.FreightCollection")
@@ -2454,308 +2483,311 @@ func init() {
 }
 
 var fileDescriptor_e26b7f7bbc391025 = []byte{
-	// 4809 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x7c, 0x4d, 0x6c, 0x23, 0x47,
-	0x76, 0xff, 0x34, 0x29, 0x51, 0xe2, 0xa3, 0x3e, 0x4b, 0x1a, 0x5b, 0x96, 0xff, 0x96, 0xfc, 0x6f,
-	0x3b, 0x86, 0x1d, 0xdb, 0x54, 0x3c, 0xfe, 0x1a, 0x7f, 0xec, 0x04, 0xa2, 0xa4, 0x99, 0x91, 0x57,
-	0xeb, 0xd1, 0x16, 0xe5, 0xf1, 0x7a, 0xc6, 0x83, 0x49, 0x89, 0x2c, 0x91, 0xbd, 0x22, 0xd9, 0x9c,
-	0xae, 0xa2, 0x3c, 0x8a, 0x83, 0xc4, 0xd9, 0x64, 0x83, 0x05, 0x12, 0x04, 0x3e, 0x6c, 0xe0, 0x3d,
-	0x24, 0x48, 0x90, 0x3d, 0x05, 0x0b, 0x64, 0x8f, 0x39, 0xe4, 0xe0, 0x43, 0x2e, 0xde, 0x64, 0x37,
-	0x30, 0x9c, 0x43, 0xbc, 0xc0, 0x42, 0x88, 0xb5, 0x40, 0xce, 0x7b, 0xc9, 0x65, 0x80, 0x20, 0x41,
-	0x7d, 0x74, 0x77, 0x75, 0xb3, 0x39, 0x62, 0x53, 0x1f, 0x99, 0xe4, 0x46, 0xd6, 0xab, 0xfa, 0xbd,
-	0xaa, 0x57, 0x55, 0xaf, 0x5e, 0xbd, 0xf7, 0xaa, 0xe1, 0xa5, 0x9a, 0xc3, 0xeb, 0x9d, 0xed, 0x62,
-	0xc5, 0x6d, 0x2e, 0x91, 0xdd, 0x8e, 0xc3, 0xf7, 0x97, 0x76, 0x89, 0x57, 0x73, 0x97, 0x48, 0xdb,
-	0x59, 0xda, 0x7b, 0x81, 0x34, 0xda, 0x75, 0xf2, 0xc2, 0x52, 0x8d, 0xb6, 0xa8, 0x47, 0x38, 0xad,
-	0x16, 0xdb, 0x9e, 0xcb, 0x5d, 0xf4, 0x64, 0xd8, 0xaa, 0xa8, 0x5a, 0x15, 0x65, 0xab, 0x22, 0x69,
-	0x3b, 0x45, 0xbf, 0xd5, 0xfc, 0xf3, 0x06, 0x76, 0xcd, 0xad, 0xb9, 0x4b, 0xb2, 0xf1, 0x76, 0x67,
-	0x47, 0xfe, 0x93, 0x7f, 0xe4, 0x2f, 0x05, 0x3a, 0x6f, 0xef, 0x5e, 0x64, 0x45, 0x47, 0x71, 0xae,
-	0xb8, 0x1e, 0x5d, 0xda, 0xeb, 0x62, 0x3c, 0x7f, 0x35, 0xac, 0x43, 0xef, 0x72, 0xda, 0x62, 0x8e,
-	0xdb, 0x62, 0xcf, 0x93, 0xb6, 0xc3, 0xa8, 0xb7, 0x47, 0xbd, 0xa5, 0xf6, 0x6e, 0x4d, 0xd0, 0x58,
-	0xb4, 0x42, 0x12, 0xd2, 0x4b, 0x21, 0x52, 0x93, 0x54, 0xea, 0x4e, 0x8b, 0x7a, 0xfb, 0x61, 0xf3,
-	0x26, 0xe5, 0x24, 0xa9, 0xd5, 0x52, 0xaf, 0x56, 0x5e, 0xa7, 0xc5, 0x9d, 0x26, 0xed, 0x6a, 0xf0,
-	0xca, 0x51, 0x0d, 0x58, 0xa5, 0x4e, 0x9b, 0x24, 0xde, 0xce, 0x7e, 0x1f, 0x66, 0x96, 0x5b, 0xa4,
-	0xb1, 0xcf, 0x1c, 0x86, 0x3b, 0xad, 0x65, 0xaf, 0xd6, 0x69, 0xd2, 0x16, 0x47, 0x8f, 0xc3, 0x50,
-	0x8b, 0x34, 0xe9, 0x9c, 0xf5, 0xb8, 0xf5, 0x74, 0xbe, 0x34, 0xf6, 0xd9, 0xc1, 0xe2, 0xb9, 0xc3,
-	0x83, 0xc5, 0xa1, 0xb7, 0x49, 0x93, 0x62, 0x49, 0x41, 0x4f, 0xc0, 0xf0, 0x1e, 0x69, 0x74, 0xe8,
-	0x5c, 0x46, 0x56, 0x19, 0xd7, 0x55, 0x86, 0xaf, 0x8b, 0x42, 0xac, 0x68, 0xf6, 0x1f, 0x64, 0x23,
-	0xf0, 0xdf, 0xa0, 0x9c, 0x54, 0x09, 0x27, 0xa8, 0x09, 0xb9, 0x06, 0xd9, 0xa6, 0x0d, 0x36, 0x67,
-	0x3d, 0x9e, 0x7d, 0xba, 0x70, 0x61, 0xad, 0xd8, 0xcf, 0x44, 0x17, 0x13, 0xa0, 0x8a, 0x1b, 0x12,
-	0x67, 0xad, 0xc5, 0xbd, 0xfd, 0xd2, 0x84, 0xee, 0x44, 0x4e, 0x15, 0x62, 0xcd, 0x04, 0xfd, 0xbe,
-	0x05, 0x05, 0xd2, 0x6a, 0xb9, 0x9c, 0x70, 0x31, 0x4d, 0x73, 0x19, 0xc9, 0xf4, 0xad, 0xc1, 0x99,
-	0x2e, 0x87, 0x60, 0x8a, 0xf3, 0x8c, 0xe6, 0x5c, 0x30, 0x28, 0xd8, 0xe4, 0x39, 0xff, 0x1a, 0x14,
-	0x8c, 0xae, 0xa2, 0x29, 0xc8, 0xee, 0xd2, 0x7d, 0x25, 0x5f, 0x2c, 0x7e, 0xa2, 0xd9, 0x88, 0x40,
-	0xb5, 0x04, 0x5f, 0xcf, 0x5c, 0xb4, 0xe6, 0x2f, 0xc1, 0x54, 0x9c, 0x61, 0x9a, 0xf6, 0xf6, 0x9f,
-	0x5a, 0x30, 0x6b, 0x8c, 0x02, 0xd3, 0x1d, 0xea, 0xd1, 0x56, 0x85, 0xa2, 0x25, 0xc8, 0x8b, 0xb9,
-	0x64, 0x6d, 0x52, 0xf1, 0xa7, 0x7a, 0x5a, 0x0f, 0x24, 0xff, 0xb6, 0x4f, 0xc0, 0x61, 0x9d, 0x60,
-	0x59, 0x64, 0xee, 0xb7, 0x2c, 0xda, 0x75, 0xc2, 0xe8, 0x5c, 0x36, 0xba, 0x2c, 0x36, 0x45, 0x21,
-	0x56, 0x34, 0xfb, 0x36, 0x3c, 0xe2, 0xf7, 0x67, 0x8b, 0x36, 0xdb, 0x0d, 0xc2, 0x69, 0xd8, 0xa9,
-	0xa3, 0x97, 0xde, 0xe3, 0x30, 0xb4, 0xeb, 0xb4, 0xaa, 0xf1, 0x5e, 0x7c, 0xdd, 0x69, 0x55, 0xb1,
-	0xa4, 0xd8, 0xbb, 0x30, 0xbe, 0xdc, 0x6e, 0x7b, 0xee, 0x1e, 0xad, 0x96, 0x39, 0xa9, 0x51, 0x74,
-	0x03, 0x80, 0xe8, 0x82, 0x65, 0x2e, 0xa1, 0x0b, 0x17, 0x7e, 0xbd, 0xa8, 0xf6, 0x4c, 0xd1, 0xdc,
-	0x33, 0xc5, 0xf6, 0x6e, 0x4d, 0x14, 0xb0, 0xa2, 0xd8, 0x9a, 0xc5, 0xbd, 0x17, 0x8a, 0x5b, 0x4e,
-	0x93, 0x96, 0x26, 0x0e, 0x0f, 0x16, 0x61, 0x39, 0x40, 0xc0, 0x06, 0x9a, 0xfd, 0x1d, 0x0b, 0xce,
-	0x2f, 0x7b, 0x35, 0x77, 0x65, 0x75, 0xb9, 0xdd, 0xbe, 0x4a, 0x49, 0x83, 0xd7, 0xcb, 0x9c, 0xf0,
-	0x0e, 0x43, 0x97, 0x20, 0xc7, 0xe4, 0x2f, 0x3d, 0x98, 0xa7, 0xfc, 0xf5, 0xa9, 0xe8, 0xf7, 0x0e,
-	0x16, 0x67, 0x13, 0x1a, 0x52, 0xac, 0x5b, 0xa1, 0x67, 0x60, 0xa4, 0x49, 0x19, 0x23, 0x35, 0x5f,
-	0xe2, 0x93, 0x1a, 0x60, 0xe4, 0x1b, 0xaa, 0x18, 0xfb, 0x74, 0xfb, 0x1f, 0x33, 0x30, 0x19, 0x60,
-	0x69, 0xf6, 0xa7, 0x30, 0xbd, 0x1d, 0x18, 0xab, 0x1b, 0x23, 0x94, 0xb3, 0x5c, 0xb8, 0xf0, 0x46,
-	0x9f, 0x3b, 0x29, 0x49, 0x48, 0xa5, 0x59, 0xcd, 0x66, 0xcc, 0x2c, 0xc5, 0x11, 0x36, 0xa8, 0x09,
-	0xc0, 0xf6, 0x5b, 0x15, 0xcd, 0x74, 0x48, 0x32, 0x7d, 0x2d, 0x25, 0xd3, 0x72, 0x00, 0x50, 0x42,
-	0x9a, 0x25, 0x84, 0x65, 0xd8, 0x60, 0x60, 0xff, 0xad, 0x05, 0x33, 0x09, 0xed, 0xd0, 0x9b, 0xb1,
-	0xf9, 0x7c, 0xb2, 0x6b, 0x3e, 0x51, 0x57, 0xb3, 0x70, 0x36, 0x9f, 0x83, 0x51, 0x8f, 0xee, 0x39,
-	0xe2, 0xa4, 0xd0, 0x12, 0x9e, 0xd2, 0xed, 0x47, 0xb1, 0x2e, 0xc7, 0x41, 0x0d, 0xf4, 0x2c, 0xe4,
-	0xfd, 0xdf, 0x42, 0xcc, 0x59, 0xb1, 0x99, 0xc4, 0xc4, 0xf9, 0x55, 0x19, 0x0e, 0xe9, 0xf6, 0x87,
-	0xb0, 0x50, 0x72, 0xf8, 0x76, 0xa7, 0xb2, 0x4b, 0xf9, 0xbb, 0x74, 0xbb, 0xee, 0xba, 0xbb, 0x98,
-	0x56, 0xa8, 0xb3, 0x47, 0xbd, 0x15, 0xb7, 0xb5, 0xe3, 0xd4, 0xd0, 0x7b, 0x90, 0x67, 0xb4, 0xe2,
-	0x51, 0x8e, 0xe9, 0x8e, 0x5e, 0xff, 0x4f, 0x1b, 0xeb, 0xbf, 0x28, 0x0e, 0x42, 0xb1, 0xda, 0x37,
-	0xdc, 0x0a, 0x69, 0x5c, 0xdb, 0xfe, 0x36, 0xad, 0xf0, 0x60, 0x4b, 0x86, 0xab, 0xa6, 0xec, 0x43,
-	0xe0, 0x10, 0xcd, 0xfe, 0x3d, 0x18, 0x5e, 0xa9, 0x13, 0x8f, 0x8b, 0xe5, 0xea, 0xd1, 0xb6, 0xfb,
-	0x0e, 0xde, 0xd0, 0xf2, 0x09, 0x96, 0x2b, 0x56, 0xc5, 0xd8, 0xa7, 0xf7, 0xb1, 0xd2, 0x9e, 0x81,
-	0x91, 0x3d, 0xea, 0x49, 0x61, 0x65, 0xa3, 0x60, 0xd7, 0x55, 0x31, 0xf6, 0xe9, 0xf6, 0xbf, 0x58,
-	0x30, 0x2b, 0x7b, 0xb0, 0xea, 0xb0, 0x8a, 0xbb, 0x47, 0xbd, 0x7d, 0x4c, 0x59, 0xa7, 0x71, 0xc2,
-	0x1d, 0x5a, 0x85, 0x29, 0x46, 0x9b, 0x4a, 0xa2, 0x8c, 0x7b, 0xc4, 0x69, 0x71, 0xdd, 0xb3, 0x39,
-	0x5d, 0x7b, 0xaa, 0x1c, 0xa3, 0xe3, 0xae, 0x16, 0xe8, 0x69, 0x18, 0xd5, 0xdd, 0x16, 0xeb, 0x58,
-	0xcc, 0xea, 0x98, 0x58, 0x00, 0x7a, 0x4c, 0x0c, 0x07, 0x54, 0xfb, 0xdf, 0x2d, 0x98, 0x96, 0xa3,
-	0x2a, 0x77, 0xb6, 0x59, 0xc5, 0x73, 0xda, 0x42, 0xfb, 0x3f, 0x88, 0x43, 0xba, 0x04, 0x13, 0x55,
-	0x5f, 0xf0, 0x1b, 0x4e, 0xd3, 0xe1, 0x72, 0x83, 0x0e, 0x97, 0x1e, 0xd2, 0x18, 0x13, 0xab, 0x11,
-	0x2a, 0x8e, 0xd5, 0xb6, 0x7f, 0x9c, 0x81, 0xf1, 0x95, 0x46, 0x87, 0xf1, 0x60, 0xb1, 0xfe, 0x16,
-	0x8c, 0x36, 0xf5, 0x51, 0xab, 0xd7, 0xea, 0x6f, 0xf4, 0xa7, 0xab, 0xd5, 0xc2, 0x15, 0xc7, 0x74,
-	0xb8, 0xc7, 0xc3, 0x32, 0x1c, 0xa0, 0xa2, 0xf7, 0x60, 0x88, 0xb5, 0x69, 0x45, 0xca, 0xa6, 0x70,
-	0xe1, 0xd5, 0xfe, 0x54, 0x49, 0xa4, 0x93, 0xe5, 0x36, 0xad, 0x84, 0x42, 0x15, 0xff, 0xb0, 0x84,
-	0x44, 0x24, 0x50, 0x12, 0xd9, 0x34, 0x7a, 0x2a, 0x0a, 0xae, 0xf4, 0xd4, 0x44, 0x54, 0xbf, 0xf8,
-	0x9a, 0xc4, 0xfe, 0x27, 0xb1, 0x34, 0xcc, 0xfa, 0x1b, 0x0e, 0xe3, 0xe8, 0xfd, 0x2e, 0xa9, 0x15,
-	0xfb, 0x93, 0x9a, 0x68, 0x2d, 0x65, 0x16, 0xe8, 0x23, 0xbf, 0xc4, 0x90, 0xd8, 0xb7, 0x60, 0xd8,
-	0xe1, 0xb4, 0xe9, 0x1b, 0x4f, 0x2f, 0x0e, 0x30, 0xaa, 0xd0, 0x1a, 0x58, 0x17, 0x48, 0x58, 0x01,
-	0xda, 0x9f, 0xc4, 0x47, 0x23, 0x84, 0x29, 0x6c, 0xb6, 0xa9, 0x0f, 0xa2, 0xaa, 0xcc, 0xb7, 0x16,
-	0xfb, 0x3c, 0x6e, 0x12, 0x15, 0x61, 0xb8, 0xb2, 0x63, 0x64, 0x86, 0xbb, 0xd8, 0xd9, 0xff, 0x65,
-	0xc1, 0x4c, 0xc2, 0xbc, 0xa0, 0x0a, 0x40, 0xc5, 0x6d, 0x55, 0x1d, 0x65, 0x4d, 0xaa, 0x4e, 0x2d,
-	0xf5, 0x27, 0xeb, 0x15, 0xbf, 0x5d, 0xb8, 0x40, 0x83, 0x22, 0x86, 0x0d, 0x58, 0xf4, 0x9d, 0x24,
-	0x01, 0x28, 0xe1, 0xbf, 0x39, 0x90, 0x00, 0x56, 0x29, 0x27, 0x4e, 0x83, 0xa5, 0x92, 0x80, 0x54,
-	0xad, 0x4a, 0x02, 0x9b, 0x9e, 0xdb, 0x74, 0x45, 0xd7, 0xb6, 0x08, 0xdb, 0x7d, 0x50, 0xb7, 0x68,
-	0xa4, 0x93, 0xbd, 0xb6, 0xa8, 0xfd, 0x73, 0x0b, 0xe6, 0x92, 0x46, 0x75, 0x06, 0xdb, 0xe8, 0x76,
-	0x74, 0x1b, 0xbd, 0x9e, 0x6a, 0x1b, 0x45, 0x3a, 0xdb, 0x63, 0x37, 0xdd, 0x84, 0xb1, 0x95, 0x8e,
-	0xe7, 0xd1, 0x16, 0x57, 0x96, 0xef, 0xd7, 0x61, 0x98, 0x39, 0x2d, 0x6d, 0x00, 0xa6, 0x33, 0x7a,
-	0xf3, 0x02, 0xbc, 0x2c, 0x1a, 0x63, 0x85, 0x61, 0xff, 0x79, 0x16, 0x66, 0x7c, 0x6d, 0x4e, 0xab,
-	0xcb, 0x1e, 0x77, 0x76, 0x48, 0x85, 0x33, 0x54, 0x85, 0xb1, 0x6a, 0x58, 0xcc, 0xb5, 0x85, 0x96,
-	0x86, 0x57, 0x60, 0x05, 0x1a, 0xf0, 0x1c, 0x47, 0x50, 0xd1, 0xbb, 0x90, 0xad, 0x39, 0x5c, 0xef,
-	0xb7, 0x8b, 0xfd, 0x49, 0xee, 0x8a, 0x13, 0xb7, 0x0a, 0x4a, 0x05, 0xcd, 0x2a, 0x7b, 0xc5, 0xe1,
-	0x58, 0x20, 0xa2, 0x6d, 0xc8, 0x39, 0x4d, 0x52, 0xa3, 0x29, 0x67, 0x65, 0x5d, 0xb4, 0x89, 0xa3,
-	0x07, 0x3a, 0x5b, 0x52, 0x19, 0xd6, 0xc8, 0x82, 0x47, 0x45, 0x9c, 0xe6, 0xca, 0x98, 0xeb, 0x7f,
-	0xe6, 0x13, 0xec, 0x9a, 0x90, 0x87, 0xa4, 0x32, 0xac, 0x91, 0xed, 0x2f, 0x33, 0x30, 0x15, 0xca,
-	0x6f, 0xc5, 0x6d, 0x36, 0x1d, 0x8e, 0xe6, 0x21, 0xe3, 0x54, 0xb5, 0xb1, 0x00, 0xba, 0x61, 0x66,
-	0x7d, 0x15, 0x67, 0x9c, 0x2a, 0x7a, 0x0a, 0x72, 0xdb, 0x1e, 0x69, 0x55, 0xea, 0xda, 0x48, 0x08,
-	0x80, 0x4b, 0xb2, 0x14, 0x6b, 0x2a, 0x7a, 0x0c, 0xb2, 0x9c, 0xd4, 0xb4, 0x6d, 0x10, 0xc8, 0x6f,
-	0x8b, 0xd4, 0xb0, 0x28, 0x17, 0x46, 0x09, 0xeb, 0xc8, 0x3d, 0x2c, 0x67, 0xde, 0x30, 0x4a, 0xca,
-	0xaa, 0x18, 0xfb, 0x74, 0xc1, 0x91, 0x74, 0x78, 0xdd, 0xf5, 0xe6, 0x86, 0xa3, 0x1c, 0x97, 0x65,
-	0x29, 0xd6, 0x54, 0x71, 0x77, 0xa9, 0xc8, 0xfe, 0x73, 0xea, 0xcd, 0xe5, 0xa2, 0x77, 0x97, 0x15,
-	0x9f, 0x80, 0xc3, 0x3a, 0xe8, 0x16, 0x14, 0x2a, 0x1e, 0x25, 0xdc, 0xf5, 0x56, 0x09, 0xa7, 0x73,
-	0x23, 0xa9, 0x57, 0xe0, 0xa4, 0xb8, 0xbe, 0xaf, 0x84, 0x10, 0xd8, 0xc4, 0xb3, 0xff, 0x2e, 0x0b,
-	0x73, 0xa1, 0x68, 0xe5, 0xdc, 0x86, 0x57, 0x56, 0x2d, 0x1e, 0xab, 0x87, 0x78, 0x9e, 0x82, 0x5c,
-	0xd5, 0xa9, 0x51, 0xc6, 0xe3, 0x52, 0x5e, 0x95, 0xa5, 0x58, 0x53, 0xd1, 0x1f, 0xc5, 0xdc, 0x14,
-	0xc3, 0x72, 0xa1, 0x5c, 0xeb, 0x6f, 0xa1, 0xf4, 0xea, 0xdc, 0x00, 0xbe, 0x0a, 0x74, 0x01, 0xa0,
-	0xe6, 0x70, 0x6d, 0x50, 0xea, 0x59, 0x0f, 0x94, 0xf5, 0x95, 0x80, 0x82, 0x8d, 0x5a, 0xe8, 0x5d,
-	0xc8, 0x4b, 0x79, 0x0d, 0xb8, 0xff, 0xe5, 0xdd, 0x66, 0xc5, 0x07, 0xc0, 0x21, 0xd6, 0xb1, 0xbd,
-	0x1f, 0x37, 0x01, 0xad, 0xdd, 0x6d, 0x7b, 0x94, 0x09, 0xb3, 0xfa, 0x3a, 0xf1, 0x1c, 0xb2, 0xdd,
-	0xa0, 0x27, 0xe5, 0xe0, 0xfa, 0x7c, 0x08, 0x46, 0x2e, 0x7b, 0xd4, 0xa9, 0xd5, 0xf9, 0x19, 0x1c,
-	0x89, 0x4f, 0xc0, 0x30, 0x69, 0x38, 0x84, 0xc9, 0xd5, 0x6d, 0x74, 0x69, 0x59, 0x14, 0x62, 0x45,
-	0x43, 0x37, 0x21, 0xe7, 0x7a, 0x4e, 0xcd, 0x69, 0xcd, 0xe5, 0x65, 0x27, 0xfa, 0xb4, 0xd4, 0xf4,
-	0x28, 0xae, 0xc9, 0xa6, 0xe1, 0x12, 0x55, 0xff, 0xb1, 0x86, 0x44, 0x37, 0x60, 0x44, 0x6d, 0x39,
-	0x5f, 0x8d, 0x2d, 0xf5, 0xad, 0x86, 0xd5, 0xae, 0x0d, 0x55, 0x83, 0xfa, 0xcf, 0xb0, 0x0f, 0x88,
-	0xca, 0x81, 0x16, 0x1e, 0x92, 0xd0, 0xcf, 0xa6, 0xd0, 0xc2, 0x3d, 0xd5, 0x6e, 0x39, 0x50, 0xbb,
-	0xc3, 0x69, 0x40, 0xa5, 0x62, 0xed, 0xa5, 0x67, 0x85, 0x88, 0xb5, 0x89, 0x9f, 0x1b, 0x40, 0xc4,
-	0x47, 0x18, 0xf7, 0xdf, 0xcf, 0xc2, 0xb4, 0xae, 0xb9, 0xe2, 0x36, 0x1a, 0xb4, 0x22, 0xef, 0x7d,
-	0x4a, 0x8b, 0x67, 0x13, 0xb5, 0xb8, 0xe3, 0xdb, 0x14, 0xea, 0x64, 0x2c, 0xa5, 0xea, 0x4d, 0xc8,
-	0xa3, 0x28, 0xed, 0x08, 0xa5, 0x23, 0x82, 0x59, 0xd2, 0xb5, 0xb4, 0x75, 0x81, 0xbe, 0x6b, 0xc1,
-	0xcc, 0x1e, 0xf5, 0x9c, 0x1d, 0xa7, 0x22, 0xf7, 0xe3, 0x55, 0x87, 0x71, 0xd7, 0xdb, 0xd7, 0xe7,
-	0xe6, 0x2b, 0xfd, 0x71, 0xbe, 0x6e, 0x00, 0xac, 0xb7, 0x76, 0xdc, 0xd2, 0xa3, 0x9a, 0xdb, 0xcc,
-	0xf5, 0x6e, 0x68, 0x9c, 0xc4, 0x6f, 0xbe, 0x0d, 0x10, 0xf6, 0x36, 0x41, 0x1d, 0x6c, 0x98, 0x9b,
-	0xb7, 0xef, 0x8e, 0xf9, 0x83, 0xf5, 0x75, 0xa7, 0xa9, 0x46, 0x3e, 0xb5, 0xa0, 0xa0, 0xe9, 0x67,
-	0x60, 0x26, 0xe2, 0xa8, 0x99, 0xf8, 0x7c, 0xaa, 0xfe, 0xf7, 0xb0, 0x0c, 0x3d, 0x18, 0x8f, 0x6c,
-	0x72, 0xf4, 0xb2, 0xf6, 0xa3, 0x2a, 0x1d, 0xf8, 0xff, 0x4d, 0x3f, 0xea, 0xbd, 0x83, 0xc5, 0xe9,
-	0x48, 0xe5, 0xd0, 0xb9, 0x7a, 0xb4, 0x5f, 0xe1, 0xf5, 0xd1, 0x1f, 0xfc, 0xd5, 0xe2, 0xb9, 0x8f,
-	0x7e, 0xf1, 0xf8, 0x39, 0xfb, 0x93, 0x2c, 0x4c, 0xc5, 0xa5, 0xda, 0x87, 0xee, 0x0d, 0x75, 0xd8,
-	0xe8, 0xa9, 0xea, 0xb0, 0xcc, 0xe9, 0xe9, 0xb0, 0xec, 0x69, 0xe8, 0xb0, 0xa1, 0x13, 0xd3, 0x61,
-	0xf6, 0x3f, 0x5b, 0x30, 0x11, 0xcc, 0xcc, 0x9d, 0x8e, 0xb0, 0x3f, 0x42, 0xa9, 0x5b, 0x27, 0x2f,
-	0xf5, 0xdb, 0x30, 0xc2, 0xdc, 0x8e, 0x57, 0x91, 0x46, 0xb6, 0x40, 0x7f, 0x29, 0x9d, 0xd2, 0x54,
-	0x6d, 0x0d, 0xcb, 0x52, 0x15, 0x60, 0x1f, 0xd5, 0xfe, 0x34, 0x13, 0x0c, 0x48, 0xd3, 0x94, 0xe1,
-	0xe5, 0x09, 0xb3, 0x54, 0x0c, 0x68, 0xd4, 0x34, 0xbc, 0x44, 0x29, 0xd6, 0x54, 0x64, 0x4b, 0x7d,
-	0xee, 0xdb, 0xff, 0xf9, 0x12, 0x68, 0xb5, 0x2c, 0x27, 0x41, 0x51, 0x50, 0x1b, 0xa6, 0x3c, 0x7a,
-	0xa7, 0xe3, 0x78, 0xb4, 0x5a, 0x76, 0xc9, 0xae, 0x30, 0x5a, 0xb4, 0x83, 0xa7, 0xcf, 0x7d, 0xbf,
-	0xda, 0xf1, 0xa4, 0x0a, 0x2b, 0xcd, 0x8a, 0xbb, 0x37, 0x8e, 0x61, 0xe1, 0x2e, 0x74, 0xe4, 0xc2,
-	0x2c, 0xd9, 0x23, 0x4e, 0x83, 0x6c, 0x3b, 0x0d, 0x87, 0xef, 0x97, 0xb9, 0x47, 0x38, 0xad, 0xed,
-	0x6b, 0x13, 0xfb, 0x0d, 0x3d, 0x96, 0xd9, 0xe5, 0x84, 0x3a, 0xf7, 0x0e, 0x16, 0x1f, 0xd5, 0xb2,
-	0x48, 0x22, 0xe3, 0x44, 0x60, 0xfb, 0x67, 0x23, 0x81, 0x86, 0xd0, 0x8e, 0x8e, 0x0f, 0xa1, 0x50,
-	0x51, 0x97, 0xc9, 0xc6, 0xfe, 0x7a, 0x4b, 0xaf, 0xe9, 0xd5, 0x01, 0x4e, 0xbb, 0xe2, 0x4a, 0x08,
-	0x13, 0xb3, 0x42, 0x0d, 0x0a, 0x36, 0xb9, 0xa1, 0x0f, 0x00, 0x94, 0xea, 0xa7, 0xd5, 0xf5, 0x96,
-	0x3e, 0xdb, 0x56, 0x06, 0xe1, 0x7d, 0x3d, 0x40, 0x51, 0xac, 0x03, 0x23, 0x2b, 0x24, 0x60, 0x83,
-	0x95, 0x18, 0xb5, 0x1f, 0xde, 0xb9, 0xec, 0x7a, 0x5a, 0x49, 0x0c, 0x34, 0xea, 0xe5, 0x10, 0x26,
-	0x6e, 0x7b, 0x87, 0x14, 0x6c, 0x72, 0x43, 0xae, 0x71, 0xae, 0xa8, 0xed, 0xbe, 0x3c, 0x08, 0x67,
-	0x3f, 0x54, 0xa9, 0xd8, 0x06, 0x47, 0x8d, 0x5f, 0x1c, 0x1e, 0x35, 0xf3, 0x1e, 0x4c, 0xc5, 0x27,
-	0x27, 0xe1, 0x40, 0xbd, 0x1a, 0x3d, 0x50, 0x2f, 0xf4, 0xa9, 0x82, 0x0c, 0x4f, 0x84, 0x19, 0xd1,
-	0xf4, 0x60, 0x32, 0x36, 0x29, 0x09, 0x2c, 0xd7, 0xa3, 0x2c, 0x5f, 0x4c, 0x63, 0x5c, 0xe8, 0xb8,
-	0x9f, 0xc9, 0x93, 0xc1, 0x54, 0x7c, 0x3a, 0x4e, 0x8c, 0x69, 0x24, 0xd8, 0x68, 0x32, 0xfd, 0x10,
-	0xc6, 0x23, 0x33, 0x91, 0xc0, 0x71, 0x2b, 0xca, 0xf1, 0x92, 0xa1, 0x4d, 0xc2, 0xcc, 0x82, 0xdb,
-	0x41, 0xea, 0x41, 0xa8, 0x58, 0x22, 0x15, 0x84, 0x86, 0x79, 0xab, 0x7c, 0xed, 0x6d, 0xd3, 0x64,
-	0xf9, 0x8b, 0x0c, 0xe4, 0x83, 0x43, 0x2b, 0x4d, 0xe4, 0x40, 0x19, 0x9b, 0x99, 0x23, 0x5c, 0x06,
-	0xd9, 0x7e, 0x5c, 0x06, 0x43, 0xbd, 0x5d, 0x06, 0x7e, 0x68, 0x33, 0x77, 0xff, 0xd0, 0xa6, 0xe1,
-	0x32, 0x18, 0xe9, 0xdf, 0x65, 0x30, 0x7a, 0xb4, 0xcb, 0xc0, 0xfe, 0x6b, 0x0b, 0x50, 0xb7, 0x7f,
-	0x28, 0x8d, 0xa0, 0x48, 0xdc, 0x94, 0x78, 0x25, 0xed, 0x65, 0xfd, 0x28, 0x8b, 0xc2, 0xbe, 0x0b,
-	0x8f, 0x5e, 0x71, 0xf8, 0xd5, 0xce, 0xf6, 0x99, 0xc7, 0xf5, 0x14, 0xe7, 0x0d, 0x72, 0xf6, 0x9c,
-	0xbf, 0x9b, 0x83, 0xc9, 0x2b, 0xce, 0xc0, 0x81, 0x2f, 0x0e, 0x0f, 0x2b, 0xe9, 0x95, 0xa9, 0xbe,
-	0xda, 0x04, 0x67, 0xa7, 0x5a, 0xd3, 0xaf, 0xeb, 0xa6, 0x0f, 0xaf, 0x24, 0x57, 0xbb, 0xd7, 0x9b,
-	0x84, 0x7b, 0x41, 0xf7, 0xbd, 0x31, 0xde, 0x80, 0x71, 0xc6, 0x3d, 0xa7, 0xc2, 0x55, 0x68, 0x8d,
-	0xcd, 0x15, 0xa4, 0x6d, 0x72, 0x5e, 0x57, 0x1f, 0x2f, 0x9b, 0x44, 0x1c, 0xad, 0x9b, 0x18, 0xb1,
-	0x1b, 0x4a, 0x1d, 0xb1, 0x5b, 0x82, 0x3c, 0x69, 0x34, 0xdc, 0x0f, 0xb6, 0x48, 0x8d, 0x69, 0x3f,
-	0x5c, 0x30, 0x21, 0xcb, 0x3e, 0x01, 0x87, 0x75, 0x50, 0x11, 0xc0, 0xa9, 0xb5, 0x5c, 0x8f, 0xca,
-	0x16, 0x39, 0x69, 0x24, 0xc9, 0x94, 0x88, 0xf5, 0xa0, 0x14, 0x1b, 0x35, 0x44, 0x37, 0x69, 0xe0,
-	0x73, 0xb9, 0xec, 0x34, 0xc4, 0x8e, 0x1c, 0x8b, 0x76, 0x73, 0x2d, 0x46, 0xc7, 0x5d, 0x2d, 0x50,
-	0x19, 0xce, 0x3b, 0x2d, 0x46, 0x2b, 0x1d, 0x8f, 0x96, 0x77, 0x9d, 0xf6, 0xd6, 0x46, 0x59, 0x2a,
-	0xf7, 0x7d, 0xa9, 0x07, 0x46, 0x4b, 0x8f, 0x69, 0xa8, 0xf3, 0xeb, 0x49, 0x95, 0x70, 0x72, 0x5b,
-	0xf4, 0x12, 0x8c, 0x39, 0xad, 0x4a, 0xa3, 0x53, 0xa5, 0x9b, 0x84, 0xd7, 0xd9, 0xdc, 0xa8, 0x1c,
-	0xcc, 0xd4, 0xe1, 0xc1, 0xe2, 0xd8, 0xba, 0x51, 0x8e, 0x23, 0xb5, 0x44, 0x2b, 0x7a, 0xd7, 0x68,
-	0x95, 0x0f, 0x5b, 0xad, 0xdd, 0x35, 0x5b, 0x99, 0xb5, 0x12, 0x22, 0xa3, 0x90, 0x2a, 0x32, 0xfa,
-	0xa3, 0x0c, 0xe4, 0x54, 0x56, 0x04, 0x7a, 0x39, 0x96, 0x7a, 0xf0, 0x58, 0x57, 0xea, 0x41, 0x21,
-	0x29, 0x83, 0xc4, 0x86, 0x9c, 0xc3, 0x58, 0x27, 0x6a, 0xd9, 0xae, 0xcb, 0x12, 0xac, 0x29, 0xd2,
-	0x33, 0x2d, 0xb7, 0xb4, 0x76, 0xdb, 0x1d, 0xf3, 0x04, 0x52, 0x3c, 0x94, 0x92, 0xc0, 0x1a, 0x59,
-	0xf0, 0x70, 0x3b, 0xbc, 0xdd, 0xe1, 0x72, 0xb9, 0x9d, 0x10, 0x8f, 0x6b, 0x12, 0x11, 0x6b, 0x64,
-	0xfb, 0x13, 0x0b, 0x26, 0x95, 0x0c, 0x56, 0xea, 0xb4, 0xb2, 0x5b, 0xe6, 0xb4, 0x2d, 0xae, 0x9a,
-	0x1d, 0x46, 0x59, 0xfc, 0xaa, 0xf9, 0x0e, 0xa3, 0x0c, 0x4b, 0x8a, 0x31, 0xfa, 0xcc, 0x69, 0x8d,
-	0xde, 0xbe, 0x08, 0xc6, 0xe4, 0xc8, 0xb4, 0x1e, 0x95, 0xdd, 0xa2, 0xec, 0x80, 0x6c, 0xa8, 0xca,
-	0x54, 0xad, 0x7d, 0xec, 0xd3, 0xed, 0xc3, 0x0c, 0x0c, 0xcb, 0xdb, 0x60, 0x1a, 0xfd, 0x17, 0x75,
-	0xdf, 0x66, 0xfa, 0x72, 0xdf, 0x1e, 0xe1, 0xe1, 0x0f, 0x5d, 0xd8, 0x43, 0xf7, 0x75, 0x61, 0xb3,
-	0x24, 0x0f, 0xf6, 0x9b, 0x29, 0x2e, 0xc1, 0x83, 0xa4, 0xd6, 0x1d, 0xd7, 0x43, 0xfc, 0x4b, 0x0b,
-	0x66, 0x93, 0x62, 0x39, 0x69, 0x64, 0xfe, 0x1c, 0x8c, 0xb6, 0x1b, 0x84, 0xef, 0xb8, 0x5e, 0x33,
-	0x9e, 0xdc, 0xb3, 0xa9, 0xcb, 0x71, 0x50, 0x03, 0x79, 0x00, 0x9e, 0x7f, 0x16, 0xfa, 0xae, 0x82,
-	0x4b, 0xc7, 0xf3, 0xf3, 0x87, 0x33, 0x1c, 0x14, 0x31, 0x6c, 0x70, 0xb1, 0xff, 0x78, 0x18, 0xa6,
-	0x65, 0x93, 0x41, 0x8f, 0xd5, 0x41, 0x96, 0x55, 0x1b, 0x1e, 0x92, 0x4e, 0x8c, 0xee, 0x93, 0x58,
-	0xad, 0xb4, 0x8b, 0xba, 0xfd, 0x43, 0xeb, 0x89, 0xb5, 0xee, 0xf5, 0xa4, 0xe0, 0x1e, 0xb8, 0xdd,
-	0xc7, 0x2b, 0xfc, 0xdf, 0x3b, 0x5e, 0xcd, 0xc5, 0x36, 0x72, 0xe4, 0x62, 0xeb, 0x79, 0x8c, 0x8e,
-	0x1e, 0xe3, 0x18, 0xed, 0x3e, 0xda, 0xf2, 0xa9, 0x8e, 0xb6, 0xbf, 0xcc, 0xc0, 0xc8, 0xa6, 0xe7,
-	0xca, 0x98, 0xe0, 0xe9, 0x07, 0x4e, 0xde, 0x19, 0x30, 0x97, 0x40, 0x40, 0x19, 0xe9, 0x3e, 0xa3,
-	0xb1, 0x54, 0x9f, 0x9b, 0xb1, 0x54, 0x9f, 0x17, 0x53, 0x01, 0x1f, 0x11, 0x07, 0xf8, 0x71, 0x06,
-	0xc6, 0x23, 0x5d, 0x78, 0x80, 0x73, 0x2e, 0x62, 0x72, 0x3a, 0xc1, 0xb4, 0xa8, 0x28, 0xf8, 0xd1,
-	0x69, 0x51, 0x91, 0xfa, 0x0f, 0x6c, 0x5a, 0x54, 0xa4, 0x97, 0x3d, 0xdc, 0xf5, 0xdf, 0xcb, 0xc4,
-	0x46, 0x23, 0xd3, 0xa2, 0x7e, 0x17, 0xa6, 0xdb, 0x7e, 0x16, 0xc8, 0xa6, 0xdb, 0x70, 0x2a, 0x0e,
-	0xf5, 0xe3, 0x3e, 0x2f, 0xa7, 0x4c, 0x91, 0x91, 0xcd, 0xf7, 0x4b, 0x8f, 0x68, 0xee, 0xd3, 0x9b,
-	0x71, 0x5c, 0xdc, 0xcd, 0x0a, 0x31, 0xc8, 0x7b, 0xb1, 0x6c, 0xa4, 0x53, 0x4a, 0xc7, 0x0a, 0xf9,
-	0xd8, 0xbf, 0xb2, 0x60, 0x26, 0x61, 0x21, 0x9c, 0x4d, 0x1e, 0x16, 0xef, 0x1e, 0xf1, 0x69, 0xe5,
-	0x5f, 0x19, 0x43, 0xfe, 0xd4, 0x82, 0x82, 0x1e, 0xf2, 0x03, 0x1b, 0x6e, 0xd2, 0xfd, 0xeb, 0xb1,
-	0x7e, 0xbf, 0xb0, 0x60, 0xcc, 0xd0, 0x74, 0x0c, 0xd5, 0x01, 0x3e, 0x20, 0x1e, 0xad, 0xbb, 0x81,
-	0x45, 0xde, 0x77, 0x10, 0xe0, 0x5d, 0xbf, 0x9d, 0x44, 0x0a, 0xa7, 0x2c, 0x28, 0x67, 0xd8, 0xc0,
-	0x46, 0xdf, 0x32, 0xfc, 0xf9, 0x4a, 0x4d, 0xf6, 0xc5, 0x45, 0x7a, 0xef, 0x14, 0x07, 0x53, 0xc5,
-	0x18, 0x51, 0x00, 0xfb, 0x27, 0x56, 0xa0, 0x94, 0x13, 0xd7, 0x60, 0xf6, 0x74, 0xd6, 0x60, 0x19,
-	0x86, 0x85, 0x8e, 0xf3, 0x53, 0xdf, 0x2f, 0xa4, 0x3e, 0x67, 0x98, 0x4e, 0xe6, 0x12, 0x3f, 0xb1,
-	0xc2, 0xb2, 0x7f, 0x98, 0x81, 0x7c, 0xb0, 0xe7, 0xcf, 0xfc, 0x10, 0x7e, 0x31, 0xa5, 0xb6, 0xea,
-	0x79, 0xb0, 0xdc, 0x8a, 0x1d, 0x2c, 0x69, 0xd5, 0xe0, 0x11, 0x87, 0xca, 0x3f, 0xa8, 0x19, 0x57,
-	0x75, 0xcf, 0x60, 0x2b, 0x6e, 0x45, 0xb7, 0xe2, 0x52, 0xca, 0xd1, 0xf4, 0xd8, 0x8c, 0x1f, 0x65,
-	0x60, 0x32, 0xa6, 0xf8, 0xd1, 0x13, 0x72, 0x51, 0xd5, 0xfc, 0x38, 0x6c, 0xd0, 0x50, 0x3b, 0xb1,
-	0x25, 0x0d, 0xed, 0x09, 0x73, 0x3a, 0x30, 0xb4, 0x5d, 0x4f, 0x0b, 0xf9, 0x6b, 0x03, 0x9d, 0x35,
-	0x3e, 0x48, 0x69, 0x5a, 0x59, 0xe2, 0x06, 0x2e, 0x8e, 0xb2, 0x41, 0x9b, 0x30, 0x4b, 0x3a, 0xdc,
-	0x0d, 0x00, 0xd6, 0x5a, 0x64, 0xbb, 0x41, 0x95, 0x53, 0x7a, 0xb4, 0xf4, 0xff, 0x82, 0xe0, 0x57,
-	0x42, 0x1d, 0x9c, 0xd8, 0xd2, 0xfe, 0x1b, 0x0b, 0x1e, 0xee, 0xd1, 0x9f, 0x3e, 0x22, 0xd2, 0x0d,
-	0x18, 0x97, 0x8f, 0xc9, 0x02, 0x39, 0xf8, 0xab, 0xb8, 0xbf, 0x99, 0x37, 0x9b, 0xaa, 0xd1, 0x47,
-	0x8a, 0x70, 0x14, 0xdc, 0xfe, 0x69, 0x06, 0x50, 0xd0, 0xd7, 0x34, 0x81, 0xf3, 0x5b, 0x30, 0xb2,
-	0xa3, 0xe2, 0x40, 0xc7, 0xcb, 0x7c, 0x28, 0x15, 0xcc, 0xe4, 0x0f, 0x1f, 0x13, 0xbd, 0x77, 0x32,
-	0x7b, 0x0d, 0xba, 0xf7, 0x19, 0xba, 0x01, 0xb0, 0xe3, 0xb4, 0x1c, 0x56, 0x1f, 0x30, 0x81, 0x4c,
-	0xde, 0x97, 0x2e, 0x07, 0x08, 0xd8, 0x40, 0xb3, 0xff, 0x2c, 0x63, 0xec, 0x61, 0x69, 0x46, 0xf5,
-	0xb5, 0xf6, 0x9f, 0x89, 0x0a, 0x33, 0xdf, 0x9d, 0x15, 0x13, 0x08, 0xe6, 0x06, 0x0c, 0xed, 0x11,
-	0xcf, 0x0f, 0xd0, 0xf7, 0x99, 0x9b, 0xda, 0x9d, 0x96, 0x16, 0xce, 0xe9, 0x75, 0xe2, 0x31, 0x2c,
-	0x31, 0x85, 0x89, 0xc9, 0x38, 0x6d, 0xfb, 0x87, 0x4b, 0x6a, 0xc5, 0xc9, 0x69, 0xdb, 0x1c, 0x20,
-	0x6d, 0xcb, 0x13, 0x80, 0xb6, 0x99, 0xfd, 0xfd, 0x11, 0x43, 0x2b, 0xe8, 0xf3, 0xec, 0x2d, 0x40,
-	0x0d, 0xc2, 0xf8, 0x55, 0xd2, 0xaa, 0x8a, 0xbd, 0x44, 0x77, 0x3c, 0xca, 0xea, 0xfa, 0x12, 0x3c,
-	0xaf, 0x51, 0xd0, 0x46, 0x57, 0x0d, 0x9c, 0xd0, 0x0a, 0xbd, 0xec, 0x3f, 0x06, 0x54, 0x52, 0x5e,
-	0x8c, 0x3c, 0x06, 0xbc, 0x77, 0xb0, 0x38, 0x11, 0xee, 0x47, 0xe3, 0x79, 0x60, 0x8a, 0x67, 0x6f,
-	0xe6, 0x7a, 0x1f, 0x3e, 0x85, 0xf5, 0xfe, 0x3b, 0x30, 0xbd, 0x13, 0x4f, 0x93, 0xd2, 0xa9, 0xa5,
-	0xaf, 0x0e, 0x98, 0x65, 0x55, 0x3a, 0x7f, 0x18, 0xe6, 0xd6, 0x84, 0xc5, 0xb8, 0x9b, 0x11, 0x72,
-	0xfd, 0xc7, 0x76, 0xd2, 0x9f, 0xa9, 0x5c, 0xd5, 0x7d, 0xef, 0xb9, 0x98, 0x27, 0x34, 0xfe, 0xcc,
-	0x4e, 0x41, 0xe2, 0x08, 0x83, 0xd8, 0x1e, 0xcc, 0x9d, 0xe4, 0x1e, 0x44, 0x2f, 0x07, 0xa9, 0x04,
-	0xa2, 0x3b, 0xd2, 0x5b, 0x90, 0xed, 0x4a, 0x02, 0x10, 0x24, 0x6c, 0xd6, 0x43, 0x1f, 0x5b, 0x70,
-	0x5e, 0x2c, 0xd6, 0xb5, 0xbb, 0xb4, 0xd2, 0x11, 0x52, 0xf1, 0xc3, 0xa9, 0x73, 0x85, 0x34, 0x97,
-	0x8f, 0x72, 0x12, 0x44, 0xe8, 0xfa, 0x48, 0x24, 0xe3, 0x64, 0xc6, 0xe8, 0xb6, 0x32, 0xc6, 0xa8,
-	0xf4, 0x2c, 0x1d, 0xdf, 0x61, 0x1c, 0x18, 0x66, 0x4a, 0xef, 0x70, 0x6a, 0xff, 0x70, 0xc8, 0x54,
-	0x57, 0xfd, 0xb9, 0xb1, 0x6f, 0xc0, 0x10, 0x27, 0x6c, 0x57, 0xef, 0x82, 0x37, 0x07, 0x78, 0x2d,
-	0x11, 0xee, 0x05, 0xe9, 0xe6, 0x90, 0x45, 0x12, 0x13, 0xcd, 0x43, 0x86, 0xb0, 0x78, 0x38, 0x78,
-	0x99, 0xe1, 0x0c, 0x61, 0x32, 0x54, 0xbc, 0xa3, 0x9d, 0x50, 0x61, 0xa8, 0x78, 0x07, 0x67, 0x9c,
-	0x1d, 0xb4, 0x0c, 0x93, 0x15, 0xb7, 0xc5, 0x9d, 0x56, 0x87, 0x5e, 0x6b, 0xad, 0x79, 0x9e, 0xeb,
-	0x69, 0x97, 0xd3, 0xc3, 0xba, 0xe2, 0xe4, 0x4a, 0x94, 0x8c, 0xe3, 0xf5, 0xd1, 0x7b, 0x30, 0xec,
-	0x51, 0xee, 0xed, 0xeb, 0x03, 0xe1, 0xe2, 0x00, 0xba, 0x0f, 0x8b, 0xf6, 0x4a, 0xca, 0xf2, 0x27,
-	0x56, 0x88, 0x81, 0xca, 0xce, 0x9d, 0x82, 0xca, 0x0e, 0x83, 0x0a, 0xd9, 0x53, 0x0b, 0x2a, 0xfc,
-	0xc8, 0x32, 0x6c, 0x84, 0x60, 0xa0, 0xe8, 0x1d, 0x18, 0xe1, 0x4e, 0x93, 0xba, 0x1d, 0x9e, 0xce,
-	0x38, 0x0d, 0xd2, 0x93, 0xa4, 0x26, 0xdc, 0x52, 0x10, 0xd8, 0xc7, 0x42, 0x97, 0x60, 0x82, 0x8a,
-	0x19, 0xd9, 0xaa, 0x0b, 0xcd, 0xee, 0x36, 0x94, 0x25, 0x36, 0x1e, 0xfa, 0xfb, 0xd6, 0x22, 0x54,
-	0x1c, 0xab, 0x6d, 0xff, 0xd4, 0x34, 0xa3, 0xff, 0xf7, 0xbf, 0x20, 0xd2, 0xae, 0xa6, 0x33, 0x7d,
-	0x3a, 0x34, 0xb0, 0xab, 0xe9, 0xc8, 0x37, 0x43, 0xef, 0xc3, 0x43, 0xc9, 0xaa, 0xe0, 0x44, 0x1e,
-	0xe3, 0xff, 0x24, 0x2e, 0x2b, 0x69, 0x81, 0xf9, 0xdb, 0xcf, 0x3a, 0x4d, 0x8b, 0x29, 0x73, 0xd2,
-	0x16, 0x93, 0x67, 0x0e, 0x45, 0x7f, 0xba, 0x00, 0xdd, 0xd2, 0xeb, 0xcc, 0x4a, 0xf3, 0x18, 0xbe,
-	0x0b, 0xa6, 0xe7, 0x5a, 0xfb, 0x99, 0x05, 0xe7, 0x13, 0x6b, 0x07, 0x32, 0xcc, 0x9c, 0xa6, 0x0c,
-	0xad, 0x93, 0x96, 0xe1, 0x1e, 0x3c, 0xf2, 0xcd, 0x0e, 0xd9, 0x3f, 0xf3, 0xac, 0x92, 0x1f, 0x64,
-	0x60, 0x0a, 0xd3, 0xb6, 0x1b, 0x89, 0x7f, 0x6d, 0xfa, 0x6f, 0xca, 0x52, 0x5c, 0x67, 0x62, 0xa9,
-	0x29, 0xa5, 0x91, 0xc8, 0x63, 0x32, 0xb1, 0x4d, 0x9b, 0xbe, 0xed, 0xda, 0xb7, 0xda, 0xe9, 0x8a,
-	0xcc, 0xa9, 0x13, 0x4b, 0xc5, 0xf8, 0x14, 0xa0, 0x40, 0x96, 0xc9, 0xbb, 0xfa, 0x50, 0x79, 0x35,
-	0x45, 0x1a, 0x70, 0x37, 0xb2, 0x2c, 0xc6, 0x0a, 0xd0, 0xfe, 0x24, 0x03, 0xea, 0xea, 0x73, 0x06,
-	0x5a, 0xf9, 0x9b, 0x11, 0xad, 0xbc, 0x94, 0xc6, 0x35, 0xd7, 0xcb, 0x05, 0x14, 0xbf, 0x96, 0xbe,
-	0x90, 0xd2, 0xdf, 0x77, 0x1f, 0xf7, 0xcf, 0xdf, 0x5b, 0x90, 0x97, 0xf5, 0xce, 0x40, 0xc1, 0x6f,
-	0x46, 0x15, 0xfc, 0xb3, 0x29, 0x46, 0xd1, 0x43, 0xb1, 0xff, 0x2a, 0xab, 0x7b, 0x1f, 0x5c, 0x7a,
-	0xeb, 0xc4, 0xab, 0xea, 0xdb, 0x5c, 0xb8, 0x3b, 0x45, 0x21, 0x56, 0xb4, 0x40, 0xa7, 0x8c, 0x9c,
-	0x82, 0x4e, 0xf9, 0x6d, 0x95, 0x43, 0x4d, 0x19, 0xa7, 0xd5, 0xcb, 0xc1, 0xb5, 0x2d, 0x9b, 0x3a,
-	0x19, 0x5c, 0x27, 0xac, 0x87, 0x9e, 0x74, 0x1c, 0x43, 0xc5, 0x5d, 0x7c, 0xc4, 0x55, 0xae, 0x1d,
-	0x57, 0xa2, 0xfa, 0x8a, 0xf3, 0xea, 0x80, 0x1a, 0x5b, 0x5d, 0xe5, 0xba, 0x8a, 0x71, 0x37, 0x23,
-	0x54, 0x87, 0x31, 0xf3, 0x19, 0x8b, 0x5e, 0xa7, 0x17, 0xd2, 0xbf, 0x97, 0x51, 0x39, 0x47, 0x66,
-	0x09, 0x8e, 0x20, 0xdb, 0x7f, 0x62, 0x01, 0x84, 0x8e, 0x6c, 0x31, 0xe7, 0x15, 0xb7, 0xd3, 0x52,
-	0x1e, 0x8c, 0x6c, 0x38, 0xe7, 0x2b, 0xa2, 0x10, 0x2b, 0x9a, 0xd8, 0x3f, 0xea, 0x1e, 0xa8, 0x17,
-	0xf5, 0x0b, 0x69, 0xae, 0x98, 0x31, 0x87, 0xb9, 0x2a, 0xc4, 0x1a, 0xd0, 0xfe, 0x28, 0x07, 0x05,
-	0x63, 0x9f, 0xc5, 0xdc, 0xe5, 0xe3, 0xa7, 0xe3, 0x2e, 0x4f, 0xf6, 0x61, 0x14, 0x06, 0xf2, 0x61,
-	0x30, 0x98, 0xd0, 0x37, 0x73, 0xff, 0xad, 0x93, 0xf2, 0xf1, 0x0c, 0x7c, 0xff, 0x47, 0xc2, 0x5a,
-	0xbe, 0x1c, 0x81, 0xc4, 0x31, 0x16, 0xc2, 0xda, 0xd6, 0x25, 0xe5, 0x4e, 0xb3, 0x49, 0xbc, 0x7d,
-	0x9d, 0x3d, 0x17, 0x58, 0xdb, 0x97, 0x23, 0x54, 0x1c, 0xab, 0x8d, 0x36, 0x83, 0x09, 0x55, 0xef,
-	0x67, 0x9e, 0x4b, 0x33, 0xa1, 0xea, 0xb6, 0x11, 0x9d, 0x47, 0x21, 0x52, 0x77, 0x5b, 0x5e, 0x56,
-	0xaa, 0x57, 0xd4, 0x27, 0xc4, 0xc4, 0x32, 0xce, 0xc9, 0x45, 0x15, 0x88, 0xf4, 0x5a, 0x57, 0x0d,
-	0x9c, 0xd0, 0x4a, 0xa8, 0x01, 0x7d, 0xc5, 0x0f, 0xf6, 0x8e, 0x76, 0xaa, 0xa4, 0xbd, 0xdf, 0x85,
-	0x47, 0xbf, 0x7c, 0x54, 0xb1, 0x12, 0x43, 0xc5, 0x5d, 0x7c, 0xd0, 0x1d, 0x18, 0x17, 0x93, 0x1c,
-	0x32, 0x86, 0x63, 0x32, 0xd6, 0xce, 0x5c, 0x03, 0x12, 0x47, 0x39, 0xd8, 0x5f, 0x64, 0x21, 0xd9,
-	0xc1, 0x10, 0xbe, 0xe7, 0xb4, 0xee, 0xf3, 0x9e, 0xf3, 0x5d, 0xc8, 0x33, 0x4e, 0x3c, 0xf5, 0xb0,
-	0x36, 0x33, 0xd8, 0xc3, 0xda, 0xb2, 0x0f, 0x80, 0x43, 0xac, 0x98, 0xb7, 0x27, 0x7b, 0xa2, 0xde,
-	0x9e, 0x0b, 0x00, 0xf2, 0x02, 0x28, 0xd5, 0x8c, 0x3c, 0x6f, 0xc6, 0xc3, 0x5d, 0xbb, 0x16, 0x50,
-	0xb0, 0x51, 0x0b, 0x7d, 0x2d, 0x38, 0xc5, 0x55, 0xce, 0xcc, 0xaf, 0x75, 0xa5, 0x38, 0xce, 0x44,
-	0xcc, 0xcb, 0x98, 0x03, 0x39, 0x45, 0x46, 0x79, 0x82, 0x63, 0x62, 0x24, 0x9d, 0x63, 0xc2, 0xfe,
-	0xcf, 0x0c, 0x44, 0xb4, 0x30, 0xfa, 0x9e, 0x05, 0xd3, 0x24, 0xf6, 0x51, 0x33, 0xdf, 0x78, 0xfe,
-	0xcd, 0x74, 0x5f, 0x9a, 0xeb, 0xfa, 0x26, 0x5a, 0x18, 0xa3, 0x8f, 0x57, 0x61, 0xb8, 0x9b, 0x29,
-	0xfa, 0x43, 0x0b, 0x66, 0x48, 0xf7, 0x57, 0xeb, 0xf4, 0xe2, 0x79, 0x6d, 0xe0, 0xcf, 0xde, 0x95,
-	0x1e, 0x3e, 0x3c, 0x58, 0x4c, 0xfa, 0x9e, 0x1f, 0x4e, 0x62, 0x87, 0x6e, 0xc2, 0x10, 0xf1, 0x6a,
-	0xbe, 0xdb, 0x3a, 0x3d, 0x5b, 0xff, 0x63, 0x84, 0xa1, 0x29, 0xb1, 0xec, 0xd5, 0x18, 0x96, 0xa0,
-	0xf6, 0x2f, 0xb2, 0x30, 0x15, 0x7f, 0x47, 0xaa, 0xdf, 0x2d, 0x0c, 0x25, 0xbe, 0x5b, 0x10, 0x7b,
-	0x4d, 0x06, 0x6e, 0xe2, 0x6f, 0xa7, 0x65, 0xfc, 0x45, 0xd1, 0x82, 0xbd, 0x26, 0x5f, 0x77, 0x0d,
-	0x1f, 0x63, 0xaf, 0xc9, 0x27, 0x5d, 0x21, 0x16, 0xba, 0x18, 0xf5, 0x84, 0xdb, 0x71, 0x4f, 0xf8,
-	0xb4, 0x39, 0x96, 0x41, 0x9d, 0xe1, 0x4d, 0x28, 0x18, 0xf3, 0xa0, 0x77, 0xf4, 0xeb, 0xa9, 0xe5,
-	0x1e, 0x2e, 0xbb, 0x49, 0x95, 0x76, 0x19, 0x52, 0x4c, 0xfc, 0x50, 0x7f, 0x48, 0x69, 0x1d, 0xcb,
-	0x5b, 0x2c, 0xc5, 0x65, 0xa0, 0xd9, 0xff, 0x6a, 0xc1, 0x78, 0xe4, 0x25, 0x8f, 0xe0, 0xe6, 0x3f,
-	0xd1, 0x1a, 0xfc, 0x0b, 0x7e, 0xd7, 0x03, 0x04, 0x6c, 0xa0, 0xa1, 0x6f, 0x43, 0xa1, 0xe1, 0xb6,
-	0x6a, 0x94, 0xf1, 0xb2, 0x4b, 0x76, 0xf5, 0x3e, 0x49, 0xeb, 0x37, 0x9b, 0x3b, 0x3c, 0x58, 0x9c,
-	0xdd, 0x50, 0x30, 0x2b, 0x6e, 0xb3, 0xdd, 0xa0, 0x5c, 0x3d, 0xe6, 0xc3, 0x26, 0xb8, 0x8c, 0xba,
-	0x07, 0x69, 0x0b, 0x0f, 0x6a, 0xd4, 0x3d, 0xcc, 0xb7, 0x38, 0xe1, 0xa8, 0x7b, 0x24, 0x91, 0xe3,
-	0x88, 0xa8, 0x7b, 0x50, 0xf7, 0x81, 0x8d, 0xba, 0x07, 0x3d, 0xec, 0x71, 0xfd, 0xfa, 0x8f, 0x8c,
-	0x31, 0x8a, 0xe8, 0x15, 0x2c, 0x73, 0x9f, 0x2b, 0xd8, 0xfb, 0x30, 0xea, 0xb4, 0x38, 0xf5, 0xf6,
-	0x48, 0x43, 0xfb, 0xbd, 0xd3, 0xae, 0xc5, 0x60, 0xa8, 0xeb, 0x1a, 0x07, 0x07, 0x88, 0xa8, 0x01,
-	0xe7, 0xfd, 0x50, 0x93, 0x47, 0x49, 0x18, 0x0c, 0xd7, 0x19, 0xb9, 0xaf, 0xf8, 0x31, 0x91, 0xcb,
-	0x49, 0x95, 0xee, 0xf5, 0x22, 0xe0, 0x64, 0x50, 0xc4, 0x60, 0x9c, 0x19, 0xbe, 0x07, 0xff, 0x44,
-	0xec, 0x33, 0x4c, 0x17, 0x77, 0xd7, 0x18, 0x69, 0xbc, 0x26, 0x28, 0x8e, 0xf2, 0xb0, 0x3f, 0xb6,
-	0x60, 0x22, 0x9a, 0x32, 0xf4, 0x3f, 0x7e, 0x0f, 0xfa, 0x22, 0x0b, 0x93, 0xb1, 0xc5, 0x1f, 0xbb,
-	0x0b, 0xe5, 0xcf, 0xf2, 0x2e, 0x94, 0x1b, 0xe8, 0x2e, 0x94, 0x7c, 0x09, 0x18, 0x1a, 0xe8, 0x12,
-	0xf0, 0x86, 0x32, 0xc4, 0xf5, 0x62, 0x5a, 0x5f, 0xd5, 0x2f, 0xf6, 0x82, 0x09, 0xde, 0x30, 0x89,
-	0x38, 0x5a, 0x57, 0x5a, 0x38, 0xd5, 0xee, 0xef, 0x50, 0xe9, 0x5b, 0xc4, 0x6b, 0x69, 0x33, 0xe9,
-	0x03, 0x00, 0x65, 0xe1, 0x24, 0x10, 0x70, 0x12, 0x3b, 0xfb, 0xe7, 0x59, 0x38, 0x9f, 0xec, 0xc6,
-	0x3c, 0xda, 0x6f, 0x7e, 0x07, 0xf2, 0xdb, 0xfe, 0x27, 0x3b, 0xb5, 0xa9, 0xd1, 0xe7, 0x13, 0xe3,
-	0xfb, 0x7f, 0xe9, 0x53, 0x19, 0x21, 0x41, 0x1d, 0x1c, 0x72, 0x41, 0x14, 0x72, 0x8a, 0x81, 0x3e,
-	0x0c, 0x96, 0xfb, 0x76, 0x77, 0xf6, 0x7a, 0x7e, 0xa8, 0xae, 0x8a, 0xaa, 0x02, 0xd6, 0xe0, 0x9a,
-	0x4d, 0x83, 0x6c, 0xeb, 0xa3, 0xa1, 0x7f, 0x36, 0xbd, 0xde, 0x1a, 0x06, 0x6c, 0x36, 0x88, 0x62,
-	0xd3, 0x20, 0xdb, 0xe8, 0x16, 0x0c, 0xdd, 0xe9, 0x10, 0x3f, 0x32, 0xd8, 0xa7, 0x89, 0xdd, 0xd3,
-	0xf1, 0xac, 0x82, 0x9e, 0x82, 0x8c, 0x25, 0xac, 0xfd, 0x21, 0x3c, 0x94, 0x9c, 0xbf, 0xd9, 0x5f,
-	0x4c, 0xa4, 0x4d, 0xb8, 0xff, 0x10, 0x30, 0xa8, 0xb1, 0x49, 0x78, 0x1d, 0x4b, 0x0a, 0x7a, 0x0c,
-	0xb2, 0x1d, 0xaf, 0x11, 0x7f, 0x1d, 0xfb, 0x0e, 0xde, 0xc0, 0xa2, 0xbc, 0xf4, 0xd6, 0x67, 0x5f,
-	0x2d, 0x9c, 0xfb, 0xfc, 0xab, 0x85, 0x73, 0x5f, 0x7e, 0xb5, 0x70, 0xee, 0xa3, 0xc3, 0x05, 0xeb,
-	0xb3, 0xc3, 0x05, 0xeb, 0xf3, 0xc3, 0x05, 0xeb, 0xcb, 0xc3, 0x05, 0xeb, 0xdf, 0x0e, 0x17, 0xac,
-	0x8f, 0x7f, 0xb9, 0x70, 0xee, 0xc6, 0x93, 0xfd, 0x7c, 0x53, 0xfd, 0xbf, 0x03, 0x00, 0x00, 0xff,
-	0xff, 0xa9, 0x61, 0x09, 0x91, 0x7a, 0x5d, 0x00, 0x00,
+	// 4856 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7c, 0x4d, 0x6c, 0x1c, 0x47,
+	0x76, 0xbf, 0x7a, 0x86, 0x1c, 0x72, 0xde, 0xf0, 0xb3, 0x48, 0xd9, 0x34, 0xfd, 0x37, 0xa9, 0x7f,
+	0xdb, 0x31, 0xec, 0xd8, 0x1e, 0x46, 0xb2, 0x65, 0xcb, 0xb2, 0x57, 0x01, 0x87, 0xa4, 0x24, 0x7a,
+	0xb9, 0x16, 0xb7, 0x86, 0x92, 0xd6, 0x92, 0x05, 0xa5, 0x38, 0x53, 0x9c, 0xe9, 0xe5, 0xcc, 0xf4,
+	0xa8, 0xab, 0x87, 0x16, 0x57, 0x41, 0xe2, 0x6c, 0xb2, 0x81, 0x81, 0x04, 0x81, 0x0f, 0x1b, 0x78,
+	0x0f, 0x09, 0x12, 0x64, 0x4f, 0xc1, 0x02, 0xd9, 0x63, 0x0e, 0x39, 0xf8, 0x90, 0x8b, 0x37, 0xf1,
+	0x06, 0x86, 0x73, 0x88, 0x03, 0x2c, 0x88, 0x98, 0x0b, 0xe4, 0x9c, 0x4b, 0x2e, 0x02, 0x02, 0x04,
+	0xf5, 0xd1, 0xdd, 0xd5, 0x3d, 0x3d, 0x62, 0xf7, 0xf0, 0x63, 0x95, 0xe4, 0x36, 0x53, 0xaf, 0xea,
+	0xf7, 0xea, 0xf3, 0xbd, 0x57, 0xef, 0xbd, 0x6a, 0x78, 0xad, 0x66, 0xb9, 0xf5, 0xce, 0x66, 0xb1,
+	0x62, 0x37, 0x17, 0xc8, 0x76, 0xc7, 0x72, 0x77, 0x17, 0xb6, 0x89, 0x53, 0xb3, 0x17, 0x48, 0xdb,
+	0x5a, 0xd8, 0x39, 0x4b, 0x1a, 0xed, 0x3a, 0x39, 0xbb, 0x50, 0xa3, 0x2d, 0xea, 0x10, 0x97, 0x56,
+	0x8b, 0x6d, 0xc7, 0x76, 0x6d, 0xf4, 0x5c, 0xd0, 0xaa, 0x28, 0x5b, 0x15, 0x45, 0xab, 0x22, 0x69,
+	0x5b, 0x45, 0xaf, 0xd5, 0xec, 0x2b, 0x1a, 0x76, 0xcd, 0xae, 0xd9, 0x0b, 0xa2, 0xf1, 0x66, 0x67,
+	0x4b, 0xfc, 0x13, 0x7f, 0xc4, 0x2f, 0x09, 0x3a, 0x6b, 0x6e, 0x5f, 0x60, 0x45, 0x4b, 0x72, 0xae,
+	0xd8, 0x0e, 0x5d, 0xd8, 0xe9, 0x62, 0x3c, 0x7b, 0x35, 0xa8, 0x43, 0xef, 0xbb, 0xb4, 0xc5, 0x2c,
+	0xbb, 0xc5, 0x5e, 0x21, 0x6d, 0x8b, 0x51, 0x67, 0x87, 0x3a, 0x0b, 0xed, 0xed, 0x1a, 0xa7, 0xb1,
+	0x70, 0x85, 0x38, 0xa4, 0xd7, 0x02, 0xa4, 0x26, 0xa9, 0xd4, 0xad, 0x16, 0x75, 0x76, 0x83, 0xe6,
+	0x4d, 0xea, 0x92, 0xb8, 0x56, 0x0b, 0xbd, 0x5a, 0x39, 0x9d, 0x96, 0x6b, 0x35, 0x69, 0x57, 0x83,
+	0xd7, 0x0f, 0x6a, 0xc0, 0x2a, 0x75, 0xda, 0x24, 0xd1, 0x76, 0xe6, 0xfb, 0x30, 0xb5, 0xd8, 0x22,
+	0x8d, 0x5d, 0x66, 0x31, 0xdc, 0x69, 0x2d, 0x3a, 0xb5, 0x4e, 0x93, 0xb6, 0x5c, 0x74, 0x06, 0x06,
+	0x5a, 0xa4, 0x49, 0x67, 0x8c, 0x33, 0xc6, 0x0b, 0xf9, 0xd2, 0xc8, 0x67, 0x7b, 0xf3, 0xa7, 0xf6,
+	0xf7, 0xe6, 0x07, 0xde, 0x25, 0x4d, 0x8a, 0x05, 0x05, 0x3d, 0x0b, 0x83, 0x3b, 0xa4, 0xd1, 0xa1,
+	0x33, 0x19, 0x51, 0x65, 0x54, 0x55, 0x19, 0xbc, 0xc1, 0x0b, 0xb1, 0xa4, 0x99, 0xbf, 0x9f, 0x0d,
+	0xc1, 0x7f, 0x8b, 0xba, 0xa4, 0x4a, 0x5c, 0x82, 0x9a, 0x90, 0x6b, 0x90, 0x4d, 0xda, 0x60, 0x33,
+	0xc6, 0x99, 0xec, 0x0b, 0x85, 0x73, 0x2b, 0xc5, 0x24, 0x0b, 0x5d, 0x8c, 0x81, 0x2a, 0xae, 0x09,
+	0x9c, 0x95, 0x96, 0xeb, 0xec, 0x96, 0xc6, 0x54, 0x27, 0x72, 0xb2, 0x10, 0x2b, 0x26, 0xe8, 0xf7,
+	0x0c, 0x28, 0x90, 0x56, 0xcb, 0x76, 0x89, 0xcb, 0x97, 0x69, 0x26, 0x23, 0x98, 0xbe, 0xd3, 0x3f,
+	0xd3, 0xc5, 0x00, 0x4c, 0x72, 0x9e, 0x52, 0x9c, 0x0b, 0x1a, 0x05, 0xeb, 0x3c, 0x67, 0xdf, 0x84,
+	0x82, 0xd6, 0x55, 0x34, 0x01, 0xd9, 0x6d, 0xba, 0x2b, 0xe7, 0x17, 0xf3, 0x9f, 0x68, 0x3a, 0x34,
+	0xa1, 0x6a, 0x06, 0x2f, 0x66, 0x2e, 0x18, 0xb3, 0x97, 0x60, 0x22, 0xca, 0x30, 0x4d, 0x7b, 0xf3,
+	0x4f, 0x0c, 0x98, 0xd6, 0x46, 0x81, 0xe9, 0x16, 0x75, 0x68, 0xab, 0x42, 0xd1, 0x02, 0xe4, 0xf9,
+	0x5a, 0xb2, 0x36, 0xa9, 0x78, 0x4b, 0x3d, 0xa9, 0x06, 0x92, 0x7f, 0xd7, 0x23, 0xe0, 0xa0, 0x8e,
+	0xbf, 0x2d, 0x32, 0x8f, 0xda, 0x16, 0xed, 0x3a, 0x61, 0x74, 0x26, 0x1b, 0xde, 0x16, 0xeb, 0xbc,
+	0x10, 0x4b, 0x9a, 0x79, 0x17, 0x9e, 0xf2, 0xfa, 0xb3, 0x41, 0x9b, 0xed, 0x06, 0x71, 0x69, 0xd0,
+	0xa9, 0x83, 0xb7, 0xde, 0x19, 0x18, 0xd8, 0xb6, 0x5a, 0xd5, 0x68, 0x2f, 0xbe, 0x69, 0xb5, 0xaa,
+	0x58, 0x50, 0xcc, 0x6d, 0x18, 0x5d, 0x6c, 0xb7, 0x1d, 0x7b, 0x87, 0x56, 0xcb, 0x2e, 0xa9, 0x51,
+	0x74, 0x0b, 0x80, 0xa8, 0x82, 0x45, 0x57, 0x40, 0x17, 0xce, 0xfd, 0x7a, 0x51, 0x9e, 0x99, 0xa2,
+	0x7e, 0x66, 0x8a, 0xed, 0xed, 0x1a, 0x2f, 0x60, 0x45, 0x7e, 0x34, 0x8b, 0x3b, 0x67, 0x8b, 0x1b,
+	0x56, 0x93, 0x96, 0xc6, 0xf6, 0xf7, 0xe6, 0x61, 0xd1, 0x47, 0xc0, 0x1a, 0x9a, 0xf9, 0x7d, 0x03,
+	0x4e, 0x2f, 0x3a, 0x35, 0x7b, 0x69, 0x79, 0xb1, 0xdd, 0xbe, 0x4a, 0x49, 0xc3, 0xad, 0x97, 0x5d,
+	0xe2, 0x76, 0x18, 0xba, 0x04, 0x39, 0x26, 0x7e, 0xa9, 0xc1, 0x3c, 0xef, 0xed, 0x4f, 0x49, 0x7f,
+	0xb8, 0x37, 0x3f, 0x1d, 0xd3, 0x90, 0x62, 0xd5, 0x0a, 0xbd, 0x08, 0x43, 0x4d, 0xca, 0x18, 0xa9,
+	0x79, 0x33, 0x3e, 0xae, 0x00, 0x86, 0xbe, 0x25, 0x8b, 0xb1, 0x47, 0x37, 0xff, 0x21, 0x03, 0xe3,
+	0x3e, 0x96, 0x62, 0x7f, 0x0c, 0xcb, 0xdb, 0x81, 0x91, 0xba, 0x36, 0x42, 0xb1, 0xca, 0x85, 0x73,
+	0x6f, 0x25, 0x3c, 0x49, 0x71, 0x93, 0x54, 0x9a, 0x56, 0x6c, 0x46, 0xf4, 0x52, 0x1c, 0x62, 0x83,
+	0x9a, 0x00, 0x6c, 0xb7, 0x55, 0x51, 0x4c, 0x07, 0x04, 0xd3, 0x37, 0x53, 0x32, 0x2d, 0xfb, 0x00,
+	0x25, 0xa4, 0x58, 0x42, 0x50, 0x86, 0x35, 0x06, 0xe6, 0xdf, 0x18, 0x30, 0x15, 0xd3, 0x0e, 0xbd,
+	0x1d, 0x59, 0xcf, 0xe7, 0xba, 0xd6, 0x13, 0x75, 0x35, 0x0b, 0x56, 0xf3, 0x65, 0x18, 0x76, 0xe8,
+	0x8e, 0xc5, 0x35, 0x85, 0x9a, 0xe1, 0x09, 0xd5, 0x7e, 0x18, 0xab, 0x72, 0xec, 0xd7, 0x40, 0x2f,
+	0x41, 0xde, 0xfb, 0xcd, 0xa7, 0x39, 0xcb, 0x0f, 0x13, 0x5f, 0x38, 0xaf, 0x2a, 0xc3, 0x01, 0xdd,
+	0x7c, 0x00, 0x73, 0x25, 0xcb, 0xdd, 0xec, 0x54, 0xb6, 0xa9, 0x7b, 0x93, 0x6e, 0xd6, 0x6d, 0x7b,
+	0x1b, 0xd3, 0x0a, 0xb5, 0x76, 0xa8, 0xb3, 0x64, 0xb7, 0xb6, 0xac, 0x1a, 0x7a, 0x0f, 0xf2, 0x8c,
+	0x56, 0x1c, 0xea, 0x62, 0xba, 0xa5, 0xf6, 0xff, 0x0b, 0xda, 0xfe, 0x2f, 0x72, 0x45, 0xc8, 0x77,
+	0xfb, 0x9a, 0x5d, 0x21, 0x8d, 0x6b, 0x9b, 0xdf, 0xa5, 0x15, 0xd7, 0x3f, 0x92, 0xc1, 0xae, 0x29,
+	0x7b, 0x10, 0x38, 0x40, 0x33, 0x7f, 0x17, 0x06, 0x97, 0xea, 0xc4, 0x71, 0xf9, 0x76, 0x75, 0x68,
+	0xdb, 0xbe, 0x8e, 0xd7, 0xd4, 0xfc, 0xf8, 0xdb, 0x15, 0xcb, 0x62, 0xec, 0xd1, 0x13, 0xec, 0xb4,
+	0x17, 0x61, 0x68, 0x87, 0x3a, 0x62, 0xb2, 0xb2, 0x61, 0xb0, 0x1b, 0xb2, 0x18, 0x7b, 0x74, 0xf3,
+	0x9f, 0x0d, 0x98, 0x16, 0x3d, 0x58, 0xb6, 0x58, 0xc5, 0xde, 0xa1, 0xce, 0x2e, 0xa6, 0xac, 0xd3,
+	0x38, 0xe2, 0x0e, 0x2d, 0xc3, 0x04, 0xa3, 0x4d, 0x39, 0xa3, 0xcc, 0x75, 0x88, 0xd5, 0x72, 0x55,
+	0xcf, 0x66, 0x54, 0xed, 0x89, 0x72, 0x84, 0x8e, 0xbb, 0x5a, 0xa0, 0x17, 0x60, 0x58, 0x75, 0x9b,
+	0xef, 0x63, 0xbe, 0xaa, 0x23, 0x7c, 0x03, 0xa8, 0x31, 0x31, 0xec, 0x53, 0xcd, 0x7f, 0x37, 0x60,
+	0x52, 0x8c, 0xaa, 0xdc, 0xd9, 0x64, 0x15, 0xc7, 0x6a, 0x73, 0xe9, 0xff, 0x38, 0x0e, 0xe9, 0x12,
+	0x8c, 0x55, 0xbd, 0x89, 0x5f, 0xb3, 0x9a, 0x96, 0x2b, 0x0e, 0xe8, 0x60, 0xe9, 0x09, 0x85, 0x31,
+	0xb6, 0x1c, 0xa2, 0xe2, 0x48, 0x6d, 0xf3, 0xa7, 0x19, 0x18, 0x5d, 0x6a, 0x74, 0x98, 0xeb, 0x6f,
+	0xd6, 0xdf, 0x82, 0xe1, 0xa6, 0x52, 0xb5, 0x6a, 0xaf, 0xfe, 0x46, 0x32, 0x59, 0x2d, 0x37, 0x2e,
+	0x57, 0xd3, 0xc1, 0x19, 0x0f, 0xca, 0xb0, 0x8f, 0x8a, 0xde, 0x83, 0x01, 0xd6, 0xa6, 0x15, 0x31,
+	0x37, 0x85, 0x73, 0x6f, 0x24, 0x13, 0x25, 0xa1, 0x4e, 0x96, 0xdb, 0xb4, 0x12, 0x4c, 0x2a, 0xff,
+	0x87, 0x05, 0x24, 0x22, 0xbe, 0x90, 0xc8, 0xa6, 0x91, 0x53, 0x61, 0x70, 0x29, 0xa7, 0xc6, 0xc2,
+	0xf2, 0xc5, 0x93, 0x24, 0xe6, 0x3f, 0xf2, 0xad, 0xa1, 0xd7, 0x5f, 0xb3, 0x98, 0x8b, 0xde, 0xef,
+	0x9a, 0xb5, 0x62, 0xb2, 0x59, 0xe3, 0xad, 0xc5, 0x9c, 0xf9, 0xf2, 0xc8, 0x2b, 0xd1, 0x66, 0xec,
+	0x3b, 0x30, 0x68, 0xb9, 0xb4, 0xe9, 0x19, 0x4f, 0xaf, 0xf6, 0x31, 0xaa, 0xc0, 0x1a, 0x58, 0xe5,
+	0x48, 0x58, 0x02, 0x9a, 0x9f, 0x44, 0x47, 0xc3, 0x27, 0x93, 0xdb, 0x6c, 0x13, 0x1f, 0x84, 0x45,
+	0x99, 0x67, 0x2d, 0x26, 0x54, 0x37, 0xb1, 0x82, 0x30, 0xd8, 0xd9, 0x11, 0x32, 0xc3, 0x5d, 0xec,
+	0xcc, 0x4f, 0xb2, 0x30, 0x15, 0xb3, 0x2e, 0xa8, 0x02, 0x50, 0xb1, 0x5b, 0x55, 0x4b, 0x5a, 0x93,
+	0xb2, 0x53, 0x0b, 0xc9, 0xe6, 0x7a, 0xc9, 0x6b, 0x17, 0x6c, 0x50, 0xbf, 0x88, 0x61, 0x0d, 0x16,
+	0xbd, 0x03, 0xc8, 0xde, 0x14, 0xd7, 0x8d, 0xea, 0x15, 0x69, 0xb4, 0x7b, 0xb2, 0x30, 0x5b, 0x9a,
+	0x55, 0x6d, 0xd1, 0xb5, 0xae, 0x1a, 0x38, 0xa6, 0x15, 0xc7, 0x6a, 0x10, 0xe6, 0x5e, 0x25, 0xad,
+	0x6a, 0x83, 0x56, 0x31, 0xdd, 0x72, 0x28, 0xab, 0x8b, 0x63, 0x9a, 0x0f, 0xb0, 0xd6, 0xba, 0x6a,
+	0xe0, 0x98, 0x56, 0xe8, 0xfb, 0x71, 0x0b, 0x23, 0x37, 0xc5, 0xdb, 0x7d, 0x2d, 0xcc, 0x32, 0x75,
+	0x89, 0xd5, 0x60, 0xa9, 0x56, 0x46, 0x88, 0x7c, 0xb9, 0x32, 0xeb, 0x8e, 0xdd, 0xb4, 0xf9, 0x28,
+	0x37, 0x08, 0xdb, 0x7e, 0x5c, 0x45, 0x47, 0xa8, 0x93, 0xbd, 0x44, 0x87, 0xf9, 0xaf, 0x06, 0xcc,
+	0xc4, 0x8d, 0xea, 0x04, 0x8e, 0xf7, 0xdd, 0xf0, 0xf1, 0xbe, 0x98, 0xea, 0x78, 0x87, 0x3a, 0xdb,
+	0xe3, 0x94, 0xdf, 0x86, 0x91, 0xa5, 0x8e, 0xe3, 0xd0, 0x96, 0x2b, 0x2d, 0xf2, 0x6f, 0xc2, 0x20,
+	0xb3, 0x5a, 0xca, 0x30, 0x4d, 0x67, 0x8c, 0xe7, 0x39, 0x78, 0x99, 0x37, 0xc6, 0x12, 0xc3, 0xfc,
+	0xb3, 0x2c, 0x4c, 0x79, 0x5a, 0x86, 0x56, 0x17, 0x1d, 0xd7, 0xda, 0x22, 0x15, 0x97, 0xa1, 0x2a,
+	0x8c, 0x54, 0x83, 0x62, 0x57, 0x59, 0x8e, 0x69, 0x78, 0xf9, 0xd6, 0xa9, 0x06, 0xef, 0xe2, 0x10,
+	0x2a, 0xba, 0x09, 0xd9, 0x9a, 0xe5, 0x2a, 0x39, 0x70, 0x21, 0xd9, 0xcc, 0x5d, 0xb1, 0xa2, 0xd6,
+	0x4a, 0xa9, 0xa0, 0x58, 0x65, 0xaf, 0x58, 0x2e, 0xe6, 0x88, 0x68, 0x13, 0x72, 0x56, 0x93, 0xd4,
+	0x68, 0xca, 0x55, 0x59, 0xe5, 0x6d, 0xa2, 0xe8, 0xbe, 0x2e, 0x11, 0x54, 0x86, 0x15, 0x32, 0xe7,
+	0x51, 0xe1, 0x56, 0x86, 0x34, 0x32, 0x93, 0xaf, 0x7c, 0x8c, 0xbd, 0x15, 0xf0, 0x10, 0x54, 0x86,
+	0x15, 0xb2, 0xf9, 0x55, 0x06, 0x26, 0x82, 0xf9, 0x5b, 0xb2, 0x9b, 0x4d, 0xcb, 0x45, 0xb3, 0x90,
+	0xb1, 0xaa, 0xca, 0x88, 0x01, 0xd5, 0x30, 0xb3, 0xba, 0x8c, 0x33, 0x56, 0x15, 0x3d, 0x0f, 0xb9,
+	0x4d, 0x87, 0xb4, 0x2a, 0x75, 0x65, 0xbc, 0xf8, 0xc0, 0x25, 0x51, 0x8a, 0x15, 0x15, 0x3d, 0x03,
+	0x59, 0x97, 0xd4, 0x94, 0xcd, 0xe2, 0xcf, 0xdf, 0x06, 0xa9, 0x61, 0x5e, 0xce, 0x8d, 0x25, 0xd6,
+	0x11, 0x67, 0x58, 0xc9, 0x3a, 0xdf, 0x58, 0x2a, 0xcb, 0x62, 0xec, 0xd1, 0x39, 0x47, 0xd2, 0x71,
+	0xeb, 0xb6, 0x33, 0x33, 0x18, 0xe6, 0xb8, 0x28, 0x4a, 0xb1, 0xa2, 0xf2, 0x3b, 0x55, 0x45, 0xf4,
+	0xdf, 0xa5, 0xce, 0x4c, 0x2e, 0x7c, 0xa7, 0x5a, 0xf2, 0x08, 0x38, 0xa8, 0x83, 0xee, 0x40, 0xa1,
+	0xe2, 0x50, 0xe2, 0xda, 0xce, 0x32, 0x71, 0xe9, 0xcc, 0x50, 0xea, 0x1d, 0x38, 0xbe, 0xbf, 0x37,
+	0x5f, 0x58, 0x0a, 0x20, 0xb0, 0x8e, 0x67, 0xfe, 0x6d, 0x16, 0x66, 0x82, 0xa9, 0x15, 0x6b, 0x1b,
+	0x5c, 0xa5, 0xd5, 0xf4, 0x18, 0x3d, 0xa6, 0xe7, 0x79, 0xc8, 0x55, 0xad, 0x1a, 0x65, 0x6e, 0x74,
+	0x96, 0x97, 0x45, 0x29, 0x56, 0x54, 0xf4, 0x87, 0x11, 0xf7, 0xc9, 0xa0, 0xd8, 0x28, 0xd7, 0x92,
+	0x6d, 0x94, 0x5e, 0x9d, 0xeb, 0xc3, 0x87, 0x82, 0xce, 0x01, 0xd4, 0x2c, 0x57, 0x19, 0xba, 0x6a,
+	0xd5, 0x7d, 0x61, 0x7d, 0xc5, 0xa7, 0x60, 0xad, 0x16, 0xba, 0x09, 0x79, 0x31, 0x5f, 0x7d, 0x9e,
+	0x7f, 0x71, 0xe7, 0x5a, 0xf2, 0x00, 0x70, 0x80, 0x75, 0x68, 0xaf, 0xcc, 0x03, 0x98, 0x5b, 0xb6,
+	0x2b, 0xdb, 0xd4, 0xb9, 0xda, 0xd9, 0x3c, 0xf1, 0x3b, 0xdb, 0x6d, 0x40, 0x2b, 0xf7, 0xdb, 0x0e,
+	0x65, 0xfc, 0xae, 0x71, 0x83, 0x38, 0x16, 0xd9, 0x6c, 0xd0, 0xa3, 0xf2, 0xfa, 0x7d, 0x31, 0x00,
+	0x43, 0x97, 0x1d, 0x6a, 0xd5, 0xea, 0xee, 0x09, 0xe8, 0xe3, 0x67, 0x61, 0x90, 0x34, 0x2c, 0xc2,
+	0xc4, 0xd1, 0xd2, 0xba, 0xb4, 0xc8, 0x0b, 0xb1, 0xa4, 0xa1, 0xdb, 0x90, 0xb3, 0x1d, 0xab, 0x66,
+	0xb5, 0x66, 0xf2, 0xa2, 0x13, 0x09, 0xcd, 0x57, 0x35, 0x8a, 0x6b, 0xa2, 0x69, 0x70, 0x3e, 0xe4,
+	0x7f, 0xac, 0x20, 0xd1, 0x2d, 0x18, 0x92, 0xe7, 0xdd, 0x93, 0xa1, 0x0b, 0x89, 0x75, 0x80, 0x14,
+	0x19, 0x81, 0x5c, 0x92, 0xff, 0x19, 0xf6, 0x00, 0x51, 0xd9, 0x57, 0x01, 0x03, 0x02, 0xfa, 0xa5,
+	0x14, 0x2a, 0xa0, 0xa7, 0xcc, 0x2f, 0xfb, 0x32, 0x7f, 0x30, 0x0d, 0xa8, 0x90, 0xea, 0xbd, 0x84,
+	0x3c, 0x9f, 0x62, 0x75, 0xef, 0xc9, 0xf5, 0x31, 0xc5, 0x07, 0xdc, 0x78, 0x7e, 0x98, 0x85, 0x49,
+	0x55, 0x73, 0xc9, 0x6e, 0x34, 0x68, 0x45, 0x98, 0xb5, 0x52, 0x85, 0x64, 0x63, 0x55, 0x88, 0xe5,
+	0x19, 0x34, 0x52, 0x2d, 0x97, 0x52, 0xf5, 0x26, 0xe0, 0x51, 0x14, 0x46, 0x8c, 0x14, 0x50, 0xfe,
+	0x2a, 0xa9, 0x5a, 0xca, 0xb4, 0x41, 0x3f, 0x30, 0x60, 0x6a, 0x87, 0x3a, 0xd6, 0x96, 0x55, 0x11,
+	0xc2, 0xe0, 0xaa, 0xc5, 0x5c, 0xdb, 0xd9, 0x55, 0x4a, 0xfb, 0xf5, 0x64, 0x9c, 0x6f, 0x68, 0x00,
+	0xab, 0xad, 0x2d, 0xbb, 0xf4, 0xb4, 0xe2, 0x36, 0x75, 0xa3, 0x1b, 0x1a, 0xc7, 0xf1, 0x9b, 0x6d,
+	0x03, 0x04, 0xbd, 0x8d, 0x91, 0x45, 0x6b, 0xfa, 0xe1, 0x4d, 0xdc, 0x31, 0x6f, 0xb0, 0x9e, 0x64,
+	0xd1, 0x65, 0xd8, 0xa7, 0x06, 0x14, 0x14, 0xfd, 0x04, 0x6c, 0x54, 0x1c, 0xb6, 0x51, 0x5f, 0x49,
+	0xd5, 0xff, 0x1e, 0x66, 0xa9, 0x03, 0xa3, 0xa1, 0x43, 0x8e, 0xce, 0x2b, 0xe7, 0xb2, 0x94, 0x81,
+	0xff, 0x5f, 0x77, 0x2e, 0x3f, 0xdc, 0x9b, 0x9f, 0x0c, 0x55, 0x0e, 0x3c, 0xce, 0x07, 0x3b, 0x5b,
+	0x2e, 0x0e, 0xff, 0xe8, 0x2f, 0xe7, 0x4f, 0x7d, 0xf8, 0x8b, 0x33, 0xa7, 0xf8, 0xb5, 0x72, 0x22,
+	0x3a, 0xab, 0x09, 0x64, 0x6f, 0x20, 0xc3, 0x86, 0x8f, 0x55, 0x86, 0x65, 0x8e, 0x4f, 0x86, 0x65,
+	0x8f, 0x43, 0x86, 0x0d, 0x1c, 0x99, 0x0c, 0x33, 0xff, 0xc9, 0x80, 0x31, 0x7f, 0x65, 0xee, 0x75,
+	0xb8, 0xf1, 0x13, 0xcc, 0xba, 0x71, 0xf4, 0xb3, 0x7e, 0x17, 0x86, 0x98, 0xdd, 0x71, 0x2a, 0xc2,
+	0xc2, 0xe7, 0xe8, 0xaf, 0xa5, 0x13, 0x9a, 0xb2, 0xad, 0x66, 0xd6, 0xca, 0x02, 0xec, 0xa1, 0x9a,
+	0x9f, 0x66, 0xfc, 0x01, 0x29, 0x9a, 0xb4, 0xfa, 0x1c, 0x6e, 0x13, 0xf3, 0x01, 0x0d, 0xeb, 0x56,
+	0x1f, 0x2f, 0xc5, 0x8a, 0x8a, 0x4c, 0x21, 0xcf, 0xbd, 0xcb, 0x47, 0xbe, 0x04, 0x4a, 0x2c, 0x8b,
+	0x45, 0x90, 0x14, 0xd4, 0x86, 0x09, 0x87, 0xde, 0xeb, 0x58, 0x0e, 0xad, 0x96, 0x6d, 0xb2, 0xcd,
+	0x2d, 0x26, 0xe5, 0xf5, 0x4a, 0x78, 0xee, 0x97, 0x3b, 0xd2, 0x43, 0x51, 0x9a, 0xe6, 0x17, 0x7f,
+	0x1c, 0xc1, 0xc2, 0x5d, 0xe8, 0xc8, 0x86, 0x69, 0xb2, 0x43, 0xac, 0x06, 0xd9, 0xb4, 0x1a, 0x96,
+	0xbb, 0x5b, 0x76, 0x1d, 0xe2, 0xd2, 0xda, 0xae, 0xb2, 0xef, 0xdf, 0x52, 0x63, 0x99, 0x5e, 0x8c,
+	0xa9, 0xf3, 0x70, 0x6f, 0xfe, 0x69, 0x35, 0x17, 0x71, 0x64, 0x1c, 0x0b, 0x6c, 0xfe, 0x7c, 0xc8,
+	0x97, 0x10, 0xca, 0xfb, 0xf3, 0x00, 0x0a, 0x15, 0x79, 0x93, 0x6d, 0xec, 0xae, 0xb6, 0xd4, 0x9e,
+	0x5e, 0xee, 0x43, 0xdb, 0x15, 0x97, 0x02, 0x98, 0x88, 0x09, 0xac, 0x51, 0xb0, 0xce, 0x0d, 0x7d,
+	0x00, 0x20, 0x45, 0x3f, 0xad, 0xae, 0xb6, 0x94, 0x6e, 0x5b, 0xea, 0x87, 0xf7, 0x0d, 0x1f, 0x45,
+	0xb2, 0xf6, 0x8d, 0xac, 0x80, 0x80, 0x35, 0x56, 0x7c, 0xd4, 0x5e, 0xcc, 0xeb, 0xb2, 0xed, 0x28,
+	0x21, 0xd1, 0xd7, 0xa8, 0x17, 0x03, 0x98, 0xa8, 0xe1, 0x1f, 0x50, 0xb0, 0xce, 0x0d, 0xd9, 0x9a,
+	0x5e, 0x91, 0xc7, 0x7d, 0xb1, 0x1f, 0xce, 0x5e, 0xfc, 0x56, 0xb2, 0xf5, 0x55, 0x8d, 0x57, 0x1c,
+	0xa8, 0x9a, 0x59, 0x07, 0x26, 0xa2, 0x8b, 0x13, 0xa3, 0x50, 0xaf, 0x86, 0x15, 0xea, 0xb9, 0x84,
+	0x22, 0x48, 0x73, 0x83, 0xe8, 0x61, 0x5e, 0x07, 0xc6, 0x23, 0x8b, 0x12, 0xc3, 0x72, 0x35, 0xcc,
+	0xf2, 0xd5, 0x34, 0xc6, 0x85, 0x0a, 0x86, 0xea, 0x3c, 0x19, 0x4c, 0x44, 0x97, 0xe3, 0xc8, 0x98,
+	0x86, 0x22, 0xb0, 0x3a, 0xd3, 0x07, 0x30, 0x1a, 0x5a, 0x89, 0x18, 0x8e, 0x1b, 0x61, 0x8e, 0x97,
+	0x34, 0x69, 0x12, 0xa4, 0x5b, 0xdc, 0xf5, 0xf3, 0x31, 0x02, 0xc1, 0x12, 0xaa, 0xc0, 0x25, 0xcc,
+	0x3b, 0xe5, 0x6b, 0xef, 0xea, 0x26, 0xcb, 0x9f, 0x67, 0x20, 0xef, 0x2b, 0xad, 0x34, 0xe1, 0x14,
+	0x69, 0x6c, 0x66, 0x0e, 0xf0, 0x57, 0x64, 0x93, 0xf8, 0x2b, 0x06, 0x7a, 0xfb, 0x2b, 0xbc, 0x78,
+	0x6f, 0xee, 0xd1, 0xf1, 0x5e, 0xcd, 0x5f, 0x31, 0x94, 0xdc, 0x5f, 0x31, 0x7c, 0xb0, 0xbf, 0xc2,
+	0xfc, 0x2b, 0x03, 0x50, 0xb7, 0x73, 0x2a, 0xcd, 0x44, 0x91, 0xa8, 0x29, 0xf1, 0x7a, 0x5a, 0x4f,
+	0xc1, 0x41, 0x16, 0x85, 0x79, 0x1f, 0x9e, 0xbe, 0x62, 0xb9, 0xbf, 0x8a, 0x8b, 0xb3, 0xe4, 0xbc,
+	0x46, 0x4e, 0x9e, 0xf3, 0x0f, 0x72, 0x30, 0x7e, 0xc5, 0xea, 0x3b, 0x1a, 0xe8, 0xc2, 0x93, 0x72,
+	0xf6, 0xca, 0x54, 0x5d, 0x6d, 0x7c, 0xdd, 0x29, 0xf7, 0xf4, 0x45, 0xd5, 0xf4, 0xc9, 0xa5, 0xf8,
+	0x6a, 0x0f, 0x7b, 0x93, 0x70, 0x2f, 0xe8, 0xc4, 0x07, 0xe3, 0x2d, 0x18, 0x65, 0xae, 0x63, 0x55,
+	0x5c, 0x19, 0x6f, 0x64, 0x33, 0x05, 0x61, 0x9b, 0x9c, 0x56, 0xd5, 0x47, 0xcb, 0x3a, 0x11, 0x87,
+	0xeb, 0xc6, 0x86, 0x31, 0x07, 0x52, 0x87, 0x31, 0x17, 0x20, 0x4f, 0x1a, 0x0d, 0xfb, 0x83, 0x0d,
+	0x52, 0x63, 0xca, 0x09, 0xe8, 0x2f, 0xc8, 0xa2, 0x47, 0xc0, 0x41, 0x1d, 0x54, 0x04, 0xb0, 0x6a,
+	0x2d, 0xdb, 0xa1, 0xa2, 0x45, 0x4e, 0x18, 0x49, 0x22, 0x4f, 0x64, 0xd5, 0x2f, 0xc5, 0x5a, 0x0d,
+	0xde, 0x4d, 0xea, 0xfb, 0x5c, 0x2e, 0x5b, 0x0d, 0x7e, 0x22, 0x47, 0xc2, 0xdd, 0x5c, 0x89, 0xd0,
+	0x71, 0x57, 0x0b, 0x54, 0x86, 0xd3, 0x56, 0x8b, 0xd1, 0x4a, 0xc7, 0xa1, 0xe5, 0x6d, 0xab, 0xbd,
+	0xb1, 0x56, 0x16, 0xc2, 0x7d, 0x57, 0xc8, 0x81, 0xe1, 0xd2, 0x33, 0x0a, 0xea, 0xf4, 0x6a, 0x5c,
+	0x25, 0x1c, 0xdf, 0x16, 0xbd, 0x06, 0x23, 0x56, 0xab, 0xd2, 0xe8, 0x54, 0xe9, 0x3a, 0x71, 0xeb,
+	0x6c, 0x66, 0x58, 0x0c, 0x66, 0x62, 0x7f, 0x6f, 0x7e, 0x64, 0x55, 0x2b, 0xc7, 0xa1, 0x5a, 0xbc,
+	0x15, 0xbd, 0xaf, 0xb5, 0xca, 0x07, 0xad, 0x56, 0xee, 0xeb, 0xad, 0xf4, 0x5a, 0x31, 0xe1, 0x62,
+	0x48, 0x15, 0x2e, 0xfe, 0x49, 0x06, 0x72, 0x32, 0x55, 0x04, 0x9d, 0x8f, 0xe4, 0x63, 0x3c, 0xd3,
+	0x95, 0x8f, 0x51, 0x88, 0x4b, 0xab, 0x31, 0x21, 0x67, 0x31, 0xd6, 0x09, 0x5b, 0xb6, 0xab, 0xa2,
+	0x04, 0x2b, 0x8a, 0x70, 0x8b, 0x8b, 0x23, 0xad, 0x7c, 0x86, 0x87, 0xd4, 0x40, 0x92, 0x87, 0x14,
+	0x12, 0x58, 0x21, 0x73, 0x1e, 0x76, 0xc7, 0x6d, 0x77, 0x5c, 0xb1, 0xdd, 0x8e, 0x88, 0xc7, 0x35,
+	0x81, 0x88, 0x15, 0xb2, 0xf9, 0x89, 0x01, 0xe3, 0x72, 0x0e, 0x96, 0xea, 0xb4, 0xb2, 0x5d, 0x76,
+	0x69, 0x9b, 0x5f, 0x35, 0x3b, 0x8c, 0xb2, 0xe8, 0x55, 0xf3, 0x3a, 0xa3, 0x0c, 0x0b, 0x8a, 0x36,
+	0xfa, 0xcc, 0x71, 0x8d, 0xde, 0xbc, 0x00, 0xda, 0xe2, 0x88, 0x5c, 0x27, 0x99, 0xf2, 0x23, 0xed,
+	0x80, 0x6c, 0x20, 0xca, 0x64, 0xad, 0x5d, 0xec, 0xd1, 0xcd, 0xfd, 0x0c, 0x0c, 0x8a, 0xdb, 0x60,
+	0x1a, 0xf9, 0x17, 0xf6, 0x1d, 0x67, 0x12, 0xf9, 0x8e, 0x0f, 0x08, 0x2f, 0x04, 0xfe, 0xf3, 0x81,
+	0x47, 0xfa, 0xcf, 0x59, 0x9c, 0xfb, 0xfc, 0xed, 0x14, 0x97, 0xe0, 0x7e, 0xf2, 0x0d, 0x0f, 0xeb,
+	0x9e, 0xfe, 0xa5, 0x01, 0xd3, 0x71, 0x81, 0xa4, 0x34, 0x73, 0xfe, 0x32, 0x0c, 0xb7, 0x1b, 0xc4,
+	0xdd, 0xb2, 0x9d, 0x66, 0x34, 0xe3, 0x69, 0x5d, 0x95, 0x63, 0xbf, 0x06, 0x72, 0x00, 0x1c, 0x4f,
+	0x17, 0x7a, 0xae, 0x82, 0x4b, 0x87, 0x0b, 0x32, 0x04, 0x2b, 0xec, 0x17, 0x31, 0xac, 0x71, 0x31,
+	0xff, 0x68, 0x10, 0x26, 0x45, 0x93, 0x7e, 0xd5, 0x6a, 0x3f, 0xdb, 0xaa, 0x0d, 0x4f, 0x08, 0x27,
+	0x46, 0xb7, 0x26, 0x96, 0x3b, 0xed, 0x82, 0x6a, 0xff, 0xc4, 0x6a, 0x6c, 0xad, 0x87, 0x3d, 0x29,
+	0xb8, 0x07, 0x6e, 0xb7, 0x7a, 0x85, 0xff, 0x7d, 0xea, 0x55, 0xdf, 0x6c, 0x43, 0x07, 0x6e, 0xb6,
+	0x9e, 0x6a, 0x74, 0xf8, 0x10, 0x6a, 0xb4, 0x5b, 0xb5, 0xe5, 0x53, 0xa9, 0xb6, 0xbf, 0xc8, 0xc0,
+	0xd0, 0xba, 0x63, 0x8b, 0x80, 0xe4, 0xf1, 0x07, 0x4e, 0xae, 0xf7, 0x99, 0xc8, 0xc0, 0xa1, 0xb4,
+	0x1c, 0xa8, 0xe1, 0x48, 0xfe, 0xd3, 0xed, 0x48, 0xfe, 0xd3, 0xab, 0xa9, 0x80, 0x0f, 0x88, 0x03,
+	0xfc, 0x34, 0x03, 0xa3, 0xa1, 0x2e, 0x3c, 0xc6, 0x09, 0x1f, 0x91, 0x79, 0x3a, 0xc2, 0x5c, 0xb1,
+	0x30, 0xf8, 0xc1, 0xb9, 0x62, 0xa1, 0xfa, 0x8f, 0x6d, 0xae, 0x58, 0xa8, 0x97, 0x3d, 0xdc, 0xf5,
+	0x1f, 0x65, 0x22, 0xa3, 0x11, 0xb9, 0x62, 0xbf, 0x03, 0x93, 0x6d, 0x2f, 0x05, 0x65, 0xdd, 0x6e,
+	0x58, 0x15, 0x8b, 0x7a, 0x71, 0x9f, 0xf3, 0x29, 0xf3, 0x73, 0x44, 0xf3, 0xdd, 0xd2, 0x53, 0x8a,
+	0xfb, 0xe4, 0x7a, 0x14, 0x17, 0x77, 0xb3, 0x42, 0x0c, 0xf2, 0x4e, 0x24, 0x15, 0xea, 0x98, 0x72,
+	0xd4, 0x02, 0x3e, 0xe6, 0x47, 0x59, 0x98, 0x8a, 0xd9, 0x08, 0xff, 0xb7, 0x93, 0xd3, 0xdc, 0xee,
+	0x95, 0x38, 0xae, 0xa4, 0x34, 0x6d, 0x29, 0x3e, 0x35, 0xa0, 0xa0, 0x96, 0xe2, 0xb1, 0x0d, 0x83,
+	0xa9, 0xfe, 0xf5, 0x38, 0x57, 0x5f, 0x1a, 0x30, 0xa2, 0x49, 0x60, 0x86, 0xea, 0x00, 0x1f, 0x10,
+	0x87, 0xd6, 0x6d, 0xff, 0xa6, 0x90, 0x38, 0x38, 0x71, 0xd3, 0x6b, 0x27, 0x90, 0x82, 0xad, 0xe4,
+	0x97, 0x33, 0xac, 0x61, 0xa3, 0xef, 0x68, 0x71, 0x06, 0x29, 0xbe, 0x13, 0x71, 0x11, 0x5e, 0x45,
+	0xc9, 0x41, 0x17, 0x7d, 0x5a, 0x74, 0xc2, 0xfc, 0x99, 0xe1, 0x2b, 0x8b, 0xd8, 0xb3, 0x91, 0x3d,
+	0x9e, 0xb3, 0x51, 0x86, 0x41, 0x2e, 0x7b, 0xbd, 0x77, 0x0a, 0xe7, 0x52, 0xeb, 0x3f, 0xa6, 0x32,
+	0xdc, 0xf8, 0x4f, 0x2c, 0xb1, 0xcc, 0x1f, 0x67, 0x20, 0xef, 0xcb, 0xa2, 0x13, 0x37, 0x0e, 0x5e,
+	0x4d, 0x29, 0x45, 0x7b, 0x2a, 0xbc, 0x3b, 0x11, 0x85, 0x97, 0x56, 0x3c, 0x1f, 0xa0, 0xec, 0xfe,
+	0x5e, 0xae, 0xb8, 0xac, 0x7b, 0x02, 0x47, 0x71, 0x23, 0x7c, 0x14, 0x17, 0x52, 0x8e, 0xa6, 0xc7,
+	0x61, 0xfc, 0x30, 0x03, 0xe3, 0x11, 0x85, 0x84, 0x9e, 0x15, 0x9b, 0xaa, 0xe6, 0xc5, 0x87, 0xfd,
+	0x86, 0xca, 0xb9, 0x2e, 0x68, 0x68, 0x87, 0x9b, 0xf9, 0xfe, 0x05, 0xc0, 0x76, 0xd4, 0x24, 0x7f,
+	0xa3, 0x2f, 0x1d, 0xe8, 0x81, 0x94, 0x26, 0xe5, 0x0d, 0x41, 0xc3, 0xc5, 0x61, 0x36, 0x68, 0x1d,
+	0xa6, 0x49, 0xc7, 0xb5, 0x7d, 0x80, 0x95, 0x16, 0xd9, 0x6c, 0x50, 0xe9, 0x2c, 0x1f, 0x2e, 0xfd,
+	0x3f, 0x3f, 0x28, 0x17, 0x53, 0x07, 0xc7, 0xb6, 0x34, 0xff, 0xda, 0x80, 0x27, 0x7b, 0xf4, 0x27,
+	0x41, 0xa4, 0xbc, 0x01, 0xa3, 0xe2, 0xe5, 0x9f, 0x3f, 0x0f, 0xde, 0x2e, 0x4e, 0xb6, 0xf2, 0x7a,
+	0x53, 0x39, 0xfa, 0x50, 0x11, 0x0e, 0x83, 0x9b, 0x9f, 0x67, 0x00, 0xf9, 0x7d, 0x4d, 0x13, 0xd0,
+	0xbf, 0x03, 0x43, 0x5b, 0x32, 0x3e, 0x75, 0xb8, 0x8c, 0x8c, 0x52, 0x41, 0x4f, 0x4a, 0xf1, 0x30,
+	0xd1, 0x7b, 0x47, 0x73, 0xd6, 0xa0, 0xfb, 0x9c, 0xa1, 0x5b, 0x00, 0x5b, 0x56, 0xcb, 0x62, 0xf5,
+	0x3e, 0xb3, 0xea, 0xc4, 0x3d, 0xee, 0xb2, 0x8f, 0x80, 0x35, 0x34, 0xf3, 0x4f, 0x33, 0xda, 0x19,
+	0x16, 0xe6, 0x5d, 0xa2, 0xbd, 0xff, 0x62, 0x78, 0x32, 0xf3, 0xdd, 0xd9, 0x3a, 0xfe, 0xc4, 0xdc,
+	0x82, 0x81, 0x1d, 0xe2, 0x78, 0x89, 0x03, 0x09, 0x13, 0x76, 0xbb, 0xd3, 0xe5, 0x82, 0x35, 0xbd,
+	0x41, 0x1c, 0x86, 0x05, 0x26, 0x37, 0x7d, 0x99, 0x4b, 0xdb, 0x9e, 0x72, 0x49, 0x2d, 0x38, 0x5d,
+	0xda, 0xd6, 0x07, 0x48, 0xdb, 0x42, 0x03, 0xd0, 0x36, 0x33, 0x7f, 0x38, 0xa4, 0x49, 0x05, 0xa5,
+	0xcf, 0x8e, 0xd2, 0x74, 0x3a, 0xef, 0xbd, 0xdc, 0x94, 0xb3, 0x3c, 0x1f, 0x7a, 0xb9, 0xf9, 0x70,
+	0x6f, 0x7e, 0x2c, 0x38, 0x8f, 0xda, 0x5b, 0xce, 0x14, 0x6f, 0x14, 0xf5, 0xfd, 0x3e, 0x78, 0x0c,
+	0xfb, 0xfd, 0xb7, 0x61, 0x72, 0x2b, 0x9a, 0xbe, 0xa5, 0xf2, 0x6d, 0xdf, 0xe8, 0x33, 0xfb, 0xab,
+	0x74, 0x7a, 0x3f, 0xc8, 0xf9, 0x09, 0x8a, 0x71, 0x37, 0x23, 0x64, 0x7b, 0x2f, 0x23, 0x85, 0x9f,
+	0x55, 0xba, 0xd0, 0x13, 0x9f, 0xb9, 0x88, 0x87, 0x36, 0xfa, 0x26, 0x52, 0x42, 0xe2, 0x10, 0x83,
+	0xc8, 0x19, 0xcc, 0x1d, 0xe5, 0x19, 0x44, 0xe7, 0xfd, 0x14, 0x07, 0xde, 0x1d, 0xe1, 0xc5, 0xc8,
+	0x76, 0x25, 0x27, 0x70, 0x12, 0xd6, 0xeb, 0xa1, 0x8f, 0x0d, 0x38, 0xcd, 0x37, 0xeb, 0xca, 0x7d,
+	0x5a, 0xe9, 0xf0, 0x59, 0xf1, 0xc2, 0xbc, 0x33, 0x85, 0x34, 0x97, 0xa2, 0x72, 0x1c, 0x44, 0xe0,
+	0x92, 0x89, 0x25, 0xe3, 0x78, 0xc6, 0xe8, 0xae, 0x34, 0xc6, 0xa8, 0xf0, 0x78, 0x1d, 0xde, 0x91,
+	0xed, 0x1b, 0x66, 0x52, 0xee, 0xb8, 0xd4, 0xfc, 0xf1, 0x80, 0x2e, 0xae, 0x92, 0xb9, 0xd7, 0x6f,
+	0xc1, 0x80, 0x4b, 0xd8, 0xb6, 0x3a, 0x05, 0x6f, 0xf7, 0xf1, 0x84, 0x24, 0x38, 0x0b, 0xc2, 0xfd,
+	0x22, 0x8a, 0x04, 0x26, 0x9a, 0x85, 0x0c, 0x61, 0xd1, 0x30, 0xf5, 0x22, 0xc3, 0x19, 0xc2, 0x44,
+	0x08, 0x7b, 0x4b, 0x39, 0xc7, 0x82, 0x10, 0xf6, 0x16, 0xce, 0x58, 0x5b, 0x68, 0x11, 0xc6, 0x2b,
+	0x76, 0xcb, 0xb5, 0x5a, 0x1d, 0x7a, 0xad, 0xb5, 0xe2, 0x38, 0xb6, 0xa3, 0x5c, 0x61, 0x4f, 0xaa,
+	0x8a, 0xe3, 0x4b, 0x61, 0x32, 0x8e, 0xd6, 0x47, 0xef, 0xc1, 0xa0, 0x43, 0x5d, 0x67, 0x57, 0x29,
+	0x84, 0x0b, 0x7d, 0xc8, 0x3e, 0xcc, 0xdb, 0xcb, 0x59, 0x16, 0x3f, 0xb1, 0x44, 0xf4, 0x45, 0x76,
+	0xee, 0x18, 0x44, 0x76, 0x10, 0xec, 0xc8, 0x1e, 0x5b, 0xb0, 0xe3, 0x27, 0x86, 0x66, 0x23, 0xf8,
+	0x03, 0x45, 0xd7, 0x61, 0xc8, 0xb5, 0x9a, 0xd4, 0xee, 0xb8, 0xe9, 0x8c, 0x53, 0x3f, 0x6d, 0x4a,
+	0x48, 0xc2, 0x0d, 0x09, 0x81, 0x3d, 0x2c, 0x74, 0x09, 0xc6, 0x28, 0x5f, 0x91, 0x8d, 0x3a, 0x97,
+	0xec, 0x76, 0x43, 0x5a, 0x62, 0xa3, 0x81, 0x1f, 0x72, 0x25, 0x44, 0xc5, 0x91, 0xda, 0xe6, 0xe7,
+	0xba, 0x19, 0xfd, 0x3f, 0xff, 0x59, 0x95, 0x72, 0x81, 0x9d, 0xe8, 0x7b, 0xaa, 0xbe, 0x5d, 0x60,
+	0x07, 0x3e, 0xa4, 0x7a, 0x1f, 0x9e, 0x88, 0x17, 0x05, 0x47, 0xf2, 0xe5, 0x84, 0x9f, 0x45, 0xe7,
+	0x4a, 0x58, 0x60, 0xde, 0xf1, 0x33, 0x8e, 0xd3, 0x62, 0xca, 0x1c, 0xb5, 0xc5, 0xe4, 0xe8, 0x43,
+	0x51, 0xdf, 0x99, 0x40, 0x77, 0xd4, 0x3e, 0x33, 0xd2, 0x7c, 0xb9, 0xa0, 0x0b, 0xa6, 0xe7, 0x5e,
+	0xfb, 0xb9, 0x01, 0xa7, 0x63, 0x6b, 0xfb, 0x73, 0x98, 0x39, 0xce, 0x39, 0x34, 0x8e, 0x7a, 0x0e,
+	0x77, 0xe0, 0xa9, 0x6f, 0x77, 0xc8, 0xee, 0x89, 0x67, 0xbb, 0xfc, 0x28, 0x03, 0x13, 0x98, 0xb6,
+	0xed, 0x50, 0x5c, 0x6e, 0xdd, 0x7b, 0x68, 0x97, 0xe2, 0x3a, 0x13, 0x49, 0x99, 0x29, 0x0d, 0x85,
+	0x5e, 0xd8, 0xf1, 0x63, 0xda, 0xf4, 0x6c, 0xd7, 0xc4, 0x62, 0xa7, 0x2b, 0x62, 0x28, 0x35, 0x96,
+	0x8c, 0x3d, 0x4a, 0x40, 0x8e, 0x2c, 0x92, 0x8a, 0x95, 0x52, 0x79, 0x23, 0x45, 0x7a, 0x72, 0x37,
+	0xb2, 0x28, 0xc6, 0x12, 0xd0, 0xfc, 0x24, 0x03, 0xf2, 0xea, 0x73, 0x02, 0x52, 0xf9, 0xdb, 0x21,
+	0xa9, 0xbc, 0x90, 0xc6, 0x35, 0xd7, 0xcb, 0x05, 0x14, 0xbd, 0x96, 0x9e, 0x4d, 0xe9, 0xef, 0x7b,
+	0x84, 0xfb, 0xe7, 0xef, 0x0c, 0xc8, 0x8b, 0x7a, 0x27, 0x20, 0xe0, 0xd7, 0xc3, 0x02, 0xfe, 0xa5,
+	0x14, 0xa3, 0xe8, 0x21, 0xd8, 0xff, 0x23, 0xab, 0x7a, 0xef, 0x5f, 0x7a, 0xeb, 0xc4, 0xa9, 0xaa,
+	0xdb, 0x5c, 0x70, 0x3a, 0x79, 0x21, 0x96, 0x34, 0x5f, 0xa6, 0x0c, 0x1d, 0x83, 0x4c, 0xf9, 0x9e,
+	0xcc, 0xed, 0xa6, 0xcc, 0xa5, 0xd5, 0xcb, 0xfe, 0xb5, 0x2d, 0x9b, 0x3a, 0x49, 0x5d, 0x25, 0xd2,
+	0x07, 0x9e, 0x74, 0x1c, 0x41, 0xc5, 0x5d, 0x7c, 0xf8, 0x55, 0xae, 0x1d, 0x15, 0xa2, 0xea, 0x8a,
+	0xf3, 0x46, 0x9f, 0x12, 0x5b, 0x5e, 0xe5, 0xba, 0x8a, 0x71, 0x37, 0x23, 0x54, 0x87, 0x11, 0xfd,
+	0x79, 0x8d, 0xda, 0xa7, 0xe7, 0xd2, 0xbf, 0xe3, 0x91, 0xb9, 0x50, 0x7a, 0x09, 0x0e, 0x21, 0x9b,
+	0x7f, 0x6c, 0x00, 0x04, 0x8e, 0x6c, 0xbe, 0xe6, 0x15, 0xbb, 0xd3, 0x92, 0x1e, 0x8c, 0x6c, 0xb0,
+	0xe6, 0x4b, 0xbc, 0x10, 0x4b, 0x1a, 0x3f, 0x3f, 0xf2, 0x1e, 0xa8, 0x36, 0xf5, 0xd9, 0x34, 0x57,
+	0xcc, 0x88, 0xc3, 0x5c, 0x16, 0x62, 0x05, 0x68, 0x7e, 0x98, 0x83, 0x82, 0x76, 0xce, 0x22, 0xee,
+	0xf2, 0xd1, 0x63, 0x0b, 0x25, 0xc5, 0xf8, 0x30, 0x0a, 0x7d, 0xf9, 0x30, 0x18, 0x8c, 0xa9, 0x9b,
+	0xb9, 0xf7, 0x06, 0x4b, 0xfa, 0x78, 0xfa, 0xbe, 0xff, 0x23, 0x6e, 0x2d, 0x5f, 0x0e, 0x41, 0xe2,
+	0x08, 0x0b, 0x6e, 0x6d, 0xab, 0x92, 0x72, 0xa7, 0xd9, 0x24, 0xce, 0xae, 0xca, 0xea, 0xf3, 0xad,
+	0xed, 0xcb, 0x21, 0x2a, 0x8e, 0xd4, 0x46, 0xeb, 0xfe, 0x82, 0xca, 0x77, 0x3d, 0x2f, 0xa7, 0x59,
+	0x50, 0x79, 0xdb, 0x08, 0xaf, 0x63, 0x8f, 0xe8, 0x5c, 0xae, 0xaf, 0xe8, 0xdc, 0xf7, 0x60, 0x42,
+	0x5d, 0xf1, 0xfd, 0xb3, 0xa3, 0x9c, 0x2a, 0x69, 0xef, 0x77, 0x81, 0xea, 0x17, 0x8f, 0x3d, 0x96,
+	0x22, 0xa8, 0xb8, 0x8b, 0x0f, 0xba, 0x07, 0xa3, 0x7c, 0x91, 0x03, 0xc6, 0x70, 0x48, 0xc6, 0xca,
+	0x99, 0xab, 0x41, 0xe2, 0x30, 0x07, 0xf3, 0xcb, 0x2c, 0xc4, 0x3b, 0x18, 0x82, 0x77, 0xa6, 0xc6,
+	0x23, 0xde, 0x99, 0xde, 0x84, 0x3c, 0x73, 0x89, 0x23, 0x5f, 0x1b, 0x67, 0xfa, 0x7b, 0x6d, 0x5c,
+	0xf6, 0x00, 0x70, 0x80, 0x15, 0xf1, 0xf6, 0x64, 0x8f, 0xd4, 0xdb, 0x73, 0x0e, 0x40, 0x5c, 0x00,
+	0x85, 0x98, 0x11, 0xfa, 0x66, 0x34, 0x38, 0xb5, 0x2b, 0x3e, 0x05, 0x6b, 0xb5, 0xd0, 0x37, 0x7c,
+	0x2d, 0x2e, 0x73, 0x79, 0x7e, 0xad, 0x2b, 0xf5, 0x72, 0x2a, 0x64, 0x5e, 0x46, 0x1c, 0xc8, 0x29,
+	0x32, 0xdd, 0x63, 0x1c, 0x13, 0x43, 0xe9, 0x1c, 0x13, 0xe6, 0x7f, 0x65, 0x20, 0x24, 0x85, 0xd1,
+	0x47, 0x06, 0x4c, 0x92, 0xc8, 0x17, 0xe8, 0x3c, 0xe3, 0xf9, 0x37, 0xd3, 0x7d, 0x16, 0xb0, 0xeb,
+	0x03, 0x76, 0x41, 0xee, 0x40, 0xb4, 0x0a, 0xc3, 0xdd, 0x4c, 0xd1, 0x1f, 0x18, 0x30, 0x45, 0xba,
+	0x3f, 0x31, 0xa8, 0x36, 0xcf, 0x9b, 0x7d, 0x7f, 0xa3, 0xb0, 0xf4, 0xe4, 0xfe, 0xde, 0x7c, 0xdc,
+	0xc7, 0x17, 0x71, 0x1c, 0x3b, 0x74, 0x1b, 0x06, 0x88, 0x53, 0xf3, 0xdc, 0xd6, 0xe9, 0xd9, 0x7a,
+	0x5f, 0x8e, 0x0c, 0x4c, 0x89, 0x45, 0xa7, 0xc6, 0xb0, 0x00, 0x35, 0x7f, 0x91, 0x85, 0x89, 0xe8,
+	0xfb, 0x56, 0xf5, 0x9e, 0x62, 0x20, 0xf6, 0x3d, 0x05, 0x3f, 0x6b, 0x22, 0x70, 0x13, 0x7d, 0xd3,
+	0x2d, 0xe2, 0x2f, 0x92, 0xe6, 0x9f, 0x35, 0xf1, 0xea, 0x6c, 0xf0, 0x10, 0x67, 0x4d, 0x3c, 0x35,
+	0x0b, 0xb0, 0xd0, 0x85, 0xb0, 0x27, 0xdc, 0x8c, 0x7a, 0xc2, 0x27, 0xf5, 0xb1, 0xf4, 0xeb, 0x0c,
+	0x6f, 0x42, 0x41, 0x5b, 0x07, 0x75, 0xa2, 0x2f, 0xa6, 0x9e, 0xf7, 0x60, 0xdb, 0x8d, 0xcb, 0x74,
+	0xd0, 0x80, 0xa2, 0xe3, 0x07, 0xf2, 0x43, 0xcc, 0xd6, 0xa1, 0xbc, 0xc5, 0x62, 0xba, 0x34, 0x34,
+	0xf3, 0x5f, 0x0c, 0x18, 0x0d, 0xbd, 0x30, 0xe2, 0xdc, 0xbc, 0xa7, 0x63, 0xfd, 0x7f, 0x6e, 0xf1,
+	0x86, 0x8f, 0x80, 0x35, 0x34, 0xf4, 0x5d, 0x28, 0x34, 0xec, 0x56, 0x8d, 0x32, 0xb7, 0x6c, 0x93,
+	0x6d, 0x75, 0x4e, 0xd2, 0xfa, 0xcd, 0x66, 0xf6, 0xf7, 0xe6, 0xa7, 0xd7, 0x24, 0xcc, 0x92, 0xdd,
+	0x6c, 0x37, 0xa8, 0x2b, 0x1f, 0x19, 0x62, 0x1d, 0x5c, 0x44, 0xdd, 0xfd, 0xb4, 0x85, 0xc7, 0x35,
+	0xea, 0x1e, 0xe4, 0x5b, 0x1c, 0x71, 0xd4, 0x3d, 0x94, 0xc8, 0x71, 0x40, 0xd4, 0xdd, 0xaf, 0xfb,
+	0xd8, 0x46, 0xdd, 0xfd, 0x1e, 0xf6, 0xb8, 0x7e, 0xfd, 0x67, 0x46, 0x1b, 0x45, 0xf8, 0x0a, 0x96,
+	0x79, 0xc4, 0x15, 0xec, 0x7d, 0x18, 0xb6, 0x5a, 0x2e, 0x75, 0x76, 0x48, 0x43, 0xf9, 0xbd, 0xd3,
+	0xee, 0x45, 0x7f, 0xa8, 0xab, 0x0a, 0x07, 0xfb, 0x88, 0xa8, 0x01, 0xa7, 0xbd, 0x50, 0x93, 0x43,
+	0x49, 0x10, 0x0c, 0x57, 0x99, 0xc2, 0xaf, 0x7b, 0x31, 0x91, 0xcb, 0x71, 0x95, 0x1e, 0xf6, 0x22,
+	0xe0, 0x78, 0x50, 0xc4, 0x60, 0x94, 0x69, 0xbe, 0x07, 0x4f, 0x23, 0x26, 0x0c, 0xd3, 0x45, 0xdd,
+	0x35, 0x5a, 0x7a, 0xb1, 0x0e, 0x8a, 0xc3, 0x3c, 0xcc, 0x8f, 0x0d, 0x18, 0x0b, 0xa7, 0x0c, 0xfd,
+	0xca, 0xef, 0x41, 0x5f, 0x66, 0x61, 0x3c, 0xb2, 0xf9, 0x23, 0x77, 0xa1, 0xfc, 0x49, 0xde, 0x85,
+	0x72, 0x7d, 0xdd, 0x85, 0xe2, 0x2f, 0x01, 0x03, 0x7d, 0x5d, 0x02, 0xde, 0x92, 0x86, 0xb8, 0xda,
+	0x4c, 0xab, 0xcb, 0xea, 0x25, 0xa1, 0xbf, 0xc0, 0x6b, 0x3a, 0x11, 0x87, 0xeb, 0x0a, 0x0b, 0xa7,
+	0xda, 0xfd, 0x71, 0x2e, 0x75, 0x8b, 0x78, 0x33, 0x6d, 0x86, 0xbf, 0x0f, 0x20, 0x2d, 0x9c, 0x18,
+	0x02, 0x8e, 0x63, 0x67, 0x7e, 0x3e, 0x00, 0xa7, 0xe3, 0xdd, 0x98, 0x07, 0xfb, 0xcd, 0xef, 0x41,
+	0x7e, 0xd3, 0xfb, 0xbe, 0xaa, 0x32, 0x35, 0x12, 0x3e, 0x7d, 0x7e, 0xf4, 0x67, 0x59, 0xa5, 0x11,
+	0xe2, 0xd7, 0xc1, 0x01, 0x17, 0xce, 0xb2, 0x2a, 0x3e, 0x0f, 0x54, 0xef, 0x6c, 0x2a, 0x7d, 0x9d,
+	0x90, 0xe5, 0xa3, 0xbf, 0x2a, 0x24, 0x59, 0xfa, 0x75, 0x70, 0xc0, 0x05, 0x51, 0xc8, 0x49, 0x06,
+	0x4a, 0xff, 0x2c, 0x26, 0xf6, 0xb0, 0xf6, 0x64, 0x26, 0x6e, 0xa7, 0xb2, 0x02, 0x56, 0xe0, 0x8a,
+	0x4d, 0x83, 0x6c, 0x2a, 0x6d, 0x94, 0x9c, 0x4d, 0xaf, 0x67, 0x97, 0x3e, 0x9b, 0x35, 0x22, 0xd9,
+	0x34, 0xc8, 0x26, 0xba, 0x03, 0x03, 0xf7, 0x3a, 0xc4, 0x0b, 0x46, 0x26, 0xb4, 0xea, 0x7b, 0xfa,
+	0xba, 0x65, 0x9c, 0x95, 0x93, 0xb1, 0x80, 0x35, 0x1f, 0xc0, 0x13, 0xf1, 0x29, 0xa3, 0xc9, 0xc2,
+	0x30, 0x6d, 0xe2, 0x7a, 0x6f, 0x22, 0xfd, 0x1a, 0xeb, 0xc4, 0xad, 0x63, 0x41, 0x41, 0xcf, 0x40,
+	0xb6, 0xe3, 0x34, 0xa2, 0x0f, 0x85, 0xaf, 0xe3, 0x35, 0xcc, 0xcb, 0x4b, 0xef, 0x7c, 0xf6, 0xf5,
+	0xdc, 0xa9, 0x2f, 0xbe, 0x9e, 0x3b, 0xf5, 0xd5, 0xd7, 0x73, 0xa7, 0x3e, 0xdc, 0x9f, 0x33, 0x3e,
+	0xdb, 0x9f, 0x33, 0xbe, 0xd8, 0x9f, 0x33, 0xbe, 0xda, 0x9f, 0x33, 0xfe, 0x6d, 0x7f, 0xce, 0xf8,
+	0xf8, 0x97, 0x73, 0xa7, 0x6e, 0x3d, 0x97, 0xe4, 0x9b, 0xfb, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff,
+	0x62, 0x62, 0xb6, 0x1b, 0x9a, 0x5f, 0x00, 0x00,
 }
 
 func (m *AnalysisRunArgument) Marshal() (dAtA []byte, err error) {
@@ -3412,6 +3444,14 @@ func (m *ClusterConfigStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	i -= len(m.LastHandledRefresh)
+	copy(dAtA[i:], m.LastHandledRefresh)
+	i = encodeVarintGenerated(dAtA, i, uint64(len(m.LastHandledRefresh)))
+	i--
+	dAtA[i] = 0x22
+	i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration))
+	i--
+	dAtA[i] = 0x18
 	if len(m.WebhookReceivers) > 0 {
 		for iNdEx := len(m.WebhookReceivers) - 1; iNdEx >= 0; iNdEx-- {
 			{
@@ -3782,6 +3822,39 @@ func (m *DiscoveredImageReference) MarshalToSizedBuffer(dAtA []byte) (int, error
 	return len(dAtA) - i, nil
 }
 
+func (m *DockerHubWebhookReceiverConfig) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *DockerHubWebhookReceiverConfig) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *DockerHubWebhookReceiverConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	{
+		size, err := m.SecretRef.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
+		}
+		i -= size
+		i = encodeVarintGenerated(dAtA, i, uint64(size))
+	}
+	i--
+	dAtA[i] = 0xa
+	return len(dAtA) - i, nil
+}
+
 func (m *ExpressionVariable) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -5198,6 +5271,14 @@ func (m *ProjectConfigStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	i -= len(m.LastHandledRefresh)
+	copy(dAtA[i:], m.LastHandledRefresh)
+	i = encodeVarintGenerated(dAtA, i, uint64(len(m.LastHandledRefresh)))
+	i--
+	dAtA[i] = 0x22
+	i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration))
+	i--
+	dAtA[i] = 0x18
 	if len(m.WebhookReceivers) > 0 {
 		for iNdEx := len(m.WebhookReceivers) - 1; iNdEx >= 0; iNdEx-- {
 			{
@@ -7135,6 +7216,18 @@ func (m *WebhookReceiverConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if m.DockerHub != nil {
+		{
+			size, err := m.DockerHub.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintGenerated(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x32
+	}
 	if m.Bitbucket != nil {
 		{
 			size, err := m.Bitbucket.MarshalToSizedBuffer(dAtA[:i])
@@ -7496,6 +7589,9 @@ func (m *ClusterConfigStatus) Size() (n int) {
 			n += 1 + l + sovGenerated(uint64(l))
 		}
 	}
+	n += 1 + sovGenerated(uint64(m.ObservedGeneration))
+	l = len(m.LastHandledRefresh)
+	n += 1 + l + sovGenerated(uint64(l))
 	return n
 }
 
@@ -7623,6 +7719,17 @@ func (m *DiscoveredImageReference) Size() (n int) {
 	return n
 }
 
+func (m *DockerHubWebhookReceiverConfig) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = m.SecretRef.Size()
+	n += 1 + l + sovGenerated(uint64(l))
+	return n
+}
+
 func (m *ExpressionVariable) Size() (n int) {
 	if m == nil {
 		return 0
@@ -8154,6 +8261,9 @@ func (m *ProjectConfigStatus) Size() (n int) {
 			n += 1 + l + sovGenerated(uint64(l))
 		}
 	}
+	n += 1 + sovGenerated(uint64(m.ObservedGeneration))
+	l = len(m.LastHandledRefresh)
+	n += 1 + l + sovGenerated(uint64(l))
 	return n
 }
 
@@ -8859,6 +8969,10 @@ func (m *WebhookReceiverConfig) Size() (n int) {
 		l = m.Bitbucket.Size()
 		n += 1 + l + sovGenerated(uint64(l))
 	}
+	if m.DockerHub != nil {
+		l = m.DockerHub.Size()
+		n += 1 + l + sovGenerated(uint64(l))
+	}
 	return n
 }
 
@@ -9102,6 +9216,8 @@ func (this *ClusterConfigStatus) String() string {
 	s := strings.Join([]string{`&ClusterConfigStatus{`,
 		`Conditions:` + repeatedStringForConditions + `,`,
 		`WebhookReceivers:` + repeatedStringForWebhookReceivers + `,`,
+		`ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`,
+		`LastHandledRefresh:` + fmt.Sprintf("%v", this.LastHandledRefresh) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -9211,6 +9327,16 @@ func (this *DiscoveredImageReference) String() string {
 	}, "")
 	return s
 }
+func (this *DockerHubWebhookReceiverConfig) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&DockerHubWebhookReceiverConfig{`,
+		`SecretRef:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.SecretRef), "LocalObjectReference", "v11.LocalObjectReference", 1), `&`, ``, 1) + `,`,
+		`}`,
+	}, "")
+	return s
+}
 func (this *ExpressionVariable) String() string {
 	if this == nil {
 		return "nil"
@@ -9647,6 +9773,8 @@ func (this *ProjectConfigStatus) String() string {
 	s := strings.Join([]string{`&ProjectConfigStatus{`,
 		`Conditions:` + repeatedStringForConditions + `,`,
 		`WebhookReceivers:` + repeatedStringForWebhookReceivers + `,`,
+		`ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`,
+		`LastHandledRefresh:` + fmt.Sprintf("%v", this.LastHandledRefresh) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -10196,6 +10324,7 @@ func (this *WebhookReceiverConfig) String() string {
 		`GitLab:` + strings.Replace(this.GitLab.String(), "GitLabWebhookReceiverConfig", "GitLabWebhookReceiverConfig", 1) + `,`,
 		`Quay:` + strings.Replace(this.Quay.String(), "QuayWebhookReceiverConfig", "QuayWebhookReceiverConfig", 1) + `,`,
 		`Bitbucket:` + strings.Replace(this.Bitbucket.String(), "BitbucketWebhookReceiverConfig", "BitbucketWebhookReceiverConfig", 1) + `,`,
+		`DockerHub:` + strings.Replace(this.DockerHub.String(), "DockerHubWebhookReceiverConfig", "DockerHubWebhookReceiverConfig", 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -12443,6 +12572,57 @@ func (m *ClusterConfigStatus) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType)
+			}
+			m.ObservedGeneration = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ObservedGeneration |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LastHandledRefresh", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.LastHandledRefresh = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -13555,6 +13735,89 @@ func (m *DiscoveredImageReference) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *DockerHubWebhookReceiverConfig) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowGenerated
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: DockerHubWebhookReceiverConfig: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: DockerHubWebhookReceiverConfig: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SecretRef", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.SecretRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipGenerated(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func (m *ExpressionVariable) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
 	iNdEx := 0
@@ -18242,6 +18505,57 @@ func (m *ProjectConfigStatus) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType)
+			}
+			m.ObservedGeneration = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ObservedGeneration |= int64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LastHandledRefresh", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.LastHandledRefresh = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -23882,6 +24196,42 @@ func (m *WebhookReceiverConfig) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 6:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DockerHub", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenerated
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenerated
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.DockerHub == nil {
+				m.DockerHub = &DockerHubWebhookReceiverConfig{}
+			}
+			if err := m.DockerHub.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenerated(dAtA[iNdEx:])
diff --git a/api/v1alpha1/generated.proto b/api/v1alpha1/generated.proto
index 85b21556..a0830561 100644
--- a/api/v1alpha1/generated.proto
+++ b/api/v1alpha1/generated.proto
@@ -247,6 +247,16 @@ message ClusterConfigStatus {
   // +listMapKey=type
   repeated .k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1;
 
+  // ObservedGeneration represents the .metadata.generation that this
+  // ClusterConfig was reconciled against.
+  optional int64 observedGeneration = 3;
+
+  // LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+  // annotation that was handled by the controller. This field can be used to
+  // determine whether the request to refresh the resource has been handled.
+  // +optional
+  optional string lastHandledRefresh = 4;
+
   // WebhookReceivers describes the status of cluster-scoped webhook receivers.
   repeated WebhookReceiverDetails webhookReceivers = 2;
 }
@@ -369,6 +379,24 @@ message DiscoveredImageReference {
   optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time createdAt = 4;
 }
 
+// DockerHubWebhookReceiverConfig describes a webhook receiver that is
+// compatible with Docker Hub payloads.
+message DockerHubWebhookReceiverConfig {
+  // SecretRef contains a reference to a Secret. For Project-scoped webhook
+  // receivers, the referenced Secret must be in the same namespace as the
+  // ProjectConfig.
+  //
+  // The Secret's data map is expected to contain a `secret` key whose value
+  // does NOT need to be shared directly with Docker Hub when registering a
+  // webhook. It is used only by Kargo to create a complex, hard-to-guess URL,
+  // which implicitly serves as a shared secret. For more information about
+  // Docker Hub webhooks, please refer to the Docker documentation:
+  //   https://docs.docker.com/docker-hub/webhooks/
+  //
+  // +kubebuilder:validation:Required
+  optional .k8s.io.api.core.v1.LocalObjectReference secretRef = 1;
+}
+
 // ExpressionVariable describes a single variable that may be referenced by
 // expressions in the context of a ClusterPromotionTask, PromotionTask,
 // Promotion, AnalysisRun arguments, or other objects that support expressions.
@@ -1090,6 +1118,16 @@ message ProjectConfigStatus {
   // +listMapKey=type
   repeated .k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1;
 
+  // ObservedGeneration represents the .metadata.generation that this
+  // ProjectConfig was reconciled against.
+  optional int64 observedGeneration = 3;
+
+  // LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+  // annotation that was handled by the controller. This field can be used to
+  // determine whether the request to refresh the resource has been handled.
+  // +optional
+  optional string lastHandledRefresh = 4;
+
   // WebhookReceivers describes the status of Project-specific webhook
   // receivers.
   repeated WebhookReceiverDetails receivers = 2;
@@ -1832,6 +1870,10 @@ message WebhookReceiverConfig {
   // compatible with Bitbucket payloads.
   optional BitbucketWebhookReceiverConfig bitbucket = 5;
 
+  // DockerHub contains the configuration for a webhook receiver that is
+  // compatible with DockerHub payloads.
+  optional DockerHubWebhookReceiverConfig dockerhub = 6;
+
   // GitHub contains the configuration for a webhook receiver that is compatible
   // with GitHub payloads.
   optional GitHubWebhookReceiverConfig github = 2;
diff --git a/api/v1alpha1/project_config_types.go b/api/v1alpha1/project_config_types.go
index e6e5f735..54a8b2c4 100644
--- a/api/v1alpha1/project_config_types.go
+++ b/api/v1alpha1/project_config_types.go
@@ -47,6 +47,14 @@ type ProjectConfigStatus struct {
 	// +listType=map
 	// +listMapKey=type
 	Conditions []metav1.Condition `json:"conditions,omitempty" patchMergeKey:"type" patchStrategy:"merge" protobuf:"bytes,1,rep,name=conditions"`
+	// ObservedGeneration represents the .metadata.generation that this
+	// ProjectConfig was reconciled against.
+	ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"`
+	// LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+	// annotation that was handled by the controller. This field can be used to
+	// determine whether the request to refresh the resource has been handled.
+	// +optional
+	LastHandledRefresh string `json:"lastHandledRefresh,omitempty" protobuf:"bytes,4,opt,name=lastHandledRefresh"`
 	// WebhookReceivers describes the status of Project-specific webhook
 	// receivers.
 	WebhookReceivers []WebhookReceiverDetails `json:"webhookReceivers,omitempty" protobuf:"bytes,2,rep,name=receivers"`
@@ -100,6 +108,9 @@ type WebhookReceiverConfig struct {
 	// Bitbucket contains the configuration for a webhook receiver that is
 	// compatible with Bitbucket payloads.
 	Bitbucket *BitbucketWebhookReceiverConfig `json:"bitbucket,omitempty" protobuf:"bytes,5,opt,name=bitbucket"`
+	// DockerHub contains the configuration for a webhook receiver that is
+	// compatible with DockerHub payloads.
+	DockerHub *DockerHubWebhookReceiverConfig `json:"dockerhub,omitempty" protobuf:"bytes,6,opt,name=dockerhub"`
 	// GitHub contains the configuration for a webhook receiver that is compatible
 	// with GitHub payloads.
 	GitHub *GitHubWebhookReceiverConfig `json:"github,omitempty" protobuf:"bytes,2,opt,name=github"`
@@ -131,6 +142,24 @@ type BitbucketWebhookReceiverConfig struct {
 	SecretRef corev1.LocalObjectReference `json:"secretRef" protobuf:"bytes,1,opt,name=secretRef"`
 }
 
+// DockerHubWebhookReceiverConfig describes a webhook receiver that is
+// compatible with Docker Hub payloads.
+type DockerHubWebhookReceiverConfig struct {
+	// SecretRef contains a reference to a Secret. For Project-scoped webhook
+	// receivers, the referenced Secret must be in the same namespace as the
+	// ProjectConfig.
+	//
+	// The Secret's data map is expected to contain a `secret` key whose value
+	// does NOT need to be shared directly with Docker Hub when registering a
+	// webhook. It is used only by Kargo to create a complex, hard-to-guess URL,
+	// which implicitly serves as a shared secret. For more information about
+	// Docker Hub webhooks, please refer to the Docker documentation:
+	//   https://docs.docker.com/docker-hub/webhooks/
+	//
+	// +kubebuilder:validation:Required
+	SecretRef corev1.LocalObjectReference `json:"secretRef" protobuf:"bytes,1,opt,name=secretRef"`
+}
+
 // GitHubWebhookReceiverConfig describes a webhook receiver that is compatible
 // with GitHub payloads.
 type GitHubWebhookReceiverConfig struct {
diff --git a/api/v1alpha1/warehouse_types.go b/api/v1alpha1/warehouse_types.go
index c95f6a82..cbbf7e25 100644
--- a/api/v1alpha1/warehouse_types.go
+++ b/api/v1alpha1/warehouse_types.go
@@ -1,6 +1,10 @@
 package v1alpha1
 
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import (
+	"time"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
 
 // +kubebuilder:validation:Enum={Lexical,NewestFromBranch,NewestTag,SemVer}
 type CommitSelectionStrategy string
@@ -39,6 +43,27 @@ type Warehouse struct {
 	Status WarehouseStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
 }
 
+// GetInterval calculates and returns interval time remaining until the next
+// requeue should occur. If the interval has passed, it returns a short duration
+// to ensure the Warehouse is requeued promptly.
+func (w *Warehouse) GetInterval(minInterval time.Duration) time.Duration {
+	effectiveInterval := w.Spec.Interval.Duration
+	if effectiveInterval < minInterval {
+		effectiveInterval = minInterval
+	}
+
+	if w.Status.DiscoveredArtifacts == nil || w.Status.DiscoveredArtifacts.DiscoveredAt.IsZero() {
+		return effectiveInterval
+	}
+
+	if interval := w.Status.DiscoveredArtifacts.DiscoveredAt.
+		Add(effectiveInterval).
+		Sub(metav1.Now().Time); interval > 0 {
+		return interval
+	}
+	return 100 * time.Millisecond
+}
+
 func (w *Warehouse) GetStatus() *WarehouseStatus {
 	return &w.Status
 }
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index cc123512..8d4eab71 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -488,6 +488,22 @@ func (in *DiscoveredImageReference) DeepCopy() *DiscoveredImageReference {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DockerHubWebhookReceiverConfig) DeepCopyInto(out *DockerHubWebhookReceiverConfig) {
+	*out = *in
+	out.SecretRef = in.SecretRef
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerHubWebhookReceiverConfig.
+func (in *DockerHubWebhookReceiverConfig) DeepCopy() *DockerHubWebhookReceiverConfig {
+	if in == nil {
+		return nil
+	}
+	out := new(DockerHubWebhookReceiverConfig)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ExpressionVariable) DeepCopyInto(out *ExpressionVariable) {
 	*out = *in
@@ -2103,6 +2119,11 @@ func (in *WebhookReceiverConfig) DeepCopyInto(out *WebhookReceiverConfig) {
 		*out = new(BitbucketWebhookReceiverConfig)
 		**out = **in
 	}
+	if in.DockerHub != nil {
+		in, out := &in.DockerHub, &out.DockerHub
+		*out = new(DockerHubWebhookReceiverConfig)
+		**out = **in
+	}
 	if in.GitHub != nil {
 		in, out := &in.GitHub, &out.GitHub
 		*out = new(GitHubWebhookReceiverConfig)
diff --git a/charts/kargo/README.md b/charts/kargo/README.md
index 1b1bd3a3..5c10d5c0 100644
--- a/charts/kargo/README.md
+++ b/charts/kargo/README.md
@@ -169,6 +169,7 @@ the Kargo controller is running.
 | `controller.reconcilers.promotions.maxConcurrentReconciles`        | optionally overrides the maximum number of Promotion resources the controller can reconcile concurrently.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `nil`               |
 | `controller.reconcilers.stages.maxConcurrentReconciles`            | optionally overrides the maximum number of (non-control flow) Stage resources the controller can reconcile concurrently.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `nil`               |
 | `controller.reconcilers.warehouses.maxConcurrentReconciles`        | optionally overrides the maximum number of Warehouse resources the controller can reconcile concurrently.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `nil`               |
+| `controller.reconcilers.warehouses.minReconciliationInterval`      | optionally sets the minimum reconciliation interval for Warehouse resources. Accepts duration format (e.g., "5m", "1h", "30s"). If a Warehouse specifies an interval lower than this minimum, the minimum value will be enforced instead. If not set, no minimum is enforced.                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `5m0s`              |
 | `controller.gitClient.name`                                        | Specifies the name of the Kargo controller (used when authoring Git commits).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `Kargo`             |
 | `controller.gitClient.email`                                       | Specifies the email of the Kargo controller (used when authoring Git commits).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `no-reply@kargo.io` |
 | `controller.gitClient.signingKeySecret.name`                       | Specifies the name of an existing `Secret` which contains the Git user's signing key. The value should be accessible under `.data.signingKey` in the same namespace as Kargo. When the signing key is a GPG key, the GPG key's name and email address identity must match the values defined for `controller.gitClient.name` and `controller.gitClient.email`.                                                                                                                                                                                                                                                                                                                                                                   | `""`                |
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_clusterconfigs.yaml b/charts/kargo/resources/crds/kargo.akuity.io_clusterconfigs.yaml
index 1b88bdd2..d10d0e6a 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_clusterconfigs.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_clusterconfigs.yaml
@@ -97,6 +97,38 @@ spec:
                       required:
                       - secretRef
                       type: object
+                    dockerhub:
+                      description: |-
+                        DockerHub contains the configuration for a webhook receiver that is
+                        compatible with DockerHub payloads.
+                      properties:
+                        secretRef:
+                          description: |-
+                            SecretRef contains a reference to a Secret. For Project-scoped webhook
+                            receivers, the referenced Secret must be in the same namespace as the
+                            ProjectConfig.
+
+                            The Secret's data map is expected to contain a `secret` key whose value
+                            does NOT need to be shared directly with Docker Hub when registering a
+                            webhook. It is used only by Kargo to create a complex, hard-to-guess URL,
+                            which implicitly serves as a shared secret. For more information about
+                            Docker Hub webhooks, please refer to the Docker documentation:
+                              https://docs.docker.com/docker-hub/webhooks/
+                          properties:
+                            name:
+                              default: ""
+                              description: |-
+                                Name of the referent.
+                                This field is effectively required, but due to backwards compatibility is
+                                allowed to be empty. Instances of this type with an empty value here are
+                                almost certainly wrong.
+                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                              type: string
+                          type: object
+                          x-kubernetes-map-type: atomic
+                      required:
+                      - secretRef
+                      type: object
                     github:
                       description: |-
                         GitHub contains the configuration for a webhook receiver that is compatible
@@ -274,6 +306,18 @@ spec:
                 x-kubernetes-list-map-keys:
                 - type
                 x-kubernetes-list-type: map
+              lastHandledRefresh:
+                description: |-
+                  LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+                  annotation that was handled by the controller. This field can be used to
+                  determine whether the request to refresh the resource has been handled.
+                type: string
+              observedGeneration:
+                description: |-
+                  ObservedGeneration represents the .metadata.generation that this
+                  ClusterConfig was reconciled against.
+                format: int64
+                type: integer
               webhookReceivers:
                 description: WebhookReceivers describes the status of cluster-scoped
                   webhook receivers.
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_projectconfigs.yaml b/charts/kargo/resources/crds/kargo.akuity.io_projectconfigs.yaml
index 65e55a12..1a47d226 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_projectconfigs.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_projectconfigs.yaml
@@ -192,6 +192,38 @@ spec:
                       required:
                       - secretRef
                       type: object
+                    dockerhub:
+                      description: |-
+                        DockerHub contains the configuration for a webhook receiver that is
+                        compatible with DockerHub payloads.
+                      properties:
+                        secretRef:
+                          description: |-
+                            SecretRef contains a reference to a Secret. For Project-scoped webhook
+                            receivers, the referenced Secret must be in the same namespace as the
+                            ProjectConfig.
+
+                            The Secret's data map is expected to contain a `secret` key whose value
+                            does NOT need to be shared directly with Docker Hub when registering a
+                            webhook. It is used only by Kargo to create a complex, hard-to-guess URL,
+                            which implicitly serves as a shared secret. For more information about
+                            Docker Hub webhooks, please refer to the Docker documentation:
+                              https://docs.docker.com/docker-hub/webhooks/
+                          properties:
+                            name:
+                              default: ""
+                              description: |-
+                                Name of the referent.
+                                This field is effectively required, but due to backwards compatibility is
+                                allowed to be empty. Instances of this type with an empty value here are
+                                almost certainly wrong.
+                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                              type: string
+                          type: object
+                          x-kubernetes-map-type: atomic
+                      required:
+                      - secretRef
+                      type: object
                     github:
                       description: |-
                         GitHub contains the configuration for a webhook receiver that is compatible
@@ -369,6 +401,18 @@ spec:
                 x-kubernetes-list-map-keys:
                 - type
                 x-kubernetes-list-type: map
+              lastHandledRefresh:
+                description: |-
+                  LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+                  annotation that was handled by the controller. This field can be used to
+                  determine whether the request to refresh the resource has been handled.
+                type: string
+              observedGeneration:
+                description: |-
+                  ObservedGeneration represents the .metadata.generation that this
+                  ProjectConfig was reconciled against.
+                format: int64
+                type: integer
               webhookReceivers:
                 description: |-
                   WebhookReceivers describes the status of Project-specific webhook
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_projects.yaml b/charts/kargo/resources/crds/kargo.akuity.io_projects.yaml
index 4513cf97..aee12b86 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_projects.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_projects.yaml
@@ -197,6 +197,38 @@ spec:
                       required:
                       - secretRef
                       type: object
+                    dockerhub:
+                      description: |-
+                        DockerHub contains the configuration for a webhook receiver that is
+                        compatible with DockerHub payloads.
+                      properties:
+                        secretRef:
+                          description: |-
+                            SecretRef contains a reference to a Secret. For Project-scoped webhook
+                            receivers, the referenced Secret must be in the same namespace as the
+                            ProjectConfig.
+
+                            The Secret's data map is expected to contain a `secret` key whose value
+                            does NOT need to be shared directly with Docker Hub when registering a
+                            webhook. It is used only by Kargo to create a complex, hard-to-guess URL,
+                            which implicitly serves as a shared secret. For more information about
+                            Docker Hub webhooks, please refer to the Docker documentation:
+                              https://docs.docker.com/docker-hub/webhooks/
+                          properties:
+                            name:
+                              default: ""
+                              description: |-
+                                Name of the referent.
+                                This field is effectively required, but due to backwards compatibility is
+                                allowed to be empty. Instances of this type with an empty value here are
+                                almost certainly wrong.
+                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                              type: string
+                          type: object
+                          x-kubernetes-map-type: atomic
+                      required:
+                      - secretRef
+                      type: object
                     github:
                       description: |-
                         GitHub contains the configuration for a webhook receiver that is compatible
diff --git a/charts/kargo/templates/controller/configmap.yaml b/charts/kargo/templates/controller/configmap.yaml
index 2dc826ca..b636cf46 100644
--- a/charts/kargo/templates/controller/configmap.yaml
+++ b/charts/kargo/templates/controller/configmap.yaml
@@ -43,4 +43,7 @@ data:
   MAX_CONCURRENT_PROMOTION_RECONCILES: {{ .Values.controller.reconcilers.promotions.maxConcurrentReconciles | default .Values.controller.reconcilers.maxConcurrentReconciles | quote }}
   MAX_CONCURRENT_STAGE_RECONCILES: {{ .Values.controller.reconcilers.stages.maxConcurrentReconciles | default .Values.controller.reconcilers.maxConcurrentReconciles | quote }}
   MAX_CONCURRENT_WAREHOUSE_RECONCILES: {{ .Values.controller.reconcilers.warehouses.maxConcurrentReconciles | default .Values.controller.reconcilers.maxConcurrentReconciles | quote }}
+  {{- if .Values.controller.reconcilers.warehouses.minReconciliationInterval }}
+  MIN_WAREHOUSE_RECONCILIATION_INTERVAL: {{ .Values.controller.reconcilers.warehouses.minReconciliationInterval | quote }}
+  {{- end }}
 {{- end }}
diff --git a/charts/kargo/values.yaml b/charts/kargo/values.yaml
index 8c7fe389..86874fd5 100755
--- a/charts/kargo/values.yaml
+++ b/charts/kargo/values.yaml
@@ -449,6 +449,8 @@ controller:
     warehouses:
       ## @param controller.reconcilers.warehouses.maxConcurrentReconciles optionally overrides the maximum number of Warehouse resources the controller can reconcile concurrently.
       maxConcurrentReconciles:
+      ## @param controller.reconcilers.warehouses.minReconciliationInterval optionally sets the minimum reconciliation interval for Warehouse resources. Accepts duration format (e.g., "5m", "1h", "30s"). If a Warehouse specifies an interval lower than this minimum, the minimum value will be enforced instead. If not set, no minimum is enforced.
+      minReconciliationInterval: "5m0s"
 
   gitClient:
     ## @param controller.gitClient.name Specifies the name of the Kargo controller (used when authoring Git commits).
diff --git a/cmd/controlplane/external_webhooks.go b/cmd/controlplane/external_webhooks.go
index 27e38c09..7e70b5e6 100644
--- a/cmd/controlplane/external_webhooks.go
+++ b/cmd/controlplane/external_webhooks.go
@@ -7,6 +7,8 @@ import (
 	"runtime"
 
 	"github.com/spf13/cobra"
+	corev1 "k8s.io/api/core/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
 	libCluster "sigs.k8s.io/controller-runtime/pkg/cluster"
 
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
@@ -79,7 +81,18 @@ func (o *externalWebhooksServerOptions) run(ctx context.Context) error {
 	}
 	kubernetes.ConfigureQPSBurst(ctx, restCfg, o.QPS, o.Burst)
 
-	cluster, err := libCluster.New(restCfg)
+	cluster, err := libCluster.New(
+		restCfg,
+		func(clusterOptions *libCluster.Options) {
+			clusterOptions.Client = client.Options{
+				Cache: &client.CacheOptions{
+					DisableFor: []client.Object{
+						&corev1.Secret{},
+					},
+				},
+			}
+		},
+	)
 	if err != nil {
 		return fmt.Errorf("error creating Kubernetes client: %w", err)
 	}
diff --git a/docs/static/img/kargo-ui.png b/docs/static/img/kargo-ui.png
new file mode 100644
index 00000000..d6921e5e
Binary files /dev/null and b/docs/static/img/kargo-ui.png differ
diff --git a/internal/api/cluster_config.go b/internal/api/cluster_config.go
index cce3e380..30cdeff2 100644
--- a/internal/api/cluster_config.go
+++ b/internal/api/cluster_config.go
@@ -3,7 +3,9 @@ package api
 import (
 	"context"
 	"fmt"
+	"time"
 
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -30,3 +32,28 @@ func GetClusterConfig(
 	}
 	return &clusterCfg, nil
 }
+
+// RefreshClusterConfig forces reconciliation the ClusterConfig by setting an
+// annotation on the ClusterConfig, causing the controller to reconcile it.
+// Currently, the annotation value is the timestamp of the request, but might in
+// the future include additional metadata/context necessary for the request.
+func RefreshClusterConfig(
+	ctx context.Context,
+	c client.Client,
+) (*kargoapi.ClusterConfig, error) {
+	config := &kargoapi.ClusterConfig{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: ClusterConfigName,
+		},
+	}
+	if err := patchAnnotation(
+		ctx,
+		c,
+		config,
+		kargoapi.AnnotationKeyRefresh,
+		time.Now().Format(time.RFC3339),
+	); err != nil {
+		return nil, fmt.Errorf("refresh: %w", err)
+	}
+	return config, nil
+}
diff --git a/internal/api/project_config.go b/internal/api/project_config.go
index 33e8e13b..64e28876 100644
--- a/internal/api/project_config.go
+++ b/internal/api/project_config.go
@@ -3,7 +3,9 @@ package api
 import (
 	"context"
 	"fmt"
+	"time"
 
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -33,3 +35,30 @@ func GetProjectConfig(
 	}
 	return &projectCfg, nil
 }
+
+// RefreshProjectConfig forces reconciliation the ProjectConfig by setting an
+// annotation on the ProjectConfig, causing the controller to reconcile it.
+// Currently, the annotation value is the timestamp of the request, but might in
+// the future include additional metadata/context necessary for the request.
+func RefreshProjectConfig(
+	ctx context.Context,
+	c client.Client,
+	project string,
+) (*kargoapi.ProjectConfig, error) {
+	config := &kargoapi.ProjectConfig{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      project,
+			Namespace: project,
+		},
+	}
+	if err := patchAnnotation(
+		ctx,
+		c,
+		config,
+		kargoapi.AnnotationKeyRefresh,
+		time.Now().Format(time.RFC3339),
+	); err != nil {
+		return nil, fmt.Errorf("refresh: %w", err)
+	}
+	return config, nil
+}
diff --git a/internal/cli/cmd/delete/cluster_config.go b/internal/cli/cmd/delete/cluster_config.go
new file mode 100644
index 00000000..60f1ed28
--- /dev/null
+++ b/internal/cli/cmd/delete/cluster_config.go
@@ -0,0 +1,103 @@
+package delete
+
+import (
+	"context"
+	"fmt"
+
+	"connectrpc.com/connect"
+	"github.com/spf13/cobra"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/cli-runtime/pkg/genericclioptions"
+	"k8s.io/cli-runtime/pkg/genericiooptions"
+
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/cli/client"
+	"github.com/akuity/kargo/internal/cli/config"
+	"github.com/akuity/kargo/internal/cli/io"
+	"github.com/akuity/kargo/internal/cli/kubernetes"
+	"github.com/akuity/kargo/internal/cli/option"
+	"github.com/akuity/kargo/internal/cli/templates"
+)
+
+type deleteClusterConfigOptions struct {
+	genericiooptions.IOStreams
+	*genericclioptions.PrintFlags
+
+	Config        config.CLIConfig
+	ClientOptions client.Options
+
+	Project string
+}
+
+func newClusterConfigCommand(
+	cfg config.CLIConfig,
+	streams genericiooptions.IOStreams,
+) *cobra.Command {
+	cmdOpts := &deleteClusterConfigOptions{
+		Config:    cfg,
+		IOStreams: streams,
+		PrintFlags: genericclioptions.NewPrintFlags("deleted").
+			WithTypeSetter(kubernetes.GetScheme()),
+	}
+
+	cmd := &cobra.Command{
+		Use:     "clusterconfig",
+		Aliases: []string{"clusterconfigs"},
+		Short:   "Delete cluster configuration",
+		Args:    option.NoArgs,
+		Example: templates.Example(`
+# Delete the cluster configuration
+kargo delete clusterconfig
+`),
+		RunE: func(cmd *cobra.Command, _ []string) error {
+			return cmdOpts.run(cmd.Context())
+		},
+	}
+
+	// Register the option flags on the command.
+	cmdOpts.addFlags(cmd)
+
+	// Set the input/output streams for the command.
+	io.SetIOStreams(cmd, cmdOpts.IOStreams)
+
+	return cmd
+}
+
+// addFlags adds the flags for the delete project config options to the provided
+// command.
+func (o *deleteClusterConfigOptions) addFlags(cmd *cobra.Command) {
+	o.ClientOptions.AddFlags(cmd.PersistentFlags())
+	o.PrintFlags.AddFlags(cmd)
+}
+
+// run removes the project config from the project.
+func (o *deleteClusterConfigOptions) run(ctx context.Context) error {
+	kargoSvcCli, err := client.GetClientFromConfig(ctx, o.Config, o.ClientOptions)
+	if err != nil {
+		return fmt.Errorf("get client from config: %w", err)
+	}
+
+	printer, err := o.PrintFlags.ToPrinter()
+	if err != nil {
+		return fmt.Errorf("create printer: %w", err)
+	}
+
+	if _, err = kargoSvcCli.DeleteClusterConfig(
+		ctx,
+		connect.NewRequest(&v1alpha1.DeleteClusterConfigRequest{}),
+	); err != nil {
+		return fmt.Errorf("delete cluster configuration: %w", err)
+	}
+
+	if err = printer.PrintObj(
+		&kargoapi.ClusterConfig{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: o.Project,
+			},
+		}, o.IOStreams.Out); err != nil {
+		return fmt.Errorf("print project configuration: %w", err)
+	}
+
+	return nil
+}
diff --git a/internal/cli/cmd/delete/delete.go b/internal/cli/cmd/delete/delete.go
index 7c67c22a..684af6ae 100644
--- a/internal/cli/cmd/delete/delete.go
+++ b/internal/cli/cmd/delete/delete.go
@@ -75,6 +75,7 @@ kargo delete warehouse --project=my-project my-warehouse
 	io.SetIOStreams(cmd, cmdOpts.IOStreams)
 
 	// Register subcommands.
+	cmd.AddCommand(newClusterConfigCommand(cfg, streams))
 	cmd.AddCommand(newCredentialsCommand(cfg, streams))
 	cmd.AddCommand(newProjectCommand(cfg, streams))
 	cmd.AddCommand(newProjectConfigCommand(cfg, streams))
diff --git a/internal/cli/cmd/delete/project_config.go b/internal/cli/cmd/delete/project_config.go
index 058d8b0a..e49a882c 100644
--- a/internal/cli/cmd/delete/project_config.go
+++ b/internal/cli/cmd/delete/project_config.go
@@ -42,20 +42,19 @@ func newProjectConfigCommand(
 	}
 
 	cmd := &cobra.Command{
-		Use:     "projectconfig [PROJECT]",
+		Use:     "projectconfig [--project=project]",
 		Aliases: []string{"projectconfigs"},
 		Short:   "Delete project configuration",
-		Args:    option.MaximumNArgs(1),
+		Args:    option.NoArgs,
 		Example: templates.Example(`
 # Delete project configuration for my-project
-kargo delete projectconfig my-project
+kargo delete projectconfig --project=my-project
 
 # Delete project configuration for the default project
 kargo config set-project my-project
 kargo delete projectconfig
 `),
-		RunE: func(cmd *cobra.Command, args []string) error {
-			cmdOpts.complete(args)
+		RunE: func(cmd *cobra.Command, _ []string) error {
 			return cmdOpts.run(cmd.Context())
 		},
 	}
@@ -74,14 +73,9 @@ kargo delete projectconfig
 func (o *deleteProjectConfigOptions) addFlags(cmd *cobra.Command) {
 	o.ClientOptions.AddFlags(cmd.PersistentFlags())
 	o.PrintFlags.AddFlags(cmd)
-}
 
-// complete sets the options from the command arguments.
-func (o *deleteProjectConfigOptions) complete(args []string) {
-	o.Project = o.Config.Project
-	if len(args) > 0 {
-		o.Project = args[0]
-	}
+	option.Project(cmd.Flags(), &o.Project, o.Config.Project,
+		"The Project for which to delete the configuration. If not set, the default project will be used.")
 }
 
 // run removes the project config from the project.
@@ -99,7 +93,7 @@ func (o *deleteProjectConfigOptions) run(ctx context.Context) error {
 	if _, err = kargoSvcCli.DeleteProjectConfig(
 		ctx,
 		connect.NewRequest(&v1alpha1.DeleteProjectConfigRequest{
-			Name: o.Project,
+			Project: o.Project,
 		}),
 	); err != nil {
 		return fmt.Errorf("delete project configuration: %w", err)
@@ -108,7 +102,8 @@ func (o *deleteProjectConfigOptions) run(ctx context.Context) error {
 	if err = printer.PrintObj(
 		&kargoapi.ProjectConfig{
 			ObjectMeta: metav1.ObjectMeta{
-				Name: o.Project,
+				Name:      o.Project,
+				Namespace: o.Project,
 			},
 		}, o.IOStreams.Out); err != nil {
 		return fmt.Errorf("print project configuration: %w", err)
diff --git a/internal/cli/cmd/get/cluster_config.go b/internal/cli/cmd/get/cluster_config.go
new file mode 100644
index 00000000..216bc86c
--- /dev/null
+++ b/internal/cli/cmd/get/cluster_config.go
@@ -0,0 +1,123 @@
+package get
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"connectrpc.com/connect"
+	"github.com/spf13/cobra"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/duration"
+	"k8s.io/cli-runtime/pkg/genericclioptions"
+	"k8s.io/cli-runtime/pkg/genericiooptions"
+
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/cli/client"
+	"github.com/akuity/kargo/internal/cli/config"
+	"github.com/akuity/kargo/internal/cli/io"
+	"github.com/akuity/kargo/internal/cli/kubernetes"
+	"github.com/akuity/kargo/internal/cli/templates"
+)
+
+type getClusterConfigOptions struct {
+	genericiooptions.IOStreams
+	*genericclioptions.PrintFlags
+
+	*getOptions
+
+	Config        config.CLIConfig
+	ClientOptions client.Options
+}
+
+func newGetClusterConfigCommand(
+	cfg config.CLIConfig,
+	streams genericiooptions.IOStreams,
+	getOptions *getOptions,
+) *cobra.Command {
+	cmdOpts := &getClusterConfigOptions{
+		Config:     cfg,
+		IOStreams:  streams,
+		getOptions: getOptions,
+		PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(kubernetes.GetScheme()),
+	}
+
+	cmd := &cobra.Command{
+		Use:     "clusterconfig [--no-headers]",
+		Aliases: []string{"clusterconfigs"},
+		Short:   "Display cluster configuration",
+		Args:    cobra.NoArgs,
+		Example: templates.Example(`
+# Get cluster configuration
+kargo get clusterconfig
+`),
+		RunE: func(cmd *cobra.Command, _ []string) error {
+			return cmdOpts.run(cmd.Context())
+		},
+	}
+
+	// Register the option flags on the command.
+	cmdOpts.addFlags(cmd)
+
+	// Set the input/output streams for the command.
+	io.SetIOStreams(cmd, cmdOpts.IOStreams)
+
+	return cmd
+}
+
+// addFlags adds the flags for the get cluster config options to the provided
+// command.
+func (o *getClusterConfigOptions) addFlags(cmd *cobra.Command) {
+	o.ClientOptions.AddFlags(cmd.PersistentFlags())
+	o.PrintFlags.AddFlags(cmd)
+}
+
+// run gets the cluster config from the server and prints it to the console.
+func (o *getClusterConfigOptions) run(ctx context.Context) error {
+	kargoSvcCli, err := client.GetClientFromConfig(ctx, o.Config, o.ClientOptions)
+	if err != nil {
+		return fmt.Errorf("get client from config: %w", err)
+	}
+
+	res := make([]*kargoapi.ClusterConfig, 0, 1)
+	resp, err := kargoSvcCli.GetClusterConfig(
+		ctx,
+		connect.NewRequest(
+			&v1alpha1.GetClusterConfigRequest{},
+		),
+	)
+	if err != nil {
+		return fmt.Errorf("get cluster configuration: %w", err)
+	}
+	if resp.Msg.GetClusterConfig() != nil {
+		res = append(res, resp.Msg.GetClusterConfig())
+	}
+
+	if err = printObjects(res, o.PrintFlags, o.IOStreams, o.NoHeaders); err != nil {
+		return fmt.Errorf("print cluster configuration: %w", err)
+	}
+	return nil
+}
+
+func newClusterConfigTable(list *metav1.List) *metav1.Table {
+	rows := make([]metav1.TableRow, len(list.Items))
+	for i, item := range list.Items {
+		cfg := item.Object.(*kargoapi.ClusterConfig) // nolint: forcetypeassert
+
+		rows[i] = metav1.TableRow{
+			Cells: []any{
+				cfg.Name,
+				duration.HumanDuration(time.Since(cfg.CreationTimestamp.Time)),
+			},
+			Object: list.Items[i],
+		}
+	}
+	return &metav1.Table{
+		ColumnDefinitions: []metav1.TableColumnDefinition{
+			{Name: "Name", Type: "string"},
+			{Name: "Age", Type: "string"},
+		},
+		Rows: rows,
+	}
+}
diff --git a/internal/cli/cmd/get/get.go b/internal/cli/cmd/get/get.go
index 554cc571..cb0f79c4 100644
--- a/internal/cli/cmd/get/get.go
+++ b/internal/cli/cmd/get/get.go
@@ -44,6 +44,7 @@ kargo get promotions --project=my-project --stage=my-stage
 	cmdOpts.addFlags(cmd)
 
 	// Register subcommands.
+	cmd.AddCommand(newGetClusterConfigCommand(cfg, streams, cmdOpts))
 	cmd.AddCommand(newGetCredentialsCommand(cfg, streams, cmdOpts))
 	cmd.AddCommand(newGetFreightCommand(cfg, streams, cmdOpts))
 	cmd.AddCommand(newGetProjectConfigCommand(cfg, streams, cmdOpts))
@@ -94,6 +95,8 @@ func printObjects[T runtime.Object](
 	switch any(t).(type) {
 	case *corev1.Secret:
 		printObj = newCredentialsTable(list)
+	case *kargoapi.ClusterConfig:
+		printObj = newClusterConfigTable(list)
 	case *kargoapi.Freight:
 		printObj = newFreightTable(list)
 	case *kargoapi.Project:
diff --git a/internal/cli/cmd/get/project_config.go b/internal/cli/cmd/get/project_config.go
index 183fac7f..c74bc980 100644
--- a/internal/cli/cmd/get/project_config.go
+++ b/internal/cli/cmd/get/project_config.go
@@ -18,6 +18,7 @@ import (
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/io"
 	"github.com/akuity/kargo/internal/cli/kubernetes"
+	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
 )
 
@@ -46,20 +47,19 @@ func newGetProjectConfigCommand(
 	}
 
 	cmd := &cobra.Command{
-		Use:     "projectconfig [PROJECT] [--no-headers]",
+		Use:     "projectconfig [--project=project] [--no-headers]",
 		Aliases: []string{"projectconfigs"},
 		Short:   "Display project configuration",
-		Args:    cobra.MaximumNArgs(1),
+		Args:    cobra.NoArgs,
 		Example: templates.Example(`
 # Get project configuration for my-project
-kargo get projectconfig my-project
+kargo get projectconfig --project=my-project
 
 # Get project configuration for the default project
 kargo config set-project my-project
 kargo get projectconfig
 `),
-		RunE: func(cmd *cobra.Command, args []string) error {
-			cmdOpts.complete(args)
+		RunE: func(cmd *cobra.Command, _ []string) error {
 			return cmdOpts.run(cmd.Context())
 		},
 	}
@@ -78,14 +78,11 @@ kargo get projectconfig
 func (o *getProjectConfigOptions) addFlags(cmd *cobra.Command) {
 	o.ClientOptions.AddFlags(cmd.PersistentFlags())
 	o.PrintFlags.AddFlags(cmd)
-}
 
-// complete sets the options from the command arguments.
-func (o *getProjectConfigOptions) complete(args []string) {
-	o.Project = o.Config.Project
-	if len(args) > 0 {
-		o.Project = args[0]
-	}
+	option.Project(
+		cmd.Flags(), &o.Project, o.Config.Project,
+		"The project for which to get the configuration. If not set, the default project will be used.",
+	)
 }
 
 // run gets the project config from the server and prints it to the console.
@@ -100,7 +97,7 @@ func (o *getProjectConfigOptions) run(ctx context.Context) error {
 		ctx,
 		connect.NewRequest(
 			&v1alpha1.GetProjectConfigRequest{
-				Name: o.Project,
+				Project: o.Project,
 			},
 		),
 	)
diff --git a/internal/cli/cmd/refresh/cluster_config.go b/internal/cli/cmd/refresh/cluster_config.go
new file mode 100644
index 00000000..6751da29
--- /dev/null
+++ b/internal/cli/cmd/refresh/cluster_config.go
@@ -0,0 +1,88 @@
+package refresh
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"connectrpc.com/connect"
+	"github.com/spf13/cobra"
+
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/api/service/v1alpha1/svcv1alpha1connect"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+	"github.com/akuity/kargo/internal/cli/config"
+	"github.com/akuity/kargo/internal/cli/option"
+	"github.com/akuity/kargo/internal/cli/templates"
+)
+
+func newRefreshClusterConfigCommand(cfg config.CLIConfig) *cobra.Command {
+	cmdOpts := &refreshOptions{
+		Config:       cfg,
+		ResourceType: refreshResourceTypeClusterConfig,
+	}
+
+	cmd := &cobra.Command{
+		Use:  "clusterconfig [--wait]",
+		Args: option.NoArgs,
+		Example: templates.Example(`
+# Refresh the cluster configuration
+kargo refresh clusterconfig
+
+# Refresh the cluster configuration and wait for it to complete
+kargo refresh clusterconfig --wait
+`),
+		RunE: func(cmd *cobra.Command, _ []string) error {
+			cmdOpts.complete(nil)
+
+			if err := cmdOpts.validate(); err != nil {
+				return err
+			}
+
+			return cmdOpts.run(cmd.Context())
+		},
+	}
+
+	// Register the option flags on the command.
+	cmdOpts.addFlags(cmd)
+
+	return cmd
+}
+
+func waitForClusterConfig(
+	ctx context.Context,
+	kargoSvcCli svcv1alpha1connect.KargoServiceClient,
+) error {
+	res, err := kargoSvcCli.WatchClusterConfig(ctx, connect.NewRequest(&v1alpha1.WatchClusterConfigRequest{}))
+	if err != nil {
+		return fmt.Errorf("watch clusterconfig: %w", err)
+	}
+	defer func() {
+		if conn, connErr := res.Conn(); connErr == nil {
+			_ = conn.CloseRequest()
+		}
+	}()
+	for {
+		if !res.Receive() {
+			if err = res.Err(); err != nil {
+				return fmt.Errorf("watch clusterconfig: %w", err)
+			}
+			return errors.New("unexpected end of watch stream")
+		}
+		msg := res.Msg()
+		if msg == nil || msg.ClusterConfig == nil {
+			return errors.New("unexpected response")
+		}
+		token, ok := api.RefreshAnnotationValue(msg.ClusterConfig.GetAnnotations())
+		if !ok {
+			return fmt.Errorf(
+				"ClusterConfig %q has no %q annotation",
+				msg.ClusterConfig.Name, kargoapi.AnnotationKeyRefresh,
+			)
+		}
+		if msg.ClusterConfig.Status.LastHandledRefresh == token {
+			return nil
+		}
+	}
+}
diff --git a/internal/cli/cmd/refresh/project_config.go b/internal/cli/cmd/refresh/project_config.go
new file mode 100644
index 00000000..d4a4730b
--- /dev/null
+++ b/internal/cli/cmd/refresh/project_config.go
@@ -0,0 +1,95 @@
+package refresh
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"connectrpc.com/connect"
+	"github.com/spf13/cobra"
+
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/api/service/v1alpha1/svcv1alpha1connect"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+	"github.com/akuity/kargo/internal/cli/config"
+	"github.com/akuity/kargo/internal/cli/option"
+	"github.com/akuity/kargo/internal/cli/templates"
+)
+
+func newRefreshProjectConfigCommand(cfg config.CLIConfig) *cobra.Command {
+	cmdOpts := &refreshOptions{
+		Config:       cfg,
+		ResourceType: refreshResourceTypeProjectConfig,
+	}
+
+	cmd := &cobra.Command{
+		Use:  "projectconfig [--project=project] [--wait]",
+		Args: option.NoArgs,
+		Example: templates.Example(`
+# Refresh the project configuration
+kargo refresh projectconfig --project=my-project
+
+# Refresh the project configuration and wait for it to complete
+kargo refresh projectconfig --project=my-project --wait
+
+# Refresh the project configuration in the default project
+kargo config set-project my-project
+kargo refresh projectconfig
+`),
+		RunE: func(cmd *cobra.Command, _ []string) error {
+			cmdOpts.complete(nil)
+
+			if err := cmdOpts.validate(); err != nil {
+				return err
+			}
+
+			return cmdOpts.run(cmd.Context())
+		},
+	}
+
+	// Register the option flags on the command.
+	cmdOpts.addFlags(cmd)
+
+	return cmd
+}
+
+func waitForProjectConfig(
+	ctx context.Context,
+	kargoSvcCli svcv1alpha1connect.KargoServiceClient,
+	project string,
+) error {
+	res, err := kargoSvcCli.WatchProjectConfig(ctx, connect.NewRequest(&v1alpha1.WatchProjectConfigRequest{
+		Project: project,
+	}))
+	if err != nil {
+		return fmt.Errorf("watch projectconfig: %w", err)
+	}
+	defer func() {
+		if conn, connErr := res.Conn(); connErr == nil {
+			_ = conn.CloseRequest()
+		}
+	}()
+	for {
+		if !res.Receive() {
+			if err = res.Err(); err != nil {
+				return fmt.Errorf("watch projectconfig: %w", err)
+			}
+			return errors.New("unexpected end of watch stream")
+		}
+		msg := res.Msg()
+		if msg == nil || msg.ProjectConfig == nil {
+			return errors.New("unexpected response")
+		}
+		token, ok := api.RefreshAnnotationValue(msg.ProjectConfig.GetAnnotations())
+		if !ok {
+			return fmt.Errorf(
+				"ProjectConfig %q has no %q annotation",
+				msg.ProjectConfig.Name, kargoapi.AnnotationKeyRefresh,
+			)
+		}
+		if msg.ProjectConfig.Status.LastHandledRefresh == token {
+			return nil
+		}
+	}
+}
diff --git a/internal/cli/cmd/refresh/refresh.go b/internal/cli/cmd/refresh/refresh.go
index 5385a8f6..e71c87c8 100644
--- a/internal/cli/cmd/refresh/refresh.go
+++ b/internal/cli/cmd/refresh/refresh.go
@@ -17,16 +17,42 @@ import (
 )
 
 const (
-	refreshResourceTypeWarehouse = "warehouse"
-	refreshResourceTypeStage     = "stage"
+	refreshResourceTypeClusterConfig refreshResourceType = "clusterconfig"
+	refreshResourceTypeProjectConfig refreshResourceType = "projectconfig"
+	refreshResourceTypeStage         refreshResourceType = "stage"
+	refreshResourceTypeWarehouse     refreshResourceType = "warehouse"
 )
 
+type refreshResourceType string
+
+func (t refreshResourceType) String() string {
+	return string(t)
+}
+
+func (t refreshResourceType) requiresName() bool {
+	switch t {
+	case refreshResourceTypeStage, refreshResourceTypeWarehouse:
+		return true
+	default:
+		return false
+	}
+}
+
+func (t refreshResourceType) requiresProject() bool {
+	switch t {
+	case refreshResourceTypeProjectConfig, refreshResourceTypeStage, refreshResourceTypeWarehouse:
+		return true
+	default:
+		return false
+	}
+}
+
 type refreshOptions struct {
 	Config        config.CLIConfig
 	ClientOptions client.Options
 
 	Project      string
-	ResourceType string
+	ResourceType refreshResourceType
 	Name         string
 	Wait         bool
 }
@@ -34,7 +60,7 @@ type refreshOptions struct {
 func NewCommand(cfg config.CLIConfig) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "refresh TYPE NAME [--wait]",
-		Short: "Refresh a stage or warehouse",
+		Short: "Refresh a Kargo resource",
 		Args:  option.NoArgs,
 		Example: templates.Example(`
 # Refresh a warehouse
@@ -42,12 +68,20 @@ kargo refresh warehouse --project=my-project my-warehouse
 
 # Refresh a stage
 kargo refresh stage --project=my-project my-stage
+
+# Refresh the cluster configuration
+kargo refresh clusterconfig
+
+# Refresh the project configuration
+kargo refresh projectconfig --project=my-project
 `),
 	}
 
 	// Register subcommands.
-	cmd.AddCommand(newRefreshWarehouseCommand(cfg))
+	cmd.AddCommand(newRefreshClusterConfigCommand(cfg))
+	cmd.AddCommand(newRefreshProjectConfigCommand(cfg))
 	cmd.AddCommand(newRefreshStageCommand(cfg))
+	cmd.AddCommand(newRefreshWarehouseCommand(cfg))
 
 	return cmd
 }
@@ -56,16 +90,19 @@ kargo refresh stage --project=my-project my-stage
 func (o *refreshOptions) addFlags(cmd *cobra.Command) {
 	o.ClientOptions.AddFlags(cmd.PersistentFlags())
 
-	option.Project(cmd.Flags(), &o.Project, o.Config.Project,
-		"The Project the resource belongs to. If not set, the default project will be used.")
+	if o.ResourceType.requiresProject() {
+		option.Project(cmd.Flags(), &o.Project, o.Config.Project,
+			"The Project the resource belongs to. If not set, the default project will be used.")
+	}
 	option.Wait(cmd.Flags(), &o.Wait, false, "Wait for the refresh to complete.")
 }
 
 // complete sets the resource type for the refresh options, and further parses
 // the command arguments to set the resource name.
-func (o *refreshOptions) complete(resourceType string, args []string) {
-	o.ResourceType = resourceType
-	o.Name = strings.TrimSpace(args[0])
+func (o *refreshOptions) complete(args []string) {
+	if o.ResourceType.requiresName() {
+		o.Name = strings.TrimSpace(args[0])
+	}
 }
 
 // validate performs validation of the options. If the options are invalid, an
@@ -77,11 +114,11 @@ func (o *refreshOptions) validate() error {
 		errs = append(errs, errors.New("resource type is required"))
 	}
 
-	if o.Project == "" {
+	if o.ResourceType.requiresProject() && o.Project == "" {
 		errs = append(errs, errors.New("project is required"))
 	}
 
-	if o.Name == "" {
+	if o.ResourceType.requiresName() && o.Name == "" {
 		errs = append(errs, errors.New("name is required"))
 	}
 
@@ -96,17 +133,22 @@ func (o *refreshOptions) run(ctx context.Context) error {
 	}
 
 	switch o.ResourceType {
-	case refreshResourceTypeWarehouse:
-		_, err = kargoSvcCli.RefreshWarehouse(ctx, connect.NewRequest(&v1alpha1.RefreshWarehouseRequest{
+	case refreshResourceTypeClusterConfig:
+		_, err = kargoSvcCli.RefreshClusterConfig(ctx, connect.NewRequest(&v1alpha1.RefreshClusterConfigRequest{}))
+	case refreshResourceTypeProjectConfig:
+		_, err = kargoSvcCli.RefreshProjectConfig(ctx, connect.NewRequest(&v1alpha1.RefreshProjectConfigRequest{
 			Project: o.Project,
-			Name:    o.Name,
 		}))
-
 	case refreshResourceTypeStage:
 		_, err = kargoSvcCli.RefreshStage(ctx, connect.NewRequest(&v1alpha1.RefreshStageRequest{
 			Project: o.Project,
 			Name:    o.Name,
 		}))
+	case refreshResourceTypeWarehouse:
+		_, err = kargoSvcCli.RefreshWarehouse(ctx, connect.NewRequest(&v1alpha1.RefreshWarehouseRequest{
+			Project: o.Project,
+			Name:    o.Name,
+		}))
 	}
 	if err != nil {
 		return fmt.Errorf("refresh %s: %w", o.ResourceType, err)
@@ -114,15 +156,29 @@ func (o *refreshOptions) run(ctx context.Context) error {
 
 	if o.Wait {
 		switch o.ResourceType {
-		case refreshResourceTypeWarehouse:
-			err = waitForWarehouse(ctx, kargoSvcCli, o.Project, o.Name)
+		case refreshResourceTypeClusterConfig:
+			err = waitForClusterConfig(ctx, kargoSvcCli)
+		case refreshResourceTypeProjectConfig:
+			err = waitForProjectConfig(ctx, kargoSvcCli, o.Project)
 		case refreshResourceTypeStage:
 			err = waitForStage(ctx, kargoSvcCli, o.Project, o.Name)
+		case refreshResourceTypeWarehouse:
+			err = waitForWarehouse(ctx, kargoSvcCli, o.Project, o.Name)
 		}
 		if err != nil {
 			return fmt.Errorf("wait %s: %w", o.ResourceType, err)
 		}
 	}
-	fmt.Printf("%s '%s/%s' refreshed\n", o.ResourceType, o.Project, o.Name)
+	fmt.Printf("%s '%s' refreshed\n", o.ResourceType, formatName(o.Project, o.Name))
 	return nil
 }
+
+func formatName(project, name string) string {
+	if project == "" {
+		return name
+	}
+	if name == "" {
+		return project
+	}
+	return fmt.Sprintf("%s/%s", project, name)
+}
diff --git a/internal/cli/cmd/refresh/stage.go b/internal/cli/cmd/refresh/stage.go
index 9e579715..f5021090 100644
--- a/internal/cli/cmd/refresh/stage.go
+++ b/internal/cli/cmd/refresh/stage.go
@@ -19,7 +19,8 @@ import (
 
 func newRefreshStageCommand(cfg config.CLIConfig) *cobra.Command {
 	cmdOpts := &refreshOptions{
-		Config: cfg,
+		Config:       cfg,
+		ResourceType: refreshResourceTypeStage,
 	}
 
 	cmd := &cobra.Command{
@@ -37,7 +38,7 @@ kargo config set-project my-project
 kargo refresh stage my-stage
 `),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			cmdOpts.complete(refreshResourceTypeStage, args)
+			cmdOpts.complete(args)
 
 			if err := cmdOpts.validate(); err != nil {
 				return err
diff --git a/internal/cli/cmd/refresh/warehouse.go b/internal/cli/cmd/refresh/warehouse.go
index 8cc35a7f..7191e384 100644
--- a/internal/cli/cmd/refresh/warehouse.go
+++ b/internal/cli/cmd/refresh/warehouse.go
@@ -19,7 +19,8 @@ import (
 
 func newRefreshWarehouseCommand(cfg config.CLIConfig) *cobra.Command {
 	cmdOpts := &refreshOptions{
-		Config: cfg,
+		Config:       cfg,
+		ResourceType: refreshResourceTypeWarehouse,
 	}
 
 	cmd := &cobra.Command{
@@ -37,7 +38,7 @@ kargo config set-project my-project
 kargo refresh warehouse my-warehouse
 `),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			cmdOpts.complete(refreshResourceTypeWarehouse, args)
+			cmdOpts.complete(args)
 
 			if err := cmdOpts.validate(); err != nil {
 				return err
diff --git a/internal/controller/management/clusterconfigs/cluster_configs.go b/internal/controller/management/clusterconfigs/cluster_configs.go
index e2a43922..30ed104e 100644
--- a/internal/controller/management/clusterconfigs/cluster_configs.go
+++ b/internal/controller/management/clusterconfigs/cluster_configs.go
@@ -11,7 +11,6 @@ import (
 	kerrors "k8s.io/apimachinery/pkg/util/errors"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/event"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 	"sigs.k8s.io/controller-runtime/pkg/predicate"
 
@@ -19,8 +18,10 @@ import (
 	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/internal/conditions"
 	"github.com/akuity/kargo/internal/controller"
+	"github.com/akuity/kargo/internal/kargo"
 	"github.com/akuity/kargo/internal/kubeclient"
 	"github.com/akuity/kargo/internal/logging"
+	intpredicate "github.com/akuity/kargo/internal/predicate"
 	"github.com/akuity/kargo/internal/webhook/external"
 )
 
@@ -45,22 +46,24 @@ func SetupReconcilerWithManager(
 	kargoMgr manager.Manager,
 	cfg ReconcilerConfig,
 ) error {
+	const maxConcurrentReconciles = 1 // There's only ever one ClusterConfig resource
+
 	if _, err := ctrl.NewControllerManagedBy(kargoMgr).
 		For(&kargoapi.ClusterConfig{}).
+		WithOptions(controller.CommonOptions(maxConcurrentReconciles)).
+		WithEventFilter(intpredicate.IgnoreDelete[client.Object]{}).
 		WithEventFilter(
-			predicate.Funcs{
-				DeleteFunc: func(event.DeleteEvent) bool {
-					return false
-				},
-			},
+			predicate.Or(
+				predicate.GenerationChangedPredicate{},
+				kargo.RefreshRequested{},
+			),
 		).
-		WithOptions(controller.CommonOptions(1)). // There's only ever one ClusterConfig resource
 		Build(newReconciler(kargoMgr.GetClient(), cfg)); err != nil {
 		return fmt.Errorf("error creating ClusterConfig reconciler: %w", err)
 	}
 	logging.LoggerFromContext(ctx).Info(
 		"Initialized ClusterConfig reconciler",
-		"maxConcurrentReconciles", 1,
+		"maxConcurrentReconciles", maxConcurrentReconciles,
 	)
 	return nil
 }
@@ -103,6 +106,11 @@ func (r *reconciler) Reconcile(
 	newStatus, reconcileErr := r.reconcile(ctx, clusterCfg)
 	logger.Debug("done reconciling ClusterConfig")
 
+	// Record the current refresh token as having been handled.
+	if token, ok := api.RefreshAnnotationValue(clusterCfg.GetAnnotations()); ok {
+		newStatus.LastHandledRefresh = token
+	}
+
 	// Patch the status of the ClusterConfig.
 	if err := kubeclient.PatchStatus(
 		ctx,
@@ -177,6 +185,10 @@ func (r *reconciler) reconcile(
 		}
 	}
 
+	// At this point, we have successfully reconciled the ClusterConfig and
+	// can set the observed generation.
+	status.ObservedGeneration = clusterCfg.GetGeneration()
+
 	return status, nil
 }
 
diff --git a/internal/controller/management/projectconfigs/project_configs.go b/internal/controller/management/projectconfigs/project_configs.go
index 74ea663b..efef640e 100644
--- a/internal/controller/management/projectconfigs/project_configs.go
+++ b/internal/controller/management/projectconfigs/project_configs.go
@@ -10,7 +10,6 @@ import (
 	kerrors "k8s.io/apimachinery/pkg/util/errors"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/event"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 	"sigs.k8s.io/controller-runtime/pkg/predicate"
 
@@ -18,8 +17,10 @@ import (
 	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/internal/conditions"
 	"github.com/akuity/kargo/internal/controller"
+	"github.com/akuity/kargo/internal/kargo"
 	"github.com/akuity/kargo/internal/kubeclient"
 	"github.com/akuity/kargo/internal/logging"
+	intpredicate "github.com/akuity/kargo/internal/predicate"
 	"github.com/akuity/kargo/internal/webhook/external"
 )
 
@@ -46,14 +47,14 @@ func SetupReconcilerWithManager(
 ) error {
 	_, err := ctrl.NewControllerManagedBy(kargoMgr).
 		For(&kargoapi.ProjectConfig{}).
+		WithOptions(controller.CommonOptions(cfg.MaxConcurrentReconciles)).
+		WithEventFilter(intpredicate.IgnoreDelete[client.Object]{}).
 		WithEventFilter(
-			predicate.Funcs{
-				DeleteFunc: func(event.DeleteEvent) bool {
-					return false
-				},
-			},
+			predicate.Or(
+				predicate.GenerationChangedPredicate{},
+				kargo.RefreshRequested{},
+			),
 		).
-		WithOptions(controller.CommonOptions(cfg.MaxConcurrentReconciles)).
 		Build(newReconciler(kargoMgr.GetClient(), cfg))
 	if err != nil {
 		return fmt.Errorf("error creating ProjectConfig reconciler: %w", err)
@@ -104,6 +105,11 @@ func (r *reconciler) Reconcile(
 	newStatus, reconcileErr := r.reconcile(ctx, projectConfig)
 	logger.Debug("done reconciling ProjectConfig")
 
+	// Record the current refresh token as having been handled.
+	if token, ok := api.RefreshAnnotationValue(projectConfig.GetAnnotations()); ok {
+		newStatus.LastHandledRefresh = token
+	}
+
 	// Patch the status of the ProjectConfig.
 	if err := kubeclient.PatchStatus(
 		ctx,
@@ -181,6 +187,10 @@ func (r *reconciler) reconcile(
 		}
 	}
 
+	// At this point, we have successfully reconciled the ProjectConfig and
+	// can set the observed generation.
+	status.ObservedGeneration = projectCfg.GetGeneration()
+
 	return status, nil
 }
 
diff --git a/internal/controller/stages/regular_stages.go b/internal/controller/stages/regular_stages.go
index 28b2d5b3..2501097e 100644
--- a/internal/controller/stages/regular_stages.go
+++ b/internal/controller/stages/regular_stages.go
@@ -277,7 +277,7 @@ func (r *RegularStageReconciler) SetupWithManager(
 			ctx,
 			&kargoapi.Stage{},
 			indexer.StagesByAnalysisRunField,
-			indexer.StagesByAnalysisRun(r.cfg.RolloutsControllerInstanceID),
+			indexer.StagesByAnalysisRun(r.cfg.ShardName),
 		); err != nil {
 			return fmt.Errorf("error setting up index for Stages by AnalysisRun: %w", err)
 		}
diff --git a/internal/controller/warehouses/warehouses.go b/internal/controller/warehouses/warehouses.go
index fa035857..ca520fe7 100644
--- a/internal/controller/warehouses/warehouses.go
+++ b/internal/controller/warehouses/warehouses.go
@@ -28,8 +28,9 @@ import (
 )
 
 type ReconcilerConfig struct {
-	ShardName               string `envconfig:"SHARD_NAME"`
-	MaxConcurrentReconciles int    `envconfig:"MAX_CONCURRENT_WAREHOUSE_RECONCILES" default:"4"`
+	ShardName                 string        `envconfig:"SHARD_NAME"`
+	MaxConcurrentReconciles   int           `envconfig:"MAX_CONCURRENT_WAREHOUSE_RECONCILES" default:"4"`
+	MinReconciliationInterval time.Duration `envconfig:"MIN_WAREHOUSE_RECONCILIATION_INTERVAL"`
 }
 
 func ReconcilerConfigFromEnv() ReconcilerConfig {
@@ -42,6 +43,7 @@ func ReconcilerConfigFromEnv() ReconcilerConfig {
 type reconciler struct {
 	client                     client.Client
 	credentialsDB              credentials.Database
+	minReconciliationInterval  time.Duration
 	imageSourceURLFnsByBaseURL map[string]func(string, string) string
 
 	// The following behaviors are overridable for testing purposes:
@@ -101,7 +103,7 @@ func SetupReconcilerWithManager(
 		).
 		WithEventFilter(shardPredicate).
 		WithOptions(controller.CommonOptions(cfg.MaxConcurrentReconciles)).
-		Complete(newReconciler(mgr.GetClient(), credentialsDB)); err != nil {
+		Complete(newReconciler(mgr.GetClient(), credentialsDB, cfg.MinReconciliationInterval)); err != nil {
 		return fmt.Errorf("error building Warehouse reconciler: %w", err)
 	}
 
@@ -116,12 +118,14 @@ func SetupReconcilerWithManager(
 func newReconciler(
 	kubeClient client.Client,
 	credentialsDB credentials.Database,
+	minReconciliationInterval time.Duration,
 ) *reconciler {
 	r := &reconciler{
-		client:                  kubeClient,
-		credentialsDB:           credentialsDB,
-		gitCloneFn:              git.Clone,
-		discoverChartVersionsFn: helm.DiscoverChartVersions,
+		client:                    kubeClient,
+		credentialsDB:             credentialsDB,
+		minReconciliationInterval: minReconciliationInterval,
+		gitCloneFn:                git.Clone,
+		discoverChartVersionsFn:   helm.DiscoverChartVersions,
 		imageSourceURLFnsByBaseURL: map[string]func(string, string) string{
 			githubURLPrefix: getGithubImageSourceURL,
 		},
@@ -200,7 +204,9 @@ func (r *reconciler) Reconcile(
 	}
 
 	// Everything succeeded, look for new changes on the defined interval.
-	return ctrl.Result{RequeueAfter: getRequeueInterval(warehouse)}, nil
+	return ctrl.Result{
+		RequeueAfter: warehouse.GetInterval(r.minReconciliationInterval),
+	}, nil
 }
 
 func (r *reconciler) syncWarehouse(
@@ -698,20 +704,3 @@ func shouldDiscoverArtifacts(
 		return false
 	}
 }
-
-// getRequeueInterval calculates and returns the time interval remaining until
-// the next requeue should occur. If the interval has already passed, it returns
-// a zero duration.
-func getRequeueInterval(warehouse *kargoapi.Warehouse) time.Duration {
-	if warehouse.Status.DiscoveredArtifacts == nil ||
-		warehouse.Status.DiscoveredArtifacts.DiscoveredAt.IsZero() {
-		return warehouse.Spec.Interval.Duration
-	}
-	interval := warehouse.Status.DiscoveredArtifacts.DiscoveredAt.
-		Add(warehouse.Spec.Interval.Duration).
-		Sub(metav1.Now().Time)
-	if interval < 0 {
-		return 0
-	}
-	return interval
-}
diff --git a/internal/image/normalization.go b/internal/image/normalization.go
new file mode 100644
index 00000000..6466acb3
--- /dev/null
+++ b/internal/image/normalization.go
@@ -0,0 +1,32 @@
+package image
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/google/go-containerregistry/pkg/name"
+)
+
+// NormalizeURL normalizes image repository URLs. Notably, hostnames docker.io
+// and index.docker.io, if present, are dropped. The optional /library prefix
+// for official images from Docker Hub, if included, is also dropped. Valid,
+// non-Docker Hub repository URLs will be returned unchanged.
+//
+// This is useful for the purposes of comparison and also in cases where a
+// canonical representation of a repository URL is needed. Any URL that cannot
+// be normalized will be returned as-is.
+func NormalizeURL(repoURL string) string {
+	parsed, err := name.ParseReference(repoURL, name.WeakValidation)
+	if err != nil {
+		return repoURL
+	}
+	reg := parsed.Context().Registry.Name()
+	repo := parsed.Context().RepositoryStr()
+	// For all images from Docker Hub, reg will be "index.docker.io" after
+	// parsing, except when the input explicitly uses "registry-1.docker.io",
+	// which is preserved.
+	if reg == "index.docker.io" || reg == "registry-1.docker.io" {
+		return strings.TrimPrefix(repo, "library/")
+	}
+	return fmt.Sprintf("%s/%s", reg, repo)
+}
diff --git a/internal/indexer/indexer.go b/internal/indexer/indexer.go
index d3622c5f..884ea866 100644
--- a/internal/indexer/indexer.go
+++ b/internal/indexer/indexer.go
@@ -17,6 +17,7 @@ import (
 	"github.com/akuity/kargo/internal/expressions"
 	"github.com/akuity/kargo/internal/git"
 	"github.com/akuity/kargo/internal/helm"
+	"github.com/akuity/kargo/internal/image"
 	"github.com/akuity/kargo/internal/logging"
 	"github.com/akuity/kargo/internal/promotion"
 )
@@ -513,14 +514,7 @@ func WarehousesBySubscribedURLs(obj client.Object) []string {
 			)
 		}
 		if sub.Image != nil && sub.Image.RepoURL != "" {
-			repoURLs = append(
-				repoURLs,
-				// TODO(fuskovic): This chart URL normalization logic is adequate for
-				// normalizing image URLs in the near term, but should eventually be
-				// replaced with dedicated image URL normalization logic.
-				// See https://github.com/akuity/kargo/issues/3999
-				helm.NormalizeChartRepositoryURL(sub.Image.RepoURL),
-			)
+			repoURLs = append(repoURLs, image.NormalizeURL(sub.Image.RepoURL))
 		}
 	}
 	return repoURLs
diff --git a/internal/server/delete_cluster_config_v1alpha1.go b/internal/server/delete_cluster_config_v1alpha1.go
new file mode 100644
index 00000000..2917a56d
--- /dev/null
+++ b/internal/server/delete_cluster_config_v1alpha1.go
@@ -0,0 +1,30 @@
+package server
+
+import (
+	"context"
+	"fmt"
+
+	"connectrpc.com/connect"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+)
+
+func (s *server) DeleteClusterConfig(
+	ctx context.Context,
+	_ *connect.Request[svcv1alpha1.DeleteClusterConfigRequest],
+) (*connect.Response[svcv1alpha1.DeleteClusterConfigResponse], error) {
+	if err := s.client.Delete(
+		ctx,
+		&kargoapi.ClusterConfig{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: api.ClusterConfigName,
+			},
+		},
+	); err != nil {
+		return nil, fmt.Errorf("delete ClusterConfig: %w", err)
+	}
+	return connect.NewResponse(&svcv1alpha1.DeleteClusterConfigResponse{}), nil
+}
diff --git a/internal/server/delete_project_config_v1alpha1.go b/internal/server/delete_project_config_v1alpha1.go
index 319873e1..157fec2d 100644
--- a/internal/server/delete_project_config_v1alpha1.go
+++ b/internal/server/delete_project_config_v1alpha1.go
@@ -15,12 +15,12 @@ func (s *server) DeleteProjectConfig(
 	ctx context.Context,
 	req *connect.Request[svcv1alpha1.DeleteProjectConfigRequest],
 ) (*connect.Response[svcv1alpha1.DeleteProjectConfigResponse], error) {
-	name := req.Msg.GetName()
-	if err := validateFieldNotEmpty("name", name); err != nil {
+	project := req.Msg.GetProject()
+	if err := validateFieldNotEmpty("project", project); err != nil {
 		return nil, err
 	}
 
-	if err := s.validateProjectExists(ctx, name); err != nil {
+	if err := s.validateProjectExists(ctx, project); err != nil {
 		return nil, err
 	}
 
@@ -28,7 +28,8 @@ func (s *server) DeleteProjectConfig(
 		ctx,
 		&kargoapi.ProjectConfig{
 			ObjectMeta: metav1.ObjectMeta{
-				Name: name,
+				Name:      project,
+				Namespace: project,
 			},
 		},
 	); err != nil {
diff --git a/internal/server/get_cluster_config_v1alpha1.go b/internal/server/get_cluster_config_v1alpha1.go
new file mode 100644
index 00000000..aacab71f
--- /dev/null
+++ b/internal/server/get_cluster_config_v1alpha1.go
@@ -0,0 +1,64 @@
+package server
+
+import (
+	"context"
+	"fmt"
+
+	"connectrpc.com/connect"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+)
+
+func (s *server) GetClusterConfig(
+	ctx context.Context,
+	req *connect.Request[svcv1alpha1.GetClusterConfigRequest],
+) (*connect.Response[svcv1alpha1.GetClusterConfigResponse], error) {
+	// Get the ClusterConfig from the Kubernetes API as an unstructured object.
+	// Using an unstructured object allows us to return the object _as presented
+	// by the API_ if a raw format is requested.
+	u := unstructured.Unstructured{
+		Object: map[string]any{
+			"apiVersion": kargoapi.GroupVersion.String(),
+			"kind":       "ClusterConfig",
+		},
+	}
+	if err := s.client.Get(ctx, client.ObjectKey{Name: api.ClusterConfigName}, &u); err != nil {
+		if client.IgnoreNotFound(err) == nil {
+			err = fmt.Errorf("ClusterConfig %q not found", api.ClusterConfigName)
+			return nil, connect.NewError(connect.CodeNotFound, err)
+		}
+		return nil, err
+	}
+
+	switch req.Msg.GetFormat() {
+	case svcv1alpha1.RawFormat_RAW_FORMAT_JSON, svcv1alpha1.RawFormat_RAW_FORMAT_YAML:
+		_, raw, err := objectOrRaw(&u, req.Msg.GetFormat())
+		if err != nil {
+			return nil, connect.NewError(connect.CodeInternal, err)
+		}
+		return connect.NewResponse(&svcv1alpha1.GetClusterConfigResponse{
+			Result: &svcv1alpha1.GetClusterConfigResponse_Raw{
+				Raw: raw,
+			},
+		}), nil
+	default:
+		p := kargoapi.ClusterConfig{}
+		if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &p); err != nil {
+			return nil, connect.NewError(connect.CodeInternal, err)
+		}
+		obj, _, err := objectOrRaw(&p, req.Msg.GetFormat())
+		if err != nil {
+			return nil, connect.NewError(connect.CodeInternal, err)
+		}
+		return connect.NewResponse(&svcv1alpha1.GetClusterConfigResponse{
+			Result: &svcv1alpha1.GetClusterConfigResponse_ClusterConfig{
+				ClusterConfig: obj,
+			},
+		}), nil
+	}
+}
diff --git a/internal/server/get_project_config_v1alpha1.go b/internal/server/get_project_config_v1alpha1.go
index a9567668..4b124079 100644
--- a/internal/server/get_project_config_v1alpha1.go
+++ b/internal/server/get_project_config_v1alpha1.go
@@ -17,8 +17,12 @@ func (s *server) GetProjectConfig(
 	ctx context.Context,
 	req *connect.Request[svcv1alpha1.GetProjectConfigRequest],
 ) (*connect.Response[svcv1alpha1.GetProjectConfigResponse], error) {
-	name := req.Msg.GetName()
-	if err := validateFieldNotEmpty("name", name); err != nil {
+	project := req.Msg.GetProject()
+	if err := validateFieldNotEmpty("project", project); err != nil {
+		return nil, err
+	}
+
+	if err := s.validateProjectExists(ctx, project); err != nil {
 		return nil, err
 	}
 
@@ -31,9 +35,9 @@ func (s *server) GetProjectConfig(
 			"kind":       "ProjectConfig",
 		},
 	}
-	if err := s.client.Get(ctx, client.ObjectKey{Name: name, Namespace: name}, &u); err != nil {
+	if err := s.client.Get(ctx, client.ObjectKey{Name: project, Namespace: project}, &u); err != nil {
 		if client.IgnoreNotFound(err) == nil {
-			err = fmt.Errorf("ProjectConfig %q not found", name)
+			err = fmt.Errorf("ProjectConfig %q not found", project)
 			return nil, connect.NewError(connect.CodeNotFound, err)
 		}
 		return nil, err
diff --git a/internal/server/refresh_cluster_config_v1alpha1.go b/internal/server/refresh_cluster_config_v1alpha1.go
new file mode 100644
index 00000000..4fe5aec0
--- /dev/null
+++ b/internal/server/refresh_cluster_config_v1alpha1.go
@@ -0,0 +1,28 @@
+package server
+
+import (
+	"context"
+
+	"connectrpc.com/connect"
+	"k8s.io/apimachinery/pkg/api/errors"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+)
+
+func (s *server) RefreshClusterConfig(
+	ctx context.Context,
+	_ *connect.Request[svcv1alpha1.RefreshClusterConfigRequest],
+) (*connect.Response[svcv1alpha1.RefreshClusterConfigResponse], error) {
+	config, err := api.RefreshClusterConfig(ctx, s.client.InternalClient())
+	if err != nil {
+		if errors.IsNotFound(err) {
+			return nil, connect.NewError(connect.CodeNotFound, err)
+		}
+		return nil, err
+	}
+
+	return connect.NewResponse(&svcv1alpha1.RefreshClusterConfigResponse{
+		ClusterConfig: config,
+	}), nil
+}
diff --git a/internal/server/refresh_project_config_v1alpha1.go b/internal/server/refresh_project_config_v1alpha1.go
new file mode 100644
index 00000000..60bab178
--- /dev/null
+++ b/internal/server/refresh_project_config_v1alpha1.go
@@ -0,0 +1,36 @@
+package server
+
+import (
+	"context"
+
+	"connectrpc.com/connect"
+	"k8s.io/apimachinery/pkg/api/errors"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+)
+
+func (s *server) RefreshProjectConfig(
+	ctx context.Context,
+	req *connect.Request[svcv1alpha1.RefreshProjectConfigRequest],
+) (*connect.Response[svcv1alpha1.RefreshProjectConfigResponse], error) {
+	project := req.Msg.GetProject()
+	if err := validateFieldNotEmpty("project", project); err != nil {
+		return nil, err
+	}
+
+	if err := s.validateProjectExists(ctx, project); err != nil {
+		return nil, err
+	}
+
+	config, err := api.RefreshProjectConfig(ctx, s.client.InternalClient(), project)
+	if err != nil {
+		if errors.IsNotFound(err) {
+			return nil, connect.NewError(connect.CodeNotFound, err)
+		}
+		return nil, err
+	}
+	return connect.NewResponse(&svcv1alpha1.RefreshProjectConfigResponse{
+		ProjectConfig: config,
+	}), nil
+}
diff --git a/internal/server/watch_cluster_config_v1alpha1.go b/internal/server/watch_cluster_config_v1alpha1.go
new file mode 100644
index 00000000..4524eed6
--- /dev/null
+++ b/internal/server/watch_cluster_config_v1alpha1.go
@@ -0,0 +1,62 @@
+package server
+
+import (
+	"context"
+	"fmt"
+
+	"connectrpc.com/connect"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/fields"
+	"k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+)
+
+func (s *server) WatchClusterConfig(
+	ctx context.Context,
+	_ *connect.Request[svcv1alpha1.WatchClusterConfigRequest],
+	stream *connect.ServerStream[svcv1alpha1.WatchClusterConfigResponse],
+) error {
+	if err := s.client.Get(ctx, client.ObjectKey{
+		Name: api.ClusterConfigName,
+	}, &kargoapi.ClusterConfig{}); err != nil {
+		return fmt.Errorf("get ClusterConfig: %w", err)
+	}
+
+	opts := metav1.ListOptions{
+		FieldSelector: fields.OneTermEqualSelector(metav1.ObjectNameField, api.ClusterConfigName).String(),
+	}
+	w, err := s.client.Watch(ctx, &kargoapi.ClusterConfig{}, api.ClusterConfigName, opts)
+	if err != nil {
+		return fmt.Errorf("watch ClusterConfig: %w", err)
+	}
+	defer w.Stop()
+	for {
+		select {
+		case <-ctx.Done():
+			return ctx.Err()
+		case e, ok := <-w.ResultChan():
+			if !ok {
+				return nil
+			}
+			u, ok := e.Object.(*unstructured.Unstructured)
+			if !ok {
+				return fmt.Errorf("unexpected object type %T", e.Object)
+			}
+			var config *kargoapi.ClusterConfig
+			if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &config); err != nil {
+				return fmt.Errorf("from unstructured: %w", err)
+			}
+			if err := stream.Send(&svcv1alpha1.WatchClusterConfigResponse{
+				ClusterConfig: config,
+				Type:          string(e.Type),
+			}); err != nil {
+				return fmt.Errorf("send response: %w", err)
+			}
+		}
+	}
+}
diff --git a/internal/server/watch_project_config_v1alpha1.go b/internal/server/watch_project_config_v1alpha1.go
new file mode 100644
index 00000000..a69e747c
--- /dev/null
+++ b/internal/server/watch_project_config_v1alpha1.go
@@ -0,0 +1,71 @@
+package server
+
+import (
+	"context"
+	"fmt"
+
+	"connectrpc.com/connect"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/fields"
+	"k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+)
+
+func (s *server) WatchProjectConfig(
+	ctx context.Context,
+	req *connect.Request[svcv1alpha1.WatchProjectConfigRequest],
+	stream *connect.ServerStream[svcv1alpha1.WatchProjectConfigResponse],
+) error {
+	project := req.Msg.GetProject()
+	if err := validateFieldNotEmpty("project", project); err != nil {
+		return err
+	}
+
+	if err := s.validateProjectExists(ctx, project); err != nil {
+		return err
+	}
+
+	if err := s.client.Get(ctx, client.ObjectKey{
+		Namespace: project,
+		Name:      project,
+	}, &kargoapi.ProjectConfig{}); err != nil {
+		return fmt.Errorf("get projectconfig: %w", err)
+	}
+
+	opts := metav1.ListOptions{
+		FieldSelector: fields.OneTermEqualSelector(metav1.ObjectNameField, project).String(),
+	}
+	w, err := s.client.Watch(ctx, &kargoapi.ProjectConfig{}, project, opts)
+	if err != nil {
+		return fmt.Errorf("watch ProjectConfig: %w", err)
+	}
+	defer w.Stop()
+	for {
+		select {
+		case <-ctx.Done():
+			return ctx.Err()
+		case e, ok := <-w.ResultChan():
+			if !ok {
+				return nil
+			}
+			u, ok := e.Object.(*unstructured.Unstructured)
+			if !ok {
+				return fmt.Errorf("unexpected object type %T", e.Object)
+			}
+			var config *kargoapi.ProjectConfig
+			if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &config); err != nil {
+				return fmt.Errorf("from unstructured: %w", err)
+			}
+			if err := stream.Send(&svcv1alpha1.WatchProjectConfigResponse{
+				ProjectConfig: config,
+				Type:          string(e.Type),
+			}); err != nil {
+				return fmt.Errorf("send response: %w", err)
+			}
+		}
+	}
+}
diff --git a/internal/webhook/external/dockerhub.go b/internal/webhook/external/dockerhub.go
new file mode 100644
index 00000000..e761ba0d
--- /dev/null
+++ b/internal/webhook/external/dockerhub.go
@@ -0,0 +1,154 @@
+package external
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/http"
+
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	xhttp "github.com/akuity/kargo/internal/http"
+	"github.com/akuity/kargo/internal/image"
+	"github.com/akuity/kargo/internal/io"
+	"github.com/akuity/kargo/internal/logging"
+)
+
+const (
+	dockerhub                    = "dockerhub"
+	dockerhubSecretDataKey       = "secret"
+	dockerhubWebhookBodyMaxBytes = 2 << 20 // 2MB
+)
+
+func init() {
+	registry.register(
+		dockerhub,
+		webhookReceiverRegistration{
+			predicate: func(cfg kargoapi.WebhookReceiverConfig) bool {
+				return cfg.DockerHub != nil
+			},
+			factory: newDockerHubWebhookReceiver,
+		},
+	)
+}
+
+// dockerhubWebhookReceiver is an implementation of WebhookReceiver that handles
+// inbound webhooks from Docker Hub.
+type dockerhubWebhookReceiver struct {
+	*baseWebhookReceiver
+}
+
+// newDockerHubWebhookReceiver returns a new instance of
+// dockerhubWebhookReceiver.
+func newDockerHubWebhookReceiver(
+	c client.Client,
+	project string,
+	cfg kargoapi.WebhookReceiverConfig,
+) WebhookReceiver {
+	return &dockerhubWebhookReceiver{
+		baseWebhookReceiver: &baseWebhookReceiver{
+			client:     c,
+			project:    project,
+			secretName: cfg.GitHub.SecretRef.Name,
+		},
+	}
+}
+
+// getReceiverType implements WebhookReceiver.
+func (d *dockerhubWebhookReceiver) getReceiverType() string {
+	return dockerhub
+}
+
+// getSecretValues implements WebhookReceiver.
+func (d *dockerhubWebhookReceiver) getSecretValues(
+	secretData map[string][]byte,
+) ([]string, error) {
+	secretValue, ok := secretData[dockerhubSecretDataKey]
+	if !ok {
+		return nil,
+			errors.New("Secret data is not valid for a Docker Hub WebhookReceiver")
+	}
+	return []string{string(secretValue)}, nil
+}
+
+// GetHandler implements WebhookReceiver.
+func (d *dockerhubWebhookReceiver) GetHandler() http.HandlerFunc {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		ctx := r.Context()
+
+		logger := logging.LoggerFromContext(ctx)
+
+		// Early check of Content-Length if available
+		if contentLength := r.ContentLength; contentLength > dockerhubWebhookBodyMaxBytes {
+			xhttp.WriteErrorJSON(
+				w,
+				xhttp.Error(
+					fmt.Errorf("content exceeds limit of %d bytes", dockerhubWebhookBodyMaxBytes),
+					http.StatusRequestEntityTooLarge,
+				),
+			)
+			return
+		}
+
+		body, err := io.LimitRead(r.Body, dockerhubWebhookBodyMaxBytes)
+		if err != nil {
+			if errors.Is(err, &io.BodyTooLargeError{}) {
+				xhttp.WriteErrorJSON(
+					w,
+					xhttp.Error(err, http.StatusRequestEntityTooLarge),
+				)
+				return
+			}
+			xhttp.WriteErrorJSON(w, err)
+			return
+		}
+
+		payload := struct {
+			Repository struct {
+				RepoName string `json:"repo_name"`
+			} `json:"repository"`
+		}{}
+
+		if err = json.Unmarshal(body, &payload); err != nil {
+			xhttp.WriteErrorJSON(
+				w,
+				xhttp.Error(errors.New("invalid request body"), http.StatusBadRequest),
+			)
+			return
+		}
+
+		// Normalize the repo name
+		repoURL := image.NormalizeURL(payload.Repository.RepoName)
+
+		logger = logger.WithValues("repoURL", repoURL)
+		ctx = logging.ContextWithLogger(ctx, logger)
+
+		result, err := refreshWarehouses(ctx, d.client, d.project, repoURL)
+		if err != nil {
+			xhttp.WriteErrorJSON(w, err)
+			return
+		}
+		if result.failures > 0 {
+			xhttp.WriteResponseJSON(
+				w,
+				http.StatusInternalServerError,
+				map[string]string{
+					"error": fmt.Sprintf("failed to refresh %d of %d warehouses",
+						result.failures,
+						result.successes+result.failures,
+					),
+				},
+			)
+			return
+		}
+		xhttp.WriteResponseJSON(
+			w,
+			http.StatusOK,
+			map[string]string{
+				"msg": fmt.Sprintf("refreshed %d warehouse(s)", result.successes),
+			},
+		)
+
+	})
+}
diff --git a/internal/webhook/external/github.go b/internal/webhook/external/github.go
index eabf1846..d9e08011 100644
--- a/internal/webhook/external/github.go
+++ b/internal/webhook/external/github.go
@@ -12,6 +12,7 @@ import (
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/git"
 	xhttp "github.com/akuity/kargo/internal/http"
+	"github.com/akuity/kargo/internal/image"
 	"github.com/akuity/kargo/internal/io"
 	"github.com/akuity/kargo/internal/logging"
 )
@@ -190,7 +191,7 @@ func (g *githubWebhookReceiver) GetHandler() http.HandlerFunc {
 				xhttp.WriteErrorJSON(w, err)
 				return
 			}
-			repoURL = ref.Context().Name()
+			repoURL = image.NormalizeURL(ref.Context().Name())
 
 		case *gh.PingEvent:
 			xhttp.WriteResponseJSON(
diff --git a/internal/webhook/external/quay.go b/internal/webhook/external/quay.go
index 9313f5c8..abb9cb1d 100644
--- a/internal/webhook/external/quay.go
+++ b/internal/webhook/external/quay.go
@@ -10,6 +10,7 @@ import (
 
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	xhttp "github.com/akuity/kargo/internal/http"
+	"github.com/akuity/kargo/internal/image"
 	"github.com/akuity/kargo/internal/io"
 	"github.com/akuity/kargo/internal/logging"
 )
@@ -124,7 +125,7 @@ func (q *quayWebhookReceiver) GetHandler() http.HandlerFunc {
 			return
 		}
 
-		repoURL := payload.DockerURL
+		repoURL := image.NormalizeURL(payload.DockerURL)
 
 		logger = logger.WithValues("repoURL", repoURL)
 		ctx = logging.ContextWithLogger(ctx, logger)
diff --git a/internal/webhook/kubernetes/clusterconfig/webhook.go b/internal/webhook/kubernetes/clusterconfig/webhook.go
index 41263d36..d9f8adca 100644
--- a/internal/webhook/kubernetes/clusterconfig/webhook.go
+++ b/internal/webhook/kubernetes/clusterconfig/webhook.go
@@ -13,11 +13,10 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/internal/webhook/kubernetes/external"
 )
 
-const acceptedName = "cluster"
-
 var clusterConfigGroupKind = schema.GroupKind{
 	Group: kargoapi.GroupVersion.Group,
 	Kind:  "ClusterConfig",
@@ -87,12 +86,12 @@ func (w *webhook) validateObjectMeta(
 	f *field.Path,
 	meta metav1.ObjectMeta,
 ) field.ErrorList {
-	if meta.Name != acceptedName {
+	if meta.Name != api.ClusterConfigName {
 		return field.ErrorList{
 			field.Invalid(
 				f.Child("name"),
 				meta.Name,
-				fmt.Sprintf("name %q must be %q", meta.Name, acceptedName),
+				fmt.Sprintf("name %q must be %q", meta.Name, api.ClusterConfigName),
 			),
 		}
 	}
diff --git a/internal/webhook/kubernetes/external/validation.go b/internal/webhook/kubernetes/external/validation.go
index 656c0bc2..b04b3011 100644
--- a/internal/webhook/kubernetes/external/validation.go
+++ b/internal/webhook/kubernetes/external/validation.go
@@ -30,6 +30,9 @@ func validateMutuallyExclusive(
 		if r.Bitbucket != nil {
 			receivers = append(receivers, "Bitbucket")
 		}
+		if r.DockerHub != nil {
+			receivers = append(receivers, "DockerHub")
+		}
 		if r.GitHub != nil {
 			receivers = append(receivers, "GitHub")
 		}
diff --git a/ui/src/features/project/pipelines/pipelines.tsx b/ui/src/features/project/pipelines/pipelines.tsx
index 423578db..1cc6ea2f 100644
--- a/ui/src/features/project/pipelines/pipelines.tsx
+++ b/ui/src/features/project/pipelines/pipelines.tsx
@@ -63,7 +63,7 @@ export const Pipelines = (props: { creatingStage?: boolean; creatingWarehouse?:
   const projectConfigQuery = useQuery(
     getProjectConfig,
     {
-      name
+      project: name
     },
     {
       transport: projectConfigTransport
diff --git a/ui/src/features/project/settings/views/project-config/project-config.tsx b/ui/src/features/project/settings/views/project-config/project-config.tsx
index d94f4370..38d63113 100644
--- a/ui/src/features/project/settings/views/project-config/project-config.tsx
+++ b/ui/src/features/project/settings/views/project-config/project-config.tsx
@@ -30,7 +30,7 @@ export const ProjectConfig = () => {
 
   const projectConfigQuery = useQuery(
     getProjectConfig,
-    { name, format: RawFormat.YAML },
+    { project: name, format: RawFormat.YAML },
     {
       transport: projectConfigTransport
     }
diff --git a/ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts b/ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts
index b0d9b8af..3be3eda8 100644
--- a/ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts
+++ b/ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts
@@ -72,6 +72,21 @@ export const deleteStage = KargoService.method.deleteStage;
  */
 export const refreshStage = KargoService.method.refreshStage;
 
+/**
+ * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.GetClusterConfig
+ */
+export const getClusterConfig = KargoService.method.getClusterConfig;
+
+/**
+ * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterConfig
+ */
+export const deleteClusterConfig = KargoService.method.deleteClusterConfig;
+
+/**
+ * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.RefreshClusterConfig
+ */
+export const refreshClusterConfig = KargoService.method.refreshClusterConfig;
+
 /**
  * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions
  */
@@ -102,15 +117,22 @@ export const getProject = KargoService.method.getProject;
  */
 export const listProjects = KargoService.method.listProjects;
 
+/**
+ * ProjectConfig APIs 
+ *
+ * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig
+ */
+export const getProjectConfig = KargoService.method.getProjectConfig;
+
 /**
  * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig
  */
 export const deleteProjectConfig = KargoService.method.deleteProjectConfig;
 
 /**
- * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig
+ * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.RefreshProjectConfig
  */
-export const getProjectConfig = KargoService.method.getProjectConfig;
+export const refreshProjectConfig = KargoService.method.refreshProjectConfig;
 
 /**
  * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight
diff --git a/ui/src/gen/api/service/v1alpha1/service_pb.ts b/ui/src/gen/api/service/v1alpha1/service_pb.ts
index e968fa00..66b6daf2 100644
--- a/ui/src/gen/api/service/v1alpha1/service_pb.ts
+++ b/ui/src/gen/api/service/v1alpha1/service_pb.ts
@@ -6,7 +6,7 @@ import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobu
 import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv1";
 import type { Timestamp } from "@bufbuild/protobuf/wkt";
 import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
-import type { ClusterPromotionTask, Freight, Project, ProjectConfig, Promotion, PromotionTask, Stage, Warehouse } from "../../v1alpha1/generated_pb";
+import type { ClusterConfig, ClusterPromotionTask, Freight, Project, ProjectConfig, Promotion, PromotionTask, Stage, Warehouse } from "../../v1alpha1/generated_pb";
 import { file_api_v1alpha1_generated } from "../../v1alpha1/generated_pb";
 import type { Event, Secret } from "../../../k8s.io/api/core/v1/generated_pb";
 import { file_k8s_io_api_core_v1_generated } from "../../../k8s.io/api/core/v1/generated_pb";
@@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf";
  * Describes the file api/service/v1alpha1/service.proto.
  */
 export const file_api_service_v1alpha1_service: GenFile = /*@__PURE__*/
-  fileDesc("CiJhcGkvc2VydmljZS92MWFscGhhMS9zZXJ2aWNlLnByb3RvEiBha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMSKrAQoRQ29tcG9uZW50VmVyc2lvbnMSQgoGc2VydmVyGAEgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVmVyc2lvbkluZm9IAIgBARI/CgNjbGkYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5WZXJzaW9uSW5mb0gBiAEBQgkKB19zZXJ2ZXJCBgoEX2NsaSKyAQoLVmVyc2lvbkluZm8SDwoHdmVyc2lvbhgBIAEoCRISCgpnaXRfY29tbWl0GAIgASgJEhYKDmdpdF90cmVlX2RpcnR5GAMgASgIEi4KCmJ1aWxkX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhIKCmdvX3ZlcnNpb24YBSABKAkSEAoIY29tcGlsZXIYBiABKAkSEAoIcGxhdGZvcm0YByABKAkiFwoVR2V0VmVyc2lvbkluZm9SZXF1ZXN0Il0KFkdldFZlcnNpb25JbmZvUmVzcG9uc2USQwoMdmVyc2lvbl9pbmZvGAEgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVmVyc2lvbkluZm8iEgoQR2V0Q29uZmlnUmVxdWVzdCItCgtBcmdvQ0RTaGFyZBILCgN1cmwYASABKAkSEQoJbmFtZXNwYWNlGAIgASgJIvgBChFHZXRDb25maWdSZXNwb25zZRJcCg1hcmdvY2Rfc2hhcmRzGAEgAygLMkUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVzcG9uc2UuQXJnb2NkU2hhcmRzRW50cnkSIQoZc2VjcmV0X21hbmFnZW1lbnRfZW5hYmxlZBgCIAEoCBpiChFBcmdvY2RTaGFyZHNFbnRyeRILCgNrZXkYASABKAkSPAoFdmFsdWUYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcmdvQ0RTaGFyZDoCOAEiGAoWR2V0UHVibGljQ29uZmlnUmVxdWVzdCKOAQoXR2V0UHVibGljQ29uZmlnUmVzcG9uc2USQQoLb2lkY19jb25maWcYASABKAsyLC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5PSURDQ29uZmlnEh0KFWFkbWluX2FjY291bnRfZW5hYmxlZBgCIAEoCBIRCglza2lwX2F1dGgYAyABKAgiWgoKT0lEQ0NvbmZpZxISCgppc3N1ZXJfdXJsGAEgASgJEhEKCWNsaWVudF9pZBgCIAEoCRIOCgZzY29wZXMYAyADKAkSFQoNY2xpX2NsaWVudF9pZBgEIAEoCSIlChFBZG1pbkxvZ2luUmVxdWVzdBIQCghwYXNzd29yZBgBIAEoCSImChJBZG1pbkxvZ2luUmVzcG9uc2USEAoIaWRfdG9rZW4YASABKAkiKQoVQ3JlYXRlUmVzb3VyY2VSZXF1ZXN0EhAKCG1hbmlmZXN0GAEgASgMIlYKFENyZWF0ZVJlc291cmNlUmVzdWx0EiMKGWNyZWF0ZWRfcmVzb3VyY2VfbWFuaWZlc3QYASABKAxIABIPCgVlcnJvchgCIAEoCUgAQggKBnJlc3VsdCJhChZDcmVhdGVSZXNvdXJjZVJlc3BvbnNlEkcKB3Jlc3VsdHMYASADKAsyNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSZXNvdXJjZVJlc3VsdCIxCh1DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCKDAQocQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3VsdBIjChljcmVhdGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASIwoZdXBkYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgCIAEoDEgAEg8KBWVycm9yGAMgASgJSABCCAoGcmVzdWx0InEKHkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXNwb25zZRJPCgdyZXN1bHRzGAEgAygLMj4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3VsdCIpChVVcGRhdGVSZXNvdXJjZVJlcXVlc3QSEAoIbWFuaWZlc3QYASABKAwiVgoUVXBkYXRlUmVzb3VyY2VSZXN1bHQSIwoZdXBkYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgBIAEoDEgAEg8KBWVycm9yGAIgASgJSABCCAoGcmVzdWx0ImEKFlVwZGF0ZVJlc291cmNlUmVzcG9uc2USRwoHcmVzdWx0cxgBIAMoCzI2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJlc291cmNlUmVzdWx0IikKFURlbGV0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCJWChREZWxldGVSZXNvdXJjZVJlc3VsdBIjChlkZWxldGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASDwoFZXJyb3IYAiABKAlIAEIICgZyZXN1bHQiYQoWRGVsZXRlUmVzb3VyY2VSZXNwb25zZRJHCgdyZXN1bHRzGAEgAygLMjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUmVzb3VyY2VSZXN1bHQiJAoRTGlzdFN0YWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJRChJMaXN0U3RhZ2VzUmVzcG9uc2USOwoGc3RhZ2VzGAEgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlIiQKEUxpc3RJbWFnZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkivwEKEkxpc3RJbWFnZXNSZXNwb25zZRJQCgZpbWFnZXMYAiADKAsyQC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0SW1hZ2VzUmVzcG9uc2UuSW1hZ2VzRW50cnkaVwoLSW1hZ2VzRW50cnkSCwoDa2V5GAEgASgJEjcKBXZhbHVlGAIgASgLMiguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVGFnTWFwOgI4ASKoAQoGVGFnTWFwEkAKBHRhZ3MYASADKAsyMi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5UYWdNYXAuVGFnc0VudHJ5GlwKCVRhZ3NFbnRyeRILCgNrZXkYASABKAkSPgoFdmFsdWUYAiABKAsyLy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5JbWFnZVN0YWdlTWFwOgI4ASKLAQoNSW1hZ2VTdGFnZU1hcBJLCgZzdGFnZXMYASADKAsyOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5JbWFnZVN0YWdlTWFwLlN0YWdlc0VudHJ5Gi0KC1N0YWdlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAEibQoPR2V0U3RhZ2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiaQoQR2V0U3RhZ2VSZXNwb25zZRI8CgVzdGFnZRgBIAEoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCIzChJXYXRjaFN0YWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIl8KE1dhdGNoU3RhZ2VzUmVzcG9uc2USOgoFc3RhZ2UYASABKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2USDAoEdHlwZRgCIAEoCSIzChJEZWxldGVTdGFnZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhUKE0RlbGV0ZVN0YWdlUmVzcG9uc2UiNAoTUmVmcmVzaFN0YWdlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiUgoUUmVmcmVzaFN0YWdlUmVzcG9uc2USOgoFc3RhZ2UYASABKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2UiRgoVTGlzdFByb21vdGlvbnNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSEgoFc3RhZ2UYAiABKAlIAIgBAUIICgZfc3RhZ2UiXQoWTGlzdFByb21vdGlvbnNSZXNwb25zZRJDCgpwcm9tb3Rpb25zGAEgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiJHChZXYXRjaFByb21vdGlvbnNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSEgoFc3RhZ2UYAiABKAlIAIgBAUIICgZfc3RhZ2UiawoXV2F0Y2hQcm9tb3Rpb25zUmVzcG9uc2USQgoJcHJvbW90aW9uGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbhIMCgR0eXBlGAIgASgJInEKE0dldFByb21vdGlvblJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJ1ChRHZXRQcm9tb3Rpb25SZXNwb25zZRJECglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IjYKFVdhdGNoUHJvbW90aW9uUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiagoWV2F0Y2hQcm9tb3Rpb25SZXNwb25zZRJCCglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uEgwKBHR5cGUYAiABKAkiNgoVQWJvcnRQcm9tb3Rpb25SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIYChZBYm9ydFByb21vdGlvblJlc3BvbnNlIiQKFERlbGV0ZVByb2plY3RSZXF1ZXN0EgwKBG5hbWUYASABKAkiFwoVRGVsZXRlUHJvamVjdFJlc3BvbnNlIioKGkRlbGV0ZVByb2plY3RDb25maWdSZXF1ZXN0EgwKBG5hbWUYASABKAkiHQobRGVsZXRlUHJvamVjdENvbmZpZ1Jlc3BvbnNlImQKF0dldFByb2plY3RDb25maWdSZXF1ZXN0EgwKBG5hbWUYASABKAkSOwoGZm9ybWF0GAIgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0IoIBChhHZXRQcm9qZWN0Q29uZmlnUmVzcG9uc2USTQoOcHJvamVjdF9jb25maWcYASABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdENvbmZpZ0gAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCJeChFHZXRQcm9qZWN0UmVxdWVzdBIMCgRuYW1lGAEgASgJEjsKBmZvcm1hdBgCIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJvChJHZXRQcm9qZWN0UmVzcG9uc2USQAoHcHJvamVjdBgBIAEoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0SAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IncKE0xpc3RQcm9qZWN0c1JlcXVlc3QSFgoJcGFnZV9zaXplGAEgASgFSACIAQESEQoEcGFnZRgCIAEoBUgBiAEBEhMKBmZpbHRlchgDIAEoCUgCiAEBQgwKCl9wYWdlX3NpemVCBwoFX3BhZ2VCCQoHX2ZpbHRlciJmChRMaXN0UHJvamVjdHNSZXNwb25zZRI/Cghwcm9qZWN0cxgBIAMoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0Eg0KBXRvdGFsGAIgASgFIlQKFUFwcHJvdmVGcmVpZ2h0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSDQoFYWxpYXMYAyABKAkSDQoFc3RhZ2UYBCABKAkiGAoWQXBwcm92ZUZyZWlnaHRSZXNwb25zZSJEChREZWxldGVGcmVpZ2h0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSDQoFYWxpYXMYAyABKAkiFwoVRGVsZXRlRnJlaWdodFJlc3BvbnNlIn4KEUdldEZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRINCgVhbGlhcxgDIAEoCRI7CgZmb3JtYXQYBCABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQibwoSR2V0RnJlaWdodFJlc3BvbnNlEkAKB2ZyZWlnaHQYASABKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodEgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCImChNXYXRjaEZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkiZAoUV2F0Y2hGcmVpZ2h0UmVzcG9uc2USPgoHZnJlaWdodBgBIAEoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0EgwKBHR5cGUYAiABKAkiXwoVUHJvbW90ZVRvU3RhZ2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkSDwoHZnJlaWdodBgDIAEoCRIVCg1mcmVpZ2h0X2FsaWFzGAQgASgJIlwKFlByb21vdGVUb1N0YWdlUmVzcG9uc2USQgoJcHJvbW90aW9uGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiJiChhQcm9tb3RlRG93bnN0cmVhbVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRINCgVzdGFnZRgCIAEoCRIPCgdmcmVpZ2h0GAMgASgJEhUKDWZyZWlnaHRfYWxpYXMYBCABKAkiYAoZUHJvbW90ZURvd25zdHJlYW1SZXNwb25zZRJDCgpwcm9tb3Rpb25zGAEgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiKKAQoTUXVlcnlGcmVpZ2h0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJEhAKCGdyb3VwX2J5GAMgASgJEg0KBWdyb3VwGAQgASgJEhAKCG9yZGVyX2J5GAUgASgJEg8KB3JldmVyc2UYBiABKAgSDwoHb3JpZ2lucxgHIAMoCSLIAQoUUXVlcnlGcmVpZ2h0UmVzcG9uc2USUgoGZ3JvdXBzGAEgAygLMkIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUXVlcnlGcmVpZ2h0UmVzcG9uc2UuR3JvdXBzRW50cnkaXAoLR3JvdXBzRW50cnkSCwoDa2V5GAEgASgJEjwKBXZhbHVlGAIgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRnJlaWdodExpc3Q6AjgBIk0KC0ZyZWlnaHRMaXN0Ej4KB2ZyZWlnaHQYASADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodCJgChlVcGRhdGVGcmVpZ2h0QWxpYXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRIRCglvbGRfYWxpYXMYAyABKAkSEQoJbmV3X2FsaWFzGAQgASgJIhwKGlVwZGF0ZUZyZWlnaHRBbGlhc1Jlc3BvbnNlIjEKD1JldmVyaWZ5UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJIhIKEFJldmVyaWZ5UmVzcG9uc2UiOgoYQWJvcnRWZXJpZmljYXRpb25SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkiGwoZQWJvcnRWZXJpZmljYXRpb25SZXNwb25zZSIoChVMaXN0V2FyZWhvdXNlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJdChZMaXN0V2FyZWhvdXNlc1Jlc3BvbnNlEkMKCndhcmVob3VzZXMYASADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlInEKE0dldFdhcmVob3VzZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJ1ChRHZXRXYXJlaG91c2VSZXNwb25zZRJECgl3YXJlaG91c2UYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IjcKFldhdGNoV2FyZWhvdXNlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJImsKF1dhdGNoV2FyZWhvdXNlc1Jlc3BvbnNlEkIKCXdhcmVob3VzZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2USDAoEdHlwZRgCIAEoCSI3ChZEZWxldGVXYXJlaG91c2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIZChdEZWxldGVXYXJlaG91c2VSZXNwb25zZSI4ChdSZWZyZXNoV2FyZWhvdXNlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiXgoYUmVmcmVzaFdhcmVob3VzZVJlc3BvbnNlEkIKCXdhcmVob3VzZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2UiLAoZTGlzdFByb2plY3RTZWNyZXRzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIkkKGkxpc3RQcm9qZWN0U2VjcmV0c1Jlc3BvbnNlEisKB3NlY3JldHMYASADKAsyGi5rOHMuaW8uYXBpLmNvcmUudjEuU2VjcmV0ItMBChpDcmVhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSVAoEZGF0YRgEIAMoCzJGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0LkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJJChtDcmVhdGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USKgoGc2VjcmV0GAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCLTAQoaVXBkYXRlUHJvamVjdFNlY3JldFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJElQKBGRhdGEYBCADKAsyRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdC5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiSQobVXBkYXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEioKBnNlY3JldBgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQiOwoaRGVsZXRlUHJvamVjdFNlY3JldFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIh0KG0RlbGV0ZVByb2plY3RTZWNyZXRSZXNwb25zZSLGAQoYQ3JlYXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgIIAEoCRIMCgR0eXBlGAMgASgJEhkKCHJlcG9fdXJsGAQgASgJUgdyZXBvVVJMEikKEXJlcG9fdXJsX2lzX3JlZ2V4GAUgASgIUg5yZXBvVVJMSXNSZWdleBIQCgh1c2VybmFtZRgGIAEoCRIQCghwYXNzd29yZBgHIAEoCSJMChlDcmVhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCI5ChhEZWxldGVDcmVkZW50aWFsc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhsKGURlbGV0ZUNyZWRlbnRpYWxzUmVzcG9uc2UicwoVR2V0Q3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiZAoWR2V0Q3JlZGVudGlhbHNSZXNwb25zZRIxCgtjcmVkZW50aWFscxgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXRIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiKQoWTGlzdENyZWRlbnRpYWxzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIkoKF0xpc3RDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgAygLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCLGAQoYVXBkYXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgIIAEoCRIMCgR0eXBlGAMgASgJEhkKCHJlcG9fdXJsGAQgASgJUgdyZXBvVVJMEikKEXJlcG9fdXJsX2lzX3JlZ2V4GAUgASgIUg5yZXBvVVJMSXNSZWdleBIQCgh1c2VybmFtZRgGIAEoCRIQCghwYXNzd29yZBgHIAEoCSJMChlVcGRhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCIvChxMaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkiggEKHUxpc3RBbmFseXNpc1RlbXBsYXRlc1Jlc3BvbnNlEmEKEmFuYWx5c2lzX3RlbXBsYXRlcxgBIAMoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5BbmFseXNpc1RlbXBsYXRlIiwKGUxpc3RQcm9tb3Rpb25UYXNrc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJqChpMaXN0UHJvbW90aW9uVGFza3NSZXNwb25zZRJMCg9wcm9tb3Rpb25fdGFza3MYASADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFzayIiCiBMaXN0Q2x1c3RlclByb21vdGlvblRhc2tzUmVxdWVzdCKAAQohTGlzdENsdXN0ZXJQcm9tb3Rpb25UYXNrc1Jlc3BvbnNlElsKF2NsdXN0ZXJfcHJvbW90aW9uX3Rhc2tzGAEgAygLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJQcm9tb3Rpb25UYXNrIngKGkdldEFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQimgEKG0dldEFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRJiChFhbmFseXNpc190ZW1wbGF0ZRgBIAEoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5BbmFseXNpc1RlbXBsYXRlSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0InUKF0dldFByb21vdGlvblRhc2tSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiggEKGEdldFByb21vdGlvblRhc2tSZXNwb25zZRJNCg5wcm9tb3Rpb25fdGFzaxgBIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UYXNrSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0ImsKHkdldENsdXN0ZXJQcm9tb3Rpb25UYXNrUmVxdWVzdBIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKmAQofR2V0Q2x1c3RlclByb21vdGlvblRhc2tSZXNwb25zZRJqCg5wcm9tb3Rpb25fdGFzaxgBIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DbHVzdGVyUHJvbW90aW9uVGFza0gAUhRjbHVzdGVyUHJvbW90aW9uVGFzaxINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiJQojTGlzdENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlc1JlcXVlc3QiswEKJExpc3RDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZXNSZXNwb25zZRKKAQoaY2x1c3Rlcl9hbmFseXNpc190ZW1wbGF0ZXMYASADKAsyTC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSGGNsdXN0ZXJhbmFseXNpc1RlbXBsYXRlcyJuCiFHZXRDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQisAEKIkdldENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2UScQoZY2x1c3Rlcl9hbmFseXNpc190ZW1wbGF0ZRgBIAEoCzJMLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5DbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCJ1ChVHZXRBbmFseXNpc1J1blJlcXVlc3QSEQoJbmFtZXNwYWNlGAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0IosBChZHZXRBbmFseXNpc1J1blJlc3BvbnNlElgKDGFuYWx5c2lzX3J1bhgBIAEoCzJALmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5BbmFseXNpc1J1bkgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCJpChlHZXRBbmFseXNpc1J1bkxvZ3NSZXF1ZXN0EhEKCW5hbWVzcGFjZRgBIAEoCRIMCgRuYW1lGAIgASgJEhMKC21ldHJpY19uYW1lGAMgASgJEhYKDmNvbnRhaW5lcl9uYW1lGAQgASgJIisKGkdldEFuYWx5c2lzUnVuTG9nc1Jlc3BvbnNlEg0KBWNodW5rGAEgASgJIj4KHURlbGV0ZUFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIgCh5EZWxldGVBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2UiNAokRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0EgwKBG5hbWUYAiABKAkiJwolRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZSIrChhMaXN0UHJvamVjdEV2ZW50c1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJGChlMaXN0UHJvamVjdEV2ZW50c1Jlc3BvbnNlEikKBmV2ZW50cxgBIAMoCzIZLms4cy5pby5hcGkuY29yZS52MS5FdmVudCJSChFDcmVhdGVSb2xlUmVxdWVzdBI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJTChJDcmVhdGVSb2xlUmVzcG9uc2USPQoEcm9sZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUiMgoRRGVsZXRlUm9sZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhQKEkRlbGV0ZVJvbGVSZXNwb25zZSKCAQoOR2V0Um9sZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhQKDGFzX3Jlc291cmNlcxgDIAEoCBI7CgZmb3JtYXQYBCABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiugEKD0dldFJvbGVSZXNwb25zZRI/CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZUgAEk0KCXJlc291cmNlcxgCIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGVSZXNvdXJjZXNIABINCgNyYXcYAyABKAxIAEIICgZyZXN1bHQiSgoGQ2xhaW1zEkAKBmNsYWltcxgBIAMoCzIwLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLkNsYWltItEBCgxHcmFudFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRyb2xlGAIgASgJEj8KC3VzZXJfY2xhaW1zGAMgASgLMiguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ2xhaW1zSAASVgoQcmVzb3VyY2VfZGV0YWlscxgEIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJlc291cmNlRGV0YWlsc0gAQgkKB3JlcXVlc3QiTgoNR3JhbnRSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSI5ChBMaXN0Um9sZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSFAoMYXNfcmVzb3VyY2VzGAIgASgIIqABChFMaXN0Um9sZXNSZXNwb25zZRI+CgVyb2xlcxgBIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUSSwoJcmVzb3VyY2VzGAIgAygLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZVJlc291cmNlcyLSAQoNUmV2b2tlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBHJvbGUYAiABKAkSPwoLdXNlcl9jbGFpbXMYAyABKAsyKC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DbGFpbXNIABJWChByZXNvdXJjZV9kZXRhaWxzGAQgASgLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUmVzb3VyY2VEZXRhaWxzSABCCQoHcmVxdWVzdCJPCg5SZXZva2VSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJSChFVcGRhdGVSb2xlUmVxdWVzdBI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJTChJVcGRhdGVSb2xlUmVzcG9uc2USPQoEcm9sZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUqUQoJUmF3Rm9ybWF0EhoKFlJBV19GT1JNQVRfVU5TUEVDSUZJRUQQABITCg9SQVdfRk9STUFUX0pTT04QARITCg9SQVdfRk9STUFUX1lBTUwQAjLDSAoMS2FyZ29TZXJ2aWNlEoMBCg5HZXRWZXJzaW9uSW5mbxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFZlcnNpb25JbmZvUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFZlcnNpb25JbmZvUmVzcG9uc2USdAoJR2V0Q29uZmlnEjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVxdWVzdBozLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENvbmZpZ1Jlc3BvbnNlEoYBCg9HZXRQdWJsaWNDb25maWcSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQdWJsaWNDb25maWdSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHVibGljQ29uZmlnUmVzcG9uc2USdwoKQWRtaW5Mb2dpbhIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFkbWluTG9naW5SZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWRtaW5Mb2dpblJlc3BvbnNlEoMBCg5DcmVhdGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVzcG9uc2USmwEKFkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2USPy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVxdWVzdBpALmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXNwb25zZRKDAQoOVXBkYXRlUmVzb3VyY2USNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSZXNvdXJjZVJlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSZXNvdXJjZVJlc3BvbnNlEoMBCg5EZWxldGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJlc291cmNlUmVzcG9uc2USdwoKTGlzdFN0YWdlcxIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RTdGFnZXNSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFN0YWdlc1Jlc3BvbnNlEncKCkxpc3RJbWFnZXMSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0SW1hZ2VzUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RJbWFnZXNSZXNwb25zZRJxCghHZXRTdGFnZRIxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFN0YWdlUmVxdWVzdBoyLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFN0YWdlUmVzcG9uc2USfAoLV2F0Y2hTdGFnZXMSNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFN0YWdlc1JlcXVlc3QaNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFN0YWdlc1Jlc3BvbnNlMAESegoLRGVsZXRlU3RhZ2USNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVTdGFnZVJlcXVlc3QaNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVTdGFnZVJlc3BvbnNlEn0KDFJlZnJlc2hTdGFnZRI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJlZnJlc2hTdGFnZVJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZWZyZXNoU3RhZ2VSZXNwb25zZRKDAQoOTGlzdFByb21vdGlvbnMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1Jlc3BvbnNlEogBCg9XYXRjaFByb21vdGlvbnMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFByb21vdGlvbnNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25zUmVzcG9uc2UwARJ9CgxHZXRQcm9tb3Rpb24SNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9tb3Rpb25SZXF1ZXN0GjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvbW90aW9uUmVzcG9uc2UShQEKDldhdGNoUHJvbW90aW9uEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXNwb25zZTABEoMBCg5BYm9ydFByb21vdGlvbhI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVzcG9uc2USgAEKDURlbGV0ZVByb2plY3QSNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0UmVxdWVzdBo3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RSZXNwb25zZRJ3CgpHZXRQcm9qZWN0EjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvamVjdFJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9qZWN0UmVzcG9uc2USfQoMTGlzdFByb2plY3RzEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RzUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0c1Jlc3BvbnNlEpIBChNEZWxldGVQcm9qZWN0Q29uZmlnEjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUHJvamVjdENvbmZpZ1JlcXVlc3QaPS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0Q29uZmlnUmVzcG9uc2USiQEKEEdldFByb2plY3RDb25maWcSOS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9qZWN0Q29uZmlnUmVxdWVzdBo6LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFByb2plY3RDb25maWdSZXNwb25zZRKDAQoOQXBwcm92ZUZyZWlnaHQSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcHByb3ZlRnJlaWdodFJlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcHByb3ZlRnJlaWdodFJlc3BvbnNlEoABCg1EZWxldGVGcmVpZ2h0EjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlRnJlaWdodFJlcXVlc3QaNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVGcmVpZ2h0UmVzcG9uc2USdwoKR2V0RnJlaWdodBIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEZyZWlnaHRSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0RnJlaWdodFJlc3BvbnNlEn8KDFdhdGNoRnJlaWdodBI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoRnJlaWdodFJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaEZyZWlnaHRSZXNwb25zZTABEoMBCg5Qcm9tb3RlVG9TdGFnZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlByb21vdGVUb1N0YWdlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlByb21vdGVUb1N0YWdlUmVzcG9uc2USjAEKEVByb21vdGVEb3duc3RyZWFtEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZURvd25zdHJlYW1SZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZURvd25zdHJlYW1SZXNwb25zZRJ9CgxRdWVyeUZyZWlnaHQSNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5RdWVyeUZyZWlnaHRSZXF1ZXN0GjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUXVlcnlGcmVpZ2h0UmVzcG9uc2USjwEKElVwZGF0ZUZyZWlnaHRBbGlhcxI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZUZyZWlnaHRBbGlhc1JlcXVlc3QaPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVGcmVpZ2h0QWxpYXNSZXNwb25zZRJxCghSZXZlcmlmeRIxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldmVyaWZ5UmVxdWVzdBoyLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldmVyaWZ5UmVzcG9uc2USjAEKEUFib3J0VmVyaWZpY2F0aW9uEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWJvcnRWZXJpZmljYXRpb25SZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWJvcnRWZXJpZmljYXRpb25SZXNwb25zZRKDAQoOTGlzdFdhcmVob3VzZXMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0V2FyZWhvdXNlc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0V2FyZWhvdXNlc1Jlc3BvbnNlEn0KDEdldFdhcmVob3VzZRI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFdhcmVob3VzZVJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRXYXJlaG91c2VSZXNwb25zZRKIAQoPV2F0Y2hXYXJlaG91c2VzEjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hXYXJlaG91c2VzUmVxdWVzdBo5LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoV2FyZWhvdXNlc1Jlc3BvbnNlMAEShgEKD0RlbGV0ZVdhcmVob3VzZRI4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVdhcmVob3VzZVJlcXVlc3QaOS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVXYXJlaG91c2VSZXNwb25zZRKJAQoQUmVmcmVzaFdhcmVob3VzZRI5LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJlZnJlc2hXYXJlaG91c2VSZXF1ZXN0GjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFdhcmVob3VzZVJlc3BvbnNlEowBChFDcmVhdGVDcmVkZW50aWFscxI6LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZUNyZWRlbnRpYWxzUmVxdWVzdBo7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZUNyZWRlbnRpYWxzUmVzcG9uc2USjAEKEURlbGV0ZUNyZWRlbnRpYWxzEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQ3JlZGVudGlhbHNSZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQ3JlZGVudGlhbHNSZXNwb25zZRKDAQoOR2V0Q3JlZGVudGlhbHMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDcmVkZW50aWFsc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDcmVkZW50aWFsc1Jlc3BvbnNlEoYBCg9MaXN0Q3JlZGVudGlhbHMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q3JlZGVudGlhbHNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdENyZWRlbnRpYWxzUmVzcG9uc2USjAEKEVVwZGF0ZUNyZWRlbnRpYWxzEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlQ3JlZGVudGlhbHNSZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlQ3JlZGVudGlhbHNSZXNwb25zZRKPAQoSTGlzdFByb2plY3RTZWNyZXRzEjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RTZWNyZXRzUmVxdWVzdBo8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0U2VjcmV0c1Jlc3BvbnNlEpIBChNDcmVhdGVQcm9qZWN0U2VjcmV0EjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUHJvamVjdFNlY3JldFJlcXVlc3QaPS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USkgEKE1VwZGF0ZVByb2plY3RTZWNyZXQSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVByb2plY3RTZWNyZXRSZXNwb25zZRKSAQoTRGVsZXRlUHJvamVjdFNlY3JldBI8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Gj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEpgBChVMaXN0QW5hbHlzaXNUZW1wbGF0ZXMSPi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXF1ZXN0Gj8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdEFuYWx5c2lzVGVtcGxhdGVzUmVzcG9uc2USkgEKE0dldEFuYWx5c2lzVGVtcGxhdGUSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRKbAQoWRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZRI/LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0GkAuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEq0BChxMaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzEkUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlc1JlcXVlc3QaRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVzcG9uc2USpwEKGkdldENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlEkMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0GkQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRKwAQodRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGUSRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QaRy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEoMBCg5HZXRBbmFseXNpc1J1bhI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzUnVuUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzUnVuUmVzcG9uc2USkQEKEkdldEFuYWx5c2lzUnVuTG9ncxI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzUnVuTG9nc1JlcXVlc3QaPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRBbmFseXNpc1J1bkxvZ3NSZXNwb25zZTABEowBChFMaXN0UHJvamVjdEV2ZW50cxI6LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0RXZlbnRzUmVxdWVzdBo7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0RXZlbnRzUmVzcG9uc2USjwEKEkxpc3RQcm9tb3Rpb25UYXNrcxI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9tb3Rpb25UYXNrc1JlcXVlc3QaPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uVGFza3NSZXNwb25zZRKkAQoZTGlzdENsdXN0ZXJQcm9tb3Rpb25UYXNrcxJCLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RDbHVzdGVyUHJvbW90aW9uVGFza3NSZXF1ZXN0GkMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdENsdXN0ZXJQcm9tb3Rpb25UYXNrc1Jlc3BvbnNlEokBChBHZXRQcm9tb3Rpb25UYXNrEjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvbW90aW9uVGFza1JlcXVlc3QaOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9tb3Rpb25UYXNrUmVzcG9uc2USngEKF0dldENsdXN0ZXJQcm9tb3Rpb25UYXNrEkAuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlclByb21vdGlvblRhc2tSZXF1ZXN0GkEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlclByb21vdGlvblRhc2tSZXNwb25zZRJ3CgpDcmVhdGVSb2xlEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUm9sZVJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSb2xlUmVzcG9uc2USdwoKRGVsZXRlUm9sZRIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJvbGVSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUm9sZVJlc3BvbnNlEm4KB0dldFJvbGUSMC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRSb2xlUmVxdWVzdBoxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFJvbGVSZXNwb25zZRJoCgVHcmFudBIuLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdyYW50UmVxdWVzdBovLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdyYW50UmVzcG9uc2USdAoJTGlzdFJvbGVzEjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFJvbGVzUmVxdWVzdBozLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RSb2xlc1Jlc3BvbnNlEmsKBlJldm9rZRIvLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldm9rZVJlcXVlc3QaMC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZXZva2VSZXNwb25zZRJ3CgpVcGRhdGVSb2xlEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlUm9sZVJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSb2xlUmVzcG9uc2VCkwIKJGNvbS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMUIMU2VydmljZVByb3RvUAFaOGdpdGh1Yi5jb20vYWt1aXR5L2thcmdvL2FwaS9zZXJ2aWNlL3YxYWxwaGExO3N2Y3YxYWxwaGExogIEQUlLU6oCIEFrdWl0eS5Jby5LYXJnby5TZXJ2aWNlLlYxYWxwaGExygIgQWt1aXR5XElvXEthcmdvXFNlcnZpY2VcVjFhbHBoYTHiAixBa3VpdHlcSW9cS2FyZ29cU2VydmljZVxWMWFscGhhMVxHUEJNZXRhZGF0YeoCJEFrdWl0eTo6SW86OkthcmdvOjpTZXJ2aWNlOjpWMWFscGhhMWIGcHJvdG8z", [file_google_protobuf_timestamp, file_api_v1alpha1_generated, file_k8s_io_api_core_v1_generated, file_api_stubs_rollouts_v1alpha1_generated, file_api_rbac_v1alpha1_generated]);
+  fileDesc("CiJhcGkvc2VydmljZS92MWFscGhhMS9zZXJ2aWNlLnByb3RvEiBha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMSKrAQoRQ29tcG9uZW50VmVyc2lvbnMSQgoGc2VydmVyGAEgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVmVyc2lvbkluZm9IAIgBARI/CgNjbGkYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5WZXJzaW9uSW5mb0gBiAEBQgkKB19zZXJ2ZXJCBgoEX2NsaSKyAQoLVmVyc2lvbkluZm8SDwoHdmVyc2lvbhgBIAEoCRISCgpnaXRfY29tbWl0GAIgASgJEhYKDmdpdF90cmVlX2RpcnR5GAMgASgIEi4KCmJ1aWxkX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhIKCmdvX3ZlcnNpb24YBSABKAkSEAoIY29tcGlsZXIYBiABKAkSEAoIcGxhdGZvcm0YByABKAkiFwoVR2V0VmVyc2lvbkluZm9SZXF1ZXN0Il0KFkdldFZlcnNpb25JbmZvUmVzcG9uc2USQwoMdmVyc2lvbl9pbmZvGAEgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVmVyc2lvbkluZm8iEgoQR2V0Q29uZmlnUmVxdWVzdCItCgtBcmdvQ0RTaGFyZBILCgN1cmwYASABKAkSEQoJbmFtZXNwYWNlGAIgASgJIvgBChFHZXRDb25maWdSZXNwb25zZRJcCg1hcmdvY2Rfc2hhcmRzGAEgAygLMkUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVzcG9uc2UuQXJnb2NkU2hhcmRzRW50cnkSIQoZc2VjcmV0X21hbmFnZW1lbnRfZW5hYmxlZBgCIAEoCBpiChFBcmdvY2RTaGFyZHNFbnRyeRILCgNrZXkYASABKAkSPAoFdmFsdWUYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcmdvQ0RTaGFyZDoCOAEiGAoWR2V0UHVibGljQ29uZmlnUmVxdWVzdCKOAQoXR2V0UHVibGljQ29uZmlnUmVzcG9uc2USQQoLb2lkY19jb25maWcYASABKAsyLC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5PSURDQ29uZmlnEh0KFWFkbWluX2FjY291bnRfZW5hYmxlZBgCIAEoCBIRCglza2lwX2F1dGgYAyABKAgiWgoKT0lEQ0NvbmZpZxISCgppc3N1ZXJfdXJsGAEgASgJEhEKCWNsaWVudF9pZBgCIAEoCRIOCgZzY29wZXMYAyADKAkSFQoNY2xpX2NsaWVudF9pZBgEIAEoCSIlChFBZG1pbkxvZ2luUmVxdWVzdBIQCghwYXNzd29yZBgBIAEoCSImChJBZG1pbkxvZ2luUmVzcG9uc2USEAoIaWRfdG9rZW4YASABKAkiKQoVQ3JlYXRlUmVzb3VyY2VSZXF1ZXN0EhAKCG1hbmlmZXN0GAEgASgMIlYKFENyZWF0ZVJlc291cmNlUmVzdWx0EiMKGWNyZWF0ZWRfcmVzb3VyY2VfbWFuaWZlc3QYASABKAxIABIPCgVlcnJvchgCIAEoCUgAQggKBnJlc3VsdCJhChZDcmVhdGVSZXNvdXJjZVJlc3BvbnNlEkcKB3Jlc3VsdHMYASADKAsyNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSZXNvdXJjZVJlc3VsdCIxCh1DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCKDAQocQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3VsdBIjChljcmVhdGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASIwoZdXBkYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgCIAEoDEgAEg8KBWVycm9yGAMgASgJSABCCAoGcmVzdWx0InEKHkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXNwb25zZRJPCgdyZXN1bHRzGAEgAygLMj4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3VsdCIpChVVcGRhdGVSZXNvdXJjZVJlcXVlc3QSEAoIbWFuaWZlc3QYASABKAwiVgoUVXBkYXRlUmVzb3VyY2VSZXN1bHQSIwoZdXBkYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgBIAEoDEgAEg8KBWVycm9yGAIgASgJSABCCAoGcmVzdWx0ImEKFlVwZGF0ZVJlc291cmNlUmVzcG9uc2USRwoHcmVzdWx0cxgBIAMoCzI2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJlc291cmNlUmVzdWx0IikKFURlbGV0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCJWChREZWxldGVSZXNvdXJjZVJlc3VsdBIjChlkZWxldGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASDwoFZXJyb3IYAiABKAlIAEIICgZyZXN1bHQiYQoWRGVsZXRlUmVzb3VyY2VSZXNwb25zZRJHCgdyZXN1bHRzGAEgAygLMjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUmVzb3VyY2VSZXN1bHQiJAoRTGlzdFN0YWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJRChJMaXN0U3RhZ2VzUmVzcG9uc2USOwoGc3RhZ2VzGAEgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlIiQKEUxpc3RJbWFnZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkivwEKEkxpc3RJbWFnZXNSZXNwb25zZRJQCgZpbWFnZXMYAiADKAsyQC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0SW1hZ2VzUmVzcG9uc2UuSW1hZ2VzRW50cnkaVwoLSW1hZ2VzRW50cnkSCwoDa2V5GAEgASgJEjcKBXZhbHVlGAIgASgLMiguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVGFnTWFwOgI4ASKoAQoGVGFnTWFwEkAKBHRhZ3MYASADKAsyMi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5UYWdNYXAuVGFnc0VudHJ5GlwKCVRhZ3NFbnRyeRILCgNrZXkYASABKAkSPgoFdmFsdWUYAiABKAsyLy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5JbWFnZVN0YWdlTWFwOgI4ASKLAQoNSW1hZ2VTdGFnZU1hcBJLCgZzdGFnZXMYASADKAsyOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5JbWFnZVN0YWdlTWFwLlN0YWdlc0VudHJ5Gi0KC1N0YWdlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAEibQoPR2V0U3RhZ2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiaQoQR2V0U3RhZ2VSZXNwb25zZRI8CgVzdGFnZRgBIAEoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCIzChJXYXRjaFN0YWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIl8KE1dhdGNoU3RhZ2VzUmVzcG9uc2USOgoFc3RhZ2UYASABKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2USDAoEdHlwZRgCIAEoCSIzChJEZWxldGVTdGFnZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhUKE0RlbGV0ZVN0YWdlUmVzcG9uc2UiNAoTUmVmcmVzaFN0YWdlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiUgoUUmVmcmVzaFN0YWdlUmVzcG9uc2USOgoFc3RhZ2UYASABKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2UiVgoXR2V0Q2x1c3RlckNvbmZpZ1JlcXVlc3QSOwoGZm9ybWF0GAEgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0IoIBChhHZXRDbHVzdGVyQ29uZmlnUmVzcG9uc2USTQoOY2x1c3Rlcl9jb25maWcYASABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2x1c3RlckNvbmZpZ0gAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCIcChpEZWxldGVDbHVzdGVyQ29uZmlnUmVxdWVzdCIdChtEZWxldGVDbHVzdGVyQ29uZmlnUmVzcG9uc2UiGwoZV2F0Y2hDbHVzdGVyQ29uZmlnUmVxdWVzdCJ3ChpXYXRjaENsdXN0ZXJDb25maWdSZXNwb25zZRJLCg5jbHVzdGVyX2NvbmZpZxgBIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DbHVzdGVyQ29uZmlnEgwKBHR5cGUYAiABKAkiHQobUmVmcmVzaENsdXN0ZXJDb25maWdSZXF1ZXN0ImsKHFJlZnJlc2hDbHVzdGVyQ29uZmlnUmVzcG9uc2USSwoOY2x1c3Rlcl9jb25maWcYASABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2x1c3RlckNvbmZpZyJGChVMaXN0UHJvbW90aW9uc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRISCgVzdGFnZRgCIAEoCUgAiAEBQggKBl9zdGFnZSJdChZMaXN0UHJvbW90aW9uc1Jlc3BvbnNlEkMKCnByb21vdGlvbnMYASADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uIkcKFldhdGNoUHJvbW90aW9uc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRISCgVzdGFnZRgCIAEoCUgAiAEBQggKBl9zdGFnZSJrChdXYXRjaFByb21vdGlvbnNSZXNwb25zZRJCCglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uEgwKBHR5cGUYAiABKAkicQoTR2V0UHJvbW90aW9uUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0InUKFEdldFByb21vdGlvblJlc3BvbnNlEkQKCXByb21vdGlvbhgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25IABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiNgoVV2F0Y2hQcm9tb3Rpb25SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSJqChZXYXRjaFByb21vdGlvblJlc3BvbnNlEkIKCXByb21vdGlvbhgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb24SDAoEdHlwZRgCIAEoCSI2ChVBYm9ydFByb21vdGlvblJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhgKFkFib3J0UHJvbW90aW9uUmVzcG9uc2UiJAoURGVsZXRlUHJvamVjdFJlcXVlc3QSDAoEbmFtZRgBIAEoCSIXChVEZWxldGVQcm9qZWN0UmVzcG9uc2UiXgoRR2V0UHJvamVjdFJlcXVlc3QSDAoEbmFtZRgBIAEoCRI7CgZmb3JtYXQYAiABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQibwoSR2V0UHJvamVjdFJlc3BvbnNlEkAKB3Byb2plY3QYASABKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdEgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCJ3ChNMaXN0UHJvamVjdHNSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUgAiAEBEhEKBHBhZ2UYAiABKAVIAYgBARITCgZmaWx0ZXIYAyABKAlIAogBAUIMCgpfcGFnZV9zaXplQgcKBV9wYWdlQgkKB19maWx0ZXIiZgoUTGlzdFByb2plY3RzUmVzcG9uc2USPwoIcHJvamVjdHMYASADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdBINCgV0b3RhbBgCIAEoBSJnChdHZXRQcm9qZWN0Q29uZmlnUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEjsKBmZvcm1hdBgCIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKCAQoYR2V0UHJvamVjdENvbmZpZ1Jlc3BvbnNlEk0KDnByb2plY3RfY29uZmlnGAEgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RDb25maWdIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiLQoaRGVsZXRlUHJvamVjdENvbmZpZ1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSIdChtEZWxldGVQcm9qZWN0Q29uZmlnUmVzcG9uc2UiLAoZV2F0Y2hQcm9qZWN0Q29uZmlnUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIncKGldhdGNoUHJvamVjdENvbmZpZ1Jlc3BvbnNlEksKDnByb2plY3RfY29uZmlnGAEgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RDb25maWcSDAoEdHlwZRgCIAEoCSIuChtSZWZyZXNoUHJvamVjdENvbmZpZ1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJrChxSZWZyZXNoUHJvamVjdENvbmZpZ1Jlc3BvbnNlEksKDnByb2plY3RfY29uZmlnGAEgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RDb25maWciVAoVQXBwcm92ZUZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRINCgVhbGlhcxgDIAEoCRINCgVzdGFnZRgEIAEoCSIYChZBcHByb3ZlRnJlaWdodFJlc3BvbnNlIkQKFERlbGV0ZUZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRINCgVhbGlhcxgDIAEoCSIXChVEZWxldGVGcmVpZ2h0UmVzcG9uc2UifgoRR2V0RnJlaWdodFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEg0KBWFsaWFzGAMgASgJEjsKBmZvcm1hdBgEIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJvChJHZXRGcmVpZ2h0UmVzcG9uc2USQAoHZnJlaWdodBgBIAEoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0SAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IiYKE1dhdGNoRnJlaWdodFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJkChRXYXRjaEZyZWlnaHRSZXNwb25zZRI+CgdmcmVpZ2h0GAEgASgLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHQSDAoEdHlwZRgCIAEoCSJfChVQcm9tb3RlVG9TdGFnZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRINCgVzdGFnZRgCIAEoCRIPCgdmcmVpZ2h0GAMgASgJEhUKDWZyZWlnaHRfYWxpYXMYBCABKAkiXAoWUHJvbW90ZVRvU3RhZ2VSZXNwb25zZRJCCglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uImIKGFByb21vdGVEb3duc3RyZWFtUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJEg8KB2ZyZWlnaHQYAyABKAkSFQoNZnJlaWdodF9hbGlhcxgEIAEoCSJgChlQcm9tb3RlRG93bnN0cmVhbVJlc3BvbnNlEkMKCnByb21vdGlvbnMYASADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uIooBChNRdWVyeUZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkSEAoIZ3JvdXBfYnkYAyABKAkSDQoFZ3JvdXAYBCABKAkSEAoIb3JkZXJfYnkYBSABKAkSDwoHcmV2ZXJzZRgGIAEoCBIPCgdvcmlnaW5zGAcgAygJIsgBChRRdWVyeUZyZWlnaHRSZXNwb25zZRJSCgZncm91cHMYASADKAsyQi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5RdWVyeUZyZWlnaHRSZXNwb25zZS5Hcm91cHNFbnRyeRpcCgtHcm91cHNFbnRyeRILCgNrZXkYASABKAkSPAoFdmFsdWUYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5GcmVpZ2h0TGlzdDoCOAEiTQoLRnJlaWdodExpc3QSPgoHZnJlaWdodBgBIAMoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0ImAKGVVwZGF0ZUZyZWlnaHRBbGlhc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhEKCW9sZF9hbGlhcxgDIAEoCRIRCgluZXdfYWxpYXMYBCABKAkiHAoaVXBkYXRlRnJlaWdodEFsaWFzUmVzcG9uc2UiMQoPUmV2ZXJpZnlSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkiEgoQUmV2ZXJpZnlSZXNwb25zZSI6ChhBYm9ydFZlcmlmaWNhdGlvblJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRINCgVzdGFnZRgCIAEoCSIbChlBYm9ydFZlcmlmaWNhdGlvblJlc3BvbnNlIigKFUxpc3RXYXJlaG91c2VzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIl0KFkxpc3RXYXJlaG91c2VzUmVzcG9uc2USQwoKd2FyZWhvdXNlcxgBIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2UicQoTR2V0V2FyZWhvdXNlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0InUKFEdldFdhcmVob3VzZVJlc3BvbnNlEkQKCXdhcmVob3VzZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2VIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiNwoWV2F0Y2hXYXJlaG91c2VzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiawoXV2F0Y2hXYXJlaG91c2VzUmVzcG9uc2USQgoJd2FyZWhvdXNlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZRIMCgR0eXBlGAIgASgJIjcKFkRlbGV0ZVdhcmVob3VzZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhkKF0RlbGV0ZVdhcmVob3VzZVJlc3BvbnNlIjgKF1JlZnJlc2hXYXJlaG91c2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSJeChhSZWZyZXNoV2FyZWhvdXNlUmVzcG9uc2USQgoJd2FyZWhvdXNlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZSLGAQoYQ3JlYXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgIIAEoCRIMCgR0eXBlGAMgASgJEhkKCHJlcG9fdXJsGAQgASgJUgdyZXBvVVJMEikKEXJlcG9fdXJsX2lzX3JlZ2V4GAUgASgIUg5yZXBvVVJMSXNSZWdleBIQCgh1c2VybmFtZRgGIAEoCRIQCghwYXNzd29yZBgHIAEoCSJMChlDcmVhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCI5ChhEZWxldGVDcmVkZW50aWFsc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhsKGURlbGV0ZUNyZWRlbnRpYWxzUmVzcG9uc2UicwoVR2V0Q3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiZAoWR2V0Q3JlZGVudGlhbHNSZXNwb25zZRIxCgtjcmVkZW50aWFscxgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXRIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiKQoWTGlzdENyZWRlbnRpYWxzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIkoKF0xpc3RDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgAygLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCLGAQoYVXBkYXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgIIAEoCRIMCgR0eXBlGAMgASgJEhkKCHJlcG9fdXJsGAQgASgJUgdyZXBvVVJMEikKEXJlcG9fdXJsX2lzX3JlZ2V4GAUgASgIUg5yZXBvVVJMSXNSZWdleBIQCgh1c2VybmFtZRgGIAEoCRIQCghwYXNzd29yZBgHIAEoCSJMChlVcGRhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCIsChlMaXN0UHJvamVjdFNlY3JldHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkiSQoaTGlzdFByb2plY3RTZWNyZXRzUmVzcG9uc2USKwoHc2VjcmV0cxgBIAMoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQi0wEKGkNyZWF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRJUCgRkYXRhGAQgAygLMkYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUHJvamVjdFNlY3JldFJlcXVlc3QuRGF0YUVudHJ5GisKCURhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIkkKG0NyZWF0ZVByb2plY3RTZWNyZXRSZXNwb25zZRIqCgZzZWNyZXQYASABKAsyGi5rOHMuaW8uYXBpLmNvcmUudjEuU2VjcmV0ItMBChpVcGRhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSVAoEZGF0YRgEIAMoCzJGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0LkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJJChtVcGRhdGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USKgoGc2VjcmV0GAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCI7ChpEZWxldGVQcm9qZWN0U2VjcmV0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiHQobRGVsZXRlUHJvamVjdFNlY3JldFJlc3BvbnNlIi8KHExpc3RBbmFseXNpc1RlbXBsYXRlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSKCAQodTGlzdEFuYWx5c2lzVGVtcGxhdGVzUmVzcG9uc2USYQoSYW5hbHlzaXNfdGVtcGxhdGVzGAEgAygLMkUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGUieAoaR2V0QW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKaAQobR2V0QW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEmIKEWFuYWx5c2lzX3RlbXBsYXRlGAEgASgLMkUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGVIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiPgodRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIiAKHkRlbGV0ZUFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZSIlCiNMaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVxdWVzdCKzAQokTGlzdENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlc1Jlc3BvbnNlEooBChpjbHVzdGVyX2FuYWx5c2lzX3RlbXBsYXRlcxgBIAMoCzJMLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5DbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVIYY2x1c3RlcmFuYWx5c2lzVGVtcGxhdGVzIm4KIUdldENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKwAQoiR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRJxChljbHVzdGVyX2FuYWx5c2lzX3RlbXBsYXRlGAEgASgLMkwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IjQKJERlbGV0ZUNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBIMCgRuYW1lGAIgASgJIicKJURlbGV0ZUNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2UidQoVR2V0QW5hbHlzaXNSdW5SZXF1ZXN0EhEKCW5hbWVzcGFjZRgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKLAQoWR2V0QW5hbHlzaXNSdW5SZXNwb25zZRJYCgxhbmFseXNpc19ydW4YASABKAsyQC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQW5hbHlzaXNSdW5IABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiaQoZR2V0QW5hbHlzaXNSdW5Mb2dzUmVxdWVzdBIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRITCgttZXRyaWNfbmFtZRgDIAEoCRIWCg5jb250YWluZXJfbmFtZRgEIAEoCSIrChpHZXRBbmFseXNpc1J1bkxvZ3NSZXNwb25zZRINCgVjaHVuaxgBIAEoCSIrChhMaXN0UHJvamVjdEV2ZW50c1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJGChlMaXN0UHJvamVjdEV2ZW50c1Jlc3BvbnNlEikKBmV2ZW50cxgBIAMoCzIZLms4cy5pby5hcGkuY29yZS52MS5FdmVudCIsChlMaXN0UHJvbW90aW9uVGFza3NSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkiagoaTGlzdFByb21vdGlvblRhc2tzUmVzcG9uc2USTAoPcHJvbW90aW9uX3Rhc2tzGAEgAygLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2sidQoXR2V0UHJvbW90aW9uVGFza1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKCAQoYR2V0UHJvbW90aW9uVGFza1Jlc3BvbnNlEk0KDnByb21vdGlvbl90YXNrGAEgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2tIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiIgogTGlzdENsdXN0ZXJQcm9tb3Rpb25UYXNrc1JlcXVlc3QigAEKIUxpc3RDbHVzdGVyUHJvbW90aW9uVGFza3NSZXNwb25zZRJbChdjbHVzdGVyX3Byb21vdGlvbl90YXNrcxgBIAMoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DbHVzdGVyUHJvbW90aW9uVGFzayJrCh5HZXRDbHVzdGVyUHJvbW90aW9uVGFza1JlcXVlc3QSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQipgEKH0dldENsdXN0ZXJQcm9tb3Rpb25UYXNrUmVzcG9uc2USagoOcHJvbW90aW9uX3Rhc2sYASABKAsyOi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2x1c3RlclByb21vdGlvblRhc2tIAFIUY2x1c3RlclByb21vdGlvblRhc2sSDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IlIKEUNyZWF0ZVJvbGVSZXF1ZXN0Ej0KBHJvbGUYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5Sb2xlIlMKEkNyZWF0ZVJvbGVSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSIyChFEZWxldGVSb2xlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiFAoSRGVsZXRlUm9sZVJlc3BvbnNlIoIBCg5HZXRSb2xlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSFAoMYXNfcmVzb3VyY2VzGAMgASgIEjsKBmZvcm1hdBgEIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCK6AQoPR2V0Um9sZVJlc3BvbnNlEj8KBHJvbGUYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5Sb2xlSAASTQoJcmVzb3VyY2VzGAIgASgLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZVJlc291cmNlc0gAEg0KA3JhdxgDIAEoDEgAQggKBnJlc3VsdCJKCgZDbGFpbXMSQAoGY2xhaW1zGAEgAygLMjAuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuQ2xhaW0i0QEKDEdyYW50UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBHJvbGUYAiABKAkSPwoLdXNlcl9jbGFpbXMYAyABKAsyKC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DbGFpbXNIABJWChByZXNvdXJjZV9kZXRhaWxzGAQgASgLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUmVzb3VyY2VEZXRhaWxzSABCCQoHcmVxdWVzdCJOCg1HcmFudFJlc3BvbnNlEj0KBHJvbGUYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5Sb2xlIjkKEExpc3RSb2xlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIUCgxhc19yZXNvdXJjZXMYAiABKAgioAEKEUxpc3RSb2xlc1Jlc3BvbnNlEj4KBXJvbGVzGAEgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZRJLCglyZXNvdXJjZXMYAiADKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5Sb2xlUmVzb3VyY2VzItIBCg1SZXZva2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEcm9sZRgCIAEoCRI/Cgt1c2VyX2NsYWltcxgDIAEoCzIoLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNsYWltc0gAElYKEHJlc291cmNlX2RldGFpbHMYBCABKAsyOi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5SZXNvdXJjZURldGFpbHNIAEIJCgdyZXF1ZXN0Ik8KDlJldm9rZVJlc3BvbnNlEj0KBHJvbGUYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5Sb2xlIlIKEVVwZGF0ZVJvbGVSZXF1ZXN0Ej0KBHJvbGUYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkucmJhYy52MWFscGhhMS5Sb2xlIlMKElVwZGF0ZVJvbGVSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSpRCglSYXdGb3JtYXQSGgoWUkFXX0ZPUk1BVF9VTlNQRUNJRklFRBAAEhMKD1JBV19GT1JNQVRfSlNPThABEhMKD1JBV19GT1JNQVRfWUFNTBACMrxPCgxLYXJnb1NlcnZpY2USgwEKDkdldFZlcnNpb25JbmZvEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0VmVyc2lvbkluZm9SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0VmVyc2lvbkluZm9SZXNwb25zZRJ0CglHZXRDb25maWcSMi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDb25maWdSZXF1ZXN0GjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVzcG9uc2UShgEKD0dldFB1YmxpY0NvbmZpZxI4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFB1YmxpY0NvbmZpZ1JlcXVlc3QaOS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQdWJsaWNDb25maWdSZXNwb25zZRJ3CgpBZG1pbkxvZ2luEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWRtaW5Mb2dpblJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BZG1pbkxvZ2luUmVzcG9uc2USgwEKDkNyZWF0ZVJlc291cmNlEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUmVzb3VyY2VSZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUmVzb3VyY2VSZXNwb25zZRKbAQoWQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZRI/LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXF1ZXN0GkAuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3BvbnNlEoMBCg5VcGRhdGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJlc291cmNlUmVzcG9uc2USgwEKDkRlbGV0ZVJlc291cmNlEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUmVzb3VyY2VSZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUmVzb3VyY2VSZXNwb25zZRJ3CgpMaXN0U3RhZ2VzEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFN0YWdlc1JlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0U3RhZ2VzUmVzcG9uc2USdwoKTGlzdEltYWdlcxIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RJbWFnZXNSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdEltYWdlc1Jlc3BvbnNlEnEKCEdldFN0YWdlEjEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0U3RhZ2VSZXF1ZXN0GjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0U3RhZ2VSZXNwb25zZRJ8CgtXYXRjaFN0YWdlcxI0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoU3RhZ2VzUmVxdWVzdBo1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoU3RhZ2VzUmVzcG9uc2UwARJ6CgtEZWxldGVTdGFnZRI0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVN0YWdlUmVxdWVzdBo1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVN0YWdlUmVzcG9uc2USfQoMUmVmcmVzaFN0YWdlEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFN0YWdlUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJlZnJlc2hTdGFnZVJlc3BvbnNlEokBChBHZXRDbHVzdGVyQ29uZmlnEjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlckNvbmZpZ1JlcXVlc3QaOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDbHVzdGVyQ29uZmlnUmVzcG9uc2USkgEKE0RlbGV0ZUNsdXN0ZXJDb25maWcSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDbHVzdGVyQ29uZmlnUmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUNsdXN0ZXJDb25maWdSZXNwb25zZRKRAQoSV2F0Y2hDbHVzdGVyQ29uZmlnEjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hDbHVzdGVyQ29uZmlnUmVxdWVzdBo8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoQ2x1c3RlckNvbmZpZ1Jlc3BvbnNlMAESlQEKFFJlZnJlc2hDbHVzdGVyQ29uZmlnEj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaENsdXN0ZXJDb25maWdSZXF1ZXN0Gj4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaENsdXN0ZXJDb25maWdSZXNwb25zZRKDAQoOTGlzdFByb21vdGlvbnMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1Jlc3BvbnNlEogBCg9XYXRjaFByb21vdGlvbnMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFByb21vdGlvbnNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25zUmVzcG9uc2UwARJ9CgxHZXRQcm9tb3Rpb24SNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9tb3Rpb25SZXF1ZXN0GjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvbW90aW9uUmVzcG9uc2UShQEKDldhdGNoUHJvbW90aW9uEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXNwb25zZTABEoMBCg5BYm9ydFByb21vdGlvbhI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVzcG9uc2USgAEKDURlbGV0ZVByb2plY3QSNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0UmVxdWVzdBo3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RSZXNwb25zZRJ3CgpHZXRQcm9qZWN0EjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvamVjdFJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9qZWN0UmVzcG9uc2USfQoMTGlzdFByb2plY3RzEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RzUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0c1Jlc3BvbnNlEokBChBHZXRQcm9qZWN0Q29uZmlnEjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvamVjdENvbmZpZ1JlcXVlc3QaOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9qZWN0Q29uZmlnUmVzcG9uc2USkgEKE0RlbGV0ZVByb2plY3RDb25maWcSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0Q29uZmlnUmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RDb25maWdSZXNwb25zZRKRAQoSV2F0Y2hQcm9qZWN0Q29uZmlnEjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9qZWN0Q29uZmlnUmVxdWVzdBo8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoUHJvamVjdENvbmZpZ1Jlc3BvbnNlMAESlQEKFFJlZnJlc2hQcm9qZWN0Q29uZmlnEj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFByb2plY3RDb25maWdSZXF1ZXN0Gj4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFByb2plY3RDb25maWdSZXNwb25zZRKDAQoOQXBwcm92ZUZyZWlnaHQSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcHByb3ZlRnJlaWdodFJlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcHByb3ZlRnJlaWdodFJlc3BvbnNlEoABCg1EZWxldGVGcmVpZ2h0EjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlRnJlaWdodFJlcXVlc3QaNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVGcmVpZ2h0UmVzcG9uc2USdwoKR2V0RnJlaWdodBIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEZyZWlnaHRSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0RnJlaWdodFJlc3BvbnNlEn8KDFdhdGNoRnJlaWdodBI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoRnJlaWdodFJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaEZyZWlnaHRSZXNwb25zZTABEoMBCg5Qcm9tb3RlVG9TdGFnZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlByb21vdGVUb1N0YWdlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlByb21vdGVUb1N0YWdlUmVzcG9uc2USjAEKEVByb21vdGVEb3duc3RyZWFtEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZURvd25zdHJlYW1SZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZURvd25zdHJlYW1SZXNwb25zZRJ9CgxRdWVyeUZyZWlnaHQSNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5RdWVyeUZyZWlnaHRSZXF1ZXN0GjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUXVlcnlGcmVpZ2h0UmVzcG9uc2USjwEKElVwZGF0ZUZyZWlnaHRBbGlhcxI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZUZyZWlnaHRBbGlhc1JlcXVlc3QaPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVGcmVpZ2h0QWxpYXNSZXNwb25zZRJxCghSZXZlcmlmeRIxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldmVyaWZ5UmVxdWVzdBoyLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldmVyaWZ5UmVzcG9uc2USjAEKEUFib3J0VmVyaWZpY2F0aW9uEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWJvcnRWZXJpZmljYXRpb25SZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWJvcnRWZXJpZmljYXRpb25SZXNwb25zZRKDAQoOTGlzdFdhcmVob3VzZXMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0V2FyZWhvdXNlc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0V2FyZWhvdXNlc1Jlc3BvbnNlEn0KDEdldFdhcmVob3VzZRI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFdhcmVob3VzZVJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRXYXJlaG91c2VSZXNwb25zZRKIAQoPV2F0Y2hXYXJlaG91c2VzEjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hXYXJlaG91c2VzUmVxdWVzdBo5LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLldhdGNoV2FyZWhvdXNlc1Jlc3BvbnNlMAEShgEKD0RlbGV0ZVdhcmVob3VzZRI4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVdhcmVob3VzZVJlcXVlc3QaOS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVXYXJlaG91c2VSZXNwb25zZRKJAQoQUmVmcmVzaFdhcmVob3VzZRI5LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJlZnJlc2hXYXJlaG91c2VSZXF1ZXN0GjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFdhcmVob3VzZVJlc3BvbnNlEowBChFDcmVhdGVDcmVkZW50aWFscxI6LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZUNyZWRlbnRpYWxzUmVxdWVzdBo7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZUNyZWRlbnRpYWxzUmVzcG9uc2USjAEKEURlbGV0ZUNyZWRlbnRpYWxzEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQ3JlZGVudGlhbHNSZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQ3JlZGVudGlhbHNSZXNwb25zZRKDAQoOR2V0Q3JlZGVudGlhbHMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDcmVkZW50aWFsc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDcmVkZW50aWFsc1Jlc3BvbnNlEoYBCg9MaXN0Q3JlZGVudGlhbHMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q3JlZGVudGlhbHNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdENyZWRlbnRpYWxzUmVzcG9uc2USjAEKEVVwZGF0ZUNyZWRlbnRpYWxzEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlQ3JlZGVudGlhbHNSZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlQ3JlZGVudGlhbHNSZXNwb25zZRKPAQoSTGlzdFByb2plY3RTZWNyZXRzEjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RTZWNyZXRzUmVxdWVzdBo8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0U2VjcmV0c1Jlc3BvbnNlEpIBChNDcmVhdGVQcm9qZWN0U2VjcmV0EjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUHJvamVjdFNlY3JldFJlcXVlc3QaPS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USkgEKE1VwZGF0ZVByb2plY3RTZWNyZXQSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVByb2plY3RTZWNyZXRSZXNwb25zZRKSAQoTRGVsZXRlUHJvamVjdFNlY3JldBI8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Gj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEpgBChVMaXN0QW5hbHlzaXNUZW1wbGF0ZXMSPi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXF1ZXN0Gj8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdEFuYWx5c2lzVGVtcGxhdGVzUmVzcG9uc2USkgEKE0dldEFuYWx5c2lzVGVtcGxhdGUSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRKbAQoWRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZRI/LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0GkAuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEq0BChxMaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzEkUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlc1JlcXVlc3QaRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVzcG9uc2USpwEKGkdldENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlEkMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0GkQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRKwAQodRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGUSRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QaRy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEoMBCg5HZXRBbmFseXNpc1J1bhI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzUnVuUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzUnVuUmVzcG9uc2USkQEKEkdldEFuYWx5c2lzUnVuTG9ncxI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzUnVuTG9nc1JlcXVlc3QaPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRBbmFseXNpc1J1bkxvZ3NSZXNwb25zZTABEowBChFMaXN0UHJvamVjdEV2ZW50cxI6LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0RXZlbnRzUmVxdWVzdBo7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0RXZlbnRzUmVzcG9uc2USjwEKEkxpc3RQcm9tb3Rpb25UYXNrcxI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9tb3Rpb25UYXNrc1JlcXVlc3QaPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uVGFza3NSZXNwb25zZRKkAQoZTGlzdENsdXN0ZXJQcm9tb3Rpb25UYXNrcxJCLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RDbHVzdGVyUHJvbW90aW9uVGFza3NSZXF1ZXN0GkMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdENsdXN0ZXJQcm9tb3Rpb25UYXNrc1Jlc3BvbnNlEokBChBHZXRQcm9tb3Rpb25UYXNrEjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvbW90aW9uVGFza1JlcXVlc3QaOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9tb3Rpb25UYXNrUmVzcG9uc2USngEKF0dldENsdXN0ZXJQcm9tb3Rpb25UYXNrEkAuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlclByb21vdGlvblRhc2tSZXF1ZXN0GkEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q2x1c3RlclByb21vdGlvblRhc2tSZXNwb25zZRJ3CgpDcmVhdGVSb2xlEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlUm9sZVJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSb2xlUmVzcG9uc2USdwoKRGVsZXRlUm9sZRIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJvbGVSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUm9sZVJlc3BvbnNlEm4KB0dldFJvbGUSMC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRSb2xlUmVxdWVzdBoxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFJvbGVSZXNwb25zZRJoCgVHcmFudBIuLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdyYW50UmVxdWVzdBovLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdyYW50UmVzcG9uc2USdAoJTGlzdFJvbGVzEjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFJvbGVzUmVxdWVzdBozLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RSb2xlc1Jlc3BvbnNlEmsKBlJldm9rZRIvLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldm9rZVJlcXVlc3QaMC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZXZva2VSZXNwb25zZRJ3CgpVcGRhdGVSb2xlEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlUm9sZVJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSb2xlUmVzcG9uc2VCkwIKJGNvbS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMUIMU2VydmljZVByb3RvUAFaOGdpdGh1Yi5jb20vYWt1aXR5L2thcmdvL2FwaS9zZXJ2aWNlL3YxYWxwaGExO3N2Y3YxYWxwaGExogIEQUlLU6oCIEFrdWl0eS5Jby5LYXJnby5TZXJ2aWNlLlYxYWxwaGExygIgQWt1aXR5XElvXEthcmdvXFNlcnZpY2VcVjFhbHBoYTHiAixBa3VpdHlcSW9cS2FyZ29cU2VydmljZVxWMWFscGhhMVxHUEJNZXRhZGF0YeoCJEFrdWl0eTo6SW86OkthcmdvOjpTZXJ2aWNlOjpWMWFscGhhMWIGcHJvdG8z", [file_google_protobuf_timestamp, file_api_v1alpha1_generated, file_k8s_io_api_core_v1_generated, file_api_stubs_rollouts_v1alpha1_generated, file_api_rbac_v1alpha1_generated]);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ComponentVersions
@@ -826,6 +826,153 @@ export type RefreshStageResponse = Message<"akuity.io.kargo.service.v1alpha1.Ref
 export const RefreshStageResponseSchema: GenMessage<RefreshStageResponse> = /*@__PURE__*/
   messageDesc(file_api_service_v1alpha1_service, 37);
 
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterConfigRequest
+ */
+export type GetClusterConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.GetClusterConfigRequest"> & {
+  /**
+   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 1;
+   */
+  format: RawFormat;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetClusterConfigRequest.
+ * Use `create(GetClusterConfigRequestSchema)` to create a new message.
+ */
+export const GetClusterConfigRequestSchema: GenMessage<GetClusterConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 38);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse
+ */
+export type GetClusterConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse"> & {
+  /**
+   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse.result
+   */
+  result: {
+    /**
+     * @generated from field: github.com.akuity.kargo.api.v1alpha1.ClusterConfig cluster_config = 1;
+     */
+    value: ClusterConfig;
+    case: "clusterConfig";
+  } | {
+    /**
+     * @generated from field: bytes raw = 2;
+     */
+    value: Uint8Array;
+    case: "raw";
+  } | { case: undefined; value?: undefined };
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetClusterConfigResponse.
+ * Use `create(GetClusterConfigResponseSchema)` to create a new message.
+ */
+export const GetClusterConfigResponseSchema: GenMessage<GetClusterConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 39);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterConfigRequest
+ */
+export type DeleteClusterConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteClusterConfigRequest"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteClusterConfigRequest.
+ * Use `create(DeleteClusterConfigRequestSchema)` to create a new message.
+ */
+export const DeleteClusterConfigRequestSchema: GenMessage<DeleteClusterConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 40);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterConfigResponse
+ */
+export type DeleteClusterConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteClusterConfigResponse"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteClusterConfigResponse.
+ * Use `create(DeleteClusterConfigResponseSchema)` to create a new message.
+ */
+export const DeleteClusterConfigResponseSchema: GenMessage<DeleteClusterConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 41);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.WatchClusterConfigRequest
+ */
+export type WatchClusterConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.WatchClusterConfigRequest"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.WatchClusterConfigRequest.
+ * Use `create(WatchClusterConfigRequestSchema)` to create a new message.
+ */
+export const WatchClusterConfigRequestSchema: GenMessage<WatchClusterConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 42);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.WatchClusterConfigResponse
+ */
+export type WatchClusterConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.WatchClusterConfigResponse"> & {
+  /**
+   * @generated from field: github.com.akuity.kargo.api.v1alpha1.ClusterConfig cluster_config = 1;
+   */
+  clusterConfig?: ClusterConfig;
+
+  /**
+   * ADDED / MODIFIED / DELETED
+   *
+   * @generated from field: string type = 2;
+   */
+  type: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.WatchClusterConfigResponse.
+ * Use `create(WatchClusterConfigResponseSchema)` to create a new message.
+ */
+export const WatchClusterConfigResponseSchema: GenMessage<WatchClusterConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 43);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.RefreshClusterConfigRequest
+ */
+export type RefreshClusterConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.RefreshClusterConfigRequest"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.RefreshClusterConfigRequest.
+ * Use `create(RefreshClusterConfigRequestSchema)` to create a new message.
+ */
+export const RefreshClusterConfigRequestSchema: GenMessage<RefreshClusterConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 44);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.RefreshClusterConfigResponse
+ */
+export type RefreshClusterConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.RefreshClusterConfigResponse"> & {
+  /**
+   * @generated from field: github.com.akuity.kargo.api.v1alpha1.ClusterConfig cluster_config = 1;
+   */
+  clusterConfig?: ClusterConfig;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.RefreshClusterConfigResponse.
+ * Use `create(RefreshClusterConfigResponseSchema)` to create a new message.
+ */
+export const RefreshClusterConfigResponseSchema: GenMessage<RefreshClusterConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 45);
+
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionsRequest
  */
@@ -846,7 +993,7 @@ export type ListPromotionsRequest = Message<"akuity.io.kargo.service.v1alpha1.Li
  * Use `create(ListPromotionsRequestSchema)` to create a new message.
  */
 export const ListPromotionsRequestSchema: GenMessage<ListPromotionsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 38);
+  messageDesc(file_api_service_v1alpha1_service, 46);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionsResponse
@@ -863,7 +1010,7 @@ export type ListPromotionsResponse = Message<"akuity.io.kargo.service.v1alpha1.L
  * Use `create(ListPromotionsResponseSchema)` to create a new message.
  */
 export const ListPromotionsResponseSchema: GenMessage<ListPromotionsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 39);
+  messageDesc(file_api_service_v1alpha1_service, 47);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionsRequest
@@ -885,7 +1032,7 @@ export type WatchPromotionsRequest = Message<"akuity.io.kargo.service.v1alpha1.W
  * Use `create(WatchPromotionsRequestSchema)` to create a new message.
  */
 export const WatchPromotionsRequestSchema: GenMessage<WatchPromotionsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 40);
+  messageDesc(file_api_service_v1alpha1_service, 48);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse
@@ -907,7 +1054,7 @@ export type WatchPromotionsResponse = Message<"akuity.io.kargo.service.v1alpha1.
  * Use `create(WatchPromotionsResponseSchema)` to create a new message.
  */
 export const WatchPromotionsResponseSchema: GenMessage<WatchPromotionsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 41);
+  messageDesc(file_api_service_v1alpha1_service, 49);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionRequest
@@ -934,7 +1081,7 @@ export type GetPromotionRequest = Message<"akuity.io.kargo.service.v1alpha1.GetP
  * Use `create(GetPromotionRequestSchema)` to create a new message.
  */
 export const GetPromotionRequestSchema: GenMessage<GetPromotionRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 42);
+  messageDesc(file_api_service_v1alpha1_service, 50);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionResponse
@@ -963,7 +1110,7 @@ export type GetPromotionResponse = Message<"akuity.io.kargo.service.v1alpha1.Get
  * Use `create(GetPromotionResponseSchema)` to create a new message.
  */
 export const GetPromotionResponseSchema: GenMessage<GetPromotionResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 43);
+  messageDesc(file_api_service_v1alpha1_service, 51);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionRequest
@@ -985,7 +1132,7 @@ export type WatchPromotionRequest = Message<"akuity.io.kargo.service.v1alpha1.Wa
  * Use `create(WatchPromotionRequestSchema)` to create a new message.
  */
 export const WatchPromotionRequestSchema: GenMessage<WatchPromotionRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 44);
+  messageDesc(file_api_service_v1alpha1_service, 52);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionResponse
@@ -1007,7 +1154,7 @@ export type WatchPromotionResponse = Message<"akuity.io.kargo.service.v1alpha1.W
  * Use `create(WatchPromotionResponseSchema)` to create a new message.
  */
 export const WatchPromotionResponseSchema: GenMessage<WatchPromotionResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 45);
+  messageDesc(file_api_service_v1alpha1_service, 53);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.AbortPromotionRequest
@@ -1029,7 +1176,7 @@ export type AbortPromotionRequest = Message<"akuity.io.kargo.service.v1alpha1.Ab
  * Use `create(AbortPromotionRequestSchema)` to create a new message.
  */
 export const AbortPromotionRequestSchema: GenMessage<AbortPromotionRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 46);
+  messageDesc(file_api_service_v1alpha1_service, 54);
 
 /**
  * explicitly empty 
@@ -1044,7 +1191,7 @@ export type AbortPromotionResponse = Message<"akuity.io.kargo.service.v1alpha1.A
  * Use `create(AbortPromotionResponseSchema)` to create a new message.
  */
 export const AbortPromotionResponseSchema: GenMessage<AbortPromotionResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 47);
+  messageDesc(file_api_service_v1alpha1_service, 55);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectRequest
@@ -1061,7 +1208,7 @@ export type DeleteProjectRequest = Message<"akuity.io.kargo.service.v1alpha1.Del
  * Use `create(DeleteProjectRequestSchema)` to create a new message.
  */
 export const DeleteProjectRequestSchema: GenMessage<DeleteProjectRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 48);
+  messageDesc(file_api_service_v1alpha1_service, 56);
 
 /**
  * explicitly empty 
@@ -1076,90 +1223,7 @@ export type DeleteProjectResponse = Message<"akuity.io.kargo.service.v1alpha1.De
  * Use `create(DeleteProjectResponseSchema)` to create a new message.
  */
 export const DeleteProjectResponseSchema: GenMessage<DeleteProjectResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 49);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest
- */
-export type DeleteProjectConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest"> & {
-  /**
-   * @generated from field: string name = 1;
-   */
-  name: string;
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest.
- * Use `create(DeleteProjectConfigRequestSchema)` to create a new message.
- */
-export const DeleteProjectConfigRequestSchema: GenMessage<DeleteProjectConfigRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 50);
-
-/**
- * explicitly empty 
- *
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse
- */
-export type DeleteProjectConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse"> & {
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse.
- * Use `create(DeleteProjectConfigResponseSchema)` to create a new message.
- */
-export const DeleteProjectConfigResponseSchema: GenMessage<DeleteProjectConfigResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 51);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest
- */
-export type GetProjectConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest"> & {
-  /**
-   * @generated from field: string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 2;
-   */
-  format: RawFormat;
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest.
- * Use `create(GetProjectConfigRequestSchema)` to create a new message.
- */
-export const GetProjectConfigRequestSchema: GenMessage<GetProjectConfigRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 52);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse
- */
-export type GetProjectConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse"> & {
-  /**
-   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse.result
-   */
-  result: {
-    /**
-     * @generated from field: github.com.akuity.kargo.api.v1alpha1.ProjectConfig project_config = 1;
-     */
-    value: ProjectConfig;
-    case: "projectConfig";
-  } | {
-    /**
-     * @generated from field: bytes raw = 2;
-     */
-    value: Uint8Array;
-    case: "raw";
-  } | { case: undefined; value?: undefined };
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse.
- * Use `create(GetProjectConfigResponseSchema)` to create a new message.
- */
-export const GetProjectConfigResponseSchema: GenMessage<GetProjectConfigResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 53);
+  messageDesc(file_api_service_v1alpha1_service, 57);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectRequest
@@ -1181,7 +1245,7 @@ export type GetProjectRequest = Message<"akuity.io.kargo.service.v1alpha1.GetPro
  * Use `create(GetProjectRequestSchema)` to create a new message.
  */
 export const GetProjectRequestSchema: GenMessage<GetProjectRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 54);
+  messageDesc(file_api_service_v1alpha1_service, 58);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectResponse
@@ -1210,7 +1274,7 @@ export type GetProjectResponse = Message<"akuity.io.kargo.service.v1alpha1.GetPr
  * Use `create(GetProjectResponseSchema)` to create a new message.
  */
 export const GetProjectResponseSchema: GenMessage<GetProjectResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 55);
+  messageDesc(file_api_service_v1alpha1_service, 59);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectsRequest
@@ -1237,7 +1301,7 @@ export type ListProjectsRequest = Message<"akuity.io.kargo.service.v1alpha1.List
  * Use `create(ListProjectsRequestSchema)` to create a new message.
  */
 export const ListProjectsRequestSchema: GenMessage<ListProjectsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 56);
+  messageDesc(file_api_service_v1alpha1_service, 60);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectsResponse
@@ -1259,39 +1323,197 @@ export type ListProjectsResponse = Message<"akuity.io.kargo.service.v1alpha1.Lis
  * Use `create(ListProjectsResponseSchema)` to create a new message.
  */
 export const ListProjectsResponseSchema: GenMessage<ListProjectsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 57);
+  messageDesc(file_api_service_v1alpha1_service, 61);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest
  */
-export type ApproveFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.ApproveFreightRequest"> & {
+export type GetProjectConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
   project: string;
 
   /**
-   * @generated from field: string name = 2;
+   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 2;
    */
-  name: string;
+  format: RawFormat;
+};
 
-  /**
-   * @generated from field: string alias = 3;
-   */
-  alias: string;
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetProjectConfigRequest.
+ * Use `create(GetProjectConfigRequestSchema)` to create a new message.
+ */
+export const GetProjectConfigRequestSchema: GenMessage<GetProjectConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 62);
 
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse
+ */
+export type GetProjectConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse"> & {
   /**
-   * @generated from field: string stage = 4;
+   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse.result
    */
-  stage: string;
+  result: {
+    /**
+     * @generated from field: github.com.akuity.kargo.api.v1alpha1.ProjectConfig project_config = 1;
+     */
+    value: ProjectConfig;
+    case: "projectConfig";
+  } | {
+    /**
+     * @generated from field: bytes raw = 2;
+     */
+    value: Uint8Array;
+    case: "raw";
+  } | { case: undefined; value?: undefined };
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ApproveFreightRequest.
- * Use `create(ApproveFreightRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetProjectConfigResponse.
+ * Use `create(GetProjectConfigResponseSchema)` to create a new message.
+ */
+export const GetProjectConfigResponseSchema: GenMessage<GetProjectConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 63);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest
+ */
+export type DeleteProjectConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigRequest.
+ * Use `create(DeleteProjectConfigRequestSchema)` to create a new message.
+ */
+export const DeleteProjectConfigRequestSchema: GenMessage<DeleteProjectConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 64);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse
+ */
+export type DeleteProjectConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectConfigResponse.
+ * Use `create(DeleteProjectConfigResponseSchema)` to create a new message.
+ */
+export const DeleteProjectConfigResponseSchema: GenMessage<DeleteProjectConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 65);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.WatchProjectConfigRequest
+ */
+export type WatchProjectConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.WatchProjectConfigRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.WatchProjectConfigRequest.
+ * Use `create(WatchProjectConfigRequestSchema)` to create a new message.
+ */
+export const WatchProjectConfigRequestSchema: GenMessage<WatchProjectConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 66);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.WatchProjectConfigResponse
+ */
+export type WatchProjectConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.WatchProjectConfigResponse"> & {
+  /**
+   * @generated from field: github.com.akuity.kargo.api.v1alpha1.ProjectConfig project_config = 1;
+   */
+  projectConfig?: ProjectConfig;
+
+  /**
+   * ADDED / MODIFIED / DELETED
+   *
+   * @generated from field: string type = 2;
+   */
+  type: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.WatchProjectConfigResponse.
+ * Use `create(WatchProjectConfigResponseSchema)` to create a new message.
+ */
+export const WatchProjectConfigResponseSchema: GenMessage<WatchProjectConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 67);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.RefreshProjectConfigRequest
+ */
+export type RefreshProjectConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.RefreshProjectConfigRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.RefreshProjectConfigRequest.
+ * Use `create(RefreshProjectConfigRequestSchema)` to create a new message.
+ */
+export const RefreshProjectConfigRequestSchema: GenMessage<RefreshProjectConfigRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 68);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.RefreshProjectConfigResponse
+ */
+export type RefreshProjectConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.RefreshProjectConfigResponse"> & {
+  /**
+   * @generated from field: github.com.akuity.kargo.api.v1alpha1.ProjectConfig project_config = 1;
+   */
+  projectConfig?: ProjectConfig;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.RefreshProjectConfigResponse.
+ * Use `create(RefreshProjectConfigResponseSchema)` to create a new message.
+ */
+export const RefreshProjectConfigResponseSchema: GenMessage<RefreshProjectConfigResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 69);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
+ */
+export type ApproveFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.ApproveFreightRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
+
+  /**
+   * @generated from field: string name = 2;
+   */
+  name: string;
+
+  /**
+   * @generated from field: string alias = 3;
+   */
+  alias: string;
+
+  /**
+   * @generated from field: string stage = 4;
+   */
+  stage: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.ApproveFreightRequest.
+ * Use `create(ApproveFreightRequestSchema)` to create a new message.
  */
 export const ApproveFreightRequestSchema: GenMessage<ApproveFreightRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 58);
+  messageDesc(file_api_service_v1alpha1_service, 70);
 
 /**
  * explicitly empty 
@@ -1306,7 +1528,7 @@ export type ApproveFreightResponse = Message<"akuity.io.kargo.service.v1alpha1.A
  * Use `create(ApproveFreightResponseSchema)` to create a new message.
  */
 export const ApproveFreightResponseSchema: GenMessage<ApproveFreightResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 59);
+  messageDesc(file_api_service_v1alpha1_service, 71);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteFreightRequest
@@ -1333,7 +1555,7 @@ export type DeleteFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.Del
  * Use `create(DeleteFreightRequestSchema)` to create a new message.
  */
 export const DeleteFreightRequestSchema: GenMessage<DeleteFreightRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 60);
+  messageDesc(file_api_service_v1alpha1_service, 72);
 
 /**
  * explicitly empty 
@@ -1348,7 +1570,7 @@ export type DeleteFreightResponse = Message<"akuity.io.kargo.service.v1alpha1.De
  * Use `create(DeleteFreightResponseSchema)` to create a new message.
  */
 export const DeleteFreightResponseSchema: GenMessage<DeleteFreightResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 61);
+  messageDesc(file_api_service_v1alpha1_service, 73);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetFreightRequest
@@ -1380,7 +1602,7 @@ export type GetFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.GetFre
  * Use `create(GetFreightRequestSchema)` to create a new message.
  */
 export const GetFreightRequestSchema: GenMessage<GetFreightRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 62);
+  messageDesc(file_api_service_v1alpha1_service, 74);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetFreightResponse
@@ -1409,7 +1631,7 @@ export type GetFreightResponse = Message<"akuity.io.kargo.service.v1alpha1.GetFr
  * Use `create(GetFreightResponseSchema)` to create a new message.
  */
 export const GetFreightResponseSchema: GenMessage<GetFreightResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 63);
+  messageDesc(file_api_service_v1alpha1_service, 75);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchFreightRequest
@@ -1426,7 +1648,7 @@ export type WatchFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.Watc
  * Use `create(WatchFreightRequestSchema)` to create a new message.
  */
 export const WatchFreightRequestSchema: GenMessage<WatchFreightRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 64);
+  messageDesc(file_api_service_v1alpha1_service, 76);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchFreightResponse
@@ -1450,7 +1672,7 @@ export type WatchFreightResponse = Message<"akuity.io.kargo.service.v1alpha1.Wat
  * Use `create(WatchFreightResponseSchema)` to create a new message.
  */
 export const WatchFreightResponseSchema: GenMessage<WatchFreightResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 65);
+  messageDesc(file_api_service_v1alpha1_service, 77);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteToStageRequest
@@ -1482,7 +1704,7 @@ export type PromoteToStageRequest = Message<"akuity.io.kargo.service.v1alpha1.Pr
  * Use `create(PromoteToStageRequestSchema)` to create a new message.
  */
 export const PromoteToStageRequestSchema: GenMessage<PromoteToStageRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 66);
+  messageDesc(file_api_service_v1alpha1_service, 78);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteToStageResponse
@@ -1499,7 +1721,7 @@ export type PromoteToStageResponse = Message<"akuity.io.kargo.service.v1alpha1.P
  * Use `create(PromoteToStageResponseSchema)` to create a new message.
  */
 export const PromoteToStageResponseSchema: GenMessage<PromoteToStageResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 67);
+  messageDesc(file_api_service_v1alpha1_service, 79);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteDownstreamRequest
@@ -1531,7 +1753,7 @@ export type PromoteDownstreamRequest = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(PromoteDownstreamRequestSchema)` to create a new message.
  */
 export const PromoteDownstreamRequestSchema: GenMessage<PromoteDownstreamRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 68);
+  messageDesc(file_api_service_v1alpha1_service, 80);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse
@@ -1548,7 +1770,7 @@ export type PromoteDownstreamResponse = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(PromoteDownstreamResponseSchema)` to create a new message.
  */
 export const PromoteDownstreamResponseSchema: GenMessage<PromoteDownstreamResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 69);
+  messageDesc(file_api_service_v1alpha1_service, 81);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.QueryFreightRequest
@@ -1595,7 +1817,7 @@ export type QueryFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.Quer
  * Use `create(QueryFreightRequestSchema)` to create a new message.
  */
 export const QueryFreightRequestSchema: GenMessage<QueryFreightRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 70);
+  messageDesc(file_api_service_v1alpha1_service, 82);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.QueryFreightResponse
@@ -1612,7 +1834,7 @@ export type QueryFreightResponse = Message<"akuity.io.kargo.service.v1alpha1.Que
  * Use `create(QueryFreightResponseSchema)` to create a new message.
  */
 export const QueryFreightResponseSchema: GenMessage<QueryFreightResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 71);
+  messageDesc(file_api_service_v1alpha1_service, 83);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.FreightList
@@ -1629,7 +1851,7 @@ export type FreightList = Message<"akuity.io.kargo.service.v1alpha1.FreightList"
  * Use `create(FreightListSchema)` to create a new message.
  */
 export const FreightListSchema: GenMessage<FreightList> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 72);
+  messageDesc(file_api_service_v1alpha1_service, 84);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateFreightAliasRequest
@@ -1661,7 +1883,7 @@ export type UpdateFreightAliasRequest = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(UpdateFreightAliasRequestSchema)` to create a new message.
  */
 export const UpdateFreightAliasRequestSchema: GenMessage<UpdateFreightAliasRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 73);
+  messageDesc(file_api_service_v1alpha1_service, 85);
 
 /**
  * explicitly empty 
@@ -1676,7 +1898,7 @@ export type UpdateFreightAliasResponse = Message<"akuity.io.kargo.service.v1alph
  * Use `create(UpdateFreightAliasResponseSchema)` to create a new message.
  */
 export const UpdateFreightAliasResponseSchema: GenMessage<UpdateFreightAliasResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 74);
+  messageDesc(file_api_service_v1alpha1_service, 86);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ReverifyRequest
@@ -1698,7 +1920,7 @@ export type ReverifyRequest = Message<"akuity.io.kargo.service.v1alpha1.Reverify
  * Use `create(ReverifyRequestSchema)` to create a new message.
  */
 export const ReverifyRequestSchema: GenMessage<ReverifyRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 75);
+  messageDesc(file_api_service_v1alpha1_service, 87);
 
 /**
  * explicitly empty 
@@ -1713,7 +1935,7 @@ export type ReverifyResponse = Message<"akuity.io.kargo.service.v1alpha1.Reverif
  * Use `create(ReverifyResponseSchema)` to create a new message.
  */
 export const ReverifyResponseSchema: GenMessage<ReverifyResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 76);
+  messageDesc(file_api_service_v1alpha1_service, 88);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.AbortVerificationRequest
@@ -1735,7 +1957,7 @@ export type AbortVerificationRequest = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(AbortVerificationRequestSchema)` to create a new message.
  */
 export const AbortVerificationRequestSchema: GenMessage<AbortVerificationRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 77);
+  messageDesc(file_api_service_v1alpha1_service, 89);
 
 /**
  * explicitly empty 
@@ -1750,7 +1972,7 @@ export type AbortVerificationResponse = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(AbortVerificationResponseSchema)` to create a new message.
  */
 export const AbortVerificationResponseSchema: GenMessage<AbortVerificationResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 78);
+  messageDesc(file_api_service_v1alpha1_service, 90);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListWarehousesRequest
@@ -1767,7 +1989,7 @@ export type ListWarehousesRequest = Message<"akuity.io.kargo.service.v1alpha1.Li
  * Use `create(ListWarehousesRequestSchema)` to create a new message.
  */
 export const ListWarehousesRequestSchema: GenMessage<ListWarehousesRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 79);
+  messageDesc(file_api_service_v1alpha1_service, 91);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListWarehousesResponse
@@ -1784,7 +2006,7 @@ export type ListWarehousesResponse = Message<"akuity.io.kargo.service.v1alpha1.L
  * Use `create(ListWarehousesResponseSchema)` to create a new message.
  */
 export const ListWarehousesResponseSchema: GenMessage<ListWarehousesResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 80);
+  messageDesc(file_api_service_v1alpha1_service, 92);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetWarehouseRequest
@@ -1811,7 +2033,7 @@ export type GetWarehouseRequest = Message<"akuity.io.kargo.service.v1alpha1.GetW
  * Use `create(GetWarehouseRequestSchema)` to create a new message.
  */
 export const GetWarehouseRequestSchema: GenMessage<GetWarehouseRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 81);
+  messageDesc(file_api_service_v1alpha1_service, 93);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetWarehouseResponse
@@ -1840,7 +2062,7 @@ export type GetWarehouseResponse = Message<"akuity.io.kargo.service.v1alpha1.Get
  * Use `create(GetWarehouseResponseSchema)` to create a new message.
  */
 export const GetWarehouseResponseSchema: GenMessage<GetWarehouseResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 82);
+  messageDesc(file_api_service_v1alpha1_service, 94);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchWarehousesRequest
@@ -1862,7 +2084,7 @@ export type WatchWarehousesRequest = Message<"akuity.io.kargo.service.v1alpha1.W
  * Use `create(WatchWarehousesRequestSchema)` to create a new message.
  */
 export const WatchWarehousesRequestSchema: GenMessage<WatchWarehousesRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 83);
+  messageDesc(file_api_service_v1alpha1_service, 95);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse
@@ -1884,7 +2106,7 @@ export type WatchWarehousesResponse = Message<"akuity.io.kargo.service.v1alpha1.
  * Use `create(WatchWarehousesResponseSchema)` to create a new message.
  */
 export const WatchWarehousesResponseSchema: GenMessage<WatchWarehousesResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 84);
+  messageDesc(file_api_service_v1alpha1_service, 96);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteWarehouseRequest
@@ -1906,7 +2128,7 @@ export type DeleteWarehouseRequest = Message<"akuity.io.kargo.service.v1alpha1.D
  * Use `create(DeleteWarehouseRequestSchema)` to create a new message.
  */
 export const DeleteWarehouseRequestSchema: GenMessage<DeleteWarehouseRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 85);
+  messageDesc(file_api_service_v1alpha1_service, 97);
 
 /**
  * explicitly empty 
@@ -1921,7 +2143,7 @@ export type DeleteWarehouseResponse = Message<"akuity.io.kargo.service.v1alpha1.
  * Use `create(DeleteWarehouseResponseSchema)` to create a new message.
  */
 export const DeleteWarehouseResponseSchema: GenMessage<DeleteWarehouseResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 86);
+  messageDesc(file_api_service_v1alpha1_service, 98);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RefreshWarehouseRequest
@@ -1943,7 +2165,7 @@ export type RefreshWarehouseRequest = Message<"akuity.io.kargo.service.v1alpha1.
  * Use `create(RefreshWarehouseRequestSchema)` to create a new message.
  */
 export const RefreshWarehouseRequestSchema: GenMessage<RefreshWarehouseRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 87);
+  messageDesc(file_api_service_v1alpha1_service, 99);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse
@@ -1960,247 +2182,78 @@ export type RefreshWarehouseResponse = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(RefreshWarehouseResponseSchema)` to create a new message.
  */
 export const RefreshWarehouseResponseSchema: GenMessage<RefreshWarehouseResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 88);
+  messageDesc(file_api_service_v1alpha1_service, 100);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
  */
-export type ListProjectSecretsRequest = Message<"akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest"> & {
+export type CreateCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
   project: string;
-};
 
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest.
- * Use `create(ListProjectSecretsRequestSchema)` to create a new message.
- */
-export const ListProjectSecretsRequestSchema: GenMessage<ListProjectSecretsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 89);
+  /**
+   * @generated from field: string name = 2;
+   */
+  name: string;
 
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
- */
-export type ListProjectSecretsResponse = Message<"akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse"> & {
   /**
-   * @generated from field: repeated k8s.io.api.core.v1.Secret secrets = 1;
+   * @generated from field: string description = 8;
    */
-  secrets: Secret[];
-};
+  description: string;
 
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse.
- * Use `create(ListProjectSecretsResponseSchema)` to create a new message.
- */
-export const ListProjectSecretsResponseSchema: GenMessage<ListProjectSecretsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 90);
+  /**
+   * type is git, helm, image
+   *
+   * @generated from field: string type = 3;
+   */
+  type: string;
 
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
- */
-export type CreateProjectSecretRequest = Message<"akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest"> & {
   /**
-   * @generated from field: string project = 1;
+   * @generated from field: string repo_url = 4 [json_name = "repoURL"];
    */
-  project: string;
+  repoUrl: string;
 
   /**
-   * @generated from field: string name = 2;
+   * @generated from field: bool repo_url_is_regex = 5 [json_name = "repoURLIsRegex"];
    */
-  name: string;
+  repoUrlIsRegex: boolean;
 
   /**
-   * @generated from field: string description = 3;
+   * @generated from field: string username = 6;
    */
-  description: string;
+  username: string;
 
   /**
-   * @generated from field: map<string, string> data = 4;
+   * @generated from field: string password = 7;
    */
-  data: { [key: string]: string };
+  password: string;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.
- * Use `create(CreateProjectSecretRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest.
+ * Use `create(CreateCredentialsRequestSchema)` to create a new message.
  */
-export const CreateProjectSecretRequestSchema: GenMessage<CreateProjectSecretRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 91);
+export const CreateCredentialsRequestSchema: GenMessage<CreateCredentialsRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 101);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
  */
-export type CreateProjectSecretResponse = Message<"akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse"> & {
+export type CreateCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse"> & {
   /**
-   * @generated from field: k8s.io.api.core.v1.Secret secret = 1;
+   * @generated from field: k8s.io.api.core.v1.Secret credentials = 1;
    */
-  secret?: Secret;
+  credentials?: Secret;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse.
- * Use `create(CreateProjectSecretResponseSchema)` to create a new message.
- */
-export const CreateProjectSecretResponseSchema: GenMessage<CreateProjectSecretResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 92);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
- */
-export type UpdateProjectSecretRequest = Message<"akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest"> & {
-  /**
-   * @generated from field: string project = 1;
-   */
-  project: string;
-
-  /**
-   * @generated from field: string name = 2;
-   */
-  name: string;
-
-  /**
-   * @generated from field: string description = 3;
-   */
-  description: string;
-
-  /**
-   * @generated from field: map<string, string> data = 4;
-   */
-  data: { [key: string]: string };
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.
- * Use `create(UpdateProjectSecretRequestSchema)` to create a new message.
- */
-export const UpdateProjectSecretRequestSchema: GenMessage<UpdateProjectSecretRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 93);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
- */
-export type UpdateProjectSecretResponse = Message<"akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse"> & {
-  /**
-   * @generated from field: k8s.io.api.core.v1.Secret secret = 1;
-   */
-  secret?: Secret;
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse.
- * Use `create(UpdateProjectSecretResponseSchema)` to create a new message.
- */
-export const UpdateProjectSecretResponseSchema: GenMessage<UpdateProjectSecretResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 94);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
- */
-export type DeleteProjectSecretRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest"> & {
-  /**
-   * @generated from field: string project = 1;
-   */
-  project: string;
-
-  /**
-   * @generated from field: string name = 2;
-   */
-  name: string;
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest.
- * Use `create(DeleteProjectSecretRequestSchema)` to create a new message.
- */
-export const DeleteProjectSecretRequestSchema: GenMessage<DeleteProjectSecretRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 95);
-
-/**
- * explicitly empty 
- *
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse
- */
-export type DeleteProjectSecretResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse"> & {
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse.
- * Use `create(DeleteProjectSecretResponseSchema)` to create a new message.
- */
-export const DeleteProjectSecretResponseSchema: GenMessage<DeleteProjectSecretResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 96);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
- */
-export type CreateCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest"> & {
-  /**
-   * @generated from field: string project = 1;
-   */
-  project: string;
-
-  /**
-   * @generated from field: string name = 2;
-   */
-  name: string;
-
-  /**
-   * @generated from field: string description = 8;
-   */
-  description: string;
-
-  /**
-   * type is git, helm, image
-   *
-   * @generated from field: string type = 3;
-   */
-  type: string;
-
-  /**
-   * @generated from field: string repo_url = 4 [json_name = "repoURL"];
-   */
-  repoUrl: string;
-
-  /**
-   * @generated from field: bool repo_url_is_regex = 5 [json_name = "repoURLIsRegex"];
-   */
-  repoUrlIsRegex: boolean;
-
-  /**
-   * @generated from field: string username = 6;
-   */
-  username: string;
-
-  /**
-   * @generated from field: string password = 7;
-   */
-  password: string;
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest.
- * Use `create(CreateCredentialsRequestSchema)` to create a new message.
- */
-export const CreateCredentialsRequestSchema: GenMessage<CreateCredentialsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 97);
-
-/**
- * @generated from message akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
- */
-export type CreateCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse"> & {
-  /**
-   * @generated from field: k8s.io.api.core.v1.Secret credentials = 1;
-   */
-  credentials?: Secret;
-};
-
-/**
- * Describes the message akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse.
- * Use `create(CreateCredentialsResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse.
+ * Use `create(CreateCredentialsResponseSchema)` to create a new message.
  */
 export const CreateCredentialsResponseSchema: GenMessage<CreateCredentialsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 98);
+  messageDesc(file_api_service_v1alpha1_service, 102);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteCredentialsRequest
@@ -2222,7 +2275,7 @@ export type DeleteCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(DeleteCredentialsRequestSchema)` to create a new message.
  */
 export const DeleteCredentialsRequestSchema: GenMessage<DeleteCredentialsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 99);
+  messageDesc(file_api_service_v1alpha1_service, 103);
 
 /**
  * explicitly empty 
@@ -2237,7 +2290,7 @@ export type DeleteCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(DeleteCredentialsResponseSchema)` to create a new message.
  */
 export const DeleteCredentialsResponseSchema: GenMessage<DeleteCredentialsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 100);
+  messageDesc(file_api_service_v1alpha1_service, 104);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetCredentialsRequest
@@ -2264,7 +2317,7 @@ export type GetCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1.Ge
  * Use `create(GetCredentialsRequestSchema)` to create a new message.
  */
 export const GetCredentialsRequestSchema: GenMessage<GetCredentialsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 101);
+  messageDesc(file_api_service_v1alpha1_service, 105);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetCredentialsResponse
@@ -2293,7 +2346,7 @@ export type GetCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha1.G
  * Use `create(GetCredentialsResponseSchema)` to create a new message.
  */
 export const GetCredentialsResponseSchema: GenMessage<GetCredentialsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 102);
+  messageDesc(file_api_service_v1alpha1_service, 106);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListCredentialsRequest
@@ -2310,7 +2363,7 @@ export type ListCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1.L
  * Use `create(ListCredentialsRequestSchema)` to create a new message.
  */
 export const ListCredentialsRequestSchema: GenMessage<ListCredentialsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 103);
+  messageDesc(file_api_service_v1alpha1_service, 107);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListCredentialsResponse
@@ -2327,7 +2380,7 @@ export type ListCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha1.
  * Use `create(ListCredentialsResponseSchema)` to create a new message.
  */
 export const ListCredentialsResponseSchema: GenMessage<ListCredentialsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 104);
+  messageDesc(file_api_service_v1alpha1_service, 108);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateCredentialsRequest
@@ -2379,7 +2432,7 @@ export type UpdateCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(UpdateCredentialsRequestSchema)` to create a new message.
  */
 export const UpdateCredentialsRequestSchema: GenMessage<UpdateCredentialsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 105);
+  messageDesc(file_api_service_v1alpha1_service, 109);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse
@@ -2396,12 +2449,12 @@ export type UpdateCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(UpdateCredentialsResponseSchema)` to create a new message.
  */
 export const UpdateCredentialsResponseSchema: GenMessage<UpdateCredentialsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 106);
+  messageDesc(file_api_service_v1alpha1_service, 110);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
  */
-export type ListAnalysisTemplatesRequest = Message<"akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest"> & {
+export type ListProjectSecretsRequest = Message<"akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
@@ -2409,97 +2462,131 @@ export type ListAnalysisTemplatesRequest = Message<"akuity.io.kargo.service.v1al
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest.
- * Use `create(ListAnalysisTemplatesRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest.
+ * Use `create(ListProjectSecretsRequestSchema)` to create a new message.
  */
-export const ListAnalysisTemplatesRequestSchema: GenMessage<ListAnalysisTemplatesRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 107);
+export const ListProjectSecretsRequestSchema: GenMessage<ListProjectSecretsRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 111);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
  */
-export type ListAnalysisTemplatesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse"> & {
+export type ListProjectSecretsResponse = Message<"akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse"> & {
   /**
-   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_templates = 1;
+   * @generated from field: repeated k8s.io.api.core.v1.Secret secrets = 1;
    */
-  analysisTemplates: AnalysisTemplate[];
+  secrets: Secret[];
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse.
- * Use `create(ListAnalysisTemplatesResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse.
+ * Use `create(ListProjectSecretsResponseSchema)` to create a new message.
  */
-export const ListAnalysisTemplatesResponseSchema: GenMessage<ListAnalysisTemplatesResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 108);
+export const ListProjectSecretsResponseSchema: GenMessage<ListProjectSecretsResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 112);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
  */
-export type ListPromotionTasksRequest = Message<"akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest"> & {
+export type CreateProjectSecretRequest = Message<"akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
   project: string;
+
+  /**
+   * @generated from field: string name = 2;
+   */
+  name: string;
+
+  /**
+   * @generated from field: string description = 3;
+   */
+  description: string;
+
+  /**
+   * @generated from field: map<string, string> data = 4;
+   */
+  data: { [key: string]: string };
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest.
- * Use `create(ListPromotionTasksRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest.
+ * Use `create(CreateProjectSecretRequestSchema)` to create a new message.
  */
-export const ListPromotionTasksRequestSchema: GenMessage<ListPromotionTasksRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 109);
+export const CreateProjectSecretRequestSchema: GenMessage<CreateProjectSecretRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 113);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
  */
-export type ListPromotionTasksResponse = Message<"akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse"> & {
+export type CreateProjectSecretResponse = Message<"akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse"> & {
   /**
-   * @generated from field: repeated github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_tasks = 1;
+   * @generated from field: k8s.io.api.core.v1.Secret secret = 1;
    */
-  promotionTasks: PromotionTask[];
+  secret?: Secret;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse.
- * Use `create(ListPromotionTasksResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse.
+ * Use `create(CreateProjectSecretResponseSchema)` to create a new message.
  */
-export const ListPromotionTasksResponseSchema: GenMessage<ListPromotionTasksResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 110);
+export const CreateProjectSecretResponseSchema: GenMessage<CreateProjectSecretResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 114);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
  */
-export type ListClusterPromotionTasksRequest = Message<"akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest"> & {
+export type UpdateProjectSecretRequest = Message<"akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
+
+  /**
+   * @generated from field: string name = 2;
+   */
+  name: string;
+
+  /**
+   * @generated from field: string description = 3;
+   */
+  description: string;
+
+  /**
+   * @generated from field: map<string, string> data = 4;
+   */
+  data: { [key: string]: string };
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest.
- * Use `create(ListClusterPromotionTasksRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest.
+ * Use `create(UpdateProjectSecretRequestSchema)` to create a new message.
  */
-export const ListClusterPromotionTasksRequestSchema: GenMessage<ListClusterPromotionTasksRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 111);
+export const UpdateProjectSecretRequestSchema: GenMessage<UpdateProjectSecretRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 115);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
  */
-export type ListClusterPromotionTasksResponse = Message<"akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse"> & {
+export type UpdateProjectSecretResponse = Message<"akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse"> & {
   /**
-   * @generated from field: repeated github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask cluster_promotion_tasks = 1;
+   * @generated from field: k8s.io.api.core.v1.Secret secret = 1;
    */
-  clusterPromotionTasks: ClusterPromotionTask[];
+  secret?: Secret;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse.
- * Use `create(ListClusterPromotionTasksResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse.
+ * Use `create(UpdateProjectSecretResponseSchema)` to create a new message.
  */
-export const ListClusterPromotionTasksResponseSchema: GenMessage<ListClusterPromotionTasksResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 112);
+export const UpdateProjectSecretResponseSchema: GenMessage<UpdateProjectSecretResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 116);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
  */
-export type GetAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest"> & {
+export type DeleteProjectSecretRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
@@ -2509,53 +2596,68 @@ export type GetAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alph
    * @generated from field: string name = 2;
    */
   name: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest.
+ * Use `create(DeleteProjectSecretRequestSchema)` to create a new message.
+ */
+export const DeleteProjectSecretRequestSchema: GenMessage<DeleteProjectSecretRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 117);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse
+ */
+export type DeleteProjectSecretResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretResponse.
+ * Use `create(DeleteProjectSecretResponseSchema)` to create a new message.
+ */
+export const DeleteProjectSecretResponseSchema: GenMessage<DeleteProjectSecretResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 118);
 
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
+ */
+export type ListAnalysisTemplatesRequest = Message<"akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest"> & {
   /**
-   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 3;
+   * @generated from field: string project = 1;
    */
-  format: RawFormat;
+  project: string;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest.
- * Use `create(GetAnalysisTemplateRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest.
+ * Use `create(ListAnalysisTemplatesRequestSchema)` to create a new message.
  */
-export const GetAnalysisTemplateRequestSchema: GenMessage<GetAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 113);
+export const ListAnalysisTemplatesRequestSchema: GenMessage<ListAnalysisTemplatesRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 119);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
  */
-export type GetAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse"> & {
+export type ListAnalysisTemplatesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse"> & {
   /**
-   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.result
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_templates = 1;
    */
-  result: {
-    /**
-     * @generated from field: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_template = 1;
-     */
-    value: AnalysisTemplate;
-    case: "analysisTemplate";
-  } | {
-    /**
-     * @generated from field: bytes raw = 2;
-     */
-    value: Uint8Array;
-    case: "raw";
-  } | { case: undefined; value?: undefined };
+  analysisTemplates: AnalysisTemplate[];
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.
- * Use `create(GetAnalysisTemplateResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse.
+ * Use `create(ListAnalysisTemplatesResponseSchema)` to create a new message.
  */
-export const GetAnalysisTemplateResponseSchema: GenMessage<GetAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 114);
+export const ListAnalysisTemplatesResponseSchema: GenMessage<ListAnalysisTemplatesResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 120);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
  */
-export type GetPromotionTaskRequest = Message<"akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest"> & {
+export type GetAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
@@ -2573,25 +2675,25 @@ export type GetPromotionTaskRequest = Message<"akuity.io.kargo.service.v1alpha1.
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest.
- * Use `create(GetPromotionTaskRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest.
+ * Use `create(GetAnalysisTemplateRequestSchema)` to create a new message.
  */
-export const GetPromotionTaskRequestSchema: GenMessage<GetPromotionTaskRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 115);
+export const GetAnalysisTemplateRequestSchema: GenMessage<GetAnalysisTemplateRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 121);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
  */
-export type GetPromotionTaskResponse = Message<"akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse"> & {
+export type GetAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse"> & {
   /**
-   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse.result
+   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.result
    */
   result: {
     /**
-     * @generated from field: github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_task = 1;
+     * @generated from field: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_template = 1;
      */
-    value: PromotionTask;
-    case: "promotionTask";
+    value: AnalysisTemplate;
+    case: "analysisTemplate";
   } | {
     /**
      * @generated from field: bytes raw = 2;
@@ -2602,62 +2704,48 @@ export type GetPromotionTaskResponse = Message<"akuity.io.kargo.service.v1alpha1
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse.
- * Use `create(GetPromotionTaskResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.
+ * Use `create(GetAnalysisTemplateResponseSchema)` to create a new message.
  */
-export const GetPromotionTaskResponseSchema: GenMessage<GetPromotionTaskResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 116);
+export const GetAnalysisTemplateResponseSchema: GenMessage<GetAnalysisTemplateResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 122);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
  */
-export type GetClusterPromotionTaskRequest = Message<"akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest"> & {
+export type DeleteAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest"> & {
   /**
-   * @generated from field: string name = 2;
+   * @generated from field: string project = 1;
    */
-  name: string;
+  project: string;
 
   /**
-   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 3;
+   * @generated from field: string name = 2;
    */
-  format: RawFormat;
+  name: string;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest.
- * Use `create(GetClusterPromotionTaskRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest.
+ * Use `create(DeleteAnalysisTemplateRequestSchema)` to create a new message.
  */
-export const GetClusterPromotionTaskRequestSchema: GenMessage<GetClusterPromotionTaskRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 117);
+export const DeleteAnalysisTemplateRequestSchema: GenMessage<DeleteAnalysisTemplateRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 123);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse
  */
-export type GetClusterPromotionTaskResponse = Message<"akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse"> & {
-  /**
-   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse.result
-   */
-  result: {
-    /**
-     * @generated from field: github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask promotion_task = 1 [json_name = "clusterPromotionTask"];
-     */
-    value: ClusterPromotionTask;
-    case: "promotionTask";
-  } | {
-    /**
-     * @generated from field: bytes raw = 2;
-     */
-    value: Uint8Array;
-    case: "raw";
-  } | { case: undefined; value?: undefined };
+export type DeleteAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse"> & {
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse.
- * Use `create(GetClusterPromotionTaskResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse.
+ * Use `create(DeleteAnalysisTemplateResponseSchema)` to create a new message.
  */
-export const GetClusterPromotionTaskResponseSchema: GenMessage<GetClusterPromotionTaskResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 118);
+export const DeleteAnalysisTemplateResponseSchema: GenMessage<DeleteAnalysisTemplateResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 124);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesRequest
@@ -2670,7 +2758,7 @@ export type ListClusterAnalysisTemplatesRequest = Message<"akuity.io.kargo.servi
  * Use `create(ListClusterAnalysisTemplatesRequestSchema)` to create a new message.
  */
 export const ListClusterAnalysisTemplatesRequestSchema: GenMessage<ListClusterAnalysisTemplatesRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 119);
+  messageDesc(file_api_service_v1alpha1_service, 125);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse
@@ -2687,7 +2775,7 @@ export type ListClusterAnalysisTemplatesResponse = Message<"akuity.io.kargo.serv
  * Use `create(ListClusterAnalysisTemplatesResponseSchema)` to create a new message.
  */
 export const ListClusterAnalysisTemplatesResponseSchema: GenMessage<ListClusterAnalysisTemplatesResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 120);
+  messageDesc(file_api_service_v1alpha1_service, 126);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest
@@ -2709,7 +2797,7 @@ export type GetClusterAnalysisTemplateRequest = Message<"akuity.io.kargo.service
  * Use `create(GetClusterAnalysisTemplateRequestSchema)` to create a new message.
  */
 export const GetClusterAnalysisTemplateRequestSchema: GenMessage<GetClusterAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 121);
+  messageDesc(file_api_service_v1alpha1_service, 127);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse
@@ -2738,7 +2826,39 @@ export type GetClusterAnalysisTemplateResponse = Message<"akuity.io.kargo.servic
  * Use `create(GetClusterAnalysisTemplateResponseSchema)` to create a new message.
  */
 export const GetClusterAnalysisTemplateResponseSchema: GenMessage<GetClusterAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 122);
+  messageDesc(file_api_service_v1alpha1_service, 128);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest
+ */
+export type DeleteClusterAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest"> & {
+  /**
+   * @generated from field: string name = 2;
+   */
+  name: string;
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest.
+ * Use `create(DeleteClusterAnalysisTemplateRequestSchema)` to create a new message.
+ */
+export const DeleteClusterAnalysisTemplateRequestSchema: GenMessage<DeleteClusterAnalysisTemplateRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 129);
+
+/**
+ * explicitly empty 
+ *
+ * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse
+ */
+export type DeleteClusterAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse.
+ * Use `create(DeleteClusterAnalysisTemplateResponseSchema)` to create a new message.
+ */
+export const DeleteClusterAnalysisTemplateResponseSchema: GenMessage<DeleteClusterAnalysisTemplateResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 130);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest
@@ -2765,7 +2885,7 @@ export type GetAnalysisRunRequest = Message<"akuity.io.kargo.service.v1alpha1.Ge
  * Use `create(GetAnalysisRunRequestSchema)` to create a new message.
  */
 export const GetAnalysisRunRequestSchema: GenMessage<GetAnalysisRunRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 123);
+  messageDesc(file_api_service_v1alpha1_service, 131);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse
@@ -2794,7 +2914,7 @@ export type GetAnalysisRunResponse = Message<"akuity.io.kargo.service.v1alpha1.G
  * Use `create(GetAnalysisRunResponseSchema)` to create a new message.
  */
 export const GetAnalysisRunResponseSchema: GenMessage<GetAnalysisRunResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 124);
+  messageDesc(file_api_service_v1alpha1_service, 132);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsRequest
@@ -2826,7 +2946,7 @@ export type GetAnalysisRunLogsRequest = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(GetAnalysisRunLogsRequestSchema)` to create a new message.
  */
 export const GetAnalysisRunLogsRequestSchema: GenMessage<GetAnalysisRunLogsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 125);
+  messageDesc(file_api_service_v1alpha1_service, 133);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisRunLogsResponse
@@ -2843,110 +2963,212 @@ export type GetAnalysisRunLogsResponse = Message<"akuity.io.kargo.service.v1alph
  * Use `create(GetAnalysisRunLogsResponseSchema)` to create a new message.
  */
 export const GetAnalysisRunLogsResponseSchema: GenMessage<GetAnalysisRunLogsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 126);
+  messageDesc(file_api_service_v1alpha1_service, 134);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
  */
-export type DeleteAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest"> & {
+export type ListProjectEventsRequest = Message<"akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest"> & {
   /**
    * @generated from field: string project = 1;
    */
   project: string;
+};
 
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest.
+ * Use `create(ListProjectEventsRequestSchema)` to create a new message.
+ */
+export const ListProjectEventsRequestSchema: GenMessage<ListProjectEventsRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 135);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
+ */
+export type ListProjectEventsResponse = Message<"akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse"> & {
   /**
-   * @generated from field: string name = 2;
+   * @generated from field: repeated k8s.io.api.core.v1.Event events = 1;
    */
-  name: string;
+  events: Event[];
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest.
- * Use `create(DeleteAnalysisTemplateRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse.
+ * Use `create(ListProjectEventsResponseSchema)` to create a new message.
  */
-export const DeleteAnalysisTemplateRequestSchema: GenMessage<DeleteAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 127);
+export const ListProjectEventsResponseSchema: GenMessage<ListProjectEventsResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 136);
 
 /**
- * explicitly empty 
- *
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest
  */
-export type DeleteAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse"> & {
+export type ListPromotionTasksRequest = Message<"akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateResponse.
- * Use `create(DeleteAnalysisTemplateResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListPromotionTasksRequest.
+ * Use `create(ListPromotionTasksRequestSchema)` to create a new message.
  */
-export const DeleteAnalysisTemplateResponseSchema: GenMessage<DeleteAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 128);
+export const ListPromotionTasksRequestSchema: GenMessage<ListPromotionTasksRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 137);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse
  */
-export type DeleteClusterAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest"> & {
+export type ListPromotionTasksResponse = Message<"akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse"> & {
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_tasks = 1;
+   */
+  promotionTasks: PromotionTask[];
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListPromotionTasksResponse.
+ * Use `create(ListPromotionTasksResponseSchema)` to create a new message.
+ */
+export const ListPromotionTasksResponseSchema: GenMessage<ListPromotionTasksResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 138);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest
+ */
+export type GetPromotionTaskRequest = Message<"akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest"> & {
+  /**
+   * @generated from field: string project = 1;
+   */
+  project: string;
+
   /**
    * @generated from field: string name = 2;
    */
   name: string;
+
+  /**
+   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 3;
+   */
+  format: RawFormat;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest.
- * Use `create(DeleteClusterAnalysisTemplateRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetPromotionTaskRequest.
+ * Use `create(GetPromotionTaskRequestSchema)` to create a new message.
  */
-export const DeleteClusterAnalysisTemplateRequestSchema: GenMessage<DeleteClusterAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 129);
+export const GetPromotionTaskRequestSchema: GenMessage<GetPromotionTaskRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 139);
 
 /**
- * explicitly empty 
- *
- * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse
  */
-export type DeleteClusterAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse"> & {
+export type GetPromotionTaskResponse = Message<"akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse"> & {
+  /**
+   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse.result
+   */
+  result: {
+    /**
+     * @generated from field: github.com.akuity.kargo.api.v1alpha1.PromotionTask promotion_task = 1;
+     */
+    value: PromotionTask;
+    case: "promotionTask";
+  } | {
+    /**
+     * @generated from field: bytes raw = 2;
+     */
+    value: Uint8Array;
+    case: "raw";
+  } | { case: undefined; value?: undefined };
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateResponse.
- * Use `create(DeleteClusterAnalysisTemplateResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetPromotionTaskResponse.
+ * Use `create(GetPromotionTaskResponseSchema)` to create a new message.
  */
-export const DeleteClusterAnalysisTemplateResponseSchema: GenMessage<DeleteClusterAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 130);
+export const GetPromotionTaskResponseSchema: GenMessage<GetPromotionTaskResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 140);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest
  */
-export type ListProjectEventsRequest = Message<"akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest"> & {
+export type ListClusterPromotionTasksRequest = Message<"akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest"> & {
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksRequest.
+ * Use `create(ListClusterPromotionTasksRequestSchema)` to create a new message.
+ */
+export const ListClusterPromotionTasksRequestSchema: GenMessage<ListClusterPromotionTasksRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 141);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse
+ */
+export type ListClusterPromotionTasksResponse = Message<"akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse"> & {
   /**
-   * @generated from field: string project = 1;
+   * @generated from field: repeated github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask cluster_promotion_tasks = 1;
    */
-  project: string;
+  clusterPromotionTasks: ClusterPromotionTask[];
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest.
- * Use `create(ListProjectEventsRequestSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.ListClusterPromotionTasksResponse.
+ * Use `create(ListClusterPromotionTasksResponseSchema)` to create a new message.
  */
-export const ListProjectEventsRequestSchema: GenMessage<ListProjectEventsRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 131);
+export const ListClusterPromotionTasksResponseSchema: GenMessage<ListClusterPromotionTasksResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 142);
 
 /**
- * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest
  */
-export type ListProjectEventsResponse = Message<"akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse"> & {
+export type GetClusterPromotionTaskRequest = Message<"akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest"> & {
   /**
-   * @generated from field: repeated k8s.io.api.core.v1.Event events = 1;
+   * @generated from field: string name = 2;
    */
-  events: Event[];
+  name: string;
+
+  /**
+   * @generated from field: akuity.io.kargo.service.v1alpha1.RawFormat format = 3;
+   */
+  format: RawFormat;
 };
 
 /**
- * Describes the message akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse.
- * Use `create(ListProjectEventsResponseSchema)` to create a new message.
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskRequest.
+ * Use `create(GetClusterPromotionTaskRequestSchema)` to create a new message.
  */
-export const ListProjectEventsResponseSchema: GenMessage<ListProjectEventsResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 132);
+export const GetClusterPromotionTaskRequestSchema: GenMessage<GetClusterPromotionTaskRequest> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 143);
+
+/**
+ * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse
+ */
+export type GetClusterPromotionTaskResponse = Message<"akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse"> & {
+  /**
+   * @generated from oneof akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse.result
+   */
+  result: {
+    /**
+     * @generated from field: github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask promotion_task = 1 [json_name = "clusterPromotionTask"];
+     */
+    value: ClusterPromotionTask;
+    case: "promotionTask";
+  } | {
+    /**
+     * @generated from field: bytes raw = 2;
+     */
+    value: Uint8Array;
+    case: "raw";
+  } | { case: undefined; value?: undefined };
+};
+
+/**
+ * Describes the message akuity.io.kargo.service.v1alpha1.GetClusterPromotionTaskResponse.
+ * Use `create(GetClusterPromotionTaskResponseSchema)` to create a new message.
+ */
+export const GetClusterPromotionTaskResponseSchema: GenMessage<GetClusterPromotionTaskResponse> = /*@__PURE__*/
+  messageDesc(file_api_service_v1alpha1_service, 144);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateRoleRequest
@@ -2963,7 +3185,7 @@ export type CreateRoleRequest = Message<"akuity.io.kargo.service.v1alpha1.Create
  * Use `create(CreateRoleRequestSchema)` to create a new message.
  */
 export const CreateRoleRequestSchema: GenMessage<CreateRoleRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 133);
+  messageDesc(file_api_service_v1alpha1_service, 145);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateRoleResponse
@@ -2980,7 +3202,7 @@ export type CreateRoleResponse = Message<"akuity.io.kargo.service.v1alpha1.Creat
  * Use `create(CreateRoleResponseSchema)` to create a new message.
  */
 export const CreateRoleResponseSchema: GenMessage<CreateRoleResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 134);
+  messageDesc(file_api_service_v1alpha1_service, 146);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteRoleRequest
@@ -3002,7 +3224,7 @@ export type DeleteRoleRequest = Message<"akuity.io.kargo.service.v1alpha1.Delete
  * Use `create(DeleteRoleRequestSchema)` to create a new message.
  */
 export const DeleteRoleRequestSchema: GenMessage<DeleteRoleRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 135);
+  messageDesc(file_api_service_v1alpha1_service, 147);
 
 /**
  * explicitly empty 
@@ -3017,7 +3239,7 @@ export type DeleteRoleResponse = Message<"akuity.io.kargo.service.v1alpha1.Delet
  * Use `create(DeleteRoleResponseSchema)` to create a new message.
  */
 export const DeleteRoleResponseSchema: GenMessage<DeleteRoleResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 136);
+  messageDesc(file_api_service_v1alpha1_service, 148);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetRoleRequest
@@ -3049,7 +3271,7 @@ export type GetRoleRequest = Message<"akuity.io.kargo.service.v1alpha1.GetRoleRe
  * Use `create(GetRoleRequestSchema)` to create a new message.
  */
 export const GetRoleRequestSchema: GenMessage<GetRoleRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 137);
+  messageDesc(file_api_service_v1alpha1_service, 149);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetRoleResponse
@@ -3084,7 +3306,7 @@ export type GetRoleResponse = Message<"akuity.io.kargo.service.v1alpha1.GetRoleR
  * Use `create(GetRoleResponseSchema)` to create a new message.
  */
 export const GetRoleResponseSchema: GenMessage<GetRoleResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 138);
+  messageDesc(file_api_service_v1alpha1_service, 150);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.Claims
@@ -3103,7 +3325,7 @@ export type Claims = Message<"akuity.io.kargo.service.v1alpha1.Claims"> & {
  * Use `create(ClaimsSchema)` to create a new message.
  */
 export const ClaimsSchema: GenMessage<Claims> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 139);
+  messageDesc(file_api_service_v1alpha1_service, 151);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GrantRequest
@@ -3142,7 +3364,7 @@ export type GrantRequest = Message<"akuity.io.kargo.service.v1alpha1.GrantReques
  * Use `create(GrantRequestSchema)` to create a new message.
  */
 export const GrantRequestSchema: GenMessage<GrantRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 140);
+  messageDesc(file_api_service_v1alpha1_service, 152);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GrantResponse
@@ -3159,7 +3381,7 @@ export type GrantResponse = Message<"akuity.io.kargo.service.v1alpha1.GrantRespo
  * Use `create(GrantResponseSchema)` to create a new message.
  */
 export const GrantResponseSchema: GenMessage<GrantResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 141);
+  messageDesc(file_api_service_v1alpha1_service, 153);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListRolesRequest
@@ -3181,7 +3403,7 @@ export type ListRolesRequest = Message<"akuity.io.kargo.service.v1alpha1.ListRol
  * Use `create(ListRolesRequestSchema)` to create a new message.
  */
 export const ListRolesRequestSchema: GenMessage<ListRolesRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 142);
+  messageDesc(file_api_service_v1alpha1_service, 154);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListRolesResponse
@@ -3205,7 +3427,7 @@ export type ListRolesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListRo
  * Use `create(ListRolesResponseSchema)` to create a new message.
  */
 export const ListRolesResponseSchema: GenMessage<ListRolesResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 143);
+  messageDesc(file_api_service_v1alpha1_service, 155);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RevokeRequest
@@ -3244,7 +3466,7 @@ export type RevokeRequest = Message<"akuity.io.kargo.service.v1alpha1.RevokeRequ
  * Use `create(RevokeRequestSchema)` to create a new message.
  */
 export const RevokeRequestSchema: GenMessage<RevokeRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 144);
+  messageDesc(file_api_service_v1alpha1_service, 156);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RevokeResponse
@@ -3261,7 +3483,7 @@ export type RevokeResponse = Message<"akuity.io.kargo.service.v1alpha1.RevokeRes
  * Use `create(RevokeResponseSchema)` to create a new message.
  */
 export const RevokeResponseSchema: GenMessage<RevokeResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 145);
+  messageDesc(file_api_service_v1alpha1_service, 157);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateRoleRequest
@@ -3278,7 +3500,7 @@ export type UpdateRoleRequest = Message<"akuity.io.kargo.service.v1alpha1.Update
  * Use `create(UpdateRoleRequestSchema)` to create a new message.
  */
 export const UpdateRoleRequestSchema: GenMessage<UpdateRoleRequest> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 146);
+  messageDesc(file_api_service_v1alpha1_service, 158);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateRoleResponse
@@ -3295,7 +3517,7 @@ export type UpdateRoleResponse = Message<"akuity.io.kargo.service.v1alpha1.Updat
  * Use `create(UpdateRoleResponseSchema)` to create a new message.
  */
 export const UpdateRoleResponseSchema: GenMessage<UpdateRoleResponse> = /*@__PURE__*/
-  messageDesc(file_api_service_v1alpha1_service, 147);
+  messageDesc(file_api_service_v1alpha1_service, 159);
 
 /**
  * @generated from enum akuity.io.kargo.service.v1alpha1.RawFormat
@@ -3442,6 +3664,38 @@ export const KargoService: GenService<{
     input: typeof RefreshStageRequestSchema;
     output: typeof RefreshStageResponseSchema;
   },
+  /**
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.GetClusterConfig
+   */
+  getClusterConfig: {
+    methodKind: "unary";
+    input: typeof GetClusterConfigRequestSchema;
+    output: typeof GetClusterConfigResponseSchema;
+  },
+  /**
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.DeleteClusterConfig
+   */
+  deleteClusterConfig: {
+    methodKind: "unary";
+    input: typeof DeleteClusterConfigRequestSchema;
+    output: typeof DeleteClusterConfigResponseSchema;
+  },
+  /**
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.WatchClusterConfig
+   */
+  watchClusterConfig: {
+    methodKind: "server_streaming";
+    input: typeof WatchClusterConfigRequestSchema;
+    output: typeof WatchClusterConfigResponseSchema;
+  },
+  /**
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.RefreshClusterConfig
+   */
+  refreshClusterConfig: {
+    methodKind: "unary";
+    input: typeof RefreshClusterConfigRequestSchema;
+    output: typeof RefreshClusterConfigResponseSchema;
+  },
   /**
    * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.ListPromotions
    */
@@ -3506,6 +3760,16 @@ export const KargoService: GenService<{
     input: typeof ListProjectsRequestSchema;
     output: typeof ListProjectsResponseSchema;
   },
+  /**
+   * ProjectConfig APIs 
+   *
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig
+   */
+  getProjectConfig: {
+    methodKind: "unary";
+    input: typeof GetProjectConfigRequestSchema;
+    output: typeof GetProjectConfigResponseSchema;
+  },
   /**
    * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.DeleteProjectConfig
    */
@@ -3515,12 +3779,20 @@ export const KargoService: GenService<{
     output: typeof DeleteProjectConfigResponseSchema;
   },
   /**
-   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.GetProjectConfig
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.WatchProjectConfig
    */
-  getProjectConfig: {
+  watchProjectConfig: {
+    methodKind: "server_streaming";
+    input: typeof WatchProjectConfigRequestSchema;
+    output: typeof WatchProjectConfigResponseSchema;
+  },
+  /**
+   * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.RefreshProjectConfig
+   */
+  refreshProjectConfig: {
     methodKind: "unary";
-    input: typeof GetProjectConfigRequestSchema;
-    output: typeof GetProjectConfigResponseSchema;
+    input: typeof RefreshProjectConfigRequestSchema;
+    output: typeof RefreshProjectConfigResponseSchema;
   },
   /**
    * @generated from rpc akuity.io.kargo.service.v1alpha1.KargoService.ApproveFreight
diff --git a/ui/src/gen/api/v1alpha1/generated_pb.ts b/ui/src/gen/api/v1alpha1/generated_pb.ts
index 5235c871..a18ec3f9 100644
--- a/ui/src/gen/api/v1alpha1/generated_pb.ts
+++ b/ui/src/gen/api/v1alpha1/generated_pb.ts
@@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf";
  * Describes the file api/v1alpha1/generated.proto.
  */
 export const file_api_v1alpha1_generated: GenFile = /*@__PURE__*/
-  fileDesc("ChxhcGkvdjFhbHBoYTEvZ2VuZXJhdGVkLnByb3RvEiRnaXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEiMgoTQW5hbHlzaXNSdW5Bcmd1bWVudBIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJIrACChNBbmFseXNpc1J1bk1ldGFkYXRhElUKBmxhYmVscxgBIAMoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1bk1ldGFkYXRhLkxhYmVsc0VudHJ5El8KC2Fubm90YXRpb25zGAIgAygLMkouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuTWV0YWRhdGEuQW5ub3RhdGlvbnNFbnRyeRotCgtMYWJlbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGjIKEEFubm90YXRpb25zRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJGChRBbmFseXNpc1J1blJlZmVyZW5jZRIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRINCgVwaGFzZRgDIAEoCSI3ChlBbmFseXNpc1RlbXBsYXRlUmVmZXJlbmNlEgwKBG5hbWUYASABKAkSDAoEa2luZBgCIAEoCSJPCg1BcHByb3ZlZFN0YWdlEj4KCmFwcHJvdmVkQXQYASABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSI4ChVBcmdvQ0RBcHBIZWFsdGhTdGF0dXMSDgoGc3RhdHVzGAEgASgJEg8KB21lc3NhZ2UYAiABKAki1AEKD0FyZ29DREFwcFN0YXR1cxIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRJRCgxoZWFsdGhTdGF0dXMYAyABKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXJnb0NEQXBwSGVhbHRoU3RhdHVzEk0KCnN5bmNTdGF0dXMYBCABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXJnb0NEQXBwU3luY1N0YXR1cyJKChNBcmdvQ0RBcHBTeW5jU3RhdHVzEg4KBnN0YXR1cxgBIAEoCRIQCghyZXZpc2lvbhgCIAEoCRIRCglyZXZpc2lvbnMYAyADKAkiXQoeQml0YnVja2V0V2ViaG9va1JlY2VpdmVyQ29uZmlnEjsKCXNlY3JldFJlZhgBIAEoCzIoLms4cy5pby5hcGkuY29yZS52MS5Mb2NhbE9iamVjdFJlZmVyZW5jZSI3CgVDaGFydBIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoCSJhChRDaGFydERpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSGAoQc2VtdmVyQ29uc3RyYWludBgDIAEoCRIQCgh2ZXJzaW9ucxgEIAMoCSJkChFDaGFydFN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSGAoQc2VtdmVyQ29uc3RyYWludBgDIAEoCRIWCg5kaXNjb3ZlcnlMaW1pdBgEIAEoBSLlAQoNQ2x1c3RlckNvbmZpZxJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkUKBHNwZWMYAiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2x1c3RlckNvbmZpZ1NwZWMSSQoGc3RhdHVzGAMgASgLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJDb25maWdTdGF0dXMimQEKEUNsdXN0ZXJDb25maWdMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEkIKBWl0ZW1zGAIgAygLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJDb25maWciagoRQ2x1c3RlckNvbmZpZ1NwZWMSVQoQd2ViaG9va1JlY2VpdmVycxgBIAMoCzI7LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XZWJob29rUmVjZWl2ZXJDb25maWcisgEKE0NsdXN0ZXJDb25maWdTdGF0dXMSQwoKY29uZGl0aW9ucxgBIAMoCzIvLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5Db25kaXRpb24SVgoQd2ViaG9va1JlY2VpdmVycxgCIAMoCzI8LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XZWJob29rUmVjZWl2ZXJEZXRhaWxzIqEBChRDbHVzdGVyUHJvbW90aW9uVGFzaxJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkUKBHNwZWMYAiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFza1NwZWMipwEKGENsdXN0ZXJQcm9tb3Rpb25UYXNrTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRJJCgVpdGVtcxgCIAMoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DbHVzdGVyUHJvbW90aW9uVGFzayJJCgxDdXJyZW50U3RhZ2USOQoFc2luY2UYASABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSK2AgoTRGlzY292ZXJlZEFydGlmYWN0cxJACgxkaXNjb3ZlcmVkQXQYBCABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRJFCgNnaXQYASADKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuR2l0RGlzY292ZXJ5UmVzdWx0EkoKBmltYWdlcxgCIAMoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5JbWFnZURpc2NvdmVyeVJlc3VsdBJKCgZjaGFydHMYAyADKAsyOi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2hhcnREaXNjb3ZlcnlSZXN1bHQisAEKEERpc2NvdmVyZWRDb21taXQSCgoCaWQYASABKAkSDgoGYnJhbmNoGAIgASgJEgsKA3RhZxgDIAEoCRIPCgdzdWJqZWN0GAQgASgJEg4KBmF1dGhvchgFIAEoCRIRCgljb21taXR0ZXIYBiABKAkSPwoLY3JlYXRvckRhdGUYByABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSKkAgoYRGlzY292ZXJlZEltYWdlUmVmZXJlbmNlEgsKA3RhZxgBIAEoCRIOCgZkaWdlc3QYAiABKAkSZAoLYW5ub3RhdGlvbnMYBSADKAsyTy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRGlzY292ZXJlZEltYWdlUmVmZXJlbmNlLkFubm90YXRpb25zRW50cnkSEgoKZ2l0UmVwb1VSTBgDIAEoCRI9CgljcmVhdGVkQXQYBCABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRoyChBBbm5vdGF0aW9uc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiMQoSRXhwcmVzc2lvblZhcmlhYmxlEgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAkiogMKB0ZyZWlnaHQSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRINCgVhbGlhcxgHIAEoCRJDCgZvcmlnaW4YCSABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodE9yaWdpbhJACgdjb21taXRzGAMgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdENvbW1pdBI7CgZpbWFnZXMYBCADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2USOwoGY2hhcnRzGAUgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0EkMKBnN0YXR1cxgGIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzIq0CChFGcmVpZ2h0Q29sbGVjdGlvbhIKCgJpZBgDIAEoCRJRCgVpdGVtcxgBIAMoCzJCLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0Q29sbGVjdGlvbi5JdGVtc0VudHJ5ElMKE3ZlcmlmaWNhdGlvbkhpc3RvcnkYAiADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuVmVyaWZpY2F0aW9uSW5mbxpkCgpJdGVtc0VudHJ5EgsKA2tleRgBIAEoCRJFCgV2YWx1ZRgCIAEoCzI2LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0UmVmZXJlbmNlOgI4ASKNAQoLRnJlaWdodExpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESPAoFaXRlbXMYAiADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodCIrCg1GcmVpZ2h0T3JpZ2luEgwKBGtpbmQYASABKAkSDAoEbmFtZRgCIAEoCSKhAgoQRnJlaWdodFJlZmVyZW5jZRIMCgRuYW1lGAEgASgJEkMKBm9yaWdpbhgIIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0T3JpZ2luEkAKB2NvbW1pdHMYAiADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuR2l0Q29tbWl0EjsKBmltYWdlcxgDIAMoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5JbWFnZRI7CgZjaGFydHMYBCADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2hhcnQinAEKDkZyZWlnaHRSZXF1ZXN0EkMKBm9yaWdpbhgBIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0T3JpZ2luEkUKB3NvdXJjZXMYAiABKAsyNC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFNvdXJjZXMimAEKDkZyZWlnaHRTb3VyY2VzEg4KBmRpcmVjdBgBIAEoCBIOCgZzdGFnZXMYAiADKAkSSAoQcmVxdWlyZWRTb2FrVGltZRgDIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5EdXJhdGlvbhIcChRhdmFpbGFiaWxpdHlTdHJhdGVneRgEIAEoCSKdBgoNRnJlaWdodFN0YXR1cxJZCgtjdXJyZW50bHlJbhgDIAMoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzLkN1cnJlbnRseUluRW50cnkSVwoKdmVyaWZpZWRJbhgBIAMoCzJDLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzLlZlcmlmaWVkSW5FbnRyeRJZCgthcHByb3ZlZEZvchgCIAMoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzLkFwcHJvdmVkRm9yRW50cnkSUwoIbWV0YWRhdGEYBCADKAsyQS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5NZXRhZGF0YUVudHJ5GmYKEEN1cnJlbnRseUluRW50cnkSCwoDa2V5GAEgASgJEkEKBXZhbHVlGAIgASgLMjIuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkN1cnJlbnRTdGFnZToCOAEaZgoPVmVyaWZpZWRJbkVudHJ5EgsKA2tleRgBIAEoCRJCCgV2YWx1ZRgCIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5WZXJpZmllZFN0YWdlOgI4ARpnChBBcHByb3ZlZEZvckVudHJ5EgsKA2tleRgBIAEoCRJCCgV2YWx1ZRgCIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BcHByb3ZlZFN0YWdlOgI4ARpvCg1NZXRhZGF0YUVudHJ5EgsKA2tleRgBIAEoCRJNCgV2YWx1ZRgCIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT046AjgBInkKCUdpdENvbW1pdBIPCgdyZXBvVVJMGAEgASgJEgoKAmlkGAIgASgJEg4KBmJyYW5jaBgDIAEoCRILCgN0YWcYBCABKAkSDwoHbWVzc2FnZRgGIAEoCRIOCgZhdXRob3IYByABKAkSEQoJY29tbWl0dGVyGAggASgJIm4KEkdpdERpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEkcKB2NvbW1pdHMYAiADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRGlzY292ZXJlZENvbW1pdCJaChtHaXRIdWJXZWJob29rUmVjZWl2ZXJDb25maWcSOwoJc2VjcmV0UmVmGAEgASgLMiguazhzLmlvLmFwaS5jb3JlLnYxLkxvY2FsT2JqZWN0UmVmZXJlbmNlIloKG0dpdExhYldlYmhvb2tSZWNlaXZlckNvbmZpZxI7CglzZWNyZXRSZWYYASABKAsyKC5rOHMuaW8uYXBpLmNvcmUudjEuTG9jYWxPYmplY3RSZWZlcmVuY2UiqAIKD0dpdFN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEh8KF2NvbW1pdFNlbGVjdGlvblN0cmF0ZWd5GAIgASgJEg4KBmJyYW5jaBgDIAEoCRIVCg1zdHJpY3RTZW12ZXJzGAsgASgIEhgKEHNlbXZlckNvbnN0cmFpbnQYBCABKAkSEQoJYWxsb3dUYWdzGAUgASgJEhIKCmlnbm9yZVRhZ3MYBiADKAkSGAoQZXhwcmVzc2lvbkZpbHRlchgMIAEoCRIdChVpbnNlY3VyZVNraXBUTFNWZXJpZnkYByABKAgSFAoMaW5jbHVkZVBhdGhzGAggAygJEhQKDGV4Y2x1ZGVQYXRocxgJIAMoCRIWCg5kaXNjb3ZlcnlMaW1pdBgKIAEoBSLIAQoGSGVhbHRoEg4KBnN0YXR1cxgBIAEoCRIOCgZpc3N1ZXMYAiADKAkSTgoGY29uZmlnGAQgASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPThJOCgZvdXRwdXQYBSABKAsyPi5rOHMuaW8uYXBpZXh0ZW5zaW9uc19hcGlzZXJ2ZXIucGtnLmFwaXMuYXBpZXh0ZW5zaW9ucy52MS5KU09OIm8KD0hlYWx0aENoZWNrU3RlcBIMCgR1c2VzGAEgASgJEk4KBmNvbmZpZxgCIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04iHgoLSGVhbHRoU3RhdHMSDwoHaGVhbHRoeRgBIAEoAyLQAQoFSW1hZ2USDwoHcmVwb1VSTBgBIAEoCRISCgpnaXRSZXBvVVJMGAIgASgJEgsKA3RhZxgDIAEoCRIOCgZkaWdlc3QYBCABKAkSUQoLYW5ub3RhdGlvbnMYBSADKAsyPC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2UuQW5ub3RhdGlvbnNFbnRyeRoyChBBbm5vdGF0aW9uc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEijQEKFEltYWdlRGlzY292ZXJ5UmVzdWx0Eg8KB3JlcG9VUkwYASABKAkSEAoIcGxhdGZvcm0YAiABKAkSUgoKcmVmZXJlbmNlcxgDIAMoCzI+LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5EaXNjb3ZlcmVkSW1hZ2VSZWZlcmVuY2Ui+QEKEUltYWdlU3Vic2NyaXB0aW9uEg8KB3JlcG9VUkwYASABKAkSEgoKZ2l0UmVwb1VSTBgCIAEoCRIeChZpbWFnZVNlbGVjdGlvblN0cmF0ZWd5GAMgASgJEhUKDXN0cmljdFNlbXZlcnMYCiABKAgSGAoQc2VtdmVyQ29uc3RyYWludBgEIAEoCRIRCglhbGxvd1RhZ3MYBSABKAkSEgoKaWdub3JlVGFncxgGIAMoCRIQCghwbGF0Zm9ybRgHIAEoCRIdChVpbnNlY3VyZVNraXBUTFNWZXJpZnkYCCABKAgSFgoOZGlzY292ZXJ5TGltaXQYCSABKAUi2QEKB1Byb2plY3QSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJFCgRzcGVjGAIgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RDb25maWdTcGVjEkMKBnN0YXR1cxgDIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0U3RhdHVzIuUBCg1Qcm9qZWN0Q29uZmlnEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESRQoEc3BlYxgCIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0Q29uZmlnU3BlYxJJCgZzdGF0dXMYAyABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdENvbmZpZ1N0YXR1cyKZAQoRUHJvamVjdENvbmZpZ0xpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESQgoFaXRlbXMYAiADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdENvbmZpZyK1AQoRUHJvamVjdENvbmZpZ1NwZWMSUAoRcHJvbW90aW9uUG9saWNpZXMYASADKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uUG9saWN5Ek4KCXJlY2VpdmVycxgCIAMoCzI7LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XZWJob29rUmVjZWl2ZXJDb25maWciqwEKE1Byb2plY3RDb25maWdTdGF0dXMSQwoKY29uZGl0aW9ucxgBIAMoCzIvLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5Db25kaXRpb24STwoJcmVjZWl2ZXJzGAIgAygLMjwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldlYmhvb2tSZWNlaXZlckRldGFpbHMijQEKC1Byb2plY3RMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEjwKBWl0ZW1zGAIgAygLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3QimgEKDFByb2plY3RTdGF0cxJICgp3YXJlaG91c2VzGAEgASgLMjQuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVN0YXRzEkAKBnN0YWdlcxgCIAEoCzIwLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZVN0YXRzIpcBCg1Qcm9qZWN0U3RhdHVzEkMKCmNvbmRpdGlvbnMYAyADKAsyLy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuQ29uZGl0aW9uEkEKBXN0YXRzGAQgASgLMjIuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RTdGF0cyLZAQoJUHJvbW90aW9uEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESQQoEc3BlYxgCIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TcGVjEkUKBnN0YXR1cxgDIAEoCzI1LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGF0dXMikQEKDVByb21vdGlvbkxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESPgoFaXRlbXMYAiADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uIpQBCg9Qcm9tb3Rpb25Qb2xpY3kSDQoFc3RhZ2UYASABKAkSVAoNc3RhZ2VTZWxlY3RvchgDIAEoCzI9LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25Qb2xpY3lTZWxlY3RvchIcChRhdXRvUHJvbW90aW9uRW5hYmxlZBgCIAEoCCJzChdQcm9tb3Rpb25Qb2xpY3lTZWxlY3RvchIMCgRuYW1lGAEgASgJEkoKDWxhYmVsU2VsZWN0b3IYAiABKAsyMy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGFiZWxTZWxlY3RvciLyAQoSUHJvbW90aW9uUmVmZXJlbmNlEgwKBG5hbWUYASABKAkSRwoHZnJlaWdodBgCIAEoCzI2LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0UmVmZXJlbmNlEkUKBnN0YXR1cxgDIAEoCzI1LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGF0dXMSPgoKZmluaXNoZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIrsBCg1Qcm9tb3Rpb25TcGVjEg0KBXN0YWdlGAEgASgJEg8KB2ZyZWlnaHQYAiABKAkSRgoEdmFycxgEIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5FeHByZXNzaW9uVmFyaWFibGUSQgoFc3RlcHMYAyADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCK3BAoPUHJvbW90aW9uU3RhdHVzEhoKEmxhc3RIYW5kbGVkUmVmcmVzaBgEIAEoCRINCgVwaGFzZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEkcKB2ZyZWlnaHQYBSABKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlZmVyZW5jZRJSChFmcmVpZ2h0Q29sbGVjdGlvbhgHIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0Q29sbGVjdGlvbhJLCgxoZWFsdGhDaGVja3MYCCADKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSGVhbHRoQ2hlY2tTdGVwEj4KCmZpbmlzaGVkQXQYBiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRITCgtjdXJyZW50U3RlcBgJIAEoAxJaChVzdGVwRXhlY3V0aW9uTWV0YWRhdGEYCyADKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RlcEV4ZWN1dGlvbk1ldGFkYXRhEk0KBXN0YXRlGAogASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPTiL7AgoNUHJvbW90aW9uU3RlcBIMCgR1c2VzGAEgASgJEkoKBHRhc2sYBSABKAsyPC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFza1JlZmVyZW5jZRIKCgJhcxgCIAEoCRIKCgJpZhgHIAEoCRIXCg9jb250aW51ZU9uRXJyb3IYCCABKAgSRwoFcmV0cnkYBCABKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcFJldHJ5EkYKBHZhcnMYBiADKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRXhwcmVzc2lvblZhcmlhYmxlEk4KBmNvbmZpZxgDIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04ibQoSUHJvbW90aW9uU3RlcFJldHJ5Ej8KB3RpbWVvdXQYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SFgoOZXJyb3JUaHJlc2hvbGQYAiABKA0imgEKDVByb21vdGlvblRhc2sSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJFCgRzcGVjGAIgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2tTcGVjIpkBChFQcm9tb3Rpb25UYXNrTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRJCCgVpdGVtcxgCIAMoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UYXNrIjQKFlByb21vdGlvblRhc2tSZWZlcmVuY2USDAoEbmFtZRgBIAEoCRIMCgRraW5kGAIgASgJIp8BChFQcm9tb3Rpb25UYXNrU3BlYxJGCgR2YXJzGAEgAygLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkV4cHJlc3Npb25WYXJpYWJsZRJCCgVzdGVwcxgCIAMoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGVwIl4KEVByb21vdGlvblRlbXBsYXRlEkkKBHNwZWMYASABKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGVtcGxhdGVTcGVjIqMBChVQcm9tb3Rpb25UZW1wbGF0ZVNwZWMSRgoEdmFycxgCIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5FeHByZXNzaW9uVmFyaWFibGUSQgoFc3RlcHMYASADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCJYChlRdWF5V2ViaG9va1JlY2VpdmVyQ29uZmlnEjsKCXNlY3JldFJlZhgBIAEoCzIoLms4cy5pby5hcGkuY29yZS52MS5Mb2NhbE9iamVjdFJlZmVyZW5jZSLmAQoQUmVwb1N1YnNjcmlwdGlvbhJCCgNnaXQYASABKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuR2l0U3Vic2NyaXB0aW9uEkYKBWltYWdlGAIgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlU3Vic2NyaXB0aW9uEkYKBWNoYXJ0GAMgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0U3Vic2NyaXB0aW9uIs0BCgVTdGFnZRJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEj0KBHNwZWMYAiABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2VTcGVjEkEKBnN0YXR1cxgDIAEoCzIxLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZVN0YXR1cyKJAQoJU3RhZ2VMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEjoKBWl0ZW1zGAIgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlItACCglTdGFnZVNwZWMSDQoFc2hhcmQYBCABKAkSRgoEdmFycxgHIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5FeHByZXNzaW9uVmFyaWFibGUSTgoQcmVxdWVzdGVkRnJlaWdodBgFIAMoCzI0LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0UmVxdWVzdBJSChFwcm9tb3Rpb25UZW1wbGF0ZRgGIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UZW1wbGF0ZRJICgx2ZXJpZmljYXRpb24YAyABKAsyMi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuVmVyaWZpY2F0aW9uIl4KClN0YWdlU3RhdHMSDQoFY291bnQYAiABKAMSQQoGaGVhbHRoGAEgASgLMjEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkhlYWx0aFN0YXRzItYDCgtTdGFnZVN0YXR1cxJDCgpjb25kaXRpb25zGA0gAygLMi8uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkNvbmRpdGlvbhIaChJsYXN0SGFuZGxlZFJlZnJlc2gYCyABKAkSTwoOZnJlaWdodEhpc3RvcnkYBCADKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodENvbGxlY3Rpb24SFgoOZnJlaWdodFN1bW1hcnkYDCABKAkSPAoGaGVhbHRoGAggASgLMiwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkhlYWx0aBIaChJvYnNlcnZlZEdlbmVyYXRpb24YBiABKAMSUgoQY3VycmVudFByb21vdGlvbhgHIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25SZWZlcmVuY2USTwoNbGFzdFByb21vdGlvbhgKIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25SZWZlcmVuY2Ui8wEKFVN0ZXBFeGVjdXRpb25NZXRhZGF0YRINCgVhbGlhcxgBIAEoCRI9CglzdGFydGVkQXQYAiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRI+CgpmaW5pc2hlZEF0GAMgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSEgoKZXJyb3JDb3VudBgEIAEoDRIOCgZzdGF0dXMYBSABKAkSDwoHbWVzc2FnZRgGIAEoCRIXCg9jb250aW51ZU9uRXJyb3IYByABKAgiiwIKDFZlcmlmaWNhdGlvbhJaChFhbmFseXNpc1RlbXBsYXRlcxgBIAMoCzI/LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1RlbXBsYXRlUmVmZXJlbmNlElYKE2FuYWx5c2lzUnVuTWV0YWRhdGEYAiABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQW5hbHlzaXNSdW5NZXRhZGF0YRJHCgRhcmdzGAMgAygLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuQXJndW1lbnQinQIKEFZlcmlmaWNhdGlvbkluZm8SCgoCaWQYBCABKAkSDQoFYWN0b3IYByABKAkSPQoJc3RhcnRUaW1lGAUgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRJPCgthbmFseXNpc1J1bhgDIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1blJlZmVyZW5jZRI+CgpmaW5pc2hUaW1lGAYgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUilAEKDVZlcmlmaWVkU3RhZ2USPgoKdmVyaWZpZWRBdBgBIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEkMKC2xvbmdlc3RTb2FrGAIgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkR1cmF0aW9uItkBCglXYXJlaG91c2USQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJBCgRzcGVjGAIgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVNwZWMSRQoGc3RhdHVzGAMgASgLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVN0YXR1cyKRAQoNV2FyZWhvdXNlTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRI+CgVpdGVtcxgCIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2UizgEKDVdhcmVob3VzZVNwZWMSDQoFc2hhcmQYAiABKAkSQAoIaW50ZXJ2YWwYBCABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SHQoVZnJlaWdodENyZWF0aW9uUG9saWN5GAMgASgJEk0KDXN1YnNjcmlwdGlvbnMYASADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUmVwb1N1YnNjcmlwdGlvbiJiCg5XYXJlaG91c2VTdGF0cxINCgVjb3VudBgCIAEoAxJBCgZoZWFsdGgYASABKAsyMS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSGVhbHRoU3RhdHMi/QEKD1dhcmVob3VzZVN0YXR1cxJDCgpjb25kaXRpb25zGAkgAygLMi8uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkNvbmRpdGlvbhIaChJsYXN0SGFuZGxlZFJlZnJlc2gYBiABKAkSGgoSb2JzZXJ2ZWRHZW5lcmF0aW9uGAQgASgDEhUKDWxhc3RGcmVpZ2h0SUQYCCABKAkSVgoTZGlzY292ZXJlZEFydGlmYWN0cxgHIAEoCzI5LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5EaXNjb3ZlcmVkQXJ0aWZhY3RzIvMCChVXZWJob29rUmVjZWl2ZXJDb25maWcSDAoEbmFtZRgBIAEoCRJXCgliaXRidWNrZXQYBSABKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQml0YnVja2V0V2ViaG9va1JlY2VpdmVyQ29uZmlnElEKBmdpdGh1YhgCIAEoCzJBLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5HaXRIdWJXZWJob29rUmVjZWl2ZXJDb25maWcSUQoGZ2l0bGFiGAMgASgLMkEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdExhYldlYmhvb2tSZWNlaXZlckNvbmZpZxJNCgRxdWF5GAQgASgLMj8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlF1YXlXZWJob29rUmVjZWl2ZXJDb25maWciQQoWV2ViaG9va1JlY2VpdmVyRGV0YWlscxIMCgRuYW1lGAEgASgJEgwKBHBhdGgYAyABKAkSCwoDdXJsGAQgASgJQpcCCihjb20uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExQg5HZW5lcmF0ZWRQcm90b1ABWiRnaXRodWIuY29tL2FrdWl0eS9rYXJnby9hcGkvdjFhbHBoYTGiAgVHQ0FLQaoCJEdpdGh1Yi5Db20uQWt1aXR5LkthcmdvLkFwaS5WMWFscGhhMcoCJEdpdGh1YlxDb21cQWt1aXR5XEthcmdvXEFwaVxWMWFscGhhMeICMEdpdGh1YlxDb21cQWt1aXR5XEthcmdvXEFwaVxWMWFscGhhMVxHUEJNZXRhZGF0YeoCKUdpdGh1Yjo6Q29tOjpBa3VpdHk6OkthcmdvOjpBcGk6OlYxYWxwaGEx", [file_k8s_io_api_core_v1_generated, file_k8s_io_apiextensions_apiserver_pkg_apis_apiextensions_v1_generated, file_k8s_io_apimachinery_pkg_apis_meta_v1_generated, file_k8s_io_apimachinery_pkg_runtime_generated, file_k8s_io_apimachinery_pkg_runtime_schema_generated]);
+  fileDesc("ChxhcGkvdjFhbHBoYTEvZ2VuZXJhdGVkLnByb3RvEiRnaXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEiMgoTQW5hbHlzaXNSdW5Bcmd1bWVudBIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJIrACChNBbmFseXNpc1J1bk1ldGFkYXRhElUKBmxhYmVscxgBIAMoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1bk1ldGFkYXRhLkxhYmVsc0VudHJ5El8KC2Fubm90YXRpb25zGAIgAygLMkouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuTWV0YWRhdGEuQW5ub3RhdGlvbnNFbnRyeRotCgtMYWJlbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGjIKEEFubm90YXRpb25zRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJGChRBbmFseXNpc1J1blJlZmVyZW5jZRIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRINCgVwaGFzZRgDIAEoCSI3ChlBbmFseXNpc1RlbXBsYXRlUmVmZXJlbmNlEgwKBG5hbWUYASABKAkSDAoEa2luZBgCIAEoCSJPCg1BcHByb3ZlZFN0YWdlEj4KCmFwcHJvdmVkQXQYASABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSI4ChVBcmdvQ0RBcHBIZWFsdGhTdGF0dXMSDgoGc3RhdHVzGAEgASgJEg8KB21lc3NhZ2UYAiABKAki1AEKD0FyZ29DREFwcFN0YXR1cxIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRJRCgxoZWFsdGhTdGF0dXMYAyABKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXJnb0NEQXBwSGVhbHRoU3RhdHVzEk0KCnN5bmNTdGF0dXMYBCABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXJnb0NEQXBwU3luY1N0YXR1cyJKChNBcmdvQ0RBcHBTeW5jU3RhdHVzEg4KBnN0YXR1cxgBIAEoCRIQCghyZXZpc2lvbhgCIAEoCRIRCglyZXZpc2lvbnMYAyADKAkiXQoeQml0YnVja2V0V2ViaG9va1JlY2VpdmVyQ29uZmlnEjsKCXNlY3JldFJlZhgBIAEoCzIoLms4cy5pby5hcGkuY29yZS52MS5Mb2NhbE9iamVjdFJlZmVyZW5jZSI3CgVDaGFydBIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoCSJhChRDaGFydERpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSGAoQc2VtdmVyQ29uc3RyYWludBgDIAEoCRIQCgh2ZXJzaW9ucxgEIAMoCSJkChFDaGFydFN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSGAoQc2VtdmVyQ29uc3RyYWludBgDIAEoCRIWCg5kaXNjb3ZlcnlMaW1pdBgEIAEoBSLlAQoNQ2x1c3RlckNvbmZpZxJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkUKBHNwZWMYAiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2x1c3RlckNvbmZpZ1NwZWMSSQoGc3RhdHVzGAMgASgLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJDb25maWdTdGF0dXMimQEKEUNsdXN0ZXJDb25maWdMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEkIKBWl0ZW1zGAIgAygLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJDb25maWciagoRQ2x1c3RlckNvbmZpZ1NwZWMSVQoQd2ViaG9va1JlY2VpdmVycxgBIAMoCzI7LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XZWJob29rUmVjZWl2ZXJDb25maWci6gEKE0NsdXN0ZXJDb25maWdTdGF0dXMSQwoKY29uZGl0aW9ucxgBIAMoCzIvLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5Db25kaXRpb24SGgoSb2JzZXJ2ZWRHZW5lcmF0aW9uGAMgASgDEhoKEmxhc3RIYW5kbGVkUmVmcmVzaBgEIAEoCRJWChB3ZWJob29rUmVjZWl2ZXJzGAIgAygLMjwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldlYmhvb2tSZWNlaXZlckRldGFpbHMioQEKFENsdXN0ZXJQcm9tb3Rpb25UYXNrEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESRQoEc3BlYxgCIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UYXNrU3BlYyKnAQoYQ2x1c3RlclByb21vdGlvblRhc2tMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEkkKBWl0ZW1zGAIgAygLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJQcm9tb3Rpb25UYXNrIkkKDEN1cnJlbnRTdGFnZRI5CgVzaW5jZRgBIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIrYCChNEaXNjb3ZlcmVkQXJ0aWZhY3RzEkAKDGRpc2NvdmVyZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEkUKA2dpdBgBIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5HaXREaXNjb3ZlcnlSZXN1bHQSSgoGaW1hZ2VzGAIgAygLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlRGlzY292ZXJ5UmVzdWx0EkoKBmNoYXJ0cxgDIAMoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DaGFydERpc2NvdmVyeVJlc3VsdCKwAQoQRGlzY292ZXJlZENvbW1pdBIKCgJpZBgBIAEoCRIOCgZicmFuY2gYAiABKAkSCwoDdGFnGAMgASgJEg8KB3N1YmplY3QYBCABKAkSDgoGYXV0aG9yGAUgASgJEhEKCWNvbW1pdHRlchgGIAEoCRI/CgtjcmVhdG9yRGF0ZRgHIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIqQCChhEaXNjb3ZlcmVkSW1hZ2VSZWZlcmVuY2USCwoDdGFnGAEgASgJEg4KBmRpZ2VzdBgCIAEoCRJkCgthbm5vdGF0aW9ucxgFIAMoCzJPLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5EaXNjb3ZlcmVkSW1hZ2VSZWZlcmVuY2UuQW5ub3RhdGlvbnNFbnRyeRISCgpnaXRSZXBvVVJMGAMgASgJEj0KCWNyZWF0ZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lGjIKEEFubm90YXRpb25zRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJdCh5Eb2NrZXJIdWJXZWJob29rUmVjZWl2ZXJDb25maWcSOwoJc2VjcmV0UmVmGAEgASgLMiguazhzLmlvLmFwaS5jb3JlLnYxLkxvY2FsT2JqZWN0UmVmZXJlbmNlIjEKEkV4cHJlc3Npb25WYXJpYWJsZRIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJIqIDCgdGcmVpZ2h0EkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESDQoFYWxpYXMYByABKAkSQwoGb3JpZ2luGAkgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRPcmlnaW4SQAoHY29tbWl0cxgDIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5HaXRDb21taXQSOwoGaW1hZ2VzGAQgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlEjsKBmNoYXJ0cxgFIAMoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DaGFydBJDCgZzdGF0dXMYBiABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cyKtAgoRRnJlaWdodENvbGxlY3Rpb24SCgoCaWQYAyABKAkSUQoFaXRlbXMYASADKAsyQi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodENvbGxlY3Rpb24uSXRlbXNFbnRyeRJTChN2ZXJpZmljYXRpb25IaXN0b3J5GAIgAygLMjYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlZlcmlmaWNhdGlvbkluZm8aZAoKSXRlbXNFbnRyeRILCgNrZXkYASABKAkSRQoFdmFsdWUYAiABKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlZmVyZW5jZToCOAEijQEKC0ZyZWlnaHRMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEjwKBWl0ZW1zGAIgAygLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHQiKwoNRnJlaWdodE9yaWdpbhIMCgRraW5kGAEgASgJEgwKBG5hbWUYAiABKAkioQIKEEZyZWlnaHRSZWZlcmVuY2USDAoEbmFtZRgBIAEoCRJDCgZvcmlnaW4YCCABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodE9yaWdpbhJACgdjb21taXRzGAIgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdENvbW1pdBI7CgZpbWFnZXMYAyADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2USOwoGY2hhcnRzGAQgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0IpwBCg5GcmVpZ2h0UmVxdWVzdBJDCgZvcmlnaW4YASABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodE9yaWdpbhJFCgdzb3VyY2VzGAIgASgLMjQuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRTb3VyY2VzIpgBCg5GcmVpZ2h0U291cmNlcxIOCgZkaXJlY3QYASABKAgSDgoGc3RhZ2VzGAIgAygJEkgKEHJlcXVpcmVkU29ha1RpbWUYAyABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SHAoUYXZhaWxhYmlsaXR5U3RyYXRlZ3kYBCABKAkinQYKDUZyZWlnaHRTdGF0dXMSWQoLY3VycmVudGx5SW4YAyADKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5DdXJyZW50bHlJbkVudHJ5ElcKCnZlcmlmaWVkSW4YASADKAsyQy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5WZXJpZmllZEluRW50cnkSWQoLYXBwcm92ZWRGb3IYAiADKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5BcHByb3ZlZEZvckVudHJ5ElMKCG1ldGFkYXRhGAQgAygLMkEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRTdGF0dXMuTWV0YWRhdGFFbnRyeRpmChBDdXJyZW50bHlJbkVudHJ5EgsKA2tleRgBIAEoCRJBCgV2YWx1ZRgCIAEoCzIyLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DdXJyZW50U3RhZ2U6AjgBGmYKD1ZlcmlmaWVkSW5FbnRyeRILCgNrZXkYASABKAkSQgoFdmFsdWUYAiABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuVmVyaWZpZWRTdGFnZToCOAEaZwoQQXBwcm92ZWRGb3JFbnRyeRILCgNrZXkYASABKAkSQgoFdmFsdWUYAiABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXBwcm92ZWRTdGFnZToCOAEabwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSTQoFdmFsdWUYAiABKAsyPi5rOHMuaW8uYXBpZXh0ZW5zaW9uc19hcGlzZXJ2ZXIucGtnLmFwaXMuYXBpZXh0ZW5zaW9ucy52MS5KU09OOgI4ASJ5CglHaXRDb21taXQSDwoHcmVwb1VSTBgBIAEoCRIKCgJpZBgCIAEoCRIOCgZicmFuY2gYAyABKAkSCwoDdGFnGAQgASgJEg8KB21lc3NhZ2UYBiABKAkSDgoGYXV0aG9yGAcgASgJEhEKCWNvbW1pdHRlchgIIAEoCSJuChJHaXREaXNjb3ZlcnlSZXN1bHQSDwoHcmVwb1VSTBgBIAEoCRJHCgdjb21taXRzGAIgAygLMjYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkRpc2NvdmVyZWRDb21taXQiWgobR2l0SHViV2ViaG9va1JlY2VpdmVyQ29uZmlnEjsKCXNlY3JldFJlZhgBIAEoCzIoLms4cy5pby5hcGkuY29yZS52MS5Mb2NhbE9iamVjdFJlZmVyZW5jZSJaChtHaXRMYWJXZWJob29rUmVjZWl2ZXJDb25maWcSOwoJc2VjcmV0UmVmGAEgASgLMiguazhzLmlvLmFwaS5jb3JlLnYxLkxvY2FsT2JqZWN0UmVmZXJlbmNlIqgCCg9HaXRTdWJzY3JpcHRpb24SDwoHcmVwb1VSTBgBIAEoCRIfChdjb21taXRTZWxlY3Rpb25TdHJhdGVneRgCIAEoCRIOCgZicmFuY2gYAyABKAkSFQoNc3RyaWN0U2VtdmVycxgLIAEoCBIYChBzZW12ZXJDb25zdHJhaW50GAQgASgJEhEKCWFsbG93VGFncxgFIAEoCRISCgppZ25vcmVUYWdzGAYgAygJEhgKEGV4cHJlc3Npb25GaWx0ZXIYDCABKAkSHQoVaW5zZWN1cmVTa2lwVExTVmVyaWZ5GAcgASgIEhQKDGluY2x1ZGVQYXRocxgIIAMoCRIUCgxleGNsdWRlUGF0aHMYCSADKAkSFgoOZGlzY292ZXJ5TGltaXQYCiABKAUiyAEKBkhlYWx0aBIOCgZzdGF0dXMYASABKAkSDgoGaXNzdWVzGAIgAygJEk4KBmNvbmZpZxgEIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04STgoGb3V0cHV0GAUgASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPTiJvCg9IZWFsdGhDaGVja1N0ZXASDAoEdXNlcxgBIAEoCRJOCgZjb25maWcYAiABKAsyPi5rOHMuaW8uYXBpZXh0ZW5zaW9uc19hcGlzZXJ2ZXIucGtnLmFwaXMuYXBpZXh0ZW5zaW9ucy52MS5KU09OIh4KC0hlYWx0aFN0YXRzEg8KB2hlYWx0aHkYASABKAMi0AEKBUltYWdlEg8KB3JlcG9VUkwYASABKAkSEgoKZ2l0UmVwb1VSTBgCIAEoCRILCgN0YWcYAyABKAkSDgoGZGlnZXN0GAQgASgJElEKC2Fubm90YXRpb25zGAUgAygLMjwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlLkFubm90YXRpb25zRW50cnkaMgoQQW5ub3RhdGlvbnNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIo0BChRJbWFnZURpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEhAKCHBsYXRmb3JtGAIgASgJElIKCnJlZmVyZW5jZXMYAyADKAsyPi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRGlzY292ZXJlZEltYWdlUmVmZXJlbmNlIvkBChFJbWFnZVN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEhIKCmdpdFJlcG9VUkwYAiABKAkSHgoWaW1hZ2VTZWxlY3Rpb25TdHJhdGVneRgDIAEoCRIVCg1zdHJpY3RTZW12ZXJzGAogASgIEhgKEHNlbXZlckNvbnN0cmFpbnQYBCABKAkSEQoJYWxsb3dUYWdzGAUgASgJEhIKCmlnbm9yZVRhZ3MYBiADKAkSEAoIcGxhdGZvcm0YByABKAkSHQoVaW5zZWN1cmVTa2lwVExTVmVyaWZ5GAggASgIEhYKDmRpc2NvdmVyeUxpbWl0GAkgASgFItkBCgdQcm9qZWN0EkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESRQoEc3BlYxgCIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0Q29uZmlnU3BlYxJDCgZzdGF0dXMYAyABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdFN0YXR1cyLlAQoNUHJvamVjdENvbmZpZxJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkUKBHNwZWMYAiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdENvbmZpZ1NwZWMSSQoGc3RhdHVzGAMgASgLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RDb25maWdTdGF0dXMimQEKEVByb2plY3RDb25maWdMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEkIKBWl0ZW1zGAIgAygLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RDb25maWcitQEKEVByb2plY3RDb25maWdTcGVjElAKEXByb21vdGlvblBvbGljaWVzGAEgAygLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblBvbGljeRJOCglyZWNlaXZlcnMYAiADKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2ViaG9va1JlY2VpdmVyQ29uZmlnIuMBChNQcm9qZWN0Q29uZmlnU3RhdHVzEkMKCmNvbmRpdGlvbnMYASADKAsyLy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuQ29uZGl0aW9uEhoKEm9ic2VydmVkR2VuZXJhdGlvbhgDIAEoAxIaChJsYXN0SGFuZGxlZFJlZnJlc2gYBCABKAkSTwoJcmVjZWl2ZXJzGAIgAygLMjwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldlYmhvb2tSZWNlaXZlckRldGFpbHMijQEKC1Byb2plY3RMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEjwKBWl0ZW1zGAIgAygLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3QimgEKDFByb2plY3RTdGF0cxJICgp3YXJlaG91c2VzGAEgASgLMjQuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVN0YXRzEkAKBnN0YWdlcxgCIAEoCzIwLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZVN0YXRzIpcBCg1Qcm9qZWN0U3RhdHVzEkMKCmNvbmRpdGlvbnMYAyADKAsyLy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuQ29uZGl0aW9uEkEKBXN0YXRzGAQgASgLMjIuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RTdGF0cyLZAQoJUHJvbW90aW9uEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESQQoEc3BlYxgCIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TcGVjEkUKBnN0YXR1cxgDIAEoCzI1LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGF0dXMikQEKDVByb21vdGlvbkxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESPgoFaXRlbXMYAiADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uIpQBCg9Qcm9tb3Rpb25Qb2xpY3kSDQoFc3RhZ2UYASABKAkSVAoNc3RhZ2VTZWxlY3RvchgDIAEoCzI9LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25Qb2xpY3lTZWxlY3RvchIcChRhdXRvUHJvbW90aW9uRW5hYmxlZBgCIAEoCCJzChdQcm9tb3Rpb25Qb2xpY3lTZWxlY3RvchIMCgRuYW1lGAEgASgJEkoKDWxhYmVsU2VsZWN0b3IYAiABKAsyMy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGFiZWxTZWxlY3RvciLyAQoSUHJvbW90aW9uUmVmZXJlbmNlEgwKBG5hbWUYASABKAkSRwoHZnJlaWdodBgCIAEoCzI2LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0UmVmZXJlbmNlEkUKBnN0YXR1cxgDIAEoCzI1LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGF0dXMSPgoKZmluaXNoZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIrsBCg1Qcm9tb3Rpb25TcGVjEg0KBXN0YWdlGAEgASgJEg8KB2ZyZWlnaHQYAiABKAkSRgoEdmFycxgEIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5FeHByZXNzaW9uVmFyaWFibGUSQgoFc3RlcHMYAyADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCK3BAoPUHJvbW90aW9uU3RhdHVzEhoKEmxhc3RIYW5kbGVkUmVmcmVzaBgEIAEoCRINCgVwaGFzZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEkcKB2ZyZWlnaHQYBSABKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlZmVyZW5jZRJSChFmcmVpZ2h0Q29sbGVjdGlvbhgHIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0Q29sbGVjdGlvbhJLCgxoZWFsdGhDaGVja3MYCCADKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSGVhbHRoQ2hlY2tTdGVwEj4KCmZpbmlzaGVkQXQYBiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRITCgtjdXJyZW50U3RlcBgJIAEoAxJaChVzdGVwRXhlY3V0aW9uTWV0YWRhdGEYCyADKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RlcEV4ZWN1dGlvbk1ldGFkYXRhEk0KBXN0YXRlGAogASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPTiL7AgoNUHJvbW90aW9uU3RlcBIMCgR1c2VzGAEgASgJEkoKBHRhc2sYBSABKAsyPC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFza1JlZmVyZW5jZRIKCgJhcxgCIAEoCRIKCgJpZhgHIAEoCRIXCg9jb250aW51ZU9uRXJyb3IYCCABKAgSRwoFcmV0cnkYBCABKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcFJldHJ5EkYKBHZhcnMYBiADKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRXhwcmVzc2lvblZhcmlhYmxlEk4KBmNvbmZpZxgDIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04ibQoSUHJvbW90aW9uU3RlcFJldHJ5Ej8KB3RpbWVvdXQYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SFgoOZXJyb3JUaHJlc2hvbGQYAiABKA0imgEKDVByb21vdGlvblRhc2sSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJFCgRzcGVjGAIgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2tTcGVjIpkBChFQcm9tb3Rpb25UYXNrTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRJCCgVpdGVtcxgCIAMoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UYXNrIjQKFlByb21vdGlvblRhc2tSZWZlcmVuY2USDAoEbmFtZRgBIAEoCRIMCgRraW5kGAIgASgJIp8BChFQcm9tb3Rpb25UYXNrU3BlYxJGCgR2YXJzGAEgAygLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkV4cHJlc3Npb25WYXJpYWJsZRJCCgVzdGVwcxgCIAMoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGVwIl4KEVByb21vdGlvblRlbXBsYXRlEkkKBHNwZWMYASABKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGVtcGxhdGVTcGVjIqMBChVQcm9tb3Rpb25UZW1wbGF0ZVNwZWMSRgoEdmFycxgCIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5FeHByZXNzaW9uVmFyaWFibGUSQgoFc3RlcHMYASADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCJYChlRdWF5V2ViaG9va1JlY2VpdmVyQ29uZmlnEjsKCXNlY3JldFJlZhgBIAEoCzIoLms4cy5pby5hcGkuY29yZS52MS5Mb2NhbE9iamVjdFJlZmVyZW5jZSLmAQoQUmVwb1N1YnNjcmlwdGlvbhJCCgNnaXQYASABKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuR2l0U3Vic2NyaXB0aW9uEkYKBWltYWdlGAIgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlU3Vic2NyaXB0aW9uEkYKBWNoYXJ0GAMgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0U3Vic2NyaXB0aW9uIs0BCgVTdGFnZRJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEj0KBHNwZWMYAiABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2VTcGVjEkEKBnN0YXR1cxgDIAEoCzIxLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZVN0YXR1cyKJAQoJU3RhZ2VMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEjoKBWl0ZW1zGAIgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlItACCglTdGFnZVNwZWMSDQoFc2hhcmQYBCABKAkSRgoEdmFycxgHIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5FeHByZXNzaW9uVmFyaWFibGUSTgoQcmVxdWVzdGVkRnJlaWdodBgFIAMoCzI0LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0UmVxdWVzdBJSChFwcm9tb3Rpb25UZW1wbGF0ZRgGIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UZW1wbGF0ZRJICgx2ZXJpZmljYXRpb24YAyABKAsyMi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuVmVyaWZpY2F0aW9uIl4KClN0YWdlU3RhdHMSDQoFY291bnQYAiABKAMSQQoGaGVhbHRoGAEgASgLMjEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkhlYWx0aFN0YXRzItYDCgtTdGFnZVN0YXR1cxJDCgpjb25kaXRpb25zGA0gAygLMi8uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkNvbmRpdGlvbhIaChJsYXN0SGFuZGxlZFJlZnJlc2gYCyABKAkSTwoOZnJlaWdodEhpc3RvcnkYBCADKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodENvbGxlY3Rpb24SFgoOZnJlaWdodFN1bW1hcnkYDCABKAkSPAoGaGVhbHRoGAggASgLMiwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkhlYWx0aBIaChJvYnNlcnZlZEdlbmVyYXRpb24YBiABKAMSUgoQY3VycmVudFByb21vdGlvbhgHIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25SZWZlcmVuY2USTwoNbGFzdFByb21vdGlvbhgKIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25SZWZlcmVuY2Ui8wEKFVN0ZXBFeGVjdXRpb25NZXRhZGF0YRINCgVhbGlhcxgBIAEoCRI9CglzdGFydGVkQXQYAiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRI+CgpmaW5pc2hlZEF0GAMgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSEgoKZXJyb3JDb3VudBgEIAEoDRIOCgZzdGF0dXMYBSABKAkSDwoHbWVzc2FnZRgGIAEoCRIXCg9jb250aW51ZU9uRXJyb3IYByABKAgiiwIKDFZlcmlmaWNhdGlvbhJaChFhbmFseXNpc1RlbXBsYXRlcxgBIAMoCzI/LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1RlbXBsYXRlUmVmZXJlbmNlElYKE2FuYWx5c2lzUnVuTWV0YWRhdGEYAiABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQW5hbHlzaXNSdW5NZXRhZGF0YRJHCgRhcmdzGAMgAygLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuQXJndW1lbnQinQIKEFZlcmlmaWNhdGlvbkluZm8SCgoCaWQYBCABKAkSDQoFYWN0b3IYByABKAkSPQoJc3RhcnRUaW1lGAUgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRJPCgthbmFseXNpc1J1bhgDIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1blJlZmVyZW5jZRI+CgpmaW5pc2hUaW1lGAYgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUilAEKDVZlcmlmaWVkU3RhZ2USPgoKdmVyaWZpZWRBdBgBIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEkMKC2xvbmdlc3RTb2FrGAIgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkR1cmF0aW9uItkBCglXYXJlaG91c2USQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJBCgRzcGVjGAIgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVNwZWMSRQoGc3RhdHVzGAMgASgLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVN0YXR1cyKRAQoNV2FyZWhvdXNlTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRI+CgVpdGVtcxgCIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2UizgEKDVdhcmVob3VzZVNwZWMSDQoFc2hhcmQYAiABKAkSQAoIaW50ZXJ2YWwYBCABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SHQoVZnJlaWdodENyZWF0aW9uUG9saWN5GAMgASgJEk0KDXN1YnNjcmlwdGlvbnMYASADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUmVwb1N1YnNjcmlwdGlvbiJiCg5XYXJlaG91c2VTdGF0cxINCgVjb3VudBgCIAEoAxJBCgZoZWFsdGgYASABKAsyMS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSGVhbHRoU3RhdHMi/QEKD1dhcmVob3VzZVN0YXR1cxJDCgpjb25kaXRpb25zGAkgAygLMi8uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkNvbmRpdGlvbhIaChJsYXN0SGFuZGxlZFJlZnJlc2gYBiABKAkSGgoSb2JzZXJ2ZWRHZW5lcmF0aW9uGAQgASgDEhUKDWxhc3RGcmVpZ2h0SUQYCCABKAkSVgoTZGlzY292ZXJlZEFydGlmYWN0cxgHIAEoCzI5LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5EaXNjb3ZlcmVkQXJ0aWZhY3RzIswDChVXZWJob29rUmVjZWl2ZXJDb25maWcSDAoEbmFtZRgBIAEoCRJXCgliaXRidWNrZXQYBSABKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQml0YnVja2V0V2ViaG9va1JlY2VpdmVyQ29uZmlnElcKCWRvY2tlcmh1YhgGIAEoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Eb2NrZXJIdWJXZWJob29rUmVjZWl2ZXJDb25maWcSUQoGZ2l0aHViGAIgASgLMkEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdEh1YldlYmhvb2tSZWNlaXZlckNvbmZpZxJRCgZnaXRsYWIYAyABKAsyQS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuR2l0TGFiV2ViaG9va1JlY2VpdmVyQ29uZmlnEk0KBHF1YXkYBCABKAsyPy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUXVheVdlYmhvb2tSZWNlaXZlckNvbmZpZyJBChZXZWJob29rUmVjZWl2ZXJEZXRhaWxzEgwKBG5hbWUYASABKAkSDAoEcGF0aBgDIAEoCRILCgN1cmwYBCABKAlClwIKKGNvbS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTFCDkdlbmVyYXRlZFByb3RvUAFaJGdpdGh1Yi5jb20vYWt1aXR5L2thcmdvL2FwaS92MWFscGhhMaICBUdDQUtBqgIkR2l0aHViLkNvbS5Ba3VpdHkuS2FyZ28uQXBpLlYxYWxwaGExygIkR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFYxYWxwaGEx4gIwR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFYxYWxwaGExXEdQQk1ldGFkYXRh6gIpR2l0aHViOjpDb206OkFrdWl0eTo6S2FyZ286OkFwaTo6VjFhbHBoYTE", [file_k8s_io_api_core_v1_generated, file_k8s_io_apiextensions_apiserver_pkg_apis_apiextensions_v1_generated, file_k8s_io_apimachinery_pkg_apis_meta_v1_generated, file_k8s_io_apimachinery_pkg_runtime_generated, file_k8s_io_apimachinery_pkg_runtime_schema_generated]);
 
 /**
  * AnalysisRunArgument represents an argument to be added to an AnalysisRun.
@@ -568,6 +568,24 @@ export type ClusterConfigStatus = Message<"github.com.akuity.kargo.api.v1alpha1.
    */
   conditions: Condition[];
 
+  /**
+   * ObservedGeneration represents the .metadata.generation that this
+   * ClusterConfig was reconciled against.
+   *
+   * @generated from field: optional int64 observedGeneration = 3;
+   */
+  observedGeneration: bigint;
+
+  /**
+   * LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+   * annotation that was handled by the controller. This field can be used to
+   * determine whether the request to refresh the resource has been handled.
+   * +optional
+   *
+   * @generated from field: optional string lastHandledRefresh = 4;
+   */
+  lastHandledRefresh: string;
+
   /**
    * WebhookReceivers describes the status of cluster-scoped webhook receivers.
    *
@@ -847,6 +865,39 @@ export type DiscoveredImageReference = Message<"github.com.akuity.kargo.api.v1al
 export const DiscoveredImageReferenceSchema: GenMessage<DiscoveredImageReference> = /*@__PURE__*/
   messageDesc(file_api_v1alpha1_generated, 21);
 
+/**
+ * DockerHubWebhookReceiverConfig describes a webhook receiver that is
+ * compatible with Docker Hub payloads.
+ *
+ * @generated from message github.com.akuity.kargo.api.v1alpha1.DockerHubWebhookReceiverConfig
+ */
+export type DockerHubWebhookReceiverConfig = Message<"github.com.akuity.kargo.api.v1alpha1.DockerHubWebhookReceiverConfig"> & {
+  /**
+   * SecretRef contains a reference to a Secret. For Project-scoped webhook
+   * receivers, the referenced Secret must be in the same namespace as the
+   * ProjectConfig.
+   *
+   * The Secret's data map is expected to contain a `secret` key whose value
+   * does NOT need to be shared directly with Docker Hub when registering a
+   * webhook. It is used only by Kargo to create a complex, hard-to-guess URL,
+   * which implicitly serves as a shared secret. For more information about
+   * Docker Hub webhooks, please refer to the Docker documentation:
+   *   https://docs.docker.com/docker-hub/webhooks/
+   *
+   * +kubebuilder:validation:Required
+   *
+   * @generated from field: optional k8s.io.api.core.v1.LocalObjectReference secretRef = 1;
+   */
+  secretRef?: LocalObjectReference;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.v1alpha1.DockerHubWebhookReceiverConfig.
+ * Use `create(DockerHubWebhookReceiverConfigSchema)` to create a new message.
+ */
+export const DockerHubWebhookReceiverConfigSchema: GenMessage<DockerHubWebhookReceiverConfig> = /*@__PURE__*/
+  messageDesc(file_api_v1alpha1_generated, 22);
+
 /**
  * ExpressionVariable describes a single variable that may be referenced by
  * expressions in the context of a ClusterPromotionTask, PromotionTask,
@@ -883,7 +934,7 @@ export type ExpressionVariable = Message<"github.com.akuity.kargo.api.v1alpha1.E
  * Use `create(ExpressionVariableSchema)` to create a new message.
  */
 export const ExpressionVariableSchema: GenMessage<ExpressionVariable> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 22);
+  messageDesc(file_api_v1alpha1_generated, 23);
 
 /**
  * Freight represents a collection of versioned artifacts.
@@ -954,7 +1005,7 @@ export type Freight = Message<"github.com.akuity.kargo.api.v1alpha1.Freight"> &
  * Use `create(FreightSchema)` to create a new message.
  */
 export const FreightSchema: GenMessage<Freight> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 23);
+  messageDesc(file_api_v1alpha1_generated, 24);
 
 /**
  * FreightCollection is a collection of FreightReferences, each of which
@@ -994,7 +1045,7 @@ export type FreightCollection = Message<"github.com.akuity.kargo.api.v1alpha1.Fr
  * Use `create(FreightCollectionSchema)` to create a new message.
  */
 export const FreightCollectionSchema: GenMessage<FreightCollection> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 24);
+  messageDesc(file_api_v1alpha1_generated, 25);
 
 /**
  * FreightList is a list of Freight resources.
@@ -1018,7 +1069,7 @@ export type FreightList = Message<"github.com.akuity.kargo.api.v1alpha1.FreightL
  * Use `create(FreightListSchema)` to create a new message.
  */
 export const FreightListSchema: GenMessage<FreightList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 25);
+  messageDesc(file_api_v1alpha1_generated, 26);
 
 /**
  * FreightOrigin describes a kind of Freight in terms of where it may have
@@ -1055,7 +1106,7 @@ export type FreightOrigin = Message<"github.com.akuity.kargo.api.v1alpha1.Freigh
  * Use `create(FreightOriginSchema)` to create a new message.
  */
 export const FreightOriginSchema: GenMessage<FreightOrigin> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 26);
+  messageDesc(file_api_v1alpha1_generated, 27);
 
 /**
  * FreightReference is a simplified representation of a piece of Freight -- not
@@ -1107,7 +1158,7 @@ export type FreightReference = Message<"github.com.akuity.kargo.api.v1alpha1.Fre
  * Use `create(FreightReferenceSchema)` to create a new message.
  */
 export const FreightReferenceSchema: GenMessage<FreightReference> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 27);
+  messageDesc(file_api_v1alpha1_generated, 28);
 
 /**
  * FreightRequest expresses a Stage's need for Freight having originated from a
@@ -1140,7 +1191,7 @@ export type FreightRequest = Message<"github.com.akuity.kargo.api.v1alpha1.Freig
  * Use `create(FreightRequestSchema)` to create a new message.
  */
 export const FreightRequestSchema: GenMessage<FreightRequest> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 28);
+  messageDesc(file_api_v1alpha1_generated, 29);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.FreightSources
@@ -1209,7 +1260,7 @@ export type FreightSources = Message<"github.com.akuity.kargo.api.v1alpha1.Freig
  * Use `create(FreightSourcesSchema)` to create a new message.
  */
 export const FreightSourcesSchema: GenMessage<FreightSources> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 29);
+  messageDesc(file_api_v1alpha1_generated, 30);
 
 /**
  * FreightStatus describes a piece of Freight's most recently observed state.
@@ -1257,7 +1308,7 @@ export type FreightStatus = Message<"github.com.akuity.kargo.api.v1alpha1.Freigh
  * Use `create(FreightStatusSchema)` to create a new message.
  */
 export const FreightStatusSchema: GenMessage<FreightStatus> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 30);
+  messageDesc(file_api_v1alpha1_generated, 31);
 
 /**
  * GitCommit describes a specific commit from a specific Git repository.
@@ -1323,7 +1374,7 @@ export type GitCommit = Message<"github.com.akuity.kargo.api.v1alpha1.GitCommit"
  * Use `create(GitCommitSchema)` to create a new message.
  */
 export const GitCommitSchema: GenMessage<GitCommit> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 31);
+  messageDesc(file_api_v1alpha1_generated, 32);
 
 /**
  * GitDiscoveryResult represents the result of a Git discovery operation for a
@@ -1360,7 +1411,7 @@ export type GitDiscoveryResult = Message<"github.com.akuity.kargo.api.v1alpha1.G
  * Use `create(GitDiscoveryResultSchema)` to create a new message.
  */
 export const GitDiscoveryResultSchema: GenMessage<GitDiscoveryResult> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 32);
+  messageDesc(file_api_v1alpha1_generated, 33);
 
 /**
  * GitHubWebhookReceiverConfig describes a webhook receiver that is compatible
@@ -1394,7 +1445,7 @@ export type GitHubWebhookReceiverConfig = Message<"github.com.akuity.kargo.api.v
  * Use `create(GitHubWebhookReceiverConfigSchema)` to create a new message.
  */
 export const GitHubWebhookReceiverConfigSchema: GenMessage<GitHubWebhookReceiverConfig> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 33);
+  messageDesc(file_api_v1alpha1_generated, 34);
 
 /**
  * GitLabWebhookReceiverConfig describes a webhook receiver that is compatible
@@ -1428,7 +1479,7 @@ export type GitLabWebhookReceiverConfig = Message<"github.com.akuity.kargo.api.v
  * Use `create(GitLabWebhookReceiverConfigSchema)` to create a new message.
  */
 export const GitLabWebhookReceiverConfigSchema: GenMessage<GitLabWebhookReceiverConfig> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 34);
+  messageDesc(file_api_v1alpha1_generated, 35);
 
 /**
  * GitSubscription defines a subscription to a Git repository.
@@ -1671,7 +1722,7 @@ export type GitSubscription = Message<"github.com.akuity.kargo.api.v1alpha1.GitS
  * Use `create(GitSubscriptionSchema)` to create a new message.
  */
 export const GitSubscriptionSchema: GenMessage<GitSubscription> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 35);
+  messageDesc(file_api_v1alpha1_generated, 36);
 
 /**
  * Health describes the health of a Stage.
@@ -1715,7 +1766,7 @@ export type Health = Message<"github.com.akuity.kargo.api.v1alpha1.Health"> & {
  * Use `create(HealthSchema)` to create a new message.
  */
 export const HealthSchema: GenMessage<Health> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 36);
+  messageDesc(file_api_v1alpha1_generated, 37);
 
 /**
  * HealthCheckStep describes a health check directive which can be executed by
@@ -1746,7 +1797,7 @@ export type HealthCheckStep = Message<"github.com.akuity.kargo.api.v1alpha1.Heal
  * Use `create(HealthCheckStepSchema)` to create a new message.
  */
 export const HealthCheckStepSchema: GenMessage<HealthCheckStep> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 37);
+  messageDesc(file_api_v1alpha1_generated, 38);
 
 /**
  * HealthStats contains a summary of the collective health of some resource
@@ -1768,7 +1819,7 @@ export type HealthStats = Message<"github.com.akuity.kargo.api.v1alpha1.HealthSt
  * Use `create(HealthStatsSchema)` to create a new message.
  */
 export const HealthStatsSchema: GenMessage<HealthStats> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 38);
+  messageDesc(file_api_v1alpha1_generated, 39);
 
 /**
  * Image describes a specific version of a container image.
@@ -1823,7 +1874,7 @@ export type Image = Message<"github.com.akuity.kargo.api.v1alpha1.Image"> & {
  * Use `create(ImageSchema)` to create a new message.
  */
 export const ImageSchema: GenMessage<Image> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 39);
+  messageDesc(file_api_v1alpha1_generated, 40);
 
 /**
  * ImageDiscoveryResult represents the result of an image discovery operation
@@ -1869,7 +1920,7 @@ export type ImageDiscoveryResult = Message<"github.com.akuity.kargo.api.v1alpha1
  * Use `create(ImageDiscoveryResultSchema)` to create a new message.
  */
 export const ImageDiscoveryResultSchema: GenMessage<ImageDiscoveryResult> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 40);
+  messageDesc(file_api_v1alpha1_generated, 41);
 
 /**
  * ImageSubscription defines a subscription to an image repository.
@@ -2038,7 +2089,7 @@ export type ImageSubscription = Message<"github.com.akuity.kargo.api.v1alpha1.Im
  * Use `create(ImageSubscriptionSchema)` to create a new message.
  */
 export const ImageSubscriptionSchema: GenMessage<ImageSubscription> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 41);
+  messageDesc(file_api_v1alpha1_generated, 42);
 
 /**
  * Project is a resource type that reconciles to a specially labeled namespace
@@ -2076,7 +2127,7 @@ export type Project = Message<"github.com.akuity.kargo.api.v1alpha1.Project"> &
  * Use `create(ProjectSchema)` to create a new message.
  */
 export const ProjectSchema: GenMessage<Project> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 42);
+  messageDesc(file_api_v1alpha1_generated, 43);
 
 /**
  * ProjectConfig is a resource type that describes the configuration of a
@@ -2110,7 +2161,7 @@ export type ProjectConfig = Message<"github.com.akuity.kargo.api.v1alpha1.Projec
  * Use `create(ProjectConfigSchema)` to create a new message.
  */
 export const ProjectConfigSchema: GenMessage<ProjectConfig> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 43);
+  messageDesc(file_api_v1alpha1_generated, 44);
 
 /**
  * ProjectConfigList is a list of ProjectConfig resources.
@@ -2134,7 +2185,7 @@ export type ProjectConfigList = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
  * Use `create(ProjectConfigListSchema)` to create a new message.
  */
 export const ProjectConfigListSchema: GenMessage<ProjectConfigList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 44);
+  messageDesc(file_api_v1alpha1_generated, 45);
 
 /**
  * ProjectSpec is a deprecated alias for ProjectConfigSpec. It is retained for
@@ -2167,7 +2218,7 @@ export type ProjectConfigSpec = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
  * Use `create(ProjectConfigSpecSchema)` to create a new message.
  */
 export const ProjectConfigSpecSchema: GenMessage<ProjectConfigSpec> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 45);
+  messageDesc(file_api_v1alpha1_generated, 46);
 
 /**
  * ProjectConfigStatus describes the current status of a ProjectConfig.
@@ -2188,6 +2239,24 @@ export type ProjectConfigStatus = Message<"github.com.akuity.kargo.api.v1alpha1.
    */
   conditions: Condition[];
 
+  /**
+   * ObservedGeneration represents the .metadata.generation that this
+   * ProjectConfig was reconciled against.
+   *
+   * @generated from field: optional int64 observedGeneration = 3;
+   */
+  observedGeneration: bigint;
+
+  /**
+   * LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh
+   * annotation that was handled by the controller. This field can be used to
+   * determine whether the request to refresh the resource has been handled.
+   * +optional
+   *
+   * @generated from field: optional string lastHandledRefresh = 4;
+   */
+  lastHandledRefresh: string;
+
   /**
    * WebhookReceivers describes the status of Project-specific webhook
    * receivers.
@@ -2202,7 +2271,7 @@ export type ProjectConfigStatus = Message<"github.com.akuity.kargo.api.v1alpha1.
  * Use `create(ProjectConfigStatusSchema)` to create a new message.
  */
 export const ProjectConfigStatusSchema: GenMessage<ProjectConfigStatus> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 46);
+  messageDesc(file_api_v1alpha1_generated, 47);
 
 /**
  * ProjectList is a list of Project resources.
@@ -2226,7 +2295,7 @@ export type ProjectList = Message<"github.com.akuity.kargo.api.v1alpha1.ProjectL
  * Use `create(ProjectListSchema)` to create a new message.
  */
 export const ProjectListSchema: GenMessage<ProjectList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 47);
+  messageDesc(file_api_v1alpha1_generated, 48);
 
 /**
  * ProjectStats contains a summary of the collective state of a Project's
@@ -2256,7 +2325,7 @@ export type ProjectStats = Message<"github.com.akuity.kargo.api.v1alpha1.Project
  * Use `create(ProjectStatsSchema)` to create a new message.
  */
 export const ProjectStatsSchema: GenMessage<ProjectStats> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 48);
+  messageDesc(file_api_v1alpha1_generated, 49);
 
 /**
  * ProjectStatus describes a Project's current status.
@@ -2290,7 +2359,7 @@ export type ProjectStatus = Message<"github.com.akuity.kargo.api.v1alpha1.Projec
  * Use `create(ProjectStatusSchema)` to create a new message.
  */
 export const ProjectStatusSchema: GenMessage<ProjectStatus> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 49);
+  messageDesc(file_api_v1alpha1_generated, 50);
 
 /**
  * Promotion represents a request to transition a particular Stage into a
@@ -2328,7 +2397,7 @@ export type Promotion = Message<"github.com.akuity.kargo.api.v1alpha1.Promotion"
  * Use `create(PromotionSchema)` to create a new message.
  */
 export const PromotionSchema: GenMessage<Promotion> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 50);
+  messageDesc(file_api_v1alpha1_generated, 51);
 
 /**
  * PromotionList contains a list of Promotion
@@ -2352,7 +2421,7 @@ export type PromotionList = Message<"github.com.akuity.kargo.api.v1alpha1.Promot
  * Use `create(PromotionListSchema)` to create a new message.
  */
 export const PromotionListSchema: GenMessage<PromotionList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 51);
+  messageDesc(file_api_v1alpha1_generated, 52);
 
 /**
  * PromotionPolicy defines policies governing the promotion of Freight to a
@@ -2401,7 +2470,7 @@ export type PromotionPolicy = Message<"github.com.akuity.kargo.api.v1alpha1.Prom
  * Use `create(PromotionPolicySchema)` to create a new message.
  */
 export const PromotionPolicySchema: GenMessage<PromotionPolicy> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 52);
+  messageDesc(file_api_v1alpha1_generated, 53);
 
 /**
  * PromotionPolicySelector is a selector that matches the resource to which
@@ -2457,7 +2526,7 @@ export type PromotionPolicySelector = Message<"github.com.akuity.kargo.api.v1alp
  * Use `create(PromotionPolicySelectorSchema)` to create a new message.
  */
 export const PromotionPolicySelectorSchema: GenMessage<PromotionPolicySelector> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 53);
+  messageDesc(file_api_v1alpha1_generated, 54);
 
 /**
  * PromotionReference contains the relevant information about a Promotion
@@ -2500,7 +2569,7 @@ export type PromotionReference = Message<"github.com.akuity.kargo.api.v1alpha1.P
  * Use `create(PromotionReferenceSchema)` to create a new message.
  */
 export const PromotionReferenceSchema: GenMessage<PromotionReference> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 54);
+  messageDesc(file_api_v1alpha1_generated, 55);
 
 /**
  * PromotionSpec describes the desired transition of a specific Stage into a
@@ -2565,7 +2634,7 @@ export type PromotionSpec = Message<"github.com.akuity.kargo.api.v1alpha1.Promot
  * Use `create(PromotionSpecSchema)` to create a new message.
  */
 export const PromotionSpecSchema: GenMessage<PromotionSpec> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 55);
+  messageDesc(file_api_v1alpha1_generated, 56);
 
 /**
  * PromotionStatus describes the current state of the transition represented by
@@ -2663,7 +2732,7 @@ export type PromotionStatus = Message<"github.com.akuity.kargo.api.v1alpha1.Prom
  * Use `create(PromotionStatusSchema)` to create a new message.
  */
 export const PromotionStatusSchema: GenMessage<PromotionStatus> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 56);
+  messageDesc(file_api_v1alpha1_generated, 57);
 
 /**
  * PromotionStep describes a directive to be executed as part of a Promotion.
@@ -2748,7 +2817,7 @@ export type PromotionStep = Message<"github.com.akuity.kargo.api.v1alpha1.Promot
  * Use `create(PromotionStepSchema)` to create a new message.
  */
 export const PromotionStepSchema: GenMessage<PromotionStep> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 57);
+  messageDesc(file_api_v1alpha1_generated, 58);
 
 /**
  * PromotionStepRetry describes the retry policy for a PromotionStep.
@@ -2807,7 +2876,7 @@ export type PromotionStepRetry = Message<"github.com.akuity.kargo.api.v1alpha1.P
  * Use `create(PromotionStepRetrySchema)` to create a new message.
  */
 export const PromotionStepRetrySchema: GenMessage<PromotionStepRetry> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 58);
+  messageDesc(file_api_v1alpha1_generated, 59);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.PromotionTask
@@ -2834,7 +2903,7 @@ export type PromotionTask = Message<"github.com.akuity.kargo.api.v1alpha1.Promot
  * Use `create(PromotionTaskSchema)` to create a new message.
  */
 export const PromotionTaskSchema: GenMessage<PromotionTask> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 59);
+  messageDesc(file_api_v1alpha1_generated, 60);
 
 /**
  * PromotionTaskList contains a list of PromotionTasks.
@@ -2858,7 +2927,7 @@ export type PromotionTaskList = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
  * Use `create(PromotionTaskListSchema)` to create a new message.
  */
 export const PromotionTaskListSchema: GenMessage<PromotionTaskList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 60);
+  messageDesc(file_api_v1alpha1_generated, 61);
 
 /**
  * PromotionTaskReference describes a reference to a PromotionTask.
@@ -2896,7 +2965,7 @@ export type PromotionTaskReference = Message<"github.com.akuity.kargo.api.v1alph
  * Use `create(PromotionTaskReferenceSchema)` to create a new message.
  */
 export const PromotionTaskReferenceSchema: GenMessage<PromotionTaskReference> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 61);
+  messageDesc(file_api_v1alpha1_generated, 62);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.PromotionTaskSpec
@@ -2930,7 +2999,7 @@ export type PromotionTaskSpec = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
  * Use `create(PromotionTaskSpecSchema)` to create a new message.
  */
 export const PromotionTaskSpecSchema: GenMessage<PromotionTaskSpec> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 62);
+  messageDesc(file_api_v1alpha1_generated, 63);
 
 /**
  * PromotionTemplate defines a template for a Promotion that can be used to
@@ -2950,7 +3019,7 @@ export type PromotionTemplate = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
  * Use `create(PromotionTemplateSchema)` to create a new message.
  */
 export const PromotionTemplateSchema: GenMessage<PromotionTemplate> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 63);
+  messageDesc(file_api_v1alpha1_generated, 64);
 
 /**
  * PromotionTemplateSpec describes the (partial) specification of a Promotion
@@ -2986,7 +3055,7 @@ export type PromotionTemplateSpec = Message<"github.com.akuity.kargo.api.v1alpha
  * Use `create(PromotionTemplateSpecSchema)` to create a new message.
  */
 export const PromotionTemplateSpecSchema: GenMessage<PromotionTemplateSpec> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 64);
+  messageDesc(file_api_v1alpha1_generated, 65);
 
 /**
  * QuayWebhookReceiverConfig describes a webhook receiver that is compatible
@@ -3022,7 +3091,7 @@ export type QuayWebhookReceiverConfig = Message<"github.com.akuity.kargo.api.v1a
  * Use `create(QuayWebhookReceiverConfigSchema)` to create a new message.
  */
 export const QuayWebhookReceiverConfigSchema: GenMessage<QuayWebhookReceiverConfig> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 65);
+  messageDesc(file_api_v1alpha1_generated, 66);
 
 /**
  * RepoSubscription describes a subscription to ONE OF a Git repository, a
@@ -3058,7 +3127,7 @@ export type RepoSubscription = Message<"github.com.akuity.kargo.api.v1alpha1.Rep
  * Use `create(RepoSubscriptionSchema)` to create a new message.
  */
 export const RepoSubscriptionSchema: GenMessage<RepoSubscription> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 66);
+  messageDesc(file_api_v1alpha1_generated, 67);
 
 /**
  * Stage is the Kargo API's main type.
@@ -3094,7 +3163,7 @@ export type Stage = Message<"github.com.akuity.kargo.api.v1alpha1.Stage"> & {
  * Use `create(StageSchema)` to create a new message.
  */
 export const StageSchema: GenMessage<Stage> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 67);
+  messageDesc(file_api_v1alpha1_generated, 68);
 
 /**
  * StageList is a list of Stage resources.
@@ -3118,7 +3187,7 @@ export type StageList = Message<"github.com.akuity.kargo.api.v1alpha1.StageList"
  * Use `create(StageListSchema)` to create a new message.
  */
 export const StageListSchema: GenMessage<StageList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 68);
+  messageDesc(file_api_v1alpha1_generated, 69);
 
 /**
  * StageSpec describes the sources of Freight used by a Stage and how to
@@ -3185,7 +3254,7 @@ export type StageSpec = Message<"github.com.akuity.kargo.api.v1alpha1.StageSpec"
  * Use `create(StageSpecSchema)` to create a new message.
  */
 export const StageSpecSchema: GenMessage<StageSpec> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 69);
+  messageDesc(file_api_v1alpha1_generated, 70);
 
 /**
  * StageStats contains a summary of the collective state of a Project's
@@ -3214,7 +3283,7 @@ export type StageStats = Message<"github.com.akuity.kargo.api.v1alpha1.StageStat
  * Use `create(StageStatsSchema)` to create a new message.
  */
 export const StageStatsSchema: GenMessage<StageStats> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 70);
+  messageDesc(file_api_v1alpha1_generated, 71);
 
 /**
  * StageStatus describes a Stages's current and recent Freight, health, and
@@ -3306,7 +3375,7 @@ export type StageStatus = Message<"github.com.akuity.kargo.api.v1alpha1.StageSta
  * Use `create(StageStatusSchema)` to create a new message.
  */
 export const StageStatusSchema: GenMessage<StageStatus> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 71);
+  messageDesc(file_api_v1alpha1_generated, 72);
 
 /**
  * StepExecutionMetadata tracks metadata pertaining to the execution of
@@ -3375,7 +3444,7 @@ export type StepExecutionMetadata = Message<"github.com.akuity.kargo.api.v1alpha
  * Use `create(StepExecutionMetadataSchema)` to create a new message.
  */
 export const StepExecutionMetadataSchema: GenMessage<StepExecutionMetadata> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 72);
+  messageDesc(file_api_v1alpha1_generated, 73);
 
 /**
  * Verification describes how to verify that a Promotion has been successful
@@ -3414,7 +3483,7 @@ export type Verification = Message<"github.com.akuity.kargo.api.v1alpha1.Verific
  * Use `create(VerificationSchema)` to create a new message.
  */
 export const VerificationSchema: GenMessage<Verification> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 73);
+  messageDesc(file_api_v1alpha1_generated, 74);
 
 /**
  * VerificationInfo contains the details of an instance of a Verification
@@ -3484,7 +3553,7 @@ export type VerificationInfo = Message<"github.com.akuity.kargo.api.v1alpha1.Ver
  * Use `create(VerificationInfoSchema)` to create a new message.
  */
 export const VerificationInfoSchema: GenMessage<VerificationInfo> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 74);
+  messageDesc(file_api_v1alpha1_generated, 75);
 
 /**
  * VerifiedStage describes a Stage in which Freight has been verified.
@@ -3516,7 +3585,7 @@ export type VerifiedStage = Message<"github.com.akuity.kargo.api.v1alpha1.Verifi
  * Use `create(VerifiedStageSchema)` to create a new message.
  */
 export const VerifiedStageSchema: GenMessage<VerifiedStage> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 75);
+  messageDesc(file_api_v1alpha1_generated, 76);
 
 /**
  * Warehouse is a source of Freight.
@@ -3551,7 +3620,7 @@ export type Warehouse = Message<"github.com.akuity.kargo.api.v1alpha1.Warehouse"
  * Use `create(WarehouseSchema)` to create a new message.
  */
 export const WarehouseSchema: GenMessage<Warehouse> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 76);
+  messageDesc(file_api_v1alpha1_generated, 77);
 
 /**
  * WarehouseList is a list of Warehouse resources.
@@ -3575,7 +3644,7 @@ export type WarehouseList = Message<"github.com.akuity.kargo.api.v1alpha1.Wareho
  * Use `create(WarehouseListSchema)` to create a new message.
  */
 export const WarehouseListSchema: GenMessage<WarehouseList> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 77);
+  messageDesc(file_api_v1alpha1_generated, 78);
 
 /**
  * WarehouseSpec describes sources of versioned artifacts to be included in
@@ -3647,7 +3716,7 @@ export type WarehouseSpec = Message<"github.com.akuity.kargo.api.v1alpha1.Wareho
  * Use `create(WarehouseSpecSchema)` to create a new message.
  */
 export const WarehouseSpecSchema: GenMessage<WarehouseSpec> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 78);
+  messageDesc(file_api_v1alpha1_generated, 79);
 
 /**
  * WarehouseStats contains a summary of the collective state of a Project's
@@ -3677,7 +3746,7 @@ export type WarehouseStats = Message<"github.com.akuity.kargo.api.v1alpha1.Wareh
  * Use `create(WarehouseStatsSchema)` to create a new message.
  */
 export const WarehouseStatsSchema: GenMessage<WarehouseStats> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 79);
+  messageDesc(file_api_v1alpha1_generated, 80);
 
 /**
  * WarehouseStatus describes a Warehouse's most recently observed state.
@@ -3736,7 +3805,7 @@ export type WarehouseStatus = Message<"github.com.akuity.kargo.api.v1alpha1.Ware
  * Use `create(WarehouseStatusSchema)` to create a new message.
  */
 export const WarehouseStatusSchema: GenMessage<WarehouseStatus> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 80);
+  messageDesc(file_api_v1alpha1_generated, 81);
 
 /**
  * WebhookReceiverConfig describes the configuration for a single webhook
@@ -3766,6 +3835,14 @@ export type WebhookReceiverConfig = Message<"github.com.akuity.kargo.api.v1alpha
    */
   bitbucket?: BitbucketWebhookReceiverConfig;
 
+  /**
+   * DockerHub contains the configuration for a webhook receiver that is
+   * compatible with DockerHub payloads.
+   *
+   * @generated from field: optional github.com.akuity.kargo.api.v1alpha1.DockerHubWebhookReceiverConfig dockerhub = 6;
+   */
+  dockerhub?: DockerHubWebhookReceiverConfig;
+
   /**
    * GitHub contains the configuration for a webhook receiver that is compatible
    * with GitHub payloads.
@@ -3796,7 +3873,7 @@ export type WebhookReceiverConfig = Message<"github.com.akuity.kargo.api.v1alpha
  * Use `create(WebhookReceiverConfigSchema)` to create a new message.
  */
 export const WebhookReceiverConfigSchema: GenMessage<WebhookReceiverConfig> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 81);
+  messageDesc(file_api_v1alpha1_generated, 82);
 
 /**
  * WebhookReceiverDetails encapsulates the details of a webhook receiver.
@@ -3831,5 +3908,5 @@ export type WebhookReceiverDetails = Message<"github.com.akuity.kargo.api.v1alph
  * Use `create(WebhookReceiverDetailsSchema)` to create a new message.
  */
 export const WebhookReceiverDetailsSchema: GenMessage<WebhookReceiverDetails> = /*@__PURE__*/
-  messageDesc(file_api_v1alpha1_generated, 82);
+  messageDesc(file_api_v1alpha1_generated, 83);
 
diff --git a/ui/src/gen/schema/clusterconfigs.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/clusterconfigs.kargo.akuity.io_v1alpha1.json
index 10fe29b7..2533f0c3 100644
--- a/ui/src/gen/schema/clusterconfigs.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/clusterconfigs.kargo.akuity.io_v1alpha1.json
@@ -42,6 +42,27 @@
                 ],
                 "type": "object"
               },
+              "dockerhub": {
+                "description": "DockerHub contains the configuration for a webhook receiver that is\ncompatible with DockerHub payloads.",
+                "properties": {
+                  "secretRef": {
+                    "description": "SecretRef contains a reference to a Secret. For Project-scoped webhook\nreceivers, the referenced Secret must be in the same namespace as the\nProjectConfig.\n\nThe Secret's data map is expected to contain a `secret` key whose value\ndoes NOT need to be shared directly with Docker Hub when registering a\nwebhook. It is used only by Kargo to create a complex, hard-to-guess URL,\nwhich implicitly serves as a shared secret. For more information about\nDocker Hub webhooks, please refer to the Docker documentation:\n  https://docs.docker.com/docker-hub/webhooks/",
+                    "properties": {
+                      "name": {
+                        "default": "",
+                        "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names",
+                        "type": "string"
+                      }
+                    },
+                    "type": "object",
+                    "x-kubernetes-map-type": "atomic"
+                  }
+                },
+                "required": [
+                  "secretRef"
+                ],
+                "type": "object"
+              },
               "github": {
                 "description": "GitHub contains the configuration for a webhook receiver that is compatible\nwith GitHub payloads.",
                 "properties": {
@@ -186,6 +207,17 @@
           ],
           "x-kubernetes-list-type": "map"
         },
+        "lastHandledRefresh": {
+          "description": "LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh\nannotation that was handled by the controller. This field can be used to\ndetermine whether the request to refresh the resource has been handled.",
+          "type": "string"
+        },
+        "observedGeneration": {
+          "description": "ObservedGeneration represents the .metadata.generation that this\nClusterConfig was reconciled against.",
+          "format": "int64",
+          "maximum": 9223372036854776000,
+          "minimum": -9223372036854776000,
+          "type": "integer"
+        },
         "webhookReceivers": {
           "description": "WebhookReceivers describes the status of cluster-scoped webhook receivers.",
           "items": {
diff --git a/ui/src/gen/schema/projectconfigs.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/projectconfigs.kargo.akuity.io_v1alpha1.json
index 4de959bc..dc5cff2e 100644
--- a/ui/src/gen/schema/projectconfigs.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/projectconfigs.kargo.akuity.io_v1alpha1.json
@@ -116,6 +116,27 @@
                 ],
                 "type": "object"
               },
+              "dockerhub": {
+                "description": "DockerHub contains the configuration for a webhook receiver that is\ncompatible with DockerHub payloads.",
+                "properties": {
+                  "secretRef": {
+                    "description": "SecretRef contains a reference to a Secret. For Project-scoped webhook\nreceivers, the referenced Secret must be in the same namespace as the\nProjectConfig.\n\nThe Secret's data map is expected to contain a `secret` key whose value\ndoes NOT need to be shared directly with Docker Hub when registering a\nwebhook. It is used only by Kargo to create a complex, hard-to-guess URL,\nwhich implicitly serves as a shared secret. For more information about\nDocker Hub webhooks, please refer to the Docker documentation:\n  https://docs.docker.com/docker-hub/webhooks/",
+                    "properties": {
+                      "name": {
+                        "default": "",
+                        "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names",
+                        "type": "string"
+                      }
+                    },
+                    "type": "object",
+                    "x-kubernetes-map-type": "atomic"
+                  }
+                },
+                "required": [
+                  "secretRef"
+                ],
+                "type": "object"
+              },
               "github": {
                 "description": "GitHub contains the configuration for a webhook receiver that is compatible\nwith GitHub payloads.",
                 "properties": {
@@ -260,6 +281,17 @@
           ],
           "x-kubernetes-list-type": "map"
         },
+        "lastHandledRefresh": {
+          "description": "LastHandledRefresh holds the value of the most recent AnnotationKeyRefresh\nannotation that was handled by the controller. This field can be used to\ndetermine whether the request to refresh the resource has been handled.",
+          "type": "string"
+        },
+        "observedGeneration": {
+          "description": "ObservedGeneration represents the .metadata.generation that this\nProjectConfig was reconciled against.",
+          "format": "int64",
+          "maximum": 9223372036854776000,
+          "minimum": -9223372036854776000,
+          "type": "integer"
+        },
         "webhookReceivers": {
           "description": "WebhookReceivers describes the status of Project-specific webhook\nreceivers.",
           "items": {
diff --git a/ui/src/gen/schema/projects.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/projects.kargo.akuity.io_v1alpha1.json
index b2124229..ce8e8104 100644
--- a/ui/src/gen/schema/projects.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/projects.kargo.akuity.io_v1alpha1.json
@@ -116,6 +116,27 @@
                 ],
                 "type": "object"
               },
+              "dockerhub": {
+                "description": "DockerHub contains the configuration for a webhook receiver that is\ncompatible with DockerHub payloads.",
+                "properties": {
+                  "secretRef": {
+                    "description": "SecretRef contains a reference to a Secret. For Project-scoped webhook\nreceivers, the referenced Secret must be in the same namespace as the\nProjectConfig.\n\nThe Secret's data map is expected to contain a `secret` key whose value\ndoes NOT need to be shared directly with Docker Hub when registering a\nwebhook. It is used only by Kargo to create a complex, hard-to-guess URL,\nwhich implicitly serves as a shared secret. For more information about\nDocker Hub webhooks, please refer to the Docker documentation:\n  https://docs.docker.com/docker-hub/webhooks/",
+                    "properties": {
+                      "name": {
+                        "default": "",
+                        "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names",
+                        "type": "string"
+                      }
+                    },
+                    "type": "object",
+                    "x-kubernetes-map-type": "atomic"
+                  }
+                },
+                "required": [
+                  "secretRef"
+                ],
+                "type": "object"
+              },
               "github": {
                 "description": "GitHub contains the configuration for a webhook receiver that is compatible\nwith GitHub payloads.",
                 "properties": {



Test patch:
diff --git a/api/v1alpha1/warehouse_types_test.go b/api/v1alpha1/warehouse_types_test.go
new file mode 100644
index 00000000..c96111ba
--- /dev/null
+++ b/api/v1alpha1/warehouse_types_test.go
@@ -0,0 +1,123 @@
+package v1alpha1
+
+import (
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func TestWarehouse_GetInterval(t *testing.T) {
+	tests := []struct {
+		name        string
+		warehouse   *Warehouse
+		minInterval time.Duration
+		assertions  func(t *testing.T, w *Warehouse, interval time.Duration, minInterval time.Duration)
+	}{
+		{
+			name: "no discovery has taken place yet, spec interval > min",
+			warehouse: &Warehouse{
+				Spec: WarehouseSpec{
+					Interval: metav1.Duration{Duration: 5 * time.Minute},
+				},
+			},
+			minInterval: 2 * time.Minute,
+			assertions: func(t *testing.T, warehouse *Warehouse, interval time.Duration, _ time.Duration) {
+				require.Equal(t, warehouse.Spec.Interval.Duration, interval)
+			},
+		},
+		{
+			name: "no discovery has taken place yet, spec interval < min",
+			warehouse: &Warehouse{
+				Spec: WarehouseSpec{
+					Interval: metav1.Duration{Duration: 2 * time.Minute},
+				},
+			},
+			minInterval: 5 * time.Minute,
+			assertions: func(t *testing.T, warehouse *Warehouse, interval time.Duration, minInterval time.Duration) {
+				require.Equal(t, minInterval, interval)
+				require.Greater(t, interval, warehouse.Spec.Interval.Duration)
+			},
+		},
+		{
+			name: "next discovery is overdue, spec interval > min",
+			warehouse: &Warehouse{
+				Spec: WarehouseSpec{
+					Interval: metav1.Duration{Duration: 5 * time.Minute},
+				},
+				Status: WarehouseStatus{
+					DiscoveredArtifacts: &DiscoveredArtifacts{
+						DiscoveredAt: metav1.NewTime(time.Now().Add(-6 * time.Minute)),
+					},
+				},
+			},
+			minInterval: 2 * time.Minute,
+			assertions: func(t *testing.T, _ *Warehouse, interval time.Duration, _ time.Duration) {
+				require.Equal(t, interval, 100*time.Millisecond)
+			},
+		},
+		{
+			name: "next discovery is overdue, spec interval < min",
+			warehouse: &Warehouse{
+				Spec: WarehouseSpec{
+					Interval: metav1.Duration{Duration: 2 * time.Minute},
+				},
+				Status: WarehouseStatus{
+					DiscoveredArtifacts: &DiscoveredArtifacts{
+						DiscoveredAt: metav1.NewTime(time.Now().Add(-6 * time.Minute)),
+					},
+				},
+			},
+			minInterval: 5 * time.Minute,
+			assertions: func(t *testing.T, _ *Warehouse, interval time.Duration, _ time.Duration) {
+				require.Equal(t, interval, 100*time.Millisecond)
+			},
+		},
+		{
+			name: "next discovery is not overdue, spec interval > min",
+			warehouse: &Warehouse{
+				Spec: WarehouseSpec{
+					Interval: metav1.Duration{Duration: 5 * time.Minute},
+				},
+				Status: WarehouseStatus{
+					DiscoveredArtifacts: &DiscoveredArtifacts{
+						DiscoveredAt: metav1.NewTime(time.Now().Add(-3 * time.Minute)),
+					},
+				},
+			},
+			minInterval: 2 * time.Minute,
+			assertions: func(t *testing.T, w *Warehouse, interval time.Duration, _ time.Duration) {
+				require.NotZero(t, interval)
+				require.Less(t, interval, w.Spec.Interval.Duration)
+				// Should be around 2 minutes (5 - 3)
+				require.InDelta(t, 2*time.Minute, interval, float64(10*time.Second))
+			},
+		},
+		{
+			name: "next discovery is not overdue, spec interval < min",
+			warehouse: &Warehouse{
+				Spec: WarehouseSpec{
+					Interval: metav1.Duration{Duration: 2 * time.Minute},
+				},
+				Status: WarehouseStatus{
+					DiscoveredArtifacts: &DiscoveredArtifacts{
+						DiscoveredAt: metav1.NewTime(time.Now().Add(-1 * time.Minute)),
+					},
+				},
+			},
+			minInterval: 5 * time.Minute,
+			assertions: func(t *testing.T, w *Warehouse, interval time.Duration, _ time.Duration) {
+				require.NotZero(t, interval)
+				// Should be around 4 minutes (5 - 1) since effective interval is min (5 minutes)
+				require.InDelta(t, 4*time.Minute, interval, float64(10*time.Second))
+				require.Greater(t, interval, w.Spec.Interval.Duration)
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertions(t, tt.warehouse, tt.warehouse.GetInterval(tt.minInterval), tt.minInterval)
+		})
+	}
+}
diff --git a/internal/controller/warehouses/warehouses_test.go b/internal/controller/warehouses/warehouses_test.go
index 3d9af5dd..c71f2ad9 100644
--- a/internal/controller/warehouses/warehouses_test.go
+++ b/internal/controller/warehouses/warehouses_test.go
@@ -20,12 +20,16 @@ import (
 
 func TestNewReconciler(t *testing.T) {
 	kubeClient := fake.NewClientBuilder().Build()
+	minReconciliationInterval := time.Duration(1000)
+
 	e := newReconciler(
 		kubeClient,
 		&credentials.FakeDB{},
+		minReconciliationInterval,
 	)
 	require.NotNil(t, e.client)
 	require.NotNil(t, e.credentialsDB)
+	require.Equal(t, minReconciliationInterval, e.minReconciliationInterval)
 	require.NotEmpty(t, e.imageSourceURLFnsByBaseURL)
 
 	// Assert that all overridable behaviors were initialized to a default:
@@ -1004,61 +1008,3 @@ func TestShouldDiscoverArtifacts(t *testing.T) {
 		})
 	}
 }
-
-func TestGetRequeueInterval(t *testing.T) {
-	testCases := []struct {
-		name       string
-		warehouse  *kargoapi.Warehouse
-		assertions func(t *testing.T, warehouse *kargoapi.Warehouse, interval time.Duration)
-	}{
-		{
-			name: "no discovery has taken place yet",
-			warehouse: &kargoapi.Warehouse{
-				Spec: kargoapi.WarehouseSpec{
-					Interval: metav1.Duration{Duration: 5 * time.Minute},
-				},
-			},
-			assertions: func(t *testing.T, warehouse *kargoapi.Warehouse, interval time.Duration) {
-				require.Equal(t, warehouse.Spec.Interval.Duration, interval)
-			},
-		},
-		{
-			name: "next discovery is overdue",
-			warehouse: &kargoapi.Warehouse{
-				Spec: kargoapi.WarehouseSpec{
-					Interval: metav1.Duration{Duration: 5 * time.Minute},
-				},
-				Status: kargoapi.WarehouseStatus{
-					DiscoveredArtifacts: &kargoapi.DiscoveredArtifacts{
-						DiscoveredAt: metav1.NewTime(time.Now().Add(-6 * time.Minute)),
-					},
-				},
-			},
-			assertions: func(t *testing.T, _ *kargoapi.Warehouse, interval time.Duration) {
-				require.Zero(t, interval)
-			},
-		},
-		{
-			name: "next discovery is not overdue",
-			warehouse: &kargoapi.Warehouse{
-				Spec: kargoapi.WarehouseSpec{
-					Interval: metav1.Duration{Duration: 5 * time.Minute},
-				},
-				Status: kargoapi.WarehouseStatus{
-					DiscoveredArtifacts: &kargoapi.DiscoveredArtifacts{
-						DiscoveredAt: metav1.NewTime(time.Now().Add(-3 * time.Minute)),
-					},
-				},
-			},
-			assertions: func(t *testing.T, warehouse *kargoapi.Warehouse, interval time.Duration) {
-				require.NotZero(t, interval)
-				require.Less(t, interval, warehouse.Spec.Interval.Duration)
-			},
-		},
-	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			testCase.assertions(t, testCase.warehouse, getRequeueInterval(testCase.warehouse))
-		})
-	}
-}
diff --git a/internal/image/normalization_test.go b/internal/image/normalization_test.go
new file mode 100644
index 00000000..bfa7ee30
--- /dev/null
+++ b/internal/image/normalization_test.go
@@ -0,0 +1,41 @@
+package image
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestNormalizeURL(t *testing.T) {
+	tests := []struct {
+		input    string
+		expected string
+	}{
+		// Official images on Docker Hub
+		{"index.docker.io/library/busybox", "busybox"},
+		{"index.docker.io/busybox", "busybox"},
+		{"registry-1.docker.io/library/busybox", "busybox"},
+		{"registry-1.docker.io/busybox", "busybox"},
+		{"docker.io/library/busybox", "busybox"},
+		{"docker.io/busybox", "busybox"},
+		{"library/busybox", "busybox"},
+		{"busybox", "busybox"},
+
+		// Other images on Docker Hub
+		{"index.docker.io/example/repo", "example/repo"},
+		{"docker.io/example/repo", "example/repo"},
+		{"example/repo", "example/repo"},
+
+		// Images from other registries
+		{"ghcr.io/example/repo", "ghcr.io/example/repo"},
+		{"quay.io/example/repo", "quay.io/example/repo"},
+
+		// Input that cannot be normalized (invalid URL)
+		{"invalid url", "invalid url"},
+	}
+
+	for _, tc := range tests {
+		got := NormalizeURL(tc.input)
+		require.Equal(t, tc.expected, got, "input: %s", tc.input)
+	}
+}
diff --git a/internal/server/get_cluster_config_v1alpha1_test.go b/internal/server/get_cluster_config_v1alpha1_test.go
new file mode 100644
index 00000000..6c855304
--- /dev/null
+++ b/internal/server/get_cluster_config_v1alpha1_test.go
@@ -0,0 +1,185 @@
+package server
+
+import (
+	"context"
+	"testing"
+
+	"connectrpc.com/connect"
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/serializer"
+	"k8s.io/client-go/rest"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+	"github.com/akuity/kargo/internal/server/kubernetes"
+)
+
+func TestGetClusterConfig(t *testing.T) {
+	testCases := map[string]struct {
+		req         *svcv1alpha1.GetClusterConfigRequest
+		objects     []client.Object
+		interceptor interceptor.Funcs
+		assertions  func(*testing.T, *connect.Response[svcv1alpha1.GetClusterConfigResponse], error)
+	}{
+		"non-existing ClusterConfig": {
+			req:     &svcv1alpha1.GetClusterConfigRequest{},
+			objects: []client.Object{},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.GetClusterConfigResponse], err error) {
+				require.Error(t, err)
+				require.Equal(t, connect.CodeNotFound, connect.CodeOf(err))
+				require.Nil(t, r)
+			},
+		},
+		"existing ClusterConfig": {
+			req: &svcv1alpha1.GetClusterConfigRequest{},
+			objects: []client.Object{
+				&kargoapi.ClusterConfig{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: api.ClusterConfigName,
+					},
+				},
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.GetClusterConfigResponse], err error) {
+				require.NoError(t, err)
+
+				require.NotNil(t, r)
+				require.Nil(t, r.Msg.GetRaw())
+
+				require.NotNil(t, r.Msg.GetClusterConfig())
+				require.Equal(t, api.ClusterConfigName, r.Msg.GetClusterConfig().Name)
+			},
+		},
+		"raw format JSON": {
+			req: &svcv1alpha1.GetClusterConfigRequest{
+				Format: svcv1alpha1.RawFormat_RAW_FORMAT_JSON,
+			},
+			objects: []client.Object{
+				&kargoapi.ClusterConfig{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "ClusterConfig",
+						APIVersion: kargoapi.GroupVersion.String(),
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name: api.ClusterConfigName,
+					},
+					Spec: kargoapi.ClusterConfigSpec{
+						WebhookReceivers: []kargoapi.WebhookReceiverConfig{
+							{
+								Name: "my-webhook-receiver",
+							},
+						},
+					},
+				},
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.GetClusterConfigResponse], err error) {
+				require.NoError(t, err)
+
+				require.NotNil(t, r)
+				require.Nil(t, r.Msg.GetClusterConfig())
+				require.NotNil(t, r.Msg.GetRaw())
+
+				scheme := runtime.NewScheme()
+				require.NoError(t, kargoapi.AddToScheme(scheme))
+
+				obj, _, err := serializer.NewCodecFactory(scheme).UniversalDeserializer().Decode(
+					r.Msg.GetRaw(),
+					nil,
+					nil,
+				)
+
+				require.NoError(t, err)
+				tObj, ok := obj.(*kargoapi.ClusterConfig)
+				require.True(t, ok)
+				require.Equal(t, api.ClusterConfigName, tObj.Name)
+				require.Equal(t, 1, len(tObj.Spec.WebhookReceivers))
+				require.Equal(t, "my-webhook-receiver", tObj.Spec.WebhookReceivers[0].Name)
+			},
+		},
+		"raw format YAML": {
+			req: &svcv1alpha1.GetClusterConfigRequest{
+				Format: svcv1alpha1.RawFormat_RAW_FORMAT_YAML,
+			},
+			objects: []client.Object{
+				&kargoapi.ClusterConfig{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "ClusterConfig",
+						APIVersion: kargoapi.GroupVersion.String(),
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name: api.ClusterConfigName,
+					},
+					Spec: kargoapi.ClusterConfigSpec{
+						WebhookReceivers: []kargoapi.WebhookReceiverConfig{
+							{
+								Name: "my-webhook-receiver",
+							},
+						},
+					},
+				},
+			},
+			assertions: func(t *testing.T, c *connect.Response[svcv1alpha1.GetClusterConfigResponse], err error) {
+				require.NoError(t, err)
+
+				require.NotNil(t, c)
+				require.Nil(t, c.Msg.GetClusterConfig())
+				require.NotNil(t, c.Msg.GetRaw())
+
+				scheme := runtime.NewScheme()
+				require.NoError(t, kargoapi.AddToScheme(scheme))
+
+				obj, _, err := serializer.NewCodecFactory(scheme).UniversalDeserializer().Decode(
+					c.Msg.GetRaw(),
+					nil,
+					nil,
+				)
+				require.NoError(t, err)
+				tObj, ok := obj.(*kargoapi.ClusterConfig)
+				require.True(t, ok)
+				require.Equal(t, api.ClusterConfigName, tObj.Name)
+				require.Equal(t, 1, len(tObj.Spec.WebhookReceivers))
+				require.Equal(t, "my-webhook-receiver", tObj.Spec.WebhookReceivers[0].Name)
+			},
+		},
+	}
+
+	for name, testCase := range testCases {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			ctx := context.Background()
+
+			client, err := kubernetes.NewClient(
+				ctx,
+				&rest.Config{},
+				kubernetes.ClientOptions{
+					SkipAuthorization: true,
+					NewInternalClient: func(
+						_ context.Context,
+						_ *rest.Config,
+						scheme *runtime.Scheme,
+					) (client.Client, error) {
+						c := fake.NewClientBuilder().WithScheme(scheme).WithInterceptorFuncs(testCase.interceptor)
+						if len(testCase.objects) > 0 {
+							c.WithObjects(testCase.objects...)
+						}
+						return c.Build(), nil
+					},
+				},
+			)
+			require.NoError(t, err)
+
+			svr := &server{
+				client: client,
+			}
+
+			res, err := (svr).GetClusterConfig(ctx, connect.NewRequest(testCase.req))
+			testCase.assertions(t, res, err)
+		})
+	}
+}
diff --git a/internal/server/get_project_config_v1alpha1_test.go b/internal/server/get_project_config_v1alpha1_test.go
index 1294712f..fd51ecbf 100644
--- a/internal/server/get_project_config_v1alpha1_test.go
+++ b/internal/server/get_project_config_v1alpha1_test.go
@@ -6,6 +6,7 @@ import (
 
 	"connectrpc.com/connect"
 	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/serializer"
@@ -17,6 +18,7 @@ import (
 	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/server/kubernetes"
+	"github.com/akuity/kargo/internal/server/validation"
 )
 
 func TestGetProjectConfig(t *testing.T) {
@@ -26,11 +28,12 @@ func TestGetProjectConfig(t *testing.T) {
 		interceptor interceptor.Funcs
 		assertions  func(*testing.T, *connect.Response[svcv1alpha1.GetProjectConfigResponse], error)
 	}{
-		"empty name": {
+		"empty project": {
 			req: &svcv1alpha1.GetProjectConfigRequest{
-				Name: "",
+				Project: "",
 			},
 			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
 				&kargoapi.ProjectConfig{
 					ObjectMeta: metav1.ObjectMeta{
 						Name: "kargo-demo",
@@ -43,9 +46,9 @@ func TestGetProjectConfig(t *testing.T) {
 				require.Nil(t, r)
 			},
 		},
-		"non-existing ProjectConfig": {
+		"non-existing project": {
 			req: &svcv1alpha1.GetProjectConfigRequest{
-				Name: "kargo-x",
+				Project: "kargo-x",
 			},
 			objects: []client.Object{},
 			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.GetProjectConfigResponse], err error) {
@@ -56,9 +59,10 @@ func TestGetProjectConfig(t *testing.T) {
 		},
 		"existing ProjectConfig": {
 			req: &svcv1alpha1.GetProjectConfigRequest{
-				Name: "kargo-demo",
+				Project: "kargo-demo",
 			},
 			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
 				&kargoapi.ProjectConfig{
 					ObjectMeta: metav1.ObjectMeta{
 						Name:      "kargo-demo",
@@ -78,10 +82,11 @@ func TestGetProjectConfig(t *testing.T) {
 		},
 		"raw format JSON": {
 			req: &svcv1alpha1.GetProjectConfigRequest{
-				Name:   "kargo-demo",
-				Format: svcv1alpha1.RawFormat_RAW_FORMAT_JSON,
+				Project: "kargo-demo",
+				Format:  svcv1alpha1.RawFormat_RAW_FORMAT_JSON,
 			},
 			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
 				&kargoapi.ProjectConfig{
 					TypeMeta: metav1.TypeMeta{
 						Kind:       "ProjectConfig",
@@ -131,10 +136,11 @@ func TestGetProjectConfig(t *testing.T) {
 		},
 		"raw format YAML": {
 			req: &svcv1alpha1.GetProjectConfigRequest{
-				Name:   "kargo-demo",
-				Format: svcv1alpha1.RawFormat_RAW_FORMAT_YAML,
+				Project: "kargo-demo",
+				Format:  svcv1alpha1.RawFormat_RAW_FORMAT_YAML,
 			},
 			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
 				&kargoapi.ProjectConfig{
 					TypeMeta: metav1.TypeMeta{
 						Kind:       "ProjectConfig",
@@ -211,7 +217,8 @@ func TestGetProjectConfig(t *testing.T) {
 			require.NoError(t, err)
 
 			svr := &server{
-				client: client,
+				client:                    client,
+				externalValidateProjectFn: validation.ValidateProject,
 			}
 
 			res, err := (svr).GetProjectConfig(ctx, connect.NewRequest(testCase.req))
diff --git a/internal/server/refresh_cluster_config_v1alpha1_test.go b/internal/server/refresh_cluster_config_v1alpha1_test.go
new file mode 100644
index 00000000..93926839
--- /dev/null
+++ b/internal/server/refresh_cluster_config_v1alpha1_test.go
@@ -0,0 +1,99 @@
+package server
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"connectrpc.com/connect"
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/rest"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
+	"github.com/akuity/kargo/internal/server/kubernetes"
+)
+
+func TestRefreshClusterConfig(t *testing.T) {
+	testSets := map[string]struct {
+		req        *svcv1alpha1.RefreshClusterConfigRequest
+		objects    []client.Object
+		assertions func(*testing.T, *connect.Response[svcv1alpha1.RefreshClusterConfigResponse], error)
+	}{
+		"non-existing ClusterConfig": {
+			req:     &svcv1alpha1.RefreshClusterConfigRequest{},
+			objects: []client.Object{},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.RefreshClusterConfigResponse], err error) {
+				require.Error(t, err)
+				require.Equal(t, connect.CodeNotFound, connect.CodeOf(err))
+				require.Nil(t, r)
+			},
+		},
+		"existing ClusterConfig": {
+			req: &svcv1alpha1.RefreshClusterConfigRequest{},
+			objects: []client.Object{
+				&kargoapi.ClusterConfig{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "ClusterConfig",
+						APIVersion: kargoapi.GroupVersion.String(),
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name: api.ClusterConfigName,
+					},
+				},
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.RefreshClusterConfigResponse], err error) {
+				require.NoError(t, err)
+
+				config := r.Msg.GetClusterConfig()
+				require.Equal(t, api.ClusterConfigName, config.Name)
+
+				annotation := config.GetAnnotations()[kargoapi.AnnotationKeyRefresh]
+				refreshTime, err := time.Parse(time.RFC3339, annotation)
+				require.NoError(t, err)
+
+				// Make sure we set timestamp is close to now
+				// Assume it doesn't take 3 seconds to run this unit test.
+				require.WithinDuration(t, time.Now(), refreshTime, 3*time.Second)
+
+			},
+		},
+	}
+	for name, ts := range testSets {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			ctx := context.Background()
+
+			client, err := kubernetes.NewClient(
+				ctx,
+				&rest.Config{},
+				kubernetes.ClientOptions{
+					SkipAuthorization: true,
+					NewInternalClient: func(
+						_ context.Context,
+						_ *rest.Config,
+						scheme *runtime.Scheme,
+					) (client.Client, error) {
+						return fake.NewClientBuilder().
+							WithScheme(scheme).
+							WithObjects(ts.objects...).
+							Build(), nil
+					},
+				},
+			)
+			require.NoError(t, err)
+
+			svr := &server{
+				client: client,
+			}
+			res, err := svr.RefreshClusterConfig(ctx, connect.NewRequest(ts.req))
+			ts.assertions(t, res, err)
+		})
+	}
+}
diff --git a/internal/server/refresh_project_config_v1alpha1_test.go b/internal/server/refresh_project_config_v1alpha1_test.go
new file mode 100644
index 00000000..9e13932d
--- /dev/null
+++ b/internal/server/refresh_project_config_v1alpha1_test.go
@@ -0,0 +1,135 @@
+package server
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"connectrpc.com/connect"
+	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/rest"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/server/kubernetes"
+	"github.com/akuity/kargo/internal/server/validation"
+)
+
+func TestRefreshProjectConfig(t *testing.T) {
+	testSets := map[string]struct {
+		req        *svcv1alpha1.RefreshProjectConfigRequest
+		objects    []client.Object
+		assertions func(*testing.T, *connect.Response[svcv1alpha1.RefreshProjectConfigResponse], error)
+	}{
+		"empty project": {
+			req: &svcv1alpha1.RefreshProjectConfigRequest{
+				Project: "",
+			},
+			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.RefreshProjectConfigResponse], err error) {
+				require.Error(t, err)
+				require.Equal(t, connect.CodeInvalidArgument, connect.CodeOf(err))
+				require.Nil(t, r)
+			},
+		},
+		"non-existing project": {
+			req: &svcv1alpha1.RefreshProjectConfigRequest{
+				Project: "kargo-x",
+			},
+			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.RefreshProjectConfigResponse], err error) {
+				require.Error(t, err)
+				require.Equal(t, connect.CodeNotFound, connect.CodeOf(err))
+				require.Nil(t, r)
+			},
+		},
+		"non-existing ProjectConfig": {
+			req: &svcv1alpha1.RefreshProjectConfigRequest{
+				Project: "kargo-demo",
+			},
+			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.RefreshProjectConfigResponse], err error) {
+				require.Error(t, err)
+				require.Equal(t, connect.CodeNotFound, connect.CodeOf(err))
+				require.Nil(t, r)
+			},
+		},
+		"existing ProjectConfig": {
+			req: &svcv1alpha1.RefreshProjectConfigRequest{
+				Project: "kargo-demo",
+			},
+			objects: []client.Object{
+				mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
+				&kargoapi.ProjectConfig{
+					TypeMeta: metav1.TypeMeta{
+						Kind:       "ProjectConfig",
+						APIVersion: kargoapi.GroupVersion.String(),
+					},
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      "kargo-demo",
+						Namespace: "kargo-demo",
+					},
+				},
+			},
+			assertions: func(t *testing.T, r *connect.Response[svcv1alpha1.RefreshProjectConfigResponse], err error) {
+				require.NoError(t, err)
+
+				config := r.Msg.GetProjectConfig()
+				require.Equal(t, "kargo-demo", config.Name)
+
+				annotation := config.GetAnnotations()[kargoapi.AnnotationKeyRefresh]
+				refreshTime, err := time.Parse(time.RFC3339, annotation)
+				require.NoError(t, err)
+
+				// Make sure we set timestamp is close to now
+				// Assume it doesn't take 3 seconds to run this unit test.
+				require.WithinDuration(t, time.Now(), refreshTime, 3*time.Second)
+
+			},
+		},
+	}
+	for name, ts := range testSets {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			ctx := context.Background()
+
+			client, err := kubernetes.NewClient(
+				ctx,
+				&rest.Config{},
+				kubernetes.ClientOptions{
+					SkipAuthorization: true,
+					NewInternalClient: func(
+						_ context.Context,
+						_ *rest.Config,
+						scheme *runtime.Scheme,
+					) (client.Client, error) {
+						return fake.NewClientBuilder().
+							WithScheme(scheme).
+							WithObjects(ts.objects...).
+							Build(), nil
+					},
+				},
+			)
+			require.NoError(t, err)
+
+			svr := &server{
+				client:                    client,
+				externalValidateProjectFn: validation.ValidateProject,
+			}
+			res, err := svr.RefreshProjectConfig(ctx, connect.NewRequest(ts.req))
+			ts.assertions(t, res, err)
+		})
+	}
+}
diff --git a/internal/webhook/external/dockerhub_test.go b/internal/webhook/external/dockerhub_test.go
new file mode 100644
index 00000000..753e6995
--- /dev/null
+++ b/internal/webhook/external/dockerhub_test.go
@@ -0,0 +1,185 @@
+package external
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"io"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
+
+	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/indexer"
+)
+
+const dockerhubWebhookRequestBody = `
+{
+	"repository": {
+		"repo_name": "example/repo"
+	}
+}`
+
+func TestDockerHubHandler(t *testing.T) {
+	const testURL = "https://webhooks.kargo.example.com/nonsense"
+
+	const testProjectName = "fake-project"
+
+	testScheme := runtime.NewScheme()
+	require.NoError(t, kargoapi.AddToScheme(testScheme))
+
+	const testToken = "mysupersecrettoken"
+	testSecretData := map[string][]byte{
+		dockerhubSecretDataKey: []byte(testToken),
+	}
+
+	testCases := []struct {
+		name       string
+		client     client.Client
+		secretData map[string][]byte
+		req        func() *http.Request
+		assertions func(*testing.T, *httptest.ResponseRecorder)
+	}{
+		{
+			name:       "request body too large",
+			secretData: testSecretData,
+			req: func() *http.Request {
+				body := make([]byte, 2<<20+1)
+				return httptest.NewRequest(
+					http.MethodPost,
+					testURL,
+					io.NopCloser(bytes.NewBuffer(body)),
+				)
+			},
+			assertions: func(t *testing.T, rr *httptest.ResponseRecorder) {
+				require.Equal(t, http.StatusRequestEntityTooLarge, rr.Code)
+				res := map[string]string{}
+				err := json.Unmarshal(rr.Body.Bytes(), &res)
+				require.NoError(t, err)
+				require.Contains(t, res["error"], "content exceeds limit")
+			},
+		},
+		{
+			name:       "malformed request body",
+			secretData: testSecretData,
+			req: func() *http.Request {
+				bodyBuf := bytes.NewBuffer([]byte("invalid json"))
+				return httptest.NewRequest(http.MethodPost, testURL, bodyBuf)
+			},
+			assertions: func(t *testing.T, rr *httptest.ResponseRecorder) {
+				require.Equal(t, http.StatusBadRequest, rr.Code)
+				require.JSONEq(t, `{"error":"invalid request body"}`, rr.Body.String())
+			},
+		},
+		{
+			name:       "partial success",
+			secretData: testSecretData,
+			client: fake.NewClientBuilder().WithScheme(testScheme).WithObjects(
+				&kargoapi.Warehouse{
+					ObjectMeta: metav1.ObjectMeta{
+						Namespace: testProjectName,
+						Name:      "fake-warehouse",
+					},
+					Spec: kargoapi.WarehouseSpec{
+						Subscriptions: []kargoapi.RepoSubscription{{
+							Image: &kargoapi.ImageSubscription{RepoURL: "example/repo"},
+						}},
+					},
+				},
+				&kargoapi.Warehouse{
+					ObjectMeta: metav1.ObjectMeta{
+						Namespace: testProjectName,
+						Name:      "another-fake-warehouse",
+					},
+					Spec: kargoapi.WarehouseSpec{
+						Subscriptions: []kargoapi.RepoSubscription{{
+							Image: &kargoapi.ImageSubscription{RepoURL: "example/repo"},
+						}},
+					},
+				},
+			).WithInterceptorFuncs(interceptor.Funcs{
+				Patch: func(
+					_ context.Context,
+					_ client.WithWatch,
+					obj client.Object,
+					_ client.Patch,
+					_ ...client.PatchOption,
+				) error {
+					if obj.GetName() == "another-fake-warehouse" {
+						return errors.New("something went wrong")
+					}
+					return nil
+				},
+			}).WithIndex(
+				&kargoapi.Warehouse{},
+				indexer.WarehousesBySubscribedURLsField,
+				indexer.WarehousesBySubscribedURLs,
+			).Build(),
+			req: func() *http.Request {
+				bodyBuf := bytes.NewBuffer([]byte(dockerhubWebhookRequestBody))
+				return httptest.NewRequest(http.MethodPost, testURL, bodyBuf)
+			},
+			assertions: func(t *testing.T, rr *httptest.ResponseRecorder) {
+				require.Equal(t, http.StatusInternalServerError, rr.Code)
+				require.JSONEq(
+					t,
+					`{"error":"failed to refresh 1 of 2 warehouses"}`,
+					rr.Body.String(),
+				)
+			},
+		},
+		{
+			name: "complete success",
+			client: fake.NewClientBuilder().WithScheme(testScheme).WithObjects(
+				&kargoapi.Warehouse{
+					ObjectMeta: metav1.ObjectMeta{
+						Namespace: testProjectName,
+						Name:      "fake-warehouse",
+					},
+					Spec: kargoapi.WarehouseSpec{
+						Subscriptions: []kargoapi.RepoSubscription{{
+							Image: &kargoapi.ImageSubscription{RepoURL: "example/repo"},
+						}},
+					},
+				},
+			).WithIndex(
+				&kargoapi.Warehouse{},
+				indexer.WarehousesBySubscribedURLsField,
+				indexer.WarehousesBySubscribedURLs,
+			).Build(),
+			req: func() *http.Request {
+				bodyBuf := bytes.NewBuffer([]byte(dockerhubWebhookRequestBody))
+				return httptest.NewRequest(http.MethodPost, testURL, bodyBuf)
+			},
+			assertions: func(t *testing.T, rr *httptest.ResponseRecorder) {
+				require.Equal(t, http.StatusOK, rr.Code)
+				require.JSONEq(
+					t,
+					`{"msg":"refreshed 1 warehouse(s)"}`,
+					rr.Body.String(),
+				)
+			},
+		},
+	}
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			w := httptest.NewRecorder()
+			(&dockerhubWebhookReceiver{
+				baseWebhookReceiver: &baseWebhookReceiver{
+					client:     testCase.client,
+					project:    testProjectName,
+					secretData: testCase.secretData,
+				},
+			}).GetHandler()(w, testCase.req())
+			testCase.assertions(t, w)
+		})
+	}
+}
diff --git a/internal/webhook/kubernetes/clusterconfig/webhook_test.go b/internal/webhook/kubernetes/clusterconfig/webhook_test.go
index 9c407bd4..079aa33b 100644
--- a/internal/webhook/kubernetes/clusterconfig/webhook_test.go
+++ b/internal/webhook/kubernetes/clusterconfig/webhook_test.go
@@ -11,6 +11,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
 )
 
 func Test_webhook_ValidateCreate(t *testing.T) {
@@ -46,7 +47,7 @@ func Test_webhook_ValidateCreate(t *testing.T) {
 			name: "duplicate webhook receiver names",
 			cfg: &kargoapi.ClusterConfig{
 				ObjectMeta: metav1.ObjectMeta{
-					Name: acceptedName,
+					Name: api.ClusterConfigName,
 				},
 				Spec: kargoapi.ClusterConfigSpec{
 					WebhookReceivers: []kargoapi.WebhookReceiverConfig{
@@ -87,7 +88,7 @@ func Test_webhook_ValidateCreate(t *testing.T) {
 			name: "valid cluster config",
 			cfg: &kargoapi.ClusterConfig{
 				ObjectMeta: metav1.ObjectMeta{
-					Name: acceptedName,
+					Name: api.ClusterConfigName,
 				},
 				Spec: kargoapi.ClusterConfigSpec{
 					WebhookReceivers: []kargoapi.WebhookReceiverConfig{
@@ -121,7 +122,7 @@ func Test_webhook_ValidateUpdate(t *testing.T) {
 			name: "duplicate webhook receiver names",
 			cfg: &kargoapi.ClusterConfig{
 				ObjectMeta: metav1.ObjectMeta{
-					Name: acceptedName,
+					Name: api.ClusterConfigName,
 				},
 				Spec: kargoapi.ClusterConfigSpec{
 					WebhookReceivers: []kargoapi.WebhookReceiverConfig{
@@ -162,7 +163,7 @@ func Test_webhook_ValidateUpdate(t *testing.T) {
 			name: "valid cluster config",
 			cfg: &kargoapi.ClusterConfig{
 				ObjectMeta: metav1.ObjectMeta{
-					Name: acceptedName,
+					Name: api.ClusterConfigName,
 				},
 				Spec: kargoapi.ClusterConfigSpec{
 					WebhookReceivers: []kargoapi.WebhookReceiverConfig{