Repository: akuity/kargo

Issue:
UI: aggregate argocd deep links back to stage view
# Checklist

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

# Proposed Feature

With promotion steps, argocd meta info became stage agnostic so technically they belongs to individual promotions. But in most cases it rarely changes and logically it is safe to attach with stage meta. So proposal is to move back the ArgoCD deep links to top of Stage details view rather than in individual promotions column. Or we can keep at both places.

# Motivation

Previously it was at top of stage view and is more accessible there rather than individual promotion steps.

# Suggested Implementation

Reuse the logic of deep link construction in individual promotion for all promotions and show the list of links on top of Stage details view

Discussion:
@jessesuen: I feel like we might just want to remove the guesswork/inference, and just start using Stage annotations and be explicit about creating links based on the apps mentioned in the annotations.@Marvin9: @hiddeco @krancour does controller needs to plug this information to stage?@krancour: Not if it's done with annotations.

Solution patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 48ce9fd9..6aa9dc60 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -17,7 +17,7 @@ jobs:
   test-unit:
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     steps:
     # Install Git from "trixie" repository to get a more recent version than
     # the one available in "stable". This can be removed once the version in
@@ -42,7 +42,7 @@ jobs:
         grep -v .pb.go coverage.txt | grep -v zz_generated | grep -v service.connect.go > coverage.tmp
         mv coverage.tmp coverage.txt
     - name: Upload coverage reports
-      uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
+      uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
       with:
         token: ${{ secrets.CODECOV_TOKEN }}
   
@@ -77,7 +77,7 @@ jobs:
       checks: write # Used to create checks (linting comments) on PRs
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     steps:
     - name: Checkout code
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -102,7 +102,7 @@ jobs:
   lint-charts:
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     steps:
     - name: Checkout code
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -126,7 +126,7 @@ jobs:
       checks: write # Used to create checks (linting comments) on PRs
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     steps:
     - name: Checkout code
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -149,7 +149,7 @@ jobs:
   check-codegen:
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     steps:
     - name: Checkout code
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -225,7 +225,7 @@ jobs:
     needs: [test-unit, lint-go, lint-charts, lint-proto, lint-and-typecheck-ui, check-codegen]
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     steps:
     - name: Checkout code
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index bf468a46..f6a76b71 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -177,7 +177,7 @@ jobs:
     if: github.event_name == 'release'
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     strategy:
       matrix:
         os: [linux, darwin, windows]
@@ -245,7 +245,7 @@ jobs:
     if: github.event_name != 'release'
     runs-on: ubuntu-latest
     container:
-      image: golang:1.23.5-bookworm
+      image: golang:1.24.1-bookworm
     strategy:
       matrix:
         os: [linux, darwin, windows]
diff --git a/Dockerfile b/Dockerfile
index f251866a..2049ff1d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,7 +20,7 @@ RUN NODE_ENV='production' VERSION=${VERSION} pnpm run build
 ####################################################################################################
 # back-end-builder
 ####################################################################################################
-FROM --platform=$BUILDPLATFORM golang:1.24.0-bookworm AS back-end-builder
+FROM --platform=$BUILDPLATFORM golang:1.24.1-bookworm AS back-end-builder
 
 ARG TARGETOS
 ARG TARGETARCH
diff --git a/Dockerfile.dev b/Dockerfile.dev
index 2b75c054..6c791c00 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -1,4 +1,4 @@
-FROM golang:1.24.0-bookworm
+FROM golang:1.24.1-bookworm
 
 ARG TARGETARCH
 
diff --git a/Makefile b/Makefile
index 394e2c92..3c87b681 100644
--- a/Makefile
+++ b/Makefile
@@ -83,7 +83,8 @@ format-go:
 lint-proto: install-buf
 	# Vendor go dependencies to build protobuf definitions
 	go mod vendor
-	$(BUF) lint api --error-format=$(BUF_LINT_ERROR_FORMAT)
+	@# Only lint hand-written .proto files
+	$(BUF) lint . --path api/service --error-format=$(BUF_LINT_ERROR_FORMAT)
 
 .PHONY: lint-charts
 lint-charts: install-helm
diff --git a/pkg/api/service/v1alpha1/service.pb.go b/api/service/v1alpha1/service.pb.go
similarity index 70%
rename from pkg/api/service/v1alpha1/service.pb.go
rename to api/service/v1alpha1/service.pb.go
index 787dce90..fc0e4fbd 100644
--- a/pkg/api/service/v1alpha1/service.pb.go
+++ b/api/service/v1alpha1/service.pb.go
@@ -2,14 +2,14 @@
 // versions:
 // 	protoc-gen-go v1.33.0
 // 	protoc        (unknown)
-// source: service/v1alpha1/service.proto
+// source: api/service/v1alpha1/service.proto
 
 package svcv1alpha1
 
 import (
 	v1alpha12 "github.com/akuity/kargo/api/rbac/v1alpha1"
+	v1alpha11 "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	v1alpha1 "github.com/akuity/kargo/api/v1alpha1"
-	v1alpha11 "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
@@ -58,11 +58,11 @@ func (x RawFormat) String() string {
 }
 
 func (RawFormat) Descriptor() protoreflect.EnumDescriptor {
-	return file_service_v1alpha1_service_proto_enumTypes[0].Descriptor()
+	return file_api_service_v1alpha1_service_proto_enumTypes[0].Descriptor()
 }
 
 func (RawFormat) Type() protoreflect.EnumType {
-	return &file_service_v1alpha1_service_proto_enumTypes[0]
+	return &file_api_service_v1alpha1_service_proto_enumTypes[0]
 }
 
 func (x RawFormat) Number() protoreflect.EnumNumber {
@@ -71,7 +71,7 @@ func (x RawFormat) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use RawFormat.Descriptor instead.
 func (RawFormat) EnumDescriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{0}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{0}
 }
 
 type ComponentVersions struct {
@@ -86,7 +86,7 @@ type ComponentVersions struct {
 func (x *ComponentVersions) Reset() {
 	*x = ComponentVersions{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[0]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -99,7 +99,7 @@ func (x *ComponentVersions) String() string {
 func (*ComponentVersions) ProtoMessage() {}
 
 func (x *ComponentVersions) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[0]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -112,7 +112,7 @@ func (x *ComponentVersions) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ComponentVersions.ProtoReflect.Descriptor instead.
 func (*ComponentVersions) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{0}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *ComponentVersions) GetServer() *VersionInfo {
@@ -146,7 +146,7 @@ type VersionInfo struct {
 func (x *VersionInfo) Reset() {
 	*x = VersionInfo{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[1]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -159,7 +159,7 @@ func (x *VersionInfo) String() string {
 func (*VersionInfo) ProtoMessage() {}
 
 func (x *VersionInfo) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[1]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -172,7 +172,7 @@ func (x *VersionInfo) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use VersionInfo.ProtoReflect.Descriptor instead.
 func (*VersionInfo) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{1}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *VersionInfo) GetVersion() string {
@@ -233,7 +233,7 @@ type GetVersionInfoRequest struct {
 func (x *GetVersionInfoRequest) Reset() {
 	*x = GetVersionInfoRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[2]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -246,7 +246,7 @@ func (x *GetVersionInfoRequest) String() string {
 func (*GetVersionInfoRequest) ProtoMessage() {}
 
 func (x *GetVersionInfoRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[2]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -259,7 +259,7 @@ func (x *GetVersionInfoRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetVersionInfoRequest.ProtoReflect.Descriptor instead.
 func (*GetVersionInfoRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{2}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{2}
 }
 
 type GetVersionInfoResponse struct {
@@ -273,7 +273,7 @@ type GetVersionInfoResponse struct {
 func (x *GetVersionInfoResponse) Reset() {
 	*x = GetVersionInfoResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[3]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -286,7 +286,7 @@ func (x *GetVersionInfoResponse) String() string {
 func (*GetVersionInfoResponse) ProtoMessage() {}
 
 func (x *GetVersionInfoResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[3]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -299,7 +299,7 @@ func (x *GetVersionInfoResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetVersionInfoResponse.ProtoReflect.Descriptor instead.
 func (*GetVersionInfoResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{3}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *GetVersionInfoResponse) GetVersionInfo() *VersionInfo {
@@ -318,7 +318,7 @@ type GetConfigRequest struct {
 func (x *GetConfigRequest) Reset() {
 	*x = GetConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[4]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -331,7 +331,7 @@ func (x *GetConfigRequest) String() string {
 func (*GetConfigRequest) ProtoMessage() {}
 
 func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[4]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -344,7 +344,7 @@ func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
 func (*GetConfigRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{4}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{4}
 }
 
 type ArgoCDShard struct {
@@ -359,7 +359,7 @@ type ArgoCDShard struct {
 func (x *ArgoCDShard) Reset() {
 	*x = ArgoCDShard{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[5]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -372,7 +372,7 @@ func (x *ArgoCDShard) String() string {
 func (*ArgoCDShard) ProtoMessage() {}
 
 func (x *ArgoCDShard) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[5]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -385,7 +385,7 @@ func (x *ArgoCDShard) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ArgoCDShard.ProtoReflect.Descriptor instead.
 func (*ArgoCDShard) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{5}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *ArgoCDShard) GetUrl() string {
@@ -414,7 +414,7 @@ type GetConfigResponse struct {
 func (x *GetConfigResponse) Reset() {
 	*x = GetConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[6]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -427,7 +427,7 @@ func (x *GetConfigResponse) String() string {
 func (*GetConfigResponse) ProtoMessage() {}
 
 func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[6]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -440,7 +440,7 @@ func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
 func (*GetConfigResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{6}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *GetConfigResponse) GetArgocdShards() map[string]*ArgoCDShard {
@@ -466,7 +466,7 @@ type GetPublicConfigRequest struct {
 func (x *GetPublicConfigRequest) Reset() {
 	*x = GetPublicConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[7]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -479,7 +479,7 @@ func (x *GetPublicConfigRequest) String() string {
 func (*GetPublicConfigRequest) ProtoMessage() {}
 
 func (x *GetPublicConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[7]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -492,7 +492,7 @@ func (x *GetPublicConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetPublicConfigRequest.ProtoReflect.Descriptor instead.
 func (*GetPublicConfigRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{7}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{7}
 }
 
 type GetPublicConfigResponse struct {
@@ -508,7 +508,7 @@ type GetPublicConfigResponse struct {
 func (x *GetPublicConfigResponse) Reset() {
 	*x = GetPublicConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[8]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -521,7 +521,7 @@ func (x *GetPublicConfigResponse) String() string {
 func (*GetPublicConfigResponse) ProtoMessage() {}
 
 func (x *GetPublicConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[8]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -534,7 +534,7 @@ func (x *GetPublicConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetPublicConfigResponse.ProtoReflect.Descriptor instead.
 func (*GetPublicConfigResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{8}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *GetPublicConfigResponse) GetOidcConfig() *OIDCConfig {
@@ -572,7 +572,7 @@ type OIDCConfig struct {
 func (x *OIDCConfig) Reset() {
 	*x = OIDCConfig{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[9]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -585,7 +585,7 @@ func (x *OIDCConfig) String() string {
 func (*OIDCConfig) ProtoMessage() {}
 
 func (x *OIDCConfig) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[9]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -598,7 +598,7 @@ func (x *OIDCConfig) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use OIDCConfig.ProtoReflect.Descriptor instead.
 func (*OIDCConfig) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{9}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{9}
 }
 
 func (x *OIDCConfig) GetIssuerUrl() string {
@@ -640,7 +640,7 @@ type AdminLoginRequest struct {
 func (x *AdminLoginRequest) Reset() {
 	*x = AdminLoginRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[10]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -653,7 +653,7 @@ func (x *AdminLoginRequest) String() string {
 func (*AdminLoginRequest) ProtoMessage() {}
 
 func (x *AdminLoginRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[10]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -666,7 +666,7 @@ func (x *AdminLoginRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AdminLoginRequest.ProtoReflect.Descriptor instead.
 func (*AdminLoginRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{10}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *AdminLoginRequest) GetPassword() string {
@@ -687,7 +687,7 @@ type AdminLoginResponse struct {
 func (x *AdminLoginResponse) Reset() {
 	*x = AdminLoginResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[11]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[11]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -700,7 +700,7 @@ func (x *AdminLoginResponse) String() string {
 func (*AdminLoginResponse) ProtoMessage() {}
 
 func (x *AdminLoginResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[11]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[11]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -713,7 +713,7 @@ func (x *AdminLoginResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AdminLoginResponse.ProtoReflect.Descriptor instead.
 func (*AdminLoginResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{11}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{11}
 }
 
 func (x *AdminLoginResponse) GetIdToken() string {
@@ -734,7 +734,7 @@ type CreateResourceRequest struct {
 func (x *CreateResourceRequest) Reset() {
 	*x = CreateResourceRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[12]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[12]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -747,7 +747,7 @@ func (x *CreateResourceRequest) String() string {
 func (*CreateResourceRequest) ProtoMessage() {}
 
 func (x *CreateResourceRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[12]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[12]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -760,7 +760,7 @@ func (x *CreateResourceRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateResourceRequest.ProtoReflect.Descriptor instead.
 func (*CreateResourceRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{12}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{12}
 }
 
 func (x *CreateResourceRequest) GetManifest() []byte {
@@ -785,7 +785,7 @@ type CreateResourceResult struct {
 func (x *CreateResourceResult) Reset() {
 	*x = CreateResourceResult{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[13]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[13]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -798,7 +798,7 @@ func (x *CreateResourceResult) String() string {
 func (*CreateResourceResult) ProtoMessage() {}
 
 func (x *CreateResourceResult) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[13]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[13]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -811,7 +811,7 @@ func (x *CreateResourceResult) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateResourceResult.ProtoReflect.Descriptor instead.
 func (*CreateResourceResult) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{13}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{13}
 }
 
 func (m *CreateResourceResult) GetResult() isCreateResourceResult_Result {
@@ -862,7 +862,7 @@ type CreateResourceResponse struct {
 func (x *CreateResourceResponse) Reset() {
 	*x = CreateResourceResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[14]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[14]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -875,7 +875,7 @@ func (x *CreateResourceResponse) String() string {
 func (*CreateResourceResponse) ProtoMessage() {}
 
 func (x *CreateResourceResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[14]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[14]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -888,7 +888,7 @@ func (x *CreateResourceResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateResourceResponse.ProtoReflect.Descriptor instead.
 func (*CreateResourceResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{14}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{14}
 }
 
 func (x *CreateResourceResponse) GetResults() []*CreateResourceResult {
@@ -909,7 +909,7 @@ type CreateOrUpdateResourceRequest struct {
 func (x *CreateOrUpdateResourceRequest) Reset() {
 	*x = CreateOrUpdateResourceRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[15]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[15]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -922,7 +922,7 @@ func (x *CreateOrUpdateResourceRequest) String() string {
 func (*CreateOrUpdateResourceRequest) ProtoMessage() {}
 
 func (x *CreateOrUpdateResourceRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[15]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[15]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -935,7 +935,7 @@ func (x *CreateOrUpdateResourceRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateOrUpdateResourceRequest.ProtoReflect.Descriptor instead.
 func (*CreateOrUpdateResourceRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{15}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{15}
 }
 
 func (x *CreateOrUpdateResourceRequest) GetManifest() []byte {
@@ -961,7 +961,7 @@ type CreateOrUpdateResourceResult struct {
 func (x *CreateOrUpdateResourceResult) Reset() {
 	*x = CreateOrUpdateResourceResult{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[16]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[16]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -974,7 +974,7 @@ func (x *CreateOrUpdateResourceResult) String() string {
 func (*CreateOrUpdateResourceResult) ProtoMessage() {}
 
 func (x *CreateOrUpdateResourceResult) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[16]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[16]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -987,7 +987,7 @@ func (x *CreateOrUpdateResourceResult) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateOrUpdateResourceResult.ProtoReflect.Descriptor instead.
 func (*CreateOrUpdateResourceResult) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{16}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{16}
 }
 
 func (m *CreateOrUpdateResourceResult) GetResult() isCreateOrUpdateResourceResult_Result {
@@ -1053,7 +1053,7 @@ type CreateOrUpdateResourceResponse struct {
 func (x *CreateOrUpdateResourceResponse) Reset() {
 	*x = CreateOrUpdateResourceResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[17]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[17]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1066,7 +1066,7 @@ func (x *CreateOrUpdateResourceResponse) String() string {
 func (*CreateOrUpdateResourceResponse) ProtoMessage() {}
 
 func (x *CreateOrUpdateResourceResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[17]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[17]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1079,7 +1079,7 @@ func (x *CreateOrUpdateResourceResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateOrUpdateResourceResponse.ProtoReflect.Descriptor instead.
 func (*CreateOrUpdateResourceResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{17}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{17}
 }
 
 func (x *CreateOrUpdateResourceResponse) GetResults() []*CreateOrUpdateResourceResult {
@@ -1100,7 +1100,7 @@ type UpdateResourceRequest struct {
 func (x *UpdateResourceRequest) Reset() {
 	*x = UpdateResourceRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[18]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[18]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1113,7 +1113,7 @@ func (x *UpdateResourceRequest) String() string {
 func (*UpdateResourceRequest) ProtoMessage() {}
 
 func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[18]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[18]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1126,7 +1126,7 @@ func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateResourceRequest.ProtoReflect.Descriptor instead.
 func (*UpdateResourceRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{18}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{18}
 }
 
 func (x *UpdateResourceRequest) GetManifest() []byte {
@@ -1151,7 +1151,7 @@ type UpdateResourceResult struct {
 func (x *UpdateResourceResult) Reset() {
 	*x = UpdateResourceResult{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[19]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[19]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1164,7 +1164,7 @@ func (x *UpdateResourceResult) String() string {
 func (*UpdateResourceResult) ProtoMessage() {}
 
 func (x *UpdateResourceResult) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[19]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[19]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1177,7 +1177,7 @@ func (x *UpdateResourceResult) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateResourceResult.ProtoReflect.Descriptor instead.
 func (*UpdateResourceResult) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{19}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{19}
 }
 
 func (m *UpdateResourceResult) GetResult() isUpdateResourceResult_Result {
@@ -1228,7 +1228,7 @@ type UpdateResourceResponse struct {
 func (x *UpdateResourceResponse) Reset() {
 	*x = UpdateResourceResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[20]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[20]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1241,7 +1241,7 @@ func (x *UpdateResourceResponse) String() string {
 func (*UpdateResourceResponse) ProtoMessage() {}
 
 func (x *UpdateResourceResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[20]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[20]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1254,7 +1254,7 @@ func (x *UpdateResourceResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateResourceResponse.ProtoReflect.Descriptor instead.
 func (*UpdateResourceResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{20}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{20}
 }
 
 func (x *UpdateResourceResponse) GetResults() []*UpdateResourceResult {
@@ -1275,7 +1275,7 @@ type DeleteResourceRequest struct {
 func (x *DeleteResourceRequest) Reset() {
 	*x = DeleteResourceRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[21]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[21]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1288,7 +1288,7 @@ func (x *DeleteResourceRequest) String() string {
 func (*DeleteResourceRequest) ProtoMessage() {}
 
 func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[21]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[21]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1301,7 +1301,7 @@ func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteResourceRequest.ProtoReflect.Descriptor instead.
 func (*DeleteResourceRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{21}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{21}
 }
 
 func (x *DeleteResourceRequest) GetManifest() []byte {
@@ -1326,7 +1326,7 @@ type DeleteResourceResult struct {
 func (x *DeleteResourceResult) Reset() {
 	*x = DeleteResourceResult{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[22]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[22]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1339,7 +1339,7 @@ func (x *DeleteResourceResult) String() string {
 func (*DeleteResourceResult) ProtoMessage() {}
 
 func (x *DeleteResourceResult) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[22]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[22]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1352,7 +1352,7 @@ func (x *DeleteResourceResult) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteResourceResult.ProtoReflect.Descriptor instead.
 func (*DeleteResourceResult) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{22}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{22}
 }
 
 func (m *DeleteResourceResult) GetResult() isDeleteResourceResult_Result {
@@ -1403,7 +1403,7 @@ type DeleteResourceResponse struct {
 func (x *DeleteResourceResponse) Reset() {
 	*x = DeleteResourceResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[23]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[23]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1416,7 +1416,7 @@ func (x *DeleteResourceResponse) String() string {
 func (*DeleteResourceResponse) ProtoMessage() {}
 
 func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[23]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[23]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1429,7 +1429,7 @@ func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteResourceResponse.ProtoReflect.Descriptor instead.
 func (*DeleteResourceResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{23}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{23}
 }
 
 func (x *DeleteResourceResponse) GetResults() []*DeleteResourceResult {
@@ -1450,7 +1450,7 @@ type ListStagesRequest struct {
 func (x *ListStagesRequest) Reset() {
 	*x = ListStagesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[24]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[24]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1463,7 +1463,7 @@ func (x *ListStagesRequest) String() string {
 func (*ListStagesRequest) ProtoMessage() {}
 
 func (x *ListStagesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[24]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[24]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1476,7 +1476,7 @@ func (x *ListStagesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListStagesRequest.ProtoReflect.Descriptor instead.
 func (*ListStagesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{24}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{24}
 }
 
 func (x *ListStagesRequest) GetProject() string {
@@ -1497,7 +1497,7 @@ type ListStagesResponse struct {
 func (x *ListStagesResponse) Reset() {
 	*x = ListStagesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[25]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[25]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1510,7 +1510,7 @@ func (x *ListStagesResponse) String() string {
 func (*ListStagesResponse) ProtoMessage() {}
 
 func (x *ListStagesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[25]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[25]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1523,7 +1523,7 @@ func (x *ListStagesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListStagesResponse.ProtoReflect.Descriptor instead.
 func (*ListStagesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{25}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{25}
 }
 
 func (x *ListStagesResponse) GetStages() []*v1alpha1.Stage {
@@ -1544,7 +1544,7 @@ type ListImagesRequest struct {
 func (x *ListImagesRequest) Reset() {
 	*x = ListImagesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[26]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[26]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1557,7 +1557,7 @@ func (x *ListImagesRequest) String() string {
 func (*ListImagesRequest) ProtoMessage() {}
 
 func (x *ListImagesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[26]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[26]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1570,7 +1570,7 @@ func (x *ListImagesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListImagesRequest.ProtoReflect.Descriptor instead.
 func (*ListImagesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{26}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{26}
 }
 
 func (x *ListImagesRequest) GetProject() string {
@@ -1592,7 +1592,7 @@ type ListImagesResponse struct {
 func (x *ListImagesResponse) Reset() {
 	*x = ListImagesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[27]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[27]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1605,7 +1605,7 @@ func (x *ListImagesResponse) String() string {
 func (*ListImagesResponse) ProtoMessage() {}
 
 func (x *ListImagesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[27]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[27]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1618,7 +1618,7 @@ func (x *ListImagesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListImagesResponse.ProtoReflect.Descriptor instead.
 func (*ListImagesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{27}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{27}
 }
 
 func (x *ListImagesResponse) GetImages() map[string]*TagMap {
@@ -1640,7 +1640,7 @@ type TagMap struct {
 func (x *TagMap) Reset() {
 	*x = TagMap{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[28]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[28]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1653,7 +1653,7 @@ func (x *TagMap) String() string {
 func (*TagMap) ProtoMessage() {}
 
 func (x *TagMap) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[28]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[28]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1666,7 +1666,7 @@ func (x *TagMap) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use TagMap.ProtoReflect.Descriptor instead.
 func (*TagMap) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{28}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{28}
 }
 
 func (x *TagMap) GetTags() map[string]*ImageStageMap {
@@ -1688,7 +1688,7 @@ type ImageStageMap struct {
 func (x *ImageStageMap) Reset() {
 	*x = ImageStageMap{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[29]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[29]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1701,7 +1701,7 @@ func (x *ImageStageMap) String() string {
 func (*ImageStageMap) ProtoMessage() {}
 
 func (x *ImageStageMap) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[29]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[29]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1714,7 +1714,7 @@ func (x *ImageStageMap) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ImageStageMap.ProtoReflect.Descriptor instead.
 func (*ImageStageMap) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{29}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{29}
 }
 
 func (x *ImageStageMap) GetStages() map[string]int32 {
@@ -1737,7 +1737,7 @@ type GetStageRequest struct {
 func (x *GetStageRequest) Reset() {
 	*x = GetStageRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[30]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[30]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1750,7 +1750,7 @@ func (x *GetStageRequest) String() string {
 func (*GetStageRequest) ProtoMessage() {}
 
 func (x *GetStageRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[30]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[30]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1763,7 +1763,7 @@ func (x *GetStageRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetStageRequest.ProtoReflect.Descriptor instead.
 func (*GetStageRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{30}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{30}
 }
 
 func (x *GetStageRequest) GetProject() string {
@@ -1802,7 +1802,7 @@ type GetStageResponse struct {
 func (x *GetStageResponse) Reset() {
 	*x = GetStageResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[31]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[31]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1815,7 +1815,7 @@ func (x *GetStageResponse) String() string {
 func (*GetStageResponse) ProtoMessage() {}
 
 func (x *GetStageResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[31]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[31]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1828,7 +1828,7 @@ func (x *GetStageResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetStageResponse.ProtoReflect.Descriptor instead.
 func (*GetStageResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{31}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{31}
 }
 
 func (m *GetStageResponse) GetResult() isGetStageResponse_Result {
@@ -1880,7 +1880,7 @@ type WatchStagesRequest struct {
 func (x *WatchStagesRequest) Reset() {
 	*x = WatchStagesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[32]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[32]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1893,7 +1893,7 @@ func (x *WatchStagesRequest) String() string {
 func (*WatchStagesRequest) ProtoMessage() {}
 
 func (x *WatchStagesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[32]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[32]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1906,7 +1906,7 @@ func (x *WatchStagesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchStagesRequest.ProtoReflect.Descriptor instead.
 func (*WatchStagesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{32}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{32}
 }
 
 func (x *WatchStagesRequest) GetProject() string {
@@ -1935,7 +1935,7 @@ type WatchStagesResponse struct {
 func (x *WatchStagesResponse) Reset() {
 	*x = WatchStagesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[33]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[33]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1948,7 +1948,7 @@ func (x *WatchStagesResponse) String() string {
 func (*WatchStagesResponse) ProtoMessage() {}
 
 func (x *WatchStagesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[33]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[33]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1961,7 +1961,7 @@ func (x *WatchStagesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchStagesResponse.ProtoReflect.Descriptor instead.
 func (*WatchStagesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{33}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{33}
 }
 
 func (x *WatchStagesResponse) GetStage() *v1alpha1.Stage {
@@ -1990,7 +1990,7 @@ type DeleteStageRequest struct {
 func (x *DeleteStageRequest) Reset() {
 	*x = DeleteStageRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[34]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[34]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2003,7 +2003,7 @@ func (x *DeleteStageRequest) String() string {
 func (*DeleteStageRequest) ProtoMessage() {}
 
 func (x *DeleteStageRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[34]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[34]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2016,7 +2016,7 @@ func (x *DeleteStageRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteStageRequest.ProtoReflect.Descriptor instead.
 func (*DeleteStageRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{34}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{34}
 }
 
 func (x *DeleteStageRequest) GetProject() string {
@@ -2042,7 +2042,7 @@ type DeleteStageResponse struct {
 func (x *DeleteStageResponse) Reset() {
 	*x = DeleteStageResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[35]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[35]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2055,7 +2055,7 @@ func (x *DeleteStageResponse) String() string {
 func (*DeleteStageResponse) ProtoMessage() {}
 
 func (x *DeleteStageResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[35]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[35]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2068,7 +2068,7 @@ func (x *DeleteStageResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteStageResponse.ProtoReflect.Descriptor instead.
 func (*DeleteStageResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{35}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{35}
 }
 
 type RefreshStageRequest struct {
@@ -2083,7 +2083,7 @@ type RefreshStageRequest struct {
 func (x *RefreshStageRequest) Reset() {
 	*x = RefreshStageRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[36]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[36]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2096,7 +2096,7 @@ func (x *RefreshStageRequest) String() string {
 func (*RefreshStageRequest) ProtoMessage() {}
 
 func (x *RefreshStageRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[36]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[36]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2109,7 +2109,7 @@ func (x *RefreshStageRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RefreshStageRequest.ProtoReflect.Descriptor instead.
 func (*RefreshStageRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{36}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{36}
 }
 
 func (x *RefreshStageRequest) GetProject() string {
@@ -2137,7 +2137,7 @@ type RefreshStageResponse struct {
 func (x *RefreshStageResponse) Reset() {
 	*x = RefreshStageResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[37]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[37]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2150,7 +2150,7 @@ func (x *RefreshStageResponse) String() string {
 func (*RefreshStageResponse) ProtoMessage() {}
 
 func (x *RefreshStageResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[37]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[37]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2163,7 +2163,7 @@ func (x *RefreshStageResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RefreshStageResponse.ProtoReflect.Descriptor instead.
 func (*RefreshStageResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{37}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{37}
 }
 
 func (x *RefreshStageResponse) GetStage() *v1alpha1.Stage {
@@ -2185,7 +2185,7 @@ type ListPromotionsRequest struct {
 func (x *ListPromotionsRequest) Reset() {
 	*x = ListPromotionsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[38]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[38]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2198,7 +2198,7 @@ func (x *ListPromotionsRequest) String() string {
 func (*ListPromotionsRequest) ProtoMessage() {}
 
 func (x *ListPromotionsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[38]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[38]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2211,7 +2211,7 @@ func (x *ListPromotionsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListPromotionsRequest.ProtoReflect.Descriptor instead.
 func (*ListPromotionsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{38}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{38}
 }
 
 func (x *ListPromotionsRequest) GetProject() string {
@@ -2239,7 +2239,7 @@ type ListPromotionsResponse struct {
 func (x *ListPromotionsResponse) Reset() {
 	*x = ListPromotionsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[39]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[39]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2252,7 +2252,7 @@ func (x *ListPromotionsResponse) String() string {
 func (*ListPromotionsResponse) ProtoMessage() {}
 
 func (x *ListPromotionsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[39]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[39]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2265,7 +2265,7 @@ func (x *ListPromotionsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListPromotionsResponse.ProtoReflect.Descriptor instead.
 func (*ListPromotionsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{39}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{39}
 }
 
 func (x *ListPromotionsResponse) GetPromotions() []*v1alpha1.Promotion {
@@ -2287,7 +2287,7 @@ type WatchPromotionsRequest struct {
 func (x *WatchPromotionsRequest) Reset() {
 	*x = WatchPromotionsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[40]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[40]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2300,7 +2300,7 @@ func (x *WatchPromotionsRequest) String() string {
 func (*WatchPromotionsRequest) ProtoMessage() {}
 
 func (x *WatchPromotionsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[40]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[40]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2313,7 +2313,7 @@ func (x *WatchPromotionsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchPromotionsRequest.ProtoReflect.Descriptor instead.
 func (*WatchPromotionsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{40}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{40}
 }
 
 func (x *WatchPromotionsRequest) GetProject() string {
@@ -2342,7 +2342,7 @@ type WatchPromotionsResponse struct {
 func (x *WatchPromotionsResponse) Reset() {
 	*x = WatchPromotionsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[41]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[41]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2355,7 +2355,7 @@ func (x *WatchPromotionsResponse) String() string {
 func (*WatchPromotionsResponse) ProtoMessage() {}
 
 func (x *WatchPromotionsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[41]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[41]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2368,7 +2368,7 @@ func (x *WatchPromotionsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchPromotionsResponse.ProtoReflect.Descriptor instead.
 func (*WatchPromotionsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{41}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{41}
 }
 
 func (x *WatchPromotionsResponse) GetPromotion() *v1alpha1.Promotion {
@@ -2398,7 +2398,7 @@ type GetPromotionRequest struct {
 func (x *GetPromotionRequest) Reset() {
 	*x = GetPromotionRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[42]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[42]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2411,7 +2411,7 @@ func (x *GetPromotionRequest) String() string {
 func (*GetPromotionRequest) ProtoMessage() {}
 
 func (x *GetPromotionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[42]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[42]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2424,7 +2424,7 @@ func (x *GetPromotionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetPromotionRequest.ProtoReflect.Descriptor instead.
 func (*GetPromotionRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{42}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{42}
 }
 
 func (x *GetPromotionRequest) GetProject() string {
@@ -2463,7 +2463,7 @@ type GetPromotionResponse struct {
 func (x *GetPromotionResponse) Reset() {
 	*x = GetPromotionResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[43]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[43]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2476,7 +2476,7 @@ func (x *GetPromotionResponse) String() string {
 func (*GetPromotionResponse) ProtoMessage() {}
 
 func (x *GetPromotionResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[43]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[43]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2489,7 +2489,7 @@ func (x *GetPromotionResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetPromotionResponse.ProtoReflect.Descriptor instead.
 func (*GetPromotionResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{43}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{43}
 }
 
 func (m *GetPromotionResponse) GetResult() isGetPromotionResponse_Result {
@@ -2541,7 +2541,7 @@ type WatchPromotionRequest struct {
 func (x *WatchPromotionRequest) Reset() {
 	*x = WatchPromotionRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[44]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[44]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2554,7 +2554,7 @@ func (x *WatchPromotionRequest) String() string {
 func (*WatchPromotionRequest) ProtoMessage() {}
 
 func (x *WatchPromotionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[44]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[44]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2567,7 +2567,7 @@ func (x *WatchPromotionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchPromotionRequest.ProtoReflect.Descriptor instead.
 func (*WatchPromotionRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{44}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{44}
 }
 
 func (x *WatchPromotionRequest) GetProject() string {
@@ -2596,7 +2596,7 @@ type WatchPromotionResponse struct {
 func (x *WatchPromotionResponse) Reset() {
 	*x = WatchPromotionResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[45]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[45]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2609,7 +2609,7 @@ func (x *WatchPromotionResponse) String() string {
 func (*WatchPromotionResponse) ProtoMessage() {}
 
 func (x *WatchPromotionResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[45]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[45]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2622,7 +2622,7 @@ func (x *WatchPromotionResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchPromotionResponse.ProtoReflect.Descriptor instead.
 func (*WatchPromotionResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{45}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{45}
 }
 
 func (x *WatchPromotionResponse) GetPromotion() *v1alpha1.Promotion {
@@ -2651,7 +2651,7 @@ type AbortPromotionRequest struct {
 func (x *AbortPromotionRequest) Reset() {
 	*x = AbortPromotionRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[46]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[46]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2664,7 +2664,7 @@ func (x *AbortPromotionRequest) String() string {
 func (*AbortPromotionRequest) ProtoMessage() {}
 
 func (x *AbortPromotionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[46]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[46]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2677,7 +2677,7 @@ func (x *AbortPromotionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AbortPromotionRequest.ProtoReflect.Descriptor instead.
 func (*AbortPromotionRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{46}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{46}
 }
 
 func (x *AbortPromotionRequest) GetProject() string {
@@ -2703,7 +2703,7 @@ type AbortPromotionResponse struct {
 func (x *AbortPromotionResponse) Reset() {
 	*x = AbortPromotionResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[47]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[47]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2716,7 +2716,7 @@ func (x *AbortPromotionResponse) String() string {
 func (*AbortPromotionResponse) ProtoMessage() {}
 
 func (x *AbortPromotionResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[47]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[47]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2729,7 +2729,7 @@ func (x *AbortPromotionResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AbortPromotionResponse.ProtoReflect.Descriptor instead.
 func (*AbortPromotionResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{47}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{47}
 }
 
 type DeleteProjectRequest struct {
@@ -2743,7 +2743,7 @@ type DeleteProjectRequest struct {
 func (x *DeleteProjectRequest) Reset() {
 	*x = DeleteProjectRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[48]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[48]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2756,7 +2756,7 @@ func (x *DeleteProjectRequest) String() string {
 func (*DeleteProjectRequest) ProtoMessage() {}
 
 func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[48]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[48]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2769,7 +2769,7 @@ func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteProjectRequest.ProtoReflect.Descriptor instead.
 func (*DeleteProjectRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{48}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{48}
 }
 
 func (x *DeleteProjectRequest) GetName() string {
@@ -2788,7 +2788,7 @@ type DeleteProjectResponse struct {
 func (x *DeleteProjectResponse) Reset() {
 	*x = DeleteProjectResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[49]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[49]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2801,7 +2801,7 @@ func (x *DeleteProjectResponse) String() string {
 func (*DeleteProjectResponse) ProtoMessage() {}
 
 func (x *DeleteProjectResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[49]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[49]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2814,7 +2814,7 @@ func (x *DeleteProjectResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteProjectResponse.ProtoReflect.Descriptor instead.
 func (*DeleteProjectResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{49}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{49}
 }
 
 type GetProjectRequest struct {
@@ -2829,7 +2829,7 @@ type GetProjectRequest struct {
 func (x *GetProjectRequest) Reset() {
 	*x = GetProjectRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[50]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[50]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2842,7 +2842,7 @@ func (x *GetProjectRequest) String() string {
 func (*GetProjectRequest) ProtoMessage() {}
 
 func (x *GetProjectRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[50]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[50]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2855,7 +2855,7 @@ func (x *GetProjectRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetProjectRequest.ProtoReflect.Descriptor instead.
 func (*GetProjectRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{50}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{50}
 }
 
 func (x *GetProjectRequest) GetName() string {
@@ -2887,7 +2887,7 @@ type GetProjectResponse struct {
 func (x *GetProjectResponse) Reset() {
 	*x = GetProjectResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[51]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[51]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2900,7 +2900,7 @@ func (x *GetProjectResponse) String() string {
 func (*GetProjectResponse) ProtoMessage() {}
 
 func (x *GetProjectResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[51]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[51]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2913,7 +2913,7 @@ func (x *GetProjectResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetProjectResponse.ProtoReflect.Descriptor instead.
 func (*GetProjectResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{51}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{51}
 }
 
 func (m *GetProjectResponse) GetResult() isGetProjectResponse_Result {
@@ -2966,7 +2966,7 @@ type ListProjectsRequest struct {
 func (x *ListProjectsRequest) Reset() {
 	*x = ListProjectsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[52]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[52]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2979,7 +2979,7 @@ func (x *ListProjectsRequest) String() string {
 func (*ListProjectsRequest) ProtoMessage() {}
 
 func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[52]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[52]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2992,7 +2992,7 @@ func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectsRequest.ProtoReflect.Descriptor instead.
 func (*ListProjectsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{52}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{52}
 }
 
 func (x *ListProjectsRequest) GetPageSize() int32 {
@@ -3028,7 +3028,7 @@ type ListProjectsResponse struct {
 func (x *ListProjectsResponse) Reset() {
 	*x = ListProjectsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[53]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[53]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3041,7 +3041,7 @@ func (x *ListProjectsResponse) String() string {
 func (*ListProjectsResponse) ProtoMessage() {}
 
 func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[53]
+	mi := &file_api_service_v1alpha1_service_proto_msgTypes[53]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3054,7 +3054,7 @@ func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectsResponse.ProtoReflect.Descriptor instead.
 func (*ListProjectsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{53}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{53}
 }
 
 func (x *ListProjectsResponse) GetProjects() []*v1alpha1.Project {
@@ -3085,7 +3085,7 @@ type ApproveFreightRequest struct {
 func (x *ApproveFreightRequest) Reset() {
 	*x = ApproveFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[54]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[54]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3098,7 +3098,7 @@ func (x *ApproveFreightRequest) String() string {
 func (*ApproveFreightRequest) ProtoMessage() {}
 
 func (x *ApproveFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[54]
+	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 {
@@ -3111,7 +3111,7 @@ func (x *ApproveFreightRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApproveFreightRequest.ProtoReflect.Descriptor instead.
 func (*ApproveFreightRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{54}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{54}
 }
 
 func (x *ApproveFreightRequest) GetProject() string {
@@ -3151,7 +3151,7 @@ type ApproveFreightResponse struct {
 func (x *ApproveFreightResponse) Reset() {
 	*x = ApproveFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[55]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[55]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3164,7 +3164,7 @@ func (x *ApproveFreightResponse) String() string {
 func (*ApproveFreightResponse) ProtoMessage() {}
 
 func (x *ApproveFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[55]
+	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 {
@@ -3177,7 +3177,7 @@ func (x *ApproveFreightResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApproveFreightResponse.ProtoReflect.Descriptor instead.
 func (*ApproveFreightResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{55}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{55}
 }
 
 type DeleteFreightRequest struct {
@@ -3193,7 +3193,7 @@ type DeleteFreightRequest struct {
 func (x *DeleteFreightRequest) Reset() {
 	*x = DeleteFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[56]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[56]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3206,7 +3206,7 @@ func (x *DeleteFreightRequest) String() string {
 func (*DeleteFreightRequest) ProtoMessage() {}
 
 func (x *DeleteFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[56]
+	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 {
@@ -3219,7 +3219,7 @@ func (x *DeleteFreightRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteFreightRequest.ProtoReflect.Descriptor instead.
 func (*DeleteFreightRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{56}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{56}
 }
 
 func (x *DeleteFreightRequest) GetProject() string {
@@ -3252,7 +3252,7 @@ type DeleteFreightResponse struct {
 func (x *DeleteFreightResponse) Reset() {
 	*x = DeleteFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[57]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[57]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3265,7 +3265,7 @@ func (x *DeleteFreightResponse) String() string {
 func (*DeleteFreightResponse) ProtoMessage() {}
 
 func (x *DeleteFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[57]
+	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 {
@@ -3278,7 +3278,7 @@ func (x *DeleteFreightResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteFreightResponse.ProtoReflect.Descriptor instead.
 func (*DeleteFreightResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{57}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{57}
 }
 
 type GetFreightRequest struct {
@@ -3295,7 +3295,7 @@ type GetFreightRequest struct {
 func (x *GetFreightRequest) Reset() {
 	*x = GetFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[58]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[58]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3308,7 +3308,7 @@ func (x *GetFreightRequest) String() string {
 func (*GetFreightRequest) ProtoMessage() {}
 
 func (x *GetFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[58]
+	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 {
@@ -3321,7 +3321,7 @@ func (x *GetFreightRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetFreightRequest.ProtoReflect.Descriptor instead.
 func (*GetFreightRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{58}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{58}
 }
 
 func (x *GetFreightRequest) GetProject() string {
@@ -3367,7 +3367,7 @@ type GetFreightResponse struct {
 func (x *GetFreightResponse) Reset() {
 	*x = GetFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[59]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[59]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3380,7 +3380,7 @@ func (x *GetFreightResponse) String() string {
 func (*GetFreightResponse) ProtoMessage() {}
 
 func (x *GetFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[59]
+	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 {
@@ -3393,7 +3393,7 @@ func (x *GetFreightResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetFreightResponse.ProtoReflect.Descriptor instead.
 func (*GetFreightResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{59}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{59}
 }
 
 func (m *GetFreightResponse) GetResult() isGetFreightResponse_Result {
@@ -3447,7 +3447,7 @@ type PromoteToStageRequest struct {
 func (x *PromoteToStageRequest) Reset() {
 	*x = PromoteToStageRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[60]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[60]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3460,7 +3460,7 @@ func (x *PromoteToStageRequest) String() string {
 func (*PromoteToStageRequest) ProtoMessage() {}
 
 func (x *PromoteToStageRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[60]
+	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 {
@@ -3473,7 +3473,7 @@ func (x *PromoteToStageRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PromoteToStageRequest.ProtoReflect.Descriptor instead.
 func (*PromoteToStageRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{60}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{60}
 }
 
 func (x *PromoteToStageRequest) GetProject() string {
@@ -3515,7 +3515,7 @@ type PromoteToStageResponse struct {
 func (x *PromoteToStageResponse) Reset() {
 	*x = PromoteToStageResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[61]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[61]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3528,7 +3528,7 @@ func (x *PromoteToStageResponse) String() string {
 func (*PromoteToStageResponse) ProtoMessage() {}
 
 func (x *PromoteToStageResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[61]
+	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 {
@@ -3541,7 +3541,7 @@ func (x *PromoteToStageResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PromoteToStageResponse.ProtoReflect.Descriptor instead.
 func (*PromoteToStageResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{61}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{61}
 }
 
 func (x *PromoteToStageResponse) GetPromotion() *v1alpha1.Promotion {
@@ -3565,7 +3565,7 @@ type PromoteDownstreamRequest struct {
 func (x *PromoteDownstreamRequest) Reset() {
 	*x = PromoteDownstreamRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[62]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[62]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3578,7 +3578,7 @@ func (x *PromoteDownstreamRequest) String() string {
 func (*PromoteDownstreamRequest) ProtoMessage() {}
 
 func (x *PromoteDownstreamRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[62]
+	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 {
@@ -3591,7 +3591,7 @@ func (x *PromoteDownstreamRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PromoteDownstreamRequest.ProtoReflect.Descriptor instead.
 func (*PromoteDownstreamRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{62}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{62}
 }
 
 func (x *PromoteDownstreamRequest) GetProject() string {
@@ -3633,7 +3633,7 @@ type PromoteDownstreamResponse struct {
 func (x *PromoteDownstreamResponse) Reset() {
 	*x = PromoteDownstreamResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[63]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[63]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3646,7 +3646,7 @@ func (x *PromoteDownstreamResponse) String() string {
 func (*PromoteDownstreamResponse) ProtoMessage() {}
 
 func (x *PromoteDownstreamResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[63]
+	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 {
@@ -3659,7 +3659,7 @@ func (x *PromoteDownstreamResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PromoteDownstreamResponse.ProtoReflect.Descriptor instead.
 func (*PromoteDownstreamResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{63}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{63}
 }
 
 func (x *PromoteDownstreamResponse) GetPromotions() []*v1alpha1.Promotion {
@@ -3686,7 +3686,7 @@ type QueryFreightRequest struct {
 func (x *QueryFreightRequest) Reset() {
 	*x = QueryFreightRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[64]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[64]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3699,7 +3699,7 @@ func (x *QueryFreightRequest) String() string {
 func (*QueryFreightRequest) ProtoMessage() {}
 
 func (x *QueryFreightRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[64]
+	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 {
@@ -3712,7 +3712,7 @@ func (x *QueryFreightRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use QueryFreightRequest.ProtoReflect.Descriptor instead.
 func (*QueryFreightRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{64}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{64}
 }
 
 func (x *QueryFreightRequest) GetProject() string {
@@ -3775,7 +3775,7 @@ type QueryFreightResponse struct {
 func (x *QueryFreightResponse) Reset() {
 	*x = QueryFreightResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[65]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[65]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3788,7 +3788,7 @@ func (x *QueryFreightResponse) String() string {
 func (*QueryFreightResponse) ProtoMessage() {}
 
 func (x *QueryFreightResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[65]
+	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 {
@@ -3801,7 +3801,7 @@ func (x *QueryFreightResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use QueryFreightResponse.ProtoReflect.Descriptor instead.
 func (*QueryFreightResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{65}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{65}
 }
 
 func (x *QueryFreightResponse) GetGroups() map[string]*FreightList {
@@ -3822,7 +3822,7 @@ type FreightList struct {
 func (x *FreightList) Reset() {
 	*x = FreightList{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[66]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[66]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3835,7 +3835,7 @@ func (x *FreightList) String() string {
 func (*FreightList) ProtoMessage() {}
 
 func (x *FreightList) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[66]
+	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 {
@@ -3848,7 +3848,7 @@ func (x *FreightList) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FreightList.ProtoReflect.Descriptor instead.
 func (*FreightList) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{66}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{66}
 }
 
 func (x *FreightList) GetFreight() []*v1alpha1.Freight {
@@ -3872,7 +3872,7 @@ type UpdateFreightAliasRequest struct {
 func (x *UpdateFreightAliasRequest) Reset() {
 	*x = UpdateFreightAliasRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[67]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[67]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3885,7 +3885,7 @@ func (x *UpdateFreightAliasRequest) String() string {
 func (*UpdateFreightAliasRequest) ProtoMessage() {}
 
 func (x *UpdateFreightAliasRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[67]
+	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 {
@@ -3898,7 +3898,7 @@ func (x *UpdateFreightAliasRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateFreightAliasRequest.ProtoReflect.Descriptor instead.
 func (*UpdateFreightAliasRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{67}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{67}
 }
 
 func (x *UpdateFreightAliasRequest) GetProject() string {
@@ -3938,7 +3938,7 @@ type UpdateFreightAliasResponse struct {
 func (x *UpdateFreightAliasResponse) Reset() {
 	*x = UpdateFreightAliasResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[68]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[68]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3951,7 +3951,7 @@ func (x *UpdateFreightAliasResponse) String() string {
 func (*UpdateFreightAliasResponse) ProtoMessage() {}
 
 func (x *UpdateFreightAliasResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[68]
+	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 {
@@ -3964,7 +3964,7 @@ func (x *UpdateFreightAliasResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateFreightAliasResponse.ProtoReflect.Descriptor instead.
 func (*UpdateFreightAliasResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{68}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{68}
 }
 
 type ReverifyRequest struct {
@@ -3979,7 +3979,7 @@ type ReverifyRequest struct {
 func (x *ReverifyRequest) Reset() {
 	*x = ReverifyRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[69]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[69]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -3992,7 +3992,7 @@ func (x *ReverifyRequest) String() string {
 func (*ReverifyRequest) ProtoMessage() {}
 
 func (x *ReverifyRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[69]
+	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 {
@@ -4005,7 +4005,7 @@ func (x *ReverifyRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ReverifyRequest.ProtoReflect.Descriptor instead.
 func (*ReverifyRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{69}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{69}
 }
 
 func (x *ReverifyRequest) GetProject() string {
@@ -4031,7 +4031,7 @@ type ReverifyResponse struct {
 func (x *ReverifyResponse) Reset() {
 	*x = ReverifyResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[70]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[70]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4044,7 +4044,7 @@ func (x *ReverifyResponse) String() string {
 func (*ReverifyResponse) ProtoMessage() {}
 
 func (x *ReverifyResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[70]
+	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 {
@@ -4057,7 +4057,7 @@ func (x *ReverifyResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ReverifyResponse.ProtoReflect.Descriptor instead.
 func (*ReverifyResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{70}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{70}
 }
 
 type AbortVerificationRequest struct {
@@ -4072,7 +4072,7 @@ type AbortVerificationRequest struct {
 func (x *AbortVerificationRequest) Reset() {
 	*x = AbortVerificationRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[71]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[71]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4085,7 +4085,7 @@ func (x *AbortVerificationRequest) String() string {
 func (*AbortVerificationRequest) ProtoMessage() {}
 
 func (x *AbortVerificationRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[71]
+	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 {
@@ -4098,7 +4098,7 @@ func (x *AbortVerificationRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AbortVerificationRequest.ProtoReflect.Descriptor instead.
 func (*AbortVerificationRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{71}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{71}
 }
 
 func (x *AbortVerificationRequest) GetProject() string {
@@ -4124,7 +4124,7 @@ type AbortVerificationResponse struct {
 func (x *AbortVerificationResponse) Reset() {
 	*x = AbortVerificationResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[72]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[72]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4137,7 +4137,7 @@ func (x *AbortVerificationResponse) String() string {
 func (*AbortVerificationResponse) ProtoMessage() {}
 
 func (x *AbortVerificationResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[72]
+	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 {
@@ -4150,7 +4150,7 @@ func (x *AbortVerificationResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AbortVerificationResponse.ProtoReflect.Descriptor instead.
 func (*AbortVerificationResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{72}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{72}
 }
 
 type ListWarehousesRequest struct {
@@ -4164,7 +4164,7 @@ type ListWarehousesRequest struct {
 func (x *ListWarehousesRequest) Reset() {
 	*x = ListWarehousesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[73]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[73]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4177,7 +4177,7 @@ func (x *ListWarehousesRequest) String() string {
 func (*ListWarehousesRequest) ProtoMessage() {}
 
 func (x *ListWarehousesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[73]
+	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 {
@@ -4190,7 +4190,7 @@ func (x *ListWarehousesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListWarehousesRequest.ProtoReflect.Descriptor instead.
 func (*ListWarehousesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{73}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{73}
 }
 
 func (x *ListWarehousesRequest) GetProject() string {
@@ -4211,7 +4211,7 @@ type ListWarehousesResponse struct {
 func (x *ListWarehousesResponse) Reset() {
 	*x = ListWarehousesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[74]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[74]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4224,7 +4224,7 @@ func (x *ListWarehousesResponse) String() string {
 func (*ListWarehousesResponse) ProtoMessage() {}
 
 func (x *ListWarehousesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[74]
+	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 {
@@ -4237,7 +4237,7 @@ func (x *ListWarehousesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListWarehousesResponse.ProtoReflect.Descriptor instead.
 func (*ListWarehousesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{74}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{74}
 }
 
 func (x *ListWarehousesResponse) GetWarehouses() []*v1alpha1.Warehouse {
@@ -4260,7 +4260,7 @@ type GetWarehouseRequest struct {
 func (x *GetWarehouseRequest) Reset() {
 	*x = GetWarehouseRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[75]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[75]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4273,7 +4273,7 @@ func (x *GetWarehouseRequest) String() string {
 func (*GetWarehouseRequest) ProtoMessage() {}
 
 func (x *GetWarehouseRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[75]
+	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 {
@@ -4286,7 +4286,7 @@ func (x *GetWarehouseRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetWarehouseRequest.ProtoReflect.Descriptor instead.
 func (*GetWarehouseRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{75}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{75}
 }
 
 func (x *GetWarehouseRequest) GetProject() string {
@@ -4325,7 +4325,7 @@ type GetWarehouseResponse struct {
 func (x *GetWarehouseResponse) Reset() {
 	*x = GetWarehouseResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[76]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[76]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4338,7 +4338,7 @@ func (x *GetWarehouseResponse) String() string {
 func (*GetWarehouseResponse) ProtoMessage() {}
 
 func (x *GetWarehouseResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[76]
+	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 {
@@ -4351,7 +4351,7 @@ func (x *GetWarehouseResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetWarehouseResponse.ProtoReflect.Descriptor instead.
 func (*GetWarehouseResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{76}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{76}
 }
 
 func (m *GetWarehouseResponse) GetResult() isGetWarehouseResponse_Result {
@@ -4403,7 +4403,7 @@ type WatchWarehousesRequest struct {
 func (x *WatchWarehousesRequest) Reset() {
 	*x = WatchWarehousesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[77]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[77]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4416,7 +4416,7 @@ func (x *WatchWarehousesRequest) String() string {
 func (*WatchWarehousesRequest) ProtoMessage() {}
 
 func (x *WatchWarehousesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[77]
+	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 {
@@ -4429,7 +4429,7 @@ func (x *WatchWarehousesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchWarehousesRequest.ProtoReflect.Descriptor instead.
 func (*WatchWarehousesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{77}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{77}
 }
 
 func (x *WatchWarehousesRequest) GetProject() string {
@@ -4458,7 +4458,7 @@ type WatchWarehousesResponse struct {
 func (x *WatchWarehousesResponse) Reset() {
 	*x = WatchWarehousesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[78]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[78]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4471,7 +4471,7 @@ func (x *WatchWarehousesResponse) String() string {
 func (*WatchWarehousesResponse) ProtoMessage() {}
 
 func (x *WatchWarehousesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[78]
+	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 {
@@ -4484,7 +4484,7 @@ func (x *WatchWarehousesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use WatchWarehousesResponse.ProtoReflect.Descriptor instead.
 func (*WatchWarehousesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{78}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{78}
 }
 
 func (x *WatchWarehousesResponse) GetWarehouse() *v1alpha1.Warehouse {
@@ -4513,7 +4513,7 @@ type DeleteWarehouseRequest struct {
 func (x *DeleteWarehouseRequest) Reset() {
 	*x = DeleteWarehouseRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[79]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[79]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4526,7 +4526,7 @@ func (x *DeleteWarehouseRequest) String() string {
 func (*DeleteWarehouseRequest) ProtoMessage() {}
 
 func (x *DeleteWarehouseRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[79]
+	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 {
@@ -4539,7 +4539,7 @@ func (x *DeleteWarehouseRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteWarehouseRequest.ProtoReflect.Descriptor instead.
 func (*DeleteWarehouseRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{79}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{79}
 }
 
 func (x *DeleteWarehouseRequest) GetProject() string {
@@ -4565,7 +4565,7 @@ type DeleteWarehouseResponse struct {
 func (x *DeleteWarehouseResponse) Reset() {
 	*x = DeleteWarehouseResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[80]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[80]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4578,7 +4578,7 @@ func (x *DeleteWarehouseResponse) String() string {
 func (*DeleteWarehouseResponse) ProtoMessage() {}
 
 func (x *DeleteWarehouseResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[80]
+	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 {
@@ -4591,7 +4591,7 @@ func (x *DeleteWarehouseResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteWarehouseResponse.ProtoReflect.Descriptor instead.
 func (*DeleteWarehouseResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{80}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{80}
 }
 
 type RefreshWarehouseRequest struct {
@@ -4606,7 +4606,7 @@ type RefreshWarehouseRequest struct {
 func (x *RefreshWarehouseRequest) Reset() {
 	*x = RefreshWarehouseRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[81]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[81]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4619,7 +4619,7 @@ func (x *RefreshWarehouseRequest) String() string {
 func (*RefreshWarehouseRequest) ProtoMessage() {}
 
 func (x *RefreshWarehouseRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[81]
+	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 {
@@ -4632,7 +4632,7 @@ func (x *RefreshWarehouseRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RefreshWarehouseRequest.ProtoReflect.Descriptor instead.
 func (*RefreshWarehouseRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{81}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{81}
 }
 
 func (x *RefreshWarehouseRequest) GetProject() string {
@@ -4660,7 +4660,7 @@ type RefreshWarehouseResponse struct {
 func (x *RefreshWarehouseResponse) Reset() {
 	*x = RefreshWarehouseResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[82]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[82]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4673,7 +4673,7 @@ func (x *RefreshWarehouseResponse) String() string {
 func (*RefreshWarehouseResponse) ProtoMessage() {}
 
 func (x *RefreshWarehouseResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[82]
+	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 {
@@ -4686,7 +4686,7 @@ func (x *RefreshWarehouseResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RefreshWarehouseResponse.ProtoReflect.Descriptor instead.
 func (*RefreshWarehouseResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{82}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{82}
 }
 
 func (x *RefreshWarehouseResponse) GetWarehouse() *v1alpha1.Warehouse {
@@ -4707,7 +4707,7 @@ type ListProjectSecretsRequest struct {
 func (x *ListProjectSecretsRequest) Reset() {
 	*x = ListProjectSecretsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[83]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[83]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4720,7 +4720,7 @@ func (x *ListProjectSecretsRequest) String() string {
 func (*ListProjectSecretsRequest) ProtoMessage() {}
 
 func (x *ListProjectSecretsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[83]
+	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 {
@@ -4733,7 +4733,7 @@ func (x *ListProjectSecretsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectSecretsRequest.ProtoReflect.Descriptor instead.
 func (*ListProjectSecretsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{83}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{83}
 }
 
 func (x *ListProjectSecretsRequest) GetProject() string {
@@ -4754,7 +4754,7 @@ type ListProjectSecretsResponse struct {
 func (x *ListProjectSecretsResponse) Reset() {
 	*x = ListProjectSecretsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[84]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[84]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4767,7 +4767,7 @@ func (x *ListProjectSecretsResponse) String() string {
 func (*ListProjectSecretsResponse) ProtoMessage() {}
 
 func (x *ListProjectSecretsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[84]
+	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 {
@@ -4780,7 +4780,7 @@ func (x *ListProjectSecretsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectSecretsResponse.ProtoReflect.Descriptor instead.
 func (*ListProjectSecretsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{84}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{84}
 }
 
 func (x *ListProjectSecretsResponse) GetSecrets() []*v1.Secret {
@@ -4804,7 +4804,7 @@ type CreateProjectSecretRequest struct {
 func (x *CreateProjectSecretRequest) Reset() {
 	*x = CreateProjectSecretRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[85]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[85]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4817,7 +4817,7 @@ func (x *CreateProjectSecretRequest) String() string {
 func (*CreateProjectSecretRequest) ProtoMessage() {}
 
 func (x *CreateProjectSecretRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[85]
+	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 {
@@ -4830,7 +4830,7 @@ func (x *CreateProjectSecretRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateProjectSecretRequest.ProtoReflect.Descriptor instead.
 func (*CreateProjectSecretRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{85}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{85}
 }
 
 func (x *CreateProjectSecretRequest) GetProject() string {
@@ -4872,7 +4872,7 @@ type CreateProjectSecretResponse struct {
 func (x *CreateProjectSecretResponse) Reset() {
 	*x = CreateProjectSecretResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[86]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[86]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4885,7 +4885,7 @@ func (x *CreateProjectSecretResponse) String() string {
 func (*CreateProjectSecretResponse) ProtoMessage() {}
 
 func (x *CreateProjectSecretResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[86]
+	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 {
@@ -4898,7 +4898,7 @@ func (x *CreateProjectSecretResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateProjectSecretResponse.ProtoReflect.Descriptor instead.
 func (*CreateProjectSecretResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{86}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{86}
 }
 
 func (x *CreateProjectSecretResponse) GetSecret() *v1.Secret {
@@ -4922,7 +4922,7 @@ type UpdateProjectSecretRequest struct {
 func (x *UpdateProjectSecretRequest) Reset() {
 	*x = UpdateProjectSecretRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[87]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[87]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -4935,7 +4935,7 @@ func (x *UpdateProjectSecretRequest) String() string {
 func (*UpdateProjectSecretRequest) ProtoMessage() {}
 
 func (x *UpdateProjectSecretRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[87]
+	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 {
@@ -4948,7 +4948,7 @@ func (x *UpdateProjectSecretRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateProjectSecretRequest.ProtoReflect.Descriptor instead.
 func (*UpdateProjectSecretRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{87}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{87}
 }
 
 func (x *UpdateProjectSecretRequest) GetProject() string {
@@ -4990,7 +4990,7 @@ type UpdateProjectSecretResponse struct {
 func (x *UpdateProjectSecretResponse) Reset() {
 	*x = UpdateProjectSecretResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[88]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[88]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5003,7 +5003,7 @@ func (x *UpdateProjectSecretResponse) String() string {
 func (*UpdateProjectSecretResponse) ProtoMessage() {}
 
 func (x *UpdateProjectSecretResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[88]
+	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 {
@@ -5016,7 +5016,7 @@ func (x *UpdateProjectSecretResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateProjectSecretResponse.ProtoReflect.Descriptor instead.
 func (*UpdateProjectSecretResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{88}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{88}
 }
 
 func (x *UpdateProjectSecretResponse) GetSecret() *v1.Secret {
@@ -5038,7 +5038,7 @@ type DeleteProjectSecretRequest struct {
 func (x *DeleteProjectSecretRequest) Reset() {
 	*x = DeleteProjectSecretRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[89]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[89]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5051,7 +5051,7 @@ func (x *DeleteProjectSecretRequest) String() string {
 func (*DeleteProjectSecretRequest) ProtoMessage() {}
 
 func (x *DeleteProjectSecretRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[89]
+	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 {
@@ -5064,7 +5064,7 @@ func (x *DeleteProjectSecretRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteProjectSecretRequest.ProtoReflect.Descriptor instead.
 func (*DeleteProjectSecretRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{89}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{89}
 }
 
 func (x *DeleteProjectSecretRequest) GetProject() string {
@@ -5090,7 +5090,7 @@ type DeleteProjectSecretResponse struct {
 func (x *DeleteProjectSecretResponse) Reset() {
 	*x = DeleteProjectSecretResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[90]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[90]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5103,7 +5103,7 @@ func (x *DeleteProjectSecretResponse) String() string {
 func (*DeleteProjectSecretResponse) ProtoMessage() {}
 
 func (x *DeleteProjectSecretResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[90]
+	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 {
@@ -5116,7 +5116,7 @@ func (x *DeleteProjectSecretResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteProjectSecretResponse.ProtoReflect.Descriptor instead.
 func (*DeleteProjectSecretResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{90}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{90}
 }
 
 type CreateCredentialsRequest struct {
@@ -5138,7 +5138,7 @@ type CreateCredentialsRequest struct {
 func (x *CreateCredentialsRequest) Reset() {
 	*x = CreateCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[91]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[91]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5151,7 +5151,7 @@ func (x *CreateCredentialsRequest) String() string {
 func (*CreateCredentialsRequest) ProtoMessage() {}
 
 func (x *CreateCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[91]
+	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 {
@@ -5164,7 +5164,7 @@ func (x *CreateCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*CreateCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{91}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{91}
 }
 
 func (x *CreateCredentialsRequest) GetProject() string {
@@ -5234,7 +5234,7 @@ type CreateCredentialsResponse struct {
 func (x *CreateCredentialsResponse) Reset() {
 	*x = CreateCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[92]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[92]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5247,7 +5247,7 @@ func (x *CreateCredentialsResponse) String() string {
 func (*CreateCredentialsResponse) ProtoMessage() {}
 
 func (x *CreateCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[92]
+	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 {
@@ -5260,7 +5260,7 @@ func (x *CreateCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*CreateCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{92}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{92}
 }
 
 func (x *CreateCredentialsResponse) GetCredentials() *v1.Secret {
@@ -5282,7 +5282,7 @@ type DeleteCredentialsRequest struct {
 func (x *DeleteCredentialsRequest) Reset() {
 	*x = DeleteCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[93]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[93]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5295,7 +5295,7 @@ func (x *DeleteCredentialsRequest) String() string {
 func (*DeleteCredentialsRequest) ProtoMessage() {}
 
 func (x *DeleteCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[93]
+	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 {
@@ -5308,7 +5308,7 @@ func (x *DeleteCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*DeleteCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{93}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{93}
 }
 
 func (x *DeleteCredentialsRequest) GetProject() string {
@@ -5334,7 +5334,7 @@ type DeleteCredentialsResponse struct {
 func (x *DeleteCredentialsResponse) Reset() {
 	*x = DeleteCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[94]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[94]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5347,7 +5347,7 @@ func (x *DeleteCredentialsResponse) String() string {
 func (*DeleteCredentialsResponse) ProtoMessage() {}
 
 func (x *DeleteCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[94]
+	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 {
@@ -5360,7 +5360,7 @@ func (x *DeleteCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*DeleteCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{94}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{94}
 }
 
 type GetCredentialsRequest struct {
@@ -5376,7 +5376,7 @@ type GetCredentialsRequest struct {
 func (x *GetCredentialsRequest) Reset() {
 	*x = GetCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[95]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[95]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5389,7 +5389,7 @@ func (x *GetCredentialsRequest) String() string {
 func (*GetCredentialsRequest) ProtoMessage() {}
 
 func (x *GetCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[95]
+	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 {
@@ -5402,7 +5402,7 @@ func (x *GetCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*GetCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{95}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{95}
 }
 
 func (x *GetCredentialsRequest) GetProject() string {
@@ -5441,7 +5441,7 @@ type GetCredentialsResponse struct {
 func (x *GetCredentialsResponse) Reset() {
 	*x = GetCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[96]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[96]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5454,7 +5454,7 @@ func (x *GetCredentialsResponse) String() string {
 func (*GetCredentialsResponse) ProtoMessage() {}
 
 func (x *GetCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[96]
+	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 {
@@ -5467,7 +5467,7 @@ func (x *GetCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*GetCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{96}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{96}
 }
 
 func (m *GetCredentialsResponse) GetResult() isGetCredentialsResponse_Result {
@@ -5518,7 +5518,7 @@ type ListCredentialsRequest struct {
 func (x *ListCredentialsRequest) Reset() {
 	*x = ListCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[97]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[97]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5531,7 +5531,7 @@ func (x *ListCredentialsRequest) String() string {
 func (*ListCredentialsRequest) ProtoMessage() {}
 
 func (x *ListCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[97]
+	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 {
@@ -5544,7 +5544,7 @@ func (x *ListCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*ListCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{97}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{97}
 }
 
 func (x *ListCredentialsRequest) GetProject() string {
@@ -5565,7 +5565,7 @@ type ListCredentialsResponse struct {
 func (x *ListCredentialsResponse) Reset() {
 	*x = ListCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[98]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[98]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5578,7 +5578,7 @@ func (x *ListCredentialsResponse) String() string {
 func (*ListCredentialsResponse) ProtoMessage() {}
 
 func (x *ListCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[98]
+	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 {
@@ -5591,7 +5591,7 @@ func (x *ListCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*ListCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{98}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{98}
 }
 
 func (x *ListCredentialsResponse) GetCredentials() []*v1.Secret {
@@ -5619,7 +5619,7 @@ type UpdateCredentialsRequest struct {
 func (x *UpdateCredentialsRequest) Reset() {
 	*x = UpdateCredentialsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[99]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[99]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5632,7 +5632,7 @@ func (x *UpdateCredentialsRequest) String() string {
 func (*UpdateCredentialsRequest) ProtoMessage() {}
 
 func (x *UpdateCredentialsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[99]
+	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 {
@@ -5645,7 +5645,7 @@ func (x *UpdateCredentialsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateCredentialsRequest.ProtoReflect.Descriptor instead.
 func (*UpdateCredentialsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{99}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{99}
 }
 
 func (x *UpdateCredentialsRequest) GetProject() string {
@@ -5715,7 +5715,7 @@ type UpdateCredentialsResponse struct {
 func (x *UpdateCredentialsResponse) Reset() {
 	*x = UpdateCredentialsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[100]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[100]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5728,7 +5728,7 @@ func (x *UpdateCredentialsResponse) String() string {
 func (*UpdateCredentialsResponse) ProtoMessage() {}
 
 func (x *UpdateCredentialsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[100]
+	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 {
@@ -5741,7 +5741,7 @@ func (x *UpdateCredentialsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateCredentialsResponse.ProtoReflect.Descriptor instead.
 func (*UpdateCredentialsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{100}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{100}
 }
 
 func (x *UpdateCredentialsResponse) GetCredentials() *v1.Secret {
@@ -5762,7 +5762,7 @@ type ListAnalysisTemplatesRequest struct {
 func (x *ListAnalysisTemplatesRequest) Reset() {
 	*x = ListAnalysisTemplatesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[101]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[101]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5775,7 +5775,7 @@ func (x *ListAnalysisTemplatesRequest) String() string {
 func (*ListAnalysisTemplatesRequest) ProtoMessage() {}
 
 func (x *ListAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[101]
+	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 {
@@ -5788,7 +5788,7 @@ func (x *ListAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAnalysisTemplatesRequest.ProtoReflect.Descriptor instead.
 func (*ListAnalysisTemplatesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{101}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{101}
 }
 
 func (x *ListAnalysisTemplatesRequest) GetProject() string {
@@ -5809,7 +5809,7 @@ type ListAnalysisTemplatesResponse struct {
 func (x *ListAnalysisTemplatesResponse) Reset() {
 	*x = ListAnalysisTemplatesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[102]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[102]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5822,7 +5822,7 @@ func (x *ListAnalysisTemplatesResponse) String() string {
 func (*ListAnalysisTemplatesResponse) ProtoMessage() {}
 
 func (x *ListAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[102]
+	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 {
@@ -5835,7 +5835,7 @@ func (x *ListAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAnalysisTemplatesResponse.ProtoReflect.Descriptor instead.
 func (*ListAnalysisTemplatesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{102}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{102}
 }
 
 func (x *ListAnalysisTemplatesResponse) GetAnalysisTemplates() []*v1alpha11.AnalysisTemplate {
@@ -5858,7 +5858,7 @@ type GetAnalysisTemplateRequest struct {
 func (x *GetAnalysisTemplateRequest) Reset() {
 	*x = GetAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[103]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[103]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5871,7 +5871,7 @@ func (x *GetAnalysisTemplateRequest) String() string {
 func (*GetAnalysisTemplateRequest) ProtoMessage() {}
 
 func (x *GetAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[103]
+	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 {
@@ -5884,7 +5884,7 @@ func (x *GetAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
 func (*GetAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{103}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{103}
 }
 
 func (x *GetAnalysisTemplateRequest) GetProject() string {
@@ -5923,7 +5923,7 @@ type GetAnalysisTemplateResponse struct {
 func (x *GetAnalysisTemplateResponse) Reset() {
 	*x = GetAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[104]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[104]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -5936,7 +5936,7 @@ func (x *GetAnalysisTemplateResponse) String() string {
 func (*GetAnalysisTemplateResponse) ProtoMessage() {}
 
 func (x *GetAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[104]
+	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 {
@@ -5949,7 +5949,7 @@ func (x *GetAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
 func (*GetAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{104}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{104}
 }
 
 func (m *GetAnalysisTemplateResponse) GetResult() isGetAnalysisTemplateResponse_Result {
@@ -5998,7 +5998,7 @@ type ListClusterAnalysisTemplatesRequest struct {
 func (x *ListClusterAnalysisTemplatesRequest) Reset() {
 	*x = ListClusterAnalysisTemplatesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[105]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[105]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6011,7 +6011,7 @@ func (x *ListClusterAnalysisTemplatesRequest) String() string {
 func (*ListClusterAnalysisTemplatesRequest) ProtoMessage() {}
 
 func (x *ListClusterAnalysisTemplatesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[105]
+	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 {
@@ -6024,7 +6024,7 @@ func (x *ListClusterAnalysisTemplatesRequest) ProtoReflect() protoreflect.Messag
 
 // Deprecated: Use ListClusterAnalysisTemplatesRequest.ProtoReflect.Descriptor instead.
 func (*ListClusterAnalysisTemplatesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{105}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{105}
 }
 
 type ListClusterAnalysisTemplatesResponse struct {
@@ -6038,7 +6038,7 @@ type ListClusterAnalysisTemplatesResponse struct {
 func (x *ListClusterAnalysisTemplatesResponse) Reset() {
 	*x = ListClusterAnalysisTemplatesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[106]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[106]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6051,7 +6051,7 @@ func (x *ListClusterAnalysisTemplatesResponse) String() string {
 func (*ListClusterAnalysisTemplatesResponse) ProtoMessage() {}
 
 func (x *ListClusterAnalysisTemplatesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[106]
+	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 {
@@ -6064,7 +6064,7 @@ func (x *ListClusterAnalysisTemplatesResponse) ProtoReflect() protoreflect.Messa
 
 // Deprecated: Use ListClusterAnalysisTemplatesResponse.ProtoReflect.Descriptor instead.
 func (*ListClusterAnalysisTemplatesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{106}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{106}
 }
 
 func (x *ListClusterAnalysisTemplatesResponse) GetClusterAnalysisTemplates() []*v1alpha11.ClusterAnalysisTemplate {
@@ -6086,7 +6086,7 @@ type GetClusterAnalysisTemplateRequest struct {
 func (x *GetClusterAnalysisTemplateRequest) Reset() {
 	*x = GetClusterAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[107]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[107]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6099,7 +6099,7 @@ func (x *GetClusterAnalysisTemplateRequest) String() string {
 func (*GetClusterAnalysisTemplateRequest) ProtoMessage() {}
 
 func (x *GetClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[107]
+	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 {
@@ -6112,7 +6112,7 @@ func (x *GetClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use GetClusterAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
 func (*GetClusterAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{107}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{107}
 }
 
 func (x *GetClusterAnalysisTemplateRequest) GetName() string {
@@ -6144,7 +6144,7 @@ type GetClusterAnalysisTemplateResponse struct {
 func (x *GetClusterAnalysisTemplateResponse) Reset() {
 	*x = GetClusterAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[108]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[108]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6157,7 +6157,7 @@ func (x *GetClusterAnalysisTemplateResponse) String() string {
 func (*GetClusterAnalysisTemplateResponse) ProtoMessage() {}
 
 func (x *GetClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[108]
+	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 {
@@ -6170,7 +6170,7 @@ func (x *GetClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use GetClusterAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
 func (*GetClusterAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{108}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{108}
 }
 
 func (m *GetClusterAnalysisTemplateResponse) GetResult() isGetClusterAnalysisTemplateResponse_Result {
@@ -6224,7 +6224,7 @@ type GetAnalysisRunRequest struct {
 func (x *GetAnalysisRunRequest) Reset() {
 	*x = GetAnalysisRunRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[109]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[109]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6237,7 +6237,7 @@ func (x *GetAnalysisRunRequest) String() string {
 func (*GetAnalysisRunRequest) ProtoMessage() {}
 
 func (x *GetAnalysisRunRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[109]
+	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 {
@@ -6250,7 +6250,7 @@ func (x *GetAnalysisRunRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAnalysisRunRequest.ProtoReflect.Descriptor instead.
 func (*GetAnalysisRunRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{109}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{109}
 }
 
 func (x *GetAnalysisRunRequest) GetNamespace() string {
@@ -6289,7 +6289,7 @@ type GetAnalysisRunResponse struct {
 func (x *GetAnalysisRunResponse) Reset() {
 	*x = GetAnalysisRunResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[110]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[110]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6302,7 +6302,7 @@ func (x *GetAnalysisRunResponse) String() string {
 func (*GetAnalysisRunResponse) ProtoMessage() {}
 
 func (x *GetAnalysisRunResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[110]
+	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 {
@@ -6315,7 +6315,7 @@ func (x *GetAnalysisRunResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAnalysisRunResponse.ProtoReflect.Descriptor instead.
 func (*GetAnalysisRunResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{110}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{110}
 }
 
 func (m *GetAnalysisRunResponse) GetResult() isGetAnalysisRunResponse_Result {
@@ -6367,7 +6367,7 @@ type DeleteAnalysisTemplateRequest struct {
 func (x *DeleteAnalysisTemplateRequest) Reset() {
 	*x = DeleteAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[111]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[111]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6380,7 +6380,7 @@ func (x *DeleteAnalysisTemplateRequest) String() string {
 func (*DeleteAnalysisTemplateRequest) ProtoMessage() {}
 
 func (x *DeleteAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[111]
+	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 {
@@ -6393,7 +6393,7 @@ func (x *DeleteAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
 func (*DeleteAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{111}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{111}
 }
 
 func (x *DeleteAnalysisTemplateRequest) GetProject() string {
@@ -6419,7 +6419,7 @@ type DeleteAnalysisTemplateResponse struct {
 func (x *DeleteAnalysisTemplateResponse) Reset() {
 	*x = DeleteAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[112]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[112]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6432,7 +6432,7 @@ func (x *DeleteAnalysisTemplateResponse) String() string {
 func (*DeleteAnalysisTemplateResponse) ProtoMessage() {}
 
 func (x *DeleteAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[112]
+	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 {
@@ -6445,7 +6445,7 @@ func (x *DeleteAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
 func (*DeleteAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{112}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{112}
 }
 
 type DeleteClusterAnalysisTemplateRequest struct {
@@ -6459,7 +6459,7 @@ type DeleteClusterAnalysisTemplateRequest struct {
 func (x *DeleteClusterAnalysisTemplateRequest) Reset() {
 	*x = DeleteClusterAnalysisTemplateRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[113]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[113]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6472,7 +6472,7 @@ func (x *DeleteClusterAnalysisTemplateRequest) String() string {
 func (*DeleteClusterAnalysisTemplateRequest) ProtoMessage() {}
 
 func (x *DeleteClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[113]
+	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 {
@@ -6485,7 +6485,7 @@ func (x *DeleteClusterAnalysisTemplateRequest) ProtoReflect() protoreflect.Messa
 
 // Deprecated: Use DeleteClusterAnalysisTemplateRequest.ProtoReflect.Descriptor instead.
 func (*DeleteClusterAnalysisTemplateRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{113}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{113}
 }
 
 func (x *DeleteClusterAnalysisTemplateRequest) GetName() string {
@@ -6504,7 +6504,7 @@ type DeleteClusterAnalysisTemplateResponse struct {
 func (x *DeleteClusterAnalysisTemplateResponse) Reset() {
 	*x = DeleteClusterAnalysisTemplateResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[114]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[114]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6517,7 +6517,7 @@ func (x *DeleteClusterAnalysisTemplateResponse) String() string {
 func (*DeleteClusterAnalysisTemplateResponse) ProtoMessage() {}
 
 func (x *DeleteClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[114]
+	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 {
@@ -6530,7 +6530,7 @@ func (x *DeleteClusterAnalysisTemplateResponse) ProtoReflect() protoreflect.Mess
 
 // Deprecated: Use DeleteClusterAnalysisTemplateResponse.ProtoReflect.Descriptor instead.
 func (*DeleteClusterAnalysisTemplateResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{114}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{114}
 }
 
 type ListProjectEventsRequest struct {
@@ -6544,7 +6544,7 @@ type ListProjectEventsRequest struct {
 func (x *ListProjectEventsRequest) Reset() {
 	*x = ListProjectEventsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[115]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[115]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6557,7 +6557,7 @@ func (x *ListProjectEventsRequest) String() string {
 func (*ListProjectEventsRequest) ProtoMessage() {}
 
 func (x *ListProjectEventsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[115]
+	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 {
@@ -6570,7 +6570,7 @@ func (x *ListProjectEventsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectEventsRequest.ProtoReflect.Descriptor instead.
 func (*ListProjectEventsRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{115}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{115}
 }
 
 func (x *ListProjectEventsRequest) GetProject() string {
@@ -6591,7 +6591,7 @@ type ListProjectEventsResponse struct {
 func (x *ListProjectEventsResponse) Reset() {
 	*x = ListProjectEventsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[116]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[116]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6604,7 +6604,7 @@ func (x *ListProjectEventsResponse) String() string {
 func (*ListProjectEventsResponse) ProtoMessage() {}
 
 func (x *ListProjectEventsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[116]
+	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 {
@@ -6617,7 +6617,7 @@ func (x *ListProjectEventsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListProjectEventsResponse.ProtoReflect.Descriptor instead.
 func (*ListProjectEventsResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{116}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{116}
 }
 
 func (x *ListProjectEventsResponse) GetEvents() []*v1.Event {
@@ -6638,7 +6638,7 @@ type CreateRoleRequest struct {
 func (x *CreateRoleRequest) Reset() {
 	*x = CreateRoleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[117]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[117]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6651,7 +6651,7 @@ func (x *CreateRoleRequest) String() string {
 func (*CreateRoleRequest) ProtoMessage() {}
 
 func (x *CreateRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[117]
+	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 {
@@ -6664,7 +6664,7 @@ func (x *CreateRoleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateRoleRequest.ProtoReflect.Descriptor instead.
 func (*CreateRoleRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{117}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{117}
 }
 
 func (x *CreateRoleRequest) GetRole() *v1alpha12.Role {
@@ -6685,7 +6685,7 @@ type CreateRoleResponse struct {
 func (x *CreateRoleResponse) Reset() {
 	*x = CreateRoleResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[118]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[118]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6698,7 +6698,7 @@ func (x *CreateRoleResponse) String() string {
 func (*CreateRoleResponse) ProtoMessage() {}
 
 func (x *CreateRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[118]
+	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 {
@@ -6711,7 +6711,7 @@ func (x *CreateRoleResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateRoleResponse.ProtoReflect.Descriptor instead.
 func (*CreateRoleResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{118}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{118}
 }
 
 func (x *CreateRoleResponse) GetRole() *v1alpha12.Role {
@@ -6733,7 +6733,7 @@ type DeleteRoleRequest struct {
 func (x *DeleteRoleRequest) Reset() {
 	*x = DeleteRoleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[119]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[119]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6746,7 +6746,7 @@ func (x *DeleteRoleRequest) String() string {
 func (*DeleteRoleRequest) ProtoMessage() {}
 
 func (x *DeleteRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[119]
+	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 {
@@ -6759,7 +6759,7 @@ func (x *DeleteRoleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteRoleRequest.ProtoReflect.Descriptor instead.
 func (*DeleteRoleRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{119}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{119}
 }
 
 func (x *DeleteRoleRequest) GetProject() string {
@@ -6785,7 +6785,7 @@ type DeleteRoleResponse struct {
 func (x *DeleteRoleResponse) Reset() {
 	*x = DeleteRoleResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[120]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[120]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6798,7 +6798,7 @@ func (x *DeleteRoleResponse) String() string {
 func (*DeleteRoleResponse) ProtoMessage() {}
 
 func (x *DeleteRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[120]
+	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 {
@@ -6811,7 +6811,7 @@ func (x *DeleteRoleResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteRoleResponse.ProtoReflect.Descriptor instead.
 func (*DeleteRoleResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{120}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{120}
 }
 
 type GetRoleRequest struct {
@@ -6828,7 +6828,7 @@ type GetRoleRequest struct {
 func (x *GetRoleRequest) Reset() {
 	*x = GetRoleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[121]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[121]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6841,7 +6841,7 @@ func (x *GetRoleRequest) String() string {
 func (*GetRoleRequest) ProtoMessage() {}
 
 func (x *GetRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[121]
+	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 {
@@ -6854,7 +6854,7 @@ func (x *GetRoleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRoleRequest.ProtoReflect.Descriptor instead.
 func (*GetRoleRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{121}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{121}
 }
 
 func (x *GetRoleRequest) GetProject() string {
@@ -6901,7 +6901,7 @@ type GetRoleResponse struct {
 func (x *GetRoleResponse) Reset() {
 	*x = GetRoleResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[122]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[122]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -6914,7 +6914,7 @@ func (x *GetRoleResponse) String() string {
 func (*GetRoleResponse) ProtoMessage() {}
 
 func (x *GetRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[122]
+	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 {
@@ -6927,7 +6927,7 @@ func (x *GetRoleResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRoleResponse.ProtoReflect.Descriptor instead.
 func (*GetRoleResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{122}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{122}
 }
 
 func (m *GetRoleResponse) GetResult() isGetRoleResponse_Result {
@@ -6992,7 +6992,7 @@ type Claims struct {
 func (x *Claims) Reset() {
 	*x = Claims{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[123]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[123]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7005,7 +7005,7 @@ func (x *Claims) String() string {
 func (*Claims) ProtoMessage() {}
 
 func (x *Claims) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[123]
+	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 {
@@ -7018,7 +7018,7 @@ func (x *Claims) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Claims.ProtoReflect.Descriptor instead.
 func (*Claims) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{123}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{123}
 }
 
 func (x *Claims) GetClaims() []*v1alpha12.Claim {
@@ -7045,7 +7045,7 @@ type GrantRequest struct {
 func (x *GrantRequest) Reset() {
 	*x = GrantRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[124]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[124]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7058,7 +7058,7 @@ func (x *GrantRequest) String() string {
 func (*GrantRequest) ProtoMessage() {}
 
 func (x *GrantRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[124]
+	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 {
@@ -7071,7 +7071,7 @@ func (x *GrantRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GrantRequest.ProtoReflect.Descriptor instead.
 func (*GrantRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{124}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{124}
 }
 
 func (x *GrantRequest) GetProject() string {
@@ -7136,7 +7136,7 @@ type GrantResponse struct {
 func (x *GrantResponse) Reset() {
 	*x = GrantResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[125]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[125]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7149,7 +7149,7 @@ func (x *GrantResponse) String() string {
 func (*GrantResponse) ProtoMessage() {}
 
 func (x *GrantResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[125]
+	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 {
@@ -7162,7 +7162,7 @@ func (x *GrantResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GrantResponse.ProtoReflect.Descriptor instead.
 func (*GrantResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{125}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{125}
 }
 
 func (x *GrantResponse) GetRole() *v1alpha12.Role {
@@ -7184,7 +7184,7 @@ type ListRolesRequest struct {
 func (x *ListRolesRequest) Reset() {
 	*x = ListRolesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[126]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[126]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7197,7 +7197,7 @@ func (x *ListRolesRequest) String() string {
 func (*ListRolesRequest) ProtoMessage() {}
 
 func (x *ListRolesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[126]
+	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 {
@@ -7210,7 +7210,7 @@ func (x *ListRolesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListRolesRequest.ProtoReflect.Descriptor instead.
 func (*ListRolesRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{126}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{126}
 }
 
 func (x *ListRolesRequest) GetProject() string {
@@ -7240,7 +7240,7 @@ type ListRolesResponse struct {
 func (x *ListRolesResponse) Reset() {
 	*x = ListRolesResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[127]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[127]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7253,7 +7253,7 @@ func (x *ListRolesResponse) String() string {
 func (*ListRolesResponse) ProtoMessage() {}
 
 func (x *ListRolesResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[127]
+	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 {
@@ -7266,7 +7266,7 @@ func (x *ListRolesResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListRolesResponse.ProtoReflect.Descriptor instead.
 func (*ListRolesResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{127}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{127}
 }
 
 func (x *ListRolesResponse) GetRoles() []*v1alpha12.Role {
@@ -7300,7 +7300,7 @@ type RevokeRequest struct {
 func (x *RevokeRequest) Reset() {
 	*x = RevokeRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[128]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[128]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7313,7 +7313,7 @@ func (x *RevokeRequest) String() string {
 func (*RevokeRequest) ProtoMessage() {}
 
 func (x *RevokeRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[128]
+	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 {
@@ -7326,7 +7326,7 @@ func (x *RevokeRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RevokeRequest.ProtoReflect.Descriptor instead.
 func (*RevokeRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{128}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{128}
 }
 
 func (x *RevokeRequest) GetProject() string {
@@ -7391,7 +7391,7 @@ type RevokeResponse struct {
 func (x *RevokeResponse) Reset() {
 	*x = RevokeResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[129]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[129]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7404,7 +7404,7 @@ func (x *RevokeResponse) String() string {
 func (*RevokeResponse) ProtoMessage() {}
 
 func (x *RevokeResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[129]
+	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 {
@@ -7417,7 +7417,7 @@ func (x *RevokeResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use RevokeResponse.ProtoReflect.Descriptor instead.
 func (*RevokeResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{129}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{129}
 }
 
 func (x *RevokeResponse) GetRole() *v1alpha12.Role {
@@ -7438,7 +7438,7 @@ type UpdateRoleRequest struct {
 func (x *UpdateRoleRequest) Reset() {
 	*x = UpdateRoleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[130]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[130]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7451,7 +7451,7 @@ func (x *UpdateRoleRequest) String() string {
 func (*UpdateRoleRequest) ProtoMessage() {}
 
 func (x *UpdateRoleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[130]
+	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 {
@@ -7464,7 +7464,7 @@ func (x *UpdateRoleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateRoleRequest.ProtoReflect.Descriptor instead.
 func (*UpdateRoleRequest) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{130}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{130}
 }
 
 func (x *UpdateRoleRequest) GetRole() *v1alpha12.Role {
@@ -7485,7 +7485,7 @@ type UpdateRoleResponse struct {
 func (x *UpdateRoleResponse) Reset() {
 	*x = UpdateRoleResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_service_v1alpha1_service_proto_msgTypes[131]
+		mi := &file_api_service_v1alpha1_service_proto_msgTypes[131]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -7498,7 +7498,7 @@ func (x *UpdateRoleResponse) String() string {
 func (*UpdateRoleResponse) ProtoMessage() {}
 
 func (x *UpdateRoleResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_service_v1alpha1_service_proto_msgTypes[131]
+	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 {
@@ -7511,7 +7511,7 @@ func (x *UpdateRoleResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateRoleResponse.ProtoReflect.Descriptor instead.
 func (*UpdateRoleResponse) Descriptor() ([]byte, []int) {
-	return file_service_v1alpha1_service_proto_rawDescGZIP(), []int{131}
+	return file_api_service_v1alpha1_service_proto_rawDescGZIP(), []int{131}
 }
 
 func (x *UpdateRoleResponse) GetRole() *v1alpha12.Role {
@@ -7521,505 +7521,306 @@ func (x *UpdateRoleResponse) GetRole() *v1alpha12.Role {
 	return nil
 }
 
-var File_service_v1alpha1_service_proto protoreflect.FileDescriptor
+var File_api_service_v1alpha1_service_proto protoreflect.FileDescriptor
 
-var file_service_v1alpha1_service_proto_rawDesc = []byte{
-	0x0a, 0x1e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x12, 0x20, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
-	0x61, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65,
-	0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x6b,
-	0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76,
-	0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x1a, 0x25, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
-	0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x72, 0x62, 0x61, 0x63, 0x2f, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
-	0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb8, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70,
-	0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4a, 0x0a,
-	0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 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, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x06,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x03, 0x63, 0x6c, 0x69,
-	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, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
-	0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x01, 0x52, 0x03, 0x63, 0x6c, 0x69, 0x88, 0x01, 0x01, 0x42,
-	0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x63,
-	0x6c, 0x69, 0x22, 0xfe, 0x01, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
-	0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a,
-	0x67, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x67, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x67,
-	0x69, 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x08, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x44, 0x69, 0x72, 0x74,
-	0x79, 0x12, 0x39, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
-	0x67, 0x6f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x67, 0x6f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x63,
-	0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63,
-	0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66,
-	0x6f, 0x72, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66,
-	0x6f, 0x72, 0x6d, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
-	0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x16,
-	0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
-	0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 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,
-	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x76, 0x65, 0x72,
-	0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x0b,
-	0x41, 0x72, 0x67, 0x6f, 0x43, 0x44, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75,
-	0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1c, 0x0a,
-	0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xab, 0x02, 0x0a, 0x11,
-	0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x6a, 0x0a, 0x0d, 0x61, 0x72, 0x67, 0x6f, 0x63, 0x64, 0x5f, 0x73, 0x68, 0x61, 0x72,
-	0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x47, 0x65, 0x74, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x72,
-	0x67, 0x6f, 0x63, 0x64, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
-	0x0c, 0x61, 0x72, 0x67, 0x6f, 0x63, 0x64, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x3a, 0x0a,
-	0x19, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
-	0x6e, 0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x17, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
-	0x6e, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x6e, 0x0a, 0x11, 0x41, 0x72, 0x67,
-	0x6f, 0x63, 0x64, 0x53, 0x68, 0x61, 0x72, 0x64, 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,
+var file_api_service_v1alpha1_service_proto_rawDesc = []byte{
+	0x0a, 0x22, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x61,
+	0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61,
+	0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2b, 0x61, 0x70, 0x69, 0x2f, 0x73,
+	0x74, 0x75, 0x62, 0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2f, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x62, 0x61, 0x63,
+	0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61,
+	0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb8, 0x01, 0x0a, 0x11, 0x43, 0x6f,
+	0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
+	0x4a, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 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, 0x41, 0x72, 0x67, 0x6f, 0x43, 0x44, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74,
-	0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69,
-	0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x4d, 0x0a, 0x0b, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f,
-	0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x76,
-	0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x0a, 0x6f, 0x69, 0x64, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32,
-	0x0a, 0x15, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
-	0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61,
-	0x64, 0x6d, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c,
-	0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x75, 0x74, 0x68, 0x22,
-	0x84, 0x01, 0x0a, 0x0a, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d,
-	0x0a, 0x0a, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a,
-	0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63,
-	0x6f, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70,
-	0x65, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
-	0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x69, 0x43, 0x6c,
-	0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x2f, 0x0a, 0x11, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x4c,
-	0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70,
-	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
-	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2f, 0x0a, 0x12, 0x41, 0x64, 0x6d, 0x69, 0x6e,
-	0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a,
-	0x08, 0x69, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x33, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x76, 0x0a,
-	0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52,
-	0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3c, 0x0a, 0x19, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
-	0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65,
-	0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x63, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66,
-	0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x72,
-	0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x6a, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
-	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x50, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 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, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
-	0x73, 0x22, 0x3b, 0x0a, 0x1d, 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, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0xbc,
-	0x01, 0x0a, 0x1c, 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, 0x75, 0x6c, 0x74, 0x12,
-	0x3c, 0x0a, 0x19, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a,
-	0x19, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
-	0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
-	0x48, 0x00, 0x52, 0x17, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x65,
-	0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72,
-	0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x7a, 0x0a,
-	0x1e, 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,
-	0x58, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 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, 0x4f, 0x72, 0x55, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
-	0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x33, 0x0a, 0x15, 0x55, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x76,
-	0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3c, 0x0a, 0x19, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66,
-	0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x75, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69,
-	0x66, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a, 0x06,
-	0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x6a, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x50, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x36, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e, 0x6b, 0x61,
+	0x61, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00,
+	0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x03, 0x63,
+	0x6c, 0x69, 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, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x01, 0x52, 0x03, 0x63, 0x6c, 0x69, 0x88, 0x01,
+	0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04,
+	0x5f, 0x63, 0x6c, 0x69, 0x22, 0xfe, 0x01, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+	0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d,
+	0x0a, 0x0a, 0x67, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a,
+	0x0e, 0x67, 0x69, 0x74, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x74, 0x79, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x44, 0x69,
+	0x72, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x69, 0x6d,
+	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x67, 0x6f, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x67, 0x6f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a,
+	0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61,
+	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61,
+	0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a,
+	0x0a, 0x16, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 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, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d,
+	0x0a, 0x0b, 0x41, 0x72, 0x67, 0x6f, 0x43, 0x44, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a,
+	0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12,
+	0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xab, 0x02,
+	0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0d, 0x61, 0x72, 0x67, 0x6f, 0x63, 0x64, 0x5f, 0x73, 0x68,
+	0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x47, 0x65,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e,
+	0x41, 0x72, 0x67, 0x6f, 0x63, 0x64, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72,
+	0x79, 0x52, 0x0c, 0x61, 0x72, 0x67, 0x6f, 0x63, 0x64, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12,
+	0x3a, 0x0a, 0x19, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x17, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
+	0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x6e, 0x0a, 0x11, 0x41,
+	0x72, 0x67, 0x6f, 0x63, 0x64, 0x53, 0x68, 0x61, 0x72, 0x64, 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, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c,
-	0x74, 0x73, 0x22, 0x33, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d,
-	0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d,
-	0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x76, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12,
-	0x3c, 0x0a, 0x19, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73,
+	0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x72, 0x67, 0x6f, 0x43, 0x44, 0x53, 0x68, 0x61, 0x72, 0x64,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x18, 0x0a, 0x16, 0x47,
+	0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62,
+	0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x4d, 0x0a, 0x0b, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 0x2e, 0x6b, 0x61, 0x72, 0x67, 0x6f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x69, 0x64, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x12, 0x32, 0x0a, 0x15, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
+	0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x13, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x61,
+	0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x61, 0x75, 0x74,
+	0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x6b, 0x69, 0x70, 0x41, 0x75, 0x74,
+	0x68, 0x22, 0x84, 0x01, 0x0a, 0x0a, 0x4f, 0x49, 0x44, 0x43, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12,
+	0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06,
+	0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63,
+	0x6f, 0x70, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x5f, 0x63, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x69,
+	0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x2f, 0x0a, 0x11, 0x41, 0x64, 0x6d, 0x69,
+	0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a,
+	0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2f, 0x0a, 0x12, 0x41, 0x64, 0x6d,
+	0x69, 0x6e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x19, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x33, 0x0a, 0x15, 0x43, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22,
+	0x76, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3c, 0x0a, 0x19, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69,
+	0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x63, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e,
+	0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x6a, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x50, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 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, 0x52, 0x65, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x1d, 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, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74,
+	0x22, 0xbc, 0x01, 0x0a, 0x1c, 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, 0x75, 0x6c,
+	0x74, 0x12, 0x3c, 0x0a, 0x19, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52,
+	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12,
+	0x3c, 0x0a, 0x19, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73,
 	0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a,
-	0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05,
+	0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05,
 	0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
-	0x6a, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
-	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x07, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75,
-	0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x2d, 0x0a, 0x11, 0x4c,
-	0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 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, 0x59, 0x0a, 0x12, 0x4c, 0x69,
-	0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 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, 0x06, 0x73,
-	0x74, 0x61, 0x67, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61,
-	0x67, 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, 0xd3, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61,
-	0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x06, 0x69,
-	0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x4c,
-	0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x69,
-	0x6d, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x63, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x45,
-	0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
-	0x02, 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, 0x54, 0x61, 0x67, 0x4d, 0x61, 0x70, 0x52,
-	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xba, 0x01, 0x0a, 0x06, 0x54,
-	0x61, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 0x2e,
+	0x7a, 0x0a, 0x1e, 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, 0x58, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 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, 0x4f, 0x72, 0x55, 0x70,
+	0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x33, 0x0a, 0x15, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74,
+	0x22, 0x76, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
+	0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3c, 0x0a, 0x19, 0x75, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e,
+	0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x75,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61,
+	0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08,
+	0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x6a, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x50, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 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, 0x54, 0x61, 0x67, 0x4d, 0x61, 0x70, 0x2e, 0x54, 0x61,
-	0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x68, 0x0a,
-	0x09, 0x54, 0x61, 0x67, 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, 0x45, 0x0a, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x6b,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73,
+	0x75, 0x6c, 0x74, 0x73, 0x22, 0x33, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
+	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a,
+	0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x76, 0x0a, 0x14, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c,
+	0x74, 0x12, 0x3c, 0x0a, 0x19, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x17, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52,
+	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12,
+	0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
+	0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
+	0x74, 0x22, 0x6a, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x07, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x2d, 0x0a,
+	0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 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, 0x59, 0x0a, 0x12,
+	0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
+	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,
+	0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x49,
+	0x6d, 0x61, 0x67, 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, 0xd3, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x49,
+	0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a,
+	0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+	0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x63, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x18, 0x02, 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, 0x54, 0x61, 0x67, 0x4d, 0x61,
+	0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xba, 0x01, 0x0a,
+	0x06, 0x54, 0x61, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18,
+	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x54, 0x61, 0x67, 0x4d, 0x61, 0x70, 0x2e,
+	0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a,
+	0x68, 0x0a, 0x09, 0x54, 0x61, 0x67, 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, 0x45,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 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, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x52, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x01, 0x0a, 0x0d, 0x49, 0x6d,
+	0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x53, 0x0a, 0x06, 0x73,
+	0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x49,
-	0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x01, 0x0a, 0x0d, 0x49, 0x6d, 0x61, 0x67,
-	0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x12, 0x53, 0x0a, 0x06, 0x73, 0x74, 0x61,
-	0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 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, 0x49, 0x6d, 0x61,
-	0x67, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65,
-	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x39,
-	0x0a, 0x0b, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
-	0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
-	0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x84, 0x01, 0x0a, 0x0f, 0x47, 0x65,
-	0x74, 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, 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, 0x75, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
+	0x6d, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x2e, 0x53, 0x74, 0x61,
+	0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73,
+	0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+	0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+	0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x84, 0x01, 0x0a, 0x0f,
+	0x47, 0x65, 0x74, 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, 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, 0x75, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18,
+	0x01, 0x20, 0x01, 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, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 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, 0x42, 0x0a, 0x12, 0x57, 0x61, 0x74,
+	0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 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, 0x6c, 0x0a,
+	0x13, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
 	0x01, 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,
-	0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 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, 0x42, 0x0a, 0x12, 0x57, 0x61, 0x74, 0x63, 0x68,
-	0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+	0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x42, 0x0a, 0x12, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 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, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
+	0x15, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
+	0x68, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x6c, 0x0a, 0x13, 0x57,
-	0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 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, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x42, 0x0a, 0x12, 0x44, 0x65, 0x6c,
-	0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x59, 0x0a, 0x14, 0x52,
+	0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
+	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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x15, 0x0a,
-	0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x59, 0x0a, 0x14, 0x52, 0x65, 0x66,
-	0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 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, 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,
+	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, 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,
-	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, 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,
+	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,
@@ -8027,193 +7828,332 @@ var file_service_v1alpha1_service_proto_rawDesc = []byte{
 	0x69, 0x6f, 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,
+	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, 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,
+	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, 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,
+	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, 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, 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, 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,
+	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, 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, 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, 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,
+	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, 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, 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, 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, 0x08,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x75, 0x72,
-	0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x55, 0x52, 0x4c,
-	0x12, 0x29, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x5f, 0x69, 0x73, 0x5f,
-	0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x70,
-	0x6f, 0x55, 0x52, 0x4c, 0x49, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x75,
-	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75,
-	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
-	0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77,
-	0x6f, 0x72, 0x64, 0x22, 0x59, 0x0a, 0x19, 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, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 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, 0x48,
-	0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 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,
+	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, 0x22, 0x1b, 0x0a, 0x19, 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, 0x22, 0x8a, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65,
-	0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	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, 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, 0x76, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
-	0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b,
-	0x63, 0x72, 0x65, 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, 0x48, 0x00, 0x52,
-	0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 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, 0x32, 0x0a, 0x16, 0x4c, 0x69,
-	0x73, 0x74, 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, 0x74, 0x22, 0x57,
-	0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65,
-	0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 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, 0x0b, 0x63, 0x72, 0x65, 0x64,
-	0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x64, 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, 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, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f,
-	0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f,
-	0x55, 0x52, 0x4c, 0x12, 0x29, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x5f,
-	0x69, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e,
-	0x72, 0x65, 0x70, 0x6f, 0x55, 0x52, 0x4c, 0x49, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1a,
-	0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61,
-	0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
-	0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x59, 0x0a, 0x19, 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, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
-	0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69,
+	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, 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, 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, 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, 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, 0xa4, 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, 0x82, 0x01,
-	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, 0x53, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f,
-	0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74,
-	0x73, 0x2e, 0x61, 0x70, 0x69, 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,
+	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, 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, 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, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x5f,
+	0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x55,
+	0x52, 0x4c, 0x12, 0x29, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x5f, 0x69,
+	0x73, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72,
+	0x65, 0x70, 0x6f, 0x55, 0x52, 0x4c, 0x49, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1a, 0x0a,
+	0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73,
+	0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73,
+	0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x59, 0x0a, 0x19, 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, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 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, 0x48, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 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, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1b, 0x0a, 0x19, 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, 0x22, 0x8a, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 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, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
 	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
@@ -8221,761 +8161,817 @@ var file_service_v1alpha1_service_proto_rawDesc = []byte{
 	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, 0xc0, 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, 0x82, 0x01, 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, 0x53, 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, 0x69, 0x6e, 0x74, 0x65, 0x72,
-	0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x72,
-	0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x61, 0x70, 0x69, 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, 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, 0xc1,
-	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, 0x98, 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, 0x5a, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
-	0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f,
-	0x75, 0x74, 0x73, 0x2e, 0x61, 0x70, 0x69, 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, 0xdd, 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, 0x98, 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, 0x5a, 0x2e, 0x67, 0x69,
+	0x72, 0x6d, 0x61, 0x74, 0x22, 0x76, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e,
+	0x0a, 0x0b, 0x63, 0x72, 0x65, 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, 0x48,
+	0x00, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 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, 0x32, 0x0a, 0x16,
+	0x4c, 0x69, 0x73, 0x74, 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, 0x74,
+	0x22, 0x57, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69,
+	0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x63,
+	0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 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, 0x0b, 0x63, 0x72,
+	0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0xfc, 0x01, 0x0a, 0x18, 0x55, 0x70,
+	0x64, 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, 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, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65,
+	0x70, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65,
+	0x70, 0x6f, 0x55, 0x52, 0x4c, 0x12, 0x29, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x75, 0x72,
+	0x6c, 0x5f, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08,
+	0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x55, 0x52, 0x4c, 0x49, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78,
+	0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08,
+	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x59, 0x0a, 0x19, 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, 0x3c, 0x0a, 0x0b, 0x63, 0x72, 0x65, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75,
-	0x74, 0x73, 0x2e, 0x61, 0x70, 0x69, 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,
+	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, 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, 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, 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, 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, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69,
-	0x73, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x0c,
-	0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x4e, 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, 0x69, 0x6e, 0x74,
-	0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
-	0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x61, 0x70, 0x69, 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,
-	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,
+	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, 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, 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, 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, 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,
+	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, 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,
+	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,
+	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, 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, 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, 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,
+	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, 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,
+	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,
+	0xa7, 0x3f, 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, 0x74, 0x79,
+	0x2e, 0x69, 0x6f, 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, 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, 0x61, 0x6b,
+	0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 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, 0x69, 0x6f,
+	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, 0x61,
+	0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 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, 0x2e, 0x69,
+	0x6f, 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, 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, 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, 0xa7, 0x3f, 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,
+	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, 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,
+	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, 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,
+	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, 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, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62,
-	0x6c, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	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, 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,
+	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, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	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, 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, 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,
+	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,
+	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, 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,
+	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, 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, 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,
+	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, 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, 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, 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,
+	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, 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,
+	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, 0x69, 0x74, 0x79, 0x2e,
+	0x69, 0x6f, 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, 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,
+	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, 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,
+	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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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, 0x61, 0x6b, 0x75, 0x69,
+	0x74, 0x79, 0x2e, 0x69, 0x6f, 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, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f,
-	0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38,
+	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, 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,
+	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,
-	0x57, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
+	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, 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,
+	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, 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,
+	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, 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, 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,
+	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, 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, 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,
+	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, 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,
+	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, 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,
-	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, 0x83, 0x01, 0x0a, 0x0e,
-	0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x46, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x37,
+	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, 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, 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,
+	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, 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,
+	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, 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, 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, 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,
+	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, 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,
+	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, 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,
+	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, 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,
-	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, 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, 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,
+	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, 0x50, 0x72, 0x6f, 0x6a,
+	0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 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, 0x69, 0x6f, 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,
+	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, 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,
+	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, 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,
+	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,
-	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, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 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,
+	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,
-	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, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x61, 0x6b, 0x75,
+	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, 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,
+	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, 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, 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, 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, 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,
+	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, 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, 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, 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, 0x8c, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73,
-	0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3a,
+	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, 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, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 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,
+	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, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
+	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, 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, 0x69, 0x74, 0x79, 0x2e, 0x69, 0x6f, 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,
-	0x97, 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, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6b, 0x75, 0x69, 0x74, 0x79, 0x2f, 0x6b, 0x61, 0x72, 0x67,
-	0x6f, 0x2f, 0x70, 0x6b, 0x67, 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, 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,
+	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, 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 (
-	file_service_v1alpha1_service_proto_rawDescOnce sync.Once
-	file_service_v1alpha1_service_proto_rawDescData = file_service_v1alpha1_service_proto_rawDesc
+	file_api_service_v1alpha1_service_proto_rawDescOnce sync.Once
+	file_api_service_v1alpha1_service_proto_rawDescData = file_api_service_v1alpha1_service_proto_rawDesc
 )
 
-func file_service_v1alpha1_service_proto_rawDescGZIP() []byte {
-	file_service_v1alpha1_service_proto_rawDescOnce.Do(func() {
-		file_service_v1alpha1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_v1alpha1_service_proto_rawDescData)
+func file_api_service_v1alpha1_service_proto_rawDescGZIP() []byte {
+	file_api_service_v1alpha1_service_proto_rawDescOnce.Do(func() {
+		file_api_service_v1alpha1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_service_v1alpha1_service_proto_rawDescData)
 	})
-	return file_service_v1alpha1_service_proto_rawDescData
+	return file_api_service_v1alpha1_service_proto_rawDescData
 }
 
-var file_service_v1alpha1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_service_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 139)
-var file_service_v1alpha1_service_proto_goTypes = []interface{}{
+var file_api_service_v1alpha1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_api_service_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 139)
+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
 	(*VersionInfo)(nil),                           // 2: akuity.io.kargo.service.v1alpha1.VersionInfo
@@ -9123,16 +9119,16 @@ var file_service_v1alpha1_service_proto_goTypes = []interface{}{
 	(*v1alpha1.Freight)(nil),                      // 144: github.com.akuity.kargo.api.v1alpha1.Freight
 	(*v1alpha1.Warehouse)(nil),                    // 145: github.com.akuity.kargo.api.v1alpha1.Warehouse
 	(*v1.Secret)(nil),                             // 146: k8s.io.api.core.v1.Secret
-	(*v1alpha11.AnalysisTemplate)(nil),            // 147: github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate
-	(*v1alpha11.ClusterAnalysisTemplate)(nil),     // 148: github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate
-	(*v1alpha11.AnalysisRun)(nil),                 // 149: github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun
+	(*v1alpha11.AnalysisTemplate)(nil),            // 147: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
+	(*v1alpha11.ClusterAnalysisTemplate)(nil),     // 148: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
+	(*v1alpha11.AnalysisRun)(nil),                 // 149: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
 	(*v1.Event)(nil),                              // 150: k8s.io.api.core.v1.Event
 	(*v1alpha12.Role)(nil),                        // 151: github.com.akuity.kargo.api.rbac.v1alpha1.Role
 	(*v1alpha12.RoleResources)(nil),               // 152: github.com.akuity.kargo.api.rbac.v1alpha1.RoleResources
 	(*v1alpha12.Claim)(nil),                       // 153: github.com.akuity.kargo.api.rbac.v1alpha1.Claim
 	(*v1alpha12.ResourceDetails)(nil),             // 154: github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
 }
-var file_service_v1alpha1_service_proto_depIdxs = []int32{
+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
 	140, // 2: akuity.io.kargo.service.v1alpha1.VersionInfo.build_time:type_name -> google.protobuf.Timestamp
@@ -9180,14 +9176,14 @@ var file_service_v1alpha1_service_proto_depIdxs = []int32{
 	146, // 44: akuity.io.kargo.service.v1alpha1.GetCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
 	146, // 45: akuity.io.kargo.service.v1alpha1.ListCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
 	146, // 46: akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse.credentials:type_name -> k8s.io.api.core.v1.Secret
-	147, // 47: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse.analysis_templates:type_name -> github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate
+	147, // 47: akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse.analysis_templates:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
 	0,   // 48: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	147, // 49: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.analysis_template:type_name -> github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate
-	148, // 50: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse.cluster_analysis_templates:type_name -> github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate
+	147, // 49: akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse.analysis_template:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
+	148, // 50: akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse.cluster_analysis_templates:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
 	0,   // 51: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	148, // 52: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse.cluster_analysis_template:type_name -> github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate
+	148, // 52: akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse.cluster_analysis_template:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
 	0,   // 53: akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest.format:type_name -> akuity.io.kargo.service.v1alpha1.RawFormat
-	149, // 54: akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse.analysis_run:type_name -> github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun
+	149, // 54: akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse.analysis_run:type_name -> github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
 	150, // 55: akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse.events:type_name -> k8s.io.api.core.v1.Event
 	151, // 56: akuity.io.kargo.service.v1alpha1.CreateRoleRequest.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
 	151, // 57: akuity.io.kargo.service.v1alpha1.CreateRoleResponse.role:type_name -> github.com.akuity.kargo.api.rbac.v1alpha1.Role
@@ -9336,13 +9332,13 @@ var file_service_v1alpha1_service_proto_depIdxs = []int32{
 	0,   // [0:76] is the sub-list for field type_name
 }
 
-func init() { file_service_v1alpha1_service_proto_init() }
-func file_service_v1alpha1_service_proto_init() {
-	if File_service_v1alpha1_service_proto != nil {
+func init() { file_api_service_v1alpha1_service_proto_init() }
+func file_api_service_v1alpha1_service_proto_init() {
+	if File_api_service_v1alpha1_service_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_service_v1alpha1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ComponentVersions); i {
 			case 0:
 				return &v.state
@@ -9354,7 +9350,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*VersionInfo); i {
 			case 0:
 				return &v.state
@@ -9366,7 +9362,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetVersionInfoRequest); i {
 			case 0:
 				return &v.state
@@ -9378,7 +9374,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetVersionInfoResponse); i {
 			case 0:
 				return &v.state
@@ -9390,7 +9386,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetConfigRequest); i {
 			case 0:
 				return &v.state
@@ -9402,7 +9398,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ArgoCDShard); i {
 			case 0:
 				return &v.state
@@ -9414,7 +9410,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetConfigResponse); i {
 			case 0:
 				return &v.state
@@ -9426,7 +9422,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetPublicConfigRequest); i {
 			case 0:
 				return &v.state
@@ -9438,7 +9434,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetPublicConfigResponse); i {
 			case 0:
 				return &v.state
@@ -9450,7 +9446,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*OIDCConfig); i {
 			case 0:
 				return &v.state
@@ -9462,7 +9458,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AdminLoginRequest); i {
 			case 0:
 				return &v.state
@@ -9474,7 +9470,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AdminLoginResponse); i {
 			case 0:
 				return &v.state
@@ -9486,7 +9482,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateResourceRequest); i {
 			case 0:
 				return &v.state
@@ -9498,7 +9494,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateResourceResult); i {
 			case 0:
 				return &v.state
@@ -9510,7 +9506,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateResourceResponse); i {
 			case 0:
 				return &v.state
@@ -9522,7 +9518,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateOrUpdateResourceRequest); i {
 			case 0:
 				return &v.state
@@ -9534,7 +9530,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateOrUpdateResourceResult); i {
 			case 0:
 				return &v.state
@@ -9546,7 +9542,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateOrUpdateResourceResponse); i {
 			case 0:
 				return &v.state
@@ -9558,7 +9554,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateResourceRequest); i {
 			case 0:
 				return &v.state
@@ -9570,7 +9566,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateResourceResult); i {
 			case 0:
 				return &v.state
@@ -9582,7 +9578,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateResourceResponse); i {
 			case 0:
 				return &v.state
@@ -9594,7 +9590,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteResourceRequest); i {
 			case 0:
 				return &v.state
@@ -9606,7 +9602,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteResourceResult); i {
 			case 0:
 				return &v.state
@@ -9618,7 +9614,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteResourceResponse); i {
 			case 0:
 				return &v.state
@@ -9630,7 +9626,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListStagesRequest); i {
 			case 0:
 				return &v.state
@@ -9642,7 +9638,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListStagesResponse); i {
 			case 0:
 				return &v.state
@@ -9654,7 +9650,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListImagesRequest); i {
 			case 0:
 				return &v.state
@@ -9666,7 +9662,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListImagesResponse); i {
 			case 0:
 				return &v.state
@@ -9678,7 +9674,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*TagMap); i {
 			case 0:
 				return &v.state
@@ -9690,7 +9686,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ImageStageMap); i {
 			case 0:
 				return &v.state
@@ -9702,7 +9698,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetStageRequest); i {
 			case 0:
 				return &v.state
@@ -9714,7 +9710,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetStageResponse); i {
 			case 0:
 				return &v.state
@@ -9726,7 +9722,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchStagesRequest); i {
 			case 0:
 				return &v.state
@@ -9738,7 +9734,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchStagesResponse); i {
 			case 0:
 				return &v.state
@@ -9750,7 +9746,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteStageRequest); i {
 			case 0:
 				return &v.state
@@ -9762,7 +9758,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteStageResponse); i {
 			case 0:
 				return &v.state
@@ -9774,7 +9770,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RefreshStageRequest); i {
 			case 0:
 				return &v.state
@@ -9786,7 +9782,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RefreshStageResponse); i {
 			case 0:
 				return &v.state
@@ -9798,7 +9794,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListPromotionsRequest); i {
 			case 0:
 				return &v.state
@@ -9810,7 +9806,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListPromotionsResponse); i {
 			case 0:
 				return &v.state
@@ -9822,7 +9818,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchPromotionsRequest); i {
 			case 0:
 				return &v.state
@@ -9834,7 +9830,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchPromotionsResponse); i {
 			case 0:
 				return &v.state
@@ -9846,7 +9842,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetPromotionRequest); i {
 			case 0:
 				return &v.state
@@ -9858,7 +9854,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetPromotionResponse); i {
 			case 0:
 				return &v.state
@@ -9870,7 +9866,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchPromotionRequest); i {
 			case 0:
 				return &v.state
@@ -9882,7 +9878,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchPromotionResponse); i {
 			case 0:
 				return &v.state
@@ -9894,7 +9890,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AbortPromotionRequest); i {
 			case 0:
 				return &v.state
@@ -9906,7 +9902,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AbortPromotionResponse); i {
 			case 0:
 				return &v.state
@@ -9918,7 +9914,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteProjectRequest); i {
 			case 0:
 				return &v.state
@@ -9930,7 +9926,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteProjectResponse); i {
 			case 0:
 				return &v.state
@@ -9942,7 +9938,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetProjectRequest); i {
 			case 0:
 				return &v.state
@@ -9954,7 +9950,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetProjectResponse); i {
 			case 0:
 				return &v.state
@@ -9966,7 +9962,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListProjectsRequest); i {
 			case 0:
 				return &v.state
@@ -9978,7 +9974,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListProjectsResponse); i {
 			case 0:
 				return &v.state
@@ -9990,7 +9986,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ApproveFreightRequest); i {
 			case 0:
 				return &v.state
@@ -10002,7 +9998,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ApproveFreightResponse); i {
 			case 0:
 				return &v.state
@@ -10014,7 +10010,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteFreightRequest); i {
 			case 0:
 				return &v.state
@@ -10026,7 +10022,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteFreightResponse); i {
 			case 0:
 				return &v.state
@@ -10038,7 +10034,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetFreightRequest); i {
 			case 0:
 				return &v.state
@@ -10050,7 +10046,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetFreightResponse); i {
 			case 0:
 				return &v.state
@@ -10062,7 +10058,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PromoteToStageRequest); i {
 			case 0:
 				return &v.state
@@ -10074,7 +10070,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PromoteToStageResponse); i {
 			case 0:
 				return &v.state
@@ -10086,7 +10082,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PromoteDownstreamRequest); i {
 			case 0:
 				return &v.state
@@ -10098,7 +10094,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PromoteDownstreamResponse); i {
 			case 0:
 				return &v.state
@@ -10110,7 +10106,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*QueryFreightRequest); i {
 			case 0:
 				return &v.state
@@ -10122,7 +10118,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*QueryFreightResponse); i {
 			case 0:
 				return &v.state
@@ -10134,7 +10130,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*FreightList); i {
 			case 0:
 				return &v.state
@@ -10146,7 +10142,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateFreightAliasRequest); i {
 			case 0:
 				return &v.state
@@ -10158,7 +10154,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateFreightAliasResponse); i {
 			case 0:
 				return &v.state
@@ -10170,7 +10166,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ReverifyRequest); i {
 			case 0:
 				return &v.state
@@ -10182,7 +10178,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ReverifyResponse); i {
 			case 0:
 				return &v.state
@@ -10194,7 +10190,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AbortVerificationRequest); i {
 			case 0:
 				return &v.state
@@ -10206,7 +10202,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AbortVerificationResponse); i {
 			case 0:
 				return &v.state
@@ -10218,7 +10214,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListWarehousesRequest); i {
 			case 0:
 				return &v.state
@@ -10230,7 +10226,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListWarehousesResponse); i {
 			case 0:
 				return &v.state
@@ -10242,7 +10238,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetWarehouseRequest); i {
 			case 0:
 				return &v.state
@@ -10254,7 +10250,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetWarehouseResponse); i {
 			case 0:
 				return &v.state
@@ -10266,7 +10262,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchWarehousesRequest); i {
 			case 0:
 				return &v.state
@@ -10278,7 +10274,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*WatchWarehousesResponse); i {
 			case 0:
 				return &v.state
@@ -10290,7 +10286,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteWarehouseRequest); i {
 			case 0:
 				return &v.state
@@ -10302,7 +10298,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteWarehouseResponse); i {
 			case 0:
 				return &v.state
@@ -10314,7 +10310,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[81].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.(*RefreshWarehouseRequest); i {
 			case 0:
 				return &v.state
@@ -10326,7 +10322,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[82].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.(*RefreshWarehouseResponse); i {
 			case 0:
 				return &v.state
@@ -10338,7 +10334,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[83].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.(*ListProjectSecretsRequest); i {
 			case 0:
 				return &v.state
@@ -10350,7 +10346,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[84].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.(*ListProjectSecretsResponse); i {
 			case 0:
 				return &v.state
@@ -10362,7 +10358,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[85].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.(*CreateProjectSecretRequest); i {
 			case 0:
 				return &v.state
@@ -10374,7 +10370,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[86].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.(*CreateProjectSecretResponse); i {
 			case 0:
 				return &v.state
@@ -10386,7 +10382,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[87].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.(*UpdateProjectSecretRequest); i {
 			case 0:
 				return &v.state
@@ -10398,7 +10394,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[88].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.(*UpdateProjectSecretResponse); i {
 			case 0:
 				return &v.state
@@ -10410,7 +10406,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[89].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.(*DeleteProjectSecretRequest); i {
 			case 0:
 				return &v.state
@@ -10422,7 +10418,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[90].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.(*DeleteProjectSecretResponse); i {
 			case 0:
 				return &v.state
@@ -10434,7 +10430,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[91].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.(*CreateCredentialsRequest); i {
 			case 0:
 				return &v.state
@@ -10446,7 +10442,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[92].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.(*CreateCredentialsResponse); i {
 			case 0:
 				return &v.state
@@ -10458,7 +10454,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[93].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.(*DeleteCredentialsRequest); i {
 			case 0:
 				return &v.state
@@ -10470,7 +10466,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[94].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.(*DeleteCredentialsResponse); i {
 			case 0:
 				return &v.state
@@ -10482,7 +10478,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[95].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.(*GetCredentialsRequest); i {
 			case 0:
 				return &v.state
@@ -10494,7 +10490,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[96].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.(*GetCredentialsResponse); i {
 			case 0:
 				return &v.state
@@ -10506,7 +10502,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[97].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.(*ListCredentialsRequest); i {
 			case 0:
 				return &v.state
@@ -10518,7 +10514,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[98].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.(*ListCredentialsResponse); i {
 			case 0:
 				return &v.state
@@ -10530,7 +10526,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[99].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.(*UpdateCredentialsRequest); i {
 			case 0:
 				return &v.state
@@ -10542,7 +10538,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[100].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.(*UpdateCredentialsResponse); i {
 			case 0:
 				return &v.state
@@ -10554,7 +10550,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListAnalysisTemplatesRequest); i {
 			case 0:
 				return &v.state
@@ -10566,7 +10562,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListAnalysisTemplatesResponse); i {
 			case 0:
 				return &v.state
@@ -10578,7 +10574,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
@@ -10590,7 +10586,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
@@ -10602,7 +10598,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListClusterAnalysisTemplatesRequest); i {
 			case 0:
 				return &v.state
@@ -10614,7 +10610,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListClusterAnalysisTemplatesResponse); i {
 			case 0:
 				return &v.state
@@ -10626,7 +10622,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetClusterAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
@@ -10638,7 +10634,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[108].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetClusterAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
@@ -10650,7 +10646,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetAnalysisRunRequest); i {
 			case 0:
 				return &v.state
@@ -10662,7 +10658,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetAnalysisRunResponse); i {
 			case 0:
 				return &v.state
@@ -10674,7 +10670,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
@@ -10686,7 +10682,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
@@ -10698,7 +10694,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteClusterAnalysisTemplateRequest); i {
 			case 0:
 				return &v.state
@@ -10710,7 +10706,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteClusterAnalysisTemplateResponse); i {
 			case 0:
 				return &v.state
@@ -10722,7 +10718,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[115].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListProjectEventsRequest); i {
 			case 0:
 				return &v.state
@@ -10734,7 +10730,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListProjectEventsResponse); i {
 			case 0:
 				return &v.state
@@ -10746,7 +10742,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[117].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateRoleRequest); i {
 			case 0:
 				return &v.state
@@ -10758,7 +10754,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[118].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateRoleResponse); i {
 			case 0:
 				return &v.state
@@ -10770,7 +10766,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[119].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.(*DeleteRoleRequest); i {
 			case 0:
 				return &v.state
@@ -10782,7 +10778,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[120].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.(*DeleteRoleResponse); i {
 			case 0:
 				return &v.state
@@ -10794,7 +10790,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[121].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetRoleRequest); i {
 			case 0:
 				return &v.state
@@ -10806,7 +10802,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[122].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetRoleResponse); i {
 			case 0:
 				return &v.state
@@ -10818,7 +10814,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[123].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Claims); i {
 			case 0:
 				return &v.state
@@ -10830,7 +10826,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[124].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GrantRequest); i {
 			case 0:
 				return &v.state
@@ -10842,7 +10838,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[125].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[125].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GrantResponse); i {
 			case 0:
 				return &v.state
@@ -10854,7 +10850,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[126].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[126].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListRolesRequest); i {
 			case 0:
 				return &v.state
@@ -10866,7 +10862,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[127].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[127].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListRolesResponse); i {
 			case 0:
 				return &v.state
@@ -10878,7 +10874,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[128].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[128].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RevokeRequest); i {
 			case 0:
 				return &v.state
@@ -10890,7 +10886,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[129].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[129].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*RevokeResponse); i {
 			case 0:
 				return &v.state
@@ -10902,7 +10898,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[130].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateRoleRequest); i {
 			case 0:
 				return &v.state
@@ -10914,7 +10910,7 @@ func file_service_v1alpha1_service_proto_init() {
 				return nil
 			}
 		}
-		file_service_v1alpha1_service_proto_msgTypes[131].Exporter = func(v interface{}, i int) interface{} {
+		file_api_service_v1alpha1_service_proto_msgTypes[131].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateRoleResponse); i {
 			case 0:
 				return &v.state
@@ -10927,73 +10923,73 @@ func file_service_v1alpha1_service_proto_init() {
 			}
 		}
 	}
-	file_service_v1alpha1_service_proto_msgTypes[0].OneofWrappers = []interface{}{}
-	file_service_v1alpha1_service_proto_msgTypes[13].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[0].OneofWrappers = []interface{}{}
+	file_api_service_v1alpha1_service_proto_msgTypes[13].OneofWrappers = []interface{}{
 		(*CreateResourceResult_CreatedResourceManifest)(nil),
 		(*CreateResourceResult_Error)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[16].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[16].OneofWrappers = []interface{}{
 		(*CreateOrUpdateResourceResult_CreatedResourceManifest)(nil),
 		(*CreateOrUpdateResourceResult_UpdatedResourceManifest)(nil),
 		(*CreateOrUpdateResourceResult_Error)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[19].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[19].OneofWrappers = []interface{}{
 		(*UpdateResourceResult_UpdatedResourceManifest)(nil),
 		(*UpdateResourceResult_Error)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[22].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[22].OneofWrappers = []interface{}{
 		(*DeleteResourceResult_DeletedResourceManifest)(nil),
 		(*DeleteResourceResult_Error)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[31].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[31].OneofWrappers = []interface{}{
 		(*GetStageResponse_Stage)(nil),
 		(*GetStageResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[38].OneofWrappers = []interface{}{}
-	file_service_v1alpha1_service_proto_msgTypes[40].OneofWrappers = []interface{}{}
-	file_service_v1alpha1_service_proto_msgTypes[43].OneofWrappers = []interface{}{
+	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{}{
 		(*GetPromotionResponse_Promotion)(nil),
 		(*GetPromotionResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[51].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[51].OneofWrappers = []interface{}{
 		(*GetProjectResponse_Project)(nil),
 		(*GetProjectResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[52].OneofWrappers = []interface{}{}
-	file_service_v1alpha1_service_proto_msgTypes[59].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[52].OneofWrappers = []interface{}{}
+	file_api_service_v1alpha1_service_proto_msgTypes[59].OneofWrappers = []interface{}{
 		(*GetFreightResponse_Freight)(nil),
 		(*GetFreightResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[76].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[76].OneofWrappers = []interface{}{
 		(*GetWarehouseResponse_Warehouse)(nil),
 		(*GetWarehouseResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[96].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[96].OneofWrappers = []interface{}{
 		(*GetCredentialsResponse_Credentials)(nil),
 		(*GetCredentialsResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[104].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[104].OneofWrappers = []interface{}{
 		(*GetAnalysisTemplateResponse_AnalysisTemplate)(nil),
 		(*GetAnalysisTemplateResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[108].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[108].OneofWrappers = []interface{}{
 		(*GetClusterAnalysisTemplateResponse_ClusterAnalysisTemplate)(nil),
 		(*GetClusterAnalysisTemplateResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[110].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[110].OneofWrappers = []interface{}{
 		(*GetAnalysisRunResponse_AnalysisRun)(nil),
 		(*GetAnalysisRunResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[122].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[122].OneofWrappers = []interface{}{
 		(*GetRoleResponse_Role)(nil),
 		(*GetRoleResponse_Resources)(nil),
 		(*GetRoleResponse_Raw)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[124].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[124].OneofWrappers = []interface{}{
 		(*GrantRequest_UserClaims)(nil),
 		(*GrantRequest_ResourceDetails)(nil),
 	}
-	file_service_v1alpha1_service_proto_msgTypes[128].OneofWrappers = []interface{}{
+	file_api_service_v1alpha1_service_proto_msgTypes[128].OneofWrappers = []interface{}{
 		(*RevokeRequest_UserClaims)(nil),
 		(*RevokeRequest_ResourceDetails)(nil),
 	}
@@ -11001,19 +10997,19 @@ func file_service_v1alpha1_service_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_service_v1alpha1_service_proto_rawDesc,
+			RawDescriptor: file_api_service_v1alpha1_service_proto_rawDesc,
 			NumEnums:      1,
 			NumMessages:   139,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_service_v1alpha1_service_proto_goTypes,
-		DependencyIndexes: file_service_v1alpha1_service_proto_depIdxs,
-		EnumInfos:         file_service_v1alpha1_service_proto_enumTypes,
-		MessageInfos:      file_service_v1alpha1_service_proto_msgTypes,
+		GoTypes:           file_api_service_v1alpha1_service_proto_goTypes,
+		DependencyIndexes: file_api_service_v1alpha1_service_proto_depIdxs,
+		EnumInfos:         file_api_service_v1alpha1_service_proto_enumTypes,
+		MessageInfos:      file_api_service_v1alpha1_service_proto_msgTypes,
 	}.Build()
-	File_service_v1alpha1_service_proto = out.File
-	file_service_v1alpha1_service_proto_rawDesc = nil
-	file_service_v1alpha1_service_proto_goTypes = nil
-	file_service_v1alpha1_service_proto_depIdxs = nil
+	File_api_service_v1alpha1_service_proto = out.File
+	file_api_service_v1alpha1_service_proto_rawDesc = nil
+	file_api_service_v1alpha1_service_proto_goTypes = nil
+	file_api_service_v1alpha1_service_proto_depIdxs = nil
 }
diff --git a/api/service/v1alpha1/service.proto b/api/service/v1alpha1/service.proto
index 708ea3ac..cf278582 100644
--- a/api/service/v1alpha1/service.proto
+++ b/api/service/v1alpha1/service.proto
@@ -3,12 +3,12 @@ syntax = "proto3";
 package akuity.io.kargo.service.v1alpha1;
 
 import "google/protobuf/timestamp.proto";
-import "v1alpha1/generated.proto";
+import "api/v1alpha1/generated.proto";
 import "k8s.io/api/core/v1/generated.proto";
-import "rollouts/api/v1alpha1/generated.proto";
-import "rbac/v1alpha1/generated.proto";
+import "api/stubs/rollouts/v1alpha1/generated.proto";
+import "api/rbac/v1alpha1/generated.proto";
 
-option go_package = "github.com/akuity/kargo/pkg/api/service/v1alpha1;svcv1alpha1";
+option go_package = "github.com/akuity/kargo/api/service/v1alpha1;svcv1alpha1";
 
 enum RawFormat {
   RAW_FORMAT_UNSPECIFIED = 0;
@@ -642,7 +642,7 @@ message ListAnalysisTemplatesRequest {
 }
 
 message ListAnalysisTemplatesResponse {
-  repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate analysis_templates = 1 [json_name = "analysisTemplates"];
+  repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_templates = 1 [json_name = "analysisTemplates"];
 }
 
 message GetAnalysisTemplateRequest {
@@ -653,7 +653,7 @@ message GetAnalysisTemplateRequest {
 
 message GetAnalysisTemplateResponse {
   oneof result {
-    github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate analysis_template = 1 [json_name = "analysisTemplate"];
+    github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_template = 1 [json_name = "analysisTemplate"];
     bytes raw = 2;
   }
 }
@@ -661,7 +661,7 @@ message GetAnalysisTemplateResponse {
 message ListClusterAnalysisTemplatesRequest {}
 
 message ListClusterAnalysisTemplatesResponse {
-  repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate cluster_analysis_templates = 1 [json_name = "clusteranalysisTemplates"];
+  repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate cluster_analysis_templates = 1 [json_name = "clusteranalysisTemplates"];
 }
 
 message GetClusterAnalysisTemplateRequest {
@@ -671,7 +671,7 @@ message GetClusterAnalysisTemplateRequest {
 
 message GetClusterAnalysisTemplateResponse {
   oneof result {
-    github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate cluster_analysis_template = 1 [json_name = "clusterAnalysisTemplate"];
+    github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate cluster_analysis_template = 1 [json_name = "clusterAnalysisTemplate"];
     bytes raw = 2;
   }
 }
@@ -684,7 +684,7 @@ message GetAnalysisRunRequest {
 
 message GetAnalysisRunResponse {
   oneof result {
-    github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun analysis_run = 1 [json_name = "analysisRun"];
+    github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun analysis_run = 1 [json_name = "analysisRun"];
     bytes raw = 2;
   }
 }
diff --git a/pkg/api/service/v1alpha1/svcv1alpha1connect/service.connect.go b/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
similarity index 99%
rename from pkg/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
rename to api/service/v1alpha1/svcv1alpha1connect/service.connect.go
index 686974f0..4499cf47 100644
--- a/pkg/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
+++ b/api/service/v1alpha1/svcv1alpha1connect/service.connect.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-connect-go. DO NOT EDIT.
 //
-// Source: service/v1alpha1/service.proto
+// Source: api/service/v1alpha1/service.proto
 
 package svcv1alpha1connect
 
@@ -8,7 +8,7 @@ import (
 	connect "connectrpc.com/connect"
 	context "context"
 	errors "errors"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	http "net/http"
 	strings "strings"
 )
@@ -202,7 +202,7 @@ const (
 
 // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package.
 var (
-	kargoServiceServiceDescriptor                             = v1alpha1.File_service_v1alpha1_service_proto.Services().ByName("KargoService")
+	kargoServiceServiceDescriptor                             = v1alpha1.File_api_service_v1alpha1_service_proto.Services().ByName("KargoService")
 	kargoServiceGetVersionInfoMethodDescriptor                = kargoServiceServiceDescriptor.Methods().ByName("GetVersionInfo")
 	kargoServiceGetConfigMethodDescriptor                     = kargoServiceServiceDescriptor.Methods().ByName("GetConfig")
 	kargoServiceGetPublicConfigMethodDescriptor               = kargoServiceServiceDescriptor.Methods().ByName("GetPublicConfig")
diff --git a/internal/controller/rollouts/api/v1alpha1/analysis_types.go b/api/stubs/rollouts/v1alpha1/analysis_types.go
similarity index 100%
rename from internal/controller/rollouts/api/v1alpha1/analysis_types.go
rename to api/stubs/rollouts/v1alpha1/analysis_types.go
diff --git a/internal/controller/rollouts/api/v1alpha1/doc.go b/api/stubs/rollouts/v1alpha1/doc.go
similarity index 100%
rename from internal/controller/rollouts/api/v1alpha1/doc.go
rename to api/stubs/rollouts/v1alpha1/doc.go
diff --git a/internal/controller/rollouts/api/v1alpha1/generated.pb.go b/api/stubs/rollouts/v1alpha1/generated.pb.go
similarity index 92%
rename from internal/controller/rollouts/api/v1alpha1/generated.pb.go
rename to api/stubs/rollouts/v1alpha1/generated.pb.go
index eff9961e..da248651 100644
--- a/internal/controller/rollouts/api/v1alpha1/generated.pb.go
+++ b/api/stubs/rollouts/v1alpha1/generated.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1/generated.proto
+// source: github.com/akuity/kargo/api/stubs/rollouts/v1alpha1/generated.proto
 
 package v1alpha1
 
@@ -35,7 +35,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 func (m *AnalysisRun) Reset()      { *m = AnalysisRun{} }
 func (*AnalysisRun) ProtoMessage() {}
 func (*AnalysisRun) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{0}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{0}
 }
 func (m *AnalysisRun) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -63,7 +63,7 @@ var xxx_messageInfo_AnalysisRun proto.InternalMessageInfo
 func (m *AnalysisRunList) Reset()      { *m = AnalysisRunList{} }
 func (*AnalysisRunList) ProtoMessage() {}
 func (*AnalysisRunList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{1}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{1}
 }
 func (m *AnalysisRunList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -91,7 +91,7 @@ var xxx_messageInfo_AnalysisRunList proto.InternalMessageInfo
 func (m *AnalysisRunSpec) Reset()      { *m = AnalysisRunSpec{} }
 func (*AnalysisRunSpec) ProtoMessage() {}
 func (*AnalysisRunSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{2}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{2}
 }
 func (m *AnalysisRunSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -119,7 +119,7 @@ var xxx_messageInfo_AnalysisRunSpec proto.InternalMessageInfo
 func (m *AnalysisRunStatus) Reset()      { *m = AnalysisRunStatus{} }
 func (*AnalysisRunStatus) ProtoMessage() {}
 func (*AnalysisRunStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{3}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{3}
 }
 func (m *AnalysisRunStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -147,7 +147,7 @@ var xxx_messageInfo_AnalysisRunStatus proto.InternalMessageInfo
 func (m *AnalysisTemplate) Reset()      { *m = AnalysisTemplate{} }
 func (*AnalysisTemplate) ProtoMessage() {}
 func (*AnalysisTemplate) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{4}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{4}
 }
 func (m *AnalysisTemplate) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -175,7 +175,7 @@ var xxx_messageInfo_AnalysisTemplate proto.InternalMessageInfo
 func (m *AnalysisTemplateList) Reset()      { *m = AnalysisTemplateList{} }
 func (*AnalysisTemplateList) ProtoMessage() {}
 func (*AnalysisTemplateList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{5}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{5}
 }
 func (m *AnalysisTemplateList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -203,7 +203,7 @@ var xxx_messageInfo_AnalysisTemplateList proto.InternalMessageInfo
 func (m *AnalysisTemplateSpec) Reset()      { *m = AnalysisTemplateSpec{} }
 func (*AnalysisTemplateSpec) ProtoMessage() {}
 func (*AnalysisTemplateSpec) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{6}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{6}
 }
 func (m *AnalysisTemplateSpec) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -231,7 +231,7 @@ var xxx_messageInfo_AnalysisTemplateSpec proto.InternalMessageInfo
 func (m *Argument) Reset()      { *m = Argument{} }
 func (*Argument) ProtoMessage() {}
 func (*Argument) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{7}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{7}
 }
 func (m *Argument) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -259,7 +259,7 @@ var xxx_messageInfo_Argument proto.InternalMessageInfo
 func (m *Authentication) Reset()      { *m = Authentication{} }
 func (*Authentication) ProtoMessage() {}
 func (*Authentication) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{8}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{8}
 }
 func (m *Authentication) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -287,7 +287,7 @@ var xxx_messageInfo_Authentication proto.InternalMessageInfo
 func (m *CloudWatchMetric) Reset()      { *m = CloudWatchMetric{} }
 func (*CloudWatchMetric) ProtoMessage() {}
 func (*CloudWatchMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{9}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{9}
 }
 func (m *CloudWatchMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -315,7 +315,7 @@ var xxx_messageInfo_CloudWatchMetric proto.InternalMessageInfo
 func (m *CloudWatchMetricDataQuery) Reset()      { *m = CloudWatchMetricDataQuery{} }
 func (*CloudWatchMetricDataQuery) ProtoMessage() {}
 func (*CloudWatchMetricDataQuery) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{10}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{10}
 }
 func (m *CloudWatchMetricDataQuery) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -343,7 +343,7 @@ var xxx_messageInfo_CloudWatchMetricDataQuery proto.InternalMessageInfo
 func (m *CloudWatchMetricStat) Reset()      { *m = CloudWatchMetricStat{} }
 func (*CloudWatchMetricStat) ProtoMessage() {}
 func (*CloudWatchMetricStat) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{11}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{11}
 }
 func (m *CloudWatchMetricStat) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -371,7 +371,7 @@ var xxx_messageInfo_CloudWatchMetricStat proto.InternalMessageInfo
 func (m *CloudWatchMetricStatMetric) Reset()      { *m = CloudWatchMetricStatMetric{} }
 func (*CloudWatchMetricStatMetric) ProtoMessage() {}
 func (*CloudWatchMetricStatMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{12}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{12}
 }
 func (m *CloudWatchMetricStatMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -399,7 +399,7 @@ var xxx_messageInfo_CloudWatchMetricStatMetric proto.InternalMessageInfo
 func (m *CloudWatchMetricStatMetricDimension) Reset()      { *m = CloudWatchMetricStatMetricDimension{} }
 func (*CloudWatchMetricStatMetricDimension) ProtoMessage() {}
 func (*CloudWatchMetricStatMetricDimension) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{13}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{13}
 }
 func (m *CloudWatchMetricStatMetricDimension) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -427,7 +427,7 @@ var xxx_messageInfo_CloudWatchMetricStatMetricDimension proto.InternalMessageInf
 func (m *ClusterAnalysisTemplate) Reset()      { *m = ClusterAnalysisTemplate{} }
 func (*ClusterAnalysisTemplate) ProtoMessage() {}
 func (*ClusterAnalysisTemplate) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{14}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{14}
 }
 func (m *ClusterAnalysisTemplate) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -455,7 +455,7 @@ var xxx_messageInfo_ClusterAnalysisTemplate proto.InternalMessageInfo
 func (m *ClusterAnalysisTemplateList) Reset()      { *m = ClusterAnalysisTemplateList{} }
 func (*ClusterAnalysisTemplateList) ProtoMessage() {}
 func (*ClusterAnalysisTemplateList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{15}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{15}
 }
 func (m *ClusterAnalysisTemplateList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -483,7 +483,7 @@ var xxx_messageInfo_ClusterAnalysisTemplateList proto.InternalMessageInfo
 func (m *DatadogMetric) Reset()      { *m = DatadogMetric{} }
 func (*DatadogMetric) ProtoMessage() {}
 func (*DatadogMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{16}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{16}
 }
 func (m *DatadogMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -511,7 +511,7 @@ var xxx_messageInfo_DatadogMetric proto.InternalMessageInfo
 func (m *DryRun) Reset()      { *m = DryRun{} }
 func (*DryRun) ProtoMessage() {}
 func (*DryRun) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{17}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{17}
 }
 func (m *DryRun) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -539,7 +539,7 @@ var xxx_messageInfo_DryRun proto.InternalMessageInfo
 func (m *FieldRef) Reset()      { *m = FieldRef{} }
 func (*FieldRef) ProtoMessage() {}
 func (*FieldRef) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{18}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{18}
 }
 func (m *FieldRef) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -567,7 +567,7 @@ var xxx_messageInfo_FieldRef proto.InternalMessageInfo
 func (m *GraphiteMetric) Reset()      { *m = GraphiteMetric{} }
 func (*GraphiteMetric) ProtoMessage() {}
 func (*GraphiteMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{19}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{19}
 }
 func (m *GraphiteMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -595,7 +595,7 @@ var xxx_messageInfo_GraphiteMetric proto.InternalMessageInfo
 func (m *InfluxdbMetric) Reset()      { *m = InfluxdbMetric{} }
 func (*InfluxdbMetric) ProtoMessage() {}
 func (*InfluxdbMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{20}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{20}
 }
 func (m *InfluxdbMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -623,7 +623,7 @@ var xxx_messageInfo_InfluxdbMetric proto.InternalMessageInfo
 func (m *JobMetric) Reset()      { *m = JobMetric{} }
 func (*JobMetric) ProtoMessage() {}
 func (*JobMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{21}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{21}
 }
 func (m *JobMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -651,7 +651,7 @@ var xxx_messageInfo_JobMetric proto.InternalMessageInfo
 func (m *KayentaMetric) Reset()      { *m = KayentaMetric{} }
 func (*KayentaMetric) ProtoMessage() {}
 func (*KayentaMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{22}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{22}
 }
 func (m *KayentaMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -679,7 +679,7 @@ var xxx_messageInfo_KayentaMetric proto.InternalMessageInfo
 func (m *KayentaScope) Reset()      { *m = KayentaScope{} }
 func (*KayentaScope) ProtoMessage() {}
 func (*KayentaScope) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{23}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{23}
 }
 func (m *KayentaScope) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -707,7 +707,7 @@ var xxx_messageInfo_KayentaScope proto.InternalMessageInfo
 func (m *KayentaThreshold) Reset()      { *m = KayentaThreshold{} }
 func (*KayentaThreshold) ProtoMessage() {}
 func (*KayentaThreshold) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{24}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{24}
 }
 func (m *KayentaThreshold) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -735,7 +735,7 @@ var xxx_messageInfo_KayentaThreshold proto.InternalMessageInfo
 func (m *Measurement) Reset()      { *m = Measurement{} }
 func (*Measurement) ProtoMessage() {}
 func (*Measurement) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{25}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{25}
 }
 func (m *Measurement) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -763,7 +763,7 @@ var xxx_messageInfo_Measurement proto.InternalMessageInfo
 func (m *MeasurementRetention) Reset()      { *m = MeasurementRetention{} }
 func (*MeasurementRetention) ProtoMessage() {}
 func (*MeasurementRetention) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{26}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{26}
 }
 func (m *MeasurementRetention) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -791,7 +791,7 @@ var xxx_messageInfo_MeasurementRetention proto.InternalMessageInfo
 func (m *Metric) Reset()      { *m = Metric{} }
 func (*Metric) ProtoMessage() {}
 func (*Metric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{27}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{27}
 }
 func (m *Metric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -819,7 +819,7 @@ var xxx_messageInfo_Metric proto.InternalMessageInfo
 func (m *MetricProvider) Reset()      { *m = MetricProvider{} }
 func (*MetricProvider) ProtoMessage() {}
 func (*MetricProvider) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{28}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{28}
 }
 func (m *MetricProvider) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -847,7 +847,7 @@ var xxx_messageInfo_MetricProvider proto.InternalMessageInfo
 func (m *MetricResult) Reset()      { *m = MetricResult{} }
 func (*MetricResult) ProtoMessage() {}
 func (*MetricResult) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{29}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{29}
 }
 func (m *MetricResult) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -875,7 +875,7 @@ var xxx_messageInfo_MetricResult proto.InternalMessageInfo
 func (m *NewRelicMetric) Reset()      { *m = NewRelicMetric{} }
 func (*NewRelicMetric) ProtoMessage() {}
 func (*NewRelicMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{30}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{30}
 }
 func (m *NewRelicMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -903,7 +903,7 @@ var xxx_messageInfo_NewRelicMetric proto.InternalMessageInfo
 func (m *OAuth2Config) Reset()      { *m = OAuth2Config{} }
 func (*OAuth2Config) ProtoMessage() {}
 func (*OAuth2Config) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{31}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{31}
 }
 func (m *OAuth2Config) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -931,7 +931,7 @@ var xxx_messageInfo_OAuth2Config proto.InternalMessageInfo
 func (m *PrometheusMetric) Reset()      { *m = PrometheusMetric{} }
 func (*PrometheusMetric) ProtoMessage() {}
 func (*PrometheusMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{32}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{32}
 }
 func (m *PrometheusMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -959,7 +959,7 @@ var xxx_messageInfo_PrometheusMetric proto.InternalMessageInfo
 func (m *RunSummary) Reset()      { *m = RunSummary{} }
 func (*RunSummary) ProtoMessage() {}
 func (*RunSummary) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{33}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{33}
 }
 func (m *RunSummary) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -987,7 +987,7 @@ var xxx_messageInfo_RunSummary proto.InternalMessageInfo
 func (m *ScopeDetail) Reset()      { *m = ScopeDetail{} }
 func (*ScopeDetail) ProtoMessage() {}
 func (*ScopeDetail) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{34}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{34}
 }
 func (m *ScopeDetail) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1015,7 +1015,7 @@ var xxx_messageInfo_ScopeDetail proto.InternalMessageInfo
 func (m *SecretKeyRef) Reset()      { *m = SecretKeyRef{} }
 func (*SecretKeyRef) ProtoMessage() {}
 func (*SecretKeyRef) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{35}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{35}
 }
 func (m *SecretKeyRef) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1043,7 +1043,7 @@ var xxx_messageInfo_SecretKeyRef proto.InternalMessageInfo
 func (m *Sigv4Config) Reset()      { *m = Sigv4Config{} }
 func (*Sigv4Config) ProtoMessage() {}
 func (*Sigv4Config) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{36}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{36}
 }
 func (m *Sigv4Config) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1071,7 +1071,7 @@ var xxx_messageInfo_Sigv4Config proto.InternalMessageInfo
 func (m *SkyWalkingMetric) Reset()      { *m = SkyWalkingMetric{} }
 func (*SkyWalkingMetric) ProtoMessage() {}
 func (*SkyWalkingMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{37}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{37}
 }
 func (m *SkyWalkingMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1099,7 +1099,7 @@ var xxx_messageInfo_SkyWalkingMetric proto.InternalMessageInfo
 func (m *ValueFrom) Reset()      { *m = ValueFrom{} }
 func (*ValueFrom) ProtoMessage() {}
 func (*ValueFrom) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{38}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{38}
 }
 func (m *ValueFrom) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1127,7 +1127,7 @@ var xxx_messageInfo_ValueFrom proto.InternalMessageInfo
 func (m *WavefrontMetric) Reset()      { *m = WavefrontMetric{} }
 func (*WavefrontMetric) ProtoMessage() {}
 func (*WavefrontMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{39}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{39}
 }
 func (m *WavefrontMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1155,7 +1155,7 @@ var xxx_messageInfo_WavefrontMetric proto.InternalMessageInfo
 func (m *WebMetric) Reset()      { *m = WebMetric{} }
 func (*WebMetric) ProtoMessage() {}
 func (*WebMetric) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{40}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{40}
 }
 func (m *WebMetric) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1183,7 +1183,7 @@ var xxx_messageInfo_WebMetric proto.InternalMessageInfo
 func (m *WebMetricHeader) Reset()      { *m = WebMetricHeader{} }
 func (*WebMetricHeader) ProtoMessage() {}
 func (*WebMetricHeader) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c5bdcafc2831c0b4, []int{41}
+	return fileDescriptor_3c0ab62a0c0c79d5, []int{41}
 }
 func (m *WebMetricHeader) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1209,268 +1209,266 @@ func (m *WebMetricHeader) XXX_DiscardUnknown() {
 var xxx_messageInfo_WebMetricHeader proto.InternalMessageInfo
 
 func init() {
-	proto.RegisterType((*AnalysisRun)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun")
-	proto.RegisterType((*AnalysisRunList)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunList")
-	proto.RegisterType((*AnalysisRunSpec)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunSpec")
-	proto.RegisterType((*AnalysisRunStatus)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunStatus")
-	proto.RegisterType((*AnalysisTemplate)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate")
-	proto.RegisterType((*AnalysisTemplateList)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateList")
-	proto.RegisterType((*AnalysisTemplateSpec)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateSpec")
-	proto.RegisterType((*Argument)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Argument")
-	proto.RegisterType((*Authentication)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Authentication")
-	proto.RegisterType((*CloudWatchMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetric")
-	proto.RegisterType((*CloudWatchMetricDataQuery)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricDataQuery")
-	proto.RegisterType((*CloudWatchMetricStat)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStat")
-	proto.RegisterType((*CloudWatchMetricStatMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetric")
-	proto.RegisterType((*CloudWatchMetricStatMetricDimension)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetricDimension")
-	proto.RegisterType((*ClusterAnalysisTemplate)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate")
-	proto.RegisterType((*ClusterAnalysisTemplateList)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplateList")
-	proto.RegisterType((*DatadogMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DatadogMetric")
-	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DatadogMetric.QueriesEntry")
-	proto.RegisterType((*DryRun)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DryRun")
-	proto.RegisterType((*FieldRef)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.FieldRef")
-	proto.RegisterType((*GraphiteMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.GraphiteMetric")
-	proto.RegisterType((*InfluxdbMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.InfluxdbMetric")
-	proto.RegisterType((*JobMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.JobMetric")
-	proto.RegisterType((*KayentaMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaMetric")
-	proto.RegisterType((*KayentaScope)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaScope")
-	proto.RegisterType((*KayentaThreshold)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaThreshold")
-	proto.RegisterType((*Measurement)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Measurement")
-	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Measurement.MetadataEntry")
-	proto.RegisterType((*MeasurementRetention)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MeasurementRetention")
-	proto.RegisterType((*Metric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Metric")
-	proto.RegisterType((*MetricProvider)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricProvider")
-	proto.RegisterMapType((map[string]encoding_json.RawMessage)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricProvider.PluginEntry")
-	proto.RegisterType((*MetricResult)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricResult")
-	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricResult.MetadataEntry")
-	proto.RegisterType((*NewRelicMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.NewRelicMetric")
-	proto.RegisterType((*OAuth2Config)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.OAuth2Config")
-	proto.RegisterType((*PrometheusMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.PrometheusMetric")
-	proto.RegisterType((*RunSummary)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.RunSummary")
-	proto.RegisterType((*ScopeDetail)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ScopeDetail")
-	proto.RegisterType((*SecretKeyRef)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SecretKeyRef")
-	proto.RegisterType((*Sigv4Config)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Sigv4Config")
-	proto.RegisterType((*SkyWalkingMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SkyWalkingMetric")
-	proto.RegisterType((*ValueFrom)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ValueFrom")
-	proto.RegisterType((*WavefrontMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WavefrontMetric")
-	proto.RegisterType((*WebMetric)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetric")
-	proto.RegisterType((*WebMetricHeader)(nil), "github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetricHeader")
+	proto.RegisterType((*AnalysisRun)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun")
+	proto.RegisterType((*AnalysisRunList)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunList")
+	proto.RegisterType((*AnalysisRunSpec)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunSpec")
+	proto.RegisterType((*AnalysisRunStatus)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunStatus")
+	proto.RegisterType((*AnalysisTemplate)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate")
+	proto.RegisterType((*AnalysisTemplateList)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateList")
+	proto.RegisterType((*AnalysisTemplateSpec)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateSpec")
+	proto.RegisterType((*Argument)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Argument")
+	proto.RegisterType((*Authentication)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Authentication")
+	proto.RegisterType((*CloudWatchMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetric")
+	proto.RegisterType((*CloudWatchMetricDataQuery)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricDataQuery")
+	proto.RegisterType((*CloudWatchMetricStat)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStat")
+	proto.RegisterType((*CloudWatchMetricStatMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetric")
+	proto.RegisterType((*CloudWatchMetricStatMetricDimension)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetricDimension")
+	proto.RegisterType((*ClusterAnalysisTemplate)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate")
+	proto.RegisterType((*ClusterAnalysisTemplateList)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplateList")
+	proto.RegisterType((*DatadogMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DatadogMetric")
+	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DatadogMetric.QueriesEntry")
+	proto.RegisterType((*DryRun)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DryRun")
+	proto.RegisterType((*FieldRef)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.FieldRef")
+	proto.RegisterType((*GraphiteMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.GraphiteMetric")
+	proto.RegisterType((*InfluxdbMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.InfluxdbMetric")
+	proto.RegisterType((*JobMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.JobMetric")
+	proto.RegisterType((*KayentaMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaMetric")
+	proto.RegisterType((*KayentaScope)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaScope")
+	proto.RegisterType((*KayentaThreshold)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaThreshold")
+	proto.RegisterType((*Measurement)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Measurement")
+	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Measurement.MetadataEntry")
+	proto.RegisterType((*MeasurementRetention)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MeasurementRetention")
+	proto.RegisterType((*Metric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Metric")
+	proto.RegisterType((*MetricProvider)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricProvider")
+	proto.RegisterMapType((map[string]encoding_json.RawMessage)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricProvider.PluginEntry")
+	proto.RegisterType((*MetricResult)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricResult")
+	proto.RegisterMapType((map[string]string)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricResult.MetadataEntry")
+	proto.RegisterType((*NewRelicMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.NewRelicMetric")
+	proto.RegisterType((*OAuth2Config)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.OAuth2Config")
+	proto.RegisterType((*PrometheusMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.PrometheusMetric")
+	proto.RegisterType((*RunSummary)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.RunSummary")
+	proto.RegisterType((*ScopeDetail)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ScopeDetail")
+	proto.RegisterType((*SecretKeyRef)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SecretKeyRef")
+	proto.RegisterType((*Sigv4Config)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Sigv4Config")
+	proto.RegisterType((*SkyWalkingMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SkyWalkingMetric")
+	proto.RegisterType((*ValueFrom)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ValueFrom")
+	proto.RegisterType((*WavefrontMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WavefrontMetric")
+	proto.RegisterType((*WebMetric)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetric")
+	proto.RegisterType((*WebMetricHeader)(nil), "github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetricHeader")
 }
 
 func init() {
-	proto.RegisterFile("github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1/generated.proto", fileDescriptor_c5bdcafc2831c0b4)
-}
-
-var fileDescriptor_c5bdcafc2831c0b4 = []byte{
-	// 3322 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5b, 0x4d, 0x6c, 0x24, 0x47,
-	0xf5, 0xdf, 0x9e, 0x0f, 0x7b, 0xe6, 0x79, 0xec, 0xf5, 0xd6, 0x7f, 0xf7, 0x9f, 0x89, 0xff, 0x89,
-	0xbd, 0xff, 0x5e, 0x11, 0xed, 0x86, 0x30, 0x43, 0x96, 0x80, 0xf2, 0x81, 0x22, 0x79, 0xec, 0x35,
-	0x78, 0xb3, 0x1f, 0xde, 0x1a, 0x27, 0x46, 0x51, 0x40, 0x29, 0xcf, 0xd4, 0xcc, 0x74, 0xdc, 0xd3,
-	0x3d, 0xe9, 0xae, 0xf6, 0xee, 0x08, 0x50, 0x88, 0x20, 0x10, 0x25, 0x1c, 0xc8, 0x0d, 0xe5, 0x06,
-	0x12, 0x07, 0x84, 0x38, 0x72, 0x03, 0x89, 0x13, 0x5a, 0x71, 0x21, 0xc7, 0x9c, 0x0c, 0x71, 0x38,
-	0x80, 0x84, 0xe0, 0x86, 0xc4, 0x2a, 0x42, 0xa8, 0xbe, 0xba, 0xab, 0x67, 0x3c, 0x59, 0x7b, 0xd3,
-	0x4e, 0x90, 0x72, 0xf2, 0xf4, 0xab, 0x57, 0xef, 0xf7, 0xea, 0x55, 0xd5, 0x7b, 0xaf, 0x5e, 0x95,
-	0xe1, 0x46, 0xd7, 0x61, 0xbd, 0x68, 0xbb, 0xd6, 0xf2, 0xfb, 0x75, 0xb2, 0x13, 0x39, 0x6c, 0x58,
-	0xdf, 0x21, 0x41, 0xd7, 0xaf, 0x3b, 0x1e, 0xa3, 0x81, 0x47, 0xdc, 0x7a, 0xcb, 0xf7, 0x58, 0xe0,
-	0xbb, 0x2e, 0x0d, 0xea, 0xfc, 0x8f, 0x1f, 0xb1, 0xb0, 0x4e, 0x06, 0x4e, 0x7d, 0xf7, 0x51, 0xe2,
-	0x0e, 0x7a, 0xe4, 0xd1, 0x7a, 0x97, 0x7a, 0x34, 0x20, 0x8c, 0xb6, 0x6b, 0x83, 0xc0, 0x67, 0x3e,
-	0x5a, 0x4e, 0x44, 0xd6, 0xa4, 0xc8, 0x9a, 0x10, 0x59, 0xd3, 0x22, 0x6b, 0x89, 0xc8, 0x9a, 0x16,
-	0x59, 0x23, 0x03, 0xa7, 0xa6, 0x45, 0x2e, 0x7c, 0xce, 0xd0, 0xaa, 0xeb, 0x77, 0xfd, 0xba, 0x90,
-	0xbc, 0x1d, 0x75, 0xc4, 0x97, 0xf8, 0x10, 0xbf, 0x24, 0xe2, 0xc2, 0xb9, 0x9d, 0xc7, 0xc3, 0x9a,
-	0xe3, 0x0b, 0xb5, 0xb6, 0x09, 0x6b, 0xf5, 0xea, 0xbb, 0x63, 0x6a, 0x2d, 0x3c, 0x96, 0x30, 0xf5,
-	0x49, 0xab, 0xe7, 0x78, 0x34, 0x18, 0xd6, 0x07, 0x3b, 0x5d, 0x4e, 0x08, 0xeb, 0x7d, 0xca, 0xc8,
-	0x41, 0xbd, 0xea, 0x93, 0x7a, 0x05, 0x91, 0xc7, 0x9c, 0x3e, 0x1d, 0xeb, 0xf0, 0xa5, 0xbb, 0x75,
-	0x08, 0x5b, 0x3d, 0xda, 0x27, 0x63, 0xfd, 0xbe, 0x30, 0xa9, 0x5f, 0xc4, 0x1c, 0x97, 0xcf, 0x46,
-	0xc8, 0x82, 0xd1, 0x4e, 0xf6, 0xfb, 0x39, 0x98, 0x59, 0xf6, 0x88, 0x3b, 0x0c, 0x9d, 0x10, 0x47,
-	0x1e, 0x7a, 0x11, 0x4a, 0x7c, 0x20, 0x6d, 0xc2, 0x48, 0xd5, 0x3a, 0x6b, 0x9d, 0x9f, 0xb9, 0xf8,
-	0xf9, 0x9a, 0x94, 0x5b, 0x33, 0xe5, 0xd6, 0x06, 0x3b, 0x5d, 0x4e, 0x08, 0x6b, 0x9c, 0xbb, 0xb6,
-	0xfb, 0x68, 0xed, 0xfa, 0xf6, 0x4b, 0xb4, 0xc5, 0xae, 0x52, 0x46, 0x1a, 0xe8, 0xf6, 0xde, 0xd2,
-	0x89, 0xfd, 0xbd, 0x25, 0x48, 0x68, 0x38, 0x96, 0x8a, 0x18, 0x14, 0xc2, 0x01, 0x6d, 0x55, 0x73,
-	0x42, 0x3a, 0xae, 0x7d, 0xe4, 0xb9, 0xae, 0x19, 0xfa, 0x37, 0x07, 0xb4, 0xd5, 0xa8, 0x28, 0xfc,
-	0x02, 0xff, 0xc2, 0x02, 0x0d, 0x7d, 0x0b, 0xa6, 0x42, 0x46, 0x58, 0x14, 0x56, 0xf3, 0x02, 0x77,
-	0x33, 0x63, 0x5c, 0x21, 0xbb, 0x31, 0xa7, 0x90, 0xa7, 0xe4, 0x37, 0x56, 0x98, 0xf6, 0x9f, 0x2d,
-	0x38, 0x69, 0x70, 0x5f, 0x71, 0x42, 0x86, 0x5e, 0x18, 0xb3, 0x74, 0xed, 0x70, 0x96, 0xe6, 0xbd,
-	0x85, 0x9d, 0xe7, 0x15, 0x5a, 0x49, 0x53, 0x0c, 0x2b, 0x87, 0x50, 0x74, 0x18, 0xed, 0x87, 0xd5,
-	0xdc, 0xd9, 0xfc, 0xf9, 0x99, 0x8b, 0xd7, 0xb2, 0x1d, 0x6e, 0x63, 0x56, 0x41, 0x17, 0xd7, 0x39,
-	0x08, 0x96, 0x58, 0xf6, 0xef, 0x0a, 0xa9, 0x61, 0x72, 0xf3, 0x23, 0x06, 0xd3, 0x7d, 0xca, 0x02,
-	0xa7, 0x15, 0x56, 0x2d, 0xa1, 0xca, 0x7a, 0x06, 0xaa, 0x5c, 0x15, 0x12, 0x1b, 0x27, 0x95, 0x16,
-	0xd3, 0xf2, 0x3b, 0xc4, 0x1a, 0x0a, 0xf5, 0xa1, 0x40, 0x82, 0xae, 0x1e, 0xfd, 0x33, 0x59, 0x8c,
-	0x3e, 0xe8, 0x46, 0x7d, 0xea, 0xb1, 0x64, 0x75, 0x2d, 0x07, 0xdd, 0x10, 0x0b, 0x18, 0x54, 0x87,
-	0x32, 0xa3, 0x41, 0xdf, 0xf1, 0x08, 0xa3, 0x62, 0x81, 0x95, 0x1a, 0xa7, 0x14, 0x5b, 0x79, 0x53,
-	0x37, 0xe0, 0x84, 0x07, 0xbd, 0x0c, 0x53, 0xed, 0x60, 0x88, 0x23, 0xaf, 0x5a, 0xc8, 0xcc, 0x28,
-	0xab, 0x42, 0x60, 0xb2, 0x06, 0xe5, 0x37, 0x56, 0x40, 0xe8, 0xe7, 0x16, 0x9c, 0xee, 0x53, 0x12,
-	0x46, 0x01, 0xe5, 0xe3, 0xc0, 0x94, 0x51, 0x8f, 0x39, 0xbe, 0x57, 0x2d, 0x0a, 0x0d, 0xb6, 0x32,
-	0x99, 0x96, 0x71, 0xf1, 0x8d, 0x07, 0x94, 0x3e, 0xa7, 0x0f, 0x6a, 0xc5, 0x07, 0xaa, 0x64, 0xff,
-	0xb5, 0x00, 0xa7, 0xc6, 0x76, 0x17, 0x7a, 0x0c, 0x8a, 0x83, 0x1e, 0x09, 0xa9, 0xd8, 0x2e, 0xe5,
-	0xc6, 0xa2, 0x5e, 0x83, 0x1b, 0x9c, 0x78, 0x67, 0x6f, 0x69, 0x56, 0x77, 0x11, 0x04, 0x2c, 0x99,
-	0xd1, 0x05, 0xbe, 0x00, 0xc3, 0x90, 0x74, 0xa9, 0x70, 0x39, 0x65, 0x73, 0xd5, 0x08, 0x32, 0xd6,
-	0xed, 0xe8, 0x87, 0x16, 0xcc, 0xca, 0x15, 0x84, 0x69, 0x18, 0xb9, 0x8c, 0x3b, 0x0b, 0x6e, 0x9b,
-	0xeb, 0x99, 0x2d, 0x59, 0x29, 0xb7, 0x71, 0x46, 0xa9, 0x30, 0x6b, 0x52, 0x43, 0x9c, 0x06, 0x47,
-	0x5b, 0x50, 0x0e, 0x19, 0x09, 0x18, 0x6d, 0x2f, 0xb3, 0x6a, 0x41, 0xb8, 0x88, 0x87, 0x0f, 0xe7,
-	0x22, 0x36, 0x9d, 0x3e, 0x6d, 0xcc, 0xf2, 0xd5, 0xd7, 0xd4, 0x02, 0x70, 0x22, 0x0b, 0xbd, 0x6a,
-	0x01, 0x04, 0x91, 0xd7, 0x8c, 0xfa, 0x7d, 0x12, 0x0c, 0xab, 0x45, 0x21, 0xfa, 0x6a, 0x06, 0x83,
-	0xc4, 0xb1, 0xd0, 0x24, 0x08, 0x24, 0x34, 0x6c, 0x80, 0xa2, 0xef, 0x5b, 0x30, 0x2b, 0x57, 0xa6,
-	0x56, 0x63, 0xea, 0x38, 0xd4, 0x38, 0xc5, 0xad, 0xbc, 0x6a, 0xe2, 0xe0, 0x34, 0xac, 0xfd, 0x0f,
-	0x0b, 0xe6, 0xf5, 0xc2, 0xd9, 0xa4, 0xfd, 0x81, 0xcb, 0xf7, 0xe7, 0xf1, 0x87, 0xc1, 0x61, 0x2a,
-	0x0c, 0x6e, 0x65, 0xe8, 0x9f, 0xf5, 0x20, 0x26, 0xc5, 0x42, 0xfb, 0xef, 0x16, 0x9c, 0x1e, 0x65,
-	0xfe, 0x18, 0x42, 0xd2, 0xad, 0x74, 0x48, 0x6a, 0x1e, 0xc3, 0x90, 0x27, 0xc4, 0xa5, 0xb7, 0x0b,
-	0xe3, 0x03, 0xfe, 0xf4, 0x04, 0xa7, 0x24, 0xd6, 0xe4, 0x3f, 0xf1, 0x58, 0x53, 0xf8, 0xef, 0x8b,
-	0x35, 0xb7, 0x2d, 0x28, 0x69, 0xfb, 0xa1, 0xb3, 0x50, 0xf0, 0x48, 0x5f, 0x47, 0x98, 0xd8, 0x9a,
-	0xd7, 0x48, 0x9f, 0x62, 0xd1, 0x82, 0x96, 0xa0, 0xb8, 0x4b, 0xdc, 0x48, 0x07, 0x93, 0x32, 0x5f,
-	0x6c, 0xcf, 0x71, 0x02, 0x96, 0x74, 0x34, 0x84, 0xb2, 0xf8, 0xb1, 0x16, 0xf8, 0x7d, 0x95, 0x6c,
-	0x5e, 0xc9, 0x60, 0xbc, 0xcf, 0x69, 0x99, 0xd2, 0xaf, 0xc7, 0x9f, 0x38, 0x41, 0xb3, 0xff, 0x6d,
-	0xc1, 0xdc, 0x72, 0xc4, 0x7a, 0x7c, 0x64, 0x2d, 0xc2, 0x47, 0xc7, 0xf3, 0xc0, 0xd0, 0xe9, 0xee,
-	0x3e, 0xa6, 0xf6, 0x73, 0x16, 0x79, 0x60, 0x93, 0xcb, 0x5b, 0xf1, 0xbd, 0x8e, 0xd3, 0x4d, 0xf6,
-	0x9b, 0x20, 0x62, 0x89, 0x85, 0x6e, 0xc2, 0x94, 0x4f, 0x22, 0xd6, 0xbb, 0xa8, 0xbc, 0x5b, 0x16,
-	0xf1, 0xf3, 0x3a, 0x1f, 0xd8, 0x45, 0x05, 0x1b, 0xaf, 0x3b, 0x49, 0xc5, 0x0a, 0xce, 0xbe, 0x63,
-	0xc1, 0xfc, 0x8a, 0xeb, 0x47, 0xed, 0x2d, 0x7e, 0x86, 0x93, 0x1b, 0x0f, 0x3d, 0x0d, 0x25, 0x01,
-	0xb3, 0x4b, 0x5c, 0x35, 0xaf, 0xb6, 0xf6, 0x52, 0xeb, 0x8a, 0x7e, 0x67, 0x6f, 0x69, 0x6e, 0x35,
-	0x0a, 0x84, 0xc9, 0x9a, 0x2c, 0x70, 0xbc, 0x2e, 0x8e, 0xfb, 0xa0, 0x9f, 0x59, 0x70, 0x4a, 0x6e,
-	0xdd, 0x55, 0xc2, 0xc8, 0x8d, 0x88, 0x06, 0x0e, 0xd5, 0x9b, 0xf7, 0x85, 0x0c, 0x46, 0x36, 0xaa,
-	0xb0, 0x46, 0x19, 0x36, 0xee, 0x57, 0x7a, 0x9e, 0xba, 0x3a, 0x0a, 0x8f, 0xc7, 0x35, 0xb2, 0x7f,
-	0x9c, 0x87, 0xfb, 0x27, 0xca, 0x42, 0x0b, 0x90, 0x73, 0xda, 0x6a, 0xfc, 0xa0, 0xe4, 0xe6, 0xd6,
-	0xdb, 0x38, 0xe7, 0xb4, 0x51, 0x0d, 0x80, 0xde, 0x1a, 0x04, 0x34, 0x0c, 0xf9, 0x1e, 0x95, 0x0b,
-	0x7b, 0x8e, 0x47, 0xae, 0x4b, 0x31, 0x15, 0x1b, 0x1c, 0x7c, 0x0f, 0xb8, 0x64, 0x9b, 0xba, 0x62,
-	0x79, 0xab, 0x3d, 0x70, 0x85, 0x13, 0xb0, 0xa4, 0xa3, 0x1f, 0x58, 0x00, 0x52, 0x41, 0x9e, 0xba,
-	0xa9, 0xdc, 0x65, 0xeb, 0x18, 0x6c, 0xc5, 0xc5, 0x4b, 0x55, 0x93, 0x6f, 0x6c, 0x40, 0xa3, 0x4d,
-	0x98, 0x1a, 0xd0, 0xc0, 0xf1, 0xdb, 0x2a, 0xcb, 0x99, 0x1c, 0xc6, 0xf9, 0x29, 0xb9, 0x26, 0x4f,
-	0xc9, 0xb5, 0x75, 0x8f, 0x5d, 0x0f, 0xe4, 0x42, 0x68, 0x00, 0x5f, 0x67, 0x1b, 0x42, 0x06, 0x56,
-	0xb2, 0xb8, 0xc1, 0x02, 0xca, 0xa2, 0xc0, 0xe3, 0xf6, 0x15, 0x89, 0x4b, 0x49, 0x6a, 0x81, 0x63,
-	0x2a, 0x36, 0x38, 0xec, 0x5f, 0xe7, 0xe0, 0xf4, 0x41, 0xaa, 0xa3, 0xd7, 0x2c, 0x98, 0x92, 0xda,
-	0xaa, 0x0d, 0xfa, 0xf5, 0x63, 0x32, 0x92, 0x0a, 0x4a, 0xf1, 0xc6, 0x51, 0x89, 0xa7, 0x02, 0x47,
-	0x5f, 0x8b, 0xcd, 0x94, 0xbb, 0x47, 0x33, 0xc5, 0x92, 0x47, 0x4c, 0x75, 0x16, 0x0a, 0xfc, 0x10,
-	0xac, 0x96, 0x4a, 0x92, 0x8e, 0xf0, 0x89, 0x12, 0x2d, 0x9c, 0x23, 0xf2, 0x1c, 0xb9, 0x4a, 0x0c,
-	0x8e, 0x67, 0x3d, 0x87, 0x61, 0xd1, 0x62, 0xbf, 0x9d, 0x83, 0x85, 0xc9, 0x83, 0x42, 0x6f, 0x5b,
-	0x00, 0x6d, 0xa7, 0x4f, 0x3d, 0xbe, 0x38, 0x75, 0x24, 0xef, 0x1c, 0xab, 0x21, 0x57, 0x35, 0x5c,
-	0x92, 0xe5, 0xc5, 0xa4, 0x10, 0x1b, 0xda, 0xa0, 0x8b, 0x7a, 0x27, 0xf0, 0x18, 0xa2, 0xf6, 0x56,
-	0xdc, 0xe7, 0x6a, 0xdc, 0x82, 0x0d, 0x2e, 0xf4, 0x59, 0x28, 0xf3, 0x58, 0x13, 0x0e, 0x48, 0x8b,
-	0x2a, 0xc3, 0x09, 0xa7, 0x7f, 0x4d, 0x13, 0x71, 0xd2, 0x6e, 0xbb, 0x70, 0xee, 0x10, 0x7a, 0x1e,
-	0x22, 0xb2, 0x9d, 0x4b, 0x47, 0xb6, 0xd8, 0xb5, 0x9b, 0xd1, 0xcd, 0xfe, 0xa7, 0x05, 0xf7, 0xad,
-	0xb8, 0x51, 0xc8, 0x68, 0xf0, 0xe9, 0x4a, 0x9a, 0x3f, 0xb0, 0xe0, 0xff, 0x26, 0x0c, 0xfc, 0x63,
-	0xc8, 0x9d, 0x5f, 0x49, 0xe7, 0xce, 0xcf, 0x67, 0xb2, 0xb8, 0x0f, 0x1c, 0xcc, 0xa4, 0x14, 0x3a,
-	0x0f, 0xb3, 0xdc, 0x95, 0xb5, 0xfd, 0x6e, 0x46, 0x61, 0xf5, 0x1c, 0x14, 0x5f, 0xe6, 0x91, 0x69,
-	0x74, 0xb9, 0x89, 0x70, 0x85, 0x65, 0x1b, 0x7a, 0xdd, 0x82, 0xe9, 0x97, 0x55, 0xc4, 0x95, 0xd9,
-	0x6b, 0x16, 0x0e, 0x32, 0x35, 0x90, 0x9a, 0x8a, 0x9f, 0x97, 0x3c, 0x16, 0x0c, 0x93, 0xac, 0x5d,
-	0x07, 0x5a, 0x0d, 0x8f, 0x2e, 0xc0, 0x74, 0xc7, 0x0f, 0xfa, 0x91, 0x4b, 0x94, 0xa7, 0x8a, 0x59,
-	0xd7, 0x24, 0x19, 0xeb, 0x76, 0xbe, 0xe7, 0xc9, 0xc0, 0x79, 0x8e, 0x06, 0xa1, 0xac, 0xaf, 0xa4,
-	0xf6, 0xfc, 0x72, 0xdc, 0x82, 0x0d, 0xae, 0x85, 0x27, 0xa1, 0x62, 0x2a, 0x82, 0xe6, 0x21, 0xbf,
-	0x43, 0x87, 0xd2, 0xb2, 0x98, 0xff, 0x44, 0xa7, 0x53, 0xfb, 0x53, 0x6d, 0xc8, 0x27, 0x73, 0x8f,
-	0x5b, 0xf6, 0x97, 0x41, 0x25, 0xe0, 0x23, 0xde, 0xc6, 0x3a, 0x8c, 0xb7, 0xb1, 0x9f, 0x82, 0xd2,
-	0x9a, 0x43, 0xdd, 0x36, 0xa6, 0x1d, 0x54, 0x87, 0x72, 0x87, 0xff, 0xde, 0x20, 0xac, 0xa7, 0xba,
-	0xc7, 0x85, 0xac, 0x35, 0xdd, 0x80, 0x13, 0x1e, 0xfb, 0x45, 0x98, 0xfb, 0x4a, 0x40, 0x06, 0x3d,
-	0x87, 0x51, 0xb5, 0x2e, 0x2e, 0xc0, 0x34, 0x69, 0xb7, 0x79, 0xaa, 0xa0, 0x04, 0xc4, 0x76, 0x5a,
-	0x96, 0x64, 0xac, 0xdb, 0x0f, 0xb5, 0x04, 0x38, 0xc2, 0xba, 0xd7, 0x71, 0xa3, 0x5b, 0xed, 0xed,
-	0x04, 0x61, 0x10, 0xf8, 0x1d, 0xc7, 0xa5, 0xa3, 0x08, 0x1b, 0x92, 0x8c, 0x75, 0xfb, 0xe1, 0x10,
-	0x7e, 0x61, 0x41, 0xf9, 0xb2, 0xaf, 0xa5, 0x7f, 0x23, 0x03, 0x2f, 0x16, 0x6f, 0xe5, 0xab, 0x4a,
-	0x92, 0xb1, 0x95, 0x9f, 0x4e, 0xf9, 0xb0, 0x07, 0x0c, 0xd9, 0x35, 0x71, 0xf3, 0xc0, 0x45, 0x5d,
-	0xf6, 0xb7, 0x27, 0x3a, 0xa2, 0x5f, 0x16, 0x61, 0xf6, 0x19, 0x32, 0xa4, 0x1e, 0x23, 0x47, 0xb7,
-	0xf8, 0x17, 0x61, 0x86, 0x0c, 0x06, 0xae, 0x3a, 0x1d, 0x28, 0xab, 0xfc, 0x8f, 0x62, 0x9f, 0x59,
-	0x4e, 0x9a, 0xb0, 0xc9, 0x87, 0x56, 0x61, 0xbe, 0x45, 0x3c, 0x12, 0x0c, 0x65, 0xfe, 0x2d, 0x16,
-	0x97, 0x8c, 0x4b, 0x55, 0xd5, 0x77, 0x7e, 0x65, 0xa4, 0x1d, 0x8f, 0xf5, 0x40, 0x97, 0x01, 0xa9,
-	0x23, 0xf0, 0x72, 0xab, 0xe5, 0x47, 0x1e, 0x13, 0x72, 0xe4, 0x66, 0x5a, 0x50, 0x72, 0xd0, 0xd5,
-	0x31, 0x0e, 0x7c, 0x40, 0x2f, 0xf4, 0x02, 0x54, 0x5b, 0x42, 0xb2, 0x72, 0x2f, 0xa6, 0x44, 0xb9,
-	0xe1, 0xce, 0x2a, 0x89, 0xd5, 0x95, 0x09, 0x7c, 0x78, 0xa2, 0x04, 0xae, 0x69, 0xc8, 0xfc, 0x80,
-	0x74, 0xa9, 0x29, 0x77, 0x2a, 0xad, 0x69, 0x73, 0x8c, 0x03, 0x1f, 0xd0, 0x0b, 0x7d, 0xcf, 0x82,
-	0x32, 0xeb, 0x05, 0x34, 0xec, 0xf9, 0x6e, 0xbb, 0x3a, 0x2d, 0x66, 0x3d, 0x8b, 0xda, 0x87, 0x5a,
-	0x03, 0x9b, 0x5a, 0xb4, 0x51, 0x71, 0xd6, 0x24, 0x9c, 0x00, 0xf3, 0x33, 0x59, 0xd8, 0xf2, 0x07,
-	0x34, 0xac, 0x96, 0x32, 0xab, 0x69, 0x2a, 0x15, 0x9a, 0x5c, 0xae, 0x71, 0xf7, 0x21, 0x60, 0xb0,
-	0x82, 0xb3, 0xff, 0x90, 0x83, 0x8a, 0xc9, 0x78, 0x88, 0x4c, 0xe4, 0x75, 0x0b, 0x2a, 0x0a, 0x5c,
-	0x74, 0x51, 0x7b, 0x25, 0x93, 0xc3, 0x2b, 0x97, 0xb7, 0x4a, 0x19, 0x71, 0xdc, 0xc6, 0x69, 0x05,
-	0x5d, 0x59, 0x31, 0xb0, 0x70, 0x0a, 0x19, 0xbd, 0x65, 0xc1, 0x49, 0x7a, 0x8b, 0xe7, 0xb2, 0x7d,
-	0xea, 0x31, 0xa9, 0x4d, 0xfe, 0x58, 0xb4, 0xb9, 0x4f, 0x69, 0x73, 0xf2, 0x52, 0x1a, 0x0e, 0x8f,
-	0xe2, 0xdb, 0xdb, 0x30, 0x3f, 0x3a, 0xf9, 0xdc, 0xa8, 0x03, 0xa2, 0x1c, 0x40, 0x3e, 0x31, 0xea,
-	0x06, 0x09, 0x43, 0x2c, 0x5a, 0xd0, 0x23, 0x50, 0xea, 0x93, 0xa0, 0xeb, 0x78, 0xc4, 0x15, 0xf6,
-	0xcc, 0x1b, 0x5e, 0x4a, 0xd1, 0x71, 0xcc, 0x61, 0xff, 0xa5, 0x00, 0x33, 0x46, 0x11, 0xe5, 0xf8,
-	0x6b, 0xef, 0xa9, 0x62, 0x77, 0x3e, 0xc3, 0x62, 0xf7, 0xf3, 0x00, 0x1d, 0xc7, 0x73, 0xc2, 0xde,
-	0x3d, 0x96, 0xd1, 0xc5, 0xb9, 0x6e, 0x2d, 0x96, 0x80, 0x0d, 0x69, 0x49, 0xca, 0x5c, 0x9c, 0x9c,
-	0x32, 0xa3, 0x37, 0x2c, 0x23, 0xa2, 0x4c, 0x65, 0x56, 0x36, 0x30, 0x66, 0xa7, 0xa6, 0xc3, 0x8c,
-	0xcc, 0x61, 0x3e, 0x2c, 0xfa, 0x6c, 0x42, 0x29, 0xa0, 0x61, 0xd4, 0xa7, 0xcb, 0x4c, 0xf9, 0xa2,
-	0xa3, 0xd8, 0xa2, 0xc2, 0xa5, 0x62, 0xd5, 0x1f, 0xc7, 0x92, 0x16, 0x9e, 0x82, 0xd9, 0x94, 0x0a,
-	0x47, 0xca, 0x5e, 0x7c, 0x38, 0xb0, 0x5c, 0x77, 0x2f, 0xb9, 0x0c, 0x9f, 0x10, 0xd7, 0xe9, 0x3b,
-	0x4c, 0xa0, 0x14, 0x93, 0x09, 0xb9, 0xc2, 0x89, 0x58, 0xb6, 0xd9, 0xff, 0x9a, 0x02, 0x75, 0xfe,
-	0x3d, 0x84, 0x2f, 0x32, 0xd3, 0xdc, 0xdc, 0x3d, 0xa4, 0xb9, 0x97, 0xa1, 0xe2, 0x78, 0x0e, 0x73,
-	0x88, 0xbb, 0x4a, 0x5d, 0x32, 0x54, 0x61, 0xf3, 0x21, 0xed, 0x7a, 0xd6, 0x8d, 0xb6, 0x03, 0xe4,
-	0xa4, 0xfa, 0xa2, 0x1b, 0x50, 0x14, 0x71, 0x45, 0xad, 0xe2, 0xa3, 0x1f, 0xd2, 0x45, 0xa5, 0x66,
-	0x85, 0x8b, 0xc0, 0x52, 0x12, 0x8f, 0xec, 0x61, 0xd4, 0x6a, 0xd1, 0x30, 0x5c, 0xf1, 0xbd, 0xb6,
-	0xc3, 0x92, 0x84, 0x35, 0x8e, 0xec, 0xcd, 0x91, 0x76, 0x3c, 0xd6, 0x83, 0x4b, 0xe9, 0x10, 0xc7,
-	0x8d, 0x02, 0x9a, 0x48, 0x99, 0x4a, 0x4b, 0x59, 0x1b, 0x69, 0xc7, 0x63, 0x3d, 0x50, 0x07, 0x2a,
-	0x8a, 0x26, 0xa6, 0x4b, 0xad, 0xcf, 0xa3, 0x8f, 0x72, 0x9e, 0x1b, 0x76, 0xcd, 0x90, 0x84, 0x53,
-	0x72, 0x51, 0x04, 0xa7, 0x1c, 0xaf, 0xe5, 0x7b, 0x2d, 0x37, 0x0a, 0x9d, 0x5d, 0x05, 0x56, 0xba,
-	0x47, 0xb0, 0x33, 0xfb, 0x7b, 0x4b, 0xa7, 0xd6, 0x47, 0xc5, 0xe1, 0x71, 0x04, 0xf4, 0xaa, 0x05,
-	0x67, 0x5a, 0xbe, 0x17, 0xd2, 0x56, 0xc4, 0x9c, 0x5d, 0x7a, 0x29, 0x08, 0xfc, 0x40, 0x62, 0x97,
-	0xef, 0x11, 0xfb, 0xfe, 0xfd, 0xbd, 0xa5, 0x33, 0x2b, 0x07, 0x89, 0xc4, 0x07, 0x23, 0xa1, 0x57,
-	0xa0, 0x34, 0x08, 0xfc, 0x5d, 0xa7, 0x4d, 0x83, 0x2a, 0x08, 0xd4, 0x1b, 0x99, 0xdd, 0x78, 0x6c,
-	0x28, 0xc1, 0x89, 0xff, 0xd1, 0x14, 0x1c, 0x83, 0xda, 0xbf, 0xa9, 0xc0, 0x5c, 0x9a, 0x1d, 0x7d,
-	0xd7, 0x02, 0x18, 0x04, 0x7e, 0x9f, 0xb2, 0x1e, 0x8d, 0x42, 0x95, 0x73, 0x67, 0x91, 0x21, 0x6d,
-	0xc4, 0x42, 0x75, 0xf5, 0x8b, 0x7b, 0x8e, 0x84, 0x8a, 0x0d, 0x58, 0x74, 0x13, 0xa6, 0x77, 0x64,
-	0x50, 0x55, 0xd9, 0xc6, 0x46, 0x76, 0x09, 0x92, 0x82, 0x9f, 0xe1, 0x81, 0x4f, 0x91, 0xb0, 0x46,
-	0x43, 0x5d, 0xc8, 0xdf, 0xa4, 0xdb, 0x19, 0xde, 0x14, 0x6c, 0x51, 0x75, 0x94, 0x69, 0x4c, 0xef,
-	0xef, 0x2d, 0xe5, 0xb7, 0xe8, 0x36, 0xe6, 0x08, 0x7c, 0x84, 0x6d, 0x79, 0xf0, 0x55, 0xfe, 0x63,
-	0x23, 0xeb, 0xa3, 0xb4, 0x1c, 0xa1, 0x22, 0x61, 0x8d, 0x86, 0x5e, 0x81, 0xf2, 0x4d, 0xb2, 0x4b,
-	0x3b, 0x81, 0xef, 0x31, 0x55, 0x86, 0xcd, 0xe2, 0xd9, 0xcf, 0x96, 0x96, 0xa9, 0xc0, 0x45, 0x0a,
-	0x10, 0x13, 0x71, 0x82, 0x89, 0xbe, 0x09, 0x25, 0x8f, 0xde, 0xc4, 0xd4, 0x75, 0x5a, 0xea, 0x96,
-	0x39, 0x8b, 0x55, 0x7f, 0x4d, 0x89, 0x54, 0xf0, 0x22, 0x36, 0x6a, 0x1a, 0x8e, 0x01, 0xf9, 0xfc,
-	0xbe, 0xe4, 0x6f, 0x2b, 0x67, 0x96, 0xc5, 0xfc, 0xc6, 0x47, 0x55, 0x39, 0xbf, 0x97, 0xfd, 0x6d,
-	0xcc, 0x11, 0xc4, 0x3e, 0x6a, 0xc5, 0x95, 0x40, 0xe5, 0xd0, 0x9a, 0xc7, 0x50, 0x06, 0x95, 0xfb,
-	0x28, 0xa1, 0x62, 0x03, 0x96, 0xdb, 0xba, 0xab, 0x0a, 0x02, 0xca, 0xaf, 0x65, 0x61, 0xeb, 0x74,
-	0x8d, 0x41, 0xda, 0x5a, 0xd3, 0x70, 0x0c, 0xc8, 0xc1, 0x1d, 0x55, 0x2b, 0xc8, 0xd0, 0xbd, 0xa5,
-	0xcb, 0x0f, 0x12, 0x5c, 0xd3, 0x70, 0x0c, 0x28, 0xec, 0x1f, 0xee, 0x0c, 0x6f, 0x12, 0x77, 0xc7,
-	0xf1, 0xba, 0xd5, 0x99, 0xcc, 0xec, 0xdf, 0xdc, 0x19, 0x6e, 0x49, 0xa1, 0xa6, 0xfd, 0x13, 0x2a,
-	0x36, 0x60, 0xd1, 0x4f, 0x2c, 0x98, 0x1a, 0xb8, 0x51, 0xd7, 0xf1, 0xaa, 0x95, 0xcc, 0x0a, 0x66,
-	0x69, 0x8f, 0x5d, 0xdb, 0x10, 0xf2, 0x65, 0xb2, 0xf9, 0x70, 0x5c, 0xf7, 0x17, 0xc4, 0x37, 0xfe,
-	0xb8, 0x54, 0xa5, 0x5e, 0xcb, 0x6f, 0x3b, 0x5e, 0xb7, 0xfe, 0x52, 0xe8, 0x7b, 0x35, 0x4c, 0x6e,
-	0xea, 0x64, 0x5f, 0x29, 0xb6, 0xf0, 0x04, 0xcc, 0x18, 0x22, 0xee, 0x96, 0x2c, 0x56, 0xcc, 0x64,
-	0xf1, 0x57, 0x53, 0x50, 0x31, 0x1f, 0xcd, 0x1c, 0x22, 0x83, 0x8b, 0x8f, 0x2e, 0xb9, 0xa3, 0x1c,
-	0x5d, 0xf8, 0x19, 0xd4, 0xb8, 0x2f, 0xd6, 0xe5, 0xc7, 0x6b, 0xd9, 0x66, 0xee, 0xc9, 0x19, 0xd4,
-	0x20, 0x86, 0x38, 0x85, 0x6c, 0x9e, 0xa2, 0x0a, 0x77, 0x39, 0x45, 0x9d, 0xd3, 0x19, 0x62, 0x31,
-	0x9d, 0xff, 0xa6, 0x72, 0xbe, 0x8b, 0x00, 0x2a, 0x83, 0xeb, 0x44, 0xae, 0x70, 0x88, 0xc5, 0x24,
-	0xb1, 0x6e, 0xc6, 0x2d, 0xd8, 0xe0, 0x42, 0x0f, 0xc1, 0x14, 0xcf, 0xa1, 0xa8, 0xac, 0x60, 0x14,
-	0x93, 0xd3, 0xfe, 0x9a, 0xa0, 0x62, 0xd5, 0x8a, 0x1e, 0xe7, 0xe9, 0x6e, 0x92, 0xf9, 0x08, 0x2f,
-	0x54, 0x4c, 0x46, 0x69, 0x26, 0x4a, 0x38, 0xc5, 0xc9, 0x55, 0xa7, 0x3c, 0x51, 0x11, 0x5e, 0xc3,
-	0x50, 0x5d, 0x64, 0x2f, 0x58, 0xb6, 0x89, 0x42, 0xd4, 0x48, 0x62, 0x23, 0x36, 0x7a, 0xd1, 0x28,
-	0x44, 0x8d, 0xb4, 0xe3, 0xb1, 0x1e, 0x7c, 0x30, 0xea, 0x45, 0xc4, 0x8c, 0xbc, 0xba, 0x9b, 0xf0,
-	0x8c, 0xe1, 0x4d, 0xf3, 0xe4, 0x96, 0xf5, 0x6e, 0x92, 0xeb, 0xf7, 0xf0, 0x47, 0xb7, 0x8f, 0x76,
-	0xc8, 0x7a, 0x11, 0xe6, 0xd2, 0xf1, 0x2a, 0xf3, 0x2a, 0xea, 0x6d, 0x0b, 0x2a, 0xe6, 0x25, 0x3d,
-	0x7a, 0x04, 0x4a, 0xcc, 0xdf, 0xa1, 0xde, 0xb3, 0x81, 0xbe, 0x20, 0x88, 0x47, 0xb7, 0x29, 0xe8,
-	0xf8, 0x0a, 0x8e, 0x39, 0x38, 0x77, 0xcb, 0x75, 0xa8, 0xc7, 0xd6, 0xdb, 0x0a, 0x26, 0xe6, 0x5e,
-	0x91, 0xf4, 0x55, 0x1c, 0x73, 0xf0, 0x65, 0x26, 0x7f, 0x37, 0x69, 0x2b, 0xa0, 0xfa, 0x76, 0x31,
-	0x29, 0xe8, 0x18, 0x6d, 0x38, 0xc5, 0x89, 0xec, 0xb8, 0x0e, 0x56, 0x38, 0x9b, 0x3f, 0x5f, 0x96,
-	0xd7, 0xbb, 0x23, 0x25, 0xab, 0xdf, 0xe7, 0x61, 0x7e, 0x34, 0x79, 0xcc, 0xba, 0xae, 0x8d, 0xde,
-	0xb2, 0x60, 0x8e, 0xa4, 0x1e, 0x6b, 0xa8, 0x1c, 0x30, 0x8b, 0x90, 0x95, 0x7e, 0x05, 0xd2, 0xf8,
-	0x5f, 0xa5, 0xc1, 0xc8, 0xeb, 0x10, 0x3c, 0xa2, 0x00, 0xfa, 0x0c, 0x4c, 0x33, 0xa7, 0x4f, 0xfd,
-	0x48, 0x1e, 0x31, 0xf3, 0x32, 0xa1, 0xdb, 0x94, 0x24, 0xac, 0xdb, 0xf8, 0x5c, 0x39, 0x62, 0x4b,
-	0x05, 0xb2, 0xf2, 0x51, 0x4a, 0xe6, 0x6a, 0x5d, 0xd1, 0x71, 0xcc, 0x81, 0xbe, 0x0d, 0xd3, 0x3d,
-	0x4a, 0xda, 0x34, 0x08, 0x55, 0xf5, 0x03, 0x67, 0x99, 0xe4, 0x7e, 0x55, 0x88, 0x4e, 0x26, 0x43,
-	0x7e, 0x87, 0x58, 0x63, 0xda, 0x7f, 0xb3, 0xc0, 0x78, 0x83, 0x98, 0x78, 0x48, 0xeb, 0xd0, 0x1e,
-	0x32, 0x77, 0x44, 0x0f, 0x99, 0x3f, 0x92, 0x87, 0x2c, 0x1c, 0xdd, 0x43, 0x16, 0x27, 0x7b, 0x48,
-	0xfb, 0xb7, 0x16, 0xcc, 0x18, 0x65, 0x45, 0xde, 0x49, 0xac, 0x6a, 0xb5, 0x68, 0x93, 0x07, 0x3b,
-	0xa2, 0xb6, 0x28, 0xdb, 0xb8, 0xee, 0x01, 0xed, 0x1a, 0x8f, 0x3f, 0xb4, 0xee, 0x58, 0x50, 0xb1,
-	0x6a, 0x95, 0x97, 0xf9, 0x74, 0x20, 0x46, 0x98, 0x37, 0x2f, 0xf3, 0xe9, 0x00, 0x8b, 0x16, 0x01,
-	0xc7, 0x48, 0xa0, 0x6f, 0xf3, 0x13, 0x38, 0x4e, 0xc4, 0xb2, 0x0d, 0x3d, 0x08, 0x79, 0xea, 0xb5,
-	0x55, 0x9d, 0x61, 0x46, 0xb1, 0xe4, 0x2f, 0x79, 0x6d, 0xcc, 0xe9, 0xf6, 0x75, 0xa8, 0xc8, 0xcd,
-	0xfa, 0x0c, 0x1d, 0x62, 0xda, 0x39, 0x44, 0x88, 0x7f, 0x50, 0x7a, 0xc2, 0x5c, 0x5a, 0x20, 0xef,
-	0xce, 0xe9, 0xf6, 0x9b, 0xdc, 0x26, 0xc9, 0xab, 0x25, 0x63, 0xb8, 0xd6, 0x87, 0x0e, 0xd7, 0x70,
-	0x91, 0xb9, 0xbb, 0xb8, 0xc8, 0x0b, 0x30, 0x1d, 0xf8, 0x2e, 0x5d, 0x0e, 0x3c, 0xe5, 0x8b, 0x62,
-	0x56, 0xcc, 0xc9, 0xf8, 0x1a, 0xd6, 0xed, 0xf6, 0x4f, 0x2d, 0x98, 0x1f, 0x4d, 0xe9, 0x32, 0xf7,
-	0x2e, 0x66, 0xd9, 0x2a, 0x7f, 0xf4, 0xb2, 0x95, 0xfd, 0x46, 0x0e, 0x92, 0x37, 0x66, 0xe8, 0x35,
-	0x0b, 0x2a, 0xa1, 0x31, 0x25, 0xea, 0x90, 0x9e, 0xc5, 0x1d, 0x82, 0x39, 0xd3, 0xb2, 0x72, 0x63,
-	0x52, 0x70, 0x0a, 0x16, 0x45, 0x50, 0xea, 0xa8, 0xab, 0x4a, 0x75, 0x4a, 0xcf, 0xe2, 0xf5, 0xa4,
-	0xbe, 0xfd, 0x94, 0x99, 0xbd, 0xfe, 0xc2, 0x31, 0x94, 0x4d, 0xe0, 0xe4, 0xc8, 0x61, 0x33, 0xf3,
-	0x5b, 0xce, 0x0f, 0x0a, 0x50, 0x8e, 0x7d, 0x1a, 0x7a, 0x42, 0xbc, 0x0a, 0xea, 0xf9, 0xfa, 0xc1,
-	0xd6, 0xff, 0x1b, 0xcf, 0x76, 0x7a, 0x7e, 0xfb, 0xce, 0xde, 0xd2, 0xc9, 0x98, 0x59, 0x92, 0xb0,
-	0xea, 0xc0, 0xb7, 0x42, 0x14, 0xb8, 0xa3, 0x5b, 0x81, 0xc7, 0x5a, 0x4e, 0x37, 0x9d, 0x71, 0xfe,
-	0xe3, 0x77, 0xc6, 0x7c, 0x2b, 0x6f, 0xfb, 0xed, 0xe1, 0xe8, 0x5b, 0x9f, 0x86, 0xdf, 0x1e, 0x62,
-	0xd1, 0x82, 0x9e, 0x86, 0x39, 0x15, 0x66, 0x9a, 0xb4, 0xe5, 0x7b, 0xed, 0x50, 0xb8, 0x89, 0x7c,
-	0x12, 0xc2, 0x36, 0x53, 0xad, 0x78, 0x84, 0x9b, 0xc7, 0x26, 0x7e, 0xec, 0x10, 0x17, 0xd8, 0x53,
-	0xe9, 0x3c, 0xe2, 0x72, 0xf3, 0xfa, 0x35, 0x71, 0x7f, 0x1d, 0x73, 0xa4, 0x22, 0xd9, 0xf4, 0x5d,
-	0x23, 0xd9, 0xaa, 0x94, 0xcd, 0xb5, 0x15, 0x89, 0x6d, 0xa5, 0x71, 0x5e, 0xcb, 0xe5, 0xb4, 0x3b,
-	0x7b, 0x1f, 0x72, 0xf6, 0x89, 0x7b, 0x1e, 0x14, 0xf8, 0xcb, 0x9f, 0x70, 0xe0, 0xb7, 0x9f, 0x85,
-	0x93, 0x23, 0x93, 0xa8, 0x7d, 0xaa, 0x75, 0xb0, 0x4f, 0x3d, 0xd4, 0x6b, 0xa1, 0x46, 0xf7, 0xf6,
-	0x7b, 0x8b, 0x27, 0xde, 0x79, 0x6f, 0xf1, 0xc4, 0xbb, 0xef, 0x2d, 0x9e, 0xf8, 0xce, 0xfe, 0xa2,
-	0x75, 0x7b, 0x7f, 0xd1, 0x7a, 0x67, 0x7f, 0xd1, 0x7a, 0x77, 0x7f, 0xd1, 0xfa, 0xd3, 0xfe, 0xa2,
-	0xf5, 0xa3, 0xf7, 0x17, 0x4f, 0x3c, 0xbf, 0xfc, 0x91, 0xff, 0x83, 0xf0, 0x3f, 0x01, 0x00, 0x00,
-	0xff, 0xff, 0x7b, 0x0c, 0x2a, 0x92, 0x85, 0x38, 0x00, 0x00,
+	proto.RegisterFile("github.com/akuity/kargo/api/stubs/rollouts/v1alpha1/generated.proto", fileDescriptor_3c0ab62a0c0c79d5)
+}
+
+var fileDescriptor_3c0ab62a0c0c79d5 = []byte{
+	// 3290 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5b, 0xcd, 0x73, 0x23, 0x47,
+	0xd9, 0xdf, 0x91, 0x2c, 0x59, 0x7a, 0x2c, 0x7b, 0xbd, 0xfd, 0xee, 0xbe, 0x51, 0xfc, 0x26, 0xf6,
+	0xbe, 0xb3, 0xf5, 0xa6, 0x36, 0x79, 0x41, 0x22, 0x9b, 0x40, 0xe5, 0x03, 0x96, 0x58, 0xf6, 0x1a,
+	0xbc, 0xd9, 0x0f, 0xa7, 0xed, 0x64, 0x93, 0x54, 0x0a, 0xd2, 0x1e, 0xb5, 0xa4, 0x59, 0x8f, 0x66,
+	0xb4, 0x33, 0x3d, 0xde, 0x55, 0x0a, 0x28, 0xa8, 0x9c, 0x20, 0x29, 0x2a, 0x05, 0x87, 0x1c, 0xb8,
+	0x71, 0xa5, 0xe0, 0xc0, 0x91, 0xe2, 0xc0, 0x8d, 0x3d, 0xe6, 0x44, 0x85, 0x8b, 0xc9, 0x9a, 0x0b,
+	0x55, 0x04, 0xfe, 0x80, 0x3d, 0x51, 0xfd, 0x35, 0xd3, 0x23, 0x59, 0x59, 0x5b, 0x72, 0x16, 0x2a,
+	0x37, 0xeb, 0xe9, 0xa7, 0x7f, 0x4f, 0xf7, 0xd3, 0x4f, 0x3f, 0x5f, 0xd3, 0x86, 0x95, 0xb6, 0xcb,
+	0x3a, 0xf1, 0x76, 0xcd, 0x09, 0xba, 0x75, 0xb2, 0x13, 0xbb, 0xac, 0x5f, 0xdf, 0x21, 0x61, 0x3b,
+	0xa8, 0x93, 0x9e, 0x5b, 0x8f, 0x58, 0xbc, 0x1d, 0xd5, 0xc3, 0xc0, 0xf3, 0x82, 0x98, 0x45, 0xf5,
+	0xdd, 0xa7, 0x89, 0xd7, 0xeb, 0x90, 0xa7, 0xeb, 0x6d, 0xea, 0xd3, 0x90, 0x30, 0xda, 0xac, 0xf5,
+	0xc2, 0x80, 0x05, 0xe8, 0x99, 0x14, 0xa4, 0x26, 0x41, 0x6a, 0x02, 0xa4, 0x46, 0x7a, 0x6e, 0x4d,
+	0x80, 0xd4, 0x34, 0x48, 0x4d, 0x83, 0x2c, 0x7c, 0xd9, 0x90, 0xdc, 0x0e, 0xda, 0x41, 0x5d, 0x60,
+	0x6d, 0xc7, 0x2d, 0xf1, 0x4b, 0xfc, 0x10, 0x7f, 0x49, 0x19, 0x0b, 0xe7, 0x76, 0x9e, 0x8b, 0x6a,
+	0xae, 0x5c, 0xd7, 0x36, 0x61, 0x4e, 0xa7, 0xbe, 0x3b, 0xb4, 0x90, 0x85, 0x67, 0x53, 0xa6, 0x2e,
+	0x71, 0x3a, 0xae, 0x4f, 0xc3, 0x7e, 0xbd, 0xb7, 0xd3, 0xe6, 0x84, 0xa8, 0xde, 0xa5, 0x8c, 0x1c,
+	0x34, 0xab, 0x3e, 0x6a, 0x56, 0x18, 0xfb, 0xcc, 0xed, 0xd2, 0xa1, 0x09, 0x5f, 0x7b, 0xd0, 0x84,
+	0xc8, 0xe9, 0xd0, 0x2e, 0x19, 0x9a, 0xf7, 0xcc, 0xa8, 0x79, 0x31, 0x73, 0xbd, 0xba, 0xeb, 0xb3,
+	0x88, 0x85, 0x83, 0x93, 0xec, 0x3f, 0xe6, 0x60, 0x66, 0xd9, 0x27, 0x5e, 0x3f, 0x72, 0x23, 0x1c,
+	0xfb, 0xe8, 0x6d, 0x28, 0xf1, 0x8d, 0x34, 0x09, 0x23, 0x55, 0xeb, 0xac, 0x75, 0x7e, 0xe6, 0xc2,
+	0x57, 0x6a, 0x12, 0xb7, 0x66, 0xe2, 0xd6, 0x7a, 0x3b, 0x6d, 0x4e, 0x88, 0x6a, 0x9c, 0xbb, 0xb6,
+	0xfb, 0x74, 0xed, 0xfa, 0xf6, 0x4d, 0xea, 0xb0, 0xab, 0x94, 0x91, 0x06, 0xba, 0xbb, 0xb7, 0x74,
+	0x62, 0x7f, 0x6f, 0x09, 0x52, 0x1a, 0x4e, 0x50, 0x51, 0x0b, 0xa6, 0xa2, 0x1e, 0x75, 0xaa, 0x39,
+	0x81, 0xbe, 0x5a, 0x1b, 0xe3, 0x74, 0x6b, 0xc6, 0x8a, 0x37, 0x7b, 0xd4, 0x69, 0x54, 0x94, 0xc4,
+	0x29, 0xfe, 0x0b, 0x0b, 0x7c, 0xe4, 0x43, 0x31, 0x62, 0x84, 0xc5, 0x51, 0x35, 0x2f, 0x24, 0xad,
+	0x4d, 0x2c, 0x49, 0xa0, 0x35, 0xe6, 0x94, 0xac, 0xa2, 0xfc, 0x8d, 0x95, 0x14, 0xfb, 0x4f, 0x16,
+	0x9c, 0x34, 0xb8, 0xaf, 0xb8, 0x11, 0x43, 0x6f, 0x0d, 0x69, 0xb3, 0x76, 0x38, 0x6d, 0xf2, 0xd9,
+	0x42, 0x97, 0xf3, 0x4a, 0x5a, 0x49, 0x53, 0x0c, 0x4d, 0x52, 0x28, 0xb8, 0x8c, 0x76, 0xa3, 0x6a,
+	0xee, 0x6c, 0xfe, 0xfc, 0xcc, 0x85, 0x97, 0x26, 0xdd, 0x60, 0x63, 0x56, 0x09, 0x2b, 0xac, 0x73,
+	0x58, 0x2c, 0xd1, 0xed, 0x9f, 0x4e, 0x65, 0x36, 0xc6, 0x55, 0x8c, 0x5a, 0x30, 0xdd, 0xa5, 0x2c,
+	0x74, 0x9d, 0xa8, 0x6a, 0x09, 0xe1, 0x2f, 0x8e, 0x25, 0xfc, 0xaa, 0xc0, 0x68, 0x9c, 0x54, 0x72,
+	0xa7, 0xe5, 0xef, 0x08, 0x6b, 0x70, 0xf4, 0x5d, 0x98, 0x22, 0x61, 0x5b, 0xef, 0xf0, 0x1b, 0xe3,
+	0xed, 0x30, 0x6c, 0xc7, 0x5d, 0xea, 0xb3, 0xd4, 0x4a, 0x96, 0xc3, 0x76, 0x84, 0x05, 0x30, 0xaa,
+	0x43, 0x99, 0xd1, 0xb0, 0xeb, 0xfa, 0x84, 0x51, 0x61, 0x28, 0xa5, 0xc6, 0x29, 0xc5, 0x56, 0xde,
+	0xd2, 0x03, 0x38, 0xe5, 0x41, 0x0e, 0x14, 0x9b, 0x61, 0x1f, 0xc7, 0x7e, 0x75, 0x6a, 0x82, 0x8d,
+	0xaf, 0x0a, 0x88, 0xd4, 0x96, 0xe4, 0x6f, 0xac, 0xa0, 0xd1, 0x2f, 0x2c, 0x38, 0xdd, 0xa5, 0x24,
+	0x8a, 0x43, 0xca, 0x57, 0x8e, 0x29, 0xa3, 0x3e, 0x73, 0x03, 0xbf, 0x5a, 0x10, 0x32, 0xd7, 0xc7,
+	0x54, 0xf6, 0x30, 0x60, 0xe3, 0x31, 0xb5, 0x82, 0xd3, 0x07, 0x8d, 0xe2, 0x03, 0x17, 0x61, 0xff,
+	0x7e, 0x0a, 0x4e, 0x0d, 0xdd, 0x0b, 0xf4, 0x2c, 0x14, 0x7a, 0x1d, 0x12, 0x51, 0x61, 0xe8, 0xe5,
+	0xc6, 0xa2, 0xb6, 0xa5, 0x0d, 0x4e, 0xbc, 0xbf, 0xb7, 0x34, 0xab, 0xa7, 0x08, 0x02, 0x96, 0xcc,
+	0xe8, 0x49, 0x6e, 0x48, 0x51, 0x44, 0xda, 0x54, 0x38, 0x84, 0xb2, 0x69, 0x0b, 0x82, 0x8c, 0xf5,
+	0x38, 0xfa, 0x01, 0xcc, 0x4a, 0xb3, 0xc0, 0x34, 0x8a, 0x3d, 0xc6, 0xef, 0x35, 0x57, 0xc6, 0xf2,
+	0x04, 0x96, 0x27, 0x91, 0x1a, 0x67, 0x94, 0xcc, 0x59, 0x93, 0x1a, 0xe1, 0xac, 0x38, 0x74, 0x03,
+	0xca, 0x11, 0x23, 0x21, 0xa3, 0xcd, 0x65, 0x56, 0x9d, 0x12, 0xb7, 0xf9, 0xa9, 0xc3, 0xdd, 0xe6,
+	0x2d, 0xb7, 0x4b, 0x1b, 0xb3, 0xdc, 0xa4, 0x36, 0x35, 0x00, 0x4e, 0xb1, 0x50, 0x04, 0x10, 0xc6,
+	0xfe, 0x66, 0xdc, 0xed, 0x92, 0xb0, 0x5f, 0x2d, 0x08, 0xe4, 0x6f, 0x8e, 0xb5, 0x2b, 0x9c, 0xc0,
+	0xa4, 0x4e, 0x38, 0xa5, 0x61, 0x43, 0x0c, 0xba, 0x03, 0xb3, 0xd2, 0xd8, 0xb4, 0xdc, 0xe2, 0xf1,
+	0xc8, 0x3d, 0xc5, 0xf5, 0xb8, 0x6a, 0x22, 0xe3, 0xac, 0x20, 0xfb, 0x9e, 0x05, 0xf3, 0xda, 0x16,
+	0xb6, 0x68, 0xb7, 0xe7, 0xf1, 0x6b, 0xf5, 0xf9, 0xc7, 0x9d, 0x9d, 0x4c, 0xdc, 0x59, 0x9f, 0xc8,
+	0x59, 0xea, 0x65, 0x8f, 0x0a, 0x3e, 0xf6, 0x27, 0x16, 0x9c, 0x1e, 0x64, 0x7e, 0x08, 0x11, 0xe1,
+	0x66, 0x36, 0x22, 0x5c, 0x3a, 0x96, 0x4d, 0x8e, 0x08, 0x0b, 0xfb, 0xf9, 0xe1, 0x2d, 0x7e, 0xb1,
+	0x62, 0x43, 0xea, 0xea, 0xf3, 0xff, 0x06, 0x57, 0x3f, 0xf5, 0x9f, 0xe0, 0xea, 0x7f, 0x67, 0x41,
+	0x49, 0xeb, 0x08, 0x9d, 0x85, 0x29, 0x9f, 0x74, 0xb5, 0x83, 0x4f, 0x34, 0x76, 0x8d, 0x74, 0x29,
+	0x16, 0x23, 0x68, 0x09, 0x0a, 0xbb, 0xc4, 0x8b, 0xb5, 0x2f, 0x2f, 0x73, 0xa3, 0x79, 0x8d, 0x13,
+	0xb0, 0xa4, 0xa3, 0x1d, 0x28, 0x8b, 0x3f, 0xd6, 0xc2, 0xa0, 0xab, 0xf2, 0xb2, 0x8b, 0x63, 0xed,
+	0xf0, 0x35, 0x8d, 0x22, 0xfd, 0x6a, 0xf2, 0x13, 0xa7, 0xf8, 0xf6, 0xbe, 0x05, 0x73, 0xcb, 0x31,
+	0xeb, 0xf0, 0xbd, 0x38, 0x84, 0xef, 0x87, 0xa7, 0x4c, 0x91, 0xdb, 0xde, 0x7d, 0x56, 0xdd, 0xbd,
+	0xf1, 0x52, 0xa6, 0x4d, 0x8e, 0xb0, 0x12, 0xf8, 0x2d, 0xb7, 0x9d, 0xde, 0x0d, 0x41, 0xc4, 0x12,
+	0x1d, 0xb9, 0x50, 0x0c, 0x48, 0xcc, 0x3a, 0x17, 0x94, 0xb7, 0x19, 0x2f, 0x46, 0x5d, 0xe7, 0x8b,
+	0xbf, 0xa0, 0x04, 0x25, 0xf6, 0x23, 0xa9, 0x58, 0x09, 0xb0, 0x3f, 0xb5, 0x60, 0x7e, 0xc5, 0x0b,
+	0xe2, 0xe6, 0x0d, 0x5e, 0xb6, 0xc8, 0x4b, 0x82, 0x2e, 0x42, 0xc9, 0xf5, 0x19, 0x0d, 0x77, 0x89,
+	0xa7, 0x4e, 0xcb, 0xd6, 0x5e, 0x63, 0x5d, 0xd1, 0xef, 0xef, 0x2d, 0xcd, 0xad, 0xc6, 0xa1, 0x50,
+	0xcb, 0x26, 0x0b, 0x5d, 0xbf, 0x8d, 0x93, 0x39, 0xe8, 0x43, 0x0b, 0x4e, 0xc9, 0x6b, 0xb6, 0x4a,
+	0x18, 0x79, 0x25, 0xa6, 0xa1, 0x4b, 0xf5, 0x45, 0xbb, 0x36, 0xd6, 0x5e, 0x06, 0x97, 0xa8, 0x71,
+	0xfb, 0x8d, 0x47, 0xd5, 0xca, 0x4e, 0x5d, 0x1d, 0x14, 0x88, 0x87, 0xd7, 0x60, 0xff, 0x38, 0x0f,
+	0x8f, 0x8e, 0xc4, 0x42, 0x0b, 0x90, 0x73, 0x9b, 0x6a, 0xc7, 0xa0, 0x70, 0x73, 0xeb, 0x4d, 0x9c,
+	0x73, 0x9b, 0xa8, 0x06, 0x40, 0xef, 0xf4, 0x42, 0x1a, 0x45, 0xfc, 0x76, 0x49, 0x03, 0x9d, 0xe3,
+	0xd1, 0xe2, 0x52, 0x42, 0xc5, 0x06, 0x07, 0xb7, 0x65, 0x8f, 0x6c, 0x53, 0x4f, 0x98, 0xa9, 0xb2,
+	0xe5, 0x2b, 0x9c, 0x80, 0x25, 0x1d, 0xf5, 0x01, 0xe4, 0xfa, 0x78, 0x02, 0xa4, 0x12, 0x82, 0xf5,
+	0x63, 0x51, 0x0e, 0x07, 0x94, 0x6b, 0x4b, 0x7f, 0x63, 0x43, 0x18, 0xda, 0x82, 0x62, 0x8f, 0x86,
+	0x6e, 0xd0, 0x54, 0xd9, 0xc2, 0xe8, 0x58, 0xc9, 0x6b, 0xbf, 0x9a, 0xac, 0xfd, 0x6a, 0xeb, 0x3e,
+	0xbb, 0x1e, 0xca, 0xb3, 0x6e, 0x00, 0x37, 0xa5, 0x0d, 0x81, 0x81, 0x15, 0x16, 0xd7, 0x50, 0x48,
+	0x59, 0x1c, 0xfa, 0x5c, 0xa1, 0x22, 0x1f, 0x28, 0xc9, 0x55, 0xe0, 0x84, 0x8a, 0x0d, 0x0e, 0xfb,
+	0xd7, 0x39, 0x38, 0x7d, 0xd0, 0xd2, 0xd1, 0x6d, 0x28, 0xca, 0xc5, 0xaa, 0x6b, 0x76, 0xfd, 0xd8,
+	0xb4, 0xa2, 0x82, 0x42, 0x72, 0x19, 0x54, 0xc2, 0xa6, 0xc4, 0xa1, 0xd7, 0x13, 0xbd, 0xe4, 0xc6,
+	0xd4, 0x4b, 0x82, 0x3c, 0xa0, 0x9b, 0xb3, 0x30, 0xc5, 0xeb, 0x3c, 0x65, 0x0c, 0x69, 0xc8, 0xe7,
+	0x27, 0x23, 0x46, 0x38, 0x47, 0xec, 0xbb, 0xd2, 0x10, 0x0c, 0x8e, 0x57, 0x7d, 0x97, 0x61, 0x31,
+	0x62, 0xbf, 0x9f, 0x83, 0x85, 0xd1, 0x9b, 0x42, 0xef, 0x5b, 0x00, 0x4d, 0xb7, 0x4b, 0x7d, 0x6e,
+	0x7e, 0x3a, 0x76, 0xbe, 0x7e, 0xcc, 0xaa, 0x5b, 0xd5, 0x02, 0xd2, 0x6c, 0x29, 0x21, 0x45, 0xd8,
+	0x90, 0x8f, 0x2e, 0x68, 0xf3, 0xe6, 0xfe, 0x5d, 0xdd, 0x97, 0x64, 0xce, 0xd5, 0x64, 0x04, 0x1b,
+	0x5c, 0xe8, 0xff, 0xa1, 0xcc, 0xe3, 0x40, 0xd4, 0x23, 0x0e, 0x55, 0xaa, 0x12, 0xee, 0xf9, 0x9a,
+	0x26, 0xe2, 0x74, 0xdc, 0xf6, 0xe0, 0xdc, 0x21, 0xd6, 0x79, 0x88, 0xa8, 0x73, 0x2e, 0x1b, 0x75,
+	0x12, 0x97, 0x6c, 0x46, 0x1e, 0xfb, 0x6f, 0x16, 0x3c, 0xb2, 0xe2, 0xc5, 0x11, 0xa3, 0xe1, 0x17,
+	0x3d, 0xf9, 0xfc, 0xa7, 0x05, 0xff, 0x33, 0x62, 0xab, 0x0f, 0x21, 0x07, 0xbd, 0x95, 0xcd, 0x41,
+	0xaf, 0x8c, 0x69, 0xc0, 0x07, 0x2e, 0x7f, 0x44, 0x2a, 0xfa, 0x5e, 0x1e, 0x66, 0xb9, 0x47, 0x6a,
+	0x06, 0xed, 0x63, 0x0a, 0x80, 0xe7, 0xa0, 0x70, 0x8b, 0x47, 0x94, 0x41, 0x93, 0x12, 0x61, 0x06,
+	0xcb, 0x31, 0xf4, 0x0e, 0x4c, 0xdf, 0x52, 0xa1, 0x51, 0x26, 0x88, 0xe3, 0xf9, 0xb9, 0xcc, 0xca,
+	0x6b, 0x2a, 0xd0, 0x5d, 0xf2, 0x59, 0xd8, 0x4f, 0x93, 0x5f, 0x1d, 0x11, 0xb5, 0x40, 0x5e, 0x37,
+	0xb7, 0x82, 0xb0, 0x1b, 0x7b, 0x44, 0x39, 0x9c, 0x84, 0x75, 0x4d, 0x92, 0xb1, 0x1e, 0xe7, 0x17,
+	0x99, 0xf4, 0xdc, 0xd7, 0x68, 0x18, 0xc9, 0x0e, 0x42, 0xe6, 0x22, 0x2f, 0x27, 0x23, 0xd8, 0xe0,
+	0x5a, 0x78, 0x01, 0x2a, 0xe6, 0x42, 0xd0, 0x3c, 0xe4, 0x77, 0x68, 0x5f, 0xaa, 0x12, 0xf3, 0x3f,
+	0xd1, 0xe9, 0xcc, 0xa5, 0x53, 0xb7, 0xec, 0x85, 0xdc, 0x73, 0x96, 0xfd, 0x75, 0x50, 0x39, 0xee,
+	0x80, 0x0b, 0xb1, 0x0e, 0xe3, 0x42, 0xec, 0x17, 0xa1, 0xb4, 0xe6, 0x52, 0xaf, 0x89, 0x69, 0x0b,
+	0xd5, 0xa1, 0xdc, 0xe2, 0x7f, 0x6f, 0x10, 0xd6, 0x51, 0xd3, 0x93, 0xe6, 0xcc, 0x9a, 0x1e, 0xc0,
+	0x29, 0x8f, 0xfd, 0x36, 0xcc, 0x7d, 0x2b, 0x24, 0xbd, 0x8e, 0xcb, 0xa8, 0x32, 0x84, 0x27, 0x61,
+	0x9a, 0x34, 0x9b, 0x3c, 0xa6, 0x2b, 0x80, 0x44, 0x4f, 0xcb, 0x92, 0x8c, 0xf5, 0xf8, 0xa1, 0xce,
+	0x9c, 0x4b, 0x58, 0xf7, 0x5b, 0x5e, 0x7c, 0xa7, 0xb9, 0x9d, 0x4a, 0xe8, 0x85, 0x41, 0xcb, 0xf5,
+	0xe8, 0xa0, 0x84, 0x0d, 0x49, 0xc6, 0x7a, 0xfc, 0x70, 0x12, 0x7e, 0x65, 0x41, 0xf9, 0x72, 0xa0,
+	0xd1, 0xbf, 0x73, 0x0c, 0xae, 0x29, 0xb9, 0xad, 0x57, 0x15, 0x92, 0x71, 0x5b, 0x2f, 0x66, 0x1c,
+	0xd3, 0x63, 0x06, 0x76, 0x4d, 0xf4, 0xc1, 0x39, 0xd4, 0xe5, 0x60, 0x7b, 0xa4, 0xaf, 0xf9, 0xa0,
+	0x00, 0xb3, 0x2f, 0x93, 0x3e, 0xf5, 0x19, 0x39, 0xba, 0xc6, 0xbf, 0x0a, 0x33, 0xa4, 0xd7, 0xf3,
+	0x54, 0x72, 0xae, 0xb4, 0xf2, 0x5f, 0x8a, 0x7d, 0x66, 0x39, 0x1d, 0xc2, 0x26, 0x1f, 0x5a, 0x85,
+	0x79, 0x87, 0xf8, 0x24, 0xec, 0xcb, 0xd4, 0x58, 0x18, 0x97, 0x0c, 0x36, 0x55, 0x35, 0x77, 0x7e,
+	0x65, 0x60, 0x1c, 0x0f, 0xcd, 0x40, 0x97, 0x01, 0xa9, 0x4a, 0x72, 0xd9, 0x71, 0x82, 0xd8, 0x67,
+	0x02, 0x47, 0x5e, 0xa6, 0x05, 0x85, 0x83, 0xae, 0x0e, 0x71, 0xe0, 0x03, 0x66, 0xa1, 0xb7, 0xa0,
+	0xea, 0x08, 0x64, 0xe5, 0x4f, 0x4c, 0x44, 0x79, 0xe1, 0xce, 0x2a, 0xc4, 0xea, 0xca, 0x08, 0x3e,
+	0x3c, 0x12, 0x81, 0xaf, 0x34, 0x62, 0x41, 0x48, 0xda, 0xd4, 0xc4, 0x2d, 0x66, 0x57, 0xba, 0x39,
+	0xc4, 0x81, 0x0f, 0x98, 0x85, 0x76, 0xa1, 0xcc, 0x3a, 0x21, 0x8d, 0x3a, 0x81, 0xd7, 0xac, 0x4e,
+	0x8b, 0x43, 0x1f, 0xaf, 0x4b, 0xa0, 0x0e, 0x7d, 0x4b, 0x83, 0x19, 0x6d, 0x53, 0x4d, 0xc2, 0xa9,
+	0x28, 0x5e, 0x11, 0x45, 0x4e, 0xd0, 0xa3, 0x51, 0xb5, 0x34, 0x41, 0xd7, 0x4e, 0x09, 0xdd, 0xe4,
+	0x48, 0x46, 0x23, 0x5e, 0x00, 0x63, 0x25, 0xc0, 0xfe, 0x6d, 0x0e, 0x2a, 0x26, 0xe3, 0x21, 0x32,
+	0x88, 0x77, 0xa0, 0xe2, 0x04, 0x3e, 0x0b, 0x03, 0x4f, 0xcc, 0x50, 0xb7, 0x61, 0xcc, 0xea, 0x90,
+	0x23, 0xac, 0x52, 0x46, 0x5c, 0xaf, 0x71, 0x5a, 0xc9, 0xaa, 0xac, 0x18, 0xe8, 0x38, 0x23, 0x0b,
+	0xbd, 0x6b, 0xc1, 0x49, 0x7a, 0x87, 0xa7, 0x99, 0xbc, 0xc8, 0x96, 0xf2, 0xf3, 0xc7, 0x24, 0xff,
+	0x11, 0x25, 0xff, 0xe4, 0xa5, 0xac, 0x00, 0x3c, 0x28, 0xd1, 0xde, 0x86, 0xf9, 0xc1, 0x13, 0xe5,
+	0x7a, 0xeb, 0x11, 0x75, 0x8d, 0xf3, 0xa9, 0xde, 0x36, 0x48, 0x14, 0x61, 0x31, 0x82, 0xbe, 0x04,
+	0xa5, 0x2e, 0x09, 0xdb, 0xae, 0x4f, 0x3c, 0xa1, 0xb3, 0xbc, 0xe1, 0x6b, 0x14, 0x1d, 0x27, 0x1c,
+	0xf6, 0x9f, 0xa7, 0x60, 0xc6, 0xe8, 0x3d, 0x7c, 0xfe, 0x1d, 0xe3, 0x4c, 0xc7, 0x36, 0x7f, 0x8c,
+	0x1d, 0xdb, 0x37, 0x01, 0x5a, 0xae, 0xef, 0x46, 0x9d, 0x31, 0x7b, 0xc1, 0xa2, 0xaa, 0x5a, 0x4b,
+	0x10, 0xb0, 0x81, 0x96, 0x66, 0xb3, 0x85, 0xd1, 0xd9, 0x2c, 0xfa, 0x9e, 0x11, 0x16, 0x8a, 0x13,
+	0x94, 0xe5, 0xc6, 0x71, 0xd4, 0x74, 0x74, 0x90, 0xa9, 0xc7, 0x67, 0x05, 0x8d, 0x2d, 0x28, 0x85,
+	0x34, 0x8a, 0xbb, 0x74, 0x99, 0x29, 0x1f, 0x72, 0x94, 0xcd, 0x57, 0x38, 0x2a, 0x56, 0xf3, 0x71,
+	0x82, 0xb4, 0xf0, 0x22, 0xcc, 0x66, 0x96, 0x70, 0xa4, 0xa4, 0x23, 0x80, 0x03, 0xdb, 0x5a, 0xe3,
+	0xa4, 0x20, 0xfc, 0x04, 0x3c, 0xb7, 0xeb, 0x32, 0x21, 0xa5, 0x90, 0x9e, 0xc0, 0x15, 0x4e, 0xc4,
+	0x72, 0xcc, 0xfe, 0x7b, 0x11, 0x54, 0xf5, 0x79, 0x08, 0xff, 0x62, 0xa6, 0xa3, 0xb9, 0x31, 0xd2,
+	0xd1, 0xcb, 0x50, 0x71, 0x7d, 0x97, 0xb9, 0xc4, 0x5b, 0xa5, 0x1e, 0xe9, 0xab, 0x68, 0xf7, 0x84,
+	0xf6, 0x2e, 0xeb, 0xc6, 0xd8, 0x01, 0x38, 0x99, 0xb9, 0xe8, 0x15, 0x28, 0x88, 0x70, 0xa0, 0xcc,
+	0xf6, 0xe8, 0x25, 0xb2, 0xe8, 0x84, 0xac, 0x70, 0x08, 0x2c, 0x91, 0x78, 0x40, 0x8e, 0x62, 0xc7,
+	0xa1, 0x51, 0xb4, 0x12, 0xf8, 0x4d, 0x97, 0xa5, 0x79, 0x66, 0x12, 0x90, 0x37, 0x07, 0xc6, 0xf1,
+	0xd0, 0x0c, 0x8e, 0xd2, 0x22, 0xae, 0x17, 0x87, 0x34, 0x45, 0x29, 0x66, 0x51, 0xd6, 0x06, 0xc6,
+	0xf1, 0xd0, 0x0c, 0xd4, 0x82, 0x8a, 0xa2, 0x89, 0xe3, 0x52, 0xf6, 0x79, 0xf4, 0x5d, 0xce, 0x73,
+	0xc5, 0xae, 0x19, 0x48, 0x38, 0x83, 0x8b, 0x62, 0x38, 0xe5, 0xfa, 0x4e, 0xe0, 0x3b, 0x5e, 0x1c,
+	0xb9, 0xbb, 0x4a, 0x58, 0x69, 0x4c, 0x61, 0x67, 0xf6, 0xf7, 0x96, 0x4e, 0xad, 0x0f, 0xc2, 0xe1,
+	0x61, 0x09, 0xe8, 0x47, 0x16, 0x9c, 0x71, 0x02, 0x3f, 0xa2, 0x4e, 0xcc, 0xdc, 0x5d, 0x7a, 0x29,
+	0x0c, 0x83, 0x50, 0xca, 0x2e, 0x8f, 0x29, 0xfb, 0xd1, 0xfd, 0xbd, 0xa5, 0x33, 0x2b, 0x07, 0x41,
+	0xe2, 0x83, 0x25, 0xa1, 0x5b, 0x50, 0xea, 0x85, 0xc1, 0xae, 0xdb, 0xa4, 0x61, 0x15, 0x84, 0xd4,
+	0x95, 0x09, 0x3a, 0xfc, 0x1b, 0x0a, 0x2a, 0xf5, 0x38, 0x9a, 0x82, 0x13, 0x31, 0xf6, 0xcf, 0x66,
+	0x60, 0x2e, 0xcb, 0x8e, 0x62, 0x80, 0x5e, 0x18, 0x74, 0x29, 0xeb, 0xd0, 0x38, 0x52, 0xb9, 0xf1,
+	0x78, 0xa9, 0xcc, 0x46, 0x02, 0xa3, 0xdb, 0x4b, 0xdc, 0x39, 0xa4, 0x54, 0x6c, 0x08, 0x42, 0x2e,
+	0x4c, 0xef, 0xc8, 0x40, 0xa9, 0xb2, 0x84, 0xc6, 0x24, 0x99, 0x8c, 0x12, 0x38, 0xc3, 0xc3, 0x97,
+	0x22, 0x61, 0x8d, 0x8f, 0xde, 0x80, 0xfc, 0x6d, 0xba, 0x3d, 0x51, 0x9b, 0xfc, 0x06, 0x55, 0x85,
+	0x44, 0x63, 0x7a, 0x7f, 0x6f, 0x29, 0x7f, 0x83, 0x6e, 0x63, 0x8e, 0xc9, 0x77, 0xd1, 0x94, 0x65,
+	0xa7, 0x72, 0x03, 0x8d, 0xc9, 0x4b, 0x57, 0xb9, 0x0b, 0x45, 0xc2, 0x1a, 0x1f, 0xdd, 0x82, 0xf2,
+	0x6d, 0xb2, 0x4b, 0x5b, 0x61, 0xe0, 0x33, 0xd5, 0xae, 0x1c, 0xef, 0xd1, 0xc7, 0x0d, 0x8d, 0xa2,
+	0xc4, 0x89, 0xf0, 0x9c, 0x10, 0x71, 0x2a, 0x05, 0x75, 0xa1, 0xe4, 0xd3, 0xdb, 0x98, 0x7a, 0xae,
+	0xa3, 0x3e, 0x6b, 0x8e, 0x67, 0xa0, 0xd7, 0x14, 0x88, 0x12, 0x28, 0x02, 0x97, 0xa6, 0xe1, 0x44,
+	0x04, 0x3f, 0xa7, 0x9b, 0xc1, 0xb6, 0xf2, 0x34, 0xe3, 0x9d, 0x53, 0x52, 0xf0, 0xc9, 0x73, 0xba,
+	0x1c, 0x6c, 0x63, 0x8e, 0xc9, 0x8d, 0xdc, 0x49, 0x7a, 0x64, 0xca, 0xbd, 0x5c, 0x3a, 0x96, 0x96,
+	0xa0, 0x34, 0xf2, 0x94, 0x8a, 0x0d, 0x41, 0x5c, 0x81, 0x6d, 0x55, 0x47, 0x2b, 0xbf, 0x32, 0x9e,
+	0x02, 0xb3, 0xc5, 0xb8, 0x54, 0xa0, 0xa6, 0xe1, 0x44, 0x04, 0x17, 0xe7, 0xaa, 0xa2, 0x7a, 0x22,
+	0x87, 0x92, 0xad, 0xcc, 0xa5, 0x38, 0x4d, 0xc3, 0x89, 0x08, 0xae, 0xd4, 0x68, 0xa7, 0x7f, 0x9b,
+	0x78, 0x3b, 0xae, 0xdf, 0xae, 0xce, 0x4c, 0xa0, 0xd4, 0xcd, 0x9d, 0xfe, 0x0d, 0x09, 0x63, 0x2a,
+	0x35, 0xa5, 0x62, 0x43, 0x10, 0xfa, 0xb9, 0x05, 0xc5, 0x9e, 0x17, 0xb7, 0x5d, 0xbf, 0x5a, 0x99,
+	0xa0, 0x5d, 0x94, 0x75, 0x83, 0xb5, 0x0d, 0x81, 0x28, 0x73, 0xb6, 0xa7, 0x92, 0xe6, 0xb5, 0x20,
+	0xfe, 0xe4, 0x2f, 0x4b, 0x55, 0xea, 0x3b, 0x41, 0xd3, 0xf5, 0xdb, 0xf5, 0x9b, 0x51, 0xe0, 0xd7,
+	0x30, 0xb9, 0xad, 0x93, 0x64, 0xb5, 0x94, 0x85, 0xe7, 0x61, 0xc6, 0x80, 0x78, 0x50, 0xce, 0x55,
+	0x31, 0x73, 0xae, 0x0f, 0x8b, 0x50, 0x31, 0x5f, 0x4c, 0x1c, 0x22, 0x11, 0x4a, 0x52, 0xfe, 0xdc,
+	0x51, 0x52, 0xfe, 0x77, 0xa0, 0x62, 0x7c, 0x9d, 0xd4, 0xdd, 0xb6, 0x97, 0x26, 0xcd, 0x78, 0xd3,
+	0xf2, 0xcc, 0x20, 0x46, 0x38, 0x23, 0xcb, 0x2c, 0x37, 0xa6, 0x1e, 0x50, 0x6e, 0x9c, 0xd3, 0x99,
+	0x55, 0x21, 0x9b, 0x37, 0x66, 0x72, 0xa5, 0x0b, 0x00, 0x2a, 0xf3, 0x69, 0xc5, 0x9e, 0xf0, 0x4e,
+	0x85, 0x34, 0x21, 0xdd, 0x4c, 0x46, 0xb0, 0xc1, 0x85, 0x9e, 0x80, 0x22, 0xcf, 0x3d, 0xa8, 0xac,
+	0xd8, 0x0b, 0x69, 0xe5, 0xbb, 0x26, 0xa8, 0x58, 0x8d, 0xa2, 0xe7, 0x78, 0x9a, 0x98, 0x66, 0x0c,
+	0xc2, 0x5f, 0x14, 0xd2, 0x5d, 0x9a, 0x09, 0x06, 0xce, 0x70, 0xf2, 0xa5, 0x53, 0x1e, 0xe0, 0xc5,
+	0x6d, 0x37, 0x96, 0x2e, 0xa2, 0x3e, 0x96, 0x63, 0xa2, 0xef, 0x32, 0x90, 0x10, 0x88, 0xeb, 0x5a,
+	0x30, 0xfa, 0x2e, 0x03, 0xe3, 0x78, 0x68, 0x06, 0xdf, 0x8c, 0xfa, 0xaa, 0x3e, 0x23, 0xbf, 0x30,
+	0x8d, 0xf8, 0x30, 0xfe, 0x7d, 0xa3, 0xc4, 0x99, 0xfc, 0xbe, 0x48, 0x0b, 0x3d, 0x7c, 0x8d, 0x33,
+	0x59, 0x35, 0xf2, 0x36, 0xcc, 0x65, 0x63, 0xc7, 0xb1, 0x77, 0x09, 0xef, 0x5a, 0x50, 0x31, 0xbf,
+	0x0f, 0xf3, 0x52, 0x9c, 0x05, 0x3b, 0xd4, 0x7f, 0x35, 0xd4, 0x1d, 0xef, 0x64, 0x77, 0x5b, 0x82,
+	0x8e, 0xaf, 0xe0, 0x84, 0x83, 0x73, 0x3b, 0x9e, 0x4b, 0x7d, 0xb6, 0xde, 0x54, 0x62, 0x12, 0xee,
+	0x15, 0x49, 0x5f, 0xc5, 0x09, 0x07, 0xb7, 0x2b, 0xf9, 0xf7, 0x26, 0x75, 0x42, 0xaa, 0x3f, 0x82,
+	0xa5, 0xcd, 0x0d, 0x63, 0x0c, 0x67, 0x38, 0x91, 0x9d, 0xb4, 0x7d, 0xa6, 0xce, 0xe6, 0xcf, 0x97,
+	0xe5, 0x67, 0xc7, 0x81, 0x7e, 0xcd, 0x6f, 0xf2, 0x30, 0x3f, 0x98, 0x82, 0x1d, 0x77, 0xdf, 0x16,
+	0xbd, 0x6b, 0xc1, 0x1c, 0xc9, 0xbc, 0x05, 0x50, 0x79, 0xd5, 0x78, 0x91, 0x26, 0xfb, 0xac, 0xa0,
+	0xf1, 0xdf, 0x4a, 0xe6, 0xc0, 0x73, 0x03, 0x3c, 0x20, 0x12, 0xfd, 0x1f, 0x4c, 0x33, 0xb7, 0x4b,
+	0x83, 0x58, 0x56, 0x5f, 0x79, 0x99, 0x32, 0x6d, 0x49, 0x12, 0xd6, 0x63, 0xfc, 0x74, 0x5c, 0x71,
+	0x6b, 0x42, 0xd9, 0x05, 0x28, 0xa5, 0xa7, 0xb3, 0xae, 0xe8, 0x38, 0xe1, 0x40, 0x01, 0x4c, 0x77,
+	0x28, 0x69, 0xd2, 0x30, 0x52, 0xad, 0x80, 0xd5, 0xc9, 0x52, 0xc5, 0x6f, 0x0b, 0xb0, 0x54, 0xe1,
+	0xf2, 0x77, 0x84, 0xb5, 0x14, 0xfb, 0x53, 0x0b, 0x8c, 0x57, 0x65, 0xa9, 0xdb, 0xb3, 0x0e, 0xed,
+	0xf6, 0x72, 0x47, 0x74, 0x7b, 0xf9, 0x23, 0xb9, 0xbd, 0xa9, 0xa3, 0xbb, 0xbd, 0xc2, 0x68, 0xb7,
+	0x67, 0xff, 0xc1, 0x82, 0x19, 0xa3, 0xa9, 0xc6, 0x27, 0x09, 0xcb, 0x55, 0x86, 0x99, 0xbe, 0x00,
+	0x11, 0x9d, 0x35, 0x39, 0xc6, 0xd7, 0x1e, 0xd2, 0xb6, 0xf1, 0xd2, 0x40, 0xaf, 0x1d, 0x0b, 0x2a,
+	0x56, 0xa3, 0xf2, 0xbb, 0x32, 0xed, 0x89, 0x1d, 0xe6, 0xcd, 0xef, 0xca, 0xb4, 0x87, 0xc5, 0x88,
+	0x10, 0xc7, 0x48, 0xa8, 0x3f, 0x2c, 0xa7, 0xe2, 0x38, 0x11, 0xcb, 0x31, 0xf4, 0x38, 0xe4, 0xa9,
+	0xdf, 0x54, 0x45, 0xf7, 0x8c, 0x62, 0xc9, 0x5f, 0xf2, 0x9b, 0x98, 0xd3, 0xed, 0xeb, 0x50, 0x91,
+	0x17, 0xf2, 0x65, 0xda, 0xc7, 0xb4, 0x75, 0x88, 0x40, 0xfd, 0xb8, 0xf4, 0x76, 0xb9, 0x2c, 0x20,
+	0x9f, 0xce, 0xe9, 0xf6, 0x7b, 0x5c, 0x27, 0xe9, 0x33, 0x18, 0x63, 0xbb, 0xd6, 0x67, 0x6e, 0xd7,
+	0x70, 0x83, 0xb9, 0x07, 0xb8, 0xc1, 0x27, 0x61, 0x3a, 0x0c, 0x3c, 0xba, 0x1c, 0xfa, 0xca, 0xdf,
+	0x24, 0xac, 0x98, 0x93, 0xf1, 0x35, 0xac, 0xc7, 0xed, 0x5f, 0x5a, 0x30, 0x3f, 0x98, 0x8a, 0x1d,
+	0xbb, 0x07, 0x31, 0x7b, 0x38, 0xf9, 0xa3, 0xf7, 0x70, 0xec, 0x7f, 0x58, 0x90, 0x3e, 0x53, 0x42,
+	0xb7, 0xa1, 0x12, 0x19, 0x27, 0xa2, 0xea, 0xd7, 0xf1, 0xba, 0xe2, 0xe6, 0xd1, 0xca, 0xbe, 0x85,
+	0x49, 0xc1, 0x19, 0x41, 0xa8, 0x0d, 0xa5, 0x96, 0xfa, 0xbe, 0xa6, 0x0a, 0xd8, 0xf1, 0x5e, 0xce,
+	0xe9, 0x8f, 0x74, 0x32, 0xcb, 0xd6, 0xbf, 0x70, 0x02, 0x6e, 0x13, 0x38, 0x39, 0x50, 0xb1, 0x1d,
+	0xfb, 0xc7, 0xb8, 0x4f, 0xa6, 0xa0, 0x9c, 0xb8, 0x2d, 0xf4, 0xbc, 0x78, 0x75, 0xd2, 0x09, 0xf4,
+	0x03, 0xa0, 0xff, 0x35, 0x1e, 0x89, 0x74, 0x82, 0xe6, 0xfd, 0xbd, 0xa5, 0x93, 0x09, 0xb3, 0x24,
+	0x61, 0x35, 0x81, 0x5b, 0x7b, 0x1c, 0x7a, 0x83, 0xd6, 0xce, 0x43, 0x26, 0xa7, 0x9b, 0x1e, 0x36,
+	0xff, 0x30, 0x3c, 0x2c, 0xbf, 0x9f, 0xdb, 0x41, 0xb3, 0x3f, 0xf8, 0x96, 0xa4, 0x11, 0x34, 0xfb,
+	0x58, 0x8c, 0xa0, 0x8b, 0x30, 0xa7, 0xa2, 0xc5, 0x26, 0x75, 0x02, 0xbf, 0x19, 0x89, 0xbb, 0x9f,
+	0x4f, 0x23, 0xd1, 0x56, 0x66, 0x14, 0x0f, 0x70, 0xf3, 0x10, 0xc3, 0x2b, 0x02, 0xf1, 0x65, 0xb5,
+	0x98, 0x4d, 0x00, 0x2e, 0x6f, 0x5e, 0xbf, 0x26, 0x3e, 0xac, 0x26, 0x1c, 0x99, 0x80, 0x34, 0xfd,
+	0xc0, 0x80, 0xb4, 0x2a, 0xb1, 0xf9, 0x6a, 0x45, 0x0a, 0x5a, 0x69, 0x9c, 0xd7, 0xb8, 0x9c, 0x76,
+	0x7f, 0xef, 0x33, 0xca, 0x92, 0x64, 0xe6, 0x41, 0x11, 0xbb, 0xfc, 0xd0, 0x23, 0xb6, 0xfd, 0x2a,
+	0x9c, 0x1c, 0x38, 0x36, 0xed, 0x1a, 0xad, 0x83, 0x5d, 0xe3, 0xa1, 0x5e, 0xa3, 0x34, 0xde, 0xb8,
+	0x7b, 0x6f, 0xf1, 0xc4, 0x47, 0xf7, 0x16, 0x4f, 0x7c, 0x7c, 0x6f, 0xf1, 0xc4, 0x0f, 0xf7, 0x17,
+	0xad, 0xbb, 0xfb, 0x8b, 0xd6, 0x47, 0xfb, 0x8b, 0xd6, 0xc7, 0xfb, 0x8b, 0xd6, 0x27, 0xfb, 0x8b,
+	0xd6, 0x07, 0x7f, 0x5d, 0x3c, 0xf1, 0xe6, 0x33, 0x63, 0xfc, 0xfb, 0xd4, 0xbf, 0x02, 0x00, 0x00,
+	0xff, 0xff, 0x24, 0x93, 0x1a, 0x42, 0x74, 0x35, 0x00, 0x00,
 }
 
 func (m *AnalysisRun) Marshal() (dAtA []byte, err error) {
diff --git a/internal/controller/rollouts/api/v1alpha1/generated.proto b/api/stubs/rollouts/v1alpha1/generated.proto
similarity index 98%
rename from internal/controller/rollouts/api/v1alpha1/generated.proto
rename to api/stubs/rollouts/v1alpha1/generated.proto
index 7456e465..43ddf5c9 100644
--- a/internal/controller/rollouts/api/v1alpha1/generated.proto
+++ b/api/stubs/rollouts/v1alpha1/generated.proto
@@ -3,7 +3,7 @@
 
 syntax = "proto2";
 
-package github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1;
+package github.com.akuity.kargo.api.stubs.rollouts.v1alpha1;
 
 import "k8s.io/api/batch/v1/generated.proto";
 import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
@@ -12,7 +12,7 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
 import "k8s.io/apimachinery/pkg/util/intstr/generated.proto";
 
 // Package-wide variables from generator "generated".
-option go_package = "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1";
+option go_package = "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1";
 
 message AnalysisRun {
   optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
diff --git a/internal/controller/rollouts/api/v1alpha1/groupversion_info.go b/api/stubs/rollouts/v1alpha1/groupversion_info.go
similarity index 100%
rename from internal/controller/rollouts/api/v1alpha1/groupversion_info.go
rename to api/stubs/rollouts/v1alpha1/groupversion_info.go
diff --git a/internal/controller/rollouts/api/v1alpha1/types.go b/api/stubs/rollouts/v1alpha1/types.go
similarity index 100%
rename from internal/controller/rollouts/api/v1alpha1/types.go
rename to api/stubs/rollouts/v1alpha1/types.go
diff --git a/internal/controller/rollouts/api/v1alpha1/zz_generated.deepcopy.go b/api/stubs/rollouts/v1alpha1/zz_generated.deepcopy.go
similarity index 100%
rename from internal/controller/rollouts/api/v1alpha1/zz_generated.deepcopy.go
rename to api/stubs/rollouts/v1alpha1/zz_generated.deepcopy.go
diff --git a/api/v1alpha1/annotations.go b/api/v1alpha1/annotations.go
index a4dc23f8..aa151b5e 100644
--- a/api/v1alpha1/annotations.go
+++ b/api/v1alpha1/annotations.go
@@ -38,4 +38,8 @@ const (
 	// AnnotationKeyPromotion is an annotation key that can be set on a
 	// resource to indicate that it is related to a specific promotion.
 	AnnotationKeyPromotion = "kargo.akuity.io/promotion"
+
+	// AnnotationKeyArgoCDContext is an annotation key that is set on a Stage
+	// to reference the last ArgoCD Applications that were part of a Promotion.
+	AnnotationKeyArgoCDContext = "kargo.akuity.io/argocd-context"
 )
diff --git a/api/v1alpha1/generated.proto b/api/v1alpha1/generated.proto
index 8d865fe4..6ac2a042 100644
--- a/api/v1alpha1/generated.proto
+++ b/api/v1alpha1/generated.proto
@@ -1004,7 +1004,7 @@ message PromotionStep {
   // Config is opaque configuration for the PromotionStep that is understood
   // only by each PromotionStep's implementation. It is legal to utilize
   // expressions in defining values at any level of this block.
-  // See https://docs.kargo.io/references/expression-language for details.
+  // See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
   optional .k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON config = 3;
 }
 
@@ -1133,7 +1133,7 @@ message PromotionVariable {
 
   // Value is the value of the variable. It is allowed to utilize expressions
   // in the value.
-  // See https://docs.kargo.io/references/expression-language for details.
+  // See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
   optional string value = 2;
 }
 
diff --git a/api/v1alpha1/promotion_types.go b/api/v1alpha1/promotion_types.go
index 223661b9..8e0cac73 100644
--- a/api/v1alpha1/promotion_types.go
+++ b/api/v1alpha1/promotion_types.go
@@ -117,7 +117,7 @@ type PromotionVariable struct {
 	Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
 	// Value is the value of the variable. It is allowed to utilize expressions
 	// in the value.
-	// See https://docs.kargo.io/references/expression-language for details.
+	// See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
 	Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
 }
 
@@ -221,7 +221,7 @@ type PromotionStep struct {
 	// Config is opaque configuration for the PromotionStep that is understood
 	// only by each PromotionStep's implementation. It is legal to utilize
 	// expressions in defining values at any level of this block.
-	// See https://docs.kargo.io/references/expression-language for details.
+	// See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
 	Config *apiextensionsv1.JSON `json:"config,omitempty" protobuf:"bytes,3,opt,name=config"`
 }
 
diff --git a/buf.gen.yaml b/buf.gen.yaml
index 4c177782..bc254085 100644
--- a/buf.gen.yaml
+++ b/buf.gen.yaml
@@ -2,9 +2,9 @@ version: v2
 managed:
   enabled: true
 plugins:
-  - remote: buf.build/protocolbuffers/go:v1.33.0
-    out: pkg/api
-    opt: paths=source_relative
-  - remote: buf.build/connectrpc/go:v1.16.0
-    out: pkg/api
-    opt: paths=source_relative
+- remote: buf.build/protocolbuffers/go:v1.33.0
+  out: .
+  opt: paths=source_relative
+- remote: buf.build/connectrpc/go:v1.16.0
+  out: .
+  opt: paths=source_relative
diff --git a/buf.kubebuilder.gen.yaml b/buf.kubebuilder.gen.yaml
new file mode 100644
index 00000000..8e50c0ef
--- /dev/null
+++ b/buf.kubebuilder.gen.yaml
@@ -0,0 +1,14 @@
+version: v2
+managed:
+  enabled: true
+plugins:
+- remote: buf.build/protocolbuffers/go:v1.33.0
+  # Send output to a temporary location because we don't actually want
+  # to keep any of this.
+  out: tmp
+  opt: paths=source_relative
+  # Send output to a temporary location because we don't actually want
+  # to keep any of this.
+- remote: buf.build/connectrpc/go:v1.16.0
+  out: tmp
+  opt: paths=source_relative
diff --git a/buf.ui.gen.yaml b/buf.ui.gen.yaml
index 40e1918f..71eea3c1 100644
--- a/buf.ui.gen.yaml
+++ b/buf.ui.gen.yaml
@@ -2,11 +2,11 @@ version: v1
 managed:
   enabled: true
 plugins:
-  - plugin: buf.build/bufbuild/es:v2.2.2
-    out: ui/src/gen
-    opt:
-      - target=ts
-  - plugin: buf.build/connectrpc/query-es:v2.0.0
-    out: ui/src/gen
-    opt:
-      - target=ts
+- plugin: buf.build/bufbuild/es:v2.2.2
+  out: ui/src/gen
+  opt:
+    - target=ts
+- plugin: buf.build/connectrpc/query-es:v2.0.0
+  out: ui/src/gen
+  opt:
+    - target=ts
diff --git a/buf.yaml b/buf.yaml
index afd366ee..bfcea04e 100644
--- a/buf.yaml
+++ b/buf.yaml
@@ -1,42 +1,20 @@
 version: v2
 modules:
-  - path: .
-    lint:
-      use:
-        - STANDARD
-      except:
-        - FIELD_NOT_REQUIRED
-        - PACKAGE_NO_IMPORT_CYCLE
-      disallow_comment_ignores: true
-    breaking:
-      use:
-        - FILE
-      except:
-        - EXTENSION_NO_DELETE
-        - FIELD_SAME_DEFAULT
-  - path: api
-    name: buf.build/akuity/kargo
-    lint:
-      use:
-        - STANDARD
-      except:
-        - FIELD_NOT_REQUIRED
-        - PACKAGE_DIRECTORY_MATCH
-        - PACKAGE_NO_IMPORT_CYCLE
-      ignore:
-        - api/rbac/v1alpha1/generated.proto
-        - api/v1alpha1/generated.proto
-    breaking:
-      use:
-        - FILE
-      except:
-        - EXTENSION_NO_DELETE
-        - FIELD_SAME_DEFAULT
-  - path: internal/controller
-    lint:
-      disallow_comment_ignores: true
-  - path: vendor
-    lint:
-      disallow_comment_ignores: true
+- path: .
+  lint:
+    use:
+    - STANDARD
+    except:
+    - FIELD_NOT_REQUIRED
+    - PACKAGE_DIRECTORY_MATCH
+    - PACKAGE_NO_IMPORT_CYCLE
+    disallow_comment_ignores: true
+  breaking:
+    use:
+    - FILE
+    except:
+    - EXTENSION_NO_DELETE
+    - FIELD_SAME_DEFAULT
+- path: vendor
 deps:
-  - buf.build/googleapis/googleapis
+- buf.build/googleapis/googleapis
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_clusterpromotiontasks.yaml b/charts/kargo/resources/crds/kargo.akuity.io_clusterpromotiontasks.yaml
index 30e22de2..7274d7dc 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_clusterpromotiontasks.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_clusterpromotiontasks.yaml
@@ -64,7 +64,7 @@ spec:
                         Config is opaque configuration for the PromotionStep that is understood
                         only by each PromotionStep's implementation. It is legal to utilize
                         expressions in defining values at any level of this block.
-                        See https://docs.kargo.io/references/expression-language for details.
+                        See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                       x-kubernetes-preserve-unknown-fields: true
                     if:
                       description: |-
@@ -163,7 +163,7 @@ spec:
                             description: |-
                               Value is the value of the variable. It is allowed to utilize expressions
                               in the value.
-                              See https://docs.kargo.io/references/expression-language for details.
+                              See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                             type: string
                         required:
                         - name
@@ -195,7 +195,7 @@ spec:
                       description: |-
                         Value is the value of the variable. It is allowed to utilize expressions
                         in the value.
-                        See https://docs.kargo.io/references/expression-language for details.
+                        See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                       type: string
                   required:
                   - name
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_promotions.yaml b/charts/kargo/resources/crds/kargo.akuity.io_promotions.yaml
index ceb2eb24..38ca7743 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_promotions.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_promotions.yaml
@@ -96,7 +96,7 @@ spec:
                         Config is opaque configuration for the PromotionStep that is understood
                         only by each PromotionStep's implementation. It is legal to utilize
                         expressions in defining values at any level of this block.
-                        See https://docs.kargo.io/references/expression-language for details.
+                        See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                       x-kubernetes-preserve-unknown-fields: true
                     if:
                       description: |-
@@ -195,7 +195,7 @@ spec:
                             description: |-
                               Value is the value of the variable. It is allowed to utilize expressions
                               in the value.
-                              See https://docs.kargo.io/references/expression-language for details.
+                              See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                             type: string
                         required:
                         - name
@@ -226,7 +226,7 @@ spec:
                       description: |-
                         Value is the value of the variable. It is allowed to utilize expressions
                         in the value.
-                        See https://docs.kargo.io/references/expression-language for details.
+                        See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                       type: string
                   required:
                   - name
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_promotiontasks.yaml b/charts/kargo/resources/crds/kargo.akuity.io_promotiontasks.yaml
index af325393..2b68f6d1 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_promotiontasks.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_promotiontasks.yaml
@@ -64,7 +64,7 @@ spec:
                         Config is opaque configuration for the PromotionStep that is understood
                         only by each PromotionStep's implementation. It is legal to utilize
                         expressions in defining values at any level of this block.
-                        See https://docs.kargo.io/references/expression-language for details.
+                        See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                       x-kubernetes-preserve-unknown-fields: true
                     if:
                       description: |-
@@ -163,7 +163,7 @@ spec:
                             description: |-
                               Value is the value of the variable. It is allowed to utilize expressions
                               in the value.
-                              See https://docs.kargo.io/references/expression-language for details.
+                              See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                             type: string
                         required:
                         - name
@@ -195,7 +195,7 @@ spec:
                       description: |-
                         Value is the value of the variable. It is allowed to utilize expressions
                         in the value.
-                        See https://docs.kargo.io/references/expression-language for details.
+                        See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                       type: string
                   required:
                   - name
diff --git a/charts/kargo/resources/crds/kargo.akuity.io_stages.yaml b/charts/kargo/resources/crds/kargo.akuity.io_stages.yaml
index b0bd2be2..be7f53e9 100644
--- a/charts/kargo/resources/crds/kargo.akuity.io_stages.yaml
+++ b/charts/kargo/resources/crds/kargo.akuity.io_stages.yaml
@@ -86,7 +86,7 @@ spec:
                                 Config is opaque configuration for the PromotionStep that is understood
                                 only by each PromotionStep's implementation. It is legal to utilize
                                 expressions in defining values at any level of this block.
-                                See https://docs.kargo.io/references/expression-language for details.
+                                See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                               x-kubernetes-preserve-unknown-fields: true
                             if:
                               description: |-
@@ -185,7 +185,7 @@ spec:
                                     description: |-
                                       Value is the value of the variable. It is allowed to utilize expressions
                                       in the value.
-                                      See https://docs.kargo.io/references/expression-language for details.
+                                      See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                                     type: string
                                 required:
                                 - name
@@ -216,7 +216,7 @@ spec:
                               description: |-
                                 Value is the value of the variable. It is allowed to utilize expressions
                                 in the value.
-                                See https://docs.kargo.io/references/expression-language for details.
+                                See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
                               type: string
                           required:
                           - name
diff --git a/cmd/controlplane/controller.go b/cmd/controlplane/controller.go
index bdd30dd2..4e497fc2 100644
--- a/cmd/controlplane/controller.go
+++ b/cmd/controlplane/controller.go
@@ -16,12 +16,12 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 	"sigs.k8s.io/controller-runtime/pkg/metrics/server"
 
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	libargocd "github.com/akuity/kargo/internal/argocd"
 	"github.com/akuity/kargo/internal/controller"
 	argocd "github.com/akuity/kargo/internal/controller/argocd/api/v1alpha1"
 	"github.com/akuity/kargo/internal/controller/promotions"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/controller/stages"
 	"github.com/akuity/kargo/internal/controller/warehouses"
 	"github.com/akuity/kargo/internal/credentials"
diff --git a/docs/docs/80-release-notes/97-v1.2.0.md b/docs/docs/80-release-notes/97-v1.2.0.md
index c23d34f0..0cd52526 100644
--- a/docs/docs/80-release-notes/97-v1.2.0.md
+++ b/docs/docs/80-release-notes/97-v1.2.0.md
@@ -72,7 +72,7 @@ spec:
 
 To use a common sequence of steps across multiple projects, use a cluster-scoped `ClusterPromotionTask` resource instead.
 
-To learn more about this exciting feature, refer to our [PromotionTasks reference doc](https://docs.kargo.io/references/promotion-steps).
+To learn more about this exciting feature, refer to our [PromotionTasks reference doc](https://docs.kargo.io/user-guide/reference-docs/promotion-steps).
 
 ### 🌊 Soak Time {#soak-time}
 
@@ -108,7 +108,7 @@ Note that `requiredSoakTime`, if specified, is _in addition to_ the usual criter
 
 * @muenchdo generously contributed two new options for the `git-open-pr` promotion step to specify a user-defined title and user-defined labels for the PRs it opens.
 
-Refer to the [Promotion Steps reference doc](https://docs.kargo.io/references/promotion-steps) for more details.
+Refer to the [Promotion Steps reference doc](https://docs.kargo.io/user-guide/reference-docs/promotion-steps) for more details.
 
 ### 🖥️ UI Improvements {#ui-improvements}
 
diff --git a/docs/docs/80-release-notes/98-v1.1.0.md b/docs/docs/80-release-notes/98-v1.1.0.md
index 0d2caed5..291ce978 100644
--- a/docs/docs/80-release-notes/98-v1.1.0.md
+++ b/docs/docs/80-release-notes/98-v1.1.0.md
@@ -6,7 +6,7 @@
 
 The community reception to Kargo's transition away from its rigid, legacy promotion mechanisms, toward more flexible promotion steps has been overwhelmingly positive. When promotion steps first appeared in v0.9.0, we knew immediately that support for an expression language would be a powerful complement to that new feature, and this release delivers on that.
 
-For more details, consult our [expression reference documentation](https://docs.kargo.io/references/expression-language). Examples in our [promotion steps reference documentation](https://docs.kargo.io/references/promotion-steps) have also been extensively updated to reflect realistic usage of the expression language.
+For more details, consult our [expression reference documentation](https://docs.kargo.io/user-guide/reference-docs/expressions). Examples in our [promotion steps reference documentation](https://docs.kargo.io/user-guide/reference-docs/promotion-steps) have also been extensively updated to reflect realistic usage of the expression language.
 
 With the advent of expression language support in promotion steps, we're noticing our own promotions processes becoming more and more similar from Stage to Stage -- often varying only in the definition of a few key variables. With this observation, it's clear that the time is right to _promote_ (pun fully intended) promotion processes to a first-class construct. So, to tease the upcoming v1.2.0 release, expect to see a new `PromotionTemplate` CRD that will enable users to DRY up their pipelines!
 
@@ -34,7 +34,7 @@ To correct for this, the `argo-cd-update` step now makes no attempt to automatic
 
 Last, but not least, all steps can now be configured with an optional timeout and error threshold. An error threshold greater than the default of one specifies the number of consecutive failed attempts to execute the step must occur before the entire Promotion is failed.
 
-__Please refer to the [promotion steps reference documentation](https://docs.kargo.io/references/promotion-steps) for detailed information about new and updated promotion steps as well as deprecated steps and fields.__
+__Please refer to the [promotion steps reference documentation](https://docs.kargo.io/user-guide/reference-docs/promotion-steps) for detailed information about new and updated promotion steps as well as deprecated steps and fields.__
 
 ### ⚙️ Resource and Concurrency Settings {#resource-and-concurrency-settings}
 
diff --git a/go.mod b/go.mod
index f41056ac..bd219eb4 100644
--- a/go.mod
+++ b/go.mod
@@ -10,10 +10,10 @@ require (
 	github.com/Masterminds/semver/v3 v3.3.1
 	github.com/adrg/xdg v0.5.3
 	github.com/aws/aws-sdk-go-v2 v1.36.3
-	github.com/aws/aws-sdk-go-v2/config v1.29.8
-	github.com/aws/aws-sdk-go-v2/credentials v1.17.61
-	github.com/aws/aws-sdk-go-v2/service/ecr v1.42.0
-	github.com/aws/aws-sdk-go-v2/service/sts v1.33.16
+	github.com/aws/aws-sdk-go-v2/config v1.29.9
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.62
+	github.com/aws/aws-sdk-go-v2/service/ecr v1.42.1
+	github.com/aws/aws-sdk-go-v2/service/sts v1.33.17
 	github.com/bacongobbler/browser v1.1.0
 	github.com/bmatcuk/doublestar/v4 v4.8.1
 	github.com/bombsimon/logrusr/v4 v4.1.0
@@ -48,12 +48,12 @@ require (
 	github.com/xeipuuv/gojsonschema v1.2.0
 	gitlab.com/gitlab-org/api/client-go v0.124.0
 	go.uber.org/ratelimit v0.3.1
-	golang.org/x/crypto v0.35.0
-	golang.org/x/net v0.35.0
-	golang.org/x/oauth2 v0.27.0
-	golang.org/x/sync v0.11.0
-	google.golang.org/api v0.223.0
-	google.golang.org/grpc v1.70.0
+	golang.org/x/crypto v0.36.0
+	golang.org/x/net v0.37.0
+	golang.org/x/oauth2 v0.28.0
+	golang.org/x/sync v0.12.0
+	google.golang.org/api v0.224.0
+	google.golang.org/grpc v1.71.0
 	google.golang.org/protobuf v1.36.5
 	gopkg.in/yaml.v3 v3.0.1
 	helm.sh/helm/v3 v3.17.1
@@ -65,7 +65,7 @@ require (
 	k8s.io/klog/v2 v2.130.1
 	k8s.io/utils v0.0.0-20241210054802-24370beab758
 	oras.land/oras-go v1.2.6
-	sigs.k8s.io/controller-runtime v0.20.2
+	sigs.k8s.io/controller-runtime v0.20.3
 	sigs.k8s.io/yaml v1.4.0
 )
 
@@ -86,8 +86,8 @@ require (
 	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 // indirect
-	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 // indirect
 	github.com/aws/smithy-go v1.22.2 // indirect
 	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/chai2010/gettext-go v1.0.2 // indirect
@@ -107,7 +107,7 @@ require (
 	github.com/gofrs/uuid v4.0.0+incompatible // indirect
 	github.com/google/go-github/v64 v64.0.0 // indirect
 	github.com/google/s2a-go v0.1.9 // indirect
-	github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
+	github.com/googleapis/enterprise-certificate-proxy v0.3.5 // indirect
 	github.com/googleapis/gax-go/v2 v2.14.1 // indirect
 	github.com/gorilla/websocket v1.5.0 // indirect
 	github.com/gosuri/uitable v0.0.4 // indirect
@@ -156,7 +156,7 @@ require (
 	github.com/containerd/containerd v1.7.24 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
-	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
 	github.com/distribution/reference v0.6.0 // indirect
 	github.com/docker/cli v27.5.0+incompatible // indirect
 	github.com/docker/distribution v2.8.3+incompatible // indirect
@@ -216,12 +216,12 @@ require (
 	go.opentelemetry.io/otel v1.34.0 // indirect
 	go.opentelemetry.io/otel/metric v1.34.0 // indirect
 	go.opentelemetry.io/otel/trace v1.34.0 // indirect
-	golang.org/x/sys v0.30.0 // indirect
-	golang.org/x/term v0.29.0 // indirect
-	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/term v0.30.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 	golang.org/x/time v0.10.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	k8s.io/apiextensions-apiserver v0.32.2
 	k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
diff --git a/go.sum b/go.sum
index 83197c09..f9247190 100644
--- a/go.sum
+++ b/go.sum
@@ -52,10 +52,10 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
 github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
-github.com/aws/aws-sdk-go-v2/config v1.29.8 h1:RpwAfYcV2lr/yRc4lWhUM9JRPQqKgKWmou3LV7UfWP4=
-github.com/aws/aws-sdk-go-v2/config v1.29.8/go.mod h1:t+G7Fq1OcO8cXTPPXzxQSnj/5Xzdc9jAAD3Xrn9/Mgo=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.61 h1:Hd/uX6Wo2iUW1JWII+rmyCD7MMhOe7ALwQXN6sKDd1o=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.61/go.mod h1:L7vaLkwHY1qgW0gG1zG0z/X0sQ5tpIY5iI13+j3qI80=
+github.com/aws/aws-sdk-go-v2/config v1.29.9 h1:Kg+fAYNaJeGXp1vmjtidss8O2uXIsXwaRqsQJKXVr+0=
+github.com/aws/aws-sdk-go-v2/config v1.29.9/go.mod h1:oU3jj2O53kgOU4TXq/yipt6ryiooYjlkqqVaZk7gY/U=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.62 h1:fvtQY3zFzYJ9CfixuAQ96IxDrBajbBWGqjNTCa79ocU=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.62/go.mod h1:ElETBxIQqcxej++Cs8GyPBbgMys5DgQPTwo7cUPDKt8=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
@@ -64,18 +64,18 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0io
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
-github.com/aws/aws-sdk-go-v2/service/ecr v1.42.0 h1:qQxVtUF36VLVgY/hDnozEL3ls9F1fGKsVsEDHddXOTM=
-github.com/aws/aws-sdk-go-v2/service/ecr v1.42.0/go.mod h1:iQ1skgw1XRK+6Lgkb0I9ODatAP72WoTILh0zXQ5DtbU=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.42.1 h1:mgtRN6wS2Frq29O7YNTn18ieokL193RFpLhUbsvs7o0=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.42.1/go.mod h1:iQ1skgw1XRK+6Lgkb0I9ODatAP72WoTILh0zXQ5DtbU=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
-github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 h1:2U9sF8nKy7UgyEeLiZTRg6ShBS22z8UnYpV6aRFL0is=
-github.com/aws/aws-sdk-go-v2/service/sso v1.25.0/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 h1:wjAdc85cXdQR5uLx5FwWvGIHm4OPJhTyzUHU8craXtE=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
-github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 h1:BHEK2Q/7CMRMCb3nySi/w8UbIcPhKvYP5s1xf8/izn0=
-github.com/aws/aws-sdk-go-v2/service/sts v1.33.16/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
+github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 h1:8JdC7Gr9NROg1Rusk25IcZeTO59zLxsKgE0gkh5O6h0=
+github.com/aws/aws-sdk-go-v2/service/sso v1.25.1/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 h1:KwuLovgQPcdjNMfFt9OhUd9a2OwcOKhxfvF4glTzLuA=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 h1:PZV5W8yk4OtH1JAuhV2PXwwO9v5G5Aoj+eMCn4T+1Kc=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
 github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
 github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
 github.com/bacongobbler/browser v1.1.0 h1:6YTctUlzcApit1vpWgh+myjh8lQUyQRD2Ltoyvy2EoM=
@@ -258,8 +258,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
-github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
+github.com/googleapis/enterprise-certificate-proxy v0.3.5 h1:VgzTY2jogw3xt39CusEnFJWm7rlsq5yL5q9XdLOuP5g=
+github.com/googleapis/enterprise-certificate-proxy v0.3.5/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
 github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
 github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
 github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
@@ -538,8 +538,8 @@ go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS
 go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
 go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
 go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
-go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
-go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
+go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
 go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
 go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
 go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
@@ -560,8 +560,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
-golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -575,18 +575,18 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
-golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
-golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
-golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
+golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
-golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -602,18 +602,18 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
-golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
-golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
+golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
+golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
-golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
 golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -629,15 +629,15 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
 gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/api v0.223.0 h1:JUTaWEriXmEy5AhvdMgksGGPEFsYfUKaPEYXd4c3Wvc=
-google.golang.org/api v0.223.0/go.mod h1:C+RS7Z+dDwds2b+zoAk5hN/eSfsiCn0UDrYof/M4d2M=
+google.golang.org/api v0.224.0 h1:Ir4UPtDsNiwIOHdExr3fAj4xZ42QjK7uQte3lORLJwU=
+google.golang.org/api v0.224.0/go.mod h1:3V39my2xAGkodXy0vEqcEtkqgw2GtrFL5WuBZlCTCOQ=
 google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
-google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
-google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2 h1:DMTIbak9GhdaSxEjvVzAeNZvyc03I61duqNbnm3SU0M=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
-google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
-google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
+google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24=
+google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
 google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@@ -684,8 +684,8 @@ k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJ
 k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk=
 oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8=
-sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc=
-sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
+sigs.k8s.io/controller-runtime v0.20.3 h1:I6Ln8JfQjHH7JbtCD2HCYHoIzajoRxPNuvhvcDbZgkI=
+sigs.k8s.io/controller-runtime v0.20.3/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
 sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
diff --git a/hack/codegen/proto.sh b/hack/codegen/proto.sh
index 465b9775..8034868a 100755
--- a/hack/codegen/proto.sh
+++ b/hack/codegen/proto.sh
@@ -1,11 +1,11 @@
 #!/usr/bin/env bash
 
-set -euxo pipefail
+set -euo pipefail
 
 readonly API_PKGS=(
   "github.com/akuity/kargo/api/v1alpha1"
+  "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
   "github.com/akuity/kargo/api/rbac/v1alpha1"
-  "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 )
 
 readonly APIMACHINERY_PKGS=(
@@ -20,90 +20,126 @@ readonly APIMACHINERY_PKGS=(
   "-k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
-# Change working directory to the root of the repository
-work_dir=$(dirname "${0}")
-work_dir=$(readlink -f "${work_dir}/../..")
-
-# Create a temporary build directory
-build_dir=$(mktemp -d)
-
-function clean() {
-  echo "Clean up intermediate resources..."
-  rm -r "${build_dir}" || true
-  rm -r "${work_dir}/pkg/api/v1alpha1" || true
-  rm -r "${work_dir}/pkg/api/rbac" || true
-  rm -r "${work_dir}/vendor" || true
-}
-trap 'clean' EXIT
-
 function main() {
-  echo "Change working directory to temporary build directory..."
-  cd "${build_dir}"
-
-  echo "Prepare build directory..."
-  # Initialize dummy module inside build directory
+  set -x
+
+  # go-to-protobuf is used for generating .proto and .pb.go files from
+  # Kubebuilder structs.
+  #
+  # It has an inconvenient requirement that the directory structure of the
+  # project must directly mirror the import paths of the packages.
+  #
+  # To account for this, we'll do all go-to-protobuf-related work in a temporary
+  # directory, and copy the generated .proto files back to the project root when
+  # we're done.
+
+  { msg "Changing working directory to temporary directory..."; } 2> /dev/null
+  cd "${tmp_dir}"
+
+  { msg "Initializing dummy module and workspace..."; } 2> /dev/null
   go mod init github.com/akuity
   go work init
 
-  # Copy source files to build directory
-  local build_src_dir
-  build_src_dir="${build_dir}/src/github.com/akuity/kargo"
+  set +x
+  msg "Copying source to temporary directory...";
+  local build_src_dir="${tmp_dir}/src/github.com/akuity/kargo"
   mkdir -p "${build_src_dir}"
-
-  # Use find to locate and copy .go files, go.mod, and go.sum
-  # while preserving the directory structure
-  find "$work_dir" \( \
+  find "$proj_dir" \( \
     -name '*.go' -o \
     -name 'go.mod' -o \
     -name 'go.sum' \
   \) -type f | while read -r file; do
-    rel_path="${file#$work_dir/}"
+    rel_path="${file#$proj_dir/}"
     dest_file="$build_src_dir/$rel_path"
     dest_dir=$(dirname "$dest_file")
     mkdir -p "$dest_dir"
     cp "$file" "$dest_file"
   done
-  go work use ./src/github.com/akuity/kargo
 
-  echo "Vendor dependencies for protobuf code generation..."
+  msg "Vendoring dependencies for .proto files generation..."
+  set -x
+  go work use ./src/github.com/akuity/kargo
   go work sync
   go work vendor
 
-  echo "Generate protobuf code from Kubebuilder structs..."
+  { msg "Generating .proto and .pb.go files from Kubebuilder structs..."; } 2> /dev/null
   go-to-protobuf \
-    --go-header-file="${work_dir}/hack/boilerplate.go.txt" \
+    --go-header-file="${proj_dir}/hack/boilerplate.go.txt" \
     --packages="$(IFS=, ; echo "${API_PKGS[*]}")" \
     --apimachinery-packages="$(IFS=, ; echo "${APIMACHINERY_PKGS[*]}")" \
-    --proto-import="${work_dir}/hack/include" \
-    --proto-import="${build_dir}/vendor" \
-    --output-dir="${build_dir}/src"
+    --proto-import="${proj_dir}/hack/include" \
+    --proto-import="${tmp_dir}/vendor" \
+    --output-dir="${tmp_dir}/src"
 
-  echo "Copy generated code to the working directory..."
-  cp -R "${build_src_dir}/api" "${work_dir}"
-  cp -R "${build_src_dir}/internal" "${work_dir}"
+  { msg "Copying generated .proto and .pb.go files back to the project root..."; } 2> /dev/null
+  cp -R "${build_src_dir}/api" "${proj_dir}"
 
-  echo "Change working directory to repository directory..."
-  cd "${work_dir}"
+  # At this point, .proto and .pb.go files generated from Kubebuilder structs
+  # are all where they belong.
 
-  echo "Vendor dependencies for protobuf code generation..."
-  go mod vendor
+  { msg "Returning to the project root..."; } 2> /dev/null
+  cd "${proj_dir}"
+
+  # Next, we'll use buf to generate Go and TypeScript bindings from the .proto
+  # files.
+  #
+  # The easiest way to get buf to see third-party .proto files is to
+  # (temporarily) vendor them into the project and add vendor/ as a path in the
+  # buf.yaml file.
 
-  echo "Generate protobuf code (Go)..."
-  buf generate api
+  { msg "Vendoring dependencies (temporarily) for code generation..."; } 2> /dev/null
+  go mod vendor
 
-  echo "Inject generated protobuf tag to Kubebuilder structs..."
+  { msg "Injecting protobuf struct tags into Kubebuilder structs..."; } 2> /dev/null
+  # buf.kubebuilder.gen.yaml sends output to a temporary location because we
+  # don't actually want to keep the generated files. We're only using them as an
+  # intermediate step to inject struct tags.
+  #
+  # NOTE: We do this only for the APIs we define ourselves. It's not applied to
+  # the "knockoff" Argo CD and Argo Rollouts types.
+  buf generate . --path api/v1alpha1 \
+    --template=buf.kubebuilder.gen.yaml
+  buf generate . --path api/rbac \
+    --template=buf.kubebuilder.gen.yaml
   go run ./hack/codegen/prototag/main.go \
-    -src-dir="${work_dir}/pkg/api/v1alpha1" \
-    -dst-dir="${work_dir}/api/v1alpha1"
+    -src-dir="${proj_dir}/tmp/api/v1alpha1" \
+    -dst-dir="${proj_dir}/api/v1alpha1"
+  go run ./hack/codegen/prototag/main.go \
+    -src-dir="${proj_dir}/tmp/api/rbac/v1alpha1" \
+    -dst-dir="${proj_dir}/api/rbac/v1alpha1"
+
+  { msg "Generating .pb.go and .connect.go files from service.proto"; } 2> /dev/null
+  buf generate . --path api/service
 
-  echo "Generate protobuf code (UI)..."
-  buf generate api \
+  { msg "Generating TypeScript bindings for UI..."; } 2> /dev/null
+  buf generate . --path api \
     --include-imports \
     --template=buf.ui.gen.yaml
 }
 
-(
-  # Include local binaries in the PATH
-  export PATH="${work_dir}/hack/bin:${PATH}"
-  main
-)
+function msg() {
+  echo -e "\033[1;32m$1\033[0m"
+}
+
+function clean() {
+  { msg "Cleaning up all intermediate resources..."; } 2> /dev/null
+  rm -rf "${proj_dir}/vendor" || true
+  rm -rf "${proj_dir}/tmp" || true
+  { msg "Done"; } 2> /dev/null
+}
+
+msg "Finding project root..."
+proj_dir=$(dirname "${0}")
+proj_dir=$(readlink -f "${proj_dir}/../..")
+msg "Project root is ${proj_dir}"
+
+# Include local binaries in the PATH
+export PATH="${proj_dir}/hack/bin:${PATH}"
+
+msg "Creating temporary directory..."
+tmp_dir=$(mktemp -d)
+msg "Temporary directory is ${tmp_dir}"
+
+trap 'clean' EXIT
+
+main
diff --git a/hack/tools/go.mod b/hack/tools/go.mod
index da65ff2e..e14dbe81 100644
--- a/hack/tools/go.mod
+++ b/hack/tools/go.mod
@@ -4,15 +4,15 @@ go 1.23.0
 
 require (
 	github.com/bufbuild/buf v1.50.0
-	github.com/golangci/golangci-lint v1.64.5
-	golang.org/x/tools v0.30.0
+	github.com/golangci/golangci-lint v1.64.6
+	golang.org/x/tools v0.31.0
 	helm.sh/helm/v3 v3.17.1
 	k8s.io/code-generator v0.32.2
 	sigs.k8s.io/controller-tools v0.17.2
 )
 
 require (
-	4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
+	4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
 	4d63.com/gochecknoglobals v0.2.2 // indirect
 	buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.3-20241031151143-70f632351282.1 // indirect
 	buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.3-20241127180247-a33202765966.1 // indirect
@@ -26,7 +26,7 @@ require (
 	connectrpc.com/connect v1.18.1 // indirect
 	connectrpc.com/otelconnect v0.7.1 // indirect
 	dario.cat/mergo v1.0.1 // indirect
-	github.com/4meepo/tagalign v1.4.1 // indirect
+	github.com/4meepo/tagalign v1.4.2 // indirect
 	github.com/Abirdcfly/dupword v0.1.3 // indirect
 	github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
 	github.com/Antonboom/errname v1.0.0 // indirect
@@ -36,7 +36,7 @@ require (
 	github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
 	github.com/Crocmagnon/fatcontext v0.7.1 // indirect
 	github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
-	github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect
+	github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect
 	github.com/MakeNowJust/heredoc v1.0.0 // indirect
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/semver/v3 v3.3.0 // indirect
@@ -67,7 +67,7 @@ require (
 	github.com/bufbuild/protovalidate-go v0.8.2 // indirect
 	github.com/butuzov/ireturn v0.3.1 // indirect
 	github.com/butuzov/mirror v1.3.0 // indirect
-	github.com/catenacyber/perfsprint v0.8.1 // indirect
+	github.com/catenacyber/perfsprint v0.8.2 // indirect
 	github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/chai2010/gettext-go v1.0.2 // indirect
@@ -146,7 +146,7 @@ require (
 	github.com/google/btree v1.0.1 // indirect
 	github.com/google/cel-go v0.22.1 // indirect
 	github.com/google/gnostic-models v0.6.8 // indirect
-	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/go-containerregistry v0.20.2 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
@@ -156,7 +156,7 @@ require (
 	github.com/gorilla/mux v1.8.1 // indirect
 	github.com/gorilla/websocket v1.5.0 // indirect
 	github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
-	github.com/gostaticanalysis/comment v1.4.2 // indirect
+	github.com/gostaticanalysis/comment v1.5.0 // indirect
 	github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
 	github.com/gostaticanalysis/nilerr v0.1.1 // indirect
 	github.com/gosuri/uitable v0.0.4 // indirect
@@ -179,8 +179,8 @@ require (
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/julz/importas v0.2.0 // indirect
 	github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
-	github.com/kisielk/errcheck v1.8.0 // indirect
-	github.com/kkHAIKE/contextcheck v1.1.5 // indirect
+	github.com/kisielk/errcheck v1.9.0 // indirect
+	github.com/kkHAIKE/contextcheck v1.1.6 // indirect
 	github.com/klauspost/compress v1.17.11 // indirect
 	github.com/klauspost/pgzip v1.2.6 // indirect
 	github.com/kulti/thelper v0.6.3 // indirect
@@ -188,7 +188,7 @@ require (
 	github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
 	github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
 	github.com/lasiar/canonicalheader v1.1.2 // indirect
-	github.com/ldez/exptostd v0.4.1 // indirect
+	github.com/ldez/exptostd v0.4.2 // indirect
 	github.com/ldez/gomoddirectives v0.6.1 // indirect
 	github.com/ldez/grignotin v0.9.0 // indirect
 	github.com/ldez/tagliatelle v0.7.1 // indirect
@@ -205,7 +205,7 @@ require (
 	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
-	github.com/mgechev/revive v1.6.1 // indirect
+	github.com/mgechev/revive v1.7.0 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/go-wordwrap v1.0.1 // indirect
@@ -232,7 +232,7 @@ require (
 	github.com/nakabonne/nestif v0.3.1 // indirect
 	github.com/nishanths/exhaustive v0.12.0 // indirect
 	github.com/nishanths/predeclared v0.2.2 // indirect
-	github.com/nunnatsa/ginkgolinter v0.19.0 // indirect
+	github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
 	github.com/olekukonko/tablewriter v0.0.5 // indirect
 	github.com/onsi/ginkgo/v2 v2.22.2 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect
@@ -259,7 +259,7 @@ require (
 	github.com/quic-go/quic-go v0.48.2 // indirect
 	github.com/raeperd/recvcheck v0.2.0 // indirect
 	github.com/rivo/uniseg v0.4.7 // indirect
-	github.com/rogpeppe/go-internal v1.13.1 // indirect
+	github.com/rogpeppe/go-internal v1.14.1 // indirect
 	github.com/rs/cors v1.11.1 // indirect
 	github.com/rubenv/sql-migrate v1.7.1 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -280,7 +280,7 @@ require (
 	github.com/sourcegraph/go-diff v0.7.0 // indirect
 	github.com/spf13/afero v1.12.0 // indirect
 	github.com/spf13/cast v1.7.0 // indirect
-	github.com/spf13/cobra v1.8.1 // indirect
+	github.com/spf13/cobra v1.9.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
 	github.com/spf13/viper v1.12.0 // indirect
@@ -290,8 +290,8 @@ require (
 	github.com/stretchr/objx v0.5.2 // indirect
 	github.com/stretchr/testify v1.10.0 // indirect
 	github.com/subosito/gotenv v1.4.1 // indirect
-	github.com/tdakkota/asciicheck v0.4.0 // indirect
-	github.com/tetafro/godot v1.4.20 // indirect
+	github.com/tdakkota/asciicheck v0.4.1 // indirect
+	github.com/tetafro/godot v1.5.0 // indirect
 	github.com/tetratelabs/wazero v1.8.2 // indirect
 	github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 // indirect
 	github.com/timonwong/loggercheck v0.10.1 // indirect
@@ -329,16 +329,16 @@ require (
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.27.0 // indirect
 	go.uber.org/zap/exp v0.3.0 // indirect
-	golang.org/x/crypto v0.33.0 // indirect
+	golang.org/x/crypto v0.36.0 // indirect
 	golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
 	golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
-	golang.org/x/mod v0.23.0 // indirect
-	golang.org/x/net v0.35.0 // indirect
+	golang.org/x/mod v0.24.0 // indirect
+	golang.org/x/net v0.37.0 // indirect
 	golang.org/x/oauth2 v0.25.0 // indirect
-	golang.org/x/sync v0.11.0 // indirect
-	golang.org/x/sys v0.30.0 // indirect
-	golang.org/x/term v0.29.0 // indirect
-	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/sync v0.12.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/term v0.30.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 	golang.org/x/time v0.9.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect
diff --git a/hack/tools/go.sum b/hack/tools/go.sum
index 4c6df7c1..5ca45458 100644
--- a/hack/tools/go.sum
+++ b/hack/tools/go.sum
@@ -1,5 +1,5 @@
-4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA=
-4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
+4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A=
+4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
 4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=
 4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
 buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.3-20241031151143-70f632351282.1 h1:dS5ier+mttGuW+lRLP/eC1CKJm2Rg3rKWy9Iy0hroIU=
@@ -29,8 +29,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
 dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
 filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
 filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
-github.com/4meepo/tagalign v1.4.1 h1:GYTu2FaPGOGb/xJalcqHeD4il5BiCywyEYZOA55P6J4=
-github.com/4meepo/tagalign v1.4.1/go.mod h1:2H9Yu6sZ67hmuraFgfZkNcg5Py9Ch/Om9l2K/2W1qS4=
+github.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E=
+github.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI=
 github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE=
 github.com/Abirdcfly/dupword v0.1.3/go.mod h1:8VbB2t7e10KRNdwTVoxdBaxla6avbhGzb8sCTygUMhw=
 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
@@ -52,8 +52,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7Oputl
 github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
 github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
-github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU=
-github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao=
+github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k=
+github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1/go.mod h1:n/LSCXNuIYqVfBlVXyHfMQkZDdp1/mmxfSjADd3z1Zg=
 github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
 github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
 github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
@@ -136,8 +136,8 @@ github.com/butuzov/ireturn v0.3.1 h1:mFgbEI6m+9W8oP/oDdfA34dLisRFCj2G6o/yiI1yZrY
 github.com/butuzov/ireturn v0.3.1/go.mod h1:ZfRp+E7eJLC0NQmk1Nrm1LOrn/gQlOykv+cVPdiXH5M=
 github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
 github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
-github.com/catenacyber/perfsprint v0.8.1 h1:bGOHuzHe0IkoGeY831RW4aSlt1lPRd3WRAScSWOaV7E=
-github.com/catenacyber/perfsprint v0.8.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50=
+github.com/catenacyber/perfsprint v0.8.2 h1:+o9zVmCSVa7M4MvabsWvESEhpsMkhfE7k0sHNGL95yw=
+github.com/catenacyber/perfsprint v0.8.2/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM=
 github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
 github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
 github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
@@ -184,7 +184,6 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
 github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
 github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
 github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -352,8 +351,8 @@ github.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUP
 github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=
 github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=
 github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
-github.com/golangci/golangci-lint v1.64.5 h1:5omC86XFBKXZgCrVdUWU+WNHKd+CWCxNx717KXnzKZY=
-github.com/golangci/golangci-lint v1.64.5/go.mod h1:WZnwq8TF0z61h3jLQ7Sk5trcP7b3kUFxLD6l1ivtdvU=
+github.com/golangci/golangci-lint v1.64.6 h1:jOLaQN41IV7bMzXuNC4UnQGll7N1xY6eFDXkXEPGKAs=
+github.com/golangci/golangci-lint v1.64.6/go.mod h1:Wz9q+6EVuqGQ94GQ96RB2mjpcZYTOGhBhbt4O7REPu4=
 github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
 github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo=
 github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c=
@@ -382,8 +381,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
 github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -409,8 +408,9 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
 github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
 github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
 github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
-github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q=
 github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
+github.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8=
+github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=
 github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk=
 github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
 github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=
@@ -475,11 +475,11 @@ github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx
 github.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyxI4SVplLd2CI=
 github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg=
-github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ=
+github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M=
+github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg=
-github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA=
+github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE=
+github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
 github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
 github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
 github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
@@ -505,8 +505,8 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhR
 github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
 github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=
 github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
-github.com/ldez/exptostd v0.4.1 h1:DIollgQ3LWZMp3HJbSXsdE2giJxMfjyHj3eX4oiD6JU=
-github.com/ldez/exptostd v0.4.1/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ=
+github.com/ldez/exptostd v0.4.2 h1:l5pOzHBz8mFOlbcifTxzfyYbgEmoUqjxLFHZkjlbHXs=
+github.com/ldez/exptostd v0.4.2/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ=
 github.com/ldez/gomoddirectives v0.6.1 h1:Z+PxGAY+217f/bSGjNZr/b2KTXcyYLgiWI6geMBN2Qc=
 github.com/ldez/gomoddirectives v0.6.1/go.mod h1:cVBiu3AHR9V31em9u2kwfMKD43ayN5/XDgr+cdaFaKs=
 github.com/ldez/grignotin v0.9.0 h1:MgOEmjZIVNn6p5wPaGp/0OKWyvq42KnzAt/DAb8O4Ow=
@@ -548,8 +548,8 @@ github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL
 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/mgechev/revive v1.6.1 h1:ncK0ZCMWtb8GXwVAmk+IeWF2ULIDsvRxSRfg5sTwQ2w=
-github.com/mgechev/revive v1.6.1/go.mod h1:/2tfHWVO8UQi/hqJsIYNEKELi+DJy/e+PQpLgTB1v88=
+github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY=
+github.com/mgechev/revive v1.7.0/go.mod h1:qZnwcNhoguE58dfi96IJeSTPeZQejNeoMQLUZGi4SW4=
 github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
 github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
 github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
@@ -608,8 +608,8 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK
 github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
 github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
 github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
-github.com/nunnatsa/ginkgolinter v0.19.0 h1:CnHRFAeBS3LdLI9h+Jidbcc5KH71GKOmaBZQk8Srnto=
-github.com/nunnatsa/ginkgolinter v0.19.0/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s=
+github.com/nunnatsa/ginkgolinter v0.19.1 h1:mjwbOlDQxZi9Cal+KfbEJTCz327OLNfwNvoZ70NJ+c4=
+github.com/nunnatsa/ginkgolinter v0.19.1/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s=
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
@@ -698,8 +698,8 @@ github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtz
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
 github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
 github.com/rubenv/sql-migrate v1.7.1 h1:f/o0WgfO/GqNuVg+6801K/KW3WdDSupzSjDYODmiUq4=
@@ -745,8 +745,8 @@ github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
 github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
 github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
 github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -780,14 +780,14 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
 github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
-github.com/tdakkota/asciicheck v0.4.0 h1:VZ13Itw4k1i7d+dpDSNS8Op645XgGHpkCEh/WHicgWw=
-github.com/tdakkota/asciicheck v0.4.0/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
+github.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8=
+github.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
 github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
 github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
 github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
 github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
-github.com/tetafro/godot v1.4.20 h1:z/p8Ek55UdNvzt4TFn2zx2KscpW4rWqcnUrdmvWJj7E=
-github.com/tetafro/godot v1.4.20/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
+github.com/tetafro/godot v1.5.0 h1:aNwfVI4I3+gdxjMgYPus9eHmoBeJIbnajOyqZYStzuw=
+github.com/tetafro/godot v1.5.0/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
 github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
 github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
 github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 h1:y4mJRFlM6fUyPhoXuFg/Yu02fg/nIPFMOY8tOqppoFg=
@@ -897,8 +897,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
-golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
-golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
@@ -920,8 +920,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
-golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
+golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -944,8 +944,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
-golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
 golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
@@ -961,8 +961,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
-golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -992,8 +992,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
-golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -1002,8 +1002,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
-golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
-golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
+golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
+golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -1014,8 +1014,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
-golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
 golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1042,8 +1042,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
 golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
-golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
-golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
+golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
+golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/internal/api/finalizers.go b/internal/api/finalizers.go
index 58024786..3947d0fd 100644
--- a/internal/api/finalizers.go
+++ b/internal/api/finalizers.go
@@ -84,6 +84,12 @@ func patchAnnotation(ctx context.Context, c client.Client, obj client.Object, ke
 	})
 }
 
+func deleteAnnotation(ctx context.Context, c client.Client, obj client.Object, key string) error {
+	return patchAnnotations(ctx, c, obj, map[string]*string{
+		key: nil,
+	})
+}
+
 func patchAnnotations(
 	ctx context.Context,
 	c client.Client,
diff --git a/internal/api/stage.go b/internal/api/stage.go
index 692e699b..9444f077 100644
--- a/internal/api/stage.go
+++ b/internal/api/stage.go
@@ -2,6 +2,7 @@ package api
 
 import (
 	"context"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"slices"
@@ -126,6 +127,54 @@ func RefreshStage(
 	return stage, nil
 }
 
+// AnnotateStageWithArgoCDContext annotates a Stage with the ArgoCD context
+// necessary for the frontend to display ArgoCD information for the Stage.
+//
+// The annotation value is a JSON-encoded list of ArgoCD apps that are
+// associated with the Stage, constructed from the HealthCheckSteps from
+// the latest Promotion.
+//
+// If no ArgoCD apps are found, the annotation is removed.
+func AnnotateStageWithArgoCDContext(
+	ctx context.Context,
+	c client.Client,
+	healthChecks []kargoapi.HealthCheckStep,
+	stage *kargoapi.Stage,
+) error {
+	var argoCDApps []map[string]any
+	for _, healthCheck := range healthChecks {
+		healthCheckConfig := healthCheck.GetConfig()
+
+		appsList, ok := healthCheckConfig["apps"].([]any)
+		if !ok {
+			continue
+		}
+
+		for _, rawApp := range appsList {
+			appConfig, ok := rawApp.(map[string]any)
+			if !ok {
+				continue
+			}
+			argoCDApps = append(argoCDApps, map[string]any{
+				"name":      appConfig["name"],
+				"namespace": appConfig["namespace"],
+			})
+		}
+	}
+
+	// If we did not find any ArgoCD apps, we should remove the annotation.
+	if len(argoCDApps) == 0 {
+		return deleteAnnotation(ctx, c, stage, kargoapi.AnnotationKeyArgoCDContext)
+	}
+
+	// Marshal the ArgoCD context to JSON and set the annotation on the Stage.
+	argoCDAppsJSON, err := json.Marshal(argoCDApps)
+	if err != nil {
+		return fmt.Errorf("failed to marshal ArgoCD context: %w", err)
+	}
+	return patchAnnotation(ctx, c, stage, kargoapi.AnnotationKeyArgoCDContext, string(argoCDAppsJSON))
+}
+
 // ReverifyStageFreight forces reconfirmation of the verification of the
 // Freight associated with a Stage by setting an AnnotationKeyReverify
 // annotation on the Stage, causing the controller to rerun the verification.
diff --git a/internal/controller/rollouts/api/v1alpha1/analysis_helpers.go b/internal/api/stubs/rollouts/analysis.go
similarity index 83%
rename from internal/controller/rollouts/api/v1alpha1/analysis_helpers.go
rename to internal/api/stubs/rollouts/analysis.go
index 4d8e5f56..c8922223 100644
--- a/internal/controller/rollouts/api/v1alpha1/analysis_helpers.go
+++ b/internal/api/stubs/rollouts/analysis.go
@@ -1,4 +1,4 @@
-package v1alpha1
+package rollouts
 
 import (
 	"context"
@@ -6,6 +6,8 @@ import (
 
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 // GetAnalysisTemplate returns a pointer to the AnalysisTemplate resource
@@ -15,8 +17,8 @@ func GetAnalysisTemplate(
 	ctx context.Context,
 	c client.Client,
 	namespacedName types.NamespacedName,
-) (*AnalysisTemplate, error) {
-	at := AnalysisTemplate{}
+) (*rolloutsapi.AnalysisTemplate, error) {
+	at := rolloutsapi.AnalysisTemplate{}
 	if err := c.Get(ctx, namespacedName, &at); err != nil {
 		if err = client.IgnoreNotFound(err); err == nil {
 			return nil, nil
@@ -38,8 +40,8 @@ func GetClusterAnalysisTemplate(
 	ctx context.Context,
 	c client.Client,
 	name string,
-) (*ClusterAnalysisTemplate, error) {
-	cat := ClusterAnalysisTemplate{}
+) (*rolloutsapi.ClusterAnalysisTemplate, error) {
+	cat := rolloutsapi.ClusterAnalysisTemplate{}
 	if err := c.Get(
 		ctx,
 		types.NamespacedName{
@@ -63,8 +65,8 @@ func GetAnalysisRun(
 	ctx context.Context,
 	c client.Client,
 	namespacedName types.NamespacedName,
-) (*AnalysisRun, error) {
-	ar := AnalysisRun{}
+) (*rolloutsapi.AnalysisRun, error) {
+	ar := rolloutsapi.AnalysisRun{}
 	if err := c.Get(ctx, namespacedName, &ar); err != nil {
 		if err = client.IgnoreNotFound(err); err == nil {
 			return nil, nil
diff --git a/pkg/api/service/v1alpha1/types.go b/internal/api/version.go
similarity index 65%
rename from pkg/api/service/v1alpha1/types.go
rename to internal/api/version.go
index 16c54f1d..a6c2565a 100644
--- a/pkg/api/service/v1alpha1/types.go
+++ b/internal/api/version.go
@@ -1,13 +1,14 @@
-package svcv1alpha1
+package api
 
 import (
 	"google.golang.org/protobuf/types/known/timestamppb"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/pkg/x/version"
 )
 
-func ToVersionProto(v version.Version) *VersionInfo {
-	return &VersionInfo{
+func ToVersionProto(v version.Version) *svcv1alpha1.VersionInfo {
+	return &svcv1alpha1.VersionInfo{
 		Version:      v.Version,
 		GitCommit:    v.GitCommit,
 		GitTreeDirty: v.GitTreeDirty,
diff --git a/internal/cli/client/client.go b/internal/cli/client/client.go
index 2d290765..78257502 100644
--- a/internal/cli/client/client.go
+++ b/internal/cli/client/client.go
@@ -10,9 +10,9 @@ import (
 	"github.com/hashicorp/go-cleanhttp"
 	"github.com/spf13/pflag"
 
+	"github.com/akuity/kargo/api/service/v1alpha1/svcv1alpha1connect"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/option"
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 type Options struct {
diff --git a/internal/cli/client/token_refresher.go b/internal/cli/client/token_refresher.go
index 32c3061a..59ff7d4a 100644
--- a/internal/cli/client/token_refresher.go
+++ b/internal/cli/client/token_refresher.go
@@ -11,8 +11,8 @@ import (
 	"github.com/golang-jwt/jwt/v5"
 	"golang.org/x/oauth2"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/config"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 // tokenRefresher is a component that helps to refresh tokens.
diff --git a/internal/cli/cmd/apply/apply.go b/internal/cli/cmd/apply/apply.go
index 2b906f5b..787f9861 100644
--- a/internal/cli/cmd/apply/apply.go
+++ b/internal/cli/cmd/apply/apply.go
@@ -13,13 +13,13 @@ import (
 	"k8s.io/cli-runtime/pkg/printers"
 	sigyaml "sigs.k8s.io/yaml"
 
+	kargosvcapi "github.com/akuity/kargo/api/service/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"
-	kargosvcapi "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type applyOptions struct {
diff --git a/internal/cli/cmd/approve/approve.go b/internal/cli/cmd/approve/approve.go
index 43721b92..bddf938a 100644
--- a/internal/cli/cmd/approve/approve.go
+++ b/internal/cli/cmd/approve/approve.go
@@ -8,11 +8,11 @@ import (
 	"connectrpc.com/connect"
 	"github.com/spf13/cobra"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type approvalOptions struct {
diff --git a/internal/cli/cmd/create/create.go b/internal/cli/cmd/create/create.go
index 657b614c..7e741bc0 100644
--- a/internal/cli/cmd/create/create.go
+++ b/internal/cli/cmd/create/create.go
@@ -12,13 +12,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 	sigyaml "sigs.k8s.io/yaml"
 
+	kargosvcapi "github.com/akuity/kargo/api/service/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"
-	kargosvcapi "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type createOptions struct {
diff --git a/internal/cli/cmd/create/credentials.go b/internal/cli/cmd/create/credentials.go
index 8bbcb99e..18e86e84 100644
--- a/internal/cli/cmd/create/credentials.go
+++ b/internal/cli/cmd/create/credentials.go
@@ -11,6 +11,7 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/io"
@@ -18,7 +19,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
 	"github.com/akuity/kargo/internal/credentials"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type createCredentialsOptions struct {
diff --git a/internal/cli/cmd/create/project.go b/internal/cli/cmd/create/project.go
index 58f3056a..ffa3fca8 100644
--- a/internal/cli/cmd/create/project.go
+++ b/internal/cli/cmd/create/project.go
@@ -13,6 +13,7 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 	sigyaml "sigs.k8s.io/yaml"
 
+	kargosvcapi "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"
@@ -20,7 +21,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	kargosvcapi "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type createProjectOptions struct {
diff --git a/internal/cli/cmd/create/role.go b/internal/cli/cmd/create/role.go
index 40441538..f1a25760 100644
--- a/internal/cli/cmd/create/role.go
+++ b/internal/cli/cmd/create/role.go
@@ -13,13 +13,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	kargosvcapi "github.com/akuity/kargo/api/service/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"
-	kargosvcapi "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type createRoleOptions struct {
diff --git a/internal/cli/cmd/delete/credentials.go b/internal/cli/cmd/delete/credentials.go
index 274c0ad9..c203163c 100644
--- a/internal/cli/cmd/delete/credentials.go
+++ b/internal/cli/cmd/delete/credentials.go
@@ -13,13 +13,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/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"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type deleteCredentialsOptions struct {
diff --git a/internal/cli/cmd/delete/delete.go b/internal/cli/cmd/delete/delete.go
index 2838f833..68a5f4fd 100644
--- a/internal/cli/cmd/delete/delete.go
+++ b/internal/cli/cmd/delete/delete.go
@@ -12,13 +12,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 	sigyaml "sigs.k8s.io/yaml"
 
+	kargosvcapi "github.com/akuity/kargo/api/service/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"
-	kargosvcapi "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type deleteOptions struct {
diff --git a/internal/cli/cmd/delete/project.go b/internal/cli/cmd/delete/project.go
index 14615cca..c3a3dcc6 100644
--- a/internal/cli/cmd/delete/project.go
+++ b/internal/cli/cmd/delete/project.go
@@ -12,6 +12,7 @@ import (
 	"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"
@@ -19,7 +20,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type deleteProjectOptions struct {
diff --git a/internal/cli/cmd/delete/role.go b/internal/cli/cmd/delete/role.go
index de2d71a9..07fd642d 100644
--- a/internal/cli/cmd/delete/role.go
+++ b/internal/cli/cmd/delete/role.go
@@ -13,13 +13,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	v1alpha1 "github.com/akuity/kargo/api/service/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"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type deleteRoleOptions struct {
diff --git a/internal/cli/cmd/delete/stage.go b/internal/cli/cmd/delete/stage.go
index 6058cd74..88262b48 100644
--- a/internal/cli/cmd/delete/stage.go
+++ b/internal/cli/cmd/delete/stage.go
@@ -12,6 +12,7 @@ import (
 	"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"
@@ -19,7 +20,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type deleteStageOptions struct {
diff --git a/internal/cli/cmd/delete/warehouse.go b/internal/cli/cmd/delete/warehouse.go
index 1c0e7c13..db51d287 100644
--- a/internal/cli/cmd/delete/warehouse.go
+++ b/internal/cli/cmd/delete/warehouse.go
@@ -13,12 +13,12 @@ import (
 	"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/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type deleteWarehouseOptions struct {
diff --git a/internal/cli/cmd/get/credentials.go b/internal/cli/cmd/get/credentials.go
index 4f34b360..fc650612 100644
--- a/internal/cli/cmd/get/credentials.go
+++ b/internal/cli/cmd/get/credentials.go
@@ -15,6 +15,7 @@ import (
 	"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"
@@ -23,7 +24,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
 	libCreds "github.com/akuity/kargo/internal/credentials"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getCredentialsOptions struct {
diff --git a/internal/cli/cmd/get/freight.go b/internal/cli/cmd/get/freight.go
index fca9719a..5af7e8e4 100644
--- a/internal/cli/cmd/get/freight.go
+++ b/internal/cli/cmd/get/freight.go
@@ -13,6 +13,7 @@ import (
 	"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"
@@ -20,7 +21,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getFreightOptions struct {
diff --git a/internal/cli/cmd/get/projects.go b/internal/cli/cmd/get/projects.go
index 3a250399..0f8330f9 100644
--- a/internal/cli/cmd/get/projects.go
+++ b/internal/cli/cmd/get/projects.go
@@ -14,6 +14,7 @@ import (
 	"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"
@@ -21,7 +22,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/templates"
 	"github.com/akuity/kargo/internal/conditions"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getProjectsOptions struct {
diff --git a/internal/cli/cmd/get/promotions.go b/internal/cli/cmd/get/promotions.go
index 69bb4732..96f5cff3 100644
--- a/internal/cli/cmd/get/promotions.go
+++ b/internal/cli/cmd/get/promotions.go
@@ -14,6 +14,7 @@ import (
 	"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"
@@ -21,7 +22,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getPromotionsOptions struct {
diff --git a/internal/cli/cmd/get/roles.go b/internal/cli/cmd/get/roles.go
index 2fb1fb3c..b6ce416e 100644
--- a/internal/cli/cmd/get/roles.go
+++ b/internal/cli/cmd/get/roles.go
@@ -16,13 +16,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	v1alpha1 "github.com/akuity/kargo/api/service/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"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getRolesOptions struct {
diff --git a/internal/cli/cmd/get/stages.go b/internal/cli/cmd/get/stages.go
index 2efd220a..ee66feeb 100644
--- a/internal/cli/cmd/get/stages.go
+++ b/internal/cli/cmd/get/stages.go
@@ -14,6 +14,7 @@ import (
 	"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"
@@ -21,7 +22,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getStagesOptions struct {
diff --git a/internal/cli/cmd/get/warehouse.go b/internal/cli/cmd/get/warehouse.go
index 65df3044..7a06ed6b 100644
--- a/internal/cli/cmd/get/warehouse.go
+++ b/internal/cli/cmd/get/warehouse.go
@@ -14,6 +14,7 @@ import (
 	"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"
@@ -21,7 +22,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type getWarehousesOptions struct {
diff --git a/internal/cli/cmd/grant/grant.go b/internal/cli/cmd/grant/grant.go
index 15b2fbbe..4177500f 100644
--- a/internal/cli/cmd/grant/grant.go
+++ b/internal/cli/cmd/grant/grant.go
@@ -12,13 +12,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type grantOptions struct {
diff --git a/internal/cli/cmd/login/login.go b/internal/cli/cmd/login/login.go
index 3eeb10a4..88b67c85 100644
--- a/internal/cli/cmd/login/login.go
+++ b/internal/cli/cmd/login/login.go
@@ -25,12 +25,12 @@ import (
 	"k8s.io/utils/strings/slices"
 	"sigs.k8s.io/controller-runtime/pkg/client/config"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	libConfig "github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
 	"github.com/akuity/kargo/internal/kubeclient"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 const defaultRandStringCharSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
diff --git a/internal/cli/cmd/promote/promote.go b/internal/cli/cmd/promote/promote.go
index b08bf087..cb638895 100644
--- a/internal/cli/cmd/promote/promote.go
+++ b/internal/cli/cmd/promote/promote.go
@@ -11,6 +11,8 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
+	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/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
@@ -18,8 +20,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/kubernetes"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 type promotionOptions struct {
diff --git a/internal/cli/cmd/refresh/refresh.go b/internal/cli/cmd/refresh/refresh.go
index e4216915..5385a8f6 100644
--- a/internal/cli/cmd/refresh/refresh.go
+++ b/internal/cli/cmd/refresh/refresh.go
@@ -9,11 +9,11 @@ import (
 	"connectrpc.com/connect"
 	"github.com/spf13/cobra"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 const (
diff --git a/internal/cli/cmd/refresh/stage.go b/internal/cli/cmd/refresh/stage.go
index df04be05..9e579715 100644
--- a/internal/cli/cmd/refresh/stage.go
+++ b/internal/cli/cmd/refresh/stage.go
@@ -8,13 +8,13 @@ import (
 	"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"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 func newRefreshStageCommand(cfg config.CLIConfig) *cobra.Command {
diff --git a/internal/cli/cmd/refresh/warehouse.go b/internal/cli/cmd/refresh/warehouse.go
index 4745a622..8cc35a7f 100644
--- a/internal/cli/cmd/refresh/warehouse.go
+++ b/internal/cli/cmd/refresh/warehouse.go
@@ -8,13 +8,13 @@ import (
 	"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"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 func newRefreshWarehouseCommand(cfg config.CLIConfig) *cobra.Command {
diff --git a/internal/cli/cmd/revoke/revoke.go b/internal/cli/cmd/revoke/revoke.go
index 0291c977..da576809 100644
--- a/internal/cli/cmd/revoke/revoke.go
+++ b/internal/cli/cmd/revoke/revoke.go
@@ -12,13 +12,13 @@ import (
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type revokeOptions struct {
diff --git a/internal/cli/cmd/update/credentials.go b/internal/cli/cmd/update/credentials.go
index c6122adb..d80f1c2f 100644
--- a/internal/cli/cmd/update/credentials.go
+++ b/internal/cli/cmd/update/credentials.go
@@ -11,6 +11,7 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/io"
@@ -18,7 +19,6 @@ import (
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
 	"github.com/akuity/kargo/internal/credentials"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type updateCredentialsOptions struct {
diff --git a/internal/cli/cmd/update/freight.go b/internal/cli/cmd/update/freight.go
index 16337019..25556143 100644
--- a/internal/cli/cmd/update/freight.go
+++ b/internal/cli/cmd/update/freight.go
@@ -8,11 +8,11 @@ import (
 	"connectrpc.com/connect"
 	"github.com/spf13/cobra"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type updateFreightAliasOptions struct {
diff --git a/internal/cli/cmd/verify/stage.go b/internal/cli/cmd/verify/stage.go
index 62088d9f..8919b79e 100644
--- a/internal/cli/cmd/verify/stage.go
+++ b/internal/cli/cmd/verify/stage.go
@@ -9,11 +9,11 @@ import (
 	"connectrpc.com/connect"
 	"github.com/spf13/cobra"
 
+	v1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/cli/client"
 	"github.com/akuity/kargo/internal/cli/config"
 	"github.com/akuity/kargo/internal/cli/option"
 	"github.com/akuity/kargo/internal/cli/templates"
-	v1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type verifyStageOptions struct {
diff --git a/internal/cli/cmd/version/version.go b/internal/cli/cmd/version/version.go
index e3f7bd3b..4fbd4026 100644
--- a/internal/cli/cmd/version/version.go
+++ b/internal/cli/cmd/version/version.go
@@ -13,14 +13,15 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/cli-runtime/pkg/genericiooptions"
 
+	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/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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 	versionpkg "github.com/akuity/kargo/pkg/x/version"
 )
 
@@ -78,7 +79,7 @@ func (o *versionOptions) addFlags(cmd *cobra.Command) {
 func (o *versionOptions) run(ctx context.Context) error {
 	printToStdout := o.PrintFlags.OutputFlagSpecified == nil || !o.PrintFlags.OutputFlagSpecified()
 
-	cliVersion := svcv1alpha1.ToVersionProto(versionpkg.GetVersion())
+	cliVersion := api.ToVersionProto(versionpkg.GetVersion())
 	if printToStdout {
 		_, _ = fmt.Fprintln(o.IOStreams.Out, "Client Version:", cliVersion.GetVersion())
 	}
diff --git a/internal/controller/management/projects/projects.go b/internal/controller/management/projects/projects.go
index f0dc8ec4..0eaecd18 100644
--- a/internal/controller/management/projects/projects.go
+++ b/internal/controller/management/projects/projects.go
@@ -20,11 +20,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/predicate"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/internal/conditions"
 	"github.com/akuity/kargo/internal/controller"
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/kubeclient"
 	"github.com/akuity/kargo/internal/logging"
 )
diff --git a/internal/controller/stages/control_flow_stages.go b/internal/controller/stages/control_flow_stages.go
index 32fa1e69..fb692c73 100644
--- a/internal/controller/stages/control_flow_stages.go
+++ b/internal/controller/stages/control_flow_stages.go
@@ -15,10 +15,10 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/predicate"
 	"sigs.k8s.io/controller-runtime/pkg/source"
 
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/internal/controller"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/indexer"
 	"github.com/akuity/kargo/internal/kargo"
 	"github.com/akuity/kargo/internal/kubeclient"
@@ -215,6 +215,14 @@ func (r *ControlFlowStageReconciler) Reconcile(ctx context.Context, req ctrl.Req
 		return ctrl.Result{Requeue: ok}, err
 	}
 
+	// Remove any stale annotations from the Stage which are not relevant to
+	// a control flow Stage.
+	if stage.GetAnnotations()[kargoapi.AnnotationKeyArgoCDContext] != "" {
+		if err := api.AnnotateStageWithArgoCDContext(ctx, r.client, nil, stage); err != nil {
+			logger.Error(err, "failed to remove Argo CD context annotation from Stage")
+		}
+	}
+
 	// Reconcile the Stage.
 	logger.Debug("reconciling Stage")
 	newStatus, reconcileErr := r.reconcile(ctx, stage, time.Now())
diff --git a/internal/controller/stages/event_handlers.go b/internal/controller/stages/event_handlers.go
index 67acc5e1..622ebae4 100644
--- a/internal/controller/stages/event_handlers.go
+++ b/internal/controller/stages/event_handlers.go
@@ -14,9 +14,9 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/event"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	argocd "github.com/akuity/kargo/internal/controller/argocd/api/v1alpha1"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/indexer"
 	"github.com/akuity/kargo/internal/logging"
 )
diff --git a/internal/controller/stages/regular_stages.go b/internal/controller/stages/regular_stages.go
index acfe1080..ed95de3d 100644
--- a/internal/controller/stages/regular_stages.go
+++ b/internal/controller/stages/regular_stages.go
@@ -27,12 +27,12 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/predicate"
 	"sigs.k8s.io/controller-runtime/pkg/source"
 
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/internal/conditions"
 	"github.com/akuity/kargo/internal/controller"
 	argocdapi "github.com/akuity/kargo/internal/controller/argocd/api/v1alpha1"
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/directives"
 	kargoEvent "github.com/akuity/kargo/internal/event"
 	exprfn "github.com/akuity/kargo/internal/expressions/function"
@@ -636,6 +636,18 @@ func (r *RegularStageReconciler) syncPromotions(
 					Message:            "Waiting for verification to be performed after successful promotion",
 					ObservedGeneration: stage.Generation,
 				})
+
+				// Annotate the Stage with the latest information related to
+				// ArgoCD Applications. This is used to provide deep links to the
+				// ArgoCD UI for the Stage in the Kargo UI.
+				//
+				// NB: If the health checks do not include ArgoCD Applications,
+				// then the annotation will be removed.
+				if err := api.AnnotateStageWithArgoCDContext(ctx, r.client, p.Status.HealthChecks, stage); err != nil {
+					// Let the error be logged, but do not return it as it is not
+					// critical to the operation of the Stage.
+					logger.Error(err, "failed to annotate Stage with ArgoCD context")
+				}
 			}
 		}
 
diff --git a/internal/controller/warehouses/git.go b/internal/controller/warehouses/git.go
index 52f9396c..9fe20eeb 100644
--- a/internal/controller/warehouses/git.go
+++ b/internal/controller/warehouses/git.go
@@ -65,7 +65,7 @@ func (r *reconciler) discoverCommits(
 		repoLogger := logger.WithValues("repo", sub.RepoURL)
 
 		// Obtain credentials for the Git repository.
-		creds, ok, err := r.credentialsDB.Get(ctx, namespace, credentials.TypeGit, sub.RepoURL)
+		creds, err := r.credentialsDB.Get(ctx, namespace, credentials.TypeGit, sub.RepoURL)
 		if err != nil {
 			return nil, fmt.Errorf(
 				"error obtaining credentials for git repo %q: %w",
@@ -74,7 +74,7 @@ func (r *reconciler) discoverCommits(
 			)
 		}
 		var repoCreds *git.RepoCredentials
-		if ok {
+		if creds != nil {
 			repoCreds = &git.RepoCredentials{
 				Username:      creds.Username,
 				Password:      creds.Password,
diff --git a/internal/controller/warehouses/helm.go b/internal/controller/warehouses/helm.go
index f420b243..6d2639f1 100644
--- a/internal/controller/warehouses/helm.go
+++ b/internal/controller/warehouses/helm.go
@@ -29,7 +29,7 @@ func (r *reconciler) discoverCharts(
 			logger = logger.WithValues("chart", sub.Name)
 		}
 
-		creds, ok, err := r.credentialsDB.Get(ctx, namespace, credentials.TypeHelm, sub.RepoURL)
+		creds, err := r.credentialsDB.Get(ctx, namespace, credentials.TypeHelm, sub.RepoURL)
 		if err != nil {
 			return nil, fmt.Errorf(
 				"error obtaining credentials for chart repository %q: %w",
@@ -38,7 +38,7 @@ func (r *reconciler) discoverCharts(
 			)
 		}
 		var helmCreds *helm.Credentials
-		if ok {
+		if creds != nil {
 			helmCreds = &helm.Credentials{
 				Username: creds.Username,
 				Password: creds.Password,
diff --git a/internal/controller/warehouses/images.go b/internal/controller/warehouses/images.go
index e42bacad..78394dec 100644
--- a/internal/controller/warehouses/images.go
+++ b/internal/controller/warehouses/images.go
@@ -33,7 +33,7 @@ func (r *reconciler) discoverImages(
 		logger := logging.LoggerFromContext(ctx).WithValues("repo", sub.RepoURL)
 
 		// Obtain credentials for the image repository.
-		creds, ok, err := r.credentialsDB.Get(ctx, namespace, credentials.TypeImage, sub.RepoURL)
+		creds, err := r.credentialsDB.Get(ctx, namespace, credentials.TypeImage, sub.RepoURL)
 		if err != nil {
 			return nil, fmt.Errorf(
 				"error obtaining credentials for image repo %q: %w",
@@ -42,7 +42,7 @@ func (r *reconciler) discoverImages(
 			)
 		}
 		var regCreds *image.Credentials
-		if ok {
+		if creds != nil {
 			regCreds = &image.Credentials{
 				Username: creds.Username,
 				Password: creds.Password,
diff --git a/internal/credentials/credentials.go b/internal/credentials/credentials.go
index ee0cfd7b..90c81bda 100644
--- a/internal/credentials/credentials.go
+++ b/internal/credentials/credentials.go
@@ -2,8 +2,6 @@ package credentials
 
 import (
 	"context"
-
-	corev1 "k8s.io/api/core/v1"
 )
 
 const (
@@ -43,10 +41,22 @@ type Credentials struct {
 	SSHPrivateKey string
 }
 
-type Helper func(
-	ctx context.Context,
-	project string,
-	credType Type,
-	repoURL string,
-	secret *corev1.Secret,
-) (*Credentials, error)
+// Provider is an interface for providing credentials for a given type,
+// repository URL and data values.
+type Provider interface {
+	// Supports returns true if the provider can provide credentials for the
+	// given type, repository URL and data values. Otherwise, it should return
+	// false.
+	Supports(credType Type, repoURL string, data map[string][]byte) bool
+
+	// GetCredentials returns the credentials for the given type, repository URL
+	// and data values. If the provider cannot provide credentials for the given
+	// type, repository URL and data, it should return nil.
+	GetCredentials(
+		ctx context.Context,
+		project string,
+		credType Type,
+		repoURL string,
+		data map[string][]byte,
+	) (*Credentials, error)
+}
diff --git a/internal/credentials/database.go b/internal/credentials/database.go
index f46461e5..0e52e5ee 100644
--- a/internal/credentials/database.go
+++ b/internal/credentials/database.go
@@ -9,7 +9,7 @@ type Database interface {
 		namespace string,
 		credType Type,
 		repo string,
-	) (Credentials, bool, error)
+	) (*Credentials, error)
 }
 
 // FakeDB is a mock implementation of the Database interface that is used to
@@ -20,7 +20,7 @@ type FakeDB struct {
 		namespace string,
 		credType Type,
 		repo string,
-	) (Credentials, bool, error)
+	) (*Credentials, error)
 }
 
 func (f *FakeDB) Get(
@@ -28,9 +28,9 @@ func (f *FakeDB) Get(
 	namespace string,
 	credType Type,
 	repo string,
-) (Credentials, bool, error) {
+) (*Credentials, error) {
 	if f.GetFn == nil {
-		return Credentials{}, false, nil
+		return nil, nil
 	}
 	return f.GetFn(ctx, namespace, credType, repo)
 }
diff --git a/internal/credentials/kubernetes/basic/basic.go b/internal/credentials/kubernetes/basic/basic.go
index d8b7e3cb..8cea568e 100644
--- a/internal/credentials/kubernetes/basic/basic.go
+++ b/internal/credentials/kubernetes/basic/basic.go
@@ -3,29 +3,40 @@ package basic
 import (
 	"context"
 
-	corev1 "k8s.io/api/core/v1"
-
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-// SecretToCreds is an implementation of credentials.Helper that simply extracts
-// a username, password, and SSH private key from a secret.
-func SecretToCreds(
+const (
+	usernameKey   = "username"
+	passwordKey   = "password"
+	sshPrivateKey = "sshPrivateKey"
+)
+
+type CredentialProvider struct{}
+
+func (*CredentialProvider) Supports(
+	_ credentials.Type, _ string, data map[string][]byte,
+) bool {
+	return len(data) > 0 &&
+		(data[usernameKey] != nil && data[passwordKey] != nil) ||
+		data[sshPrivateKey] != nil
+}
+
+func (p *CredentialProvider) GetCredentials(
 	_ context.Context,
 	_ string,
-	_ credentials.Type,
-	_ string,
-	secret *corev1.Secret,
+	credType credentials.Type,
+	repoURL string,
+	data map[string][]byte,
 ) (*credentials.Credentials, error) {
-	if secret == nil {
-		// This helper can't handle this
+	if !p.Supports(credType, repoURL, data) {
 		return nil, nil
 	}
 
 	creds := &credentials.Credentials{
-		Username:      string(secret.Data["username"]),
-		Password:      string(secret.Data["password"]),
-		SSHPrivateKey: string(secret.Data["sshPrivateKey"]),
+		Username:      string(data[usernameKey]),
+		Password:      string(data[passwordKey]),
+		SSHPrivateKey: string(data[sshPrivateKey]),
 	}
 	if (creds.Username != "" && creds.Password != "") ||
 		creds.SSHPrivateKey != "" {
diff --git a/internal/credentials/kubernetes/database.go b/internal/credentials/kubernetes/database.go
index 436ef844..6d7bb307 100644
--- a/internal/credentials/kubernetes/database.go
+++ b/internal/credentials/kubernetes/database.go
@@ -6,6 +6,7 @@ import (
 	"slices"
 	"strings"
 
+	"github.com/davecgh/go-spew/spew"
 	"github.com/kelseyhightower/envconfig"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/labels"
@@ -26,9 +27,9 @@ import (
 // utilizes a Kubernetes controller runtime client to retrieve credentials
 // stored in Kubernetes Secrets.
 type database struct {
-	kargoClient       client.Client
-	credentialHelpers []credentials.Helper
-	cfg               DatabaseConfig
+	kargoClient         client.Client
+	credentialProviders []credentials.Provider
+	cfg                 DatabaseConfig
 }
 
 // DatabaseConfig represents configuration for a Kubernetes based implementation
@@ -53,25 +54,28 @@ func NewDatabase(
 	kargoClient client.Client,
 	cfg DatabaseConfig,
 ) credentials.Database {
-	credentialHelpers := []credentials.Helper{
-		basic.SecretToCreds,
-		ecr.NewAccessKeyCredentialHelper(),
-		ecr.NewManagedIdentityCredentialHelper(ctx),
-		gar.NewServiceAccountKeyCredentialHelper(),
-		gar.NewWorkloadIdentityFederationCredentialHelper(ctx),
-		github.NewAppCredentialHelper(),
+	var credentialProviders = []credentials.Provider{
+		&basic.CredentialProvider{},
+		ecr.NewAccessKeyProvider(),
+		ecr.NewManagedIdentityProvider(ctx),
+		gar.NewServiceAccountKeyProvider(),
+		gar.NewWorkloadIdentityFederationProvider(ctx),
+		github.NewAppCredentialProvider(),
 	}
-	finalCredentialHelpers := make([]credentials.Helper, 0, len(credentialHelpers))
-	for _, helper := range credentialHelpers {
-		if helper != nil {
-			finalCredentialHelpers = append(finalCredentialHelpers, helper)
-		}
+
+	db := &database{
+		kargoClient: kargoClient,
+		cfg:         cfg,
 	}
-	return &database{
-		kargoClient:       kargoClient,
-		credentialHelpers: finalCredentialHelpers,
-		cfg:               cfg,
+
+	for _, p := range credentialProviders {
+		if p != nil {
+			spew.Dump(p)
+			db.credentialProviders = append(db.credentialProviders, p)
+		}
 	}
+
+	return db
 }
 
 func (k *database) Get(
@@ -79,7 +83,7 @@ func (k *database) Get(
 	namespace string,
 	credType credentials.Type,
 	repoURL string,
-) (credentials.Credentials, bool, error) {
+) (*credentials.Credentials, error) {
 	// If we are dealing with an insecure HTTP endpoint (of any type),
 	// refuse to return any credentials
 	if !k.cfg.AllowCredentialsOverHTTP && strings.HasPrefix(repoURL, "http://") {
@@ -87,7 +91,7 @@ func (k *database) Get(
 			"refused to get credentials for insecure HTTP endpoint",
 			"repoURL", repoURL,
 		)
-		return credentials.Credentials{}, false, nil
+		return nil, nil
 	}
 
 	var secret *corev1.Secret
@@ -100,7 +104,7 @@ func (k *database) Get(
 		credType,
 		repoURL,
 	); err != nil {
-		return credentials.Credentials{}, false, err
+		return nil, err
 	}
 
 	if secret == nil {
@@ -112,7 +116,7 @@ func (k *database) Get(
 				credType,
 				repoURL,
 			); err != nil {
-				return credentials.Credentials{}, false, err
+				return nil, err
 			}
 			if secret != nil {
 				break
@@ -120,17 +124,22 @@ func (k *database) Get(
 		}
 	}
 
-	for _, helper := range k.credentialHelpers {
-		creds, err := helper(ctx, namespace, credType, repoURL, secret)
+	var data map[string][]byte
+	if secret != nil {
+		data = secret.Data
+	}
+
+	for _, p := range k.credentialProviders {
+		creds, err := p.GetCredentials(ctx, namespace, credType, repoURL, data)
 		if err != nil {
-			return credentials.Credentials{}, false, err
+			return nil, err
 		}
 		if creds != nil {
-			return *creds, true, nil
+			return creds, nil
 		}
 	}
 
-	return credentials.Credentials{}, false, nil
+	return nil, nil
 }
 
 func (k *database) getCredentialsSecret(
diff --git a/internal/credentials/kubernetes/ecr/access_key.go b/internal/credentials/kubernetes/ecr/access_key.go
index d2edd008..a2171b89 100644
--- a/internal/credentials/kubernetes/ecr/access_key.go
+++ b/internal/credentials/kubernetes/ecr/access_key.go
@@ -2,7 +2,6 @@ package ecr
 
 import (
 	"context"
-	"crypto/sha256"
 	"encoding/base64"
 	"fmt"
 	"strings"
@@ -12,7 +11,6 @@ import (
 	awscreds "github.com/aws/aws-sdk-go-v2/credentials"
 	"github.com/aws/aws-sdk-go-v2/service/ecr"
 	"github.com/patrickmn/go-cache"
-	corev1 "k8s.io/api/core/v1"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
@@ -23,118 +21,101 @@ const (
 	secretKey = "awsSecretAccessKey"
 )
 
-type accessKeyCredentialHelper struct {
+type AccessKeyProvider struct {
 	tokenCache *cache.Cache
 
-	// The following behaviors are overridable for testing purposes:
-
-	getAuthTokenFn func(
-		ctx context.Context,
-		region string,
-		accessKeyID string,
-		secretAccessKey string,
-	) (string, error)
+	getAuthTokenFn func(ctx context.Context, region, accessKeyID, secretAccessKey string) (string, error)
 }
 
-// NewAccessKeyCredentialHelper returns an implementation of credentials.Helper
-// that utilizes a cache to avoid unnecessary calls to AWS.
-func NewAccessKeyCredentialHelper() credentials.Helper {
-	a := &accessKeyCredentialHelper{
+func NewAccessKeyProvider() credentials.Provider {
+	p := &AccessKeyProvider{
 		tokenCache: cache.New(
 			// Tokens live for 12 hours. We'll hang on to them for 10.
 			10*time.Hour, // Default ttl for each entry
 			time.Hour,    // Cleanup interval
 		),
 	}
-	a.getAuthTokenFn = a.getAuthToken
-	return a.getCredentials
+	p.getAuthTokenFn = p.getAuthToken
+	return p
 }
 
-func (a *accessKeyCredentialHelper) getCredentials(
-	ctx context.Context,
-	_ string,
-	credType credentials.Type,
-	repoURL string,
-	secret *corev1.Secret,
-) (*credentials.Credentials, error) {
-	if (credType != credentials.TypeImage && credType != credentials.TypeHelm) || secret == nil {
-		// This helper can't handle this
-		return nil, nil
+func (p *AccessKeyProvider) Supports(credType credentials.Type, repoURL string, data map[string][]byte) bool {
+	if (credType != credentials.TypeImage && credType != credentials.TypeHelm) || len(data) == 0 {
+		return false
 	}
 
 	if credType == credentials.TypeHelm && !strings.HasPrefix(repoURL, "oci://") {
-		// Only OCI Helm repos are supported in ECR
-		return nil, nil
+		return false
 	}
 
-	matches := ecrURLRegex.FindStringSubmatch(repoURL)
-	if len(matches) != 2 { // This doesn't look like an ECR URL
-		return nil, nil
+	if matches := ecrURLRegex.FindStringSubmatch(repoURL); len(matches) != 2 {
+		return false
 	}
 
-	region := string(secret.Data[regionKey])
-	accessKeyID := string(secret.Data[idKey])
-	secretAccessKey := string(secret.Data[secretKey])
-	if region == "" && accessKeyID == "" && secretAccessKey == "" {
-		// None of these fields are set, so there's nothing to do here.
+	return data[regionKey] != nil && data[idKey] != nil && data[secretKey] != nil
+}
+
+func (p *AccessKeyProvider) GetCredentials(
+	ctx context.Context,
+	_ string,
+	credType credentials.Type,
+	repoURL string,
+	data map[string][]byte,
+) (*credentials.Credentials, error) {
+	if !p.Supports(credType, repoURL, data) {
 		return nil, nil
 	}
-	// If we get to here, at least one of the fields is set. Now if they aren't
-	// all set, we should return an error.
-	if region == "" || accessKeyID == "" || secretAccessKey == "" {
-		return nil, fmt.Errorf(
-			"%s, %s, and %s must all be set or all be unset",
-			regionKey, idKey, secretKey,
-		)
-	}
 
-	cacheKey := a.tokenCacheKey(region, accessKeyID, secretAccessKey)
+	var (
+		region, accessKeyID, secretAccessKey = string(data[regionKey]), string(data[idKey]), string(data[secretKey])
+		cacheKey                             = tokenCacheKey(region, accessKeyID, secretAccessKey)
+	)
 
-	if entry, exists := a.tokenCache.Get(cacheKey); exists {
+	// Check the cache for the token
+	if entry, exists := p.tokenCache.Get(cacheKey); exists {
 		return decodeAuthToken(entry.(string)) // nolint: forcetypeassert
 	}
 
-	encodedToken, err := a.getAuthTokenFn(ctx, region, accessKeyID, secretAccessKey)
-	if err != nil {
-		return nil, fmt.Errorf("error getting ECR auth token: %w", err)
-	}
-
-	if encodedToken == "" {
-		return nil, nil
+	// Cache miss, get a new token
+	encodedToken, err := p.getAuthTokenFn(ctx, region, accessKeyID, secretAccessKey)
+	if err != nil || encodedToken == "" {
+		if err != nil {
+			err = fmt.Errorf("error getting ECR auth token: %w", err)
+		}
+		return nil, err
 	}
 
 	// Cache the encoded token
-	a.tokenCache.Set(cacheKey, encodedToken, cache.DefaultExpiration)
+	p.tokenCache.Set(cacheKey, encodedToken, cache.DefaultExpiration)
 
 	return decodeAuthToken(encodedToken)
 }
 
-// tokenCacheKey returns a cache key for an ECR authorization token. The key is
-// a hash of the region, access key ID, and secret access key. Using a hash
-// ensures that the secret access key is not stored in plaintext in the cache.
-func (a *accessKeyCredentialHelper) tokenCacheKey(region, accessKeyID, secretAccessKey string) string {
-	return fmt.Sprintf(
-		"%x",
-		sha256.Sum256([]byte(
-			fmt.Sprintf("%s:%s:%s", region, accessKeyID, secretAccessKey),
-		)),
-	)
-}
-
-// getAuthToken returns an ECR authorization token by calling out to AWS with
-// the provided credentials.
-func (a *accessKeyCredentialHelper) getAuthToken(
+// getAuthToken gets an ECR authorization token using the provided access key ID
+// and secret access key. It returns the encoded token, which is a base64 string
+// containing a username and password separated by a colon.
+func (p *AccessKeyProvider) getAuthToken(
 	ctx context.Context, region, accessKeyID, secretAccessKey string,
 ) (string, error) {
 	svc := ecr.NewFromConfig(aws.Config{
 		Region:      region,
 		Credentials: awscreds.NewStaticCredentialsProvider(accessKeyID, secretAccessKey, ""),
 	})
+
 	output, err := svc.GetAuthorizationToken(ctx, &ecr.GetAuthorizationTokenInput{})
 	if err != nil {
 		return "", fmt.Errorf("error getting ECR authorization token: %w", err)
 	}
-	return *output.AuthorizationData[0].AuthorizationToken, nil
+
+	if output == nil || len(output.AuthorizationData) == 0 {
+		return "", fmt.Errorf("no authorization data returned")
+	}
+
+	if token := output.AuthorizationData[0].AuthorizationToken; token != nil {
+		return *token, nil
+	}
+
+	return "", fmt.Errorf("no authorization token returned")
 }
 
 // decodeAuthToken decodes an ECR authorization token by base64 decoding it and
diff --git a/internal/credentials/kubernetes/ecr/common.go b/internal/credentials/kubernetes/ecr/common.go
index b55ba8cc..64404f47 100644
--- a/internal/credentials/kubernetes/ecr/common.go
+++ b/internal/credentials/kubernetes/ecr/common.go
@@ -1,5 +1,25 @@
 package ecr
 
-import "regexp"
+import (
+	"crypto/sha256"
+	"fmt"
+	"regexp"
+)
 
+// ecrURLRegex is a regex that matches ECR URLs.
 var ecrURLRegex = regexp.MustCompile(`^(?:oci://)?[0-9]{12}\.dkr\.ecr\.(.+)\.amazonaws\.com/`)
+
+// tokenCacheKey returns a cache key in the form of a hash for the given parts.
+// Using a hash ensures that any sensitive data is not stored in a decodable
+// form.
+func tokenCacheKey(parts ...string) string {
+	const separator = ":"
+	h := sha256.New()
+	for i := range parts {
+		if i > 0 {
+			_, _ = h.Write([]byte(separator))
+		}
+		_, _ = h.Write([]byte(parts[i]))
+	}
+	return fmt.Sprintf("%x", h.Sum(nil))
+}
diff --git a/internal/credentials/kubernetes/ecr/managed_identity.go b/internal/credentials/kubernetes/ecr/managed_identity.go
index 1f8a63a5..da6bde71 100644
--- a/internal/credentials/kubernetes/ecr/managed_identity.go
+++ b/internal/credentials/kubernetes/ecr/managed_identity.go
@@ -2,7 +2,6 @@ package ecr
 
 import (
 	"context"
-	"crypto/sha256"
 	"errors"
 	"fmt"
 	"net/http"
@@ -16,103 +15,115 @@ import (
 	"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
 	"github.com/aws/aws-sdk-go-v2/service/ecr"
 	"github.com/aws/aws-sdk-go-v2/service/sts"
+	"github.com/hashicorp/go-cleanhttp"
 	"github.com/patrickmn/go-cache"
-	corev1 "k8s.io/api/core/v1"
 
 	"github.com/akuity/kargo/internal/credentials"
 	"github.com/akuity/kargo/internal/logging"
 )
 
-type managedIdentityCredentialHelper struct {
-	awsAccountID string
+const roleARNFormat = "arn:aws:iam::%s:role/kargo-project-%s"
 
+type ManagedIdentityProvider struct {
 	tokenCache *cache.Cache
 
-	// The following behaviors are overridable for testing purposes:
+	accountID string
 
-	getAuthTokenFn func(
-		ctx context.Context,
-		region string,
-		project string,
-	) (string, error)
+	getAuthTokenFn func(ctx context.Context, region, project string) (string, error)
 }
 
-// NewManagedIdentityCredentialHelper returns an implementation of
-// credentials.Helper that utilizes a cache to avoid unnecessary calls to AWS.
-func NewManagedIdentityCredentialHelper(ctx context.Context) credentials.Helper {
+func NewManagedIdentityProvider(ctx context.Context) credentials.Provider {
 	logger := logging.LoggerFromContext(ctx)
-	var awsAccountID string
-	if os.Getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI") != "" {
+
+	switch {
+	case os.Getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI") != "":
 		logger.Info("EKS Pod Identity appears to be in use")
-	} else if os.Getenv("AWS_ROLE_ARN") != "" && os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE") != "" {
+	case os.Getenv("AWS_ROLE_ARN") != "" && os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE") != "":
 		logger.Info("AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN set; assuming IRSA is being used")
-	} else {
+	default:
 		logger.Info("Neither AWS_CONTAINER_CREDENTIALS_FULL_URI nor AWS_WEB_IDENTITY_TOKEN_FILE " +
 			"and AWS_ROLE_ARN are set; assuming neither EKS Pod Identity nor IRSA are in use")
 		return nil
 	}
+
+	var awsAccountID string
 	cfg, err := config.LoadDefaultConfig(ctx)
 	if err != nil {
 		logger.Error(
 			err, "error loading AWS config; AWS credentials integration will be disabled",
 		)
-	} else {
-		stsSvc := sts.NewFromConfig(cfg)
-		res, err := stsSvc.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
-		if err != nil {
-			logger.Error(
-				err, "error getting caller identity; AWS credentials integration will be disabled",
-			)
-		} else {
-			logger.Debug(
-				"got AWS account ID",
-				"account", *res.Account,
-			)
-			awsAccountID = *res.Account
-		}
+		return nil
 	}
-	p := &managedIdentityCredentialHelper{
-		awsAccountID: awsAccountID,
+	cfg.HTTPClient = cleanhttp.DefaultClient()
+
+	stsSvc := sts.NewFromConfig(cfg)
+	res, err := stsSvc.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
+	if err != nil {
+		logger.Error(
+			err, "error getting caller identity; AWS credentials integration will be disabled",
+		)
+		return nil
+	}
+
+	logger.Debug("got AWS account ID", "account", *res.Account)
+	awsAccountID = *res.Account
+
+	p := &ManagedIdentityProvider{
 		tokenCache: cache.New(
 			// Tokens live for 12 hours. We'll hang on to them for 10.
 			10*time.Hour, // Default ttl for each entry
 			time.Hour,    // Cleanup interval
 		),
+		accountID: awsAccountID,
 	}
 	p.getAuthTokenFn = p.getAuthToken
-	return p.getCredentials
+	return p
+}
+
+func (p *ManagedIdentityProvider) Supports(credType credentials.Type, repoURL string, _ map[string][]byte) bool {
+	if p.accountID == "" {
+		return false
+	}
+
+	if credType != credentials.TypeImage && credType != credentials.TypeHelm {
+		return false
+	}
+
+	if credType == credentials.TypeHelm && !strings.HasPrefix(repoURL, "oci://") {
+		return false
+	}
+
+	return true
 }
 
-func (p *managedIdentityCredentialHelper) getCredentials(
+func (p *ManagedIdentityProvider) GetCredentials(
 	ctx context.Context,
 	project string,
 	credType credentials.Type,
 	repoURL string,
-	_ *corev1.Secret,
+	_ map[string][]byte,
 ) (*credentials.Credentials, error) {
-	if (credType != credentials.TypeImage && credType != credentials.TypeHelm) ||
-		p.awsAccountID == "" { // Pod Identity isn't set up for this controller
-		// This helper can't handle this
-		return nil, nil
-	}
-
-	if credType == credentials.TypeHelm && !strings.HasPrefix(repoURL, "oci://") {
-		// Only OCI Helm repos are supported in ECR
+	if !p.Supports(credType, repoURL, nil) {
 		return nil, nil
 	}
 
+	// Extract the region from the ECR URL
 	matches := ecrURLRegex.FindStringSubmatch(repoURL)
 	if len(matches) != 2 { // This doesn't look like an ECR URL
 		return nil, nil
 	}
-	region := matches[1]
 
-	cacheKey := p.tokenCacheKey(region, project)
+	var (
+		region   = matches[1]
+		cacheKey = tokenCacheKey(region, project)
+	)
 
+	// Check the cache for the token
 	if entry, exists := p.tokenCache.Get(cacheKey); exists {
 		return decodeAuthToken(entry.(string)) // nolint: forcetypeassert
 	}
 
+	// Cache miss, get a new token
 	encodedToken, err := p.getAuthTokenFn(ctx, region, project)
 	if err != nil {
 		// This might mean the controller's IAM role isn't authorized to assume the
@@ -123,6 +134,7 @@ func (p *managedIdentityCredentialHelper) getCredentials(
 		return nil, fmt.Errorf("error getting ECR auth token: %w", err)
 	}
 
+	// If we didn't get a token, we'll treat this as no credentials found
 	if encodedToken == "" {
 		return nil, nil
 	}
@@ -133,41 +145,34 @@ func (p *managedIdentityCredentialHelper) getCredentials(
 	return decodeAuthToken(encodedToken)
 }
 
-func (p *managedIdentityCredentialHelper) tokenCacheKey(region, project string) string {
-	return fmt.Sprintf(
-		"%x",
-		sha256.Sum256([]byte(
-			fmt.Sprintf("%s:%s", region, project),
-		)),
-	)
-}
-
 // getAuthToken returns an ECR authorization token obtained by assuming a
 // project-specific IAM role and using that to obtain a short-lived ECR access
 // token.
-func (p *managedIdentityCredentialHelper) getAuthToken(
-	ctx context.Context,
-	region string,
-	project string,
-) (string, error) {
+func (p *ManagedIdentityProvider) getAuthToken(ctx context.Context, region, project string) (string, error) {
 	logger := logging.LoggerFromContext(ctx)
+
 	cfg, err := config.LoadDefaultConfig(ctx)
 	if err != nil {
 		logger.Error(err, "error loading AWS config")
 		return "", nil
 	}
+	cfg.HTTPClient = cleanhttp.DefaultClient()
+
 	ecrSvc := ecr.NewFromConfig(aws.Config{
-		Region: region,
+		HTTPClient: cleanhttp.DefaultClient(),
+		Region:     region,
 		Credentials: stscreds.NewAssumeRoleProvider(
 			sts.NewFromConfig(cfg),
-			fmt.Sprintf("arn:aws:iam::%s:role/kargo-project-%s", p.awsAccountID, project),
+			fmt.Sprintf(roleARNFormat, p.accountID, project),
 		),
 	})
+
 	logger = logger.WithValues(
-		"awsAccountID", p.awsAccountID,
+		"awsAccountID", p.accountID,
 		"awsRegion", region,
 		"project", project,
 	)
+
 	output, err := ecrSvc.GetAuthorizationToken(ctx, &ecr.GetAuthorizationTokenInput{})
 	if err != nil {
 		var re *awshttp.ResponseError
@@ -179,6 +184,7 @@ func (p *managedIdentityCredentialHelper) getAuthToken(
 				"or project-specific role is not authorized to obtain an ECR auth token. " +
 				"Falling back to using controller's IAM role directly.",
 		)
+
 		cfg.Region = region
 		ecrSvc = ecr.NewFromConfig(cfg)
 		output, err = ecrSvc.GetAuthorizationToken(ctx, &ecr.GetAuthorizationTokenInput{})
diff --git a/internal/credentials/kubernetes/gar/common.go b/internal/credentials/kubernetes/gar/common.go
index 5b4a6169..4de54d21 100644
--- a/internal/credentials/kubernetes/gar/common.go
+++ b/internal/credentials/kubernetes/gar/common.go
@@ -1,6 +1,10 @@
 package gar
 
-import "regexp"
+import (
+	"crypto/sha256"
+	"fmt"
+	"regexp"
+)
 
 const accessTokenUsername = "oauth2accesstoken"
 
@@ -8,3 +12,7 @@ var (
 	gcrURLRegex = regexp.MustCompile(`^(?:.+\.)?gcr\.io/`) // Legacy
 	garURLRegex = regexp.MustCompile(`^.+-docker\.pkg\.dev/`)
 )
+
+func tokenCacheKey(key string) string {
+	return fmt.Sprintf("%x", sha256.Sum256([]byte(key)))
+}
diff --git a/internal/credentials/kubernetes/gar/service_account_key.go b/internal/credentials/kubernetes/gar/service_account_key.go
index 47eef042..cc685868 100644
--- a/internal/credentials/kubernetes/gar/service_account_key.go
+++ b/internal/credentials/kubernetes/gar/service_account_key.go
@@ -2,85 +2,89 @@ package gar
 
 import (
 	"context"
-	"crypto/sha256"
 	"encoding/base64"
 	"fmt"
 	"time"
 
 	"github.com/patrickmn/go-cache"
 	"golang.org/x/oauth2/google"
-	corev1 "k8s.io/api/core/v1"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-const serviceAccountKeyKey = "gcpServiceAccountKey"
+const (
+	serviceAccountKeyKey = "gcpServiceAccountKey"
 
-type serviceAccountKeyCredentialHelper struct {
-	tokenCache *cache.Cache
+	scopeStorageRead = "https://www.googleapis.com/auth/devstorage.read_only"
+)
 
-	// The following behaviors are overridable for testing purposes:
+type ServiceAccountKeyProvider struct {
+	tokenCache *cache.Cache
 
-	getAccessTokenFn func(context.Context, string) (string, error)
+	getAccessTokenFn func(ctx context.Context, encodedServiceAccountKey string) (string, error)
 }
 
-// NewServiceAccountKeyCredentialHelper returns an implementation
-// credentials.Helper that utilizes a cache to avoid unnecessary calls to GCP.
-func NewServiceAccountKeyCredentialHelper() credentials.Helper {
-	s := &serviceAccountKeyCredentialHelper{
+func NewServiceAccountKeyProvider() credentials.Provider {
+	p := &ServiceAccountKeyProvider{
 		tokenCache: cache.New(
 			// Access tokens live for one hour. We'll hang on to them for 40 minutes.
 			40*time.Minute, // Default ttl for each entry
 			time.Hour,      // Cleanup interval
 		),
 	}
-	s.getAccessTokenFn = s.getAccessToken
-	return s.getCredentials
+	p.getAccessTokenFn = p.getAccessToken
+	return p
 }
 
-func (s *serviceAccountKeyCredentialHelper) getCredentials(
-	ctx context.Context,
-	_ string,
-	credType credentials.Type,
-	repoURL string,
-	secret *corev1.Secret,
-) (*credentials.Credentials, error) {
-	if credType != credentials.TypeImage || secret == nil {
-		// This helper can't handle this
-		return nil, nil
+func (p *ServiceAccountKeyProvider) Supports(credType credentials.Type, repoURL string, data map[string][]byte) bool {
+	if credType != credentials.TypeImage || data == nil || data[serviceAccountKeyKey] == nil {
+		return false
 	}
 
 	if !garURLRegex.MatchString(repoURL) && !gcrURLRegex.MatchString(repoURL) {
-		// This doesn't look like a Google Artifact Registry URL
-		return nil, nil
+		return false
 	}
 
-	// This should be base64 encoded
-	encodedServiceAccountKey := string(secret.Data[serviceAccountKeyKey])
-	if encodedServiceAccountKey == "" {
+	return true
+}
+
+func (p *ServiceAccountKeyProvider) GetCredentials(
+	ctx context.Context,
+	_ string,
+	credType credentials.Type,
+	repoURL string,
+	data map[string][]byte,
+) (*credentials.Credentials, error) {
+	if !p.Supports(credType, repoURL, data) {
 		return nil, nil
 	}
 
-	cacheKey := s.tokenCacheKey(encodedServiceAccountKey)
+	var (
+		encodedServiceAccountKey = string(data[serviceAccountKeyKey])
+		cacheKey                 = tokenCacheKey(encodedServiceAccountKey)
+	)
 
-	if entry, exists := s.tokenCache.Get(cacheKey); exists {
+	// Check the cache for the token
+	if entry, exists := p.tokenCache.Get(cacheKey); exists {
 		return &credentials.Credentials{
 			Username: accessTokenUsername,
 			Password: entry.(string), // nolint: forcetypeassert
 		}, nil
 	}
 
-	accessToken, err := s.getAccessTokenFn(ctx, encodedServiceAccountKey)
+	// Cache miss, get a new token
+	accessToken, err := p.getAccessTokenFn(ctx, encodedServiceAccountKey)
 	if err != nil {
 		return nil, fmt.Errorf("error getting GCP access token: %w", err)
 	}
 
+	// If we didn't get a token, we'll treat this as no credentials found
 	if accessToken == "" {
 		return nil, nil
 	}
 
-	// Cache the access token
-	s.tokenCache.Set(cacheKey, accessToken, cache.DefaultExpiration)
+	// Cache the token
+	p.tokenCache.Set(cacheKey, accessToken, cache.DefaultExpiration)
 
 	return &credentials.Credentials{
 		Username: accessTokenUsername,
@@ -88,19 +92,9 @@ func (s *serviceAccountKeyCredentialHelper) getCredentials(
 	}, nil
 }
 
-// tokenCacheKey returns a cache key for a GCP access token. The key is a hash
-// of the provided (encoded) service account key. Using a hash ensures that a
-// decodable service account key is not stored in the cache.
-func (s *serviceAccountKeyCredentialHelper) tokenCacheKey(encodedServiceAccountKey string) string {
-	return fmt.Sprintf(
-		"%x",
-		sha256.Sum256([]byte(encodedServiceAccountKey)),
-	)
-}
-
 // getAccessToken returns a GCP access token retrieved using the provided base64
 // encoded service account key. The access token is valid for one hour.
-func (s *serviceAccountKeyCredentialHelper) getAccessToken(
+func (p *ServiceAccountKeyProvider) getAccessToken(
 	ctx context.Context,
 	encodedServiceAccountKey string,
 ) (string, error) {
@@ -108,10 +102,12 @@ func (s *serviceAccountKeyCredentialHelper) getAccessToken(
 	if err != nil {
 		return "", fmt.Errorf("error decoding service account key: %w", err)
 	}
-	config, err := google.JWTConfigFromJSON(decodedKey, "https://www.googleapis.com/auth/devstorage.read_only")
+
+	config, err := google.JWTConfigFromJSON(decodedKey, scopeStorageRead)
 	if err != nil {
 		return "", fmt.Errorf("error parsing service account key: %w", err)
 	}
+
 	tokenSource := config.TokenSource(ctx)
 	token, err := tokenSource.Token()
 	if err != nil {
diff --git a/internal/credentials/kubernetes/gar/workload_identity_federation.go b/internal/credentials/kubernetes/gar/workload_identity_federation.go
index d2444f52..1bb5b976 100644
--- a/internal/credentials/kubernetes/gar/workload_identity_federation.go
+++ b/internal/credentials/kubernetes/gar/workload_identity_federation.go
@@ -8,91 +8,101 @@ import (
 	"cloud.google.com/go/compute/metadata"
 	"github.com/patrickmn/go-cache"
 	"google.golang.org/api/iamcredentials/v1"
-	corev1 "k8s.io/api/core/v1"
 
 	"github.com/akuity/kargo/internal/credentials"
 	"github.com/akuity/kargo/internal/logging"
 )
 
-type workloadIdentityFederationCredentialHelper struct {
-	gcpProjectID string
+const (
+	gcpResourceNameFormat = "projects/-/serviceAccounts/kargo-project-%s@%s.iam.gserviceaccount.com"
+)
 
+type WorkloadIdentityFederationProvider struct {
 	tokenCache *cache.Cache
 
-	// The following behaviors are overridable for testing purposes:
+	projectID string
 
-	getAccessTokenFn func(ctx context.Context, kargoProject string) (string, error)
+	getAccessTokenFn func(ctx context.Context, project string) (string, error)
 }
 
-// NewWorkloadIdentityFederationCredentialHelper returns an implementation of
-// credentials.Helper that utilizes a cache to avoid unnecessary calls to GCP.
-func NewWorkloadIdentityFederationCredentialHelper(
-	ctx context.Context,
-) credentials.Helper {
+func NewWorkloadIdentityFederationProvider(ctx context.Context) credentials.Provider {
 	logger := logging.LoggerFromContext(ctx)
-	var gcpProjectID string
+
 	if !metadata.OnGCE() {
 		logger.Info("not running within GCE; assuming GCP Workload Identity Federation is not in use")
 		return nil
 	}
 	logger.Info("controller appears to be running within GCE")
-	var err error
-	if gcpProjectID, err = metadata.ProjectIDWithContext(ctx); err != nil {
+
+	projectID, err := metadata.ProjectIDWithContext(ctx)
+	if err != nil {
 		logger.Error(err, "error getting GCP project ID")
-	} else {
-		logger.Debug(
-			"got GCP project ID",
-			"project", gcpProjectID,
-		)
+		return nil
 	}
-	w := &workloadIdentityFederationCredentialHelper{
-		gcpProjectID: gcpProjectID,
+	logger.Debug("got GCP project ID", "project", projectID)
+
+	p := &WorkloadIdentityFederationProvider{
 		tokenCache: cache.New(
 			// Access tokens live for one hour. We'll hang on to them for 40 minutes.
 			40*time.Minute, // Default ttl for each entry
 			time.Hour,      // Cleanup interval
 		),
+		projectID: projectID,
 	}
-	w.getAccessTokenFn = w.getAccessToken
-	return w.getCredentials
+	p.getAccessTokenFn = p.getAccessToken
+	return p
 }
 
-func (w *workloadIdentityFederationCredentialHelper) getCredentials(
-	ctx context.Context,
-	kargoProject string,
+func (p *WorkloadIdentityFederationProvider) Supports(
 	credType credentials.Type,
 	repoURL string,
-	_ *corev1.Secret,
-) (*credentials.Credentials, error) {
-	if credType != credentials.TypeImage ||
-		w.gcpProjectID == "" { // Controller isn't running within GCE
-		// This helper can't handle this
-		return nil, nil
+	_ map[string][]byte,
+) bool {
+	if p.projectID == "" || credType != credentials.TypeImage {
+		return false
 	}
 
 	if !garURLRegex.MatchString(repoURL) && !gcrURLRegex.MatchString(repoURL) {
-		// This doesn't look like a Google Artifact Registry URL
+		return false
+	}
+
+	return true
+}
+
+func (p *WorkloadIdentityFederationProvider) GetCredentials(
+	ctx context.Context,
+	project string,
+	credType credentials.Type,
+	repoURL string,
+	_ map[string][]byte,
+) (*credentials.Credentials, error) {
+	if !p.Supports(credType, repoURL, nil) {
 		return nil, nil
 	}
 
-	if entry, exists := w.tokenCache.Get(kargoProject); exists {
+	var cacheKey = tokenCacheKey(project)
+
+	// Check the cache for the token
+	if entry, exists := p.tokenCache.Get(cacheKey); exists {
 		return &credentials.Credentials{
 			Username: accessTokenUsername,
 			Password: entry.(string), // nolint: forcetypeassert
 		}, nil
 	}
 
-	accessToken, err := w.getAccessTokenFn(ctx, kargoProject)
+	// Cache miss, get a new token
+	accessToken, err := p.getAccessTokenFn(ctx, project)
 	if err != nil {
 		return nil, fmt.Errorf("error getting GCP access token: %w", err)
 	}
 
+	// If we didn't get a token, we'll treat this as no credentials found
 	if accessToken == "" {
 		return nil, nil
 	}
 
-	// Cache the access token
-	w.tokenCache.Set(kargoProject, accessToken, cache.DefaultExpiration)
+	// Cache the token
+	p.tokenCache.Set(cacheKey, accessToken, cache.DefaultExpiration)
 
 	return &credentials.Credentials{
 		Username: accessTokenUsername,
@@ -102,28 +112,25 @@ func (w *workloadIdentityFederationCredentialHelper) getCredentials(
 
 // getAccessToken returns a GCP access token retrieved using the provided base64
 // encoded service account key. The access token is valid for one hour.
-func (w *workloadIdentityFederationCredentialHelper) getAccessToken(
+func (p *WorkloadIdentityFederationProvider) getAccessToken(
 	ctx context.Context,
 	kargoProject string,
 ) (string, error) {
 	logger := logging.LoggerFromContext(ctx)
+
 	iamSvc, err := iamcredentials.NewService(ctx)
 	if err != nil {
 		logger.Error(err, "error creating IAM Credentials service client")
 		return "", nil
 	}
-	logger = logger.WithValues(
-		"gcpProjectID", w.gcpProjectID,
-		"kargoProject", kargoProject,
-	)
+
+	logger = logger.WithValues("gcpProjectID", p.projectID, "kargoProject", kargoProject)
+
 	resp, err := iamSvc.Projects.ServiceAccounts.GenerateAccessToken(
-		fmt.Sprintf(
-			"projects/-/serviceAccounts/kargo-project-%s@%s.iam.gserviceaccount.com",
-			kargoProject, w.gcpProjectID,
-		),
+		fmt.Sprintf(gcpResourceNameFormat, kargoProject, p.projectID),
 		&iamcredentials.GenerateAccessTokenRequest{
 			Scope: []string{
-				"https://www.googleapis.com/auth/cloud-platform",
+				iamcredentials.CloudPlatformScope,
 			},
 		},
 	).Do()
@@ -131,6 +138,7 @@ func (w *workloadIdentityFederationCredentialHelper) getAccessToken(
 		logger.Error(err, "error generating access token")
 		return "", nil
 	}
+
 	logger.Debug("generated Artifact Registry access token")
 	return resp.AccessToken, nil
 }
diff --git a/internal/credentials/kubernetes/github/app.go b/internal/credentials/kubernetes/github/app.go
index 5c41c0f5..f4f074b0 100644
--- a/internal/credentials/kubernetes/github/app.go
+++ b/internal/credentials/kubernetes/github/app.go
@@ -6,13 +6,15 @@ import (
 	"encoding/base64"
 	"errors"
 	"fmt"
+	"net/url"
 	"regexp"
 	"strconv"
+	"strings"
 	"time"
 
+	"github.com/hashicorp/go-cleanhttp"
 	"github.com/jferrl/go-githubauth"
 	"github.com/patrickmn/go-cache"
-	corev1 "k8s.io/api/core/v1"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
@@ -22,96 +24,99 @@ const (
 	installationIDKey = "githubAppInstallationID"
 	privateKeyKey     = "githubAppPrivateKey"
 
+	githubHost = "github.com"
+
 	accessTokenUsername = "kargo"
 )
 
 var base64Regex = regexp.MustCompile(`^[a-zA-Z0-9+/]*={0,2}$`)
 
-type appCredentialHelper struct {
+type AppCredentialProvider struct {
 	tokenCache *cache.Cache
 
-	// The following behaviors are overridable for testing purposes:
-
-	getAccessTokenFn func(
-		appID int64,
-		installationID int64,
-		encodedKey string,
-	) (string, error)
+	getAccessTokenFn func(appID, installationID int64, encodedPrivateKey, baseURL string) (string, error)
 }
 
-// NewAppCredentialHelper returns an implementation of credentials.Helper that
-// utilizes a cache to avoid unnecessary calls to GitHub.
-func NewAppCredentialHelper() credentials.Helper {
-	a := &appCredentialHelper{
+// NewAppCredentialProvider returns an implementation of credentials.Provider.
+func NewAppCredentialProvider() credentials.Provider {
+	p := &AppCredentialProvider{
 		tokenCache: cache.New(
 			// Access tokens live for one hour. We'll hang on to them for 40 minutes.
 			40*time.Minute, // Default ttl for each entry
 			time.Hour,      // Cleanup interval
 		),
 	}
-	a.getAccessTokenFn = a.getAccessToken
-	return a.getCredentials
+	p.getAccessTokenFn = p.getAccessToken
+	return p
+}
+
+func (p *AppCredentialProvider) Supports(credType credentials.Type, _ string, data map[string][]byte) bool {
+	if credType != credentials.TypeGit || len(data) == 0 {
+		return false
+	}
+
+	return data[appIDKey] != nil && data[installationIDKey] != nil && data[privateKeyKey] != nil
 }
 
-func (a *appCredentialHelper) getCredentials(
+func (p *AppCredentialProvider) GetCredentials(
 	_ context.Context,
 	_ string,
 	credType credentials.Type,
-	_ string,
-	secret *corev1.Secret,
+	repoURL string,
+	data map[string][]byte,
 ) (*credentials.Credentials, error) {
-	if credType != credentials.TypeGit || secret == nil {
-		// This helper can't handle this
+	if !p.Supports(credType, repoURL, data) {
 		return nil, nil
 	}
 
-	appIDStr := string(secret.Data[appIDKey])
-	installationIDStr := string(secret.Data[installationIDKey])
-	encodedPrivateKey := string(secret.Data[privateKeyKey])
-	if appIDStr == "" && installationIDStr == "" && encodedPrivateKey == "" {
-		// None of these fields are set, so there's nothing to do here.
-		return nil, nil
-	}
-	// If we get to here, at least one of the fields is set. Now if they aren't
-	// all set, we should return an error.
-	if appIDStr == "" || installationIDStr == "" || encodedPrivateKey == "" {
-		return nil, fmt.Errorf(
-			"%s, %s, and %s must all be set or all be unset",
-			appIDKey, installationIDKey, privateKeyKey,
-		)
-	}
-	appID, err := strconv.ParseInt(appIDStr, 10, 64)
+	appID, err := strconv.ParseInt(string(data[appIDKey]), 10, 64)
 	if err != nil {
 		return nil, fmt.Errorf("error parsing app ID: %w", err)
 	}
-	installationID, err := strconv.ParseInt(installationIDStr, 10, 64)
+
+	installID, err := strconv.ParseInt(string(data[installationIDKey]), 10, 64)
 	if err != nil {
 		return nil, fmt.Errorf("error parsing installation ID: %w", err)
 	}
-	return a.getUsernameAndPassword(appID, installationID, encodedPrivateKey)
+
+	baseURL, err := extractBaseURL(repoURL)
+	if err != nil {
+		return nil, fmt.Errorf("error extracting base URL from : %w", err)
+	}
+
+	return p.getUsernameAndPassword(appID, installID, string(data[privateKeyKey]), baseURL)
 }
 
-func (a *appCredentialHelper) getUsernameAndPassword(
+// getUsernameAndPassword gets a username and password for the given app and
+// installation IDs. The private key is the PEM-encoded private key for the
+// GitHub App. The base URL is the scheme and host of the repository URL, which
+// is used to determine whether the repository is hosted on GitHub Enterprise.
+func (p *AppCredentialProvider) getUsernameAndPassword(
 	appID int64,
 	installationID int64,
-	encodedPrivateKey string,
+	encodedPrivateKey, baseURL string,
 ) (*credentials.Credentials, error) {
-	cacheKey := a.tokenCacheKey(appID, installationID, encodedPrivateKey)
+	cacheKey := tokenCacheKey(baseURL, appID, installationID, encodedPrivateKey)
 
-	if entry, exists := a.tokenCache.Get(cacheKey); exists {
+	// Check the cache for the token
+	if entry, exists := p.tokenCache.Get(cacheKey); exists {
 		return &credentials.Credentials{
 			Username: accessTokenUsername,
 			Password: entry.(string), // nolint: forcetypeassert
 		}, nil
 	}
 
-	accessToken, err := a.getAccessTokenFn(appID, installationID, encodedPrivateKey)
+	// Cache miss, get a new token
+	accessToken, err := p.getAccessTokenFn(
+		appID, installationID,
+		encodedPrivateKey, baseURL,
+	)
 	if err != nil {
 		return nil, fmt.Errorf("error getting installation access token: %w", err)
 	}
 
-	// Cache the access token
-	a.tokenCache.Set(cacheKey, accessToken, cache.DefaultExpiration)
+	// Cache the new token
+	p.tokenCache.Set(cacheKey, accessToken, cache.DefaultExpiration)
 
 	return &credentials.Credentials{
 		Username: accessTokenUsername,
@@ -119,36 +124,37 @@ func (a *appCredentialHelper) getUsernameAndPassword(
 	}, nil
 }
 
-// tokenCacheKey returns a cache key for an installation access token. The key is
-// a hash of the app ID, installation ID, and encoded private key. Using a
-// hash ensures that a decodable key is not stored in the cache.
-func (a *appCredentialHelper) tokenCacheKey(
-	appID int64,
-	installationID int64,
-	encodedPrivateKey string,
-) string {
-	return fmt.Sprintf(
-		"%x",
-		sha256.Sum256([]byte(
-			fmt.Sprintf("%d:%d:%s", appID, installationID, encodedPrivateKey),
-		)),
-	)
-}
-
-func (a *appCredentialHelper) getAccessToken(
-	appID int64,
-	installationID int64,
-	encodedPrivateKey string,
+// getAccessToken gets an installation access token for the given app and
+// installation IDs. The private key is the PEM-encoded private key for the
+// GitHub App. The base URL is the scheme and host of the repository URL, which
+// is used to determine whether the repository is hosted on GitHub Enterprise.
+func (p *AppCredentialProvider) getAccessToken(
+	appID, installationID int64,
+	encodedPrivateKey, baseURL string,
 ) (string, error) {
 	decodedKey, err := decodeKey(encodedPrivateKey)
 	if err != nil {
 		return "", err
 	}
+
 	appTokenSource, err := githubauth.NewApplicationTokenSource(appID, decodedKey)
 	if err != nil {
 		return "", fmt.Errorf("error creating application token source: %w", err)
 	}
-	installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)
+
+	installationOpts := []githubauth.InstallationTokenSourceOpt{
+		githubauth.WithHTTPClient(cleanhttp.DefaultClient()),
+	}
+	if baseURL != "" {
+		if !strings.HasPrefix(baseURL, "http://") && !strings.HasPrefix(baseURL, "https://") {
+			return "", fmt.Errorf("can only request access tokens for HTTP or HTTPS URLs")
+		}
+		if !strings.HasSuffix(baseURL, "://"+githubHost) {
+			installationOpts = append(installationOpts, githubauth.WithEnterpriseURLs(baseURL, baseURL))
+		}
+	}
+	installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource, installationOpts...)
+
 	token, err := installationTokenSource.Token()
 	if err != nil {
 		return "", fmt.Errorf("error getting installation access token: %w", err)
@@ -156,6 +162,21 @@ func (a *appCredentialHelper) getAccessToken(
 	return token.AccessToken, nil
 }
 
+// tokenCacheKey returns a cache key for an installation access token. The key
+// is a hash of the hostname, app ID, installation ID, and encoded private key.
+// Using a hash ensures that a decodable key is not stored in the cache.
+func tokenCacheKey(baseURL string, appID, installationID int64, encodedPrivateKey string) string {
+	return fmt.Sprintf(
+		"%x",
+		sha256.Sum256([]byte(
+			fmt.Sprintf(
+				"%s:%d:%d:%s",
+				baseURL, appID, installationID, encodedPrivateKey,
+			),
+		)),
+	)
+}
+
 // decodeKey attempts to base64 decode a key. If successful, it returns the
 // result. If it fails, it attempts to infer whether the input was simply NOT
 // base64 encoded or whether it appears to have been base64 encoded but
@@ -180,3 +201,13 @@ func decodeKey(key string) ([]byte, error) {
 	}
 	return decodedKey, nil
 }
+
+// extractBaseURL extracts the base URL from a full repository URL. The base
+// URL is the scheme and host of the repository URL.
+func extractBaseURL(fullURL string) (string, error) {
+	u, err := url.Parse(fullURL)
+	if err != nil {
+		return "", fmt.Errorf("error parsing URL: %w", err)
+	}
+	return u.Scheme + "://" + u.Host, nil
+}
diff --git a/internal/directives/git_cloner.go b/internal/directives/git_cloner.go
index 8bb6d97e..7b3161e5 100644
--- a/internal/directives/git_cloner.go
+++ b/internal/directives/git_cloner.go
@@ -93,7 +93,7 @@ func (g *gitCloner) runPromotionStep(
 	cfg builtin.GitCloneConfig,
 ) (PromotionStepResult, error) {
 	var repoCreds *git.RepoCredentials
-	creds, found, err := stepCtx.CredentialsDB.Get(
+	creds, err := stepCtx.CredentialsDB.Get(
 		ctx,
 		stepCtx.Project,
 		credentials.TypeGit,
@@ -103,7 +103,7 @@ func (g *gitCloner) runPromotionStep(
 		return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored},
 			fmt.Errorf("error getting credentials for %s: %w", cfg.RepoURL, err)
 	}
-	if found {
+	if creds != nil {
 		repoCreds = &git.RepoCredentials{
 			Username:      creds.Username,
 			Password:      creds.Password,
diff --git a/internal/directives/git_pr_opener.go b/internal/directives/git_pr_opener.go
index 156c754e..5063ec62 100644
--- a/internal/directives/git_pr_opener.go
+++ b/internal/directives/git_pr_opener.go
@@ -95,7 +95,7 @@ func (g *gitPROpener) runPromotionStep(
 	sourceBranch := cfg.SourceBranch
 
 	var repoCreds *git.RepoCredentials
-	creds, found, err := stepCtx.CredentialsDB.Get(
+	creds, err := stepCtx.CredentialsDB.Get(
 		ctx,
 		stepCtx.Project,
 		credentials.TypeGit,
@@ -105,7 +105,7 @@ func (g *gitPROpener) runPromotionStep(
 		return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored},
 			fmt.Errorf("error getting credentials for %s: %w", cfg.RepoURL, err)
 	}
-	if found {
+	if creds != nil {
 		repoCreds = &git.RepoCredentials{
 			Username:      creds.Username,
 			Password:      creds.Password,
diff --git a/internal/directives/git_pr_waiter.go b/internal/directives/git_pr_waiter.go
index 7da05b6a..d36834cd 100644
--- a/internal/directives/git_pr_waiter.go
+++ b/internal/directives/git_pr_waiter.go
@@ -66,7 +66,7 @@ func (g *gitPRWaiter) runPromotionStep(
 	cfg builtin.GitWaitForPRConfig,
 ) (PromotionStepResult, error) {
 	var repoCreds *git.RepoCredentials
-	creds, found, err := stepCtx.CredentialsDB.Get(
+	creds, err := stepCtx.CredentialsDB.Get(
 		ctx,
 		stepCtx.Project,
 		credentials.TypeGit,
@@ -76,7 +76,7 @@ func (g *gitPRWaiter) runPromotionStep(
 		return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored},
 			fmt.Errorf("error getting credentials for %s: %w", cfg.RepoURL, err)
 	}
-	if found {
+	if creds != nil {
 		repoCreds = &git.RepoCredentials{
 			Username:      creds.Username,
 			Password:      creds.Password,
diff --git a/internal/directives/git_pusher.go b/internal/directives/git_pusher.go
index 3ae22fe5..d3fc0cf1 100644
--- a/internal/directives/git_pusher.go
+++ b/internal/directives/git_pusher.go
@@ -93,17 +93,17 @@ func (g *gitPushPusher) runPromotionStep(
 		return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored},
 			fmt.Errorf("error loading working tree from %s: %w", cfg.Path, err)
 	}
-	var creds credentials.Credentials
-	var found bool
-	if creds, found, err = stepCtx.CredentialsDB.Get(
+	creds, err := stepCtx.CredentialsDB.Get(
 		ctx,
 		stepCtx.Project,
 		credentials.TypeGit,
 		workTree.URL(),
-	); err != nil {
+	)
+	if err != nil {
 		return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored},
 			fmt.Errorf("error getting credentials for %s: %w", workTree.URL(), err)
-	} else if found {
+	}
+	if creds != nil {
 		loadOpts.Credentials = &git.RepoCredentials{
 			Username:      creds.Username,
 			Password:      creds.Password,
diff --git a/internal/directives/helm_chart_updater.go b/internal/directives/helm_chart_updater.go
index e63a6559..b2e784c0 100644
--- a/internal/directives/helm_chart_updater.go
+++ b/internal/directives/helm_chart_updater.go
@@ -332,11 +332,11 @@ func (h *helmChartUpdater) setupDependencyRepositories(
 				URL:  dep.Repository,
 			}
 
-			creds, ok, err := credentialsDB.Get(ctx, project, credentials.TypeHelm, dep.Repository)
+			creds, err := credentialsDB.Get(ctx, project, credentials.TypeHelm, dep.Repository)
 			if err != nil {
 				return fmt.Errorf("failed to obtain credentials for chart repository %q: %w", dep.Repository, err)
 			}
-			if ok {
+			if creds != nil {
 				entry.Username = creds.Username
 				entry.Password = creds.Password
 			}
@@ -344,11 +344,11 @@ func (h *helmChartUpdater) setupDependencyRepositories(
 			repositoryFile.Update(entry)
 		case strings.HasPrefix(dep.Repository, "oci://"):
 			credURL := "oci://" + path.Join(helm.NormalizeChartRepositoryURL(dep.Repository), dep.Name)
-			creds, ok, err := credentialsDB.Get(ctx, project, credentials.TypeHelm, credURL)
+			creds, err := credentialsDB.Get(ctx, project, credentials.TypeHelm, credURL)
 			if err != nil {
 				return fmt.Errorf("failed to obtain credentials for chart repository %q: %w", dep.Repository, err)
 			}
-			if ok {
+			if creds != nil {
 				if err = registryClient.Login(
 					strings.TrimPrefix(dep.Repository, "oci://"),
 					registry.LoginOptBasicAuth(creds.Username, creds.Password),
diff --git a/internal/rollouts/analysis_run_builder.go b/internal/rollouts/analysis_run_builder.go
index 17903aad..b08a135a 100644
--- a/internal/rollouts/analysis_run_builder.go
+++ b/internal/rollouts/analysis_run_builder.go
@@ -14,8 +14,8 @@ import (
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/expressions"
 )
 
diff --git a/internal/rollouts/analysis_template.go b/internal/rollouts/analysis_template.go
index 22ea4c12..b7b9b505 100644
--- a/internal/rollouts/analysis_template.go
+++ b/internal/rollouts/analysis_template.go
@@ -3,7 +3,7 @@ package rollouts
 import (
 	"fmt"
 
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 // flattenTemplates combines multiple analysis templates into a single
diff --git a/internal/server/abort_promotion.go b/internal/server/abort_promotion.go
index ac6db19c..6d87a17e 100644
--- a/internal/server/abort_promotion.go
+++ b/internal/server/abort_promotion.go
@@ -6,9 +6,9 @@ import (
 	"connectrpc.com/connect"
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) AbortPromotion(
diff --git a/internal/server/abort_verification_v1alpha1.go b/internal/server/abort_verification_v1alpha1.go
index 8f6882ec..74b71703 100644
--- a/internal/server/abort_verification_v1alpha1.go
+++ b/internal/server/abort_verification_v1alpha1.go
@@ -6,8 +6,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) AbortVerification(
diff --git a/internal/server/admin_login_v1alpha1.go b/internal/server/admin_login_v1alpha1.go
index 5d129d5c..5ba3ffa8 100644
--- a/internal/server/admin_login_v1alpha1.go
+++ b/internal/server/admin_login_v1alpha1.go
@@ -11,7 +11,7 @@ import (
 	"github.com/google/uuid"
 	"golang.org/x/crypto/bcrypt"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func init() {
diff --git a/internal/server/approve_freight_v1alpha1.go b/internal/server/approve_freight_v1alpha1.go
index a8065d9f..ec00956d 100644
--- a/internal/server/approve_freight_v1alpha1.go
+++ b/internal/server/approve_freight_v1alpha1.go
@@ -12,11 +12,11 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"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"
 	"github.com/akuity/kargo/internal/kubeclient"
 	"github.com/akuity/kargo/internal/server/user"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ApproveFreight(
diff --git a/internal/server/common.go b/internal/server/common.go
index 4bd443aa..96861913 100644
--- a/internal/server/common.go
+++ b/internal/server/common.go
@@ -13,8 +13,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	sigyaml "sigs.k8s.io/yaml"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 var (
diff --git a/internal/server/create_credentials_v1alpha1.go b/internal/server/create_credentials_v1alpha1.go
index dad5ffaa..05bd5052 100644
--- a/internal/server/create_credentials_v1alpha1.go
+++ b/internal/server/create_credentials_v1alpha1.go
@@ -9,9 +9,9 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	libCreds "github.com/akuity/kargo/internal/credentials"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type credentials struct {
diff --git a/internal/server/create_or_update_resource_v1alpha1.go b/internal/server/create_or_update_resource_v1alpha1.go
index 8d045a4e..b29d59a7 100644
--- a/internal/server/create_or_update_resource_v1alpha1.go
+++ b/internal/server/create_or_update_resource_v1alpha1.go
@@ -10,7 +10,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	sigyaml "sigs.k8s.io/yaml"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) CreateOrUpdateResource(
diff --git a/internal/server/create_project_secret_v1alpha1.go b/internal/server/create_project_secret_v1alpha1.go
index fad10c98..74f52f55 100644
--- a/internal/server/create_project_secret_v1alpha1.go
+++ b/internal/server/create_project_secret_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type projectSecret struct {
diff --git a/internal/server/create_resource_v1alpha1.go b/internal/server/create_resource_v1alpha1.go
index a7177a64..d15c2508 100644
--- a/internal/server/create_resource_v1alpha1.go
+++ b/internal/server/create_resource_v1alpha1.go
@@ -12,7 +12,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	sigyaml "sigs.k8s.io/yaml"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) CreateResource(
diff --git a/internal/server/create_role_v1alpha1.go b/internal/server/create_role_v1alpha1.go
index 4e3225a1..eabf6dc7 100644
--- a/internal/server/create_role_v1alpha1.go
+++ b/internal/server/create_role_v1alpha1.go
@@ -6,7 +6,7 @@ import (
 
 	"connectrpc.com/connect"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) CreateRole(
diff --git a/internal/server/delete_analysistemplate_v1alpha1.go b/internal/server/delete_analysistemplate_v1alpha1.go
index f8aceec3..e935c990 100644
--- a/internal/server/delete_analysistemplate_v1alpha1.go
+++ b/internal/server/delete_analysistemplate_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 	"connectrpc.com/connect"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) DeleteAnalysisTemplate(
diff --git a/internal/server/delete_clusteranalysistemplate_v1alpha1.go b/internal/server/delete_clusteranalysistemplate_v1alpha1.go
index 35793de4..2242f8f0 100644
--- a/internal/server/delete_clusteranalysistemplate_v1alpha1.go
+++ b/internal/server/delete_clusteranalysistemplate_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 	"connectrpc.com/connect"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) DeleteClusterAnalysisTemplate(
diff --git a/internal/server/delete_credentials_v1alpha1.go b/internal/server/delete_credentials_v1alpha1.go
index 63d5b68c..c568e9dc 100644
--- a/internal/server/delete_credentials_v1alpha1.go
+++ b/internal/server/delete_credentials_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) DeleteCredentials(
diff --git a/internal/server/delete_freight_v1alpha1.go b/internal/server/delete_freight_v1alpha1.go
index ed49ac7a..1f30a738 100644
--- a/internal/server/delete_freight_v1alpha1.go
+++ b/internal/server/delete_freight_v1alpha1.go
@@ -7,7 +7,7 @@ import (
 
 	"connectrpc.com/connect"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) DeleteFreight(
diff --git a/internal/server/delete_project_secret_v1alpha1.go b/internal/server/delete_project_secret_v1alpha1.go
index d7abb4b1..0ebab4d3 100644
--- a/internal/server/delete_project_secret_v1alpha1.go
+++ b/internal/server/delete_project_secret_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) DeleteProjectSecret(
diff --git a/internal/server/delete_project_v1alpha1.go b/internal/server/delete_project_v1alpha1.go
index 685fce55..0dcb65da 100644
--- a/internal/server/delete_project_v1alpha1.go
+++ b/internal/server/delete_project_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) DeleteProject(
diff --git a/internal/server/delete_resource_v1alpha1.go b/internal/server/delete_resource_v1alpha1.go
index 66bf1898..e9cddbf3 100644
--- a/internal/server/delete_resource_v1alpha1.go
+++ b/internal/server/delete_resource_v1alpha1.go
@@ -8,7 +8,7 @@ import (
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	sigyaml "sigs.k8s.io/yaml"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) DeleteResource(
diff --git a/internal/server/delete_role_v1alpha1.go b/internal/server/delete_role_v1alpha1.go
index bc4e47d6..db013600 100644
--- a/internal/server/delete_role_v1alpha1.go
+++ b/internal/server/delete_role_v1alpha1.go
@@ -6,7 +6,7 @@ import (
 
 	"connectrpc.com/connect"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) DeleteRole(
diff --git a/internal/server/delete_stage_v1alpha1.go b/internal/server/delete_stage_v1alpha1.go
index caef0ba3..98ee1d1e 100644
--- a/internal/server/delete_stage_v1alpha1.go
+++ b/internal/server/delete_stage_v1alpha1.go
@@ -7,8 +7,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) DeleteStage(
diff --git a/internal/server/delete_warehouse_v1alpha1.go b/internal/server/delete_warehouse_v1alpha1.go
index 5a639a22..ada4d5ce 100644
--- a/internal/server/delete_warehouse_v1alpha1.go
+++ b/internal/server/delete_warehouse_v1alpha1.go
@@ -7,8 +7,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) DeleteWarehouse(
diff --git a/internal/server/get_analysisrun_v1alpha1.go b/internal/server/get_analysisrun_v1alpha1.go
index 774d88c3..cae9dead 100644
--- a/internal/server/get_analysisrun_v1alpha1.go
+++ b/internal/server/get_analysisrun_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) GetAnalysisRun(
diff --git a/internal/server/get_analysistemplate_v1alpha1.go b/internal/server/get_analysistemplate_v1alpha1.go
index cc9e5a44..b3320d04 100644
--- a/internal/server/get_analysistemplate_v1alpha1.go
+++ b/internal/server/get_analysistemplate_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) GetAnalysisTemplate(
diff --git a/internal/server/get_clusteranalysistemplate_v1alpha1.go b/internal/server/get_clusteranalysistemplate_v1alpha1.go
index 0a5023d3..0865fcd3 100644
--- a/internal/server/get_clusteranalysistemplate_v1alpha1.go
+++ b/internal/server/get_clusteranalysistemplate_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) GetClusterAnalysisTemplate(
diff --git a/internal/server/get_config_v1alpha1.go b/internal/server/get_config_v1alpha1.go
index 499d7228..fdaf0ceb 100644
--- a/internal/server/get_config_v1alpha1.go
+++ b/internal/server/get_config_v1alpha1.go
@@ -5,8 +5,8 @@ import (
 
 	"connectrpc.com/connect"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	libargocd "github.com/akuity/kargo/internal/argocd"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetConfig(
diff --git a/internal/server/get_credentials_v1alpha1.go b/internal/server/get_credentials_v1alpha1.go
index 3356db03..ee5ee0f8 100644
--- a/internal/server/get_credentials_v1alpha1.go
+++ b/internal/server/get_credentials_v1alpha1.go
@@ -8,9 +8,9 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	libCreds "github.com/akuity/kargo/internal/credentials"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 const redacted = "*** REDACTED ***"
diff --git a/internal/server/get_freight_v1alpha1.go b/internal/server/get_freight_v1alpha1.go
index 24c675f5..1291c846 100644
--- a/internal/server/get_freight_v1alpha1.go
+++ b/internal/server/get_freight_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetFreight(
diff --git a/internal/server/get_project_v1alpha1.go b/internal/server/get_project_v1alpha1.go
index b4665ed8..4b72765f 100644
--- a/internal/server/get_project_v1alpha1.go
+++ b/internal/server/get_project_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetProject(
diff --git a/internal/server/get_promotion_v1alpha1.go b/internal/server/get_promotion_v1alpha1.go
index ab145ea0..48593a43 100644
--- a/internal/server/get_promotion_v1alpha1.go
+++ b/internal/server/get_promotion_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetPromotion(
diff --git a/internal/server/get_public_config_v1alpha1.go b/internal/server/get_public_config_v1alpha1.go
index 639e9432..e8e699dc 100644
--- a/internal/server/get_public_config_v1alpha1.go
+++ b/internal/server/get_public_config_v1alpha1.go
@@ -5,7 +5,7 @@ import (
 
 	"connectrpc.com/connect"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) GetPublicConfig(
diff --git a/internal/server/get_role_v1alpha1.go b/internal/server/get_role_v1alpha1.go
index a654b22c..b1db1aaf 100644
--- a/internal/server/get_role_v1alpha1.go
+++ b/internal/server/get_role_v1alpha1.go
@@ -10,8 +10,8 @@ import (
 	sigyaml "sigs.k8s.io/yaml"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/server/rbac"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetRole(
diff --git a/internal/server/get_stage_v1alpha1.go b/internal/server/get_stage_v1alpha1.go
index 0935cb94..9c38b9c1 100644
--- a/internal/server/get_stage_v1alpha1.go
+++ b/internal/server/get_stage_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetStage(
diff --git a/internal/server/get_version_info_v1alpha1.go b/internal/server/get_version_info_v1alpha1.go
index 43de724d..417f5d66 100644
--- a/internal/server/get_version_info_v1alpha1.go
+++ b/internal/server/get_version_info_v1alpha1.go
@@ -5,7 +5,8 @@ import (
 
 	"connectrpc.com/connect"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/internal/api"
 	"github.com/akuity/kargo/pkg/x/version"
 )
 
@@ -15,7 +16,7 @@ func (s *server) GetVersionInfo(
 ) (*connect.Response[svcv1alpha1.GetVersionInfoResponse], error) {
 	return connect.NewResponse(
 		&svcv1alpha1.GetVersionInfoResponse{
-			VersionInfo: svcv1alpha1.ToVersionProto(version.GetVersion()),
+			VersionInfo: api.ToVersionProto(version.GetVersion()),
 		},
 	), nil
 }
diff --git a/internal/server/get_warehouse_v1alpha1.go b/internal/server/get_warehouse_v1alpha1.go
index 767d9644..802a90f6 100644
--- a/internal/server/get_warehouse_v1alpha1.go
+++ b/internal/server/get_warehouse_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) GetWarehouse(
diff --git a/internal/server/grant_v1alpha1.go b/internal/server/grant_v1alpha1.go
index e313e1df..cf286ff3 100644
--- a/internal/server/grant_v1alpha1.go
+++ b/internal/server/grant_v1alpha1.go
@@ -8,7 +8,7 @@ import (
 	"connectrpc.com/connect"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) Grant(
diff --git a/internal/server/grpc_health.go b/internal/server/grpc_health.go
index d8c579f8..6e32d9b8 100644
--- a/internal/server/grpc_health.go
+++ b/internal/server/grpc_health.go
@@ -3,7 +3,7 @@ package server
 import (
 	"connectrpc.com/grpchealth"
 
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
+	"github.com/akuity/kargo/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 func NewHealthChecker() grpchealth.Checker {
diff --git a/internal/server/kubernetes/client.go b/internal/server/kubernetes/client.go
index f512d54c..1cd42972 100644
--- a/internal/server/kubernetes/client.go
+++ b/internal/server/kubernetes/client.go
@@ -25,8 +25,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
 	libCluster "sigs.k8s.io/controller-runtime/pkg/cluster"
 
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/indexer"
 	"github.com/akuity/kargo/internal/logging"
 	"github.com/akuity/kargo/internal/server/user"
diff --git a/internal/server/list_analysistemplates_v1alpha1.go b/internal/server/list_analysistemplates_v1alpha1.go
index f9477e8f..acd6c868 100644
--- a/internal/server/list_analysistemplates_v1alpha1.go
+++ b/internal/server/list_analysistemplates_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) ListAnalysisTemplates(
diff --git a/internal/server/list_clusteranalysistemplates_v1alpha1.go b/internal/server/list_clusteranalysistemplates_v1alpha1.go
index bfe2bfd8..224c11e8 100644
--- a/internal/server/list_clusteranalysistemplates_v1alpha1.go
+++ b/internal/server/list_clusteranalysistemplates_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 
 	"connectrpc.com/connect"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func (s *server) ListClusterAnalysisTemplates(
diff --git a/internal/server/list_credentials_v1alpha1.go b/internal/server/list_credentials_v1alpha1.go
index 5371cb9b..238b8b61 100644
--- a/internal/server/list_credentials_v1alpha1.go
+++ b/internal/server/list_credentials_v1alpha1.go
@@ -12,8 +12,8 @@ import (
 	"k8s.io/apimachinery/pkg/selection"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListCredentials(
diff --git a/internal/server/list_images_v1alpha1.go b/internal/server/list_images_v1alpha1.go
index 154135dc..2ff5b561 100644
--- a/internal/server/list_images_v1alpha1.go
+++ b/internal/server/list_images_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListImages(
diff --git a/internal/server/list_project_events_v1alpha1.go b/internal/server/list_project_events_v1alpha1.go
index c590fbc9..d4b8bb3d 100644
--- a/internal/server/list_project_events_v1alpha1.go
+++ b/internal/server/list_project_events_v1alpha1.go
@@ -10,9 +10,9 @@ import (
 	"k8s.io/apimachinery/pkg/fields"
 	"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/indexer"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListProjectEvents(
diff --git a/internal/server/list_project_secrets_v1alpha1.go b/internal/server/list_project_secrets_v1alpha1.go
index 63dc8f7b..563dbcd7 100644
--- a/internal/server/list_project_secrets_v1alpha1.go
+++ b/internal/server/list_project_secrets_v1alpha1.go
@@ -10,8 +10,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListProjectSecrets(
diff --git a/internal/server/list_projects_v1alpha1.go b/internal/server/list_projects_v1alpha1.go
index 0d7e4f3a..114f584e 100644
--- a/internal/server/list_projects_v1alpha1.go
+++ b/internal/server/list_projects_v1alpha1.go
@@ -8,8 +8,8 @@ import (
 
 	"connectrpc.com/connect"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListProjects(
diff --git a/internal/server/list_promotions_v1alpha1.go b/internal/server/list_promotions_v1alpha1.go
index a2487b56..d79f8cf8 100644
--- a/internal/server/list_promotions_v1alpha1.go
+++ b/internal/server/list_promotions_v1alpha1.go
@@ -8,10 +8,10 @@ import (
 	"connectrpc.com/connect"
 	"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"
 	"github.com/akuity/kargo/internal/indexer"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListPromotions(
diff --git a/internal/server/list_roles_v1alpha1.go b/internal/server/list_roles_v1alpha1.go
index b36effd0..0f111a4b 100644
--- a/internal/server/list_roles_v1alpha1.go
+++ b/internal/server/list_roles_v1alpha1.go
@@ -8,7 +8,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) ListRoles(
diff --git a/internal/server/list_stages_v1alpha1.go b/internal/server/list_stages_v1alpha1.go
index 9129fdfc..e75c2424 100644
--- a/internal/server/list_stages_v1alpha1.go
+++ b/internal/server/list_stages_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListStages(
diff --git a/internal/server/list_warehouses_v1alpha1.go b/internal/server/list_warehouses_v1alpha1.go
index 278f8a72..f3fc7148 100644
--- a/internal/server/list_warehouses_v1alpha1.go
+++ b/internal/server/list_warehouses_v1alpha1.go
@@ -7,8 +7,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) ListWarehouses(
diff --git a/internal/server/promote_downstream_v1alpha1.go b/internal/server/promote_downstream_v1alpha1.go
index 24ab0902..909c76ef 100644
--- a/internal/server/promote_downstream_v1alpha1.go
+++ b/internal/server/promote_downstream_v1alpha1.go
@@ -9,9 +9,9 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"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/kargo"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 // PromoteDownstream creates Promotion resources to transition all Stages
diff --git a/internal/server/promote_to_stage_v1alpha1.go b/internal/server/promote_to_stage_v1alpha1.go
index 5eb2d590..7a1e0710 100644
--- a/internal/server/promote_to_stage_v1alpha1.go
+++ b/internal/server/promote_to_stage_v1alpha1.go
@@ -10,12 +10,12 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
 
+	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/event"
 	"github.com/akuity/kargo/internal/kargo"
 	"github.com/akuity/kargo/internal/server/user"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 // PromoteToStage creates a Promotion resource to transition a specified Stage
diff --git a/internal/server/query_freights_v1alpha1.go b/internal/server/query_freights_v1alpha1.go
index a8768e42..4a53688c 100644
--- a/internal/server/query_freights_v1alpha1.go
+++ b/internal/server/query_freights_v1alpha1.go
@@ -13,10 +13,10 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"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"
 	"github.com/akuity/kargo/internal/indexer"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 const (
diff --git a/internal/server/rbac/policy_rules.go b/internal/server/rbac/policy_rules.go
index cd7166fb..79d69951 100644
--- a/internal/server/rbac/policy_rules.go
+++ b/internal/server/rbac/policy_rules.go
@@ -8,8 +8,8 @@ import (
 	rbacv1 "k8s.io/api/rbac/v1"
 	kubeerr "k8s.io/apimachinery/pkg/api/errors"
 
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 )
 
 var (
diff --git a/internal/server/refresh_stage_v1alpha1.go b/internal/server/refresh_stage_v1alpha1.go
index 96bbc472..5b961e6e 100644
--- a/internal/server/refresh_stage_v1alpha1.go
+++ b/internal/server/refresh_stage_v1alpha1.go
@@ -6,8 +6,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) RefreshStage(
diff --git a/internal/server/refresh_warehouse_v1alpha1.go b/internal/server/refresh_warehouse_v1alpha1.go
index cbe42e49..0ade4460 100644
--- a/internal/server/refresh_warehouse_v1alpha1.go
+++ b/internal/server/refresh_warehouse_v1alpha1.go
@@ -6,8 +6,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) RefreshWarehouse(
diff --git a/internal/server/reverify_v1alpha1.go b/internal/server/reverify_v1alpha1.go
index f32c7431..71379a29 100644
--- a/internal/server/reverify_v1alpha1.go
+++ b/internal/server/reverify_v1alpha1.go
@@ -6,8 +6,8 @@ import (
 	"connectrpc.com/connect"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) Reverify(
diff --git a/internal/server/revoke_v1alpha1.go b/internal/server/revoke_v1alpha1.go
index 37aa540a..4db5b85e 100644
--- a/internal/server/revoke_v1alpha1.go
+++ b/internal/server/revoke_v1alpha1.go
@@ -8,7 +8,7 @@ import (
 	"connectrpc.com/connect"
 
 	rbacapi "github.com/akuity/kargo/api/rbac/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) Revoke(
diff --git a/internal/server/server.go b/internal/server/server.go
index 0aa20250..2523c463 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -23,9 +23,11 @@ import (
 	"k8s.io/client-go/tools/record"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	"github.com/akuity/kargo/api/service/v1alpha1/svcv1alpha1connect"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/api"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	rollouts "github.com/akuity/kargo/internal/api/stubs/rollouts"
 	httputil "github.com/akuity/kargo/internal/http"
 	"github.com/akuity/kargo/internal/logging"
 	"github.com/akuity/kargo/internal/server/config"
@@ -34,7 +36,6 @@ import (
 	"github.com/akuity/kargo/internal/server/option"
 	"github.com/akuity/kargo/internal/server/rbac"
 	"github.com/akuity/kargo/internal/server/validation"
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 var (
@@ -133,19 +134,19 @@ type server struct {
 		context.Context,
 		client.Client,
 		types.NamespacedName,
-	) (*rollouts.AnalysisTemplate, error)
+	) (*rolloutsapi.AnalysisTemplate, error)
 
 	getClusterAnalysisTemplateFn func(
 		context.Context,
 		client.Client,
 		string,
-	) (*rollouts.ClusterAnalysisTemplate, error)
+	) (*rolloutsapi.ClusterAnalysisTemplate, error)
 
 	getAnalysisRunFn func(
 		context.Context,
 		client.Client,
 		types.NamespacedName,
-	) (*rollouts.AnalysisRun, error)
+	) (*rolloutsapi.AnalysisRun, error)
 
 	// Special authorizations:
 	authorizeFn func(
diff --git a/internal/server/update_credentials_v1alpha1.go b/internal/server/update_credentials_v1alpha1.go
index 9bf7c772..7b705db8 100644
--- a/internal/server/update_credentials_v1alpha1.go
+++ b/internal/server/update_credentials_v1alpha1.go
@@ -8,9 +8,9 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	libCreds "github.com/akuity/kargo/internal/credentials"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 type credentialsUpdate struct {
diff --git a/internal/server/update_freight_alias_v1alpha1.go b/internal/server/update_freight_alias_v1alpha1.go
index f598562f..0ceb52cf 100644
--- a/internal/server/update_freight_alias_v1alpha1.go
+++ b/internal/server/update_freight_alias_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 // UpdateFreightAlias updates a piece of Freight's human-friendly alias.
diff --git a/internal/server/update_project_secret_v1alpha1.go b/internal/server/update_project_secret_v1alpha1.go
index 961c8613..e80a371d 100644
--- a/internal/server/update_project_secret_v1alpha1.go
+++ b/internal/server/update_project_secret_v1alpha1.go
@@ -9,8 +9,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) UpdateProjectSecret(
diff --git a/internal/server/update_resource_v1alpha1.go b/internal/server/update_resource_v1alpha1.go
index 87c0563f..948a9ff6 100644
--- a/internal/server/update_resource_v1alpha1.go
+++ b/internal/server/update_resource_v1alpha1.go
@@ -9,7 +9,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	sigyaml "sigs.k8s.io/yaml"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) UpdateResource(
diff --git a/internal/server/update_role_v1alpha1.go b/internal/server/update_role_v1alpha1.go
index 9be10be5..a69cfacc 100644
--- a/internal/server/update_role_v1alpha1.go
+++ b/internal/server/update_role_v1alpha1.go
@@ -6,7 +6,7 @@ import (
 
 	"connectrpc.com/connect"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 )
 
 func (s *server) UpdateRole(
diff --git a/internal/server/watch_promotion_v1alpha1.go b/internal/server/watch_promotion_v1alpha1.go
index 2042490b..05e6e77f 100644
--- a/internal/server/watch_promotion_v1alpha1.go
+++ b/internal/server/watch_promotion_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) WatchPromotion(
diff --git a/internal/server/watch_promotions_v1alpha1.go b/internal/server/watch_promotions_v1alpha1.go
index 9fd4d146..f84a529f 100644
--- a/internal/server/watch_promotions_v1alpha1.go
+++ b/internal/server/watch_promotions_v1alpha1.go
@@ -10,8 +10,8 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) WatchPromotions(
diff --git a/internal/server/watch_stages_v1alpha1.go b/internal/server/watch_stages_v1alpha1.go
index df4dd929..8206f62b 100644
--- a/internal/server/watch_stages_v1alpha1.go
+++ b/internal/server/watch_stages_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	libClient "sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) WatchStages(
diff --git a/internal/server/watch_warehouses_v1alpha1.go b/internal/server/watch_warehouses_v1alpha1.go
index dc0b3e76..2f791212 100644
--- a/internal/server/watch_warehouses_v1alpha1.go
+++ b/internal/server/watch_warehouses_v1alpha1.go
@@ -11,8 +11,8 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	libClient "sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func (s *server) WatchWarehouses(
diff --git a/ui/package.json b/ui/package.json
index e38600b8..d25b66d5 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -31,22 +31,22 @@
     "autoprefixer": "^10.4.20",
     "cssnano": "^7.0.6",
     "eslint": "^9.17.0",
-    "eslint-config-prettier": "^9.1.0",
+    "eslint-config-prettier": "^10.1.1",
     "eslint-plugin-import": "^2.31.0",
     "eslint-plugin-prettier": "^5.2.3",
     "eslint-plugin-react": "^7.37.4",
     "eslint-plugin-react-refresh": "^0.4.19",
-    "globals": "^15.13.0",
+    "globals": "^16.0.0",
     "json-stable-stringify": "^1.1.1",
     "less": "^4.2.2",
     "postcss": "^8.4.49",
     "prettier": "^3.4.2",
-    "tailwindcss": "^3.4.16",
+    "tailwindcss": "^3.4.17",
     "typescript": "^5.7.3",
     "vite": "^6.0.9",
     "vite-plugin-compression": "^0.5.1",
     "vite-tsconfig-paths": "^5.1.4",
-    "vitest": "^2.1.9",
+    "vitest": "^3.0.8",
     "zx": "^8.3.2"
   },
   "packageManager": "pnpm@9.0.3",
@@ -60,7 +60,7 @@
     "@fortawesome/free-brands-svg-icons": "^6.7.1",
     "@fortawesome/free-solid-svg-icons": "^6.7.1",
     "@fortawesome/react-fontawesome": "^0.2.2",
-    "@hookform/resolvers": "^3.9.1",
+    "@hookform/resolvers": "^4.1.3",
     "@monaco-editor/react": "^4.6.0",
     "@rjsf/antd": "^5.23.2",
     "@rjsf/core": "^5.23.2",
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
index f45d6d3f..4ffb2908 100644
--- a/ui/pnpm-lock.yaml
+++ b/ui/pnpm-lock.yaml
@@ -36,8 +36,8 @@ importers:
         specifier: ^0.2.2
         version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0)
       '@hookform/resolvers':
-        specifier: ^3.9.1
-        version: 3.9.1(react-hook-form@7.54.2(react@19.0.0))
+        specifier: ^4.1.3
+        version: 4.1.3(react-hook-form@7.54.2(react@19.0.0))
       '@monaco-editor/react':
         specifier: ^4.6.0
         version: 4.6.0(monaco-editor@0.52.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -169,14 +169,14 @@ importers:
         specifier: ^9.17.0
         version: 9.17.0(jiti@1.21.7)
       eslint-config-prettier:
-        specifier: ^9.1.0
-        version: 9.1.0(eslint@9.17.0(jiti@1.21.7))
+        specifier: ^10.1.1
+        version: 10.1.1(eslint@9.17.0(jiti@1.21.7))
       eslint-plugin-import:
         specifier: ^2.31.0
         version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))
       eslint-plugin-prettier:
         specifier: ^5.2.3
-        version: 5.2.3(eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2)
+        version: 5.2.3(eslint-config-prettier@10.1.1(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2)
       eslint-plugin-react:
         specifier: ^7.37.4
         version: 7.37.4(eslint@9.17.0(jiti@1.21.7))
@@ -184,8 +184,8 @@ importers:
         specifier: ^0.4.19
         version: 0.4.19(eslint@9.17.0(jiti@1.21.7))
       globals:
-        specifier: ^15.13.0
-        version: 15.14.0
+        specifier: ^16.0.0
+        version: 16.0.0
       json-stable-stringify:
         specifier: ^1.1.1
         version: 1.2.1
@@ -199,7 +199,7 @@ importers:
         specifier: ^3.4.2
         version: 3.4.2
       tailwindcss:
-        specifier: ^3.4.16
+        specifier: ^3.4.17
         version: 3.4.17
       typescript:
         specifier: ^5.7.3
@@ -214,8 +214,8 @@ importers:
         specifier: ^5.1.4
         version: 5.1.4(typescript@5.7.3)(vite@6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0))
       vitest:
-        specifier: ^2.1.9
-        version: 2.1.9(@types/node@22.10.5)(less@4.2.2)
+        specifier: ^3.0.8
+        version: 3.0.8(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0)
       zx:
         specifier: ^8.3.2
         version: 8.3.2
@@ -399,204 +399,102 @@ packages:
   '@emotion/unitless@0.7.5':
     resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==}
 
-  '@esbuild/aix-ppc64@0.21.5':
-    resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [aix]
-
   '@esbuild/aix-ppc64@0.24.2':
     resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
     engines: {node: '>=18'}
     cpu: [ppc64]
     os: [aix]
 
-  '@esbuild/android-arm64@0.21.5':
-    resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [android]
-
   '@esbuild/android-arm64@0.24.2':
     resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [android]
 
-  '@esbuild/android-arm@0.21.5':
-    resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [android]
-
   '@esbuild/android-arm@0.24.2':
     resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
     engines: {node: '>=18'}
     cpu: [arm]
     os: [android]
 
-  '@esbuild/android-x64@0.21.5':
-    resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [android]
-
   '@esbuild/android-x64@0.24.2':
     resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [android]
 
-  '@esbuild/darwin-arm64@0.21.5':
-    resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [darwin]
-
   '@esbuild/darwin-arm64@0.24.2':
     resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [darwin]
 
-  '@esbuild/darwin-x64@0.21.5':
-    resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [darwin]
-
   '@esbuild/darwin-x64@0.24.2':
     resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [darwin]
 
-  '@esbuild/freebsd-arm64@0.21.5':
-    resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [freebsd]
-
   '@esbuild/freebsd-arm64@0.24.2':
     resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [freebsd]
 
-  '@esbuild/freebsd-x64@0.21.5':
-    resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [freebsd]
-
   '@esbuild/freebsd-x64@0.24.2':
     resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [freebsd]
 
-  '@esbuild/linux-arm64@0.21.5':
-    resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [linux]
-
   '@esbuild/linux-arm64@0.24.2':
     resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [linux]
 
-  '@esbuild/linux-arm@0.21.5':
-    resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [linux]
-
   '@esbuild/linux-arm@0.24.2':
     resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
     engines: {node: '>=18'}
     cpu: [arm]
     os: [linux]
 
-  '@esbuild/linux-ia32@0.21.5':
-    resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [linux]
-
   '@esbuild/linux-ia32@0.24.2':
     resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
     engines: {node: '>=18'}
     cpu: [ia32]
     os: [linux]
 
-  '@esbuild/linux-loong64@0.21.5':
-    resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
-    engines: {node: '>=12'}
-    cpu: [loong64]
-    os: [linux]
-
   '@esbuild/linux-loong64@0.24.2':
     resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
     engines: {node: '>=18'}
     cpu: [loong64]
     os: [linux]
 
-  '@esbuild/linux-mips64el@0.21.5':
-    resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
-    engines: {node: '>=12'}
-    cpu: [mips64el]
-    os: [linux]
-
   '@esbuild/linux-mips64el@0.24.2':
     resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
     engines: {node: '>=18'}
     cpu: [mips64el]
     os: [linux]
 
-  '@esbuild/linux-ppc64@0.21.5':
-    resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [linux]
-
   '@esbuild/linux-ppc64@0.24.2':
     resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
     engines: {node: '>=18'}
     cpu: [ppc64]
     os: [linux]
 
-  '@esbuild/linux-riscv64@0.21.5':
-    resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
-    engines: {node: '>=12'}
-    cpu: [riscv64]
-    os: [linux]
-
   '@esbuild/linux-riscv64@0.24.2':
     resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
     engines: {node: '>=18'}
     cpu: [riscv64]
     os: [linux]
 
-  '@esbuild/linux-s390x@0.21.5':
-    resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
-    engines: {node: '>=12'}
-    cpu: [s390x]
-    os: [linux]
-
   '@esbuild/linux-s390x@0.24.2':
     resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
     engines: {node: '>=18'}
     cpu: [s390x]
     os: [linux]
 
-  '@esbuild/linux-x64@0.21.5':
-    resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [linux]
-
   '@esbuild/linux-x64@0.24.2':
     resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
     engines: {node: '>=18'}
@@ -609,12 +507,6 @@ packages:
     cpu: [arm64]
     os: [netbsd]
 
-  '@esbuild/netbsd-x64@0.21.5':
-    resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [netbsd]
-
   '@esbuild/netbsd-x64@0.24.2':
     resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
     engines: {node: '>=18'}
@@ -627,60 +519,30 @@ packages:
     cpu: [arm64]
     os: [openbsd]
 
-  '@esbuild/openbsd-x64@0.21.5':
-    resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [openbsd]
-
   '@esbuild/openbsd-x64@0.24.2':
     resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [openbsd]
 
-  '@esbuild/sunos-x64@0.21.5':
-    resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [sunos]
-
   '@esbuild/sunos-x64@0.24.2':
     resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [sunos]
 
-  '@esbuild/win32-arm64@0.21.5':
-    resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [win32]
-
   '@esbuild/win32-arm64@0.24.2':
     resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [win32]
 
-  '@esbuild/win32-ia32@0.21.5':
-    resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [win32]
-
   '@esbuild/win32-ia32@0.24.2':
     resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
     engines: {node: '>=18'}
     cpu: [ia32]
     os: [win32]
 
-  '@esbuild/win32-x64@0.21.5':
-    resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [win32]
-
   '@esbuild/win32-x64@0.24.2':
     resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
     engines: {node: '>=18'}
@@ -756,8 +618,8 @@ packages:
       '@fortawesome/fontawesome-svg-core': ~1 || ~6
       react: '>=16.3'
 
-  '@hookform/resolvers@3.9.1':
-    resolution: {integrity: sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==}
+  '@hookform/resolvers@4.1.3':
+    resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==}
     peerDependencies:
       react-hook-form: ^7.0.0
 
@@ -933,194 +795,102 @@ packages:
     cpu: [arm]
     os: [android]
 
-  '@rollup/rollup-android-arm-eabi@4.34.2':
-    resolution: {integrity: sha512-6Fyg9yQbwJR+ykVdT9sid1oc2ewejS6h4wzQltmJfSW53N60G/ah9pngXGANdy9/aaE/TcUFpWosdm7JXS1WTQ==}
-    cpu: [arm]
-    os: [android]
-
   '@rollup/rollup-android-arm64@4.31.0':
     resolution: {integrity: sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==}
     cpu: [arm64]
     os: [android]
 
-  '@rollup/rollup-android-arm64@4.34.2':
-    resolution: {integrity: sha512-K5GfWe+vtQ3kyEbihrimM38UgX57UqHp+oME7X/EX9Im6suwZfa7Hsr8AtzbJvukTpwMGs+4s29YMSO3rwWtsw==}
-    cpu: [arm64]
-    os: [android]
-
   '@rollup/rollup-darwin-arm64@4.31.0':
     resolution: {integrity: sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==}
     cpu: [arm64]
     os: [darwin]
 
-  '@rollup/rollup-darwin-arm64@4.34.2':
-    resolution: {integrity: sha512-PSN58XG/V/tzqDb9kDGutUruycgylMlUE59f40ny6QIRNsTEIZsrNQTJKUN2keMMSmlzgunMFqyaGLmly39sug==}
-    cpu: [arm64]
-    os: [darwin]
-
   '@rollup/rollup-darwin-x64@4.31.0':
     resolution: {integrity: sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==}
     cpu: [x64]
     os: [darwin]
 
-  '@rollup/rollup-darwin-x64@4.34.2':
-    resolution: {integrity: sha512-gQhK788rQJm9pzmXyfBB84VHViDERhAhzGafw+E5mUpnGKuxZGkMVDa3wgDFKT6ukLC5V7QTifzsUKdNVxp5qQ==}
-    cpu: [x64]
-    os: [darwin]
-
   '@rollup/rollup-freebsd-arm64@4.31.0':
     resolution: {integrity: sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==}
     cpu: [arm64]
     os: [freebsd]
 
-  '@rollup/rollup-freebsd-arm64@4.34.2':
-    resolution: {integrity: sha512-eiaHgQwGPpxLC3+zTAcdKl4VsBl3r0AiJOd1Um/ArEzAjN/dbPK1nROHrVkdnoE6p7Svvn04w3f/jEZSTVHunA==}
-    cpu: [arm64]
-    os: [freebsd]
-
   '@rollup/rollup-freebsd-x64@4.31.0':
     resolution: {integrity: sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==}
     cpu: [x64]
     os: [freebsd]
 
-  '@rollup/rollup-freebsd-x64@4.34.2':
-    resolution: {integrity: sha512-lhdiwQ+jf8pewYOTG4bag0Qd68Jn1v2gO1i0mTuiD+Qkt5vNfHVK/jrT7uVvycV8ZchlzXp5HDVmhpzjC6mh0g==}
-    cpu: [x64]
-    os: [freebsd]
-
   '@rollup/rollup-linux-arm-gnueabihf@4.31.0':
     resolution: {integrity: sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==}
     cpu: [arm]
     os: [linux]
 
-  '@rollup/rollup-linux-arm-gnueabihf@4.34.2':
-    resolution: {integrity: sha512-lfqTpWjSvbgQP1vqGTXdv+/kxIznKXZlI109WkIFPbud41bjigjNmOAAKoazmRGx+k9e3rtIdbq2pQZPV1pMig==}
-    cpu: [arm]
-    os: [linux]
-
   '@rollup/rollup-linux-arm-musleabihf@4.31.0':
     resolution: {integrity: sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==}
     cpu: [arm]
     os: [linux]
 
-  '@rollup/rollup-linux-arm-musleabihf@4.34.2':
-    resolution: {integrity: sha512-RGjqULqIurqqv+NJTyuPgdZhka8ImMLB32YwUle2BPTDqDoXNgwFjdjQC59FbSk08z0IqlRJjrJ0AvDQ5W5lpw==}
-    cpu: [arm]
-    os: [linux]
-
   '@rollup/rollup-linux-arm64-gnu@4.31.0':
     resolution: {integrity: sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==}
     cpu: [arm64]
     os: [linux]
 
-  '@rollup/rollup-linux-arm64-gnu@4.34.2':
-    resolution: {integrity: sha512-ZvkPiheyXtXlFqHpsdgscx+tZ7hoR59vOettvArinEspq5fxSDSgfF+L5wqqJ9R4t+n53nyn0sKxeXlik7AY9Q==}
-    cpu: [arm64]
-    os: [linux]
-
   '@rollup/rollup-linux-arm64-musl@4.31.0':
     resolution: {integrity: sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==}
     cpu: [arm64]
     os: [linux]
 
-  '@rollup/rollup-linux-arm64-musl@4.34.2':
-    resolution: {integrity: sha512-UlFk+E46TZEoxD9ufLKDBzfSG7Ki03fo6hsNRRRHF+KuvNZ5vd1RRVQm8YZlGsjcJG8R252XFK0xNPay+4WV7w==}
-    cpu: [arm64]
-    os: [linux]
-
   '@rollup/rollup-linux-loongarch64-gnu@4.31.0':
     resolution: {integrity: sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==}
     cpu: [loong64]
     os: [linux]
 
-  '@rollup/rollup-linux-loongarch64-gnu@4.34.2':
-    resolution: {integrity: sha512-hJhfsD9ykx59jZuuoQgYT1GEcNNi3RCoEmbo5OGfG8RlHOiVS7iVNev9rhLKh7UBYq409f4uEw0cclTXx8nh8Q==}
-    cpu: [loong64]
-    os: [linux]
-
   '@rollup/rollup-linux-powerpc64le-gnu@4.31.0':
     resolution: {integrity: sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==}
     cpu: [ppc64]
     os: [linux]
 
-  '@rollup/rollup-linux-powerpc64le-gnu@4.34.2':
-    resolution: {integrity: sha512-g/O5IpgtrQqPegvqopvmdCF9vneLE7eqYfdPWW8yjPS8f63DNam3U4ARL1PNNB64XHZDHKpvO2Giftf43puB8Q==}
-    cpu: [ppc64]
-    os: [linux]
-
   '@rollup/rollup-linux-riscv64-gnu@4.31.0':
     resolution: {integrity: sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==}
     cpu: [riscv64]
     os: [linux]
 
-  '@rollup/rollup-linux-riscv64-gnu@4.34.2':
-    resolution: {integrity: sha512-bSQijDC96M6PuooOuXHpvXUYiIwsnDmqGU8+br2U7iPoykNi9JtMUpN7K6xml29e0evK0/g0D1qbAUzWZFHY5Q==}
-    cpu: [riscv64]
-    os: [linux]
-
   '@rollup/rollup-linux-s390x-gnu@4.31.0':
     resolution: {integrity: sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==}
     cpu: [s390x]
     os: [linux]
 
-  '@rollup/rollup-linux-s390x-gnu@4.34.2':
-    resolution: {integrity: sha512-49TtdeVAsdRuiUHXPrFVucaP4SivazetGUVH8CIxVsNsaPHV4PFkpLmH9LeqU/R4Nbgky9lzX5Xe1NrzLyraVA==}
-    cpu: [s390x]
-    os: [linux]
-
   '@rollup/rollup-linux-x64-gnu@4.31.0':
     resolution: {integrity: sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==}
     cpu: [x64]
     os: [linux]
 
-  '@rollup/rollup-linux-x64-gnu@4.34.2':
-    resolution: {integrity: sha512-j+jFdfOycLIQ7FWKka9Zd3qvsIyugg5LeZuHF6kFlXo6MSOc6R1w37YUVy8VpAKd81LMWGi5g9J25P09M0SSIw==}
-    cpu: [x64]
-    os: [linux]
-
   '@rollup/rollup-linux-x64-musl@4.31.0':
     resolution: {integrity: sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==}
     cpu: [x64]
     os: [linux]
 
-  '@rollup/rollup-linux-x64-musl@4.34.2':
-    resolution: {integrity: sha512-aDPHyM/D2SpXfSNCVWCxyHmOqN9qb7SWkY1+vaXqMNMXslZYnwh9V/UCudl6psyG0v6Ukj7pXanIpfZwCOEMUg==}
-    cpu: [x64]
-    os: [linux]
-
   '@rollup/rollup-win32-arm64-msvc@4.31.0':
     resolution: {integrity: sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==}
     cpu: [arm64]
     os: [win32]
 
-  '@rollup/rollup-win32-arm64-msvc@4.34.2':
-    resolution: {integrity: sha512-LQRkCyUBnAo7r8dbEdtNU08EKLCJMgAk2oP5H3R7BnUlKLqgR3dUjrLBVirmc1RK6U6qhtDw29Dimeer8d5hzQ==}
-    cpu: [arm64]
-    os: [win32]
-
   '@rollup/rollup-win32-ia32-msvc@4.31.0':
     resolution: {integrity: sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==}
     cpu: [ia32]
     os: [win32]
 
-  '@rollup/rollup-win32-ia32-msvc@4.34.2':
-    resolution: {integrity: sha512-wt8OhpQUi6JuPFkm1wbVi1BByeag87LDFzeKSXzIdGcX4bMLqORTtKxLoCbV57BHYNSUSOKlSL4BYYUghainYA==}
-    cpu: [ia32]
-    os: [win32]
-
   '@rollup/rollup-win32-x64-msvc@4.31.0':
     resolution: {integrity: sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==}
     cpu: [x64]
     os: [win32]
 
-  '@rollup/rollup-win32-x64-msvc@4.34.2':
-    resolution: {integrity: sha512-rUrqINax0TvrPBXrFKg0YbQx18NpPN3NNrgmaao9xRNbTwek7lOXObhx8tQy8gelmQ/gLaGy1WptpU2eKJZImg==}
-    cpu: [x64]
-    os: [win32]
-
   '@rtsao/scc@1.1.0':
     resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
 
+  '@standard-schema/utils@0.3.0':
+    resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
+
   '@tanstack/query-core@5.62.15':
     resolution: {integrity: sha512-wT20X14CxcWY8YLJ/1pnsXn/y1Q2uRJZYWW93PWRtZt+3/JlGZyiyTcO4pGnqycnP7CokCROAyatsraosqZsDA==}
 
@@ -1296,34 +1066,34 @@ packages:
     peerDependencies:
       vite: ^4.2.0 || ^5.0.0 || ^6.0.0
 
-  '@vitest/expect@2.1.9':
-    resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==}
+  '@vitest/expect@3.0.8':
+    resolution: {integrity: sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==}
 
-  '@vitest/mocker@2.1.9':
-    resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==}
+  '@vitest/mocker@3.0.8':
+    resolution: {integrity: sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==}
     peerDependencies:
       msw: ^2.4.9
-      vite: ^5.0.0
+      vite: ^5.0.0 || ^6.0.0
     peerDependenciesMeta:
       msw:
         optional: true
       vite:
         optional: true
 
-  '@vitest/pretty-format@2.1.9':
-    resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==}
+  '@vitest/pretty-format@3.0.8':
+    resolution: {integrity: sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==}
 
-  '@vitest/runner@2.1.9':
-    resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==}
+  '@vitest/runner@3.0.8':
+    resolution: {integrity: sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==}
 
-  '@vitest/snapshot@2.1.9':
-    resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==}
+  '@vitest/snapshot@3.0.8':
+    resolution: {integrity: sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==}
 
-  '@vitest/spy@2.1.9':
-    resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==}
+  '@vitest/spy@3.0.8':
+    resolution: {integrity: sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==}
 
-  '@vitest/utils@2.1.9':
-    resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==}
+  '@vitest/utils@3.0.8':
+    resolution: {integrity: sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==}
 
   '@xyflow/react@12.3.6':
     resolution: {integrity: sha512-9GS+cz8hDZahpvTrVCmySAEgKUL8oN4b2q1DluHrKtkqhAMWfH2s7kblhbM4Y4Y4SUnH2lt4drXKZ/4/Lot/2Q==}
@@ -1503,8 +1273,8 @@ packages:
   caniuse-lite@1.0.30001690:
     resolution: {integrity: sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==}
 
-  chai@5.1.2:
-    resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==}
+  chai@5.2.0:
+    resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
     engines: {node: '>=12'}
 
   chalk@4.1.2:
@@ -1852,11 +1622,6 @@ packages:
     resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
     engines: {node: '>= 0.4'}
 
-  esbuild@0.21.5:
-    resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
-    engines: {node: '>=12'}
-    hasBin: true
-
   esbuild@0.24.2:
     resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
     engines: {node: '>=18'}
@@ -1870,8 +1635,8 @@ packages:
     resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
     engines: {node: '>=10'}
 
-  eslint-config-prettier@9.1.0:
-    resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==}
+  eslint-config-prettier@10.1.1:
+    resolution: {integrity: sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==}
     hasBin: true
     peerDependencies:
       eslint: '>=7.0.0'
@@ -1983,8 +1748,8 @@ packages:
   eventemitter3@4.0.7:
     resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
 
-  expect-type@1.1.0:
-    resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==}
+  expect-type@1.2.0:
+    resolution: {integrity: sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==}
     engines: {node: '>=12.0.0'}
 
   fast-deep-equal@3.1.3:
@@ -2036,8 +1801,8 @@ packages:
     resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
     engines: {node: '>= 0.4'}
 
-  foreground-child@3.3.0:
-    resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+  foreground-child@3.3.1:
+    resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
     engines: {node: '>=14'}
 
   fraction.js@4.3.7:
@@ -2108,8 +1873,8 @@ packages:
     resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
     engines: {node: '>=18'}
 
-  globals@15.14.0:
-    resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==}
+  globals@16.0.0:
+    resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==}
     engines: {node: '>=18'}
 
   globalthis@1.0.4:
@@ -2642,8 +2407,8 @@ packages:
     resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
     engines: {node: '>=16 || 14 >=14.18'}
 
-  pathe@1.1.2:
-    resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+  pathe@2.0.3:
+    resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
 
   pathval@2.0.0:
     resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
@@ -3272,11 +3037,6 @@ packages:
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
 
-  rollup@4.34.2:
-    resolution: {integrity: sha512-sBDUoxZEaqLu9QeNalL8v3jw6WjPku4wfZGyTU7l7m1oC+rpRihXc/n/H+4148ZkGz5Xli8CHMns//fFGKvpIQ==}
-    engines: {node: '>=18.0.0', npm: '>=8.0.0'}
-    hasBin: true
-
   run-parallel@1.2.0:
     resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
 
@@ -3380,8 +3140,8 @@ packages:
   state-local@1.0.7:
     resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
 
-  std-env@3.8.0:
-    resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
+  std-env@3.8.1:
+    resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==}
 
   string-convert@0.2.1:
     resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==}
@@ -3492,8 +3252,8 @@ packages:
     resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
     engines: {node: ^18.0.0 || >=20.0.0}
 
-  tinyrainbow@1.2.0:
-    resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==}
+  tinyrainbow@2.0.0:
+    resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
     engines: {node: '>=14.0.0'}
 
   tinyspy@3.0.2:
@@ -3613,9 +3373,9 @@ packages:
   victory-vendor@36.9.2:
     resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==}
 
-  vite-node@2.1.9:
-    resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==}
-    engines: {node: ^18.0.0 || >=20.0.0}
+  vite-node@3.0.8:
+    resolution: {integrity: sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==}
+    engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
 
   vite-plugin-compression@0.5.1:
@@ -3636,37 +3396,6 @@ packages:
       vite:
         optional: true
 
-  vite@5.4.14:
-    resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
-    engines: {node: ^18.0.0 || >=20.0.0}
-    hasBin: true
-    peerDependencies:
-      '@types/node': ^18.0.0 || >=20.0.0
-      less: '*'
-      lightningcss: ^1.21.0
-      sass: '*'
-      sass-embedded: '*'
-      stylus: '*'
-      sugarss: '*'
-      terser: ^5.4.0
-    peerDependenciesMeta:
-      '@types/node':
-        optional: true
-      less:
-        optional: true
-      lightningcss:
-        optional: true
-      sass:
-        optional: true
-      sass-embedded:
-        optional: true
-      stylus:
-        optional: true
-      sugarss:
-        optional: true
-      terser:
-        optional: true
-
   vite@6.0.9:
     resolution: {integrity: sha512-MSgUxHcaXLtnBPktkbUSoQUANApKYuxZ6DrbVENlIorbhL2dZydTLaZ01tjUoE3szeFzlFk9ANOKk0xurh4MKA==}
     engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -3707,20 +3436,23 @@ packages:
       yaml:
         optional: true
 
-  vitest@2.1.9:
-    resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==}
-    engines: {node: ^18.0.0 || >=20.0.0}
+  vitest@3.0.8:
+    resolution: {integrity: sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==}
+    engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
     peerDependencies:
       '@edge-runtime/vm': '*'
-      '@types/node': ^18.0.0 || >=20.0.0
-      '@vitest/browser': 2.1.9
-      '@vitest/ui': 2.1.9
+      '@types/debug': ^4.1.12
+      '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+      '@vitest/browser': 3.0.8
+      '@vitest/ui': 3.0.8
       happy-dom: '*'
       jsdom: '*'
     peerDependenciesMeta:
       '@edge-runtime/vm':
         optional: true
+      '@types/debug':
+        optional: true
       '@types/node':
         optional: true
       '@vitest/browser':
@@ -4053,147 +3785,78 @@ snapshots:
 
   '@emotion/unitless@0.7.5': {}
 
-  '@esbuild/aix-ppc64@0.21.5':
-    optional: true
-
   '@esbuild/aix-ppc64@0.24.2':
     optional: true
 
-  '@esbuild/android-arm64@0.21.5':
-    optional: true
-
   '@esbuild/android-arm64@0.24.2':
     optional: true
 
-  '@esbuild/android-arm@0.21.5':
-    optional: true
-
   '@esbuild/android-arm@0.24.2':
     optional: true
 
-  '@esbuild/android-x64@0.21.5':
-    optional: true
-
   '@esbuild/android-x64@0.24.2':
     optional: true
 
-  '@esbuild/darwin-arm64@0.21.5':
-    optional: true
-
   '@esbuild/darwin-arm64@0.24.2':
     optional: true
 
-  '@esbuild/darwin-x64@0.21.5':
-    optional: true
-
   '@esbuild/darwin-x64@0.24.2':
     optional: true
 
-  '@esbuild/freebsd-arm64@0.21.5':
-    optional: true
-
   '@esbuild/freebsd-arm64@0.24.2':
     optional: true
 
-  '@esbuild/freebsd-x64@0.21.5':
-    optional: true
-
   '@esbuild/freebsd-x64@0.24.2':
     optional: true
 
-  '@esbuild/linux-arm64@0.21.5':
-    optional: true
-
   '@esbuild/linux-arm64@0.24.2':
     optional: true
 
-  '@esbuild/linux-arm@0.21.5':
-    optional: true
-
   '@esbuild/linux-arm@0.24.2':
     optional: true
 
-  '@esbuild/linux-ia32@0.21.5':
-    optional: true
-
   '@esbuild/linux-ia32@0.24.2':
     optional: true
 
-  '@esbuild/linux-loong64@0.21.5':
-    optional: true
-
   '@esbuild/linux-loong64@0.24.2':
     optional: true
 
-  '@esbuild/linux-mips64el@0.21.5':
-    optional: true
-
   '@esbuild/linux-mips64el@0.24.2':
     optional: true
 
-  '@esbuild/linux-ppc64@0.21.5':
-    optional: true
-
   '@esbuild/linux-ppc64@0.24.2':
     optional: true
 
-  '@esbuild/linux-riscv64@0.21.5':
-    optional: true
-
   '@esbuild/linux-riscv64@0.24.2':
     optional: true
 
-  '@esbuild/linux-s390x@0.21.5':
-    optional: true
-
   '@esbuild/linux-s390x@0.24.2':
     optional: true
 
-  '@esbuild/linux-x64@0.21.5':
-    optional: true
-
   '@esbuild/linux-x64@0.24.2':
     optional: true
 
   '@esbuild/netbsd-arm64@0.24.2':
     optional: true
 
-  '@esbuild/netbsd-x64@0.21.5':
-    optional: true
-
   '@esbuild/netbsd-x64@0.24.2':
     optional: true
 
   '@esbuild/openbsd-arm64@0.24.2':
     optional: true
 
-  '@esbuild/openbsd-x64@0.21.5':
-    optional: true
-
   '@esbuild/openbsd-x64@0.24.2':
     optional: true
 
-  '@esbuild/sunos-x64@0.21.5':
-    optional: true
-
   '@esbuild/sunos-x64@0.24.2':
     optional: true
 
-  '@esbuild/win32-arm64@0.21.5':
-    optional: true
-
   '@esbuild/win32-arm64@0.24.2':
     optional: true
 
-  '@esbuild/win32-ia32@0.21.5':
-    optional: true
-
   '@esbuild/win32-ia32@0.24.2':
     optional: true
 
-  '@esbuild/win32-x64@0.21.5':
-    optional: true
-
   '@esbuild/win32-x64@0.24.2':
     optional: true
 
@@ -4264,8 +3927,9 @@ snapshots:
       prop-types: 15.8.1
       react: 19.0.0
 
-  '@hookform/resolvers@3.9.1(react-hook-form@7.54.2(react@19.0.0))':
+  '@hookform/resolvers@4.1.3(react-hook-form@7.54.2(react@19.0.0))':
     dependencies:
+      '@standard-schema/utils': 0.3.0
       react-hook-form: 7.54.2(react@19.0.0)
 
   '@humanfs/core@0.19.1': {}
@@ -4462,119 +4126,64 @@ snapshots:
   '@rollup/rollup-android-arm-eabi@4.31.0':
     optional: true
 
-  '@rollup/rollup-android-arm-eabi@4.34.2':
-    optional: true
-
   '@rollup/rollup-android-arm64@4.31.0':
     optional: true
 
-  '@rollup/rollup-android-arm64@4.34.2':
-    optional: true
-
   '@rollup/rollup-darwin-arm64@4.31.0':
     optional: true
 
-  '@rollup/rollup-darwin-arm64@4.34.2':
-    optional: true
-
   '@rollup/rollup-darwin-x64@4.31.0':
     optional: true
 
-  '@rollup/rollup-darwin-x64@4.34.2':
-    optional: true
-
   '@rollup/rollup-freebsd-arm64@4.31.0':
     optional: true
 
-  '@rollup/rollup-freebsd-arm64@4.34.2':
-    optional: true
-
   '@rollup/rollup-freebsd-x64@4.31.0':
     optional: true
 
-  '@rollup/rollup-freebsd-x64@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-arm-gnueabihf@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-arm-gnueabihf@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-arm-musleabihf@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-arm-musleabihf@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-arm64-gnu@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-arm64-gnu@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-arm64-musl@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-arm64-musl@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-loongarch64-gnu@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-loongarch64-gnu@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-powerpc64le-gnu@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-powerpc64le-gnu@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-riscv64-gnu@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-riscv64-gnu@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-s390x-gnu@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-s390x-gnu@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-x64-gnu@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-x64-gnu@4.34.2':
-    optional: true
-
   '@rollup/rollup-linux-x64-musl@4.31.0':
     optional: true
 
-  '@rollup/rollup-linux-x64-musl@4.34.2':
-    optional: true
-
   '@rollup/rollup-win32-arm64-msvc@4.31.0':
     optional: true
 
-  '@rollup/rollup-win32-arm64-msvc@4.34.2':
-    optional: true
-
   '@rollup/rollup-win32-ia32-msvc@4.31.0':
     optional: true
 
-  '@rollup/rollup-win32-ia32-msvc@4.34.2':
-    optional: true
-
   '@rollup/rollup-win32-x64-msvc@4.31.0':
     optional: true
 
-  '@rollup/rollup-win32-x64-msvc@4.34.2':
-    optional: true
-
   '@rtsao/scc@1.1.0': {}
 
+  '@standard-schema/utils@0.3.0': {}
+
   '@tanstack/query-core@5.62.15': {}
 
   '@tanstack/query-devtools@5.62.9': {}
@@ -4789,45 +4398,45 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  '@vitest/expect@2.1.9':
+  '@vitest/expect@3.0.8':
     dependencies:
-      '@vitest/spy': 2.1.9
-      '@vitest/utils': 2.1.9
-      chai: 5.1.2
-      tinyrainbow: 1.2.0
+      '@vitest/spy': 3.0.8
+      '@vitest/utils': 3.0.8
+      chai: 5.2.0
+      tinyrainbow: 2.0.0
 
-  '@vitest/mocker@2.1.9(vite@5.4.14(@types/node@22.10.5)(less@4.2.2))':
+  '@vitest/mocker@3.0.8(vite@6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0))':
     dependencies:
-      '@vitest/spy': 2.1.9
+      '@vitest/spy': 3.0.8
       estree-walker: 3.0.3
       magic-string: 0.30.17
     optionalDependencies:
-      vite: 5.4.14(@types/node@22.10.5)(less@4.2.2)
+      vite: 6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0)
 
-  '@vitest/pretty-format@2.1.9':
+  '@vitest/pretty-format@3.0.8':
     dependencies:
-      tinyrainbow: 1.2.0
+      tinyrainbow: 2.0.0
 
-  '@vitest/runner@2.1.9':
+  '@vitest/runner@3.0.8':
     dependencies:
-      '@vitest/utils': 2.1.9
-      pathe: 1.1.2
+      '@vitest/utils': 3.0.8
+      pathe: 2.0.3
 
-  '@vitest/snapshot@2.1.9':
+  '@vitest/snapshot@3.0.8':
     dependencies:
-      '@vitest/pretty-format': 2.1.9
+      '@vitest/pretty-format': 3.0.8
       magic-string: 0.30.17
-      pathe: 1.1.2
+      pathe: 2.0.3
 
-  '@vitest/spy@2.1.9':
+  '@vitest/spy@3.0.8':
     dependencies:
       tinyspy: 3.0.2
 
-  '@vitest/utils@2.1.9':
+  '@vitest/utils@3.0.8':
     dependencies:
-      '@vitest/pretty-format': 2.1.9
+      '@vitest/pretty-format': 3.0.8
       loupe: 3.1.3
-      tinyrainbow: 1.2.0
+      tinyrainbow: 2.0.0
 
   '@xyflow/react@12.3.6(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
     dependencies:
@@ -5098,7 +4707,7 @@ snapshots:
 
   caniuse-lite@1.0.30001690: {}
 
-  chai@5.1.2:
+  chai@5.2.0:
     dependencies:
       assertion-error: 2.0.1
       check-error: 2.1.1
@@ -5543,32 +5152,6 @@ snapshots:
       is-date-object: 1.1.0
       is-symbol: 1.1.1
 
-  esbuild@0.21.5:
-    optionalDependencies:
-      '@esbuild/aix-ppc64': 0.21.5
-      '@esbuild/android-arm': 0.21.5
-      '@esbuild/android-arm64': 0.21.5
-      '@esbuild/android-x64': 0.21.5
-      '@esbuild/darwin-arm64': 0.21.5
-      '@esbuild/darwin-x64': 0.21.5
-      '@esbuild/freebsd-arm64': 0.21.5
-      '@esbuild/freebsd-x64': 0.21.5
-      '@esbuild/linux-arm': 0.21.5
-      '@esbuild/linux-arm64': 0.21.5
-      '@esbuild/linux-ia32': 0.21.5
-      '@esbuild/linux-loong64': 0.21.5
-      '@esbuild/linux-mips64el': 0.21.5
-      '@esbuild/linux-ppc64': 0.21.5
-      '@esbuild/linux-riscv64': 0.21.5
-      '@esbuild/linux-s390x': 0.21.5
-      '@esbuild/linux-x64': 0.21.5
-      '@esbuild/netbsd-x64': 0.21.5
-      '@esbuild/openbsd-x64': 0.21.5
-      '@esbuild/sunos-x64': 0.21.5
-      '@esbuild/win32-arm64': 0.21.5
-      '@esbuild/win32-ia32': 0.21.5
-      '@esbuild/win32-x64': 0.21.5
-
   esbuild@0.24.2:
     optionalDependencies:
       '@esbuild/aix-ppc64': 0.24.2
@@ -5601,7 +5184,7 @@ snapshots:
 
   escape-string-regexp@4.0.0: {}
 
-  eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)):
+  eslint-config-prettier@10.1.1(eslint@9.17.0(jiti@1.21.7)):
     dependencies:
       eslint: 9.17.0(jiti@1.21.7)
 
@@ -5652,14 +5235,14 @@ snapshots:
       - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2):
+  eslint-plugin-prettier@5.2.3(eslint-config-prettier@10.1.1(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2):
     dependencies:
       eslint: 9.17.0(jiti@1.21.7)
       prettier: 3.4.2
       prettier-linter-helpers: 1.0.0
       synckit: 0.9.2
     optionalDependencies:
-      eslint-config-prettier: 9.1.0(eslint@9.17.0(jiti@1.21.7))
+      eslint-config-prettier: 10.1.1(eslint@9.17.0(jiti@1.21.7))
 
   eslint-plugin-react-refresh@0.4.19(eslint@9.17.0(jiti@1.21.7)):
     dependencies:
@@ -5761,7 +5344,7 @@ snapshots:
 
   eventemitter3@4.0.7: {}
 
-  expect-type@1.1.0: {}
+  expect-type@1.2.0: {}
 
   fast-deep-equal@3.1.3: {}
 
@@ -5811,7 +5394,7 @@ snapshots:
     dependencies:
       is-callable: 1.2.7
 
-  foreground-child@3.3.0:
+  foreground-child@3.3.1:
     dependencies:
       cross-spawn: 7.0.6
       signal-exit: 4.1.0
@@ -5887,7 +5470,7 @@ snapshots:
 
   glob@10.4.5:
     dependencies:
-      foreground-child: 3.3.0
+      foreground-child: 3.3.1
       jackspeak: 3.4.3
       minimatch: 9.0.5
       minipass: 7.1.2
@@ -5898,7 +5481,7 @@ snapshots:
 
   globals@14.0.0: {}
 
-  globals@15.14.0: {}
+  globals@16.0.0: {}
 
   globalthis@1.0.4:
     dependencies:
@@ -6434,7 +6017,7 @@ snapshots:
       lru-cache: 10.4.3
       minipass: 7.1.2
 
-  pathe@1.1.2: {}
+  pathe@2.0.3: {}
 
   pathval@2.0.0: {}
 
@@ -7159,31 +6742,6 @@ snapshots:
       '@rollup/rollup-win32-x64-msvc': 4.31.0
       fsevents: 2.3.3
 
-  rollup@4.34.2:
-    dependencies:
-      '@types/estree': 1.0.6
-    optionalDependencies:
-      '@rollup/rollup-android-arm-eabi': 4.34.2
-      '@rollup/rollup-android-arm64': 4.34.2
-      '@rollup/rollup-darwin-arm64': 4.34.2
-      '@rollup/rollup-darwin-x64': 4.34.2
-      '@rollup/rollup-freebsd-arm64': 4.34.2
-      '@rollup/rollup-freebsd-x64': 4.34.2
-      '@rollup/rollup-linux-arm-gnueabihf': 4.34.2
-      '@rollup/rollup-linux-arm-musleabihf': 4.34.2
-      '@rollup/rollup-linux-arm64-gnu': 4.34.2
-      '@rollup/rollup-linux-arm64-musl': 4.34.2
-      '@rollup/rollup-linux-loongarch64-gnu': 4.34.2
-      '@rollup/rollup-linux-powerpc64le-gnu': 4.34.2
-      '@rollup/rollup-linux-riscv64-gnu': 4.34.2
-      '@rollup/rollup-linux-s390x-gnu': 4.34.2
-      '@rollup/rollup-linux-x64-gnu': 4.34.2
-      '@rollup/rollup-linux-x64-musl': 4.34.2
-      '@rollup/rollup-win32-arm64-msvc': 4.34.2
-      '@rollup/rollup-win32-ia32-msvc': 4.34.2
-      '@rollup/rollup-win32-x64-msvc': 4.34.2
-      fsevents: 2.3.3
-
   run-parallel@1.2.0:
     dependencies:
       queue-microtask: 1.2.3
@@ -7299,7 +6857,7 @@ snapshots:
 
   state-local@1.0.7: {}
 
-  std-env@3.8.0: {}
+  std-env@3.8.1: {}
 
   string-convert@0.2.1: {}
 
@@ -7460,7 +7018,7 @@ snapshots:
 
   tinypool@1.0.2: {}
 
-  tinyrainbow@1.2.0: {}
+  tinyrainbow@2.0.0: {}
 
   tinyspy@3.0.2: {}
 
@@ -7595,15 +7153,16 @@ snapshots:
       d3-time: 3.1.0
       d3-timer: 3.0.1
 
-  vite-node@2.1.9(@types/node@22.10.5)(less@4.2.2):
+  vite-node@3.0.8(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0):
     dependencies:
       cac: 6.7.14
       debug: 4.4.0
       es-module-lexer: 1.6.0
-      pathe: 1.1.2
-      vite: 5.4.14(@types/node@22.10.5)(less@4.2.2)
+      pathe: 2.0.3
+      vite: 6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0)
     transitivePeerDependencies:
       - '@types/node'
+      - jiti
       - less
       - lightningcss
       - sass
@@ -7612,6 +7171,8 @@ snapshots:
       - sugarss
       - supports-color
       - terser
+      - tsx
+      - yaml
 
   vite-plugin-compression@0.5.1(vite@6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0)):
     dependencies:
@@ -7637,16 +7198,6 @@ snapshots:
       - supports-color
       - typescript
 
-  vite@5.4.14(@types/node@22.10.5)(less@4.2.2):
-    dependencies:
-      esbuild: 0.21.5
-      postcss: 8.4.49
-      rollup: 4.34.2
-    optionalDependencies:
-      '@types/node': 22.10.5
-      fsevents: 2.3.3
-      less: 4.2.2
-
   vite@6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0):
     dependencies:
       esbuild: 0.24.2
@@ -7659,31 +7210,32 @@ snapshots:
       less: 4.2.2
       yaml: 2.7.0
 
-  vitest@2.1.9(@types/node@22.10.5)(less@4.2.2):
+  vitest@3.0.8(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0):
     dependencies:
-      '@vitest/expect': 2.1.9
-      '@vitest/mocker': 2.1.9(vite@5.4.14(@types/node@22.10.5)(less@4.2.2))
-      '@vitest/pretty-format': 2.1.9
-      '@vitest/runner': 2.1.9
-      '@vitest/snapshot': 2.1.9
-      '@vitest/spy': 2.1.9
-      '@vitest/utils': 2.1.9
-      chai: 5.1.2
+      '@vitest/expect': 3.0.8
+      '@vitest/mocker': 3.0.8(vite@6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0))
+      '@vitest/pretty-format': 3.0.8
+      '@vitest/runner': 3.0.8
+      '@vitest/snapshot': 3.0.8
+      '@vitest/spy': 3.0.8
+      '@vitest/utils': 3.0.8
+      chai: 5.2.0
       debug: 4.4.0
-      expect-type: 1.1.0
+      expect-type: 1.2.0
       magic-string: 0.30.17
-      pathe: 1.1.2
-      std-env: 3.8.0
+      pathe: 2.0.3
+      std-env: 3.8.1
       tinybench: 2.9.0
       tinyexec: 0.3.2
       tinypool: 1.0.2
-      tinyrainbow: 1.2.0
-      vite: 5.4.14(@types/node@22.10.5)(less@4.2.2)
-      vite-node: 2.1.9(@types/node@22.10.5)(less@4.2.2)
+      tinyrainbow: 2.0.0
+      vite: 6.0.9(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0)
+      vite-node: 3.0.8(@types/node@22.10.5)(jiti@1.21.7)(less@4.2.2)(yaml@2.7.0)
       why-is-node-running: 2.3.0
     optionalDependencies:
       '@types/node': 22.10.5
     transitivePeerDependencies:
+      - jiti
       - less
       - lightningcss
       - msw
@@ -7693,6 +7245,8 @@ snapshots:
       - sugarss
       - supports-color
       - terser
+      - tsx
+      - yaml
 
   vscode-jsonrpc@8.2.0: {}
 
diff --git a/ui/src/features/assemble-freight/assemble-freight.tsx b/ui/src/features/assemble-freight/assemble-freight.tsx
index 12feafda..bd47ce83 100644
--- a/ui/src/features/assemble-freight/assemble-freight.tsx
+++ b/ui/src/features/assemble-freight/assemble-freight.tsx
@@ -8,7 +8,7 @@ import { useParams } from 'react-router-dom';
 import yaml from 'yaml';
 
 import { newErrorHandler, newTransportWithAuth } from '@ui/config/transport';
-import { createResource } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { createResource } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import {
   Chart,
   ChartDiscoveryResult,
@@ -20,7 +20,7 @@ import {
   Image,
   ImageDiscoveryResult,
   Warehouse
-} from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { FreightContents } from '../freight-timeline/freight-contents';
 
diff --git a/ui/src/features/assemble-freight/commit-table.tsx b/ui/src/features/assemble-freight/commit-table.tsx
index eaefaa4f..1dc7cf7b 100644
--- a/ui/src/features/assemble-freight/commit-table.tsx
+++ b/ui/src/features/assemble-freight/commit-table.tsx
@@ -1,6 +1,6 @@
 import { Radio, Table } from 'antd';
 
-import { DiscoveredCommit } from '@ui/gen/v1alpha1/generated_pb';
+import { DiscoveredCommit } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 import { TruncatedCopyable } from './truncated-copyable';
diff --git a/ui/src/features/assemble-freight/image-table.tsx b/ui/src/features/assemble-freight/image-table.tsx
index 9d1bcc3e..35fb0853 100644
--- a/ui/src/features/assemble-freight/image-table.tsx
+++ b/ui/src/features/assemble-freight/image-table.tsx
@@ -2,7 +2,7 @@ import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Radio, Table } from 'antd';
 
-import { DiscoveredImageReference } from '@ui/gen/v1alpha1/generated_pb';
+import { DiscoveredImageReference } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 import { TruncatedCopyable } from './truncated-copyable';
diff --git a/ui/src/features/assemble-freight/types.ts b/ui/src/features/assemble-freight/types.ts
index 6d0820a7..101bfa40 100644
--- a/ui/src/features/assemble-freight/types.ts
+++ b/ui/src/features/assemble-freight/types.ts
@@ -4,7 +4,7 @@ import {
   DiscoveredImageReference,
   GitDiscoveryResult,
   ImageDiscoveryResult
-} from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/v1alpha1/generated_pb';
 
 export type DiscoveryResult = ImageDiscoveryResult | ChartDiscoveryResult | GitDiscoveryResult;
 export type FreightInfo = DiscoveredImageReference | string | DiscoveredCommit;
diff --git a/ui/src/features/auth/admin-login.tsx b/ui/src/features/auth/admin-login.tsx
index 2afc1347..2cd982b0 100644
--- a/ui/src/features/auth/admin-login.tsx
+++ b/ui/src/features/auth/admin-login.tsx
@@ -4,7 +4,7 @@ import { Button, Input } from 'antd';
 import { useForm } from 'react-hook-form';
 import { z } from 'zod';
 
-import { adminLogin } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { adminLogin } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import { zodValidators } from '@ui/utils/validators';
 
 import { FieldContainer } from '../common/form/field-container';
diff --git a/ui/src/features/auth/oidc-login.tsx b/ui/src/features/auth/oidc-login.tsx
index f6f3c8be..d259c21d 100644
--- a/ui/src/features/auth/oidc-login.tsx
+++ b/ui/src/features/auth/oidc-login.tsx
@@ -15,7 +15,7 @@ import {
 import React from 'react';
 import { useLocation } from 'react-router-dom';
 
-import { OIDCConfig } from '@ui/gen/service/v1alpha1/service_pb';
+import { OIDCConfig } from '@ui/gen/api/service/v1alpha1/service_pb';
 
 import { useAuthContext } from './context/use-auth-context';
 import {
diff --git a/ui/src/features/auth/oidc-utils.ts b/ui/src/features/auth/oidc-utils.ts
index c1ea81c3..424dab74 100644
--- a/ui/src/features/auth/oidc-utils.ts
+++ b/ui/src/features/auth/oidc-utils.ts
@@ -1,6 +1,6 @@
 import { AuthorizationServer, ClientAuth } from 'oauth4webapi';
 
-import { OIDCConfig } from '@ui/gen/service/v1alpha1/service_pb';
+import { OIDCConfig } from '@ui/gen/api/service/v1alpha1/service_pb';
 
 export const oidcClientAuth: ClientAuth = () => {
   // equivalent function for token_endpoint_auth_method: 'none'
diff --git a/ui/src/features/auth/protected-route.tsx b/ui/src/features/auth/protected-route.tsx
index 7f0b25b0..37030ed6 100644
--- a/ui/src/features/auth/protected-route.tsx
+++ b/ui/src/features/auth/protected-route.tsx
@@ -5,7 +5,7 @@ import { Navigate, Outlet } from 'react-router-dom';
 import { paths } from '@ui/config/paths';
 import { transport, transportWithAuth } from '@ui/config/transport';
 import { PromotionDirectivesRegistryContextProvider } from '@ui/features/promotion-directives/registry/context/registry-context-provider';
-import { getPublicConfig } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { getPublicConfig } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import { ModalContextProvider } from '../common/modal/modal-context-provider';
 
diff --git a/ui/src/features/auth/token-renew.tsx b/ui/src/features/auth/token-renew.tsx
index ee870019..b767a09c 100644
--- a/ui/src/features/auth/token-renew.tsx
+++ b/ui/src/features/auth/token-renew.tsx
@@ -13,7 +13,7 @@ import { useNavigate, useSearchParams } from 'react-router-dom';
 
 import { redirectToQueryParam, refreshTokenKey } from '@ui/config/auth';
 import { paths } from '@ui/config/paths';
-import { getPublicConfig } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { getPublicConfig } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import { LoadingState } from '../common';
 
diff --git a/ui/src/features/common/analysis-modal/analysis-modal.tsx b/ui/src/features/common/analysis-modal/analysis-modal.tsx
index a19e6cca..5b07542b 100644
--- a/ui/src/features/common/analysis-modal/analysis-modal.tsx
+++ b/ui/src/features/common/analysis-modal/analysis-modal.tsx
@@ -6,9 +6,9 @@ import classNames from 'classnames';
 import { useMemo, useState } from 'react';
 import { useParams } from 'react-router-dom';
 
-import { AnalysisRun } from '@ui/gen/rollouts/api/v1alpha1/generated_pb';
-import { getAnalysisRun } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
+import { getAnalysisRun } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { AnalysisRun } from '@ui/gen/api/stubs/rollouts/v1alpha1/generated_pb';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 
 import YamlEditor from '../code-editor/yaml-editor-lazy';
diff --git a/ui/src/features/common/analysis-modal/transforms.ts b/ui/src/features/common/analysis-modal/transforms.ts
index 4ba64ab8..5545279c 100644
--- a/ui/src/features/common/analysis-modal/transforms.ts
+++ b/ui/src/features/common/analysis-modal/transforms.ts
@@ -1,5 +1,4 @@
 // eslint-disable-file @typescript-eslint/ban-ts-comment
-import { IntOrString } from '@ui/gen/k8s.io/apimachinery/pkg/util/intstr/generated_pb';
 import {
   AnalysisRunSpec,
   AnalysisRunStatus,
@@ -9,7 +8,8 @@ import {
   Measurement,
   MetricProvider,
   MetricResult
-} from '@ui/gen/rollouts/api/v1alpha1/generated_pb';
+} from '@ui/gen/api/stubs/rollouts/v1alpha1/generated_pb';
+import { IntOrString } from '@ui/gen/k8s.io/apimachinery/pkg/util/intstr/generated_pb';
 
 import {
   AnalysisStatus,
diff --git a/ui/src/features/common/analysis-modal/types.ts b/ui/src/features/common/analysis-modal/types.ts
index c5a6db07..cf644a40 100644
--- a/ui/src/features/common/analysis-modal/types.ts
+++ b/ui/src/features/common/analysis-modal/types.ts
@@ -1,4 +1,8 @@
-import { Measurement, Metric, MetricResult } from '@ui/gen/rollouts/api/v1alpha1/generated_pb';
+import {
+  Measurement,
+  Metric,
+  MetricResult
+} from '@ui/gen/api/stubs/rollouts/v1alpha1/generated_pb';
 
 export enum AnalysisStatus {
   Successful = 'Successful',
diff --git a/ui/src/features/common/commit-info.tsx b/ui/src/features/common/commit-info.tsx
index a273ab3b..a3cb5579 100644
--- a/ui/src/features/common/commit-info.tsx
+++ b/ui/src/features/common/commit-info.tsx
@@ -1,4 +1,4 @@
-import { GitCommit } from '@ui/gen/v1alpha1/generated_pb';
+import { GitCommit } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export const CommitInfo = ({ commit }: { commit: GitCommit }) => (
   <div className='grid grid-cols-2'>
diff --git a/ui/src/features/common/health-status/health-status-icon.tsx b/ui/src/features/common/health-status/health-status-icon.tsx
index 58a97c77..6e528fa9 100644
--- a/ui/src/features/common/health-status/health-status-icon.tsx
+++ b/ui/src/features/common/health-status/health-status-icon.tsx
@@ -11,7 +11,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from 'antd';
 import { CSSProperties } from 'react';
 
-import { Health } from '@ui/gen/v1alpha1/generated_pb';
+import { Health } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { HealthStatus, healthStatusToEnum } from './utils';
 
diff --git a/ui/src/features/common/promotion-directive-step-status/utils.test.ts b/ui/src/features/common/promotion-directive-step-status/utils.test.ts
index 6d412924..0823ca10 100644
--- a/ui/src/features/common/promotion-directive-step-status/utils.test.ts
+++ b/ui/src/features/common/promotion-directive-step-status/utils.test.ts
@@ -1,6 +1,6 @@
 import { expect, test } from 'vitest';
 
-import { PromotionStatus } from '@ui/gen/v1alpha1/generated_pb';
+import { PromotionStatus } from '@ui/gen/api/v1alpha1/generated_pb';
 import { PlainMessage } from '@ui/utils/connectrpc-utils';
 
 import { PromotionStatusPhase } from '../promotion-status/utils';
diff --git a/ui/src/features/common/promotion-directive-step-status/utils.ts b/ui/src/features/common/promotion-directive-step-status/utils.ts
index b21a6e86..29d4ea92 100644
--- a/ui/src/features/common/promotion-directive-step-status/utils.ts
+++ b/ui/src/features/common/promotion-directive-step-status/utils.ts
@@ -1,5 +1,5 @@
 import { PromotionStatusPhase } from '@ui/features/common/promotion-status/utils';
-import { PromotionStatus } from '@ui/gen/v1alpha1/generated_pb';
+import { PromotionStatus } from '@ui/gen/api/v1alpha1/generated_pb';
 
 // UI concludes from Promotion's status data
 export enum PromotionDirectiveStepStatus {
diff --git a/ui/src/features/common/promotion-status/promotion-status-icon.tsx b/ui/src/features/common/promotion-status/promotion-status-icon.tsx
index 49f6437f..98dd34b6 100644
--- a/ui/src/features/common/promotion-status/promotion-status-icon.tsx
+++ b/ui/src/features/common/promotion-status/promotion-status-icon.tsx
@@ -8,7 +8,7 @@ import {
 import { theme } from 'antd';
 
 import { MessageTooltip } from '@ui/features/project/pipelines/message-tooltip';
-import { PromotionStatus } from '@ui/gen/v1alpha1/generated_pb';
+import { PromotionStatus } from '@ui/gen/api/v1alpha1/generated_pb';
 
 const PhaseAndMessage = ({ status }: { status: PromotionStatus }) => (
   <div>
diff --git a/ui/src/features/common/promotion-status/utils.ts b/ui/src/features/common/promotion-status/utils.ts
index d64c2817..469f0f04 100644
--- a/ui/src/features/common/promotion-status/utils.ts
+++ b/ui/src/features/common/promotion-status/utils.ts
@@ -1,4 +1,4 @@
-import { Promotion } from '@ui/gen/v1alpha1/generated_pb';
+import { Promotion } from '@ui/gen/api/v1alpha1/generated_pb';
 
 // TODO: can we map this to promotion_types.go?
 export enum PromotionStatusPhase {
diff --git a/ui/src/features/common/stage-tag.tsx b/ui/src/features/common/stage-tag.tsx
index 57285e28..82f3db73 100644
--- a/ui/src/features/common/stage-tag.tsx
+++ b/ui/src/features/common/stage-tag.tsx
@@ -1,6 +1,6 @@
 import { Tooltip } from 'antd';
 
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { StagePopover } from '../project/list/project-item/stage-popover';
 import { ColorMap } from '../stage/utils';
diff --git a/ui/src/features/common/utils.ts b/ui/src/features/common/utils.ts
index c203e96c..ed558ed9 100644
--- a/ui/src/features/common/utils.ts
+++ b/ui/src/features/common/utils.ts
@@ -1,5 +1,5 @@
+import { Freight, FreightReference, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { ObjectMeta } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
-import { Freight, FreightReference, Stage } from '@ui/gen/v1alpha1/generated_pb';
 import { PlainMessageRecursive } from '@ui/utils/connectrpc-utils';
 
 export const ALIAS_LABEL_KEY = 'kargo.akuity.io/alias';
diff --git a/ui/src/features/freight-timeline/freight-contents.tsx b/ui/src/features/freight-timeline/freight-contents.tsx
index e7f85f8b..e5cc4754 100644
--- a/ui/src/features/freight-timeline/freight-contents.tsx
+++ b/ui/src/features/freight-timeline/freight-contents.tsx
@@ -2,7 +2,7 @@ import { faDocker, faGitAlt } from '@fortawesome/free-brands-svg-icons';
 import { faAnchor } from '@fortawesome/free-solid-svg-icons';
 import classNames from 'classnames';
 
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 import { urlForImage } from '@ui/utils/url';
 
 import { CommitInfo } from '../common/commit-info';
diff --git a/ui/src/features/freight-timeline/freight-item-label.tsx b/ui/src/features/freight-timeline/freight-item-label.tsx
index 33fddf21..c10255b6 100644
--- a/ui/src/features/freight-timeline/freight-item-label.tsx
+++ b/ui/src/features/freight-timeline/freight-item-label.tsx
@@ -4,7 +4,7 @@ import { Tooltip } from 'antd';
 import { format, formatDistance } from 'date-fns';
 import { useEffect, useState } from 'react';
 
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate, PlainMessageRecursive } from '@ui/utils/connectrpc-utils';
 
 import { getAlias } from '../common/utils';
diff --git a/ui/src/features/freight-timeline/freight-item.tsx b/ui/src/features/freight-timeline/freight-item.tsx
index b61ef4f2..fa1ad32c 100644
--- a/ui/src/features/freight-timeline/freight-item.tsx
+++ b/ui/src/features/freight-timeline/freight-item.tsx
@@ -1,6 +1,6 @@
 import classNames from 'classnames';
 
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { FreightMode } from '../project/pipelines/types';
 
diff --git a/ui/src/features/freight-timeline/freight-timeline-header.tsx b/ui/src/features/freight-timeline/freight-timeline-header.tsx
index d51b39ca..f1aff0df 100644
--- a/ui/src/features/freight-timeline/freight-timeline-header.tsx
+++ b/ui/src/features/freight-timeline/freight-timeline-header.tsx
@@ -18,7 +18,7 @@ import { generatePath, useNavigate, useParams } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
 import { ColorContext } from '@ui/context/colors';
-import { Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { CollapseMode, FreightTimelineAction } from '../project/pipelines/types';
 
diff --git a/ui/src/features/freight-timeline/freight-timeline.tsx b/ui/src/features/freight-timeline/freight-timeline.tsx
index e01c73ad..3ed73523 100644
--- a/ui/src/features/freight-timeline/freight-timeline.tsx
+++ b/ui/src/features/freight-timeline/freight-timeline.tsx
@@ -8,8 +8,8 @@ import {
   promoteDownstream,
   promoteToStage,
   queryFreight
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Freight, Stage } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Freight, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { FreightActionMenu } from '../project/pipelines/freight-action-menu';
 import { CollapseMode, FreightTimelineAction } from '../project/pipelines/types';
diff --git a/ui/src/features/freight-timeline/stage-indicators.tsx b/ui/src/features/freight-timeline/stage-indicators.tsx
index 96020a77..943aab5f 100644
--- a/ui/src/features/freight-timeline/stage-indicators.tsx
+++ b/ui/src/features/freight-timeline/stage-indicators.tsx
@@ -2,7 +2,7 @@ import { Tooltip } from 'antd';
 import { useContext } from 'react';
 
 import { ColorContext } from '@ui/context/colors';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 const StageIndicator = ({
   stage,
diff --git a/ui/src/features/freight/freight-details.tsx b/ui/src/features/freight/freight-details.tsx
index 4150c5d8..285a3f08 100644
--- a/ui/src/features/freight/freight-details.tsx
+++ b/ui/src/features/freight/freight-details.tsx
@@ -7,7 +7,7 @@ import { useEffect, useState } from 'react';
 import { generatePath, useNavigate, useParams } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
-import { Freight, FreightSchema } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight, FreightSchema } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { Description } from '../common/description';
 import { ManifestPreview } from '../common/manifest-preview';
diff --git a/ui/src/features/freight/freight-status-list.tsx b/ui/src/features/freight/freight-status-list.tsx
index 15292018..d6564fbb 100644
--- a/ui/src/features/freight/freight-status-list.tsx
+++ b/ui/src/features/freight/freight-status-list.tsx
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { useContext } from 'react';
 
 import { ColorContext } from '@ui/context/colors';
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 
 const StageIndicator = ({ stageName, icon }: { stageName: string; icon?: IconDefinition }) => {
   const { stageColorMap } = useContext(ColorContext);
diff --git a/ui/src/features/project/analysis-templates/analysis-templates-list.tsx b/ui/src/features/project/analysis-templates/analysis-templates-list.tsx
index e84b8bbb..7bb7b0dd 100644
--- a/ui/src/features/project/analysis-templates/analysis-templates-list.tsx
+++ b/ui/src/features/project/analysis-templates/analysis-templates-list.tsx
@@ -8,11 +8,11 @@ import { useParams } from 'react-router-dom';
 import { useConfirmModal } from '@ui/features/common/confirm-modal/use-confirm-modal';
 import { descriptionExpandable } from '@ui/features/common/description-expandable';
 import { useModal } from '@ui/features/common/modal/use-modal';
-import { AnalysisTemplate } from '@ui/gen/rollouts/api/v1alpha1/generated_pb';
 import {
   deleteAnalysisTemplate,
   listAnalysisTemplates
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { AnalysisTemplate } from '@ui/gen/api/stubs/rollouts/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 import { CreateAnalysisTemplateModal } from './create-analysis-template-modal';
diff --git a/ui/src/features/project/analysis-templates/create-analysis-template-modal.tsx b/ui/src/features/project/analysis-templates/create-analysis-template-modal.tsx
index 2d01bc36..354a26e7 100644
--- a/ui/src/features/project/analysis-templates/create-analysis-template-modal.tsx
+++ b/ui/src/features/project/analysis-templates/create-analysis-template-modal.tsx
@@ -10,7 +10,7 @@ import { queryCache } from '@ui/features/utils/cache';
 import {
   createResource,
   listAnalysisTemplates
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import { decodeUint8ArrayYamlManifestToJson } from '@ui/utils/decode-raw-data';
 
 import { getAnalysisTemplateYAMLExample } from './utils/analysis-template-example';
diff --git a/ui/src/features/project/analysis-templates/edit-analysis-template-modal.tsx b/ui/src/features/project/analysis-templates/edit-analysis-template-modal.tsx
index ce7766b2..67e7ccca 100644
--- a/ui/src/features/project/analysis-templates/edit-analysis-template-modal.tsx
+++ b/ui/src/features/project/analysis-templates/edit-analysis-template-modal.tsx
@@ -10,8 +10,8 @@ import {
   getAnalysisTemplate,
   listAnalysisTemplates,
   updateResource
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 
 import { getAnalysisTemplateYAMLExample } from './utils/analysis-template-example';
diff --git a/ui/src/features/project/credentials/create-credentials-modal.tsx b/ui/src/features/project/credentials/create-credentials-modal.tsx
index e7f91afd..7b051f62 100644
--- a/ui/src/features/project/credentials/create-credentials-modal.tsx
+++ b/ui/src/features/project/credentials/create-credentials-modal.tsx
@@ -10,13 +10,13 @@ import { FieldContainer } from '@ui/features/common/form/field-container';
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
 import { SegmentLabel } from '@ui/features/common/segment-label';
 import { dnsRegex } from '@ui/features/common/utils';
-import { Secret } from '@ui/gen/k8s.io/api/core/v1/generated_pb';
 import {
   createCredentials,
   createProjectSecret,
   updateCredentials,
   updateProjectSecret
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Secret } from '@ui/gen/k8s.io/api/core/v1/generated_pb';
 import { zodValidators } from '@ui/utils/validators';
 
 import { SecretEditor } from './secret-editor';
@@ -117,7 +117,9 @@ export const CreateCredentialsModal = ({ project, onSuccess, editing, init, ...p
     if (credentialType === 'generic') {
       const data: Record<string, string> = {};
 
+      // @ts-expect-error zod infer problem
       if (values?.data?.length > 0) {
+        // @ts-expect-error zod infer problem
         for (const [k, v] of values.data) {
           data[k] = v;
         }
diff --git a/ui/src/features/project/credentials/credentials-list.tsx b/ui/src/features/project/credentials/credentials-list.tsx
index a0f7fe2d..e9ea2799 100644
--- a/ui/src/features/project/credentials/credentials-list.tsx
+++ b/ui/src/features/project/credentials/credentials-list.tsx
@@ -13,13 +13,13 @@ import { useParams } from 'react-router-dom';
 import { useConfirmModal } from '@ui/features/common/confirm-modal/use-confirm-modal';
 import { descriptionExpandable } from '@ui/features/common/description-expandable';
 import { useModal } from '@ui/features/common/modal/use-modal';
-import { Secret } from '@ui/gen/k8s.io/api/core/v1/generated_pb';
 import {
   deleteCredentials,
   deleteProjectSecret,
   listCredentials,
   listProjectSecrets
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Secret } from '@ui/gen/k8s.io/api/core/v1/generated_pb';
 
 import { CreateCredentialsModal } from './create-credentials-modal';
 import { CredentialTypeLabelKey, CredentialsDataKey, CredentialsType } from './types';
diff --git a/ui/src/features/project/events/events.tsx b/ui/src/features/project/events/events.tsx
index 0cc79ff7..97b850fb 100644
--- a/ui/src/features/project/events/events.tsx
+++ b/ui/src/features/project/events/events.tsx
@@ -11,9 +11,9 @@ import { format } from 'date-fns';
 import moment from 'moment';
 import { useParams } from 'react-router-dom';
 
+import { listProjectEvents } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import { Event } from '@ui/gen/k8s.io/api/core/v1/generated_pb';
 import { Time } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
-import { listProjectEvents } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 const EventValue = ({ label, children }: { label: string; children: React.ReactNode }) => {
diff --git a/ui/src/features/project/list/create-project-modal.tsx b/ui/src/features/project/list/create-project-modal.tsx
index f9c1be58..15bfe606 100644
--- a/ui/src/features/project/list/create-project-modal.tsx
+++ b/ui/src/features/project/list/create-project-modal.tsx
@@ -11,8 +11,8 @@ import { YamlEditor } from '@ui/features/common/code-editor/yaml-editor';
 import { FieldContainer } from '@ui/features/common/form/field-container';
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
 import { queryCache } from '@ui/features/utils/cache';
+import { createResource } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import schema from '@ui/gen/schema/projects.kargo.akuity.io_v1alpha1.json';
-import { createResource } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
 import { decodeUint8ArrayYamlManifestToJson } from '@ui/utils/decode-raw-data';
 import { zodValidators } from '@ui/utils/validators';
 
diff --git a/ui/src/features/project/list/project-item/project-item.tsx b/ui/src/features/project/list/project-item/project-item.tsx
index e595815f..4c3a2a7c 100644
--- a/ui/src/features/project/list/project-item/project-item.tsx
+++ b/ui/src/features/project/list/project-item/project-item.tsx
@@ -5,7 +5,7 @@ import { paths } from '@ui/config/paths';
 import { Description } from '@ui/features/common/description';
 import { StageTag } from '@ui/features/common/stage-tag';
 import { getColors } from '@ui/features/stage/utils';
-import { Project, Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Project, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import * as styles from './project-item.module.less';
 
diff --git a/ui/src/features/project/list/project-item/stage-popover.tsx b/ui/src/features/project/list/project-item/stage-popover.tsx
index 60488cae..c5bcf6cd 100644
--- a/ui/src/features/project/list/project-item/stage-popover.tsx
+++ b/ui/src/features/project/list/project-item/stage-popover.tsx
@@ -11,8 +11,8 @@ import { getAlias } from '@ui/features/common/utils';
 import {
   getFreight,
   getPromotion
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Freight, FreightReference, Promotion, Stage } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Freight, FreightReference, Promotion, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 export const StagePopover = ({ project, stage }: { project?: string; stage?: Stage }) => {
diff --git a/ui/src/features/project/list/project-list-filter.tsx b/ui/src/features/project/list/project-list-filter.tsx
index ecd08674..571b59cc 100644
--- a/ui/src/features/project/list/project-list-filter.tsx
+++ b/ui/src/features/project/list/project-list-filter.tsx
@@ -6,7 +6,7 @@ import { useState } from 'react';
 import { useNavigate } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
-import { listProjects } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { listProjects } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 export const ProjectListFilter = ({
   onChange,
diff --git a/ui/src/features/project/list/projects-list.tsx b/ui/src/features/project/list/projects-list.tsx
index 1c7c928b..23a8c03f 100644
--- a/ui/src/features/project/list/projects-list.tsx
+++ b/ui/src/features/project/list/projects-list.tsx
@@ -7,7 +7,7 @@ import { LoadingState } from '@ui/features/common';
 import {
   listProjects,
   listStages
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import { useLocalStorage } from '../../../utils/use-local-storage';
 
diff --git a/ui/src/features/project/pipelines/context/pipeline-context.ts b/ui/src/features/project/pipelines/context/pipeline-context.ts
index 5cebf83d..1280c623 100644
--- a/ui/src/features/project/pipelines/context/pipeline-context.ts
+++ b/ui/src/features/project/pipelines/context/pipeline-context.ts
@@ -1,6 +1,6 @@
 import { createContext } from 'react';
 
-import { Freight, Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { FreightTimelineAction } from '../types';
 import { PipelineStateHook } from '../utils/state';
@@ -16,6 +16,10 @@ export interface PipelineContextType {
   project: string;
   onHover: (hover: boolean, id: string, isStage?: boolean) => void;
   onPromoteClick: (stage: Stage, type: FreightTimelineAction) => void;
+
+  // array of node ids
+  hideParents: string[];
+  onHideParents(parents: string[]): void;
 }
 
 export const PipelineContext = createContext<PipelineContextType | null>(null);
diff --git a/ui/src/features/project/pipelines/delete-freight-modal.tsx b/ui/src/features/project/pipelines/delete-freight-modal.tsx
index 09e03218..41d291bb 100644
--- a/ui/src/features/project/pipelines/delete-freight-modal.tsx
+++ b/ui/src/features/project/pipelines/delete-freight-modal.tsx
@@ -4,8 +4,8 @@ import { useParams } from 'react-router-dom';
 
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
 import { getAlias } from '@ui/features/common/utils';
-import { deleteFreight } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { deleteFreight } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { onError } from '../pipelines/utils/util';
 
diff --git a/ui/src/features/project/pipelines/freight-action-menu.tsx b/ui/src/features/project/pipelines/freight-action-menu.tsx
index 6594025b..52b299c0 100644
--- a/ui/src/features/project/pipelines/freight-action-menu.tsx
+++ b/ui/src/features/project/pipelines/freight-action-menu.tsx
@@ -12,7 +12,7 @@ import { Dropdown, message } from 'antd';
 
 import { useModal } from '@ui/features/common/modal/use-modal';
 import { getAlias } from '@ui/features/common/utils';
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { DeleteFreightModal } from './delete-freight-modal';
 import { UpdateFreightAliasModal } from './update-freight-alias-modal';
diff --git a/ui/src/features/project/pipelines/graph.tsx b/ui/src/features/project/pipelines/graph.tsx
index 07b7918a..d7748998 100644
--- a/ui/src/features/project/pipelines/graph.tsx
+++ b/ui/src/features/project/pipelines/graph.tsx
@@ -1,7 +1,7 @@
 import { Controls, ReactFlow } from '@xyflow/react';
 import { memo, useEffect } from 'react';
 
-import { Stage, Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage, Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { usePipelineContext } from './context/use-pipeline-context';
 import { CustomNode } from './nodes/custom-node';
@@ -19,14 +19,15 @@ const nodeTypes = {
 };
 
 export const Graph = memo((props: GraphProps) => {
+  const pipelineContext = usePipelineContext();
+
   const { controlledNodes, controlledEdges } = useReactFlowPipelineGraph(
     props.project,
     props.stages,
-    props.warehouses
+    props.warehouses,
+    pipelineContext?.hideParents
   );
 
-  const pipelineContext = usePipelineContext();
-
   useEffect(() => {
     const action = pipelineContext?.state?.action;
 
diff --git a/ui/src/features/project/pipelines/images.tsx b/ui/src/features/project/pipelines/images.tsx
index 7123c122..9ca40caa 100644
--- a/ui/src/features/project/pipelines/images.tsx
+++ b/ui/src/features/project/pipelines/images.tsx
@@ -9,8 +9,8 @@ import semver from 'semver';
 
 import { paths } from '@ui/config/paths';
 import { ColorContext } from '@ui/context/colors';
-import { TagMap } from '@ui/gen/service/v1alpha1/service_pb';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { TagMap } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { useLocalStorage } from '@ui/utils/use-local-storage';
 
 const ImageTagRow = ({
diff --git a/ui/src/features/project/pipelines/nodes/custom-node.tsx b/ui/src/features/project/pipelines/nodes/custom-node.tsx
index 001838ee..f67d2c94 100644
--- a/ui/src/features/project/pipelines/nodes/custom-node.tsx
+++ b/ui/src/features/project/pipelines/nodes/custom-node.tsx
@@ -1,7 +1,12 @@
+import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Handle, Position } from '@xyflow/react';
-import { PropsWithChildren } from 'react';
+import { Button } from 'antd';
+import { PropsWithChildren, ReactNode } from 'react';
 
-import { RepoSubscription, Stage, Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { RepoSubscription, Stage, Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
+
+import { usePipelineContext } from '../context/use-pipeline-context';
 
 import styles from './custom-node.module.less';
 import { StageNode } from './stage-node';
@@ -50,6 +55,8 @@ export const CustomNode = ({
 };
 
 CustomNode.Container = (props: PropsWithChildren<{ stage?: Stage; warehouse?: Warehouse }>) => {
+  const pipelineContext = usePipelineContext();
+
   if (props.stage?.metadata?.name) {
     const howManyStagesDoThisStageSubscribe = props.stage?.spec?.requestedFreight?.length || 0;
 
@@ -84,8 +91,55 @@ CustomNode.Container = (props: PropsWithChildren<{ stage?: Stage; warehouse?: Wa
     );
   }
 
+  let HideParents: ReactNode;
+  if (props.warehouse?.metadata?.name) {
+    const hideParentsOption = !!props.warehouse;
+
+    const subscription = props.warehouse?.spec?.subscriptions?.[0];
+
+    const repoURL =
+      subscription?.image?.repoURL || subscription?.git?.repoURL || subscription?.chart?.repoURL;
+
+    const warehouseNodeIndex = `${props.warehouse?.metadata?.name}-${repoURL}`;
+
+    const parentsHidden = pipelineContext?.hideParents?.includes(warehouseNodeIndex);
+
+    HideParents = hideParentsOption && (
+      <Button
+        size='small'
+        className='absolute top-[50%] translate-y-[-50%] translate-x-[-50%] z-10'
+        icon={
+          <FontAwesomeIcon
+            icon={parentsHidden ? faEye : faEyeSlash}
+            onClick={() => {
+              const parents = new Set(pipelineContext?.hideParents);
+
+              for (const subscription of props.warehouse?.spec?.subscriptions || []) {
+                const repoURL =
+                  subscription.image?.repoURL ||
+                  subscription.git?.repoURL ||
+                  subscription.chart?.repoURL;
+
+                // TODO: centralize node id construction logic
+                const nodeIndex = `${props.warehouse?.metadata?.name}-${repoURL}`;
+
+                if (!parentsHidden) {
+                  parents.add(nodeIndex);
+                } else {
+                  parents.delete(nodeIndex);
+                }
+              }
+
+              pipelineContext?.onHideParents(Array.from(parents));
+            }}
+          />
+        }
+      />
+    );
+  }
   return (
     <>
+      {HideParents}
       <Handle
         id={props.warehouse?.metadata?.name || ''}
         type='target'
diff --git a/ui/src/features/project/pipelines/nodes/freight-indicators.tsx b/ui/src/features/project/pipelines/nodes/freight-indicators.tsx
index e4a041dc..bfc7f638 100644
--- a/ui/src/features/project/pipelines/nodes/freight-indicators.tsx
+++ b/ui/src/features/project/pipelines/nodes/freight-indicators.tsx
@@ -4,7 +4,7 @@ import { useContext } from 'react';
 
 import { ColorContext } from '@ui/context/colors';
 import { getAlias } from '@ui/features/common/utils';
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export const FreightIndicators = ({
   freight,
diff --git a/ui/src/features/project/pipelines/nodes/freight-label.tsx b/ui/src/features/project/pipelines/nodes/freight-label.tsx
index 1f6bca23..e7ae278a 100644
--- a/ui/src/features/project/pipelines/nodes/freight-label.tsx
+++ b/ui/src/features/project/pipelines/nodes/freight-label.tsx
@@ -6,7 +6,7 @@ import { format, formatDistance } from 'date-fns';
 import { useEffect, useState } from 'react';
 
 import { CommitInfo } from '@ui/features/common/commit-info';
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 import { getAlias } from '../../../common/utils';
@@ -32,6 +32,12 @@ export const FreightLabel = ({ freight }: { freight?: Freight }) => {
     }
   );
 
+  const totalImages = freight?.images?.length || 0;
+  const totalCommits = freight?.commits?.length || 0;
+  const totalCharts = freight?.charts?.length || 0;
+
+  const totalSubscriptions = totalImages + totalCommits + totalCharts;
+
   return (
     <div
       className='cursor-pointer font-semibold min-w-0 w-full text-center'
@@ -67,7 +73,7 @@ export const FreightLabel = ({ freight }: { freight?: Freight }) => {
             </Tooltip>
           )}
           <div className='flex items-center gap-1 my-1 justify-center text-gray-500'>
-            {(freight?.images || []).map((image) => {
+            {(freight?.images || []).slice(0, 2).map((image) => {
               const key = `${image.repoURL}:${image?.tag}`;
               return (
                 <Tooltip key={key} title={key} placement='bottom'>
@@ -75,12 +81,12 @@ export const FreightLabel = ({ freight }: { freight?: Freight }) => {
                 </Tooltip>
               );
             })}
-            {(freight?.commits || []).map((commit) => (
+            {(freight?.commits || []).slice(0, 2).map((commit) => (
               <Tooltip key={commit.id} title={<CommitInfo commit={commit} />} placement='bottom'>
                 <FontAwesomeIcon icon={faGitAlt} />
               </Tooltip>
             ))}
-            {(freight?.charts || []).map((chart) => {
+            {(freight?.charts || []).slice(0, 2).map((chart) => {
               const key = chart.repoURL;
               return (
                 <Tooltip key={key} title={key} placement='bottom'>
@@ -88,6 +94,9 @@ export const FreightLabel = ({ freight }: { freight?: Freight }) => {
                 </Tooltip>
               );
             })}
+            {totalSubscriptions > 6 && (
+              <div className='text-xs text-gray-400'>+{totalSubscriptions - 6}</div>
+            )}
           </div>
         </>
       ) : (
diff --git a/ui/src/features/project/pipelines/nodes/stage-node.tsx b/ui/src/features/project/pipelines/nodes/stage-node.tsx
index e6d69f82..2eff65f6 100644
--- a/ui/src/features/project/pipelines/nodes/stage-node.tsx
+++ b/ui/src/features/project/pipelines/nodes/stage-node.tsx
@@ -27,8 +27,8 @@ import { getColors } from '@ui/features/stage/utils';
 import {
   approveFreight,
   promoteToStage
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Freight, Stage } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Freight, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 import { useLocalStorage } from '@ui/utils/use-local-storage';
 
diff --git a/ui/src/features/project/pipelines/nodes/subscription-node.tsx b/ui/src/features/project/pipelines/nodes/subscription-node.tsx
index 0c7b51f3..1ccbda13 100644
--- a/ui/src/features/project/pipelines/nodes/subscription-node.tsx
+++ b/ui/src/features/project/pipelines/nodes/subscription-node.tsx
@@ -5,7 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from 'antd';
 import classNames from 'classnames';
 
-import { RepoSubscription } from '@ui/gen/v1alpha1/generated_pb';
+import { RepoSubscription } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import styles from './custom-node.module.less';
 
diff --git a/ui/src/features/project/pipelines/nodes/util.ts b/ui/src/features/project/pipelines/nodes/util.ts
index cb3bf452..bf18f93b 100644
--- a/ui/src/features/project/pipelines/nodes/util.ts
+++ b/ui/src/features/project/pipelines/nodes/util.ts
@@ -1,4 +1,4 @@
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export const lastVerificationErrored = (stage: Stage): boolean => {
   const freightHistory = stage?.status?.freightHistory;
diff --git a/ui/src/features/project/pipelines/nodes/warehouse-node.tsx b/ui/src/features/project/pipelines/nodes/warehouse-node.tsx
index 76e4ed50..9f2b9cb1 100644
--- a/ui/src/features/project/pipelines/nodes/warehouse-node.tsx
+++ b/ui/src/features/project/pipelines/nodes/warehouse-node.tsx
@@ -14,8 +14,8 @@ import { generatePath, useNavigate } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
 import { ColorContext } from '@ui/context/colors';
-import { refreshWarehouse } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { refreshWarehouse } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { usePipelineContext } from '../context/use-pipeline-context';
 import { onError } from '../utils/util';
diff --git a/ui/src/features/project/pipelines/pipelines.tsx b/ui/src/features/project/pipelines/pipelines.tsx
index c85b9400..a6d08f1f 100644
--- a/ui/src/features/project/pipelines/pipelines.tsx
+++ b/ui/src/features/project/pipelines/pipelines.tsx
@@ -11,7 +11,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { useQueryClient } from '@tanstack/react-query';
 import { Button, Dropdown, Spin, Tooltip } from 'antd';
 import classNames from 'classnames';
-import React, { Suspense, lazy, useCallback, useEffect, useMemo, useRef } from 'react';
+import React, { Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState } from 'react';
 import { generatePath, useNavigate, useParams } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
@@ -39,8 +39,8 @@ import {
   listImages,
   listWarehouses,
   queryFreight
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Freight, Project, Stage, Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Freight, Project, Stage, Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 import { useDocumentEvent } from '@ui/utils/document';
 import { useLocalStorage } from '@ui/utils/use-local-storage';
 
@@ -272,6 +272,8 @@ export const Pipelines = ({
     [name, data?.stages]
   );
 
+  const [hideParents, setHideParents] = useState<string[]>([]);
+
   if (isLoading || isLoadingFreight || isLoadingImages || isLoadingWarehouse)
     return <LoadingState />;
 
@@ -417,7 +419,9 @@ export const Pipelines = ({
               setSelectedWarehouse(newWarehouse) {
                 lastExplicitlySelectedWarehouse.current = newWarehouse;
                 setSelectedWarehouse(newWarehouse);
-              }
+              },
+              hideParents,
+              onHideParents: setHideParents
             }}
           >
             <Graph
diff --git a/ui/src/features/project/pipelines/types.ts b/ui/src/features/project/pipelines/types.ts
index 88d24d1c..fac0bc44 100644
--- a/ui/src/features/project/pipelines/types.ts
+++ b/ui/src/features/project/pipelines/types.ts
@@ -4,7 +4,7 @@ import {
   ImageSubscription,
   Stage,
   Warehouse
-} from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { StageNodeDimensions } from './nodes/stage-node';
 
diff --git a/ui/src/features/project/pipelines/update-freight-alias-modal.tsx b/ui/src/features/project/pipelines/update-freight-alias-modal.tsx
index 147c7223..228eaf8e 100644
--- a/ui/src/features/project/pipelines/update-freight-alias-modal.tsx
+++ b/ui/src/features/project/pipelines/update-freight-alias-modal.tsx
@@ -9,8 +9,8 @@ import { z } from 'zod';
 import { FieldContainer } from '@ui/features/common/form/field-container';
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
 import { getAlias } from '@ui/features/common/utils';
-import { updateFreightAlias } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { updateFreightAlias } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 import { zodValidators } from '@ui/utils/validators';
 
 type Props = ModalComponentProps & {
diff --git a/ui/src/features/project/pipelines/utils/use-pipeline-graph.ts b/ui/src/features/project/pipelines/utils/use-pipeline-graph.ts
index d5ef0509..a83a46ca 100644
--- a/ui/src/features/project/pipelines/utils/use-pipeline-graph.ts
+++ b/ui/src/features/project/pipelines/utils/use-pipeline-graph.ts
@@ -3,7 +3,7 @@ import { graphlib, layout } from 'dagre';
 import { useContext, useEffect, useMemo } from 'react';
 
 import { ColorContext } from '@ui/context/colors';
-import { RepoSubscription, Stage, Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { RepoSubscription, Stage, Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { NodeType, RepoNodeDimensions, getNodeDimensions } from '../types';
 
@@ -20,7 +20,8 @@ export type GraphMeta = {
 export const useReactFlowPipelineGraph = (
   project: string | undefined,
   stages: Stage[],
-  warehouses: Warehouse[]
+  warehouses: Warehouse[],
+  hiddenParents: string[] = []
 ) => {
   const { warehouseColorMap } = useContext(ColorContext);
 
@@ -104,6 +105,9 @@ export const useReactFlowPipelineGraph = (
           label: node,
           value: dagreNode?.warehouse || dagreNode?.subscription || dagreNode?.stage,
           warehouses: warehouses?.length || 0
+        },
+        style: {
+          visibility: hiddenParents.includes(node) ? 'hidden' : 'visible'
         }
       });
     }
@@ -127,7 +131,7 @@ export const useReactFlowPipelineGraph = (
         },
         style: {
           strokeWidth: 2,
-          visibility: 'visible',
+          visibility: hiddenParents.includes(edge.v) ? 'hidden' : 'visible',
           stroke: dagreEdge?.edgeColor
         }
       });
@@ -137,7 +141,7 @@ export const useReactFlowPipelineGraph = (
       nodes: reactFlowNodes,
       edges: reactFlowEdges
     };
-  }, [project, stages, warehouses, warehouseColorMap]);
+  }, [project, stages, warehouses, warehouseColorMap, hiddenParents]);
 
   const controlledNodes = useNodesState(calculatedNodesAndEdges.nodes);
 
diff --git a/ui/src/features/project/pipelines/utils/use-promotion-eligible-freight.ts b/ui/src/features/project/pipelines/utils/use-promotion-eligible-freight.ts
index 1b340b9a..c60a7056 100644
--- a/ui/src/features/project/pipelines/utils/use-promotion-eligible-freight.ts
+++ b/ui/src/features/project/pipelines/utils/use-promotion-eligible-freight.ts
@@ -1,6 +1,6 @@
 import { useMemo } from 'react';
 
-import { Freight } from '@ui/gen/v1alpha1/generated_pb';
+import { Freight } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { FreightTimelineAction } from '../types';
 
diff --git a/ui/src/features/project/pipelines/utils/useImages.ts b/ui/src/features/project/pipelines/utils/useImages.ts
index 4e7c6aff..07b420a4 100644
--- a/ui/src/features/project/pipelines/utils/useImages.ts
+++ b/ui/src/features/project/pipelines/utils/useImages.ts
@@ -2,7 +2,7 @@ import { useContext, useMemo } from 'react';
 
 import { ColorContext } from '@ui/context/colors';
 import { getCurrentFreight } from '@ui/features/common/utils';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { StageStyleMap } from '../types';
 
diff --git a/ui/src/features/project/pipelines/utils/util.ts b/ui/src/features/project/pipelines/utils/util.ts
index 3658535e..dc847dcc 100644
--- a/ui/src/features/project/pipelines/utils/util.ts
+++ b/ui/src/features/project/pipelines/utils/util.ts
@@ -1,8 +1,8 @@
 import { ConnectError } from '@connectrpc/connect';
 import { message } from 'antd';
 
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { Time } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
 
 export const getSeconds = (ts?: Time): number => Number(ts?.seconds) || 0;
 
diff --git a/ui/src/features/project/pipelines/utils/watcher.ts b/ui/src/features/project/pipelines/utils/watcher.ts
index 15cb7fbe..9ac315b5 100644
--- a/ui/src/features/project/pipelines/utils/watcher.ts
+++ b/ui/src/features/project/pipelines/utils/watcher.ts
@@ -4,12 +4,11 @@ import { createConnectQueryKey } from '@connectrpc/connect-query';
 import { QueryClient } from '@tanstack/react-query';
 
 import { transportWithAuth } from '@ui/config/transport';
-import { ObjectMeta } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
 import {
   getStage,
   listStages,
   listWarehouses
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import {
   GetStageRequestSchema,
   KargoService,
@@ -17,8 +16,9 @@ import {
   ListStagesResponse,
   ListWarehousesRequestSchema,
   ListWarehousesResponse
-} from '@ui/gen/service/v1alpha1/service_pb';
-import { Stage, Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service_pb';
+import { Stage, Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
+import { ObjectMeta } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
 
 async function ProcessEvents<T extends { type: string }, S extends { metadata?: ObjectMeta }>(
   stream: AsyncIterable<T>,
diff --git a/ui/src/features/project/pipelines/warehouse/edit-warehouse.tsx b/ui/src/features/project/pipelines/warehouse/edit-warehouse.tsx
index c50ec7fd..016f30cb 100644
--- a/ui/src/features/project/pipelines/warehouse/edit-warehouse.tsx
+++ b/ui/src/features/project/pipelines/warehouse/edit-warehouse.tsx
@@ -11,12 +11,12 @@ import { z } from 'zod';
 import { YamlEditor } from '@ui/features/common/code-editor/yaml-editor';
 import { FieldContainer } from '@ui/features/common/form/field-container';
 import { WarehouseManifestsGen } from '@ui/features/utils/manifest-generator';
-import schema from '@ui/gen/schema/warehouses.kargo.akuity.io_v1alpha1.json';
 import {
   getWarehouse,
   updateResource
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
+import schema from '@ui/gen/schema/warehouses.kargo.akuity.io_v1alpha1.json';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 import { zodValidators } from '@ui/utils/validators';
 
diff --git a/ui/src/features/project/pipelines/warehouse/repo-subscriptions.tsx b/ui/src/features/project/pipelines/warehouse/repo-subscriptions.tsx
index febde1d6..fd8580b1 100644
--- a/ui/src/features/project/pipelines/warehouse/repo-subscriptions.tsx
+++ b/ui/src/features/project/pipelines/warehouse/repo-subscriptions.tsx
@@ -1,6 +1,6 @@
 import { Descriptions, Typography } from 'antd';
 
-import { RepoSubscription } from '@ui/gen/v1alpha1/generated_pb';
+import { RepoSubscription } from '@ui/gen/api/v1alpha1/generated_pb';
 import { urlForImage } from '@ui/utils/url';
 
 type Props = {
diff --git a/ui/src/features/project/pipelines/warehouse/warehouse-actions.tsx b/ui/src/features/project/pipelines/warehouse/warehouse-actions.tsx
index d9ea2c6f..c7f83d17 100644
--- a/ui/src/features/project/pipelines/warehouse/warehouse-actions.tsx
+++ b/ui/src/features/project/pipelines/warehouse/warehouse-actions.tsx
@@ -10,8 +10,8 @@ import { useConfirmModal } from '@ui/features/common/confirm-modal/use-confirm-m
 import {
   deleteWarehouse,
   listWarehouses
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export const WarehouseActions = ({ warehouse }: { warehouse: Warehouse }) => {
   const { name: projectName } = useParams();
diff --git a/ui/src/features/project/pipelines/warehouse/warehouse-details.tsx b/ui/src/features/project/pipelines/warehouse/warehouse-details.tsx
index 802deaa0..40678622 100644
--- a/ui/src/features/project/pipelines/warehouse/warehouse-details.tsx
+++ b/ui/src/features/project/pipelines/warehouse/warehouse-details.tsx
@@ -13,7 +13,7 @@ import { generatePath, useNavigate, useParams } from 'react-router-dom';
 import { paths } from '@ui/config/paths';
 import { AssembleFreight } from '@ui/features/assemble-freight/assemble-freight';
 import { SmallLabel } from '@ui/features/common/small-label';
-import { Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { EditWarehouse } from './edit-warehouse';
 import { RepoSubscriptions } from './repo-subscriptions';
diff --git a/ui/src/features/project/pipelines/warehouse/warehouse-error.ts b/ui/src/features/project/pipelines/warehouse/warehouse-error.ts
index d81e7800..2dedd97c 100644
--- a/ui/src/features/project/pipelines/warehouse/warehouse-error.ts
+++ b/ui/src/features/project/pipelines/warehouse/warehouse-error.ts
@@ -1,4 +1,4 @@
-import { Warehouse } from '@ui/gen/v1alpha1/generated_pb';
+import { Warehouse } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export const getWarehouseError = (warehouse: Warehouse): string | null => {
   let message: string | null = null;
diff --git a/ui/src/features/project/roles/create-role.tsx b/ui/src/features/project/roles/create-role.tsx
index 47dcbea1..0b48aee4 100644
--- a/ui/src/features/project/roles/create-role.tsx
+++ b/ui/src/features/project/roles/create-role.tsx
@@ -11,9 +11,12 @@ import { z } from 'zod';
 import { FieldContainer } from '@ui/features/common/form/field-container';
 import { MultiStringEditor } from '@ui/features/common/form/multi-string-editor';
 import { DESCRIPTION_ANNOTATION_KEY, dnsRegex } from '@ui/features/common/utils';
+import { Claim, ClaimSchema, Role } from '@ui/gen/api/rbac/v1alpha1/generated_pb';
+import {
+  createRole,
+  updateRole
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import { PolicyRule } from '@ui/gen/k8s.io/api/rbac/v1/generated_pb';
-import { Claim, ClaimSchema, Role } from '@ui/gen/rbac/v1alpha1/generated_pb';
-import { createRole, updateRole } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
 import { zodValidators } from '@ui/utils/validators';
 
 import { RuleEditor } from './rule-editor';
@@ -96,7 +99,7 @@ export const CreateRole = ({ editing, onSuccess, project, hide }: Props) => {
   });
 
   const onSubmit = handleSubmit((values) => {
-    const annotations = annotationsWithDescription(values.description);
+    const annotations = annotationsWithDescription(values.description || '');
     const getClaims = (): Claim[] => {
       const claimsArray: Claim[] = [];
       multiFields.map((field) => {
diff --git a/ui/src/features/project/roles/delete-role-modal.tsx b/ui/src/features/project/roles/delete-role-modal.tsx
index 8153a2aa..2b67d106 100644
--- a/ui/src/features/project/roles/delete-role-modal.tsx
+++ b/ui/src/features/project/roles/delete-role-modal.tsx
@@ -2,7 +2,7 @@ import { useMutation } from '@connectrpc/connect-query';
 import { Modal } from 'antd';
 import { useParams } from 'react-router-dom';
 
-import { deleteRole } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { deleteRole } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 export const DeleteRoleModal = ({
   name,
diff --git a/ui/src/features/project/roles/roles.tsx b/ui/src/features/project/roles/roles.tsx
index 46b2ed79..e2df4128 100644
--- a/ui/src/features/project/roles/roles.tsx
+++ b/ui/src/features/project/roles/roles.tsx
@@ -15,8 +15,11 @@ import { useParams } from 'react-router-dom';
 import { ConfirmModal } from '@ui/features/common/confirm-modal/confirm-modal';
 import { descriptionExpandable } from '@ui/features/common/description-expandable';
 import { useModal } from '@ui/features/common/modal/use-modal';
-import { Role } from '@ui/gen/rbac/v1alpha1/generated_pb';
-import { deleteRole, listRoles } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { Role } from '@ui/gen/api/rbac/v1alpha1/generated_pb';
+import {
+  deleteRole,
+  listRoles
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import { CreateRole } from './create-role';
 import { RulesModal } from './rules-modal';
diff --git a/ui/src/features/project/roles/rule-editor.tsx b/ui/src/features/project/roles/rule-editor.tsx
index 590a1208..40d37dcd 100644
--- a/ui/src/features/project/roles/rule-editor.tsx
+++ b/ui/src/features/project/roles/rule-editor.tsx
@@ -104,6 +104,7 @@ export const RuleEditor = ({
           <FieldContainer control={control} name='resourceNames' className='w-full'>
             {({ field }) => (
               <MultiStringEditor
+                // @ts-expect-error zod infer problem
                 value={field.value}
                 onChange={field.onChange}
                 placeholder='my-stage'
diff --git a/ui/src/features/project/settings/components/delete-project-modal.tsx b/ui/src/features/project/settings/components/delete-project-modal.tsx
index aae53e46..0949231c 100644
--- a/ui/src/features/project/settings/components/delete-project-modal.tsx
+++ b/ui/src/features/project/settings/components/delete-project-modal.tsx
@@ -10,7 +10,7 @@ import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
 import {
   deleteResource,
   listProjects
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import { projectYAMLExample } from '../../list/utils/project-yaml-example';
 
diff --git a/ui/src/features/project/settings/components/edit-project-modal.tsx b/ui/src/features/project/settings/components/edit-project-modal.tsx
index c172f63f..24dea106 100644
--- a/ui/src/features/project/settings/components/edit-project-modal.tsx
+++ b/ui/src/features/project/settings/components/edit-project-modal.tsx
@@ -10,12 +10,12 @@ import { z } from 'zod';
 import { YamlEditor } from '@ui/features/common/code-editor/yaml-editor';
 import { FieldContainer } from '@ui/features/common/form/field-container';
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
-import schema from '@ui/gen/schema/projects.kargo.akuity.io_v1alpha1.json';
 import {
   getProject,
   updateResource
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
+import schema from '@ui/gen/schema/projects.kargo.akuity.io_v1alpha1.json';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 import { zodValidators } from '@ui/utils/validators';
 
diff --git a/ui/src/features/promotion-directives/utils.ts b/ui/src/features/promotion-directives/utils.ts
index 11df7b78..f9d59410 100644
--- a/ui/src/features/promotion-directives/utils.ts
+++ b/ui/src/features/promotion-directives/utils.ts
@@ -1,4 +1,4 @@
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 
 // context to bridge directives and pipelines UI
diff --git a/ui/src/features/settings/analysis-templates/analysis-templates.tsx b/ui/src/features/settings/analysis-templates/analysis-templates.tsx
index 8550e7f7..6f9cc5b2 100644
--- a/ui/src/features/settings/analysis-templates/analysis-templates.tsx
+++ b/ui/src/features/settings/analysis-templates/analysis-templates.tsx
@@ -7,11 +7,11 @@ import { format } from 'date-fns';
 import { useConfirmModal } from '@ui/features/common/confirm-modal/use-confirm-modal';
 import { descriptionExpandable } from '@ui/features/common/description-expandable';
 import { useModal } from '@ui/features/common/modal/use-modal';
-import { ClusterAnalysisTemplate } from '@ui/gen/rollouts/api/v1alpha1/generated_pb';
 import {
   deleteClusterAnalysisTemplate,
   listClusterAnalysisTemplates
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { ClusterAnalysisTemplate } from '@ui/gen/api/stubs/rollouts/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 import { CreateClusterAnalysisTemplateModal } from './create-cluster-analysis-template-modal';
diff --git a/ui/src/features/settings/analysis-templates/create-cluster-analysis-template-modal.tsx b/ui/src/features/settings/analysis-templates/create-cluster-analysis-template-modal.tsx
index e6195538..0b45023a 100644
--- a/ui/src/features/settings/analysis-templates/create-cluster-analysis-template-modal.tsx
+++ b/ui/src/features/settings/analysis-templates/create-cluster-analysis-template-modal.tsx
@@ -10,7 +10,7 @@ import { ModalProps } from '@ui/features/common/modal/use-modal';
 import {
   createResource,
   listClusterAnalysisTemplates
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import { getClusterAnalysisTemplateYAMLExample } from '../../utils/cluster-analysis-template-example';
 
diff --git a/ui/src/features/settings/analysis-templates/edit-cluster-analysis-template-modal.tsx b/ui/src/features/settings/analysis-templates/edit-cluster-analysis-template-modal.tsx
index ae94b44b..5b547616 100644
--- a/ui/src/features/settings/analysis-templates/edit-cluster-analysis-template-modal.tsx
+++ b/ui/src/features/settings/analysis-templates/edit-cluster-analysis-template-modal.tsx
@@ -11,8 +11,8 @@ import {
   getClusterAnalysisTemplate,
   listClusterAnalysisTemplates,
   updateResource
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 
 import { getClusterAnalysisTemplateYAMLExample } from '../../utils/cluster-analysis-template-example';
diff --git a/ui/src/features/stage/create-stage.tsx b/ui/src/features/stage/create-stage.tsx
index 223f33fb..d76d1455 100644
--- a/ui/src/features/stage/create-stage.tsx
+++ b/ui/src/features/stage/create-stage.tsx
@@ -19,10 +19,10 @@ import { z } from 'zod';
 import { paths } from '@ui/config/paths';
 import { YamlEditor } from '@ui/features/common/code-editor/yaml-editor';
 import { FieldContainer } from '@ui/features/common/form/field-container';
+import { createResource } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { PromotionStep, Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 import { JSON } from '@ui/gen/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated_pb';
 import schema from '@ui/gen/schema/stages.kargo.akuity.io_v1alpha1.json';
-import { createResource } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { PromotionStep, Stage } from '@ui/gen/v1alpha1/generated_pb';
 import { PlainMessage } from '@ui/utils/connectrpc-utils';
 import { cleanEmptyObjectValues } from '@ui/utils/helpers';
 import { zodValidators } from '@ui/utils/validators';
@@ -157,7 +157,7 @@ export const CreateStage = ({
           Create Stage
         </Typography.Title>
         <Typography.Link
-          href='https://docs.kargo.io/concepts/#stage-resources'
+          href='https://docs.kargo.io/user-guide/how-to-guides/working-with-stages'
           target='_blank'
           className='ml-3'
         >
@@ -208,7 +208,9 @@ export const CreateStage = ({
           className='mb-4'
         >
           <FieldContainer name='name' label='Name' control={wizardControl}>
-            {({ field }) => <Input {...field} placeholder='my-stage' />}
+            {({ field }) => (
+              <Input {...field} value={field.value as string} placeholder='my-stage' />
+            )}
           </FieldContainer>
           <FieldContainer name='color' label='Color' control={wizardControl}>
             {({ field }) => (
diff --git a/ui/src/features/stage/create-warehouse/create-warehouse-wizard.tsx b/ui/src/features/stage/create-warehouse/create-warehouse-wizard.tsx
index 59267259..6db3a5aa 100644
--- a/ui/src/features/stage/create-warehouse/create-warehouse-wizard.tsx
+++ b/ui/src/features/stage/create-warehouse/create-warehouse-wizard.tsx
@@ -10,7 +10,7 @@ import { DescriptionFieldTemplate } from '@ui/features/common/form/rjsf/descript
 import { FieldTemplate } from '@ui/features/common/form/rjsf/field-template';
 import { ObjectFieldTemplate } from '@ui/features/common/form/rjsf/object-field-template';
 import rjsfStylesOverride from '@ui/features/common/form/rjsf/style-overrides.module.less';
-import { WarehouseSpec } from '@ui/gen/v1alpha1/generated_pb';
+import { WarehouseSpec } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { warehouseCreateFormJSONSchema } from './schema';
 import { SubscriptionWizard } from './subscription-wizard';
diff --git a/ui/src/features/stage/create-warehouse/create-warehouse.tsx b/ui/src/features/stage/create-warehouse/create-warehouse.tsx
index 66fbe99d..31018d9e 100644
--- a/ui/src/features/stage/create-warehouse/create-warehouse.tsx
+++ b/ui/src/features/stage/create-warehouse/create-warehouse.tsx
@@ -10,8 +10,8 @@ import { paths } from '@ui/config/paths';
 import { YamlEditor } from '@ui/features/common/code-editor/yaml-editor';
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
 import { WarehouseManifestsGen } from '@ui/features/utils/manifest-generator';
+import { createResource } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import warehouseSchema from '@ui/gen/schema/warehouses.kargo.akuity.io_v1alpha1.json';
-import { createResource } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
 
 import { CreateWarehouseWizard } from './create-warehouse-wizard';
 
@@ -122,7 +122,7 @@ const CreateWarehouse = (props: ModalComponentProps) => {
             Create Warehouse
           </Typography.Title>
           <Typography.Link
-            href='https://docs.kargo.io/concepts/#warehouse-resources'
+            href='https://docs.kargo.io/user-guide/how-to-guides/working-with-warehouses'
             target='_blank'
             className='ml-3'
           >
diff --git a/ui/src/features/stage/create-warehouse/subscription-wizard.tsx b/ui/src/features/stage/create-warehouse/subscription-wizard.tsx
index 51f20fda..20eedce2 100644
--- a/ui/src/features/stage/create-warehouse/subscription-wizard.tsx
+++ b/ui/src/features/stage/create-warehouse/subscription-wizard.tsx
@@ -14,7 +14,7 @@ import { FieldTemplate } from '@ui/features/common/form/rjsf/field-template';
 import { ObjectFieldTemplate } from '@ui/features/common/form/rjsf/object-field-template';
 import { IconSetByKargoTerminology } from '@ui/features/common/icons';
 import { ObjectDescription } from '@ui/features/common/object-description';
-import { RepoSubscription } from '@ui/gen/v1alpha1/generated_pb';
+import { RepoSubscription } from '@ui/gen/api/v1alpha1/generated_pb';
 import { PlainMessage } from '@ui/utils/connectrpc-utils';
 
 import { warehouseCreateFormJSONSchema } from './schema';
diff --git a/ui/src/features/stage/edit-stage-modal.tsx b/ui/src/features/stage/edit-stage-modal.tsx
index abe77e4a..8005bdab 100644
--- a/ui/src/features/stage/edit-stage-modal.tsx
+++ b/ui/src/features/stage/edit-stage-modal.tsx
@@ -8,12 +8,12 @@ import { z } from 'zod';
 import { YamlEditor } from '@ui/features/common/code-editor/yaml-editor';
 import { FieldContainer } from '@ui/features/common/form/field-container';
 import { ModalComponentProps } from '@ui/features/common/modal/modal-context';
-import schema from '@ui/gen/schema/stages.kargo.akuity.io_v1alpha1.json';
 import {
   getStage,
   updateResource
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
+import schema from '@ui/gen/schema/stages.kargo.akuity.io_v1alpha1.json';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 import { zodValidators } from '@ui/utils/validators';
 
diff --git a/ui/src/features/stage/freight-history.tsx b/ui/src/features/stage/freight-history.tsx
index dee6eec2..bb7006ad 100644
--- a/ui/src/features/stage/freight-history.tsx
+++ b/ui/src/features/stage/freight-history.tsx
@@ -9,15 +9,15 @@ import { generatePath, Link, useNavigate } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
 import freightTimelineStyles from '@ui/features/freight-timeline/freight-timeline.module.less';
-import { ObjectMetaSchema } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
-import { queryFreight } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { queryFreight } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import {
   Freight,
   FreightReference,
   FreightRequest,
   FreightSchema,
   StageStatus
-} from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/v1alpha1/generated_pb';
+import { ObjectMetaSchema } from '@ui/gen/k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb';
 import { PlainMessage } from '@ui/utils/connectrpc-utils';
 
 import { LoadingState } from '../common';
diff --git a/ui/src/features/stage/promotion-details-modal.tsx b/ui/src/features/stage/promotion-details-modal.tsx
index 2ee58316..bd8dbc34 100644
--- a/ui/src/features/stage/promotion-details-modal.tsx
+++ b/ui/src/features/stage/promotion-details-modal.tsx
@@ -27,8 +27,8 @@ import {
 import { usePromotionDirectivesRegistryContext } from '@ui/features/promotion-directives/registry/context/use-registry-context';
 import { Runner } from '@ui/features/promotion-directives/registry/types';
 import { canAbortPromotion } from '@ui/features/stage/utils/promotion';
-import { abortPromotion } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Promotion, PromotionSchema, PromotionStep } from '@ui/gen/v1alpha1/generated_pb';
+import { abortPromotion } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Promotion, PromotionSchema, PromotionStep } from '@ui/gen/api/v1alpha1/generated_pb';
 import uiPlugins from '@ui/plugins';
 import { UiPluginHoles } from '@ui/plugins/atoms/ui-plugin-hole/ui-plugin-holes';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
diff --git a/ui/src/features/stage/promotion-steps-wizard/use-promotion-wizard-steps-state.ts b/ui/src/features/stage/promotion-steps-wizard/use-promotion-wizard-steps-state.ts
index f35b1214..dad69e88 100644
--- a/ui/src/features/stage/promotion-steps-wizard/use-promotion-wizard-steps-state.ts
+++ b/ui/src/features/stage/promotion-steps-wizard/use-promotion-wizard-steps-state.ts
@@ -3,7 +3,7 @@ import { parse, stringify } from 'yaml';
 
 import { usePromotionDirectivesRegistryContext } from '@ui/features/promotion-directives/registry/context/use-registry-context';
 import { Runner } from '@ui/features/promotion-directives/registry/types';
-import { PromotionStep } from '@ui/gen/v1alpha1/generated_pb';
+import { PromotionStep } from '@ui/gen/api/v1alpha1/generated_pb';
 import { PlainMessage } from '@ui/utils/connectrpc-utils';
 
 import { RunnerWithConfiguration } from './types';
diff --git a/ui/src/features/stage/promotions.tsx b/ui/src/features/stage/promotions.tsx
index 91a7764a..d020c1e1 100644
--- a/ui/src/features/stage/promotions.tsx
+++ b/ui/src/features/stage/promotions.tsx
@@ -17,11 +17,11 @@ import {
 import {
   getFreight,
   listPromotions
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { ListPromotionsResponse } from '@ui/gen/service/v1alpha1/service_pb';
-import { KargoService } from '@ui/gen/service/v1alpha1/service_pb';
-import { ArgoCDShard } from '@ui/gen/service/v1alpha1/service_pb';
-import { Freight, Promotion } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { ListPromotionsResponse } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { KargoService } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { ArgoCDShard } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { Freight, Promotion } from '@ui/gen/api/v1alpha1/generated_pb';
 import uiPlugins from '@ui/plugins';
 import { UiPluginHoles } from '@ui/plugins/atoms/ui-plugin-hole/ui-plugin-holes';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
diff --git a/ui/src/features/stage/requested-freight-editor.tsx b/ui/src/features/stage/requested-freight-editor.tsx
index db5673c9..9baabb92 100644
--- a/ui/src/features/stage/requested-freight-editor.tsx
+++ b/ui/src/features/stage/requested-freight-editor.tsx
@@ -5,7 +5,7 @@ import { Alert, AutoComplete, Button, Flex, Select, Switch, Tooltip } from 'antd
 import classNames from 'classnames';
 import { useForm } from 'react-hook-form';
 
-import { FreightOrigin, FreightRequest, FreightSources } from '@ui/gen/v1alpha1/generated_pb';
+import { FreightOrigin, FreightRequest, FreightSources } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { FieldContainer } from '../common/form/field-container';
 
diff --git a/ui/src/features/stage/requested-freight.tsx b/ui/src/features/stage/requested-freight.tsx
index 11893071..40963256 100644
--- a/ui/src/features/stage/requested-freight.tsx
+++ b/ui/src/features/stage/requested-freight.tsx
@@ -6,7 +6,7 @@ import { Link, generatePath } from 'react-router-dom';
 
 import { paths } from '@ui/config/paths';
 import { ColorContext } from '@ui/context/colors';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { SmallLabel } from '../common/small-label';
 import { StageTag } from '../common/stage-tag';
diff --git a/ui/src/features/stage/stage-actions.tsx b/ui/src/features/stage/stage-actions.tsx
index e51dedf1..1eedfcf4 100644
--- a/ui/src/features/stage/stage-actions.tsx
+++ b/ui/src/features/stage/stage-actions.tsx
@@ -20,8 +20,8 @@ import {
   queryFreight,
   refreshStage,
   reverify
-} from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 import { useConfirmModal } from '../common/confirm-modal/use-confirm-modal';
 import { useModal } from '../common/modal/use-modal';
diff --git a/ui/src/features/stage/stage-details.tsx b/ui/src/features/stage/stage-details.tsx
index fd5fd2be..0b1b574d 100644
--- a/ui/src/features/stage/stage-details.tsx
+++ b/ui/src/features/stage/stage-details.tsx
@@ -1,5 +1,8 @@
 import { useQuery } from '@connectrpc/connect-query';
-import { Divider, Drawer, Skeleton, Tabs, Typography } from 'antd';
+import { faChevronDown, faExternalLink } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Divider, Drawer, Skeleton, Space, Tabs, Typography } from 'antd';
+import Dropdown from 'antd/es/dropdown/dropdown';
 import moment from 'moment';
 import { useEffect, useMemo, useState } from 'react';
 import { generatePath, useNavigate, useParams } from 'react-router-dom';
@@ -10,9 +13,12 @@ import { HealthStatusIcon } from '@ui/features/common/health-status/health-statu
 import { StagePhaseIcon } from '@ui/features/common/stage-phase/stage-phase-icon';
 import { StagePhase } from '@ui/features/common/stage-phase/utils';
 import { useImages } from '@ui/features/project/pipelines/utils/useImages';
-import { getConfig, getStage } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { RawFormat } from '@ui/gen/service/v1alpha1/service_pb';
-import { Stage, VerificationInfo } from '@ui/gen/v1alpha1/generated_pb';
+import {
+  getConfig,
+  getStage
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { RawFormat } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { Stage, VerificationInfo } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 
@@ -80,6 +86,44 @@ export const StageDetails = ({ stage }: { stage: Stage }) => {
   const shardKey = stage?.metadata?.labels['kargo.akuity.io/shard'] || '';
   const argocdShard = config?.argocdShards?.[shardKey];
 
+  const argocdLinks = useMemo(() => {
+    const argocdContextKey = 'kargo.akuity.io/argocd-context';
+
+    if (!argocdShard) {
+      return [];
+    }
+
+    const argocdShardUrl = argocdShard?.url?.endsWith('/')
+      ? argocdShard?.url?.slice(0, -1)
+      : argocdShard?.url;
+
+    const rawValues = stage.metadata?.annotations?.[argocdContextKey];
+
+    if (!rawValues) {
+      return [];
+    }
+
+    try {
+      const parsedValues = JSON.parse(rawValues) as Array<{
+        name: string;
+        namespace: string;
+      }>;
+
+      return (
+        parsedValues?.map(
+          (parsedValue) =>
+            `${argocdShardUrl}/applications/${parsedValue.namespace}/${parsedValue.name}`
+        ) || []
+      );
+    } catch (e) {
+      // deliberately do not crash
+      // eslint-disable-next-line no-console
+      console.error(e);
+
+      return [];
+    }
+  }, [argocdShard, stage]);
+
   return (
     <Drawer open={!!stageName} onClose={onClose} width={'80%'} closable={false}>
       {stage && (
@@ -98,6 +142,56 @@ export const StageDetails = ({ stage }: { stage: Stage }) => {
                 <Description item={stage} loading={false} className='mt-2' />
               </div>
             </div>
+            {argocdLinks?.length > 0 ? (
+              <div className='ml-auto mr-5 text-base flex gap-2 items-center'>
+                {argocdLinks?.length === 1 && (
+                  <a
+                    target='_blank'
+                    href={argocdLinks[0]}
+                    className='ml-auto mr-5 text-base flex gap-2 items-center'
+                  >
+                    ArgoCD
+                    <FontAwesomeIcon icon={faExternalLink} className='text-xs' />
+                  </a>
+                )}
+                {argocdLinks?.length > 1 && (
+                  <Dropdown
+                    menu={{
+                      items: argocdLinks.map((link, idx) => {
+                        const parts = link?.split('/');
+                        const name = parts?.[parts.length - 1];
+                        const namespace = parts?.[parts.length - 2];
+                        return {
+                          key: idx,
+                          label: (
+                            <a target='_blank' href={link}>
+                              {namespace} - {name}
+                              <FontAwesomeIcon icon={faExternalLink} className='text-xs ml-2' />
+                            </a>
+                          )
+                        };
+                      })
+                    }}
+                  >
+                    <a onClick={(e) => e.preventDefault()}>
+                      <Space>
+                        ArgoCD
+                        <FontAwesomeIcon icon={faChevronDown} className='text-xs' />
+                      </Space>
+                    </a>
+                  </Dropdown>
+                )}
+              </div>
+            ) : argocdShard?.url ? (
+              <a
+                target='_blank'
+                href={argocdShard?.url}
+                className='ml-auto mr-5 text-base flex gap-2 items-center'
+              >
+                ArgoCD
+                <FontAwesomeIcon icon={faExternalLink} className='text-xs' />
+              </a>
+            ) : null}
             <StageActions stage={stage} verificationRunning={isVerificationRunning} />
           </div>
           <Divider style={{ marginTop: '1em' }} />
diff --git a/ui/src/features/stage/utils/promotion.ts b/ui/src/features/stage/utils/promotion.ts
index be80d84a..550d7677 100644
--- a/ui/src/features/stage/utils/promotion.ts
+++ b/ui/src/features/stage/utils/promotion.ts
@@ -4,7 +4,7 @@ import {
   getPromotionStatusPhase,
   isPromotionPhaseTerminal
 } from '@ui/features/common/promotion-status/utils';
-import { Promotion } from '@ui/gen/v1alpha1/generated_pb';
+import { Promotion } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 export const canAbortPromotion = (promotion: Promotion) =>
diff --git a/ui/src/features/stage/verifications.tsx b/ui/src/features/stage/verifications.tsx
index a0f27aab..dec57aea 100644
--- a/ui/src/features/stage/verifications.tsx
+++ b/ui/src/features/stage/verifications.tsx
@@ -4,7 +4,7 @@ import { format } from 'date-fns';
 import moment from 'moment';
 import { useMemo, useState } from 'react';
 
-import { VerificationInfo } from '@ui/gen/v1alpha1/generated_pb';
+import { VerificationInfo } from '@ui/gen/api/v1alpha1/generated_pb';
 import { timestampDate } from '@ui/utils/connectrpc-utils';
 
 import { AnalysisModal } from '../common/analysis-modal/analysis-modal';
diff --git a/ui/src/features/utils/cache/analysis-templates.ts b/ui/src/features/utils/cache/analysis-templates.ts
index eeec3c14..4a98c15c 100644
--- a/ui/src/features/utils/cache/analysis-templates.ts
+++ b/ui/src/features/utils/cache/analysis-templates.ts
@@ -2,9 +2,9 @@ import { create } from '@bufbuild/protobuf';
 import { createConnectQueryKey, createProtobufSafeUpdater } from '@connectrpc/connect-query';
 
 import { queryClient } from '@ui/config/query-client';
-import { AnalysisTemplate } from '@ui/gen/rollouts/api/v1alpha1/generated_pb';
-import { listAnalysisTemplates } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { ListAnalysisTemplatesResponseSchema } from '@ui/gen/service/v1alpha1/service_pb';
+import { listAnalysisTemplates } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { ListAnalysisTemplatesResponseSchema } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { AnalysisTemplate } from '@ui/gen/api/stubs/rollouts/v1alpha1/generated_pb';
 
 export default {
   add: (project: string, templates: AnalysisTemplate[]) => {
diff --git a/ui/src/features/utils/cache/image-stage-matrix.ts b/ui/src/features/utils/cache/image-stage-matrix.ts
index 2deb40c2..8f45794b 100644
--- a/ui/src/features/utils/cache/image-stage-matrix.ts
+++ b/ui/src/features/utils/cache/image-stage-matrix.ts
@@ -4,14 +4,14 @@ import { createConnectQueryKey } from '@connectrpc/connect-query';
 import { queryClient } from '@ui/config/query-client';
 import { transportWithAuth } from '@ui/config/transport';
 import { PromotionStatusPhase } from '@ui/features/common/promotion-status/utils';
-import { listImages } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { listImages } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 import {
   ImageStageMap,
   ListImagesRequestSchema,
   ListImagesResponse,
   TagMap
-} from '@ui/gen/service/v1alpha1/service_pb';
-import { Stage } from '@ui/gen/v1alpha1/generated_pb';
+} from '@ui/gen/api/service/v1alpha1/service_pb';
+import { Stage } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export default {
   /**
diff --git a/ui/src/features/utils/cache/project.ts b/ui/src/features/utils/cache/project.ts
index e7a87ddf..c657016a 100644
--- a/ui/src/features/utils/cache/project.ts
+++ b/ui/src/features/utils/cache/project.ts
@@ -2,9 +2,9 @@ import { create } from '@bufbuild/protobuf';
 import { createConnectQueryKey, createProtobufSafeUpdater } from '@connectrpc/connect-query';
 
 import { queryClient } from '@ui/config/query-client';
-import { listProjects } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { ListProjectsResponseSchema } from '@ui/gen/service/v1alpha1/service_pb';
-import { Project } from '@ui/gen/v1alpha1/generated_pb';
+import { listProjects } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { ListProjectsResponseSchema } from '@ui/gen/api/service/v1alpha1/service_pb';
+import { Project } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export default {
   add: (projects: Project[]) => {
diff --git a/ui/src/features/utils/manifest-generator.ts b/ui/src/features/utils/manifest-generator.ts
index 2e485eda..3a63a898 100644
--- a/ui/src/features/utils/manifest-generator.ts
+++ b/ui/src/features/utils/manifest-generator.ts
@@ -1,6 +1,6 @@
 import { stringify } from 'yaml';
 
-import { WarehouseSpec } from '@ui/gen/v1alpha1/generated_pb';
+import { WarehouseSpec } from '@ui/gen/api/v1alpha1/generated_pb';
 import { PartialRecursive, PlainMessageRecursive } from '@ui/utils/connectrpc-utils';
 import { cleanEmptyObjectValues } from '@ui/utils/helpers';
 
diff --git a/ui/src/gen/rbac/v1alpha1/generated_pb.ts b/ui/src/gen/api/rbac/v1alpha1/generated_pb.ts
similarity index 59%
rename from ui/src/gen/rbac/v1alpha1/generated_pb.ts
rename to ui/src/gen/api/rbac/v1alpha1/generated_pb.ts
index 78094b9c..310d8aa3 100644
--- a/ui/src/gen/rbac/v1alpha1/generated_pb.ts
+++ b/ui/src/gen/api/rbac/v1alpha1/generated_pb.ts
@@ -1,26 +1,26 @@
 // This file was autogenerated by go-to-protobuf. Do not edit it manually!
 
 // @generated by protoc-gen-es v2.2.2 with parameter "target=ts"
-// @generated from file rbac/v1alpha1/generated.proto (package github.com.akuity.kargo.api.rbac.v1alpha1, syntax proto2)
+// @generated from file api/rbac/v1alpha1/generated.proto (package github.com.akuity.kargo.api.rbac.v1alpha1, syntax proto2)
 /* eslint-disable */
 
 import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
 import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
-import type { ServiceAccount } from "../../k8s.io/api/core/v1/generated_pb";
-import { file_k8s_io_api_core_v1_generated } from "../../k8s.io/api/core/v1/generated_pb";
-import type { PolicyRule, Role as Role$1, RoleBinding } from "../../k8s.io/api/rbac/v1/generated_pb";
-import { file_k8s_io_api_rbac_v1_generated } from "../../k8s.io/api/rbac/v1/generated_pb";
-import type { ObjectMeta } from "../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
-import { file_k8s_io_apimachinery_pkg_apis_meta_v1_generated } from "../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
-import { file_k8s_io_apimachinery_pkg_runtime_generated } from "../../k8s.io/apimachinery/pkg/runtime/generated_pb";
-import { file_k8s_io_apimachinery_pkg_runtime_schema_generated } from "../../k8s.io/apimachinery/pkg/runtime/schema/generated_pb";
+import type { ServiceAccount } from "../../../k8s.io/api/core/v1/generated_pb";
+import { file_k8s_io_api_core_v1_generated } from "../../../k8s.io/api/core/v1/generated_pb";
+import type { PolicyRule, Role as Role$1, RoleBinding } from "../../../k8s.io/api/rbac/v1/generated_pb";
+import { file_k8s_io_api_rbac_v1_generated } from "../../../k8s.io/api/rbac/v1/generated_pb";
+import type { ObjectMeta } from "../../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
+import { file_k8s_io_apimachinery_pkg_apis_meta_v1_generated } from "../../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
+import { file_k8s_io_apimachinery_pkg_runtime_generated } from "../../../k8s.io/apimachinery/pkg/runtime/generated_pb";
+import { file_k8s_io_apimachinery_pkg_runtime_schema_generated } from "../../../k8s.io/apimachinery/pkg/runtime/schema/generated_pb";
 import type { Message } from "@bufbuild/protobuf";
 
 /**
- * Describes the file rbac/v1alpha1/generated.proto.
+ * Describes the file api/rbac/v1alpha1/generated.proto.
  */
-export const file_rbac_v1alpha1_generated: GenFile = /*@__PURE__*/
-  fileDesc("Ch1yYmFjL3YxYWxwaGExL2dlbmVyYXRlZC5wcm90bxIpZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEiJQoFQ2xhaW0SDAoEbmFtZRgBIAEoCRIOCgZ2YWx1ZXMYAiADKAkiTAoPUmVzb3VyY2VEZXRhaWxzEhQKDHJlc291cmNlVHlwZRgBIAEoCRIUCgxyZXNvdXJjZU5hbWUYAiABKAkSDQoFdmVyYnMYAyADKAki0QEKBFJvbGUSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRIUCgxrYXJnb01hbmFnZWQYAiABKAgSQAoGY2xhaW1zGAcgAygLMjAuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuQ2xhaW0SLQoFcnVsZXMYBiADKAsyHi5rOHMuaW8uYXBpLnJiYWMudjEuUG9saWN5UnVsZSLvAQoNUm9sZVJlc291cmNlcxJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEjoKDnNlcnZpY2VBY2NvdW50GAIgASgLMiIuazhzLmlvLmFwaS5jb3JlLnYxLlNlcnZpY2VBY2NvdW50EicKBXJvbGVzGAMgAygLMhguazhzLmlvLmFwaS5yYmFjLnYxLlJvbGUSNQoMcm9sZUJpbmRpbmdzGAQgAygLMh8uazhzLmlvLmFwaS5yYmFjLnYxLlJvbGVCaW5kaW5nQrcCCi1jb20uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTFCDkdlbmVyYXRlZFByb3RvUAFaKWdpdGh1Yi5jb20vYWt1aXR5L2thcmdvL2FwaS9yYmFjL3YxYWxwaGExogIGR0NBS0FSqgIpR2l0aHViLkNvbS5Ba3VpdHkuS2FyZ28uQXBpLlJiYWMuVjFhbHBoYTHKAilHaXRodWJcQ29tXEFrdWl0eVxLYXJnb1xBcGlcUmJhY1xWMWFscGhhMeICNUdpdGh1YlxDb21cQWt1aXR5XEthcmdvXEFwaVxSYmFjXFYxYWxwaGExXEdQQk1ldGFkYXRh6gIvR2l0aHViOjpDb206OkFrdWl0eTo6S2FyZ286OkFwaTo6UmJhYzo6VjFhbHBoYTE", [file_k8s_io_api_core_v1_generated, file_k8s_io_api_rbac_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]);
+export const file_api_rbac_v1alpha1_generated: GenFile = /*@__PURE__*/
+  fileDesc("CiFhcGkvcmJhYy92MWFscGhhMS9nZW5lcmF0ZWQucHJvdG8SKWdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExIiUKBUNsYWltEgwKBG5hbWUYASABKAkSDgoGdmFsdWVzGAIgAygJIkwKD1Jlc291cmNlRGV0YWlscxIUCgxyZXNvdXJjZVR5cGUYASABKAkSFAoMcmVzb3VyY2VOYW1lGAIgASgJEg0KBXZlcmJzGAMgAygJItEBCgRSb2xlEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESFAoMa2FyZ29NYW5hZ2VkGAIgASgIEkAKBmNsYWltcxgHIAMoCzIwLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLkNsYWltEi0KBXJ1bGVzGAYgAygLMh4uazhzLmlvLmFwaS5yYmFjLnYxLlBvbGljeVJ1bGUi7wEKDVJvbGVSZXNvdXJjZXMSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRI6Cg5zZXJ2aWNlQWNjb3VudBgCIAEoCzIiLms4cy5pby5hcGkuY29yZS52MS5TZXJ2aWNlQWNjb3VudBInCgVyb2xlcxgDIAMoCzIYLms4cy5pby5hcGkucmJhYy52MS5Sb2xlEjUKDHJvbGVCaW5kaW5ncxgEIAMoCzIfLms4cy5pby5hcGkucmJhYy52MS5Sb2xlQmluZGluZ0K3AgotY29tLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExQg5HZW5lcmF0ZWRQcm90b1ABWilnaXRodWIuY29tL2FrdWl0eS9rYXJnby9hcGkvcmJhYy92MWFscGhhMaICBkdDQUtBUqoCKUdpdGh1Yi5Db20uQWt1aXR5LkthcmdvLkFwaS5SYmFjLlYxYWxwaGExygIpR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFJiYWNcVjFhbHBoYTHiAjVHaXRodWJcQ29tXEFrdWl0eVxLYXJnb1xBcGlcUmJhY1xWMWFscGhhMVxHUEJNZXRhZGF0YeoCL0dpdGh1Yjo6Q29tOjpBa3VpdHk6OkthcmdvOjpBcGk6OlJiYWM6OlYxYWxwaGEx", [file_k8s_io_api_core_v1_generated, file_k8s_io_api_rbac_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]);
 
 /**
  * @generated from message github.com.akuity.kargo.api.rbac.v1alpha1.Claim
@@ -42,7 +42,7 @@ export type Claim = Message<"github.com.akuity.kargo.api.rbac.v1alpha1.Claim"> &
  * Use `create(ClaimSchema)` to create a new message.
  */
 export const ClaimSchema: GenMessage<Claim> = /*@__PURE__*/
-  messageDesc(file_rbac_v1alpha1_generated, 0);
+  messageDesc(file_api_rbac_v1alpha1_generated, 0);
 
 /**
  * @generated from message github.com.akuity.kargo.api.rbac.v1alpha1.ResourceDetails
@@ -69,7 +69,7 @@ export type ResourceDetails = Message<"github.com.akuity.kargo.api.rbac.v1alpha1
  * Use `create(ResourceDetailsSchema)` to create a new message.
  */
 export const ResourceDetailsSchema: GenMessage<ResourceDetails> = /*@__PURE__*/
-  messageDesc(file_rbac_v1alpha1_generated, 1);
+  messageDesc(file_api_rbac_v1alpha1_generated, 1);
 
 /**
  * +kubebuilder:object:root=true
@@ -103,7 +103,7 @@ export type Role = Message<"github.com.akuity.kargo.api.rbac.v1alpha1.Role"> & {
  * Use `create(RoleSchema)` to create a new message.
  */
 export const RoleSchema: GenMessage<Role> = /*@__PURE__*/
-  messageDesc(file_rbac_v1alpha1_generated, 2);
+  messageDesc(file_api_rbac_v1alpha1_generated, 2);
 
 /**
  * +kubebuilder:object:root=true
@@ -137,5 +137,5 @@ export type RoleResources = Message<"github.com.akuity.kargo.api.rbac.v1alpha1.R
  * Use `create(RoleResourcesSchema)` to create a new message.
  */
 export const RoleResourcesSchema: GenMessage<RoleResources> = /*@__PURE__*/
-  messageDesc(file_rbac_v1alpha1_generated, 3);
+  messageDesc(file_api_rbac_v1alpha1_generated, 3);
 
diff --git a/ui/src/gen/service/v1alpha1/service-KargoService_connectquery.ts b/ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts
similarity index 98%
rename from ui/src/gen/service/v1alpha1/service-KargoService_connectquery.ts
rename to ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts
index 827d3082..41aff3d5 100644
--- a/ui/src/gen/service/v1alpha1/service-KargoService_connectquery.ts
+++ b/ui/src/gen/api/service/v1alpha1/service-KargoService_connectquery.ts
@@ -1,5 +1,5 @@
 // @generated by protoc-gen-connect-query v2.0.0 with parameter "target=ts"
-// @generated from file service/v1alpha1/service.proto (package akuity.io.kargo.service.v1alpha1, syntax proto3)
+// @generated from file api/service/v1alpha1/service.proto (package akuity.io.kargo.service.v1alpha1, syntax proto3)
 /* eslint-disable */
 
 import { KargoService } from "./service_pb";
diff --git a/ui/src/gen/service/v1alpha1/service_pb.ts b/ui/src/gen/api/service/v1alpha1/service_pb.ts
similarity index 74%
rename from ui/src/gen/service/v1alpha1/service_pb.ts
rename to ui/src/gen/api/service/v1alpha1/service_pb.ts
index c7a6e5b4..1081feb3 100644
--- a/ui/src/gen/service/v1alpha1/service_pb.ts
+++ b/ui/src/gen/api/service/v1alpha1/service_pb.ts
@@ -1,5 +1,5 @@
 // @generated by protoc-gen-es v2.2.2 with parameter "target=ts"
-// @generated from file service/v1alpha1/service.proto (package akuity.io.kargo.service.v1alpha1, syntax proto3)
+// @generated from file api/service/v1alpha1/service.proto (package akuity.io.kargo.service.v1alpha1, syntax proto3)
 /* eslint-disable */
 
 import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv1";
@@ -7,20 +7,20 @@ import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf
 import type { Timestamp } from "@bufbuild/protobuf/wkt";
 import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
 import type { Freight, Project, Promotion, Stage, Warehouse } from "../../v1alpha1/generated_pb";
-import { file_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";
-import type { AnalysisRun, AnalysisTemplate, ClusterAnalysisTemplate } from "../../rollouts/api/v1alpha1/generated_pb";
-import { file_rollouts_api_v1alpha1_generated } from "../../rollouts/api/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";
+import type { AnalysisRun, AnalysisTemplate, ClusterAnalysisTemplate } from "../../stubs/rollouts/v1alpha1/generated_pb";
+import { file_api_stubs_rollouts_v1alpha1_generated } from "../../stubs/rollouts/v1alpha1/generated_pb";
 import type { Claim, ResourceDetails, Role, RoleResources } from "../../rbac/v1alpha1/generated_pb";
-import { file_rbac_v1alpha1_generated } from "../../rbac/v1alpha1/generated_pb";
+import { file_api_rbac_v1alpha1_generated } from "../../rbac/v1alpha1/generated_pb";
 import type { Message } from "@bufbuild/protobuf";
 
 /**
- * Describes the file service/v1alpha1/service.proto.
+ * Describes the file api/service/v1alpha1/service.proto.
  */
-export const file_service_v1alpha1_service: GenFile = /*@__PURE__*/
-  fileDesc("Ch5zZXJ2aWNlL3YxYWxwaGExL3NlcnZpY2UucHJvdG8SIGFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExIqsBChFDb21wb25lbnRWZXJzaW9ucxJCCgZzZXJ2ZXIYASABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5WZXJzaW9uSW5mb0gAiAEBEj8KA2NsaRgCIAEoCzItLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlZlcnNpb25JbmZvSAGIAQFCCQoHX3NlcnZlckIGCgRfY2xpIrIBCgtWZXJzaW9uSW5mbxIPCgd2ZXJzaW9uGAEgASgJEhIKCmdpdF9jb21taXQYAiABKAkSFgoOZ2l0X3RyZWVfZGlydHkYAyABKAgSLgoKYnVpbGRfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASEgoKZ29fdmVyc2lvbhgFIAEoCRIQCghjb21waWxlchgGIAEoCRIQCghwbGF0Zm9ybRgHIAEoCSIXChVHZXRWZXJzaW9uSW5mb1JlcXVlc3QiXQoWR2V0VmVyc2lvbkluZm9SZXNwb25zZRJDCgx2ZXJzaW9uX2luZm8YASABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5WZXJzaW9uSW5mbyISChBHZXRDb25maWdSZXF1ZXN0Ii0KC0FyZ29DRFNoYXJkEgsKA3VybBgBIAEoCRIRCgluYW1lc3BhY2UYAiABKAki+AEKEUdldENvbmZpZ1Jlc3BvbnNlElwKDWFyZ29jZF9zaGFyZHMYASADKAsyRS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDb25maWdSZXNwb25zZS5BcmdvY2RTaGFyZHNFbnRyeRIhChlzZWNyZXRfbWFuYWdlbWVudF9lbmFibGVkGAIgASgIGmIKEUFyZ29jZFNoYXJkc0VudHJ5EgsKA2tleRgBIAEoCRI8CgV2YWx1ZRgCIAEoCzItLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFyZ29DRFNoYXJkOgI4ASIYChZHZXRQdWJsaWNDb25maWdSZXF1ZXN0Io4BChdHZXRQdWJsaWNDb25maWdSZXNwb25zZRJBCgtvaWRjX2NvbmZpZxgBIAEoCzIsLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLk9JRENDb25maWcSHQoVYWRtaW5fYWNjb3VudF9lbmFibGVkGAIgASgIEhEKCXNraXBfYXV0aBgDIAEoCCJaCgpPSURDQ29uZmlnEhIKCmlzc3Vlcl91cmwYASABKAkSEQoJY2xpZW50X2lkGAIgASgJEg4KBnNjb3BlcxgDIAMoCRIVCg1jbGlfY2xpZW50X2lkGAQgASgJIiUKEUFkbWluTG9naW5SZXF1ZXN0EhAKCHBhc3N3b3JkGAEgASgJIiYKEkFkbWluTG9naW5SZXNwb25zZRIQCghpZF90b2tlbhgBIAEoCSIpChVDcmVhdGVSZXNvdXJjZVJlcXVlc3QSEAoIbWFuaWZlc3QYASABKAwiVgoUQ3JlYXRlUmVzb3VyY2VSZXN1bHQSIwoZY3JlYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgBIAEoDEgAEg8KBWVycm9yGAIgASgJSABCCAoGcmVzdWx0ImEKFkNyZWF0ZVJlc291cmNlUmVzcG9uc2USRwoHcmVzdWx0cxgBIAMoCzI2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVzdWx0IjEKHUNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXF1ZXN0EhAKCG1hbmlmZXN0GAEgASgMIoMBChxDcmVhdGVPclVwZGF0ZVJlc291cmNlUmVzdWx0EiMKGWNyZWF0ZWRfcmVzb3VyY2VfbWFuaWZlc3QYASABKAxIABIjChl1cGRhdGVkX3Jlc291cmNlX21hbmlmZXN0GAIgASgMSAASDwoFZXJyb3IYAyABKAlIAEIICgZyZXN1bHQicQoeQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3BvbnNlEk8KB3Jlc3VsdHMYASADKAsyPi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVzdWx0IikKFVVwZGF0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCJWChRVcGRhdGVSZXNvdXJjZVJlc3VsdBIjChl1cGRhdGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASDwoFZXJyb3IYAiABKAlIAEIICgZyZXN1bHQiYQoWVXBkYXRlUmVzb3VyY2VSZXNwb25zZRJHCgdyZXN1bHRzGAEgAygLMjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlUmVzb3VyY2VSZXN1bHQiKQoVRGVsZXRlUmVzb3VyY2VSZXF1ZXN0EhAKCG1hbmlmZXN0GAEgASgMIlYKFERlbGV0ZVJlc291cmNlUmVzdWx0EiMKGWRlbGV0ZWRfcmVzb3VyY2VfbWFuaWZlc3QYASABKAxIABIPCgVlcnJvchgCIAEoCUgAQggKBnJlc3VsdCJhChZEZWxldGVSZXNvdXJjZVJlc3BvbnNlEkcKB3Jlc3VsdHMYASADKAsyNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVSZXNvdXJjZVJlc3VsdCIkChFMaXN0U3RhZ2VzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIlEKEkxpc3RTdGFnZXNSZXNwb25zZRI7CgZzdGFnZXMYASADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2UiJAoRTGlzdEltYWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSK/AQoSTGlzdEltYWdlc1Jlc3BvbnNlElAKBmltYWdlcxgCIAMoCzJALmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RJbWFnZXNSZXNwb25zZS5JbWFnZXNFbnRyeRpXCgtJbWFnZXNFbnRyeRILCgNrZXkYASABKAkSNwoFdmFsdWUYAiABKAsyKC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5UYWdNYXA6AjgBIqgBCgZUYWdNYXASQAoEdGFncxgBIAMoCzIyLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlRhZ01hcC5UYWdzRW50cnkaXAoJVGFnc0VudHJ5EgsKA2tleRgBIAEoCRI+CgV2YWx1ZRgCIAEoCzIvLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkltYWdlU3RhZ2VNYXA6AjgBIosBCg1JbWFnZVN0YWdlTWFwEksKBnN0YWdlcxgBIAMoCzI7LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkltYWdlU3RhZ2VNYXAuU3RhZ2VzRW50cnkaLQoLU3RhZ2VzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgFOgI4ASJtCg9HZXRTdGFnZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJpChBHZXRTdGFnZVJlc3BvbnNlEjwKBXN0YWdlGAEgASgLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IjMKEldhdGNoU3RhZ2VzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiXwoTV2F0Y2hTdGFnZXNSZXNwb25zZRI6CgVzdGFnZRgBIAEoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZRIMCgR0eXBlGAIgASgJIjMKEkRlbGV0ZVN0YWdlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiFQoTRGVsZXRlU3RhZ2VSZXNwb25zZSI0ChNSZWZyZXNoU3RhZ2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSJSChRSZWZyZXNoU3RhZ2VSZXNwb25zZRI6CgVzdGFnZRgBIAEoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZSJGChVMaXN0UHJvbW90aW9uc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRISCgVzdGFnZRgCIAEoCUgAiAEBQggKBl9zdGFnZSJdChZMaXN0UHJvbW90aW9uc1Jlc3BvbnNlEkMKCnByb21vdGlvbnMYASADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uIkcKFldhdGNoUHJvbW90aW9uc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRISCgVzdGFnZRgCIAEoCUgAiAEBQggKBl9zdGFnZSJrChdXYXRjaFByb21vdGlvbnNSZXNwb25zZRJCCglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uEgwKBHR5cGUYAiABKAkicQoTR2V0UHJvbW90aW9uUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0InUKFEdldFByb21vdGlvblJlc3BvbnNlEkQKCXByb21vdGlvbhgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25IABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiNgoVV2F0Y2hQcm9tb3Rpb25SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSJqChZXYXRjaFByb21vdGlvblJlc3BvbnNlEkIKCXByb21vdGlvbhgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb24SDAoEdHlwZRgCIAEoCSI2ChVBYm9ydFByb21vdGlvblJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhgKFkFib3J0UHJvbW90aW9uUmVzcG9uc2UiJAoURGVsZXRlUHJvamVjdFJlcXVlc3QSDAoEbmFtZRgBIAEoCSIXChVEZWxldGVQcm9qZWN0UmVzcG9uc2UiXgoRR2V0UHJvamVjdFJlcXVlc3QSDAoEbmFtZRgBIAEoCRI7CgZmb3JtYXQYAiABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQibwoSR2V0UHJvamVjdFJlc3BvbnNlEkAKB3Byb2plY3QYASABKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdEgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCJ3ChNMaXN0UHJvamVjdHNSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUgAiAEBEhEKBHBhZ2UYAiABKAVIAYgBARITCgZmaWx0ZXIYAyABKAlIAogBAUIMCgpfcGFnZV9zaXplQgcKBV9wYWdlQgkKB19maWx0ZXIiZgoUTGlzdFByb2plY3RzUmVzcG9uc2USPwoIcHJvamVjdHMYASADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdBINCgV0b3RhbBgCIAEoBSJUChVBcHByb3ZlRnJlaWdodFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEg0KBWFsaWFzGAMgASgJEg0KBXN0YWdlGAQgASgJIhgKFkFwcHJvdmVGcmVpZ2h0UmVzcG9uc2UiRAoURGVsZXRlRnJlaWdodFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEg0KBWFsaWFzGAMgASgJIhcKFURlbGV0ZUZyZWlnaHRSZXNwb25zZSJ+ChFHZXRGcmVpZ2h0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSDQoFYWxpYXMYAyABKAkSOwoGZm9ybWF0GAQgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0Im8KEkdldEZyZWlnaHRSZXNwb25zZRJACgdmcmVpZ2h0GAEgASgLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiXwoVUHJvbW90ZVRvU3RhZ2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkSDwoHZnJlaWdodBgDIAEoCRIVCg1mcmVpZ2h0X2FsaWFzGAQgASgJIlwKFlByb21vdGVUb1N0YWdlUmVzcG9uc2USQgoJcHJvbW90aW9uGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiJiChhQcm9tb3RlRG93bnN0cmVhbVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRINCgVzdGFnZRgCIAEoCRIPCgdmcmVpZ2h0GAMgASgJEhUKDWZyZWlnaHRfYWxpYXMYBCABKAkiYAoZUHJvbW90ZURvd25zdHJlYW1SZXNwb25zZRJDCgpwcm9tb3Rpb25zGAEgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiKKAQoTUXVlcnlGcmVpZ2h0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJEhAKCGdyb3VwX2J5GAMgASgJEg0KBWdyb3VwGAQgASgJEhAKCG9yZGVyX2J5GAUgASgJEg8KB3JldmVyc2UYBiABKAgSDwoHb3JpZ2lucxgHIAMoCSLIAQoUUXVlcnlGcmVpZ2h0UmVzcG9uc2USUgoGZ3JvdXBzGAEgAygLMkIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUXVlcnlGcmVpZ2h0UmVzcG9uc2UuR3JvdXBzRW50cnkaXAoLR3JvdXBzRW50cnkSCwoDa2V5GAEgASgJEjwKBXZhbHVlGAIgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRnJlaWdodExpc3Q6AjgBIk0KC0ZyZWlnaHRMaXN0Ej4KB2ZyZWlnaHQYASADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodCJgChlVcGRhdGVGcmVpZ2h0QWxpYXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRIRCglvbGRfYWxpYXMYAyABKAkSEQoJbmV3X2FsaWFzGAQgASgJIhwKGlVwZGF0ZUZyZWlnaHRBbGlhc1Jlc3BvbnNlIjEKD1JldmVyaWZ5UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJIhIKEFJldmVyaWZ5UmVzcG9uc2UiOgoYQWJvcnRWZXJpZmljYXRpb25SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkiGwoZQWJvcnRWZXJpZmljYXRpb25SZXNwb25zZSIoChVMaXN0V2FyZWhvdXNlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJdChZMaXN0V2FyZWhvdXNlc1Jlc3BvbnNlEkMKCndhcmVob3VzZXMYASADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlInEKE0dldFdhcmVob3VzZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJ1ChRHZXRXYXJlaG91c2VSZXNwb25zZRJECgl3YXJlaG91c2UYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IjcKFldhdGNoV2FyZWhvdXNlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJImsKF1dhdGNoV2FyZWhvdXNlc1Jlc3BvbnNlEkIKCXdhcmVob3VzZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2USDAoEdHlwZRgCIAEoCSI3ChZEZWxldGVXYXJlaG91c2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIZChdEZWxldGVXYXJlaG91c2VSZXNwb25zZSI4ChdSZWZyZXNoV2FyZWhvdXNlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiXgoYUmVmcmVzaFdhcmVob3VzZVJlc3BvbnNlEkIKCXdhcmVob3VzZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2UiLAoZTGlzdFByb2plY3RTZWNyZXRzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIkkKGkxpc3RQcm9qZWN0U2VjcmV0c1Jlc3BvbnNlEisKB3NlY3JldHMYASADKAsyGi5rOHMuaW8uYXBpLmNvcmUudjEuU2VjcmV0ItMBChpDcmVhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSVAoEZGF0YRgEIAMoCzJGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0LkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJJChtDcmVhdGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USKgoGc2VjcmV0GAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCLTAQoaVXBkYXRlUHJvamVjdFNlY3JldFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJElQKBGRhdGEYBCADKAsyRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdC5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiSQobVXBkYXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEioKBnNlY3JldBgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQiOwoaRGVsZXRlUHJvamVjdFNlY3JldFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIh0KG0RlbGV0ZVByb2plY3RTZWNyZXRSZXNwb25zZSLGAQoYQ3JlYXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgIIAEoCRIMCgR0eXBlGAMgASgJEhkKCHJlcG9fdXJsGAQgASgJUgdyZXBvVVJMEikKEXJlcG9fdXJsX2lzX3JlZ2V4GAUgASgIUg5yZXBvVVJMSXNSZWdleBIQCgh1c2VybmFtZRgGIAEoCRIQCghwYXNzd29yZBgHIAEoCSJMChlDcmVhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCI5ChhEZWxldGVDcmVkZW50aWFsc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhsKGURlbGV0ZUNyZWRlbnRpYWxzUmVzcG9uc2UicwoVR2V0Q3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiZAoWR2V0Q3JlZGVudGlhbHNSZXNwb25zZRIxCgtjcmVkZW50aWFscxgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXRIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQiKQoWTGlzdENyZWRlbnRpYWxzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIkoKF0xpc3RDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgAygLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCLGAQoYVXBkYXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgIIAEoCRIMCgR0eXBlGAMgASgJEhkKCHJlcG9fdXJsGAQgASgJUgdyZXBvVVJMEikKEXJlcG9fdXJsX2lzX3JlZ2V4GAUgASgIUg5yZXBvVVJMSXNSZWdleBIQCgh1c2VybmFtZRgGIAEoCRIQCghwYXNzd29yZBgHIAEoCSJMChlVcGRhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEi8KC2NyZWRlbnRpYWxzGAEgASgLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCIvChxMaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkikAEKHUxpc3RBbmFseXNpc1RlbXBsYXRlc1Jlc3BvbnNlEm8KEmFuYWx5c2lzX3RlbXBsYXRlcxgBIAMoCzJTLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGUieAoaR2V0QW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKoAQobR2V0QW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEnAKEWFuYWx5c2lzX3RlbXBsYXRlGAEgASgLMlMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuQW5hbHlzaXNUZW1wbGF0ZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCIlCiNMaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVxdWVzdCLBAQokTGlzdENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlc1Jlc3BvbnNlEpgBChpjbHVzdGVyX2FuYWx5c2lzX3RlbXBsYXRlcxgBIAMoCzJaLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUhhjbHVzdGVyYW5hbHlzaXNUZW1wbGF0ZXMibgohR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0EgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0Ir4BCiJHZXRDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEn8KGWNsdXN0ZXJfYW5hbHlzaXNfdGVtcGxhdGUYASABKAsyWi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5DbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCJ1ChVHZXRBbmFseXNpc1J1blJlcXVlc3QSEQoJbmFtZXNwYWNlGAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0IpkBChZHZXRBbmFseXNpc1J1blJlc3BvbnNlEmYKDGFuYWx5c2lzX3J1bhgBIAEoCzJOLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0Ij4KHURlbGV0ZUFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIgCh5EZWxldGVBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2UiNAokRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0EgwKBG5hbWUYAiABKAkiJwolRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZSIrChhMaXN0UHJvamVjdEV2ZW50c1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJGChlMaXN0UHJvamVjdEV2ZW50c1Jlc3BvbnNlEikKBmV2ZW50cxgBIAMoCzIZLms4cy5pby5hcGkuY29yZS52MS5FdmVudCJSChFDcmVhdGVSb2xlUmVxdWVzdBI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJTChJDcmVhdGVSb2xlUmVzcG9uc2USPQoEcm9sZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUiMgoRRGVsZXRlUm9sZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhQKEkRlbGV0ZVJvbGVSZXNwb25zZSKCAQoOR2V0Um9sZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhQKDGFzX3Jlc291cmNlcxgDIAEoCBI7CgZmb3JtYXQYBCABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiugEKD0dldFJvbGVSZXNwb25zZRI/CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZUgAEk0KCXJlc291cmNlcxgCIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGVSZXNvdXJjZXNIABINCgNyYXcYAyABKAxIAEIICgZyZXN1bHQiSgoGQ2xhaW1zEkAKBmNsYWltcxgBIAMoCzIwLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLkNsYWltItEBCgxHcmFudFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRyb2xlGAIgASgJEj8KC3VzZXJfY2xhaW1zGAMgASgLMiguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ2xhaW1zSAASVgoQcmVzb3VyY2VfZGV0YWlscxgEIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJlc291cmNlRGV0YWlsc0gAQgkKB3JlcXVlc3QiTgoNR3JhbnRSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSI5ChBMaXN0Um9sZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSFAoMYXNfcmVzb3VyY2VzGAIgASgIIqABChFMaXN0Um9sZXNSZXNwb25zZRI+CgVyb2xlcxgBIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUSSwoJcmVzb3VyY2VzGAIgAygLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZVJlc291cmNlcyLSAQoNUmV2b2tlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBHJvbGUYAiABKAkSPwoLdXNlcl9jbGFpbXMYAyABKAsyKC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DbGFpbXNIABJWChByZXNvdXJjZV9kZXRhaWxzGAQgASgLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUmVzb3VyY2VEZXRhaWxzSABCCQoHcmVxdWVzdCJPCg5SZXZva2VSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJSChFVcGRhdGVSb2xlUmVxdWVzdBI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJTChJVcGRhdGVSb2xlUmVzcG9uc2USPQoEcm9sZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUqUQoJUmF3Rm9ybWF0EhoKFlJBV19GT1JNQVRfVU5TUEVDSUZJRUQQABITCg9SQVdfRk9STUFUX0pTT04QARITCg9SQVdfRk9STUFUX1lBTUwQAjKnPwoMS2FyZ29TZXJ2aWNlEoMBCg5HZXRWZXJzaW9uSW5mbxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFZlcnNpb25JbmZvUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFZlcnNpb25JbmZvUmVzcG9uc2USdAoJR2V0Q29uZmlnEjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVxdWVzdBozLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENvbmZpZ1Jlc3BvbnNlEoYBCg9HZXRQdWJsaWNDb25maWcSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQdWJsaWNDb25maWdSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHVibGljQ29uZmlnUmVzcG9uc2USdwoKQWRtaW5Mb2dpbhIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFkbWluTG9naW5SZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWRtaW5Mb2dpblJlc3BvbnNlEoMBCg5DcmVhdGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVzcG9uc2USmwEKFkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2USPy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVxdWVzdBpALmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXNwb25zZRKDAQoOVXBkYXRlUmVzb3VyY2USNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSZXNvdXJjZVJlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSZXNvdXJjZVJlc3BvbnNlEoMBCg5EZWxldGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJlc291cmNlUmVzcG9uc2USdwoKTGlzdFN0YWdlcxIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RTdGFnZXNSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFN0YWdlc1Jlc3BvbnNlEncKCkxpc3RJbWFnZXMSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0SW1hZ2VzUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RJbWFnZXNSZXNwb25zZRJxCghHZXRTdGFnZRIxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFN0YWdlUmVxdWVzdBoyLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFN0YWdlUmVzcG9uc2USfAoLV2F0Y2hTdGFnZXMSNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFN0YWdlc1JlcXVlc3QaNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFN0YWdlc1Jlc3BvbnNlMAESegoLRGVsZXRlU3RhZ2USNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVTdGFnZVJlcXVlc3QaNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVTdGFnZVJlc3BvbnNlEn0KDFJlZnJlc2hTdGFnZRI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJlZnJlc2hTdGFnZVJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZWZyZXNoU3RhZ2VSZXNwb25zZRKDAQoOTGlzdFByb21vdGlvbnMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1Jlc3BvbnNlEogBCg9XYXRjaFByb21vdGlvbnMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFByb21vdGlvbnNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25zUmVzcG9uc2UwARJ9CgxHZXRQcm9tb3Rpb24SNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9tb3Rpb25SZXF1ZXN0GjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvbW90aW9uUmVzcG9uc2UShQEKDldhdGNoUHJvbW90aW9uEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXNwb25zZTABEoMBCg5BYm9ydFByb21vdGlvbhI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVzcG9uc2USgAEKDURlbGV0ZVByb2plY3QSNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0UmVxdWVzdBo3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RSZXNwb25zZRJ3CgpHZXRQcm9qZWN0EjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvamVjdFJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9qZWN0UmVzcG9uc2USfQoMTGlzdFByb2plY3RzEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RzUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0c1Jlc3BvbnNlEoMBCg5BcHByb3ZlRnJlaWdodBI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFwcHJvdmVGcmVpZ2h0UmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFwcHJvdmVGcmVpZ2h0UmVzcG9uc2USgAEKDURlbGV0ZUZyZWlnaHQSNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVGcmVpZ2h0UmVxdWVzdBo3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUZyZWlnaHRSZXNwb25zZRJ3CgpHZXRGcmVpZ2h0EjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0RnJlaWdodFJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRGcmVpZ2h0UmVzcG9uc2USgwEKDlByb21vdGVUb1N0YWdlEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZVRvU3RhZ2VSZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZVRvU3RhZ2VSZXNwb25zZRKMAQoRUHJvbW90ZURvd25zdHJlYW0SOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5Qcm9tb3RlRG93bnN0cmVhbVJlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5Qcm9tb3RlRG93bnN0cmVhbVJlc3BvbnNlEn0KDFF1ZXJ5RnJlaWdodBI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlF1ZXJ5RnJlaWdodFJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5RdWVyeUZyZWlnaHRSZXNwb25zZRKPAQoSVXBkYXRlRnJlaWdodEFsaWFzEjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlRnJlaWdodEFsaWFzUmVxdWVzdBo8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZUZyZWlnaHRBbGlhc1Jlc3BvbnNlEnEKCFJldmVyaWZ5EjEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmV2ZXJpZnlSZXF1ZXN0GjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmV2ZXJpZnlSZXNwb25zZRKMAQoRQWJvcnRWZXJpZmljYXRpb24SOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BYm9ydFZlcmlmaWNhdGlvblJlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BYm9ydFZlcmlmaWNhdGlvblJlc3BvbnNlEoMBCg5MaXN0V2FyZWhvdXNlcxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RXYXJlaG91c2VzUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RXYXJlaG91c2VzUmVzcG9uc2USfQoMR2V0V2FyZWhvdXNlEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0V2FyZWhvdXNlUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFdhcmVob3VzZVJlc3BvbnNlEogBCg9XYXRjaFdhcmVob3VzZXMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFdhcmVob3VzZXNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hXYXJlaG91c2VzUmVzcG9uc2UwARKGAQoPRGVsZXRlV2FyZWhvdXNlEjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlV2FyZWhvdXNlUmVxdWVzdBo5LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVdhcmVob3VzZVJlc3BvbnNlEokBChBSZWZyZXNoV2FyZWhvdXNlEjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFdhcmVob3VzZVJlcXVlc3QaOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZWZyZXNoV2FyZWhvdXNlUmVzcG9uc2USjAEKEUNyZWF0ZUNyZWRlbnRpYWxzEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlQ3JlZGVudGlhbHNSZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlQ3JlZGVudGlhbHNSZXNwb25zZRKMAQoRRGVsZXRlQ3JlZGVudGlhbHMSOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDcmVkZW50aWFsc1JlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDcmVkZW50aWFsc1Jlc3BvbnNlEoMBCg5HZXRDcmVkZW50aWFscxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENyZWRlbnRpYWxzUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENyZWRlbnRpYWxzUmVzcG9uc2UShgEKD0xpc3RDcmVkZW50aWFscxI4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RDcmVkZW50aWFsc1JlcXVlc3QaOS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q3JlZGVudGlhbHNSZXNwb25zZRKMAQoRVXBkYXRlQ3JlZGVudGlhbHMSOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVDcmVkZW50aWFsc1JlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEo8BChJMaXN0UHJvamVjdFNlY3JldHMSOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvamVjdFNlY3JldHNSZXF1ZXN0GjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RTZWNyZXRzUmVzcG9uc2USkgEKE0NyZWF0ZVByb2plY3RTZWNyZXQSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVByb2plY3RTZWNyZXRSZXNwb25zZRKSAQoTVXBkYXRlUHJvamVjdFNlY3JldBI8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Gj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEpIBChNEZWxldGVQcm9qZWN0U2VjcmV0EjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUHJvamVjdFNlY3JldFJlcXVlc3QaPS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USmAEKFUxpc3RBbmFseXNpc1RlbXBsYXRlcxI+LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RBbmFseXNpc1RlbXBsYXRlc1JlcXVlc3QaPy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXNwb25zZRKSAQoTR2V0QW5hbHlzaXNUZW1wbGF0ZRI8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0Gj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0QW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEpsBChZEZWxldGVBbmFseXNpc1RlbXBsYXRlEj8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QaQC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2USrQEKHExpc3RDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZXMSRS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVxdWVzdBpGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZXNSZXNwb25zZRKnAQoaR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGUSQy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QaRC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlErABCh1EZWxldGVDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZRJGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBpHLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2USgwEKDkdldEFuYWx5c2lzUnVuEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0QW5hbHlzaXNSdW5SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0QW5hbHlzaXNSdW5SZXNwb25zZRKMAQoRTGlzdFByb2plY3RFdmVudHMSOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvamVjdEV2ZW50c1JlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvamVjdEV2ZW50c1Jlc3BvbnNlEncKCkNyZWF0ZVJvbGUSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSb2xlUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJvbGVSZXNwb25zZRJ3CgpEZWxldGVSb2xlEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUm9sZVJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVSb2xlUmVzcG9uc2USbgoHR2V0Um9sZRIwLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFJvbGVSZXF1ZXN0GjEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Um9sZVJlc3BvbnNlEmgKBUdyYW50Ei4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR3JhbnRSZXF1ZXN0Gi8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR3JhbnRSZXNwb25zZRJ0CglMaXN0Um9sZXMSMi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Um9sZXNSZXF1ZXN0GjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFJvbGVzUmVzcG9uc2USawoGUmV2b2tlEi8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmV2b2tlUmVxdWVzdBowLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldm9rZVJlc3BvbnNlEncKClVwZGF0ZVJvbGUSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSb2xlUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJvbGVSZXNwb25zZUKXAgokY29tLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExQgxTZXJ2aWNlUHJvdG9QAVo8Z2l0aHViLmNvbS9ha3VpdHkva2FyZ28vcGtnL2FwaS9zZXJ2aWNlL3YxYWxwaGExO3N2Y3YxYWxwaGExogIEQUlLU6oCIEFrdWl0eS5Jby5LYXJnby5TZXJ2aWNlLlYxYWxwaGExygIgQWt1aXR5XElvXEthcmdvXFNlcnZpY2VcVjFhbHBoYTHiAixBa3VpdHlcSW9cS2FyZ29cU2VydmljZVxWMWFscGhhMVxHUEJNZXRhZGF0YeoCJEFrdWl0eTo6SW86OkthcmdvOjpTZXJ2aWNlOjpWMWFscGhhMWIGcHJvdG8z", [file_google_protobuf_timestamp, file_v1alpha1_generated, file_k8s_io_api_core_v1_generated, file_rollouts_api_v1alpha1_generated, file_rbac_v1alpha1_generated]);
+export const file_api_service_v1alpha1_service: GenFile = /*@__PURE__*/
+  fileDesc("CiJhcGkvc2VydmljZS92MWFscGhhMS9zZXJ2aWNlLnByb3RvEiBha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMSKrAQoRQ29tcG9uZW50VmVyc2lvbnMSQgoGc2VydmVyGAEgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVmVyc2lvbkluZm9IAIgBARI/CgNjbGkYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5WZXJzaW9uSW5mb0gBiAEBQgkKB19zZXJ2ZXJCBgoEX2NsaSKyAQoLVmVyc2lvbkluZm8SDwoHdmVyc2lvbhgBIAEoCRISCgpnaXRfY29tbWl0GAIgASgJEhYKDmdpdF90cmVlX2RpcnR5GAMgASgIEi4KCmJ1aWxkX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhIKCmdvX3ZlcnNpb24YBSABKAkSEAoIY29tcGlsZXIYBiABKAkSEAoIcGxhdGZvcm0YByABKAkiFwoVR2V0VmVyc2lvbkluZm9SZXF1ZXN0Il0KFkdldFZlcnNpb25JbmZvUmVzcG9uc2USQwoMdmVyc2lvbl9pbmZvGAEgASgLMi0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVmVyc2lvbkluZm8iEgoQR2V0Q29uZmlnUmVxdWVzdCItCgtBcmdvQ0RTaGFyZBILCgN1cmwYASABKAkSEQoJbmFtZXNwYWNlGAIgASgJIvgBChFHZXRDb25maWdSZXNwb25zZRJcCg1hcmdvY2Rfc2hhcmRzGAEgAygLMkUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVzcG9uc2UuQXJnb2NkU2hhcmRzRW50cnkSIQoZc2VjcmV0X21hbmFnZW1lbnRfZW5hYmxlZBgCIAEoCBpiChFBcmdvY2RTaGFyZHNFbnRyeRILCgNrZXkYASABKAkSPAoFdmFsdWUYAiABKAsyLS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BcmdvQ0RTaGFyZDoCOAEiGAoWR2V0UHVibGljQ29uZmlnUmVxdWVzdCKOAQoXR2V0UHVibGljQ29uZmlnUmVzcG9uc2USQQoLb2lkY19jb25maWcYASABKAsyLC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5PSURDQ29uZmlnEh0KFWFkbWluX2FjY291bnRfZW5hYmxlZBgCIAEoCBIRCglza2lwX2F1dGgYAyABKAgiWgoKT0lEQ0NvbmZpZxISCgppc3N1ZXJfdXJsGAEgASgJEhEKCWNsaWVudF9pZBgCIAEoCRIOCgZzY29wZXMYAyADKAkSFQoNY2xpX2NsaWVudF9pZBgEIAEoCSIlChFBZG1pbkxvZ2luUmVxdWVzdBIQCghwYXNzd29yZBgBIAEoCSImChJBZG1pbkxvZ2luUmVzcG9uc2USEAoIaWRfdG9rZW4YASABKAkiKQoVQ3JlYXRlUmVzb3VyY2VSZXF1ZXN0EhAKCG1hbmlmZXN0GAEgASgMIlYKFENyZWF0ZVJlc291cmNlUmVzdWx0EiMKGWNyZWF0ZWRfcmVzb3VyY2VfbWFuaWZlc3QYASABKAxIABIPCgVlcnJvchgCIAEoCUgAQggKBnJlc3VsdCJhChZDcmVhdGVSZXNvdXJjZVJlc3BvbnNlEkcKB3Jlc3VsdHMYASADKAsyNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSZXNvdXJjZVJlc3VsdCIxCh1DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCKDAQocQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3VsdBIjChljcmVhdGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASIwoZdXBkYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgCIAEoDEgAEg8KBWVycm9yGAMgASgJSABCCAoGcmVzdWx0InEKHkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXNwb25zZRJPCgdyZXN1bHRzGAEgAygLMj4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlT3JVcGRhdGVSZXNvdXJjZVJlc3VsdCIpChVVcGRhdGVSZXNvdXJjZVJlcXVlc3QSEAoIbWFuaWZlc3QYASABKAwiVgoUVXBkYXRlUmVzb3VyY2VSZXN1bHQSIwoZdXBkYXRlZF9yZXNvdXJjZV9tYW5pZmVzdBgBIAEoDEgAEg8KBWVycm9yGAIgASgJSABCCAoGcmVzdWx0ImEKFlVwZGF0ZVJlc291cmNlUmVzcG9uc2USRwoHcmVzdWx0cxgBIAMoCzI2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJlc291cmNlUmVzdWx0IikKFURlbGV0ZVJlc291cmNlUmVxdWVzdBIQCghtYW5pZmVzdBgBIAEoDCJWChREZWxldGVSZXNvdXJjZVJlc3VsdBIjChlkZWxldGVkX3Jlc291cmNlX21hbmlmZXN0GAEgASgMSAASDwoFZXJyb3IYAiABKAlIAEIICgZyZXN1bHQiYQoWRGVsZXRlUmVzb3VyY2VSZXNwb25zZRJHCgdyZXN1bHRzGAEgAygLMjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUmVzb3VyY2VSZXN1bHQiJAoRTGlzdFN0YWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJRChJMaXN0U3RhZ2VzUmVzcG9uc2USOwoGc3RhZ2VzGAEgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlIiQKEUxpc3RJbWFnZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkivwEKEkxpc3RJbWFnZXNSZXNwb25zZRJQCgZpbWFnZXMYAiADKAsyQC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0SW1hZ2VzUmVzcG9uc2UuSW1hZ2VzRW50cnkaVwoLSW1hZ2VzRW50cnkSCwoDa2V5GAEgASgJEjcKBXZhbHVlGAIgASgLMiguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVGFnTWFwOgI4ASKoAQoGVGFnTWFwEkAKBHRhZ3MYASADKAsyMi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5UYWdNYXAuVGFnc0VudHJ5GlwKCVRhZ3NFbnRyeRILCgNrZXkYASABKAkSPgoFdmFsdWUYAiABKAsyLy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5JbWFnZVN0YWdlTWFwOgI4ASKLAQoNSW1hZ2VTdGFnZU1hcBJLCgZzdGFnZXMYASADKAsyOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5JbWFnZVN0YWdlTWFwLlN0YWdlc0VudHJ5Gi0KC1N0YWdlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAEibQoPR2V0U3RhZ2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiaQoQR2V0U3RhZ2VSZXNwb25zZRI8CgVzdGFnZRgBIAEoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCIzChJXYXRjaFN0YWdlc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIl8KE1dhdGNoU3RhZ2VzUmVzcG9uc2USOgoFc3RhZ2UYASABKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2USDAoEdHlwZRgCIAEoCSIzChJEZWxldGVTdGFnZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhUKE0RlbGV0ZVN0YWdlUmVzcG9uc2UiNAoTUmVmcmVzaFN0YWdlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiUgoUUmVmcmVzaFN0YWdlUmVzcG9uc2USOgoFc3RhZ2UYASABKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2UiRgoVTGlzdFByb21vdGlvbnNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSEgoFc3RhZ2UYAiABKAlIAIgBAUIICgZfc3RhZ2UiXQoWTGlzdFByb21vdGlvbnNSZXNwb25zZRJDCgpwcm9tb3Rpb25zGAEgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiJHChZXYXRjaFByb21vdGlvbnNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSEgoFc3RhZ2UYAiABKAlIAIgBAUIICgZfc3RhZ2UiawoXV2F0Y2hQcm9tb3Rpb25zUmVzcG9uc2USQgoJcHJvbW90aW9uGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbhIMCgR0eXBlGAIgASgJInEKE0dldFByb21vdGlvblJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJ1ChRHZXRQcm9tb3Rpb25SZXNwb25zZRJECglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IjYKFVdhdGNoUHJvbW90aW9uUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiagoWV2F0Y2hQcm9tb3Rpb25SZXNwb25zZRJCCglwcm9tb3Rpb24YASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uEgwKBHR5cGUYAiABKAkiNgoVQWJvcnRQcm9tb3Rpb25SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIYChZBYm9ydFByb21vdGlvblJlc3BvbnNlIiQKFERlbGV0ZVByb2plY3RSZXF1ZXN0EgwKBG5hbWUYASABKAkiFwoVRGVsZXRlUHJvamVjdFJlc3BvbnNlIl4KEUdldFByb2plY3RSZXF1ZXN0EgwKBG5hbWUYASABKAkSOwoGZm9ybWF0GAIgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0Im8KEkdldFByb2plY3RSZXNwb25zZRJACgdwcm9qZWN0GAEgASgLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RIABINCgNyYXcYAiABKAxIAEIICgZyZXN1bHQidwoTTGlzdFByb2plY3RzUmVxdWVzdBIWCglwYWdlX3NpemUYASABKAVIAIgBARIRCgRwYWdlGAIgASgFSAGIAQESEwoGZmlsdGVyGAMgASgJSAKIAQFCDAoKX3BhZ2Vfc2l6ZUIHCgVfcGFnZUIJCgdfZmlsdGVyImYKFExpc3RQcm9qZWN0c1Jlc3BvbnNlEj8KCHByb2plY3RzGAEgAygLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3QSDQoFdG90YWwYAiABKAUiVAoVQXBwcm92ZUZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRINCgVhbGlhcxgDIAEoCRINCgVzdGFnZRgEIAEoCSIYChZBcHByb3ZlRnJlaWdodFJlc3BvbnNlIkQKFERlbGV0ZUZyZWlnaHRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRINCgVhbGlhcxgDIAEoCSIXChVEZWxldGVGcmVpZ2h0UmVzcG9uc2UifgoRR2V0RnJlaWdodFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEg0KBWFsaWFzGAMgASgJEjsKBmZvcm1hdBgEIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCJvChJHZXRGcmVpZ2h0UmVzcG9uc2USQAoHZnJlaWdodBgBIAEoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0SAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0Il8KFVByb21vdGVUb1N0YWdlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJEg8KB2ZyZWlnaHQYAyABKAkSFQoNZnJlaWdodF9hbGlhcxgEIAEoCSJcChZQcm9tb3RlVG9TdGFnZVJlc3BvbnNlEkIKCXByb21vdGlvbhgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb24iYgoYUHJvbW90ZURvd25zdHJlYW1SZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDQoFc3RhZ2UYAiABKAkSDwoHZnJlaWdodBgDIAEoCRIVCg1mcmVpZ2h0X2FsaWFzGAQgASgJImAKGVByb21vdGVEb3duc3RyZWFtUmVzcG9uc2USQwoKcHJvbW90aW9ucxgBIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb24iigEKE1F1ZXJ5RnJlaWdodFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRINCgVzdGFnZRgCIAEoCRIQCghncm91cF9ieRgDIAEoCRINCgVncm91cBgEIAEoCRIQCghvcmRlcl9ieRgFIAEoCRIPCgdyZXZlcnNlGAYgASgIEg8KB29yaWdpbnMYByADKAkiyAEKFFF1ZXJ5RnJlaWdodFJlc3BvbnNlElIKBmdyb3VwcxgBIAMoCzJCLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlF1ZXJ5RnJlaWdodFJlc3BvbnNlLkdyb3Vwc0VudHJ5GlwKC0dyb3Vwc0VudHJ5EgsKA2tleRgBIAEoCRI8CgV2YWx1ZRgCIAEoCzItLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkZyZWlnaHRMaXN0OgI4ASJNCgtGcmVpZ2h0TGlzdBI+CgdmcmVpZ2h0GAEgAygLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHQiYAoZVXBkYXRlRnJlaWdodEFsaWFzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSEQoJb2xkX2FsaWFzGAMgASgJEhEKCW5ld19hbGlhcxgEIAEoCSIcChpVcGRhdGVGcmVpZ2h0QWxpYXNSZXNwb25zZSIxCg9SZXZlcmlmeVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRINCgVzdGFnZRgCIAEoCSISChBSZXZlcmlmeVJlc3BvbnNlIjoKGEFib3J0VmVyaWZpY2F0aW9uUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEg0KBXN0YWdlGAIgASgJIhsKGUFib3J0VmVyaWZpY2F0aW9uUmVzcG9uc2UiKAoVTGlzdFdhcmVob3VzZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkiXQoWTGlzdFdhcmVob3VzZXNSZXNwb25zZRJDCgp3YXJlaG91c2VzGAEgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZSJxChNHZXRXYXJlaG91c2VSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQidQoUR2V0V2FyZWhvdXNlUmVzcG9uc2USRAoJd2FyZWhvdXNlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCI3ChZXYXRjaFdhcmVob3VzZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSJrChdXYXRjaFdhcmVob3VzZXNSZXNwb25zZRJCCgl3YXJlaG91c2UYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlEgwKBHR5cGUYAiABKAkiNwoWRGVsZXRlV2FyZWhvdXNlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkiGQoXRGVsZXRlV2FyZWhvdXNlUmVzcG9uc2UiOAoXUmVmcmVzaFdhcmVob3VzZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIl4KGFJlZnJlc2hXYXJlaG91c2VSZXNwb25zZRJCCgl3YXJlaG91c2UYASABKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlIiwKGUxpc3RQcm9qZWN0U2VjcmV0c1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJJChpMaXN0UHJvamVjdFNlY3JldHNSZXNwb25zZRIrCgdzZWNyZXRzGAEgAygLMhouazhzLmlvLmFwaS5jb3JlLnYxLlNlY3JldCLTAQoaQ3JlYXRlUHJvamVjdFNlY3JldFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJElQKBGRhdGEYBCADKAsyRi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdC5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiSQobQ3JlYXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEioKBnNlY3JldBgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQi0wEKGlVwZGF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRJUCgRkYXRhGAQgAygLMkYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlUHJvamVjdFNlY3JldFJlcXVlc3QuRGF0YUVudHJ5GisKCURhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIkkKG1VwZGF0ZVByb2plY3RTZWNyZXRSZXNwb25zZRIqCgZzZWNyZXQYASABKAsyGi5rOHMuaW8uYXBpLmNvcmUudjEuU2VjcmV0IjsKGkRlbGV0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIdChtEZWxldGVQcm9qZWN0U2VjcmV0UmVzcG9uc2UixgEKGENyZWF0ZUNyZWRlbnRpYWxzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YCCABKAkSDAoEdHlwZRgDIAEoCRIZCghyZXBvX3VybBgEIAEoCVIHcmVwb1VSTBIpChFyZXBvX3VybF9pc19yZWdleBgFIAEoCFIOcmVwb1VSTElzUmVnZXgSEAoIdXNlcm5hbWUYBiABKAkSEAoIcGFzc3dvcmQYByABKAkiTAoZQ3JlYXRlQ3JlZGVudGlhbHNSZXNwb25zZRIvCgtjcmVkZW50aWFscxgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQiOQoYRGVsZXRlQ3JlZGVudGlhbHNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIbChlEZWxldGVDcmVkZW50aWFsc1Jlc3BvbnNlInMKFUdldENyZWRlbnRpYWxzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0ImQKFkdldENyZWRlbnRpYWxzUmVzcG9uc2USMQoLY3JlZGVudGlhbHMYASABKAsyGi5rOHMuaW8uYXBpLmNvcmUudjEuU2VjcmV0SAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0IikKFkxpc3RDcmVkZW50aWFsc1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJKChdMaXN0Q3JlZGVudGlhbHNSZXNwb25zZRIvCgtjcmVkZW50aWFscxgBIAMoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQixgEKGFVwZGF0ZUNyZWRlbnRpYWxzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSEwoLZGVzY3JpcHRpb24YCCABKAkSDAoEdHlwZRgDIAEoCRIZCghyZXBvX3VybBgEIAEoCVIHcmVwb1VSTBIpChFyZXBvX3VybF9pc19yZWdleBgFIAEoCFIOcmVwb1VSTElzUmVnZXgSEAoIdXNlcm5hbWUYBiABKAkSEAoIcGFzc3dvcmQYByABKAkiTAoZVXBkYXRlQ3JlZGVudGlhbHNSZXNwb25zZRIvCgtjcmVkZW50aWFscxgBIAEoCzIaLms4cy5pby5hcGkuY29yZS52MS5TZWNyZXQiLwocTGlzdEFuYWx5c2lzVGVtcGxhdGVzUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJIoIBCh1MaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXNwb25zZRJhChJhbmFseXNpc190ZW1wbGF0ZXMYASADKAsyRS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQW5hbHlzaXNUZW1wbGF0ZSJ4ChpHZXRBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBG5hbWUYAiABKAkSOwoGZm9ybWF0GAMgASgOMisuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmF3Rm9ybWF0IpoBChtHZXRBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2USYgoRYW5hbHlzaXNfdGVtcGxhdGUYASABKAsyRS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQW5hbHlzaXNUZW1wbGF0ZUgAEg0KA3JhdxgCIAEoDEgAQggKBnJlc3VsdCIlCiNMaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVxdWVzdCKzAQokTGlzdENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlc1Jlc3BvbnNlEooBChpjbHVzdGVyX2FuYWx5c2lzX3RlbXBsYXRlcxgBIAMoCzJMLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5DbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVIYY2x1c3RlcmFuYWx5c2lzVGVtcGxhdGVzIm4KIUdldENsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBIMCgRuYW1lGAIgASgJEjsKBmZvcm1hdBgDIAEoDjIrLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJhd0Zvcm1hdCKwAQoiR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZRJxChljbHVzdGVyX2FuYWx5c2lzX3RlbXBsYXRlGAEgASgLMkwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0InUKFUdldEFuYWx5c2lzUnVuUmVxdWVzdBIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRI7CgZmb3JtYXQYAyABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiiwEKFkdldEFuYWx5c2lzUnVuUmVzcG9uc2USWAoMYW5hbHlzaXNfcnVuGAEgASgLMkAuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFuYWx5c2lzUnVuSAASDQoDcmF3GAIgASgMSABCCAoGcmVzdWx0Ij4KHURlbGV0ZUFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSIgCh5EZWxldGVBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2UiNAokRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0EgwKBG5hbWUYAiABKAkiJwolRGVsZXRlQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGVSZXNwb25zZSIrChhMaXN0UHJvamVjdEV2ZW50c1JlcXVlc3QSDwoHcHJvamVjdBgBIAEoCSJGChlMaXN0UHJvamVjdEV2ZW50c1Jlc3BvbnNlEikKBmV2ZW50cxgBIAMoCzIZLms4cy5pby5hcGkuY29yZS52MS5FdmVudCJSChFDcmVhdGVSb2xlUmVxdWVzdBI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJTChJDcmVhdGVSb2xlUmVzcG9uc2USPQoEcm9sZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUiMgoRRGVsZXRlUm9sZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJIhQKEkRlbGV0ZVJvbGVSZXNwb25zZSKCAQoOR2V0Um9sZVJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRuYW1lGAIgASgJEhQKDGFzX3Jlc291cmNlcxgDIAEoCBI7CgZmb3JtYXQYBCABKA4yKy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SYXdGb3JtYXQiugEKD0dldFJvbGVSZXNwb25zZRI/CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZUgAEk0KCXJlc291cmNlcxgCIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGVSZXNvdXJjZXNIABINCgNyYXcYAyABKAxIAEIICgZyZXN1bHQiSgoGQ2xhaW1zEkAKBmNsYWltcxgBIAMoCzIwLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLkNsYWltItEBCgxHcmFudFJlcXVlc3QSDwoHcHJvamVjdBgBIAEoCRIMCgRyb2xlGAIgASgJEj8KC3VzZXJfY2xhaW1zGAMgASgLMiguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ2xhaW1zSAASVgoQcmVzb3VyY2VfZGV0YWlscxgEIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJlc291cmNlRGV0YWlsc0gAQgkKB3JlcXVlc3QiTgoNR3JhbnRSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSI5ChBMaXN0Um9sZXNSZXF1ZXN0Eg8KB3Byb2plY3QYASABKAkSFAoMYXNfcmVzb3VyY2VzGAIgASgIIqABChFMaXN0Um9sZXNSZXNwb25zZRI+CgVyb2xlcxgBIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUSSwoJcmVzb3VyY2VzGAIgAygLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZVJlc291cmNlcyLSAQoNUmV2b2tlUmVxdWVzdBIPCgdwcm9qZWN0GAEgASgJEgwKBHJvbGUYAiABKAkSPwoLdXNlcl9jbGFpbXMYAyABKAsyKC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DbGFpbXNIABJWChByZXNvdXJjZV9kZXRhaWxzGAQgASgLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUmVzb3VyY2VEZXRhaWxzSABCCQoHcmVxdWVzdCJPCg5SZXZva2VSZXNwb25zZRI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJSChFVcGRhdGVSb2xlUmVxdWVzdBI9CgRyb2xlGAEgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnJiYWMudjFhbHBoYTEuUm9sZSJTChJVcGRhdGVSb2xlUmVzcG9uc2USPQoEcm9sZRgBIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5yYmFjLnYxYWxwaGExLlJvbGUqUQoJUmF3Rm9ybWF0EhoKFlJBV19GT1JNQVRfVU5TUEVDSUZJRUQQABITCg9SQVdfRk9STUFUX0pTT04QARITCg9SQVdfRk9STUFUX1lBTUwQAjKnPwoMS2FyZ29TZXJ2aWNlEoMBCg5HZXRWZXJzaW9uSW5mbxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFZlcnNpb25JbmZvUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFZlcnNpb25JbmZvUmVzcG9uc2USdAoJR2V0Q29uZmlnEjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Q29uZmlnUmVxdWVzdBozLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENvbmZpZ1Jlc3BvbnNlEoYBCg9HZXRQdWJsaWNDb25maWcSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQdWJsaWNDb25maWdSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHVibGljQ29uZmlnUmVzcG9uc2USdwoKQWRtaW5Mb2dpbhIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFkbWluTG9naW5SZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQWRtaW5Mb2dpblJlc3BvbnNlEoMBCg5DcmVhdGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJlc291cmNlUmVzcG9uc2USmwEKFkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2USPy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVPclVwZGF0ZVJlc291cmNlUmVxdWVzdBpALmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZU9yVXBkYXRlUmVzb3VyY2VSZXNwb25zZRKDAQoOVXBkYXRlUmVzb3VyY2USNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSZXNvdXJjZVJlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSZXNvdXJjZVJlc3BvbnNlEoMBCg5EZWxldGVSZXNvdXJjZRI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJlc291cmNlUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVJlc291cmNlUmVzcG9uc2USdwoKTGlzdFN0YWdlcxIzLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RTdGFnZXNSZXF1ZXN0GjQuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFN0YWdlc1Jlc3BvbnNlEncKCkxpc3RJbWFnZXMSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0SW1hZ2VzUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RJbWFnZXNSZXNwb25zZRJxCghHZXRTdGFnZRIxLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFN0YWdlUmVxdWVzdBoyLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFN0YWdlUmVzcG9uc2USfAoLV2F0Y2hTdGFnZXMSNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFN0YWdlc1JlcXVlc3QaNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFN0YWdlc1Jlc3BvbnNlMAESegoLRGVsZXRlU3RhZ2USNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVTdGFnZVJlcXVlc3QaNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVTdGFnZVJlc3BvbnNlEn0KDFJlZnJlc2hTdGFnZRI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJlZnJlc2hTdGFnZVJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZWZyZXNoU3RhZ2VSZXNwb25zZRKDAQoOTGlzdFByb21vdGlvbnMSNy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1JlcXVlc3QaOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvbW90aW9uc1Jlc3BvbnNlEogBCg9XYXRjaFByb21vdGlvbnMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFByb21vdGlvbnNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25zUmVzcG9uc2UwARJ9CgxHZXRQcm9tb3Rpb24SNS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9tb3Rpb25SZXF1ZXN0GjYuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvbW90aW9uUmVzcG9uc2UShQEKDldhdGNoUHJvbW90aW9uEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hQcm9tb3Rpb25SZXNwb25zZTABEoMBCg5BYm9ydFByb21vdGlvbhI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFib3J0UHJvbW90aW9uUmVzcG9uc2USgAEKDURlbGV0ZVByb2plY3QSNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0UmVxdWVzdBo3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVByb2plY3RSZXNwb25zZRJ3CgpHZXRQcm9qZWN0EjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0UHJvamVjdFJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRQcm9qZWN0UmVzcG9uc2USfQoMTGlzdFByb2plY3RzEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RzUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RQcm9qZWN0c1Jlc3BvbnNlEoMBCg5BcHByb3ZlRnJlaWdodBI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFwcHJvdmVGcmVpZ2h0UmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkFwcHJvdmVGcmVpZ2h0UmVzcG9uc2USgAEKDURlbGV0ZUZyZWlnaHQSNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVGcmVpZ2h0UmVxdWVzdBo3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUZyZWlnaHRSZXNwb25zZRJ3CgpHZXRGcmVpZ2h0EjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0RnJlaWdodFJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRGcmVpZ2h0UmVzcG9uc2USgwEKDlByb21vdGVUb1N0YWdlEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZVRvU3RhZ2VSZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUHJvbW90ZVRvU3RhZ2VSZXNwb25zZRKMAQoRUHJvbW90ZURvd25zdHJlYW0SOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5Qcm9tb3RlRG93bnN0cmVhbVJlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5Qcm9tb3RlRG93bnN0cmVhbVJlc3BvbnNlEn0KDFF1ZXJ5RnJlaWdodBI1LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlF1ZXJ5RnJlaWdodFJlcXVlc3QaNi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5RdWVyeUZyZWlnaHRSZXNwb25zZRKPAQoSVXBkYXRlRnJlaWdodEFsaWFzEjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlRnJlaWdodEFsaWFzUmVxdWVzdBo8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZUZyZWlnaHRBbGlhc1Jlc3BvbnNlEnEKCFJldmVyaWZ5EjEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmV2ZXJpZnlSZXF1ZXN0GjIuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmV2ZXJpZnlSZXNwb25zZRKMAQoRQWJvcnRWZXJpZmljYXRpb24SOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BYm9ydFZlcmlmaWNhdGlvblJlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5BYm9ydFZlcmlmaWNhdGlvblJlc3BvbnNlEoMBCg5MaXN0V2FyZWhvdXNlcxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RXYXJlaG91c2VzUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RXYXJlaG91c2VzUmVzcG9uc2USfQoMR2V0V2FyZWhvdXNlEjUuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0V2FyZWhvdXNlUmVxdWVzdBo2LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFdhcmVob3VzZVJlc3BvbnNlEogBCg9XYXRjaFdhcmVob3VzZXMSOC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5XYXRjaFdhcmVob3VzZXNSZXF1ZXN0GjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuV2F0Y2hXYXJlaG91c2VzUmVzcG9uc2UwARKGAQoPRGVsZXRlV2FyZWhvdXNlEjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlV2FyZWhvdXNlUmVxdWVzdBo5LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZVdhcmVob3VzZVJlc3BvbnNlEokBChBSZWZyZXNoV2FyZWhvdXNlEjkuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmVmcmVzaFdhcmVob3VzZVJlcXVlc3QaOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5SZWZyZXNoV2FyZWhvdXNlUmVzcG9uc2USjAEKEUNyZWF0ZUNyZWRlbnRpYWxzEjouYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlQ3JlZGVudGlhbHNSZXF1ZXN0GjsuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuQ3JlYXRlQ3JlZGVudGlhbHNSZXNwb25zZRKMAQoRRGVsZXRlQ3JlZGVudGlhbHMSOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDcmVkZW50aWFsc1JlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVDcmVkZW50aWFsc1Jlc3BvbnNlEoMBCg5HZXRDcmVkZW50aWFscxI3LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENyZWRlbnRpYWxzUmVxdWVzdBo4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldENyZWRlbnRpYWxzUmVzcG9uc2UShgEKD0xpc3RDcmVkZW50aWFscxI4LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RDcmVkZW50aWFsc1JlcXVlc3QaOS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q3JlZGVudGlhbHNSZXNwb25zZRKMAQoRVXBkYXRlQ3JlZGVudGlhbHMSOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVDcmVkZW50aWFsc1JlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVDcmVkZW50aWFsc1Jlc3BvbnNlEo8BChJMaXN0UHJvamVjdFNlY3JldHMSOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvamVjdFNlY3JldHNSZXF1ZXN0GjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFByb2plY3RTZWNyZXRzUmVzcG9uc2USkgEKE0NyZWF0ZVByb2plY3RTZWNyZXQSPC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVQcm9qZWN0U2VjcmV0UmVxdWVzdBo9LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVByb2plY3RTZWNyZXRSZXNwb25zZRKSAQoTVXBkYXRlUHJvamVjdFNlY3JldBI8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVByb2plY3RTZWNyZXRSZXF1ZXN0Gj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuVXBkYXRlUHJvamVjdFNlY3JldFJlc3BvbnNlEpIBChNEZWxldGVQcm9qZWN0U2VjcmV0EjwuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUHJvamVjdFNlY3JldFJlcXVlc3QaPS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVQcm9qZWN0U2VjcmV0UmVzcG9uc2USmAEKFUxpc3RBbmFseXNpc1RlbXBsYXRlcxI+LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RBbmFseXNpc1RlbXBsYXRlc1JlcXVlc3QaPy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0QW5hbHlzaXNUZW1wbGF0ZXNSZXNwb25zZRKSAQoTR2V0QW5hbHlzaXNUZW1wbGF0ZRI8LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldEFuYWx5c2lzVGVtcGxhdGVSZXF1ZXN0Gj0uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0QW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlEpsBChZEZWxldGVBbmFseXNpc1RlbXBsYXRlEj8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QaQC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2USrQEKHExpc3RDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZXMSRS5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGVzUmVxdWVzdBpGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkxpc3RDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZXNSZXNwb25zZRKnAQoaR2V0Q2x1c3RlckFuYWx5c2lzVGVtcGxhdGUSQy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlcXVlc3QaRC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5HZXRDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZVJlc3BvbnNlErABCh1EZWxldGVDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZRJGLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVxdWVzdBpHLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkRlbGV0ZUNsdXN0ZXJBbmFseXNpc1RlbXBsYXRlUmVzcG9uc2USgwEKDkdldEFuYWx5c2lzUnVuEjcuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0QW5hbHlzaXNSdW5SZXF1ZXN0GjguYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0QW5hbHlzaXNSdW5SZXNwb25zZRKMAQoRTGlzdFByb2plY3RFdmVudHMSOi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvamVjdEV2ZW50c1JlcXVlc3QaOy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0UHJvamVjdEV2ZW50c1Jlc3BvbnNlEncKCkNyZWF0ZVJvbGUSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5DcmVhdGVSb2xlUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkNyZWF0ZVJvbGVSZXNwb25zZRJ3CgpEZWxldGVSb2xlEjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuRGVsZXRlUm9sZVJlcXVlc3QaNC5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5EZWxldGVSb2xlUmVzcG9uc2USbgoHR2V0Um9sZRIwLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLkdldFJvbGVSZXF1ZXN0GjEuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR2V0Um9sZVJlc3BvbnNlEmgKBUdyYW50Ei4uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR3JhbnRSZXF1ZXN0Gi8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuR3JhbnRSZXNwb25zZRJ0CglMaXN0Um9sZXMSMi5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5MaXN0Um9sZXNSZXF1ZXN0GjMuYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuTGlzdFJvbGVzUmVzcG9uc2USawoGUmV2b2tlEi8uYWt1aXR5LmlvLmthcmdvLnNlcnZpY2UudjFhbHBoYTEuUmV2b2tlUmVxdWVzdBowLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlJldm9rZVJlc3BvbnNlEncKClVwZGF0ZVJvbGUSMy5ha3VpdHkuaW8ua2FyZ28uc2VydmljZS52MWFscGhhMS5VcGRhdGVSb2xlUmVxdWVzdBo0LmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExLlVwZGF0ZVJvbGVSZXNwb25zZUKTAgokY29tLmFrdWl0eS5pby5rYXJnby5zZXJ2aWNlLnYxYWxwaGExQgxTZXJ2aWNlUHJvdG9QAVo4Z2l0aHViLmNvbS9ha3VpdHkva2FyZ28vYXBpL3NlcnZpY2UvdjFhbHBoYTE7c3ZjdjFhbHBoYTGiAgRBSUtTqgIgQWt1aXR5LklvLkthcmdvLlNlcnZpY2UuVjFhbHBoYTHKAiBBa3VpdHlcSW9cS2FyZ29cU2VydmljZVxWMWFscGhhMeICLEFrdWl0eVxJb1xLYXJnb1xTZXJ2aWNlXFYxYWxwaGExXEdQQk1ldGFkYXRh6gIkQWt1aXR5OjpJbzo6S2FyZ286OlNlcnZpY2U6OlYxYWxwaGExYgZwcm90bzM", [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
@@ -42,7 +42,7 @@ export type ComponentVersions = Message<"akuity.io.kargo.service.v1alpha1.Compon
  * Use `create(ComponentVersionsSchema)` to create a new message.
  */
 export const ComponentVersionsSchema: GenMessage<ComponentVersions> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 0);
+  messageDesc(file_api_service_v1alpha1_service, 0);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.VersionInfo
@@ -89,7 +89,7 @@ export type VersionInfo = Message<"akuity.io.kargo.service.v1alpha1.VersionInfo"
  * Use `create(VersionInfoSchema)` to create a new message.
  */
 export const VersionInfoSchema: GenMessage<VersionInfo> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 1);
+  messageDesc(file_api_service_v1alpha1_service, 1);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetVersionInfoRequest
@@ -102,7 +102,7 @@ export type GetVersionInfoRequest = Message<"akuity.io.kargo.service.v1alpha1.Ge
  * Use `create(GetVersionInfoRequestSchema)` to create a new message.
  */
 export const GetVersionInfoRequestSchema: GenMessage<GetVersionInfoRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 2);
+  messageDesc(file_api_service_v1alpha1_service, 2);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetVersionInfoResponse
@@ -119,7 +119,7 @@ export type GetVersionInfoResponse = Message<"akuity.io.kargo.service.v1alpha1.G
  * Use `create(GetVersionInfoResponseSchema)` to create a new message.
  */
 export const GetVersionInfoResponseSchema: GenMessage<GetVersionInfoResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 3);
+  messageDesc(file_api_service_v1alpha1_service, 3);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetConfigRequest
@@ -132,7 +132,7 @@ export type GetConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.GetConf
  * Use `create(GetConfigRequestSchema)` to create a new message.
  */
 export const GetConfigRequestSchema: GenMessage<GetConfigRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 4);
+  messageDesc(file_api_service_v1alpha1_service, 4);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ArgoCDShard
@@ -154,7 +154,7 @@ export type ArgoCDShard = Message<"akuity.io.kargo.service.v1alpha1.ArgoCDShard"
  * Use `create(ArgoCDShardSchema)` to create a new message.
  */
 export const ArgoCDShardSchema: GenMessage<ArgoCDShard> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 5);
+  messageDesc(file_api_service_v1alpha1_service, 5);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetConfigResponse
@@ -176,7 +176,7 @@ export type GetConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.GetCon
  * Use `create(GetConfigResponseSchema)` to create a new message.
  */
 export const GetConfigResponseSchema: GenMessage<GetConfigResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 6);
+  messageDesc(file_api_service_v1alpha1_service, 6);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetPublicConfigRequest
@@ -189,7 +189,7 @@ export type GetPublicConfigRequest = Message<"akuity.io.kargo.service.v1alpha1.G
  * Use `create(GetPublicConfigRequestSchema)` to create a new message.
  */
 export const GetPublicConfigRequestSchema: GenMessage<GetPublicConfigRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 7);
+  messageDesc(file_api_service_v1alpha1_service, 7);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetPublicConfigResponse
@@ -216,7 +216,7 @@ export type GetPublicConfigResponse = Message<"akuity.io.kargo.service.v1alpha1.
  * Use `create(GetPublicConfigResponseSchema)` to create a new message.
  */
 export const GetPublicConfigResponseSchema: GenMessage<GetPublicConfigResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 8);
+  messageDesc(file_api_service_v1alpha1_service, 8);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.OIDCConfig
@@ -248,7 +248,7 @@ export type OIDCConfig = Message<"akuity.io.kargo.service.v1alpha1.OIDCConfig">
  * Use `create(OIDCConfigSchema)` to create a new message.
  */
 export const OIDCConfigSchema: GenMessage<OIDCConfig> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 9);
+  messageDesc(file_api_service_v1alpha1_service, 9);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.AdminLoginRequest
@@ -265,7 +265,7 @@ export type AdminLoginRequest = Message<"akuity.io.kargo.service.v1alpha1.AdminL
  * Use `create(AdminLoginRequestSchema)` to create a new message.
  */
 export const AdminLoginRequestSchema: GenMessage<AdminLoginRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 10);
+  messageDesc(file_api_service_v1alpha1_service, 10);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.AdminLoginResponse
@@ -282,7 +282,7 @@ export type AdminLoginResponse = Message<"akuity.io.kargo.service.v1alpha1.Admin
  * Use `create(AdminLoginResponseSchema)` to create a new message.
  */
 export const AdminLoginResponseSchema: GenMessage<AdminLoginResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 11);
+  messageDesc(file_api_service_v1alpha1_service, 11);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateResourceRequest
@@ -299,7 +299,7 @@ export type CreateResourceRequest = Message<"akuity.io.kargo.service.v1alpha1.Cr
  * Use `create(CreateResourceRequestSchema)` to create a new message.
  */
 export const CreateResourceRequestSchema: GenMessage<CreateResourceRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 12);
+  messageDesc(file_api_service_v1alpha1_service, 12);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateResourceResult
@@ -328,7 +328,7 @@ export type CreateResourceResult = Message<"akuity.io.kargo.service.v1alpha1.Cre
  * Use `create(CreateResourceResultSchema)` to create a new message.
  */
 export const CreateResourceResultSchema: GenMessage<CreateResourceResult> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 13);
+  messageDesc(file_api_service_v1alpha1_service, 13);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateResourceResponse
@@ -345,7 +345,7 @@ export type CreateResourceResponse = Message<"akuity.io.kargo.service.v1alpha1.C
  * Use `create(CreateResourceResponseSchema)` to create a new message.
  */
 export const CreateResourceResponseSchema: GenMessage<CreateResourceResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 14);
+  messageDesc(file_api_service_v1alpha1_service, 14);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceRequest
@@ -362,7 +362,7 @@ export type CreateOrUpdateResourceRequest = Message<"akuity.io.kargo.service.v1a
  * Use `create(CreateOrUpdateResourceRequestSchema)` to create a new message.
  */
 export const CreateOrUpdateResourceRequestSchema: GenMessage<CreateOrUpdateResourceRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 15);
+  messageDesc(file_api_service_v1alpha1_service, 15);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceResult
@@ -397,7 +397,7 @@ export type CreateOrUpdateResourceResult = Message<"akuity.io.kargo.service.v1al
  * Use `create(CreateOrUpdateResourceResultSchema)` to create a new message.
  */
 export const CreateOrUpdateResourceResultSchema: GenMessage<CreateOrUpdateResourceResult> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 16);
+  messageDesc(file_api_service_v1alpha1_service, 16);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateOrUpdateResourceResponse
@@ -414,7 +414,7 @@ export type CreateOrUpdateResourceResponse = Message<"akuity.io.kargo.service.v1
  * Use `create(CreateOrUpdateResourceResponseSchema)` to create a new message.
  */
 export const CreateOrUpdateResourceResponseSchema: GenMessage<CreateOrUpdateResourceResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 17);
+  messageDesc(file_api_service_v1alpha1_service, 17);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateResourceRequest
@@ -431,7 +431,7 @@ export type UpdateResourceRequest = Message<"akuity.io.kargo.service.v1alpha1.Up
  * Use `create(UpdateResourceRequestSchema)` to create a new message.
  */
 export const UpdateResourceRequestSchema: GenMessage<UpdateResourceRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 18);
+  messageDesc(file_api_service_v1alpha1_service, 18);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateResourceResult
@@ -460,7 +460,7 @@ export type UpdateResourceResult = Message<"akuity.io.kargo.service.v1alpha1.Upd
  * Use `create(UpdateResourceResultSchema)` to create a new message.
  */
 export const UpdateResourceResultSchema: GenMessage<UpdateResourceResult> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 19);
+  messageDesc(file_api_service_v1alpha1_service, 19);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateResourceResponse
@@ -477,7 +477,7 @@ export type UpdateResourceResponse = Message<"akuity.io.kargo.service.v1alpha1.U
  * Use `create(UpdateResourceResponseSchema)` to create a new message.
  */
 export const UpdateResourceResponseSchema: GenMessage<UpdateResourceResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 20);
+  messageDesc(file_api_service_v1alpha1_service, 20);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteResourceRequest
@@ -494,7 +494,7 @@ export type DeleteResourceRequest = Message<"akuity.io.kargo.service.v1alpha1.De
  * Use `create(DeleteResourceRequestSchema)` to create a new message.
  */
 export const DeleteResourceRequestSchema: GenMessage<DeleteResourceRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 21);
+  messageDesc(file_api_service_v1alpha1_service, 21);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteResourceResult
@@ -523,7 +523,7 @@ export type DeleteResourceResult = Message<"akuity.io.kargo.service.v1alpha1.Del
  * Use `create(DeleteResourceResultSchema)` to create a new message.
  */
 export const DeleteResourceResultSchema: GenMessage<DeleteResourceResult> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 22);
+  messageDesc(file_api_service_v1alpha1_service, 22);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteResourceResponse
@@ -540,7 +540,7 @@ export type DeleteResourceResponse = Message<"akuity.io.kargo.service.v1alpha1.D
  * Use `create(DeleteResourceResponseSchema)` to create a new message.
  */
 export const DeleteResourceResponseSchema: GenMessage<DeleteResourceResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 23);
+  messageDesc(file_api_service_v1alpha1_service, 23);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListStagesRequest
@@ -557,7 +557,7 @@ export type ListStagesRequest = Message<"akuity.io.kargo.service.v1alpha1.ListSt
  * Use `create(ListStagesRequestSchema)` to create a new message.
  */
 export const ListStagesRequestSchema: GenMessage<ListStagesRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 24);
+  messageDesc(file_api_service_v1alpha1_service, 24);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListStagesResponse
@@ -574,7 +574,7 @@ export type ListStagesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListS
  * Use `create(ListStagesResponseSchema)` to create a new message.
  */
 export const ListStagesResponseSchema: GenMessage<ListStagesResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 25);
+  messageDesc(file_api_service_v1alpha1_service, 25);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListImagesRequest
@@ -591,7 +591,7 @@ export type ListImagesRequest = Message<"akuity.io.kargo.service.v1alpha1.ListIm
  * Use `create(ListImagesRequestSchema)` to create a new message.
  */
 export const ListImagesRequestSchema: GenMessage<ListImagesRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 26);
+  messageDesc(file_api_service_v1alpha1_service, 26);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListImagesResponse
@@ -610,7 +610,7 @@ export type ListImagesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListI
  * Use `create(ListImagesResponseSchema)` to create a new message.
  */
 export const ListImagesResponseSchema: GenMessage<ListImagesResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 27);
+  messageDesc(file_api_service_v1alpha1_service, 27);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.TagMap
@@ -629,7 +629,7 @@ export type TagMap = Message<"akuity.io.kargo.service.v1alpha1.TagMap"> & {
  * Use `create(TagMapSchema)` to create a new message.
  */
 export const TagMapSchema: GenMessage<TagMap> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 28);
+  messageDesc(file_api_service_v1alpha1_service, 28);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ImageStageMap
@@ -648,7 +648,7 @@ export type ImageStageMap = Message<"akuity.io.kargo.service.v1alpha1.ImageStage
  * Use `create(ImageStageMapSchema)` to create a new message.
  */
 export const ImageStageMapSchema: GenMessage<ImageStageMap> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 29);
+  messageDesc(file_api_service_v1alpha1_service, 29);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetStageRequest
@@ -675,7 +675,7 @@ export type GetStageRequest = Message<"akuity.io.kargo.service.v1alpha1.GetStage
  * Use `create(GetStageRequestSchema)` to create a new message.
  */
 export const GetStageRequestSchema: GenMessage<GetStageRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 30);
+  messageDesc(file_api_service_v1alpha1_service, 30);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetStageResponse
@@ -704,7 +704,7 @@ export type GetStageResponse = Message<"akuity.io.kargo.service.v1alpha1.GetStag
  * Use `create(GetStageResponseSchema)` to create a new message.
  */
 export const GetStageResponseSchema: GenMessage<GetStageResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 31);
+  messageDesc(file_api_service_v1alpha1_service, 31);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchStagesRequest
@@ -726,7 +726,7 @@ export type WatchStagesRequest = Message<"akuity.io.kargo.service.v1alpha1.Watch
  * Use `create(WatchStagesRequestSchema)` to create a new message.
  */
 export const WatchStagesRequestSchema: GenMessage<WatchStagesRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 32);
+  messageDesc(file_api_service_v1alpha1_service, 32);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchStagesResponse
@@ -748,7 +748,7 @@ export type WatchStagesResponse = Message<"akuity.io.kargo.service.v1alpha1.Watc
  * Use `create(WatchStagesResponseSchema)` to create a new message.
  */
 export const WatchStagesResponseSchema: GenMessage<WatchStagesResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 33);
+  messageDesc(file_api_service_v1alpha1_service, 33);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteStageRequest
@@ -770,7 +770,7 @@ export type DeleteStageRequest = Message<"akuity.io.kargo.service.v1alpha1.Delet
  * Use `create(DeleteStageRequestSchema)` to create a new message.
  */
 export const DeleteStageRequestSchema: GenMessage<DeleteStageRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 34);
+  messageDesc(file_api_service_v1alpha1_service, 34);
 
 /**
  * explicitly empty 
@@ -785,7 +785,7 @@ export type DeleteStageResponse = Message<"akuity.io.kargo.service.v1alpha1.Dele
  * Use `create(DeleteStageResponseSchema)` to create a new message.
  */
 export const DeleteStageResponseSchema: GenMessage<DeleteStageResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 35);
+  messageDesc(file_api_service_v1alpha1_service, 35);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RefreshStageRequest
@@ -807,7 +807,7 @@ export type RefreshStageRequest = Message<"akuity.io.kargo.service.v1alpha1.Refr
  * Use `create(RefreshStageRequestSchema)` to create a new message.
  */
 export const RefreshStageRequestSchema: GenMessage<RefreshStageRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 36);
+  messageDesc(file_api_service_v1alpha1_service, 36);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RefreshStageResponse
@@ -824,7 +824,7 @@ export type RefreshStageResponse = Message<"akuity.io.kargo.service.v1alpha1.Ref
  * Use `create(RefreshStageResponseSchema)` to create a new message.
  */
 export const RefreshStageResponseSchema: GenMessage<RefreshStageResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 37);
+  messageDesc(file_api_service_v1alpha1_service, 37);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionsRequest
@@ -846,7 +846,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_service_v1alpha1_service, 38);
+  messageDesc(file_api_service_v1alpha1_service, 38);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListPromotionsResponse
@@ -863,7 +863,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_service_v1alpha1_service, 39);
+  messageDesc(file_api_service_v1alpha1_service, 39);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionsRequest
@@ -885,7 +885,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_service_v1alpha1_service, 40);
+  messageDesc(file_api_service_v1alpha1_service, 40);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionsResponse
@@ -907,7 +907,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_service_v1alpha1_service, 41);
+  messageDesc(file_api_service_v1alpha1_service, 41);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionRequest
@@ -934,7 +934,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_service_v1alpha1_service, 42);
+  messageDesc(file_api_service_v1alpha1_service, 42);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetPromotionResponse
@@ -963,7 +963,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_service_v1alpha1_service, 43);
+  messageDesc(file_api_service_v1alpha1_service, 43);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionRequest
@@ -985,7 +985,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_service_v1alpha1_service, 44);
+  messageDesc(file_api_service_v1alpha1_service, 44);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchPromotionResponse
@@ -1007,7 +1007,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_service_v1alpha1_service, 45);
+  messageDesc(file_api_service_v1alpha1_service, 45);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.AbortPromotionRequest
@@ -1029,7 +1029,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_service_v1alpha1_service, 46);
+  messageDesc(file_api_service_v1alpha1_service, 46);
 
 /**
  * explicitly empty 
@@ -1044,7 +1044,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_service_v1alpha1_service, 47);
+  messageDesc(file_api_service_v1alpha1_service, 47);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectRequest
@@ -1061,7 +1061,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_service_v1alpha1_service, 48);
+  messageDesc(file_api_service_v1alpha1_service, 48);
 
 /**
  * explicitly empty 
@@ -1076,7 +1076,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_service_v1alpha1_service, 49);
+  messageDesc(file_api_service_v1alpha1_service, 49);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectRequest
@@ -1098,7 +1098,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_service_v1alpha1_service, 50);
+  messageDesc(file_api_service_v1alpha1_service, 50);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetProjectResponse
@@ -1127,7 +1127,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_service_v1alpha1_service, 51);
+  messageDesc(file_api_service_v1alpha1_service, 51);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectsRequest
@@ -1154,7 +1154,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_service_v1alpha1_service, 52);
+  messageDesc(file_api_service_v1alpha1_service, 52);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectsResponse
@@ -1176,7 +1176,7 @@ 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_service_v1alpha1_service, 53);
+  messageDesc(file_api_service_v1alpha1_service, 53);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ApproveFreightRequest
@@ -1208,7 +1208,7 @@ export type ApproveFreightRequest = Message<"akuity.io.kargo.service.v1alpha1.Ap
  * Use `create(ApproveFreightRequestSchema)` to create a new message.
  */
 export const ApproveFreightRequestSchema: GenMessage<ApproveFreightRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 54);
+  messageDesc(file_api_service_v1alpha1_service, 54);
 
 /**
  * explicitly empty 
@@ -1223,7 +1223,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_service_v1alpha1_service, 55);
+  messageDesc(file_api_service_v1alpha1_service, 55);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteFreightRequest
@@ -1250,7 +1250,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_service_v1alpha1_service, 56);
+  messageDesc(file_api_service_v1alpha1_service, 56);
 
 /**
  * explicitly empty 
@@ -1265,7 +1265,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_service_v1alpha1_service, 57);
+  messageDesc(file_api_service_v1alpha1_service, 57);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetFreightRequest
@@ -1297,7 +1297,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_service_v1alpha1_service, 58);
+  messageDesc(file_api_service_v1alpha1_service, 58);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetFreightResponse
@@ -1326,7 +1326,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_service_v1alpha1_service, 59);
+  messageDesc(file_api_service_v1alpha1_service, 59);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteToStageRequest
@@ -1358,7 +1358,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_service_v1alpha1_service, 60);
+  messageDesc(file_api_service_v1alpha1_service, 60);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteToStageResponse
@@ -1375,7 +1375,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_service_v1alpha1_service, 61);
+  messageDesc(file_api_service_v1alpha1_service, 61);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteDownstreamRequest
@@ -1407,7 +1407,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_service_v1alpha1_service, 62);
+  messageDesc(file_api_service_v1alpha1_service, 62);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.PromoteDownstreamResponse
@@ -1424,7 +1424,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_service_v1alpha1_service, 63);
+  messageDesc(file_api_service_v1alpha1_service, 63);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.QueryFreightRequest
@@ -1471,7 +1471,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_service_v1alpha1_service, 64);
+  messageDesc(file_api_service_v1alpha1_service, 64);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.QueryFreightResponse
@@ -1488,7 +1488,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_service_v1alpha1_service, 65);
+  messageDesc(file_api_service_v1alpha1_service, 65);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.FreightList
@@ -1505,7 +1505,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_service_v1alpha1_service, 66);
+  messageDesc(file_api_service_v1alpha1_service, 66);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateFreightAliasRequest
@@ -1537,7 +1537,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_service_v1alpha1_service, 67);
+  messageDesc(file_api_service_v1alpha1_service, 67);
 
 /**
  * explicitly empty 
@@ -1552,7 +1552,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_service_v1alpha1_service, 68);
+  messageDesc(file_api_service_v1alpha1_service, 68);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ReverifyRequest
@@ -1574,7 +1574,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_service_v1alpha1_service, 69);
+  messageDesc(file_api_service_v1alpha1_service, 69);
 
 /**
  * explicitly empty 
@@ -1589,7 +1589,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_service_v1alpha1_service, 70);
+  messageDesc(file_api_service_v1alpha1_service, 70);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.AbortVerificationRequest
@@ -1611,7 +1611,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_service_v1alpha1_service, 71);
+  messageDesc(file_api_service_v1alpha1_service, 71);
 
 /**
  * explicitly empty 
@@ -1626,7 +1626,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_service_v1alpha1_service, 72);
+  messageDesc(file_api_service_v1alpha1_service, 72);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListWarehousesRequest
@@ -1643,7 +1643,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_service_v1alpha1_service, 73);
+  messageDesc(file_api_service_v1alpha1_service, 73);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListWarehousesResponse
@@ -1660,7 +1660,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_service_v1alpha1_service, 74);
+  messageDesc(file_api_service_v1alpha1_service, 74);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetWarehouseRequest
@@ -1687,7 +1687,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_service_v1alpha1_service, 75);
+  messageDesc(file_api_service_v1alpha1_service, 75);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetWarehouseResponse
@@ -1716,7 +1716,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_service_v1alpha1_service, 76);
+  messageDesc(file_api_service_v1alpha1_service, 76);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchWarehousesRequest
@@ -1738,7 +1738,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_service_v1alpha1_service, 77);
+  messageDesc(file_api_service_v1alpha1_service, 77);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.WatchWarehousesResponse
@@ -1760,7 +1760,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_service_v1alpha1_service, 78);
+  messageDesc(file_api_service_v1alpha1_service, 78);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteWarehouseRequest
@@ -1782,7 +1782,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_service_v1alpha1_service, 79);
+  messageDesc(file_api_service_v1alpha1_service, 79);
 
 /**
  * explicitly empty 
@@ -1797,7 +1797,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_service_v1alpha1_service, 80);
+  messageDesc(file_api_service_v1alpha1_service, 80);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RefreshWarehouseRequest
@@ -1819,7 +1819,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_service_v1alpha1_service, 81);
+  messageDesc(file_api_service_v1alpha1_service, 81);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RefreshWarehouseResponse
@@ -1836,7 +1836,7 @@ 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_service_v1alpha1_service, 82);
+  messageDesc(file_api_service_v1alpha1_service, 82);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectSecretsRequest
@@ -1853,7 +1853,7 @@ export type ListProjectSecretsRequest = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(ListProjectSecretsRequestSchema)` to create a new message.
  */
 export const ListProjectSecretsRequestSchema: GenMessage<ListProjectSecretsRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 83);
+  messageDesc(file_api_service_v1alpha1_service, 83);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectSecretsResponse
@@ -1870,7 +1870,7 @@ export type ListProjectSecretsResponse = Message<"akuity.io.kargo.service.v1alph
  * Use `create(ListProjectSecretsResponseSchema)` to create a new message.
  */
 export const ListProjectSecretsResponseSchema: GenMessage<ListProjectSecretsResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 84);
+  messageDesc(file_api_service_v1alpha1_service, 84);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateProjectSecretRequest
@@ -1902,7 +1902,7 @@ export type CreateProjectSecretRequest = Message<"akuity.io.kargo.service.v1alph
  * Use `create(CreateProjectSecretRequestSchema)` to create a new message.
  */
 export const CreateProjectSecretRequestSchema: GenMessage<CreateProjectSecretRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 85);
+  messageDesc(file_api_service_v1alpha1_service, 85);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateProjectSecretResponse
@@ -1919,7 +1919,7 @@ export type CreateProjectSecretResponse = Message<"akuity.io.kargo.service.v1alp
  * Use `create(CreateProjectSecretResponseSchema)` to create a new message.
  */
 export const CreateProjectSecretResponseSchema: GenMessage<CreateProjectSecretResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 86);
+  messageDesc(file_api_service_v1alpha1_service, 86);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretRequest
@@ -1951,7 +1951,7 @@ export type UpdateProjectSecretRequest = Message<"akuity.io.kargo.service.v1alph
  * Use `create(UpdateProjectSecretRequestSchema)` to create a new message.
  */
 export const UpdateProjectSecretRequestSchema: GenMessage<UpdateProjectSecretRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 87);
+  messageDesc(file_api_service_v1alpha1_service, 87);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateProjectSecretResponse
@@ -1968,7 +1968,7 @@ export type UpdateProjectSecretResponse = Message<"akuity.io.kargo.service.v1alp
  * Use `create(UpdateProjectSecretResponseSchema)` to create a new message.
  */
 export const UpdateProjectSecretResponseSchema: GenMessage<UpdateProjectSecretResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 88);
+  messageDesc(file_api_service_v1alpha1_service, 88);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteProjectSecretRequest
@@ -1990,7 +1990,7 @@ export type DeleteProjectSecretRequest = Message<"akuity.io.kargo.service.v1alph
  * Use `create(DeleteProjectSecretRequestSchema)` to create a new message.
  */
 export const DeleteProjectSecretRequestSchema: GenMessage<DeleteProjectSecretRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 89);
+  messageDesc(file_api_service_v1alpha1_service, 89);
 
 /**
  * explicitly empty 
@@ -2005,7 +2005,7 @@ export type DeleteProjectSecretResponse = Message<"akuity.io.kargo.service.v1alp
  * Use `create(DeleteProjectSecretResponseSchema)` to create a new message.
  */
 export const DeleteProjectSecretResponseSchema: GenMessage<DeleteProjectSecretResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 90);
+  messageDesc(file_api_service_v1alpha1_service, 90);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateCredentialsRequest
@@ -2059,7 +2059,7 @@ export type CreateCredentialsRequest = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(CreateCredentialsRequestSchema)` to create a new message.
  */
 export const CreateCredentialsRequestSchema: GenMessage<CreateCredentialsRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 91);
+  messageDesc(file_api_service_v1alpha1_service, 91);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateCredentialsResponse
@@ -2076,7 +2076,7 @@ export type CreateCredentialsResponse = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(CreateCredentialsResponseSchema)` to create a new message.
  */
 export const CreateCredentialsResponseSchema: GenMessage<CreateCredentialsResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 92);
+  messageDesc(file_api_service_v1alpha1_service, 92);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteCredentialsRequest
@@ -2098,7 +2098,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_service_v1alpha1_service, 93);
+  messageDesc(file_api_service_v1alpha1_service, 93);
 
 /**
  * explicitly empty 
@@ -2113,7 +2113,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_service_v1alpha1_service, 94);
+  messageDesc(file_api_service_v1alpha1_service, 94);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetCredentialsRequest
@@ -2140,7 +2140,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_service_v1alpha1_service, 95);
+  messageDesc(file_api_service_v1alpha1_service, 95);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetCredentialsResponse
@@ -2169,7 +2169,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_service_v1alpha1_service, 96);
+  messageDesc(file_api_service_v1alpha1_service, 96);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListCredentialsRequest
@@ -2186,7 +2186,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_service_v1alpha1_service, 97);
+  messageDesc(file_api_service_v1alpha1_service, 97);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListCredentialsResponse
@@ -2203,7 +2203,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_service_v1alpha1_service, 98);
+  messageDesc(file_api_service_v1alpha1_service, 98);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateCredentialsRequest
@@ -2255,7 +2255,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_service_v1alpha1_service, 99);
+  messageDesc(file_api_service_v1alpha1_service, 99);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateCredentialsResponse
@@ -2272,7 +2272,7 @@ 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_service_v1alpha1_service, 100);
+  messageDesc(file_api_service_v1alpha1_service, 100);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesRequest
@@ -2289,14 +2289,14 @@ export type ListAnalysisTemplatesRequest = Message<"akuity.io.kargo.service.v1al
  * Use `create(ListAnalysisTemplatesRequestSchema)` to create a new message.
  */
 export const ListAnalysisTemplatesRequestSchema: GenMessage<ListAnalysisTemplatesRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 101);
+  messageDesc(file_api_service_v1alpha1_service, 101);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse
  */
 export type ListAnalysisTemplatesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListAnalysisTemplatesResponse"> & {
   /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate analysis_templates = 1;
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_templates = 1;
    */
   analysisTemplates: AnalysisTemplate[];
 };
@@ -2306,7 +2306,7 @@ export type ListAnalysisTemplatesResponse = Message<"akuity.io.kargo.service.v1a
  * Use `create(ListAnalysisTemplatesResponseSchema)` to create a new message.
  */
 export const ListAnalysisTemplatesResponseSchema: GenMessage<ListAnalysisTemplatesResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 102);
+  messageDesc(file_api_service_v1alpha1_service, 102);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateRequest
@@ -2333,7 +2333,7 @@ export type GetAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1alph
  * Use `create(GetAnalysisTemplateRequestSchema)` to create a new message.
  */
 export const GetAnalysisTemplateRequestSchema: GenMessage<GetAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 103);
+  messageDesc(file_api_service_v1alpha1_service, 103);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisTemplateResponse
@@ -2344,7 +2344,7 @@ export type GetAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alp
    */
   result: {
     /**
-     * @generated from field: github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate analysis_template = 1;
+     * @generated from field: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate analysis_template = 1;
      */
     value: AnalysisTemplate;
     case: "analysisTemplate";
@@ -2362,7 +2362,7 @@ export type GetAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1alp
  * Use `create(GetAnalysisTemplateResponseSchema)` to create a new message.
  */
 export const GetAnalysisTemplateResponseSchema: GenMessage<GetAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 104);
+  messageDesc(file_api_service_v1alpha1_service, 104);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesRequest
@@ -2375,14 +2375,14 @@ export type ListClusterAnalysisTemplatesRequest = Message<"akuity.io.kargo.servi
  * Use `create(ListClusterAnalysisTemplatesRequestSchema)` to create a new message.
  */
 export const ListClusterAnalysisTemplatesRequestSchema: GenMessage<ListClusterAnalysisTemplatesRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 105);
+  messageDesc(file_api_service_v1alpha1_service, 105);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse
  */
 export type ListClusterAnalysisTemplatesResponse = Message<"akuity.io.kargo.service.v1alpha1.ListClusterAnalysisTemplatesResponse"> & {
   /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate cluster_analysis_templates = 1 [json_name = "clusteranalysisTemplates"];
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate cluster_analysis_templates = 1 [json_name = "clusteranalysisTemplates"];
    */
   clusterAnalysisTemplates: ClusterAnalysisTemplate[];
 };
@@ -2392,7 +2392,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_service_v1alpha1_service, 106);
+  messageDesc(file_api_service_v1alpha1_service, 106);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateRequest
@@ -2414,7 +2414,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_service_v1alpha1_service, 107);
+  messageDesc(file_api_service_v1alpha1_service, 107);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetClusterAnalysisTemplateResponse
@@ -2425,7 +2425,7 @@ export type GetClusterAnalysisTemplateResponse = Message<"akuity.io.kargo.servic
    */
   result: {
     /**
-     * @generated from field: github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate cluster_analysis_template = 1;
+     * @generated from field: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate cluster_analysis_template = 1;
      */
     value: ClusterAnalysisTemplate;
     case: "clusterAnalysisTemplate";
@@ -2443,7 +2443,7 @@ export type GetClusterAnalysisTemplateResponse = Message<"akuity.io.kargo.servic
  * Use `create(GetClusterAnalysisTemplateResponseSchema)` to create a new message.
  */
 export const GetClusterAnalysisTemplateResponseSchema: GenMessage<GetClusterAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 108);
+  messageDesc(file_api_service_v1alpha1_service, 108);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisRunRequest
@@ -2470,7 +2470,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_service_v1alpha1_service, 109);
+  messageDesc(file_api_service_v1alpha1_service, 109);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetAnalysisRunResponse
@@ -2481,7 +2481,7 @@ export type GetAnalysisRunResponse = Message<"akuity.io.kargo.service.v1alpha1.G
    */
   result: {
     /**
-     * @generated from field: github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun analysis_run = 1;
+     * @generated from field: github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun analysis_run = 1;
      */
     value: AnalysisRun;
     case: "analysisRun";
@@ -2499,7 +2499,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_service_v1alpha1_service, 110);
+  messageDesc(file_api_service_v1alpha1_service, 110);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteAnalysisTemplateRequest
@@ -2521,7 +2521,7 @@ export type DeleteAnalysisTemplateRequest = Message<"akuity.io.kargo.service.v1a
  * Use `create(DeleteAnalysisTemplateRequestSchema)` to create a new message.
  */
 export const DeleteAnalysisTemplateRequestSchema: GenMessage<DeleteAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 111);
+  messageDesc(file_api_service_v1alpha1_service, 111);
 
 /**
  * explicitly empty 
@@ -2536,7 +2536,7 @@ export type DeleteAnalysisTemplateResponse = Message<"akuity.io.kargo.service.v1
  * Use `create(DeleteAnalysisTemplateResponseSchema)` to create a new message.
  */
 export const DeleteAnalysisTemplateResponseSchema: GenMessage<DeleteAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 112);
+  messageDesc(file_api_service_v1alpha1_service, 112);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteClusterAnalysisTemplateRequest
@@ -2553,7 +2553,7 @@ export type DeleteClusterAnalysisTemplateRequest = Message<"akuity.io.kargo.serv
  * Use `create(DeleteClusterAnalysisTemplateRequestSchema)` to create a new message.
  */
 export const DeleteClusterAnalysisTemplateRequestSchema: GenMessage<DeleteClusterAnalysisTemplateRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 113);
+  messageDesc(file_api_service_v1alpha1_service, 113);
 
 /**
  * explicitly empty 
@@ -2568,7 +2568,7 @@ export type DeleteClusterAnalysisTemplateResponse = Message<"akuity.io.kargo.ser
  * Use `create(DeleteClusterAnalysisTemplateResponseSchema)` to create a new message.
  */
 export const DeleteClusterAnalysisTemplateResponseSchema: GenMessage<DeleteClusterAnalysisTemplateResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 114);
+  messageDesc(file_api_service_v1alpha1_service, 114);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectEventsRequest
@@ -2585,7 +2585,7 @@ export type ListProjectEventsRequest = Message<"akuity.io.kargo.service.v1alpha1
  * Use `create(ListProjectEventsRequestSchema)` to create a new message.
  */
 export const ListProjectEventsRequestSchema: GenMessage<ListProjectEventsRequest> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 115);
+  messageDesc(file_api_service_v1alpha1_service, 115);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListProjectEventsResponse
@@ -2602,7 +2602,7 @@ export type ListProjectEventsResponse = Message<"akuity.io.kargo.service.v1alpha
  * Use `create(ListProjectEventsResponseSchema)` to create a new message.
  */
 export const ListProjectEventsResponseSchema: GenMessage<ListProjectEventsResponse> = /*@__PURE__*/
-  messageDesc(file_service_v1alpha1_service, 116);
+  messageDesc(file_api_service_v1alpha1_service, 116);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateRoleRequest
@@ -2619,7 +2619,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_service_v1alpha1_service, 117);
+  messageDesc(file_api_service_v1alpha1_service, 117);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.CreateRoleResponse
@@ -2636,7 +2636,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_service_v1alpha1_service, 118);
+  messageDesc(file_api_service_v1alpha1_service, 118);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.DeleteRoleRequest
@@ -2658,7 +2658,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_service_v1alpha1_service, 119);
+  messageDesc(file_api_service_v1alpha1_service, 119);
 
 /**
  * explicitly empty 
@@ -2673,7 +2673,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_service_v1alpha1_service, 120);
+  messageDesc(file_api_service_v1alpha1_service, 120);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetRoleRequest
@@ -2705,7 +2705,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_service_v1alpha1_service, 121);
+  messageDesc(file_api_service_v1alpha1_service, 121);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GetRoleResponse
@@ -2740,7 +2740,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_service_v1alpha1_service, 122);
+  messageDesc(file_api_service_v1alpha1_service, 122);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.Claims
@@ -2759,7 +2759,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_service_v1alpha1_service, 123);
+  messageDesc(file_api_service_v1alpha1_service, 123);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GrantRequest
@@ -2798,7 +2798,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_service_v1alpha1_service, 124);
+  messageDesc(file_api_service_v1alpha1_service, 124);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.GrantResponse
@@ -2815,7 +2815,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_service_v1alpha1_service, 125);
+  messageDesc(file_api_service_v1alpha1_service, 125);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListRolesRequest
@@ -2837,7 +2837,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_service_v1alpha1_service, 126);
+  messageDesc(file_api_service_v1alpha1_service, 126);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.ListRolesResponse
@@ -2861,7 +2861,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_service_v1alpha1_service, 127);
+  messageDesc(file_api_service_v1alpha1_service, 127);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RevokeRequest
@@ -2900,7 +2900,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_service_v1alpha1_service, 128);
+  messageDesc(file_api_service_v1alpha1_service, 128);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.RevokeResponse
@@ -2917,7 +2917,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_service_v1alpha1_service, 129);
+  messageDesc(file_api_service_v1alpha1_service, 129);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateRoleRequest
@@ -2934,7 +2934,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_service_v1alpha1_service, 130);
+  messageDesc(file_api_service_v1alpha1_service, 130);
 
 /**
  * @generated from message akuity.io.kargo.service.v1alpha1.UpdateRoleResponse
@@ -2951,7 +2951,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_service_v1alpha1_service, 131);
+  messageDesc(file_api_service_v1alpha1_service, 131);
 
 /**
  * @generated from enum akuity.io.kargo.service.v1alpha1.RawFormat
@@ -2977,7 +2977,7 @@ export enum RawFormat {
  * Describes the enum akuity.io.kargo.service.v1alpha1.RawFormat.
  */
 export const RawFormatSchema: GenEnum<RawFormat> = /*@__PURE__*/
-  enumDesc(file_service_v1alpha1_service, 0);
+  enumDesc(file_api_service_v1alpha1_service, 0);
 
 /**
  * @generated from service akuity.io.kargo.service.v1alpha1.KargoService
@@ -3467,5 +3467,5 @@ export const KargoService: GenService<{
     output: typeof UpdateRoleResponseSchema;
   },
 }> = /*@__PURE__*/
-  serviceDesc(file_service_v1alpha1_service, 0);
+  serviceDesc(file_api_service_v1alpha1_service, 0);
 
diff --git a/ui/src/gen/api/stubs/rollouts/v1alpha1/generated_pb.ts b/ui/src/gen/api/stubs/rollouts/v1alpha1/generated_pb.ts
new file mode 100644
index 00000000..3143f204
--- /dev/null
+++ b/ui/src/gen/api/stubs/rollouts/v1alpha1/generated_pb.ts
@@ -0,0 +1,1352 @@
+// This file was autogenerated by go-to-protobuf. Do not edit it manually!
+
+// @generated by protoc-gen-es v2.2.2 with parameter "target=ts"
+// @generated from file api/stubs/rollouts/v1alpha1/generated.proto (package github.com.akuity.kargo.api.stubs.rollouts.v1alpha1, syntax proto2)
+/* eslint-disable */
+
+import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
+import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
+import type { JobSpec } from "../../../../k8s.io/api/batch/v1/generated_pb";
+import { file_k8s_io_api_batch_v1_generated } from "../../../../k8s.io/api/batch/v1/generated_pb";
+import type { ListMeta, ObjectMeta, Time } from "../../../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
+import { file_k8s_io_apimachinery_pkg_apis_meta_v1_generated } from "../../../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
+import { file_k8s_io_apimachinery_pkg_runtime_generated } from "../../../../k8s.io/apimachinery/pkg/runtime/generated_pb";
+import { file_k8s_io_apimachinery_pkg_runtime_schema_generated } from "../../../../k8s.io/apimachinery/pkg/runtime/schema/generated_pb";
+import type { IntOrString } from "../../../../k8s.io/apimachinery/pkg/util/intstr/generated_pb";
+import { file_k8s_io_apimachinery_pkg_util_intstr_generated } from "../../../../k8s.io/apimachinery/pkg/util/intstr/generated_pb";
+import type { Message } from "@bufbuild/protobuf";
+
+/**
+ * Describes the file api/stubs/rollouts/v1alpha1/generated.proto.
+ */
+export const file_api_stubs_rollouts_v1alpha1_generated: GenFile = /*@__PURE__*/
+  fileDesc("CithcGkvc3R1YnMvcm9sbG91dHMvdjFhbHBoYTEvZ2VuZXJhdGVkLnByb3RvEjNnaXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEi/QEKC0FuYWx5c2lzUnVuEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESUgoEc3BlYxgCIAEoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5BbmFseXNpc1J1blNwZWMSVgoGc3RhdHVzGAMgASgLMkYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFuYWx5c2lzUnVuU3RhdHVzIqQBCg9BbmFseXNpc1J1bkxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESTwoFaXRlbXMYAiADKAsyQC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQW5hbHlzaXNSdW4i9QIKD0FuYWx5c2lzUnVuU3BlYxJMCgdtZXRyaWNzGAEgAygLMjsuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLk1ldHJpYxJLCgRhcmdzGAIgAygLMj0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFyZ3VtZW50EhEKCXRlcm1pbmF0ZRgDIAEoCBJLCgZkcnlSdW4YBCADKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuRHJ5UnVuEmcKFG1lYXN1cmVtZW50UmV0ZW50aW9uGAUgAygLMkkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLk1lYXN1cmVtZW50UmV0ZW50aW9uIvkCChFBbmFseXNpc1J1blN0YXR1cxINCgVwaGFzZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJElgKDW1ldHJpY1Jlc3VsdHMYAyADKAsyQS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuTWV0cmljUmVzdWx0Ej0KCXN0YXJ0ZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lElMKCnJ1blN1bW1hcnkYBSABKAsyPy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuUnVuU3VtbWFyeRJWCg1kcnlSdW5TdW1tYXJ5GAYgASgLMj8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLlJ1blN1bW1hcnkirwEKEEFuYWx5c2lzVGVtcGxhdGUSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJXCgRzcGVjGAIgASgLMkkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGVTcGVjIq4BChRBbmFseXNpc1RlbXBsYXRlTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRJUCgVpdGVtcxgCIAMoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5BbmFseXNpc1RlbXBsYXRlIucCChRBbmFseXNpc1RlbXBsYXRlU3BlYxJMCgdtZXRyaWNzGAEgAygLMjsuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLk1ldHJpYxJLCgRhcmdzGAIgAygLMj0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFyZ3VtZW50EksKBmRyeVJ1bhgDIAMoCzI7LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5EcnlSdW4SZwoUbWVhc3VyZW1lbnRSZXRlbnRpb24YBCADKAsySS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuTWVhc3VyZW1lbnRSZXRlbnRpb24iegoIQXJndW1lbnQSDAoEbmFtZRgBIAEoCRINCgV2YWx1ZRgCIAEoCRJRCgl2YWx1ZUZyb20YAyABKAsyPi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuVmFsdWVGcm9tIrQBCg5BdXRoZW50aWNhdGlvbhJPCgVzaWd2NBgBIAEoCzJALmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5TaWd2NENvbmZpZxJRCgZvYXV0aDIYAiABKAsyQS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuT0F1dGgyQ29uZmlnIo8BChBDbG91ZFdhdGNoTWV0cmljEhAKCGludGVydmFsGAEgASgJEmkKEW1ldHJpY0RhdGFRdWVyaWVzGAIgAygLMk4uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkNsb3VkV2F0Y2hNZXRyaWNEYXRhUXVlcnki/wEKGUNsb3VkV2F0Y2hNZXRyaWNEYXRhUXVlcnkSCgoCaWQYASABKAkSEgoKZXhwcmVzc2lvbhgCIAEoCRINCgVsYWJlbBgDIAEoCRJdCgptZXRyaWNTdGF0GAQgASgLMkkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkNsb3VkV2F0Y2hNZXRyaWNTdGF0EkAKBnBlcmlvZBgFIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLnV0aWwuaW50c3RyLkludE9yU3RyaW5nEhIKCnJldHVybkRhdGEYBiABKAgi1QEKFENsb3VkV2F0Y2hNZXRyaWNTdGF0El8KBm1ldHJpYxgBIAEoCzJPLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5DbG91ZFdhdGNoTWV0cmljU3RhdE1ldHJpYxJACgZwZXJpb2QYAiABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy51dGlsLmludHN0ci5JbnRPclN0cmluZxIMCgRzdGF0GAMgASgJEgwKBHVuaXQYBCABKAkisQEKGkNsb3VkV2F0Y2hNZXRyaWNTdGF0TWV0cmljEmwKCmRpbWVuc2lvbnMYASADKAsyWC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQ2xvdWRXYXRjaE1ldHJpY1N0YXRNZXRyaWNEaW1lbnNpb24SEgoKbWV0cmljTmFtZRgCIAEoCRIRCgluYW1lc3BhY2UYAyABKAkiQgojQ2xvdWRXYXRjaE1ldHJpY1N0YXRNZXRyaWNEaW1lbnNpb24SDAoEbmFtZRgBIAEoCRINCgV2YWx1ZRgCIAEoCSK2AQoXQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGUSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJXCgRzcGVjGAIgASgLMkkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGVTcGVjIrwBChtDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZUxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESWwoFaXRlbXMYAiADKAsyTC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQ2x1c3RlckFuYWx5c2lzVGVtcGxhdGUi5wEKDURhdGFkb2dNZXRyaWMSEAoIaW50ZXJ2YWwYASABKAkSDQoFcXVlcnkYAiABKAkSYAoHcXVlcmllcxgDIAMoCzJPLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5EYXRhZG9nTWV0cmljLlF1ZXJpZXNFbnRyeRIPCgdmb3JtdWxhGAQgASgJEhIKCmFwaVZlcnNpb24YBSABKAkaLgoMUXVlcmllc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiHAoGRHJ5UnVuEhIKCm1ldHJpY05hbWUYASABKAkiHQoIRmllbGRSZWYSEQoJZmllbGRQYXRoGAEgASgJIjAKDkdyYXBoaXRlTWV0cmljEg8KB2FkZHJlc3MYASABKAkSDQoFcXVlcnkYAiABKAkiMAoOSW5mbHV4ZGJNZXRyaWMSDwoHcHJvZmlsZRgBIAEoCRINCgVxdWVyeRgCIAEoCSJ7CglKb2JNZXRyaWMSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRIqCgRzcGVjGAIgASgLMhwuazhzLmlvLmFwaS5iYXRjaC52MS5Kb2JTcGVjItYCCg1LYXllbnRhTWV0cmljEg8KB2FkZHJlc3MYASABKAkSEwoLYXBwbGljYXRpb24YAiABKAkSGAoQY2FuYXJ5Q29uZmlnTmFtZRgDIAEoCRIaChJtZXRyaWNzQWNjb3VudE5hbWUYBCABKAkSIAoYY29uZmlndXJhdGlvbkFjY291bnROYW1lGAUgASgJEhoKEnN0b3JhZ2VBY2NvdW50TmFtZRgGIAEoCRJYCgl0aHJlc2hvbGQYByABKAsyRS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuS2F5ZW50YVRocmVzaG9sZBJRCgZzY29wZXMYCCADKAsyQS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuS2F5ZW50YVNjb3BlIs8BCgxLYXllbnRhU2NvcGUSDAoEbmFtZRgBIAEoCRJWCgxjb250cm9sU2NvcGUYAiABKAsyQC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuU2NvcGVEZXRhaWwSWQoPZXhwZXJpbWVudFNjb3BlGAMgASgLMkAuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLlNjb3BlRGV0YWlsIjIKEEtheWVudGFUaHJlc2hvbGQSDAoEcGFzcxgBIAEoAxIQCghtYXJnaW5hbBgCIAEoAyKMAwoLTWVhc3VyZW1lbnQSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRI9CglzdGFydGVkQXQYAyABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRI+CgpmaW5pc2hlZEF0GAQgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSDQoFdmFsdWUYBSABKAkSYAoIbWV0YWRhdGEYBiADKAsyTi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuTWVhc3VyZW1lbnQuTWV0YWRhdGFFbnRyeRI8CghyZXN1bWVBdBgHIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lGi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASI5ChRNZWFzdXJlbWVudFJldGVudGlvbhISCgptZXRyaWNOYW1lGAEgASgJEg0KBWxpbWl0GAIgASgFIvADCgZNZXRyaWMSDAoEbmFtZRgBIAEoCRIQCghpbnRlcnZhbBgCIAEoCRIUCgxpbml0aWFsRGVsYXkYAyABKAkSPwoFY291bnQYBCABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy51dGlsLmludHN0ci5JbnRPclN0cmluZxIYChBzdWNjZXNzQ29uZGl0aW9uGAUgASgJEhgKEGZhaWx1cmVDb25kaXRpb24YBiABKAkSRgoMZmFpbHVyZUxpbWl0GAcgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cudXRpbC5pbnRzdHIuSW50T3JTdHJpbmcSSwoRaW5jb25jbHVzaXZlTGltaXQYCCABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy51dGlsLmludHN0ci5JbnRPclN0cmluZxJPChVjb25zZWN1dGl2ZUVycm9yTGltaXQYCSABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy51dGlsLmludHN0ci5JbnRPclN0cmluZxJVCghwcm92aWRlchgKIAEoCzJDLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5NZXRyaWNQcm92aWRlciLTCAoOTWV0cmljUHJvdmlkZXISWQoKcHJvbWV0aGV1cxgBIAEoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5Qcm9tZXRoZXVzTWV0cmljElMKB2theWVudGEYAiABKAsyQi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuS2F5ZW50YU1ldHJpYxJLCgN3ZWIYAyABKAsyPi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuV2ViTWV0cmljElMKB2RhdGFkb2cYBCABKAsyQi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuRGF0YWRvZ01ldHJpYxJXCgl3YXZlZnJvbnQYBSABKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuV2F2ZWZyb250TWV0cmljElUKCG5ld1JlbGljGAYgASgLMkMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLk5ld1JlbGljTWV0cmljEksKA2pvYhgHIAEoCzI+LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5Kb2JNZXRyaWMSWQoKY2xvdWRXYXRjaBgIIAEoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5DbG91ZFdhdGNoTWV0cmljElUKCGdyYXBoaXRlGAkgASgLMkMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkdyYXBoaXRlTWV0cmljElUKCGluZmx1eGRiGAogASgLMkMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLkluZmx1eGRiTWV0cmljElkKCnNreXdhbGtpbmcYCyABKAsyRS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuU2t5V2Fsa2luZ01ldHJpYxJfCgZwbHVnaW4YDCADKAsyTy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuTWV0cmljUHJvdmlkZXIuUGx1Z2luRW50cnkaLQoLUGx1Z2luRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4ASKqAwoMTWV0cmljUmVzdWx0EgwKBG5hbWUYASABKAkSDQoFcGhhc2UYAiABKAkSVgoMbWVhc3VyZW1lbnRzGAMgAygLMkAuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLk1lYXN1cmVtZW50Eg8KB21lc3NhZ2UYBCABKAkSDQoFY291bnQYBSABKAUSEgoKc3VjY2Vzc2Z1bBgGIAEoBRIOCgZmYWlsZWQYByABKAUSFAoMaW5jb25jbHVzaXZlGAggASgFEg0KBWVycm9yGAkgASgFEhgKEGNvbnNlY3V0aXZlRXJyb3IYCiABKAUSDgoGZHJ5UnVuGAsgASgIEmEKCG1ldGFkYXRhGAwgAygLMk8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLk1ldHJpY1Jlc3VsdC5NZXRhZGF0YUVudHJ5Gi8KDU1ldGFkYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIwCg5OZXdSZWxpY01ldHJpYxIPCgdwcm9maWxlGAEgASgJEg0KBXF1ZXJ5GAIgASgJIlgKDE9BdXRoMkNvbmZpZxIQCgh0b2tlblVybBgBIAEoCRIQCghjbGllbnRJZBgCIAEoCRIUCgxjbGllbnRTZWNyZXQYAyABKAkSDgoGc2NvcGVzGAQgAygJIokCChBQcm9tZXRoZXVzTWV0cmljEg8KB2FkZHJlc3MYASABKAkSDQoFcXVlcnkYAiABKAkSWwoOYXV0aGVudGljYXRpb24YAyABKAsyQy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkuc3R1YnMucm9sbG91dHMudjFhbHBoYTEuQXV0aGVudGljYXRpb24SDwoHdGltZW91dBgEIAEoAxIQCghpbnNlY3VyZRgFIAEoCBJVCgdoZWFkZXJzGAYgAygLMkQuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLldlYk1ldHJpY0hlYWRlciJkCgpSdW5TdW1tYXJ5Eg0KBWNvdW50GAEgASgFEhIKCnN1Y2Nlc3NmdWwYAiABKAUSDgoGZmFpbGVkGAMgASgFEhQKDGluY29uY2x1c2l2ZRgEIAEoBRINCgVlcnJvchgFIAEoBSJWCgtTY29wZURldGFpbBINCgVzY29wZRgBIAEoCRIOCgZyZWdpb24YAiABKAkSDAoEc3RlcBgDIAEoAxINCgVzdGFydBgEIAEoCRILCgNlbmQYBSABKAkiKQoMU2VjcmV0S2V5UmVmEgwKBG5hbWUYASABKAkSCwoDa2V5GAIgASgJIj8KC1NpZ3Y0Q29uZmlnEg4KBnJlZ2lvbhgBIAEoCRIPCgdwcm9maWxlGAIgASgJEg8KB3JvbGVBcm4YAyABKAkiRAoQU2t5V2Fsa2luZ01ldHJpYxIPCgdhZGRyZXNzGAEgASgJEg0KBXF1ZXJ5GAIgASgJEhAKCGludGVydmFsGAMgASgJIrUBCglWYWx1ZUZyb20SVwoMc2VjcmV0S2V5UmVmGAEgASgLMkEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExLlNlY3JldEtleVJlZhJPCghmaWVsZFJlZhgCIAEoCzI9LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5GaWVsZFJlZiIxCg9XYXZlZnJvbnRNZXRyaWMSDwoHYWRkcmVzcxgBIAEoCRINCgVxdWVyeRgCIAEoCSK4AgoJV2ViTWV0cmljEg4KBm1ldGhvZBgBIAEoCRILCgN1cmwYAiABKAkSVQoHaGVhZGVycxgDIAMoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5XZWJNZXRyaWNIZWFkZXISDAoEYm9keRgEIAEoCRIWCg50aW1lb3V0U2Vjb25kcxgFIAEoAxIQCghqc29uUGF0aBgGIAEoCRIQCghpbnNlY3VyZRgHIAEoCBIQCghqc29uQm9keRgIIAEoDBJbCg5hdXRoZW50aWNhdGlvbhgJIAEoCzJDLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS5zdHVicy5yb2xsb3V0cy52MWFscGhhMS5BdXRoZW50aWNhdGlvbiItCg9XZWJNZXRyaWNIZWFkZXISCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJQvUCCjdjb20uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnN0dWJzLnJvbGxvdXRzLnYxYWxwaGExQg5HZW5lcmF0ZWRQcm90b1ABWjNnaXRodWIuY29tL2FrdWl0eS9rYXJnby9hcGkvc3R1YnMvcm9sbG91dHMvdjFhbHBoYTGiAgdHQ0FLQVNSqgIzR2l0aHViLkNvbS5Ba3VpdHkuS2FyZ28uQXBpLlN0dWJzLlJvbGxvdXRzLlYxYWxwaGExygIzR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFN0dWJzXFJvbGxvdXRzXFYxYWxwaGEx4gI/R2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFN0dWJzXFJvbGxvdXRzXFYxYWxwaGExXEdQQk1ldGFkYXRh6gI6R2l0aHViOjpDb206OkFrdWl0eTo6S2FyZ286OkFwaTo6U3R1YnM6OlJvbGxvdXRzOjpWMWFscGhhMQ", [file_k8s_io_api_batch_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, file_k8s_io_apimachinery_pkg_util_intstr_generated]);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun
+ */
+export type AnalysisRun = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
+   */
+  metadata?: ObjectMeta;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunSpec spec = 2;
+   */
+  spec?: AnalysisRunSpec;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunStatus status = 3;
+   */
+  status?: AnalysisRunStatus;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun.
+ * Use `create(AnalysisRunSchema)` to create a new message.
+ */
+export const AnalysisRunSchema: GenMessage<AnalysisRun> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 0);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunList
+ */
+export type AnalysisRunList = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunList"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
+   */
+  metadata?: ListMeta;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRun items = 2;
+   */
+  items: AnalysisRun[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunList.
+ * Use `create(AnalysisRunListSchema)` to create a new message.
+ */
+export const AnalysisRunListSchema: GenMessage<AnalysisRunList> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 1);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunSpec
+ */
+export type AnalysisRunSpec = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunSpec"> & {
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Metric metrics = 1;
+   */
+  metrics: Metric[];
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Argument args = 2;
+   */
+  args: Argument[];
+
+  /**
+   * @generated from field: optional bool terminate = 3;
+   */
+  terminate: boolean;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DryRun dryRun = 4;
+   */
+  dryRun: DryRun[];
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MeasurementRetention measurementRetention = 5;
+   */
+  measurementRetention: MeasurementRetention[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunSpec.
+ * Use `create(AnalysisRunSpecSchema)` to create a new message.
+ */
+export const AnalysisRunSpecSchema: GenMessage<AnalysisRunSpec> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 2);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunStatus
+ */
+export type AnalysisRunStatus = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunStatus"> & {
+  /**
+   * @generated from field: optional string phase = 1;
+   */
+  phase: string;
+
+  /**
+   * @generated from field: optional string message = 2;
+   */
+  message: string;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricResult metricResults = 3;
+   */
+  metricResults: MetricResult[];
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 4;
+   */
+  startedAt?: Time;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.RunSummary runSummary = 5;
+   */
+  runSummary?: RunSummary;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.RunSummary dryRunSummary = 6;
+   */
+  dryRunSummary?: RunSummary;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisRunStatus.
+ * Use `create(AnalysisRunStatusSchema)` to create a new message.
+ */
+export const AnalysisRunStatusSchema: GenMessage<AnalysisRunStatus> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 3);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate
+ */
+export type AnalysisTemplate = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
+   */
+  metadata?: ObjectMeta;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateSpec spec = 2;
+   */
+  spec?: AnalysisTemplateSpec;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate.
+ * Use `create(AnalysisTemplateSchema)` to create a new message.
+ */
+export const AnalysisTemplateSchema: GenMessage<AnalysisTemplate> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 4);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateList
+ */
+export type AnalysisTemplateList = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateList"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
+   */
+  metadata?: ListMeta;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplate items = 2;
+   */
+  items: AnalysisTemplate[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateList.
+ * Use `create(AnalysisTemplateListSchema)` to create a new message.
+ */
+export const AnalysisTemplateListSchema: GenMessage<AnalysisTemplateList> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 5);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateSpec
+ */
+export type AnalysisTemplateSpec = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateSpec"> & {
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Metric metrics = 1;
+   */
+  metrics: Metric[];
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Argument args = 2;
+   */
+  args: Argument[];
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DryRun dryRun = 3;
+   */
+  dryRun: DryRun[];
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MeasurementRetention measurementRetention = 4;
+   */
+  measurementRetention: MeasurementRetention[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateSpec.
+ * Use `create(AnalysisTemplateSpecSchema)` to create a new message.
+ */
+export const AnalysisTemplateSpecSchema: GenMessage<AnalysisTemplateSpec> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 6);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Argument
+ */
+export type Argument = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Argument"> & {
+  /**
+   * @generated from field: optional string name = 1;
+   */
+  name: string;
+
+  /**
+   * @generated from field: optional string value = 2;
+   */
+  value: string;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ValueFrom valueFrom = 3;
+   */
+  valueFrom?: ValueFrom;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Argument.
+ * Use `create(ArgumentSchema)` to create a new message.
+ */
+export const ArgumentSchema: GenMessage<Argument> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 7);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Authentication
+ */
+export type Authentication = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Authentication"> & {
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Sigv4Config sigv4 = 1;
+   */
+  sigv4?: Sigv4Config;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.OAuth2Config oauth2 = 2;
+   */
+  oauth2?: OAuth2Config;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Authentication.
+ * Use `create(AuthenticationSchema)` to create a new message.
+ */
+export const AuthenticationSchema: GenMessage<Authentication> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 8);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetric
+ */
+export type CloudWatchMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetric"> & {
+  /**
+   * @generated from field: optional string interval = 1;
+   */
+  interval: string;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricDataQuery metricDataQueries = 2;
+   */
+  metricDataQueries: CloudWatchMetricDataQuery[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetric.
+ * Use `create(CloudWatchMetricSchema)` to create a new message.
+ */
+export const CloudWatchMetricSchema: GenMessage<CloudWatchMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 9);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricDataQuery
+ */
+export type CloudWatchMetricDataQuery = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricDataQuery"> & {
+  /**
+   * @generated from field: optional string id = 1;
+   */
+  id: string;
+
+  /**
+   * @generated from field: optional string expression = 2;
+   */
+  expression: string;
+
+  /**
+   * @generated from field: optional string label = 3;
+   */
+  label: string;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStat metricStat = 4;
+   */
+  metricStat?: CloudWatchMetricStat;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString period = 5;
+   */
+  period?: IntOrString;
+
+  /**
+   * @generated from field: optional bool returnData = 6;
+   */
+  returnData: boolean;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricDataQuery.
+ * Use `create(CloudWatchMetricDataQuerySchema)` to create a new message.
+ */
+export const CloudWatchMetricDataQuerySchema: GenMessage<CloudWatchMetricDataQuery> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 10);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStat
+ */
+export type CloudWatchMetricStat = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStat"> & {
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetric metric = 1;
+   */
+  metric?: CloudWatchMetricStatMetric;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString period = 2;
+   */
+  period?: IntOrString;
+
+  /**
+   * @generated from field: optional string stat = 3;
+   */
+  stat: string;
+
+  /**
+   * @generated from field: optional string unit = 4;
+   */
+  unit: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStat.
+ * Use `create(CloudWatchMetricStatSchema)` to create a new message.
+ */
+export const CloudWatchMetricStatSchema: GenMessage<CloudWatchMetricStat> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 11);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetric
+ */
+export type CloudWatchMetricStatMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetric"> & {
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetricDimension dimensions = 1;
+   */
+  dimensions: CloudWatchMetricStatMetricDimension[];
+
+  /**
+   * @generated from field: optional string metricName = 2;
+   */
+  metricName: string;
+
+  /**
+   * @generated from field: optional string namespace = 3;
+   */
+  namespace: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetric.
+ * Use `create(CloudWatchMetricStatMetricSchema)` to create a new message.
+ */
+export const CloudWatchMetricStatMetricSchema: GenMessage<CloudWatchMetricStatMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 12);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetricDimension
+ */
+export type CloudWatchMetricStatMetricDimension = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetricDimension"> & {
+  /**
+   * @generated from field: optional string name = 1;
+   */
+  name: string;
+
+  /**
+   * @generated from field: optional string value = 2;
+   */
+  value: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetricStatMetricDimension.
+ * Use `create(CloudWatchMetricStatMetricDimensionSchema)` to create a new message.
+ */
+export const CloudWatchMetricStatMetricDimensionSchema: GenMessage<CloudWatchMetricStatMetricDimension> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 13);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate
+ */
+export type ClusterAnalysisTemplate = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
+   */
+  metadata?: ObjectMeta;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.AnalysisTemplateSpec spec = 2;
+   */
+  spec?: AnalysisTemplateSpec;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate.
+ * Use `create(ClusterAnalysisTemplateSchema)` to create a new message.
+ */
+export const ClusterAnalysisTemplateSchema: GenMessage<ClusterAnalysisTemplate> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 14);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplateList
+ */
+export type ClusterAnalysisTemplateList = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplateList"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
+   */
+  metadata?: ListMeta;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplate items = 2;
+   */
+  items: ClusterAnalysisTemplate[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ClusterAnalysisTemplateList.
+ * Use `create(ClusterAnalysisTemplateListSchema)` to create a new message.
+ */
+export const ClusterAnalysisTemplateListSchema: GenMessage<ClusterAnalysisTemplateList> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 15);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DatadogMetric
+ */
+export type DatadogMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DatadogMetric"> & {
+  /**
+   * @generated from field: optional string interval = 1;
+   */
+  interval: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+
+  /**
+   * @generated from field: map<string, string> queries = 3;
+   */
+  queries: { [key: string]: string };
+
+  /**
+   * @generated from field: optional string formula = 4;
+   */
+  formula: string;
+
+  /**
+   * @generated from field: optional string apiVersion = 5;
+   */
+  apiVersion: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DatadogMetric.
+ * Use `create(DatadogMetricSchema)` to create a new message.
+ */
+export const DatadogMetricSchema: GenMessage<DatadogMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 16);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DryRun
+ */
+export type DryRun = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DryRun"> & {
+  /**
+   * @generated from field: optional string metricName = 1;
+   */
+  metricName: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DryRun.
+ * Use `create(DryRunSchema)` to create a new message.
+ */
+export const DryRunSchema: GenMessage<DryRun> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 17);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.FieldRef
+ */
+export type FieldRef = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.FieldRef"> & {
+  /**
+   * Required: Path of the field to select in the specified API version
+   *
+   * @generated from field: optional string fieldPath = 1;
+   */
+  fieldPath: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.FieldRef.
+ * Use `create(FieldRefSchema)` to create a new message.
+ */
+export const FieldRefSchema: GenMessage<FieldRef> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 18);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.GraphiteMetric
+ */
+export type GraphiteMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.GraphiteMetric"> & {
+  /**
+   * @generated from field: optional string address = 1;
+   */
+  address: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.GraphiteMetric.
+ * Use `create(GraphiteMetricSchema)` to create a new message.
+ */
+export const GraphiteMetricSchema: GenMessage<GraphiteMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 19);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.InfluxdbMetric
+ */
+export type InfluxdbMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.InfluxdbMetric"> & {
+  /**
+   * @generated from field: optional string profile = 1;
+   */
+  profile: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.InfluxdbMetric.
+ * Use `create(InfluxdbMetricSchema)` to create a new message.
+ */
+export const InfluxdbMetricSchema: GenMessage<InfluxdbMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 20);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.JobMetric
+ */
+export type JobMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.JobMetric"> & {
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
+   */
+  metadata?: ObjectMeta;
+
+  /**
+   * @generated from field: optional k8s.io.api.batch.v1.JobSpec spec = 2;
+   */
+  spec?: JobSpec;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.JobMetric.
+ * Use `create(JobMetricSchema)` to create a new message.
+ */
+export const JobMetricSchema: GenMessage<JobMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 21);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaMetric
+ */
+export type KayentaMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaMetric"> & {
+  /**
+   * @generated from field: optional string address = 1;
+   */
+  address: string;
+
+  /**
+   * @generated from field: optional string application = 2;
+   */
+  application: string;
+
+  /**
+   * @generated from field: optional string canaryConfigName = 3;
+   */
+  canaryConfigName: string;
+
+  /**
+   * @generated from field: optional string metricsAccountName = 4;
+   */
+  metricsAccountName: string;
+
+  /**
+   * @generated from field: optional string configurationAccountName = 5;
+   */
+  configurationAccountName: string;
+
+  /**
+   * @generated from field: optional string storageAccountName = 6;
+   */
+  storageAccountName: string;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaThreshold threshold = 7;
+   */
+  threshold?: KayentaThreshold;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaScope scopes = 8;
+   */
+  scopes: KayentaScope[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaMetric.
+ * Use `create(KayentaMetricSchema)` to create a new message.
+ */
+export const KayentaMetricSchema: GenMessage<KayentaMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 22);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaScope
+ */
+export type KayentaScope = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaScope"> & {
+  /**
+   * @generated from field: optional string name = 1;
+   */
+  name: string;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ScopeDetail controlScope = 2;
+   */
+  controlScope?: ScopeDetail;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ScopeDetail experimentScope = 3;
+   */
+  experimentScope?: ScopeDetail;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaScope.
+ * Use `create(KayentaScopeSchema)` to create a new message.
+ */
+export const KayentaScopeSchema: GenMessage<KayentaScope> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 23);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaThreshold
+ */
+export type KayentaThreshold = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaThreshold"> & {
+  /**
+   * @generated from field: optional int64 pass = 1;
+   */
+  pass: bigint;
+
+  /**
+   * @generated from field: optional int64 marginal = 2;
+   */
+  marginal: bigint;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaThreshold.
+ * Use `create(KayentaThresholdSchema)` to create a new message.
+ */
+export const KayentaThresholdSchema: GenMessage<KayentaThreshold> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 24);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Measurement
+ */
+export type Measurement = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Measurement"> & {
+  /**
+   * @generated from field: optional string phase = 1;
+   */
+  phase: string;
+
+  /**
+   * @generated from field: optional string message = 2;
+   */
+  message: string;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 3;
+   */
+  startedAt?: Time;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time finishedAt = 4;
+   */
+  finishedAt?: Time;
+
+  /**
+   * @generated from field: optional string value = 5;
+   */
+  value: string;
+
+  /**
+   * @generated from field: map<string, string> metadata = 6;
+   */
+  metadata: { [key: string]: string };
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time resumeAt = 7;
+   */
+  resumeAt?: Time;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Measurement.
+ * Use `create(MeasurementSchema)` to create a new message.
+ */
+export const MeasurementSchema: GenMessage<Measurement> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 25);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MeasurementRetention
+ */
+export type MeasurementRetention = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MeasurementRetention"> & {
+  /**
+   * @generated from field: optional string metricName = 1;
+   */
+  metricName: string;
+
+  /**
+   * @generated from field: optional int32 limit = 2;
+   */
+  limit: number;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MeasurementRetention.
+ * Use `create(MeasurementRetentionSchema)` to create a new message.
+ */
+export const MeasurementRetentionSchema: GenMessage<MeasurementRetention> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 26);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Metric
+ */
+export type Metric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Metric"> & {
+  /**
+   * @generated from field: optional string name = 1;
+   */
+  name: string;
+
+  /**
+   * @generated from field: optional string interval = 2;
+   */
+  interval: string;
+
+  /**
+   * @generated from field: optional string initialDelay = 3;
+   */
+  initialDelay: string;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString count = 4;
+   */
+  count?: IntOrString;
+
+  /**
+   * @generated from field: optional string successCondition = 5;
+   */
+  successCondition: string;
+
+  /**
+   * @generated from field: optional string failureCondition = 6;
+   */
+  failureCondition: string;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString failureLimit = 7;
+   */
+  failureLimit?: IntOrString;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString inconclusiveLimit = 8;
+   */
+  inconclusiveLimit?: IntOrString;
+
+  /**
+   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString consecutiveErrorLimit = 9;
+   */
+  consecutiveErrorLimit?: IntOrString;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricProvider provider = 10;
+   */
+  provider?: MetricProvider;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Metric.
+ * Use `create(MetricSchema)` to create a new message.
+ */
+export const MetricSchema: GenMessage<Metric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 27);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricProvider
+ */
+export type MetricProvider = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricProvider"> & {
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.PrometheusMetric prometheus = 1;
+   */
+  prometheus?: PrometheusMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.KayentaMetric kayenta = 2;
+   */
+  kayenta?: KayentaMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetric web = 3;
+   */
+  web?: WebMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.DatadogMetric datadog = 4;
+   */
+  datadog?: DatadogMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WavefrontMetric wavefront = 5;
+   */
+  wavefront?: WavefrontMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.NewRelicMetric newRelic = 6;
+   */
+  newRelic?: NewRelicMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.JobMetric job = 7;
+   */
+  job?: JobMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.CloudWatchMetric cloudWatch = 8;
+   */
+  cloudWatch?: CloudWatchMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.GraphiteMetric graphite = 9;
+   */
+  graphite?: GraphiteMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.InfluxdbMetric influxdb = 10;
+   */
+  influxdb?: InfluxdbMetric;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SkyWalkingMetric skywalking = 11;
+   */
+  skywalking?: SkyWalkingMetric;
+
+  /**
+   * @generated from field: map<string, bytes> plugin = 12;
+   */
+  plugin: { [key: string]: Uint8Array };
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricProvider.
+ * Use `create(MetricProviderSchema)` to create a new message.
+ */
+export const MetricProviderSchema: GenMessage<MetricProvider> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 28);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricResult
+ */
+export type MetricResult = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricResult"> & {
+  /**
+   * @generated from field: optional string name = 1;
+   */
+  name: string;
+
+  /**
+   * @generated from field: optional string phase = 2;
+   */
+  phase: string;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Measurement measurements = 3;
+   */
+  measurements: Measurement[];
+
+  /**
+   * @generated from field: optional string message = 4;
+   */
+  message: string;
+
+  /**
+   * @generated from field: optional int32 count = 5;
+   */
+  count: number;
+
+  /**
+   * @generated from field: optional int32 successful = 6;
+   */
+  successful: number;
+
+  /**
+   * @generated from field: optional int32 failed = 7;
+   */
+  failed: number;
+
+  /**
+   * @generated from field: optional int32 inconclusive = 8;
+   */
+  inconclusive: number;
+
+  /**
+   * @generated from field: optional int32 error = 9;
+   */
+  error: number;
+
+  /**
+   * @generated from field: optional int32 consecutiveError = 10;
+   */
+  consecutiveError: number;
+
+  /**
+   * @generated from field: optional bool dryRun = 11;
+   */
+  dryRun: boolean;
+
+  /**
+   * @generated from field: map<string, string> metadata = 12;
+   */
+  metadata: { [key: string]: string };
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.MetricResult.
+ * Use `create(MetricResultSchema)` to create a new message.
+ */
+export const MetricResultSchema: GenMessage<MetricResult> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 29);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.NewRelicMetric
+ */
+export type NewRelicMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.NewRelicMetric"> & {
+  /**
+   * @generated from field: optional string profile = 1;
+   */
+  profile: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.NewRelicMetric.
+ * Use `create(NewRelicMetricSchema)` to create a new message.
+ */
+export const NewRelicMetricSchema: GenMessage<NewRelicMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 30);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.OAuth2Config
+ */
+export type OAuth2Config = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.OAuth2Config"> & {
+  /**
+   * @generated from field: optional string tokenUrl = 1;
+   */
+  tokenUrl: string;
+
+  /**
+   * @generated from field: optional string clientId = 2;
+   */
+  clientId: string;
+
+  /**
+   * @generated from field: optional string clientSecret = 3;
+   */
+  clientSecret: string;
+
+  /**
+   * @generated from field: repeated string scopes = 4;
+   */
+  scopes: string[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.OAuth2Config.
+ * Use `create(OAuth2ConfigSchema)` to create a new message.
+ */
+export const OAuth2ConfigSchema: GenMessage<OAuth2Config> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 31);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.PrometheusMetric
+ */
+export type PrometheusMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.PrometheusMetric"> & {
+  /**
+   * @generated from field: optional string address = 1;
+   */
+  address: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Authentication authentication = 3;
+   */
+  authentication?: Authentication;
+
+  /**
+   * @generated from field: optional int64 timeout = 4;
+   */
+  timeout: bigint;
+
+  /**
+   * @generated from field: optional bool insecure = 5;
+   */
+  insecure: boolean;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetricHeader headers = 6;
+   */
+  headers: WebMetricHeader[];
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.PrometheusMetric.
+ * Use `create(PrometheusMetricSchema)` to create a new message.
+ */
+export const PrometheusMetricSchema: GenMessage<PrometheusMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 32);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.RunSummary
+ */
+export type RunSummary = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.RunSummary"> & {
+  /**
+   * @generated from field: optional int32 count = 1;
+   */
+  count: number;
+
+  /**
+   * @generated from field: optional int32 successful = 2;
+   */
+  successful: number;
+
+  /**
+   * @generated from field: optional int32 failed = 3;
+   */
+  failed: number;
+
+  /**
+   * @generated from field: optional int32 inconclusive = 4;
+   */
+  inconclusive: number;
+
+  /**
+   * @generated from field: optional int32 error = 5;
+   */
+  error: number;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.RunSummary.
+ * Use `create(RunSummarySchema)` to create a new message.
+ */
+export const RunSummarySchema: GenMessage<RunSummary> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 33);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ScopeDetail
+ */
+export type ScopeDetail = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ScopeDetail"> & {
+  /**
+   * @generated from field: optional string scope = 1;
+   */
+  scope: string;
+
+  /**
+   * @generated from field: optional string region = 2;
+   */
+  region: string;
+
+  /**
+   * @generated from field: optional int64 step = 3;
+   */
+  step: bigint;
+
+  /**
+   * @generated from field: optional string start = 4;
+   */
+  start: string;
+
+  /**
+   * @generated from field: optional string end = 5;
+   */
+  end: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ScopeDetail.
+ * Use `create(ScopeDetailSchema)` to create a new message.
+ */
+export const ScopeDetailSchema: GenMessage<ScopeDetail> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 34);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SecretKeyRef
+ */
+export type SecretKeyRef = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SecretKeyRef"> & {
+  /**
+   * @generated from field: optional string name = 1;
+   */
+  name: string;
+
+  /**
+   * @generated from field: optional string key = 2;
+   */
+  key: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SecretKeyRef.
+ * Use `create(SecretKeyRefSchema)` to create a new message.
+ */
+export const SecretKeyRefSchema: GenMessage<SecretKeyRef> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 35);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Sigv4Config
+ */
+export type Sigv4Config = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Sigv4Config"> & {
+  /**
+   * @generated from field: optional string region = 1;
+   */
+  region: string;
+
+  /**
+   * @generated from field: optional string profile = 2;
+   */
+  profile: string;
+
+  /**
+   * @generated from field: optional string roleArn = 3;
+   */
+  roleArn: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Sigv4Config.
+ * Use `create(Sigv4ConfigSchema)` to create a new message.
+ */
+export const Sigv4ConfigSchema: GenMessage<Sigv4Config> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 36);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SkyWalkingMetric
+ */
+export type SkyWalkingMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SkyWalkingMetric"> & {
+  /**
+   * @generated from field: optional string address = 1;
+   */
+  address: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+
+  /**
+   * @generated from field: optional string interval = 3;
+   */
+  interval: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SkyWalkingMetric.
+ * Use `create(SkyWalkingMetricSchema)` to create a new message.
+ */
+export const SkyWalkingMetricSchema: GenMessage<SkyWalkingMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 37);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ValueFrom
+ */
+export type ValueFrom = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ValueFrom"> & {
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.SecretKeyRef secretKeyRef = 1;
+   */
+  secretKeyRef?: SecretKeyRef;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.FieldRef fieldRef = 2;
+   */
+  fieldRef?: FieldRef;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.ValueFrom.
+ * Use `create(ValueFromSchema)` to create a new message.
+ */
+export const ValueFromSchema: GenMessage<ValueFrom> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 38);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WavefrontMetric
+ */
+export type WavefrontMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WavefrontMetric"> & {
+  /**
+   * @generated from field: optional string address = 1;
+   */
+  address: string;
+
+  /**
+   * @generated from field: optional string query = 2;
+   */
+  query: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WavefrontMetric.
+ * Use `create(WavefrontMetricSchema)` to create a new message.
+ */
+export const WavefrontMetricSchema: GenMessage<WavefrontMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 39);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetric
+ */
+export type WebMetric = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetric"> & {
+  /**
+   * @generated from field: optional string method = 1;
+   */
+  method: string;
+
+  /**
+   * URL is the address of the web metric
+   *
+   * @generated from field: optional string url = 2;
+   */
+  url: string;
+
+  /**
+   * @generated from field: repeated github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetricHeader headers = 3;
+   */
+  headers: WebMetricHeader[];
+
+  /**
+   * @generated from field: optional string body = 4;
+   */
+  body: string;
+
+  /**
+   * @generated from field: optional int64 timeoutSeconds = 5;
+   */
+  timeoutSeconds: bigint;
+
+  /**
+   * @generated from field: optional string jsonPath = 6;
+   */
+  jsonPath: string;
+
+  /**
+   * @generated from field: optional bool insecure = 7;
+   */
+  insecure: boolean;
+
+  /**
+   * @generated from field: optional bytes jsonBody = 8;
+   */
+  jsonBody: Uint8Array;
+
+  /**
+   * @generated from field: optional github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.Authentication authentication = 9;
+   */
+  authentication?: Authentication;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetric.
+ * Use `create(WebMetricSchema)` to create a new message.
+ */
+export const WebMetricSchema: GenMessage<WebMetric> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 40);
+
+/**
+ * @generated from message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetricHeader
+ */
+export type WebMetricHeader = Message<"github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetricHeader"> & {
+  /**
+   * @generated from field: optional string key = 1;
+   */
+  key: string;
+
+  /**
+   * @generated from field: optional string value = 2;
+   */
+  value: string;
+};
+
+/**
+ * Describes the message github.com.akuity.kargo.api.stubs.rollouts.v1alpha1.WebMetricHeader.
+ * Use `create(WebMetricHeaderSchema)` to create a new message.
+ */
+export const WebMetricHeaderSchema: GenMessage<WebMetricHeader> = /*@__PURE__*/
+  messageDesc(file_api_stubs_rollouts_v1alpha1_generated, 41);
+
diff --git a/ui/src/gen/v1alpha1/generated_pb.ts b/ui/src/gen/api/v1alpha1/generated_pb.ts
similarity index 83%
rename from ui/src/gen/v1alpha1/generated_pb.ts
rename to ui/src/gen/api/v1alpha1/generated_pb.ts
index eccf387e..d3d8adf0 100644
--- a/ui/src/gen/v1alpha1/generated_pb.ts
+++ b/ui/src/gen/api/v1alpha1/generated_pb.ts
@@ -1,24 +1,24 @@
 // This file was autogenerated by go-to-protobuf. Do not edit it manually!
 
 // @generated by protoc-gen-es v2.2.2 with parameter "target=ts"
-// @generated from file v1alpha1/generated.proto (package github.com.akuity.kargo.api.v1alpha1, syntax proto2)
+// @generated from file api/v1alpha1/generated.proto (package github.com.akuity.kargo.api.v1alpha1, syntax proto2)
 /* eslint-disable */
 
 import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
 import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
-import type { JSON } from "../k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated_pb";
-import { file_k8s_io_apiextensions_apiserver_pkg_apis_apiextensions_v1_generated } from "../k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated_pb";
-import type { Condition, Duration, ListMeta, ObjectMeta, Time } from "../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
-import { file_k8s_io_apimachinery_pkg_apis_meta_v1_generated } from "../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
-import { file_k8s_io_apimachinery_pkg_runtime_generated } from "../k8s.io/apimachinery/pkg/runtime/generated_pb";
-import { file_k8s_io_apimachinery_pkg_runtime_schema_generated } from "../k8s.io/apimachinery/pkg/runtime/schema/generated_pb";
+import type { JSON } from "../../k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated_pb";
+import { file_k8s_io_apiextensions_apiserver_pkg_apis_apiextensions_v1_generated } from "../../k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated_pb";
+import type { Condition, Duration, ListMeta, ObjectMeta, Time } from "../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
+import { file_k8s_io_apimachinery_pkg_apis_meta_v1_generated } from "../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
+import { file_k8s_io_apimachinery_pkg_runtime_generated } from "../../k8s.io/apimachinery/pkg/runtime/generated_pb";
+import { file_k8s_io_apimachinery_pkg_runtime_schema_generated } from "../../k8s.io/apimachinery/pkg/runtime/schema/generated_pb";
 import type { Message } from "@bufbuild/protobuf";
 
 /**
- * Describes the file v1alpha1/generated.proto.
+ * Describes the file api/v1alpha1/generated.proto.
  */
-export const file_v1alpha1_generated: GenFile = /*@__PURE__*/
-  fileDesc("Chh2MWFscGhhMS9nZW5lcmF0ZWQucHJvdG8SJGdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMSIyChNBbmFseXNpc1J1bkFyZ3VtZW50EgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAkisAIKE0FuYWx5c2lzUnVuTWV0YWRhdGESVQoGbGFiZWxzGAEgAygLMkUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuTWV0YWRhdGEuTGFiZWxzRW50cnkSXwoLYW5ub3RhdGlvbnMYAiADKAsySi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQW5hbHlzaXNSdW5NZXRhZGF0YS5Bbm5vdGF0aW9uc0VudHJ5Gi0KC0xhYmVsc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaMgoQQW5ub3RhdGlvbnNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIkYKFEFuYWx5c2lzUnVuUmVmZXJlbmNlEhEKCW5hbWVzcGFjZRgBIAEoCRIMCgRuYW1lGAIgASgJEg0KBXBoYXNlGAMgASgJIjcKGUFuYWx5c2lzVGVtcGxhdGVSZWZlcmVuY2USDAoEbmFtZRgBIAEoCRIMCgRraW5kGAIgASgJIk8KDUFwcHJvdmVkU3RhZ2USPgoKYXBwcm92ZWRBdBgBIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIjgKFUFyZ29DREFwcEhlYWx0aFN0YXR1cxIOCgZzdGF0dXMYASABKAkSDwoHbWVzc2FnZRgCIAEoCSLUAQoPQXJnb0NEQXBwU3RhdHVzEhEKCW5hbWVzcGFjZRgBIAEoCRIMCgRuYW1lGAIgASgJElEKDGhlYWx0aFN0YXR1cxgDIAEoCzI7LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BcmdvQ0RBcHBIZWFsdGhTdGF0dXMSTQoKc3luY1N0YXR1cxgEIAEoCzI5LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BcmdvQ0RBcHBTeW5jU3RhdHVzIkoKE0FyZ29DREFwcFN5bmNTdGF0dXMSDgoGc3RhdHVzGAEgASgJEhAKCHJldmlzaW9uGAIgASgJEhEKCXJldmlzaW9ucxgDIAMoCSI3CgVDaGFydBIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoCSJhChRDaGFydERpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSGAoQc2VtdmVyQ29uc3RyYWludBgDIAEoCRIQCgh2ZXJzaW9ucxgEIAMoCSJkChFDaGFydFN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEgwKBG5hbWUYAiABKAkSGAoQc2VtdmVyQ29uc3RyYWludBgDIAEoCRIWCg5kaXNjb3ZlcnlMaW1pdBgEIAEoBSKhAQoUQ2x1c3RlclByb21vdGlvblRhc2sSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJFCgRzcGVjGAIgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2tTcGVjIqcBChhDbHVzdGVyUHJvbW90aW9uVGFza0xpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESSQoFaXRlbXMYAiADKAsyOi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2x1c3RlclByb21vdGlvblRhc2siSQoMQ3VycmVudFN0YWdlEjkKBXNpbmNlGAEgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUitgIKE0Rpc2NvdmVyZWRBcnRpZmFjdHMSQAoMZGlzY292ZXJlZEF0GAQgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSRQoDZ2l0GAEgAygLMjguZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdERpc2NvdmVyeVJlc3VsdBJKCgZpbWFnZXMYAiADKAsyOi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2VEaXNjb3ZlcnlSZXN1bHQSSgoGY2hhcnRzGAMgAygLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0RGlzY292ZXJ5UmVzdWx0IrABChBEaXNjb3ZlcmVkQ29tbWl0EgoKAmlkGAEgASgJEg4KBmJyYW5jaBgCIAEoCRILCgN0YWcYAyABKAkSDwoHc3ViamVjdBgEIAEoCRIOCgZhdXRob3IYBSABKAkSEQoJY29tbWl0dGVyGAYgASgJEj8KC2NyZWF0b3JEYXRlGAcgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUiigEKGERpc2NvdmVyZWRJbWFnZVJlZmVyZW5jZRILCgN0YWcYASABKAkSDgoGZGlnZXN0GAIgASgJEhIKCmdpdFJlcG9VUkwYAyABKAkSPQoJY3JlYXRlZEF0GAQgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUiogMKB0ZyZWlnaHQSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRINCgVhbGlhcxgHIAEoCRJDCgZvcmlnaW4YCSABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodE9yaWdpbhJACgdjb21taXRzGAMgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdENvbW1pdBI7CgZpbWFnZXMYBCADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2USOwoGY2hhcnRzGAUgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0EkMKBnN0YXR1cxgGIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzIq0CChFGcmVpZ2h0Q29sbGVjdGlvbhIKCgJpZBgDIAEoCRJRCgVpdGVtcxgBIAMoCzJCLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0Q29sbGVjdGlvbi5JdGVtc0VudHJ5ElMKE3ZlcmlmaWNhdGlvbkhpc3RvcnkYAiADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuVmVyaWZpY2F0aW9uSW5mbxpkCgpJdGVtc0VudHJ5EgsKA2tleRgBIAEoCRJFCgV2YWx1ZRgCIAEoCzI2LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0UmVmZXJlbmNlOgI4ASKNAQoLRnJlaWdodExpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESPAoFaXRlbXMYAiADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodCIrCg1GcmVpZ2h0T3JpZ2luEgwKBGtpbmQYASABKAkSDAoEbmFtZRgCIAEoCSKhAgoQRnJlaWdodFJlZmVyZW5jZRIMCgRuYW1lGAEgASgJEkMKBm9yaWdpbhgIIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0T3JpZ2luEkAKB2NvbW1pdHMYAiADKAsyLy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuR2l0Q29tbWl0EjsKBmltYWdlcxgDIAMoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5JbWFnZRI7CgZjaGFydHMYBCADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2hhcnQinAEKDkZyZWlnaHRSZXF1ZXN0EkMKBm9yaWdpbhgBIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0T3JpZ2luEkUKB3NvdXJjZXMYAiABKAsyNC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFNvdXJjZXMimAEKDkZyZWlnaHRTb3VyY2VzEg4KBmRpcmVjdBgBIAEoCBIOCgZzdGFnZXMYAiADKAkSSAoQcmVxdWlyZWRTb2FrVGltZRgDIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5EdXJhdGlvbhIcChRhdmFpbGFiaWxpdHlTdHJhdGVneRgEIAEoCSLXBAoNRnJlaWdodFN0YXR1cxJZCgtjdXJyZW50bHlJbhgDIAMoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzLkN1cnJlbnRseUluRW50cnkSVwoKdmVyaWZpZWRJbhgBIAMoCzJDLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzLlZlcmlmaWVkSW5FbnRyeRJZCgthcHByb3ZlZEZvchgCIAMoCzJELmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0U3RhdHVzLkFwcHJvdmVkRm9yRW50cnkaZgoQQ3VycmVudGx5SW5FbnRyeRILCgNrZXkYASABKAkSQQoFdmFsdWUYAiABKAsyMi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ3VycmVudFN0YWdlOgI4ARpmCg9WZXJpZmllZEluRW50cnkSCwoDa2V5GAEgASgJEkIKBXZhbHVlGAIgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlZlcmlmaWVkU3RhZ2U6AjgBGmcKEEFwcHJvdmVkRm9yRW50cnkSCwoDa2V5GAEgASgJEkIKBXZhbHVlGAIgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFwcHJvdmVkU3RhZ2U6AjgBInkKCUdpdENvbW1pdBIPCgdyZXBvVVJMGAEgASgJEgoKAmlkGAIgASgJEg4KBmJyYW5jaBgDIAEoCRILCgN0YWcYBCABKAkSDwoHbWVzc2FnZRgGIAEoCRIOCgZhdXRob3IYByABKAkSEQoJY29tbWl0dGVyGAggASgJIm4KEkdpdERpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEkcKB2NvbW1pdHMYAiADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRGlzY292ZXJlZENvbW1pdCKOAgoPR2l0U3Vic2NyaXB0aW9uEg8KB3JlcG9VUkwYASABKAkSHwoXY29tbWl0U2VsZWN0aW9uU3RyYXRlZ3kYAiABKAkSDgoGYnJhbmNoGAMgASgJEhUKDXN0cmljdFNlbXZlcnMYCyABKAgSGAoQc2VtdmVyQ29uc3RyYWludBgEIAEoCRIRCglhbGxvd1RhZ3MYBSABKAkSEgoKaWdub3JlVGFncxgGIAMoCRIdChVpbnNlY3VyZVNraXBUTFNWZXJpZnkYByABKAgSFAoMaW5jbHVkZVBhdGhzGAggAygJEhQKDGV4Y2x1ZGVQYXRocxgJIAMoCRIWCg5kaXNjb3ZlcnlMaW1pdBgKIAEoBSLIAQoGSGVhbHRoEg4KBnN0YXR1cxgBIAEoCRIOCgZpc3N1ZXMYAiADKAkSTgoGY29uZmlnGAQgASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPThJOCgZvdXRwdXQYBSABKAsyPi5rOHMuaW8uYXBpZXh0ZW5zaW9uc19hcGlzZXJ2ZXIucGtnLmFwaXMuYXBpZXh0ZW5zaW9ucy52MS5KU09OIm8KD0hlYWx0aENoZWNrU3RlcBIMCgR1c2VzGAEgASgJEk4KBmNvbmZpZxgCIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04iSQoFSW1hZ2USDwoHcmVwb1VSTBgBIAEoCRISCgpnaXRSZXBvVVJMGAIgASgJEgsKA3RhZxgDIAEoCRIOCgZkaWdlc3QYBCABKAkijQEKFEltYWdlRGlzY292ZXJ5UmVzdWx0Eg8KB3JlcG9VUkwYASABKAkSEAoIcGxhdGZvcm0YAiABKAkSUgoKcmVmZXJlbmNlcxgDIAMoCzI+LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5EaXNjb3ZlcmVkSW1hZ2VSZWZlcmVuY2Ui+QEKEUltYWdlU3Vic2NyaXB0aW9uEg8KB3JlcG9VUkwYASABKAkSEgoKZ2l0UmVwb1VSTBgCIAEoCRIeChZpbWFnZVNlbGVjdGlvblN0cmF0ZWd5GAMgASgJEhUKDXN0cmljdFNlbXZlcnMYCiABKAgSGAoQc2VtdmVyQ29uc3RyYWludBgEIAEoCRIRCglhbGxvd1RhZ3MYBSABKAkSEgoKaWdub3JlVGFncxgGIAMoCRIQCghwbGF0Zm9ybRgHIAEoCRIdChVpbnNlY3VyZVNraXBUTFNWZXJpZnkYCCABKAgSFgoOZGlzY292ZXJ5TGltaXQYCSABKAUi0wEKB1Byb2plY3QSQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRI/CgRzcGVjGAIgASgLMjEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb2plY3RTcGVjEkMKBnN0YXR1cxgDIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0U3RhdHVzIo0BCgtQcm9qZWN0TGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRI8CgVpdGVtcxgCIAMoCzItLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0Il8KC1Byb2plY3RTcGVjElAKEXByb21vdGlvblBvbGljaWVzGAEgAygLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblBvbGljeSJ0Cg1Qcm9qZWN0U3RhdHVzEkMKCmNvbmRpdGlvbnMYAyADKAsyLy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuQ29uZGl0aW9uEg0KBXBoYXNlGAEgASgJEg8KB21lc3NhZ2UYAiABKAki2QEKCVByb21vdGlvbhJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkEKBHNwZWMYAiABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3BlYxJFCgZzdGF0dXMYAyABKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RhdHVzIpEBCg1Qcm9tb3Rpb25MaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEj4KBWl0ZW1zGAIgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvbiI+Cg9Qcm9tb3Rpb25Qb2xpY3kSDQoFc3RhZ2UYASABKAkSHAoUYXV0b1Byb21vdGlvbkVuYWJsZWQYAiABKAgi8gEKElByb21vdGlvblJlZmVyZW5jZRIMCgRuYW1lGAEgASgJEkcKB2ZyZWlnaHQYAiABKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlZmVyZW5jZRJFCgZzdGF0dXMYAyABKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RhdHVzEj4KCmZpbmlzaGVkQXQYBCABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSK6AQoNUHJvbW90aW9uU3BlYxINCgVzdGFnZRgBIAEoCRIPCgdmcmVpZ2h0GAIgASgJEkUKBHZhcnMYBCADKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVmFyaWFibGUSQgoFc3RlcHMYAyADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCK3BAoPUHJvbW90aW9uU3RhdHVzEhoKEmxhc3RIYW5kbGVkUmVmcmVzaBgEIAEoCRINCgVwaGFzZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEkcKB2ZyZWlnaHQYBSABKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlZmVyZW5jZRJSChFmcmVpZ2h0Q29sbGVjdGlvbhgHIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0Q29sbGVjdGlvbhJLCgxoZWFsdGhDaGVja3MYCCADKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSGVhbHRoQ2hlY2tTdGVwEj4KCmZpbmlzaGVkQXQYBiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRITCgtjdXJyZW50U3RlcBgJIAEoAxJaChVzdGVwRXhlY3V0aW9uTWV0YWRhdGEYCyADKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RlcEV4ZWN1dGlvbk1ldGFkYXRhEk0KBXN0YXRlGAogASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPTiLhAgoNUHJvbW90aW9uU3RlcBIMCgR1c2VzGAEgASgJEkoKBHRhc2sYBSABKAsyPC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFza1JlZmVyZW5jZRIKCgJhcxgCIAEoCRIKCgJpZhgHIAEoCRJHCgVyZXRyeRgEIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGVwUmV0cnkSRQoEdmFycxgGIAMoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25WYXJpYWJsZRJOCgZjb25maWcYAyABKAsyPi5rOHMuaW8uYXBpZXh0ZW5zaW9uc19hcGlzZXJ2ZXIucGtnLmFwaXMuYXBpZXh0ZW5zaW9ucy52MS5KU09OIm0KElByb21vdGlvblN0ZXBSZXRyeRI/Cgd0aW1lb3V0GAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkR1cmF0aW9uEhYKDmVycm9yVGhyZXNob2xkGAIgASgNIpoBCg1Qcm9tb3Rpb25UYXNrEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESRQoEc3BlYxgCIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UYXNrU3BlYyKZAQoRUHJvbW90aW9uVGFza0xpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESQgoFaXRlbXMYAiADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFzayI0ChZQcm9tb3Rpb25UYXNrUmVmZXJlbmNlEgwKBG5hbWUYASABKAkSDAoEa2luZBgCIAEoCSKeAQoRUHJvbW90aW9uVGFza1NwZWMSRQoEdmFycxgBIAMoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25WYXJpYWJsZRJCCgVzdGVwcxgCIAMoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGVwIl4KEVByb21vdGlvblRlbXBsYXRlEkkKBHNwZWMYASABKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGVtcGxhdGVTcGVjIqIBChVQcm9tb3Rpb25UZW1wbGF0ZVNwZWMSRQoEdmFycxgCIAMoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25WYXJpYWJsZRJCCgVzdGVwcxgBIAMoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25TdGVwIjAKEVByb21vdGlvblZhcmlhYmxlEgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAki5gEKEFJlcG9TdWJzY3JpcHRpb24SQgoDZ2l0GAEgASgLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdFN1YnNjcmlwdGlvbhJGCgVpbWFnZRgCIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5JbWFnZVN1YnNjcmlwdGlvbhJGCgVjaGFydBgDIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DaGFydFN1YnNjcmlwdGlvbiLNAQoFU3RhZ2USQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRI9CgRzcGVjGAIgASgLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlU3BlYxJBCgZzdGF0dXMYAyABKAsyMS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2VTdGF0dXMiiQEKCVN0YWdlTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRI6CgVpdGVtcxgCIAMoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZSKIAgoJU3RhZ2VTcGVjEg0KBXNoYXJkGAQgASgJEk4KEHJlcXVlc3RlZEZyZWlnaHQYBSADKAsyNC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlcXVlc3QSUgoRcHJvbW90aW9uVGVtcGxhdGUYBiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGVtcGxhdGUSSAoMdmVyaWZpY2F0aW9uGAMgASgLMjIuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlZlcmlmaWNhdGlvbiL2AwoLU3RhZ2VTdGF0dXMSQwoKY29uZGl0aW9ucxgNIAMoCzIvLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5Db25kaXRpb24SGgoSbGFzdEhhbmRsZWRSZWZyZXNoGAsgASgJEg0KBXBoYXNlGAEgASgJEk8KDmZyZWlnaHRIaXN0b3J5GAQgAygLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRDb2xsZWN0aW9uEhYKDmZyZWlnaHRTdW1tYXJ5GAwgASgJEjwKBmhlYWx0aBgIIAEoCzIsLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5IZWFsdGgSDwoHbWVzc2FnZRgJIAEoCRIaChJvYnNlcnZlZEdlbmVyYXRpb24YBiABKAMSUgoQY3VycmVudFByb21vdGlvbhgHIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25SZWZlcmVuY2USTwoNbGFzdFByb21vdGlvbhgKIAEoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25SZWZlcmVuY2Ui2gEKFVN0ZXBFeGVjdXRpb25NZXRhZGF0YRINCgVhbGlhcxgBIAEoCRI9CglzdGFydGVkQXQYAiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRI+CgpmaW5pc2hlZEF0GAMgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSEgoKZXJyb3JDb3VudBgEIAEoDRIOCgZzdGF0dXMYBSABKAkSDwoHbWVzc2FnZRgGIAEoCSKLAgoMVmVyaWZpY2F0aW9uEloKEWFuYWx5c2lzVGVtcGxhdGVzGAEgAygLMj8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGVSZWZlcmVuY2USVgoTYW5hbHlzaXNSdW5NZXRhZGF0YRgCIAEoCzI5LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1bk1ldGFkYXRhEkcKBGFyZ3MYAyADKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQW5hbHlzaXNSdW5Bcmd1bWVudCKdAgoQVmVyaWZpY2F0aW9uSW5mbxIKCgJpZBgEIAEoCRINCgVhY3RvchgHIAEoCRI9CglzdGFydFRpbWUYBSABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRINCgVwaGFzZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEk8KC2FuYWx5c2lzUnVuGAMgASgLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuUmVmZXJlbmNlEj4KCmZpbmlzaFRpbWUYBiABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSKUAQoNVmVyaWZpZWRTdGFnZRI+Cgp2ZXJpZmllZEF0GAEgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSQwoLbG9uZ2VzdFNvYWsYAiABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24i2QEKCVdhcmVob3VzZRJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkEKBHNwZWMYAiABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlU3BlYxJFCgZzdGF0dXMYAyABKAsyNS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuV2FyZWhvdXNlU3RhdHVzIpEBCg1XYXJlaG91c2VMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEj4KBWl0ZW1zGAIgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZSLOAQoNV2FyZWhvdXNlU3BlYxINCgVzaGFyZBgCIAEoCRJACghpbnRlcnZhbBgEIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5EdXJhdGlvbhIdChVmcmVpZ2h0Q3JlYXRpb25Qb2xpY3kYAyABKAkSTQoNc3Vic2NyaXB0aW9ucxgBIAMoCzI2LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5SZXBvU3Vic2NyaXB0aW9uIv0BCg9XYXJlaG91c2VTdGF0dXMSQwoKY29uZGl0aW9ucxgJIAMoCzIvLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5Db25kaXRpb24SGgoSbGFzdEhhbmRsZWRSZWZyZXNoGAYgASgJEhoKEm9ic2VydmVkR2VuZXJhdGlvbhgEIAEoAxIVCg1sYXN0RnJlaWdodElEGAggASgJElYKE2Rpc2NvdmVyZWRBcnRpZmFjdHMYByABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRGlzY292ZXJlZEFydGlmYWN0c0KXAgooY29tLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMUIOR2VuZXJhdGVkUHJvdG9QAVokZ2l0aHViLmNvbS9ha3VpdHkva2FyZ28vYXBpL3YxYWxwaGExogIFR0NBS0GqAiRHaXRodWIuQ29tLkFrdWl0eS5LYXJnby5BcGkuVjFhbHBoYTHKAiRHaXRodWJcQ29tXEFrdWl0eVxLYXJnb1xBcGlcVjFhbHBoYTHiAjBHaXRodWJcQ29tXEFrdWl0eVxLYXJnb1xBcGlcVjFhbHBoYTFcR1BCTWV0YWRhdGHqAilHaXRodWI6OkNvbTo6QWt1aXR5OjpLYXJnbzo6QXBpOjpWMWFscGhhMQ", [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]);
+export const file_api_v1alpha1_generated: GenFile = /*@__PURE__*/
+  fileDesc("ChxhcGkvdjFhbHBoYTEvZ2VuZXJhdGVkLnByb3RvEiRnaXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEiMgoTQW5hbHlzaXNSdW5Bcmd1bWVudBIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJIrACChNBbmFseXNpc1J1bk1ldGFkYXRhElUKBmxhYmVscxgBIAMoCzJFLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1bk1ldGFkYXRhLkxhYmVsc0VudHJ5El8KC2Fubm90YXRpb25zGAIgAygLMkouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuTWV0YWRhdGEuQW5ub3RhdGlvbnNFbnRyeRotCgtMYWJlbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGjIKEEFubm90YXRpb25zRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJGChRBbmFseXNpc1J1blJlZmVyZW5jZRIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRINCgVwaGFzZRgDIAEoCSI3ChlBbmFseXNpc1RlbXBsYXRlUmVmZXJlbmNlEgwKBG5hbWUYASABKAkSDAoEa2luZBgCIAEoCSJPCg1BcHByb3ZlZFN0YWdlEj4KCmFwcHJvdmVkQXQYASABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZSI4ChVBcmdvQ0RBcHBIZWFsdGhTdGF0dXMSDgoGc3RhdHVzGAEgASgJEg8KB21lc3NhZ2UYAiABKAki1AEKD0FyZ29DREFwcFN0YXR1cxIRCgluYW1lc3BhY2UYASABKAkSDAoEbmFtZRgCIAEoCRJRCgxoZWFsdGhTdGF0dXMYAyABKAsyOy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXJnb0NEQXBwSGVhbHRoU3RhdHVzEk0KCnN5bmNTdGF0dXMYBCABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQXJnb0NEQXBwU3luY1N0YXR1cyJKChNBcmdvQ0RBcHBTeW5jU3RhdHVzEg4KBnN0YXR1cxgBIAEoCRIQCghyZXZpc2lvbhgCIAEoCRIRCglyZXZpc2lvbnMYAyADKAkiNwoFQ2hhcnQSDwoHcmVwb1VSTBgBIAEoCRIMCgRuYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAkiYQoUQ2hhcnREaXNjb3ZlcnlSZXN1bHQSDwoHcmVwb1VSTBgBIAEoCRIMCgRuYW1lGAIgASgJEhgKEHNlbXZlckNvbnN0cmFpbnQYAyABKAkSEAoIdmVyc2lvbnMYBCADKAkiZAoRQ2hhcnRTdWJzY3JpcHRpb24SDwoHcmVwb1VSTBgBIAEoCRIMCgRuYW1lGAIgASgJEhgKEHNlbXZlckNvbnN0cmFpbnQYAyABKAkSFgoOZGlzY292ZXJ5TGltaXQYBCABKAUioQEKFENsdXN0ZXJQcm9tb3Rpb25UYXNrEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESRQoEc3BlYxgCIAEoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25UYXNrU3BlYyKnAQoYQ2x1c3RlclByb21vdGlvblRhc2tMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEkkKBWl0ZW1zGAIgAygLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNsdXN0ZXJQcm9tb3Rpb25UYXNrIkkKDEN1cnJlbnRTdGFnZRI5CgVzaW5jZRgBIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIrYCChNEaXNjb3ZlcmVkQXJ0aWZhY3RzEkAKDGRpc2NvdmVyZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEkUKA2dpdBgBIAMoCzI4LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5HaXREaXNjb3ZlcnlSZXN1bHQSSgoGaW1hZ2VzGAIgAygLMjouZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlRGlzY292ZXJ5UmVzdWx0EkoKBmNoYXJ0cxgDIAMoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DaGFydERpc2NvdmVyeVJlc3VsdCKwAQoQRGlzY292ZXJlZENvbW1pdBIKCgJpZBgBIAEoCRIOCgZicmFuY2gYAiABKAkSCwoDdGFnGAMgASgJEg8KB3N1YmplY3QYBCABKAkSDgoGYXV0aG9yGAUgASgJEhEKCWNvbW1pdHRlchgGIAEoCRI/CgtjcmVhdG9yRGF0ZRgHIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIooBChhEaXNjb3ZlcmVkSW1hZ2VSZWZlcmVuY2USCwoDdGFnGAEgASgJEg4KBmRpZ2VzdBgCIAEoCRISCgpnaXRSZXBvVVJMGAMgASgJEj0KCWNyZWF0ZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lIqIDCgdGcmVpZ2h0EkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESDQoFYWxpYXMYByABKAkSQwoGb3JpZ2luGAkgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRPcmlnaW4SQAoHY29tbWl0cxgDIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5HaXRDb21taXQSOwoGaW1hZ2VzGAQgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkltYWdlEjsKBmNoYXJ0cxgFIAMoCzIrLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5DaGFydBJDCgZzdGF0dXMYBiABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cyKtAgoRRnJlaWdodENvbGxlY3Rpb24SCgoCaWQYAyABKAkSUQoFaXRlbXMYASADKAsyQi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodENvbGxlY3Rpb24uSXRlbXNFbnRyeRJTChN2ZXJpZmljYXRpb25IaXN0b3J5GAIgAygLMjYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlZlcmlmaWNhdGlvbkluZm8aZAoKSXRlbXNFbnRyeRILCgNrZXkYASABKAkSRQoFdmFsdWUYAiABKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFJlZmVyZW5jZToCOAEijQEKC0ZyZWlnaHRMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEjwKBWl0ZW1zGAIgAygLMi0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHQiKwoNRnJlaWdodE9yaWdpbhIMCgRraW5kGAEgASgJEgwKBG5hbWUYAiABKAkioQIKEEZyZWlnaHRSZWZlcmVuY2USDAoEbmFtZRgBIAEoCRJDCgZvcmlnaW4YCCABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodE9yaWdpbhJACgdjb21taXRzGAIgAygLMi8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkdpdENvbW1pdBI7CgZpbWFnZXMYAyADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2USOwoGY2hhcnRzGAQgAygLMisuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkNoYXJ0IpwBCg5GcmVpZ2h0UmVxdWVzdBJDCgZvcmlnaW4YASABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodE9yaWdpbhJFCgdzb3VyY2VzGAIgASgLMjQuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRTb3VyY2VzIpgBCg5GcmVpZ2h0U291cmNlcxIOCgZkaXJlY3QYASABKAgSDgoGc3RhZ2VzGAIgAygJEkgKEHJlcXVpcmVkU29ha1RpbWUYAyABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SHAoUYXZhaWxhYmlsaXR5U3RyYXRlZ3kYBCABKAki1wQKDUZyZWlnaHRTdGF0dXMSWQoLY3VycmVudGx5SW4YAyADKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5DdXJyZW50bHlJbkVudHJ5ElcKCnZlcmlmaWVkSW4YASADKAsyQy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5WZXJpZmllZEluRW50cnkSWQoLYXBwcm92ZWRGb3IYAiADKAsyRC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodFN0YXR1cy5BcHByb3ZlZEZvckVudHJ5GmYKEEN1cnJlbnRseUluRW50cnkSCwoDa2V5GAEgASgJEkEKBXZhbHVlGAIgASgLMjIuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkN1cnJlbnRTdGFnZToCOAEaZgoPVmVyaWZpZWRJbkVudHJ5EgsKA2tleRgBIAEoCRJCCgV2YWx1ZRgCIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5WZXJpZmllZFN0YWdlOgI4ARpnChBBcHByb3ZlZEZvckVudHJ5EgsKA2tleRgBIAEoCRJCCgV2YWx1ZRgCIAEoCzIzLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BcHByb3ZlZFN0YWdlOgI4ASJ5CglHaXRDb21taXQSDwoHcmVwb1VSTBgBIAEoCRIKCgJpZBgCIAEoCRIOCgZicmFuY2gYAyABKAkSCwoDdGFnGAQgASgJEg8KB21lc3NhZ2UYBiABKAkSDgoGYXV0aG9yGAcgASgJEhEKCWNvbW1pdHRlchgIIAEoCSJuChJHaXREaXNjb3ZlcnlSZXN1bHQSDwoHcmVwb1VSTBgBIAEoCRJHCgdjb21taXRzGAIgAygLMjYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkRpc2NvdmVyZWRDb21taXQijgIKD0dpdFN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEh8KF2NvbW1pdFNlbGVjdGlvblN0cmF0ZWd5GAIgASgJEg4KBmJyYW5jaBgDIAEoCRIVCg1zdHJpY3RTZW12ZXJzGAsgASgIEhgKEHNlbXZlckNvbnN0cmFpbnQYBCABKAkSEQoJYWxsb3dUYWdzGAUgASgJEhIKCmlnbm9yZVRhZ3MYBiADKAkSHQoVaW5zZWN1cmVTa2lwVExTVmVyaWZ5GAcgASgIEhQKDGluY2x1ZGVQYXRocxgIIAMoCRIUCgxleGNsdWRlUGF0aHMYCSADKAkSFgoOZGlzY292ZXJ5TGltaXQYCiABKAUiyAEKBkhlYWx0aBIOCgZzdGF0dXMYASABKAkSDgoGaXNzdWVzGAIgAygJEk4KBmNvbmZpZxgEIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04STgoGb3V0cHV0GAUgASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPTiJvCg9IZWFsdGhDaGVja1N0ZXASDAoEdXNlcxgBIAEoCRJOCgZjb25maWcYAiABKAsyPi5rOHMuaW8uYXBpZXh0ZW5zaW9uc19hcGlzZXJ2ZXIucGtnLmFwaXMuYXBpZXh0ZW5zaW9ucy52MS5KU09OIkkKBUltYWdlEg8KB3JlcG9VUkwYASABKAkSEgoKZ2l0UmVwb1VSTBgCIAEoCRILCgN0YWcYAyABKAkSDgoGZGlnZXN0GAQgASgJIo0BChRJbWFnZURpc2NvdmVyeVJlc3VsdBIPCgdyZXBvVVJMGAEgASgJEhAKCHBsYXRmb3JtGAIgASgJElIKCnJlZmVyZW5jZXMYAyADKAsyPi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRGlzY292ZXJlZEltYWdlUmVmZXJlbmNlIvkBChFJbWFnZVN1YnNjcmlwdGlvbhIPCgdyZXBvVVJMGAEgASgJEhIKCmdpdFJlcG9VUkwYAiABKAkSHgoWaW1hZ2VTZWxlY3Rpb25TdHJhdGVneRgDIAEoCRIVCg1zdHJpY3RTZW12ZXJzGAogASgIEhgKEHNlbXZlckNvbnN0cmFpbnQYBCABKAkSEQoJYWxsb3dUYWdzGAUgASgJEhIKCmlnbm9yZVRhZ3MYBiADKAkSEAoIcGxhdGZvcm0YByABKAkSHQoVaW5zZWN1cmVTa2lwVExTVmVyaWZ5GAggASgIEhYKDmRpc2NvdmVyeUxpbWl0GAkgASgFItMBCgdQcm9qZWN0EkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESPwoEc3BlYxgCIAEoCzIxLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9qZWN0U3BlYxJDCgZzdGF0dXMYAyABKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdFN0YXR1cyKNAQoLUHJvamVjdExpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESPAoFaXRlbXMYAiADKAsyLS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvamVjdCJfCgtQcm9qZWN0U3BlYxJQChFwcm9tb3Rpb25Qb2xpY2llcxgBIAMoCzI1LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb25Qb2xpY3kidAoNUHJvamVjdFN0YXR1cxJDCgpjb25kaXRpb25zGAMgAygLMi8uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkNvbmRpdGlvbhINCgVwaGFzZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJItkBCglQcm9tb3Rpb24SQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJBCgRzcGVjGAIgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblNwZWMSRQoGc3RhdHVzGAMgASgLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblN0YXR1cyKRAQoNUHJvbW90aW9uTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRI+CgVpdGVtcxgCIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5Qcm9tb3Rpb24iPgoPUHJvbW90aW9uUG9saWN5Eg0KBXN0YWdlGAEgASgJEhwKFGF1dG9Qcm9tb3Rpb25FbmFibGVkGAIgASgIIvIBChJQcm9tb3Rpb25SZWZlcmVuY2USDAoEbmFtZRgBIAEoCRJHCgdmcmVpZ2h0GAIgASgLMjYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRSZWZlcmVuY2USRQoGc3RhdHVzGAMgASgLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblN0YXR1cxI+CgpmaW5pc2hlZEF0GAQgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUiugEKDVByb21vdGlvblNwZWMSDQoFc3RhZ2UYASABKAkSDwoHZnJlaWdodBgCIAEoCRJFCgR2YXJzGAQgAygLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblZhcmlhYmxlEkIKBXN0ZXBzGAMgAygLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblN0ZXAitwQKD1Byb21vdGlvblN0YXR1cxIaChJsYXN0SGFuZGxlZFJlZnJlc2gYBCABKAkSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRJHCgdmcmVpZ2h0GAUgASgLMjYuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRSZWZlcmVuY2USUgoRZnJlaWdodENvbGxlY3Rpb24YByABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuRnJlaWdodENvbGxlY3Rpb24SSwoMaGVhbHRoQ2hlY2tzGAggAygLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkhlYWx0aENoZWNrU3RlcBI+CgpmaW5pc2hlZEF0GAYgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSEwoLY3VycmVudFN0ZXAYCSABKAMSWgoVc3RlcEV4ZWN1dGlvbk1ldGFkYXRhGAsgAygLMjsuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0ZXBFeGVjdXRpb25NZXRhZGF0YRJNCgVzdGF0ZRgKIAEoCzI+Lms4cy5pby5hcGlleHRlbnNpb25zX2FwaXNlcnZlci5wa2cuYXBpcy5hcGlleHRlbnNpb25zLnYxLkpTT04i4QIKDVByb21vdGlvblN0ZXASDAoEdXNlcxgBIAEoCRJKCgR0YXNrGAUgASgLMjwuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2tSZWZlcmVuY2USCgoCYXMYAiABKAkSCgoCaWYYByABKAkSRwoFcmV0cnkYBCABKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcFJldHJ5EkUKBHZhcnMYBiADKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVmFyaWFibGUSTgoGY29uZmlnGAMgASgLMj4uazhzLmlvLmFwaWV4dGVuc2lvbnNfYXBpc2VydmVyLnBrZy5hcGlzLmFwaWV4dGVuc2lvbnMudjEuSlNPTiJtChJQcm9tb3Rpb25TdGVwUmV0cnkSPwoHdGltZW91dBgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5EdXJhdGlvbhIWCg5lcnJvclRocmVzaG9sZBgCIAEoDSKaAQoNUHJvbW90aW9uVGFzaxJCCghtZXRhZGF0YRgBIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5PYmplY3RNZXRhEkUKBHNwZWMYAiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVGFza1NwZWMimQEKEVByb21vdGlvblRhc2tMaXN0EkAKCG1ldGFkYXRhGAEgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkxpc3RNZXRhEkIKBWl0ZW1zGAIgAygLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRhc2siNAoWUHJvbW90aW9uVGFza1JlZmVyZW5jZRIMCgRuYW1lGAEgASgJEgwKBGtpbmQYAiABKAkingEKEVByb21vdGlvblRhc2tTcGVjEkUKBHZhcnMYASADKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVmFyaWFibGUSQgoFc3RlcHMYAiADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCJeChFQcm9tb3Rpb25UZW1wbGF0ZRJJCgRzcGVjGAEgASgLMjsuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRlbXBsYXRlU3BlYyKiAQoVUHJvbW90aW9uVGVtcGxhdGVTcGVjEkUKBHZhcnMYAiADKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uVmFyaWFibGUSQgoFc3RlcHMYASADKAsyMy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uU3RlcCIwChFQcm9tb3Rpb25WYXJpYWJsZRIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJIuYBChBSZXBvU3Vic2NyaXB0aW9uEkIKA2dpdBgBIAEoCzI1LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5HaXRTdWJzY3JpcHRpb24SRgoFaW1hZ2UYAiABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSW1hZ2VTdWJzY3JpcHRpb24SRgoFY2hhcnQYAyABKAsyNy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQ2hhcnRTdWJzY3JpcHRpb24izQEKBVN0YWdlEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESPQoEc3BlYxgCIAEoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5TdGFnZVNwZWMSQQoGc3RhdHVzGAMgASgLMjEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlN0YWdlU3RhdHVzIokBCglTdGFnZUxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESOgoFaXRlbXMYAiADKAsyKy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuU3RhZ2UiiAIKCVN0YWdlU3BlYxINCgVzaGFyZBgEIAEoCRJOChByZXF1ZXN0ZWRGcmVpZ2h0GAUgAygLMjQuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkZyZWlnaHRSZXF1ZXN0ElIKEXByb21vdGlvblRlbXBsYXRlGAYgASgLMjcuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLlByb21vdGlvblRlbXBsYXRlEkgKDHZlcmlmaWNhdGlvbhgDIAEoCzIyLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5WZXJpZmljYXRpb24i9gMKC1N0YWdlU3RhdHVzEkMKCmNvbmRpdGlvbnMYDSADKAsyLy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuQ29uZGl0aW9uEhoKEmxhc3RIYW5kbGVkUmVmcmVzaBgLIAEoCRINCgVwaGFzZRgBIAEoCRJPCg5mcmVpZ2h0SGlzdG9yeRgEIAMoCzI3LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5GcmVpZ2h0Q29sbGVjdGlvbhIWCg5mcmVpZ2h0U3VtbWFyeRgMIAEoCRI8CgZoZWFsdGgYCCABKAsyLC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuSGVhbHRoEg8KB21lc3NhZ2UYCSABKAkSGgoSb2JzZXJ2ZWRHZW5lcmF0aW9uGAYgASgDElIKEGN1cnJlbnRQcm9tb3Rpb24YByABKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uUmVmZXJlbmNlEk8KDWxhc3RQcm9tb3Rpb24YCiABKAsyOC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUHJvbW90aW9uUmVmZXJlbmNlItoBChVTdGVwRXhlY3V0aW9uTWV0YWRhdGESDQoFYWxpYXMYASABKAkSPQoJc3RhcnRlZEF0GAIgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSPgoKZmluaXNoZWRBdBgDIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEhIKCmVycm9yQ291bnQYBCABKA0SDgoGc3RhdHVzGAUgASgJEg8KB21lc3NhZ2UYBiABKAkiiwIKDFZlcmlmaWNhdGlvbhJaChFhbmFseXNpc1RlbXBsYXRlcxgBIAMoCzI/LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1RlbXBsYXRlUmVmZXJlbmNlElYKE2FuYWx5c2lzUnVuTWV0YWRhdGEYAiABKAsyOS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuQW5hbHlzaXNSdW5NZXRhZGF0YRJHCgRhcmdzGAMgAygLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuQXJndW1lbnQinQIKEFZlcmlmaWNhdGlvbkluZm8SCgoCaWQYBCABKAkSDQoFYWN0b3IYByABKAkSPQoJc3RhcnRUaW1lGAUgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRJPCgthbmFseXNpc1J1bhgDIAEoCzI6LmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5BbmFseXNpc1J1blJlZmVyZW5jZRI+CgpmaW5pc2hUaW1lGAYgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUilAEKDVZlcmlmaWVkU3RhZ2USPgoKdmVyaWZpZWRBdBgBIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEkMKC2xvbmdlc3RTb2FrGAIgASgLMi4uazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLkR1cmF0aW9uItkBCglXYXJlaG91c2USQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJBCgRzcGVjGAIgASgLMjMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVNwZWMSRQoGc3RhdHVzGAMgASgLMjUuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLldhcmVob3VzZVN0YXR1cyKRAQoNV2FyZWhvdXNlTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRI+CgVpdGVtcxgCIAMoCzIvLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmFwaS52MWFscGhhMS5XYXJlaG91c2UizgEKDVdhcmVob3VzZVNwZWMSDQoFc2hhcmQYAiABKAkSQAoIaW50ZXJ2YWwYBCABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRHVyYXRpb24SHQoVZnJlaWdodENyZWF0aW9uUG9saWN5GAMgASgJEk0KDXN1YnNjcmlwdGlvbnMYASADKAsyNi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTEuUmVwb1N1YnNjcmlwdGlvbiL9AQoPV2FyZWhvdXNlU3RhdHVzEkMKCmNvbmRpdGlvbnMYCSADKAsyLy5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuQ29uZGl0aW9uEhoKEmxhc3RIYW5kbGVkUmVmcmVzaBgGIAEoCRIaChJvYnNlcnZlZEdlbmVyYXRpb24YBCABKAMSFQoNbGFzdEZyZWlnaHRJRBgIIAEoCRJWChNkaXNjb3ZlcmVkQXJ0aWZhY3RzGAcgASgLMjkuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uYXBpLnYxYWxwaGExLkRpc2NvdmVyZWRBcnRpZmFjdHNClwIKKGNvbS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5hcGkudjFhbHBoYTFCDkdlbmVyYXRlZFByb3RvUAFaJGdpdGh1Yi5jb20vYWt1aXR5L2thcmdvL2FwaS92MWFscGhhMaICBUdDQUtBqgIkR2l0aHViLkNvbS5Ba3VpdHkuS2FyZ28uQXBpLlYxYWxwaGExygIkR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFYxYWxwaGEx4gIwR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cQXBpXFYxYWxwaGExXEdQQk1ldGFkYXRh6gIpR2l0aHViOjpDb206OkFrdWl0eTo6S2FyZ286OkFwaTo6VjFhbHBoYTE", [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.
@@ -50,7 +50,7 @@ export type AnalysisRunArgument = Message<"github.com.akuity.kargo.api.v1alpha1.
  * Use `create(AnalysisRunArgumentSchema)` to create a new message.
  */
 export const AnalysisRunArgumentSchema: GenMessage<AnalysisRunArgument> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 0);
+  messageDesc(file_api_v1alpha1_generated, 0);
 
 /**
  * AnalysisRunMetadata contains optional metadata that should be applied to all
@@ -79,7 +79,7 @@ export type AnalysisRunMetadata = Message<"github.com.akuity.kargo.api.v1alpha1.
  * Use `create(AnalysisRunMetadataSchema)` to create a new message.
  */
 export const AnalysisRunMetadataSchema: GenMessage<AnalysisRunMetadata> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 1);
+  messageDesc(file_api_v1alpha1_generated, 1);
 
 /**
  * AnalysisRunReference is a reference to an AnalysisRun.
@@ -114,7 +114,7 @@ export type AnalysisRunReference = Message<"github.com.akuity.kargo.api.v1alpha1
  * Use `create(AnalysisRunReferenceSchema)` to create a new message.
  */
 export const AnalysisRunReferenceSchema: GenMessage<AnalysisRunReference> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 2);
+  messageDesc(file_api_v1alpha1_generated, 2);
 
 /**
  * AnalysisTemplateReference is a reference to an AnalysisTemplate.
@@ -149,7 +149,7 @@ export type AnalysisTemplateReference = Message<"github.com.akuity.kargo.api.v1a
  * Use `create(AnalysisTemplateReferenceSchema)` to create a new message.
  */
 export const AnalysisTemplateReferenceSchema: GenMessage<AnalysisTemplateReference> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 3);
+  messageDesc(file_api_v1alpha1_generated, 3);
 
 /**
  * ApprovedStage describes a Stage for which Freight has been (manually)
@@ -171,7 +171,7 @@ export type ApprovedStage = Message<"github.com.akuity.kargo.api.v1alpha1.Approv
  * Use `create(ApprovedStageSchema)` to create a new message.
  */
 export const ApprovedStageSchema: GenMessage<ApprovedStage> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 4);
+  messageDesc(file_api_v1alpha1_generated, 4);
 
 /**
  * ArgoCDAppHealthStatus describes the health of an ArgoCD Application.
@@ -195,7 +195,7 @@ export type ArgoCDAppHealthStatus = Message<"github.com.akuity.kargo.api.v1alpha
  * Use `create(ArgoCDAppHealthStatusSchema)` to create a new message.
  */
 export const ArgoCDAppHealthStatusSchema: GenMessage<ArgoCDAppHealthStatus> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 5);
+  messageDesc(file_api_v1alpha1_generated, 5);
 
 /**
  * ArgoCDAppStatus describes the current state of a single ArgoCD Application.
@@ -237,7 +237,7 @@ export type ArgoCDAppStatus = Message<"github.com.akuity.kargo.api.v1alpha1.Argo
  * Use `create(ArgoCDAppStatusSchema)` to create a new message.
  */
 export const ArgoCDAppStatusSchema: GenMessage<ArgoCDAppStatus> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 6);
+  messageDesc(file_api_v1alpha1_generated, 6);
 
 /**
  * ArgoCDAppSyncStatus describes the sync status of an ArgoCD Application.
@@ -266,7 +266,7 @@ export type ArgoCDAppSyncStatus = Message<"github.com.akuity.kargo.api.v1alpha1.
  * Use `create(ArgoCDAppSyncStatusSchema)` to create a new message.
  */
 export const ArgoCDAppSyncStatusSchema: GenMessage<ArgoCDAppSyncStatus> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 7);
+  messageDesc(file_api_v1alpha1_generated, 7);
 
 /**
  * Chart describes a specific version of a Helm chart.
@@ -306,7 +306,7 @@ export type Chart = Message<"github.com.akuity.kargo.api.v1alpha1.Chart"> & {
  * Use `create(ChartSchema)` to create a new message.
  */
 export const ChartSchema: GenMessage<Chart> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 8);
+  messageDesc(file_api_v1alpha1_generated, 8);
 
 /**
  * ChartDiscoveryResult represents the result of a chart discovery operation for
@@ -359,7 +359,7 @@ export type ChartDiscoveryResult = Message<"github.com.akuity.kargo.api.v1alpha1
  * Use `create(ChartDiscoveryResultSchema)` to create a new message.
  */
 export const ChartDiscoveryResultSchema: GenMessage<ChartDiscoveryResult> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 9);
+  messageDesc(file_api_v1alpha1_generated, 9);
 
 /**
  * ChartSubscription defines a subscription to a Helm chart repository.
@@ -429,7 +429,7 @@ export type ChartSubscription = Message<"github.com.akuity.kargo.api.v1alpha1.Ch
  * Use `create(ChartSubscriptionSchema)` to create a new message.
  */
 export const ChartSubscriptionSchema: GenMessage<ChartSubscription> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 10);
+  messageDesc(file_api_v1alpha1_generated, 10);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.ClusterPromotionTask
@@ -456,7 +456,7 @@ export type ClusterPromotionTask = Message<"github.com.akuity.kargo.api.v1alpha1
  * Use `create(ClusterPromotionTaskSchema)` to create a new message.
  */
 export const ClusterPromotionTaskSchema: GenMessage<ClusterPromotionTask> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 11);
+  messageDesc(file_api_v1alpha1_generated, 11);
 
 /**
  * ClusterPromotionTaskList contains a list of PromotionTasks.
@@ -480,7 +480,7 @@ export type ClusterPromotionTaskList = Message<"github.com.akuity.kargo.api.v1al
  * Use `create(ClusterPromotionTaskListSchema)` to create a new message.
  */
 export const ClusterPromotionTaskListSchema: GenMessage<ClusterPromotionTaskList> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 12);
+  messageDesc(file_api_v1alpha1_generated, 12);
 
 /**
  * CurrentStage reflects a Stage's current use of Freight.
@@ -503,7 +503,7 @@ export type CurrentStage = Message<"github.com.akuity.kargo.api.v1alpha1.Current
  * Use `create(CurrentStageSchema)` to create a new message.
  */
 export const CurrentStageSchema: GenMessage<CurrentStage> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 13);
+  messageDesc(file_api_v1alpha1_generated, 13);
 
 /**
  * DiscoveredArtifacts holds the artifacts discovered by the Warehouse for its
@@ -557,7 +557,7 @@ export type DiscoveredArtifacts = Message<"github.com.akuity.kargo.api.v1alpha1.
  * Use `create(DiscoveredArtifactsSchema)` to create a new message.
  */
 export const DiscoveredArtifactsSchema: GenMessage<DiscoveredArtifacts> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 14);
+  messageDesc(file_api_v1alpha1_generated, 14);
 
 /**
  * DiscoveredCommit represents a commit discovered by a Warehouse for a
@@ -628,7 +628,7 @@ export type DiscoveredCommit = Message<"github.com.akuity.kargo.api.v1alpha1.Dis
  * Use `create(DiscoveredCommitSchema)` to create a new message.
  */
 export const DiscoveredCommitSchema: GenMessage<DiscoveredCommit> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 15);
+  messageDesc(file_api_v1alpha1_generated, 15);
 
 /**
  * DiscoveredImageReference represents an image reference discovered by a
@@ -681,7 +681,7 @@ export type DiscoveredImageReference = Message<"github.com.akuity.kargo.api.v1al
  * Use `create(DiscoveredImageReferenceSchema)` to create a new message.
  */
 export const DiscoveredImageReferenceSchema: GenMessage<DiscoveredImageReference> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 16);
+  messageDesc(file_api_v1alpha1_generated, 16);
 
 /**
  * Freight represents a collection of versioned artifacts.
@@ -752,7 +752,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_v1alpha1_generated, 17);
+  messageDesc(file_api_v1alpha1_generated, 17);
 
 /**
  * FreightCollection is a collection of FreightReferences, each of which
@@ -792,7 +792,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_v1alpha1_generated, 18);
+  messageDesc(file_api_v1alpha1_generated, 18);
 
 /**
  * FreightList is a list of Freight resources.
@@ -816,7 +816,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_v1alpha1_generated, 19);
+  messageDesc(file_api_v1alpha1_generated, 19);
 
 /**
  * FreightOrigin describes a kind of Freight in terms of where it may have
@@ -853,7 +853,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_v1alpha1_generated, 20);
+  messageDesc(file_api_v1alpha1_generated, 20);
 
 /**
  * FreightReference is a simplified representation of a piece of Freight -- not
@@ -905,7 +905,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_v1alpha1_generated, 21);
+  messageDesc(file_api_v1alpha1_generated, 21);
 
 /**
  * FreightRequest expresses a Stage's need for Freight having originated from a
@@ -938,7 +938,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_v1alpha1_generated, 22);
+  messageDesc(file_api_v1alpha1_generated, 22);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.FreightSources
@@ -998,7 +998,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_v1alpha1_generated, 23);
+  messageDesc(file_api_v1alpha1_generated, 23);
 
 /**
  * FreightStatus describes a piece of Freight's most recently observed state.
@@ -1037,7 +1037,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_v1alpha1_generated, 24);
+  messageDesc(file_api_v1alpha1_generated, 24);
 
 /**
  * GitCommit describes a specific commit from a specific Git repository.
@@ -1103,7 +1103,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_v1alpha1_generated, 25);
+  messageDesc(file_api_v1alpha1_generated, 25);
 
 /**
  * GitDiscoveryResult represents the result of a Git discovery operation for a
@@ -1139,7 +1139,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_v1alpha1_generated, 26);
+  messageDesc(file_api_v1alpha1_generated, 26);
 
 /**
  * GitSubscription defines a subscription to a Git repository.
@@ -1309,7 +1309,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_v1alpha1_generated, 27);
+  messageDesc(file_api_v1alpha1_generated, 27);
 
 /**
  * Health describes the health of a Stage.
@@ -1353,7 +1353,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_v1alpha1_generated, 28);
+  messageDesc(file_api_v1alpha1_generated, 28);
 
 /**
  * HealthCheckStep describes a health check directive which can be executed by
@@ -1384,7 +1384,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_v1alpha1_generated, 29);
+  messageDesc(file_api_v1alpha1_generated, 29);
 
 /**
  * Image describes a specific version of a container image.
@@ -1430,7 +1430,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_v1alpha1_generated, 30);
+  messageDesc(file_api_v1alpha1_generated, 30);
 
 /**
  * ImageDiscoveryResult represents the result of an image discovery operation
@@ -1476,7 +1476,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_v1alpha1_generated, 31);
+  messageDesc(file_api_v1alpha1_generated, 31);
 
 /**
  * ImageSubscription defines a subscription to an image repository.
@@ -1623,7 +1623,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_v1alpha1_generated, 32);
+  messageDesc(file_api_v1alpha1_generated, 32);
 
 /**
  * Project is a resource type that reconciles to a specially labeled namespace
@@ -1657,7 +1657,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_v1alpha1_generated, 33);
+  messageDesc(file_api_v1alpha1_generated, 33);
 
 /**
  * ProjectList is a list of Project resources.
@@ -1681,7 +1681,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_v1alpha1_generated, 34);
+  messageDesc(file_api_v1alpha1_generated, 34);
 
 /**
  * ProjectSpec describes a Project.
@@ -1703,7 +1703,7 @@ export type ProjectSpec = Message<"github.com.akuity.kargo.api.v1alpha1.ProjectS
  * Use `create(ProjectSpecSchema)` to create a new message.
  */
 export const ProjectSpecSchema: GenMessage<ProjectSpec> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 35);
+  messageDesc(file_api_v1alpha1_generated, 35);
 
 /**
  * ProjectStatus describes a Project's current status.
@@ -1749,7 +1749,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_v1alpha1_generated, 36);
+  messageDesc(file_api_v1alpha1_generated, 36);
 
 /**
  * Promotion represents a request to transition a particular Stage into a
@@ -1787,7 +1787,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_v1alpha1_generated, 37);
+  messageDesc(file_api_v1alpha1_generated, 37);
 
 /**
  * PromotionList contains a list of Promotion
@@ -1811,7 +1811,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_v1alpha1_generated, 38);
+  messageDesc(file_api_v1alpha1_generated, 38);
 
 /**
  * PromotionPolicy defines policies governing the promotion of Freight to a
@@ -1847,7 +1847,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_v1alpha1_generated, 39);
+  messageDesc(file_api_v1alpha1_generated, 39);
 
 /**
  * PromotionReference contains the relevant information about a Promotion
@@ -1890,7 +1890,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_v1alpha1_generated, 40);
+  messageDesc(file_api_v1alpha1_generated, 40);
 
 /**
  * PromotionSpec describes the desired transition of a specific Stage into a
@@ -1953,7 +1953,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_v1alpha1_generated, 41);
+  messageDesc(file_api_v1alpha1_generated, 41);
 
 /**
  * PromotionStatus describes the current state of the transition represented by
@@ -2051,7 +2051,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_v1alpha1_generated, 42);
+  messageDesc(file_api_v1alpha1_generated, 42);
 
 /**
  * PromotionStep describes a directive to be executed as part of a Promotion.
@@ -2114,7 +2114,7 @@ export type PromotionStep = Message<"github.com.akuity.kargo.api.v1alpha1.Promot
    * Config is opaque configuration for the PromotionStep that is understood
    * only by each PromotionStep's implementation. It is legal to utilize
    * expressions in defining values at any level of this block.
-   * See https://docs.kargo.io/references/expression-language for details.
+   * See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
    *
    * @generated from field: optional k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON config = 3;
    */
@@ -2126,7 +2126,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_v1alpha1_generated, 43);
+  messageDesc(file_api_v1alpha1_generated, 43);
 
 /**
  * PromotionStepRetry describes the retry policy for a PromotionStep.
@@ -2185,7 +2185,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_v1alpha1_generated, 44);
+  messageDesc(file_api_v1alpha1_generated, 44);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.PromotionTask
@@ -2212,7 +2212,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_v1alpha1_generated, 45);
+  messageDesc(file_api_v1alpha1_generated, 45);
 
 /**
  * PromotionTaskList contains a list of PromotionTasks.
@@ -2236,7 +2236,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_v1alpha1_generated, 46);
+  messageDesc(file_api_v1alpha1_generated, 46);
 
 /**
  * PromotionTaskReference describes a reference to a PromotionTask.
@@ -2273,7 +2273,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_v1alpha1_generated, 47);
+  messageDesc(file_api_v1alpha1_generated, 47);
 
 /**
  * @generated from message github.com.akuity.kargo.api.v1alpha1.PromotionTaskSpec
@@ -2307,7 +2307,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_v1alpha1_generated, 48);
+  messageDesc(file_api_v1alpha1_generated, 48);
 
 /**
  * PromotionTemplate defines a template for a Promotion that can be used to
@@ -2327,7 +2327,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_v1alpha1_generated, 49);
+  messageDesc(file_api_v1alpha1_generated, 49);
 
 /**
  * PromotionTemplateSpec describes the (partial) specification of a Promotion
@@ -2363,7 +2363,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_v1alpha1_generated, 50);
+  messageDesc(file_api_v1alpha1_generated, 50);
 
 /**
  * PromotionVariable describes a single variable that may be referenced by
@@ -2385,7 +2385,7 @@ export type PromotionVariable = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
   /**
    * Value is the value of the variable. It is allowed to utilize expressions
    * in the value.
-   * See https://docs.kargo.io/references/expression-language for details.
+   * See https://docs.kargo.io/user-guide/reference-docs/expressions for details.
    *
    * @generated from field: optional string value = 2;
    */
@@ -2397,7 +2397,7 @@ export type PromotionVariable = Message<"github.com.akuity.kargo.api.v1alpha1.Pr
  * Use `create(PromotionVariableSchema)` to create a new message.
  */
 export const PromotionVariableSchema: GenMessage<PromotionVariable> = /*@__PURE__*/
-  messageDesc(file_v1alpha1_generated, 51);
+  messageDesc(file_api_v1alpha1_generated, 51);
 
 /**
  * RepoSubscription describes a subscription to ONE OF a Git repository, a
@@ -2433,7 +2433,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_v1alpha1_generated, 52);
+  messageDesc(file_api_v1alpha1_generated, 52);
 
 /**
  * Stage is the Kargo API's main type.
@@ -2469,7 +2469,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_v1alpha1_generated, 53);
+  messageDesc(file_api_v1alpha1_generated, 53);
 
 /**
  * StageList is a list of Stage resources.
@@ -2493,7 +2493,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_v1alpha1_generated, 54);
+  messageDesc(file_api_v1alpha1_generated, 54);
 
 /**
  * StageSpec describes the sources of Freight used by a Stage and how to
@@ -2551,7 +2551,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_v1alpha1_generated, 55);
+  messageDesc(file_api_v1alpha1_generated, 55);
 
 /**
  * StageStatus describes a Stages's current and recent Freight, health, and
@@ -2658,7 +2658,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_v1alpha1_generated, 56);
+  messageDesc(file_api_v1alpha1_generated, 56);
 
 /**
  * StepExecutionMetadata tracks metadata pertaining to the execution of
@@ -2717,7 +2717,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_v1alpha1_generated, 57);
+  messageDesc(file_api_v1alpha1_generated, 57);
 
 /**
  * Verification describes how to verify that a Promotion has been successful
@@ -2756,7 +2756,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_v1alpha1_generated, 58);
+  messageDesc(file_api_v1alpha1_generated, 58);
 
 /**
  * VerificationInfo contains the details of an instance of a Verification
@@ -2826,7 +2826,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_v1alpha1_generated, 59);
+  messageDesc(file_api_v1alpha1_generated, 59);
 
 /**
  * VerifiedStage describes a Stage in which Freight has been verified.
@@ -2858,7 +2858,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_v1alpha1_generated, 60);
+  messageDesc(file_api_v1alpha1_generated, 60);
 
 /**
  * Warehouse is a source of Freight.
@@ -2893,7 +2893,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_v1alpha1_generated, 61);
+  messageDesc(file_api_v1alpha1_generated, 61);
 
 /**
  * WarehouseList is a list of Warehouse resources.
@@ -2917,7 +2917,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_v1alpha1_generated, 62);
+  messageDesc(file_api_v1alpha1_generated, 62);
 
 /**
  * WarehouseSpec describes sources of versioned artifacts to be included in
@@ -2983,7 +2983,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_v1alpha1_generated, 63);
+  messageDesc(file_api_v1alpha1_generated, 63);
 
 /**
  * WarehouseStatus describes a Warehouse's most recently observed state.
@@ -3042,5 +3042,5 @@ 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_v1alpha1_generated, 64);
+  messageDesc(file_api_v1alpha1_generated, 64);
 
diff --git a/ui/src/gen/rollouts/api/v1alpha1/generated_pb.ts b/ui/src/gen/rollouts/api/v1alpha1/generated_pb.ts
deleted file mode 100644
index 3386fe59..00000000
--- a/ui/src/gen/rollouts/api/v1alpha1/generated_pb.ts
+++ /dev/null
@@ -1,1352 +0,0 @@
-// This file was autogenerated by go-to-protobuf. Do not edit it manually!
-
-// @generated by protoc-gen-es v2.2.2 with parameter "target=ts"
-// @generated from file rollouts/api/v1alpha1/generated.proto (package github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1, syntax proto2)
-/* eslint-disable */
-
-import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
-import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
-import type { JobSpec } from "../../../k8s.io/api/batch/v1/generated_pb";
-import { file_k8s_io_api_batch_v1_generated } from "../../../k8s.io/api/batch/v1/generated_pb";
-import type { ListMeta, ObjectMeta, Time } from "../../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
-import { file_k8s_io_apimachinery_pkg_apis_meta_v1_generated } from "../../../k8s.io/apimachinery/pkg/apis/meta/v1/generated_pb";
-import { file_k8s_io_apimachinery_pkg_runtime_generated } from "../../../k8s.io/apimachinery/pkg/runtime/generated_pb";
-import { file_k8s_io_apimachinery_pkg_runtime_schema_generated } from "../../../k8s.io/apimachinery/pkg/runtime/schema/generated_pb";
-import type { IntOrString } from "../../../k8s.io/apimachinery/pkg/util/intstr/generated_pb";
-import { file_k8s_io_apimachinery_pkg_util_intstr_generated } from "../../../k8s.io/apimachinery/pkg/util/intstr/generated_pb";
-import type { Message } from "@bufbuild/protobuf";
-
-/**
- * Describes the file rollouts/api/v1alpha1/generated.proto.
- */
-export const file_rollouts_api_v1alpha1_generated: GenFile = /*@__PURE__*/
-  fileDesc("CiVyb2xsb3V0cy9hcGkvdjFhbHBoYTEvZ2VuZXJhdGVkLnByb3RvEkFnaXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMSKZAgoLQW5hbHlzaXNSdW4SQgoIbWV0YWRhdGEYASABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuT2JqZWN0TWV0YRJgCgRzcGVjGAIgASgLMlIuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuQW5hbHlzaXNSdW5TcGVjEmQKBnN0YXR1cxgDIAEoCzJULmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFuYWx5c2lzUnVuU3RhdHVzIrIBCg9BbmFseXNpc1J1bkxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESXQoFaXRlbXMYAiADKAsyTi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5BbmFseXNpc1J1biKtAwoPQW5hbHlzaXNSdW5TcGVjEloKB21ldHJpY3MYASADKAsySS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5NZXRyaWMSWQoEYXJncxgCIAMoCzJLLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFyZ3VtZW50EhEKCXRlcm1pbmF0ZRgDIAEoCBJZCgZkcnlSdW4YBCADKAsySS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5EcnlSdW4SdQoUbWVhc3VyZW1lbnRSZXRlbnRpb24YBSADKAsyVy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5NZWFzdXJlbWVudFJldGVudGlvbiKjAwoRQW5hbHlzaXNSdW5TdGF0dXMSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRJmCg1tZXRyaWNSZXN1bHRzGAMgAygLMk8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuTWV0cmljUmVzdWx0Ej0KCXN0YXJ0ZWRBdBgEIAEoCzIqLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5UaW1lEmEKCnJ1blN1bW1hcnkYBSABKAsyTS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5SdW5TdW1tYXJ5EmQKDWRyeVJ1blN1bW1hcnkYBiABKAsyTS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5SdW5TdW1tYXJ5Ir0BChBBbmFseXNpc1RlbXBsYXRlEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESZQoEc3BlYxgCIAEoCzJXLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGVTcGVjIrwBChRBbmFseXNpc1RlbXBsYXRlTGlzdBJACghtZXRhZGF0YRgBIAEoCzIuLms4cy5pby5hcGltYWNoaW5lcnkucGtnLmFwaXMubWV0YS52MS5MaXN0TWV0YRJiCgVpdGVtcxgCIAMoCzJTLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGUinwMKFEFuYWx5c2lzVGVtcGxhdGVTcGVjEloKB21ldHJpY3MYASADKAsySS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5NZXRyaWMSWQoEYXJncxgCIAMoCzJLLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFyZ3VtZW50ElkKBmRyeVJ1bhgDIAMoCzJJLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkRyeVJ1bhJ1ChRtZWFzdXJlbWVudFJldGVudGlvbhgEIAMoCzJXLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLk1lYXN1cmVtZW50UmV0ZW50aW9uIogBCghBcmd1bWVudBIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJEl8KCXZhbHVlRnJvbRgDIAEoCzJMLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLlZhbHVlRnJvbSLQAQoOQXV0aGVudGljYXRpb24SXQoFc2lndjQYASABKAsyTi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5TaWd2NENvbmZpZxJfCgZvYXV0aDIYAiABKAsyTy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5PQXV0aDJDb25maWcinQEKEENsb3VkV2F0Y2hNZXRyaWMSEAoIaW50ZXJ2YWwYASABKAkSdwoRbWV0cmljRGF0YVF1ZXJpZXMYAiADKAsyXC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5DbG91ZFdhdGNoTWV0cmljRGF0YVF1ZXJ5Io0CChlDbG91ZFdhdGNoTWV0cmljRGF0YVF1ZXJ5EgoKAmlkGAEgASgJEhIKCmV4cHJlc3Npb24YAiABKAkSDQoFbGFiZWwYAyABKAkSawoKbWV0cmljU3RhdBgEIAEoCzJXLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkNsb3VkV2F0Y2hNZXRyaWNTdGF0EkAKBnBlcmlvZBgFIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLnV0aWwuaW50c3RyLkludE9yU3RyaW5nEhIKCnJldHVybkRhdGEYBiABKAgi4wEKFENsb3VkV2F0Y2hNZXRyaWNTdGF0Em0KBm1ldHJpYxgBIAEoCzJdLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkNsb3VkV2F0Y2hNZXRyaWNTdGF0TWV0cmljEkAKBnBlcmlvZBgCIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLnV0aWwuaW50c3RyLkludE9yU3RyaW5nEgwKBHN0YXQYAyABKAkSDAoEdW5pdBgEIAEoCSK/AQoaQ2xvdWRXYXRjaE1ldHJpY1N0YXRNZXRyaWMSegoKZGltZW5zaW9ucxgBIAMoCzJmLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkNsb3VkV2F0Y2hNZXRyaWNTdGF0TWV0cmljRGltZW5zaW9uEhIKCm1ldHJpY05hbWUYAiABKAkSEQoJbmFtZXNwYWNlGAMgASgJIkIKI0Nsb3VkV2F0Y2hNZXRyaWNTdGF0TWV0cmljRGltZW5zaW9uEgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAkixAEKF0NsdXN0ZXJBbmFseXNpc1RlbXBsYXRlEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESZQoEc3BlYxgCIAEoCzJXLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkFuYWx5c2lzVGVtcGxhdGVTcGVjIsoBChtDbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZUxpc3QSQAoIbWV0YWRhdGEYASABKAsyLi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuTGlzdE1ldGESaQoFaXRlbXMYAiADKAsyWi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5DbHVzdGVyQW5hbHlzaXNUZW1wbGF0ZSL1AQoNRGF0YWRvZ01ldHJpYxIQCghpbnRlcnZhbBgBIAEoCRINCgVxdWVyeRgCIAEoCRJuCgdxdWVyaWVzGAMgAygLMl0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuRGF0YWRvZ01ldHJpYy5RdWVyaWVzRW50cnkSDwoHZm9ybXVsYRgEIAEoCRISCgphcGlWZXJzaW9uGAUgASgJGi4KDFF1ZXJpZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIhwKBkRyeVJ1bhISCgptZXRyaWNOYW1lGAEgASgJIh0KCEZpZWxkUmVmEhEKCWZpZWxkUGF0aBgBIAEoCSIwCg5HcmFwaGl0ZU1ldHJpYxIPCgdhZGRyZXNzGAEgASgJEg0KBXF1ZXJ5GAIgASgJIjAKDkluZmx1eGRiTWV0cmljEg8KB3Byb2ZpbGUYASABKAkSDQoFcXVlcnkYAiABKAkiewoJSm9iTWV0cmljEkIKCG1ldGFkYXRhGAEgASgLMjAuazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLk9iamVjdE1ldGESKgoEc3BlYxgCIAEoCzIcLms4cy5pby5hcGkuYmF0Y2gudjEuSm9iU3BlYyLyAgoNS2F5ZW50YU1ldHJpYxIPCgdhZGRyZXNzGAEgASgJEhMKC2FwcGxpY2F0aW9uGAIgASgJEhgKEGNhbmFyeUNvbmZpZ05hbWUYAyABKAkSGgoSbWV0cmljc0FjY291bnROYW1lGAQgASgJEiAKGGNvbmZpZ3VyYXRpb25BY2NvdW50TmFtZRgFIAEoCRIaChJzdG9yYWdlQWNjb3VudE5hbWUYBiABKAkSZgoJdGhyZXNob2xkGAcgASgLMlMuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuS2F5ZW50YVRocmVzaG9sZBJfCgZzY29wZXMYCCADKAsyTy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5LYXllbnRhU2NvcGUi6wEKDEtheWVudGFTY29wZRIMCgRuYW1lGAEgASgJEmQKDGNvbnRyb2xTY29wZRgCIAEoCzJOLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLlNjb3BlRGV0YWlsEmcKD2V4cGVyaW1lbnRTY29wZRgDIAEoCzJOLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLlNjb3BlRGV0YWlsIjIKEEtheWVudGFUaHJlc2hvbGQSDAoEcGFzcxgBIAEoAxIQCghtYXJnaW5hbBgCIAEoAyKaAwoLTWVhc3VyZW1lbnQSDQoFcGhhc2UYASABKAkSDwoHbWVzc2FnZRgCIAEoCRI9CglzdGFydGVkQXQYAyABKAsyKi5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuVGltZRI+CgpmaW5pc2hlZEF0GAQgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUSDQoFdmFsdWUYBSABKAkSbgoIbWV0YWRhdGEYBiADKAsyXC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5NZWFzdXJlbWVudC5NZXRhZGF0YUVudHJ5EjwKCHJlc3VtZUF0GAcgASgLMiouazhzLmlvLmFwaW1hY2hpbmVyeS5wa2cuYXBpcy5tZXRhLnYxLlRpbWUaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIjkKFE1lYXN1cmVtZW50UmV0ZW50aW9uEhIKCm1ldHJpY05hbWUYASABKAkSDQoFbGltaXQYAiABKAUi/gMKBk1ldHJpYxIMCgRuYW1lGAEgASgJEhAKCGludGVydmFsGAIgASgJEhQKDGluaXRpYWxEZWxheRgDIAEoCRI/CgVjb3VudBgEIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLnV0aWwuaW50c3RyLkludE9yU3RyaW5nEhgKEHN1Y2Nlc3NDb25kaXRpb24YBSABKAkSGAoQZmFpbHVyZUNvbmRpdGlvbhgGIAEoCRJGCgxmYWlsdXJlTGltaXQYByABKAsyMC5rOHMuaW8uYXBpbWFjaGluZXJ5LnBrZy51dGlsLmludHN0ci5JbnRPclN0cmluZxJLChFpbmNvbmNsdXNpdmVMaW1pdBgIIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLnV0aWwuaW50c3RyLkludE9yU3RyaW5nEk8KFWNvbnNlY3V0aXZlRXJyb3JMaW1pdBgJIAEoCzIwLms4cy5pby5hcGltYWNoaW5lcnkucGtnLnV0aWwuaW50c3RyLkludE9yU3RyaW5nEmMKCHByb3ZpZGVyGAogASgLMlEuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuTWV0cmljUHJvdmlkZXIi+wkKDk1ldHJpY1Byb3ZpZGVyEmcKCnByb21ldGhldXMYASABKAsyUy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5Qcm9tZXRoZXVzTWV0cmljEmEKB2theWVudGEYAiABKAsyUC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5LYXllbnRhTWV0cmljElkKA3dlYhgDIAEoCzJMLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLldlYk1ldHJpYxJhCgdkYXRhZG9nGAQgASgLMlAuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuRGF0YWRvZ01ldHJpYxJlCgl3YXZlZnJvbnQYBSABKAsyUi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5XYXZlZnJvbnRNZXRyaWMSYwoIbmV3UmVsaWMYBiABKAsyUS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5OZXdSZWxpY01ldHJpYxJZCgNqb2IYByABKAsyTC5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5Kb2JNZXRyaWMSZwoKY2xvdWRXYXRjaBgIIAEoCzJTLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkNsb3VkV2F0Y2hNZXRyaWMSYwoIZ3JhcGhpdGUYCSABKAsyUS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5HcmFwaGl0ZU1ldHJpYxJjCghpbmZsdXhkYhgKIAEoCzJRLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkluZmx1eGRiTWV0cmljEmcKCnNreXdhbGtpbmcYCyABKAsyUy5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5Ta3lXYWxraW5nTWV0cmljEm0KBnBsdWdpbhgMIAMoCzJdLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLk1ldHJpY1Byb3ZpZGVyLlBsdWdpbkVudHJ5Gi0KC1BsdWdpbkVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAEixgMKDE1ldHJpY1Jlc3VsdBIMCgRuYW1lGAEgASgJEg0KBXBoYXNlGAIgASgJEmQKDG1lYXN1cmVtZW50cxgDIAMoCzJOLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLk1lYXN1cmVtZW50Eg8KB21lc3NhZ2UYBCABKAkSDQoFY291bnQYBSABKAUSEgoKc3VjY2Vzc2Z1bBgGIAEoBRIOCgZmYWlsZWQYByABKAUSFAoMaW5jb25jbHVzaXZlGAggASgFEg0KBWVycm9yGAkgASgFEhgKEGNvbnNlY3V0aXZlRXJyb3IYCiABKAUSDgoGZHJ5UnVuGAsgASgIEm8KCG1ldGFkYXRhGAwgAygLMl0uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuTWV0cmljUmVzdWx0Lk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIjAKDk5ld1JlbGljTWV0cmljEg8KB3Byb2ZpbGUYASABKAkSDQoFcXVlcnkYAiABKAkiWAoMT0F1dGgyQ29uZmlnEhAKCHRva2VuVXJsGAEgASgJEhAKCGNsaWVudElkGAIgASgJEhQKDGNsaWVudFNlY3JldBgDIAEoCRIOCgZzY29wZXMYBCADKAkipQIKEFByb21ldGhldXNNZXRyaWMSDwoHYWRkcmVzcxgBIAEoCRINCgVxdWVyeRgCIAEoCRJpCg5hdXRoZW50aWNhdGlvbhgDIAEoCzJRLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkF1dGhlbnRpY2F0aW9uEg8KB3RpbWVvdXQYBCABKAMSEAoIaW5zZWN1cmUYBSABKAgSYwoHaGVhZGVycxgGIAMoCzJSLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLldlYk1ldHJpY0hlYWRlciJkCgpSdW5TdW1tYXJ5Eg0KBWNvdW50GAEgASgFEhIKCnN1Y2Nlc3NmdWwYAiABKAUSDgoGZmFpbGVkGAMgASgFEhQKDGluY29uY2x1c2l2ZRgEIAEoBRINCgVlcnJvchgFIAEoBSJWCgtTY29wZURldGFpbBINCgVzY29wZRgBIAEoCRIOCgZyZWdpb24YAiABKAkSDAoEc3RlcBgDIAEoAxINCgVzdGFydBgEIAEoCRILCgNlbmQYBSABKAkiKQoMU2VjcmV0S2V5UmVmEgwKBG5hbWUYASABKAkSCwoDa2V5GAIgASgJIj8KC1NpZ3Y0Q29uZmlnEg4KBnJlZ2lvbhgBIAEoCRIPCgdwcm9maWxlGAIgASgJEg8KB3JvbGVBcm4YAyABKAkiRAoQU2t5V2Fsa2luZ01ldHJpYxIPCgdhZGRyZXNzGAEgASgJEg0KBXF1ZXJ5GAIgASgJEhAKCGludGVydmFsGAMgASgJItEBCglWYWx1ZUZyb20SZQoMc2VjcmV0S2V5UmVmGAEgASgLMk8uZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuU2VjcmV0S2V5UmVmEl0KCGZpZWxkUmVmGAIgASgLMksuZ2l0aHViLmNvbS5ha3VpdHkua2FyZ28uaW50ZXJuYWwuY29udHJvbGxlci5yb2xsb3V0cy5hcGkudjFhbHBoYTEuRmllbGRSZWYiMQoPV2F2ZWZyb250TWV0cmljEg8KB2FkZHJlc3MYASABKAkSDQoFcXVlcnkYAiABKAki1AIKCVdlYk1ldHJpYxIOCgZtZXRob2QYASABKAkSCwoDdXJsGAIgASgJEmMKB2hlYWRlcnMYAyADKAsyUi5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMS5XZWJNZXRyaWNIZWFkZXISDAoEYm9keRgEIAEoCRIWCg50aW1lb3V0U2Vjb25kcxgFIAEoAxIQCghqc29uUGF0aBgGIAEoCRIQCghpbnNlY3VyZRgHIAEoCBIQCghqc29uQm9keRgIIAEoDBJpCg5hdXRoZW50aWNhdGlvbhgJIAEoCzJRLmdpdGh1Yi5jb20uYWt1aXR5LmthcmdvLmludGVybmFsLmNvbnRyb2xsZXIucm9sbG91dHMuYXBpLnYxYWxwaGExLkF1dGhlbnRpY2F0aW9uIi0KD1dlYk1ldHJpY0hlYWRlchILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAlCywMKRWNvbS5naXRodWIuY29tLmFrdWl0eS5rYXJnby5pbnRlcm5hbC5jb250cm9sbGVyLnJvbGxvdXRzLmFwaS52MWFscGhhMUIOR2VuZXJhdGVkUHJvdG9QAVpBZ2l0aHViLmNvbS9ha3VpdHkva2FyZ28vaW50ZXJuYWwvY29udHJvbGxlci9yb2xsb3V0cy9hcGkvdjFhbHBoYTGiAghHQ0FLSUNSQaoCQUdpdGh1Yi5Db20uQWt1aXR5LkthcmdvLkludGVybmFsLkNvbnRyb2xsZXIuUm9sbG91dHMuQXBpLlYxYWxwaGExygJBR2l0aHViXENvbVxBa3VpdHlcS2FyZ29cSW50ZXJuYWxcQ29udHJvbGxlclxSb2xsb3V0c1xBcGlcVjFhbHBoYTHiAk1HaXRodWJcQ29tXEFrdWl0eVxLYXJnb1xJbnRlcm5hbFxDb250cm9sbGVyXFJvbGxvdXRzXEFwaVxWMWFscGhhMVxHUEJNZXRhZGF0YeoCSUdpdGh1Yjo6Q29tOjpBa3VpdHk6OkthcmdvOjpJbnRlcm5hbDo6Q29udHJvbGxlcjo6Um9sbG91dHM6OkFwaTo6VjFhbHBoYTE", [file_k8s_io_api_batch_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, file_k8s_io_apimachinery_pkg_util_intstr_generated]);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun
- */
-export type AnalysisRun = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
-   */
-  metadata?: ObjectMeta;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunSpec spec = 2;
-   */
-  spec?: AnalysisRunSpec;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunStatus status = 3;
-   */
-  status?: AnalysisRunStatus;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun.
- * Use `create(AnalysisRunSchema)` to create a new message.
- */
-export const AnalysisRunSchema: GenMessage<AnalysisRun> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 0);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunList
- */
-export type AnalysisRunList = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunList"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
-   */
-  metadata?: ListMeta;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRun items = 2;
-   */
-  items: AnalysisRun[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunList.
- * Use `create(AnalysisRunListSchema)` to create a new message.
- */
-export const AnalysisRunListSchema: GenMessage<AnalysisRunList> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 1);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunSpec
- */
-export type AnalysisRunSpec = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunSpec"> & {
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Metric metrics = 1;
-   */
-  metrics: Metric[];
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Argument args = 2;
-   */
-  args: Argument[];
-
-  /**
-   * @generated from field: optional bool terminate = 3;
-   */
-  terminate: boolean;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DryRun dryRun = 4;
-   */
-  dryRun: DryRun[];
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MeasurementRetention measurementRetention = 5;
-   */
-  measurementRetention: MeasurementRetention[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunSpec.
- * Use `create(AnalysisRunSpecSchema)` to create a new message.
- */
-export const AnalysisRunSpecSchema: GenMessage<AnalysisRunSpec> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 2);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunStatus
- */
-export type AnalysisRunStatus = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunStatus"> & {
-  /**
-   * @generated from field: optional string phase = 1;
-   */
-  phase: string;
-
-  /**
-   * @generated from field: optional string message = 2;
-   */
-  message: string;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricResult metricResults = 3;
-   */
-  metricResults: MetricResult[];
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 4;
-   */
-  startedAt?: Time;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.RunSummary runSummary = 5;
-   */
-  runSummary?: RunSummary;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.RunSummary dryRunSummary = 6;
-   */
-  dryRunSummary?: RunSummary;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisRunStatus.
- * Use `create(AnalysisRunStatusSchema)` to create a new message.
- */
-export const AnalysisRunStatusSchema: GenMessage<AnalysisRunStatus> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 3);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate
- */
-export type AnalysisTemplate = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
-   */
-  metadata?: ObjectMeta;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateSpec spec = 2;
-   */
-  spec?: AnalysisTemplateSpec;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate.
- * Use `create(AnalysisTemplateSchema)` to create a new message.
- */
-export const AnalysisTemplateSchema: GenMessage<AnalysisTemplate> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 4);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateList
- */
-export type AnalysisTemplateList = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateList"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
-   */
-  metadata?: ListMeta;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplate items = 2;
-   */
-  items: AnalysisTemplate[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateList.
- * Use `create(AnalysisTemplateListSchema)` to create a new message.
- */
-export const AnalysisTemplateListSchema: GenMessage<AnalysisTemplateList> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 5);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateSpec
- */
-export type AnalysisTemplateSpec = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateSpec"> & {
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Metric metrics = 1;
-   */
-  metrics: Metric[];
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Argument args = 2;
-   */
-  args: Argument[];
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DryRun dryRun = 3;
-   */
-  dryRun: DryRun[];
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MeasurementRetention measurementRetention = 4;
-   */
-  measurementRetention: MeasurementRetention[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateSpec.
- * Use `create(AnalysisTemplateSpecSchema)` to create a new message.
- */
-export const AnalysisTemplateSpecSchema: GenMessage<AnalysisTemplateSpec> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 6);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Argument
- */
-export type Argument = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Argument"> & {
-  /**
-   * @generated from field: optional string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: optional string value = 2;
-   */
-  value: string;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ValueFrom valueFrom = 3;
-   */
-  valueFrom?: ValueFrom;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Argument.
- * Use `create(ArgumentSchema)` to create a new message.
- */
-export const ArgumentSchema: GenMessage<Argument> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 7);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Authentication
- */
-export type Authentication = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Authentication"> & {
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Sigv4Config sigv4 = 1;
-   */
-  sigv4?: Sigv4Config;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.OAuth2Config oauth2 = 2;
-   */
-  oauth2?: OAuth2Config;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Authentication.
- * Use `create(AuthenticationSchema)` to create a new message.
- */
-export const AuthenticationSchema: GenMessage<Authentication> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 8);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetric
- */
-export type CloudWatchMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetric"> & {
-  /**
-   * @generated from field: optional string interval = 1;
-   */
-  interval: string;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricDataQuery metricDataQueries = 2;
-   */
-  metricDataQueries: CloudWatchMetricDataQuery[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetric.
- * Use `create(CloudWatchMetricSchema)` to create a new message.
- */
-export const CloudWatchMetricSchema: GenMessage<CloudWatchMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 9);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricDataQuery
- */
-export type CloudWatchMetricDataQuery = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricDataQuery"> & {
-  /**
-   * @generated from field: optional string id = 1;
-   */
-  id: string;
-
-  /**
-   * @generated from field: optional string expression = 2;
-   */
-  expression: string;
-
-  /**
-   * @generated from field: optional string label = 3;
-   */
-  label: string;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStat metricStat = 4;
-   */
-  metricStat?: CloudWatchMetricStat;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString period = 5;
-   */
-  period?: IntOrString;
-
-  /**
-   * @generated from field: optional bool returnData = 6;
-   */
-  returnData: boolean;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricDataQuery.
- * Use `create(CloudWatchMetricDataQuerySchema)` to create a new message.
- */
-export const CloudWatchMetricDataQuerySchema: GenMessage<CloudWatchMetricDataQuery> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 10);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStat
- */
-export type CloudWatchMetricStat = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStat"> & {
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetric metric = 1;
-   */
-  metric?: CloudWatchMetricStatMetric;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString period = 2;
-   */
-  period?: IntOrString;
-
-  /**
-   * @generated from field: optional string stat = 3;
-   */
-  stat: string;
-
-  /**
-   * @generated from field: optional string unit = 4;
-   */
-  unit: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStat.
- * Use `create(CloudWatchMetricStatSchema)` to create a new message.
- */
-export const CloudWatchMetricStatSchema: GenMessage<CloudWatchMetricStat> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 11);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetric
- */
-export type CloudWatchMetricStatMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetric"> & {
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetricDimension dimensions = 1;
-   */
-  dimensions: CloudWatchMetricStatMetricDimension[];
-
-  /**
-   * @generated from field: optional string metricName = 2;
-   */
-  metricName: string;
-
-  /**
-   * @generated from field: optional string namespace = 3;
-   */
-  namespace: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetric.
- * Use `create(CloudWatchMetricStatMetricSchema)` to create a new message.
- */
-export const CloudWatchMetricStatMetricSchema: GenMessage<CloudWatchMetricStatMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 12);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetricDimension
- */
-export type CloudWatchMetricStatMetricDimension = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetricDimension"> & {
-  /**
-   * @generated from field: optional string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: optional string value = 2;
-   */
-  value: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetricStatMetricDimension.
- * Use `create(CloudWatchMetricStatMetricDimensionSchema)` to create a new message.
- */
-export const CloudWatchMetricStatMetricDimensionSchema: GenMessage<CloudWatchMetricStatMetricDimension> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 13);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate
- */
-export type ClusterAnalysisTemplate = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
-   */
-  metadata?: ObjectMeta;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.AnalysisTemplateSpec spec = 2;
-   */
-  spec?: AnalysisTemplateSpec;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate.
- * Use `create(ClusterAnalysisTemplateSchema)` to create a new message.
- */
-export const ClusterAnalysisTemplateSchema: GenMessage<ClusterAnalysisTemplate> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 14);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplateList
- */
-export type ClusterAnalysisTemplateList = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplateList"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
-   */
-  metadata?: ListMeta;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplate items = 2;
-   */
-  items: ClusterAnalysisTemplate[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ClusterAnalysisTemplateList.
- * Use `create(ClusterAnalysisTemplateListSchema)` to create a new message.
- */
-export const ClusterAnalysisTemplateListSchema: GenMessage<ClusterAnalysisTemplateList> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 15);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DatadogMetric
- */
-export type DatadogMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DatadogMetric"> & {
-  /**
-   * @generated from field: optional string interval = 1;
-   */
-  interval: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-
-  /**
-   * @generated from field: map<string, string> queries = 3;
-   */
-  queries: { [key: string]: string };
-
-  /**
-   * @generated from field: optional string formula = 4;
-   */
-  formula: string;
-
-  /**
-   * @generated from field: optional string apiVersion = 5;
-   */
-  apiVersion: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DatadogMetric.
- * Use `create(DatadogMetricSchema)` to create a new message.
- */
-export const DatadogMetricSchema: GenMessage<DatadogMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 16);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DryRun
- */
-export type DryRun = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DryRun"> & {
-  /**
-   * @generated from field: optional string metricName = 1;
-   */
-  metricName: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DryRun.
- * Use `create(DryRunSchema)` to create a new message.
- */
-export const DryRunSchema: GenMessage<DryRun> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 17);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.FieldRef
- */
-export type FieldRef = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.FieldRef"> & {
-  /**
-   * Required: Path of the field to select in the specified API version
-   *
-   * @generated from field: optional string fieldPath = 1;
-   */
-  fieldPath: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.FieldRef.
- * Use `create(FieldRefSchema)` to create a new message.
- */
-export const FieldRefSchema: GenMessage<FieldRef> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 18);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.GraphiteMetric
- */
-export type GraphiteMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.GraphiteMetric"> & {
-  /**
-   * @generated from field: optional string address = 1;
-   */
-  address: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.GraphiteMetric.
- * Use `create(GraphiteMetricSchema)` to create a new message.
- */
-export const GraphiteMetricSchema: GenMessage<GraphiteMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 19);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.InfluxdbMetric
- */
-export type InfluxdbMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.InfluxdbMetric"> & {
-  /**
-   * @generated from field: optional string profile = 1;
-   */
-  profile: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.InfluxdbMetric.
- * Use `create(InfluxdbMetricSchema)` to create a new message.
- */
-export const InfluxdbMetricSchema: GenMessage<InfluxdbMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 20);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.JobMetric
- */
-export type JobMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.JobMetric"> & {
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
-   */
-  metadata?: ObjectMeta;
-
-  /**
-   * @generated from field: optional k8s.io.api.batch.v1.JobSpec spec = 2;
-   */
-  spec?: JobSpec;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.JobMetric.
- * Use `create(JobMetricSchema)` to create a new message.
- */
-export const JobMetricSchema: GenMessage<JobMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 21);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaMetric
- */
-export type KayentaMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaMetric"> & {
-  /**
-   * @generated from field: optional string address = 1;
-   */
-  address: string;
-
-  /**
-   * @generated from field: optional string application = 2;
-   */
-  application: string;
-
-  /**
-   * @generated from field: optional string canaryConfigName = 3;
-   */
-  canaryConfigName: string;
-
-  /**
-   * @generated from field: optional string metricsAccountName = 4;
-   */
-  metricsAccountName: string;
-
-  /**
-   * @generated from field: optional string configurationAccountName = 5;
-   */
-  configurationAccountName: string;
-
-  /**
-   * @generated from field: optional string storageAccountName = 6;
-   */
-  storageAccountName: string;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaThreshold threshold = 7;
-   */
-  threshold?: KayentaThreshold;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaScope scopes = 8;
-   */
-  scopes: KayentaScope[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaMetric.
- * Use `create(KayentaMetricSchema)` to create a new message.
- */
-export const KayentaMetricSchema: GenMessage<KayentaMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 22);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaScope
- */
-export type KayentaScope = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaScope"> & {
-  /**
-   * @generated from field: optional string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ScopeDetail controlScope = 2;
-   */
-  controlScope?: ScopeDetail;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ScopeDetail experimentScope = 3;
-   */
-  experimentScope?: ScopeDetail;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaScope.
- * Use `create(KayentaScopeSchema)` to create a new message.
- */
-export const KayentaScopeSchema: GenMessage<KayentaScope> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 23);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaThreshold
- */
-export type KayentaThreshold = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaThreshold"> & {
-  /**
-   * @generated from field: optional int64 pass = 1;
-   */
-  pass: bigint;
-
-  /**
-   * @generated from field: optional int64 marginal = 2;
-   */
-  marginal: bigint;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaThreshold.
- * Use `create(KayentaThresholdSchema)` to create a new message.
- */
-export const KayentaThresholdSchema: GenMessage<KayentaThreshold> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 24);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Measurement
- */
-export type Measurement = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Measurement"> & {
-  /**
-   * @generated from field: optional string phase = 1;
-   */
-  phase: string;
-
-  /**
-   * @generated from field: optional string message = 2;
-   */
-  message: string;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 3;
-   */
-  startedAt?: Time;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time finishedAt = 4;
-   */
-  finishedAt?: Time;
-
-  /**
-   * @generated from field: optional string value = 5;
-   */
-  value: string;
-
-  /**
-   * @generated from field: map<string, string> metadata = 6;
-   */
-  metadata: { [key: string]: string };
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.apis.meta.v1.Time resumeAt = 7;
-   */
-  resumeAt?: Time;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Measurement.
- * Use `create(MeasurementSchema)` to create a new message.
- */
-export const MeasurementSchema: GenMessage<Measurement> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 25);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MeasurementRetention
- */
-export type MeasurementRetention = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MeasurementRetention"> & {
-  /**
-   * @generated from field: optional string metricName = 1;
-   */
-  metricName: string;
-
-  /**
-   * @generated from field: optional int32 limit = 2;
-   */
-  limit: number;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MeasurementRetention.
- * Use `create(MeasurementRetentionSchema)` to create a new message.
- */
-export const MeasurementRetentionSchema: GenMessage<MeasurementRetention> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 26);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Metric
- */
-export type Metric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Metric"> & {
-  /**
-   * @generated from field: optional string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: optional string interval = 2;
-   */
-  interval: string;
-
-  /**
-   * @generated from field: optional string initialDelay = 3;
-   */
-  initialDelay: string;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString count = 4;
-   */
-  count?: IntOrString;
-
-  /**
-   * @generated from field: optional string successCondition = 5;
-   */
-  successCondition: string;
-
-  /**
-   * @generated from field: optional string failureCondition = 6;
-   */
-  failureCondition: string;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString failureLimit = 7;
-   */
-  failureLimit?: IntOrString;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString inconclusiveLimit = 8;
-   */
-  inconclusiveLimit?: IntOrString;
-
-  /**
-   * @generated from field: optional k8s.io.apimachinery.pkg.util.intstr.IntOrString consecutiveErrorLimit = 9;
-   */
-  consecutiveErrorLimit?: IntOrString;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricProvider provider = 10;
-   */
-  provider?: MetricProvider;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Metric.
- * Use `create(MetricSchema)` to create a new message.
- */
-export const MetricSchema: GenMessage<Metric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 27);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricProvider
- */
-export type MetricProvider = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricProvider"> & {
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.PrometheusMetric prometheus = 1;
-   */
-  prometheus?: PrometheusMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.KayentaMetric kayenta = 2;
-   */
-  kayenta?: KayentaMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetric web = 3;
-   */
-  web?: WebMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.DatadogMetric datadog = 4;
-   */
-  datadog?: DatadogMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WavefrontMetric wavefront = 5;
-   */
-  wavefront?: WavefrontMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.NewRelicMetric newRelic = 6;
-   */
-  newRelic?: NewRelicMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.JobMetric job = 7;
-   */
-  job?: JobMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.CloudWatchMetric cloudWatch = 8;
-   */
-  cloudWatch?: CloudWatchMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.GraphiteMetric graphite = 9;
-   */
-  graphite?: GraphiteMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.InfluxdbMetric influxdb = 10;
-   */
-  influxdb?: InfluxdbMetric;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SkyWalkingMetric skywalking = 11;
-   */
-  skywalking?: SkyWalkingMetric;
-
-  /**
-   * @generated from field: map<string, bytes> plugin = 12;
-   */
-  plugin: { [key: string]: Uint8Array };
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricProvider.
- * Use `create(MetricProviderSchema)` to create a new message.
- */
-export const MetricProviderSchema: GenMessage<MetricProvider> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 28);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricResult
- */
-export type MetricResult = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricResult"> & {
-  /**
-   * @generated from field: optional string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: optional string phase = 2;
-   */
-  phase: string;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Measurement measurements = 3;
-   */
-  measurements: Measurement[];
-
-  /**
-   * @generated from field: optional string message = 4;
-   */
-  message: string;
-
-  /**
-   * @generated from field: optional int32 count = 5;
-   */
-  count: number;
-
-  /**
-   * @generated from field: optional int32 successful = 6;
-   */
-  successful: number;
-
-  /**
-   * @generated from field: optional int32 failed = 7;
-   */
-  failed: number;
-
-  /**
-   * @generated from field: optional int32 inconclusive = 8;
-   */
-  inconclusive: number;
-
-  /**
-   * @generated from field: optional int32 error = 9;
-   */
-  error: number;
-
-  /**
-   * @generated from field: optional int32 consecutiveError = 10;
-   */
-  consecutiveError: number;
-
-  /**
-   * @generated from field: optional bool dryRun = 11;
-   */
-  dryRun: boolean;
-
-  /**
-   * @generated from field: map<string, string> metadata = 12;
-   */
-  metadata: { [key: string]: string };
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.MetricResult.
- * Use `create(MetricResultSchema)` to create a new message.
- */
-export const MetricResultSchema: GenMessage<MetricResult> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 29);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.NewRelicMetric
- */
-export type NewRelicMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.NewRelicMetric"> & {
-  /**
-   * @generated from field: optional string profile = 1;
-   */
-  profile: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.NewRelicMetric.
- * Use `create(NewRelicMetricSchema)` to create a new message.
- */
-export const NewRelicMetricSchema: GenMessage<NewRelicMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 30);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.OAuth2Config
- */
-export type OAuth2Config = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.OAuth2Config"> & {
-  /**
-   * @generated from field: optional string tokenUrl = 1;
-   */
-  tokenUrl: string;
-
-  /**
-   * @generated from field: optional string clientId = 2;
-   */
-  clientId: string;
-
-  /**
-   * @generated from field: optional string clientSecret = 3;
-   */
-  clientSecret: string;
-
-  /**
-   * @generated from field: repeated string scopes = 4;
-   */
-  scopes: string[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.OAuth2Config.
- * Use `create(OAuth2ConfigSchema)` to create a new message.
- */
-export const OAuth2ConfigSchema: GenMessage<OAuth2Config> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 31);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.PrometheusMetric
- */
-export type PrometheusMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.PrometheusMetric"> & {
-  /**
-   * @generated from field: optional string address = 1;
-   */
-  address: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Authentication authentication = 3;
-   */
-  authentication?: Authentication;
-
-  /**
-   * @generated from field: optional int64 timeout = 4;
-   */
-  timeout: bigint;
-
-  /**
-   * @generated from field: optional bool insecure = 5;
-   */
-  insecure: boolean;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetricHeader headers = 6;
-   */
-  headers: WebMetricHeader[];
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.PrometheusMetric.
- * Use `create(PrometheusMetricSchema)` to create a new message.
- */
-export const PrometheusMetricSchema: GenMessage<PrometheusMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 32);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.RunSummary
- */
-export type RunSummary = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.RunSummary"> & {
-  /**
-   * @generated from field: optional int32 count = 1;
-   */
-  count: number;
-
-  /**
-   * @generated from field: optional int32 successful = 2;
-   */
-  successful: number;
-
-  /**
-   * @generated from field: optional int32 failed = 3;
-   */
-  failed: number;
-
-  /**
-   * @generated from field: optional int32 inconclusive = 4;
-   */
-  inconclusive: number;
-
-  /**
-   * @generated from field: optional int32 error = 5;
-   */
-  error: number;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.RunSummary.
- * Use `create(RunSummarySchema)` to create a new message.
- */
-export const RunSummarySchema: GenMessage<RunSummary> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 33);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ScopeDetail
- */
-export type ScopeDetail = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ScopeDetail"> & {
-  /**
-   * @generated from field: optional string scope = 1;
-   */
-  scope: string;
-
-  /**
-   * @generated from field: optional string region = 2;
-   */
-  region: string;
-
-  /**
-   * @generated from field: optional int64 step = 3;
-   */
-  step: bigint;
-
-  /**
-   * @generated from field: optional string start = 4;
-   */
-  start: string;
-
-  /**
-   * @generated from field: optional string end = 5;
-   */
-  end: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ScopeDetail.
- * Use `create(ScopeDetailSchema)` to create a new message.
- */
-export const ScopeDetailSchema: GenMessage<ScopeDetail> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 34);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SecretKeyRef
- */
-export type SecretKeyRef = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SecretKeyRef"> & {
-  /**
-   * @generated from field: optional string name = 1;
-   */
-  name: string;
-
-  /**
-   * @generated from field: optional string key = 2;
-   */
-  key: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SecretKeyRef.
- * Use `create(SecretKeyRefSchema)` to create a new message.
- */
-export const SecretKeyRefSchema: GenMessage<SecretKeyRef> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 35);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Sigv4Config
- */
-export type Sigv4Config = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Sigv4Config"> & {
-  /**
-   * @generated from field: optional string region = 1;
-   */
-  region: string;
-
-  /**
-   * @generated from field: optional string profile = 2;
-   */
-  profile: string;
-
-  /**
-   * @generated from field: optional string roleArn = 3;
-   */
-  roleArn: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Sigv4Config.
- * Use `create(Sigv4ConfigSchema)` to create a new message.
- */
-export const Sigv4ConfigSchema: GenMessage<Sigv4Config> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 36);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SkyWalkingMetric
- */
-export type SkyWalkingMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SkyWalkingMetric"> & {
-  /**
-   * @generated from field: optional string address = 1;
-   */
-  address: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-
-  /**
-   * @generated from field: optional string interval = 3;
-   */
-  interval: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SkyWalkingMetric.
- * Use `create(SkyWalkingMetricSchema)` to create a new message.
- */
-export const SkyWalkingMetricSchema: GenMessage<SkyWalkingMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 37);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ValueFrom
- */
-export type ValueFrom = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ValueFrom"> & {
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.SecretKeyRef secretKeyRef = 1;
-   */
-  secretKeyRef?: SecretKeyRef;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.FieldRef fieldRef = 2;
-   */
-  fieldRef?: FieldRef;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.ValueFrom.
- * Use `create(ValueFromSchema)` to create a new message.
- */
-export const ValueFromSchema: GenMessage<ValueFrom> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 38);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WavefrontMetric
- */
-export type WavefrontMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WavefrontMetric"> & {
-  /**
-   * @generated from field: optional string address = 1;
-   */
-  address: string;
-
-  /**
-   * @generated from field: optional string query = 2;
-   */
-  query: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WavefrontMetric.
- * Use `create(WavefrontMetricSchema)` to create a new message.
- */
-export const WavefrontMetricSchema: GenMessage<WavefrontMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 39);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetric
- */
-export type WebMetric = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetric"> & {
-  /**
-   * @generated from field: optional string method = 1;
-   */
-  method: string;
-
-  /**
-   * URL is the address of the web metric
-   *
-   * @generated from field: optional string url = 2;
-   */
-  url: string;
-
-  /**
-   * @generated from field: repeated github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetricHeader headers = 3;
-   */
-  headers: WebMetricHeader[];
-
-  /**
-   * @generated from field: optional string body = 4;
-   */
-  body: string;
-
-  /**
-   * @generated from field: optional int64 timeoutSeconds = 5;
-   */
-  timeoutSeconds: bigint;
-
-  /**
-   * @generated from field: optional string jsonPath = 6;
-   */
-  jsonPath: string;
-
-  /**
-   * @generated from field: optional bool insecure = 7;
-   */
-  insecure: boolean;
-
-  /**
-   * @generated from field: optional bytes jsonBody = 8;
-   */
-  jsonBody: Uint8Array;
-
-  /**
-   * @generated from field: optional github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.Authentication authentication = 9;
-   */
-  authentication?: Authentication;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetric.
- * Use `create(WebMetricSchema)` to create a new message.
- */
-export const WebMetricSchema: GenMessage<WebMetric> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 40);
-
-/**
- * @generated from message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetricHeader
- */
-export type WebMetricHeader = Message<"github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetricHeader"> & {
-  /**
-   * @generated from field: optional string key = 1;
-   */
-  key: string;
-
-  /**
-   * @generated from field: optional string value = 2;
-   */
-  value: string;
-};
-
-/**
- * Describes the message github.com.akuity.kargo.internal.controller.rollouts.api.v1alpha1.WebMetricHeader.
- * Use `create(WebMetricHeaderSchema)` to create a new message.
- */
-export const WebMetricHeaderSchema: GenMessage<WebMetricHeader> = /*@__PURE__*/
-  messageDesc(file_rollouts_api_v1alpha1_generated, 41);
-
diff --git a/ui/src/gen/schema/clusterpromotiontasks.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/clusterpromotiontasks.kargo.akuity.io_v1alpha1.json
index 9ba1c399..33108dcf 100644
--- a/ui/src/gen/schema/clusterpromotiontasks.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/clusterpromotiontasks.kargo.akuity.io_v1alpha1.json
@@ -25,7 +25,7 @@
                 "type": "string"
               },
               "config": {
-                "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/references/expression-language for details.",
+                "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                 "x-kubernetes-preserve-unknown-fields": true
               },
               "if": {
@@ -90,7 +90,7 @@
                       "type": "string"
                     },
                     "value": {
-                      "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                      "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                       "type": "string"
                     }
                   },
@@ -125,7 +125,7 @@
                 "type": "string"
               },
               "value": {
-                "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                 "type": "string"
               }
             },
diff --git a/ui/src/gen/schema/promotions.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/promotions.kargo.akuity.io_v1alpha1.json
index fa8c7cff..ed8573eb 100644
--- a/ui/src/gen/schema/promotions.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/promotions.kargo.akuity.io_v1alpha1.json
@@ -40,7 +40,7 @@
                 "type": "string"
               },
               "config": {
-                "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/references/expression-language for details.",
+                "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                 "x-kubernetes-preserve-unknown-fields": true
               },
               "if": {
@@ -105,7 +105,7 @@
                       "type": "string"
                     },
                     "value": {
-                      "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                      "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                       "type": "string"
                     }
                   },
@@ -140,7 +140,7 @@
                 "type": "string"
               },
               "value": {
-                "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                 "type": "string"
               }
             },
diff --git a/ui/src/gen/schema/promotiontasks.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/promotiontasks.kargo.akuity.io_v1alpha1.json
index 3ff92ed0..396f2e15 100644
--- a/ui/src/gen/schema/promotiontasks.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/promotiontasks.kargo.akuity.io_v1alpha1.json
@@ -25,7 +25,7 @@
                 "type": "string"
               },
               "config": {
-                "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/references/expression-language for details.",
+                "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                 "x-kubernetes-preserve-unknown-fields": true
               },
               "if": {
@@ -90,7 +90,7 @@
                       "type": "string"
                     },
                     "value": {
-                      "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                      "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                       "type": "string"
                     }
                   },
@@ -125,7 +125,7 @@
                 "type": "string"
               },
               "value": {
-                "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                 "type": "string"
               }
             },
diff --git a/ui/src/gen/schema/stages.kargo.akuity.io_v1alpha1.json b/ui/src/gen/schema/stages.kargo.akuity.io_v1alpha1.json
index 64e6549a..21c95792 100644
--- a/ui/src/gen/schema/stages.kargo.akuity.io_v1alpha1.json
+++ b/ui/src/gen/schema/stages.kargo.akuity.io_v1alpha1.json
@@ -32,7 +32,7 @@
                         "type": "string"
                       },
                       "config": {
-                        "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/references/expression-language for details.",
+                        "description": "Config is opaque configuration for the PromotionStep that is understood\nonly by each PromotionStep's implementation. It is legal to utilize\nexpressions in defining values at any level of this block.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                         "x-kubernetes-preserve-unknown-fields": true
                       },
                       "if": {
@@ -97,7 +97,7 @@
                               "type": "string"
                             },
                             "value": {
-                              "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                              "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                               "type": "string"
                             }
                           },
@@ -132,7 +132,7 @@
                         "type": "string"
                       },
                       "value": {
-                        "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/references/expression-language for details.",
+                        "description": "Value is the value of the variable. It is allowed to utilize expressions\nin the value.\nSee https://docs.kargo.io/user-guide/reference-docs/expressions for details.",
                         "type": "string"
                       }
                     },
diff --git a/ui/src/pages/login/login.tsx b/ui/src/pages/login/login.tsx
index 388361c0..6ce21d98 100644
--- a/ui/src/pages/login/login.tsx
+++ b/ui/src/pages/login/login.tsx
@@ -9,7 +9,7 @@ import { useAuthContext } from '@ui/features/auth/context/use-auth-context';
 import { OIDCLogin } from '@ui/features/auth/oidc-login';
 import { LoadingState } from '@ui/features/common';
 import { KargoLogo } from '@ui/features/common/logo/logo';
-import { getPublicConfig } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
+import { getPublicConfig } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
 
 import * as styles from './login.module.less';
 
diff --git a/ui/src/pages/project.tsx b/ui/src/pages/project.tsx
index 69baec05..f6c91471 100644
--- a/ui/src/pages/project.tsx
+++ b/ui/src/pages/project.tsx
@@ -22,8 +22,11 @@ import { Events } from '@ui/features/project/events/events';
 import { Pipelines } from '@ui/features/project/pipelines/pipelines';
 import { Roles } from '@ui/features/project/roles/roles';
 import { ProjectSettings } from '@ui/features/project/settings/project-settings';
-import { getConfig, getProject } from '@ui/gen/service/v1alpha1/service-KargoService_connectquery';
-import { Project as _Project } from '@ui/gen/v1alpha1/generated_pb';
+import {
+  getConfig,
+  getProject
+} from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
+import { Project as _Project } from '@ui/gen/api/v1alpha1/generated_pb';
 
 export const Project = ({
   tab = 'pipelines',
diff --git a/ui/src/plugins/argocd-plugin/argocd-plugin.tsx b/ui/src/plugins/argocd-plugin/argocd-plugin.tsx
deleted file mode 100644
index a8fe2905..00000000
--- a/ui/src/plugins/argocd-plugin/argocd-plugin.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { PluginsInstallation } from '../atoms/plugin-interfaces';
-
-import promotionDeepLinkPlugin from './deep-link/promotion';
-
-const plugin: PluginsInstallation = {
-  DeepLinkPlugin: {
-    Promotion: promotionDeepLinkPlugin
-  }
-};
-
-export default plugin;
diff --git a/ui/src/plugins/argocd-plugin/deep-link/promotion.tsx b/ui/src/plugins/argocd-plugin/deep-link/promotion.tsx
deleted file mode 100644
index 981639ef..00000000
--- a/ui/src/plugins/argocd-plugin/deep-link/promotion.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Dropdown, Space, Tooltip } from 'antd';
-
-import { getPromotionHealthCheckConfig } from '@ui/plugins/atoms/plugin-helper';
-import { DeepLinkPluginsInstallation } from '@ui/plugins/atoms/plugin-interfaces';
-
-const plugin: DeepLinkPluginsInstallation['Promotion'] = {
-  shouldRender(opts) {
-    return (
-      Boolean(opts?.isLatestPromotion) &&
-      Boolean(opts.promotion?.spec?.steps?.find((step) => step?.uses === 'argocd-update')) &&
-      (opts.promotion?.status?.healthChecks?.length || 0) > 0
-    );
-  },
-  render(props) {
-    if (!props.unstable_argocdShardUrl) {
-      return (
-        <Tooltip title='Unknown ArgoCD shard' className='cursor-pointer text-xs text-gray-400'>
-          ArgoCD
-        </Tooltip>
-      );
-    }
-
-    // argocd shards sometimes might have base path included
-    // in those cases, we must not omit those pathname in order to have valid
-    const unstable_argocdShardUrl = props.unstable_argocdShardUrl.endsWith('/')
-      ? props.unstable_argocdShardUrl.slice(0, -1)
-      : props.unstable_argocdShardUrl;
-
-    const healthChecks = (props.promotion?.status?.healthChecks || []).filter(
-      (hc) => hc?.uses === 'argocd-update'
-    );
-
-    // health checks contains nested apps
-    // ie. healthChecks:
-    // - uses: argocd-update
-    //   config:
-    //     apps:
-    //       - name: app
-    //         namespace: ns
-    const apps = [];
-
-    for (const healthCheck of healthChecks) {
-      const healthCheckConfig = getPromotionHealthCheckConfig(healthCheck);
-
-      // @ts-expect-error we don't have type but as long as we are sure whats coming in.. its safe to assume
-      for (const app of healthCheckConfig?.apps || []) {
-        apps.push(app);
-      }
-    }
-
-    if (apps.length === 1) {
-      return (
-        <a
-          target='_blank'
-          href={`${unstable_argocdShardUrl}/applications/${apps[0].namespace}/${apps[0].name}`}
-        >
-          ArgoCD
-        </a>
-      );
-    }
-
-    return (
-      <Dropdown
-        menu={{
-          items: apps.map((app, idx) => ({
-            key: idx,
-            label: (
-              <a
-                target='_blank'
-                href={`${unstable_argocdShardUrl}/applications/${app.namespace}/${app.name}`}
-              >
-                {app.namespace} - {app.name}
-              </a>
-            )
-          }))
-        }}
-      >
-        <a onClick={(e) => e.preventDefault()}>
-          <Space>
-            ArgoCD
-            <FontAwesomeIcon icon={faChevronDown} className='text-xs' />
-          </Space>
-        </a>
-      </Dropdown>
-    );
-  }
-};
-
-export default plugin;
diff --git a/ui/src/plugins/atoms/plugin-helper.ts b/ui/src/plugins/atoms/plugin-helper.ts
index af7c1791..6c87eb59 100644
--- a/ui/src/plugins/atoms/plugin-helper.ts
+++ b/ui/src/plugins/atoms/plugin-helper.ts
@@ -1,4 +1,4 @@
-import { HealthCheckStep, Promotion, PromotionStep } from '@ui/gen/v1alpha1/generated_pb';
+import { HealthCheckStep, Promotion, PromotionStep } from '@ui/gen/api/v1alpha1/generated_pb';
 import { decodeRawData } from '@ui/utils/decode-raw-data';
 
 export const getPromotionStepConfig = (step: PromotionStep): Record<string, unknown> =>
diff --git a/ui/src/plugins/atoms/plugin-interfaces.ts b/ui/src/plugins/atoms/plugin-interfaces.ts
index e6cff5f7..c345814f 100644
--- a/ui/src/plugins/atoms/plugin-interfaces.ts
+++ b/ui/src/plugins/atoms/plugin-interfaces.ts
@@ -12,7 +12,7 @@
 import { ReactNode } from 'react';
 
 import { PromotionDirectiveStepStatus } from '@ui/features/common/promotion-directive-step-status/utils';
-import { Promotion, PromotionStep } from '@ui/gen/v1alpha1/generated_pb';
+import { Promotion, PromotionStep } from '@ui/gen/api/v1alpha1/generated_pb';
 
 interface DeepLinksPluginProps {
   PromotionStep: {
diff --git a/ui/src/plugins/index.tsx b/ui/src/plugins/index.tsx
index 528eb1d9..2f67feb8 100644
--- a/ui/src/plugins/index.tsx
+++ b/ui/src/plugins/index.tsx
@@ -1,7 +1,6 @@
-import argocdPlugin from './argocd-plugin/argocd-plugin';
 import { PluginsInstallation } from './atoms/plugin-interfaces';
 import prPlugin from './pr-plugin/pr-plugin';
 
-const plugins: PluginsInstallation[] = [prPlugin, argocdPlugin];
+const plugins: PluginsInstallation[] = [prPlugin];
 
 export default plugins;
diff --git a/ui/src/plugins/pr-plugin/get-pr-link.ts b/ui/src/plugins/pr-plugin/get-pr-link.ts
index 647140f3..1a911760 100644
--- a/ui/src/plugins/pr-plugin/get-pr-link.ts
+++ b/ui/src/plugins/pr-plugin/get-pr-link.ts
@@ -1,6 +1,6 @@
 import gitUrlParse from 'git-url-parse';
 
-import { PromotionStep } from '@ui/gen/v1alpha1/generated_pb';
+import { PromotionStep } from '@ui/gen/api/v1alpha1/generated_pb';
 import { getPromotionStepConfig } from '@ui/plugins/atoms/plugin-helper';
 
 export const getPullRequestLink = (



Test patch:
diff --git a/internal/api/finalizers_test.go b/internal/api/finalizers_test.go
index 8fd30340..e14d95cb 100644
--- a/internal/api/finalizers_test.go
+++ b/internal/api/finalizers_test.go
@@ -224,3 +224,80 @@ func Test_patchAnnotation(t *testing.T) {
 		})
 	}
 }
+
+func Test_deleteAnnotation(t *testing.T) {
+	scheme := k8sruntime.NewScheme()
+	require.NoError(t, kargoapi.SchemeBuilder.AddToScheme(scheme))
+
+	newFakeClient := func(obj ...client.Object) client.Client {
+		return fake.NewClientBuilder().
+			WithScheme(scheme).
+			WithObjects(obj...).
+			Build()
+	}
+
+	testCases := map[string]struct {
+		obj         client.Object
+		client      client.Client
+		key         string
+		value       string
+		errExpected bool
+	}{
+		"stage without annotation": {
+			obj: &kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "stage",
+				},
+			},
+			client: newFakeClient(&kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "stage",
+				},
+			}),
+			key: "key",
+		},
+		"stage with existing annotation": {
+			obj: &kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "stage",
+				},
+			},
+			client: newFakeClient(&kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "stage",
+					Annotations: map[string]string{
+						"key": "value",
+					},
+				},
+			}),
+			key: "key",
+		},
+		"non-existing stage": {
+			obj: &kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "stage",
+				},
+			},
+			client:      newFakeClient(),
+			key:         "key",
+			value:       "value",
+			errExpected: true,
+		},
+	}
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			err := deleteAnnotation(context.Background(), tc.client, tc.obj, tc.key)
+			if tc.errExpected {
+				require.Error(t, err)
+				return
+			}
+			require.NotContains(t, tc.obj.GetAnnotations(), tc.key)
+		})
+	}
+}
diff --git a/internal/api/stage_test.go b/internal/api/stage_test.go
index 1c7f7d58..ebedcef1 100644
--- a/internal/api/stage_test.go
+++ b/internal/api/stage_test.go
@@ -7,6 +7,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
+	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	k8sruntime "k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
@@ -551,3 +552,85 @@ func TestAbortStageFreightVerification(t *testing.T) {
 		}).String(), stage.Annotations[kargoapi.AnnotationKeyAbort])
 	})
 }
+
+func TestAnnotateStageWithArgoCDContext(t *testing.T) {
+	scheme := k8sruntime.NewScheme()
+	require.NoError(t, kargoapi.SchemeBuilder.AddToScheme(scheme))
+
+	t.Run("not found", func(t *testing.T) {
+		c := fake.NewClientBuilder().WithScheme(scheme).Build()
+
+		err := AnnotateStageWithArgoCDContext(context.TODO(), c, []kargoapi.HealthCheckStep{}, &kargoapi.Stage{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fake-stage",
+				Namespace: "fake-namespace",
+			},
+		})
+		require.ErrorContains(t, err, "not found")
+	})
+
+	t.Run("success", func(t *testing.T) {
+		c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(
+			&kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "fake-stage",
+					Namespace: "fake-namespace",
+				},
+			},
+		).Build()
+
+		err := AnnotateStageWithArgoCDContext(context.TODO(), c, []kargoapi.HealthCheckStep{
+			{
+				Uses: "argocd-update",
+				Config: &apiextensionsv1.JSON{
+					Raw: []byte(`{"apps": [{"name": "fake-argo-app", "namespace": "fake-argo-namespace"}]}`),
+				},
+			},
+		}, &kargoapi.Stage{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fake-stage",
+				Namespace: "fake-namespace",
+			},
+		})
+		require.NoError(t, err)
+
+		stage, err := GetStage(context.TODO(), c, types.NamespacedName{
+			Namespace: "fake-namespace",
+			Name:      "fake-stage",
+		})
+		require.NoError(t, err)
+		require.Equal(t,
+			`[{"name":"fake-argo-app","namespace":"fake-argo-namespace"}]`,
+			stage.Annotations[kargoapi.AnnotationKeyArgoCDContext])
+	})
+
+	t.Run("no ArgoCD apps", func(t *testing.T) {
+		c := fake.NewClientBuilder().WithScheme(scheme).WithObjects(
+			&kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "fake-stage",
+					Namespace: "fake-namespace",
+					Annotations: map[string]string{
+						kargoapi.AnnotationKeyArgoCDContext: "fake-annotation",
+					},
+				},
+			},
+		).Build()
+
+		err := AnnotateStageWithArgoCDContext(context.TODO(), c, []kargoapi.HealthCheckStep{}, &kargoapi.Stage{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fake-stage",
+				Namespace: "fake-namespace",
+			},
+		})
+		require.NoError(t, err)
+
+		stage, err := GetStage(context.TODO(), c, types.NamespacedName{
+			Namespace: "fake-namespace",
+			Name:      "fake-stage",
+		})
+		require.NoError(t, err)
+
+		require.NotContains(t, stage.Annotations, kargoapi.AnnotationKeyArgoCDContext)
+	})
+}
diff --git a/internal/controller/rollouts/api/v1alpha1/analysis_helpers_test.go b/internal/api/stubs/rollouts/analysis_test.go
similarity index 73%
rename from internal/controller/rollouts/api/v1alpha1/analysis_helpers_test.go
rename to internal/api/stubs/rollouts/analysis_test.go
index 766797f7..01f1ad89 100644
--- a/internal/controller/rollouts/api/v1alpha1/analysis_helpers_test.go
+++ b/internal/api/stubs/rollouts/analysis_test.go
@@ -1,4 +1,4 @@
-package v1alpha1
+package rollouts
 
 import (
 	"context"
@@ -10,21 +10,23 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func TestGetAnalysisTemplate(t *testing.T) {
 	scheme := k8sruntime.NewScheme()
-	require.NoError(t, SchemeBuilder.AddToScheme(scheme))
+	require.NoError(t, rolloutsapi.SchemeBuilder.AddToScheme(scheme))
 
 	testCases := []struct {
 		name       string
 		client     client.Client
-		assertions func(*testing.T, *AnalysisTemplate, error)
+		assertions func(*testing.T, *rolloutsapi.AnalysisTemplate, error)
 	}{
 		{
 			name:   "not found",
 			client: fake.NewClientBuilder().WithScheme(scheme).Build(),
-			assertions: func(t *testing.T, template *AnalysisTemplate, err error) {
+			assertions: func(t *testing.T, template *rolloutsapi.AnalysisTemplate, err error) {
 				require.NoError(t, err)
 				require.Nil(t, template)
 			},
@@ -33,14 +35,14 @@ func TestGetAnalysisTemplate(t *testing.T) {
 		{
 			name: "found",
 			client: fake.NewClientBuilder().WithScheme(scheme).WithObjects(
-				&AnalysisTemplate{
+				&rolloutsapi.AnalysisTemplate{
 					ObjectMeta: metav1.ObjectMeta{
 						Name:      "fake-template",
 						Namespace: "fake-namespace",
 					},
 				},
 			).Build(),
-			assertions: func(t *testing.T, template *AnalysisTemplate, err error) {
+			assertions: func(t *testing.T, template *rolloutsapi.AnalysisTemplate, err error) {
 				require.NoError(t, err)
 				require.Equal(t, "fake-template", template.Name)
 				require.Equal(t, "fake-namespace", template.Namespace)
@@ -65,17 +67,17 @@ func TestGetAnalysisTemplate(t *testing.T) {
 
 func TestGetClusterAnalysisTemplate(t *testing.T) {
 	scheme := k8sruntime.NewScheme()
-	require.NoError(t, SchemeBuilder.AddToScheme(scheme))
+	require.NoError(t, rolloutsapi.SchemeBuilder.AddToScheme(scheme))
 
 	testCases := []struct {
 		name       string
 		client     client.Client
-		assertions func(*testing.T, *ClusterAnalysisTemplate, error)
+		assertions func(*testing.T, *rolloutsapi.ClusterAnalysisTemplate, error)
 	}{
 		{
 			name:   "not found",
 			client: fake.NewClientBuilder().WithScheme(scheme).Build(),
-			assertions: func(t *testing.T, template *ClusterAnalysisTemplate, err error) {
+			assertions: func(t *testing.T, template *rolloutsapi.ClusterAnalysisTemplate, err error) {
 				require.NoError(t, err)
 				require.Nil(t, template)
 			},
@@ -84,13 +86,13 @@ func TestGetClusterAnalysisTemplate(t *testing.T) {
 		{
 			name: "found",
 			client: fake.NewClientBuilder().WithScheme(scheme).WithObjects(
-				&ClusterAnalysisTemplate{
+				&rolloutsapi.ClusterAnalysisTemplate{
 					ObjectMeta: metav1.ObjectMeta{
 						Name: "fake-template",
 					},
 				},
 			).Build(),
-			assertions: func(t *testing.T, template *ClusterAnalysisTemplate, err error) {
+			assertions: func(t *testing.T, template *rolloutsapi.ClusterAnalysisTemplate, err error) {
 				require.NoError(t, err)
 				require.Equal(t, "fake-template", template.Name)
 			},
@@ -111,17 +113,17 @@ func TestGetClusterAnalysisTemplate(t *testing.T) {
 
 func TestGetAnalysisRun(t *testing.T) {
 	scheme := k8sruntime.NewScheme()
-	require.NoError(t, SchemeBuilder.AddToScheme(scheme))
+	require.NoError(t, rolloutsapi.SchemeBuilder.AddToScheme(scheme))
 
 	testCases := []struct {
 		name       string
 		client     client.Client
-		assertions func(*testing.T, *AnalysisRun, error)
+		assertions func(*testing.T, *rolloutsapi.AnalysisRun, error)
 	}{
 		{
 			name:   "not found",
 			client: fake.NewClientBuilder().WithScheme(scheme).Build(),
-			assertions: func(t *testing.T, run *AnalysisRun, err error) {
+			assertions: func(t *testing.T, run *rolloutsapi.AnalysisRun, err error) {
 				require.NoError(t, err)
 				require.Nil(t, run)
 			},
@@ -130,14 +132,14 @@ func TestGetAnalysisRun(t *testing.T) {
 		{
 			name: "found",
 			client: fake.NewClientBuilder().WithScheme(scheme).WithObjects(
-				&AnalysisRun{
+				&rolloutsapi.AnalysisRun{
 					ObjectMeta: metav1.ObjectMeta{
 						Name:      "fake-run",
 						Namespace: "fake-namespace",
 					},
 				},
 			).Build(),
-			assertions: func(t *testing.T, run *AnalysisRun, err error) {
+			assertions: func(t *testing.T, run *rolloutsapi.AnalysisRun, err error) {
 				require.NoError(t, err)
 				require.Equal(t, "fake-run", run.Name)
 				require.Equal(t, "fake-namespace", run.Namespace)
diff --git a/internal/controller/stages/control_flow_stages_test.go b/internal/controller/stages/control_flow_stages_test.go
index 43d652b2..73b36550 100644
--- a/internal/controller/stages/control_flow_stages_test.go
+++ b/internal/controller/stages/control_flow_stages_test.go
@@ -20,8 +20,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/indexer"
 	fakeevent "github.com/akuity/kargo/internal/kubernetes/event/fake"
 )
@@ -147,6 +147,30 @@ func TestControlFlowStageReconciler_Reconcile(t *testing.T) {
 				assert.Contains(t, stage.Finalizers, kargoapi.FinalizerName)
 			},
 		},
+		{
+			name: "removes stale annotations",
+			req:  ctrl.Request{NamespacedName: testStage},
+			stage: &kargoapi.Stage{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace:  testProject,
+					Name:       testStageName,
+					Finalizers: []string{kargoapi.FinalizerName},
+					Annotations: map[string]string{
+						kargoapi.AnnotationKeyArgoCDContext: "old-argocd-context",
+					},
+				},
+			},
+			assertions: func(t *testing.T, c client.Client, result ctrl.Result, err error) {
+				require.NoError(t, err)
+				assert.Equal(t, ctrl.Result{}, result)
+
+				// Verify annotation was removed
+				stage := &kargoapi.Stage{}
+				err = c.Get(context.Background(), testStage, stage)
+				require.NoError(t, err)
+				assert.NotContains(t, stage.Annotations, kargoapi.AnnotationKeyArgoCDContext)
+			},
+		},
 		{
 			name: "reconcile error",
 			req:  ctrl.Request{NamespacedName: testStage},
diff --git a/internal/controller/stages/event_handlers_test.go b/internal/controller/stages/event_handlers_test.go
index db337356..5de053f4 100644
--- a/internal/controller/stages/event_handlers_test.go
+++ b/internal/controller/stages/event_handlers_test.go
@@ -18,9 +18,9 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/event"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	argocd "github.com/akuity/kargo/internal/controller/argocd/api/v1alpha1"
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/indexer"
 )
 
diff --git a/internal/controller/stages/regular_stages_test.go b/internal/controller/stages/regular_stages_test.go
index 6bac1825..4f4ef374 100644
--- a/internal/controller/stages/regular_stages_test.go
+++ b/internal/controller/stages/regular_stages_test.go
@@ -21,9 +21,9 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
 
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	"github.com/akuity/kargo/internal/conditions"
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 	"github.com/akuity/kargo/internal/directives"
 	"github.com/akuity/kargo/internal/indexer"
 	fakeevent "github.com/akuity/kargo/internal/kubernetes/event/fake"
diff --git a/internal/controller/warehouses/git_test.go b/internal/controller/warehouses/git_test.go
index 8bc39a29..dcdb0536 100644
--- a/internal/controller/warehouses/git_test.go
+++ b/internal/controller/warehouses/git_test.go
@@ -46,8 +46,8 @@ func TestDiscoverCommits(t *testing.T) {
 						string,
 						credentials.Type,
 						string,
-					) (credentials.Credentials, bool, error) {
-						return credentials.Credentials{}, false, errors.New("something went wrong")
+					) (*credentials.Credentials, error) {
+						return nil, errors.New("something went wrong")
 					},
 				},
 			},
diff --git a/internal/controller/warehouses/helm_test.go b/internal/controller/warehouses/helm_test.go
index 0aeb5ae1..7fc8996b 100644
--- a/internal/controller/warehouses/helm_test.go
+++ b/internal/controller/warehouses/helm_test.go
@@ -39,8 +39,8 @@ func TestDiscoverCharts(t *testing.T) {
 						string,
 						credentials.Type,
 						string,
-					) (credentials.Credentials, bool, error) {
-						return credentials.Credentials{}, false, fmt.Errorf("something went wrong")
+					) (*credentials.Credentials, error) {
+						return nil, fmt.Errorf("something went wrong")
 					},
 				},
 			},
diff --git a/internal/controller/warehouses/images_test.go b/internal/controller/warehouses/images_test.go
index 43f07f50..fa6261ed 100644
--- a/internal/controller/warehouses/images_test.go
+++ b/internal/controller/warehouses/images_test.go
@@ -39,8 +39,8 @@ func TestDiscoverImages(t *testing.T) {
 						string,
 						credentials.Type,
 						string,
-					) (credentials.Credentials, bool, error) {
-						return credentials.Credentials{}, false, fmt.Errorf("something went wrong")
+					) (*credentials.Credentials, error) {
+						return nil, fmt.Errorf("something went wrong")
 					},
 				},
 			},
diff --git a/internal/credentials/kubernetes/basic/basic_test.go b/internal/credentials/kubernetes/basic/basic_test.go
new file mode 100644
index 00000000..98c92fd3
--- /dev/null
+++ b/internal/credentials/kubernetes/basic/basic_test.go
@@ -0,0 +1,241 @@
+package basic
+
+import (
+	"context"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/akuity/kargo/internal/credentials"
+)
+
+func TestCredentialProvider_Supports(t *testing.T) {
+	tests := []struct {
+		name     string
+		credType credentials.Type
+		repoURL  string
+		data     map[string][]byte
+		expected bool
+	}{
+		{
+			name:     "empty data",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data:     map[string][]byte{},
+			expected: false,
+		},
+		{
+			name:     "username only",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: []byte("user"),
+			},
+			expected: false,
+		},
+		{
+			name:     "password only",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				passwordKey: []byte("pass"),
+			},
+			expected: false,
+		},
+		{
+			name:     "username and password",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: []byte("user"),
+				passwordKey: []byte("pass"),
+			},
+			expected: true,
+		},
+		{
+			name:     "ssh private key only",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				sshPrivateKey: []byte("key-data"),
+			},
+			expected: true,
+		},
+		{
+			name:     "all credentials",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey:   []byte("user"),
+				passwordKey:   []byte("pass"),
+				sshPrivateKey: []byte("key-data"),
+			},
+			expected: true,
+		},
+		{
+			name:     "nil username value",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: nil,
+				passwordKey: []byte("pass"),
+			},
+			expected: false,
+		},
+		{
+			name:     "nil password value",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: []byte("user"),
+				passwordKey: nil,
+			},
+			expected: false,
+		},
+		{
+			name:     "nil ssh private key value",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				sshPrivateKey: nil,
+			},
+			expected: false,
+		},
+	}
+
+	provider := &CredentialProvider{}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			result := provider.Supports(test.credType, test.repoURL, test.data)
+			assert.Equal(t, test.expected, result)
+		})
+	}
+}
+
+func TestCredentialProvider_GetCredentials(t *testing.T) {
+	tests := []struct {
+		name       string
+		credType   credentials.Type
+		repoURL    string
+		data       map[string][]byte
+		assertions func(t *testing.T, creds *credentials.Credentials, err error)
+	}{
+		{
+			name:     "empty data",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data:     map[string][]byte{},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name:     "username only",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: []byte("user"),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name:     "password only",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				passwordKey: []byte("pass"),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name:     "username and password",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: []byte("user"),
+				passwordKey: []byte("pass"),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "user", creds.Username)
+				assert.Equal(t, "pass", creds.Password)
+				assert.Empty(t, creds.SSHPrivateKey, "SSHPrivateKey should be empty")
+			},
+		},
+		{
+			name:     "ssh private key only",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				sshPrivateKey: []byte("key-data"),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Empty(t, creds.Username, "Username should be empty")
+				assert.Empty(t, creds.Password, "Password should be empty")
+				assert.Equal(t, "key-data", creds.SSHPrivateKey)
+			},
+		},
+		{
+			name:     "all credentials",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey:   []byte("user"),
+				passwordKey:   []byte("pass"),
+				sshPrivateKey: []byte("key-data"),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "user", creds.Username)
+				assert.Equal(t, "pass", creds.Password)
+				assert.Equal(t, "key-data", creds.SSHPrivateKey)
+			},
+		},
+		{
+			name:     "empty username and password strings",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				usernameKey: []byte(""),
+				passwordKey: []byte(""),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name:     "empty ssh private key string",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/example/repository.git",
+			data: map[string][]byte{
+				sshPrivateKey: []byte(""),
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
+			},
+		},
+	}
+
+	provider := &CredentialProvider{}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			creds, err := provider.GetCredentials(context.Background(), "", test.credType, test.repoURL, test.data)
+			test.assertions(t, creds, err)
+		})
+	}
+}
diff --git a/internal/credentials/kubernetes/database_test.go b/internal/credentials/kubernetes/database_test.go
index b6579211..4e63df4d 100644
--- a/internal/credentials/kubernetes/database_test.go
+++ b/internal/credentials/kubernetes/database_test.go
@@ -327,7 +327,7 @@ func TestGet(t *testing.T) {
 
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			creds, found, err := NewDatabase(
+			creds, err := NewDatabase(
 				context.Background(),
 				fake.NewClientBuilder().WithObjects(testCase.secrets...).Build(),
 				testCase.cfg,
@@ -340,12 +340,11 @@ func TestGet(t *testing.T) {
 			require.NoError(t, err)
 
 			if testCase.expected == nil {
-				require.False(t, found)
-				require.Empty(t, creds)
+				require.Nil(t, creds)
 				return
 			}
 
-			require.True(t, found)
+			require.NotNil(t, creds)
 			require.Equal(
 				t,
 				string(testCase.expected.Data["username"]),
diff --git a/internal/credentials/kubernetes/ecr/access_key_test.go b/internal/credentials/kubernetes/ecr/access_key_test.go
index 6f130c69..73eb290b 100644
--- a/internal/credentials/kubernetes/ecr/access_key_test.go
+++ b/internal/credentials/kubernetes/ecr/access_key_test.go
@@ -2,252 +2,317 @@ package ecr
 
 import (
 	"context"
-	"encoding/base64"
-	"fmt"
+	"errors"
 	"testing"
 
 	"github.com/patrickmn/go-cache"
-	"github.com/stretchr/testify/require"
-	corev1 "k8s.io/api/core/v1"
+	"github.com/stretchr/testify/assert"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-func TestAccessKeyCredentialHelper(t *testing.T) {
+func TestNewAccessKeyProvider(t *testing.T) {
+	provider := NewAccessKeyProvider().(*AccessKeyProvider) // nolint:forcetypeassert
+
+	assert.NotNil(t, provider)
+	assert.NotNil(t, provider.tokenCache)
+	assert.NotNil(t, provider.getAuthTokenFn)
+}
+
+func TestAccessKeyProvider_Supports(t *testing.T) {
 	const (
-		testAWSAccountID    = "123456789012"
-		testRegion          = "fake-region"
-		testAccessKeyID     = "fake-id"
-		testSecretAccessKey = "fake-secret"
-		testUsername        = "fake-username"
-		testPassword        = "fake-password"
-	)
-	testRepoURL := fmt.Sprintf("%s.dkr.ecr.%s.amazonaws.com/fake/repo/", testAWSAccountID, testRegion)
-	testToken := fmt.Sprintf("%s:%s", testUsername, testPassword)
-	testEncodedToken := base64.StdEncoding.EncodeToString([]byte(testToken))
-
-	warmTokenCache := cache.New(0, 0)
-	warmTokenCache.Set(
-		(&accessKeyCredentialHelper{}).tokenCacheKey(testRegion, testAccessKeyID, testSecretAccessKey),
-		testEncodedToken,
-		cache.DefaultExpiration,
+		fakeRepoURL    = "123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo"
+		fakeOCIRepoURL = "oci://123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo"
+
+		fakeRegion = "us-west-2"
+		fakeID     = "AKIAIOSFODNN7EXAMPLE"                     // nolint:gosec
+		fakeSecret = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" // nolint:gosec
 	)
 
 	testCases := []struct {
-		name       string
-		credType   credentials.Type
-		repoURL    string
-		secret     *corev1.Secret
-		helper     *accessKeyCredentialHelper
-		assertions func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error)
+		name     string
+		credType credentials.Type
+		repoURL  string
+		data     map[string][]byte
+		expected bool
 	}{
 		{
-			name:     "cred type is not image",
-			credType: credentials.TypeGit,
-			secret:   &corev1.Secret{},
-			helper:   &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			name:     "valid image credentials",
+			credType: credentials.TypeImage,
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
+			expected: true,
 		},
 		{
-			name:     "cred type is not oci helm",
+			name:     "valid helm oci credentials",
 			credType: credentials.TypeHelm,
-			repoURL:  testRepoURL,
-			secret:   &corev1.Secret{},
-			helper:   &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeOCIRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
+			expected: true,
 		},
 		{
-			name:     "secret is nil",
+			name:     "helm but not oci",
+			credType: credentials.TypeHelm,
+			repoURL:  "https://123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo",
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
+			},
+			expected: false,
+		},
+		{
+			name:     "missing region",
 			credType: credentials.TypeImage,
-			helper:   &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
+			expected: false,
 		},
 		{
-			name:     "not an ecr url",
+			name:     "missing access key ID",
 			credType: credentials.TypeImage,
-			repoURL:  "not-an-ecr-url",
-			secret:   &corev1.Secret{},
-			helper:   &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				secretKey: []byte(fakeSecret),
 			},
+			expected: false,
 		},
 		{
-			name:     "no aws details provided",
+			name:     "missing secret key",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret:   &corev1.Secret{},
-			helper:   &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
 			},
+			expected: false,
 		},
 		{
-			name:     "region missing",
+			name:     "invalid URL format",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					idKey:     []byte(testAccessKeyID),
-					secretKey: []byte(testSecretAccessKey),
-				},
+			repoURL:  "not-an-ecr-url",
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
-			helper: &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "must all be set or all be unset")
+			expected: false,
+		},
+		{
+			name:     "unsupported credential type",
+			credType: credentials.TypeGit,
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
+			expected: false,
 		},
 		{
-			name:     "access key id missing",
+			name:     "empty data",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					regionKey: []byte(testRegion),
-					secretKey: []byte(testSecretAccessKey),
-				},
+			repoURL:  fakeRepoURL,
+			data:     map[string][]byte{},
+			expected: false,
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			provider := NewAccessKeyProvider()
+			result := provider.Supports(tt.credType, tt.repoURL, tt.data)
+			assert.Equal(t, tt.expected, result)
+		})
+	}
+}
+
+func TestAccessKeyProvider_GetCredentials(t *testing.T) {
+	ctx := context.Background()
+
+	const (
+		fakeRepoURL = "123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo"
+		fakeRegion  = "us-west-2"
+		fakeID      = "AKIAIOSFODNN7EXAMPLE"                     // nolint:gosec
+		fakeSecret  = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" // nolint:gosec
+		// base64 of "AWS:password"
+		fakeToken = "QVdTOnBhc3N3b3Jk" // nolint:gosec
+	)
+
+	testCases := []struct {
+		name           string
+		credType       credentials.Type
+		repoURL        string
+		data           map[string][]byte
+		getAuthTokenFn func(ctx context.Context, region, accessKeyID, secretAccessKey string) (string, error)
+		setupCache     func(cache *cache.Cache)
+		assertions     func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error)
+	}{
+		{
+			name:     "unsupported credentials",
+			credType: credentials.TypeGit,
+			repoURL:  "not-an-ecr-url",
+			data:     map[string][]byte{},
+			getAuthTokenFn: func(_ context.Context, _, _, _ string) (string, error) {
+				return "", nil
 			},
-			helper: &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "must all be set or all be unset")
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 		{
-			name:     "secret access key missing",
+			name:     "cache hit",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					regionKey: []byte(testRegion),
-					idKey:     []byte(testAccessKeyID),
-				},
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
+			},
+			setupCache: func(c *cache.Cache) {
+				c.Set(
+					tokenCacheKey(fakeRegion, fakeID, fakeSecret),
+					fakeToken, // base64 of "AWS:password"
+					cache.DefaultExpiration,
+				)
 			},
-			helper: &accessKeyCredentialHelper{},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "must all be set or all be unset")
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "AWS", creds.Username)
+				assert.Equal(t, "password", creds.Password)
 			},
 		},
 		{
-			name:     "cache hit",
+			name:     "cache miss, successful token fetch",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					regionKey: []byte(testRegion),
-					idKey:     []byte(testAccessKeyID),
-					secretKey: []byte(testSecretAccessKey),
-				},
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
-			helper: &accessKeyCredentialHelper{
-				tokenCache: warmTokenCache,
+			getAuthTokenFn: func(_ context.Context, _, _, _ string) (string, error) {
+				return fakeToken, nil
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, testUsername, creds.Username)
-				require.Equal(t, testPassword, creds.Password)
+			assertions: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "AWS", creds.Username)
+				assert.Equal(t, "password", creds.Password)
+
+				// Verify the token was cached
+				token, found := c.Get(tokenCacheKey(fakeRegion, fakeID, fakeSecret))
+				assert.True(t, found)
+				assert.Equal(t, fakeToken, token)
 			},
 		},
 		{
-			name:     "cache miss; error getting auth token",
+			name:     "error in getAuthToken",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					regionKey: []byte(testRegion),
-					idKey:     []byte(testAccessKeyID),
-					secretKey: []byte(testSecretAccessKey),
-				},
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
 			},
-			helper: &accessKeyCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAuthTokenFn: func(context.Context, string, string, string) (string, error) {
-					return "", fmt.Errorf("something went wrong")
-				},
+			getAuthTokenFn: func(_ context.Context, _, _, _ string) (string, error) {
+				return "", errors.New("auth token error")
 			},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "error getting ECR auth token")
-				require.ErrorContains(t, err, "something went wrong")
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "error getting ECR auth token")
+				assert.Nil(t, creds)
 			},
 		},
 		{
-			name:     "cache miss; success",
+			name:     "empty token from getAuthToken",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					regionKey: []byte(testRegion),
-					idKey:     []byte(testAccessKeyID),
-					secretKey: []byte(testSecretAccessKey),
-				},
-			},
-			helper: &accessKeyCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAuthTokenFn: func(context.Context, string, string, string) (string, error) {
-					return testEncodedToken, nil
-				},
-			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, testUsername, creds.Username)
-				require.Equal(t, testPassword, creds.Password)
-				_, found := c.Get(
-					(&accessKeyCredentialHelper{}).tokenCacheKey(testRegion, testAccessKeyID, testSecretAccessKey),
-				)
-				require.True(t, found)
+			repoURL:  fakeRepoURL,
+			data: map[string][]byte{
+				regionKey: []byte(fakeRegion),
+				idKey:     []byte(fakeID),
+				secretKey: []byte(fakeSecret),
+			},
+			getAuthTokenFn: func(_ context.Context, _, _, _ string) (string, error) {
+				return "", nil
+			},
+			assertions: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
+
+				// Verify the token was not cached
+				_, found := c.Get(tokenCacheKey(fakeRegion, fakeID, fakeSecret))
+				assert.False(t, found)
 			},
 		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			provider := NewAccessKeyProvider().(*AccessKeyProvider) // nolint:forcetypeassert
+			provider.getAuthTokenFn = tt.getAuthTokenFn
+
+			if tt.setupCache != nil {
+				tt.setupCache(provider.tokenCache)
+			}
+
+			creds, err := provider.GetCredentials(ctx, "", tt.credType, tt.repoURL, tt.data)
+			tt.assertions(t, provider.tokenCache, creds, err)
+		})
+	}
+}
+
+func Test_decodeAuthToken(t *testing.T) {
+	testCases := []struct {
+		name       string
+		token      string
+		assertions func(t *testing.T, creds *credentials.Credentials, err error)
+	}{
 		{
-			name:     "cache miss; success (helm)",
-			credType: credentials.TypeHelm,
-			repoURL:  fmt.Sprintf("oci://%s", testRepoURL),
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					regionKey: []byte(testRegion),
-					idKey:     []byte(testAccessKeyID),
-					secretKey: []byte(testSecretAccessKey),
-				},
-			},
-			helper: &accessKeyCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAuthTokenFn: func(context.Context, string, string, string) (string, error) {
-					return testEncodedToken, nil
-				},
-			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, testUsername, creds.Username)
-				require.Equal(t, testPassword, creds.Password)
-				_, found := c.Get(
-					(&accessKeyCredentialHelper{}).tokenCacheKey(testRegion, testAccessKeyID, testSecretAccessKey),
-				)
-				require.True(t, found)
+			name:  "valid token",
+			token: "QVdTOnBhc3N3b3Jk", // base64 of "AWS:password"
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "AWS", creds.Username)
+				assert.Equal(t, "password", creds.Password)
+			},
+		},
+		{
+			name:  "invalid base64",
+			token: "invalid-base64",
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "error decoding token")
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name:  "valid base64 but invalid format",
+			token: "bm90LWEtdmFsaWQtdG9rZW4=", // base64 of "not-a-valid-token"
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "invalid token format")
+				assert.Nil(t, creds)
 			},
 		},
 	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			creds, err := testCase.helper.getCredentials(
-				context.Background(),
-				"", // project is irrelevant for this helper
-				testCase.credType,
-				testCase.repoURL,
-				testCase.secret,
-			)
-			testCase.assertions(t, creds, testCase.helper.tokenCache, err)
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			creds, err := decodeAuthToken(tt.token)
+			tt.assertions(t, creds, err)
 		})
 	}
 }
diff --git a/internal/credentials/kubernetes/ecr/common_test.go b/internal/credentials/kubernetes/ecr/common_test.go
new file mode 100644
index 00000000..2aad079d
--- /dev/null
+++ b/internal/credentials/kubernetes/ecr/common_test.go
@@ -0,0 +1,40 @@
+package ecr
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_tokenCacheKey(t *testing.T) {
+	testCases := []struct {
+		name  string
+		parts []string
+		want  string
+	}{
+		{
+			name:  "single part",
+			parts: []string{"region1"},
+			want:  "7507acda9c58034d4f38545edd121b4c8572483cbc5c7dc40f3daa2c74d8430a",
+		},
+		{
+			name:  "multiple parts",
+			parts: []string{"region1", "key1", "secret1"},
+			want:  "559495d4cca6055810e755d40dfdeeb1aa0a937f3030463be970b9cd2d586002",
+		},
+		{
+			name:  "no parts",
+			parts: []string{},
+			want:  "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			for i := 0; i < 100000; i++ {
+				result := tokenCacheKey(tt.parts...)
+				assert.Equal(t, tt.want, result)
+			}
+		})
+	}
+}
diff --git a/internal/credentials/kubernetes/ecr/managed_identity_test.go b/internal/credentials/kubernetes/ecr/managed_identity_test.go
index cbeed03a..9439a97d 100644
--- a/internal/credentials/kubernetes/ecr/managed_identity_test.go
+++ b/internal/credentials/kubernetes/ecr/managed_identity_test.go
@@ -2,173 +2,222 @@ package ecr
 
 import (
 	"context"
-	"encoding/base64"
-	"fmt"
+	"errors"
 	"testing"
+	"time"
 
 	"github.com/patrickmn/go-cache"
-	"github.com/stretchr/testify/require"
+	"github.com/stretchr/testify/assert"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-func TestPodIdentityCredentialHelper(t *testing.T) {
+func TestManagedIdentityProvider_Supports(t *testing.T) {
 	const (
-		testAWSAccountID = "123456789012"
-		testRegion       = "fake-region"
-		testProject      = "fake-project"
-		testUsername     = "fake-username"
-		testPassword     = "fake-password"
-	)
-	testRepoURL := fmt.Sprintf("%s.dkr.ecr.%s.amazonaws.com/fake/repo/", testAWSAccountID, testRegion)
-	testToken := fmt.Sprintf("%s:%s", testUsername, testPassword)
-	testEncodedToken := base64.StdEncoding.EncodeToString([]byte(testToken))
-
-	warmTokenCache := cache.New(0, 0)
-	warmTokenCache.Set(
-		(&managedIdentityCredentialHelper{}).tokenCacheKey(testRegion, testProject),
-		testEncodedToken,
-		cache.DefaultExpiration,
+		fakeAccountID  = "123456789012"
+		fakeRepoURL    = "123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo"
+		fakeOCIRepoURL = "oci://123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo"
 	)
 
 	testCases := []struct {
-		name       string
-		credType   credentials.Type
-		repoURL    string
-		helper     *managedIdentityCredentialHelper
-		assertions func(*testing.T, *credentials.Credentials, *cache.Cache, error)
+		name     string
+		provider *ManagedIdentityProvider
+		credType credentials.Type
+		repoURL  string
+		expected bool
 	}{
 		{
-			name:     "cred type is not image",
-			credType: credentials.TypeGit,
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
-			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			name: "no account ID configured",
+			provider: &ManagedIdentityProvider{
+				accountID: "",
 			},
+			credType: credentials.TypeImage,
+			repoURL:  fakeRepoURL,
+			expected: false,
 		},
 		{
-			name:     "EKS Pod Identity not in use",
+			name: "image credentials supported",
+			provider: &ManagedIdentityProvider{
+				accountID: fakeAccountID,
+			},
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper:   &managedIdentityCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeRepoURL,
+			expected: true,
+		},
+		{
+			name: "OCI helm credentials supported",
+			provider: &ManagedIdentityProvider{
+				accountID: fakeAccountID,
 			},
+			credType: credentials.TypeHelm,
+			repoURL:  fakeOCIRepoURL,
+			expected: true,
 		},
 		{
-			name:     "repo URL does not match ECR URL regex",
-			credType: credentials.TypeImage,
-			repoURL:  "ghcr.io/fake-org/fake-repo",
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
+			name: "non-OCI helm credentials not supported",
+			provider: &ManagedIdentityProvider{
+				accountID: fakeAccountID,
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			credType: credentials.TypeHelm,
+			repoURL:  "https://123456789012.dkr.ecr.us-west-2.amazonaws.com/repo",
+			expected: false,
+		},
+		{
+			name: "git credentials not supported",
+			provider: &ManagedIdentityProvider{
+				accountID: fakeAccountID,
 			},
+			credType: credentials.TypeGit,
+			repoURL:  fakeRepoURL,
+			expected: false,
 		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			result := tt.provider.Supports(tt.credType, tt.repoURL, nil)
+			assert.Equal(t, tt.expected, result)
+		})
+	}
+}
+
+func TestManagedIdentityProvider_GetCredentials(t *testing.T) {
+	ctx := context.Background()
+
+	const (
+		fakeAccountID = "123456789012"
+		fakeProject   = "fake-project"
+		fakeRepoURL   = "123456789012.dkr.ecr.us-west-2.amazonaws.com/repo"
+		fakeRegion    = "us-west-2"
+		// base64 of "AWS:password"
+		fakeToken = "QVdTOnBhc3N3b3Jk" // nolint:gosec
+	)
+
+	testCases := []struct {
+		name       string
+		provider   *ManagedIdentityProvider
+		project    string
+		credType   credentials.Type
+		repoURL    string
+		setupCache func(cache *cache.Cache)
+		assertions func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error)
+	}{
 		{
-			name:     "helm repo URL does not match ECR URL regex",
-			credType: credentials.TypeHelm,
-			repoURL:  testRepoURL,
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
+			name: "not supported",
+			provider: &ManagedIdentityProvider{
+				accountID:  fakeAccountID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			project:  fakeProject,
+			credType: credentials.TypeGit,
+			repoURL:  "git://repo",
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 		{
-			name:     "cache hit",
-			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
-				tokenCache:   warmTokenCache,
+			name: "non-ECR URL",
+			provider: &ManagedIdentityProvider{
+				accountID:  fakeAccountID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, testUsername, creds.Username)
-				require.Equal(t, testPassword, creds.Password)
+			project:  fakeProject,
+			credType: credentials.TypeImage,
+			repoURL:  "not-an-ecr-url",
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 		{
-			name:     "cache miss; error getting auth token",
+			name: "cache hit",
+			provider: &ManagedIdentityProvider{
+				accountID:  fakeAccountID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+			},
+			project:  fakeProject,
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
-				tokenCache:   cache.New(0, 0),
-				getAuthTokenFn: func(context.Context, string, string) (string, error) {
-					return "", fmt.Errorf("something went wrong")
-				},
+			repoURL:  fakeRepoURL,
+			setupCache: func(c *cache.Cache) {
+				cacheKey := tokenCacheKey(fakeRegion, fakeProject)
+				c.Set(cacheKey, fakeToken, cache.DefaultExpiration)
 			},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "error getting ECR auth token")
-				require.ErrorContains(t, err, "something went wrong")
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "AWS", creds.Username)
+				assert.Equal(t, "password", creds.Password)
 			},
 		},
 		{
-			name:     "cache miss; success",
+			name: "cache miss, successful token fetch",
+			provider: &ManagedIdentityProvider{
+				accountID:  fakeAccountID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+				getAuthTokenFn: func(_ context.Context, _, _ string) (string, error) {
+					return fakeToken, nil
+				},
+			},
+			project:  fakeProject,
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
-				tokenCache:   cache.New(0, 0),
-				getAuthTokenFn: func(context.Context, string, string) (string, error) {
-					return testEncodedToken, nil
+			repoURL:  fakeRepoURL,
+			assertions: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, "AWS", creds.Username)
+				assert.Equal(t, "password", creds.Password)
+
+				// Verify the token was cached
+				cachedToken, found := c.Get(tokenCacheKey(fakeRegion, fakeProject))
+				assert.True(t, found)
+				assert.Equal(t, fakeToken, cachedToken)
+			},
+		},
+		{
+			name: "error in getAuthToken",
+			provider: &ManagedIdentityProvider{
+				accountID:  fakeAccountID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+				getAuthTokenFn: func(_ context.Context, _, _ string) (string, error) {
+					return "", errors.New("auth token error")
 				},
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, testUsername, creds.Username)
-				require.Equal(t, testPassword, creds.Password)
-				_, found := c.Get(
-					(&managedIdentityCredentialHelper{}).tokenCacheKey(testRegion, testProject),
-				)
-				require.True(t, found)
+			project:  fakeProject,
+			credType: credentials.TypeImage,
+			repoURL:  fakeRepoURL,
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "error getting ECR auth token")
+				assert.Nil(t, creds)
 			},
 		},
 		{
-			name:     "cache miss; success (helm)",
-			credType: credentials.TypeHelm,
-			repoURL:  fmt.Sprintf("oci://%s", testRepoURL),
-			helper: &managedIdentityCredentialHelper{
-				awsAccountID: testAWSAccountID,
-				tokenCache:   cache.New(0, 0),
-				getAuthTokenFn: func(context.Context, string, string) (string, error) {
-					return testEncodedToken, nil
+			name: "empty token from getAuthToken",
+			provider: &ManagedIdentityProvider{
+				accountID:  fakeAccountID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+				getAuthTokenFn: func(_ context.Context, _, _ string) (string, error) {
+					return "", nil
 				},
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, testUsername, creds.Username)
-				require.Equal(t, testPassword, creds.Password)
-				_, found := c.Get(
-					(&managedIdentityCredentialHelper{}).tokenCacheKey(testRegion, testProject),
-				)
-				require.True(t, found)
+			project:  fakeProject,
+			credType: credentials.TypeImage,
+			repoURL:  fakeRepoURL,
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			creds, err := testCase.helper.getCredentials(
-				context.Background(),
-				testProject,
-				testCase.credType,
-				testCase.repoURL,
-				nil, // Secret not used by this helper
-			)
-			testCase.assertions(t, creds, testCase.helper.tokenCache, err)
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			if tt.setupCache != nil {
+				tt.setupCache(tt.provider.tokenCache)
+			}
+
+			creds, err := tt.provider.GetCredentials(ctx, tt.project, tt.credType, tt.repoURL, nil)
+			tt.assertions(t, tt.provider.tokenCache, creds, err)
 		})
 	}
 }
diff --git a/internal/credentials/kubernetes/gar/common_test.go b/internal/credentials/kubernetes/gar/common_test.go
new file mode 100644
index 00000000..23364201
--- /dev/null
+++ b/internal/credentials/kubernetes/gar/common_test.go
@@ -0,0 +1,30 @@
+package gar
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_tokenCacheKey(t *testing.T) {
+	tests := []struct {
+		key  string
+		want string
+	}{
+		{
+			key:  "test123",
+			want: "ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae",
+		},
+		{
+			key:  "123test",
+			want: "a8327d4a49d4631631d090a72297d8d749337a30e6eb0416bd3655b71e36481b",
+		},
+	}
+	for _, tt := range tests {
+		t.Run("", func(t *testing.T) {
+			for i := 0; i < 100000; i++ {
+				assert.Equal(t, tt.want, tokenCacheKey(tt.key))
+			}
+		})
+	}
+}
diff --git a/internal/credentials/kubernetes/gar/service_account_key_test.go b/internal/credentials/kubernetes/gar/service_account_key_test.go
index eaa27c9e..bc2cf21b 100644
--- a/internal/credentials/kubernetes/gar/service_account_key_test.go
+++ b/internal/credentials/kubernetes/gar/service_account_key_test.go
@@ -2,159 +2,209 @@ package gar
 
 import (
 	"context"
-	"encoding/base64"
-	"fmt"
+	"errors"
 	"testing"
 
 	"github.com/patrickmn/go-cache"
-	"github.com/stretchr/testify/require"
-	corev1 "k8s.io/api/core/v1"
+	"github.com/stretchr/testify/assert"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-func TestServiceAccountKeyCredentialHelper(t *testing.T) {
-	const (
-		testGCPProjectID      = "fake-project-123456"
-		testRegion            = "fake-region"
-		testServiceAccountKey = "fake-key"
-		testAccessToken       = "fake-token"
-	)
-	testRepoURL := fmt.Sprintf("%s-docker.pkg.dev/%s/debian/debian", testRegion, testGCPProjectID)
-	testEncodedServiceAccountKey := base64.StdEncoding.EncodeToString([]byte(testServiceAccountKey))
+func TestNewServiceAccountKeyProvider(t *testing.T) {
+	provider := NewServiceAccountKeyProvider().(*ServiceAccountKeyProvider) // nolint:forcetypeassert
+	assert.NotNil(t, provider)
+
+	assert.NotNil(t, provider.tokenCache)
+	assert.NotNil(t, provider.getAccessTokenFn)
+}
 
-	warmTokenCache := cache.New(0, 0)
-	warmTokenCache.Set(
-		(&serviceAccountKeyCredentialHelper{}).tokenCacheKey(testEncodedServiceAccountKey),
-		testAccessToken,
-		cache.DefaultExpiration,
+func TestServiceAccountKeyProvider_Supports(t *testing.T) {
+	const (
+		fakeGCRRepoURL        = "gcr.io/my-project/my-repo"
+		fakeGARRepoURL        = "us-central1-docker.pkg.dev/my-project/my-repo"
+		fakeServiceAccountKey = "base64-encoded-service-account-key"
 	)
 
 	testCases := []struct {
-		name       string
-		credType   credentials.Type
-		repoURL    string
-		secret     *corev1.Secret
-		helper     *serviceAccountKeyCredentialHelper
-		assertions func(*testing.T, *credentials.Credentials, *cache.Cache, error)
+		name     string
+		credType credentials.Type
+		repoURL  string
+		data     map[string][]byte
+		expected bool
 	}{
 		{
-			name:     "cred type is not image",
-			credType: credentials.TypeGit,
-			secret:   &corev1.Secret{},
-			helper:   &serviceAccountKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			name:     "valid GAR repo with service account key",
+			credType: credentials.TypeImage,
+			repoURL:  fakeGARRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
 			},
+			expected: true,
 		},
 		{
-			name:     "secret is nil",
+			name:     "valid GCR repo with service account key",
 			credType: credentials.TypeImage,
-			helper:   &serviceAccountKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeGCRRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
 			},
+			expected: true,
 		},
 		{
-			name:     "not a gar url",
-			credType: credentials.TypeImage,
-			repoURL:  "not-a-gar-url",
-			secret:   &corev1.Secret{},
-			helper:   &serviceAccountKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			name:     "wrong credential type",
+			credType: credentials.TypeHelm,
+			repoURL:  fakeGARRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
 			},
+			expected: false,
 		},
 		{
-			name:     "no service account key provided",
+			name:     "missing service account key",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret:   &corev1.Secret{},
-			helper:   &serviceAccountKeyCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeGARRepoURL,
+			data:     map[string][]byte{},
+			expected: false,
+		},
+		{
+			name:     "nil data",
+			credType: credentials.TypeImage,
+			repoURL:  fakeGARRepoURL,
+			data:     nil,
+			expected: false,
+		},
+		{
+			name:     "non-GAR/GCR URL",
+			credType: credentials.TypeImage,
+			repoURL:  "docker.io/library/nginx",
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
+			},
+			expected: false,
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			provider := NewServiceAccountKeyProvider()
+			result := provider.Supports(tt.credType, tt.repoURL, tt.data)
+			assert.Equal(t, tt.expected, result)
+		})
+	}
+}
+
+func TestServiceAccountKeyProvider_GetCredentials(t *testing.T) {
+	ctx := context.Background()
+
+	const (
+		fakeGARRepoURL        = "us-central1-docker.pkg.dev/my-project/my-repo"
+		fakeServiceAccountKey = "base64-encoded-service-account-key"
+		fakeAccessToken       = "fake-access-token"
+	)
+
+	testCases := []struct {
+		name             string
+		credType         credentials.Type
+		repoURL          string
+		data             map[string][]byte
+		getAccessTokenFn func(ctx context.Context, encodedServiceAccountKey string) (string, error)
+		setupCache       func(c *cache.Cache)
+		assertions       func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error)
+	}{
+		{
+			name:     "unsupported credentials",
+			credType: credentials.TypeHelm,
+			repoURL:  fakeGARRepoURL,
+			data:     map[string][]byte{},
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 		{
 			name:     "cache hit",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					serviceAccountKeyKey: []byte(testEncodedServiceAccountKey),
-				},
+			repoURL:  fakeGARRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
 			},
-			helper: &serviceAccountKeyCredentialHelper{
-				tokenCache: warmTokenCache,
+			setupCache: func(c *cache.Cache) {
+				cacheKey := tokenCacheKey(fakeServiceAccountKey)
+				c.Set(cacheKey, fakeAccessToken, cache.DefaultExpiration)
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, accessTokenUsername, creds.Username)
-				require.Equal(t, testAccessToken, creds.Password)
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, fakeAccessToken, creds.Password)
 			},
 		},
 		{
-			name:     "cache miss; error getting access token",
+			name:     "cache miss, successful token fetch",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					serviceAccountKeyKey: []byte(testEncodedServiceAccountKey),
-				},
-			},
-			helper: &serviceAccountKeyCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAccessTokenFn: func(context.Context, string) (string, error) {
-					return "", fmt.Errorf("something went wrong")
-				},
-			},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "error getting GCP access token")
-				require.ErrorContains(t, err, "something went wrong")
+			repoURL:  fakeGARRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
+			},
+			getAccessTokenFn: func(_ context.Context, _ string) (string, error) {
+				return fakeAccessToken, nil
+			},
+			assertions: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, fakeAccessToken, creds.Password)
+
+				// Verify the token was cached
+				cachedToken, found := c.Get(tokenCacheKey(fakeServiceAccountKey))
+				assert.True(t, found)
+				assert.Equal(t, fakeAccessToken, cachedToken)
 			},
 		},
 		{
-			name:     "cache miss; success",
+			name:     "error in getAccessToken",
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					serviceAccountKeyKey: []byte(testEncodedServiceAccountKey),
-				},
-			},
-			helper: &serviceAccountKeyCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAccessTokenFn: func(context.Context, string) (string, error) {
-					return testAccessToken, nil
-				},
-			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, accessTokenUsername, creds.Username)
-				require.Equal(t, testAccessToken, creds.Password)
-				_, found := c.Get(
-					(&serviceAccountKeyCredentialHelper{}).tokenCacheKey(testEncodedServiceAccountKey),
-				)
-				require.True(t, found)
+			repoURL:  fakeGARRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
+			},
+			getAccessTokenFn: func(_ context.Context, _ string) (string, error) {
+				return "", errors.New("access token error")
+			},
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "error getting GCP access token")
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name:     "empty token from getAccessToken",
+			credType: credentials.TypeImage,
+			repoURL:  fakeGARRepoURL,
+			data: map[string][]byte{
+				serviceAccountKeyKey: []byte(fakeServiceAccountKey),
+			},
+			getAccessTokenFn: func(_ context.Context, _ string) (string, error) {
+				return "", nil
+			},
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			creds, err := testCase.helper.getCredentials(
-				context.Background(),
-				"", // project is irrelevant for this helper
-				testCase.credType,
-				testCase.repoURL,
-				testCase.secret,
-			)
-			testCase.assertions(t, creds, testCase.helper.tokenCache, err)
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			provider := NewServiceAccountKeyProvider().(*ServiceAccountKeyProvider) // nolint:forcetypeassert
+			provider.getAccessTokenFn = tt.getAccessTokenFn
+
+			if tt.setupCache != nil {
+				tt.setupCache(provider.tokenCache)
+			}
+
+			creds, err := provider.GetCredentials(ctx, "", tt.credType, tt.repoURL, tt.data)
+			tt.assertions(t, provider.tokenCache, creds, err)
 		})
 	}
 }
diff --git a/internal/credentials/kubernetes/gar/workload_identity_federation_test.go b/internal/credentials/kubernetes/gar/workload_identity_federation_test.go
index 657a4993..955b2b67 100644
--- a/internal/credentials/kubernetes/gar/workload_identity_federation_test.go
+++ b/internal/credentials/kubernetes/gar/workload_identity_federation_test.go
@@ -4,144 +4,208 @@ import (
 	"context"
 	"fmt"
 	"testing"
+	"time"
 
 	"github.com/patrickmn/go-cache"
-	"github.com/stretchr/testify/require"
+	"github.com/stretchr/testify/assert"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-func TestWorkloadIdentityFederationCredentialHelper(t *testing.T) {
+func TestWorkloadIdentityFederationProvider_Supports(t *testing.T) {
 	const (
-		testGCPProjectID = "fake-project-123456"
-		testRegion       = "fake-region"
-		testKargoProject = "fake-project"
-		testToken        = "fake-token"
+		fakeProjectID  = "test-project"
+		fakeGCRRepoURL = "gcr.io/my-project/my-repo"
+		fakeGARRepoURL = "us-central1-docker.pkg.dev/my-project/my-repo"
 	)
-	testRepoURL := fmt.Sprintf("%s-docker.pkg.dev/%s/debian/debian", testRegion, testGCPProjectID)
-
-	warmTokenCache := cache.New(0, 0)
-	warmTokenCache.Set(testKargoProject, testToken, cache.DefaultExpiration)
 
 	testCases := []struct {
-		name       string
-		credType   credentials.Type
-		repoURL    string
-		helper     *workloadIdentityFederationCredentialHelper
-		assertions func(*testing.T, *credentials.Credentials, *cache.Cache, error)
+		name     string
+		provider *WorkloadIdentityFederationProvider
+		credType credentials.Type
+		repoURL  string
+		assert   func(t *testing.T, result bool)
 	}{
 		{
-			name:     "cred type is not image",
-			credType: credentials.TypeGit,
-			helper:   &workloadIdentityFederationCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			name: "supports image credentials for GAR URL",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID: fakeProjectID,
+			},
+			credType: credentials.TypeImage,
+			repoURL:  fakeGARRepoURL,
+			assert: func(t *testing.T, result bool) {
+				assert.True(t, result, "should support GAR URL with image credentials")
 			},
 		},
 		{
-			name:     "GCP Workload Identity Federation not in use",
+			name: "supports image credentials for GCR URL",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID: fakeProjectID,
+			},
 			credType: credentials.TypeImage,
-			helper:   &workloadIdentityFederationCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  fakeGCRRepoURL,
+			assert: func(t *testing.T, result bool) {
+				assert.True(t, result, "should support GCR URL with image credentials")
 			},
 		},
 		{
-			name:     "repo URL does not match Artifact Registry URL regex",
-			credType: credentials.TypeImage,
-			repoURL:  "ghcr.io/fake-org/fake-repo",
-			helper: &workloadIdentityFederationCredentialHelper{
-				gcpProjectID: testGCPProjectID,
+			name: "rejects non-image credentials",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID: fakeProjectID,
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			credType: credentials.TypeGit,
+			repoURL:  fakeGARRepoURL,
+			assert: func(t *testing.T, result bool) {
+				assert.False(t, result, "should not support non-image credentials")
 			},
 		},
 		{
-			name:     "cache hit",
-			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper: &workloadIdentityFederationCredentialHelper{
-				gcpProjectID: testGCPProjectID,
-				tokenCache:   warmTokenCache,
+			name: "rejects non-GAR/GCR URL",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID: fakeProjectID,
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, accessTokenUsername, creds.Username)
-				require.Equal(t, testToken, creds.Password)
+			credType: credentials.TypeImage,
+			repoURL:  "docker.io/library/alpine",
+			assert: func(t *testing.T, result bool) {
+				assert.False(t, result, "should not support non-GAR/GCR URL")
 			},
 		},
 		{
-			name:     "cache miss; error getting access token",
+			name:     "rejects empty project ID",
+			provider: &WorkloadIdentityFederationProvider{},
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper: &workloadIdentityFederationCredentialHelper{
-				gcpProjectID: testGCPProjectID,
-				tokenCache:   cache.New(0, 0),
-				getAccessTokenFn: func(context.Context, string) (string, error) {
-					return "", fmt.Errorf("something went wrong")
-				},
+			repoURL:  fakeGARRepoURL,
+			assert: func(t *testing.T, result bool) {
+				assert.False(t, result, "should not support when project ID is empty")
 			},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "error getting GCP access token")
-				require.ErrorContains(t, err, "something went wrong")
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			result := tt.provider.Supports(tt.credType, tt.repoURL, nil)
+			tt.assert(t, result)
+		})
+	}
+}
+
+func TestWorkloadIdentityFederationProvider_GetCredentials(t *testing.T) {
+	const (
+		fakeProjectID  = "test-project"
+		fakeProject    = "kargo-project"
+		fakeGCRRepoURL = "gcr.io/my-project/my-repo"
+		fakeToken      = "fake-token"
+	)
+
+	testCases := []struct {
+		name       string
+		provider   *WorkloadIdentityFederationProvider
+		setupCache func(c *cache.Cache)
+		project    string
+		credType   credentials.Type
+		repoURL    string
+		assert     func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error)
+	}{
+		{
+			name: "returns nil when not supported",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID: fakeProjectID,
+			},
+			project:  fakeProject,
+			credType: credentials.TypeGit, // Not supported
+			repoURL:  fakeGCRRepoURL,
+			assert: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
 			},
 		},
 		{
-			name:     "cache miss; success (artifact registry)",
+			name: "cache hit",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID:  fakeProjectID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+			},
+			setupCache: func(c *cache.Cache) {
+				c.Set(tokenCacheKey(fakeProject), fakeToken, cache.DefaultExpiration)
+			},
+			project:  fakeProject,
 			credType: credentials.TypeImage,
-			repoURL:  testRepoURL,
-			helper: &workloadIdentityFederationCredentialHelper{
-				gcpProjectID: testGCPProjectID,
-				tokenCache:   cache.New(0, 0),
-				getAccessTokenFn: func(context.Context, string) (string, error) {
-					return testToken, nil
+			repoURL:  fakeGCRRepoURL,
+			assert: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, fakeToken, creds.Password)
+			},
+		},
+		{
+			name: "cache miss, successful token fetch",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID:  fakeProjectID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+				getAccessTokenFn: func(_ context.Context, _ string) (string, error) {
+					return fakeToken, nil
 				},
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, accessTokenUsername, creds.Username)
-				require.Equal(t, testToken, creds.Password)
-				_, found := c.Get(testKargoProject)
-				require.True(t, found)
+			project:  fakeProject,
+			credType: credentials.TypeImage,
+			repoURL:  fakeGCRRepoURL,
+			assert: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, fakeToken, creds.Password)
+
+				// Verify the token was cached
+				token, found := c.Get(tokenCacheKey(fakeProject))
+				assert.True(t, found)
+				assert.Equal(t, fakeToken, token)
 			},
 		},
 		{
-			name:     "cache miss; success (container registry; legacy)",
+			name: "error in getAccessToken",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID:  fakeProjectID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+				getAccessTokenFn: func(_ context.Context, _ string) (string, error) {
+					return "", fmt.Errorf("token fetch error")
+				},
+			},
+			project:  fakeProject,
 			credType: credentials.TypeImage,
-			repoURL:  "us.gcr.io/fake-project/fake-image:fake-tag",
-			helper: &workloadIdentityFederationCredentialHelper{
-				gcpProjectID: testGCPProjectID,
-				tokenCache:   cache.New(0, 0),
-				getAccessTokenFn: func(context.Context, string) (string, error) {
-					return testToken, nil
+			repoURL:  fakeGCRRepoURL,
+			assert: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "token fetch error")
+				assert.Nil(t, creds)
+			},
+		},
+		{
+			name: "empty token from getAccessToken",
+			provider: &WorkloadIdentityFederationProvider{
+				projectID:  fakeProjectID,
+				tokenCache: cache.New(10*time.Hour, time.Hour),
+				getAccessTokenFn: func(_ context.Context, _ string) (string, error) {
+					return "", nil
 				},
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, c *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, accessTokenUsername, creds.Username)
-				require.Equal(t, testToken, creds.Password)
-				_, found := c.Get(testKargoProject)
-				require.True(t, found)
+			project:  fakeProject,
+			credType: credentials.TypeImage,
+			repoURL:  fakeGCRRepoURL,
+			assert: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.Nil(t, creds)
 			},
 		},
 	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			creds, err := testCase.helper.getCredentials(
-				context.Background(),
-				testKargoProject,
-				testCase.credType,
-				testCase.repoURL,
-				nil, // Secret not used by this helper
-			)
-			testCase.assertions(t, creds, testCase.helper.tokenCache, err)
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			if tt.setupCache != nil {
+				tt.setupCache(tt.provider.tokenCache)
+			}
+
+			creds, err := tt.provider.GetCredentials(context.Background(), tt.project, tt.credType, tt.repoURL, nil)
+			tt.assert(t, tt.provider.tokenCache, creds, err)
 		})
 	}
 }
diff --git a/internal/credentials/kubernetes/github/app_test.go b/internal/credentials/kubernetes/github/app_test.go
index 87f29323..7073062e 100644
--- a/internal/credentials/kubernetes/github/app_test.go
+++ b/internal/credentials/kubernetes/github/app_test.go
@@ -3,193 +3,324 @@ package github
 import (
 	"context"
 	"encoding/base64"
-	"fmt"
-	"strconv"
+	"errors"
 	"testing"
 
 	"github.com/patrickmn/go-cache"
+	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	corev1 "k8s.io/api/core/v1"
 
 	"github.com/akuity/kargo/internal/credentials"
 )
 
-func TestAppCredentialHelper(t *testing.T) {
-	const (
-		testAppIDStr          = "12345"
-		testInstallationIDStr = "67890"
-		testPrivateKey        = "fake-private-key"
-		testAccessToken       = "fake-access-token"
-	)
-	testInstallationID, err := strconv.ParseInt(testInstallationIDStr, 10, 64)
-	require.NoError(t, err)
-	testAppID, err := strconv.ParseInt(testAppIDStr, 10, 64)
-	require.NoError(t, err)
-
-	warmTokenCache := cache.New(0, 0)
-	warmTokenCache.Set(
-		(&appCredentialHelper{}).tokenCacheKey(testAppID, testInstallationID, testPrivateKey),
-		testAccessToken,
-		cache.DefaultExpiration,
-	)
+func TestNewAppCredentialProvider(t *testing.T) {
+	provider := NewAppCredentialProvider().(*AppCredentialProvider) // nolint:forcetypeassert
+	assert.NotNil(t, provider)
+
+	assert.NotNil(t, provider.tokenCache)
+	assert.NotNil(t, provider.getAccessTokenFn)
+}
+
+func TestAppCredentialProvider_Supports(t *testing.T) {
+	p := NewAppCredentialProvider()
 
 	testCases := []struct {
-		name       string
-		credType   credentials.Type
-		secret     *corev1.Secret
-		helper     *appCredentialHelper
-		assertions func(*testing.T, *credentials.Credentials, *cache.Cache, error)
+		name     string
+		credType credentials.Type
+		repoURL  string
+		data     map[string][]byte
+		expected bool
 	}{
 		{
-			name:     "cred type is not git",
-			credType: credentials.TypeImage,
-			helper:   &appCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			name:     "supports valid Git credential with all required fields",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
 			},
+			expected: true,
 		},
 		{
-			name:     "secret is nil",
+			name:     "does not support non-Git credential type",
+			credType: credentials.Type("other"),
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
+			},
+			expected: false,
+		},
+		{
+			name:     "does not support empty data",
 			credType: credentials.TypeGit,
-			helper:   &appCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  "https://github.com/akuity/kargo",
+			data:     map[string][]byte{},
+			expected: false,
+		},
+		{
+			name:     "does not support missing appID",
+			credType: credentials.TypeGit,
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
 			},
+			expected: false,
 		},
 		{
-			name:     "no github details provided",
+			name:     "does not support missing installationID",
 			credType: credentials.TypeGit,
-			secret:   &corev1.Secret{},
-			helper:   &appCredentialHelper{},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.Nil(t, creds)
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:      []byte("123"),
+				privateKeyKey: []byte("private-key"),
 			},
+			expected: false,
 		},
 		{
-			name:     "app ID missing",
+			name:     "does not support missing privateKey",
 			credType: credentials.TypeGit,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					installationIDKey: []byte(testInstallationIDStr),
-					privateKeyKey:     []byte(testPrivateKey),
-				},
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+			},
+			expected: false,
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			result := p.Supports(tt.credType, tt.repoURL, tt.data)
+			assert.Equal(t, tt.expected, result)
+		})
+	}
+}
+
+func TestAppCredentialProvider_GetCredentials(t *testing.T) {
+	ctx := context.Background()
+
+	testCases := []struct {
+		name             string
+		credType         credentials.Type
+		repoURL          string
+		data             map[string][]byte
+		getAccessTokenFn func(appID, installationID int64, encodedPrivateKey, baseURL string) (string, error)
+		assertions       func(t *testing.T, creds *credentials.Credentials, err error)
+	}{
+		{
+			name:     "unsupported credential type",
+			credType: credentials.Type("other"),
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
 			},
-			helper: &appCredentialHelper{},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "must all be set or all be unset")
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.NoError(t, err)
 			},
 		},
 		{
-			name:     "installation ID missing",
+			name:     "invalid app ID",
 			credType: credentials.TypeGit,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					appIDKey:      []byte(testAppIDStr),
-					privateKeyKey: []byte(testPrivateKey),
-				},
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("invalid"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
 			},
-			helper: &appCredentialHelper{},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "must all be set or all be unset")
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.Error(t, err)
+				assert.ErrorContains(t, err, "error parsing app ID")
 			},
 		},
 		{
-			name:     "private key missing",
+			name:     "invalid installation ID",
 			credType: credentials.TypeGit,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					appIDKey:          []byte(testAppIDStr),
-					installationIDKey: []byte(testInstallationIDStr),
-				},
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("invalid"),
+				privateKeyKey:     []byte("private-key"),
 			},
-			helper: &appCredentialHelper{},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "must all be set or all be unset")
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.Error(t, err)
+				assert.ErrorContains(t, err, "error parsing installation ID")
 			},
 		},
 		{
-			name:     "cache hit",
+			name:     "invalid repo URL",
 			credType: credentials.TypeGit,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					appIDKey:          []byte(testAppIDStr),
-					installationIDKey: []byte(testInstallationIDStr),
-					privateKeyKey:     []byte(testPrivateKey),
-				},
-			},
-			helper: &appCredentialHelper{
-				tokenCache: warmTokenCache,
+			repoURL:  "://invalid",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
 			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, "kargo", creds.Username)
-				require.Equal(t, testAccessToken, creds.Password)
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.Error(t, err)
+				assert.ErrorContains(t, err, "error extracting base URL")
 			},
 		},
 		{
-			name:     "cache miss; error getting access token",
+			name:     "error getting token",
 			credType: credentials.TypeGit,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					appIDKey:          []byte(testAppIDStr),
-					installationIDKey: []byte(testInstallationIDStr),
-					privateKeyKey:     []byte(testPrivateKey),
-				},
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
 			},
-			helper: &appCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAccessTokenFn: func(int64, int64, string) (string, error) {
-					return "", fmt.Errorf("something went wrong")
-				},
+			getAccessTokenFn: func(_, _ int64, _, _ string) (string, error) {
+				return "", errors.New("token error")
 			},
-			assertions: func(t *testing.T, _ *credentials.Credentials, _ *cache.Cache, err error) {
-				require.ErrorContains(t, err, "error getting installation access token")
-				require.ErrorContains(t, err, "something went wrong")
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.Nil(t, creds)
+				assert.Error(t, err)
+				assert.ErrorContains(t, err, "token error")
 			},
 		},
 		{
-			name:     "cache miss; success",
+			name:     "successful token retrieval",
 			credType: credentials.TypeGit,
-			secret: &corev1.Secret{
-				Data: map[string][]byte{
-					appIDKey:          []byte(testAppIDStr),
-					installationIDKey: []byte(testInstallationIDStr),
-					privateKeyKey:     []byte(testPrivateKey),
-				},
-			},
-			helper: &appCredentialHelper{
-				tokenCache: cache.New(0, 0),
-				getAccessTokenFn: func(int64, int64, string) (string, error) {
-					return testAccessToken, nil
-				},
-			},
-			assertions: func(t *testing.T, creds *credentials.Credentials, _ *cache.Cache, err error) {
-				require.NoError(t, err)
-				require.NotNil(t, creds)
-				require.Equal(t, "kargo", creds.Username)
-				require.Equal(t, testAccessToken, creds.Password)
+			repoURL:  "https://github.com/akuity/kargo",
+			data: map[string][]byte{
+				appIDKey:          []byte("123"),
+				installationIDKey: []byte("456"),
+				privateKeyKey:     []byte("private-key"),
+			},
+			getAccessTokenFn: func(_, _ int64, _, _ string) (string, error) {
+				return "test-token", nil
+			},
+			assertions: func(t *testing.T, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, "test-token", creds.Password)
 			},
 		},
 	}
-	for _, testCase := range testCases {
-		t.Run(testCase.name, func(t *testing.T) {
-			creds, err := testCase.helper.getCredentials(
-				context.Background(),
-				"", // project is irrelevant for this helper
-				testCase.credType,
-				"", // repoURL is irrelevant for this helper
-				testCase.secret,
-			)
-			testCase.assertions(t, creds, testCase.helper.tokenCache, err)
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			provider := NewAppCredentialProvider().(*AppCredentialProvider) // nolint:forcetypeassert
+
+			if tt.getAccessTokenFn != nil {
+				provider.getAccessTokenFn = tt.getAccessTokenFn
+			}
+
+			creds, err := provider.GetCredentials(ctx, "", tt.credType, tt.repoURL, tt.data)
+			tt.assertions(t, creds, err)
 		})
 	}
 }
 
-func TestGetAccessToken(t *testing.T) {
+func TestAppCredentialProvider_getUsernameAndPassword(t *testing.T) {
+	const (
+		fakeAppID          = int64(123)
+		fakeInstallationID = int64(456)
+		fakePrivateKey     = "private-key"
+		fakeBaseURL        = "https://github.com"
+		fakeAccessToken    = "test-token"
+	)
+
+	testCases := []struct {
+		name              string
+		appID             int64
+		installationID    int64
+		encodedPrivateKey string
+		baseURL           string
+		setupCache        func(c *cache.Cache)
+		getAccessTokenFn  func(appID, installationID int64, encodedPrivateKey, baseURL string) (string, error)
+		assertions        func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error)
+	}{
+		{
+			name:              "cache hit",
+			appID:             fakeAppID,
+			installationID:    fakeInstallationID,
+			encodedPrivateKey: fakePrivateKey,
+			baseURL:           fakeBaseURL,
+			setupCache: func(c *cache.Cache) {
+				cacheKey := tokenCacheKey(fakeBaseURL, fakeAppID, fakeInstallationID, fakePrivateKey)
+				c.Set(cacheKey, fakeAccessToken, cache.DefaultExpiration)
+			},
+			assertions: func(t *testing.T, _ *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, fakeAccessToken, creds.Password)
+			},
+		},
+		{
+			name:              "cache miss, successful token fetch",
+			appID:             fakeAppID,
+			installationID:    fakeInstallationID,
+			encodedPrivateKey: fakePrivateKey,
+			baseURL:           fakeBaseURL,
+			getAccessTokenFn: func(_, _ int64, _, _ string) (string, error) {
+				return fakeAccessToken, nil
+			},
+			assertions: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.NoError(t, err)
+				assert.NotNil(t, creds)
+				assert.Equal(t, accessTokenUsername, creds.Username)
+				assert.Equal(t, fakeAccessToken, creds.Password)
+
+				// Verify the token was cached
+				cacheKey := tokenCacheKey(fakeBaseURL, fakeAppID, fakeInstallationID, fakePrivateKey)
+				cachedToken, found := c.Get(cacheKey)
+				assert.True(t, found)
+				assert.Equal(t, fakeAccessToken, cachedToken)
+			},
+		},
+		{
+			name:              "error in getAccessToken",
+			appID:             fakeAppID,
+			installationID:    fakeInstallationID,
+			encodedPrivateKey: fakePrivateKey,
+			baseURL:           fakeBaseURL,
+			getAccessTokenFn: func(_, _ int64, _, _ string) (string, error) {
+				return "", errors.New("token error")
+			},
+			assertions: func(t *testing.T, c *cache.Cache, creds *credentials.Credentials, err error) {
+				assert.ErrorContains(t, err, "token error")
+				assert.Nil(t, creds)
+
+				// Verify the token was not cached
+				cacheKey := tokenCacheKey(fakeBaseURL, fakeAppID, fakeInstallationID, fakePrivateKey)
+				_, found := c.Get(cacheKey)
+				assert.False(t, found)
+			},
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			provider := NewAppCredentialProvider().(*AppCredentialProvider) // nolint:forcetypeassert
+
+			if tt.setupCache != nil {
+				tt.setupCache(provider.tokenCache)
+			}
+
+			if tt.getAccessTokenFn != nil {
+				provider.getAccessTokenFn = tt.getAccessTokenFn
+			}
+
+			creds, err := provider.getUsernameAndPassword(tt.appID, tt.installationID, tt.encodedPrivateKey, tt.baseURL)
+			tt.assertions(t, provider.tokenCache, creds, err)
+		})
+	}
+}
+
+func Test_decodeKey(t *testing.T) {
 	const key = "-----BEGIN PRIVATE KEY-----\nfakekey\n-----END PRIVATE KEY-----"
 	testCases := []struct {
 		name        string
@@ -225,3 +356,50 @@ func TestGetAccessToken(t *testing.T) {
 		})
 	}
 }
+
+func Test_extractBaseURL(t *testing.T) {
+	testCases := []struct {
+		name        string
+		url         string
+		expected    string
+		shouldError bool
+	}{
+		{
+			name:        "valid HTTPS URL",
+			url:         "https://github.com/akuity/kargo",
+			expected:    "https://github.com",
+			shouldError: false,
+		},
+		{
+			name:        "valid HTTP URL",
+			url:         "http://github.com/akuity/kargo",
+			expected:    "http://github.com",
+			shouldError: false,
+		},
+		{
+			name:        "invalid URL",
+			url:         "://invalid",
+			expected:    "",
+			shouldError: true,
+		},
+		{
+			name:        "URL with port",
+			url:         "https://github.com:8080/akuity/kargo",
+			expected:    "https://github.com:8080",
+			shouldError: false,
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			result, err := extractBaseURL(tt.url)
+
+			if tt.shouldError {
+				assert.Error(t, err)
+			} else {
+				assert.NoError(t, err)
+				assert.Equal(t, tt.expected, result)
+			}
+		})
+	}
+}
diff --git a/internal/directives/helm_chart_updater_test.go b/internal/directives/helm_chart_updater_test.go
index eea32eab..63e86ccb 100644
--- a/internal/directives/helm_chart_updater_test.go
+++ b/internal/directives/helm_chart_updater_test.go
@@ -470,11 +470,11 @@ func Test_helmChartUpdater_updateDependencies(t *testing.T) {
 
 		// Prepare the credentials database
 		credentialsDB := &credentials.FakeDB{
-			GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-				return credentials.Credentials{
+			GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+				return &credentials.Credentials{
 					Username: "username",
 					Password: "password",
-				}, true, nil
+				}, nil
 			},
 		}
 
@@ -504,8 +504,8 @@ func Test_helmChartUpdater_updateDependencies(t *testing.T) {
 		{
 			name: "error loading dependency credentials",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{}, false, fmt.Errorf("something went wrong")
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return nil, fmt.Errorf("something went wrong")
 				},
 			},
 			chartDependencies: []chartDependency{
@@ -522,11 +522,11 @@ func Test_helmChartUpdater_updateDependencies(t *testing.T) {
 		{
 			name: "writes repository file",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return &credentials.Credentials{
 						Username: "username",
 						Password: "password",
-					}, true, nil
+					}, nil
 				},
 			},
 			chartDependencies: []chartDependency{
@@ -707,11 +707,11 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "HTTPS repository with credentials",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return &credentials.Credentials{
 						Username: "username",
 						Password: "password",
-					}, true, nil
+					}, nil
 				},
 			},
 			repositoryFile: repo.NewFile(),
@@ -737,11 +737,11 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "HTTP repository without credentials",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return &credentials.Credentials{
 						Username: "username",
 						Password: "password",
-					}, true, nil
+					}, nil
 				},
 			},
 			repositoryFile: repo.NewFile(),
@@ -767,11 +767,11 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "mixed HTTP and HTTPS repositories",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return &credentials.Credentials{
 						Username: "username",
 						Password: "password",
-					}, true, nil
+					}, nil
 				},
 			},
 			repositoryFile: repo.NewFile(),
@@ -818,11 +818,11 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "OCI credentials",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return &credentials.Credentials{
 						Username: "username",
 						Password: "password",
-					}, true, nil
+					}, nil
 				},
 			},
 			buildDependencies: func(registryURL string) []chartDependency {
@@ -855,11 +855,11 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "multiple HTTPS repositories",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return &credentials.Credentials{
 						Username: "username",
 						Password: "password",
-					}, true, nil
+					}, nil
 				},
 			},
 			repositoryFile: repo.NewFile(),
@@ -892,8 +892,8 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "error getting credentials",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{}, false, fmt.Errorf("something went wrong")
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return nil, fmt.Errorf("something went wrong")
 				},
 			},
 			buildDependencies: func(string) []chartDependency {
@@ -915,8 +915,8 @@ func Test_helmChartUpdater_setupDependencyRepositories(t *testing.T) {
 		{
 			name: "unauthenticated HTTPS repository",
 			credentialsDB: &credentials.FakeDB{
-				GetFn: func(context.Context, string, credentials.Type, string) (credentials.Credentials, bool, error) {
-					return credentials.Credentials{}, false, nil
+				GetFn: func(context.Context, string, credentials.Type, string) (*credentials.Credentials, error) {
+					return nil, nil
 				},
 			},
 			repositoryFile: repo.NewFile(),
diff --git a/internal/rollouts/analysis_run_builder_test.go b/internal/rollouts/analysis_run_builder_test.go
index b789a5b5..852536d1 100644
--- a/internal/rollouts/analysis_run_builder_test.go
+++ b/internal/rollouts/analysis_run_builder_test.go
@@ -15,8 +15,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
 )
 
 func TestAnalysisRunBuilder_Build(t *testing.T) {
diff --git a/internal/rollouts/analysis_template_test.go b/internal/rollouts/analysis_template_test.go
index 2911cf88..cce24adf 100644
--- a/internal/rollouts/analysis_template_test.go
+++ b/internal/rollouts/analysis_template_test.go
@@ -7,7 +7,7 @@ import (
 	"github.com/stretchr/testify/require"
 	"k8s.io/utils/ptr"
 
-	rolloutsapi "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 )
 
 func Test_flattenTemplates(t *testing.T) {
diff --git a/internal/server/approve_freight_v1alpha1_test.go b/internal/server/approve_freight_v1alpha1_test.go
index cd3632a8..66625de4 100644
--- a/internal/server/approve_freight_v1alpha1_test.go
+++ b/internal/server/approve_freight_v1alpha1_test.go
@@ -12,9 +12,9 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	fakeevent "github.com/akuity/kargo/internal/kubernetes/event/fake"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestApproveFreight(t *testing.T) {
diff --git a/internal/server/create_credentials_v1alpha1_test.go b/internal/server/create_credentials_v1alpha1_test.go
index 242810ca..94d3d7f9 100644
--- a/internal/server/create_credentials_v1alpha1_test.go
+++ b/internal/server/create_credentials_v1alpha1_test.go
@@ -14,11 +14,11 @@ import (
 	"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"
 	libCreds "github.com/akuity/kargo/internal/credentials"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestCreateCredentials(t *testing.T) {
diff --git a/internal/server/create_project_secret_v1alpha1_test.go b/internal/server/create_project_secret_v1alpha1_test.go
index 12808ee1..52b4da51 100644
--- a/internal/server/create_project_secret_v1alpha1_test.go
+++ b/internal/server/create_project_secret_v1alpha1_test.go
@@ -14,10 +14,10 @@ import (
 	"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/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestCreateProjectSecret(t *testing.T) {
diff --git a/internal/server/delete_analysistemplate_v1alpha1_test.go b/internal/server/delete_analysistemplate_v1alpha1_test.go
index 676f2132..6df10b33 100644
--- a/internal/server/delete_analysistemplate_v1alpha1_test.go
+++ b/internal/server/delete_analysistemplate_v1alpha1_test.go
@@ -13,11 +13,12 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
+	"github.com/akuity/kargo/internal/api/stubs/rollouts"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestDeleteAnalysisTemplate(t *testing.T) {
@@ -100,7 +101,7 @@ func TestDeleteAnalysisTemplate(t *testing.T) {
 							WithScheme(scheme).
 							WithObjects(
 								mustNewObject[corev1.Namespace]("testdata/namespace.yaml"),
-								mustNewObject[rollouts.AnalysisTemplate]("testdata/analysistemplate.yaml"),
+								mustNewObject[rolloutsapi.AnalysisTemplate]("testdata/analysistemplate.yaml"),
 							).
 							Build(), nil
 					},
diff --git a/internal/server/delete_clusteranalysistemplate_v1alpha1_test.go b/internal/server/delete_clusteranalysistemplate_v1alpha1_test.go
index afa8c10a..c28b0dfa 100644
--- a/internal/server/delete_clusteranalysistemplate_v1alpha1_test.go
+++ b/internal/server/delete_clusteranalysistemplate_v1alpha1_test.go
@@ -12,11 +12,12 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rolloutsapi "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
+	rollouts "github.com/akuity/kargo/internal/api/stubs/rollouts"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestDeleteClusterAnalysisTemplate(t *testing.T) {
@@ -78,7 +79,7 @@ func TestDeleteClusterAnalysisTemplate(t *testing.T) {
 						return fake.NewClientBuilder().
 							WithScheme(scheme).
 							WithObjects(
-								mustNewObject[rollouts.ClusterAnalysisTemplate]("testdata/clusteranalysistemplate.yaml"),
+								mustNewObject[rolloutsapi.ClusterAnalysisTemplate]("testdata/clusteranalysistemplate.yaml"),
 							).
 							Build(), nil
 					},
diff --git a/internal/server/delete_project_secret_v1alpha1_test.go b/internal/server/delete_project_secret_v1alpha1_test.go
index 4f97725b..153c0b58 100644
--- a/internal/server/delete_project_secret_v1alpha1_test.go
+++ b/internal/server/delete_project_secret_v1alpha1_test.go
@@ -14,11 +14,11 @@ import (
 	"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/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestDeleteProjectSecret(t *testing.T) {
diff --git a/internal/server/get_analysisrun_v1alpha1_test.go b/internal/server/get_analysisrun_v1alpha1_test.go
index 67c87b22..721238bc 100644
--- a/internal/server/get_analysisrun_v1alpha1_test.go
+++ b/internal/server/get_analysisrun_v1alpha1_test.go
@@ -15,10 +15,10 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetAnalysisRun(t *testing.T) {
diff --git a/internal/server/get_analysistemplate_v1alpha1_test.go b/internal/server/get_analysistemplate_v1alpha1_test.go
index d5a39e06..76be646d 100644
--- a/internal/server/get_analysistemplate_v1alpha1_test.go
+++ b/internal/server/get_analysistemplate_v1alpha1_test.go
@@ -15,11 +15,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetAnalysisTemplate(t *testing.T) {
diff --git a/internal/server/get_clusteranalysistemplate_v1alpha1_test.go b/internal/server/get_clusteranalysistemplate_v1alpha1_test.go
index 91578fa7..f98e81c9 100644
--- a/internal/server/get_clusteranalysistemplate_v1alpha1_test.go
+++ b/internal/server/get_clusteranalysistemplate_v1alpha1_test.go
@@ -14,11 +14,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetClusterAnalysisTemplate(t *testing.T) {
diff --git a/internal/server/get_config_v1alpha1_test.go b/internal/server/get_config_v1alpha1_test.go
index 7fa4bc48..b8d56869 100644
--- a/internal/server/get_config_v1alpha1_test.go
+++ b/internal/server/get_config_v1alpha1_test.go
@@ -7,8 +7,8 @@ import (
 	"connectrpc.com/connect"
 	"github.com/stretchr/testify/require"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	"github.com/akuity/kargo/internal/server/config"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetConfig(t *testing.T) {
diff --git a/internal/server/get_credentials_v1alpha1_test.go b/internal/server/get_credentials_v1alpha1_test.go
index cfb5869f..d7e98bbc 100644
--- a/internal/server/get_credentials_v1alpha1_test.go
+++ b/internal/server/get_credentials_v1alpha1_test.go
@@ -14,12 +14,12 @@ import (
 	"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"
 	libCreds "github.com/akuity/kargo/internal/credentials"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetCredentials(t *testing.T) {
diff --git a/internal/server/get_freight_v1alpha1_test.go b/internal/server/get_freight_v1alpha1_test.go
index 62be6d9e..ce6680ed 100644
--- a/internal/server/get_freight_v1alpha1_test.go
+++ b/internal/server/get_freight_v1alpha1_test.go
@@ -16,10 +16,10 @@ import (
 	"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/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetFreight(t *testing.T) {
diff --git a/internal/server/get_project_v1alpha1_test.go b/internal/server/get_project_v1alpha1_test.go
index cced6058..981226be 100644
--- a/internal/server/get_project_v1alpha1_test.go
+++ b/internal/server/get_project_v1alpha1_test.go
@@ -15,9 +15,9 @@ import (
 	"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/server/kubernetes"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetProject(t *testing.T) {
diff --git a/internal/server/get_promotion_v1alpha1_test.go b/internal/server/get_promotion_v1alpha1_test.go
index 3081a5b7..e6e1be69 100644
--- a/internal/server/get_promotion_v1alpha1_test.go
+++ b/internal/server/get_promotion_v1alpha1_test.go
@@ -16,10 +16,10 @@ import (
 	"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/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetPromotion(t *testing.T) {
diff --git a/internal/server/get_stage_v1alpha1_test.go b/internal/server/get_stage_v1alpha1_test.go
index 4786fc91..247d2ce6 100644
--- a/internal/server/get_stage_v1alpha1_test.go
+++ b/internal/server/get_stage_v1alpha1_test.go
@@ -15,10 +15,10 @@ import (
 	"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/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetStage(t *testing.T) {
diff --git a/internal/server/get_warehouse_v1alpha1_test.go b/internal/server/get_warehouse_v1alpha1_test.go
index ad07c217..498808ad 100644
--- a/internal/server/get_warehouse_v1alpha1_test.go
+++ b/internal/server/get_warehouse_v1alpha1_test.go
@@ -16,10 +16,10 @@ import (
 	"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/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestGetWarehouse(t *testing.T) {
diff --git a/internal/server/list_analysistemplates_v1alpha1_test.go b/internal/server/list_analysistemplates_v1alpha1_test.go
index 2b1dc39a..ebe6ba4e 100644
--- a/internal/server/list_analysistemplates_v1alpha1_test.go
+++ b/internal/server/list_analysistemplates_v1alpha1_test.go
@@ -12,11 +12,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestListAnalysisTemplates(t *testing.T) {
diff --git a/internal/server/list_clusteranalysistemplates_v1alpha1_test.go b/internal/server/list_clusteranalysistemplates_v1alpha1_test.go
index aacbe22d..b6a5526b 100644
--- a/internal/server/list_clusteranalysistemplates_v1alpha1_test.go
+++ b/internal/server/list_clusteranalysistemplates_v1alpha1_test.go
@@ -11,11 +11,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
-	rollouts "github.com/akuity/kargo/internal/controller/rollouts/api/v1alpha1"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	rollouts "github.com/akuity/kargo/api/stubs/rollouts/v1alpha1"
 	"github.com/akuity/kargo/internal/server/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestListClusterAnalysisTemplates(t *testing.T) {
diff --git a/internal/server/list_project_secrets_v1alpha1_test.go b/internal/server/list_project_secrets_v1alpha1_test.go
index 386fc8c2..56e430e8 100644
--- a/internal/server/list_project_secrets_v1alpha1_test.go
+++ b/internal/server/list_project_secrets_v1alpha1_test.go
@@ -13,11 +13,11 @@ import (
 	"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/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestListProjectSecrets(t *testing.T) {
diff --git a/internal/server/list_projects_v1alpha1_test.go b/internal/server/list_projects_v1alpha1_test.go
index 41372929..8bc3286d 100644
--- a/internal/server/list_projects_v1alpha1_test.go
+++ b/internal/server/list_projects_v1alpha1_test.go
@@ -12,9 +12,9 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestListProjects(t *testing.T) {
diff --git a/internal/server/list_promotions_v1alpha1_test.go b/internal/server/list_promotions_v1alpha1_test.go
index dc00856e..0986b2ba 100644
--- a/internal/server/list_promotions_v1alpha1_test.go
+++ b/internal/server/list_promotions_v1alpha1_test.go
@@ -15,10 +15,10 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestListPromotions(t *testing.T) {
diff --git a/internal/server/list_stages_v1alpha1_test.go b/internal/server/list_stages_v1alpha1_test.go
index 4411095a..7a932b55 100644
--- a/internal/server/list_stages_v1alpha1_test.go
+++ b/internal/server/list_stages_v1alpha1_test.go
@@ -12,10 +12,10 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestListStages(t *testing.T) {
diff --git a/internal/server/option/error_test.go b/internal/server/option/error_test.go
index 78599716..cf5dff7d 100644
--- a/internal/server/option/error_test.go
+++ b/internal/server/option/error_test.go
@@ -11,8 +11,8 @@ import (
 	kubeerr "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
-	"github.com/akuity/kargo/pkg/api/service/v1alpha1/svcv1alpha1connect"
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
+	"github.com/akuity/kargo/api/service/v1alpha1/svcv1alpha1connect"
 )
 
 type getVersionInfoHandlerFunc func(
diff --git a/internal/server/promote_downstream_v1alpha1_test.go b/internal/server/promote_downstream_v1alpha1_test.go
index 8d229b5a..975316ea 100644
--- a/internal/server/promote_downstream_v1alpha1_test.go
+++ b/internal/server/promote_downstream_v1alpha1_test.go
@@ -13,9 +13,9 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	fakeevent "github.com/akuity/kargo/internal/kubernetes/event/fake"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestPromoteDownstream(t *testing.T) {
diff --git a/internal/server/promote_to_stage_v1alpha1_test.go b/internal/server/promote_to_stage_v1alpha1_test.go
index ca48ff3c..adb7758a 100644
--- a/internal/server/promote_to_stage_v1alpha1_test.go
+++ b/internal/server/promote_to_stage_v1alpha1_test.go
@@ -13,9 +13,9 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
 	fakeevent "github.com/akuity/kargo/internal/kubernetes/event/fake"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestPromoteToStage(t *testing.T) {
diff --git a/internal/server/query_freights_v1alpha1_test.go b/internal/server/query_freights_v1alpha1_test.go
index 0bf2df70..bf75af5d 100644
--- a/internal/server/query_freights_v1alpha1_test.go
+++ b/internal/server/query_freights_v1alpha1_test.go
@@ -12,8 +12,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestQueryFreight(t *testing.T) {
diff --git a/internal/server/refresh_stage_v1alpha1_test.go b/internal/server/refresh_stage_v1alpha1_test.go
index 66a30efd..c7c8b02c 100644
--- a/internal/server/refresh_stage_v1alpha1_test.go
+++ b/internal/server/refresh_stage_v1alpha1_test.go
@@ -13,10 +13,10 @@ import (
 	"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"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestRefreshStage(t *testing.T) {
diff --git a/internal/server/update_freight_alias_v1alpha1_test.go b/internal/server/update_freight_alias_v1alpha1_test.go
index 3e9beafd..a196c2f8 100644
--- a/internal/server/update_freight_alias_v1alpha1_test.go
+++ b/internal/server/update_freight_alias_v1alpha1_test.go
@@ -10,8 +10,8 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	svcv1alpha1 "github.com/akuity/kargo/api/service/v1alpha1"
 	kargoapi "github.com/akuity/kargo/api/v1alpha1"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestUpdateFreightAlias(t *testing.T) {
diff --git a/internal/server/update_project_secret_v1alpha1_test.go b/internal/server/update_project_secret_v1alpha1_test.go
index 2afc34e3..795b5527 100644
--- a/internal/server/update_project_secret_v1alpha1_test.go
+++ b/internal/server/update_project_secret_v1alpha1_test.go
@@ -14,11 +14,11 @@ import (
 	"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/config"
 	"github.com/akuity/kargo/internal/server/kubernetes"
 	"github.com/akuity/kargo/internal/server/validation"
-	svcv1alpha1 "github.com/akuity/kargo/pkg/api/service/v1alpha1"
 )
 
 func TestUpdateProjectSecret(t *testing.T) {