Repository: armadaproject/armada
Pull request #3494 (2024-04-04 17:27:21)

Adding endpoint to allow requesting a job be preempted


Patch:
diff --git a/client/DotNet/Armada.Client/ClientGenerated.cs b/client/DotNet/Armada.Client/ClientGenerated.cs
index 08634ba0..9c49f5cd 100644
--- a/client/DotNet/Armada.Client/ClientGenerated.cs
+++ b/client/DotNet/Armada.Client/ClientGenerated.cs
@@ -594,6 +594,73 @@ namespace GResearch.Armada.Client
             }
         }
     
+        /// <returns>A successful response.</returns>
+        /// <exception cref="ApiException">A server side error occurred.</exception>
+        public System.Threading.Tasks.Task<object> PreemptJobsAsync(ApiJobPreemptRequest body)
+        {
+            return PreemptJobsAsync(body, System.Threading.CancellationToken.None);
+        }
+    
+        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
+        /// <returns>A successful response.</returns>
+        /// <exception cref="ApiException">A server side error occurred.</exception>
+        public async System.Threading.Tasks.Task<object> PreemptJobsAsync(ApiJobPreemptRequest body, System.Threading.CancellationToken cancellationToken)
+        {
+            var urlBuilder_ = new System.Text.StringBuilder();
+            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/v1/job/preempt");
+    
+            var client_ = _httpClient;
+            try
+            {
+                using (var request_ = new System.Net.Http.HttpRequestMessage())
+                {
+                    var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value));
+                    content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+                    request_.Content = content_;
+                    request_.Method = new System.Net.Http.HttpMethod("POST");
+                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+    
+                    PrepareRequest(client_, request_, urlBuilder_);
+                    var url_ = urlBuilder_.ToString();
+                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+                    PrepareRequest(client_, request_, url_);
+    
+                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+                    try
+                    {
+                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
+                        if (response_.Content != null && response_.Content.Headers != null)
+                        {
+                            foreach (var item_ in response_.Content.Headers)
+                                headers_[item_.Key] = item_.Value;
+                        }
+    
+                        ProcessResponse(client_, response_);
+    
+                        var status_ = ((int)response_.StatusCode).ToString();
+                        if (status_ == "200") 
+                        {
+                            var objectResponse_ = await ReadObjectResponseAsync<object>(response_, headers_).ConfigureAwait(false);
+                            return objectResponse_.Object;
+                        }
+                        else
+                        {
+                            var objectResponse_ = await ReadObjectResponseAsync<RuntimeError>(response_, headers_).ConfigureAwait(false);
+                            throw new ApiException<RuntimeError>("An unexpected error response.", (int)response_.StatusCode, objectResponse_.Text, headers_, objectResponse_.Object, null);
+                        }
+                    }
+                    finally
+                    {
+                        if (response_ != null)
+                            response_.Dispose();
+                    }
+                }
+            }
+            finally
+            {
+            }
+        }
+    
         /// <returns>A successful response.</returns>
         /// <exception cref="ApiException">A server side error occurred.</exception>
         public System.Threading.Tasks.Task<ApiJobReprioritizeResponse> ReprioritizeJobsAsync(ApiJobReprioritizeRequest body)
@@ -1294,6 +1361,9 @@ namespace GResearch.Armada.Client
         [Newtonsoft.Json.JsonProperty("preempted", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
         public ApiJobPreemptedEvent Preempted { get; set; }
     
+        [Newtonsoft.Json.JsonProperty("preempting", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public ApiJobPreemptingEvent Preempting { get; set; }
+    
         [Newtonsoft.Json.JsonProperty("queued", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
         public ApiJobQueuedEvent Queued { get; set; }
     
@@ -1818,6 +1888,21 @@ namespace GResearch.Armada.Client
         public string Queue { get; set; }
     
     
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.27.0 (Newtonsoft.Json v12.0.0.0)")]
+    public partial class ApiJobPreemptRequest 
+    {
+        [Newtonsoft.Json.JsonProperty("jobIds", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public System.Collections.Generic.ICollection<string> JobIds { get; set; }
+    
+        [Newtonsoft.Json.JsonProperty("jobSetId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public string JobSetId { get; set; }
+    
+        [Newtonsoft.Json.JsonProperty("queue", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public string Queue { get; set; }
+    
+    
     }
     
     [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.27.0 (Newtonsoft.Json v12.0.0.0)")]
@@ -1848,6 +1933,27 @@ namespace GResearch.Armada.Client
         public string RunId { get; set; }
     
     
+    }
+    
+    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.27.0 (Newtonsoft.Json v12.0.0.0)")]
+    public partial class ApiJobPreemptingEvent 
+    {
+        [Newtonsoft.Json.JsonProperty("created", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public System.DateTimeOffset? Created { get; set; }
+    
+        [Newtonsoft.Json.JsonProperty("jobId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public string JobId { get; set; }
+    
+        [Newtonsoft.Json.JsonProperty("jobSetId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public string JobSetId { get; set; }
+    
+        [Newtonsoft.Json.JsonProperty("queue", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public string Queue { get; set; }
+    
+        [Newtonsoft.Json.JsonProperty("requestor", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+        public string Requestor { get; set; }
+    
+    
     }
     
     [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.0.27.0 (Newtonsoft.Json v12.0.0.0)")]
diff --git a/cmd/armadactl/cmd/preempt.go b/cmd/armadactl/cmd/preempt.go
new file mode 100644
index 00000000..e1dd0df8
--- /dev/null
+++ b/cmd/armadactl/cmd/preempt.go
@@ -0,0 +1,39 @@
+package cmd
+
+import (
+	"github.com/spf13/cobra"
+
+	"github.com/armadaproject/armada/internal/armadactl"
+)
+
+func preemptCmd() *cobra.Command {
+	a := armadactl.New()
+	cmd := &cobra.Command{
+		Use:   "preempt",
+		Short: "Prempt jobs in armada.",
+		Long:  `Preempt jobs by queue, jobset and jobId.`,
+		Args:  cobra.ExactArgs(0),
+		PreRunE: func(cmd *cobra.Command, args []string) error {
+			return initParams(cmd, a.Params)
+		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			jobId, _ := cmd.Flags().GetString("jobId")
+			queue, _ := cmd.Flags().GetString("queue")
+			jobSetId, _ := cmd.Flags().GetString("jobSet")
+			return a.Preempt(queue, jobSetId, jobId)
+		},
+	}
+	cmd.Flags().String("jobId", "", "job to cancel")
+	if err := cmd.MarkFlagRequired("jobId"); err != nil {
+		panic(err)
+	}
+	cmd.Flags().String("queue", "", "queue of the job to be cancelled")
+	if err := cmd.MarkFlagRequired("queue"); err != nil {
+		panic(err)
+	}
+	cmd.Flags().String("jobSet", "", "jobSet of the job to be cancelled")
+	if err := cmd.MarkFlagRequired("jobSet"); err != nil {
+		panic(err)
+	}
+	return cmd
+}
diff --git a/cmd/armadactl/cmd/root.go b/cmd/armadactl/cmd/root.go
index e18db3df..1e6eacfd 100644
--- a/cmd/armadactl/cmd/root.go
+++ b/cmd/armadactl/cmd/root.go
@@ -45,6 +45,7 @@ The location of this file can be passed in using --config argument or picked fro
 		getQueueSchedulingReportCmd(armadactl.New()),
 		getJobSchedulingReportCmd(armadactl.New()),
 		configCmd(armadactl.New()),
+		preemptCmd(),
 	)
 
 	return cmd
diff --git a/internal/armada/permissions/permissions.go b/internal/armada/permissions/permissions.go
index 16ab1355..cab12193 100644
--- a/internal/armada/permissions/permissions.go
+++ b/internal/armada/permissions/permissions.go
@@ -8,6 +8,7 @@ import "github.com/armadaproject/armada/internal/common/auth/permission"
 const (
 	SubmitAnyJobs       permission.Permission = "submit_any_jobs"
 	CancelAnyJobs                             = "cancel_any_jobs"
+	PreemptAnyJobs                            = "preempt_any_jobs"
 	ReprioritizeAnyJobs                       = "reprioritize_any_jobs"
 	WatchAllEvents                            = "watch_all_events"
 	CreateQueue                               = "create_queue"
diff --git a/internal/armada/repository/apimessages/conversions.go b/internal/armada/repository/apimessages/conversions.go
index b8940b6c..ddcd00c7 100644
--- a/internal/armada/repository/apimessages/conversions.go
+++ b/internal/armada/repository/apimessages/conversions.go
@@ -27,6 +27,8 @@ func FromEventSequence(es *armadaevents.EventSequence) ([]*api.EventMessage, err
 			convertedEvents, err = FromInternalCancelled(es.UserId, es.Queue, es.JobSetName, *event.Created, esEvent.CancelledJob)
 		case *armadaevents.EventSequence_Event_CancelJob:
 			convertedEvents, err = FromInternalCancel(es.UserId, es.Queue, es.JobSetName, *event.Created, esEvent.CancelJob)
+		case *armadaevents.EventSequence_Event_JobPreemptionRequested:
+			convertedEvents, err = FromInternalPreemptionRequested(es.UserId, es.Queue, es.JobSetName, *event.Created, esEvent.JobPreemptionRequested)
 		case *armadaevents.EventSequence_Event_ReprioritiseJob:
 			convertedEvents, err = FromInternalReprioritiseJob(es.UserId, es.Queue, es.JobSetName, *event.Created, esEvent.ReprioritiseJob)
 		case *armadaevents.EventSequence_Event_ReprioritisedJob:
@@ -111,6 +113,27 @@ func FromInternalSubmit(owner string, groups []string, queue string, jobSet stri
 	}, nil
 }
 
+func FromInternalPreemptionRequested(userId string, queueName string, jobSetName string, time time.Time, e *armadaevents.JobPreemptionRequested) ([]*api.EventMessage, error) {
+	jobId, err := armadaevents.UlidStringFromProtoUuid(e.JobId)
+	if err != nil {
+		return nil, err
+	}
+
+	return []*api.EventMessage{
+		{
+			Events: &api.EventMessage_Preempting{
+				Preempting: &api.JobPreemptingEvent{
+					JobId:     jobId,
+					JobSetId:  jobSetName,
+					Queue:     queueName,
+					Created:   time,
+					Requestor: userId,
+				},
+			},
+		},
+	}, nil
+}
+
 func FromInternalCancel(userId string, queueName string, jobSetName string, time time.Time, e *armadaevents.CancelJob) ([]*api.EventMessage, error) {
 	jobId, err := armadaevents.UlidStringFromProtoUuid(e.JobId)
 	if err != nil {
diff --git a/internal/armada/server/submit_to_log.go b/internal/armada/server/submit_to_log.go
index a365033c..3ad2243d 100644
--- a/internal/armada/server/submit_to_log.go
+++ b/internal/armada/server/submit_to_log.go
@@ -386,6 +386,32 @@ func eventSequenceForJobIds(jobIds []string, q, jobSet, userId string, groups []
 	return sequence, validIds
 }
 
+func preemptJobEventSequenceForJobIds(jobIds []string, q, jobSet, userId string, groups []string) (*armadaevents.EventSequence, error) {
+	sequence := &armadaevents.EventSequence{
+		Queue:      q,
+		JobSetName: jobSet,
+		UserId:     userId,
+		Groups:     groups,
+		Events:     []*armadaevents.EventSequence_Event{},
+	}
+	for _, jobIdStr := range jobIds {
+		jobId, err := armadaevents.ProtoUuidFromUlidString(jobIdStr)
+		if err != nil {
+			log.WithError(err).Errorf("could not convert job id to uuid: %s", jobIdStr)
+			return nil, fmt.Errorf("could not convert job id to uuid: %s", jobIdStr)
+		}
+		sequence.Events = append(sequence.Events, &armadaevents.EventSequence_Event{
+			Created: pointer.Now(),
+			Event: &armadaevents.EventSequence_Event_JobPreemptionRequested{
+				JobPreemptionRequested: &armadaevents.JobPreemptionRequested{
+					JobId: jobId,
+				},
+			},
+		})
+	}
+	return sequence, nil
+}
+
 func (srv *PulsarSubmitServer) CancelJobSet(grpcCtx context.Context, req *api.JobSetCancelRequest) (*types.Empty, error) {
 	ctx := armadacontext.FromGrpcCtx(grpcCtx)
 	if req.Queue == "" {
@@ -572,6 +598,44 @@ func (srv *PulsarSubmitServer) ReprioritizeJobs(grpcCtx context.Context, req *ap
 	}, nil
 }
 
+func (srv *PulsarSubmitServer) PreemptJobs(grpcCtx context.Context, req *api.JobPreemptRequest) (*types.Empty, error) {
+	ctx := armadacontext.FromGrpcCtx(grpcCtx)
+
+	if req.Queue == "" {
+		return nil, &armadaerrors.ErrInvalidArgument{
+			Name:    "Queue",
+			Value:   req.Queue,
+			Message: "queue cannot be empty when preempting jobs",
+		}
+	}
+	if req.JobSetId == "" {
+		return nil, &armadaerrors.ErrInvalidArgument{
+			Name:    "JobSetId",
+			Value:   req.JobSetId,
+			Message: "jobset cannot be empty when preempting jobs",
+		}
+	}
+
+	userId, groups, err := srv.Authorize(ctx, req.Queue, permissions.PreemptAnyJobs, queue.PermissionVerbPreempt)
+	if err != nil {
+		return nil, err
+	}
+
+	sequence, err := preemptJobEventSequenceForJobIds(req.JobIds, req.Queue, req.JobSetId, userId, groups)
+	if err != nil {
+		return nil, err
+	}
+
+	// send the message to both schedulers because jobs may be on either
+	err = srv.publishToPulsar(ctx, []*armadaevents.EventSequence{sequence}, schedulers.All)
+	if err != nil {
+		log.WithError(err).Error("failed send to Pulsar")
+		return nil, status.Error(codes.Internal, "Failed to send message")
+	}
+
+	return &types.Empty{}, nil
+}
+
 // Authorize authorises a user request to submit a state transition message to the log.
 // User information used for authorization is extracted from the provided context.
 // Checks that the user has either anyPerm (e.g., permissions.SubmitAnyJobs) or perm (e.g., PermissionVerbSubmit) for this queue.
diff --git a/internal/armadactl/preempt.go b/internal/armadactl/preempt.go
new file mode 100644
index 00000000..8c9b183a
--- /dev/null
+++ b/internal/armadactl/preempt.go
@@ -0,0 +1,34 @@
+package armadactl
+
+import (
+	"fmt"
+
+	"github.com/pkg/errors"
+
+	"github.com/armadaproject/armada/internal/common"
+	"github.com/armadaproject/armada/pkg/api"
+	"github.com/armadaproject/armada/pkg/client"
+)
+
+// Preempt a job.
+func (a *App) Preempt(queue string, jobSetId string, jobId string) (outerErr error) {
+	apiConnectionDetails := a.Params.ApiConnectionDetails
+
+	fmt.Fprintf(a.Out, "Requesting preemption of job matching queue: %s, job set: %s, and job Id: %s\n", queue, jobSetId, jobId)
+	return client.WithSubmitClient(apiConnectionDetails, func(c api.SubmitClient) error {
+		ctx, cancel := common.ContextWithDefaultTimeout()
+		defer cancel()
+
+		_, err := c.PreemptJobs(ctx, &api.JobPreemptRequest{
+			JobIds:   []string{jobId},
+			JobSetId: jobSetId,
+			Queue:    queue,
+		})
+		if err != nil {
+			return errors.Wrapf(err, "error preempting job matching queue: %s, job set: %s, and job id: %s", queue, jobSetId, jobId)
+		}
+
+		fmt.Fprintf(a.Out, "Requested preemption for job %s\n", jobId)
+		return nil
+	})
+}
diff --git a/internal/scheduler/database/migrations/008_add_run_preemption_requested.sql b/internal/scheduler/database/migrations/008_add_run_preemption_requested.sql
new file mode 100644
index 00000000..7e7b98b4
--- /dev/null
+++ b/internal/scheduler/database/migrations/008_add_run_preemption_requested.sql
@@ -0,0 +1,5 @@
+ALTER TABLE runs ADD COLUMN preempt_requested boolean NOT NULL DEFAULT false;
+ALTER TABLE runs ADD COLUMN queue text;
+UPDATE runs as jr SET queue = j.queue from jobs as j WHERE j.job_id = jr.job_id;
+ALTER TABLE runs ALTER COLUMN queue SET NOT NULL;
+CREATE INDEX idx_runs_queue_jobset ON runs (queue, job_set);
diff --git a/internal/scheduler/database/models.go b/internal/scheduler/database/models.go
index 37f3c73c..a48323bc 100644
--- a/internal/scheduler/database/models.go
+++ b/internal/scheduler/database/models.go
@@ -79,4 +79,6 @@ type Run struct {
 	Pending                bool       `db:"pending"`
 	PreemptedTimestamp     *time.Time `db:"preempted_timestamp"`
 	PodRequirementsOverlay []byte     `db:"pod_requirements_overlay"`
+	PreemptRequested       bool       `db:"preempt_requested"`
+	Queue                  string     `db:"queue"`
 }
diff --git a/internal/scheduler/database/query.sql.go b/internal/scheduler/database/query.sql.go
index 65e2b60a..c2a904c0 100644
--- a/internal/scheduler/database/query.sql.go
+++ b/internal/scheduler/database/query.sql.go
@@ -90,6 +90,21 @@ func (q *Queries) MarkJobRunsFailedById(ctx context.Context, runIds []uuid.UUID)
 	return err
 }
 
+const markJobRunsPreemptRequestedByJobId = `-- name: MarkJobRunsPreemptRequestedByJobId :exec
+UPDATE runs SET preempt_requested = true WHERE queue = $1 and job_set = $2 and job_id = ANY($3::text[])
+`
+
+type MarkJobRunsPreemptRequestedByJobIdParams struct {
+	Queue  string   `db:"queue"`
+	JobSet string   `db:"job_set"`
+	JobIds []string `db:"job_ids"`
+}
+
+func (q *Queries) MarkJobRunsPreemptRequestedByJobId(ctx context.Context, arg MarkJobRunsPreemptRequestedByJobIdParams) error {
+	_, err := q.db.Exec(ctx, markJobRunsPreemptRequestedByJobId, arg.Queue, arg.JobSet, arg.JobIds)
+	return err
+}
+
 const markJobRunsReturnedById = `-- name: MarkJobRunsReturnedById :exec
 UPDATE runs SET returned = true WHERE run_id = ANY($1::UUID[])
 `
@@ -427,7 +442,7 @@ func (q *Queries) SelectNewJobs(ctx context.Context, arg SelectNewJobsParams) ([
 }
 
 const selectNewRuns = `-- name: SelectNewRuns :many
-SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay FROM runs WHERE serial > $1 ORDER BY serial LIMIT $2
+SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue FROM runs WHERE serial > $1 ORDER BY serial LIMIT $2
 `
 
 type SelectNewRunsParams struct {
@@ -468,6 +483,8 @@ func (q *Queries) SelectNewRuns(ctx context.Context, arg SelectNewRunsParams) ([
 			&i.Pending,
 			&i.PreemptedTimestamp,
 			&i.PodRequirementsOverlay,
+			&i.PreemptRequested,
+			&i.Queue,
 		); err != nil {
 			return nil, err
 		}
@@ -480,7 +497,7 @@ func (q *Queries) SelectNewRuns(ctx context.Context, arg SelectNewRunsParams) ([
 }
 
 const selectNewRunsForJobs = `-- name: SelectNewRunsForJobs :many
-SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay FROM runs WHERE serial > $1 AND job_id = ANY($2::text[]) ORDER BY serial
+SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue FROM runs WHERE serial > $1 AND job_id = ANY($2::text[]) ORDER BY serial
 `
 
 type SelectNewRunsForJobsParams struct {
@@ -521,6 +538,8 @@ func (q *Queries) SelectNewRunsForJobs(ctx context.Context, arg SelectNewRunsFor
 			&i.Pending,
 			&i.PreemptedTimestamp,
 			&i.PodRequirementsOverlay,
+			&i.PreemptRequested,
+			&i.Queue,
 		); err != nil {
 			return nil, err
 		}
diff --git a/internal/scheduler/database/query/query.sql b/internal/scheduler/database/query/query.sql
index 2de42c42..4b3dc424 100644
--- a/internal/scheduler/database/query/query.sql
+++ b/internal/scheduler/database/query/query.sql
@@ -37,6 +37,9 @@ SELECT run_id FROM runs;
 -- name: SelectNewRunsForJobs :many
 SELECT * FROM runs WHERE serial > $1 AND job_id = ANY(sqlc.arg(job_ids)::text[]) ORDER BY serial;
 
+-- name: MarkJobRunsPreemptRequestedByJobId :exec
+UPDATE runs SET preempt_requested = true WHERE queue = sqlc.arg(queue) and job_set = sqlc.arg(job_set) and job_id = ANY(sqlc.arg(job_ids)::text[]);
+
 -- name: MarkJobRunsSucceededById :exec
 UPDATE runs SET succeeded = true WHERE run_id = ANY(sqlc.arg(run_ids)::UUID[]);
 
diff --git a/internal/scheduler/jobdb/job.go b/internal/scheduler/jobdb/job.go
index 8d9a9e89..90482f9d 100644
--- a/internal/scheduler/jobdb/job.go
+++ b/internal/scheduler/jobdb/job.go
@@ -380,6 +380,11 @@ func (job *Job) Priority() uint32 {
 	return job.priority
 }
 
+// Priority returns the priority class of the job.
+func (job *Job) GetPriorityClass() types.PriorityClass {
+	return job.priorityClass
+}
+
 // GetSchedulingKey returns the scheduling key associated with a job.
 // The second return value is always true since scheduling keys are computed at job creation time.
 // This is needed for compatibility with interfaces.LegacySchedulerJob.
@@ -638,6 +643,7 @@ func (job *Job) WithNewRun(executor string, nodeId, nodeName string, scheduledAt
 		false,
 		false,
 		false,
+		false,
 		nil,
 		nil,
 		nil,
diff --git a/internal/scheduler/jobdb/job_run.go b/internal/scheduler/jobdb/job_run.go
index e6a0fd2b..af5c5a48 100644
--- a/internal/scheduler/jobdb/job_run.go
+++ b/internal/scheduler/jobdb/job_run.go
@@ -42,6 +42,8 @@ type JobRun struct {
 	running bool
 	// The time at which the run was reported as running by the executor.
 	runningTime *time.Time
+	// True if a user has requested this run be preempted.
+	preemptRequested bool
 	// True if the run has been reported as preempted by the executor.
 	preempted bool
 	// The time at which the run was reported as preempted by the executor.
@@ -219,6 +221,7 @@ func (jobDb *JobDb) CreateRun(
 	leased bool,
 	pending bool,
 	running bool,
+	preemptRequested bool,
 	preempted bool,
 	succeeded bool,
 	failed bool,
@@ -242,6 +245,7 @@ func (jobDb *JobDb) CreateRun(
 		leased:              leased,
 		pending:             pending,
 		running:             running,
+		preemptRequested:    preemptRequested,
 		preempted:           preempted,
 		succeeded:           succeeded,
 		failed:              failed,
@@ -389,6 +393,18 @@ func (run *JobRun) WithRunningTime(runningTime *time.Time) *JobRun {
 	return run
 }
 
+// PreemptRequested Returns true if there has been a request this run is preempted
+func (run *JobRun) PreemptRequested() bool {
+	return run.preemptRequested
+}
+
+// WithPreemptRequested returns a copy of the job run with the preemptRequested status updated.
+func (run *JobRun) WithPreemptRequested(preemptRequested bool) *JobRun {
+	run = run.DeepCopy()
+	run.preemptRequested = preemptRequested
+	return run
+}
+
 // Preempted Returns true if the executor has reported the job run as preempted
 func (run *JobRun) Preempted() bool {
 	return run.preempted
@@ -398,7 +414,7 @@ func (run *JobRun) PreemptedTime() *time.Time {
 	return run.preemptedTime
 }
 
-// WithRunning returns a copy of the job run with the running status updated.
+// WithPreempted returns a copy of the job run with the preempted status updated.
 func (run *JobRun) WithPreempted(preempted bool) *JobRun {
 	run = run.DeepCopy()
 	run.preempted = preempted
diff --git a/internal/scheduler/jobdb/reconciliation.go b/internal/scheduler/jobdb/reconciliation.go
index cda480fd..7052f3ce 100644
--- a/internal/scheduler/jobdb/reconciliation.go
+++ b/internal/scheduler/jobdb/reconciliation.go
@@ -183,6 +183,9 @@ func (jobDb *JobDb) reconcileRunDifferences(jobRun *JobRun, jobRepoRun *database
 			jobRun = jobRun.WithRunning(true).WithRunningTime(jobRepoRun.RunningTimestamp)
 			rst.Running = true
 		}
+		if jobRepoRun.PreemptRequested && !jobRun.PreemptRequested() {
+			jobRun = jobRun.WithPreemptRequested(true)
+		}
 		if jobRepoRun.Preempted && !jobRun.Preempted() {
 			jobRun = jobRun.WithPreempted(true).WithRunning(false).WithPreemptedTime(jobRepoRun.PreemptedTimestamp)
 			rst.Preempted = true
@@ -294,6 +297,7 @@ func (jobDb *JobDb) schedulerRunFromDatabaseRun(dbRun *database.Run) *JobRun {
 		dbRun.LeasedTimestamp != nil,
 		dbRun.Pending,
 		dbRun.Running,
+		dbRun.PreemptRequested,
 		dbRun.Preempted,
 		dbRun.Succeeded,
 		dbRun.Failed,
diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go
index fb955fe9..62ebc87f 100644
--- a/internal/scheduler/scheduler.go
+++ b/internal/scheduler/scheduler.go
@@ -513,53 +513,57 @@ func AppendEventSequencesFromPreemptedJobs(eventSequences []*armadaevents.EventS
 		eventSequences = append(eventSequences, &armadaevents.EventSequence{
 			Queue:      job.Queue(),
 			JobSetName: job.Jobset(),
-			Events: []*armadaevents.EventSequence_Event{
-				{
-					Created: &time,
-					Event: &armadaevents.EventSequence_Event_JobRunPreempted{
-						JobRunPreempted: &armadaevents.JobRunPreempted{
-							PreemptedRunId: armadaevents.ProtoUuidFromUuid(run.Id()),
-							PreemptedJobId: jobId,
-						},
-					},
+			Events:     createEventsForPreemptedJob(jobId, armadaevents.ProtoUuidFromUuid(run.Id()), time),
+		})
+	}
+	return eventSequences, nil
+}
+
+func createEventsForPreemptedJob(jobId *armadaevents.Uuid, runId *armadaevents.Uuid, time time.Time) []*armadaevents.EventSequence_Event {
+	return []*armadaevents.EventSequence_Event{
+		{
+			Created: &time,
+			Event: &armadaevents.EventSequence_Event_JobRunPreempted{
+				JobRunPreempted: &armadaevents.JobRunPreempted{
+					PreemptedRunId: runId,
+					PreemptedJobId: jobId,
 				},
-				{
-					Created: &time,
-					Event: &armadaevents.EventSequence_Event_JobRunErrors{
-						JobRunErrors: &armadaevents.JobRunErrors{
-							RunId: armadaevents.ProtoUuidFromUuid(run.Id()),
-							JobId: jobId,
-							Errors: []*armadaevents.Error{
-								{
-									Terminal: true,
-									Reason: &armadaevents.Error_JobRunPreemptedError{
-										JobRunPreemptedError: &armadaevents.JobRunPreemptedError{},
-									},
-								},
+			},
+		},
+		{
+			Created: &time,
+			Event: &armadaevents.EventSequence_Event_JobRunErrors{
+				JobRunErrors: &armadaevents.JobRunErrors{
+					RunId: runId,
+					JobId: jobId,
+					Errors: []*armadaevents.Error{
+						{
+							Terminal: true,
+							Reason: &armadaevents.Error_JobRunPreemptedError{
+								JobRunPreemptedError: &armadaevents.JobRunPreemptedError{},
 							},
 						},
 					},
 				},
-				{
-					Created: &time,
-					Event: &armadaevents.EventSequence_Event_JobErrors{
-						JobErrors: &armadaevents.JobErrors{
-							JobId: jobId,
-							Errors: []*armadaevents.Error{
-								{
-									Terminal: true,
-									Reason: &armadaevents.Error_JobRunPreemptedError{
-										JobRunPreemptedError: &armadaevents.JobRunPreemptedError{},
-									},
-								},
+			},
+		},
+		{
+			Created: &time,
+			Event: &armadaevents.EventSequence_Event_JobErrors{
+				JobErrors: &armadaevents.JobErrors{
+					JobId: jobId,
+					Errors: []*armadaevents.Error{
+						{
+							Terminal: true,
+							Reason: &armadaevents.Error_JobRunPreemptedError{
+								JobRunPreemptedError: &armadaevents.JobRunPreemptedError{},
 							},
 						},
 					},
 				},
 			},
-		})
+		},
 	}
-	return eventSequences, nil
 }
 
 func AppendEventSequencesFromScheduledJobs(eventSequences []*armadaevents.EventSequence, jctxs []*schedulercontext.JobSchedulingContext, additionalAnnotationsByJobId map[string]map[string]string) ([]*armadaevents.EventSequence, error) {
@@ -803,6 +807,9 @@ func (s *Scheduler) generateUpdateMessagesFromJob(job *jobdb.Job, jobRunErrors m
 
 				events = append(events, jobErrors)
 			}
+		} else if lastRun.PreemptRequested() && job.GetPriorityClass().Preemptible {
+			job = job.WithQueued(false).WithFailed(true).WithUpdatedRun(lastRun.WithoutTerminal().WithFailed(true))
+			events = append(events, createEventsForPreemptedJob(jobId, armadaevents.ProtoUuidFromUuid(lastRun.Id()), s.clock.Now())...)
 		}
 	}
 
diff --git a/internal/scheduleringester/dbops.go b/internal/scheduleringester/dbops.go
index 236b6b76..47105c06 100644
--- a/internal/scheduleringester/dbops.go
+++ b/internal/scheduleringester/dbops.go
@@ -116,24 +116,25 @@ func discardNilOps(ops []DbOperation) []DbOperation {
 }
 
 type (
-	InsertJobs                 map[string]*schedulerdb.Job
-	InsertRuns                 map[uuid.UUID]*JobRunDetails
-	UpdateJobSetPriorities     map[JobSetKey]int64
-	MarkJobSetsCancelRequested map[JobSetKey]*JobSetCancelAction
-	MarkJobsCancelRequested    map[string]bool
-	MarkJobsCancelled          map[string]time.Time
-	MarkJobsSucceeded          map[string]bool
-	MarkJobsFailed             map[string]bool
-	UpdateJobPriorities        map[string]int64
-	UpdateJobSchedulingInfo    map[string]*JobSchedulingInfoUpdate
-	UpdateJobQueuedState       map[string]*JobQueuedStateUpdate
-	MarkRunsSucceeded          map[uuid.UUID]time.Time
-	MarkRunsFailed             map[uuid.UUID]*JobRunFailed
-	MarkRunsRunning            map[uuid.UUID]time.Time
-	MarkRunsPending            map[uuid.UUID]time.Time
-	MarkRunsPreempted          map[uuid.UUID]time.Time
-	InsertJobRunErrors         map[uuid.UUID]*schedulerdb.JobRunError
-	InsertPartitionMarker      struct {
+	InsertJobs                     map[string]*schedulerdb.Job
+	InsertRuns                     map[uuid.UUID]*JobRunDetails
+	UpdateJobSetPriorities         map[JobSetKey]int64
+	MarkJobSetsCancelRequested     map[JobSetKey]*JobSetCancelAction
+	MarkJobsCancelRequested        map[string]bool
+	MarkJobsCancelled              map[string]time.Time
+	MarkJobsSucceeded              map[string]bool
+	MarkJobsFailed                 map[string]bool
+	UpdateJobPriorities            map[string]int64
+	UpdateJobSchedulingInfo        map[string]*JobSchedulingInfoUpdate
+	UpdateJobQueuedState           map[string]*JobQueuedStateUpdate
+	MarkRunsSucceeded              map[uuid.UUID]time.Time
+	MarkRunsFailed                 map[uuid.UUID]*JobRunFailed
+	MarkRunsForJobPreemptRequested map[JobSetKey][]string
+	MarkRunsRunning                map[uuid.UUID]time.Time
+	MarkRunsPending                map[uuid.UUID]time.Time
+	MarkRunsPreempted              map[uuid.UUID]time.Time
+	InsertJobRunErrors             map[uuid.UUID]*schedulerdb.JobRunError
+	InsertPartitionMarker          struct {
 		markers []*schedulerdb.Marker
 	}
 )
@@ -172,6 +173,10 @@ func (a MarkJobsCancelRequested) Merge(b DbOperation) bool {
 	return mergeInMap(a, b)
 }
 
+func (a MarkRunsForJobPreemptRequested) Merge(b DbOperation) bool {
+	return mergeListMaps(a, b)
+}
+
 func (a UpdateJobSchedulingInfo) Merge(b DbOperation) bool {
 	switch op := b.(type) {
 	case UpdateJobSchedulingInfo:
@@ -258,7 +263,7 @@ func (a *InsertPartitionMarker) Merge(b DbOperation) bool {
 }
 
 // mergeInMap merges an op b into a, provided that b is of the same type as a.
-// For example, if a is of type MarkJobSetsCancelRequested, b is only merged if also of type MarkJobsCancelRequested.
+// For example, if a is of type MarkJobSetsCancelRequested, b is only merged if also of type MarkJobSetsCancelRequested.
 // Returns true if the ops were merged and false otherwise.
 func mergeInMap[M ~map[K]V, K comparable, V any](a M, b DbOperation) bool {
 	// Using a type switch here, since using a type assertion
@@ -271,6 +276,27 @@ func mergeInMap[M ~map[K]V, K comparable, V any](a M, b DbOperation) bool {
 	return false
 }
 
+// mergeListMaps merges an op b into a, provided that b is of the same type as a.
+// If merged, the resulting map will contain all keys from a and b
+// In case both a and b have the same key, the values for that key will be combined
+// Returns true if the ops were merged and false otherwise.
+func mergeListMaps[M ~map[K][]V, K comparable, V any](a M, b DbOperation) bool {
+	// Using a type switch here, since using a type assertion
+	// (which should also work in theory) crashes the go1.19 compiler.
+	switch op := b.(type) {
+	case M:
+		for k, v := range op {
+			if _, present := a[k]; present {
+				a[k] = append(a[k], v...)
+			} else {
+				a[k] = v
+			}
+		}
+		return true
+	}
+	return false
+}
+
 func (a InsertJobs) CanBeAppliedBefore(b DbOperation) bool {
 	// We don't check for job and run ops here,
 	// since job and run ops can never appear before the corresponding InsertJobs.
@@ -318,6 +344,10 @@ func (a MarkJobsCancelRequested) CanBeAppliedBefore(b DbOperation) bool {
 	return !definesJob(a, b) && !definesRunForJob(a, b)
 }
 
+func (a MarkRunsForJobPreemptRequested) CanBeAppliedBefore(b DbOperation) bool {
+	return !definesJobInSet(a, b) && !definesRunInSet(a, b)
+}
+
 func (a MarkJobsSucceeded) CanBeAppliedBefore(b DbOperation) bool {
 	return !definesJob(a, b)
 }
diff --git a/internal/scheduleringester/instructions.go b/internal/scheduleringester/instructions.go
index 50934667..e22dcac5 100644
--- a/internal/scheduleringester/instructions.go
+++ b/internal/scheduleringester/instructions.go
@@ -93,6 +93,8 @@ func (c *InstructionConverter) dbOperationsFromEventSequence(es *armadaevents.Ev
 			operationsFromEvent, err = c.handleJobSucceeded(event.GetJobSucceeded())
 		case *armadaevents.EventSequence_Event_JobErrors:
 			operationsFromEvent, err = c.handleJobErrors(event.GetJobErrors())
+		case *armadaevents.EventSequence_Event_JobPreemptionRequested:
+			operationsFromEvent, err = c.handleJobPreemptionRequested(event.GetJobPreemptionRequested(), meta)
 		case *armadaevents.EventSequence_Event_ReprioritiseJob:
 			operationsFromEvent, err = c.handleReprioritiseJob(event.GetReprioritiseJob())
 		case *armadaevents.EventSequence_Event_ReprioritiseJobSet:
@@ -205,6 +207,7 @@ func (c *InstructionConverter) handleJobRunLeased(jobRunLeased *armadaevents.Job
 				JobID:                  jobId,
 				Created:                eventTime.UnixNano(),
 				JobSet:                 meta.jobset,
+				Queue:                  meta.queue,
 				Executor:               jobRunLeased.GetExecutorId(),
 				Node:                   jobRunLeased.GetNodeId(),
 				ScheduledAtPriority:    scheduledAtPriority,
@@ -321,6 +324,19 @@ func (c *InstructionConverter) handleJobErrors(jobErrors *armadaevents.JobErrors
 	return nil, nil
 }
 
+func (c *InstructionConverter) handleJobPreemptionRequested(preemptionRequested *armadaevents.JobPreemptionRequested, meta eventSequenceCommon) ([]DbOperation, error) {
+	jobId, err := armadaevents.UlidStringFromProtoUuid(preemptionRequested.GetJobId())
+	if err != nil {
+		return nil, err
+	}
+	return []DbOperation{MarkRunsForJobPreemptRequested{
+		JobSetKey{
+			queue:  meta.queue,
+			jobSet: meta.jobset,
+		}: []string{jobId},
+	}}, nil
+}
+
 func (c *InstructionConverter) handleReprioritiseJob(reprioritiseJob *armadaevents.ReprioritiseJob) ([]DbOperation, error) {
 	jobId, err := armadaevents.UlidStringFromProtoUuid(reprioritiseJob.GetJobId())
 	if err != nil {
diff --git a/internal/scheduleringester/schedulerdb.go b/internal/scheduleringester/schedulerdb.go
index 70c09833..5deb71c8 100644
--- a/internal/scheduleringester/schedulerdb.go
+++ b/internal/scheduleringester/schedulerdb.go
@@ -195,6 +195,18 @@ func (s *SchedulerDb) WriteDbOp(ctx *armadacontext.Context, tx pgx.Tx, op DbOper
 		if _, err := tx.Exec(ctx, sqlStmt, jobIds, canceled, cancelTimes); err != nil {
 			return errors.WithStack(err)
 		}
+	case MarkRunsForJobPreemptRequested:
+		for key, value := range o {
+			params := schedulerdb.MarkJobRunsPreemptRequestedByJobIdParams{
+				Queue:  key.queue,
+				JobSet: key.jobSet,
+				JobIds: value,
+			}
+			err := queries.MarkJobRunsPreemptRequestedByJobId(ctx, params)
+			if err != nil {
+				return errors.WithStack(err)
+			}
+		}
 	case MarkJobsSucceeded:
 		jobIds := maps.Keys(o)
 		err := queries.MarkJobsSucceededById(ctx, jobIds)
@@ -352,8 +364,8 @@ func multiColumnRunsUpdateStmt(id, phaseColumn, timeStampColumn string) string {
 	return fmt.Sprintf(`update runs set
 	%[2]v = runs_temp.%[2]v,
 	%[3]v = runs_temp.%[3]v
-	from (select * from unnest($1::%[4]v[], $2::boolean[] ,$3::timestamptz[])) 
-	as runs_temp(%[1]v, %[2]v, %[3]v) 
+	from (select * from unnest($1::%[4]v[], $2::boolean[] ,$3::timestamptz[]))
+	as runs_temp(%[1]v, %[2]v, %[3]v)
 	where runs.%[1]v = runs_temp.%[1]v;`,
 		id, phaseColumn, timeStampColumn, idPgType)
 }
diff --git a/pkg/api/api.swagger.go b/pkg/api/api.swagger.go
index 16554af4..278fc698 100644
--- a/pkg/api/api.swagger.go
+++ b/pkg/api/api.swagger.go
@@ -309,6 +309,36 @@ func SwaggerJsonTemplate() string {
 		"        }\n" +
 		"      }\n" +
 		"    },\n" +
+		"    \"/v1/job/preempt\": {\n" +
+		"      \"post\": {\n" +
+		"        \"tags\": [\n" +
+		"          \"Submit\"\n" +
+		"        ],\n" +
+		"        \"operationId\": \"PreemptJobs\",\n" +
+		"        \"parameters\": [\n" +
+		"          {\n" +
+		"            \"name\": \"body\",\n" +
+		"            \"in\": \"body\",\n" +
+		"            \"required\": true,\n" +
+		"            \"schema\": {\n" +
+		"              \"$ref\": \"#/definitions/apiJobPreemptRequest\"\n" +
+		"            }\n" +
+		"          }\n" +
+		"        ],\n" +
+		"        \"responses\": {\n" +
+		"          \"200\": {\n" +
+		"            \"description\": \"A successful response.\",\n" +
+		"            \"schema\": {}\n" +
+		"          },\n" +
+		"          \"default\": {\n" +
+		"            \"description\": \"An unexpected error response.\",\n" +
+		"            \"schema\": {\n" +
+		"              \"$ref\": \"#/definitions/runtimeError\"\n" +
+		"            }\n" +
+		"          }\n" +
+		"        }\n" +
+		"      }\n" +
+		"    },\n" +
 		"    \"/v1/job/reprioritize\": {\n" +
 		"      \"post\": {\n" +
 		"        \"tags\": [\n" +
@@ -658,6 +688,9 @@ func SwaggerJsonTemplate() string {
 		"        \"preempted\": {\n" +
 		"          \"$ref\": \"#/definitions/apiJobPreemptedEvent\"\n" +
 		"        },\n" +
+		"        \"preempting\": {\n" +
+		"          \"$ref\": \"#/definitions/apiJobPreemptingEvent\"\n" +
+		"        },\n" +
 		"        \"queued\": {\n" +
 		"          \"$ref\": \"#/definitions/apiJobQueuedEvent\"\n" +
 		"        },\n" +
@@ -1231,6 +1264,24 @@ func SwaggerJsonTemplate() string {
 		"        }\n" +
 		"      }\n" +
 		"    },\n" +
+		"    \"apiJobPreemptRequest\": {\n" +
+		"      \"type\": \"object\",\n" +
+		"      \"title\": \"swagger:model\",\n" +
+		"      \"properties\": {\n" +
+		"        \"jobIds\": {\n" +
+		"          \"type\": \"array\",\n" +
+		"          \"items\": {\n" +
+		"            \"type\": \"string\"\n" +
+		"          }\n" +
+		"        },\n" +
+		"        \"jobSetId\": {\n" +
+		"          \"type\": \"string\"\n" +
+		"        },\n" +
+		"        \"queue\": {\n" +
+		"          \"type\": \"string\"\n" +
+		"        }\n" +
+		"      }\n" +
+		"    },\n" +
 		"    \"apiJobPreemptedEvent\": {\n" +
 		"      \"type\": \"object\",\n" +
 		"      \"properties\": {\n" +
@@ -1261,6 +1312,27 @@ func SwaggerJsonTemplate() string {
 		"        }\n" +
 		"      }\n" +
 		"    },\n" +
+		"    \"apiJobPreemptingEvent\": {\n" +
+		"      \"type\": \"object\",\n" +
+		"      \"properties\": {\n" +
+		"        \"created\": {\n" +
+		"          \"type\": \"string\",\n" +
+		"          \"format\": \"date-time\"\n" +
+		"        },\n" +
+		"        \"jobId\": {\n" +
+		"          \"type\": \"string\"\n" +
+		"        },\n" +
+		"        \"jobSetId\": {\n" +
+		"          \"type\": \"string\"\n" +
+		"        },\n" +
+		"        \"queue\": {\n" +
+		"          \"type\": \"string\"\n" +
+		"        },\n" +
+		"        \"requestor\": {\n" +
+		"          \"type\": \"string\"\n" +
+		"        }\n" +
+		"      }\n" +
+		"    },\n" +
 		"    \"apiJobQueuedEvent\": {\n" +
 		"      \"type\": \"object\",\n" +
 		"      \"properties\": {\n" +
diff --git a/pkg/api/api.swagger.json b/pkg/api/api.swagger.json
index 501bcf5f..586e1e97 100644
--- a/pkg/api/api.swagger.json
+++ b/pkg/api/api.swagger.json
@@ -298,6 +298,36 @@
         }
       }
     },
+    "/v1/job/preempt": {
+      "post": {
+        "tags": [
+          "Submit"
+        ],
+        "operationId": "PreemptJobs",
+        "parameters": [
+          {
+            "name": "body",
+            "in": "body",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/apiJobPreemptRequest"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "A successful response.",
+            "schema": {}
+          },
+          "default": {
+            "description": "An unexpected error response.",
+            "schema": {
+              "$ref": "#/definitions/runtimeError"
+            }
+          }
+        }
+      }
+    },
     "/v1/job/reprioritize": {
       "post": {
         "tags": [
@@ -647,6 +677,9 @@
         "preempted": {
           "$ref": "#/definitions/apiJobPreemptedEvent"
         },
+        "preempting": {
+          "$ref": "#/definitions/apiJobPreemptingEvent"
+        },
         "queued": {
           "$ref": "#/definitions/apiJobQueuedEvent"
         },
@@ -1220,6 +1253,24 @@
         }
       }
     },
+    "apiJobPreemptRequest": {
+      "type": "object",
+      "title": "swagger:model",
+      "properties": {
+        "jobIds": {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "jobSetId": {
+          "type": "string"
+        },
+        "queue": {
+          "type": "string"
+        }
+      }
+    },
     "apiJobPreemptedEvent": {
       "type": "object",
       "properties": {
@@ -1250,6 +1301,27 @@
         }
       }
     },
+    "apiJobPreemptingEvent": {
+      "type": "object",
+      "properties": {
+        "created": {
+          "type": "string",
+          "format": "date-time"
+        },
+        "jobId": {
+          "type": "string"
+        },
+        "jobSetId": {
+          "type": "string"
+        },
+        "queue": {
+          "type": "string"
+        },
+        "requestor": {
+          "type": "string"
+        }
+      }
+    },
     "apiJobQueuedEvent": {
       "type": "object",
       "properties": {
diff --git a/pkg/api/event.pb.go b/pkg/api/event.pb.go
index c8825e18..a0e531e6 100644
--- a/pkg/api/event.pb.go
+++ b/pkg/api/event.pb.go
@@ -1151,6 +1151,81 @@ func (m *JobFailedEvent) GetCause() Cause {
 	return Cause_Error
 }
 
+type JobPreemptingEvent struct {
+	JobId     string    `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
+	JobSetId  string    `protobuf:"bytes,2,opt,name=job_set_id,json=jobSetId,proto3" json:"jobSetId,omitempty"`
+	Queue     string    `protobuf:"bytes,3,opt,name=queue,proto3" json:"queue,omitempty"`
+	Created   time.Time `protobuf:"bytes,4,opt,name=created,proto3,stdtime" json:"created"`
+	Requestor string    `protobuf:"bytes,5,opt,name=requestor,proto3" json:"requestor,omitempty"`
+}
+
+func (m *JobPreemptingEvent) Reset()      { *m = JobPreemptingEvent{} }
+func (*JobPreemptingEvent) ProtoMessage() {}
+func (*JobPreemptingEvent) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7758595c3bb8cf56, []int{11}
+}
+func (m *JobPreemptingEvent) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *JobPreemptingEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_JobPreemptingEvent.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *JobPreemptingEvent) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_JobPreemptingEvent.Merge(m, src)
+}
+func (m *JobPreemptingEvent) XXX_Size() int {
+	return m.Size()
+}
+func (m *JobPreemptingEvent) XXX_DiscardUnknown() {
+	xxx_messageInfo_JobPreemptingEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_JobPreemptingEvent proto.InternalMessageInfo
+
+func (m *JobPreemptingEvent) GetJobId() string {
+	if m != nil {
+		return m.JobId
+	}
+	return ""
+}
+
+func (m *JobPreemptingEvent) GetJobSetId() string {
+	if m != nil {
+		return m.JobSetId
+	}
+	return ""
+}
+
+func (m *JobPreemptingEvent) GetQueue() string {
+	if m != nil {
+		return m.Queue
+	}
+	return ""
+}
+
+func (m *JobPreemptingEvent) GetCreated() time.Time {
+	if m != nil {
+		return m.Created
+	}
+	return time.Time{}
+}
+
+func (m *JobPreemptingEvent) GetRequestor() string {
+	if m != nil {
+		return m.Requestor
+	}
+	return ""
+}
+
 type JobPreemptedEvent struct {
 	JobId           string    `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
 	JobSetId        string    `protobuf:"bytes,2,opt,name=job_set_id,json=jobSetId,proto3" json:"jobSetId,omitempty"`
@@ -1165,7 +1240,7 @@ type JobPreemptedEvent struct {
 func (m *JobPreemptedEvent) Reset()      { *m = JobPreemptedEvent{} }
 func (*JobPreemptedEvent) ProtoMessage() {}
 func (*JobPreemptedEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{11}
+	return fileDescriptor_7758595c3bb8cf56, []int{12}
 }
 func (m *JobPreemptedEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1258,7 +1333,7 @@ type JobFailedEventCompressed struct {
 func (m *JobFailedEventCompressed) Reset()      { *m = JobFailedEventCompressed{} }
 func (*JobFailedEventCompressed) ProtoMessage() {}
 func (*JobFailedEventCompressed) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{12}
+	return fileDescriptor_7758595c3bb8cf56, []int{13}
 }
 func (m *JobFailedEventCompressed) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1310,7 +1385,7 @@ type JobSucceededEvent struct {
 func (m *JobSucceededEvent) Reset()      { *m = JobSucceededEvent{} }
 func (*JobSucceededEvent) ProtoMessage() {}
 func (*JobSucceededEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{13}
+	return fileDescriptor_7758595c3bb8cf56, []int{14}
 }
 func (m *JobSucceededEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1427,7 +1502,7 @@ type JobUtilisationEvent struct {
 func (m *JobUtilisationEvent) Reset()      { *m = JobUtilisationEvent{} }
 func (*JobUtilisationEvent) ProtoMessage() {}
 func (*JobUtilisationEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{14}
+	return fileDescriptor_7758595c3bb8cf56, []int{15}
 }
 func (m *JobUtilisationEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1552,7 +1627,7 @@ type JobReprioritizingEvent struct {
 func (m *JobReprioritizingEvent) Reset()      { *m = JobReprioritizingEvent{} }
 func (*JobReprioritizingEvent) ProtoMessage() {}
 func (*JobReprioritizingEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{15}
+	return fileDescriptor_7758595c3bb8cf56, []int{16}
 }
 func (m *JobReprioritizingEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1635,7 +1710,7 @@ type JobReprioritizedEvent struct {
 func (m *JobReprioritizedEvent) Reset()      { *m = JobReprioritizedEvent{} }
 func (*JobReprioritizedEvent) ProtoMessage() {}
 func (*JobReprioritizedEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{16}
+	return fileDescriptor_7758595c3bb8cf56, []int{17}
 }
 func (m *JobReprioritizedEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1718,7 +1793,7 @@ type JobCancellingEvent struct {
 func (m *JobCancellingEvent) Reset()      { *m = JobCancellingEvent{} }
 func (*JobCancellingEvent) ProtoMessage() {}
 func (*JobCancellingEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{17}
+	return fileDescriptor_7758595c3bb8cf56, []int{18}
 }
 func (m *JobCancellingEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1801,7 +1876,7 @@ type JobCancelledEvent struct {
 func (m *JobCancelledEvent) Reset()      { *m = JobCancelledEvent{} }
 func (*JobCancelledEvent) ProtoMessage() {}
 func (*JobCancelledEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{18}
+	return fileDescriptor_7758595c3bb8cf56, []int{19}
 }
 func (m *JobCancelledEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1888,7 +1963,7 @@ type JobTerminatedEvent struct {
 func (m *JobTerminatedEvent) Reset()      { *m = JobTerminatedEvent{} }
 func (*JobTerminatedEvent) ProtoMessage() {}
 func (*JobTerminatedEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{19}
+	return fileDescriptor_7758595c3bb8cf56, []int{20}
 }
 func (m *JobTerminatedEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1999,7 +2074,7 @@ type JobUpdatedEvent struct {
 func (m *JobUpdatedEvent) Reset()      { *m = JobUpdatedEvent{} }
 func (*JobUpdatedEvent) ProtoMessage() {}
 func (*JobUpdatedEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{20}
+	return fileDescriptor_7758595c3bb8cf56, []int{21}
 }
 func (m *JobUpdatedEvent) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2093,13 +2168,14 @@ type EventMessage struct {
 	//	*EventMessage_Updated
 	//	*EventMessage_FailedCompressed
 	//	*EventMessage_Preempted
+	//	*EventMessage_Preempting
 	Events isEventMessage_Events `protobuf_oneof:"events"`
 }
 
 func (m *EventMessage) Reset()      { *m = EventMessage{} }
 func (*EventMessage) ProtoMessage() {}
 func (*EventMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{21}
+	return fileDescriptor_7758595c3bb8cf56, []int{22}
 }
 func (m *EventMessage) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2197,6 +2273,9 @@ type EventMessage_FailedCompressed struct {
 type EventMessage_Preempted struct {
 	Preempted *JobPreemptedEvent `protobuf:"bytes,21,opt,name=preempted,proto3,oneof" json:"preempted,omitempty"`
 }
+type EventMessage_Preempting struct {
+	Preempting *JobPreemptingEvent `protobuf:"bytes,22,opt,name=preempting,proto3,oneof" json:"preempting,omitempty"`
+}
 
 func (*EventMessage_Submitted) isEventMessage_Events()        {}
 func (*EventMessage_Queued) isEventMessage_Events()           {}
@@ -2219,6 +2298,7 @@ func (*EventMessage_Reprioritizing) isEventMessage_Events()   {}
 func (*EventMessage_Updated) isEventMessage_Events()          {}
 func (*EventMessage_FailedCompressed) isEventMessage_Events() {}
 func (*EventMessage_Preempted) isEventMessage_Events()        {}
+func (*EventMessage_Preempting) isEventMessage_Events()       {}
 
 func (m *EventMessage) GetEvents() isEventMessage_Events {
 	if m != nil {
@@ -2374,6 +2454,13 @@ func (m *EventMessage) GetPreempted() *JobPreemptedEvent {
 	return nil
 }
 
+func (m *EventMessage) GetPreempting() *JobPreemptingEvent {
+	if x, ok := m.GetEvents().(*EventMessage_Preempting); ok {
+		return x.Preempting
+	}
+	return nil
+}
+
 // XXX_OneofWrappers is for the internal use of the proto package.
 func (*EventMessage) XXX_OneofWrappers() []interface{} {
 	return []interface{}{
@@ -2398,6 +2485,7 @@ func (*EventMessage) XXX_OneofWrappers() []interface{} {
 		(*EventMessage_Updated)(nil),
 		(*EventMessage_FailedCompressed)(nil),
 		(*EventMessage_Preempted)(nil),
+		(*EventMessage_Preempting)(nil),
 	}
 }
 
@@ -2412,7 +2500,7 @@ type ContainerStatus struct {
 func (m *ContainerStatus) Reset()      { *m = ContainerStatus{} }
 func (*ContainerStatus) ProtoMessage() {}
 func (*ContainerStatus) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{22}
+	return fileDescriptor_7758595c3bb8cf56, []int{23}
 }
 func (m *ContainerStatus) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2485,7 +2573,7 @@ type EventStreamMessage struct {
 func (m *EventStreamMessage) Reset()      { *m = EventStreamMessage{} }
 func (*EventStreamMessage) ProtoMessage() {}
 func (*EventStreamMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{23}
+	return fileDescriptor_7758595c3bb8cf56, []int{24}
 }
 func (m *EventStreamMessage) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2542,7 +2630,7 @@ type JobSetRequest struct {
 func (m *JobSetRequest) Reset()      { *m = JobSetRequest{} }
 func (*JobSetRequest) ProtoMessage() {}
 func (*JobSetRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{24}
+	return fileDescriptor_7758595c3bb8cf56, []int{25}
 }
 func (m *JobSetRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2631,7 +2719,7 @@ type WatchRequest struct {
 func (m *WatchRequest) Reset()      { *m = WatchRequest{} }
 func (*WatchRequest) ProtoMessage() {}
 func (*WatchRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_7758595c3bb8cf56, []int{25}
+	return fileDescriptor_7758595c3bb8cf56, []int{26}
 }
 func (m *WatchRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -2710,6 +2798,7 @@ func init() {
 	proto.RegisterType((*JobUnableToScheduleEvent)(nil), "api.JobUnableToScheduleEvent")
 	proto.RegisterType((*JobFailedEvent)(nil), "api.JobFailedEvent")
 	proto.RegisterMapType((map[string]int32)(nil), "api.JobFailedEvent.ExitCodesEntry")
+	proto.RegisterType((*JobPreemptingEvent)(nil), "api.JobPreemptingEvent")
 	proto.RegisterType((*JobPreemptedEvent)(nil), "api.JobPreemptedEvent")
 	proto.RegisterType((*JobFailedEventCompressed)(nil), "api.JobFailedEventCompressed")
 	proto.RegisterType((*JobSucceededEvent)(nil), "api.JobSucceededEvent")
@@ -2732,165 +2821,167 @@ func init() {
 func init() { proto.RegisterFile("pkg/api/event.proto", fileDescriptor_7758595c3bb8cf56) }
 
 var fileDescriptor_7758595c3bb8cf56 = []byte{
-	// 2517 bytes of a gzipped FileDescriptorProto
+	// 2546 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4d, 0x6c, 0x1b, 0xc7,
-	0x15, 0xd6, 0x52, 0xe2, 0xdf, 0x50, 0xbf, 0xa3, 0x1f, 0xaf, 0x69, 0x5b, 0x14, 0x36, 0x40, 0xa3,
-	0x18, 0x31, 0x99, 0xca, 0x49, 0x11, 0x18, 0x41, 0x0b, 0x53, 0x96, 0x13, 0x09, 0x71, 0xec, 0x50,
-	0x36, 0xd2, 0x16, 0x01, 0x98, 0xe5, 0xee, 0x88, 0x5a, 0x89, 0xdc, 0xd9, 0xec, 0x8f, 0x6d, 0xc5,
-	0x08, 0x50, 0xb4, 0x68, 0x91, 0x4b, 0xd1, 0x14, 0xed, 0x3d, 0x39, 0xb7, 0x97, 0x5e, 0x7a, 0xed,
-	0xa1, 0xe8, 0x21, 0xbd, 0xb9, 0xe8, 0x25, 0x27, 0xb6, 0xb5, 0x93, 0xa2, 0xe0, 0xa1, 0xf7, 0xde,
-	0x8a, 0x79, 0x33, 0x4b, 0xce, 0xac, 0x68, 0x48, 0x66, 0x9a, 0xd4, 0x20, 0x78, 0x49, 0xcc, 0xef,
-	0xcd, 0x7b, 0xf3, 0xe6, 0xcd, 0xf7, 0x66, 0xde, 0xec, 0x8c, 0xd0, 0xa2, 0x77, 0xd8, 0xac, 0x98,
-	0x9e, 0x53, 0x21, 0x77, 0x89, 0x1b, 0x96, 0x3d, 0x9f, 0x86, 0x14, 0x4f, 0x9a, 0x9e, 0x53, 0x2c,
-	0x35, 0x29, 0x6d, 0xb6, 0x48, 0x05, 0xa0, 0x46, 0xb4, 0x57, 0x09, 0x9d, 0x36, 0x09, 0x42, 0xb3,
-	0xed, 0xf1, 0x56, 0xc5, 0xa5, 0x58, 0x35, 0x88, 0x1a, 0x6d, 0x27, 0x4c, 0xa2, 0xfb, 0xc4, 0x6c,
-	0x85, 0xfb, 0x02, 0x3d, 0x97, 0x34, 0x46, 0xda, 0x5e, 0x78, 0x24, 0x84, 0x97, 0x9a, 0x4e, 0xb8,
-	0x1f, 0x35, 0xca, 0x16, 0x6d, 0x57, 0x9a, 0xb4, 0x49, 0xfb, 0xad, 0xd8, 0x2f, 0xf8, 0x01, 0xff,
-	0x12, 0xcd, 0xcf, 0x0b, 0x5b, 0xac, 0x13, 0xd3, 0x75, 0x69, 0x68, 0x86, 0x0e, 0x75, 0x03, 0x21,
-	0x7d, 0xf9, 0xf0, 0xd5, 0xa0, 0xec, 0x50, 0x26, 0x6d, 0x9b, 0xd6, 0xbe, 0xe3, 0x12, 0xff, 0xa8,
-	0x12, 0xfb, 0xe4, 0x93, 0x80, 0x46, 0xbe, 0x45, 0x2a, 0x4d, 0xe2, 0x12, 0xdf, 0x0c, 0x89, 0xcd,
-	0xb5, 0x8c, 0x5f, 0xa7, 0xd0, 0xc2, 0x0e, 0x6d, 0xec, 0xc2, 0x48, 0x42, 0x62, 0x6f, 0xb1, 0x68,
-	0xe0, 0x8b, 0x28, 0x73, 0x40, 0x1b, 0x75, 0xc7, 0xd6, 0xb5, 0x35, 0x6d, 0x3d, 0x5f, 0x5d, 0xec,
-	0x76, 0x4a, 0x73, 0x07, 0xb4, 0xb1, 0x6d, 0xbf, 0x48, 0xdb, 0x4e, 0x08, 0x63, 0xa8, 0xa5, 0x01,
-	0xc0, 0x2f, 0x23, 0xc4, 0xda, 0x06, 0x24, 0x64, 0xed, 0x53, 0xd0, 0x7e, 0xa5, 0xdb, 0x29, 0xe1,
-	0x03, 0xda, 0xd8, 0x25, 0xa1, 0xa2, 0x92, 0x8b, 0x31, 0xfc, 0x02, 0x4a, 0xbf, 0x1f, 0x91, 0x88,
-	0xe8, 0x93, 0xfd, 0x0e, 0x00, 0x90, 0x3b, 0x00, 0x00, 0x6f, 0xa3, 0xac, 0xe5, 0x13, 0xe6, 0xb3,
-	0x3e, 0xb5, 0xa6, 0xad, 0x17, 0x36, 0x8a, 0x65, 0x1e, 0x88, 0x72, 0x1c, 0xae, 0xf2, 0xed, 0x78,
-	0x86, 0xaa, 0x8b, 0x9f, 0x75, 0x4a, 0x13, 0xdd, 0x4e, 0x29, 0x56, 0xf9, 0xf8, 0x6f, 0x25, 0xad,
-	0x16, 0xff, 0xc0, 0xcf, 0xa3, 0xc9, 0x03, 0xda, 0xd0, 0xd3, 0x60, 0x26, 0x57, 0x36, 0x3d, 0xa7,
-	0xbc, 0x43, 0x1b, 0xd5, 0x82, 0x50, 0x62, 0xc2, 0x1a, 0xfb, 0x8f, 0xf1, 0x2f, 0x0d, 0xcd, 0xee,
-	0xd0, 0xc6, 0xdb, 0xcc, 0x81, 0xd1, 0x8e, 0x89, 0xf1, 0xfb, 0x14, 0x5a, 0xd9, 0xa1, 0x8d, 0x6b,
-	0x91, 0xd7, 0x72, 0x2c, 0x33, 0x24, 0xd7, 0x69, 0xe4, 0x8e, 0x38, 0x0d, 0x36, 0xd1, 0x1c, 0xf5,
-	0x9d, 0xa6, 0xe3, 0x9a, 0xad, 0xba, 0x18, 0x60, 0x1a, 0xfa, 0x3f, 0xd7, 0xed, 0x94, 0xce, 0xc4,
-	0xa2, 0x9d, 0xc4, 0x40, 0x67, 0x14, 0x81, 0xf1, 0x69, 0x0a, 0x28, 0xf2, 0x26, 0x31, 0x83, 0x51,
-	0x4f, 0x9b, 0xef, 0x20, 0x64, 0xb5, 0xa2, 0x20, 0x24, 0x7e, 0x3f, 0x54, 0x67, 0xba, 0x9d, 0xd2,
-	0xa2, 0x40, 0x15, 0x67, 0xf3, 0x3d, 0xd0, 0xf8, 0xc5, 0x14, 0x5a, 0x8e, 0x43, 0x54, 0x23, 0x61,
-	0xe4, 0xbb, 0xe3, 0x48, 0x0d, 0x8c, 0x14, 0x7e, 0x11, 0x65, 0x7c, 0x62, 0x06, 0xd4, 0xd5, 0x33,
-	0xa0, 0xb3, 0xd4, 0xed, 0x94, 0xe6, 0x39, 0x22, 0x29, 0x88, 0x36, 0xf8, 0x7b, 0x68, 0xe6, 0x30,
-	0x6a, 0x10, 0xdf, 0x25, 0x21, 0x09, 0x58, 0x47, 0x59, 0x50, 0x2a, 0x76, 0x3b, 0xa5, 0x95, 0xbe,
-	0x40, 0xe9, 0x6b, 0x5a, 0xc6, 0x99, 0x9b, 0x1e, 0xb5, 0xeb, 0x6e, 0xd4, 0x6e, 0x10, 0x5f, 0xcf,
-	0xad, 0x69, 0xeb, 0x69, 0xee, 0xa6, 0x47, 0xed, 0xb7, 0x00, 0x94, 0xdd, 0xec, 0x81, 0xac, 0x63,
-	0x3f, 0x72, 0xeb, 0x66, 0x08, 0x22, 0x62, 0xeb, 0xf9, 0x35, 0x6d, 0x3d, 0xc7, 0x3b, 0xf6, 0x23,
-	0xf7, 0x6a, 0x8c, 0xcb, 0x1d, 0xcb, 0xb8, 0xf1, 0x6f, 0x0d, 0x2d, 0xc5, 0x8c, 0xd8, 0xba, 0xef,
-	0x39, 0xfe, 0xa8, 0xaf, 0xae, 0x3f, 0x9f, 0x42, 0x73, 0x3b, 0xb4, 0x71, 0x8b, 0xb8, 0xb6, 0xe3,
-	0x36, 0xc7, 0xe4, 0x1f, 0x44, 0xfe, 0x63, 0x74, 0xce, 0x7c, 0x25, 0x3a, 0x67, 0x4f, 0x4d, 0xe7,
-	0x97, 0x50, 0x0e, 0xf4, 0xcc, 0x36, 0x81, 0x24, 0xc8, 0x57, 0x97, 0xbb, 0x9d, 0xd2, 0x02, 0x6b,
-	0x60, 0xb6, 0xe5, 0x58, 0x65, 0x05, 0xc4, 0x5c, 0x8d, 0x35, 0x02, 0xcf, 0xb4, 0x08, 0x24, 0x80,
-	0x70, 0x55, 0xb4, 0x01, 0x5c, 0x76, 0x55, 0xc6, 0x8d, 0x3f, 0x72, 0x3e, 0xd4, 0x22, 0xd7, 0x1d,
-	0xf3, 0xe1, 0xeb, 0xe2, 0xc3, 0x65, 0x94, 0x77, 0xa9, 0x4d, 0xf8, 0xc4, 0x66, 0xfb, 0x31, 0x62,
-	0x60, 0x62, 0x66, 0x73, 0x31, 0x36, 0xf4, 0x9a, 0x28, 0x93, 0x28, 0x3f, 0x1c, 0x89, 0xd0, 0x53,
-	0x92, 0xe8, 0x77, 0x19, 0xb4, 0xc8, 0x8a, 0x10, 0xb7, 0xe9, 0x93, 0x20, 0xd8, 0x76, 0xf7, 0xe8,
-	0x98, 0x48, 0xa3, 0x45, 0x24, 0x34, 0x1c, 0x91, 0x0a, 0x4f, 0x47, 0x24, 0xfc, 0x00, 0x2d, 0x38,
-	0x9c, 0x44, 0x75, 0xd3, 0xb6, 0xd9, 0xff, 0x49, 0xa0, 0xe7, 0xd7, 0x26, 0xd7, 0x0b, 0x1b, 0xe5,
-	0xf8, 0x74, 0x94, 0x64, 0x59, 0x59, 0x00, 0x57, 0x63, 0x85, 0x2d, 0x37, 0xf4, 0x8f, 0xaa, 0xab,
-	0xdd, 0x4e, 0xa9, 0xe8, 0x24, 0x44, 0x52, 0xc7, 0xf3, 0x49, 0x59, 0xf1, 0x10, 0x2d, 0x0f, 0x34,
-	0x85, 0x9f, 0x43, 0x93, 0x87, 0xe4, 0x08, 0x38, 0x9c, 0xae, 0x2e, 0x74, 0x3b, 0xa5, 0x99, 0x43,
-	0x72, 0x24, 0x99, 0x62, 0x52, 0xc6, 0xc4, 0xbb, 0x66, 0x2b, 0x22, 0x82, 0xba, 0xc0, 0x44, 0x00,
-	0x64, 0x26, 0x02, 0x70, 0x25, 0xf5, 0xaa, 0x66, 0xfc, 0x67, 0x0a, 0xe9, 0x3b, 0xb4, 0x71, 0xc7,
-	0x35, 0x1b, 0x2d, 0x72, 0x9b, 0xee, 0x5a, 0xfb, 0xc4, 0x8e, 0x5a, 0x64, 0x9c, 0x37, 0xcf, 0x40,
-	0x35, 0xaa, 0x64, 0x59, 0x6e, 0xa8, 0x2c, 0xcb, 0x3f, 0xc3, 0x59, 0x66, 0x3c, 0xcc, 0xc2, 0x49,
-	0xf1, 0xba, 0xe9, 0xb4, 0xc6, 0xe7, 0x9f, 0xff, 0x05, 0xe3, 0xde, 0x45, 0x88, 0xdc, 0x77, 0xc2,
-	0xba, 0x45, 0x6d, 0x12, 0xe8, 0x59, 0x58, 0xaf, 0x8c, 0x78, 0xbd, 0x92, 0xc2, 0x5c, 0xde, 0xba,
-	0xef, 0x84, 0x9b, 0xac, 0x11, 0x5f, 0xa3, 0xce, 0x32, 0x4f, 0x48, 0x8c, 0xf5, 0x0d, 0xeb, 0x5a,
-	0x2d, 0xdf, 0x83, 0x8f, 0xf3, 0x39, 0xf7, 0x55, 0xf8, 0x9c, 0x1f, 0x8a, 0xcf, 0x68, 0x28, 0x3e,
-	0xcf, 0x0c, 0xc7, 0xe7, 0xd9, 0xa7, 0xdc, 0x35, 0x6c, 0x84, 0x2d, 0xea, 0x86, 0xa6, 0xe3, 0x12,
-	0xbf, 0x1e, 0x84, 0x66, 0x18, 0xb1, 0x6d, 0xa3, 0x00, 0xd3, 0xb0, 0x04, 0xd3, 0xb0, 0x19, 0x8b,
-	0x77, 0x41, 0x5a, 0x2d, 0x75, 0x3b, 0xa5, 0x73, 0x96, 0x0a, 0x2a, 0xbb, 0xc3, 0xc2, 0x31, 0x21,
-	0x7e, 0x05, 0xa5, 0x2d, 0x33, 0x0a, 0x88, 0x3e, 0xbd, 0xa6, 0xad, 0xcf, 0x6e, 0x20, 0x6e, 0x98,
-	0x21, 0x9c, 0xcc, 0x20, 0x94, 0xc9, 0x0c, 0x40, 0xd1, 0x46, 0xb3, 0xea, 0xac, 0xcb, 0xdb, 0x49,
-	0xfe, 0x74, 0xdb, 0x49, 0xfa, 0xc4, 0xed, 0xe4, 0xcb, 0x49, 0xf8, 0x6c, 0x7a, 0xcb, 0x27, 0xfc,
-	0x60, 0x3b, 0xce, 0xea, 0x41, 0x59, 0x7d, 0x11, 0x65, 0xfc, 0xc8, 0xed, 0x17, 0x5e, 0xe0, 0xae,
-	0x1f, 0xb9, 0x6a, 0x3c, 0x00, 0xc0, 0xdb, 0x68, 0xc1, 0xe3, 0xd1, 0x74, 0xee, 0x92, 0xf8, 0xab,
-	0x1c, 0xdf, 0x49, 0x2e, 0x74, 0x3b, 0xa5, 0xb3, 0x7d, 0x61, 0xf2, 0xbb, 0xdc, 0x5c, 0x42, 0x94,
-	0x30, 0x25, 0x3c, 0xc8, 0x0d, 0x32, 0x55, 0x4b, 0xf8, 0x32, 0x97, 0x10, 0x19, 0x5b, 0x50, 0x35,
-	0x48, 0x4b, 0xca, 0x26, 0x6d, 0x7b, 0x50, 0xab, 0xc0, 0x5c, 0xc0, 0xdd, 0x01, 0x4c, 0xf6, 0x34,
-	0x1f, 0x1c, 0x00, 0xf2, 0xe0, 0x00, 0x30, 0xfe, 0x34, 0x25, 0xbe, 0xb2, 0x5b, 0x16, 0x21, 0xf6,
-	0x98, 0x2e, 0xe3, 0x73, 0xdf, 0x50, 0xe7, 0xbe, 0x4f, 0xf2, 0x70, 0xee, 0xbb, 0x13, 0x3a, 0x2d,
-	0x27, 0x80, 0xcb, 0x9f, 0x31, 0x91, 0xbe, 0x16, 0x22, 0x7d, 0xa4, 0xa1, 0xe5, 0x1b, 0xe6, 0xfd,
-	0x9a, 0xb8, 0x35, 0x0b, 0xae, 0x53, 0xff, 0x16, 0xf1, 0x1d, 0x6a, 0x8b, 0x62, 0xe3, 0x72, 0x5c,
-	0x6c, 0x24, 0xa7, 0xa2, 0x3c, 0x50, 0x8b, 0x57, 0x1f, 0x17, 0xc4, 0x58, 0x07, 0x5b, 0xae, 0x0d,
-	0x86, 0x47, 0xbd, 0x38, 0xc6, 0x3f, 0xd3, 0xd0, 0x4a, 0x48, 0x43, 0xb3, 0x55, 0xb7, 0xa2, 0x76,
-	0xd4, 0x32, 0x61, 0xcd, 0x8e, 0x02, 0xb3, 0xc9, 0x36, 0x7e, 0x16, 0xeb, 0x8d, 0x27, 0xc6, 0xfa,
-	0x36, 0x53, 0xdb, 0xec, 0x69, 0xdd, 0x61, 0x4a, 0x3c, 0xd4, 0xe7, 0x45, 0xa8, 0x97, 0xc2, 0x01,
-	0x4d, 0x6a, 0x03, 0xd1, 0xe2, 0xa7, 0x1a, 0x2a, 0x3e, 0x79, 0xf6, 0x4e, 0x57, 0x45, 0xfc, 0x40,
-	0xae, 0x22, 0xd8, 0x19, 0x9a, 0xdf, 0xc9, 0x96, 0xe5, 0x3b, 0xd9, 0xb2, 0x77, 0xd8, 0x84, 0x21,
-	0xc5, 0x77, 0xb2, 0xe5, 0xb7, 0x23, 0xd3, 0x0d, 0x9d, 0xf0, 0xe8, 0xa4, 0xaa, 0xa3, 0xf8, 0x89,
-	0x86, 0xce, 0x3e, 0x71, 0xd0, 0xcf, 0x82, 0x87, 0xc6, 0x97, 0xfc, 0x32, 0xb1, 0x46, 0x3c, 0xdf,
-	0xa1, 0xbe, 0x13, 0x3a, 0x1f, 0x8c, 0xfc, 0x57, 0xce, 0xd7, 0xd0, 0xb4, 0x4b, 0xee, 0xd5, 0xc5,
-	0x80, 0x8f, 0x60, 0x99, 0xd2, 0xe0, 0xa8, 0xb1, 0xec, 0x92, 0x7b, 0xb7, 0x04, 0x2c, 0xb9, 0x50,
-	0x90, 0x60, 0xfc, 0x0a, 0xca, 0xfb, 0xe4, 0xfd, 0x88, 0x04, 0x21, 0xf5, 0xc5, 0x32, 0x05, 0x89,
-	0xda, 0x03, 0xe5, 0x44, 0xed, 0x81, 0xc6, 0x17, 0x29, 0xb8, 0x59, 0x93, 0xe2, 0x3c, 0xea, 0x45,
-	0xc5, 0xff, 0x25, 0xcc, 0x7f, 0x49, 0x21, 0xbc, 0x43, 0x1b, 0x9b, 0xa6, 0x6b, 0x91, 0x56, 0x6b,
-	0xe4, 0xa9, 0xac, 0x44, 0x29, 0x7d, 0xda, 0x28, 0x3d, 0xdd, 0xe1, 0xdd, 0x78, 0xc8, 0x5f, 0x9c,
-	0x88, 0x98, 0x8e, 0x3a, 0x6d, 0xbf, 0x91, 0x90, 0xfe, 0x61, 0x0a, 0x68, 0x7a, 0x9b, 0xf8, 0x6d,
-	0xc7, 0x35, 0xc7, 0xc7, 0xd1, 0x67, 0xf9, 0x9e, 0xf1, 0x9b, 0x39, 0x2a, 0x48, 0x04, 0xca, 0x9d,
-	0x82, 0x40, 0x7f, 0x4e, 0xc1, 0xad, 0xe4, 0x1d, 0xcf, 0x1e, 0x7d, 0xf6, 0x0c, 0x99, 0x91, 0xe2,
-	0xe9, 0x58, 0xe6, 0xc4, 0xa7, 0x63, 0xbf, 0x9d, 0x45, 0xd3, 0x10, 0xc1, 0x1b, 0x24, 0x60, 0xc5,
-	0x19, 0xbe, 0x89, 0xf2, 0x41, 0xfc, 0xbc, 0x0e, 0x62, 0x59, 0xd8, 0x58, 0x89, 0xf5, 0xd5, 0x77,
-	0x77, 0xdc, 0x91, 0x5e, 0xe3, 0xbe, 0x23, 0x6f, 0x4c, 0xd4, 0xfa, 0x36, 0xf0, 0x26, 0xca, 0x40,
-	0x54, 0x6c, 0x51, 0xc4, 0x2d, 0xc6, 0xd6, 0xa4, 0xe7, 0x6a, 0x7c, 0xc2, 0x79, 0x33, 0xc5, 0x8e,
-	0x50, 0xc5, 0x36, 0x9a, 0xb3, 0xe3, 0x27, 0x5f, 0xf5, 0x3d, 0x1a, 0xb9, 0xb6, 0x3e, 0x0f, 0xd6,
-	0xce, 0xc5, 0xd6, 0x06, 0xbc, 0x08, 0xab, 0x9e, 0xef, 0x76, 0x4a, 0xba, 0xad, 0x08, 0x14, 0xeb,
-	0xb3, 0xaa, 0x8c, 0xb9, 0xda, 0x82, 0x07, 0x52, 0x30, 0xc7, 0x92, 0xab, 0xd2, 0xb3, 0x29, 0xee,
-	0x2a, 0x6f, 0xa6, 0xba, 0xca, 0x31, 0xfc, 0x1e, 0x9a, 0x85, 0x7f, 0xd5, 0x7d, 0xf1, 0x86, 0xa8,
-	0xc7, 0x01, 0xd9, 0x98, 0xf2, 0xc0, 0x88, 0xbf, 0xe4, 0x6a, 0xc9, 0xb8, 0x62, 0x7a, 0x46, 0x11,
-	0xe1, 0x77, 0x11, 0x07, 0xea, 0x84, 0xbf, 0x49, 0x11, 0x2f, 0x04, 0xcf, 0x2a, 0x1d, 0xc8, 0xef,
-	0x55, 0x78, 0x26, 0xb6, 0x24, 0x58, 0x31, 0x3f, 0x2d, 0x4b, 0xf0, 0xeb, 0x28, 0xeb, 0xf1, 0xf7,
-	0x1f, 0x82, 0x3e, 0x4b, 0xb1, 0x5d, 0xf9, 0x59, 0x88, 0x58, 0x13, 0x38, 0xa2, 0x58, 0x8b, 0xb5,
-	0x99, 0x21, 0x9f, 0x3f, 0x1c, 0x80, 0xc5, 0x47, 0x32, 0x24, 0xbf, 0x27, 0xe0, 0x86, 0x44, 0x43,
-	0xd5, 0x90, 0x00, 0x71, 0x1b, 0xe1, 0x08, 0x6e, 0xc2, 0xea, 0x21, 0xad, 0x07, 0xe2, 0x2e, 0x0c,
-	0x56, 0x8a, 0xc2, 0xc6, 0x85, 0xde, 0x79, 0x6b, 0xd0, 0x5d, 0x19, 0xbf, 0xe7, 0x8b, 0x12, 0x22,
-	0xa5, 0x97, 0xf9, 0xa4, 0x94, 0xb1, 0x60, 0x0f, 0x3e, 0xa1, 0xc1, 0xea, 0x27, 0xb1, 0x40, 0xfa,
-	0xb0, 0xc6, 0x59, 0xc0, 0x9b, 0xa9, 0x2c, 0xe0, 0x18, 0x4f, 0x23, 0xf1, 0xfd, 0x0c, 0x96, 0x43,
-	0x25, 0x8d, 0xe4, 0x0f, 0x6b, 0x71, 0x1a, 0x09, 0x2c, 0x99, 0x46, 0x02, 0xc6, 0x75, 0x34, 0xe3,
-	0xcb, 0xf5, 0x33, 0x1c, 0x5d, 0x25, 0x56, 0x1d, 0x2f, 0xae, 0x39, 0xab, 0x14, 0x25, 0x95, 0x55,
-	0x8a, 0x08, 0xef, 0x22, 0x64, 0xf5, 0x2a, 0x47, 0xf8, 0x8c, 0x5d, 0xd8, 0x38, 0x13, 0x5b, 0x4f,
-	0xd4, 0x94, 0x55, 0x9d, 0x1d, 0x57, 0xfb, 0xcd, 0x15, 0xbb, 0x92, 0x19, 0x16, 0x06, 0x2b, 0x2e,
-	0x9d, 0xe0, 0x83, 0xbf, 0x14, 0x06, 0xb5, 0xa6, 0x12, 0x7b, 0x62, 0x8c, 0xa9, 0x61, 0xe8, 0xc1,
-	0xcc, 0xcb, 0xb0, 0x57, 0x38, 0xc0, 0x5d, 0x80, 0xe4, 0x65, 0xa2, 0xa4, 0xe0, 0x5e, 0xf6, 0x9b,
-	0xab, 0x5e, 0xf6, 0x71, 0xfc, 0x0e, 0x2a, 0x44, 0xfd, 0xe3, 0xba, 0x3e, 0x07, 0x56, 0xf5, 0x27,
-	0x9d, 0xe4, 0x79, 0x19, 0x2f, 0x29, 0x28, 0x76, 0x65, 0x4b, 0xf8, 0xfb, 0x68, 0x3a, 0xbe, 0xb1,
-	0x76, 0xdc, 0x3d, 0xaa, 0x2f, 0xa8, 0x96, 0x93, 0x97, 0xd5, 0xdc, 0xb2, 0xd3, 0x47, 0x55, 0xcb,
-	0x92, 0x00, 0x5b, 0x68, 0xd6, 0x57, 0x8e, 0xad, 0x3a, 0x56, 0xd7, 0xc3, 0x01, 0x87, 0x5a, 0xbe,
-	0x1e, 0xaa, 0x6a, 0xea, 0x7a, 0xa8, 0xca, 0x58, 0x06, 0x47, 0x7c, 0x93, 0xd5, 0x17, 0xd5, 0x0c,
-	0x96, 0xf7, 0x5e, 0x9e, 0xc1, 0xa2, 0xa1, 0x9a, 0xc1, 0x02, 0xc4, 0x87, 0x48, 0xe4, 0x4a, 0xff,
-	0x83, 0xb4, 0xbe, 0xa4, 0xe6, 0xef, 0xc0, 0xaf, 0xd6, 0x3c, 0x7f, 0x93, 0xaa, 0x6a, 0xfe, 0x26,
-	0xa5, 0x8c, 0x73, 0x5e, 0x7c, 0xd3, 0xa1, 0x2f, 0xab, 0x9c, 0x53, 0xaf, 0x40, 0x44, 0x39, 0x14,
-	0x63, 0x2a, 0xe7, 0x7a, 0x70, 0x35, 0x87, 0x32, 0xf0, 0x61, 0x3c, 0x30, 0x7e, 0x92, 0x42, 0x73,
-	0x89, 0xdb, 0x22, 0xfc, 0x2d, 0x34, 0x05, 0xa5, 0x12, 0xaf, 0x3b, 0x70, 0xb7, 0x53, 0x9a, 0x75,
-	0xd5, 0x3a, 0x09, 0xe4, 0x78, 0x03, 0xe5, 0xe2, 0x5b, 0x3b, 0x71, 0x6d, 0x03, 0x35, 0x47, 0x8c,
-	0xc9, 0x35, 0x47, 0x8c, 0xe1, 0x0a, 0xca, 0xb6, 0xf9, 0xbe, 0x2c, 0xaa, 0x0e, 0x08, 0xb5, 0x80,
-	0xe4, 0x4a, 0x4c, 0x40, 0x52, 0x21, 0x35, 0x75, 0x8a, 0x9b, 0xc9, 0xde, 0xa5, 0x55, 0xfa, 0x69,
-	0x2e, 0xad, 0x8c, 0x0f, 0x10, 0x86, 0xf0, 0xed, 0x86, 0x3e, 0x31, 0xdb, 0x71, 0xe1, 0xb0, 0x86,
-	0x52, 0xbd, 0xea, 0x6b, 0xbe, 0xdb, 0x29, 0x4d, 0x3b, 0x72, 0x1d, 0x95, 0x72, 0x6c, 0x5c, 0xed,
-	0x8f, 0x86, 0x97, 0x02, 0x0b, 0xd0, 0xa1, 0x5c, 0x7e, 0x9c, 0x34, 0x40, 0xe3, 0xa7, 0x93, 0x68,
-	0x66, 0x07, 0x4a, 0xb2, 0x1a, 0x2f, 0x76, 0x4e, 0xd1, 0xef, 0x0b, 0x28, 0x7d, 0xcf, 0x0c, 0xad,
-	0x7d, 0xe8, 0x35, 0xc7, 0x87, 0x06, 0x80, 0x3c, 0x34, 0x00, 0xf0, 0x26, 0x9a, 0xdb, 0xf3, 0x69,
-	0xbb, 0x2e, 0xba, 0x63, 0xf5, 0xe1, 0x64, 0xff, 0xad, 0x35, 0x13, 0x09, 0x47, 0xd5, 0xb7, 0xd6,
-	0x8a, 0xa0, 0x5f, 0x29, 0x4e, 0x9d, 0x58, 0x29, 0x5e, 0x43, 0xb3, 0xc4, 0xf7, 0xa9, 0xbf, 0xbd,
-	0x77, 0xc3, 0x09, 0x02, 0x96, 0xc6, 0x69, 0xf0, 0x11, 0x32, 0x55, 0x95, 0x48, 0xca, 0x09, 0x1d,
-	0xfc, 0x1a, 0x9a, 0xde, 0xa3, 0xbe, 0x45, 0xea, 0x2d, 0xd2, 0x34, 0xad, 0x23, 0xd8, 0xb7, 0x73,
-	0x7c, 0x31, 0x01, 0xfc, 0x4d, 0x80, 0xe5, 0xaf, 0x0d, 0x12, 0x8c, 0x2f, 0xa3, 0x3c, 0xd7, 0x76,
-	0xc9, 0x3d, 0xd8, 0xa9, 0x73, 0x9c, 0x99, 0x00, 0xbe, 0x45, 0xee, 0xc9, 0xcc, 0x8c, 0x31, 0xe3,
-	0x97, 0x29, 0x34, 0xfd, 0x0e, 0x0b, 0x59, 0x3c, 0x0d, 0xbd, 0x41, 0x6b, 0x27, 0x0e, 0x7a, 0xb8,
-	0xfa, 0xfb, 0x12, 0xca, 0xc2, 0xd4, 0xf4, 0xa6, 0x84, 0x6f, 0xc1, 0x3e, 0x6d, 0x2b, 0x0a, 0x19,
-	0x8e, 0x1c, 0x8b, 0xc9, 0xd4, 0xf0, 0x31, 0x49, 0x9f, 0x2e, 0x26, 0x17, 0xbf, 0x8b, 0xd2, 0x90,
-	0x3c, 0x38, 0x8f, 0xd2, 0x5b, 0x6c, 0x86, 0xe6, 0x27, 0x70, 0x01, 0x65, 0xb7, 0xee, 0x3a, 0x56,
-	0x48, 0xec, 0x79, 0x0d, 0x67, 0xd1, 0xe4, 0xcd, 0x9b, 0x37, 0xe6, 0x53, 0x78, 0x09, 0xcd, 0x5f,
-	0x23, 0xa6, 0xdd, 0x72, 0x5c, 0xb2, 0x75, 0x9f, 0x6f, 0xf0, 0xf3, 0x93, 0x1b, 0xff, 0xd4, 0x50,
-	0x9a, 0x9f, 0x66, 0x08, 0x9a, 0x7b, 0x9d, 0x84, 0x9c, 0xe7, 0x80, 0x04, 0x18, 0xf7, 0xaa, 0x87,
-	0x1e, 0xf5, 0x8b, 0x67, 0xfa, 0xf9, 0xa3, 0xe4, 0xa2, 0xf1, 0xdc, 0x8f, 0xff, 0xfa, 0xc5, 0xaf,
-	0x52, 0x17, 0x0c, 0xbd, 0x72, 0xf7, 0xdb, 0x95, 0x03, 0xda, 0xb8, 0x14, 0x90, 0xb0, 0xf2, 0x00,
-	0xa2, 0xff, 0x61, 0xe5, 0x81, 0x63, 0x7f, 0x78, 0x45, 0xbb, 0xf8, 0x92, 0x86, 0xaf, 0xa0, 0x34,
-	0xcc, 0x21, 0xe6, 0x89, 0x28, 0xcf, 0xe7, 0x93, 0x6d, 0x4f, 0x7e, 0x94, 0xd2, 0x40, 0x37, 0xf3,
-	0x06, 0xfc, 0xe9, 0x10, 0x5e, 0x39, 0x76, 0xb8, 0xd9, 0x62, 0x81, 0x29, 0xf2, 0x6d, 0x8e, 0x37,
-	0xda, 0xdc, 0x27, 0xd6, 0x61, 0x8d, 0x04, 0x1e, 0x75, 0x03, 0x52, 0x7d, 0xef, 0xf3, 0x7f, 0xac,
-	0x4e, 0xfc, 0xe8, 0xd1, 0xaa, 0xf6, 0xd9, 0xa3, 0x55, 0xed, 0xe1, 0xa3, 0x55, 0xed, 0xef, 0x8f,
-	0x56, 0xb5, 0x8f, 0x1f, 0xaf, 0x4e, 0x3c, 0x7c, 0xbc, 0x3a, 0xf1, 0xf9, 0xe3, 0xd5, 0x89, 0x1f,
-	0x3e, 0x2f, 0xfd, 0xad, 0x91, 0xe9, 0xb7, 0x4d, 0xdb, 0xf4, 0x7c, 0x7a, 0x40, 0xac, 0x50, 0xfc,
-	0x8a, 0xff, 0x54, 0xe8, 0x37, 0xa9, 0xa5, 0xab, 0x00, 0xdc, 0xe2, 0xe2, 0xf2, 0x36, 0x2d, 0x5f,
-	0xf5, 0x9c, 0x46, 0x06, 0x7c, 0xb9, 0xfc, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x45, 0x20,
-	0xae, 0x38, 0x35, 0x00, 0x00,
+	0xf5, 0xd7, 0x52, 0xe2, 0xd7, 0x50, 0x9f, 0xa3, 0x0f, 0xaf, 0x69, 0x5b, 0x14, 0x18, 0xe0, 0x1f,
+	0xc5, 0x88, 0xc9, 0xfc, 0xe5, 0xa4, 0x08, 0x8c, 0xa0, 0x85, 0x29, 0xcb, 0x89, 0x84, 0x38, 0x76,
+	0x28, 0x1b, 0x69, 0x8b, 0x00, 0xcc, 0x72, 0x77, 0x44, 0xad, 0x44, 0xee, 0x6c, 0xf6, 0xc3, 0xb6,
+	0x62, 0x04, 0x08, 0x5a, 0xb4, 0xc8, 0xa5, 0x68, 0x8a, 0xf6, 0x9e, 0x00, 0xbd, 0xf5, 0xd4, 0x4b,
+	0xaf, 0x3d, 0x14, 0x3d, 0xa4, 0x37, 0x17, 0xbd, 0xe4, 0xc4, 0xb6, 0x76, 0x52, 0x14, 0x3c, 0xf4,
+	0xde, 0x5b, 0x31, 0x6f, 0x66, 0xb9, 0x33, 0x2b, 0x1a, 0x92, 0x99, 0x26, 0x35, 0x08, 0x5e, 0x12,
+	0xf3, 0xf7, 0x66, 0xde, 0xbc, 0x79, 0xf3, 0x7b, 0x33, 0x6f, 0xf6, 0x8d, 0xd0, 0xa2, 0x7b, 0xd8,
+	0xaa, 0x1a, 0xae, 0x5d, 0x25, 0x77, 0x89, 0x13, 0x54, 0x5c, 0x8f, 0x06, 0x14, 0x4f, 0x1a, 0xae,
+	0x5d, 0x2c, 0xb5, 0x28, 0x6d, 0xb5, 0x49, 0x15, 0xa0, 0x66, 0xb8, 0x57, 0x0d, 0xec, 0x0e, 0xf1,
+	0x03, 0xa3, 0xe3, 0xf2, 0x56, 0xc5, 0xa5, 0xa8, 0xab, 0x1f, 0x36, 0x3b, 0x76, 0x90, 0x44, 0xf7,
+	0x89, 0xd1, 0x0e, 0xf6, 0x05, 0x7a, 0x2e, 0xa9, 0x8c, 0x74, 0xdc, 0xe0, 0x48, 0x08, 0x2f, 0xb5,
+	0xec, 0x60, 0x3f, 0x6c, 0x56, 0x4c, 0xda, 0xa9, 0xb6, 0x68, 0x8b, 0xc6, 0xad, 0xd8, 0x2f, 0xf8,
+	0x01, 0xff, 0x12, 0xcd, 0xcf, 0x0b, 0x5d, 0x6c, 0x10, 0xc3, 0x71, 0x68, 0x60, 0x04, 0x36, 0x75,
+	0x7c, 0x21, 0x7d, 0xf9, 0xf0, 0x55, 0xbf, 0x62, 0x53, 0x26, 0xed, 0x18, 0xe6, 0xbe, 0xed, 0x10,
+	0xef, 0xa8, 0x1a, 0xd9, 0xe4, 0x11, 0x9f, 0x86, 0x9e, 0x49, 0xaa, 0x2d, 0xe2, 0x10, 0xcf, 0x08,
+	0x88, 0xc5, 0x7b, 0x95, 0x7f, 0x95, 0x42, 0x0b, 0x3b, 0xb4, 0xb9, 0x0b, 0x33, 0x09, 0x88, 0xb5,
+	0xc5, 0xbc, 0x81, 0x2f, 0xa2, 0xcc, 0x01, 0x6d, 0x36, 0x6c, 0x4b, 0xd7, 0xd6, 0xb4, 0xf5, 0x7c,
+	0x6d, 0xb1, 0xd7, 0x2d, 0xcd, 0x1d, 0xd0, 0xe6, 0xb6, 0xf5, 0x22, 0xed, 0xd8, 0x01, 0xcc, 0xa1,
+	0x9e, 0x06, 0x00, 0xbf, 0x8c, 0x10, 0x6b, 0xeb, 0x93, 0x80, 0xb5, 0x4f, 0x41, 0xfb, 0x95, 0x5e,
+	0xb7, 0x84, 0x0f, 0x68, 0x73, 0x97, 0x04, 0x4a, 0x97, 0x5c, 0x84, 0xe1, 0x17, 0x50, 0xfa, 0xfd,
+	0x90, 0x84, 0x44, 0x9f, 0x8c, 0x07, 0x00, 0x40, 0x1e, 0x00, 0x00, 0xbc, 0x8d, 0xb2, 0xa6, 0x47,
+	0x98, 0xcd, 0xfa, 0xd4, 0x9a, 0xb6, 0x5e, 0xd8, 0x28, 0x56, 0xb8, 0x23, 0x2a, 0x91, 0xbb, 0x2a,
+	0xb7, 0xa3, 0x15, 0xaa, 0x2d, 0x7e, 0xde, 0x2d, 0x4d, 0xf4, 0xba, 0xa5, 0xa8, 0xcb, 0x27, 0x7f,
+	0x2d, 0x69, 0xf5, 0xe8, 0x07, 0x7e, 0x1e, 0x4d, 0x1e, 0xd0, 0xa6, 0x9e, 0x06, 0x35, 0xb9, 0x8a,
+	0xe1, 0xda, 0x95, 0x1d, 0xda, 0xac, 0x15, 0x44, 0x27, 0x26, 0xac, 0xb3, 0xff, 0x94, 0xff, 0xa9,
+	0xa1, 0xd9, 0x1d, 0xda, 0x7c, 0x9b, 0x19, 0x30, 0xda, 0x3e, 0x29, 0xff, 0x2e, 0x85, 0x56, 0x76,
+	0x68, 0xf3, 0x5a, 0xe8, 0xb6, 0x6d, 0xd3, 0x08, 0xc8, 0x75, 0x1a, 0x3a, 0x23, 0x4e, 0x83, 0x4d,
+	0x34, 0x47, 0x3d, 0xbb, 0x65, 0x3b, 0x46, 0xbb, 0x21, 0x26, 0x98, 0x86, 0xf1, 0xcf, 0xf5, 0xba,
+	0xa5, 0x33, 0x91, 0x68, 0x27, 0x31, 0xd1, 0x19, 0x45, 0x50, 0xfe, 0x2c, 0x05, 0x14, 0x79, 0x93,
+	0x18, 0xfe, 0xa8, 0x87, 0xcd, 0x77, 0x10, 0x32, 0xdb, 0xa1, 0x1f, 0x10, 0x2f, 0x76, 0xd5, 0x99,
+	0x5e, 0xb7, 0xb4, 0x28, 0x50, 0xc5, 0xd8, 0x7c, 0x1f, 0x2c, 0xff, 0x7c, 0x0a, 0x2d, 0x47, 0x2e,
+	0xaa, 0x93, 0x20, 0xf4, 0x9c, 0xb1, 0xa7, 0x06, 0x7a, 0x0a, 0xbf, 0x88, 0x32, 0x1e, 0x31, 0x7c,
+	0xea, 0xe8, 0x19, 0xe8, 0xb3, 0xd4, 0xeb, 0x96, 0xe6, 0x39, 0x22, 0x75, 0x10, 0x6d, 0xf0, 0xf7,
+	0xd0, 0xcc, 0x61, 0xd8, 0x24, 0x9e, 0x43, 0x02, 0xe2, 0xb3, 0x81, 0xb2, 0xd0, 0xa9, 0xd8, 0xeb,
+	0x96, 0x56, 0x62, 0x81, 0x32, 0xd6, 0xb4, 0x8c, 0x33, 0x33, 0x5d, 0x6a, 0x35, 0x9c, 0xb0, 0xd3,
+	0x24, 0x9e, 0x9e, 0x5b, 0xd3, 0xd6, 0xd3, 0xdc, 0x4c, 0x97, 0x5a, 0x6f, 0x01, 0x28, 0x9b, 0xd9,
+	0x07, 0xd9, 0xc0, 0x5e, 0xe8, 0x34, 0x8c, 0x00, 0x44, 0xc4, 0xd2, 0xf3, 0x6b, 0xda, 0x7a, 0x8e,
+	0x0f, 0xec, 0x85, 0xce, 0xd5, 0x08, 0x97, 0x07, 0x96, 0xf1, 0xf2, 0xbf, 0x34, 0xb4, 0x14, 0x31,
+	0x62, 0xeb, 0xbe, 0x6b, 0x7b, 0xa3, 0xbe, 0xbb, 0xfe, 0x6c, 0x0a, 0xcd, 0xed, 0xd0, 0xe6, 0x2d,
+	0xe2, 0x58, 0xb6, 0xd3, 0x1a, 0x93, 0x7f, 0x10, 0xf9, 0x8f, 0xd1, 0x39, 0xf3, 0xb5, 0xe8, 0x9c,
+	0x3d, 0x35, 0x9d, 0x5f, 0x42, 0x39, 0xe8, 0x67, 0x74, 0x08, 0x04, 0x41, 0xbe, 0xb6, 0xdc, 0xeb,
+	0x96, 0x16, 0x58, 0x03, 0xa3, 0x23, 0xfb, 0x2a, 0x2b, 0x20, 0x66, 0x6a, 0xd4, 0xc3, 0x77, 0x0d,
+	0x93, 0x40, 0x00, 0x08, 0x53, 0x45, 0x1b, 0xc0, 0x65, 0x53, 0x65, 0xbc, 0xfc, 0x07, 0xce, 0x87,
+	0x7a, 0xe8, 0x38, 0x63, 0x3e, 0x7c, 0x53, 0x7c, 0xb8, 0x8c, 0xf2, 0x0e, 0xb5, 0x08, 0x5f, 0xd8,
+	0x6c, 0xec, 0x23, 0x06, 0x26, 0x56, 0x36, 0x17, 0x61, 0x43, 0xef, 0x89, 0x32, 0x89, 0xf2, 0xc3,
+	0x91, 0x08, 0x3d, 0x25, 0x89, 0x7e, 0x9b, 0x41, 0x8b, 0x2c, 0x09, 0x71, 0x5a, 0x1e, 0xf1, 0xfd,
+	0x6d, 0x67, 0x8f, 0x8e, 0x89, 0x34, 0x5a, 0x44, 0x42, 0xc3, 0x11, 0xa9, 0xf0, 0x74, 0x44, 0xc2,
+	0x0f, 0xd0, 0x82, 0xcd, 0x49, 0xd4, 0x30, 0x2c, 0x8b, 0xfd, 0x9f, 0xf8, 0x7a, 0x7e, 0x6d, 0x72,
+	0xbd, 0xb0, 0x51, 0x89, 0x6e, 0x47, 0x49, 0x96, 0x55, 0x04, 0x70, 0x35, 0xea, 0xb0, 0xe5, 0x04,
+	0xde, 0x51, 0x6d, 0xb5, 0xd7, 0x2d, 0x15, 0xed, 0x84, 0x48, 0x1a, 0x78, 0x3e, 0x29, 0x2b, 0x1e,
+	0xa2, 0xe5, 0x81, 0xaa, 0xf0, 0x73, 0x68, 0xf2, 0x90, 0x1c, 0x01, 0x87, 0xd3, 0xb5, 0x85, 0x5e,
+	0xb7, 0x34, 0x73, 0x48, 0x8e, 0x24, 0x55, 0x4c, 0xca, 0x98, 0x78, 0xd7, 0x68, 0x87, 0x44, 0x50,
+	0x17, 0x98, 0x08, 0x80, 0xcc, 0x44, 0x00, 0xae, 0xa4, 0x5e, 0xd5, 0xca, 0xff, 0x9e, 0x42, 0xfa,
+	0x0e, 0x6d, 0xde, 0x71, 0x8c, 0x66, 0x9b, 0xdc, 0xa6, 0xbb, 0xe6, 0x3e, 0xb1, 0xc2, 0x36, 0x19,
+	0xc7, 0xcd, 0x33, 0x90, 0x8d, 0x2a, 0x51, 0x96, 0x1b, 0x2a, 0xca, 0xf2, 0xcf, 0x70, 0x94, 0x95,
+	0x1f, 0x66, 0xe1, 0xa6, 0x78, 0xdd, 0xb0, 0xdb, 0xe3, 0xfb, 0xcf, 0x7f, 0x83, 0x71, 0xef, 0x22,
+	0x44, 0xee, 0xdb, 0x41, 0xc3, 0xa4, 0x16, 0xf1, 0xf5, 0x2c, 0xec, 0x57, 0xe5, 0x68, 0xbf, 0x92,
+	0xdc, 0x5c, 0xd9, 0xba, 0x6f, 0x07, 0x9b, 0xac, 0x11, 0xdf, 0xa3, 0xce, 0x32, 0x4b, 0x48, 0x84,
+	0xc5, 0x8a, 0x75, 0xad, 0x9e, 0xef, 0xc3, 0xc7, 0xf9, 0x9c, 0xfb, 0x3a, 0x7c, 0xce, 0x0f, 0xc5,
+	0x67, 0x34, 0x14, 0x9f, 0x67, 0x86, 0xe3, 0xf3, 0xec, 0x53, 0x9e, 0x1a, 0x16, 0xc2, 0x26, 0x75,
+	0x02, 0xc3, 0x76, 0x88, 0xd7, 0xf0, 0x03, 0x23, 0x08, 0xd9, 0xb1, 0x51, 0x80, 0x65, 0x58, 0x82,
+	0x65, 0xd8, 0x8c, 0xc4, 0xbb, 0x20, 0xad, 0x95, 0x7a, 0xdd, 0xd2, 0x39, 0x53, 0x05, 0x95, 0xd3,
+	0x61, 0xe1, 0x98, 0x10, 0xbf, 0x82, 0xd2, 0xa6, 0x11, 0xfa, 0x44, 0x9f, 0x5e, 0xd3, 0xd6, 0x67,
+	0x37, 0x10, 0x57, 0xcc, 0x10, 0x4e, 0x66, 0x10, 0xca, 0x64, 0x06, 0xa0, 0x68, 0xa1, 0x59, 0x75,
+	0xd5, 0xe5, 0xe3, 0x24, 0x7f, 0xba, 0xe3, 0x24, 0x7d, 0xe2, 0x71, 0xf2, 0xeb, 0x14, 0xc2, 0xec,
+	0x5a, 0xe7, 0x11, 0x26, 0x1a, 0xf9, 0x4c, 0xfe, 0x15, 0x94, 0xf7, 0xc8, 0xfb, 0x21, 0xf1, 0x03,
+	0xea, 0xc9, 0x51, 0xdd, 0x07, 0x65, 0x6e, 0xf6, 0xc1, 0xf2, 0x57, 0x93, 0xf0, 0x71, 0x59, 0x78,
+	0x69, 0xbc, 0xf7, 0x0d, 0xde, 0xfb, 0x2e, 0xa2, 0x8c, 0x17, 0x3a, 0x71, 0x7a, 0x0a, 0xe6, 0x7a,
+	0xa1, 0xa3, 0xfa, 0x03, 0x00, 0xbc, 0x8d, 0x16, 0x5c, 0xc1, 0xb9, 0xbb, 0x24, 0xfa, 0x76, 0xc9,
+	0xcf, 0xdb, 0x0b, 0xbd, 0x6e, 0xe9, 0x6c, 0x2c, 0x4c, 0x7e, 0xbd, 0x9c, 0x4b, 0x88, 0x12, 0xaa,
+	0x84, 0x05, 0xb9, 0x41, 0xaa, 0xea, 0x09, 0x5b, 0xe6, 0x12, 0xa2, 0xf2, 0x16, 0xe4, 0x56, 0xd2,
+	0xc6, 0xbb, 0x49, 0x3b, 0x2e, 0x64, 0x74, 0xb0, 0x16, 0x50, 0x61, 0x81, 0xc5, 0x9e, 0xe6, 0x93,
+	0x03, 0x40, 0x9e, 0x1c, 0x00, 0xe5, 0x3f, 0x4e, 0x89, 0x5a, 0x84, 0x69, 0x12, 0x62, 0x8d, 0xe9,
+	0x32, 0xbe, 0x1d, 0x0f, 0x75, 0x3b, 0xfe, 0x34, 0x0f, 0xb7, 0xe3, 0x3b, 0x81, 0xdd, 0xb6, 0x7d,
+	0x28, 0x91, 0x8d, 0x89, 0xf4, 0x8d, 0x10, 0xe9, 0x63, 0x0d, 0x2d, 0xdf, 0x30, 0xee, 0xd7, 0x45,
+	0x6d, 0xd1, 0xbf, 0x4e, 0xbd, 0x5b, 0xc4, 0xb3, 0xa9, 0x25, 0x52, 0xb2, 0xcb, 0x51, 0x4a, 0x96,
+	0x5c, 0x8a, 0xca, 0xc0, 0x5e, 0x3c, 0x47, 0xbb, 0x20, 0xe6, 0x3a, 0x58, 0x73, 0x7d, 0x30, 0x3c,
+	0xea, 0x57, 0x08, 0xfc, 0x53, 0x0d, 0xad, 0x04, 0x34, 0x30, 0xda, 0x0d, 0x33, 0xec, 0x84, 0x6d,
+	0x03, 0xf6, 0xec, 0xd0, 0x37, 0x5a, 0x2c, 0x3d, 0x62, 0xbe, 0xde, 0x78, 0xa2, 0xaf, 0x6f, 0xb3,
+	0x6e, 0x9b, 0xfd, 0x5e, 0x77, 0x58, 0x27, 0xee, 0xea, 0xf3, 0xc2, 0xd5, 0x4b, 0xc1, 0x80, 0x26,
+	0xf5, 0x81, 0x68, 0xf1, 0x33, 0x0d, 0x15, 0x9f, 0xbc, 0x7a, 0xa7, 0xcb, 0xb5, 0x7e, 0x20, 0xe7,
+	0x5a, 0x85, 0x8d, 0x4a, 0x85, 0x57, 0xae, 0x2b, 0x72, 0xe5, 0xba, 0xe2, 0x1e, 0xb6, 0x60, 0x4a,
+	0x51, 0xe5, 0xba, 0xf2, 0x76, 0x68, 0x38, 0x81, 0x1d, 0x1c, 0x9d, 0x94, 0x9b, 0x15, 0x3f, 0xd5,
+	0xd0, 0xd9, 0x27, 0x4e, 0xfa, 0x59, 0xb0, 0xb0, 0xfc, 0x15, 0x2f, 0xb9, 0xd6, 0x89, 0xeb, 0xd9,
+	0xd4, 0xb3, 0x03, 0xfb, 0x83, 0x91, 0xcf, 0x20, 0x5f, 0x43, 0xd3, 0x0e, 0xb9, 0xd7, 0x10, 0x13,
+	0x3e, 0x82, 0x6d, 0x4a, 0x83, 0x0b, 0xd9, 0xb2, 0x43, 0xee, 0xdd, 0x12, 0xb0, 0x64, 0x42, 0x41,
+	0x82, 0xd5, 0xfc, 0x33, 0x73, 0xea, 0xfc, 0xf3, 0xcb, 0x14, 0xd4, 0x1f, 0x25, 0x3f, 0x8f, 0x7a,
+	0x52, 0xf1, 0x3f, 0x71, 0xf3, 0x9f, 0xf9, 0x65, 0x68, 0xd3, 0x70, 0x4c, 0xd2, 0x6e, 0x8f, 0x2f,
+	0x43, 0x03, 0xbd, 0xf4, 0x74, 0x9f, 0x38, 0xca, 0x0f, 0xf9, 0xbb, 0x1c, 0xe1, 0xd3, 0x51, 0xa7,
+	0xed, 0xb7, 0xe2, 0xd2, 0xdf, 0x4f, 0x01, 0x4d, 0x6f, 0x13, 0xaf, 0x63, 0x3b, 0xc6, 0xf8, 0x3a,
+	0xfa, 0x2c, 0x57, 0x63, 0xbf, 0x9d, 0xab, 0x82, 0x44, 0xa0, 0xdc, 0x29, 0x08, 0xf4, 0xa7, 0x14,
+	0xd4, 0x6e, 0xef, 0xb8, 0xd6, 0xe8, 0xb3, 0x67, 0xc8, 0x88, 0x14, 0x0f, 0xec, 0x32, 0x27, 0x3e,
+	0xb0, 0xfb, 0x68, 0x0e, 0x4d, 0x83, 0x07, 0x6f, 0x10, 0x9f, 0x25, 0x67, 0xf8, 0x26, 0xca, 0xfb,
+	0xd1, 0x23, 0x44, 0xf0, 0x65, 0x61, 0x63, 0x25, 0xea, 0xaf, 0xbe, 0x4e, 0xe4, 0x86, 0xf4, 0x1b,
+	0xc7, 0x86, 0xbc, 0x31, 0x51, 0x8f, 0x75, 0xe0, 0x4d, 0x94, 0x01, 0xaf, 0x58, 0x22, 0x89, 0x5b,
+	0x8c, 0xb4, 0x49, 0x8f, 0xfa, 0xf8, 0x82, 0xf3, 0x66, 0x8a, 0x1e, 0xd1, 0x15, 0x5b, 0x68, 0xce,
+	0x8a, 0x1e, 0xc6, 0x35, 0xf6, 0x68, 0xe8, 0x58, 0xfa, 0x3c, 0x68, 0x3b, 0x17, 0x69, 0x1b, 0xf0,
+	0x6e, 0xae, 0x76, 0xbe, 0xd7, 0x2d, 0xe9, 0x96, 0x22, 0x50, 0xb4, 0xcf, 0xaa, 0x32, 0x66, 0x6a,
+	0x1b, 0x9e, 0x91, 0xc1, 0x1a, 0x4b, 0xa6, 0x4a, 0x8f, 0xcb, 0xb8, 0xa9, 0xbc, 0x99, 0x6a, 0x2a,
+	0xc7, 0xf0, 0x7b, 0x68, 0x16, 0xfe, 0xd5, 0xf0, 0xc4, 0x4b, 0xab, 0x3e, 0x07, 0x64, 0x65, 0xca,
+	0x33, 0x2c, 0xfe, 0xde, 0xad, 0x2d, 0xe3, 0x8a, 0xea, 0x19, 0x45, 0x84, 0xdf, 0x45, 0x1c, 0x68,
+	0x10, 0xfe, 0x72, 0x47, 0xbc, 0xa3, 0x3c, 0xab, 0x0c, 0x20, 0xbf, 0xea, 0xe1, 0x91, 0xd8, 0x96,
+	0x60, 0x45, 0xfd, 0xb4, 0x2c, 0xc1, 0xaf, 0xa3, 0xac, 0xcb, 0x5f, 0xc9, 0x08, 0xfa, 0x2c, 0x45,
+	0x7a, 0xe5, 0xc7, 0x33, 0x62, 0x4f, 0xe0, 0x88, 0xa2, 0x2d, 0xea, 0xcd, 0x14, 0x79, 0xfc, 0x79,
+	0x05, 0x6c, 0x3e, 0x92, 0x22, 0xf9, 0xd5, 0x05, 0x57, 0x24, 0x1a, 0xaa, 0x8a, 0x04, 0x88, 0x3b,
+	0x08, 0x87, 0x50, 0x2f, 0x6c, 0x04, 0xb4, 0xe1, 0x8b, 0x8a, 0x21, 0xec, 0x14, 0x85, 0x8d, 0x0b,
+	0xfd, 0xfb, 0xd6, 0xa0, 0x8a, 0x22, 0xaf, 0x86, 0x86, 0x09, 0x91, 0x32, 0xca, 0x7c, 0x52, 0xca,
+	0x58, 0xb0, 0x07, 0x9f, 0xd0, 0x60, 0xf7, 0x93, 0x58, 0x20, 0x7d, 0x58, 0xe3, 0x2c, 0xe0, 0xcd,
+	0x54, 0x16, 0x70, 0x8c, 0x87, 0x91, 0xf8, 0x7e, 0x06, 0xdb, 0xa1, 0x12, 0x46, 0xf2, 0x87, 0xb5,
+	0x28, 0x8c, 0x04, 0x96, 0x0c, 0x23, 0x01, 0xe3, 0x06, 0x9a, 0xf1, 0xe4, 0xfc, 0x19, 0xae, 0xae,
+	0x12, 0xab, 0x8e, 0x27, 0xd7, 0x9c, 0x55, 0x4a, 0x27, 0x95, 0x55, 0x8a, 0x08, 0xef, 0x22, 0x64,
+	0xf6, 0x33, 0x47, 0xf8, 0xd8, 0x5f, 0xd8, 0x38, 0x13, 0x69, 0x4f, 0xe4, 0x94, 0x35, 0x9d, 0x5d,
+	0x57, 0xe3, 0xe6, 0x8a, 0x5e, 0x49, 0x0d, 0x73, 0x83, 0x19, 0xa5, 0x4e, 0x50, 0x16, 0x91, 0xdc,
+	0xa0, 0xe6, 0x54, 0xe2, 0x4c, 0x8c, 0x30, 0xd5, 0x0d, 0x7d, 0x98, 0x59, 0x19, 0xf4, 0x13, 0x07,
+	0xa8, 0x98, 0x48, 0x56, 0x26, 0x52, 0x0a, 0x6e, 0x65, 0xdc, 0x5c, 0xb5, 0x32, 0xc6, 0xf1, 0x3b,
+	0xa8, 0x10, 0xc6, 0xd7, 0x75, 0x7d, 0x0e, 0xb4, 0xea, 0x4f, 0xba, 0xc9, 0xf3, 0x34, 0x5e, 0xea,
+	0xa0, 0xe8, 0x95, 0x35, 0xe1, 0xef, 0xa3, 0xe9, 0xa8, 0xae, 0x6f, 0x3b, 0x7b, 0x54, 0x5f, 0x50,
+	0x35, 0x27, 0x4b, 0xfa, 0x5c, 0xb3, 0x1d, 0xa3, 0xaa, 0x66, 0x49, 0x80, 0x4d, 0x34, 0xeb, 0x29,
+	0xd7, 0x56, 0x1d, 0xab, 0xfb, 0xe1, 0x80, 0x4b, 0x2d, 0xdf, 0x0f, 0xd5, 0x6e, 0xea, 0x7e, 0xa8,
+	0xca, 0x58, 0x04, 0x87, 0xfc, 0x90, 0xd5, 0x17, 0xd5, 0x08, 0x96, 0xcf, 0x5e, 0x1e, 0xc1, 0xa2,
+	0xa1, 0x1a, 0xc1, 0x02, 0xc4, 0x87, 0x48, 0xc4, 0x4a, 0xfc, 0x41, 0x5a, 0x5f, 0x52, 0xe3, 0x77,
+	0xe0, 0x57, 0x6b, 0x1e, 0xbf, 0xc9, 0xae, 0x6a, 0xfc, 0x26, 0xa5, 0x8c, 0x73, 0x6e, 0x54, 0xe9,
+	0xd0, 0x97, 0x55, 0xce, 0xa9, 0x25, 0x10, 0x91, 0x0e, 0x45, 0x98, 0xca, 0xb9, 0x3e, 0xcc, 0x38,
+	0xe7, 0xf6, 0x0b, 0x4c, 0xfa, 0x8a, 0xca, 0xb9, 0x44, 0xe9, 0x89, 0x73, 0x2e, 0x6e, 0xae, 0x72,
+	0x2e, 0xc6, 0x6b, 0x39, 0x94, 0x81, 0xaf, 0xed, 0x7e, 0xf9, 0xc7, 0x29, 0x34, 0x97, 0x28, 0xd4,
+	0xe1, 0xff, 0x43, 0x53, 0x90, 0x7f, 0xf1, 0x64, 0x06, 0xf7, 0xba, 0xa5, 0x59, 0x47, 0x4d, 0xbe,
+	0x40, 0x8e, 0x37, 0x50, 0x2e, 0x2a, 0x98, 0x8a, 0x8a, 0x19, 0x24, 0x32, 0x11, 0x26, 0x27, 0x32,
+	0x11, 0x86, 0xab, 0x28, 0xdb, 0xe1, 0x87, 0xbd, 0x48, 0x65, 0x60, 0xfd, 0x04, 0x24, 0xa7, 0x77,
+	0x02, 0x92, 0xb2, 0xb3, 0xa9, 0x53, 0x14, 0x85, 0xfb, 0xf5, 0xc2, 0xf4, 0xd3, 0xd4, 0x0b, 0xcb,
+	0x1f, 0x20, 0x0c, 0x0e, 0xdc, 0x0d, 0x3c, 0x62, 0x74, 0xa2, 0x6c, 0x64, 0x0d, 0xa5, 0xfa, 0x29,
+	0xdd, 0x7c, 0xaf, 0x5b, 0x9a, 0xb6, 0xe5, 0xe4, 0x2c, 0x65, 0x5b, 0xb8, 0x16, 0xcf, 0x86, 0xe7,
+	0x17, 0x0b, 0x30, 0xa0, 0x9c, 0xd3, 0x9c, 0x34, 0xc1, 0xf2, 0x4f, 0x26, 0xd1, 0xcc, 0x0e, 0xe4,
+	0x79, 0x75, 0x9e, 0x41, 0x9d, 0x62, 0xdc, 0x17, 0x50, 0xfa, 0x9e, 0x11, 0x98, 0xfb, 0x30, 0x6a,
+	0x8e, 0x4f, 0x0d, 0x00, 0x79, 0x6a, 0x00, 0xe0, 0x4d, 0x34, 0xb7, 0xe7, 0xd1, 0x4e, 0x43, 0x0c,
+	0xc7, 0x92, 0xce, 0xc9, 0xf8, 0x99, 0x3b, 0x13, 0x09, 0x43, 0xd5, 0x67, 0xee, 0x8a, 0x20, 0x4e,
+	0x3f, 0xa7, 0x4e, 0x4c, 0x3f, 0xaf, 0xa1, 0x59, 0xe2, 0x79, 0xd4, 0xdb, 0xde, 0xbb, 0x61, 0xfb,
+	0x3e, 0xe3, 0x6c, 0x1a, 0x6c, 0x84, 0xf0, 0x57, 0x25, 0x52, 0xe7, 0x44, 0x1f, 0xfc, 0x1a, 0x9a,
+	0xde, 0xa3, 0x9e, 0x49, 0x1a, 0x6d, 0xd2, 0x32, 0xcc, 0x23, 0x48, 0x06, 0x72, 0x7c, 0x87, 0x02,
+	0xfc, 0x4d, 0x80, 0xe5, 0x4f, 0x18, 0x12, 0x8c, 0x2f, 0xa3, 0x3c, 0xef, 0xed, 0x90, 0x7b, 0x70,
+	0xfc, 0xe7, 0x38, 0x33, 0x01, 0x7c, 0x8b, 0xdc, 0x93, 0x99, 0x19, 0x61, 0xe5, 0x5f, 0xa4, 0xd0,
+	0xf4, 0x3b, 0xcc, 0x65, 0xd1, 0x32, 0xf4, 0x27, 0xad, 0x9d, 0x38, 0xe9, 0xe1, 0x92, 0xfa, 0x4b,
+	0x28, 0x0b, 0x4b, 0xd3, 0x5f, 0x12, 0x7e, 0xae, 0x7b, 0xb4, 0xa3, 0x74, 0xc8, 0x70, 0xe4, 0x98,
+	0x4f, 0xa6, 0x86, 0xf7, 0x49, 0xfa, 0x74, 0x3e, 0xb9, 0xf8, 0x5d, 0x94, 0x86, 0xe0, 0xc1, 0x79,
+	0x94, 0xde, 0x62, 0x2b, 0x34, 0x3f, 0x81, 0x0b, 0x28, 0xbb, 0x75, 0xd7, 0x36, 0x03, 0x62, 0xcd,
+	0x6b, 0x38, 0x8b, 0x26, 0x6f, 0xde, 0xbc, 0x31, 0x9f, 0xc2, 0x4b, 0x68, 0xfe, 0x1a, 0x31, 0xac,
+	0xb6, 0xed, 0x90, 0xad, 0xfb, 0x3c, 0x6b, 0x98, 0x9f, 0xdc, 0xf8, 0x87, 0x86, 0xd2, 0xfc, 0x8a,
+	0x44, 0xd0, 0xdc, 0xeb, 0x24, 0xe0, 0x3c, 0x07, 0xc4, 0xc7, 0xb8, 0x9f, 0x92, 0xf4, 0xa9, 0x5f,
+	0x3c, 0x13, 0xc7, 0x8f, 0x12, 0x8b, 0xe5, 0xe7, 0x7e, 0xf4, 0x97, 0x2f, 0x7f, 0x99, 0xba, 0x50,
+	0xd6, 0xab, 0x77, 0xff, 0xbf, 0x7a, 0x40, 0x9b, 0x97, 0x7c, 0x12, 0x54, 0x1f, 0x80, 0xf7, 0x3f,
+	0xac, 0x3e, 0xb0, 0xad, 0x0f, 0xaf, 0x68, 0x17, 0x5f, 0xd2, 0xf0, 0x15, 0x94, 0x86, 0x35, 0xc4,
+	0x3c, 0x10, 0xe5, 0xf5, 0x7c, 0xb2, 0xee, 0xc9, 0x8f, 0x53, 0x1a, 0xf4, 0xcd, 0xbc, 0x01, 0x7f,
+	0xb5, 0x85, 0x57, 0x8e, 0xdd, 0x98, 0xb6, 0x98, 0x63, 0x8a, 0xfc, 0xec, 0xe4, 0x8d, 0x36, 0xf7,
+	0x89, 0x79, 0x58, 0x27, 0xbe, 0x4b, 0x1d, 0x9f, 0xd4, 0xde, 0xfb, 0xe2, 0xef, 0xab, 0x13, 0x1f,
+	0x3d, 0x5a, 0xd5, 0x3e, 0x7f, 0xb4, 0xaa, 0x3d, 0x7c, 0xb4, 0xaa, 0xfd, 0xed, 0xd1, 0xaa, 0xf6,
+	0xc9, 0xe3, 0xd5, 0x89, 0x87, 0x8f, 0x57, 0x27, 0xbe, 0x78, 0xbc, 0x3a, 0xf1, 0xc3, 0xe7, 0xa5,
+	0x3f, 0xf3, 0x32, 0xbc, 0x8e, 0x61, 0x19, 0xae, 0x47, 0x0f, 0x88, 0x19, 0x88, 0x5f, 0xd1, 0x5f,
+	0x69, 0xfd, 0x26, 0xb5, 0x74, 0x15, 0x80, 0x5b, 0x5c, 0x5c, 0xd9, 0xa6, 0x95, 0xab, 0xae, 0xdd,
+	0xcc, 0x80, 0x2d, 0x97, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x2f, 0x05, 0xeb, 0xb3, 0x36,
+	0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -3993,6 +4084,65 @@ func (m *JobFailedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	return len(dAtA) - i, nil
 }
 
+func (m *JobPreemptingEvent) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *JobPreemptingEvent) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *JobPreemptingEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.Requestor) > 0 {
+		i -= len(m.Requestor)
+		copy(dAtA[i:], m.Requestor)
+		i = encodeVarintEvent(dAtA, i, uint64(len(m.Requestor)))
+		i--
+		dAtA[i] = 0x2a
+	}
+	n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err13 != nil {
+		return 0, err13
+	}
+	i -= n13
+	i = encodeVarintEvent(dAtA, i, uint64(n13))
+	i--
+	dAtA[i] = 0x22
+	if len(m.Queue) > 0 {
+		i -= len(m.Queue)
+		copy(dAtA[i:], m.Queue)
+		i = encodeVarintEvent(dAtA, i, uint64(len(m.Queue)))
+		i--
+		dAtA[i] = 0x1a
+	}
+	if len(m.JobSetId) > 0 {
+		i -= len(m.JobSetId)
+		copy(dAtA[i:], m.JobSetId)
+		i = encodeVarintEvent(dAtA, i, uint64(len(m.JobSetId)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.JobId) > 0 {
+		i -= len(m.JobId)
+		copy(dAtA[i:], m.JobId)
+		i = encodeVarintEvent(dAtA, i, uint64(len(m.JobId)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
 func (m *JobPreemptedEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -4041,12 +4191,12 @@ func (m *JobPreemptedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err13 != nil {
-		return 0, err13
+	n14, err14 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err14 != nil {
+		return 0, err14
 	}
-	i -= n13
-	i = encodeVarintEvent(dAtA, i, uint64(n13))
+	i -= n14
+	i = encodeVarintEvent(dAtA, i, uint64(n14))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4163,12 +4313,12 @@ func (m *JobSucceededEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n14, err14 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err14 != nil {
-		return 0, err14
+	n15, err15 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err15 != nil {
+		return 0, err15
 	}
-	i -= n14
-	i = encodeVarintEvent(dAtA, i, uint64(n14))
+	i -= n15
+	i = encodeVarintEvent(dAtA, i, uint64(n15))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4303,12 +4453,12 @@ func (m *JobUtilisationEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n17, err17 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err17 != nil {
-		return 0, err17
+	n18, err18 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err18 != nil {
+		return 0, err18
 	}
-	i -= n17
-	i = encodeVarintEvent(dAtA, i, uint64(n17))
+	i -= n18
+	i = encodeVarintEvent(dAtA, i, uint64(n18))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4368,12 +4518,12 @@ func (m *JobReprioritizingEvent) MarshalToSizedBuffer(dAtA []byte) (int, error)
 		i--
 		dAtA[i] = 0x29
 	}
-	n18, err18 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err18 != nil {
-		return 0, err18
+	n19, err19 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err19 != nil {
+		return 0, err19
 	}
-	i -= n18
-	i = encodeVarintEvent(dAtA, i, uint64(n18))
+	i -= n19
+	i = encodeVarintEvent(dAtA, i, uint64(n19))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4433,12 +4583,12 @@ func (m *JobReprioritizedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x29
 	}
-	n19, err19 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err19 != nil {
-		return 0, err19
+	n20, err20 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err20 != nil {
+		return 0, err20
 	}
-	i -= n19
-	i = encodeVarintEvent(dAtA, i, uint64(n19))
+	i -= n20
+	i = encodeVarintEvent(dAtA, i, uint64(n20))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4499,12 +4649,12 @@ func (m *JobCancellingEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n20, err20 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err20 != nil {
-		return 0, err20
+	n21, err21 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err21 != nil {
+		return 0, err21
 	}
-	i -= n20
-	i = encodeVarintEvent(dAtA, i, uint64(n20))
+	i -= n21
+	i = encodeVarintEvent(dAtA, i, uint64(n21))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4565,12 +4715,12 @@ func (m *JobCancelledEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n21, err21 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err21 != nil {
-		return 0, err21
+	n22, err22 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err22 != nil {
+		return 0, err22
 	}
-	i -= n21
-	i = encodeVarintEvent(dAtA, i, uint64(n21))
+	i -= n22
+	i = encodeVarintEvent(dAtA, i, uint64(n22))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4657,12 +4807,12 @@ func (m *JobTerminatedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n22, err22 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err22 != nil {
-		return 0, err22
+	n23, err23 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err23 != nil {
+		return 0, err23
 	}
-	i -= n22
-	i = encodeVarintEvent(dAtA, i, uint64(n22))
+	i -= n23
+	i = encodeVarintEvent(dAtA, i, uint64(n23))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -4726,12 +4876,12 @@ func (m *JobUpdatedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		i--
 		dAtA[i] = 0x2a
 	}
-	n24, err24 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
-	if err24 != nil {
-		return 0, err24
+	n25, err25 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):])
+	if err25 != nil {
+		return 0, err25
 	}
-	i -= n24
-	i = encodeVarintEvent(dAtA, i, uint64(n24))
+	i -= n25
+	i = encodeVarintEvent(dAtA, i, uint64(n25))
 	i--
 	dAtA[i] = 0x22
 	if len(m.Queue) > 0 {
@@ -5243,6 +5393,29 @@ func (m *EventMessage_Preempted) MarshalToSizedBuffer(dAtA []byte) (int, error)
 	}
 	return len(dAtA) - i, nil
 }
+func (m *EventMessage_Preempting) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EventMessage_Preempting) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	if m.Preempting != nil {
+		{
+			size, err := m.Preempting.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintEvent(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xb2
+	}
+	return len(dAtA) - i, nil
+}
 func (m *ContainerStatus) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -5923,6 +6096,33 @@ func (m *JobFailedEvent) Size() (n int) {
 	return n
 }
 
+func (m *JobPreemptingEvent) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.JobId)
+	if l > 0 {
+		n += 1 + l + sovEvent(uint64(l))
+	}
+	l = len(m.JobSetId)
+	if l > 0 {
+		n += 1 + l + sovEvent(uint64(l))
+	}
+	l = len(m.Queue)
+	if l > 0 {
+		n += 1 + l + sovEvent(uint64(l))
+	}
+	l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Created)
+	n += 1 + l + sovEvent(uint64(l))
+	l = len(m.Requestor)
+	if l > 0 {
+		n += 1 + l + sovEvent(uint64(l))
+	}
+	return n
+}
+
 func (m *JobPreemptedEvent) Size() (n int) {
 	if m == nil {
 		return 0
@@ -6546,6 +6746,18 @@ func (m *EventMessage_Preempted) Size() (n int) {
 	}
 	return n
 }
+func (m *EventMessage_Preempting) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.Preempting != nil {
+		l = m.Preempting.Size()
+		n += 2 + l + sovEvent(uint64(l))
+	}
+	return n
+}
 func (m *ContainerStatus) Size() (n int) {
 	if m == nil {
 		return 0
@@ -6867,6 +7079,20 @@ func (this *JobFailedEvent) String() string {
 	}, "")
 	return s
 }
+func (this *JobPreemptingEvent) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&JobPreemptingEvent{`,
+		`JobId:` + fmt.Sprintf("%v", this.JobId) + `,`,
+		`JobSetId:` + fmt.Sprintf("%v", this.JobSetId) + `,`,
+		`Queue:` + fmt.Sprintf("%v", this.Queue) + `,`,
+		`Created:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Created), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`,
+		`Requestor:` + fmt.Sprintf("%v", this.Requestor) + `,`,
+		`}`,
+	}, "")
+	return s
+}
 func (this *JobPreemptedEvent) String() string {
 	if this == nil {
 		return "nil"
@@ -7268,6 +7494,16 @@ func (this *EventMessage_Preempted) String() string {
 	}, "")
 	return s
 }
+func (this *EventMessage_Preempting) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&EventMessage_Preempting{`,
+		`Preempting:` + strings.Replace(fmt.Sprintf("%v", this.Preempting), "JobPreemptingEvent", "JobPreemptingEvent", 1) + `,`,
+		`}`,
+	}, "")
+	return s
+}
 func (this *ContainerStatus) String() string {
 	if this == nil {
 		return "nil"
@@ -10738,6 +10974,217 @@ func (m *JobFailedEvent) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *JobPreemptingEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowEvent
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: JobPreemptingEvent: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: JobPreemptingEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobId", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthEvent
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.JobId = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthEvent
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.JobSetId = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthEvent
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Queue = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Created", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthEvent
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Created, dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Requestor", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthEvent
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Requestor = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipEvent(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
 	iNdEx := 0
@@ -14399,6 +14846,41 @@ func (m *EventMessage) Unmarshal(dAtA []byte) error {
 			}
 			m.Events = &EventMessage_Preempted{v}
 			iNdEx = postIndex
+		case 22:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Preempting", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthEvent
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvent
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			v := &JobPreemptingEvent{}
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			m.Events = &EventMessage_Preempting{v}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipEvent(dAtA[iNdEx:])
diff --git a/pkg/api/event.proto b/pkg/api/event.proto
index 3a54d1a8..97a5f771 100644
--- a/pkg/api/event.proto
+++ b/pkg/api/event.proto
@@ -135,6 +135,14 @@ message JobFailedEvent {
     Cause cause = 12;
 }
 
+message JobPreemptingEvent {
+  string job_id = 1;
+  string job_set_id = 2;
+  string queue = 3;
+  google.protobuf.Timestamp created = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
+  string requestor = 5;
+}
+
 message JobPreemptedEvent {
     string job_id = 1;
     string job_set_id = 2;
@@ -260,6 +268,7 @@ message EventMessage {
         JobUpdatedEvent updated = 19;
         JobFailedEventCompressed failedCompressed = 20;  // This event is for internal armada use only
         JobPreemptedEvent preempted = 21;
+        JobPreemptingEvent preempting = 22;
     }
 }
 
diff --git a/pkg/api/event_util.go b/pkg/api/event_util.go
index 36743bb1..cfce5205 100644
--- a/pkg/api/event_util.go
+++ b/pkg/api/event_util.go
@@ -73,6 +73,8 @@ func UnwrapEvent(message *EventMessage) (Event, error) {
 		return event.IngressInfo, nil
 	case *EventMessage_Updated:
 		return event.Updated, nil
+	case *EventMessage_Preempting:
+		return event.Preempting, nil
 	case *EventMessage_Preempted:
 		return event.Preempted, nil
 	}
@@ -195,6 +197,12 @@ func Wrap(event Event) (*EventMessage, error) {
 				Updated: typed,
 			},
 		}, nil
+	case *JobPreemptingEvent:
+		return &EventMessage{
+			Events: &EventMessage_Preempting{
+				Preempting: typed,
+			},
+		}, nil
 	case *JobPreemptedEvent:
 		return &EventMessage{
 			Events: &EventMessage_Preempted{
diff --git a/pkg/api/submit.pb.go b/pkg/api/submit.pb.go
index 477367cb..a03e5205 100644
--- a/pkg/api/submit.pb.go
+++ b/pkg/api/submit.pb.go
@@ -468,6 +468,66 @@ func (m *JobSubmitRequest) GetJobRequestItems() []*JobSubmitRequestItem {
 	return nil
 }
 
+// swagger:model
+type JobPreemptRequest struct {
+	Queue    string   `protobuf:"bytes,1,opt,name=queue,proto3" json:"queue,omitempty"`
+	JobSetId string   `protobuf:"bytes,2,opt,name=job_set_id,json=jobSetId,proto3" json:"jobSetId,omitempty"`
+	JobIds   []string `protobuf:"bytes,3,rep,name=job_ids,json=jobIds,proto3" json:"jobIds,omitempty"`
+}
+
+func (m *JobPreemptRequest) Reset()      { *m = JobPreemptRequest{} }
+func (*JobPreemptRequest) ProtoMessage() {}
+func (*JobPreemptRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_e998bacb27df16c1, []int{4}
+}
+func (m *JobPreemptRequest) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *JobPreemptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_JobPreemptRequest.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *JobPreemptRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_JobPreemptRequest.Merge(m, src)
+}
+func (m *JobPreemptRequest) XXX_Size() int {
+	return m.Size()
+}
+func (m *JobPreemptRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_JobPreemptRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_JobPreemptRequest proto.InternalMessageInfo
+
+func (m *JobPreemptRequest) GetQueue() string {
+	if m != nil {
+		return m.Queue
+	}
+	return ""
+}
+
+func (m *JobPreemptRequest) GetJobSetId() string {
+	if m != nil {
+		return m.JobSetId
+	}
+	return ""
+}
+
+func (m *JobPreemptRequest) GetJobIds() []string {
+	if m != nil {
+		return m.JobIds
+	}
+	return nil
+}
+
 // swagger:model
 type JobCancelRequest struct {
 	JobId    string   `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
@@ -480,7 +540,7 @@ type JobCancelRequest struct {
 func (m *JobCancelRequest) Reset()      { *m = JobCancelRequest{} }
 func (*JobCancelRequest) ProtoMessage() {}
 func (*JobCancelRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{4}
+	return fileDescriptor_e998bacb27df16c1, []int{5}
 }
 func (m *JobCancelRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -555,7 +615,7 @@ type JobSetCancelRequest struct {
 func (m *JobSetCancelRequest) Reset()      { *m = JobSetCancelRequest{} }
 func (*JobSetCancelRequest) ProtoMessage() {}
 func (*JobSetCancelRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{5}
+	return fileDescriptor_e998bacb27df16c1, []int{6}
 }
 func (m *JobSetCancelRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -620,7 +680,7 @@ type JobSetFilter struct {
 func (m *JobSetFilter) Reset()      { *m = JobSetFilter{} }
 func (*JobSetFilter) ProtoMessage() {}
 func (*JobSetFilter) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{6}
+	return fileDescriptor_e998bacb27df16c1, []int{7}
 }
 func (m *JobSetFilter) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -703,7 +763,7 @@ type Job struct {
 func (m *Job) Reset()      { *m = Job{} }
 func (*Job) ProtoMessage() {}
 func (*Job) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{7}
+	return fileDescriptor_e998bacb27df16c1, []int{8}
 }
 func (m *Job) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -899,7 +959,7 @@ type JobReprioritizeRequest struct {
 func (m *JobReprioritizeRequest) Reset()      { *m = JobReprioritizeRequest{} }
 func (*JobReprioritizeRequest) ProtoMessage() {}
 func (*JobReprioritizeRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{8}
+	return fileDescriptor_e998bacb27df16c1, []int{9}
 }
 func (m *JobReprioritizeRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -964,7 +1024,7 @@ type JobReprioritizeResponse struct {
 func (m *JobReprioritizeResponse) Reset()      { *m = JobReprioritizeResponse{} }
 func (*JobReprioritizeResponse) ProtoMessage() {}
 func (*JobReprioritizeResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{9}
+	return fileDescriptor_e998bacb27df16c1, []int{10}
 }
 func (m *JobReprioritizeResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1008,7 +1068,7 @@ type JobSubmitResponseItem struct {
 func (m *JobSubmitResponseItem) Reset()      { *m = JobSubmitResponseItem{} }
 func (*JobSubmitResponseItem) ProtoMessage() {}
 func (*JobSubmitResponseItem) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{10}
+	return fileDescriptor_e998bacb27df16c1, []int{11}
 }
 func (m *JobSubmitResponseItem) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1059,7 +1119,7 @@ type JobSubmitResponse struct {
 func (m *JobSubmitResponse) Reset()      { *m = JobSubmitResponse{} }
 func (*JobSubmitResponse) ProtoMessage() {}
 func (*JobSubmitResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{11}
+	return fileDescriptor_e998bacb27df16c1, []int{12}
 }
 func (m *JobSubmitResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1111,7 +1171,7 @@ type Queue struct {
 func (m *Queue) Reset()      { *m = Queue{} }
 func (*Queue) ProtoMessage() {}
 func (*Queue) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{12}
+	return fileDescriptor_e998bacb27df16c1, []int{13}
 }
 func (m *Queue) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1198,7 +1258,7 @@ type Queue_Permissions struct {
 func (m *Queue_Permissions) Reset()      { *m = Queue_Permissions{} }
 func (*Queue_Permissions) ProtoMessage() {}
 func (*Queue_Permissions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{12, 0}
+	return fileDescriptor_e998bacb27df16c1, []int{13, 0}
 }
 func (m *Queue_Permissions) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1249,7 +1309,7 @@ type Queue_Permissions_Subject struct {
 func (m *Queue_Permissions_Subject) Reset()      { *m = Queue_Permissions_Subject{} }
 func (*Queue_Permissions_Subject) ProtoMessage() {}
 func (*Queue_Permissions_Subject) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{12, 0, 0}
+	return fileDescriptor_e998bacb27df16c1, []int{13, 0, 0}
 }
 func (m *Queue_Permissions_Subject) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1304,7 +1364,7 @@ type PriorityClassResourceLimits struct {
 func (m *PriorityClassResourceLimits) Reset()      { *m = PriorityClassResourceLimits{} }
 func (*PriorityClassResourceLimits) ProtoMessage() {}
 func (*PriorityClassResourceLimits) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{13}
+	return fileDescriptor_e998bacb27df16c1, []int{14}
 }
 func (m *PriorityClassResourceLimits) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1354,7 +1414,7 @@ type PriorityClassPoolResourceLimits struct {
 func (m *PriorityClassPoolResourceLimits) Reset()      { *m = PriorityClassPoolResourceLimits{} }
 func (*PriorityClassPoolResourceLimits) ProtoMessage() {}
 func (*PriorityClassPoolResourceLimits) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{14}
+	return fileDescriptor_e998bacb27df16c1, []int{15}
 }
 func (m *PriorityClassPoolResourceLimits) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1398,7 +1458,7 @@ type QueueList struct {
 func (m *QueueList) Reset()      { *m = QueueList{} }
 func (*QueueList) ProtoMessage() {}
 func (*QueueList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{15}
+	return fileDescriptor_e998bacb27df16c1, []int{16}
 }
 func (m *QueueList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1442,7 +1502,7 @@ type CancellationResult struct {
 func (m *CancellationResult) Reset()      { *m = CancellationResult{} }
 func (*CancellationResult) ProtoMessage() {}
 func (*CancellationResult) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{16}
+	return fileDescriptor_e998bacb27df16c1, []int{17}
 }
 func (m *CancellationResult) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1486,7 +1546,7 @@ type QueueGetRequest struct {
 func (m *QueueGetRequest) Reset()      { *m = QueueGetRequest{} }
 func (*QueueGetRequest) ProtoMessage() {}
 func (*QueueGetRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{17}
+	return fileDescriptor_e998bacb27df16c1, []int{18}
 }
 func (m *QueueGetRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1530,7 +1590,7 @@ type StreamingQueueGetRequest struct {
 func (m *StreamingQueueGetRequest) Reset()      { *m = StreamingQueueGetRequest{} }
 func (*StreamingQueueGetRequest) ProtoMessage() {}
 func (*StreamingQueueGetRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{18}
+	return fileDescriptor_e998bacb27df16c1, []int{19}
 }
 func (m *StreamingQueueGetRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1574,7 +1634,7 @@ type QueueDeleteRequest struct {
 func (m *QueueDeleteRequest) Reset()      { *m = QueueDeleteRequest{} }
 func (*QueueDeleteRequest) ProtoMessage() {}
 func (*QueueDeleteRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{19}
+	return fileDescriptor_e998bacb27df16c1, []int{20}
 }
 func (m *QueueDeleteRequest) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1619,7 +1679,7 @@ type JobSetInfo struct {
 func (m *JobSetInfo) Reset()      { *m = JobSetInfo{} }
 func (*JobSetInfo) ProtoMessage() {}
 func (*JobSetInfo) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{20}
+	return fileDescriptor_e998bacb27df16c1, []int{21}
 }
 func (m *JobSetInfo) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1677,7 +1737,7 @@ type QueueUpdateResponse struct {
 func (m *QueueUpdateResponse) Reset()      { *m = QueueUpdateResponse{} }
 func (*QueueUpdateResponse) ProtoMessage() {}
 func (*QueueUpdateResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{21}
+	return fileDescriptor_e998bacb27df16c1, []int{22}
 }
 func (m *QueueUpdateResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1727,7 +1787,7 @@ type BatchQueueUpdateResponse struct {
 func (m *BatchQueueUpdateResponse) Reset()      { *m = BatchQueueUpdateResponse{} }
 func (*BatchQueueUpdateResponse) ProtoMessage() {}
 func (*BatchQueueUpdateResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{22}
+	return fileDescriptor_e998bacb27df16c1, []int{23}
 }
 func (m *BatchQueueUpdateResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1771,7 +1831,7 @@ type QueueCreateResponse struct {
 func (m *QueueCreateResponse) Reset()      { *m = QueueCreateResponse{} }
 func (*QueueCreateResponse) ProtoMessage() {}
 func (*QueueCreateResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{23}
+	return fileDescriptor_e998bacb27df16c1, []int{24}
 }
 func (m *QueueCreateResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1821,7 +1881,7 @@ type BatchQueueCreateResponse struct {
 func (m *BatchQueueCreateResponse) Reset()      { *m = BatchQueueCreateResponse{} }
 func (*BatchQueueCreateResponse) ProtoMessage() {}
 func (*BatchQueueCreateResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{24}
+	return fileDescriptor_e998bacb27df16c1, []int{25}
 }
 func (m *BatchQueueCreateResponse) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1864,7 +1924,7 @@ type EndMarker struct {
 func (m *EndMarker) Reset()      { *m = EndMarker{} }
 func (*EndMarker) ProtoMessage() {}
 func (*EndMarker) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{25}
+	return fileDescriptor_e998bacb27df16c1, []int{26}
 }
 func (m *EndMarker) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1903,7 +1963,7 @@ type StreamingQueueMessage struct {
 func (m *StreamingQueueMessage) Reset()      { *m = StreamingQueueMessage{} }
 func (*StreamingQueueMessage) ProtoMessage() {}
 func (*StreamingQueueMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptor_e998bacb27df16c1, []int{26}
+	return fileDescriptor_e998bacb27df16c1, []int{27}
 }
 func (m *StreamingQueueMessage) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -1989,6 +2049,7 @@ func init() {
 	proto.RegisterMapType((map[string]string)(nil), "api.IngressConfig.AnnotationsEntry")
 	proto.RegisterType((*ServiceConfig)(nil), "api.ServiceConfig")
 	proto.RegisterType((*JobSubmitRequest)(nil), "api.JobSubmitRequest")
+	proto.RegisterType((*JobPreemptRequest)(nil), "api.JobPreemptRequest")
 	proto.RegisterType((*JobCancelRequest)(nil), "api.JobCancelRequest")
 	proto.RegisterType((*JobSetCancelRequest)(nil), "api.JobSetCancelRequest")
 	proto.RegisterType((*JobSetFilter)(nil), "api.JobSetFilter")
@@ -2028,187 +2089,190 @@ func init() {
 func init() { proto.RegisterFile("pkg/api/submit.proto", fileDescriptor_e998bacb27df16c1) }
 
 var fileDescriptor_e998bacb27df16c1 = []byte{
-	// 2878 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0x4b, 0x6f, 0x1b, 0xd7,
-	0xf5, 0xd7, 0x90, 0x12, 0x25, 0x1e, 0xea, 0x41, 0x5d, 0xbd, 0x46, 0xb4, 0x43, 0xca, 0x93, 0xc4,
-	0x7f, 0x59, 0x48, 0xa8, 0x58, 0xf9, 0x07, 0xb5, 0xdd, 0x14, 0x86, 0x28, 0xd1, 0xb6, 0x1c, 0x9b,
-	0x56, 0x28, 0x2b, 0x69, 0x8a, 0xa2, 0xcc, 0x90, 0x73, 0x45, 0x8d, 0xc4, 0x99, 0x61, 0x66, 0x86,
-	0x72, 0xd5, 0x22, 0x40, 0x51, 0x14, 0xed, 0x36, 0x45, 0x77, 0x2d, 0x90, 0x0f, 0x90, 0x2e, 0xda,
-	0x45, 0xd1, 0xcf, 0x90, 0x65, 0x80, 0xa2, 0x40, 0xba, 0x61, 0x5a, 0xa7, 0x0f, 0x80, 0xbb, 0xee,
-	0xbb, 0x28, 0xee, 0xb9, 0x33, 0x9c, 0x3b, 0x7c, 0x88, 0x94, 0x63, 0x25, 0x9b, 0xee, 0x74, 0x7f,
-	0xf7, 0xbc, 0xe7, 0xdc, 0x73, 0xcf, 0xb9, 0x14, 0xcc, 0xd7, 0x8f, 0xab, 0xeb, 0x6a, 0x5d, 0x5f,
-	0x77, 0x1a, 0x65, 0x43, 0x77, 0xb3, 0x75, 0xdb, 0x72, 0x2d, 0x12, 0x55, 0xeb, 0x7a, 0xea, 0x52,
-	0xd5, 0xb2, 0xaa, 0x35, 0xba, 0x8e, 0x50, 0xb9, 0x71, 0xb0, 0x4e, 0x8d, 0xba, 0x7b, 0xca, 0x29,
-	0x52, 0x99, 0xce, 0x4d, 0x57, 0x37, 0xa8, 0xe3, 0xaa, 0x46, 0xdd, 0x23, 0x50, 0x8e, 0x6f, 0x38,
-	0x59, 0xdd, 0x42, 0xd9, 0x15, 0xcb, 0xa6, 0xeb, 0x27, 0xd7, 0xd7, 0xab, 0xd4, 0xa4, 0xb6, 0xea,
-	0x52, 0xcd, 0xa3, 0x59, 0x15, 0x68, 0x4c, 0xea, 0x3e, 0xb1, 0xec, 0x63, 0xdd, 0xac, 0xf6, 0xa2,
-	0xbc, 0xec, 0xa9, 0x63, 0x94, 0xaa, 0x69, 0x5a, 0xae, 0xea, 0xea, 0x96, 0xe9, 0x78, 0xbb, 0xaf,
-	0x56, 0x75, 0xf7, 0xb0, 0x51, 0xce, 0x56, 0x2c, 0x63, 0xbd, 0x6a, 0x55, 0xad, 0xc0, 0x2a, 0xb6,
-	0xc2, 0x05, 0xfe, 0xe5, 0x91, 0xb7, 0x7d, 0x3e, 0xa4, 0x6a, 0xcd, 0x3d, 0xe4, 0xa8, 0xd2, 0x8a,
-	0xc3, 0xfc, 0x7d, 0xab, 0xbc, 0x87, 0x71, 0x28, 0xd2, 0x0f, 0x1a, 0xd4, 0x71, 0x77, 0x5c, 0x6a,
-	0x90, 0x0d, 0x98, 0xa8, 0xdb, 0xba, 0x65, 0xeb, 0xee, 0xa9, 0x2c, 0xad, 0x48, 0xab, 0x52, 0x6e,
-	0xb1, 0xd5, 0xcc, 0x10, 0x1f, 0x7b, 0xc5, 0x32, 0x74, 0x17, 0x43, 0x53, 0x6c, 0xd3, 0x91, 0x37,
-	0x20, 0x6e, 0xaa, 0x06, 0x75, 0xea, 0x6a, 0x85, 0xca, 0xd1, 0x15, 0x69, 0x35, 0x9e, 0x5b, 0x6a,
-	0x35, 0x33, 0x73, 0x6d, 0x50, 0xe0, 0x0a, 0x28, 0xc9, 0xeb, 0x10, 0xaf, 0xd4, 0x74, 0x6a, 0xba,
-	0x25, 0x5d, 0x93, 0x27, 0x90, 0x0d, 0x75, 0x71, 0x70, 0x47, 0x13, 0x75, 0xf9, 0x18, 0xd9, 0x83,
-	0x58, 0x4d, 0x2d, 0xd3, 0x9a, 0x23, 0x8f, 0xae, 0x44, 0x57, 0x13, 0x1b, 0x2f, 0x67, 0xd5, 0xba,
-	0x9e, 0xed, 0xe5, 0x4a, 0xf6, 0x01, 0xd2, 0xe5, 0x4d, 0xd7, 0x3e, 0xcd, 0xcd, 0xb7, 0x9a, 0x99,
-	0x24, 0x67, 0x14, 0xc4, 0x7a, 0xa2, 0x48, 0x15, 0x12, 0x42, 0x9c, 0xe5, 0x31, 0x94, 0xbc, 0xd6,
-	0x5f, 0xf2, 0x66, 0x40, 0xcc, 0xc5, 0x2f, 0xb7, 0x9a, 0x99, 0x05, 0x41, 0x84, 0xa0, 0x43, 0x94,
-	0x4c, 0x7e, 0x21, 0xc1, 0xbc, 0x4d, 0x3f, 0x68, 0xe8, 0x36, 0xd5, 0x4a, 0xa6, 0xa5, 0xd1, 0x92,
-	0xe7, 0x4c, 0x0c, 0x55, 0x5e, 0xef, 0xaf, 0xb2, 0xe8, 0x71, 0x15, 0x2c, 0x8d, 0x8a, 0x8e, 0x29,
-	0xad, 0x66, 0xe6, 0xb2, 0xdd, 0xb5, 0x19, 0x18, 0x20, 0x4b, 0x45, 0xd2, 0xbd, 0x4f, 0x1e, 0xc1,
-	0x44, 0xdd, 0xd2, 0x4a, 0x4e, 0x9d, 0x56, 0xe4, 0xc8, 0x8a, 0xb4, 0x9a, 0xd8, 0xb8, 0x94, 0xe5,
-	0x09, 0x8a, 0x36, 0xb0, 0x24, 0xce, 0x9e, 0x5c, 0xcf, 0xee, 0x5a, 0xda, 0x5e, 0x9d, 0x56, 0xf0,
-	0x7b, 0xce, 0xd6, 0xf9, 0x22, 0x24, 0x7b, 0xdc, 0x03, 0xc9, 0x2e, 0xc4, 0x7d, 0x81, 0x8e, 0x3c,
-	0x8e, 0xee, 0x9c, 0x29, 0x91, 0xa7, 0x15, 0x5f, 0x38, 0xa1, 0xb4, 0xf2, 0x30, 0xb2, 0x05, 0xe3,
-	0xba, 0x59, 0xb5, 0xa9, 0xe3, 0xc8, 0x71, 0x94, 0x47, 0x50, 0xd0, 0x0e, 0xc7, 0xb6, 0x2c, 0xf3,
-	0x40, 0xaf, 0xe6, 0x16, 0x98, 0x61, 0x1e, 0x99, 0x20, 0xc5, 0xe7, 0x24, 0x77, 0x60, 0xc2, 0xa1,
-	0xf6, 0x89, 0x5e, 0xa1, 0x8e, 0x0c, 0x82, 0x94, 0x3d, 0x0e, 0x7a, 0x52, 0xd0, 0x18, 0x9f, 0x4e,
-	0x34, 0xc6, 0xc7, 0x58, 0x8e, 0x3b, 0x95, 0x43, 0xaa, 0x35, 0x6a, 0xd4, 0x96, 0x13, 0x41, 0x8e,
-	0xb7, 0x41, 0x31, 0xc7, 0xdb, 0x20, 0xd9, 0x81, 0xd9, 0x0f, 0x1a, 0xb4, 0x41, 0x4b, 0xae, 0x5b,
-	0x2b, 0x39, 0xb4, 0x62, 0x99, 0x9a, 0x23, 0x4f, 0xae, 0x48, 0xab, 0xd1, 0xdc, 0x0b, 0xad, 0x66,
-	0x66, 0x19, 0x37, 0x1f, 0xbb, 0xb5, 0x3d, 0xbe, 0x25, 0x08, 0x99, 0xe9, 0xd8, 0x4a, 0xa9, 0x90,
-	0x10, 0x3e, 0x3c, 0x79, 0x11, 0xa2, 0xc7, 0x94, 0x9f, 0xd1, 0x78, 0x6e, 0xb6, 0xd5, 0xcc, 0x4c,
-	0x1d, 0x53, 0xf1, 0x78, 0xb2, 0x5d, 0x72, 0x0d, 0xc6, 0x4e, 0xd4, 0x5a, 0x83, 0xe2, 0x27, 0x8e,
-	0xe7, 0xe6, 0x5a, 0xcd, 0xcc, 0x0c, 0x02, 0x02, 0x21, 0xa7, 0xb8, 0x15, 0xb9, 0x21, 0xa5, 0x0e,
-	0x20, 0xd9, 0x99, 0xda, 0x17, 0xa2, 0xc7, 0x80, 0xa5, 0x3e, 0xf9, 0x7c, 0x11, 0xea, 0x94, 0x7f,
-	0x47, 0x61, 0x2a, 0x94, 0x35, 0xe4, 0x16, 0x8c, 0xba, 0xa7, 0x75, 0x8a, 0x6a, 0xa6, 0x37, 0x92,
-	0x62, 0x5e, 0x3d, 0x3e, 0xad, 0x53, 0x2c, 0x17, 0xd3, 0x8c, 0x22, 0x94, 0xeb, 0xc8, 0xc3, 0x94,
-	0xd7, 0x2d, 0xdb, 0x75, 0xe4, 0xc8, 0x4a, 0x74, 0x75, 0x8a, 0x2b, 0x47, 0x40, 0x54, 0x8e, 0x00,
-	0x79, 0x3f, 0x5c, 0x57, 0xa2, 0x98, 0x7f, 0x2f, 0x76, 0x67, 0xf1, 0xb3, 0x17, 0x94, 0x9b, 0x90,
-	0x70, 0x6b, 0x4e, 0x89, 0x9a, 0x6a, 0xb9, 0x46, 0x35, 0x79, 0x74, 0x45, 0x5a, 0x9d, 0xc8, 0xc9,
-	0xad, 0x66, 0x66, 0xde, 0x65, 0x11, 0x45, 0x54, 0xe0, 0x85, 0x00, 0xc5, 0xf2, 0x4b, 0x6d, 0xb7,
-	0xc4, 0x0a, 0xb2, 0x3c, 0x26, 0x94, 0x5f, 0x6a, 0xbb, 0x05, 0xd5, 0xa0, 0xa1, 0xf2, 0xeb, 0x61,
-	0xe4, 0x36, 0x4c, 0x35, 0x1c, 0x5a, 0xaa, 0xd4, 0x1a, 0x8e, 0x4b, 0xed, 0x9d, 0x5d, 0x39, 0x86,
-	0x1a, 0x53, 0xad, 0x66, 0x66, 0xb1, 0xe1, 0xd0, 0x2d, 0x1f, 0x17, 0x98, 0x27, 0x45, 0xfc, 0xeb,
-	0x4a, 0x31, 0xc5, 0x85, 0xa9, 0xd0, 0x11, 0x27, 0x37, 0x7a, 0x7c, 0x72, 0x8f, 0x02, 0x3f, 0x39,
-	0xe9, 0xfe, 0xe4, 0xe7, 0xfe, 0xe0, 0xca, 0x5f, 0x24, 0x48, 0x76, 0x96, 0x6f, 0xc6, 0x8f, 0x67,
-	0xd9, 0x73, 0x10, 0xf9, 0x11, 0x10, 0xf9, 0x11, 0x20, 0xff, 0x0f, 0x70, 0x64, 0x95, 0x4b, 0x0e,
-	0xc5, 0x3b, 0x31, 0x12, 0x7c, 0x94, 0x23, 0xab, 0xbc, 0x47, 0x3b, 0xee, 0x44, 0x1f, 0x23, 0x1a,
-	0xcc, 0x32, 0x2e, 0x9b, 0xeb, 0x2b, 0x31, 0x02, 0x3f, 0xd9, 0x96, 0xfb, 0xde, 0x28, 0xbc, 0xfe,
-	0x1c, 0x59, 0x65, 0x01, 0x0b, 0xd5, 0x9f, 0x8e, 0x2d, 0xe5, 0x3f, 0xdc, 0xb7, 0x2d, 0xd5, 0xac,
-	0xd0, 0x9a, 0xef, 0xdb, 0x1a, 0xc4, 0x98, 0x6a, 0x5d, 0x13, 0x9d, 0x3b, 0xb2, 0xca, 0x21, 0x4b,
-	0xc7, 0x10, 0x78, 0x46, 0xe7, 0xda, 0xd1, 0x8b, 0x0e, 0x8c, 0xde, 0xab, 0x30, 0xce, 0x8d, 0xe1,
-	0xcd, 0x41, 0x9c, 0xdf, 0xfa, 0xa8, 0x3c, 0x74, 0xeb, 0x73, 0x84, 0xbc, 0x02, 0x31, 0x9b, 0xaa,
-	0x8e, 0x65, 0x7a, 0xd9, 0x8f, 0xd4, 0x1c, 0x11, 0xa9, 0x39, 0xa2, 0xfc, 0x43, 0x82, 0xb9, 0xfb,
-	0x68, 0x54, 0x38, 0x02, 0x61, 0xaf, 0xa4, 0xf3, 0x7a, 0x15, 0x19, 0xe8, 0xd5, 0x6d, 0x88, 0x1d,
-	0xe8, 0x35, 0x97, 0xda, 0x18, 0x81, 0xc4, 0xc6, 0x6c, 0xfb, 0x93, 0x52, 0xf7, 0x0e, 0x6e, 0x70,
-	0xcb, 0x39, 0x91, 0x68, 0x39, 0x47, 0x04, 0x3f, 0x47, 0x87, 0xf0, 0xf3, 0x2d, 0x98, 0x14, 0x65,
-	0x93, 0x6f, 0x43, 0xcc, 0x71, 0x55, 0x97, 0x3a, 0xb2, 0xb4, 0x12, 0x5d, 0x9d, 0xde, 0x98, 0x6a,
-	0xab, 0x67, 0x28, 0x17, 0xc6, 0x09, 0x44, 0x61, 0x1c, 0x51, 0xbe, 0x98, 0x81, 0xe8, 0x7d, 0xab,
-	0x4c, 0x56, 0x20, 0xd2, 0x0e, 0x4e, 0xb2, 0xd5, 0xcc, 0x4c, 0xea, 0x62, 0x58, 0x22, 0xba, 0x16,
-	0x6e, 0x06, 0xa7, 0x86, 0x6c, 0x06, 0x2f, 0x3c, 0xa3, 0x42, 0x9d, 0xed, 0xf8, 0xd0, 0x9d, 0x6d,
-	0xae, 0xdd, 0xa4, 0xf2, 0xc6, 0x65, 0xde, 0x8f, 0xd9, 0x39, 0x7a, 0xd2, 0x77, 0xc2, 0x77, 0x07,
-	0x84, 0x8f, 0xf3, 0xb3, 0xdf, 0x18, 0x27, 0x7d, 0x3a, 0xd0, 0x04, 0x2a, 0x58, 0x69, 0x2b, 0x78,
-	0xde, 0x0d, 0xe7, 0x35, 0x18, 0xb3, 0x9e, 0x98, 0xd4, 0xf6, 0x3a, 0x7d, 0x8c, 0x3a, 0x02, 0x62,
-	0xd4, 0x11, 0x20, 0x14, 0x2e, 0xf1, 0xa6, 0x09, 0x97, 0xce, 0xa1, 0x5e, 0x2f, 0x35, 0x1c, 0x6a,
-	0x97, 0xaa, 0xb6, 0xd5, 0xa8, 0x3b, 0xf2, 0x0c, 0x9e, 0xed, 0xab, 0xad, 0x66, 0x46, 0x41, 0xb2,
-	0x47, 0x3e, 0xd5, 0xbe, 0x43, 0xed, 0xbb, 0x48, 0x23, 0xc8, 0x94, 0xfb, 0xd1, 0x90, 0x9f, 0x49,
-	0x70, 0xb5, 0x62, 0x19, 0x75, 0x76, 0x0f, 0x53, 0xad, 0x74, 0x96, 0xca, 0xb9, 0x15, 0x69, 0x75,
-	0x32, 0xf7, 0x5a, 0xab, 0x99, 0x79, 0x25, 0xe0, 0x78, 0x7b, 0xb0, 0x72, 0x65, 0x30, 0x75, 0x68,
-	0xe2, 0x1a, 0x1d, 0x72, 0xe2, 0x12, 0xbb, 0xf7, 0xb1, 0xe7, 0xde, 0xbd, 0x4f, 0x3e, 0x8f, 0xee,
-	0xfd, 0xd7, 0x12, 0xac, 0x78, 0x7d, 0xb0, 0x6e, 0x56, 0x4b, 0x36, 0x75, 0xac, 0x86, 0x5d, 0xa1,
-	0x25, 0x2f, 0x35, 0x0c, 0x6a, 0xba, 0x8e, 0xbc, 0x80, 0xb6, 0xaf, 0xf6, 0xd2, 0x54, 0xf4, 0x18,
-	0x8a, 0x02, 0x7d, 0xee, 0xea, 0xa7, 0xcd, 0xcc, 0x48, 0xab, 0x99, 0x49, 0x07, 0x92, 0x7b, 0xd1,
-	0x15, 0x07, 0xec, 0x93, 0x1d, 0x18, 0xaf, 0xd8, 0x94, 0x8d, 0xdc, 0xd8, 0xc0, 0x24, 0x36, 0x52,
-	0x59, 0x3e, 0x73, 0x67, 0xfd, 0x61, 0x3a, 0xfb, 0xd8, 0x1f, 0xf1, 0x73, 0x73, 0x9e, 0x52, 0x9f,
-	0xe5, 0xa3, 0x2f, 0x32, 0x52, 0xd1, 0x5f, 0x88, 0x53, 0xca, 0xf4, 0x73, 0x99, 0x52, 0x92, 0x5f,
-	0x61, 0x4a, 0xf9, 0x3e, 0x24, 0x8e, 0x6f, 0x38, 0x25, 0xdf, 0xa0, 0x59, 0x14, 0x75, 0x45, 0x0c,
-	0x6f, 0xf0, 0xf2, 0xc0, 0x82, 0xec, 0x59, 0xc9, 0x3b, 0xc6, 0xe3, 0x1b, 0xce, 0x4e, 0x97, 0x89,
-	0x10, 0xa0, 0xac, 0x24, 0x31, 0xe9, 0x9e, 0x36, 0x99, 0xf4, 0x4f, 0x13, 0xcf, 0xee, 0xb6, 0x5c,
-	0x6f, 0xdd, 0x21, 0xd7, 0x43, 0xc3, 0xb3, 0xd5, 0xfc, 0x57, 0x9b, 0xad, 0x16, 0xff, 0x37, 0x5b,
-	0x7d, 0xad, 0xb3, 0xd5, 0x3f, 0x25, 0x58, 0xbc, 0xcf, 0x3a, 0x45, 0xaf, 0x36, 0xe9, 0x3f, 0xa2,
-	0x7e, 0x67, 0x24, 0xb4, 0x63, 0xd2, 0x10, 0xed, 0xd8, 0x85, 0x5f, 0xe6, 0x6f, 0xc2, 0xa4, 0x49,
-	0x9f, 0x94, 0x3a, 0x8a, 0x2d, 0xde, 0x9b, 0x26, 0x7d, 0xb2, 0xdb, 0x5d, 0x6f, 0x13, 0x02, 0xac,
-	0xfc, 0x36, 0x02, 0x4b, 0x5d, 0x8e, 0x3a, 0x75, 0xcb, 0x74, 0x28, 0xf9, 0x8d, 0x04, 0xb2, 0x1d,
-	0x6c, 0xe0, 0x27, 0x66, 0x15, 0xaf, 0x51, 0x73, 0xb9, 0xef, 0x89, 0x8d, 0x9b, 0xfe, 0xc5, 0xda,
-	0x4b, 0x40, 0xb6, 0xd8, 0xc1, 0x5c, 0xe4, 0xbc, 0xfc, 0xc6, 0x7d, 0xb9, 0xd5, 0xcc, 0x5c, 0xb1,
-	0x7b, 0x53, 0x08, 0xd6, 0x2e, 0xf5, 0x21, 0x49, 0xd9, 0x70, 0xf9, 0x2c, 0xf9, 0x17, 0x92, 0x16,
-	0x26, 0x2c, 0x08, 0x43, 0x07, 0xf7, 0x12, 0xdf, 0x17, 0xcf, 0x33, 0x30, 0x5c, 0x83, 0x31, 0x6a,
-	0xdb, 0x96, 0x2d, 0xea, 0x44, 0x40, 0x24, 0x45, 0x40, 0xf9, 0x10, 0x66, 0xbb, 0xf4, 0x91, 0x43,
-	0x20, 0x7c, 0x2e, 0xe2, 0x6b, 0x6f, 0x30, 0xe2, 0xdf, 0x23, 0xd5, 0x39, 0x18, 0x05, 0x36, 0xe6,
-	0xd2, 0xad, 0x66, 0x26, 0x85, 0xe3, 0x4f, 0x00, 0x8a, 0x91, 0x4e, 0x76, 0xee, 0x29, 0x7f, 0x9e,
-	0x80, 0x31, 0xbc, 0xe0, 0xc9, 0x55, 0x18, 0xc5, 0x81, 0x9a, 0x7b, 0x87, 0x43, 0xa5, 0x19, 0x1e,
-	0xa6, 0x71, 0x9f, 0xe4, 0x61, 0xc6, 0x4f, 0xc4, 0xd2, 0x81, 0x5a, 0x71, 0x3d, 0x2f, 0xa5, 0xdc,
-	0xe5, 0x56, 0x33, 0x23, 0xfb, 0x5b, 0x77, 0x70, 0x47, 0x60, 0x9e, 0x0e, 0xef, 0xb0, 0xf9, 0x1f,
-	0xfb, 0x14, 0xde, 0xb6, 0xe0, 0xd0, 0x17, 0xe7, 0x55, 0x97, 0xc1, 0xbc, 0xdd, 0x10, 0xab, 0x6e,
-	0x80, 0xb2, 0xe3, 0x80, 0xdd, 0x8d, 0xcf, 0xcb, 0x47, 0x26, 0x3c, 0x0e, 0x88, 0x77, 0x31, 0x27,
-	0x04, 0x98, 0x54, 0x61, 0xa6, 0x7d, 0xa5, 0xd7, 0x74, 0x43, 0x77, 0xfd, 0x67, 0xd3, 0x34, 0x06,
-	0x16, 0x83, 0xd1, 0xbe, 0xc3, 0x1f, 0x20, 0x01, 0xcf, 0x66, 0x16, 0x5c, 0xd9, 0x0e, 0x6d, 0x84,
-	0x5a, 0x92, 0xe9, 0xf0, 0x1e, 0xf9, 0x9d, 0x04, 0x57, 0x3b, 0x34, 0x95, 0xca, 0xa7, 0xed, 0x53,
-	0x5c, 0xaa, 0xd4, 0x54, 0xc7, 0xe1, 0x8f, 0x18, 0xe3, 0xc2, 0x23, 0x6a, 0x2f, 0x03, 0x72, 0xa7,
-	0xfe, 0x69, 0xde, 0x62, 0x4c, 0x05, 0xd5, 0xa0, 0xdc, 0xa6, 0x6b, 0xde, 0x0d, 0x7f, 0xc5, 0x1e,
-	0x44, 0x5f, 0x1c, 0x4c, 0x42, 0xf6, 0x20, 0x51, 0xa7, 0xb6, 0xa1, 0x3b, 0x0e, 0x76, 0xee, 0xfc,
-	0x69, 0x77, 0x51, 0xb0, 0x6a, 0x37, 0xd8, 0xe5, 0xf1, 0x16, 0xc8, 0xc5, 0x78, 0x0b, 0x70, 0xea,
-	0x5f, 0x12, 0x24, 0x04, 0x3e, 0x52, 0x84, 0x09, 0xa7, 0x51, 0x3e, 0xa2, 0x95, 0x76, 0x85, 0x49,
-	0xf7, 0xd6, 0x90, 0xdd, 0xe3, 0x64, 0x5e, 0xf7, 0xe0, 0xf1, 0x84, 0xba, 0x07, 0x0f, 0xc3, 0x33,
-	0x4e, 0xed, 0x32, 0x7f, 0xe8, 0xf0, 0xcf, 0x38, 0x03, 0x42, 0x67, 0x9c, 0x01, 0xa9, 0xf7, 0x60,
-	0xdc, 0x93, 0xcb, 0x32, 0xfe, 0x58, 0x37, 0x35, 0x31, 0xe3, 0xd9, 0x5a, 0xcc, 0x78, 0xb6, 0x6e,
-	0x9f, 0x8c, 0xc8, 0xd9, 0x27, 0x23, 0xa5, 0xc3, 0x5c, 0x8f, 0xbc, 0x79, 0x86, 0x2a, 0x25, 0x0d,
-	0xbc, 0x2b, 0x3f, 0x96, 0xe0, 0xea, 0x70, 0x29, 0x32, 0x9c, 0xfa, 0xb7, 0x44, 0xf5, 0xfe, 0x30,
-	0x15, 0x12, 0xd8, 0xa1, 0x6d, 0x50, 0x19, 0xfd, 0xf9, 0x18, 0x5c, 0x3a, 0x83, 0x9f, 0x35, 0xd9,
-	0xcb, 0x86, 0xfa, 0x43, 0xdd, 0x68, 0x18, 0x41, 0x87, 0x7d, 0x60, 0xab, 0x15, 0x56, 0xe4, 0xbd,
-	0xbc, 0xf8, 0xce, 0x20, 0x2b, 0xb2, 0x0f, 0xb9, 0x04, 0x1f, 0xbd, 0xe3, 0xf1, 0xf3, 0xb3, 0x91,
-	0xf1, 0xce, 0xc6, 0x92, 0xd1, 0x9b, 0xaa, 0xd8, 0x6f, 0x83, 0xfc, 0x41, 0x82, 0x2b, 0x7d, 0x8d,
-	0xc3, 0x33, 0x6c, 0x59, 0x35, 0xcc, 0xb5, 0xc4, 0xc6, 0xd6, 0xb3, 0x1a, 0x99, 0x3b, 0xdd, 0xb5,
-	0xac, 0x9a, 0x77, 0x51, 0x7a, 0xa6, 0xbe, 0x60, 0x9c, 0x45, 0x5b, 0x3c, 0x7b, 0x9b, 0x5d, 0x97,
-	0x67, 0x05, 0xe4, 0xa2, 0x12, 0x51, 0x19, 0xec, 0xe0, 0x70, 0xaa, 0x1f, 0x85, 0x93, 0xf0, 0xa5,
-	0xee, 0xc8, 0x62, 0x14, 0xce, 0x97, 0x88, 0x7f, 0x8c, 0x40, 0x66, 0x80, 0x0c, 0xf2, 0xf1, 0x10,
-	0xc9, 0xb8, 0x39, 0x8c, 0x35, 0x17, 0x94, 0x90, 0xdf, 0xc4, 0x97, 0x55, 0xf2, 0x10, 0xc7, 0x92,
-	0xfc, 0x40, 0x77, 0x5c, 0x72, 0x03, 0x62, 0xd8, 0x8a, 0xfa, 0x25, 0x1b, 0x82, 0x92, 0xcd, 0x9b,
-	0x63, 0xbe, 0x2b, 0x36, 0xc7, 0x1c, 0x51, 0xf6, 0x81, 0xf0, 0x67, 0xc7, 0x9a, 0xd0, 0xbf, 0x91,
-	0xdb, 0x30, 0x55, 0xe1, 0x28, 0xd5, 0x84, 0x3e, 0x1b, 0x5f, 0xe3, 0xdb, 0x1b, 0xe1, 0x6e, 0x7b,
-	0x52, 0xc4, 0x95, 0x9b, 0x30, 0x83, 0xda, 0xef, 0xd2, 0xf6, 0x6b, 0xf5, 0x90, 0x0d, 0x8c, 0x72,
-	0x1b, 0xe4, 0x3d, 0xd7, 0xa6, 0xaa, 0xa1, 0x9b, 0xd5, 0x4e, 0x19, 0x2f, 0x42, 0xd4, 0x6c, 0x18,
-	0x28, 0x62, 0x8a, 0x07, 0xd2, 0x6c, 0x18, 0x62, 0x20, 0xcd, 0x86, 0xa1, 0xbc, 0x09, 0x04, 0xf9,
-	0xb6, 0x69, 0x8d, 0xba, 0xf4, 0xbc, 0xea, 0x3f, 0x91, 0x00, 0xf8, 0x3b, 0xe5, 0x8e, 0x79, 0x60,
-	0x0d, 0xdd, 0x76, 0xdd, 0x84, 0x04, 0x46, 0x54, 0x2b, 0x1d, 0x59, 0x78, 0xd1, 0x49, 0xab, 0x63,
-	0xbc, 0x5f, 0xe2, 0xf0, 0x7d, 0x2b, 0x74, 0xdb, 0x41, 0x80, 0x32, 0xd6, 0x1a, 0x55, 0x1d, 0x9f,
-	0x35, 0x1a, 0xb0, 0x72, 0xb8, 0x93, 0x35, 0x40, 0x95, 0x27, 0x30, 0x87, 0xae, 0xee, 0xd7, 0x35,
-	0xd5, 0x0d, 0xc6, 0x86, 0x37, 0xc4, 0x1f, 0x06, 0xc2, 0xd9, 0x70, 0xd6, 0x1c, 0x73, 0x8e, 0xb6,
-	0xb8, 0x01, 0x72, 0x4e, 0x75, 0x2b, 0x87, 0xbd, 0xb4, 0xbf, 0x07, 0x53, 0x07, 0xaa, 0x5e, 0xf3,
-	0x5f, 0xbe, 0xfc, 0x9c, 0x94, 0x03, 0x2b, 0xc2, 0x0c, 0x3c, 0xad, 0x38, 0xcb, 0xdb, 0x9d, 0x79,
-	0x3a, 0x29, 0xe2, 0x6d, 0x7f, 0xb7, 0xf0, 0x8d, 0xe4, 0x9b, 0xf2, 0xb7, 0x43, 0xfb, 0x60, 0x7f,
-	0xc3, 0x0c, 0xe7, 0xf0, 0x37, 0x01, 0xf1, 0xbc, 0xa9, 0x3d, 0x54, 0xed, 0x63, 0x6a, 0x2b, 0x1f,
-	0x49, 0xb0, 0x10, 0x3e, 0x19, 0x0f, 0xa9, 0xe3, 0xa8, 0x55, 0x4a, 0xbe, 0x75, 0x3e, 0xff, 0xef,
-	0x8d, 0x04, 0xcf, 0xd0, 0x51, 0x6a, 0x6a, 0x5e, 0x41, 0x9f, 0x46, 0xb6, 0xb6, 0x3e, 0x7e, 0xbe,
-	0xa8, 0xd8, 0x70, 0xdd, 0x1b, 0x29, 0x32, 0xfa, 0xdc, 0x38, 0x8c, 0xd1, 0x13, 0x6a, 0xba, 0x6b,
-	0x29, 0x48, 0x08, 0xbf, 0x6e, 0x92, 0x04, 0x8c, 0x7b, 0xcb, 0xe4, 0xc8, 0xda, 0x35, 0x48, 0x08,
-	0x3f, 0x83, 0x91, 0x49, 0x98, 0x28, 0x58, 0x1a, 0xdd, 0xb5, 0x6c, 0x37, 0x39, 0xc2, 0x56, 0xf7,
-	0xa8, 0xaa, 0xd5, 0x18, 0xa9, 0xb4, 0xf6, 0x4b, 0x09, 0x26, 0xfc, 0x87, 0x7f, 0x02, 0x10, 0x7b,
-	0x7b, 0x3f, 0xbf, 0x9f, 0xdf, 0x4e, 0x8e, 0x30, 0x81, 0xbb, 0xf9, 0xc2, 0xf6, 0x4e, 0xe1, 0x6e,
-	0x52, 0x62, 0x8b, 0xe2, 0x7e, 0xa1, 0xc0, 0x16, 0x11, 0x32, 0x05, 0xf1, 0xbd, 0xfd, 0xad, 0xad,
-	0x7c, 0x7e, 0x3b, 0xbf, 0x9d, 0x8c, 0x32, 0xa6, 0x3b, 0x9b, 0x3b, 0x0f, 0xf2, 0xdb, 0xc9, 0x51,
-	0x46, 0xb7, 0x5f, 0x78, 0xab, 0xf0, 0xe8, 0xdd, 0x42, 0x72, 0x8c, 0xd3, 0xe5, 0x1e, 0xee, 0x3c,
-	0x7e, 0x9c, 0xdf, 0x4e, 0xc6, 0x18, 0xdd, 0x83, 0xfc, 0xe6, 0x5e, 0x7e, 0x3b, 0x39, 0xce, 0xb6,
-	0x76, 0x8b, 0xf9, 0xfc, 0xc3, 0x5d, 0xb6, 0x35, 0xc1, 0x96, 0x5b, 0x9b, 0x85, 0xad, 0xfc, 0x03,
-	0x26, 0x25, 0xbe, 0xf1, 0xfb, 0x09, 0x88, 0xf1, 0x11, 0x8e, 0xbc, 0x03, 0xc0, 0xff, 0xc2, 0xe3,
-	0xba, 0xd0, 0xf3, 0x97, 0xaf, 0xd4, 0x62, 0xef, 0xb9, 0x4f, 0x59, 0xfe, 0xe9, 0x9f, 0xfe, 0xfe,
-	0xab, 0xc8, 0x9c, 0x32, 0xbd, 0x7e, 0x72, 0x7d, 0xfd, 0xc8, 0x2a, 0x7b, 0xff, 0x22, 0x74, 0x4b,
-	0x5a, 0x23, 0xef, 0x02, 0xf0, 0xda, 0x1b, 0x96, 0x1b, 0xfa, 0x19, 0x28, 0xb5, 0x84, 0x70, 0x77,
-	0x8d, 0xee, 0x16, 0xcc, 0x0b, 0x30, 0x13, 0xfc, 0x03, 0x98, 0x6c, 0x0b, 0xde, 0xa3, 0x2e, 0x91,
-	0x85, 0x5f, 0x76, 0xc2, 0xd2, 0x17, 0xbb, 0x9e, 0x27, 0xf3, 0xec, 0x43, 0x2b, 0x97, 0x51, 0xf8,
-	0xa2, 0x32, 0xeb, 0x09, 0x77, 0xa8, 0x2b, 0xc8, 0x37, 0x21, 0x29, 0xbe, 0x36, 0xa0, 0xf9, 0x97,
-	0x7a, 0xbf, 0x43, 0x70, 0x35, 0x97, 0xcf, 0x7a, 0xa4, 0x50, 0x32, 0xa8, 0x6c, 0x59, 0x99, 0xf7,
-	0x3d, 0x11, 0x1e, 0x1c, 0x28, 0xd3, 0x77, 0x17, 0x12, 0xfc, 0x08, 0xf1, 0x51, 0x58, 0xc8, 0xef,
-	0xbe, 0x0e, 0xcc, 0xa3, 0xcc, 0x69, 0x25, 0xce, 0x64, 0x62, 0xb2, 0x33, 0x41, 0x15, 0x98, 0x14,
-	0x04, 0x39, 0x64, 0x3a, 0x90, 0xc4, 0xee, 0xd1, 0xd4, 0x0b, 0xb8, 0xee, 0x77, 0xd2, 0x95, 0x97,
-	0x50, 0x68, 0x5a, 0x59, 0x66, 0x42, 0xcb, 0x8c, 0x8a, 0x6a, 0xeb, 0xfc, 0xbd, 0xd6, 0x3b, 0xfb,
-	0x4c, 0x49, 0x01, 0x12, 0xbc, 0xc0, 0x0d, 0x6f, 0xed, 0x25, 0x14, 0xbc, 0x90, 0x4a, 0xb6, 0xad,
-	0x5d, 0xff, 0x31, 0xbb, 0x56, 0x3e, 0xf4, 0x8c, 0x16, 0xe4, 0x0d, 0x36, 0x3a, 0x5c, 0x5d, 0x7d,
-	0xa3, 0x53, 0x21, 0xa3, 0x1b, 0x48, 0x23, 0x18, 0xfd, 0x5d, 0x48, 0xf0, 0xfb, 0x92, 0x1b, 0xbd,
-	0x14, 0xe8, 0x08, 0x5d, 0xa3, 0x7d, 0x3d, 0x90, 0x51, 0x0b, 0x59, 0xeb, 0xf2, 0x80, 0xdc, 0x81,
-	0x89, 0xbb, 0xd4, 0xe5, 0x62, 0xe7, 0x03, 0xb1, 0xc1, 0xad, 0x9e, 0x12, 0x22, 0xe4, 0xcb, 0x21,
-	0xdd, 0x72, 0x34, 0x88, 0xfb, 0x72, 0x1c, 0xc2, 0x7d, 0xee, 0xd7, 0x27, 0xa4, 0x52, 0x3d, 0xb6,
-	0xbd, 0x62, 0xa9, 0xa4, 0x50, 0xc3, 0x3c, 0x21, 0x62, 0x3c, 0x78, 0x20, 0x5e, 0x93, 0xc8, 0x2d,
-	0x88, 0xdd, 0xc3, 0xff, 0x67, 0x23, 0x7d, 0x3c, 0x4d, 0xf1, 0xc3, 0xc4, 0x89, 0xb6, 0x0e, 0x69,
-	0xe5, 0xb8, 0x5d, 0xd7, 0xdf, 0xff, 0xfc, 0x6f, 0xe9, 0x91, 0x9f, 0x3c, 0x4d, 0x4b, 0x9f, 0x3e,
-	0x4d, 0x4b, 0x9f, 0x3d, 0x4d, 0x4b, 0x7f, 0x7d, 0x9a, 0x96, 0x3e, 0xfa, 0x32, 0x3d, 0xf2, 0xd9,
-	0x97, 0xe9, 0x91, 0xcf, 0xbf, 0x4c, 0x8f, 0x7c, 0xef, 0xff, 0x84, 0x7f, 0xb1, 0x53, 0x6d, 0x43,
-	0xd5, 0xd4, 0xba, 0x6d, 0xb1, 0x61, 0xd7, 0x5b, 0xad, 0x7b, 0xff, 0x53, 0xf7, 0x49, 0x64, 0x7e,
-	0x13, 0x81, 0x5d, 0xbe, 0x9d, 0xdd, 0xb1, 0xb2, 0x9b, 0x75, 0xbd, 0x1c, 0x43, 0x5b, 0x5e, 0xff,
-	0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe2, 0xc5, 0xd2, 0xf1, 0x70, 0x28, 0x00, 0x00,
+	// 2927 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x6f, 0x1b, 0xd7,
+	0xd5, 0xd7, 0x88, 0x12, 0x25, 0x9e, 0xd1, 0x83, 0xba, 0x7a, 0x8d, 0x68, 0x87, 0x94, 0x27, 0x89,
+	0x3f, 0x59, 0x48, 0xa8, 0x58, 0xf9, 0x82, 0xcf, 0xf6, 0x97, 0xc2, 0x10, 0x25, 0xda, 0xa6, 0x63,
+	0xd3, 0x0a, 0x65, 0x25, 0x4d, 0x51, 0x94, 0x19, 0x72, 0xae, 0xa8, 0x91, 0xc8, 0x19, 0x66, 0x66,
+	0x28, 0x57, 0x2d, 0x02, 0x14, 0x45, 0xd1, 0x2e, 0xba, 0x49, 0xd1, 0x5d, 0x0b, 0x64, 0xd3, 0x5d,
+	0xba, 0xe8, 0xa6, 0xe8, 0xdf, 0x90, 0x65, 0x80, 0xa2, 0x40, 0xba, 0x61, 0x5a, 0xa7, 0x0f, 0x80,
+	0xbb, 0xee, 0xbb, 0x28, 0xee, 0xb9, 0x33, 0x9c, 0x3b, 0x7c, 0x88, 0x94, 0x63, 0x25, 0x9b, 0xee,
+	0x74, 0xcf, 0x3d, 0xe7, 0x77, 0x1e, 0x73, 0xee, 0xb9, 0xe7, 0x5c, 0x0a, 0x16, 0xea, 0xc7, 0x95,
+	0x0d, 0xad, 0x6e, 0x6c, 0x38, 0x8d, 0x52, 0xcd, 0x70, 0xd3, 0x75, 0xdb, 0x72, 0x2d, 0x12, 0xd1,
+	0xea, 0x46, 0xe2, 0x52, 0xc5, 0xb2, 0x2a, 0x55, 0xba, 0x81, 0xa4, 0x52, 0xe3, 0x60, 0x83, 0xd6,
+	0xea, 0xee, 0x29, 0xe7, 0x48, 0xa4, 0x3a, 0x37, 0x5d, 0xa3, 0x46, 0x1d, 0x57, 0xab, 0xd5, 0x3d,
+	0x06, 0xf5, 0xf8, 0x86, 0x93, 0x36, 0x2c, 0xc4, 0x2e, 0x5b, 0x36, 0xdd, 0x38, 0xb9, 0xbe, 0x51,
+	0xa1, 0x26, 0xb5, 0x35, 0x97, 0xea, 0x1e, 0xcf, 0x9a, 0xc0, 0x63, 0x52, 0xf7, 0x89, 0x65, 0x1f,
+	0x1b, 0x66, 0xa5, 0x17, 0xe7, 0x65, 0x4f, 0x1d, 0xe3, 0xd4, 0x4c, 0xd3, 0x72, 0x35, 0xd7, 0xb0,
+	0x4c, 0xc7, 0xdb, 0x7d, 0xb5, 0x62, 0xb8, 0x87, 0x8d, 0x52, 0xba, 0x6c, 0xd5, 0x36, 0x2a, 0x56,
+	0xc5, 0x0a, 0xac, 0x62, 0x2b, 0x5c, 0xe0, 0x5f, 0x1e, 0x7b, 0xdb, 0xe7, 0x43, 0xaa, 0x55, 0xdd,
+	0x43, 0x4e, 0x55, 0x5b, 0x31, 0x58, 0xb8, 0x6f, 0x95, 0xf6, 0x30, 0x0e, 0x05, 0xfa, 0x41, 0x83,
+	0x3a, 0x6e, 0xce, 0xa5, 0x35, 0xb2, 0x09, 0x93, 0x75, 0xdb, 0xb0, 0x6c, 0xc3, 0x3d, 0x55, 0xa4,
+	0x55, 0x69, 0x4d, 0xca, 0x2c, 0xb5, 0x9a, 0x29, 0xe2, 0xd3, 0x5e, 0xb1, 0x6a, 0x86, 0x8b, 0xa1,
+	0x29, 0xb4, 0xf9, 0xc8, 0x1b, 0x10, 0x33, 0xb5, 0x1a, 0x75, 0xea, 0x5a, 0x99, 0x2a, 0x91, 0x55,
+	0x69, 0x2d, 0x96, 0x59, 0x6e, 0x35, 0x53, 0xf3, 0x6d, 0xa2, 0x20, 0x15, 0x70, 0x92, 0xd7, 0x21,
+	0x56, 0xae, 0x1a, 0xd4, 0x74, 0x8b, 0x86, 0xae, 0x4c, 0xa2, 0x18, 0xea, 0xe2, 0xc4, 0x9c, 0x2e,
+	0xea, 0xf2, 0x69, 0x64, 0x0f, 0xa2, 0x55, 0xad, 0x44, 0xab, 0x8e, 0x32, 0xb6, 0x1a, 0x59, 0x93,
+	0x37, 0x5f, 0x4e, 0x6b, 0x75, 0x23, 0xdd, 0xcb, 0x95, 0xf4, 0x03, 0xe4, 0xcb, 0x9a, 0xae, 0x7d,
+	0x9a, 0x59, 0x68, 0x35, 0x53, 0x71, 0x2e, 0x28, 0xc0, 0x7a, 0x50, 0xa4, 0x02, 0xb2, 0x10, 0x67,
+	0x65, 0x1c, 0x91, 0xd7, 0xfb, 0x23, 0x6f, 0x05, 0xcc, 0x1c, 0x7e, 0xa5, 0xd5, 0x4c, 0x2d, 0x0a,
+	0x10, 0x82, 0x0e, 0x11, 0x99, 0xfc, 0x4c, 0x82, 0x05, 0x9b, 0x7e, 0xd0, 0x30, 0x6c, 0xaa, 0x17,
+	0x4d, 0x4b, 0xa7, 0x45, 0xcf, 0x99, 0x28, 0xaa, 0xbc, 0xde, 0x5f, 0x65, 0xc1, 0x93, 0xca, 0x5b,
+	0x3a, 0x15, 0x1d, 0x53, 0x5b, 0xcd, 0xd4, 0x65, 0xbb, 0x6b, 0x33, 0x30, 0x40, 0x91, 0x0a, 0xa4,
+	0x7b, 0x9f, 0x3c, 0x82, 0xc9, 0xba, 0xa5, 0x17, 0x9d, 0x3a, 0x2d, 0x2b, 0xa3, 0xab, 0xd2, 0x9a,
+	0xbc, 0x79, 0x29, 0xcd, 0x13, 0x14, 0x6d, 0x60, 0x49, 0x9c, 0x3e, 0xb9, 0x9e, 0xde, 0xb5, 0xf4,
+	0xbd, 0x3a, 0x2d, 0xe3, 0xf7, 0x9c, 0xab, 0xf3, 0x45, 0x08, 0x7b, 0xc2, 0x23, 0x92, 0x5d, 0x88,
+	0xf9, 0x80, 0x8e, 0x32, 0x81, 0xee, 0x9c, 0x89, 0xc8, 0xd3, 0x8a, 0x2f, 0x9c, 0x50, 0x5a, 0x79,
+	0x34, 0xb2, 0x0d, 0x13, 0x86, 0x59, 0xb1, 0xa9, 0xe3, 0x28, 0x31, 0xc4, 0x23, 0x08, 0x94, 0xe3,
+	0xb4, 0x6d, 0xcb, 0x3c, 0x30, 0x2a, 0x99, 0x45, 0x66, 0x98, 0xc7, 0x26, 0xa0, 0xf8, 0x92, 0xe4,
+	0x0e, 0x4c, 0x3a, 0xd4, 0x3e, 0x31, 0xca, 0xd4, 0x51, 0x40, 0x40, 0xd9, 0xe3, 0x44, 0x0f, 0x05,
+	0x8d, 0xf1, 0xf9, 0x44, 0x63, 0x7c, 0x1a, 0xcb, 0x71, 0xa7, 0x7c, 0x48, 0xf5, 0x46, 0x95, 0xda,
+	0x8a, 0x1c, 0xe4, 0x78, 0x9b, 0x28, 0xe6, 0x78, 0x9b, 0x48, 0x72, 0x30, 0xf7, 0x41, 0x83, 0x36,
+	0x68, 0xd1, 0x75, 0xab, 0x45, 0x87, 0x96, 0x2d, 0x53, 0x77, 0x94, 0xa9, 0x55, 0x69, 0x2d, 0x92,
+	0x79, 0xa1, 0xd5, 0x4c, 0xad, 0xe0, 0xe6, 0x63, 0xb7, 0xba, 0xc7, 0xb7, 0x04, 0x90, 0xd9, 0x8e,
+	0xad, 0x84, 0x06, 0xb2, 0xf0, 0xe1, 0xc9, 0x8b, 0x10, 0x39, 0xa6, 0xfc, 0x8c, 0xc6, 0x32, 0x73,
+	0xad, 0x66, 0x6a, 0xfa, 0x98, 0x8a, 0xc7, 0x93, 0xed, 0x92, 0x6b, 0x30, 0x7e, 0xa2, 0x55, 0x1b,
+	0x14, 0x3f, 0x71, 0x2c, 0x33, 0xdf, 0x6a, 0xa6, 0x66, 0x91, 0x20, 0x30, 0x72, 0x8e, 0x5b, 0xa3,
+	0x37, 0xa4, 0xc4, 0x01, 0xc4, 0x3b, 0x53, 0xfb, 0x42, 0xf4, 0xd4, 0x60, 0xb9, 0x4f, 0x3e, 0x5f,
+	0x84, 0x3a, 0xf5, 0x5f, 0x11, 0x98, 0x0e, 0x65, 0x0d, 0xb9, 0x05, 0x63, 0xee, 0x69, 0x9d, 0xa2,
+	0x9a, 0x99, 0xcd, 0xb8, 0x98, 0x57, 0x8f, 0x4f, 0xeb, 0x14, 0xcb, 0xc5, 0x0c, 0xe3, 0x08, 0xe5,
+	0x3a, 0xca, 0x30, 0xe5, 0x75, 0xcb, 0x76, 0x1d, 0x65, 0x74, 0x35, 0xb2, 0x36, 0xcd, 0x95, 0x23,
+	0x41, 0x54, 0x8e, 0x04, 0xf2, 0x7e, 0xb8, 0xae, 0x44, 0x30, 0xff, 0x5e, 0xec, 0xce, 0xe2, 0x67,
+	0x2f, 0x28, 0x37, 0x41, 0x76, 0xab, 0x4e, 0x91, 0x9a, 0x5a, 0xa9, 0x4a, 0x75, 0x65, 0x6c, 0x55,
+	0x5a, 0x9b, 0xcc, 0x28, 0xad, 0x66, 0x6a, 0xc1, 0x65, 0x11, 0x45, 0xaa, 0x20, 0x0b, 0x01, 0x15,
+	0xcb, 0x2f, 0xb5, 0xdd, 0x22, 0x2b, 0xc8, 0xca, 0xb8, 0x50, 0x7e, 0xa9, 0xed, 0xe6, 0xb5, 0x1a,
+	0x0d, 0x95, 0x5f, 0x8f, 0x46, 0x6e, 0xc3, 0x74, 0xc3, 0xa1, 0xc5, 0x72, 0xb5, 0xe1, 0xb8, 0xd4,
+	0xce, 0xed, 0x2a, 0x51, 0xd4, 0x98, 0x68, 0x35, 0x53, 0x4b, 0x0d, 0x87, 0x6e, 0xfb, 0x74, 0x41,
+	0x78, 0x4a, 0xa4, 0x7f, 0x5d, 0x29, 0xa6, 0xba, 0x30, 0x1d, 0x3a, 0xe2, 0xe4, 0x46, 0x8f, 0x4f,
+	0xee, 0x71, 0xe0, 0x27, 0x27, 0xdd, 0x9f, 0xfc, 0xdc, 0x1f, 0x5c, 0xfd, 0xb3, 0x04, 0xf1, 0xce,
+	0xf2, 0xcd, 0xe4, 0xf1, 0x2c, 0x7b, 0x0e, 0xa2, 0x3c, 0x12, 0x44, 0x79, 0x24, 0x90, 0xff, 0x05,
+	0x38, 0xb2, 0x4a, 0x45, 0x87, 0xe2, 0x9d, 0x38, 0x1a, 0x7c, 0x94, 0x23, 0xab, 0xb4, 0x47, 0x3b,
+	0xee, 0x44, 0x9f, 0x46, 0x74, 0x98, 0x63, 0x52, 0x36, 0xd7, 0x57, 0x64, 0x0c, 0x7e, 0xb2, 0xad,
+	0xf4, 0xbd, 0x51, 0x78, 0xfd, 0x39, 0xb2, 0x4a, 0x02, 0x2d, 0x54, 0x7f, 0x3a, 0xb6, 0xd4, 0xdf,
+	0x48, 0x30, 0x77, 0xdf, 0x2a, 0xed, 0xda, 0x94, 0x31, 0x7c, 0x6d, 0xce, 0xbd, 0x0a, 0x13, 0x4c,
+	0xca, 0xd0, 0xb9, 0x4b, 0x31, 0x7e, 0x95, 0x1f, 0x59, 0xa5, 0x5c, 0xa8, 0x5c, 0x46, 0x39, 0x45,
+	0xfd, 0x37, 0xff, 0x02, 0xdb, 0x9a, 0x59, 0xa6, 0x55, 0xdf, 0xc8, 0x75, 0x88, 0x72, 0x0c, 0xd1,
+	0x4a, 0x14, 0x10, 0xad, 0x44, 0xc2, 0x33, 0x5a, 0xd9, 0x0e, 0x43, 0x64, 0x60, 0x18, 0x04, 0x87,
+	0xc6, 0x06, 0x3b, 0x44, 0x5e, 0x81, 0xa8, 0x4d, 0x35, 0xc7, 0x32, 0xbd, 0x33, 0x8a, 0xdc, 0x9c,
+	0x22, 0x72, 0x73, 0x8a, 0xfa, 0x77, 0x09, 0xe6, 0xef, 0xa3, 0x51, 0xe1, 0x08, 0x84, 0xbd, 0x92,
+	0xce, 0xeb, 0xd5, 0xe8, 0x40, 0xaf, 0x6e, 0x43, 0xf4, 0xc0, 0xa8, 0xba, 0xd4, 0xc6, 0x08, 0xc8,
+	0x9b, 0x73, 0xed, 0xc4, 0xa3, 0xee, 0x1d, 0xdc, 0xe0, 0x96, 0x73, 0x26, 0xd1, 0x72, 0x4e, 0x11,
+	0xfc, 0x1c, 0x1b, 0xc2, 0xcf, 0xb7, 0x60, 0x4a, 0xc4, 0x26, 0xff, 0x0f, 0x51, 0xc7, 0xd5, 0x5c,
+	0xea, 0x28, 0xd2, 0x6a, 0x64, 0x6d, 0x66, 0x73, 0xba, 0xad, 0x9e, 0x51, 0x39, 0x18, 0x67, 0x10,
+	0xc1, 0x38, 0x45, 0xfd, 0x62, 0x16, 0x22, 0xf7, 0xad, 0x12, 0x59, 0x85, 0xd1, 0x76, 0x70, 0xe2,
+	0xad, 0x66, 0x6a, 0xca, 0x10, 0xc3, 0x32, 0x6a, 0xe8, 0xe1, 0x96, 0x75, 0x7a, 0xc8, 0x96, 0xf5,
+	0xc2, 0x33, 0x2a, 0xd4, 0x7f, 0x4f, 0x0c, 0xdd, 0x7f, 0x67, 0xda, 0xad, 0x34, 0x6f, 0xaf, 0x16,
+	0xfc, 0x98, 0x9d, 0xa3, 0x73, 0x7e, 0x27, 0x7c, 0xc3, 0x41, 0xb8, 0xe8, 0x3c, 0xfb, 0xbd, 0x76,
+	0xd2, 0xa7, 0x4f, 0x96, 0x51, 0xc1, 0x6a, 0x5b, 0xc1, 0xf3, 0x6e, 0x8b, 0xaf, 0xc1, 0xb8, 0xf5,
+	0xc4, 0xa4, 0xb6, 0x37, 0x8f, 0x60, 0xd4, 0x91, 0x20, 0x46, 0x1d, 0x09, 0x84, 0xc2, 0x25, 0xde,
+	0xda, 0xe1, 0xd2, 0x39, 0x34, 0xea, 0xc5, 0x86, 0x43, 0xed, 0x62, 0xc5, 0xb6, 0x1a, 0x75, 0x47,
+	0x99, 0xc5, 0xb3, 0x7d, 0xb5, 0xd5, 0x4c, 0xa9, 0xc8, 0xf6, 0xc8, 0xe7, 0xda, 0x77, 0xa8, 0x7d,
+	0x17, 0x79, 0x04, 0x4c, 0xa5, 0x1f, 0x0f, 0xf9, 0x89, 0x04, 0x57, 0xcb, 0x56, 0xad, 0xce, 0xba,
+	0x05, 0xaa, 0x17, 0xcf, 0x52, 0x39, 0xbf, 0x2a, 0xad, 0x4d, 0x65, 0x5e, 0x6b, 0x35, 0x53, 0xaf,
+	0x04, 0x12, 0x6f, 0x0f, 0x56, 0xae, 0x0e, 0xe6, 0x0e, 0xcd, 0x85, 0x63, 0x43, 0xce, 0x85, 0xe2,
+	0x8c, 0x31, 0xfe, 0xdc, 0x67, 0x8c, 0xa9, 0xe7, 0x31, 0x63, 0xfc, 0x4a, 0x82, 0x55, 0xaf, 0x5b,
+	0x37, 0xcc, 0x4a, 0xd1, 0xa6, 0x8e, 0xd5, 0xb0, 0xcb, 0xb4, 0xe8, 0xa5, 0x46, 0x8d, 0x9a, 0xae,
+	0xa3, 0x2c, 0xa2, 0xed, 0x6b, 0xbd, 0x34, 0x15, 0x3c, 0x81, 0x82, 0xc0, 0x9f, 0xb9, 0xfa, 0x69,
+	0x33, 0x35, 0xd2, 0x6a, 0xa6, 0x92, 0x01, 0x72, 0x2f, 0xbe, 0xc2, 0x80, 0x7d, 0x92, 0x83, 0x89,
+	0xb2, 0x4d, 0x35, 0x97, 0xea, 0xd8, 0x66, 0xc9, 0x9b, 0x89, 0x34, 0x7f, 0x19, 0x48, 0xfb, 0x23,
+	0x7f, 0xfa, 0xb1, 0xff, 0x10, 0x91, 0x99, 0xf7, 0x94, 0xfa, 0x22, 0x1f, 0x7d, 0x91, 0x92, 0x0a,
+	0xfe, 0x42, 0x9c, 0xa5, 0x66, 0x9e, 0xcb, 0x2c, 0x15, 0xff, 0x0a, 0xb3, 0xd4, 0x77, 0x41, 0x3e,
+	0xbe, 0xe1, 0x14, 0x7d, 0x83, 0xe6, 0x10, 0xea, 0x8a, 0x18, 0xde, 0xe0, 0x7d, 0x84, 0x05, 0xd9,
+	0xb3, 0x92, 0xf7, 0xb5, 0xc7, 0x37, 0x9c, 0x5c, 0x97, 0x89, 0x10, 0x50, 0x59, 0x49, 0x62, 0xe8,
+	0x9e, 0x36, 0x85, 0xf4, 0x4f, 0x13, 0xcf, 0xee, 0x36, 0xae, 0xb7, 0xee, 0xc0, 0xf5, 0xa8, 0xe1,
+	0x09, 0x70, 0xe1, 0xab, 0x4d, 0x80, 0x4b, 0xff, 0x9d, 0x00, 0xbf, 0xd6, 0x09, 0xf0, 0x1f, 0x12,
+	0x2c, 0xdd, 0x67, 0xfd, 0xac, 0x57, 0x9b, 0x8c, 0x1f, 0x50, 0xbf, 0x33, 0x12, 0xda, 0x31, 0x69,
+	0x88, 0x76, 0xec, 0xc2, 0x2f, 0xf3, 0x37, 0x61, 0xca, 0xa4, 0x4f, 0x8a, 0x1d, 0xc5, 0x16, 0xef,
+	0x4d, 0x93, 0x3e, 0xd9, 0xed, 0xae, 0xb7, 0xb2, 0x40, 0x56, 0x7f, 0x3b, 0x0a, 0xcb, 0x5d, 0x8e,
+	0x3a, 0x75, 0xcb, 0x74, 0x28, 0xf9, 0xb5, 0x04, 0x8a, 0x1d, 0x6c, 0xe0, 0x27, 0x66, 0x15, 0xaf,
+	0x51, 0x75, 0xb9, 0xef, 0xf2, 0xe6, 0x4d, 0xff, 0x62, 0xed, 0x05, 0x90, 0x2e, 0x74, 0x08, 0x17,
+	0xb8, 0x2c, 0xbf, 0x71, 0x5f, 0x6e, 0x35, 0x53, 0x57, 0xec, 0xde, 0x1c, 0x82, 0xb5, 0xcb, 0x7d,
+	0x58, 0x12, 0x36, 0x5c, 0x3e, 0x0b, 0xff, 0x42, 0xd2, 0xc2, 0x84, 0x45, 0x61, 0x34, 0xe2, 0x5e,
+	0xe2, 0x2b, 0xe8, 0x79, 0x06, 0x86, 0x6b, 0x30, 0x4e, 0x6d, 0xdb, 0xb2, 0x45, 0x9d, 0x48, 0x10,
+	0x59, 0x91, 0xa0, 0x7e, 0x88, 0x13, 0x54, 0x58, 0x1f, 0x39, 0x04, 0xc2, 0xa7, 0x37, 0xbe, 0xf6,
+	0xc6, 0x37, 0xfe, 0x3d, 0x12, 0x9d, 0xe3, 0x5b, 0x60, 0x63, 0x26, 0xd9, 0x6a, 0xa6, 0x12, 0x38,
+	0xa4, 0x05, 0x44, 0x31, 0xd2, 0xf1, 0xce, 0x3d, 0xf5, 0x4f, 0x93, 0x30, 0x8e, 0x17, 0x3c, 0xb9,
+	0x0a, 0x63, 0x38, 0xf6, 0x73, 0xef, 0x70, 0xf4, 0x35, 0xc3, 0x23, 0x3f, 0xee, 0x93, 0x2c, 0xcc,
+	0xfa, 0x89, 0x58, 0x3c, 0xd0, 0xca, 0xae, 0xe7, 0xa5, 0x94, 0xb9, 0xdc, 0x6a, 0xa6, 0x14, 0x7f,
+	0xeb, 0x0e, 0xee, 0x08, 0xc2, 0x33, 0xe1, 0x1d, 0x72, 0x13, 0x64, 0xec, 0x53, 0x78, 0xdb, 0xe2,
+	0xcd, 0x71, 0x58, 0x75, 0x19, 0x99, 0xb7, 0x1b, 0x62, 0xd5, 0x0d, 0xa8, 0xec, 0x38, 0x60, 0x77,
+	0xe3, 0xcb, 0xf2, 0x91, 0x09, 0x8f, 0x03, 0xd2, 0xbb, 0x84, 0x65, 0x81, 0x4c, 0x2a, 0x30, 0xdb,
+	0xbe, 0xd2, 0xab, 0x46, 0xcd, 0x70, 0xfd, 0xc7, 0xdd, 0x24, 0x06, 0x16, 0x83, 0xd1, 0xbe, 0xc3,
+	0x1f, 0x20, 0x03, 0xcf, 0x66, 0x16, 0x5c, 0xc5, 0x0e, 0x6d, 0x84, 0x5a, 0x92, 0x99, 0xf0, 0x1e,
+	0xf9, 0x9d, 0x04, 0x57, 0x3b, 0x34, 0x15, 0x4b, 0xa7, 0xed, 0x53, 0x5c, 0x2c, 0x57, 0x35, 0xc7,
+	0xe1, 0x4f, 0x2d, 0x13, 0xc2, 0x53, 0x6f, 0x2f, 0x03, 0x32, 0xa7, 0xfe, 0x69, 0xde, 0x66, 0x42,
+	0x79, 0xad, 0x46, 0xb9, 0x4d, 0xd7, 0xbc, 0x1b, 0xfe, 0x8a, 0x3d, 0x88, 0xbf, 0x30, 0x98, 0x85,
+	0xec, 0x81, 0x5c, 0xa7, 0x76, 0xcd, 0x70, 0x1c, 0xec, 0xdc, 0xf9, 0x03, 0xf4, 0x92, 0x60, 0xd5,
+	0x6e, 0xb0, 0xcb, 0xe3, 0x2d, 0xb0, 0x8b, 0xf1, 0x16, 0xc8, 0x89, 0x7f, 0x4a, 0x20, 0x0b, 0x72,
+	0xa4, 0x00, 0x93, 0x4e, 0xa3, 0x74, 0x44, 0xcb, 0xed, 0x0a, 0x93, 0xec, 0xad, 0x21, 0xbd, 0xc7,
+	0xd9, 0xbc, 0xee, 0xc1, 0x93, 0x09, 0x75, 0x0f, 0x1e, 0x0d, 0xcf, 0x38, 0xb5, 0x4b, 0xfc, 0x39,
+	0xc6, 0x3f, 0xe3, 0x8c, 0x10, 0x3a, 0xe3, 0x8c, 0x90, 0x78, 0x0f, 0x26, 0x3c, 0x5c, 0x96, 0xf1,
+	0xc7, 0x86, 0xa9, 0x8b, 0x19, 0xcf, 0xd6, 0x62, 0xc6, 0xb3, 0x75, 0xfb, 0x64, 0x8c, 0x9e, 0x7d,
+	0x32, 0x12, 0x06, 0xcc, 0xf7, 0xc8, 0x9b, 0x67, 0xa8, 0x52, 0xd2, 0xc0, 0xbb, 0xf2, 0x63, 0x09,
+	0xae, 0x0e, 0x97, 0x22, 0xc3, 0xa9, 0x7f, 0x4b, 0x54, 0xef, 0x0f, 0x53, 0x21, 0xc0, 0x0e, 0x6d,
+	0x83, 0xca, 0xe8, 0x4f, 0xc7, 0xe1, 0xd2, 0x19, 0xf2, 0xac, 0xc9, 0x5e, 0xa9, 0x69, 0xdf, 0x37,
+	0x6a, 0x8d, 0x5a, 0xd0, 0x61, 0x1f, 0xd8, 0x5a, 0x99, 0x15, 0x79, 0x2f, 0x2f, 0xbe, 0x35, 0xc8,
+	0x8a, 0xf4, 0x43, 0x8e, 0xe0, 0x53, 0xef, 0x78, 0xf2, 0xfc, 0x6c, 0xa4, 0xbc, 0xb3, 0xb1, 0x5c,
+	0xeb, 0xcd, 0x55, 0xe8, 0xb7, 0x41, 0x7e, 0x2f, 0xc1, 0x95, 0xbe, 0xc6, 0xe1, 0x19, 0xb6, 0xac,
+	0x2a, 0xe6, 0x9a, 0xbc, 0xb9, 0xfd, 0xac, 0x46, 0x66, 0x4e, 0x77, 0x2d, 0xab, 0xea, 0x5d, 0x94,
+	0x9e, 0xa9, 0x2f, 0xd4, 0xce, 0xe2, 0x2d, 0x9c, 0xbd, 0xcd, 0xae, 0xcb, 0xb3, 0x02, 0x72, 0x51,
+	0x89, 0xa8, 0x0e, 0x76, 0x70, 0x38, 0xd5, 0x8f, 0xc2, 0x49, 0xf8, 0x52, 0x77, 0x64, 0x31, 0x0a,
+	0xe7, 0x4b, 0xc4, 0x3f, 0x8c, 0x42, 0x6a, 0x00, 0x06, 0xf9, 0x78, 0x88, 0x64, 0xdc, 0x1a, 0xc6,
+	0x9a, 0x0b, 0x4a, 0xc8, 0x6f, 0xe2, 0xcb, 0xaa, 0x59, 0x88, 0x61, 0x49, 0x7e, 0x60, 0x38, 0x2e,
+	0xb9, 0x01, 0x51, 0x6c, 0x45, 0xfd, 0x92, 0x0d, 0x41, 0xc9, 0xe6, 0xcd, 0x31, 0xdf, 0x15, 0x9b,
+	0x63, 0x4e, 0x51, 0xf7, 0x81, 0xf0, 0x67, 0xc7, 0xaa, 0xd0, 0xbf, 0x91, 0xdb, 0x30, 0x5d, 0xe6,
+	0x54, 0xaa, 0x0b, 0x7d, 0x36, 0xfe, 0x66, 0xd0, 0xde, 0x08, 0x77, 0xdb, 0x53, 0x22, 0x5d, 0xbd,
+	0x09, 0xb3, 0xa8, 0xfd, 0x2e, 0x6d, 0x3f, 0x3b, 0x0f, 0xd9, 0xc0, 0xa8, 0xb7, 0x41, 0xd9, 0x73,
+	0x6d, 0xaa, 0xd5, 0x0c, 0xb3, 0xd2, 0x89, 0xf1, 0x22, 0x44, 0xcc, 0x46, 0x0d, 0x21, 0xa6, 0x79,
+	0x20, 0xcd, 0x46, 0x4d, 0x0c, 0xa4, 0xd9, 0xa8, 0xa9, 0x6f, 0x02, 0x41, 0xb9, 0x1d, 0x5a, 0xa5,
+	0x2e, 0x3d, 0xaf, 0xfa, 0x4f, 0x24, 0x00, 0xfe, 0x4e, 0x99, 0x33, 0x0f, 0xac, 0xa1, 0xdb, 0xae,
+	0x9b, 0x20, 0x63, 0x44, 0xf5, 0xe2, 0x91, 0x85, 0x17, 0x9d, 0xb4, 0x36, 0xce, 0xfb, 0x25, 0x4e,
+	0xbe, 0x6f, 0x85, 0x6e, 0x3b, 0x08, 0xa8, 0x4c, 0xb4, 0x4a, 0x35, 0xc7, 0x17, 0x8d, 0x04, 0xa2,
+	0x9c, 0xdc, 0x29, 0x1a, 0x50, 0xd5, 0x27, 0x30, 0x8f, 0xae, 0xee, 0xd7, 0x75, 0xcd, 0x0d, 0xc6,
+	0x86, 0x37, 0xc4, 0x17, 0xfe, 0x70, 0x36, 0x9c, 0x35, 0xc7, 0x9c, 0xa3, 0x2d, 0x6e, 0x80, 0x92,
+	0xd1, 0xdc, 0xf2, 0x61, 0x2f, 0xed, 0xef, 0xc1, 0xf4, 0x81, 0x66, 0x54, 0xfd, 0x97, 0x2f, 0x3f,
+	0x27, 0x95, 0xc0, 0x8a, 0xb0, 0x00, 0x4f, 0x2b, 0x2e, 0xf2, 0x76, 0x67, 0x9e, 0x4e, 0x89, 0xf4,
+	0xb6, 0xbf, 0xdb, 0xf8, 0x46, 0xf2, 0x4d, 0xf9, 0xdb, 0xa1, 0x7d, 0xb0, 0xbf, 0x61, 0x81, 0x73,
+	0xf8, 0x2b, 0x43, 0x2c, 0x6b, 0xea, 0x0f, 0x35, 0xfb, 0x98, 0xda, 0xea, 0x47, 0x12, 0x2c, 0x86,
+	0x4f, 0xc6, 0x43, 0xea, 0x38, 0x5a, 0x85, 0x92, 0xff, 0x3b, 0x9f, 0xff, 0xf7, 0x46, 0x82, 0x67,
+	0xe8, 0x08, 0x35, 0x75, 0xaf, 0xa0, 0xcf, 0xa0, 0x58, 0x5b, 0x1f, 0x3f, 0x5f, 0x54, 0x6c, 0xb8,
+	0xee, 0x8d, 0x14, 0x18, 0x7f, 0x66, 0x02, 0xc6, 0xe9, 0x09, 0x35, 0xdd, 0xf5, 0x04, 0xc8, 0xc2,
+	0x6f, 0xb0, 0x44, 0x86, 0x09, 0x6f, 0x19, 0x1f, 0x59, 0xbf, 0x06, 0xb2, 0xf0, 0x63, 0x1d, 0x99,
+	0x82, 0xc9, 0xbc, 0xa5, 0xd3, 0x5d, 0xcb, 0x76, 0xe3, 0x23, 0x6c, 0x75, 0x8f, 0x6a, 0x7a, 0x95,
+	0xb1, 0x4a, 0xeb, 0xbf, 0x90, 0x60, 0xd2, 0x7f, 0xf8, 0x27, 0x00, 0xd1, 0xb7, 0xf7, 0xb3, 0xfb,
+	0xd9, 0x9d, 0xf8, 0x08, 0x03, 0xdc, 0xcd, 0xe6, 0x77, 0x72, 0xf9, 0xbb, 0x71, 0x89, 0x2d, 0x0a,
+	0xfb, 0xf9, 0x3c, 0x5b, 0x8c, 0x92, 0x69, 0x88, 0xed, 0xed, 0x6f, 0x6f, 0x67, 0xb3, 0x3b, 0xd9,
+	0x9d, 0x78, 0x84, 0x09, 0xdd, 0xd9, 0xca, 0x3d, 0xc8, 0xee, 0xc4, 0xc7, 0x18, 0xdf, 0x7e, 0xfe,
+	0xad, 0xfc, 0xa3, 0x77, 0xf3, 0xf1, 0x71, 0xce, 0x97, 0x79, 0x98, 0x7b, 0xfc, 0x38, 0xbb, 0x13,
+	0x8f, 0x32, 0xbe, 0x07, 0xd9, 0xad, 0xbd, 0xec, 0x4e, 0x7c, 0x82, 0x6d, 0xed, 0x16, 0xb2, 0xd9,
+	0x87, 0xbb, 0x6c, 0x6b, 0x92, 0x2d, 0xb7, 0xb7, 0xf2, 0xdb, 0xd9, 0x07, 0x0c, 0x25, 0xb6, 0xf9,
+	0xf3, 0x18, 0x44, 0xf9, 0x08, 0x47, 0xde, 0x01, 0xe0, 0x7f, 0xe1, 0x71, 0x5d, 0xec, 0xf9, 0xfb,
+	0x5c, 0x62, 0xa9, 0xf7, 0xdc, 0xa7, 0xae, 0xfc, 0xf8, 0x8f, 0x7f, 0xfb, 0xe5, 0xe8, 0xbc, 0x3a,
+	0xb3, 0x71, 0x72, 0x7d, 0xe3, 0xc8, 0x2a, 0x79, 0xff, 0xc8, 0x74, 0x4b, 0x5a, 0x27, 0xef, 0x02,
+	0xf0, 0xda, 0x1b, 0xc6, 0x0d, 0xfd, 0x0c, 0x94, 0x58, 0x46, 0x72, 0x77, 0x8d, 0xee, 0x06, 0xe6,
+	0x05, 0x98, 0x01, 0x7f, 0x0f, 0xa6, 0xda, 0xc0, 0x7b, 0xd4, 0x25, 0x8a, 0xf0, 0xcb, 0x4e, 0x18,
+	0x7d, 0xa9, 0xeb, 0x79, 0x32, 0xcb, 0x3e, 0xb4, 0x7a, 0x19, 0xc1, 0x97, 0xd4, 0x39, 0x0f, 0xdc,
+	0xa1, 0xae, 0x80, 0x6f, 0x42, 0x5c, 0x7c, 0x6d, 0x40, 0xf3, 0x2f, 0xf5, 0x7e, 0x87, 0xe0, 0x6a,
+	0x2e, 0x9f, 0xf5, 0x48, 0xa1, 0xa6, 0x50, 0xd9, 0x8a, 0xba, 0xe0, 0x7b, 0x22, 0x3c, 0x38, 0x50,
+	0xa6, 0xef, 0x3d, 0x90, 0xbd, 0xdf, 0x30, 0x51, 0x55, 0x3b, 0xd4, 0xe1, 0x1f, 0x36, 0xfb, 0x3a,
+	0x93, 0x40, 0xfc, 0x05, 0x75, 0xd6, 0xc7, 0xaf, 0x73, 0x39, 0x06, 0x7d, 0x17, 0x64, 0x7e, 0x3a,
+	0xf9, 0x94, 0x2d, 0x1c, 0x9d, 0xbe, 0x70, 0x0b, 0x08, 0x37, 0xa3, 0xc6, 0x18, 0x1c, 0x9e, 0x23,
+	0x06, 0x54, 0x86, 0x29, 0x01, 0xc8, 0x21, 0x33, 0x01, 0x12, 0xbb, 0xa2, 0x13, 0x2f, 0xe0, 0xba,
+	0x5f, 0x11, 0x51, 0x5f, 0x42, 0xd0, 0xa4, 0xba, 0xc2, 0x40, 0x4b, 0x8c, 0x8b, 0xea, 0x1b, 0xfc,
+	0x29, 0xd8, 0x2b, 0x2b, 0x4c, 0x49, 0x1e, 0x64, 0x5e, 0x3b, 0x87, 0xb7, 0xf6, 0x12, 0x02, 0x2f,
+	0x26, 0xe2, 0x6d, 0x6b, 0x37, 0x7e, 0xc8, 0x6e, 0xac, 0x0f, 0x3d, 0xa3, 0x05, 0xbc, 0xc1, 0x46,
+	0x87, 0x0b, 0xb7, 0x6f, 0x74, 0x22, 0x64, 0x74, 0x03, 0x79, 0x04, 0xa3, 0xbf, 0x0d, 0x32, 0xbf,
+	0x8a, 0xb9, 0xd1, 0xcb, 0x81, 0x8e, 0xd0, 0x0d, 0xdd, 0xd7, 0x03, 0x05, 0xb5, 0x90, 0xf5, 0x2e,
+	0x0f, 0xc8, 0x1d, 0x98, 0xbc, 0x4b, 0x5d, 0x0e, 0xbb, 0x10, 0xc0, 0x06, 0x0d, 0x43, 0x42, 0x88,
+	0x90, 0x8f, 0x43, 0xba, 0x71, 0x74, 0x88, 0xf9, 0x38, 0x0e, 0xe1, 0x3e, 0xf7, 0x6b, 0x41, 0x12,
+	0x89, 0x1e, 0xdb, 0x5e, 0x1d, 0xf6, 0x13, 0x8d, 0x10, 0x31, 0x1e, 0x3c, 0x10, 0xaf, 0x49, 0xe4,
+	0x16, 0x44, 0xef, 0xe1, 0x3f, 0xf4, 0x91, 0x3e, 0x9e, 0x26, 0xf8, 0x39, 0xe5, 0x4c, 0xdb, 0x87,
+	0xb4, 0x7c, 0xdc, 0xbe, 0x32, 0xde, 0xff, 0xfc, 0xaf, 0xc9, 0x91, 0x1f, 0x3d, 0x4d, 0x4a, 0x9f,
+	0x3e, 0x4d, 0x4a, 0x9f, 0x3d, 0x4d, 0x4a, 0x7f, 0x79, 0x9a, 0x94, 0x3e, 0xfa, 0x32, 0x39, 0xf2,
+	0xd9, 0x97, 0xc9, 0x91, 0xcf, 0xbf, 0x4c, 0x8e, 0x7c, 0xe7, 0x7f, 0x84, 0xff, 0x31, 0xd4, 0xec,
+	0x9a, 0xa6, 0x6b, 0x75, 0xdb, 0x62, 0x73, 0xb4, 0xb7, 0xda, 0xf0, 0xfe, 0xa9, 0xf0, 0x93, 0xd1,
+	0x85, 0x2d, 0x24, 0xec, 0xf2, 0xed, 0x74, 0xce, 0x4a, 0x6f, 0xd5, 0x8d, 0x52, 0x14, 0x6d, 0x79,
+	0xfd, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x8a, 0x17, 0x1c, 0x71, 0x29, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -2227,6 +2291,7 @@ type SubmitClient interface {
 	CancelJobs(ctx context.Context, in *JobCancelRequest, opts ...grpc.CallOption) (*CancellationResult, error)
 	CancelJobSet(ctx context.Context, in *JobSetCancelRequest, opts ...grpc.CallOption) (*types.Empty, error)
 	ReprioritizeJobs(ctx context.Context, in *JobReprioritizeRequest, opts ...grpc.CallOption) (*JobReprioritizeResponse, error)
+	PreemptJobs(ctx context.Context, in *JobPreemptRequest, opts ...grpc.CallOption) (*types.Empty, error)
 	CreateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error)
 	CreateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueCreateResponse, error)
 	UpdateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error)
@@ -2281,6 +2346,15 @@ func (c *submitClient) ReprioritizeJobs(ctx context.Context, in *JobReprioritize
 	return out, nil
 }
 
+func (c *submitClient) PreemptJobs(ctx context.Context, in *JobPreemptRequest, opts ...grpc.CallOption) (*types.Empty, error) {
+	out := new(types.Empty)
+	err := c.cc.Invoke(ctx, "/api.Submit/PreemptJobs", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 func (c *submitClient) CreateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) {
 	out := new(types.Empty)
 	err := c.cc.Invoke(ctx, "/api.Submit/CreateQueue", in, out, opts...)
@@ -2382,6 +2456,7 @@ type SubmitServer interface {
 	CancelJobs(context.Context, *JobCancelRequest) (*CancellationResult, error)
 	CancelJobSet(context.Context, *JobSetCancelRequest) (*types.Empty, error)
 	ReprioritizeJobs(context.Context, *JobReprioritizeRequest) (*JobReprioritizeResponse, error)
+	PreemptJobs(context.Context, *JobPreemptRequest) (*types.Empty, error)
 	CreateQueue(context.Context, *Queue) (*types.Empty, error)
 	CreateQueues(context.Context, *QueueList) (*BatchQueueCreateResponse, error)
 	UpdateQueue(context.Context, *Queue) (*types.Empty, error)
@@ -2408,6 +2483,9 @@ func (*UnimplementedSubmitServer) CancelJobSet(ctx context.Context, req *JobSetC
 func (*UnimplementedSubmitServer) ReprioritizeJobs(ctx context.Context, req *JobReprioritizeRequest) (*JobReprioritizeResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method ReprioritizeJobs not implemented")
 }
+func (*UnimplementedSubmitServer) PreemptJobs(ctx context.Context, req *JobPreemptRequest) (*types.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PreemptJobs not implemented")
+}
 func (*UnimplementedSubmitServer) CreateQueue(ctx context.Context, req *Queue) (*types.Empty, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method CreateQueue not implemented")
 }
@@ -2509,6 +2587,24 @@ func _Submit_ReprioritizeJobs_Handler(srv interface{}, ctx context.Context, dec
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Submit_PreemptJobs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(JobPreemptRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(SubmitServer).PreemptJobs(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/api.Submit/PreemptJobs",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(SubmitServer).PreemptJobs(ctx, req.(*JobPreemptRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 func _Submit_CreateQueue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 	in := new(Queue)
 	if err := dec(in); err != nil {
@@ -2676,6 +2772,10 @@ var _Submit_serviceDesc = grpc.ServiceDesc{
 			MethodName: "ReprioritizeJobs",
 			Handler:    _Submit_ReprioritizeJobs_Handler,
 		},
+		{
+			MethodName: "PreemptJobs",
+			Handler:    _Submit_PreemptJobs_Handler,
+		},
 		{
 			MethodName: "CreateQueue",
 			Handler:    _Submit_CreateQueue_Handler,
@@ -3070,6 +3170,52 @@ func (m *JobSubmitRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	return len(dAtA) - i, nil
 }
 
+func (m *JobPreemptRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *JobPreemptRequest) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *JobPreemptRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if len(m.JobIds) > 0 {
+		for iNdEx := len(m.JobIds) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.JobIds[iNdEx])
+			copy(dAtA[i:], m.JobIds[iNdEx])
+			i = encodeVarintSubmit(dAtA, i, uint64(len(m.JobIds[iNdEx])))
+			i--
+			dAtA[i] = 0x1a
+		}
+	}
+	if len(m.JobSetId) > 0 {
+		i -= len(m.JobSetId)
+		copy(dAtA[i:], m.JobSetId)
+		i = encodeVarintSubmit(dAtA, i, uint64(len(m.JobSetId)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.Queue) > 0 {
+		i -= len(m.Queue)
+		copy(dAtA[i:], m.Queue)
+		i = encodeVarintSubmit(dAtA, i, uint64(len(m.Queue)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
 func (m *JobCancelRequest) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -4579,6 +4725,29 @@ func (m *JobSubmitRequest) Size() (n int) {
 	return n
 }
 
+func (m *JobPreemptRequest) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = len(m.Queue)
+	if l > 0 {
+		n += 1 + l + sovSubmit(uint64(l))
+	}
+	l = len(m.JobSetId)
+	if l > 0 {
+		n += 1 + l + sovSubmit(uint64(l))
+	}
+	if len(m.JobIds) > 0 {
+		for _, s := range m.JobIds {
+			l = len(s)
+			n += 1 + l + sovSubmit(uint64(l))
+		}
+	}
+	return n
+}
+
 func (m *JobCancelRequest) Size() (n int) {
 	if m == nil {
 		return 0
@@ -5295,6 +5464,18 @@ func (this *JobSubmitRequest) String() string {
 	}, "")
 	return s
 }
+func (this *JobPreemptRequest) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&JobPreemptRequest{`,
+		`Queue:` + fmt.Sprintf("%v", this.Queue) + `,`,
+		`JobSetId:` + fmt.Sprintf("%v", this.JobSetId) + `,`,
+		`JobIds:` + fmt.Sprintf("%v", this.JobIds) + `,`,
+		`}`,
+	}, "")
+	return s
+}
 func (this *JobCancelRequest) String() string {
 	if this == nil {
 		return "nil"
@@ -7094,6 +7275,152 @@ func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowSubmit
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: JobPreemptRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: JobPreemptRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSubmit
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Queue = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSubmit
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.JobSetId = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSubmit
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipSubmit(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthSubmit
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func (m *JobCancelRequest) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
 	iNdEx := 0
diff --git a/pkg/api/submit.pb.gw.go b/pkg/api/submit.pb.gw.go
index 6c15c622..59e891d3 100644
--- a/pkg/api/submit.pb.gw.go
+++ b/pkg/api/submit.pb.gw.go
@@ -169,6 +169,40 @@ func local_request_Submit_ReprioritizeJobs_0(ctx context.Context, marshaler runt
 
 }
 
+func request_Submit_PreemptJobs_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq JobPreemptRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.PreemptJobs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Submit_PreemptJobs_0(ctx context.Context, marshaler runtime.Marshaler, server SubmitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq JobPreemptRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.PreemptJobs(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
 func request_Submit_CreateQueue_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
 	var protoReq Queue
 	var metadata runtime.ServerMetadata
@@ -575,6 +609,29 @@ func RegisterSubmitHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser
 
 	})
 
+	mux.Handle("POST", pattern_Submit_PreemptJobs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Submit_PreemptJobs_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Submit_PreemptJobs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
 	mux.Handle("POST", pattern_Submit_CreateQueue_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
@@ -841,6 +898,26 @@ func RegisterSubmitHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli
 
 	})
 
+	mux.Handle("POST", pattern_Submit_PreemptJobs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Submit_PreemptJobs_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Submit_PreemptJobs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
 	mux.Handle("POST", pattern_Submit_CreateQueue_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
@@ -993,6 +1070,8 @@ var (
 
 	pattern_Submit_ReprioritizeJobs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "job", "reprioritize"}, "", runtime.AssumeColonVerbOpt(true)))
 
+	pattern_Submit_PreemptJobs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "job", "preempt"}, "", runtime.AssumeColonVerbOpt(true)))
+
 	pattern_Submit_CreateQueue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "queue"}, "", runtime.AssumeColonVerbOpt(true)))
 
 	pattern_Submit_CreateQueues_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "batched", "create_queues"}, "", runtime.AssumeColonVerbOpt(true)))
@@ -1017,6 +1096,8 @@ var (
 
 	forward_Submit_ReprioritizeJobs_0 = runtime.ForwardResponseMessage
 
+	forward_Submit_PreemptJobs_0 = runtime.ForwardResponseMessage
+
 	forward_Submit_CreateQueue_0 = runtime.ForwardResponseMessage
 
 	forward_Submit_CreateQueues_0 = runtime.ForwardResponseMessage
diff --git a/pkg/api/submit.proto b/pkg/api/submit.proto
index c6803874..41f6a126 100644
--- a/pkg/api/submit.proto
+++ b/pkg/api/submit.proto
@@ -64,6 +64,13 @@ message JobSubmitRequest {
     repeated JobSubmitRequestItem job_request_items = 3;
 }
 
+// swagger:model
+message JobPreemptRequest {
+  string queue = 1;
+  string job_set_id = 2;
+  repeated string job_ids = 3;
+}
+
 // swagger:model
 message JobCancelRequest {
     string job_id = 1;
@@ -287,6 +294,12 @@ service Submit {
             body: "*"
         };
     }
+    rpc PreemptJobs (JobPreemptRequest) returns (google.protobuf.Empty) {
+      option (google.api.http) = {
+        post: "/v1/job/preempt"
+        body: "*"
+      };
+    }
     rpc CreateQueue (Queue) returns (google.protobuf.Empty) {
         option (google.api.http) = {
             post: "/v1/queue"
diff --git a/pkg/armadaevents/events.pb.go b/pkg/armadaevents/events.pb.go
index 6185d70f..e9418f58 100644
--- a/pkg/armadaevents/events.pb.go
+++ b/pkg/armadaevents/events.pb.go
@@ -204,6 +204,7 @@ type EventSequence_Event struct {
 	//	*EventSequence_Event_PartitionMarker
 	//	*EventSequence_Event_JobRunPreemptionRequested
 	//	*EventSequence_Event_JobRequeued
+	//	*EventSequence_Event_JobPreemptionRequested
 	Event isEventSequence_Event_Event `protobuf_oneof:"event"`
 }
 
@@ -309,6 +310,9 @@ type EventSequence_Event_JobRunPreemptionRequested struct {
 type EventSequence_Event_JobRequeued struct {
 	JobRequeued *JobRequeued `protobuf:"bytes,22,opt,name=jobRequeued,proto3,oneof" json:"jobRequeued,omitempty"`
 }
+type EventSequence_Event_JobPreemptionRequested struct {
+	JobPreemptionRequested *JobPreemptionRequested `protobuf:"bytes,23,opt,name=jobPreemptionRequested,proto3,oneof" json:"jobPreemptionRequested,omitempty"`
+}
 
 func (*EventSequence_Event_SubmitJob) isEventSequence_Event_Event()                 {}
 func (*EventSequence_Event_ReprioritiseJob) isEventSequence_Event_Event()           {}
@@ -331,6 +335,7 @@ func (*EventSequence_Event_JobRunPreempted) isEventSequence_Event_Event()
 func (*EventSequence_Event_PartitionMarker) isEventSequence_Event_Event()           {}
 func (*EventSequence_Event_JobRunPreemptionRequested) isEventSequence_Event_Event() {}
 func (*EventSequence_Event_JobRequeued) isEventSequence_Event_Event()               {}
+func (*EventSequence_Event_JobPreemptionRequested) isEventSequence_Event_Event()    {}
 
 func (m *EventSequence_Event) GetEvent() isEventSequence_Event_Event {
 	if m != nil {
@@ -493,6 +498,13 @@ func (m *EventSequence_Event) GetJobRequeued() *JobRequeued {
 	return nil
 }
 
+func (m *EventSequence_Event) GetJobPreemptionRequested() *JobPreemptionRequested {
+	if x, ok := m.GetEvent().(*EventSequence_Event_JobPreemptionRequested); ok {
+		return x.JobPreemptionRequested
+	}
+	return nil
+}
+
 // XXX_OneofWrappers is for the internal use of the proto package.
 func (*EventSequence_Event) XXX_OneofWrappers() []interface{} {
 	return []interface{}{
@@ -517,6 +529,7 @@ func (*EventSequence_Event) XXX_OneofWrappers() []interface{} {
 		(*EventSequence_Event_PartitionMarker)(nil),
 		(*EventSequence_Event_JobRunPreemptionRequested)(nil),
 		(*EventSequence_Event_JobRequeued)(nil),
+		(*EventSequence_Event_JobPreemptionRequested)(nil),
 	}
 }
 
@@ -3468,6 +3481,51 @@ func (m *JobRunPreemptionRequested) GetJobId() *Uuid {
 	return nil
 }
 
+// Indicates that a user has requested for the job to be pre-empted.
+type JobPreemptionRequested struct {
+	JobId *Uuid `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
+}
+
+func (m *JobPreemptionRequested) Reset()         { *m = JobPreemptionRequested{} }
+func (m *JobPreemptionRequested) String() string { return proto.CompactTextString(m) }
+func (*JobPreemptionRequested) ProtoMessage()    {}
+func (*JobPreemptionRequested) Descriptor() ([]byte, []int) {
+	return fileDescriptor_6aab92ca59e015f8, []int{43}
+}
+func (m *JobPreemptionRequested) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *JobPreemptionRequested) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_JobPreemptionRequested.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *JobPreemptionRequested) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_JobPreemptionRequested.Merge(m, src)
+}
+func (m *JobPreemptionRequested) XXX_Size() int {
+	return m.Size()
+}
+func (m *JobPreemptionRequested) XXX_DiscardUnknown() {
+	xxx_messageInfo_JobPreemptionRequested.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_JobPreemptionRequested proto.InternalMessageInfo
+
+func (m *JobPreemptionRequested) GetJobId() *Uuid {
+	if m != nil {
+		return m.JobId
+	}
+	return nil
+}
+
 func init() {
 	proto.RegisterEnum("armadaevents.JobState", JobState_name, JobState_value)
 	proto.RegisterEnum("armadaevents.KubernetesReason", KubernetesReason_name, KubernetesReason_value)
@@ -3521,238 +3579,241 @@ func init() {
 	proto.RegisterType((*JobRunPreempted)(nil), "armadaevents.JobRunPreempted")
 	proto.RegisterType((*PartitionMarker)(nil), "armadaevents.PartitionMarker")
 	proto.RegisterType((*JobRunPreemptionRequested)(nil), "armadaevents.JobRunPreemptionRequested")
+	proto.RegisterType((*JobPreemptionRequested)(nil), "armadaevents.JobPreemptionRequested")
 }
 
 func init() { proto.RegisterFile("pkg/armadaevents/events.proto", fileDescriptor_6aab92ca59e015f8) }
 
 var fileDescriptor_6aab92ca59e015f8 = []byte{
-	// 3604 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5b, 0x4b, 0x6c, 0x1b, 0xd7,
-	0xb9, 0xf6, 0x90, 0x12, 0x1f, 0x3f, 0xf5, 0xa0, 0x8f, 0x25, 0x85, 0x56, 0x6c, 0x51, 0x1e, 0xe7,
-	0xde, 0x38, 0x41, 0x42, 0x26, 0xce, 0x03, 0x79, 0x5c, 0x24, 0x10, 0x6d, 0xc5, 0xb6, 0x62, 0xd9,
-	0x0a, 0x65, 0xe5, 0xfa, 0x06, 0xb9, 0x60, 0x86, 0x9c, 0x23, 0x6a, 0xac, 0xe1, 0x0c, 0x33, 0x0f,
-	0x59, 0x02, 0xb2, 0xb8, 0xb9, 0xb8, 0x37, 0xdd, 0xa5, 0x06, 0x9a, 0x45, 0x81, 0x2e, 0xd2, 0x6d,
-	0x03, 0x74, 0xdd, 0x75, 0x57, 0xcd, 0xa2, 0x28, 0xd2, 0x5d, 0x57, 0x6c, 0x91, 0xa0, 0x8b, 0x72,
-	0xd1, 0x75, 0xdb, 0x4d, 0x8b, 0xf3, 0x9a, 0x39, 0x67, 0x38, 0xb4, 0xe5, 0x57, 0x9d, 0xc2, 0x2b,
-	0x69, 0xbe, 0xff, 0x39, 0xe7, 0xf1, 0xcf, 0xff, 0xff, 0xe7, 0x10, 0x4e, 0xf6, 0x77, 0xbb, 0x75,
-	0xc3, 0xeb, 0x19, 0xa6, 0x81, 0xf7, 0xb0, 0x13, 0xf8, 0x75, 0xf6, 0xa7, 0xd6, 0xf7, 0xdc, 0xc0,
-	0x45, 0x53, 0x32, 0x69, 0x51, 0xdf, 0x7d, 0xcd, 0xaf, 0x59, 0x6e, 0xdd, 0xe8, 0x5b, 0xf5, 0x8e,
-	0xeb, 0xe1, 0xfa, 0xde, 0x8b, 0xf5, 0x2e, 0x76, 0xb0, 0x67, 0x04, 0xd8, 0x64, 0x12, 0x8b, 0x67,
-	0x24, 0x1e, 0x07, 0x07, 0x37, 0x5d, 0x6f, 0xd7, 0x72, 0xba, 0x69, 0x9c, 0xd5, 0xae, 0xeb, 0x76,
-	0x6d, 0x5c, 0xa7, 0x4f, 0xed, 0x70, 0xbb, 0x1e, 0x58, 0x3d, 0xec, 0x07, 0x46, 0xaf, 0xcf, 0x19,
-	0x5e, 0x8e, 0x55, 0xf5, 0x8c, 0xce, 0x8e, 0xe5, 0x60, 0xef, 0xa0, 0x4e, 0xfd, 0xed, 0x5b, 0x75,
-	0x0f, 0xfb, 0x6e, 0xe8, 0x75, 0xf0, 0x88, 0xda, 0xe7, 0xbb, 0x56, 0xb0, 0x13, 0xb6, 0x6b, 0x1d,
-	0xb7, 0x57, 0xef, 0xba, 0x5d, 0x37, 0xd6, 0x4f, 0x9e, 0xe8, 0x03, 0xfd, 0x8f, 0xb3, 0xbf, 0x61,
-	0x39, 0x01, 0xf6, 0x1c, 0xc3, 0xae, 0xfb, 0x9d, 0x1d, 0x6c, 0x86, 0x36, 0xf6, 0xe2, 0xff, 0xdc,
-	0xf6, 0x0d, 0xdc, 0x09, 0xfc, 0x11, 0x80, 0xc9, 0xea, 0xb7, 0xe6, 0x60, 0x7a, 0x95, 0x0c, 0xcd,
-	0x26, 0xfe, 0x38, 0xc4, 0x4e, 0x07, 0xa3, 0x67, 0x60, 0xf2, 0xe3, 0x10, 0x87, 0xb8, 0xa2, 0x2d,
-	0x6b, 0x67, 0x8a, 0x8d, 0x63, 0xc3, 0x41, 0x75, 0x96, 0x02, 0xcf, 0xb9, 0x3d, 0x2b, 0xc0, 0xbd,
-	0x7e, 0x70, 0xd0, 0x64, 0x1c, 0xe8, 0x0d, 0x98, 0xba, 0xe1, 0xb6, 0x5b, 0x3e, 0x0e, 0x5a, 0x8e,
-	0xd1, 0xc3, 0x95, 0x0c, 0x95, 0xa8, 0x0c, 0x07, 0xd5, 0xb9, 0x1b, 0x6e, 0x7b, 0x13, 0x07, 0x57,
-	0x8c, 0x9e, 0x2c, 0x06, 0x31, 0x8a, 0x9e, 0x87, 0x7c, 0xe8, 0x63, 0xaf, 0x65, 0x99, 0x95, 0x2c,
-	0x15, 0x9b, 0x1b, 0x0e, 0xaa, 0x65, 0x02, 0x5d, 0x32, 0x25, 0x91, 0x1c, 0x43, 0xd0, 0x73, 0x90,
-	0xeb, 0x7a, 0x6e, 0xd8, 0xf7, 0x2b, 0x13, 0xcb, 0x59, 0xc1, 0xcd, 0x10, 0x99, 0x9b, 0x21, 0xe8,
-	0x2a, 0xe4, 0xd8, 0x7c, 0x57, 0x26, 0x97, 0xb3, 0x67, 0x4a, 0x67, 0x4f, 0xd5, 0xe4, 0x45, 0x50,
-	0x53, 0x5e, 0x98, 0x3d, 0x31, 0x85, 0x8c, 0x2e, 0x2b, 0xe4, 0xcb, 0xe6, 0x4f, 0x47, 0x61, 0x92,
-	0xf2, 0xa1, 0xab, 0x90, 0xef, 0x78, 0x98, 0x4c, 0x56, 0x05, 0x2d, 0x6b, 0x67, 0x4a, 0x67, 0x17,
-	0x6b, 0x6c, 0x11, 0xd4, 0xc4, 0x24, 0xd5, 0xae, 0x89, 0x45, 0xd0, 0x38, 0x3e, 0x1c, 0x54, 0x8f,
-	0x72, 0xf6, 0x58, 0xeb, 0xad, 0xdf, 0x57, 0xb5, 0xa6, 0xd0, 0x82, 0x36, 0xa0, 0xe8, 0x87, 0xed,
-	0x9e, 0x15, 0xac, 0xb9, 0x6d, 0x3a, 0xe6, 0xa5, 0xb3, 0x4f, 0xa8, 0xee, 0x6e, 0x0a, 0x72, 0xe3,
-	0x89, 0xe1, 0xa0, 0x7a, 0x2c, 0xe2, 0x8e, 0x35, 0x5e, 0x3c, 0xd2, 0x8c, 0x95, 0xa0, 0x1d, 0x98,
-	0xf5, 0x70, 0xdf, 0xb3, 0x5c, 0xcf, 0x0a, 0x2c, 0x1f, 0x13, 0xbd, 0x19, 0xaa, 0xf7, 0xa4, 0xaa,
-	0xb7, 0xa9, 0x32, 0x35, 0x4e, 0x0e, 0x07, 0xd5, 0xe3, 0x09, 0x49, 0xc5, 0x46, 0x52, 0x2d, 0x0a,
-	0x00, 0x25, 0xa0, 0x4d, 0x1c, 0xd0, 0xf9, 0x2c, 0x9d, 0x5d, 0xbe, 0xad, 0xb1, 0x4d, 0x1c, 0x34,
-	0x96, 0x87, 0x83, 0xea, 0x89, 0x51, 0x79, 0xc5, 0x64, 0x8a, 0x7e, 0x64, 0x43, 0x59, 0x46, 0x4d,
-	0xf2, 0x82, 0x13, 0xd4, 0xe6, 0xd2, 0x78, 0x9b, 0x84, 0xab, 0xb1, 0x34, 0x1c, 0x54, 0x17, 0x93,
-	0xb2, 0x8a, 0xbd, 0x11, 0xcd, 0x64, 0x7e, 0x3a, 0x86, 0xd3, 0xc1, 0x36, 0x31, 0x33, 0x99, 0x36,
-	0x3f, 0xe7, 0x04, 0x99, 0xcd, 0x4f, 0xc4, 0xad, 0xce, 0x4f, 0x04, 0xa3, 0x0f, 0x61, 0x2a, 0x7a,
-	0x20, 0xe3, 0x95, 0xe3, 0xeb, 0x28, 0x5d, 0x29, 0x19, 0xa9, 0xc5, 0xe1, 0xa0, 0xba, 0x20, 0xcb,
-	0x28, 0xaa, 0x15, 0x6d, 0xb1, 0x76, 0x9b, 0x8d, 0x4c, 0x7e, 0xbc, 0x76, 0xc6, 0x21, 0x6b, 0xb7,
-	0x47, 0x47, 0x44, 0xd1, 0x46, 0xb4, 0x93, 0x4d, 0x1c, 0x76, 0x3a, 0x18, 0x9b, 0xd8, 0xac, 0x14,
-	0xd2, 0xb4, 0xaf, 0x49, 0x1c, 0x4c, 0xbb, 0x2c, 0xa3, 0x6a, 0x97, 0x29, 0x64, 0xac, 0x6f, 0xb8,
-	0xed, 0x55, 0xcf, 0x73, 0x3d, 0xbf, 0x52, 0x4c, 0x1b, 0xeb, 0x35, 0x41, 0x66, 0x63, 0x1d, 0x71,
-	0xab, 0x63, 0x1d, 0xc1, 0xdc, 0xdf, 0x66, 0xe8, 0x5c, 0xc6, 0x86, 0x8f, 0xcd, 0x0a, 0x8c, 0xf1,
-	0x37, 0xe2, 0x88, 0xfc, 0x8d, 0x90, 0x11, 0x7f, 0x23, 0x0a, 0x32, 0x61, 0x86, 0x3d, 0xaf, 0xf8,
-	0xbe, 0xd5, 0x75, 0xb0, 0x59, 0x29, 0x51, 0xfd, 0x27, 0xd2, 0xf4, 0x0b, 0x9e, 0xc6, 0x89, 0xe1,
-	0xa0, 0x5a, 0x51, 0xe5, 0x14, 0x1b, 0x09, 0x9d, 0xe8, 0x23, 0x98, 0x66, 0x48, 0x33, 0x74, 0x1c,
-	0xcb, 0xe9, 0x56, 0xa6, 0xa8, 0x91, 0x27, 0xd3, 0x8c, 0x70, 0x96, 0xc6, 0x93, 0xc3, 0x41, 0xf5,
-	0x09, 0x45, 0x4a, 0x31, 0xa1, 0x2a, 0x24, 0x11, 0x83, 0x01, 0xf1, 0xc4, 0x4e, 0xa7, 0x45, 0x8c,
-	0x35, 0x95, 0x89, 0x45, 0x8c, 0x84, 0xa4, 0x1a, 0x31, 0x12, 0xc4, 0x78, 0x3e, 0xf8, 0x24, 0xcf,
-	0x8c, 0x9f, 0x0f, 0x3e, 0xcf, 0xd2, 0x7c, 0xa4, 0x4c, 0xb5, 0xa2, 0x0d, 0x7d, 0x02, 0xe4, 0xc3,
-	0x73, 0x3e, 0xec, 0xdb, 0x56, 0xc7, 0x08, 0xf0, 0x79, 0x1c, 0xe0, 0x0e, 0x89, 0xd4, 0xb3, 0xd4,
-	0x8a, 0x3e, 0x62, 0x65, 0x84, 0xb3, 0xa1, 0x0f, 0x07, 0xd5, 0xa5, 0x34, 0x1d, 0x8a, 0xd5, 0x54,
-	0x2b, 0xe8, 0x7f, 0x34, 0x98, 0xf7, 0x03, 0xc3, 0x31, 0x0d, 0xdb, 0x75, 0xf0, 0x25, 0xa7, 0xeb,
-	0x61, 0xdf, 0xbf, 0xe4, 0x6c, 0xbb, 0x95, 0x32, 0xb5, 0x7f, 0x3a, 0x11, 0xd6, 0xd3, 0x58, 0x1b,
-	0xa7, 0x87, 0x83, 0x6a, 0x35, 0x55, 0x8b, 0xe2, 0x41, 0xba, 0x21, 0xb4, 0x0f, 0xc7, 0x44, 0x56,
-	0xb1, 0x15, 0x58, 0xb6, 0xe5, 0x1b, 0x81, 0xe5, 0x3a, 0x95, 0xa3, 0xd4, 0xfe, 0xa9, 0x64, 0x74,
-	0x1c, 0x61, 0x6c, 0x9c, 0x1a, 0x0e, 0xaa, 0x27, 0x53, 0x34, 0x28, 0xb6, 0xd3, 0x4c, 0xc4, 0x4b,
-	0x68, 0xc3, 0xc3, 0x84, 0x11, 0x9b, 0x95, 0x63, 0xe3, 0x97, 0x50, 0xc4, 0x24, 0x2f, 0xa1, 0x08,
-	0x4c, 0x5b, 0x42, 0x11, 0x91, 0x58, 0xea, 0x1b, 0x5e, 0x60, 0x11, 0xb3, 0xeb, 0x86, 0xb7, 0x8b,
-	0xbd, 0xca, 0x5c, 0x9a, 0xa5, 0x0d, 0x95, 0x89, 0x59, 0x4a, 0x48, 0xaa, 0x96, 0x12, 0x44, 0x74,
-	0x4b, 0x03, 0xd5, 0x35, 0xcb, 0x75, 0x9a, 0x24, 0x6d, 0xf0, 0xc9, 0xeb, 0xcd, 0x53, 0xa3, 0x4f,
-	0xdf, 0xe6, 0xf5, 0x64, 0xf6, 0xc6, 0xd3, 0xc3, 0x41, 0xf5, 0xf4, 0x58, 0x6d, 0x8a, 0x23, 0xe3,
-	0x8d, 0xa2, 0xeb, 0x50, 0x22, 0x44, 0x4c, 0x13, 0x30, 0xb3, 0xb2, 0x40, 0x7d, 0x38, 0x3e, 0xea,
-	0x03, 0x67, 0xa0, 0x19, 0xc8, 0xbc, 0x24, 0xa1, 0xd8, 0x91, 0x55, 0x35, 0xf2, 0x30, 0x49, 0xe5,
-	0xf5, 0x61, 0x0e, 0x8e, 0xa5, 0xac, 0x0d, 0xf4, 0x16, 0xe4, 0xbc, 0xd0, 0x21, 0x09, 0x1b, 0xcb,
-	0x52, 0x90, 0x6a, 0x75, 0x2b, 0xb4, 0x4c, 0x96, 0x2d, 0x7a, 0xa1, 0xa3, 0xe4, 0x70, 0x93, 0x14,
-	0x20, 0xf2, 0x24, 0x5b, 0xb4, 0x4c, 0x9e, 0x8d, 0x8c, 0x95, 0xbf, 0xe1, 0xb6, 0x55, 0x79, 0x0a,
-	0x20, 0x0c, 0xd3, 0x62, 0xe1, 0xb5, 0x2c, 0xb2, 0xab, 0x58, 0x9e, 0xf1, 0x94, 0xaa, 0xe6, 0xdd,
-	0xb0, 0x8d, 0x3d, 0x07, 0x07, 0xd8, 0x17, 0xef, 0x40, 0xb7, 0x15, 0x8d, 0x22, 0x9e, 0x84, 0x48,
-	0xfa, 0xa7, 0x64, 0x1c, 0x7d, 0xa1, 0x41, 0xa5, 0x67, 0xec, 0xb7, 0x04, 0xe8, 0xb7, 0xb6, 0x5d,
-	0xaf, 0xd5, 0xc7, 0x9e, 0xe5, 0x9a, 0x34, 0xf9, 0x2c, 0x9d, 0xfd, 0x8f, 0x3b, 0x6e, 0xa4, 0xda,
-	0xba, 0xb1, 0x2f, 0x60, 0xff, 0x1d, 0xd7, 0xdb, 0xa0, 0xe2, 0xab, 0x4e, 0xe0, 0x1d, 0x34, 0x4e,
-	0x7e, 0x3d, 0xa8, 0x1e, 0x21, 0xd3, 0xd2, 0x4b, 0xe3, 0x69, 0xa6, 0xc3, 0xe8, 0x87, 0x1a, 0x2c,
-	0x04, 0x6e, 0x60, 0xd8, 0xad, 0x4e, 0xd8, 0x0b, 0x6d, 0x23, 0xb0, 0xf6, 0x70, 0x2b, 0xf4, 0x8d,
-	0x2e, 0xe6, 0x39, 0xee, 0x9b, 0x77, 0x76, 0xea, 0x1a, 0x91, 0x3f, 0x17, 0x89, 0x6f, 0x11, 0x69,
-	0xe6, 0xd3, 0x09, 0xee, 0xd3, 0x5c, 0x90, 0xc2, 0xd2, 0x4c, 0x45, 0x17, 0x7f, 0xaa, 0xc1, 0xe2,
-	0xf8, 0xd7, 0x44, 0xa7, 0x21, 0xbb, 0x8b, 0x0f, 0x78, 0x15, 0x71, 0x74, 0x38, 0xa8, 0x4e, 0xef,
-	0xe2, 0x03, 0x69, 0xd4, 0x09, 0x15, 0xfd, 0x17, 0x4c, 0xee, 0x19, 0x76, 0x88, 0xf9, 0x92, 0xa8,
-	0xd5, 0x58, 0xbd, 0x54, 0x93, 0xeb, 0xa5, 0x5a, 0x7f, 0xb7, 0x4b, 0x80, 0x9a, 0x98, 0x91, 0xda,
-	0x7b, 0xa1, 0xe1, 0x04, 0x56, 0x70, 0xc0, 0x96, 0x0b, 0x55, 0x20, 0x2f, 0x17, 0x0a, 0xbc, 0x91,
-	0x79, 0x4d, 0x5b, 0xfc, 0x52, 0x83, 0xe3, 0x63, 0x5f, 0xfa, 0xfb, 0xe0, 0xa1, 0xde, 0x82, 0x09,
-	0xb2, 0xf0, 0x49, 0x7d, 0xb3, 0x63, 0x75, 0x77, 0x5e, 0x7d, 0x99, 0xba, 0x93, 0x63, 0xe5, 0x08,
-	0x43, 0xe4, 0x72, 0x84, 0x21, 0xa4, 0x46, 0xb3, 0xdd, 0x9b, 0xaf, 0xbe, 0x4c, 0x9d, 0xca, 0x31,
-	0x23, 0x14, 0x90, 0x8d, 0x50, 0x40, 0xff, 0x7b, 0x0e, 0x8a, 0x51, 0x01, 0x21, 0xed, 0x41, 0xed,
-	0x9e, 0xf6, 0xe0, 0x45, 0x28, 0x9b, 0xd8, 0xe4, 0x5f, 0x3e, 0xcb, 0x75, 0xc4, 0x6e, 0x2e, 0xb2,
-	0xe8, 0xaa, 0xd0, 0x14, 0xf9, 0xd9, 0x04, 0x09, 0x9d, 0x85, 0x02, 0x4f, 0xb4, 0x0f, 0xe8, 0x46,
-	0x9e, 0x6e, 0x2c, 0x0c, 0x07, 0x55, 0x24, 0x30, 0x49, 0x34, 0xe2, 0x43, 0x4d, 0x00, 0x56, 0xbd,
-	0xae, 0xe3, 0xc0, 0xe0, 0x29, 0x7f, 0x45, 0x7d, 0x83, 0xab, 0x11, 0x9d, 0xd5, 0xa1, 0x31, 0xbf,
-	0x5c, 0x87, 0xc6, 0x28, 0xfa, 0x10, 0xa0, 0x67, 0x58, 0x0e, 0x93, 0xe3, 0xf9, 0xbd, 0x3e, 0x2e,
-	0xa4, 0xac, 0x47, 0x9c, 0x4c, 0x7b, 0x2c, 0x29, 0x6b, 0x8f, 0x51, 0x52, 0x2d, 0xf2, 0x7a, 0xbb,
-	0x92, 0xa3, 0xbb, 0x74, 0x69, 0x9c, 0x6a, 0xae, 0x76, 0x9e, 0x54, 0x8c, 0x5c, 0x44, 0xd2, 0x29,
-	0xb4, 0x90, 0x61, 0xb3, 0xad, 0x6d, 0x1c, 0x58, 0x3d, 0x4c, 0x33, 0x7b, 0x3e, 0x6c, 0x02, 0x93,
-	0x87, 0x4d, 0x60, 0xe8, 0x35, 0x00, 0x23, 0x58, 0x77, 0xfd, 0xe0, 0xaa, 0xd3, 0xc1, 0x34, 0x63,
-	0x2f, 0x30, 0xf7, 0x63, 0x54, 0x76, 0x3f, 0x46, 0xd1, 0x9b, 0x50, 0xea, 0xf3, 0x8f, 0x50, 0xdb,
-	0xc6, 0x34, 0x23, 0x2f, 0xb0, 0x4f, 0x8a, 0x04, 0x4b, 0xb2, 0x32, 0x37, 0xba, 0x00, 0xb3, 0x1d,
-	0xd7, 0xe9, 0x84, 0x9e, 0x87, 0x9d, 0xce, 0xc1, 0xa6, 0xb1, 0x8d, 0x69, 0xf6, 0x5d, 0x60, 0x4b,
-	0x25, 0x41, 0x92, 0x97, 0x4a, 0x82, 0x84, 0x5e, 0x81, 0x62, 0xd4, 0xbd, 0xa0, 0x09, 0x76, 0x91,
-	0x17, 0xc2, 0x02, 0x94, 0x84, 0x63, 0x4e, 0xe2, 0xbc, 0xe5, 0x47, 0x59, 0x1a, 0x4d, 0x9a, 0xb9,
-	0xf3, 0x12, 0x2c, 0x3b, 0x2f, 0xc1, 0xe8, 0x12, 0x1c, 0xa5, 0xdf, 0xc5, 0x56, 0x10, 0xd8, 0x2d,
-	0x1f, 0x77, 0x5c, 0xc7, 0xf4, 0x69, 0x4e, 0x9c, 0x65, 0xee, 0x53, 0xe2, 0xb5, 0xc0, 0xde, 0x64,
-	0x24, 0xd9, 0xfd, 0x04, 0x49, 0xff, 0xb5, 0x06, 0x73, 0x69, 0x4b, 0x28, 0xb1, 0x9c, 0xb5, 0x07,
-	0xb2, 0x9c, 0xdf, 0x87, 0x42, 0xdf, 0x35, 0x5b, 0x7e, 0x1f, 0x77, 0x78, 0xc4, 0x4a, 0x2c, 0xe6,
-	0x0d, 0xd7, 0xdc, 0xec, 0xe3, 0xce, 0x7f, 0x5a, 0xc1, 0xce, 0xca, 0x9e, 0x6b, 0x99, 0x97, 0x2d,
-	0x9f, 0xaf, 0xba, 0x3e, 0xa3, 0x28, 0x19, 0x42, 0x9e, 0x83, 0x8d, 0x02, 0xe4, 0x98, 0x15, 0xfd,
-	0x37, 0x59, 0x28, 0x27, 0x97, 0xed, 0xbf, 0xd2, 0xab, 0xa0, 0xeb, 0x90, 0xb7, 0x58, 0xca, 0xcc,
-	0x33, 0x88, 0x7f, 0x93, 0x62, 0x7a, 0x2d, 0x6e, 0xf8, 0xd5, 0xf6, 0x5e, 0xac, 0xf1, 0xdc, 0x9a,
-	0x0e, 0x01, 0xd5, 0xcc, 0x25, 0x55, 0xcd, 0x1c, 0x44, 0x4d, 0xc8, 0xfb, 0xd8, 0xdb, 0xb3, 0x3a,
-	0x98, 0x07, 0xa7, 0xaa, 0xac, 0xb9, 0xe3, 0x7a, 0x98, 0xe8, 0xdc, 0x64, 0x2c, 0xb1, 0x4e, 0x2e,
-	0xa3, 0xea, 0xe4, 0x20, 0x7a, 0x1f, 0x8a, 0x1d, 0xd7, 0xd9, 0xb6, 0xba, 0xeb, 0x46, 0x9f, 0x87,
-	0xa7, 0x93, 0x69, 0x5a, 0xcf, 0x09, 0x26, 0xde, 0x84, 0x10, 0x8f, 0x89, 0x26, 0x44, 0xc4, 0x15,
-	0x4f, 0xe8, 0x9f, 0x27, 0x00, 0xe2, 0xc9, 0x41, 0xaf, 0x43, 0x09, 0xef, 0xe3, 0x4e, 0x18, 0xb8,
-	0x9e, 0xf8, 0x4e, 0xf0, 0x9e, 0x9e, 0x80, 0x95, 0xc0, 0x0e, 0x31, 0x4a, 0x36, 0xaa, 0x63, 0xf4,
-	0xb0, 0xdf, 0x37, 0x3a, 0xa2, 0x19, 0x48, 0x9d, 0x89, 0x40, 0x79, 0xa3, 0x46, 0x20, 0xfa, 0x77,
-	0x98, 0xa0, 0xed, 0x43, 0xd6, 0x07, 0x44, 0xc3, 0x41, 0x75, 0xc6, 0x51, 0x1b, 0x87, 0x94, 0x8e,
-	0xde, 0x86, 0xe9, 0xdd, 0x68, 0xe1, 0x11, 0xdf, 0x26, 0xa8, 0x00, 0x4d, 0xed, 0x62, 0x82, 0xe2,
-	0xdd, 0x94, 0x8c, 0xa3, 0x6d, 0x28, 0x19, 0x8e, 0xe3, 0x06, 0xf4, 0x1b, 0x24, 0x7a, 0x83, 0xcf,
-	0x8c, 0x5b, 0xa6, 0xb5, 0x95, 0x98, 0x97, 0x65, 0x49, 0x34, 0x78, 0x48, 0x1a, 0xe4, 0xe0, 0x21,
-	0xc1, 0xa8, 0x09, 0x39, 0xdb, 0x68, 0x63, 0x5b, 0x04, 0xfd, 0xa7, 0xc6, 0x9a, 0xb8, 0x4c, 0xd9,
-	0x98, 0x76, 0xfa, 0xc9, 0x67, 0x72, 0xf2, 0x27, 0x9f, 0x21, 0x8b, 0xdb, 0x50, 0x4e, 0xfa, 0x73,
-	0xb8, 0x04, 0xe6, 0x19, 0x39, 0x81, 0x29, 0xde, 0x31, 0x65, 0x32, 0xa0, 0x24, 0x39, 0xf5, 0x30,
-	0x4c, 0xe8, 0x3f, 0xd3, 0x60, 0x2e, 0x6d, 0xef, 0xa2, 0x75, 0x69, 0xc7, 0x6b, 0xbc, 0xc7, 0x91,
-	0xb2, 0xd4, 0xb9, 0xec, 0x98, 0xad, 0x1e, 0x6f, 0xf4, 0x06, 0xcc, 0x38, 0xae, 0x89, 0x5b, 0x06,
-	0x31, 0x60, 0x5b, 0x7e, 0x50, 0xc9, 0xd0, 0xde, 0x31, 0xed, 0x8d, 0x10, 0xca, 0x8a, 0x20, 0x48,
-	0xd2, 0xd3, 0x0a, 0x41, 0xff, 0x7f, 0x0d, 0x66, 0x13, 0xad, 0xcb, 0xfb, 0x4e, 0xa2, 0xe4, 0xd4,
-	0x27, 0x73, 0xb8, 0xd4, 0x47, 0xff, 0x51, 0x06, 0x4a, 0x52, 0x5d, 0x77, 0xdf, 0x3e, 0xdc, 0x80,
-	0x59, 0xfe, 0xa5, 0xb4, 0x9c, 0x2e, 0x2b, 0xa7, 0x32, 0xbc, 0x49, 0x31, 0x72, 0x52, 0xb0, 0xe6,
-	0xb6, 0x37, 0x23, 0x5e, 0x5a, 0x4d, 0xd1, 0x0e, 0x96, 0xaf, 0x60, 0x92, 0x89, 0x19, 0x95, 0x82,
-	0xae, 0xc3, 0x42, 0xd8, 0x37, 0x8d, 0x00, 0xb7, 0x7c, 0xde, 0x73, 0x6f, 0x39, 0x61, 0xaf, 0x8d,
-	0x3d, 0xba, 0xe3, 0x27, 0x59, 0xcf, 0x85, 0x71, 0x88, 0xa6, 0xfc, 0x15, 0x4a, 0x97, 0x74, 0xce,
-	0xa5, 0xd1, 0xf5, 0x8b, 0x80, 0x46, 0xfb, 0xca, 0xca, 0xf8, 0x6a, 0x87, 0x1c, 0xdf, 0xcf, 0x34,
-	0x28, 0x27, 0xdb, 0xc5, 0x8f, 0x64, 0xa2, 0x0f, 0xa0, 0x18, 0xb5, 0x7e, 0xef, 0xdb, 0x81, 0xe7,
-	0x20, 0xe7, 0x61, 0xc3, 0x77, 0x1d, 0xbe, 0x33, 0x69, 0x88, 0x61, 0x88, 0x1c, 0x62, 0x18, 0xa2,
-	0x5f, 0x83, 0x29, 0x36, 0x82, 0xef, 0x58, 0x76, 0x80, 0x3d, 0x74, 0x1e, 0x72, 0x7e, 0x60, 0x04,
-	0xd8, 0xaf, 0x68, 0xcb, 0xd9, 0x33, 0x33, 0x67, 0x17, 0x46, 0xbb, 0xbc, 0x84, 0xcc, 0xb4, 0x32,
-	0x4e, 0x59, 0x2b, 0x43, 0xf4, 0xff, 0xd5, 0x60, 0x4a, 0x6e, 0x66, 0x3f, 0x18, 0xb5, 0x77, 0xf9,
-	0x6a, 0x9f, 0x08, 0x1f, 0xec, 0x07, 0x33, 0xb3, 0x77, 0x67, 0xfd, 0x17, 0x1a, 0x1b, 0xd9, 0xa8,
-	0x0b, 0x7a, 0xbf, 0xe6, 0xbb, 0x71, 0x2b, 0x84, 0xec, 0x30, 0x9f, 0x06, 0xb6, 0xc3, 0xb6, 0x42,
-	0x68, 0xf8, 0x53, 0xc4, 0xe5, 0xf0, 0xa7, 0x10, 0xf4, 0x2f, 0x26, 0xa9, 0xe7, 0x71, 0xc7, 0xfb,
-	0x51, 0x37, 0x81, 0x12, 0xd9, 0x49, 0xf6, 0x2e, 0xb2, 0x93, 0xe7, 0x21, 0x4f, 0x3f, 0x07, 0x51,
-	0xe2, 0x40, 0x27, 0x8d, 0x40, 0xea, 0x89, 0x23, 0x43, 0x6e, 0x13, 0xb5, 0x26, 0xef, 0x2f, 0x6a,
-	0xa1, 0x16, 0x1c, 0xdf, 0x31, 0xfc, 0x96, 0x88, 0xb3, 0x66, 0xcb, 0x08, 0x5a, 0x51, 0x9c, 0xc8,
-	0xd1, 0x32, 0xe5, 0xa9, 0xe1, 0xa0, 0xba, 0xbc, 0x63, 0xf8, 0x9b, 0x82, 0x67, 0x25, 0xd8, 0x18,
-	0x8d, 0x1a, 0x0b, 0xe9, 0x1c, 0x68, 0x0b, 0xe6, 0xd3, 0x95, 0xe7, 0xa9, 0xe7, 0xb4, 0xc9, 0xeb,
-	0xdf, 0x56, 0xf3, 0xb1, 0x14, 0x32, 0xfa, 0x54, 0x83, 0x0a, 0xf9, 0x3e, 0x7b, 0xf8, 0xe3, 0xd0,
-	0xf2, 0x70, 0x8f, 0xcc, 0x58, 0xcb, 0xdd, 0xc3, 0x9e, 0x6d, 0x1c, 0xf0, 0xd3, 0x9a, 0x53, 0xa3,
-	0x5f, 0x8f, 0x0d, 0xd7, 0x6c, 0x4a, 0x02, 0xec, 0xd5, 0xfa, 0x2a, 0x78, 0x95, 0x29, 0x91, 0x5f,
-	0x2d, 0x9d, 0x63, 0x6d, 0xa2, 0x50, 0x28, 0x17, 0xf5, 0xbf, 0x6a, 0x30, 0xa3, 0x1e, 0xaa, 0x3c,
-	0xf2, 0x85, 0x39, 0xb2, 0x25, 0xb3, 0x0f, 0x69, 0x4b, 0xfe, 0x45, 0x83, 0x69, 0xe5, 0xac, 0xe7,
-	0xf1, 0x79, 0xf5, 0x1f, 0x67, 0x60, 0x21, 0x5d, 0xcd, 0x43, 0x29, 0x40, 0x2f, 0x02, 0x49, 0x25,
-	0x2f, 0xc5, 0xb9, 0xd1, 0xfc, 0x48, 0xfd, 0x49, 0x5f, 0x41, 0xe4, 0xa1, 0x23, 0x87, 0x34, 0x42,
-	0x1c, 0x5d, 0x87, 0x92, 0x25, 0x1d, 0x07, 0x65, 0xd3, 0xba, 0xf6, 0xf2, 0x21, 0x10, 0xeb, 0x52,
-	0x8c, 0x39, 0xfa, 0x91, 0x55, 0x35, 0x72, 0x30, 0x41, 0x92, 0x37, 0x7d, 0x0f, 0xf2, 0xdc, 0x1d,
-	0xf4, 0x12, 0x14, 0x69, 0x9c, 0xa3, 0x35, 0x15, 0x4b, 0xdc, 0x69, 0xda, 0x41, 0xc0, 0xc4, 0x85,
-	0x8c, 0x82, 0xc0, 0xd0, 0xab, 0x00, 0x64, 0x6b, 0xf3, 0x08, 0x97, 0xa1, 0x71, 0x82, 0xd6, 0x6e,
-	0x7d, 0xd7, 0x1c, 0x09, 0x6b, 0xc5, 0x08, 0xd4, 0x7f, 0x9e, 0x81, 0x92, 0x7c, 0x00, 0x75, 0x4f,
-	0xc6, 0x3f, 0x01, 0x51, 0x57, 0xb7, 0x0c, 0xd3, 0x24, 0x7f, 0xb1, 0xf8, 0xa4, 0xd5, 0xc7, 0x0e,
-	0x92, 0xf8, 0x7f, 0x45, 0x48, 0xb0, 0x2a, 0x8a, 0x1e, 0xf1, 0x5b, 0x09, 0x92, 0x64, 0xb5, 0x9c,
-	0xa4, 0x2d, 0xee, 0xc2, 0x7c, 0xaa, 0x2a, 0xb9, 0xf6, 0x99, 0x7c, 0x50, 0xb5, 0xcf, 0x2f, 0x27,
-	0x61, 0x3e, 0xf5, 0xe0, 0xef, 0x91, 0xef, 0x62, 0x75, 0x07, 0x65, 0x1f, 0xc8, 0x0e, 0xfa, 0x4c,
-	0x4b, 0x9b, 0x59, 0x76, 0x88, 0xf2, 0xfa, 0x21, 0x4e, 0x43, 0x1f, 0xd4, 0x1c, 0xab, 0xcb, 0x72,
-	0xf2, 0x9e, 0xf6, 0x44, 0xee, 0xb0, 0x7b, 0x02, 0xbd, 0xc0, 0xca, 0x58, 0x6a, 0x2b, 0x4f, 0x6d,
-	0x89, 0x08, 0x91, 0x30, 0x95, 0xe7, 0x10, 0x7a, 0x1b, 0xa6, 0x85, 0x04, 0x6b, 0x9e, 0x14, 0xe2,
-	0xce, 0x06, 0xe7, 0x49, 0xf6, 0x4f, 0xa6, 0x64, 0xfc, 0x9f, 0xbb, 0x86, 0xff, 0xa6, 0xc1, 0x6c,
-	0xe2, 0x26, 0xc0, 0xe3, 0xf3, 0x0d, 0xfa, 0x5c, 0x83, 0x62, 0x74, 0x09, 0xe5, 0xbe, 0x13, 0xf9,
-	0x15, 0xc8, 0x61, 0x76, 0x11, 0x82, 0x85, 0xbb, 0x63, 0x89, 0x8b, 0x6a, 0x84, 0xc6, 0xaf, 0xa6,
-	0x25, 0xee, 0x3e, 0x34, 0xb9, 0xa0, 0xfe, 0x5b, 0x4d, 0xa4, 0xe8, 0xb1, 0x4f, 0x8f, 0x74, 0x2a,
-	0xe2, 0x77, 0xca, 0xde, 0xeb, 0x3b, 0xfd, 0xaa, 0x08, 0x93, 0x94, 0x8f, 0x94, 0xd0, 0x01, 0xf6,
-	0x7a, 0x96, 0x63, 0xd8, 0xf4, 0x75, 0x0a, 0x6c, 0xdf, 0x0a, 0x4c, 0xde, 0xb7, 0x02, 0x43, 0x3b,
-	0x30, 0x1b, 0xb7, 0xfd, 0xa8, 0x9a, 0xf4, 0xfb, 0x6f, 0xef, 0xaa, 0x4c, 0xac, 0xb1, 0x9f, 0x90,
-	0x54, 0x2f, 0x08, 0x24, 0x88, 0xc8, 0x84, 0x99, 0x8e, 0xeb, 0x04, 0x86, 0xe5, 0x60, 0x8f, 0x19,
-	0xca, 0xa6, 0xdd, 0xff, 0x39, 0xa7, 0xf0, 0xb0, 0xee, 0x89, 0x2a, 0xa7, 0xde, 0xff, 0x51, 0x69,
-	0xe8, 0x23, 0x98, 0x16, 0x65, 0x0c, 0x33, 0x32, 0x91, 0x76, 0xff, 0x67, 0x55, 0x66, 0x61, 0x4b,
-	0x5a, 0x91, 0x52, 0xef, 0xff, 0x28, 0x24, 0x64, 0x43, 0xb9, 0xef, 0x9a, 0x5b, 0x0e, 0x4f, 0xde,
-	0x8d, 0xb6, 0x8d, 0x79, 0xaf, 0x79, 0x69, 0x24, 0xe5, 0x51, 0xb8, 0x58, 0x28, 0x4e, 0xca, 0xaa,
-	0x37, 0xea, 0x92, 0x54, 0xf4, 0x21, 0x4c, 0xd9, 0xa4, 0x9a, 0x5c, 0xdd, 0xef, 0x5b, 0x1e, 0x36,
-	0xd3, 0xef, 0xbf, 0x5d, 0x96, 0x38, 0x58, 0x20, 0x94, 0x65, 0xd4, 0x3b, 0x40, 0x32, 0x85, 0xcc,
-	0x7e, 0xcf, 0xd8, 0x6f, 0x86, 0x8e, 0xbf, 0xba, 0xcf, 0xef, 0x32, 0xe5, 0xd3, 0x66, 0x7f, 0x5d,
-	0x65, 0x62, 0xb3, 0x9f, 0x90, 0x54, 0x67, 0x3f, 0x41, 0x44, 0x97, 0x69, 0x9c, 0x67, 0x53, 0xc2,
-	0xee, 0xc1, 0x2d, 0x8c, 0x8c, 0x16, 0x9b, 0x0d, 0xd6, 0xf6, 0xe1, 0x4f, 0x8a, 0xd2, 0x48, 0x03,
-	0x9f, 0x03, 0xfa, 0xda, 0x4d, 0x1c, 0x84, 0x9e, 0x83, 0x4d, 0x5e, 0x54, 0x8d, 0xce, 0x81, 0xc2,
-	0x15, 0xcd, 0x81, 0x82, 0x8e, 0xcc, 0x81, 0x42, 0x25, 0x6b, 0xaa, 0xef, 0x9a, 0xd7, 0xd8, 0x96,
-	0x09, 0xa2, 0x8b, 0x71, 0x4f, 0x8e, 0x98, 0x8a, 0x59, 0xd8, 0x9a, 0x52, 0xa4, 0xd4, 0x35, 0xa5,
-	0x90, 0xf8, 0x5d, 0x2c, 0xf9, 0xe6, 0x0e, 0x1b, 0xa9, 0xd2, 0x98, 0xbb, 0x58, 0x23, 0x9c, 0xd1,
-	0x5d, 0xac, 0x11, 0xca, 0xc8, 0x5d, 0xac, 0x11, 0x0e, 0x62, 0xbd, 0x6b, 0x38, 0xdd, 0x35, 0xb7,
-	0xad, 0xae, 0xea, 0xa9, 0x34, 0xeb, 0x17, 0x52, 0x38, 0x99, 0xf5, 0x34, 0x1d, 0xaa, 0xf5, 0x34,
-	0x8e, 0x46, 0x41, 0xb4, 0x87, 0xf4, 0x2f, 0x35, 0x98, 0x4d, 0xc4, 0x19, 0xf4, 0x16, 0x44, 0x37,
-	0x4e, 0xae, 0x1d, 0xf4, 0x45, 0x9a, 0xac, 0xdc, 0x50, 0x21, 0x78, 0xda, 0x0d, 0x15, 0x82, 0xa3,
-	0xcb, 0x00, 0xd1, 0x37, 0xe9, 0x76, 0x41, 0x9a, 0xe6, 0x68, 0x31, 0xa7, 0x9c, 0xa3, 0xc5, 0xa8,
-	0xfe, 0x4d, 0x16, 0x0a, 0x62, 0xa1, 0x3e, 0x94, 0x32, 0xaa, 0x0e, 0xf9, 0x1e, 0xf6, 0xe9, 0x4d,
-	0x95, 0x4c, 0x9c, 0x0d, 0x71, 0x48, 0xce, 0x86, 0x38, 0xa4, 0x26, 0x6b, 0xd9, 0x7b, 0x4a, 0xd6,
-	0x26, 0x0e, 0x9d, 0xac, 0x61, 0x7a, 0x4a, 0x2d, 0x85, 0x5b, 0x71, 0x2e, 0x74, 0xfb, 0x18, 0x2e,
-	0xce, 0xb0, 0x65, 0xc1, 0xc4, 0x19, 0xb6, 0x4c, 0x42, 0xbb, 0x70, 0x54, 0x3a, 0xbb, 0xe2, 0xbd,
-	0x43, 0x12, 0xf8, 0x66, 0xc6, 0x5f, 0x09, 0x68, 0x52, 0x2e, 0xb6, 0xbd, 0x77, 0x13, 0xa8, 0x9c,
-	0xed, 0x26, 0x69, 0xfa, 0x1f, 0x33, 0x30, 0xa3, 0xfa, 0xfb, 0x50, 0x26, 0xf6, 0x25, 0x28, 0xe2,
-	0x7d, 0x2b, 0x68, 0x75, 0x5c, 0x13, 0xf3, 0x92, 0x91, 0xce, 0x13, 0x01, 0xcf, 0xb9, 0xa6, 0x32,
-	0x4f, 0x02, 0x93, 0x57, 0x43, 0xf6, 0x50, 0xab, 0x21, 0x6e, 0xb5, 0x4e, 0xdc, 0xb9, 0xd5, 0x9a,
-	0x3e, 0xce, 0xc5, 0x87, 0x34, 0xce, 0xb7, 0x32, 0x50, 0x4e, 0x46, 0xe3, 0xef, 0xc7, 0x16, 0x52,
-	0x77, 0x43, 0xf6, 0xd0, 0xbb, 0xe1, 0x6d, 0x98, 0x26, 0xb9, 0xa3, 0x11, 0x04, 0xfc, 0x0e, 0xe7,
-	0x04, 0xcd, 0xb9, 0x58, 0x6c, 0x0a, 0x9d, 0x15, 0x81, 0x2b, 0xb1, 0x49, 0xc2, 0xf5, 0x4f, 0x33,
-	0x30, 0xad, 0x7c, 0x35, 0x1e, 0xbf, 0x90, 0xa2, 0xcf, 0xc2, 0xb4, 0x92, 0x8c, 0xe9, 0xff, 0xc7,
-	0xd6, 0x89, 0x9a, 0x05, 0x3d, 0x7e, 0xe3, 0x32, 0x03, 0x53, 0x72, 0x56, 0xa7, 0x37, 0x60, 0x36,
-	0x91, 0x84, 0xc9, 0x2f, 0xa0, 0x1d, 0xe6, 0x05, 0xf4, 0x05, 0x98, 0x4b, 0xcb, 0x1d, 0xf4, 0x0b,
-	0x30, 0x97, 0xf6, 0x55, 0xbf, 0x7b, 0x03, 0x5f, 0x69, 0xd4, 0xc2, 0xe8, 0x6d, 0xef, 0x8b, 0x00,
-	0x0e, 0xbe, 0xd9, 0xba, 0x63, 0xf9, 0xc7, 0xc6, 0x13, 0xdf, 0x5c, 0x4b, 0x54, 0x4b, 0x05, 0x81,
-	0x11, 0x4d, 0xae, 0x6d, 0xb6, 0xee, 0x58, 0x74, 0x51, 0x4d, 0xae, 0x6d, 0x8e, 0x68, 0x12, 0x98,
-	0xfe, 0x83, 0xac, 0xa8, 0xcc, 0xe3, 0xeb, 0xd2, 0x1f, 0x40, 0xb9, 0x2f, 0x1e, 0xee, 0xec, 0x2d,
-	0xad, 0x4d, 0x22, 0xfe, 0xa4, 0xa5, 0x19, 0x95, 0xa2, 0xea, 0xe6, 0x45, 0x67, 0xe6, 0x90, 0xba,
-	0x9b, 0x89, 0xea, 0x73, 0x46, 0xa5, 0xa0, 0xff, 0x86, 0xa3, 0xe2, 0x36, 0xd9, 0x1e, 0x16, 0x8e,
-	0x67, 0xc7, 0x2a, 0x67, 0xb7, 0xbb, 0x23, 0x81, 0xa4, 0xe7, 0xb3, 0x09, 0x52, 0x42, 0x3d, 0xf7,
-	0x7d, 0xe2, 0xb0, 0xea, 0x93, 0xce, 0xcf, 0x26, 0x48, 0xfa, 0xe7, 0x1a, 0xcc, 0x26, 0x2e, 0xa0,
-	0xa3, 0xf3, 0x50, 0xa0, 0xbf, 0x4f, 0xbb, 0xfd, 0x0c, 0xd0, 0x05, 0x49, 0xf9, 0x14, 0x0b, 0x79,
-	0x0e, 0xa1, 0x57, 0xa0, 0x18, 0xdd, 0x53, 0xe7, 0xa7, 0xca, 0x6c, 0xf3, 0x09, 0x50, 0xd9, 0x7c,
-	0x02, 0xd4, 0x7f, 0xa2, 0xc1, 0xf1, 0xb1, 0x97, 0xd3, 0x1f, 0x75, 0xcf, 0xe0, 0xd9, 0x17, 0xa0,
-	0x20, 0xce, 0x7d, 0x11, 0x40, 0xee, 0xbd, 0xad, 0xd5, 0xad, 0xd5, 0xf3, 0xe5, 0x23, 0xa8, 0x04,
-	0xf9, 0x8d, 0xd5, 0x2b, 0xe7, 0x2f, 0x5d, 0xb9, 0x50, 0xd6, 0xc8, 0x43, 0x73, 0xeb, 0xca, 0x15,
-	0xf2, 0x90, 0x79, 0xf6, 0xb2, 0x7c, 0x0b, 0x8d, 0x7d, 0x8f, 0xd1, 0x14, 0x14, 0x56, 0xfa, 0x7d,
-	0x1a, 0x00, 0x98, 0xec, 0xea, 0x9e, 0x45, 0xf6, 0x6a, 0x59, 0x43, 0x79, 0xc8, 0x5e, 0xbd, 0xba,
-	0x5e, 0xce, 0xa0, 0x39, 0x28, 0x9f, 0xc7, 0x86, 0x69, 0x5b, 0x0e, 0x16, 0x51, 0xa7, 0x9c, 0x6d,
-	0xdc, 0xf8, 0xfa, 0xdb, 0x25, 0xed, 0x9b, 0x6f, 0x97, 0xb4, 0x3f, 0x7c, 0xbb, 0xa4, 0xdd, 0xfa,
-	0x6e, 0xe9, 0xc8, 0x37, 0xdf, 0x2d, 0x1d, 0xf9, 0xdd, 0x77, 0x4b, 0x47, 0x3e, 0x78, 0x41, 0xfa,
-	0x2d, 0x26, 0x7b, 0xa7, 0xbe, 0xe7, 0x92, 0x80, 0xcb, 0x9f, 0xea, 0xc9, 0x5f, 0x9f, 0x7e, 0x95,
-	0x39, 0xb9, 0x42, 0x1f, 0x37, 0x18, 0x5f, 0xed, 0x92, 0x5b, 0x63, 0x00, 0xfd, 0x01, 0xa1, 0xdf,
-	0xce, 0xd1, 0x1f, 0x0a, 0xbe, 0xf4, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x71, 0x86, 0xa5,
-	0xb8, 0x3a, 0x00, 0x00,
+	// 3635 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5b, 0x49, 0x6c, 0x1b, 0xd7,
+	0xf9, 0xf7, 0x90, 0x12, 0x97, 0x8f, 0x5a, 0xe8, 0x67, 0x49, 0xa6, 0x15, 0x5b, 0x94, 0xc7, 0xf9,
+	0xff, 0xe3, 0x04, 0x09, 0x95, 0x38, 0x0b, 0xb2, 0x14, 0x09, 0x44, 0x5b, 0xb1, 0xad, 0x58, 0xb6,
+	0x42, 0x59, 0xa9, 0x1b, 0xa4, 0x60, 0x86, 0x9c, 0x27, 0x6a, 0x2c, 0x72, 0x86, 0x99, 0x45, 0x96,
+	0x80, 0x1c, 0x9a, 0x22, 0x4d, 0x6f, 0xa9, 0x81, 0x06, 0x68, 0x81, 0x1e, 0xd2, 0x6b, 0x03, 0xf4,
+	0xdc, 0x73, 0x4f, 0xcd, 0xa1, 0x28, 0xd2, 0x5b, 0x4f, 0x6c, 0x91, 0xa0, 0x17, 0x1e, 0x8a, 0x1e,
+	0xdb, 0x5e, 0x5a, 0xbc, 0x6d, 0xe6, 0xbd, 0x99, 0xa1, 0x2d, 0x6f, 0x75, 0x0a, 0x9f, 0xa4, 0xf9,
+	0x7d, 0xeb, 0xdb, 0xbe, 0xf9, 0xbe, 0x6f, 0x1e, 0xe1, 0x44, 0x7f, 0xa7, 0xb3, 0x64, 0xb8, 0x3d,
+	0xc3, 0x34, 0xf0, 0x2e, 0xb6, 0x7d, 0x6f, 0x89, 0xfd, 0xa9, 0xf5, 0x5d, 0xc7, 0x77, 0xd0, 0x84,
+	0x4c, 0x9a, 0xd7, 0x77, 0x5e, 0xf6, 0x6a, 0x96, 0xb3, 0x64, 0xf4, 0xad, 0xa5, 0xb6, 0xe3, 0xe2,
+	0xa5, 0xdd, 0xe7, 0x96, 0x3a, 0xd8, 0xc6, 0xae, 0xe1, 0x63, 0x93, 0x49, 0xcc, 0x9f, 0x96, 0x78,
+	0x6c, 0xec, 0xdf, 0x70, 0xdc, 0x1d, 0xcb, 0xee, 0xa4, 0x71, 0x56, 0x3b, 0x8e, 0xd3, 0xe9, 0xe2,
+	0x25, 0xfa, 0xd4, 0x0a, 0xb6, 0x96, 0x7c, 0xab, 0x87, 0x3d, 0xdf, 0xe8, 0xf5, 0x39, 0xc3, 0x0b,
+	0x91, 0xaa, 0x9e, 0xd1, 0xde, 0xb6, 0x6c, 0xec, 0xee, 0x2f, 0x51, 0x7f, 0xfb, 0xd6, 0x92, 0x8b,
+	0x3d, 0x27, 0x70, 0xdb, 0x38, 0xa1, 0xf6, 0x99, 0x8e, 0xe5, 0x6f, 0x07, 0xad, 0x5a, 0xdb, 0xe9,
+	0x2d, 0x75, 0x9c, 0x8e, 0x13, 0xe9, 0x27, 0x4f, 0xf4, 0x81, 0xfe, 0xc7, 0xd9, 0x5f, 0xb5, 0x6c,
+	0x1f, 0xbb, 0xb6, 0xd1, 0x5d, 0xf2, 0xda, 0xdb, 0xd8, 0x0c, 0xba, 0xd8, 0x8d, 0xfe, 0x73, 0x5a,
+	0xd7, 0x71, 0xdb, 0xf7, 0x12, 0x00, 0x93, 0xd5, 0x7f, 0x36, 0x0b, 0x93, 0x2b, 0x64, 0x6a, 0x36,
+	0xf0, 0x07, 0x01, 0xb6, 0xdb, 0x18, 0x3d, 0x09, 0xe3, 0x1f, 0x04, 0x38, 0xc0, 0x15, 0x6d, 0x51,
+	0x3b, 0x5d, 0xac, 0x1f, 0x19, 0x0e, 0xaa, 0xd3, 0x14, 0x78, 0xda, 0xe9, 0x59, 0x3e, 0xee, 0xf5,
+	0xfd, 0xfd, 0x06, 0xe3, 0x40, 0xaf, 0xc2, 0xc4, 0x75, 0xa7, 0xd5, 0xf4, 0xb0, 0xdf, 0xb4, 0x8d,
+	0x1e, 0xae, 0x64, 0xa8, 0x44, 0x65, 0x38, 0xa8, 0xce, 0x5c, 0x77, 0x5a, 0x1b, 0xd8, 0xbf, 0x6c,
+	0xf4, 0x64, 0x31, 0x88, 0x50, 0xf4, 0x0c, 0xe4, 0x03, 0x0f, 0xbb, 0x4d, 0xcb, 0xac, 0x64, 0xa9,
+	0xd8, 0xcc, 0x70, 0x50, 0x2d, 0x13, 0xe8, 0xa2, 0x29, 0x89, 0xe4, 0x18, 0x82, 0x9e, 0x86, 0x5c,
+	0xc7, 0x75, 0x82, 0xbe, 0x57, 0x19, 0x5b, 0xcc, 0x0a, 0x6e, 0x86, 0xc8, 0xdc, 0x0c, 0x41, 0x57,
+	0x20, 0xc7, 0xd6, 0xbb, 0x32, 0xbe, 0x98, 0x3d, 0x5d, 0x3a, 0x73, 0xb2, 0x26, 0x6f, 0x82, 0x9a,
+	0x32, 0x60, 0xf6, 0xc4, 0x14, 0x32, 0xba, 0xac, 0x90, 0x6f, 0x9b, 0xbf, 0x23, 0x18, 0xa7, 0x7c,
+	0xe8, 0x0a, 0xe4, 0xdb, 0x2e, 0x26, 0x8b, 0x55, 0x41, 0x8b, 0xda, 0xe9, 0xd2, 0x99, 0xf9, 0x1a,
+	0xdb, 0x04, 0x35, 0xb1, 0x48, 0xb5, 0xab, 0x62, 0x13, 0xd4, 0x8f, 0x0d, 0x07, 0xd5, 0xc3, 0x9c,
+	0x3d, 0xd2, 0x7a, 0xf3, 0xcf, 0x55, 0xad, 0x21, 0xb4, 0xa0, 0x75, 0x28, 0x7a, 0x41, 0xab, 0x67,
+	0xf9, 0xab, 0x4e, 0x8b, 0xce, 0x79, 0xe9, 0xcc, 0x51, 0xd5, 0xdd, 0x0d, 0x41, 0xae, 0x1f, 0x1d,
+	0x0e, 0xaa, 0x47, 0x42, 0xee, 0x48, 0xe3, 0x85, 0x43, 0x8d, 0x48, 0x09, 0xda, 0x86, 0x69, 0x17,
+	0xf7, 0x5d, 0xcb, 0x71, 0x2d, 0xdf, 0xf2, 0x30, 0xd1, 0x9b, 0xa1, 0x7a, 0x4f, 0xa8, 0x7a, 0x1b,
+	0x2a, 0x53, 0xfd, 0xc4, 0x70, 0x50, 0x3d, 0x16, 0x93, 0x54, 0x6c, 0xc4, 0xd5, 0x22, 0x1f, 0x50,
+	0x0c, 0xda, 0xc0, 0x3e, 0x5d, 0xcf, 0xd2, 0x99, 0xc5, 0x5b, 0x1a, 0xdb, 0xc0, 0x7e, 0x7d, 0x71,
+	0x38, 0xa8, 0x1e, 0x4f, 0xca, 0x2b, 0x26, 0x53, 0xf4, 0xa3, 0x2e, 0x94, 0x65, 0xd4, 0x24, 0x03,
+	0x1c, 0xa3, 0x36, 0x17, 0x46, 0xdb, 0x24, 0x5c, 0xf5, 0x85, 0xe1, 0xa0, 0x3a, 0x1f, 0x97, 0x55,
+	0xec, 0x25, 0x34, 0x93, 0xf5, 0x69, 0x1b, 0x76, 0x1b, 0x77, 0x89, 0x99, 0xf1, 0xb4, 0xf5, 0x39,
+	0x2b, 0xc8, 0x6c, 0x7d, 0x42, 0x6e, 0x75, 0x7d, 0x42, 0x18, 0xbd, 0x07, 0x13, 0xe1, 0x03, 0x99,
+	0xaf, 0x1c, 0xdf, 0x47, 0xe9, 0x4a, 0xc9, 0x4c, 0xcd, 0x0f, 0x07, 0xd5, 0x39, 0x59, 0x46, 0x51,
+	0xad, 0x68, 0x8b, 0xb4, 0x77, 0xd9, 0xcc, 0xe4, 0x47, 0x6b, 0x67, 0x1c, 0xb2, 0xf6, 0x6e, 0x72,
+	0x46, 0x14, 0x6d, 0x44, 0x3b, 0x39, 0xc4, 0x41, 0xbb, 0x8d, 0xb1, 0x89, 0xcd, 0x4a, 0x21, 0x4d,
+	0xfb, 0xaa, 0xc4, 0xc1, 0xb4, 0xcb, 0x32, 0xaa, 0x76, 0x99, 0x42, 0xe6, 0xfa, 0xba, 0xd3, 0x5a,
+	0x71, 0x5d, 0xc7, 0xf5, 0x2a, 0xc5, 0xb4, 0xb9, 0x5e, 0x15, 0x64, 0x36, 0xd7, 0x21, 0xb7, 0x3a,
+	0xd7, 0x21, 0xcc, 0xfd, 0x6d, 0x04, 0xf6, 0x25, 0x6c, 0x78, 0xd8, 0xac, 0xc0, 0x08, 0x7f, 0x43,
+	0x8e, 0xd0, 0xdf, 0x10, 0x49, 0xf8, 0x1b, 0x52, 0x90, 0x09, 0x53, 0xec, 0x79, 0xd9, 0xf3, 0xac,
+	0x8e, 0x8d, 0xcd, 0x4a, 0x89, 0xea, 0x3f, 0x9e, 0xa6, 0x5f, 0xf0, 0xd4, 0x8f, 0x0f, 0x07, 0xd5,
+	0x8a, 0x2a, 0xa7, 0xd8, 0x88, 0xe9, 0x44, 0xef, 0xc3, 0x24, 0x43, 0x1a, 0x81, 0x6d, 0x5b, 0x76,
+	0xa7, 0x32, 0x41, 0x8d, 0x3c, 0x96, 0x66, 0x84, 0xb3, 0xd4, 0x1f, 0x1b, 0x0e, 0xaa, 0x47, 0x15,
+	0x29, 0xc5, 0x84, 0xaa, 0x90, 0x44, 0x0c, 0x06, 0x44, 0x0b, 0x3b, 0x99, 0x16, 0x31, 0x56, 0x55,
+	0x26, 0x16, 0x31, 0x62, 0x92, 0x6a, 0xc4, 0x88, 0x11, 0xa3, 0xf5, 0xe0, 0x8b, 0x3c, 0x35, 0x7a,
+	0x3d, 0xf8, 0x3a, 0x4b, 0xeb, 0x91, 0xb2, 0xd4, 0x8a, 0x36, 0xf4, 0x21, 0x90, 0x17, 0xcf, 0xb9,
+	0xa0, 0xdf, 0xb5, 0xda, 0x86, 0x8f, 0xcf, 0x61, 0x1f, 0xb7, 0x49, 0xa4, 0x9e, 0xa6, 0x56, 0xf4,
+	0x84, 0x95, 0x04, 0x67, 0x5d, 0x1f, 0x0e, 0xaa, 0x0b, 0x69, 0x3a, 0x14, 0xab, 0xa9, 0x56, 0xd0,
+	0x0f, 0x34, 0x98, 0xf5, 0x7c, 0xc3, 0x36, 0x8d, 0xae, 0x63, 0xe3, 0x8b, 0x76, 0xc7, 0xc5, 0x9e,
+	0x77, 0xd1, 0xde, 0x72, 0x2a, 0x65, 0x6a, 0xff, 0x54, 0x2c, 0xac, 0xa7, 0xb1, 0xd6, 0x4f, 0x0d,
+	0x07, 0xd5, 0x6a, 0xaa, 0x16, 0xc5, 0x83, 0x74, 0x43, 0x68, 0x0f, 0x8e, 0x88, 0xac, 0x62, 0xd3,
+	0xb7, 0xba, 0x96, 0x67, 0xf8, 0x96, 0x63, 0x57, 0x0e, 0x53, 0xfb, 0x27, 0xe3, 0xd1, 0x31, 0xc1,
+	0x58, 0x3f, 0x39, 0x1c, 0x54, 0x4f, 0xa4, 0x68, 0x50, 0x6c, 0xa7, 0x99, 0x88, 0xb6, 0xd0, 0xba,
+	0x8b, 0x09, 0x23, 0x36, 0x2b, 0x47, 0x46, 0x6f, 0xa1, 0x90, 0x49, 0xde, 0x42, 0x21, 0x98, 0xb6,
+	0x85, 0x42, 0x22, 0xb1, 0xd4, 0x37, 0x5c, 0xdf, 0x22, 0x66, 0xd7, 0x0c, 0x77, 0x07, 0xbb, 0x95,
+	0x99, 0x34, 0x4b, 0xeb, 0x2a, 0x13, 0xb3, 0x14, 0x93, 0x54, 0x2d, 0xc5, 0x88, 0xe8, 0xa6, 0x06,
+	0xaa, 0x6b, 0x96, 0x63, 0x37, 0x48, 0xda, 0xe0, 0x91, 0xe1, 0xcd, 0x52, 0xa3, 0x4f, 0xdc, 0x62,
+	0x78, 0x32, 0x7b, 0xfd, 0x89, 0xe1, 0xa0, 0x7a, 0x6a, 0xa4, 0x36, 0xc5, 0x91, 0xd1, 0x46, 0xd1,
+	0x35, 0x28, 0x11, 0x22, 0xa6, 0x09, 0x98, 0x59, 0x99, 0xa3, 0x3e, 0x1c, 0x4b, 0xfa, 0xc0, 0x19,
+	0x68, 0x06, 0x32, 0x2b, 0x49, 0x28, 0x76, 0x64, 0x55, 0xe8, 0x63, 0x0d, 0xc8, 0x31, 0x4b, 0x1b,
+	0xe9, 0x51, 0x6a, 0xe5, 0xf1, 0x84, 0x95, 0xb4, 0x61, 0x3e, 0x3e, 0x1c, 0x54, 0x17, 0xd3, 0xf5,
+	0x28, 0xb6, 0x47, 0xd8, 0xaa, 0xe7, 0x61, 0x9c, 0x1a, 0xd0, 0x87, 0x39, 0x38, 0x92, 0xb2, 0x45,
+	0xd1, 0xeb, 0x90, 0x73, 0x03, 0x9b, 0xe4, 0x8d, 0x2c, 0x59, 0x42, 0xaa, 0x5b, 0x9b, 0x81, 0x65,
+	0xb2, 0xa4, 0xd5, 0x0d, 0x6c, 0x25, 0x95, 0x1c, 0xa7, 0x00, 0x91, 0x27, 0x49, 0xab, 0x65, 0xf2,
+	0xa4, 0x68, 0xa4, 0xfc, 0x75, 0xa7, 0xa5, 0xca, 0x53, 0x00, 0x61, 0x98, 0x14, 0xfb, 0xbf, 0x69,
+	0x91, 0xc3, 0x9d, 0x4d, 0x9b, 0x9d, 0xb7, 0x82, 0x16, 0x76, 0x6d, 0xec, 0x63, 0x4f, 0x8c, 0x81,
+	0x9e, 0x6e, 0x1a, 0xcc, 0x5c, 0x09, 0x91, 0xf4, 0x4f, 0xc8, 0x38, 0xfa, 0x4c, 0x83, 0x4a, 0xcf,
+	0xd8, 0x6b, 0x0a, 0xd0, 0x6b, 0x6e, 0x39, 0x6e, 0xb3, 0x8f, 0x5d, 0xcb, 0x31, 0x69, 0x0e, 0x5c,
+	0x3a, 0xf3, 0x9d, 0xdb, 0x9e, 0xe7, 0xda, 0x9a, 0xb1, 0x27, 0x60, 0xef, 0x4d, 0xc7, 0x5d, 0xa7,
+	0xe2, 0x2b, 0xb6, 0xef, 0xee, 0xd7, 0x4f, 0x7c, 0x39, 0xa8, 0x1e, 0x22, 0xbb, 0xa3, 0x97, 0xc6,
+	0xd3, 0x48, 0x87, 0xd1, 0x4f, 0x34, 0x98, 0xf3, 0x1d, 0xdf, 0xe8, 0x36, 0xdb, 0x41, 0x2f, 0xe8,
+	0x1a, 0xbe, 0xb5, 0x8b, 0x9b, 0x81, 0x67, 0x74, 0x30, 0x4f, 0xb5, 0x5f, 0xbb, 0xbd, 0x53, 0x57,
+	0x89, 0xfc, 0xd9, 0x50, 0x7c, 0x93, 0x48, 0x33, 0x9f, 0x8e, 0x73, 0x9f, 0x66, 0xfc, 0x14, 0x96,
+	0x46, 0x2a, 0x3a, 0xff, 0x4b, 0x0d, 0xe6, 0x47, 0x0f, 0x13, 0x9d, 0x82, 0xec, 0x0e, 0xde, 0xe7,
+	0xc5, 0xcc, 0xe1, 0xe1, 0xa0, 0x3a, 0xb9, 0x83, 0xf7, 0xa5, 0x59, 0x27, 0x54, 0xf4, 0x3d, 0x18,
+	0xdf, 0x35, 0xba, 0x01, 0xe6, 0x5b, 0xa2, 0x56, 0x63, 0x65, 0x5b, 0x4d, 0x2e, 0xdb, 0x6a, 0xfd,
+	0x9d, 0x0e, 0x01, 0x6a, 0x62, 0x45, 0x6a, 0x6f, 0x07, 0x86, 0xed, 0x5b, 0xfe, 0x3e, 0xdb, 0x2e,
+	0x54, 0x81, 0xbc, 0x5d, 0x28, 0xf0, 0x6a, 0xe6, 0x65, 0x6d, 0xfe, 0x73, 0x0d, 0x8e, 0x8d, 0x1c,
+	0xf4, 0xb7, 0xc1, 0x43, 0xbd, 0x09, 0x63, 0x64, 0xe3, 0x93, 0x32, 0x6b, 0xdb, 0xea, 0x6c, 0xbf,
+	0xf4, 0x02, 0x75, 0x27, 0xc7, 0xaa, 0x22, 0x86, 0xc8, 0x55, 0x11, 0x43, 0x48, 0xa9, 0xd8, 0x75,
+	0x6e, 0xbc, 0xf4, 0x02, 0x75, 0x2a, 0xc7, 0x8c, 0x50, 0x40, 0x36, 0x42, 0x01, 0xfd, 0xdf, 0x39,
+	0x28, 0x86, 0x75, 0x8c, 0x74, 0x06, 0xb5, 0xbb, 0x3a, 0x83, 0x17, 0xa0, 0x6c, 0x62, 0x93, 0xbf,
+	0x80, 0x2d, 0xc7, 0x16, 0xa7, 0xb9, 0xc8, 0x82, 0xbc, 0x42, 0x53, 0xe4, 0xa7, 0x63, 0x24, 0x74,
+	0x06, 0x0a, 0x3c, 0xdf, 0xdf, 0xa7, 0x07, 0x79, 0xb2, 0x3e, 0x37, 0x1c, 0x54, 0x91, 0xc0, 0x24,
+	0xd1, 0x90, 0x0f, 0x35, 0x00, 0x58, 0x11, 0xbd, 0x86, 0x7d, 0x83, 0x57, 0x1e, 0x15, 0x75, 0x04,
+	0x57, 0x42, 0x3a, 0x2b, 0x87, 0x23, 0x7e, 0xb9, 0x1c, 0x8e, 0x50, 0xf4, 0x1e, 0x40, 0xcf, 0xb0,
+	0x6c, 0x26, 0xc7, 0xcb, 0x0c, 0x7d, 0x54, 0x48, 0x59, 0x0b, 0x39, 0x99, 0xf6, 0x48, 0x52, 0xd6,
+	0x1e, 0xa1, 0xa4, 0x68, 0xe5, 0x65, 0x7f, 0x25, 0x47, 0x4f, 0xe9, 0xc2, 0x28, 0xd5, 0x5c, 0xed,
+	0x2c, 0x29, 0x5c, 0xb9, 0x88, 0xa4, 0x53, 0x68, 0x21, 0xd3, 0xd6, 0xb5, 0xb6, 0xb0, 0x6f, 0xf5,
+	0x30, 0x2d, 0x30, 0xf8, 0xb4, 0x09, 0x4c, 0x9e, 0x36, 0x81, 0xa1, 0x97, 0x01, 0x0c, 0x7f, 0xcd,
+	0xf1, 0xfc, 0x2b, 0x76, 0x1b, 0xd3, 0xc2, 0xa1, 0xc0, 0xdc, 0x8f, 0x50, 0xd9, 0xfd, 0x08, 0x45,
+	0xaf, 0x41, 0xa9, 0xcf, 0x5f, 0x15, 0xad, 0x2e, 0xa6, 0x85, 0x41, 0x81, 0xbd, 0xd9, 0x24, 0x58,
+	0x92, 0x95, 0xb9, 0xd1, 0x79, 0x98, 0x6e, 0x3b, 0x76, 0x3b, 0x70, 0x5d, 0x6c, 0xb7, 0xf7, 0x37,
+	0x8c, 0x2d, 0x4c, 0x8b, 0x80, 0x02, 0xdb, 0x2a, 0x31, 0x92, 0xbc, 0x55, 0x62, 0x24, 0xf4, 0x22,
+	0x14, 0xc3, 0x26, 0x0a, 0xcd, 0xf3, 0x8b, 0xbc, 0x1e, 0x17, 0xa0, 0x24, 0x1c, 0x71, 0x12, 0xe7,
+	0x2d, 0x2f, 0x4c, 0x16, 0x69, 0xee, 0xce, 0x9d, 0x97, 0x60, 0xd9, 0x79, 0x09, 0x46, 0x17, 0xe1,
+	0x30, 0x7d, 0x3d, 0x37, 0x7d, 0xbf, 0xdb, 0xf4, 0x70, 0xdb, 0xb1, 0x4d, 0x8f, 0xa6, 0xe6, 0x59,
+	0xe6, 0x3e, 0x25, 0x5e, 0xf5, 0xbb, 0x1b, 0x8c, 0x24, 0xbb, 0x1f, 0x23, 0xe9, 0xbf, 0xd7, 0x60,
+	0x26, 0x6d, 0x0b, 0xc5, 0xb6, 0xb3, 0x76, 0x5f, 0xb6, 0xf3, 0x3b, 0x50, 0xe8, 0x3b, 0x66, 0xd3,
+	0xeb, 0xe3, 0x36, 0x8f, 0x58, 0xb1, 0xcd, 0xbc, 0xee, 0x98, 0x1b, 0x7d, 0xdc, 0xfe, 0xae, 0xe5,
+	0x6f, 0x2f, 0xef, 0x3a, 0x96, 0x79, 0xc9, 0xf2, 0xf8, 0xae, 0xeb, 0x33, 0x8a, 0x92, 0x2c, 0xe4,
+	0x39, 0x58, 0x2f, 0x40, 0x8e, 0x59, 0xd1, 0xff, 0x90, 0x85, 0x72, 0x7c, 0xdb, 0xfe, 0x2f, 0x0d,
+	0x05, 0x5d, 0x83, 0xbc, 0xc5, 0x32, 0x77, 0x9e, 0x41, 0xfc, 0x9f, 0x14, 0xd3, 0x6b, 0x51, 0xdf,
+	0xb1, 0xb6, 0xfb, 0x5c, 0x8d, 0xa7, 0xf8, 0x74, 0x0a, 0xa8, 0x66, 0x2e, 0xa9, 0x6a, 0xe6, 0x20,
+	0x6a, 0x40, 0xde, 0xc3, 0xee, 0xae, 0xd5, 0xc6, 0x3c, 0x38, 0x55, 0x65, 0xcd, 0x6d, 0xc7, 0xc5,
+	0x44, 0xe7, 0x06, 0x63, 0x89, 0x74, 0x72, 0x19, 0x55, 0x27, 0x07, 0xd1, 0x3b, 0x50, 0x6c, 0x3b,
+	0xf6, 0x96, 0xd5, 0x59, 0x33, 0xfa, 0x3c, 0x3c, 0x9d, 0x48, 0xd3, 0x7a, 0x56, 0x30, 0xf1, 0x5e,
+	0x88, 0x78, 0x8c, 0xf5, 0x42, 0x42, 0xae, 0x68, 0x41, 0xff, 0x36, 0x06, 0x10, 0x2d, 0x0e, 0x7a,
+	0x05, 0x4a, 0x78, 0x0f, 0xb7, 0x03, 0xdf, 0x71, 0xc5, 0x7b, 0x82, 0xb7, 0x16, 0x05, 0xac, 0x04,
+	0x76, 0x88, 0x50, 0x72, 0x50, 0x6d, 0xa3, 0x87, 0xbd, 0xbe, 0xd1, 0x16, 0x3d, 0x49, 0xea, 0x4c,
+	0x08, 0xca, 0x07, 0x35, 0x04, 0xd1, 0xff, 0xc3, 0x18, 0xed, 0x62, 0xb2, 0x76, 0x24, 0x1a, 0x0e,
+	0xaa, 0x53, 0xb6, 0xda, 0xbf, 0xa4, 0x74, 0xf4, 0x06, 0x4c, 0xee, 0x84, 0x1b, 0x8f, 0xf8, 0x36,
+	0x46, 0x05, 0x68, 0x6a, 0x17, 0x11, 0x14, 0xef, 0x26, 0x64, 0x1c, 0x6d, 0x41, 0xc9, 0xb0, 0x6d,
+	0xc7, 0xa7, 0xef, 0x20, 0xd1, 0xa2, 0x7c, 0x72, 0xd4, 0x36, 0xad, 0x2d, 0x47, 0xbc, 0x2c, 0x4b,
+	0xa2, 0xc1, 0x43, 0xd2, 0x20, 0x07, 0x0f, 0x09, 0x46, 0x0d, 0xc8, 0x75, 0x8d, 0x16, 0xee, 0x8a,
+	0xa0, 0xff, 0xf8, 0x48, 0x13, 0x97, 0x28, 0x1b, 0xd3, 0x4e, 0x5f, 0xf9, 0x4c, 0x4e, 0x7e, 0xe5,
+	0x33, 0x64, 0x7e, 0x0b, 0xca, 0x71, 0x7f, 0x0e, 0x96, 0xc0, 0x3c, 0x29, 0x27, 0x30, 0xc5, 0xdb,
+	0xa6, 0x4c, 0x06, 0x94, 0x24, 0xa7, 0x1e, 0x84, 0x09, 0xfd, 0x57, 0x1a, 0xcc, 0xa4, 0x9d, 0x5d,
+	0xb4, 0x26, 0x9d, 0x78, 0x8d, 0xb7, 0x5a, 0x52, 0xb6, 0x3a, 0x97, 0x1d, 0x71, 0xd4, 0xa3, 0x83,
+	0x5e, 0x87, 0x29, 0xdb, 0x31, 0x71, 0xd3, 0x20, 0x06, 0xba, 0x96, 0xe7, 0x57, 0x32, 0xb4, 0x85,
+	0x4d, 0x5b, 0x34, 0x84, 0xb2, 0x2c, 0x08, 0x92, 0xf4, 0xa4, 0x42, 0xd0, 0x7f, 0xa4, 0xc1, 0x74,
+	0xac, 0x83, 0x7a, 0xcf, 0x49, 0x94, 0x9c, 0xfa, 0x64, 0x0e, 0x96, 0xfa, 0xe8, 0x3f, 0xcd, 0x40,
+	0x49, 0x2a, 0x2f, 0xef, 0xd9, 0x87, 0xeb, 0x30, 0xcd, 0xdf, 0x94, 0x96, 0xdd, 0x61, 0xe5, 0x54,
+	0x86, 0xf7, 0x4a, 0x12, 0x1f, 0x2c, 0x56, 0x9d, 0xd6, 0x46, 0xc8, 0x4b, 0xab, 0x29, 0xda, 0x48,
+	0xf3, 0x14, 0x4c, 0x32, 0x31, 0xa5, 0x52, 0xd0, 0x35, 0x98, 0x0b, 0xfa, 0xa6, 0xe1, 0xe3, 0xa6,
+	0xc7, 0x5b, 0xff, 0x4d, 0x3b, 0xe8, 0xb5, 0xb0, 0x4b, 0x4f, 0xfc, 0x38, 0x6b, 0xfd, 0x30, 0x0e,
+	0xf1, 0x6d, 0xe0, 0x32, 0xa5, 0x4b, 0x3a, 0x67, 0xd2, 0xe8, 0xfa, 0x05, 0x40, 0xc9, 0xf6, 0xb6,
+	0x32, 0xbf, 0xda, 0x01, 0xe7, 0xf7, 0x13, 0x0d, 0xca, 0xf1, 0xae, 0xf5, 0x43, 0x59, 0xe8, 0x7d,
+	0x28, 0x86, 0x1d, 0xe8, 0x7b, 0x76, 0xe0, 0x69, 0xc8, 0xb9, 0xd8, 0xf0, 0x1c, 0x9b, 0x9f, 0x4c,
+	0x1a, 0x62, 0x18, 0x22, 0x87, 0x18, 0x86, 0xe8, 0x57, 0x61, 0x82, 0xcd, 0xe0, 0x9b, 0x56, 0xd7,
+	0xc7, 0x2e, 0x3a, 0x07, 0x39, 0xcf, 0x37, 0x7c, 0xec, 0x55, 0xb4, 0xc5, 0xec, 0xe9, 0xa9, 0x33,
+	0x73, 0xc9, 0x66, 0x33, 0x21, 0x33, 0xad, 0x8c, 0x53, 0xd6, 0xca, 0x10, 0xfd, 0x87, 0x1a, 0x4c,
+	0xc8, 0x3d, 0xf5, 0xfb, 0xa3, 0xf6, 0x0e, 0x87, 0xf6, 0xa1, 0xf0, 0xa1, 0x7b, 0x7f, 0x56, 0xf6,
+	0xce, 0xac, 0xff, 0x46, 0x63, 0x33, 0x1b, 0x36, 0x63, 0xef, 0xd5, 0x7c, 0x27, 0x6a, 0x85, 0x90,
+	0x13, 0xe6, 0xd1, 0xc0, 0x76, 0xd0, 0x56, 0x08, 0x0d, 0x7f, 0x8a, 0xb8, 0x1c, 0xfe, 0x14, 0x82,
+	0xfe, 0xd9, 0x38, 0xf5, 0x3c, 0x6a, 0xbc, 0x3f, 0xec, 0x26, 0x50, 0x2c, 0x3b, 0xc9, 0xde, 0x41,
+	0x76, 0xf2, 0x0c, 0xe4, 0xe9, 0xeb, 0x20, 0x4c, 0x1c, 0xe8, 0xa2, 0x11, 0x48, 0xfd, 0xf0, 0xc9,
+	0x90, 0x5b, 0x44, 0xad, 0xf1, 0x7b, 0x8b, 0x5a, 0xa8, 0x09, 0xc7, 0xb6, 0x0d, 0xaf, 0x29, 0xe2,
+	0xac, 0xd9, 0x34, 0xfc, 0x66, 0x18, 0x27, 0x72, 0xb4, 0x4c, 0xa1, 0xcd, 0xbc, 0x6d, 0xc3, 0xdb,
+	0x10, 0x3c, 0xcb, 0xfe, 0x7a, 0x32, 0x6a, 0xcc, 0xa5, 0x73, 0xa0, 0x4d, 0x98, 0x4d, 0x57, 0x9e,
+	0xa7, 0x9e, 0xd3, 0x5e, 0xb3, 0x77, 0x4b, 0xcd, 0x47, 0x52, 0xc8, 0xe8, 0x23, 0x0d, 0x2a, 0xe4,
+	0xfd, 0xec, 0xe2, 0x0f, 0x02, 0xcb, 0xc5, 0x3d, 0xb2, 0x62, 0x4d, 0x67, 0x17, 0xbb, 0x5d, 0x63,
+	0x9f, 0x7f, 0x34, 0x3a, 0x99, 0x7c, 0x7b, 0xac, 0x3b, 0x66, 0x43, 0x12, 0x60, 0x43, 0xeb, 0xab,
+	0xe0, 0x15, 0xa6, 0x44, 0x1e, 0x5a, 0x3a, 0xc7, 0xea, 0x58, 0xa1, 0x50, 0x2e, 0xea, 0xff, 0xd4,
+	0x60, 0x4a, 0xfd, 0xb6, 0xf3, 0xd0, 0x37, 0x66, 0xe2, 0x48, 0x66, 0x1f, 0xd0, 0x91, 0xfc, 0x87,
+	0x06, 0x93, 0xca, 0x27, 0xa7, 0x47, 0x67, 0xe8, 0x3f, 0xcf, 0xc0, 0x5c, 0xba, 0x9a, 0x07, 0x52,
+	0x80, 0x5e, 0x00, 0x92, 0x4a, 0x5e, 0x8c, 0x72, 0xa3, 0xd9, 0x44, 0xfd, 0x49, 0x87, 0x20, 0xf2,
+	0xd0, 0xc4, 0xb7, 0x22, 0x21, 0x8e, 0xae, 0x41, 0xc9, 0x92, 0xbe, 0x4a, 0x65, 0xd3, 0x3e, 0x1e,
+	0xc8, 0xdf, 0xa2, 0x58, 0x97, 0x62, 0xc4, 0x17, 0x28, 0x59, 0x55, 0x3d, 0x07, 0x63, 0x24, 0x79,
+	0xd3, 0x77, 0x21, 0xcf, 0xdd, 0x41, 0xcf, 0x43, 0x91, 0xc6, 0x39, 0x5a, 0x53, 0xb1, 0xc4, 0x9d,
+	0xa6, 0x1d, 0x04, 0x8c, 0xdd, 0x0b, 0x29, 0x08, 0x0c, 0xbd, 0x04, 0x40, 0x8e, 0x36, 0x8f, 0x70,
+	0x19, 0x1a, 0x27, 0x68, 0xed, 0xd6, 0x77, 0xcc, 0x44, 0x58, 0x2b, 0x86, 0xa0, 0xfe, 0xeb, 0x0c,
+	0x94, 0xe4, 0xef, 0x60, 0x77, 0x65, 0xfc, 0x43, 0x10, 0x75, 0x75, 0xd3, 0x30, 0x4d, 0xf2, 0x17,
+	0x8b, 0x57, 0xda, 0xd2, 0xc8, 0x49, 0x12, 0xff, 0x2f, 0x0b, 0x09, 0x56, 0x45, 0xd1, 0x9b, 0x06,
+	0x56, 0x8c, 0x24, 0x59, 0x2d, 0xc7, 0x69, 0xf3, 0x3b, 0x30, 0x9b, 0xaa, 0x4a, 0xae, 0x7d, 0xc6,
+	0xef, 0x57, 0xed, 0xf3, 0xdb, 0x71, 0x98, 0x4d, 0xfd, 0xfe, 0xf8, 0xd0, 0x4f, 0xb1, 0x7a, 0x82,
+	0xb2, 0xf7, 0xe5, 0x04, 0x7d, 0xa2, 0xa5, 0xad, 0x2c, 0xfb, 0x88, 0xf2, 0xca, 0x01, 0x3e, 0xca,
+	0xde, 0xaf, 0x35, 0x56, 0xb7, 0xe5, 0xf8, 0x5d, 0x9d, 0x89, 0xdc, 0x41, 0xcf, 0x04, 0x7a, 0x96,
+	0x95, 0xb1, 0xd4, 0x56, 0x9e, 0xda, 0x12, 0x11, 0x22, 0x66, 0x2a, 0xcf, 0x21, 0xf4, 0x06, 0x4c,
+	0x0a, 0x09, 0xd6, 0x3c, 0x29, 0x44, 0x9d, 0x0d, 0xce, 0x13, 0xef, 0x9f, 0x4c, 0xc8, 0xf8, 0x7f,
+	0x77, 0x0f, 0xff, 0x4b, 0x83, 0xe9, 0xd8, 0x85, 0x84, 0x47, 0xe7, 0x1d, 0xf4, 0xa9, 0x06, 0xc5,
+	0xf0, 0x2e, 0xcc, 0x3d, 0x27, 0xf2, 0xcb, 0x90, 0xc3, 0xec, 0x3e, 0x06, 0x0b, 0x77, 0x47, 0x62,
+	0xf7, 0xe5, 0x08, 0x8d, 0xdf, 0x90, 0x8b, 0x5d, 0xc1, 0x68, 0x70, 0x41, 0xfd, 0x8f, 0x9a, 0x48,
+	0xd1, 0x23, 0x9f, 0x1e, 0xea, 0x52, 0x44, 0x63, 0xca, 0xde, 0xed, 0x98, 0x7e, 0x57, 0x84, 0x71,
+	0xca, 0x47, 0x4a, 0x68, 0x1f, 0xbb, 0x3d, 0xcb, 0x36, 0xba, 0x74, 0x38, 0x05, 0x76, 0x6e, 0x05,
+	0x26, 0x9f, 0x5b, 0x81, 0xa1, 0x6d, 0x98, 0x8e, 0xda, 0x7e, 0x54, 0x4d, 0xfa, 0x35, 0xbc, 0xb7,
+	0x54, 0x26, 0xd6, 0xd8, 0x8f, 0x49, 0xaa, 0xf7, 0x14, 0x62, 0x44, 0x64, 0xc2, 0x54, 0xdb, 0xb1,
+	0x7d, 0xc3, 0xb2, 0xb1, 0xcb, 0x0c, 0x65, 0xd3, 0xae, 0x21, 0x9d, 0x55, 0x78, 0x58, 0xf7, 0x44,
+	0x95, 0x53, 0xaf, 0x21, 0xa9, 0x34, 0xf4, 0x3e, 0x4c, 0x8a, 0x32, 0x86, 0x19, 0x19, 0x4b, 0xbb,
+	0x86, 0xb4, 0x22, 0xb3, 0xb0, 0x2d, 0xad, 0x48, 0xa9, 0xd7, 0x90, 0x14, 0x12, 0xea, 0x42, 0xb9,
+	0xef, 0x98, 0x9b, 0x36, 0x4f, 0xde, 0x8d, 0x56, 0x17, 0xf3, 0x5e, 0xf3, 0x42, 0x22, 0xe5, 0x51,
+	0xb8, 0x58, 0x28, 0x8e, 0xcb, 0xaa, 0x17, 0xfb, 0xe2, 0x54, 0xf4, 0x1e, 0x4c, 0x74, 0x49, 0x35,
+	0xb9, 0xb2, 0xd7, 0xb7, 0x5c, 0x6c, 0xa6, 0x5f, 0xc3, 0xbb, 0x24, 0x71, 0xb0, 0x40, 0x28, 0xcb,
+	0xa8, 0x57, 0x91, 0x64, 0x0a, 0x59, 0xfd, 0x9e, 0xb1, 0xd7, 0x08, 0x6c, 0x6f, 0x65, 0x8f, 0x5f,
+	0xa9, 0xca, 0xa7, 0xad, 0xfe, 0x9a, 0xca, 0xc4, 0x56, 0x3f, 0x26, 0xa9, 0xae, 0x7e, 0x8c, 0x88,
+	0x2e, 0xd1, 0x38, 0xcf, 0x96, 0x84, 0x5d, 0xc7, 0x9b, 0x4b, 0xcc, 0x16, 0x5b, 0x0d, 0xd6, 0xf6,
+	0xe1, 0x4f, 0x8a, 0xd2, 0x50, 0x03, 0x5f, 0x03, 0x3a, 0xec, 0x06, 0xf6, 0x03, 0xd7, 0xc6, 0x26,
+	0x2f, 0xaa, 0x92, 0x6b, 0xa0, 0x70, 0x85, 0x6b, 0xa0, 0xa0, 0x89, 0x35, 0x50, 0xa8, 0x64, 0x4f,
+	0xf5, 0x1d, 0xf3, 0x2a, 0x3b, 0x32, 0x7e, 0x78, 0x3f, 0xef, 0xb1, 0x84, 0xa9, 0x88, 0x85, 0xed,
+	0x29, 0x45, 0x4a, 0xdd, 0x53, 0x0a, 0x89, 0x5f, 0x09, 0x93, 0x2f, 0x10, 0xb1, 0x99, 0x2a, 0x8d,
+	0xb8, 0x12, 0x96, 0xe0, 0x0c, 0xaf, 0x84, 0x25, 0x28, 0x89, 0x2b, 0x61, 0x09, 0x0e, 0x62, 0xbd,
+	0x63, 0xd8, 0x9d, 0x55, 0xa7, 0xa5, 0xee, 0xea, 0x89, 0x34, 0xeb, 0xe7, 0x53, 0x38, 0x99, 0xf5,
+	0x34, 0x1d, 0xaa, 0xf5, 0x34, 0x8e, 0x7a, 0x41, 0xb4, 0x87, 0xf4, 0xcf, 0x35, 0x98, 0x8e, 0xc5,
+	0x19, 0xf4, 0x3a, 0x84, 0x37, 0x4e, 0xae, 0xee, 0xf7, 0x45, 0x9a, 0xac, 0xdc, 0x50, 0x21, 0x78,
+	0xda, 0x0d, 0x15, 0x82, 0xa3, 0x4b, 0x00, 0xe1, 0x3b, 0xe9, 0x56, 0x41, 0x9a, 0xe6, 0x68, 0x11,
+	0xa7, 0x9c, 0xa3, 0x45, 0xa8, 0xfe, 0x55, 0x16, 0x0a, 0x62, 0xa3, 0x3e, 0x90, 0x32, 0x6a, 0x09,
+	0xf2, 0x3d, 0xec, 0xd1, 0x9b, 0x2a, 0x99, 0x28, 0x1b, 0xe2, 0x90, 0x9c, 0x0d, 0x71, 0x48, 0x4d,
+	0xd6, 0xb2, 0x77, 0x95, 0xac, 0x8d, 0x1d, 0x38, 0x59, 0xc3, 0xf4, 0x2b, 0xb5, 0x14, 0x6e, 0xc5,
+	0x77, 0xa1, 0x5b, 0xc7, 0x70, 0xf1, 0x0d, 0x5b, 0x16, 0x8c, 0x7d, 0xc3, 0x96, 0x49, 0x68, 0x07,
+	0x0e, 0x4b, 0xdf, 0xae, 0x78, 0xef, 0x90, 0x04, 0xbe, 0xa9, 0xd1, 0x57, 0x02, 0x1a, 0x94, 0x8b,
+	0x1d, 0xef, 0x9d, 0x18, 0x2a, 0x67, 0xbb, 0x71, 0x9a, 0xfe, 0xd7, 0x0c, 0x4c, 0xa9, 0xfe, 0x3e,
+	0x90, 0x85, 0x7d, 0x1e, 0x8a, 0x78, 0xcf, 0xf2, 0x9b, 0x6d, 0xc7, 0xc4, 0xbc, 0x64, 0xa4, 0xeb,
+	0x44, 0xc0, 0xb3, 0x8e, 0xa9, 0xac, 0x93, 0xc0, 0xe4, 0xdd, 0x90, 0x3d, 0xd0, 0x6e, 0x88, 0x5a,
+	0xad, 0x63, 0xb7, 0x6f, 0xb5, 0xa6, 0xcf, 0x73, 0xf1, 0x01, 0xcd, 0xf3, 0xcd, 0x0c, 0x94, 0xe3,
+	0xd1, 0xf8, 0xdb, 0x71, 0x84, 0xd4, 0xd3, 0x90, 0x3d, 0xf0, 0x69, 0x78, 0x03, 0x26, 0x49, 0xee,
+	0x68, 0xf8, 0x3e, 0xbf, 0x4a, 0x3a, 0x46, 0x73, 0x2e, 0x16, 0x9b, 0x02, 0x7b, 0x59, 0xe0, 0x4a,
+	0x6c, 0x92, 0x70, 0xfd, 0xa3, 0x0c, 0x4c, 0x2a, 0x6f, 0x8d, 0x47, 0x2f, 0xa4, 0xe8, 0xd3, 0x30,
+	0xa9, 0x24, 0x63, 0xfa, 0xc7, 0x6c, 0x9f, 0xa8, 0x59, 0xd0, 0xa3, 0x37, 0x2f, 0x53, 0x30, 0x21,
+	0x67, 0x75, 0x7a, 0x1d, 0xa6, 0x63, 0x49, 0x98, 0x3c, 0x00, 0xed, 0x20, 0x03, 0xd0, 0xe7, 0x60,
+	0x26, 0x2d, 0x77, 0xd0, 0xcf, 0xc3, 0x4c, 0xda, 0x5b, 0xfd, 0xce, 0x0d, 0x7c, 0xa1, 0x51, 0x0b,
+	0xc9, 0x4b, 0xe7, 0x17, 0x00, 0x6c, 0x7c, 0xa3, 0x79, 0xdb, 0xf2, 0x8f, 0xcd, 0x27, 0xbe, 0xb1,
+	0x1a, 0xab, 0x96, 0x0a, 0x02, 0x23, 0x9a, 0x9c, 0xae, 0xd9, 0xbc, 0x6d, 0xd1, 0x45, 0x35, 0x39,
+	0x5d, 0x33, 0xa1, 0x49, 0x60, 0xfa, 0x8f, 0xb3, 0xa2, 0x32, 0x8f, 0x6e, 0x6d, 0xbf, 0x0b, 0xe5,
+	0xbe, 0x78, 0xb8, 0xbd, 0xb7, 0xb4, 0x36, 0x09, 0xf9, 0xe3, 0x96, 0xa6, 0x54, 0x8a, 0xaa, 0x9b,
+	0x17, 0x9d, 0x99, 0x03, 0xea, 0x6e, 0xc4, 0xaa, 0xcf, 0x29, 0x95, 0x82, 0xbe, 0x0f, 0x87, 0xc5,
+	0x6d, 0xb2, 0x5d, 0x2c, 0x1c, 0xcf, 0x8e, 0x54, 0xce, 0x2e, 0x99, 0x87, 0x02, 0x71, 0xcf, 0xa7,
+	0x63, 0xa4, 0x98, 0x7a, 0xee, 0xfb, 0xd8, 0x41, 0xd5, 0xc7, 0x9d, 0x9f, 0x8e, 0x91, 0xf4, 0x4f,
+	0x35, 0x98, 0x8e, 0xdd, 0x83, 0x47, 0xe7, 0xa0, 0x40, 0x7f, 0x26, 0x77, 0xeb, 0x15, 0xa0, 0x1b,
+	0x92, 0xf2, 0x29, 0x16, 0xf2, 0x1c, 0x42, 0x2f, 0x42, 0x31, 0xbc, 0x2e, 0xcf, 0xbf, 0x2a, 0xb3,
+	0xc3, 0x27, 0x40, 0xe5, 0xf0, 0x09, 0x50, 0xff, 0x85, 0x06, 0xc7, 0x46, 0xde, 0x91, 0x7f, 0xd8,
+	0x3d, 0x03, 0xfd, 0x1a, 0xcc, 0xa5, 0x5f, 0x6b, 0xbf, 0xd7, 0x0e, 0xcb, 0x53, 0xcf, 0x42, 0x41,
+	0x7c, 0x51, 0x46, 0x00, 0xb9, 0xb7, 0x37, 0x57, 0x36, 0x57, 0xce, 0x95, 0x0f, 0xa1, 0x12, 0xe4,
+	0xd7, 0x57, 0x2e, 0x9f, 0xbb, 0x78, 0xf9, 0x7c, 0x59, 0x23, 0x0f, 0x8d, 0xcd, 0xcb, 0x97, 0xc9,
+	0x43, 0xe6, 0xa9, 0x4b, 0xf2, 0xfd, 0x36, 0xf6, 0xa6, 0x47, 0x13, 0x50, 0x58, 0xee, 0xf7, 0x69,
+	0x68, 0x61, 0xb2, 0x2b, 0xbb, 0x16, 0x89, 0x02, 0x65, 0x0d, 0xe5, 0x21, 0x7b, 0xe5, 0xca, 0x5a,
+	0x39, 0x83, 0x66, 0xa0, 0x7c, 0x0e, 0x1b, 0x66, 0xd7, 0xb2, 0xb1, 0x88, 0x67, 0xe5, 0x6c, 0xfd,
+	0xfa, 0x97, 0x5f, 0x2f, 0x68, 0x5f, 0x7d, 0xbd, 0xa0, 0xfd, 0xe5, 0xeb, 0x05, 0xed, 0xe6, 0x37,
+	0x0b, 0x87, 0xbe, 0xfa, 0x66, 0xe1, 0xd0, 0x9f, 0xbe, 0x59, 0x38, 0xf4, 0xee, 0xb3, 0xd2, 0x8f,
+	0x4d, 0xd9, 0x98, 0xfa, 0xae, 0x43, 0x42, 0x39, 0x7f, 0x5a, 0x8a, 0xff, 0xbc, 0xf6, 0x8b, 0xcc,
+	0x89, 0x65, 0xfa, 0xb8, 0xce, 0xf8, 0x6a, 0x17, 0x9d, 0x1a, 0x03, 0xe8, 0x2f, 0x24, 0xbd, 0x56,
+	0x8e, 0xfe, 0x12, 0xf2, 0xf9, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x03, 0x65, 0x0b, 0x79, 0x99,
+	0x3b, 0x00, 0x00,
 }
 
 func (m *EventSequence) Marshal() (dAtA []byte, err error) {
@@ -4319,6 +4380,29 @@ func (m *EventSequence_Event_JobRequeued) MarshalToSizedBuffer(dAtA []byte) (int
 	}
 	return len(dAtA) - i, nil
 }
+func (m *EventSequence_Event_JobPreemptionRequested) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EventSequence_Event_JobPreemptionRequested) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	if m.JobPreemptionRequested != nil {
+		{
+			size, err := m.JobPreemptionRequested.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintEvents(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x1
+		i--
+		dAtA[i] = 0xba
+	}
+	return len(dAtA) - i, nil
+}
 func (m *ResourceUtilisation) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -5152,20 +5236,20 @@ func (m *JobSetFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	var l int
 	_ = l
 	if len(m.States) > 0 {
-		dAtA45 := make([]byte, len(m.States)*10)
-		var j44 int
+		dAtA46 := make([]byte, len(m.States)*10)
+		var j45 int
 		for _, num := range m.States {
 			for num >= 1<<7 {
-				dAtA45[j44] = uint8(uint64(num)&0x7f | 0x80)
+				dAtA46[j45] = uint8(uint64(num)&0x7f | 0x80)
 				num >>= 7
-				j44++
+				j45++
 			}
-			dAtA45[j44] = uint8(num)
-			j44++
+			dAtA46[j45] = uint8(num)
+			j45++
 		}
-		i -= j44
-		copy(dAtA[i:], dAtA45[:j44])
-		i = encodeVarintEvents(dAtA, i, uint64(j44))
+		i -= j45
+		copy(dAtA[i:], dAtA46[:j45])
+		i = encodeVarintEvents(dAtA, i, uint64(j45))
 		i--
 		dAtA[i] = 0xa
 	}
@@ -5200,20 +5284,20 @@ func (m *CancelJobSet) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		dAtA[i] = 0x12
 	}
 	if len(m.States) > 0 {
-		dAtA47 := make([]byte, len(m.States)*10)
-		var j46 int
+		dAtA48 := make([]byte, len(m.States)*10)
+		var j47 int
 		for _, num := range m.States {
 			for num >= 1<<7 {
-				dAtA47[j46] = uint8(uint64(num)&0x7f | 0x80)
+				dAtA48[j47] = uint8(uint64(num)&0x7f | 0x80)
 				num >>= 7
-				j46++
+				j47++
 			}
-			dAtA47[j46] = uint8(num)
-			j46++
+			dAtA48[j47] = uint8(num)
+			j47++
 		}
-		i -= j46
-		copy(dAtA[i:], dAtA47[:j46])
-		i = encodeVarintEvents(dAtA, i, uint64(j46))
+		i -= j47
+		copy(dAtA[i:], dAtA48[:j47])
+		i = encodeVarintEvents(dAtA, i, uint64(j47))
 		i--
 		dAtA[i] = 0xa
 	}
@@ -6913,6 +6997,41 @@ func (m *JobRunPreemptionRequested) MarshalToSizedBuffer(dAtA []byte) (int, erro
 	return len(dAtA) - i, nil
 }
 
+func (m *JobPreemptionRequested) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *JobPreemptionRequested) MarshalTo(dAtA []byte) (int, error) {
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *JobPreemptionRequested) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
+	_ = i
+	var l int
+	_ = l
+	if m.JobId != nil {
+		{
+			size, err := m.JobId.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintEvents(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
+}
+
 func encodeVarintEvents(dAtA []byte, offset int, v uint64) int {
 	offset -= sovEvents(v)
 	base := offset
@@ -7225,6 +7344,18 @@ func (m *EventSequence_Event_JobRequeued) Size() (n int) {
 	}
 	return n
 }
+func (m *EventSequence_Event_JobPreemptionRequested) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.JobPreemptionRequested != nil {
+		l = m.JobPreemptionRequested.Size()
+		n += 2 + l + sovEvents(uint64(l))
+	}
+	return n
+}
 func (m *ResourceUtilisation) Size() (n int) {
 	if m == nil {
 		return 0
@@ -8333,6 +8464,19 @@ func (m *JobRunPreemptionRequested) Size() (n int) {
 	return n
 }
 
+func (m *JobPreemptionRequested) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	if m.JobId != nil {
+		l = m.JobId.Size()
+		n += 1 + l + sovEvents(uint64(l))
+	}
+	return n
+}
+
 func sovEvents(x uint64) (n int) {
 	return (math_bits.Len64(x|1) + 6) / 7
 }
@@ -9351,6 +9495,41 @@ func (m *EventSequence_Event) Unmarshal(dAtA []byte) error {
 			}
 			m.Event = &EventSequence_Event_JobRequeued{v}
 			iNdEx = postIndex
+		case 23:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobPreemptionRequested", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthEvents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvents
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			v := &JobPreemptionRequested{}
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			m.Event = &EventSequence_Event_JobPreemptionRequested{v}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipEvents(dAtA[iNdEx:])
@@ -16391,6 +16570,92 @@ func (m *JobRunPreemptionRequested) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *JobPreemptionRequested) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowEvents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: JobPreemptionRequested: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: JobPreemptionRequested: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobId", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowEvents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthEvents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthEvents
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.JobId == nil {
+				m.JobId = &Uuid{}
+			}
+			if err := m.JobId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipEvents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
+				return ErrInvalidLengthEvents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func skipEvents(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
diff --git a/pkg/armadaevents/events.proto b/pkg/armadaevents/events.proto
index d68759a6..f70d5f2a 100644
--- a/pkg/armadaevents/events.proto
+++ b/pkg/armadaevents/events.proto
@@ -90,6 +90,7 @@ message EventSequence {
             PartitionMarker partitionMarker = 20;
             JobRunPreemptionRequested jobRunPreemptionRequested = 21;
             JobRequeued jobRequeued = 22;
+            JobPreemptionRequested jobPreemptionRequested = 23;
         }
     }
     // The system is namespaced by queue, and all events are associated with a job set.
@@ -543,3 +544,8 @@ message JobRunPreemptionRequested {
     Uuid run_id = 1;
     Uuid job_id = 2;
 }
+
+// Indicates that a user has requested for the job to be pre-empted.
+message JobPreemptionRequested {
+  Uuid job_id = 1;
+}
diff --git a/pkg/client/queue/permission_verb.go b/pkg/client/queue/permission_verb.go
index f215b1b7..e1bd5642 100644
--- a/pkg/client/queue/permission_verb.go
+++ b/pkg/client/queue/permission_verb.go
@@ -12,6 +12,7 @@ type PermissionVerb string
 const (
 	PermissionVerbSubmit       PermissionVerb = "submit"
 	PermissionVerbCancel       PermissionVerb = "cancel"
+	PermissionVerbPreempt      PermissionVerb = "preempt"
 	PermissionVerbReprioritize PermissionVerb = "reprioritize"
 	PermissionVerbWatch        PermissionVerb = "watch"
 )


Test patch:
diff --git a/internal/armada/repository/apimessages/conversions_test.go b/internal/armada/repository/apimessages/conversions_test.go
index 40c9e66c..fb7bf125 100644
--- a/internal/armada/repository/apimessages/conversions_test.go
+++ b/internal/armada/repository/apimessages/conversions_test.go
@@ -925,6 +925,35 @@ func TestConvertIngressInfo(t *testing.T) {
 	assert.Equal(t, expected, apiEvents)
 }
 
+func TestConvertJobPreemptionRequested(t *testing.T) {
+	preemptRequest := &armadaevents.EventSequence_Event{
+		Created: &baseTime,
+		Event: &armadaevents.EventSequence_Event_JobPreemptionRequested{
+			JobPreemptionRequested: &armadaevents.JobPreemptionRequested{
+				JobId: jobIdProto,
+			},
+		},
+	}
+
+	expected := []*api.EventMessage{
+		{
+			Events: &api.EventMessage_Preempting{
+				Preempting: &api.JobPreemptingEvent{
+					JobId:     jobIdString,
+					JobSetId:  jobSetName,
+					Queue:     queue,
+					Created:   baseTime,
+					Requestor: userId,
+				},
+			},
+		},
+	}
+
+	apiEvents, err := FromEventSequence(toEventSeq(preemptRequest))
+	assert.NoError(t, err)
+	assert.Equal(t, expected, apiEvents)
+}
+
 func TestConvertJobRunPreempted(t *testing.T) {
 	preempted := &armadaevents.EventSequence_Event{
 		Created: &baseTime,
diff --git a/internal/common/ingest/testfixtures/event.go b/internal/common/ingest/testfixtures/event.go
index a4a4fa16..b47ca3a2 100644
--- a/internal/common/ingest/testfixtures/event.go
+++ b/internal/common/ingest/testfixtures/event.go
@@ -384,6 +384,15 @@ var JobReprioritised = &armadaevents.EventSequence_Event{
 	},
 }
 
+var JobPreemptionRequested = &armadaevents.EventSequence_Event{
+	Created: &testfixtures.BaseTime,
+	Event: &armadaevents.EventSequence_Event_JobPreemptionRequested{
+		JobPreemptionRequested: &armadaevents.JobPreemptionRequested{
+			JobId: JobIdProto,
+		},
+	},
+}
+
 var JobPreempted = &armadaevents.EventSequence_Event{
 	Created: &testfixtures.BaseTime,
 	Event: &armadaevents.EventSequence_Event_JobRunPreempted{
diff --git a/internal/scheduler/jobdb/job_run_test.go b/internal/scheduler/jobdb/job_run_test.go
index e3cec287..497025a3 100644
--- a/internal/scheduler/jobdb/job_run_test.go
+++ b/internal/scheduler/jobdb/job_run_test.go
@@ -53,6 +53,7 @@ var baseJobRun = jobDb.CreateRun(
 	false,
 	false,
 	false,
+	false,
 	nil,
 	nil,
 	nil,
@@ -94,6 +95,12 @@ func TestJobRun_TestCancelled(t *testing.T) {
 	assert.True(t, cancelledRun.Cancelled())
 }
 
+func TestJobRun_TestPreemptRequested(t *testing.T) {
+	preemptRequestedRun := baseJobRun.WithPreemptRequested(true)
+	assert.False(t, baseJobRun.PreemptRequested())
+	assert.True(t, preemptRequestedRun.PreemptRequested())
+}
+
 func TestJobRun_TestReturned(t *testing.T) {
 	returnedRun := baseJobRun.WithReturned(true)
 	assert.False(t, baseJobRun.Returned())
@@ -122,6 +129,7 @@ func TestDeepCopy(t *testing.T) {
 		true,
 		true,
 		true,
+		true,
 		nil,
 		nil,
 		nil,
@@ -145,6 +153,7 @@ func TestDeepCopy(t *testing.T) {
 		true,
 		true,
 		true,
+		true,
 		nil,
 		nil,
 		nil,
diff --git a/internal/scheduler/scheduler_test.go b/internal/scheduler/scheduler_test.go
index 884b8db6..6fc1930e 100644
--- a/internal/scheduler/scheduler_test.go
+++ b/internal/scheduler/scheduler_test.go
@@ -59,7 +59,22 @@ var (
 		Version: 1,
 	}
 	failFastSchedulingInfoBytes = protoutil.MustMarshall(failFastSchedulingInfo)
-	schedulingInfo              = &schedulerobjects.JobSchedulingInfo{
+	preemptibleSchedulingInfo   = &schedulerobjects.JobSchedulingInfo{
+		AtMostOnce:        true,
+		Preemptible:       true,
+		PriorityClassName: testfixtures.PriorityClass1,
+		ObjectRequirements: []*schedulerobjects.ObjectRequirements{
+			{
+				Requirements: &schedulerobjects.ObjectRequirements_PodRequirements{
+					PodRequirements: &schedulerobjects.PodRequirements{
+						Priority: int32(10),
+					},
+				},
+			},
+		},
+		Version: 1,
+	}
+	schedulingInfo = &schedulerobjects.JobSchedulingInfo{
 		AtMostOnce: true,
 		ObjectRequirements: []*schedulerobjects.ObjectRequirements{
 			{
@@ -173,6 +188,20 @@ var leasedJob = testfixtures.JobDb.NewJob(
 	1,
 ).WithNewRun("testExecutor", "test-node", "node", 5)
 
+var preemptibleLeasedJob = testfixtures.JobDb.NewJob(
+	util.NewULID(),
+	"testJobset",
+	"testQueue",
+	0,
+	preemptibleSchedulingInfo,
+	false,
+	1,
+	false,
+	false,
+	false,
+	1,
+).WithNewRun("testExecutor", "test-node", "node", 5)
+
 var cancelledJob = testfixtures.JobDb.NewJob(
 	util.NewULID(),
 	"testJobset",
@@ -212,6 +241,7 @@ var returnedOnceLeasedJob = testfixtures.JobDb.NewJob(
 	false,
 	false,
 	false,
+	false,
 	true,
 	false,
 	nil,
@@ -292,6 +322,7 @@ var (
 		false,
 		false,
 		false,
+		false,
 		true,
 		false,
 		nil,
@@ -320,6 +351,7 @@ func TestScheduler_TestCycle(t *testing.T) {
 		expectedJobRunErrors             []string                          // ids of jobs we expect to have produced jobRunErrors messages
 		expectedJobErrors                []string                          // ids of jobs we expect to have produced jobErrors messages
 		expectedJobsToFail               []string                          // ids of jobs we expect to fail without having failed the overall scheduling cycle
+		expectedJobsRunsToPreempt        []string                          // ids of jobs we expect to be preempted by the scheduler
 		expectedJobRunPreempted          []string                          // ids of jobs we expect to have produced jobRunPreempted messages
 		expectedJobCancelled             []string                          // ids of jobs we expect to have  produced cancelled messages
 		expectedJobRequestCancel         []string                          // ids of jobs we expect to have produced request cancel
@@ -589,6 +621,39 @@ func TestScheduler_TestCycle(t *testing.T) {
 			expectedTerminal:      []string{leasedJob.Id()},
 			expectedQueuedVersion: leasedJob.QueuedVersion(),
 		},
+		"Job Run preemption requested": {
+			initialJobs: []*jobdb.Job{preemptibleLeasedJob},
+			runUpdates: []database.Run{
+				{
+					RunID:            preemptibleLeasedJob.LatestRun().Id(),
+					JobID:            preemptibleLeasedJob.Id(),
+					JobSet:           "testJobSet",
+					Executor:         "testExecutor",
+					PreemptRequested: true,
+					Serial:           1,
+				},
+			},
+			expectedJobRunPreempted: []string{preemptibleLeasedJob.Id()},
+			expectedJobErrors:       []string{preemptibleLeasedJob.Id()},
+			expectedJobRunErrors:    []string{preemptibleLeasedJob.Id()},
+			expectedTerminal:        []string{preemptibleLeasedJob.Id()},
+			expectedQueuedVersion:   preemptibleLeasedJob.QueuedVersion(),
+		},
+		"Job Run preemption requested - job not pre-emptible - no action expected": {
+			initialJobs: []*jobdb.Job{leasedJob},
+			runUpdates: []database.Run{
+				{
+					RunID:            leasedJob.LatestRun().Id(),
+					JobID:            leasedJob.Id(),
+					JobSet:           "testJobSet",
+					Executor:         "testExecutor",
+					PreemptRequested: true,
+					Serial:           1,
+				},
+			},
+			expectedLeased:        []string{leasedJob.Id()},
+			expectedQueuedVersion: leasedJob.QueuedVersion(),
+		},
 		"New job from postgres with expired queue ttl is cancel requested": {
 			jobUpdates: []database.Job{
 				{
@@ -758,12 +823,13 @@ func TestScheduler_TestCycle(t *testing.T) {
 			expectedQueuedVersion: leasedJob.QueuedVersion(),
 		},
 		"Job preempted": {
-			initialJobs:             []*jobdb.Job{leasedJob},
-			expectedJobRunPreempted: []string{leasedJob.Id()},
-			expectedJobErrors:       []string{leasedJob.Id()},
-			expectedJobRunErrors:    []string{leasedJob.Id()},
-			expectedTerminal:        []string{leasedJob.Id()},
-			expectedQueuedVersion:   leasedJob.QueuedVersion(),
+			initialJobs:               []*jobdb.Job{leasedJob},
+			expectedJobsRunsToPreempt: []string{leasedJob.Id()},
+			expectedJobRunPreempted:   []string{leasedJob.Id()},
+			expectedJobErrors:         []string{leasedJob.Id()},
+			expectedJobRunErrors:      []string{leasedJob.Id()},
+			expectedTerminal:          []string{leasedJob.Id()},
+			expectedQueuedVersion:     leasedJob.QueuedVersion(),
 		},
 		"Fetch fails": {
 			initialJobs:           []*jobdb.Job{leasedJob},
@@ -798,7 +864,7 @@ func TestScheduler_TestCycle(t *testing.T) {
 			testClock := clock.NewFakeClock(time.Now())
 			schedulingAlgo := &testSchedulingAlgo{
 				jobsToSchedule: tc.expectedJobRunLeased,
-				jobsToPreempt:  tc.expectedJobRunPreempted,
+				jobsToPreempt:  tc.expectedJobsRunsToPreempt,
 				jobsToFail:     tc.expectedJobsToFail,
 				shouldError:    tc.scheduleError,
 			}
@@ -956,7 +1022,7 @@ func subtractEventsFromOutstandingEventsByType(eventSequences []*armadaevents.Ev
 			key := fmt.Sprintf("%T", event.Event)
 			_, ok := outstandingEventsByType[key][jobId]
 			if !ok {
-				return errors.Errorf("received unexpected event for job %s: %v", jobId, event.Event)
+				return errors.Errorf("received unexpected event for job %s: %T - %v", jobId, event.Event, event.Event)
 			}
 			delete(outstandingEventsByType[key], jobId)
 		}
@@ -1122,6 +1188,7 @@ func TestScheduler_TestSyncState(t *testing.T) {
 						false,
 						false,
 						false,
+						false,
 						nil,
 						nil,
 						nil,
diff --git a/internal/scheduleringester/dbops_test.go b/internal/scheduleringester/dbops_test.go
index a3e7e807..552f24a2 100644
--- a/internal/scheduleringester/dbops_test.go
+++ b/internal/scheduleringester/dbops_test.go
@@ -32,6 +32,35 @@ func TestMerge(t *testing.T) {
 	assert.Equal(t, MarkJobsCancelRequested{jobId1: false, jobId2: true, jobId3: true}, markJobsCancelled1)
 }
 
+func TestMerge_MarkRunsForJobPreemptRequested(t *testing.T) {
+	jobId1 := util.NewULID()
+	jobId2 := util.NewULID()
+	jobId3 := util.NewULID()
+	jobId4 := util.NewULID()
+	markPreemptRequested1 := MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobId1}}
+	markPreemptRequested2 := MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobId2}}
+	markPreemptRequested3 := MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set2"}: []string{jobId3}}
+	markPreemptRequested4 := MarkRunsForJobPreemptRequested{JobSetKey{queue: "test-queue-2", jobSet: "set1"}: []string{jobId4}}
+
+	ok := markPreemptRequested1.Merge(markPreemptRequested2)
+	assert.True(t, ok)
+	ok = markPreemptRequested1.Merge(markPreemptRequested3)
+	assert.True(t, ok)
+	ok = markPreemptRequested1.Merge(markPreemptRequested4)
+	assert.True(t, ok)
+
+	assert.Equal(t,
+		MarkRunsForJobPreemptRequested{
+			// When jobset key matches, values are merged
+			JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobId1, jobId2},
+			// Does not merge values when different jobset in key
+			JobSetKey{queue: testQueueName, jobSet: "set2"}: []string{jobId3},
+			// Does not merge values when different queue in key
+			JobSetKey{queue: "test-queue-2", jobSet: "set1"}: []string{jobId4},
+		},
+		markPreemptRequested1)
+}
+
 func TestMerge_UpdateJobSchedulingInfo(t *testing.T) {
 	jobId1 := util.NewULID()
 	jobId2 := util.NewULID()
@@ -156,6 +185,14 @@ func TestDbOperationOptimisation(t *testing.T) {
 			MarkJobsCancelRequested{jobIds[1]: true},                                                                                                 // 4
 			MarkJobsCancelRequested{jobIds[2]: true},                                                                                                 // 4
 		}},
+		"MarkRunsForJobPreemptRequested": {N: 2, Ops: []DbOperation{
+			InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}},      // 1
+			InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}},      // 1
+			MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[0]}}, // 2                                                            // 2
+			MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[1]}}, // 2                                                            // 2
+			InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}},      // 1
+			MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[2]}}, // 2
+		}},
 		"MarkJobsSucceeded": {N: 2, Ops: []DbOperation{
 			InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0]}}, // 1
 			MarkJobsSucceeded{jobIds[0]: true},                        // 2
diff --git a/internal/scheduleringester/instructions_test.go b/internal/scheduleringester/instructions_test.go
index 87598bfb..848c6d91 100644
--- a/internal/scheduleringester/instructions_test.go
+++ b/internal/scheduleringester/instructions_test.go
@@ -58,6 +58,7 @@ func TestConvertSequence(t *testing.T) {
 					RunID:                  f.RunIdUuid,
 					JobID:                  f.JobIdString,
 					JobSet:                 f.JobSetName,
+					Queue:                  f.Queue,
 					Executor:               f.ExecutorId,
 					Node:                   f.NodeName,
 					ScheduledAtPriority:    &f.ScheduledAtPriority,
@@ -83,6 +84,10 @@ func TestConvertSequence(t *testing.T) {
 			events:   []*armadaevents.EventSequence_Event{f.Assigned},
 			expected: []DbOperation{MarkRunsPending{f.RunIdUuid: f.BaseTime}},
 		},
+		"job preemption requested": {
+			events:   []*armadaevents.EventSequence_Event{f.JobPreemptionRequested},
+			expected: []DbOperation{MarkRunsForJobPreemptRequested{JobSetKey{queue: f.Queue, jobSet: f.JobSetName}: []string{f.JobIdString}}},
+		},
 		"job run preempted": {
 			events:   []*armadaevents.EventSequence_Event{f.JobPreempted},
 			expected: []DbOperation{MarkRunsPreempted{f.RunIdUuid: f.BaseTime}},
diff --git a/internal/scheduleringester/schedulerdb_test.go b/internal/scheduleringester/schedulerdb_test.go
index 7be39edf..c3c50af5 100644
--- a/internal/scheduleringester/schedulerdb_test.go
+++ b/internal/scheduleringester/schedulerdb_test.go
@@ -12,6 +12,7 @@ import (
 	"github.com/stretchr/testify/require"
 	"golang.org/x/exp/constraints"
 	"golang.org/x/exp/maps"
+	"k8s.io/utils/strings/slices"
 
 	"github.com/armadaproject/armada/internal/common/armadacontext"
 	"github.com/armadaproject/armada/internal/common/ingest/metrics"
@@ -87,6 +88,23 @@ func TestWriteOps(t *testing.T) {
 				jobIds[1]: 3,
 			},
 		}},
+		"MarkRunsForJobPreemptRequested": {Ops: []DbOperation{
+			InsertJobs{
+				jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"},
+				jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"},
+				jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set2"},
+				jobIds[3]: &schedulerdb.Job{JobID: jobIds[3], Queue: "queue-2", JobSet: "set1"},
+				jobIds[4]: &schedulerdb.Job{JobID: jobIds[4], Queue: "queue-2", JobSet: "set2"},
+			},
+			InsertRuns{
+				runIds[0]: &JobRunDetails{Queue: testQueueName, DbRun: &schedulerdb.Run{JobID: jobIds[0], RunID: runIds[0], Queue: testQueueName, JobSet: "set1"}},
+				runIds[1]: &JobRunDetails{Queue: testQueueName, DbRun: &schedulerdb.Run{JobID: jobIds[1], RunID: runIds[1], Queue: testQueueName, JobSet: "set1"}},
+				runIds[2]: &JobRunDetails{Queue: testQueueName, DbRun: &schedulerdb.Run{JobID: jobIds[2], RunID: runIds[2], Queue: testQueueName, JobSet: "set2"}},
+				runIds[3]: &JobRunDetails{Queue: testQueueName, DbRun: &schedulerdb.Run{JobID: jobIds[3], RunID: runIds[3], Queue: "queue-2", JobSet: "set1"}},
+				runIds[4]: &JobRunDetails{Queue: testQueueName, DbRun: &schedulerdb.Run{JobID: jobIds[4], RunID: runIds[4], Queue: "queue-2", JobSet: "set2"}},
+			},
+			MarkRunsForJobPreemptRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[0], jobIds[1]}},
+		}},
 		"MarkJobSetsCancelRequested": {Ops: []DbOperation{
 			InsertJobs{
 				jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"},
@@ -479,6 +497,32 @@ func assertOpSuccess(t *testing.T, schedulerDb *SchedulerDb, serials map[string]
 			}
 		}
 		assert.Equal(t, len(expected), numChanged)
+	case MarkRunsForJobPreemptRequested:
+		jobs, err := selectNewJobs(ctx, 0)
+		if err != nil {
+			return errors.WithStack(err)
+		}
+
+		runsChanged := 0
+		for _, job := range jobs {
+			if req, ok := expected[JobSetKey{queue: job.Queue, jobSet: job.JobSet}]; ok {
+				runs, err := queries.SelectNewRunsForJobs(ctx, schedulerdb.SelectNewRunsForJobsParams{
+					Serial: serials["runs"],
+					JobIds: []string{job.JobID},
+				})
+				if err != nil {
+					return errors.WithStack(err)
+				}
+				for _, run := range runs {
+					if slices.Contains(req, run.JobID) {
+						assert.True(t, run.PreemptRequested)
+						runsChanged++
+					}
+				}
+			}
+		}
+
+		assert.Greater(t, runsChanged, 0)
 	case MarkJobsCancelled:
 		jobs, err := selectNewJobs(ctx, serials["jobs"])
 		if err != nil {