From 453c02e4b9fa84e01f7ab98987d53b93ec2cccec Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:09 -0500 Subject: [PATCH 01/16] fix: add preemptive_job_id field to internal JobRunPreempted proto Signed-off-by: William Vega --- pkg/armadaevents/events.pb.go | 534 +++++++++++++++++++--------------- pkg/armadaevents/events.proto | 1 + 2 files changed, 294 insertions(+), 241 deletions(-) diff --git a/pkg/armadaevents/events.pb.go b/pkg/armadaevents/events.pb.go index ed7f800a3b7..528652f2503 100644 --- a/pkg/armadaevents/events.pb.go +++ b/pkg/armadaevents/events.pb.go @@ -3362,9 +3362,10 @@ func (m *ReconciliationError) GetMessage() string { // Message to indicate that a JobRun has been preempted. type JobRunPreempted struct { - PreemptedJobId string `protobuf:"bytes,5,opt,name=preempted_job_id,json=preemptedJobId,proto3" json:"preemptedJobId,omitempty"` - PreemptedRunId string `protobuf:"bytes,6,opt,name=preempted_run_id,json=preemptedRunId,proto3" json:"preemptedRunId,omitempty"` - Reason string `protobuf:"bytes,7,opt,name=reason,proto3" json:"reason,omitempty"` + PreemptedJobId string `protobuf:"bytes,5,opt,name=preempted_job_id,json=preemptedJobId,proto3" json:"preemptedJobId,omitempty"` + PreemptedRunId string `protobuf:"bytes,6,opt,name=preempted_run_id,json=preemptedRunId,proto3" json:"preemptedRunId,omitempty"` + Reason string `protobuf:"bytes,7,opt,name=reason,proto3" json:"reason,omitempty"` + PreemptiveJobId string `protobuf:"bytes,8,opt,name=preemptive_job_id,json=preemptiveJobId,proto3" json:"preemptiveJobId,omitempty"` } func (m *JobRunPreempted) Reset() { *m = JobRunPreempted{} } @@ -3421,6 +3422,13 @@ func (m *JobRunPreempted) GetReason() string { return "" } +func (m *JobRunPreempted) GetPreemptiveJobId() string { + if m != nil { + return m.PreemptiveJobId + } + return "" +} + // Message used internally by Armada to see if messages can be propagated through a pulsar partition type PartitionMarker struct { // Group id identifies the group of partition markers, one per partition @@ -3751,244 +3759,245 @@ func init() { func init() { proto.RegisterFile("pkg/armadaevents/events.proto", fileDescriptor_6aab92ca59e015f8) } var fileDescriptor_6aab92ca59e015f8 = []byte{ - // 3787 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3b, 0x4d, 0x6f, 0x1b, 0xd7, - 0xb5, 0x1e, 0x7e, 0xf3, 0x50, 0xa2, 0xe8, 0xab, 0x0f, 0xd3, 0x4a, 0x2c, 0xca, 0x74, 0x5e, 0x62, - 0x07, 0x09, 0xe5, 0x38, 0x2f, 0x0f, 0xf9, 0x78, 0x48, 0x20, 0xda, 0xf2, 0x87, 0x62, 0xd9, 0x32, - 0x65, 0xe5, 0xf9, 0x3d, 0x04, 0x60, 0x86, 0x9c, 0x2b, 0x6a, 0x2c, 0x72, 0x86, 0x99, 0x0f, 0x45, - 0x02, 0x02, 0xbc, 0xa4, 0x48, 0xbb, 0xce, 0xa6, 0x40, 0x91, 0x4d, 0xb3, 0xe9, 0xa2, 0x05, 0xba, - 0x6c, 0x7f, 0x43, 0x17, 0x45, 0x91, 0x4d, 0x81, 0x6e, 0x4a, 0x14, 0x09, 0xba, 0xe1, 0xa2, 0x3f, - 0x20, 0xab, 0xe2, 0x7e, 0xcc, 0xcc, 0xbd, 0xc3, 0x4b, 0x8b, 0x72, 0x2c, 0xc3, 0x41, 0x56, 0xd2, - 0x9c, 0xcf, 0x3b, 0xe7, 0x9c, 0x7b, 0xe6, 0x9c, 0x73, 0x2f, 0xe1, 0x5c, 0x7f, 0xaf, 0xb3, 0xa2, - 0x3b, 0x3d, 0xdd, 0xd0, 0xf1, 0x3e, 0xb6, 0x3c, 0x77, 0x85, 0xfd, 0xa9, 0xf5, 0x1d, 0xdb, 0xb3, - 0xd1, 0x94, 0x88, 0x5a, 0xac, 0xee, 0xbd, 0xe9, 0xd6, 0x4c, 0x7b, 0x45, 0xef, 0x9b, 0x2b, 0x6d, - 0xdb, 0xc1, 0x2b, 0xfb, 0xaf, 0xad, 0x74, 0xb0, 0x85, 0x1d, 0xdd, 0xc3, 0x06, 0xe3, 0x58, 0xbc, - 0x28, 0xd0, 0x58, 0xd8, 0xfb, 0xc4, 0x76, 0xf6, 0x4c, 0xab, 0xa3, 0xa2, 0xac, 0x74, 0x6c, 0xbb, - 0xd3, 0xc5, 0x2b, 0xf4, 0xa9, 0xe5, 0xef, 0xac, 0x78, 0x66, 0x0f, 0xbb, 0x9e, 0xde, 0xeb, 0x73, - 0x82, 0xff, 0x8c, 0x44, 0xf5, 0xf4, 0xf6, 0xae, 0x69, 0x61, 0xe7, 0x70, 0x85, 0xae, 0xb7, 0x6f, - 0xae, 0x38, 0xd8, 0xb5, 0x7d, 0xa7, 0x8d, 0x47, 0xc4, 0xbe, 0x6d, 0x5a, 0x1e, 0x76, 0x2c, 0xbd, - 0xbb, 0xe2, 0xb6, 0x77, 0xb1, 0xe1, 0x77, 0xb1, 0x13, 0xfd, 0x67, 0xb7, 0x1e, 0xe2, 0xb6, 0xe7, - 0x8e, 0x00, 0x18, 0x6f, 0xf5, 0xef, 0xf3, 0x30, 0xbd, 0x46, 0xde, 0x75, 0x0b, 0x7f, 0xec, 0x63, - 0xab, 0x8d, 0xd1, 0x25, 0x48, 0x7f, 0xec, 0x63, 0x1f, 0x97, 0xb5, 0x65, 0xed, 0x62, 0xbe, 0x3e, - 0x3b, 0x1c, 0x54, 0x66, 0x28, 0xe0, 0x15, 0xbb, 0x67, 0x7a, 0xb8, 0xd7, 0xf7, 0x0e, 0x1b, 0x8c, - 0x02, 0xbd, 0x0d, 0x53, 0x0f, 0xed, 0x56, 0xd3, 0xc5, 0x5e, 0xd3, 0xd2, 0x7b, 0xb8, 0x9c, 0xa0, - 0x1c, 0xe5, 0xe1, 0xa0, 0x32, 0xf7, 0xd0, 0x6e, 0x6d, 0x61, 0xef, 0x8e, 0xde, 0x13, 0xd9, 0x20, - 0x82, 0xa2, 0x57, 0x21, 0xeb, 0xbb, 0xd8, 0x69, 0x9a, 0x46, 0x39, 0x49, 0xd9, 0xe6, 0x86, 0x83, - 0x4a, 0x89, 0x80, 0x6e, 0x19, 0x02, 0x4b, 0x86, 0x41, 0xd0, 0x2b, 0x90, 0xe9, 0x38, 0xb6, 0xdf, - 0x77, 0xcb, 0xa9, 0xe5, 0x64, 0x40, 0xcd, 0x20, 0x22, 0x35, 0x83, 0xa0, 0xbb, 0x90, 0x61, 0x0e, - 0x2c, 0xa7, 0x97, 0x93, 0x17, 0x0b, 0x57, 0xce, 0xd7, 0x44, 0xaf, 0xd6, 0xa4, 0x17, 0x66, 0x4f, - 0x4c, 0x20, 0xc3, 0x8b, 0x02, 0x79, 0x1c, 0xfc, 0x71, 0x16, 0xd2, 0x94, 0x0e, 0xbd, 0x0f, 0xd9, - 0xb6, 0x83, 0x89, 0xf5, 0xcb, 0x68, 0x59, 0xbb, 0x58, 0xb8, 0xb2, 0x58, 0x63, 0x5e, 0xad, 0x05, - 0x5e, 0xad, 0xdd, 0x0f, 0xbc, 0x5a, 0x9f, 0x1f, 0x0e, 0x2a, 0xa7, 0x39, 0xb9, 0x20, 0x35, 0x90, - 0x80, 0x36, 0x21, 0xef, 0xfa, 0xad, 0x9e, 0xe9, 0xad, 0xdb, 0x2d, 0x6a, 0xef, 0xc2, 0x95, 0x33, - 0xf2, 0x52, 0xb7, 0x02, 0x74, 0xfd, 0xcc, 0x70, 0x50, 0x99, 0x0d, 0xa9, 0x23, 0x69, 0x37, 0x4f, - 0x35, 0x22, 0x21, 0x68, 0x17, 0x66, 0x1c, 0xdc, 0x77, 0x4c, 0xdb, 0x31, 0x3d, 0xd3, 0xc5, 0x44, - 0x6e, 0x82, 0xca, 0x3d, 0x27, 0xcb, 0x6d, 0xc8, 0x44, 0xf5, 0x73, 0xc3, 0x41, 0xe5, 0x6c, 0x8c, - 0x53, 0xd2, 0x11, 0x17, 0x8b, 0x3c, 0x40, 0x31, 0xd0, 0x16, 0xf6, 0xa8, 0x2f, 0x0b, 0x57, 0x96, - 0x1f, 0xa9, 0x6c, 0x0b, 0x7b, 0xf5, 0xe5, 0xe1, 0xa0, 0xf2, 0xfc, 0x28, 0xbf, 0xa4, 0x52, 0x21, - 0x1f, 0x75, 0xa1, 0x24, 0x42, 0x0d, 0xf2, 0x82, 0x29, 0xaa, 0x73, 0x69, 0xbc, 0x4e, 0x42, 0x55, - 0x5f, 0x1a, 0x0e, 0x2a, 0x8b, 0x71, 0x5e, 0x49, 0xdf, 0x88, 0x64, 0xe2, 0x9f, 0xb6, 0x6e, 0xb5, - 0x71, 0x97, 0xa8, 0x49, 0xab, 0xfc, 0x73, 0x35, 0x40, 0x33, 0xff, 0x84, 0xd4, 0xb2, 0x7f, 0x42, - 0x30, 0xfa, 0x10, 0xa6, 0xc2, 0x07, 0x62, 0xaf, 0x0c, 0x8f, 0x21, 0xb5, 0x50, 0x62, 0xa9, 0xc5, - 0xe1, 0xa0, 0xb2, 0x20, 0xf2, 0x48, 0xa2, 0x25, 0x69, 0x91, 0xf4, 0x2e, 0xb3, 0x4c, 0x76, 0xbc, - 0x74, 0x46, 0x21, 0x4a, 0xef, 0x8e, 0x5a, 0x44, 0x92, 0x46, 0xa4, 0x93, 0x0d, 0xec, 0xb7, 0xdb, - 0x18, 0x1b, 0xd8, 0x28, 0xe7, 0x54, 0xd2, 0xd7, 0x05, 0x0a, 0x26, 0x5d, 0xe4, 0x91, 0xa5, 0x8b, - 0x18, 0x62, 0xeb, 0x87, 0x76, 0x6b, 0xcd, 0x71, 0x6c, 0xc7, 0x2d, 0xe7, 0x55, 0xb6, 0x5e, 0x0f, - 0xd0, 0xcc, 0xd6, 0x21, 0xb5, 0x6c, 0xeb, 0x10, 0xcc, 0xd7, 0xdb, 0xf0, 0xad, 0xdb, 0x58, 0x77, - 0xb1, 0x51, 0x86, 0x31, 0xeb, 0x0d, 0x29, 0xc2, 0xf5, 0x86, 0x90, 0x91, 0xf5, 0x86, 0x18, 0x64, - 0x40, 0x91, 0x3d, 0xaf, 0xba, 0xae, 0xd9, 0xb1, 0xb0, 0x51, 0x2e, 0x50, 0xf9, 0xcf, 0xab, 0xe4, - 0x07, 0x34, 0xf5, 0xe7, 0x87, 0x83, 0x4a, 0x59, 0xe6, 0x93, 0x74, 0xc4, 0x64, 0xa2, 0x8f, 0x60, - 0x9a, 0x41, 0x1a, 0xbe, 0x65, 0x99, 0x56, 0xa7, 0x3c, 0x45, 0x95, 0x3c, 0xa7, 0x52, 0xc2, 0x49, - 0xea, 0xcf, 0x0d, 0x07, 0x95, 0x33, 0x12, 0x97, 0xa4, 0x42, 0x16, 0x48, 0x32, 0x06, 0x03, 0x44, - 0x8e, 0x9d, 0x56, 0x65, 0x8c, 0x75, 0x99, 0x88, 0x65, 0x8c, 0x18, 0xa7, 0x9c, 0x31, 0x62, 0xc8, - 0xc8, 0x1f, 0xdc, 0xc9, 0xc5, 0xf1, 0xfe, 0xe0, 0x7e, 0x16, 0xfc, 0xa1, 0x70, 0xb5, 0x24, 0x0d, - 0x7d, 0xa6, 0xc1, 0xbc, 0xeb, 0xe9, 0x96, 0xa1, 0x77, 0x6d, 0x0b, 0xdf, 0xb2, 0x3a, 0x0e, 0x76, - 0xdd, 0x5b, 0xd6, 0x8e, 0x5d, 0x2e, 0x51, 0x3d, 0x17, 0x62, 0x89, 0x55, 0x45, 0x5a, 0xbf, 0x30, - 0x1c, 0x54, 0x2a, 0x4a, 0x29, 0x92, 0x66, 0xb5, 0x22, 0x74, 0x00, 0xb3, 0xc1, 0x47, 0x7a, 0xdb, - 0x33, 0xbb, 0xa6, 0xab, 0x7b, 0xa6, 0x6d, 0x95, 0x4f, 0x53, 0xfd, 0xe7, 0xe3, 0xf9, 0x69, 0x84, - 0xb0, 0x7e, 0x7e, 0x38, 0xa8, 0x9c, 0x53, 0x48, 0x90, 0x74, 0xab, 0x54, 0x44, 0x4e, 0xdc, 0x74, - 0x30, 0x21, 0xc4, 0x46, 0x79, 0x76, 0xbc, 0x13, 0x43, 0x22, 0xd1, 0x89, 0x21, 0x50, 0xe5, 0xc4, - 0x10, 0x49, 0x34, 0xf5, 0x75, 0xc7, 0x33, 0x89, 0xda, 0x0d, 0xdd, 0xd9, 0xc3, 0x4e, 0x79, 0x4e, - 0xa5, 0x69, 0x53, 0x26, 0x62, 0x9a, 0x62, 0x9c, 0xb2, 0xa6, 0x18, 0x12, 0x7d, 0xa9, 0x81, 0xbc, - 0x34, 0xd3, 0xb6, 0x1a, 0xe4, 0xa3, 0xed, 0x92, 0xd7, 0x9b, 0xa7, 0x4a, 0x5f, 0x7a, 0xc4, 0xeb, - 0x89, 0xe4, 0xf5, 0x97, 0x86, 0x83, 0xca, 0x85, 0xb1, 0xd2, 0xa4, 0x85, 0x8c, 0x57, 0x8a, 0x1e, - 0x40, 0x81, 0x20, 0x31, 0x2d, 0x7f, 0x8c, 0xf2, 0x02, 0x5d, 0xc3, 0xd9, 0xd1, 0x35, 0x70, 0x82, - 0xfa, 0xd9, 0xe1, 0xa0, 0x32, 0x2f, 0x70, 0x48, 0x7a, 0x44, 0x51, 0xe8, 0x0b, 0x0d, 0x48, 0xa0, - 0xab, 0xde, 0xf4, 0x0c, 0xd5, 0xf2, 0xc2, 0x88, 0x16, 0xd5, 0x6b, 0xbe, 0x30, 0x1c, 0x54, 0x96, - 0xd5, 0x72, 0x24, 0xdd, 0x63, 0x74, 0x45, 0x71, 0x14, 0x7e, 0x24, 0xca, 0xe5, 0xf1, 0x71, 0x14, - 0x12, 0x89, 0x71, 0x14, 0x02, 0x55, 0x71, 0x14, 0x22, 0x79, 0x32, 0xf8, 0x40, 0xef, 0x9a, 0x06, - 0x2d, 0xa6, 0xce, 0x8e, 0x49, 0x06, 0x21, 0x45, 0x98, 0x0c, 0x42, 0xc8, 0x48, 0x32, 0x88, 0x68, - 0xb3, 0x90, 0xa6, 0x22, 0xaa, 0x5f, 0xe5, 0x61, 0x56, 0xb1, 0xd5, 0x10, 0x86, 0xe9, 0x60, 0x1f, - 0x35, 0x4d, 0x92, 0x24, 0x92, 0x2a, 0x2b, 0xbf, 0xef, 0xb7, 0xb0, 0x63, 0x61, 0x0f, 0xbb, 0x81, - 0x0c, 0x9a, 0x25, 0xe8, 0x4a, 0x1c, 0x01, 0x22, 0xd4, 0x76, 0x53, 0x22, 0x1c, 0x7d, 0xa5, 0x41, - 0xb9, 0xa7, 0x1f, 0x34, 0x03, 0xa0, 0xdb, 0xdc, 0xb1, 0x9d, 0x66, 0x1f, 0x3b, 0xa6, 0x6d, 0xd0, - 0x4a, 0xb6, 0x70, 0xe5, 0xbf, 0x8f, 0xcc, 0x0b, 0xb5, 0x0d, 0xfd, 0x20, 0x00, 0xbb, 0xd7, 0x6d, - 0x67, 0x93, 0xb2, 0xaf, 0x59, 0x9e, 0x73, 0xc8, 0x12, 0x56, 0x4f, 0x85, 0x17, 0xd6, 0x34, 0xaf, - 0x24, 0x40, 0xbf, 0xd4, 0x60, 0xc1, 0xb3, 0x3d, 0xbd, 0xdb, 0x6c, 0xfb, 0x3d, 0xbf, 0xab, 0x7b, - 0xe6, 0x3e, 0x6e, 0xfa, 0xae, 0xde, 0xc1, 0xbc, 0x6c, 0x7e, 0xe7, 0xe8, 0xa5, 0xdd, 0x27, 0xfc, - 0x57, 0x43, 0xf6, 0x6d, 0xc2, 0xcd, 0x56, 0x56, 0x1d, 0x0e, 0x2a, 0x4b, 0x9e, 0x02, 0x2d, 0x2c, - 0x6c, 0x4e, 0x85, 0x47, 0x2f, 0x43, 0x86, 0xb4, 0x15, 0xa6, 0x41, 0xab, 0x23, 0xde, 0x82, 0x3c, - 0xb4, 0x5b, 0x52, 0x63, 0x90, 0xa6, 0x00, 0x42, 0xeb, 0xf8, 0x16, 0xa1, 0xcd, 0x46, 0xb4, 0x8e, - 0x6f, 0xc9, 0xb4, 0x14, 0x40, 0x9d, 0xa1, 0xef, 0x77, 0xd4, 0xce, 0xc8, 0x4d, 0xea, 0x8c, 0xd5, - 0xfd, 0xce, 0x23, 0x9d, 0xa1, 0xab, 0xf0, 0xa2, 0x33, 0x94, 0x04, 0x8b, 0x5f, 0x6b, 0xb0, 0x38, - 0xde, 0xcf, 0xe8, 0x02, 0x24, 0xf7, 0xf0, 0x21, 0xef, 0xc9, 0x4e, 0x0f, 0x07, 0x95, 0xe9, 0x3d, - 0x7c, 0x28, 0x48, 0x25, 0x58, 0xf4, 0xbf, 0x90, 0xde, 0xd7, 0xbb, 0x3e, 0xe6, 0x25, 0x7f, 0xad, - 0xc6, 0xda, 0xc9, 0x9a, 0xd8, 0x4e, 0xd6, 0xfa, 0x7b, 0x1d, 0x02, 0xa8, 0x05, 0x56, 0xa8, 0xdd, - 0xf3, 0x75, 0xcb, 0x33, 0xbd, 0x43, 0x66, 0x3b, 0x2a, 0x40, 0xb4, 0x1d, 0x05, 0xbc, 0x9d, 0x78, - 0x53, 0x5b, 0xfc, 0xb5, 0x06, 0x67, 0xc7, 0xfa, 0xfb, 0x99, 0x58, 0x21, 0x31, 0xe2, 0x78, 0xff, - 0x3c, 0x0b, 0x4b, 0x5c, 0x4f, 0xe5, 0xb4, 0x52, 0x62, 0x3d, 0x95, 0x4b, 0x94, 0x92, 0xd5, 0xef, - 0x33, 0x90, 0x0f, 0x1b, 0x3c, 0x74, 0x13, 0x4a, 0x06, 0x36, 0xfc, 0x7e, 0xd7, 0x6c, 0xd3, 0x48, - 0x23, 0x41, 0xcd, 0x3a, 0x6a, 0x9a, 0x5d, 0x25, 0x9c, 0x14, 0xde, 0x33, 0x31, 0x14, 0xba, 0x02, - 0x39, 0xde, 0xc8, 0x1c, 0xd2, 0xbc, 0x36, 0x5d, 0x5f, 0x18, 0x0e, 0x2a, 0x28, 0x80, 0x09, 0xac, - 0x21, 0x1d, 0x6a, 0x00, 0xb0, 0xc9, 0xc0, 0x06, 0xf6, 0x74, 0xde, 0x52, 0x95, 0xe5, 0xdd, 0x70, - 0x37, 0xc4, 0xb3, 0x1e, 0x3f, 0xa2, 0x17, 0x7b, 0xfc, 0x08, 0x8a, 0x3e, 0x04, 0xe8, 0xe9, 0xa6, - 0xc5, 0xf8, 0x78, 0xff, 0x54, 0x1d, 0x97, 0x61, 0x37, 0x42, 0x4a, 0x26, 0x3d, 0xe2, 0x14, 0xa5, - 0x47, 0x50, 0x74, 0x17, 0xb2, 0x7c, 0x96, 0x51, 0xce, 0xd0, 0xcd, 0xbb, 0x34, 0x4e, 0x34, 0x17, - 0x4b, 0xbb, 0x71, 0xce, 0x22, 0x76, 0xe3, 0x1c, 0x44, 0xcc, 0xd6, 0x35, 0x77, 0xb0, 0x67, 0xf6, - 0x30, 0xcd, 0x26, 0xdc, 0x6c, 0x01, 0x4c, 0x34, 0x5b, 0x00, 0x43, 0x6f, 0x02, 0xe8, 0xde, 0x86, - 0xed, 0x7a, 0x77, 0xad, 0x36, 0xa6, 0x1d, 0x51, 0x8e, 0x2d, 0x3f, 0x82, 0x8a, 0xcb, 0x8f, 0xa0, - 0xe8, 0x1d, 0x28, 0xf4, 0xf9, 0x17, 0xb8, 0xd5, 0xc5, 0xb4, 0xe3, 0xc9, 0xb1, 0x82, 0x41, 0x00, - 0x0b, 0xbc, 0x22, 0x35, 0xba, 0x01, 0x33, 0x6d, 0xdb, 0x6a, 0xfb, 0x8e, 0x83, 0xad, 0xf6, 0xe1, - 0x96, 0xbe, 0x83, 0x69, 0x77, 0x93, 0x63, 0xa1, 0x12, 0x43, 0x89, 0xa1, 0x12, 0x43, 0xa1, 0x37, - 0x20, 0x1f, 0x4e, 0x86, 0x68, 0x03, 0x93, 0xe7, 0x83, 0x86, 0x00, 0x28, 0x30, 0x47, 0x94, 0x64, - 0xf1, 0xa6, 0x7b, 0x8d, 0x07, 0x1d, 0xa6, 0x4d, 0x09, 0x5f, 0xbc, 0x00, 0x16, 0x17, 0x2f, 0x80, - 0x85, 0xfc, 0x5e, 0x3c, 0x32, 0xbf, 0x5f, 0x87, 0x12, 0x3e, 0x60, 0xd3, 0xad, 0x26, 0x61, 0xf2, - 0x1d, 0x93, 0xd6, 0xf3, 0x79, 0xd6, 0x49, 0x05, 0xb8, 0x75, 0xbb, 0xb5, 0xed, 0x98, 0x02, 0x7b, - 0x51, 0xc6, 0x84, 0xdb, 0x6e, 0xba, 0x54, 0x5c, 0x4f, 0xe5, 0x66, 0x4a, 0xa5, 0xea, 0x9f, 0x35, - 0x98, 0x53, 0x45, 0x5f, 0x6c, 0x27, 0x68, 0x4f, 0x64, 0x27, 0x7c, 0x00, 0xb9, 0xbe, 0x6d, 0x34, - 0xdd, 0x3e, 0x6e, 0xf3, 0xbc, 0x12, 0xdb, 0x07, 0x9b, 0xb6, 0xb1, 0xd5, 0xc7, 0xed, 0xff, 0x31, - 0xbd, 0xdd, 0xd5, 0x7d, 0xdb, 0x34, 0x6e, 0x9b, 0x2e, 0x0f, 0xd8, 0x3e, 0xc3, 0x48, 0xc5, 0x4e, - 0x96, 0x03, 0xeb, 0x39, 0xc8, 0x30, 0x2d, 0xd5, 0xbf, 0x24, 0xa1, 0x14, 0x8f, 0xf8, 0x1f, 0xd3, - 0xab, 0xa0, 0x07, 0x90, 0x35, 0x59, 0x2f, 0xc5, 0x6b, 0xb1, 0xff, 0x10, 0x32, 0x6f, 0x2d, 0x1a, - 0xac, 0xd6, 0xf6, 0x5f, 0xab, 0xf1, 0xa6, 0x8b, 0x9a, 0x80, 0x4a, 0xe6, 0x9c, 0xb2, 0x64, 0x0e, - 0x44, 0x0d, 0xc8, 0xba, 0xd8, 0xd9, 0x37, 0xdb, 0x98, 0xe7, 0xb5, 0x8a, 0x28, 0xb9, 0x6d, 0x3b, - 0x98, 0xc8, 0xdc, 0x62, 0x24, 0x91, 0x4c, 0xce, 0x23, 0xcb, 0xe4, 0x40, 0xf4, 0x01, 0xe4, 0xdb, - 0xb6, 0xb5, 0x63, 0x76, 0x36, 0xf4, 0x3e, 0xcf, 0x6c, 0xe7, 0x54, 0x52, 0xaf, 0x06, 0x44, 0x7c, - 0x3e, 0x14, 0x3c, 0xc6, 0xe6, 0x43, 0x21, 0x55, 0xe4, 0xd0, 0x7f, 0xa5, 0x00, 0x22, 0xe7, 0xa0, - 0xb7, 0xa0, 0x80, 0x0f, 0x70, 0xdb, 0xf7, 0x6c, 0x3a, 0x33, 0xd5, 0xa2, 0x51, 0x6b, 0x00, 0x96, - 0xb6, 0x0f, 0x44, 0x50, 0xb2, 0xc7, 0x2d, 0xbd, 0x87, 0xdd, 0xbe, 0xde, 0x0e, 0x66, 0xb4, 0x74, - 0x31, 0x21, 0x50, 0xdc, 0xe3, 0x21, 0x10, 0xbd, 0x08, 0x29, 0x3a, 0xd5, 0x65, 0xe3, 0x59, 0x34, - 0x1c, 0x54, 0x8a, 0x96, 0x3c, 0xcf, 0xa5, 0x78, 0xf4, 0x1e, 0x4c, 0xef, 0x85, 0x81, 0x47, 0xd6, - 0x96, 0xa2, 0x0c, 0xb4, 0x48, 0x8e, 0x10, 0xd2, 0xea, 0xa6, 0x44, 0x38, 0xda, 0x81, 0x82, 0x6e, - 0x59, 0xb6, 0x47, 0x3f, 0x5f, 0xc1, 0xc8, 0xf6, 0xd2, 0xb8, 0x30, 0xad, 0xad, 0x46, 0xb4, 0xac, - 0xec, 0xa2, 0x79, 0x47, 0x90, 0x20, 0xe6, 0x1d, 0x01, 0x8c, 0x1a, 0x90, 0xe9, 0xea, 0x2d, 0xdc, - 0x0d, 0xbe, 0x17, 0x2f, 0x8c, 0x55, 0x71, 0x9b, 0x92, 0x31, 0xe9, 0x74, 0x30, 0xcc, 0xf8, 0xc4, - 0xc1, 0x30, 0x83, 0x2c, 0xee, 0x40, 0x29, 0xbe, 0x9e, 0xc9, 0xca, 0x8c, 0x4b, 0x62, 0x99, 0x91, - 0x3f, 0xb2, 0xb2, 0xd1, 0xa1, 0x20, 0x2c, 0xea, 0x24, 0x54, 0x54, 0x7f, 0xab, 0xc1, 0x9c, 0x6a, - 0xef, 0xa2, 0x0d, 0x61, 0xc7, 0x6b, 0x7c, 0xfc, 0xa4, 0x08, 0x75, 0xce, 0x3b, 0x66, 0xab, 0x47, - 0x1b, 0xbd, 0x0e, 0x45, 0xcb, 0x36, 0x70, 0x53, 0x27, 0x0a, 0xba, 0xa6, 0xeb, 0x95, 0x13, 0x74, - 0xa4, 0x4f, 0xc7, 0x56, 0x04, 0xb3, 0x1a, 0x20, 0x04, 0xee, 0x69, 0x09, 0x51, 0xfd, 0x04, 0x66, - 0x62, 0x43, 0x65, 0xa9, 0xe8, 0x49, 0x4c, 0x58, 0xf4, 0x44, 0x5f, 0xa2, 0xe4, 0x51, 0x5f, 0x22, - 0xf6, 0x05, 0xa9, 0xfe, 0x3c, 0x01, 0x05, 0xa1, 0xc3, 0x47, 0x0f, 0x61, 0x86, 0x7f, 0x15, 0x4d, - 0xab, 0xc3, 0x3a, 0xc9, 0x04, 0x1f, 0x37, 0x8d, 0x9c, 0xb8, 0xac, 0xdb, 0xad, 0xad, 0x90, 0x96, - 0x36, 0x92, 0xf4, 0x1b, 0xe6, 0x4a, 0x30, 0xf1, 0x1b, 0x26, 0x63, 0xd0, 0x03, 0x58, 0xf0, 0xfb, - 0xa4, 0xbf, 0x6d, 0xba, 0xfc, 0xec, 0xa2, 0x69, 0xf9, 0xbd, 0x16, 0x76, 0xe8, 0xea, 0xd3, 0xac, - 0xe3, 0x62, 0x14, 0xc1, 0xe1, 0xc6, 0x1d, 0x8a, 0x17, 0x3b, 0x2e, 0x15, 0x5e, 0xb0, 0x43, 0x6a, - 0x42, 0x3b, 0xdc, 0x04, 0x34, 0x3a, 0xd5, 0x97, 0x7c, 0xa0, 0x4d, 0xe6, 0x83, 0xea, 0x01, 0x94, - 0xe2, 0xb3, 0xfa, 0xa7, 0xe4, 0xcb, 0x3d, 0xc8, 0x87, 0x93, 0x76, 0xf4, 0x0a, 0x64, 0x1c, 0xac, - 0xbb, 0xb6, 0xc5, 0x77, 0x0b, 0xdd, 0xf6, 0x0c, 0x22, 0x6e, 0x7b, 0x06, 0x79, 0x0c, 0x65, 0xf7, - 0x61, 0x8a, 0x19, 0xe9, 0xba, 0xd9, 0xf5, 0xb0, 0x83, 0xae, 0x41, 0xc6, 0xf5, 0x74, 0x0f, 0xbb, - 0x65, 0x6d, 0x39, 0x79, 0xb1, 0x78, 0x65, 0x61, 0x74, 0x8c, 0x4e, 0xd0, 0x6c, 0x1d, 0x8c, 0x52, - 0x5c, 0x07, 0x83, 0x54, 0x7f, 0xa6, 0xc1, 0x94, 0x78, 0x5a, 0xf0, 0x64, 0xc4, 0x1e, 0xcf, 0x18, - 0x24, 0x71, 0x4c, 0x89, 0x87, 0x0a, 0x27, 0x67, 0x4b, 0xf2, 0x15, 0x64, 0x47, 0x12, 0x4d, 0xdf, - 0xc5, 0x0e, 0x8f, 0x56, 0xfa, 0x15, 0x64, 0xe0, 0x6d, 0x57, 0x8a, 0x76, 0x88, 0xa0, 0xdc, 0x0d, - 0x64, 0xad, 0xe2, 0x11, 0x05, 0xea, 0x44, 0x83, 0x20, 0xb2, 0xc9, 0x5c, 0x9a, 0x8c, 0x26, 0x1d, - 0x04, 0xd1, 0x94, 0x25, 0xb1, 0x8b, 0x29, 0x4b, 0x42, 0x3c, 0x46, 0xc8, 0x7c, 0x9d, 0xa6, 0x6b, - 0x8d, 0x8e, 0x1c, 0x62, 0x35, 0x40, 0xf2, 0x18, 0x35, 0xc0, 0xab, 0x90, 0xa5, 0x49, 0x37, 0xdc, - 0xe2, 0xd4, 0x27, 0x04, 0x24, 0x1f, 0xb7, 0x32, 0xc8, 0x23, 0x52, 0x4d, 0xfa, 0x07, 0xa6, 0x9a, - 0x26, 0x9c, 0xdd, 0xd5, 0xdd, 0x66, 0x90, 0x1c, 0x8d, 0xa6, 0xee, 0x35, 0xc3, 0xbd, 0x9e, 0xa1, - 0x7d, 0x04, 0x1d, 0x62, 0xee, 0xea, 0xee, 0x56, 0x40, 0xb3, 0xea, 0x6d, 0x8e, 0xee, 0xfc, 0x05, - 0x35, 0x05, 0xda, 0x86, 0x79, 0xb5, 0xf0, 0x2c, 0x5d, 0x39, 0x9d, 0xb1, 0xbb, 0x8f, 0x94, 0x3c, - 0xab, 0x40, 0xa3, 0xcf, 0x35, 0x28, 0x93, 0xaf, 0xa0, 0x83, 0x3f, 0xf6, 0x4d, 0x07, 0xf7, 0x48, - 0x58, 0x34, 0xed, 0x7d, 0xec, 0x74, 0xf5, 0x43, 0x7e, 0x5c, 0x75, 0x7e, 0x34, 0xe5, 0x6f, 0xda, - 0x46, 0x43, 0x60, 0x60, 0xaf, 0xd6, 0x97, 0x81, 0x77, 0x99, 0x10, 0xf1, 0xd5, 0xd4, 0x14, 0x42, - 0x08, 0xc1, 0x31, 0x06, 0x63, 0x85, 0x23, 0x07, 0x63, 0x2f, 0x42, 0xaa, 0x6f, 0xdb, 0x5d, 0xda, - 0xc6, 0xf1, 0x4a, 0x8f, 0x3c, 0x8b, 0x95, 0x1e, 0x79, 0x16, 0x67, 0x17, 0xeb, 0xa9, 0x5c, 0xae, - 0x94, 0x27, 0x9f, 0xc3, 0xa2, 0x7c, 0xc2, 0x35, 0xba, 0xa1, 0x92, 0x27, 0xbe, 0xa1, 0x52, 0xc7, - 0xb0, 0x46, 0x7a, 0x62, 0x6b, 0x64, 0x26, 0xb7, 0x46, 0xf5, 0x8b, 0x04, 0x4c, 0x4b, 0x87, 0x70, - 0x3f, 0x4d, 0x33, 0xfc, 0x2a, 0x01, 0x0b, 0xea, 0x57, 0x3a, 0x91, 0x56, 0xf4, 0x26, 0x90, 0xa2, - 0xf2, 0x56, 0x54, 0x74, 0xcd, 0x8f, 0x74, 0xa2, 0xd4, 0x9c, 0x41, 0x45, 0x3a, 0x72, 0x8e, 0x17, - 0xb0, 0xa3, 0x07, 0x50, 0x30, 0x85, 0x13, 0xc3, 0xa4, 0xea, 0x60, 0x47, 0x3c, 0x27, 0x64, 0xa3, - 0x8e, 0x31, 0xa7, 0x83, 0xa2, 0xa8, 0x7a, 0x06, 0x52, 0xa4, 0x2a, 0xac, 0xee, 0x43, 0x96, 0x2f, - 0x07, 0xbd, 0x0e, 0x79, 0x9a, 0x8b, 0x69, 0x77, 0xc5, 0x4a, 0x78, 0x5a, 0xde, 0x10, 0x60, 0xec, - 0xc6, 0x4c, 0x2e, 0x80, 0xa1, 0xff, 0x02, 0x20, 0xe9, 0x87, 0x67, 0xe1, 0x04, 0xcd, 0x65, 0xb4, - 0x8b, 0xeb, 0xdb, 0xc6, 0x48, 0xea, 0xcd, 0x87, 0xc0, 0xea, 0xef, 0x13, 0x50, 0x10, 0xcf, 0x28, - 0x1f, 0x4b, 0xf9, 0xa7, 0x10, 0x74, 0xd8, 0x4d, 0xdd, 0x30, 0xc8, 0x5f, 0x1c, 0x7c, 0x28, 0x57, - 0xc6, 0x1a, 0x29, 0xf8, 0x7f, 0x35, 0xe0, 0x60, 0xfd, 0x14, 0xbd, 0x87, 0x61, 0xc6, 0x50, 0x82, - 0xd6, 0x52, 0x1c, 0xb7, 0xb8, 0x07, 0xf3, 0x4a, 0x51, 0x62, 0x17, 0x94, 0x7e, 0x52, 0x5d, 0xd0, - 0x6f, 0xd2, 0x30, 0xaf, 0x3c, 0x1b, 0x8e, 0x45, 0x70, 0xf2, 0x89, 0x44, 0xf0, 0x2f, 0x34, 0x95, - 0x65, 0xd9, 0xc1, 0xd0, 0x5b, 0x13, 0x1c, 0x58, 0x3f, 0x29, 0x1b, 0xcb, 0x61, 0x91, 0x7e, 0xac, - 0x98, 0xcc, 0x4c, 0x1a, 0x93, 0xe8, 0x32, 0x6b, 0x28, 0xa9, 0x2e, 0x76, 0x6c, 0x13, 0xec, 0xd0, - 0x98, 0xaa, 0x2c, 0x07, 0xa1, 0xf7, 0x60, 0x3a, 0xe0, 0x60, 0x63, 0x8c, 0x5c, 0x34, 0x63, 0xe0, - 0x34, 0xf1, 0x49, 0xc6, 0x94, 0x08, 0x17, 0xb2, 0x64, 0xfe, 0x18, 0x59, 0x12, 0x8e, 0xca, 0x92, - 0x4f, 0x35, 0x36, 0xa5, 0x54, 0x3b, 0xd0, 0x60, 0x26, 0x76, 0x25, 0xe3, 0x47, 0xff, 0xcd, 0x91, - 0x5e, 0xf0, 0x33, 0x0d, 0xf2, 0xe1, 0x8d, 0x1f, 0xb4, 0x0a, 0x19, 0xcc, 0x6e, 0x8d, 0xb0, 0xb4, - 0x33, 0x1b, 0xbb, 0xd1, 0x47, 0x70, 0xfc, 0x0e, 0x5f, 0xec, 0xa2, 0x48, 0x83, 0x33, 0x3e, 0x46, - 0x01, 0xfe, 0x07, 0x2d, 0x28, 0xc0, 0x47, 0x56, 0x91, 0xfc, 0xe1, 0xab, 0x38, 0x39, 0xd3, 0x7d, - 0x0f, 0x90, 0xa6, 0x6b, 0x21, 0x8d, 0xb4, 0x87, 0x9d, 0x9e, 0x69, 0xe9, 0x5d, 0x1a, 0x8a, 0x39, - 0xb6, 0xab, 0x03, 0x98, 0xb8, 0xab, 0x03, 0x18, 0xda, 0x85, 0x99, 0x68, 0x3c, 0x47, 0xc5, 0xa8, - 0xaf, 0x10, 0xbe, 0x2f, 0x13, 0xb1, 0xa3, 0x87, 0x18, 0xa7, 0x7c, 0x07, 0x20, 0x86, 0x44, 0x06, - 0x14, 0xdb, 0xb6, 0xe5, 0xe9, 0xa6, 0x85, 0x1d, 0xa6, 0x28, 0xa9, 0xba, 0x42, 0x75, 0x55, 0xa2, - 0x61, 0x43, 0x13, 0x99, 0x4f, 0xbe, 0x42, 0x25, 0xe3, 0xd0, 0x47, 0x30, 0x1d, 0x34, 0x42, 0x4c, - 0x49, 0x4a, 0x75, 0x85, 0x6a, 0x4d, 0x24, 0x61, 0x9b, 0x41, 0xe2, 0x92, 0xaf, 0x50, 0x49, 0x28, - 0xf4, 0x21, 0x4c, 0x75, 0x49, 0x87, 0xb6, 0x76, 0xd0, 0x37, 0x1d, 0x6c, 0xa8, 0x2f, 0xf5, 0xdd, - 0x16, 0x28, 0x58, 0xe2, 0x12, 0x79, 0xe4, 0xbb, 0x0c, 0x22, 0x86, 0xf8, 0xa3, 0xa7, 0x1f, 0x34, - 0x7c, 0xcb, 0x5d, 0x3b, 0xe0, 0x17, 0xb4, 0xb2, 0x2a, 0x7f, 0x6c, 0xc8, 0x44, 0xcc, 0x1f, 0x31, - 0x4e, 0xd9, 0x1f, 0x31, 0x24, 0xba, 0x4d, 0xf3, 0x32, 0x33, 0x12, 0xbb, 0xdc, 0xb7, 0x30, 0x52, - 0x50, 0x31, 0xfb, 0xb0, 0x71, 0x0c, 0x7f, 0x92, 0x84, 0x86, 0x12, 0x50, 0x17, 0x4a, 0x7d, 0xdb, - 0xa0, 0xaf, 0xdd, 0xc0, 0x9e, 0xef, 0x58, 0xd8, 0xe0, 0x8d, 0xd2, 0xd2, 0x88, 0x54, 0x89, 0x8a, - 0x7d, 0xbe, 0xe2, 0xbc, 0xf2, 0x55, 0xcd, 0x38, 0x16, 0x7d, 0x0a, 0x73, 0xb1, 0xab, 0x4a, 0xec, - 0x3d, 0x0a, 0xaa, 0x23, 0x8a, 0x75, 0x05, 0x25, 0xeb, 0x69, 0x55, 0x32, 0x24, 0xcd, 0x4a, 0x2d, - 0x44, 0x7b, 0x47, 0xb7, 0x3a, 0xeb, 0x76, 0x6b, 0xdb, 0xe2, 0x4d, 0xa0, 0xde, 0xea, 0x62, 0x7e, - 0x5b, 0x2f, 0xa6, 0xfd, 0x86, 0x82, 0x92, 0x69, 0x57, 0xc9, 0x90, 0xb5, 0xab, 0x28, 0xc2, 0x6b, - 0x49, 0xa4, 0xac, 0x08, 0xaf, 0xef, 0xa9, 0xae, 0x25, 0x31, 0x02, 0xe1, 0x5a, 0x12, 0x03, 0x28, - 0xae, 0x25, 0x31, 0x04, 0xbb, 0xd1, 0xd6, 0xb6, 0xad, 0xb6, 0xd9, 0x35, 0xe9, 0x88, 0x9b, 0x19, - 0xb5, 0xa8, 0xbe, 0xd1, 0x36, 0x42, 0x18, 0xdc, 0x68, 0x1b, 0x41, 0xc4, 0x6f, 0xb4, 0x8d, 0x10, - 0xa0, 0x9b, 0x50, 0xda, 0xd1, 0xcd, 0xae, 0xef, 0xe0, 0x66, 0x5b, 0xf7, 0x70, 0xc7, 0x76, 0x0e, - 0xf9, 0xc1, 0x1f, 0x8d, 0x6b, 0x8e, 0xbb, 0xca, 0x51, 0xe2, 0x11, 0x67, 0x0c, 0x85, 0xee, 0xc1, - 0x6c, 0x20, 0xc9, 0xf5, 0x5b, 0xa1, 0xb0, 0xd3, 0x54, 0x18, 0xbd, 0x87, 0xcc, 0xd1, 0x5b, 0x11, - 0x56, 0x90, 0x87, 0x46, 0xb1, 0xf5, 0x5c, 0x30, 0xe0, 0x5a, 0x4f, 0xe5, 0xd2, 0xa5, 0xcc, 0x7a, - 0x2a, 0x07, 0xa5, 0x02, 0x3f, 0x57, 0xbc, 0x07, 0x33, 0xb1, 0xcc, 0x88, 0xde, 0x85, 0xf0, 0x56, - 0xd0, 0xfd, 0xc3, 0x7e, 0x50, 0x76, 0x4b, 0xb7, 0x88, 0x08, 0x5c, 0x75, 0x8b, 0x88, 0xc0, 0xab, - 0x5f, 0xa6, 0x20, 0x17, 0x6c, 0xbd, 0x13, 0x69, 0xa4, 0x56, 0x20, 0xdb, 0xc3, 0x2e, 0xbd, 0xf9, - 0x93, 0x88, 0xea, 0x31, 0x0e, 0x12, 0xeb, 0x31, 0x0e, 0x92, 0xcb, 0xc5, 0xe4, 0x63, 0x95, 0x8b, - 0xa9, 0x89, 0xcb, 0x45, 0x4c, 0x0f, 0xbb, 0x85, 0x94, 0x1e, 0x9c, 0x11, 0x3d, 0xfa, 0x3b, 0x11, - 0x1c, 0x85, 0x8b, 0x8c, 0xb1, 0xa3, 0x70, 0x11, 0x85, 0xf6, 0xe0, 0xb4, 0x70, 0x8e, 0xc5, 0x07, - 0x98, 0x24, 0x95, 0x17, 0xc7, 0xdf, 0x2c, 0x68, 0x50, 0x2a, 0x96, 0xb0, 0xf6, 0x62, 0x50, 0xb1, - 0xde, 0x8e, 0xe3, 0x48, 0x48, 0x18, 0xb8, 0xe5, 0x77, 0x36, 0xb8, 0xd9, 0xb3, 0x51, 0x48, 0x88, - 0x70, 0x31, 0x24, 0x44, 0x78, 0xf5, 0x9f, 0x09, 0x28, 0xca, 0xef, 0x7b, 0x22, 0x81, 0xf1, 0x3a, - 0xe4, 0xf1, 0x81, 0xe9, 0x35, 0xdb, 0xb6, 0x81, 0x79, 0xd3, 0x49, 0xfd, 0x4c, 0x80, 0x57, 0x6d, - 0x43, 0xf2, 0x73, 0x00, 0x13, 0xa3, 0x29, 0x39, 0x51, 0x34, 0x45, 0xf3, 0xe2, 0xd4, 0x04, 0xf3, - 0x62, 0xa5, 0x9f, 0xf2, 0x27, 0xe3, 0xa7, 0xea, 0x37, 0x09, 0x28, 0xc5, 0xbf, 0x4f, 0xcf, 0xc6, - 0x16, 0x94, 0x77, 0x53, 0x72, 0xe2, 0xdd, 0xf4, 0x1e, 0x4c, 0x93, 0xa2, 0x52, 0xf7, 0x3c, 0x7e, - 0x51, 0x38, 0x45, 0xeb, 0x42, 0x96, 0x8d, 0x7c, 0x6b, 0x35, 0x80, 0x4b, 0xd9, 0x48, 0x80, 0x8f, - 0x84, 0x6e, 0xfa, 0x98, 0xa1, 0xfb, 0x79, 0x02, 0xa6, 0x37, 0x6d, 0xe3, 0x3e, 0xab, 0x37, 0xbd, - 0x67, 0xc5, 0x9e, 0x4f, 0x33, 0xa5, 0x55, 0x67, 0x60, 0x5a, 0x2a, 0x38, 0xab, 0x5f, 0xb0, 0x38, - 0x93, 0xbf, 0xeb, 0x3f, 0x3d, 0xbb, 0x14, 0x61, 0x4a, 0xac, 0x93, 0xab, 0x75, 0x98, 0x89, 0x95, - 0xb5, 0xe2, 0x0b, 0x68, 0x93, 0xbc, 0x40, 0xf5, 0x1a, 0xcc, 0xa9, 0xea, 0x3d, 0x21, 0xeb, 0x68, - 0x13, 0x1c, 0x72, 0xdd, 0x80, 0x39, 0x55, 0xdd, 0x76, 0xfc, 0xe5, 0xbc, 0xcb, 0x0f, 0x90, 0x79, - 0x85, 0x75, 0x6c, 0xfe, 0xeb, 0x30, 0xab, 0xa8, 0xb4, 0x8e, 0x2f, 0xe7, 0xaf, 0xe1, 0x00, 0x21, - 0xba, 0xdc, 0x7f, 0x1d, 0x4a, 0xfd, 0xe0, 0xa1, 0xc9, 0xdb, 0xd4, 0x74, 0x74, 0xdb, 0x2a, 0xc4, - 0xad, 0xc7, 0xfa, 0xd5, 0xa2, 0x8c, 0x91, 0xe5, 0xf0, 0x16, 0x36, 0xa3, 0x90, 0xd3, 0x88, 0xf5, - 0xb2, 0x45, 0x19, 0x23, 0xb8, 0x28, 0x7b, 0xb4, 0x8b, 0x68, 0x0b, 0x9c, 0xae, 0x7e, 0xa6, 0xc1, - 0x4c, 0xec, 0xc7, 0x07, 0xe8, 0x32, 0xe4, 0xe8, 0x2f, 0x03, 0xa3, 0xe6, 0x9f, 0x5a, 0x87, 0xc2, - 0xa4, 0x05, 0x64, 0x39, 0x08, 0xbd, 0x01, 0xf9, 0xf0, 0xf7, 0x08, 0xfc, 0x08, 0x9a, 0xc5, 0x6f, - 0x00, 0x94, 0xe2, 0x37, 0x00, 0xf2, 0xb9, 0xc1, 0xff, 0xc3, 0xd9, 0xb1, 0xbf, 0x44, 0x38, 0xd6, - 0x71, 0x67, 0x34, 0x00, 0x48, 0x1d, 0x6b, 0x00, 0x70, 0x00, 0x0b, 0xea, 0x1f, 0x08, 0x08, 0xda, - 0x13, 0x47, 0x6a, 0x8f, 0xac, 0x9f, 0x9c, 0xd0, 0xfa, 0x89, 0xea, 0x1e, 0x9d, 0x98, 0x84, 0x17, - 0xf1, 0xd1, 0x25, 0x48, 0xf7, 0x6d, 0xbb, 0xeb, 0xf2, 0x3b, 0x1e, 0x54, 0x1d, 0x05, 0x88, 0xea, - 0x28, 0xe0, 0x31, 0xe6, 0x33, 0x7e, 0x10, 0xc1, 0xd1, 0xcf, 0x0a, 0x9e, 0x82, 0x75, 0x5f, 0xbe, - 0x0c, 0xb9, 0xe0, 0x1c, 0x1d, 0x01, 0x64, 0xee, 0x6d, 0xaf, 0x6d, 0xaf, 0x5d, 0x2b, 0x9d, 0x42, - 0x05, 0xc8, 0x6e, 0xae, 0xdd, 0xb9, 0x76, 0xeb, 0xce, 0x8d, 0x92, 0x46, 0x1e, 0x1a, 0xdb, 0x77, - 0xee, 0x90, 0x87, 0xc4, 0xcb, 0xb7, 0xc5, 0xbb, 0x79, 0xbc, 0x02, 0x9c, 0x82, 0xdc, 0x6a, 0xbf, - 0x4f, 0x37, 0x2f, 0xe3, 0x5d, 0xdb, 0x37, 0x49, 0x46, 0x28, 0x69, 0x28, 0x0b, 0xc9, 0xbb, 0x77, - 0x37, 0x4a, 0x09, 0x34, 0x07, 0xa5, 0x6b, 0x58, 0x37, 0xba, 0xa6, 0x85, 0x83, 0xfc, 0x57, 0x4a, - 0xd6, 0x1f, 0xfe, 0xe9, 0xdb, 0x25, 0xed, 0x9b, 0x6f, 0x97, 0xb4, 0x7f, 0x7c, 0xbb, 0xa4, 0x7d, - 0xf9, 0xdd, 0xd2, 0xa9, 0x6f, 0xbe, 0x5b, 0x3a, 0xf5, 0xb7, 0xef, 0x96, 0x4e, 0xfd, 0xdf, 0xe5, - 0x8e, 0xe9, 0xed, 0xfa, 0xad, 0x5a, 0xdb, 0xee, 0xf1, 0x9f, 0x38, 0xf7, 0x1d, 0x9b, 0x24, 0x1a, - 0xfe, 0xb4, 0x12, 0xff, 0xed, 0xf3, 0xef, 0x12, 0xe7, 0x56, 0xe9, 0xe3, 0x26, 0xa3, 0xab, 0xdd, - 0xb2, 0x6b, 0x0c, 0x40, 0x7f, 0xed, 0xea, 0xb6, 0x32, 0xf4, 0x57, 0xad, 0xaf, 0xff, 0x3b, 0x00, - 0x00, 0xff, 0xff, 0xd3, 0x8d, 0xc0, 0xbf, 0x36, 0x3d, 0x00, 0x00, + // 3805 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3b, 0x4b, 0x6f, 0x1b, 0xd7, + 0xd5, 0x1e, 0xbe, 0x79, 0x28, 0x51, 0xf4, 0xd5, 0xc3, 0xb4, 0x12, 0x8b, 0x32, 0x9d, 0x2f, 0xb1, + 0x83, 0x84, 0x72, 0x9c, 0x2f, 0x1f, 0xf2, 0xf8, 0x90, 0x40, 0xb4, 0xe5, 0x87, 0x62, 0xd9, 0x32, + 0x65, 0xe5, 0xf3, 0x57, 0x04, 0x60, 0x86, 0x9c, 0x2b, 0x6a, 0x2c, 0x72, 0x86, 0x99, 0x87, 0x22, + 0x01, 0x01, 0x9a, 0x14, 0x69, 0xd7, 0xd9, 0x14, 0x28, 0xb2, 0x69, 0x36, 0x5d, 0xb4, 0x40, 0x97, + 0xed, 0x6f, 0xe8, 0xa2, 0x28, 0xb2, 0xec, 0xa6, 0x44, 0x91, 0xa0, 0x1b, 0x2e, 0xfa, 0x03, 0xb2, + 0x2a, 0xee, 0x63, 0x66, 0xee, 0x1d, 0x5e, 0x5a, 0x94, 0x63, 0x19, 0x0e, 0xb2, 0x92, 0xe6, 0x3c, + 0xef, 0xdc, 0x73, 0xee, 0x99, 0x73, 0xce, 0x3d, 0x84, 0x73, 0xfd, 0xbd, 0xce, 0x8a, 0xee, 0xf4, + 0x74, 0x43, 0xc7, 0xfb, 0xd8, 0xf2, 0xdc, 0x15, 0xf6, 0xa7, 0xd6, 0x77, 0x6c, 0xcf, 0x46, 0x53, + 0x22, 0x6a, 0xb1, 0xba, 0xf7, 0xa6, 0x5b, 0x33, 0xed, 0x15, 0xbd, 0x6f, 0xae, 0xb4, 0x6d, 0x07, + 0xaf, 0xec, 0xbf, 0xb6, 0xd2, 0xc1, 0x16, 0x76, 0x74, 0x0f, 0x1b, 0x8c, 0x63, 0xf1, 0xa2, 0x40, + 0x63, 0x61, 0xef, 0x13, 0xdb, 0xd9, 0x33, 0xad, 0x8e, 0x8a, 0xb2, 0xd2, 0xb1, 0xed, 0x4e, 0x17, + 0xaf, 0xd0, 0xa7, 0x96, 0xbf, 0xb3, 0xe2, 0x99, 0x3d, 0xec, 0x7a, 0x7a, 0xaf, 0xcf, 0x09, 0xfe, + 0x3b, 0x12, 0xd5, 0xd3, 0xdb, 0xbb, 0xa6, 0x85, 0x9d, 0xc3, 0x15, 0xba, 0xde, 0xbe, 0xb9, 0xe2, + 0x60, 0xd7, 0xf6, 0x9d, 0x36, 0x1e, 0x11, 0xfb, 0xb6, 0x69, 0x79, 0xd8, 0xb1, 0xf4, 0xee, 0x8a, + 0xdb, 0xde, 0xc5, 0x86, 0xdf, 0xc5, 0x4e, 0xf4, 0x9f, 0xdd, 0x7a, 0x88, 0xdb, 0x9e, 0x3b, 0x02, + 0x60, 0xbc, 0xd5, 0x7f, 0xcc, 0xc3, 0xf4, 0x1a, 0x79, 0xd7, 0x2d, 0xfc, 0xb1, 0x8f, 0xad, 0x36, + 0x46, 0x97, 0x20, 0xfd, 0xb1, 0x8f, 0x7d, 0x5c, 0xd6, 0x96, 0xb5, 0x8b, 0xf9, 0xfa, 0xec, 0x70, + 0x50, 0x99, 0xa1, 0x80, 0x57, 0xec, 0x9e, 0xe9, 0xe1, 0x5e, 0xdf, 0x3b, 0x6c, 0x30, 0x0a, 0xf4, + 0x36, 0x4c, 0x3d, 0xb4, 0x5b, 0x4d, 0x17, 0x7b, 0x4d, 0x4b, 0xef, 0xe1, 0x72, 0x82, 0x72, 0x94, + 0x87, 0x83, 0xca, 0xdc, 0x43, 0xbb, 0xb5, 0x85, 0xbd, 0x3b, 0x7a, 0x4f, 0x64, 0x83, 0x08, 0x8a, + 0x5e, 0x85, 0xac, 0xef, 0x62, 0xa7, 0x69, 0x1a, 0xe5, 0x24, 0x65, 0x9b, 0x1b, 0x0e, 0x2a, 0x25, + 0x02, 0xba, 0x65, 0x08, 0x2c, 0x19, 0x06, 0x41, 0xaf, 0x40, 0xa6, 0xe3, 0xd8, 0x7e, 0xdf, 0x2d, + 0xa7, 0x96, 0x93, 0x01, 0x35, 0x83, 0x88, 0xd4, 0x0c, 0x82, 0xee, 0x42, 0x86, 0x19, 0xb0, 0x9c, + 0x5e, 0x4e, 0x5e, 0x2c, 0x5c, 0x39, 0x5f, 0x13, 0xad, 0x5a, 0x93, 0x5e, 0x98, 0x3d, 0x31, 0x81, + 0x0c, 0x2f, 0x0a, 0xe4, 0x7e, 0xf0, 0xe7, 0x59, 0x48, 0x53, 0x3a, 0xf4, 0x3e, 0x64, 0xdb, 0x0e, + 0x26, 0xbb, 0x5f, 0x46, 0xcb, 0xda, 0xc5, 0xc2, 0x95, 0xc5, 0x1a, 0xb3, 0x6a, 0x2d, 0xb0, 0x6a, + 0xed, 0x7e, 0x60, 0xd5, 0xfa, 0xfc, 0x70, 0x50, 0x39, 0xcd, 0xc9, 0x05, 0xa9, 0x81, 0x04, 0xb4, + 0x09, 0x79, 0xd7, 0x6f, 0xf5, 0x4c, 0x6f, 0xdd, 0x6e, 0xd1, 0xfd, 0x2e, 0x5c, 0x39, 0x23, 0x2f, + 0x75, 0x2b, 0x40, 0xd7, 0xcf, 0x0c, 0x07, 0x95, 0xd9, 0x90, 0x3a, 0x92, 0x76, 0xf3, 0x54, 0x23, + 0x12, 0x82, 0x76, 0x61, 0xc6, 0xc1, 0x7d, 0xc7, 0xb4, 0x1d, 0xd3, 0x33, 0x5d, 0x4c, 0xe4, 0x26, + 0xa8, 0xdc, 0x73, 0xb2, 0xdc, 0x86, 0x4c, 0x54, 0x3f, 0x37, 0x1c, 0x54, 0xce, 0xc6, 0x38, 0x25, + 0x1d, 0x71, 0xb1, 0xc8, 0x03, 0x14, 0x03, 0x6d, 0x61, 0x8f, 0xda, 0xb2, 0x70, 0x65, 0xf9, 0x91, + 0xca, 0xb6, 0xb0, 0x57, 0x5f, 0x1e, 0x0e, 0x2a, 0xcf, 0x8f, 0xf2, 0x4b, 0x2a, 0x15, 0xf2, 0x51, + 0x17, 0x4a, 0x22, 0xd4, 0x20, 0x2f, 0x98, 0xa2, 0x3a, 0x97, 0xc6, 0xeb, 0x24, 0x54, 0xf5, 0xa5, + 0xe1, 0xa0, 0xb2, 0x18, 0xe7, 0x95, 0xf4, 0x8d, 0x48, 0x26, 0xf6, 0x69, 0xeb, 0x56, 0x1b, 0x77, + 0x89, 0x9a, 0xb4, 0xca, 0x3e, 0x57, 0x03, 0x34, 0xb3, 0x4f, 0x48, 0x2d, 0xdb, 0x27, 0x04, 0xa3, + 0x0f, 0x61, 0x2a, 0x7c, 0x20, 0xfb, 0x95, 0xe1, 0x3e, 0xa4, 0x16, 0x4a, 0x76, 0x6a, 0x71, 0x38, + 0xa8, 0x2c, 0x88, 0x3c, 0x92, 0x68, 0x49, 0x5a, 0x24, 0xbd, 0xcb, 0x76, 0x26, 0x3b, 0x5e, 0x3a, + 0xa3, 0x10, 0xa5, 0x77, 0x47, 0x77, 0x44, 0x92, 0x46, 0xa4, 0x93, 0x03, 0xec, 0xb7, 0xdb, 0x18, + 0x1b, 0xd8, 0x28, 0xe7, 0x54, 0xd2, 0xd7, 0x05, 0x0a, 0x26, 0x5d, 0xe4, 0x91, 0xa5, 0x8b, 0x18, + 0xb2, 0xd7, 0x0f, 0xed, 0xd6, 0x9a, 0xe3, 0xd8, 0x8e, 0x5b, 0xce, 0xab, 0xf6, 0x7a, 0x3d, 0x40, + 0xb3, 0xbd, 0x0e, 0xa9, 0xe5, 0xbd, 0x0e, 0xc1, 0x7c, 0xbd, 0x0d, 0xdf, 0xba, 0x8d, 0x75, 0x17, + 0x1b, 0x65, 0x18, 0xb3, 0xde, 0x90, 0x22, 0x5c, 0x6f, 0x08, 0x19, 0x59, 0x6f, 0x88, 0x41, 0x06, + 0x14, 0xd9, 0xf3, 0xaa, 0xeb, 0x9a, 0x1d, 0x0b, 0x1b, 0xe5, 0x02, 0x95, 0xff, 0xbc, 0x4a, 0x7e, + 0x40, 0x53, 0x7f, 0x7e, 0x38, 0xa8, 0x94, 0x65, 0x3e, 0x49, 0x47, 0x4c, 0x26, 0xfa, 0x08, 0xa6, + 0x19, 0xa4, 0xe1, 0x5b, 0x96, 0x69, 0x75, 0xca, 0x53, 0x54, 0xc9, 0x73, 0x2a, 0x25, 0x9c, 0xa4, + 0xfe, 0xdc, 0x70, 0x50, 0x39, 0x23, 0x71, 0x49, 0x2a, 0x64, 0x81, 0x24, 0x62, 0x30, 0x40, 0x64, + 0xd8, 0x69, 0x55, 0xc4, 0x58, 0x97, 0x89, 0x58, 0xc4, 0x88, 0x71, 0xca, 0x11, 0x23, 0x86, 0x8c, + 0xec, 0xc1, 0x8d, 0x5c, 0x1c, 0x6f, 0x0f, 0x6e, 0x67, 0xc1, 0x1e, 0x0a, 0x53, 0x4b, 0xd2, 0xd0, + 0x67, 0x1a, 0xcc, 0xbb, 0x9e, 0x6e, 0x19, 0x7a, 0xd7, 0xb6, 0xf0, 0x2d, 0xab, 0xe3, 0x60, 0xd7, + 0xbd, 0x65, 0xed, 0xd8, 0xe5, 0x12, 0xd5, 0x73, 0x21, 0x16, 0x58, 0x55, 0xa4, 0xf5, 0x0b, 0xc3, + 0x41, 0xa5, 0xa2, 0x94, 0x22, 0x69, 0x56, 0x2b, 0x42, 0x07, 0x30, 0x1b, 0x7c, 0xa4, 0xb7, 0x3d, + 0xb3, 0x6b, 0xba, 0xba, 0x67, 0xda, 0x56, 0xf9, 0x34, 0xd5, 0x7f, 0x3e, 0x1e, 0x9f, 0x46, 0x08, + 0xeb, 0xe7, 0x87, 0x83, 0xca, 0x39, 0x85, 0x04, 0x49, 0xb7, 0x4a, 0x45, 0x64, 0xc4, 0x4d, 0x07, + 0x13, 0x42, 0x6c, 0x94, 0x67, 0xc7, 0x1b, 0x31, 0x24, 0x12, 0x8d, 0x18, 0x02, 0x55, 0x46, 0x0c, + 0x91, 0x44, 0x53, 0x5f, 0x77, 0x3c, 0x93, 0xa8, 0xdd, 0xd0, 0x9d, 0x3d, 0xec, 0x94, 0xe7, 0x54, + 0x9a, 0x36, 0x65, 0x22, 0xa6, 0x29, 0xc6, 0x29, 0x6b, 0x8a, 0x21, 0xd1, 0x97, 0x1a, 0xc8, 0x4b, + 0x33, 0x6d, 0xab, 0x41, 0x3e, 0xda, 0x2e, 0x79, 0xbd, 0x79, 0xaa, 0xf4, 0xa5, 0x47, 0xbc, 0x9e, + 0x48, 0x5e, 0x7f, 0x69, 0x38, 0xa8, 0x5c, 0x18, 0x2b, 0x4d, 0x5a, 0xc8, 0x78, 0xa5, 0xe8, 0x01, + 0x14, 0x08, 0x12, 0xd3, 0xf4, 0xc7, 0x28, 0x2f, 0xd0, 0x35, 0x9c, 0x1d, 0x5d, 0x03, 0x27, 0xa8, + 0x9f, 0x1d, 0x0e, 0x2a, 0xf3, 0x02, 0x87, 0xa4, 0x47, 0x14, 0x85, 0xbe, 0xd0, 0x80, 0x38, 0xba, + 0xea, 0x4d, 0xcf, 0x50, 0x2d, 0x2f, 0x8c, 0x68, 0x51, 0xbd, 0xe6, 0x0b, 0xc3, 0x41, 0x65, 0x59, + 0x2d, 0x47, 0xd2, 0x3d, 0x46, 0x57, 0xe4, 0x47, 0xe1, 0x47, 0xa2, 0x5c, 0x1e, 0xef, 0x47, 0x21, + 0x91, 0xe8, 0x47, 0x21, 0x50, 0xe5, 0x47, 0x21, 0x92, 0x07, 0x83, 0x0f, 0xf4, 0xae, 0x69, 0xd0, + 0x64, 0xea, 0xec, 0x98, 0x60, 0x10, 0x52, 0x84, 0xc1, 0x20, 0x84, 0x8c, 0x04, 0x83, 0x88, 0x36, + 0x0b, 0x69, 0x2a, 0xa2, 0xfa, 0x55, 0x1e, 0x66, 0x15, 0x47, 0x0d, 0x61, 0x98, 0x0e, 0xce, 0x51, + 0xd3, 0x24, 0x41, 0x22, 0xa9, 0xda, 0xe5, 0xf7, 0xfd, 0x16, 0x76, 0x2c, 0xec, 0x61, 0x37, 0x90, + 0x41, 0xa3, 0x04, 0x5d, 0x89, 0x23, 0x40, 0x84, 0xdc, 0x6e, 0x4a, 0x84, 0xa3, 0xaf, 0x34, 0x28, + 0xf7, 0xf4, 0x83, 0x66, 0x00, 0x74, 0x9b, 0x3b, 0xb6, 0xd3, 0xec, 0x63, 0xc7, 0xb4, 0x0d, 0x9a, + 0xc9, 0x16, 0xae, 0xfc, 0xef, 0x91, 0x71, 0xa1, 0xb6, 0xa1, 0x1f, 0x04, 0x60, 0xf7, 0xba, 0xed, + 0x6c, 0x52, 0xf6, 0x35, 0xcb, 0x73, 0x0e, 0x59, 0xc0, 0xea, 0xa9, 0xf0, 0xc2, 0x9a, 0xe6, 0x95, + 0x04, 0xe8, 0xd7, 0x1a, 0x2c, 0x78, 0xb6, 0xa7, 0x77, 0x9b, 0x6d, 0xbf, 0xe7, 0x77, 0x75, 0xcf, + 0xdc, 0xc7, 0x4d, 0xdf, 0xd5, 0x3b, 0x98, 0xa7, 0xcd, 0xef, 0x1c, 0xbd, 0xb4, 0xfb, 0x84, 0xff, + 0x6a, 0xc8, 0xbe, 0x4d, 0xb8, 0xd9, 0xca, 0xaa, 0xc3, 0x41, 0x65, 0xc9, 0x53, 0xa0, 0x85, 0x85, + 0xcd, 0xa9, 0xf0, 0xe8, 0x65, 0xc8, 0x90, 0xb2, 0xc2, 0x34, 0x68, 0x76, 0xc4, 0x4b, 0x90, 0x87, + 0x76, 0x4b, 0x2a, 0x0c, 0xd2, 0x14, 0x40, 0x68, 0x1d, 0xdf, 0x22, 0xb4, 0xd9, 0x88, 0xd6, 0xf1, + 0x2d, 0x99, 0x96, 0x02, 0xa8, 0x31, 0xf4, 0xfd, 0x8e, 0xda, 0x18, 0xb9, 0x49, 0x8d, 0xb1, 0xba, + 0xdf, 0x79, 0xa4, 0x31, 0x74, 0x15, 0x5e, 0x34, 0x86, 0x92, 0x60, 0xf1, 0x6b, 0x0d, 0x16, 0xc7, + 0xdb, 0x19, 0x5d, 0x80, 0xe4, 0x1e, 0x3e, 0xe4, 0x35, 0xd9, 0xe9, 0xe1, 0xa0, 0x32, 0xbd, 0x87, + 0x0f, 0x05, 0xa9, 0x04, 0x8b, 0xfe, 0x1f, 0xd2, 0xfb, 0x7a, 0xd7, 0xc7, 0x3c, 0xe5, 0xaf, 0xd5, + 0x58, 0x39, 0x59, 0x13, 0xcb, 0xc9, 0x5a, 0x7f, 0xaf, 0x43, 0x00, 0xb5, 0x60, 0x17, 0x6a, 0xf7, + 0x7c, 0xdd, 0xf2, 0x4c, 0xef, 0x90, 0xed, 0x1d, 0x15, 0x20, 0xee, 0x1d, 0x05, 0xbc, 0x9d, 0x78, + 0x53, 0x5b, 0xfc, 0xad, 0x06, 0x67, 0xc7, 0xda, 0xfb, 0x99, 0x58, 0x21, 0xd9, 0xc4, 0xf1, 0xf6, + 0x79, 0x16, 0x96, 0xb8, 0x9e, 0xca, 0x69, 0xa5, 0xc4, 0x7a, 0x2a, 0x97, 0x28, 0x25, 0xab, 0xdf, + 0x67, 0x20, 0x1f, 0x16, 0x78, 0xe8, 0x26, 0x94, 0x0c, 0x6c, 0xf8, 0xfd, 0xae, 0xd9, 0xa6, 0x9e, + 0x46, 0x9c, 0x9a, 0x55, 0xd4, 0x34, 0xba, 0x4a, 0x38, 0xc9, 0xbd, 0x67, 0x62, 0x28, 0x74, 0x05, + 0x72, 0xbc, 0x90, 0x39, 0xa4, 0x71, 0x6d, 0xba, 0xbe, 0x30, 0x1c, 0x54, 0x50, 0x00, 0x13, 0x58, + 0x43, 0x3a, 0xd4, 0x00, 0x60, 0x9d, 0x81, 0x0d, 0xec, 0xe9, 0xbc, 0xa4, 0x2a, 0xcb, 0xa7, 0xe1, + 0x6e, 0x88, 0x67, 0x35, 0x7e, 0x44, 0x2f, 0xd6, 0xf8, 0x11, 0x14, 0x7d, 0x08, 0xd0, 0xd3, 0x4d, + 0x8b, 0xf1, 0xf1, 0xfa, 0xa9, 0x3a, 0x2e, 0xc2, 0x6e, 0x84, 0x94, 0x4c, 0x7a, 0xc4, 0x29, 0x4a, + 0x8f, 0xa0, 0xe8, 0x2e, 0x64, 0x79, 0x2f, 0xa3, 0x9c, 0xa1, 0x87, 0x77, 0x69, 0x9c, 0x68, 0x2e, + 0x96, 0x56, 0xe3, 0x9c, 0x45, 0xac, 0xc6, 0x39, 0x88, 0x6c, 0x5b, 0xd7, 0xdc, 0xc1, 0x9e, 0xd9, + 0xc3, 0x34, 0x9a, 0xf0, 0x6d, 0x0b, 0x60, 0xe2, 0xb6, 0x05, 0x30, 0xf4, 0x26, 0x80, 0xee, 0x6d, + 0xd8, 0xae, 0x77, 0xd7, 0x6a, 0x63, 0x5a, 0x11, 0xe5, 0xd8, 0xf2, 0x23, 0xa8, 0xb8, 0xfc, 0x08, + 0x8a, 0xde, 0x81, 0x42, 0x9f, 0x7f, 0x81, 0x5b, 0x5d, 0x4c, 0x2b, 0x9e, 0x1c, 0x4b, 0x18, 0x04, + 0xb0, 0xc0, 0x2b, 0x52, 0xa3, 0x1b, 0x30, 0xd3, 0xb6, 0xad, 0xb6, 0xef, 0x38, 0xd8, 0x6a, 0x1f, + 0x6e, 0xe9, 0x3b, 0x98, 0x56, 0x37, 0x39, 0xe6, 0x2a, 0x31, 0x94, 0xe8, 0x2a, 0x31, 0x14, 0x7a, + 0x03, 0xf2, 0x61, 0x67, 0x88, 0x16, 0x30, 0x79, 0xde, 0x68, 0x08, 0x80, 0x02, 0x73, 0x44, 0x49, + 0x16, 0x6f, 0xba, 0xd7, 0xb8, 0xd3, 0x61, 0x5a, 0x94, 0xf0, 0xc5, 0x0b, 0x60, 0x71, 0xf1, 0x02, + 0x58, 0x88, 0xef, 0xc5, 0x23, 0xe3, 0xfb, 0x75, 0x28, 0xe1, 0x03, 0xd6, 0xdd, 0x6a, 0x12, 0x26, + 0xdf, 0x31, 0x69, 0x3e, 0x9f, 0x67, 0x95, 0x54, 0x80, 0x5b, 0xb7, 0x5b, 0xdb, 0x8e, 0x29, 0xb0, + 0x17, 0x65, 0x4c, 0x78, 0xec, 0xa6, 0x4b, 0xc5, 0xf5, 0x54, 0x6e, 0xa6, 0x54, 0xaa, 0xfe, 0x55, + 0x83, 0x39, 0x95, 0xf7, 0xc5, 0x4e, 0x82, 0xf6, 0x44, 0x4e, 0xc2, 0x07, 0x90, 0xeb, 0xdb, 0x46, + 0xd3, 0xed, 0xe3, 0x36, 0x8f, 0x2b, 0xb1, 0x73, 0xb0, 0x69, 0x1b, 0x5b, 0x7d, 0xdc, 0xfe, 0x3f, + 0xd3, 0xdb, 0x5d, 0xdd, 0xb7, 0x4d, 0xe3, 0xb6, 0xe9, 0x72, 0x87, 0xed, 0x33, 0x8c, 0x94, 0xec, + 0x64, 0x39, 0xb0, 0x9e, 0x83, 0x0c, 0xd3, 0x52, 0xfd, 0x5b, 0x12, 0x4a, 0x71, 0x8f, 0xff, 0x31, + 0xbd, 0x0a, 0x7a, 0x00, 0x59, 0x93, 0xd5, 0x52, 0x3c, 0x17, 0xfb, 0x2f, 0x21, 0xf2, 0xd6, 0xa2, + 0xc6, 0x6a, 0x6d, 0xff, 0xb5, 0x1a, 0x2f, 0xba, 0xe8, 0x16, 0x50, 0xc9, 0x9c, 0x53, 0x96, 0xcc, + 0x81, 0xa8, 0x01, 0x59, 0x17, 0x3b, 0xfb, 0x66, 0x1b, 0xf3, 0xb8, 0x56, 0x11, 0x25, 0xb7, 0x6d, + 0x07, 0x13, 0x99, 0x5b, 0x8c, 0x24, 0x92, 0xc9, 0x79, 0x64, 0x99, 0x1c, 0x88, 0x3e, 0x80, 0x7c, + 0xdb, 0xb6, 0x76, 0xcc, 0xce, 0x86, 0xde, 0xe7, 0x91, 0xed, 0x9c, 0x4a, 0xea, 0xd5, 0x80, 0x88, + 0xf7, 0x87, 0x82, 0xc7, 0x58, 0x7f, 0x28, 0xa4, 0x8a, 0x0c, 0xfa, 0xef, 0x14, 0x40, 0x64, 0x1c, + 0xf4, 0x16, 0x14, 0xf0, 0x01, 0x6e, 0xfb, 0x9e, 0x4d, 0x7b, 0xa6, 0x5a, 0xd4, 0x6a, 0x0d, 0xc0, + 0xd2, 0xf1, 0x81, 0x08, 0x4a, 0xce, 0xb8, 0xa5, 0xf7, 0xb0, 0xdb, 0xd7, 0xdb, 0x41, 0x8f, 0x96, + 0x2e, 0x26, 0x04, 0x8a, 0x67, 0x3c, 0x04, 0xa2, 0x17, 0x21, 0x45, 0xbb, 0xba, 0xac, 0x3d, 0x8b, + 0x86, 0x83, 0x4a, 0xd1, 0x92, 0xfb, 0xb9, 0x14, 0x8f, 0xde, 0x83, 0xe9, 0xbd, 0xd0, 0xf1, 0xc8, + 0xda, 0x52, 0x94, 0x81, 0x26, 0xc9, 0x11, 0x42, 0x5a, 0xdd, 0x94, 0x08, 0x47, 0x3b, 0x50, 0xd0, + 0x2d, 0xcb, 0xf6, 0xe8, 0xe7, 0x2b, 0x68, 0xd9, 0x5e, 0x1a, 0xe7, 0xa6, 0xb5, 0xd5, 0x88, 0x96, + 0xa5, 0x5d, 0x34, 0xee, 0x08, 0x12, 0xc4, 0xb8, 0x23, 0x80, 0x51, 0x03, 0x32, 0x5d, 0xbd, 0x85, + 0xbb, 0xc1, 0xf7, 0xe2, 0x85, 0xb1, 0x2a, 0x6e, 0x53, 0x32, 0x26, 0x9d, 0x36, 0x86, 0x19, 0x9f, + 0xd8, 0x18, 0x66, 0x90, 0xc5, 0x1d, 0x28, 0xc5, 0xd7, 0x33, 0x59, 0x9a, 0x71, 0x49, 0x4c, 0x33, + 0xf2, 0x47, 0x66, 0x36, 0x3a, 0x14, 0x84, 0x45, 0x9d, 0x84, 0x8a, 0xea, 0xef, 0x35, 0x98, 0x53, + 0x9d, 0x5d, 0xb4, 0x21, 0x9c, 0x78, 0x8d, 0xb7, 0x9f, 0x14, 0xae, 0xce, 0x79, 0xc7, 0x1c, 0xf5, + 0xe8, 0xa0, 0xd7, 0xa1, 0x68, 0xd9, 0x06, 0x6e, 0xea, 0x44, 0x41, 0xd7, 0x74, 0xbd, 0x72, 0x82, + 0xb6, 0xf4, 0x69, 0xdb, 0x8a, 0x60, 0x56, 0x03, 0x84, 0xc0, 0x3d, 0x2d, 0x21, 0xaa, 0x9f, 0xc0, + 0x4c, 0xac, 0xa9, 0x2c, 0x25, 0x3d, 0x89, 0x09, 0x93, 0x9e, 0xe8, 0x4b, 0x94, 0x3c, 0xea, 0x4b, + 0xc4, 0xbe, 0x20, 0xd5, 0x5f, 0x26, 0xa0, 0x20, 0x54, 0xf8, 0xe8, 0x21, 0xcc, 0xf0, 0xaf, 0xa2, + 0x69, 0x75, 0x58, 0x25, 0x99, 0xe0, 0xed, 0xa6, 0x91, 0x1b, 0x97, 0x75, 0xbb, 0xb5, 0x15, 0xd2, + 0xd2, 0x42, 0x92, 0x7e, 0xc3, 0x5c, 0x09, 0x26, 0x7e, 0xc3, 0x64, 0x0c, 0x7a, 0x00, 0x0b, 0x7e, + 0x9f, 0xd4, 0xb7, 0x4d, 0x97, 0xdf, 0x5d, 0x34, 0x2d, 0xbf, 0xd7, 0xc2, 0x0e, 0x5d, 0x7d, 0x9a, + 0x55, 0x5c, 0x8c, 0x22, 0xb8, 0xdc, 0xb8, 0x43, 0xf1, 0x62, 0xc5, 0xa5, 0xc2, 0x0b, 0xfb, 0x90, + 0x9a, 0x70, 0x1f, 0x6e, 0x02, 0x1a, 0xed, 0xea, 0x4b, 0x36, 0xd0, 0x26, 0xb3, 0x41, 0xf5, 0x00, + 0x4a, 0xf1, 0x5e, 0xfd, 0x53, 0xb2, 0xe5, 0x1e, 0xe4, 0xc3, 0x4e, 0x3b, 0x7a, 0x05, 0x32, 0x0e, + 0xd6, 0x5d, 0xdb, 0xe2, 0xa7, 0x85, 0x1e, 0x7b, 0x06, 0x11, 0x8f, 0x3d, 0x83, 0x3c, 0x86, 0xb2, + 0xfb, 0x30, 0xc5, 0x36, 0xe9, 0xba, 0xd9, 0xf5, 0xb0, 0x83, 0xae, 0x41, 0xc6, 0xf5, 0x74, 0x0f, + 0xbb, 0x65, 0x6d, 0x39, 0x79, 0xb1, 0x78, 0x65, 0x61, 0xb4, 0x8d, 0x4e, 0xd0, 0x6c, 0x1d, 0x8c, + 0x52, 0x5c, 0x07, 0x83, 0x54, 0x7f, 0xa1, 0xc1, 0x94, 0x78, 0x5b, 0xf0, 0x64, 0xc4, 0x1e, 0x6f, + 0x33, 0x48, 0xe0, 0x98, 0x12, 0x2f, 0x15, 0x4e, 0x6e, 0x2f, 0xc9, 0x57, 0x90, 0x5d, 0x49, 0x34, + 0x7d, 0x17, 0x3b, 0xdc, 0x5b, 0xe9, 0x57, 0x90, 0x81, 0xb7, 0x5d, 0xc9, 0xdb, 0x21, 0x82, 0x72, + 0x33, 0x90, 0xb5, 0x8a, 0x57, 0x14, 0xa8, 0x13, 0x35, 0x82, 0xc8, 0x21, 0x73, 0x69, 0x30, 0x9a, + 0xb4, 0x11, 0x44, 0x43, 0x96, 0xc4, 0x2e, 0x86, 0x2c, 0x09, 0xf1, 0x18, 0x2e, 0xf3, 0x75, 0x9a, + 0xae, 0x35, 0xba, 0x72, 0x88, 0xe5, 0x00, 0xc9, 0x63, 0xe4, 0x00, 0xaf, 0x42, 0x96, 0x06, 0xdd, + 0xf0, 0x88, 0x53, 0x9b, 0x10, 0x90, 0x7c, 0xdd, 0xca, 0x20, 0x8f, 0x08, 0x35, 0xe9, 0x1f, 0x18, + 0x6a, 0x9a, 0x70, 0x76, 0x57, 0x77, 0x9b, 0x41, 0x70, 0x34, 0x9a, 0xba, 0xd7, 0x0c, 0xcf, 0x7a, + 0x86, 0xd6, 0x11, 0xb4, 0x89, 0xb9, 0xab, 0xbb, 0x5b, 0x01, 0xcd, 0xaa, 0xb7, 0x39, 0x7a, 0xf2, + 0x17, 0xd4, 0x14, 0x68, 0x1b, 0xe6, 0xd5, 0xc2, 0xb3, 0x74, 0xe5, 0xb4, 0xc7, 0xee, 0x3e, 0x52, + 0xf2, 0xac, 0x02, 0x8d, 0x3e, 0xd7, 0xa0, 0x4c, 0xbe, 0x82, 0x0e, 0xfe, 0xd8, 0x37, 0x1d, 0xdc, + 0x23, 0x6e, 0xd1, 0xb4, 0xf7, 0xb1, 0xd3, 0xd5, 0x0f, 0xf9, 0x75, 0xd5, 0xf9, 0xd1, 0x90, 0xbf, + 0x69, 0x1b, 0x0d, 0x81, 0x81, 0xbd, 0x5a, 0x5f, 0x06, 0xde, 0x65, 0x42, 0xc4, 0x57, 0x53, 0x53, + 0x08, 0x2e, 0x04, 0xc7, 0x68, 0x8c, 0x15, 0x8e, 0x6c, 0x8c, 0xbd, 0x08, 0xa9, 0xbe, 0x6d, 0x77, + 0x69, 0x19, 0xc7, 0x33, 0x3d, 0xf2, 0x2c, 0x66, 0x7a, 0xe4, 0x59, 0xec, 0x5d, 0xac, 0xa7, 0x72, + 0xb9, 0x52, 0x9e, 0x7c, 0x0e, 0x8b, 0xf2, 0x0d, 0xd7, 0xe8, 0x81, 0x4a, 0x9e, 0xf8, 0x81, 0x4a, + 0x1d, 0x63, 0x37, 0xd2, 0x13, 0xef, 0x46, 0x66, 0xf2, 0xdd, 0xa8, 0x7e, 0x91, 0x80, 0x69, 0xe9, + 0x12, 0xee, 0xa7, 0xb9, 0x0d, 0xbf, 0x49, 0xc0, 0x82, 0xfa, 0x95, 0x4e, 0xa4, 0x14, 0xbd, 0x09, + 0x24, 0xa9, 0xbc, 0x15, 0x25, 0x5d, 0xf3, 0x23, 0x95, 0x28, 0xdd, 0xce, 0x20, 0x23, 0x1d, 0xb9, + 0xc7, 0x0b, 0xd8, 0xd1, 0x03, 0x28, 0x98, 0xc2, 0x8d, 0x61, 0x52, 0x75, 0xb1, 0x23, 0xde, 0x13, + 0xb2, 0x56, 0xc7, 0x98, 0xdb, 0x41, 0x51, 0x54, 0x3d, 0x03, 0x29, 0x92, 0x15, 0x56, 0xf7, 0x21, + 0xcb, 0x97, 0x83, 0x5e, 0x87, 0x3c, 0x8d, 0xc5, 0xb4, 0xba, 0x62, 0x29, 0x3c, 0x4d, 0x6f, 0x08, + 0x30, 0x36, 0x31, 0x93, 0x0b, 0x60, 0xe8, 0x7f, 0x00, 0x48, 0xf8, 0xe1, 0x51, 0x38, 0x41, 0x63, + 0x19, 0xad, 0xe2, 0xfa, 0xb6, 0x31, 0x12, 0x7a, 0xf3, 0x21, 0xb0, 0xfa, 0xc7, 0x04, 0x14, 0xc4, + 0x3b, 0xca, 0xc7, 0x52, 0xfe, 0x29, 0x04, 0x15, 0x76, 0x53, 0x37, 0x0c, 0xf2, 0x17, 0x07, 0x1f, + 0xca, 0x95, 0xb1, 0x9b, 0x14, 0xfc, 0xbf, 0x1a, 0x70, 0xb0, 0x7a, 0x8a, 0xce, 0x61, 0x98, 0x31, + 0x94, 0xa0, 0xb5, 0x14, 0xc7, 0x2d, 0xee, 0xc1, 0xbc, 0x52, 0x94, 0x58, 0x05, 0xa5, 0x9f, 0x54, + 0x15, 0xf4, 0xbb, 0x34, 0xcc, 0x2b, 0xef, 0x86, 0x63, 0x1e, 0x9c, 0x7c, 0x22, 0x1e, 0xfc, 0x2b, + 0x4d, 0xb5, 0xb3, 0xec, 0x62, 0xe8, 0xad, 0x09, 0x2e, 0xac, 0x9f, 0xd4, 0x1e, 0xcb, 0x6e, 0x91, + 0x7e, 0x2c, 0x9f, 0xcc, 0x4c, 0xea, 0x93, 0xe8, 0x32, 0x2b, 0x28, 0xa9, 0x2e, 0x76, 0x6d, 0x13, + 0x9c, 0xd0, 0x98, 0xaa, 0x2c, 0x07, 0xa1, 0xf7, 0x60, 0x3a, 0xe0, 0x60, 0x6d, 0x8c, 0x5c, 0xd4, + 0x63, 0xe0, 0x34, 0xf1, 0x4e, 0xc6, 0x94, 0x08, 0x17, 0xa2, 0x64, 0xfe, 0x18, 0x51, 0x12, 0x8e, + 0x8a, 0x92, 0x4f, 0xd5, 0x37, 0xa5, 0x50, 0x3b, 0xd0, 0x60, 0x26, 0x36, 0x92, 0xf1, 0xa3, 0xff, + 0xe6, 0x48, 0x2f, 0xf8, 0x99, 0x06, 0xf9, 0x70, 0xe2, 0x07, 0xad, 0x42, 0x06, 0xb3, 0xa9, 0x11, + 0x16, 0x76, 0x66, 0x63, 0x13, 0x7d, 0x04, 0xc7, 0x67, 0xf8, 0x62, 0x83, 0x22, 0x0d, 0xce, 0xf8, + 0x18, 0x09, 0xf8, 0x9f, 0xb4, 0x20, 0x01, 0x1f, 0x59, 0x45, 0xf2, 0x87, 0xaf, 0xe2, 0xe4, 0xb6, + 0xee, 0x7b, 0x80, 0x34, 0x5d, 0x0b, 0x29, 0xa4, 0x3d, 0xec, 0xf4, 0x4c, 0x4b, 0xef, 0x52, 0x57, + 0xcc, 0xb1, 0x53, 0x1d, 0xc0, 0xc4, 0x53, 0x1d, 0xc0, 0xd0, 0x2e, 0xcc, 0x44, 0xed, 0x39, 0x2a, + 0x46, 0x3d, 0x42, 0xf8, 0xbe, 0x4c, 0xc4, 0xae, 0x1e, 0x62, 0x9c, 0xf2, 0x0c, 0x40, 0x0c, 0x89, + 0x0c, 0x28, 0xb6, 0x6d, 0xcb, 0xd3, 0x4d, 0x0b, 0x3b, 0x4c, 0x51, 0x52, 0x35, 0x42, 0x75, 0x55, + 0xa2, 0x61, 0x4d, 0x13, 0x99, 0x4f, 0x1e, 0xa1, 0x92, 0x71, 0xe8, 0x23, 0x98, 0x0e, 0x0a, 0x21, + 0xa6, 0x24, 0xa5, 0x1a, 0xa1, 0x5a, 0x13, 0x49, 0xd8, 0x61, 0x90, 0xb8, 0xe4, 0x11, 0x2a, 0x09, + 0x85, 0x3e, 0x84, 0xa9, 0x2e, 0xa9, 0xd0, 0xd6, 0x0e, 0xfa, 0xa6, 0x83, 0x0d, 0xf5, 0x50, 0xdf, + 0x6d, 0x81, 0x82, 0x05, 0x2e, 0x91, 0x47, 0x9e, 0x65, 0x10, 0x31, 0xc4, 0x1e, 0x3d, 0xfd, 0xa0, + 0xe1, 0x5b, 0xee, 0xda, 0x01, 0x1f, 0xd0, 0xca, 0xaa, 0xec, 0xb1, 0x21, 0x13, 0x31, 0x7b, 0xc4, + 0x38, 0x65, 0x7b, 0xc4, 0x90, 0xe8, 0x36, 0x8d, 0xcb, 0x6c, 0x93, 0xd8, 0x70, 0xdf, 0xc2, 0x48, + 0x42, 0xc5, 0xf6, 0x87, 0xb5, 0x63, 0xf8, 0x93, 0x24, 0x34, 0x94, 0x80, 0xba, 0x50, 0xea, 0xdb, + 0x06, 0x7d, 0xed, 0x06, 0xf6, 0x7c, 0xc7, 0xc2, 0x06, 0x2f, 0x94, 0x96, 0x46, 0xa4, 0x4a, 0x54, + 0xec, 0xf3, 0x15, 0xe7, 0x95, 0x47, 0x35, 0xe3, 0x58, 0xf4, 0x29, 0xcc, 0xc5, 0x46, 0x95, 0xd8, + 0x7b, 0x14, 0x54, 0x57, 0x14, 0xeb, 0x0a, 0x4a, 0x56, 0xd3, 0xaa, 0x64, 0x48, 0x9a, 0x95, 0x5a, + 0x88, 0xf6, 0x8e, 0x6e, 0x75, 0xd6, 0xed, 0xd6, 0xb6, 0xc5, 0x8b, 0x40, 0xbd, 0xd5, 0xc5, 0x7c, + 0x5a, 0x2f, 0xa6, 0xfd, 0x86, 0x82, 0x92, 0x69, 0x57, 0xc9, 0x90, 0xb5, 0xab, 0x28, 0xc2, 0xb1, + 0x24, 0x92, 0x56, 0x84, 0xe3, 0x7b, 0xaa, 0xb1, 0x24, 0x46, 0x20, 0x8c, 0x25, 0x31, 0x80, 0x62, + 0x2c, 0x89, 0x21, 0xd8, 0x44, 0x5b, 0xdb, 0xb6, 0xda, 0x66, 0xd7, 0xa4, 0x2d, 0x6e, 0xb6, 0xa9, + 0x45, 0xf5, 0x44, 0xdb, 0x08, 0x61, 0x30, 0xd1, 0x36, 0x82, 0x88, 0x4f, 0xb4, 0x8d, 0x10, 0xa0, + 0x9b, 0x50, 0xda, 0xd1, 0xcd, 0xae, 0xef, 0xe0, 0x66, 0x5b, 0xf7, 0x70, 0xc7, 0x76, 0x0e, 0xf9, + 0xc5, 0x1f, 0xf5, 0x6b, 0x8e, 0xbb, 0xca, 0x51, 0xe2, 0x15, 0x67, 0x0c, 0x85, 0xee, 0xc1, 0x6c, + 0x20, 0xc9, 0xf5, 0x5b, 0xa1, 0xb0, 0xd3, 0x54, 0x18, 0x9d, 0x43, 0xe6, 0xe8, 0xad, 0x08, 0x2b, + 0xc8, 0x43, 0xa3, 0xd8, 0x7a, 0x2e, 0x68, 0x70, 0xad, 0xa7, 0x72, 0xe9, 0x52, 0x66, 0x3d, 0x95, + 0x83, 0x52, 0x81, 0xdf, 0x2b, 0xde, 0x83, 0x99, 0x58, 0x64, 0x44, 0xef, 0x42, 0x38, 0x15, 0x74, + 0xff, 0xb0, 0x1f, 0xa4, 0xdd, 0xd2, 0x14, 0x11, 0x81, 0xab, 0xa6, 0x88, 0x08, 0xbc, 0xfa, 0x65, + 0x0a, 0x72, 0xc1, 0xd1, 0x3b, 0x91, 0x42, 0x6a, 0x05, 0xb2, 0x3d, 0xec, 0xd2, 0xc9, 0x9f, 0x44, + 0x94, 0x8f, 0x71, 0x90, 0x98, 0x8f, 0x71, 0x90, 0x9c, 0x2e, 0x26, 0x1f, 0x2b, 0x5d, 0x4c, 0x4d, + 0x9c, 0x2e, 0x62, 0x7a, 0xd9, 0x2d, 0x84, 0xf4, 0xe0, 0x8e, 0xe8, 0xd1, 0xdf, 0x89, 0xe0, 0x2a, + 0x5c, 0x64, 0x8c, 0x5d, 0x85, 0x8b, 0x28, 0xb4, 0x07, 0xa7, 0x85, 0x7b, 0x2c, 0xde, 0xc0, 0x24, + 0xa1, 0xbc, 0x38, 0x7e, 0xb2, 0xa0, 0x41, 0xa9, 0x58, 0xc0, 0xda, 0x8b, 0x41, 0xc5, 0x7c, 0x3b, + 0x8e, 0x23, 0x2e, 0x61, 0xe0, 0x96, 0xdf, 0xd9, 0xe0, 0xdb, 0x9e, 0x8d, 0x5c, 0x42, 0x84, 0x8b, + 0x2e, 0x21, 0xc2, 0xab, 0xff, 0x4a, 0x40, 0x51, 0x7e, 0xdf, 0x13, 0x71, 0x8c, 0xd7, 0x21, 0x8f, + 0x0f, 0x4c, 0xaf, 0xd9, 0xb6, 0x0d, 0xcc, 0x8b, 0x4e, 0x6a, 0x67, 0x02, 0xbc, 0x6a, 0x1b, 0x92, + 0x9d, 0x03, 0x98, 0xe8, 0x4d, 0xc9, 0x89, 0xbc, 0x29, 0xea, 0x17, 0xa7, 0x26, 0xe8, 0x17, 0x2b, + 0xed, 0x94, 0x3f, 0x19, 0x3b, 0x55, 0xbf, 0x49, 0x40, 0x29, 0xfe, 0x7d, 0x7a, 0x36, 0x8e, 0xa0, + 0x7c, 0x9a, 0x92, 0x13, 0x9f, 0xa6, 0xf7, 0x60, 0x9a, 0x24, 0x95, 0xba, 0xe7, 0xf1, 0x41, 0xe1, + 0x14, 0xcd, 0x0b, 0x59, 0x34, 0xf2, 0xad, 0xd5, 0x00, 0x2e, 0x45, 0x23, 0x01, 0x3e, 0xe2, 0xba, + 0xe9, 0x63, 0xba, 0xee, 0xe7, 0x09, 0x98, 0xde, 0xb4, 0x8d, 0xfb, 0x2c, 0xdf, 0xf4, 0x9e, 0x95, + 0xfd, 0x7c, 0x9a, 0x21, 0xad, 0x3a, 0x03, 0xd3, 0x52, 0xc2, 0x59, 0xfd, 0x82, 0xf9, 0x99, 0xfc, + 0x5d, 0xff, 0xe9, 0xed, 0x4b, 0x11, 0xa6, 0xc4, 0x3c, 0xb9, 0x5a, 0x87, 0x99, 0x58, 0x5a, 0x2b, + 0xbe, 0x80, 0x36, 0xc9, 0x0b, 0x54, 0xaf, 0xc1, 0x9c, 0x2a, 0xdf, 0x13, 0xa2, 0x8e, 0x36, 0xc1, + 0x25, 0xd7, 0x0d, 0x98, 0x53, 0xe5, 0x6d, 0xc7, 0x5f, 0xce, 0xbb, 0xfc, 0x02, 0x99, 0x67, 0x58, + 0xc7, 0xe6, 0xbf, 0x0e, 0xb3, 0x8a, 0x4c, 0xeb, 0xf8, 0x72, 0xbe, 0x4e, 0x04, 0x0d, 0x84, 0x68, + 0xb8, 0xff, 0x3a, 0x94, 0xfa, 0xc1, 0x43, 0x93, 0x97, 0xa9, 0xe9, 0x68, 0xda, 0x2a, 0xc4, 0xad, + 0xc7, 0xea, 0xd5, 0xa2, 0x8c, 0x91, 0xe5, 0xf0, 0x12, 0x36, 0xa3, 0x90, 0xd3, 0x88, 0xd5, 0xb2, + 0x45, 0x19, 0x23, 0x98, 0x28, 0x3b, 0xc1, 0x87, 0xe1, 0x16, 0x9c, 0x0e, 0x66, 0xe4, 0xf6, 0x71, + 0xb0, 0xfc, 0x5c, 0x94, 0x33, 0x46, 0xc8, 0xf8, 0xfa, 0x67, 0x62, 0x28, 0x5a, 0x4d, 0xa7, 0xab, + 0x9f, 0x69, 0x30, 0x13, 0xfb, 0x1d, 0x03, 0xba, 0x0c, 0x39, 0xfa, 0x23, 0xc3, 0xa8, 0x8f, 0x40, + 0x37, 0x9a, 0xc2, 0x24, 0x99, 0x59, 0x0e, 0x42, 0x6f, 0x40, 0x3e, 0xfc, 0x69, 0x03, 0xbf, 0xcd, + 0x66, 0x47, 0x21, 0x00, 0x4a, 0x47, 0x21, 0x00, 0xf2, 0x16, 0xc4, 0xcf, 0xe1, 0xec, 0xd8, 0x1f, + 0x35, 0x1c, 0xeb, 0xe6, 0x34, 0xea, 0x25, 0xa4, 0x8e, 0xd5, 0x4b, 0x38, 0x80, 0x05, 0xf5, 0x6f, + 0x0d, 0x04, 0xed, 0x89, 0x23, 0xb5, 0x47, 0x86, 0x4c, 0x1e, 0x6d, 0xc8, 0xf0, 0x7a, 0x7e, 0x4a, + 0x9c, 0xff, 0x47, 0x97, 0x20, 0xdd, 0xb7, 0xed, 0xae, 0xcb, 0xc7, 0x45, 0xa8, 0x3a, 0x0a, 0x10, + 0xd5, 0x51, 0xc0, 0x63, 0xb4, 0x7a, 0xfc, 0xe0, 0x30, 0x44, 0xbf, 0x50, 0x78, 0x0a, 0xbb, 0xfb, + 0xf2, 0x65, 0xc8, 0x05, 0x57, 0xf2, 0x08, 0x20, 0x73, 0x6f, 0x7b, 0x6d, 0x7b, 0xed, 0x5a, 0xe9, + 0x14, 0x2a, 0x40, 0x76, 0x73, 0xed, 0xce, 0xb5, 0x5b, 0x77, 0x6e, 0x94, 0x34, 0xf2, 0xd0, 0xd8, + 0xbe, 0x73, 0x87, 0x3c, 0x24, 0x5e, 0xbe, 0x2d, 0x8e, 0xf9, 0xf1, 0x64, 0x72, 0x0a, 0x72, 0xab, + 0xfd, 0x3e, 0x8d, 0x03, 0x8c, 0x77, 0x6d, 0xdf, 0x24, 0xc1, 0xa5, 0xa4, 0xa1, 0x2c, 0x24, 0xef, + 0xde, 0xdd, 0x28, 0x25, 0xd0, 0x1c, 0x94, 0xae, 0x61, 0xdd, 0xe8, 0x9a, 0x16, 0x0e, 0x42, 0x69, + 0x29, 0x59, 0x7f, 0xf8, 0x97, 0x6f, 0x97, 0xb4, 0x6f, 0xbe, 0x5d, 0xd2, 0xfe, 0xf9, 0xed, 0x92, + 0xf6, 0xe5, 0x77, 0x4b, 0xa7, 0xbe, 0xf9, 0x6e, 0xe9, 0xd4, 0xdf, 0xbf, 0x5b, 0x3a, 0xf5, 0xb3, + 0xcb, 0x1d, 0xd3, 0xdb, 0xf5, 0x5b, 0xb5, 0xb6, 0xdd, 0xe3, 0xbf, 0x96, 0xee, 0x3b, 0x36, 0x89, + 0x59, 0xfc, 0x69, 0x25, 0xfe, 0x33, 0xea, 0x3f, 0x24, 0xce, 0xad, 0xd2, 0xc7, 0x4d, 0x46, 0x57, + 0xbb, 0x65, 0xd7, 0x18, 0x80, 0xfe, 0x70, 0xd6, 0x6d, 0x65, 0xe8, 0x0f, 0x64, 0x5f, 0xff, 0x4f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xd1, 0x6a, 0x53, 0x7f, 0x81, 0x3d, 0x00, 0x00, } func (m *EventSequence) Marshal() (dAtA []byte, err error) { @@ -7018,6 +7027,13 @@ func (m *JobRunPreempted) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PreemptiveJobId) > 0 { + i -= len(m.PreemptiveJobId) + copy(dAtA[i:], m.PreemptiveJobId) + i = encodeVarintEvents(dAtA, i, uint64(len(m.PreemptiveJobId))) + i-- + dAtA[i] = 0x42 + } if len(m.Reason) > 0 { i -= len(m.Reason) copy(dAtA[i:], m.Reason) @@ -8679,6 +8695,10 @@ func (m *JobRunPreempted) Size() (n int) { if l > 0 { n += 1 + l + sovEvents(uint64(l)) } + l = len(m.PreemptiveJobId) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } return n } @@ -16878,6 +16898,38 @@ func (m *JobRunPreempted) Unmarshal(dAtA []byte) error { } m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreemptiveJobId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PreemptiveJobId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) diff --git a/pkg/armadaevents/events.proto b/pkg/armadaevents/events.proto index db0096c6489..f99d5fb1f60 100644 --- a/pkg/armadaevents/events.proto +++ b/pkg/armadaevents/events.proto @@ -545,6 +545,7 @@ message JobRunPreempted{ string preempted_job_id = 5; string preempted_run_id = 6; string reason = 7; + string preemptive_job_id = 8; } // Message used internally by Armada to see if messages can be propagated through a pulsar partition From 4075d40a6ff75561dfbc3f60cbd103b1358d5597 Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:12 -0500 Subject: [PATCH 02/16] fix: add scheduler_termination_reason JSONB column to job_run Signed-off-by: William Vega --- .../schema/migrations/034_add_scheduler_termination_reason.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql diff --git a/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql b/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql new file mode 100644 index 00000000000..5806a876f85 --- /dev/null +++ b/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql @@ -0,0 +1 @@ +ALTER TABLE job_run ADD COLUMN scheduler_termination_reason JSONB; \ No newline at end of file From 8178115b25ac124e03b314f9515d740bfad72401 Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:16 -0500 Subject: [PATCH 03/16] fix: add SchedulerTerminationReason field to UpdateJobRunInstruction Signed-off-by: William Vega --- internal/lookoutingester/model/model.go | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/internal/lookoutingester/model/model.go b/internal/lookoutingester/model/model.go index d5675955a39..9e81653db90 100644 --- a/internal/lookoutingester/model/model.go +++ b/internal/lookoutingester/model/model.go @@ -57,18 +57,19 @@ type CreateJobRunInstruction struct { // UpdateJobRunInstruction is an instruction to update an existing row in the job runs table type UpdateJobRunInstruction struct { - RunId string - Node *string - Pending *time.Time - Started *time.Time - Finished *time.Time - JobRunState *int32 - Error []byte - Debug []byte - ExitCode *int32 - IngressAddresses map[int32]string - FailureCategory *string - FailureSubcategory *string + RunId string + Node *string + Pending *time.Time + Started *time.Time + Finished *time.Time + JobRunState *int32 + Error []byte + Debug []byte + ExitCode *int32 + IngressAddresses map[int32]string + FailureCategory *string + FailureSubcategory *string + SchedulerTerminationReason map[string]any } // CreateJobErrorInstruction is an instruction to create a new row in the job_error table From f1af88da6bf08cb8f1b715c2b59cbf98585d5b55 Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:19 -0500 Subject: [PATCH 04/16] fix: wire SchedulerTerminationReason through insertion.go DB write path Signed-off-by: William Vega --- internal/lookoutingester/lookoutdb/insertion.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/internal/lookoutingester/lookoutdb/insertion.go b/internal/lookoutingester/lookoutdb/insertion.go index 03c0b5779dc..817c6ceebf8 100644 --- a/internal/lookoutingester/lookoutdb/insertion.go +++ b/internal/lookoutingester/lookoutdb/insertion.go @@ -725,7 +725,8 @@ func (l *LookoutDb) UpdateJobRunsBatch(ctx *armadacontext.Context, instructions exit_code int, ingress_addresses jsonb, failure_category varchar(63), - failure_subcategory varchar(63) + failure_subcategory varchar(63), + scheduler_termination_reason jsonb ) ON COMMIT DROP;`, tmpTable)) if err != nil { l.metrics.RecordDBError(commonmetrics.DBOperationCreateTempTable) @@ -749,6 +750,7 @@ func (l *LookoutDb) UpdateJobRunsBatch(ctx *armadacontext.Context, instructions "ingress_addresses", "failure_category", "failure_subcategory", + "scheduler_termination_reason", }, pgx.CopyFromSlice(len(instructions), func(i int) ([]interface{}, error) { return []interface{}{ @@ -764,6 +766,7 @@ func (l *LookoutDb) UpdateJobRunsBatch(ctx *armadacontext.Context, instructions instructions[i].IngressAddresses, instructions[i].FailureCategory, instructions[i].FailureSubcategory, + instructions[i].SchedulerTerminationReason, }, nil }), ) @@ -785,7 +788,8 @@ func (l *LookoutDb) UpdateJobRunsBatch(ctx *armadacontext.Context, instructions exit_code = coalesce(tmp.exit_code, job_run.exit_code), ingress_addresses = coalesce(tmp.ingress_addresses, job_run.ingress_addresses), failure_category = coalesce(tmp.failure_category, job_run.failure_category), - failure_subcategory = coalesce(tmp.failure_subcategory, job_run.failure_subcategory) + failure_subcategory = coalesce(tmp.failure_subcategory, job_run.failure_subcategory), + scheduler_termination_reason = coalesce(tmp.scheduler_termination_reason, job_run.scheduler_termination_reason) FROM %s as tmp where tmp.run_id = job_run.run_id`, tmpTable), ) if err != nil { @@ -811,7 +815,8 @@ func (l *LookoutDb) UpdateJobRunsScalar(ctx *armadacontext.Context, instructions debug = coalesce($9, debug), ingress_addresses = coalesce($10, ingress_addresses), failure_category = coalesce($11, failure_category), - failure_subcategory = coalesce($12, failure_subcategory) + failure_subcategory = coalesce($12, failure_subcategory), + scheduler_termination_reason = coalesce($13, scheduler_termination_reason) WHERE run_id = $1` for _, i := range instructions { err := l.withDatabaseRetryInsert(ctx, func() error { @@ -828,6 +833,7 @@ func (l *LookoutDb) UpdateJobRunsScalar(ctx *armadacontext.Context, instructions i.IngressAddresses, i.FailureCategory, i.FailureSubcategory, + i.SchedulerTerminationReason, ) if err != nil { l.metrics.RecordDBError(commonmetrics.DBOperationUpdate) @@ -1034,6 +1040,9 @@ func conflateJobRunUpdates(updates []*model.UpdateJobRunInstruction) []*model.Up if update.FailureSubcategory != nil { existing.FailureSubcategory = update.FailureSubcategory } + if update.SchedulerTerminationReason != nil { + existing.SchedulerTerminationReason = update.SchedulerTerminationReason + } } else { updatesById[update.RunId] = update } From fdd2c2e8d2055a5411183b3dafaa60aef8df179b Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:22 -0500 Subject: [PATCH 05/16] fix: populate SchedulerTerminationReason in handleJobRunPreempted Signed-off-by: William Vega --- .../instructions/instructions.go | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/internal/lookoutingester/instructions/instructions.go b/internal/lookoutingester/instructions/instructions.go index fd90fa9720d..a1da2fd086c 100644 --- a/internal/lookoutingester/instructions/instructions.go +++ b/internal/lookoutingester/instructions/instructions.go @@ -476,11 +476,16 @@ func (c *InstructionConverter) handleJobRunErrors(ts time.Time, event *armadaeve } func (c *InstructionConverter) handleJobRunPreempted(ts time.Time, event *armadaevents.JobRunPreempted, update *model.InstructionSet) error { + terminationReasonArgs := map[string]any{} + if event.PreemptiveJobId != "" { + terminationReasonArgs["preemptingJobId"] = event.PreemptiveJobId + } jobRun := model.UpdateJobRunInstruction{ - RunId: event.PreemptedRunId, - JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), - Finished: &ts, - Error: tryCompressError(event.PreemptedJobId, event.Reason, c.compressor), + RunId: event.PreemptedRunId, + JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), + Finished: &ts, + Error: tryCompressError(event.PreemptedJobId, event.Reason, c.compressor), + SchedulerTerminationReason: BuildTerminationReason(event.Reason, terminationReasonArgs), } update.JobRunsToUpdate = append(update.JobRunsToUpdate, &jobRun) return nil @@ -554,3 +559,13 @@ func getJobPriorityClass(job *api.Job) *string { } return nil } + +func BuildTerminationReason(reason string, args map[string]any) map[string]any { + result := map[string]any{ + "reason": reason, + } + if len(args) > 0 { + result["args"] = args + } + return result +} From 1c3da33c980a7a9105820a2fdc6118fc48e28bd1 Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:25 -0500 Subject: [PATCH 06/16] fix: thread PreemptiveJobId through scheduler preemption events Signed-off-by: William Vega --- internal/scheduler/scheduler.go | 22 ++++++--- internal/scheduler/scheduler_test.go | 74 ++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 7 deletions(-) diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index 7ca9db4dfa9..31f28d30f6e 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -644,7 +644,7 @@ func AppendEventSequencesFromPreemptedJobs(eventSequences []*armadaevents.EventS eventSequences = append(eventSequences, &armadaevents.EventSequence{ Queue: jctx.Job.Queue(), JobSetName: jctx.Job.Jobset(), - Events: createEventsForPreemptedJob(jctx.JobId, run.Id(), jctx.PreemptionDescription, time), + Events: createEventsForPreemptedJob(jctx.JobId, run.Id(), preemptingJobId(jctx.PreemptingJob), jctx.PreemptionDescription, time), }) } return eventSequences, nil @@ -674,15 +674,23 @@ func createEventsForFailedJob(jobId string, runId string, error *armadaevents.Er } } -func createEventsForPreemptedJob(jobId string, runId string, reason string, time time.Time) []*armadaevents.EventSequence_Event { +func preemptingJobId(preemptingJob *jobdb.Job) string { + if preemptingJob == nil { + return "" + } + return preemptingJob.Id() +} + +func createEventsForPreemptedJob(jobId string, runId string, preemptiveJobId string, reason string, time time.Time) []*armadaevents.EventSequence_Event { return []*armadaevents.EventSequence_Event{ { Created: protoutil.ToTimestamp(time), Event: &armadaevents.EventSequence_Event_JobRunPreempted{ JobRunPreempted: &armadaevents.JobRunPreempted{ - PreemptedRunId: runId, - PreemptedJobId: jobId, - Reason: reason, + PreemptedRunId: runId, + PreemptedJobId: jobId, + Reason: reason, + PreemptiveJobId: preemptiveJobId, }, }, }, @@ -759,7 +767,7 @@ func AppendEventSequencesFromReconciliationFailureJobs(eventSequences []*armadae es := &armadaevents.EventSequence{ Queue: jobInfo.Job.Queue(), JobSetName: jobInfo.Job.Jobset(), - Events: createEventsForPreemptedJob(jobInfo.Job.Id(), run.Id(), jobInfo.Reason, time), + Events: createEventsForPreemptedJob(jobInfo.Job.Id(), run.Id(), "", jobInfo.Reason, time), } eventSequences = append(eventSequences, es) } @@ -1021,7 +1029,7 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo if lastRun.PreemptReason() != nil && *lastRun.PreemptReason() != "" { reason = *lastRun.PreemptReason() } - events = append(events, createEventsForPreemptedJob(job.Id(), lastRun.Id(), reason, s.clock.Now())...) + events = append(events, createEventsForPreemptedJob(job.Id(), lastRun.Id(), "", reason, s.clock.Now())...) s.metrics.ReportJobPreemptedWithType(job, schedulercontext.PreemptedViaApi) } } diff --git a/internal/scheduler/scheduler_test.go b/internal/scheduler/scheduler_test.go index e428afe5de7..f591d88f2aa 100644 --- a/internal/scheduler/scheduler_test.go +++ b/internal/scheduler/scheduler_test.go @@ -3524,3 +3524,77 @@ func createPreemptibleGangJob() *jobdb.Job { true, ).WithNewRun("testExecutor", "test-node", "node", "pool", 5) } + +func TestPreemptingJobId(t *testing.T) { + // nil job returns empty string + assert.Equal(t, "", preemptingJobId(nil)) + + // job returns its ID + job := testfixtures.NewJob( + util.NewULID(), + "testJobset", + "testQueue", + 0, + toInternalSchedulingInfo(preemptibleGangSchedulingInfo), + false, + 1, + false, + false, + false, + 1, + true, + ) + assert.Equal(t, job.Id(), preemptingJobId(job)) +} + +func TestAppendEventSequencesFromPreemptedJobs_PopulatesPreemptiveJobId(t *testing.T) { + preemptingJob := testfixtures.NewJob( + util.NewULID(), + "testJobset", + "testQueue", + 0, + toInternalSchedulingInfo(preemptibleGangSchedulingInfo), + false, + 1, + false, + false, + false, + 1, + true, + ) + preemptingJobId := preemptingJob.Id() + + preemptedJob := testfixtures.NewJob( + util.NewULID(), + "testJobset", + "testQueue", + 0, + toInternalSchedulingInfo(preemptibleGangSchedulingInfo), + false, + 1, + false, + false, + false, + 1, + true, + ).WithNewRun("testExecutor", "test-node", "node", "pool", 5) + preemptedRun := preemptedJob.LatestRun() + + jctx := &schedulercontext.JobSchedulingContext{ + Job: preemptedJob, + PreemptingJob: preemptingJob, + PreemptionDescription: "preempted by fair-share", + } + + sequences, err := AppendEventSequencesFromPreemptedJobs(nil, []*schedulercontext.JobSchedulingContext{jctx}, time.Now()) + assert.NoError(t, err) + assert.Len(t, sequences, 1) + + events := sequences[0].Events + assert.Len(t, events, 3) // JobRunPreempted + JobRunErrors + JobErrors + + preemptedEvent := events[0].GetJobRunPreempted() + assert.NotNil(t, preemptedEvent) + assert.Equal(t, preemptedRun.Id(), preemptedEvent.PreemptedRunId) + assert.Equal(t, preemptingJobId, preemptedEvent.PreemptiveJobId) +} From b042f3005842f84d9b66ba6abbc7fd25a00680ff Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:28 -0500 Subject: [PATCH 07/16] fix: wire PreemptiveJobId through FromInternalJobRunPreempted Signed-off-by: William Vega --- .../server/event/conversion/conversions.go | 13 ++++++----- .../event/conversion/conversions_test.go | 23 +++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/internal/server/event/conversion/conversions.go b/internal/server/event/conversion/conversions.go index 21e7c6ea8a8..a6c2c1a83af 100644 --- a/internal/server/event/conversion/conversions.go +++ b/internal/server/event/conversion/conversions.go @@ -440,12 +440,13 @@ func FromInternalJobRunPreempted(queueName string, jobSetName string, time time. } apiEvent := &api.JobPreemptedEvent{ - JobId: e.PreemptedJobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), - RunId: e.PreemptedRunId, - Reason: e.Reason, + JobId: e.PreemptedJobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + RunId: e.PreemptedRunId, + Reason: e.Reason, + PreemptiveJobId: e.PreemptiveJobId, } return []*api.EventMessage{ diff --git a/internal/server/event/conversion/conversions_test.go b/internal/server/event/conversion/conversions_test.go index 1f8793ef670..5122ece005e 100644 --- a/internal/server/event/conversion/conversions_test.go +++ b/internal/server/event/conversion/conversions_test.go @@ -872,13 +872,16 @@ func TestConvertJobPreemptionRequested(t *testing.T) { } func TestConvertJobRunPreempted(t *testing.T) { + preemptiveJobId := "456e7890-e89b-12d3-a456-426614174001" + preempted := &armadaevents.EventSequence_Event{ Created: baseTimeProto, Event: &armadaevents.EventSequence_Event_JobRunPreempted{ JobRunPreempted: &armadaevents.JobRunPreempted{ - PreemptedJobId: jobId, - PreemptedRunId: runId, - Reason: "Preempted reason", + PreemptedJobId: jobId, + PreemptedRunId: runId, + PreemptiveJobId: preemptiveJobId, + Reason: "Preempted reason", }, }, } @@ -887,18 +890,18 @@ func TestConvertJobRunPreempted(t *testing.T) { { Events: &api.EventMessage_Preempted{ Preempted: &api.JobPreemptedEvent{ - JobId: jobId, - JobSetId: jobSetName, - Queue: queue, - Created: protoutil.ToTimestamp(baseTime), - RunId: runId, - Reason: "Preempted reason", + JobId: jobId, + JobSetId: jobSetName, + Queue: queue, + Created: protoutil.ToTimestamp(baseTime), + RunId: runId, + Reason: "Preempted reason", + PreemptiveJobId: preemptiveJobId, }, }, }, } - // both PreemptiveJobId and PreemptiveRunId not nil apiEvents, err := FromEventSequence(toEventSeq(preempted)) assert.NoError(t, err) assert.Equal(t, expected, apiEvents) From 35f767e49ecbd14cd392a13ecec6c541a0d6063b Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:32 -0500 Subject: [PATCH 08/16] fix: add fixtures and update instructions tests for fair-share preemption Signed-off-by: William Vega --- internal/common/ingest/testfixtures/event.go | 15 ++++ .../instructions/instructions_test.go | 69 +++++++++++++++++-- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/internal/common/ingest/testfixtures/event.go b/internal/common/ingest/testfixtures/event.go index d8645fd16b1..0e6e2eef731 100644 --- a/internal/common/ingest/testfixtures/event.go +++ b/internal/common/ingest/testfixtures/event.go @@ -21,6 +21,7 @@ import ( const ( JobId = "01f3j0g1md4qx7z5qb148qnh4r" RunId = "123e4567-e89b-12d3-a456-426614174000" + PreemptingJobId = "456e7890-e89b-12d3-a456-426614174001" PartitionMarkerGroupId = "223e4567-e89b-12d3-a456-426614174000" JobsetName = "testJobset" ExecutorId = "testCluster" @@ -43,6 +44,7 @@ const ( LeaseReturnedMsg = "lease returned error message" UnschedulableMsg = "test pod is unschedulable" PreemptionReason = "job preempted" + CancelReason = "sample cancel reason" PartitionMarkerPartitionId = 456 ExecutorCordonReason = "bad executor" @@ -467,6 +469,19 @@ var JobRunPreempted = &armadaevents.EventSequence_Event{ }, } +// JobRunPreemptedFairShare represents a fair-share preemption where the preempting job is known. +var JobRunPreemptedFairShare = &armadaevents.EventSequence_Event{ + Created: testfixtures.BasetimeProto, + Event: &armadaevents.EventSequence_Event_JobRunPreempted{ + JobRunPreempted: &armadaevents.JobRunPreempted{ + PreemptedJobId: JobId, + PreemptedRunId: RunId, + PreemptiveJobId: PreemptingJobId, + Reason: PreemptionReason, + }, + }, +} + var JobRunFailed = &armadaevents.EventSequence_Event{ Created: testfixtures.BasetimeProto, Event: &armadaevents.EventSequence_Event_JobRunErrors{ diff --git a/internal/lookoutingester/instructions/instructions_test.go b/internal/lookoutingester/instructions/instructions_test.go index aa27de85844..8e4107e692d 100644 --- a/internal/lookoutingester/instructions/instructions_test.go +++ b/internal/lookoutingester/instructions/instructions_test.go @@ -1,6 +1,7 @@ package instructions import ( + "encoding/json" "strings" "testing" @@ -174,10 +175,19 @@ var expectedReconciliationErrRun = model.UpdateJobRunInstruction{ } var expectedPreemptedRun = model.UpdateJobRunInstruction{ - RunId: testfixtures.RunId, - Finished: &testfixtures.BaseTime, - JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), - Error: []byte(testfixtures.PreemptionReason), + RunId: testfixtures.RunId, + Finished: &testfixtures.BaseTime, + JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), + Error: []byte(testfixtures.PreemptionReason), + SchedulerTerminationReason: BuildTerminationReason(testfixtures.PreemptionReason, nil), +} + +var expectedFairSharePreemptedRun = model.UpdateJobRunInstruction{ + RunId: testfixtures.RunId, + Finished: &testfixtures.BaseTime, + JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), + Error: []byte(testfixtures.PreemptionReason), + SchedulerTerminationReason: BuildTerminationReason(testfixtures.PreemptionReason, map[string]any{"preemptingJobId": testfixtures.PreemptingJobId}), } var expectedCancelledRun = model.UpdateJobRunInstruction{ @@ -256,7 +266,7 @@ func TestConvert(t *testing.T) { cancelledWithReason, err := testfixtures.DeepCopy(testfixtures.JobCancelled) assert.NoError(t, err) - cancelledWithReason.GetCancelledJob().Reason = "some reason" + cancelledWithReason.GetCancelledJob().Reason = testfixtures.CancelReason tests := map[string]struct { events *utils.EventsWithIds[*armadaevents.EventSequence] @@ -355,7 +365,7 @@ func TestConvert(t *testing.T) { JobsToUpdate: []*model.UpdateJobInstruction{{ JobId: testfixtures.JobId, State: pointer.Int32(lookout.JobCancelledOrdinal), - CancelReason: pointer.String("some reason"), + CancelReason: pointer.String(testfixtures.CancelReason), CancelUser: pointer.String(testfixtures.CancelUser), Cancelled: &testfixtures.BaseTime, LastTransitionTime: &testfixtures.BaseTime, @@ -465,6 +475,16 @@ func TestConvert(t *testing.T) { MessageIds: []pulsar.MessageID{pulsarutils.NewMessageId(1)}, }, }, + "job run preempted (fair-share)": { + events: &utils.EventsWithIds[*armadaevents.EventSequence]{ + Events: []*armadaevents.EventSequence{testfixtures.NewEventSequence(testfixtures.JobRunPreemptedFairShare)}, + MessageIds: []pulsar.MessageID{pulsarutils.NewMessageId(1)}, + }, + expected: &model.InstructionSet{ + JobRunsToUpdate: []*model.UpdateJobRunInstruction{&expectedFairSharePreemptedRun}, + MessageIds: []pulsar.MessageID{pulsarutils.NewMessageId(1)}, + }, + }, "invalid event without created time": { events: &utils.EventsWithIds[*armadaevents.EventSequence]{ Events: []*armadaevents.EventSequence{ @@ -696,3 +716,40 @@ func TestSanitizeForJsonb(t *testing.T) { assert.Equal(t, "", sanitizeForJsonb("\x00")) assert.Equal(t, "", sanitizeForJsonb("")) } + +// TestBuildTerminationReason_WireFormat pins the exact JSON shape written to the +// scheduler_termination_reason column. This is a contract test: if the output +// format changes, this test breaks and the author knows they are changing the +// wire format stored in the database. +// +// Preemption (no preempting job): {"reason": "..."} +// Preemption (fair-share): {"args": {"preemptingJobId": "..."}, "reason": "..."} +func TestBuildTerminationReason_WireFormat(t *testing.T) { + tests := []struct { + name string + reason string + args map[string]any + expectedJSON string + }{ + { + name: "preemption without preempting run", + reason: testfixtures.PreemptionReason, + args: nil, + expectedJSON: `{"reason":"` + testfixtures.PreemptionReason + `"}`, + }, + { + name: "preemption with preempting job (fair-share)", + reason: testfixtures.PreemptionReason, + args: map[string]any{"preemptingJobId": testfixtures.PreemptingJobId}, + expectedJSON: `{"args":{"preemptingJobId":"` + testfixtures.PreemptingJobId + `"},"reason":"` + testfixtures.PreemptionReason + `"}`, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result := BuildTerminationReason(tc.reason, tc.args) + b, err := json.Marshal(result) + assert.NoError(t, err) + assert.Equal(t, tc.expectedJSON, string(b)) + }) + } +} From 66682cd4a8eeae8bfafa96a8a1f8bb43a3181dfa Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:35 -0500 Subject: [PATCH 09/16] fix: update insertion_test.go for SchedulerTerminationReason column Signed-off-by: William Vega --- .../lookoutdb/insertion_test.go | 131 ++++++++++++------ 1 file changed, 91 insertions(+), 40 deletions(-) diff --git a/internal/lookoutingester/lookoutdb/insertion_test.go b/internal/lookoutingester/lookoutdb/insertion_test.go index 0f53b5dfffe..daba2d674f7 100644 --- a/internal/lookoutingester/lookoutdb/insertion_test.go +++ b/internal/lookoutingester/lookoutdb/insertion_test.go @@ -17,6 +17,7 @@ import ( "github.com/armadaproject/armada/internal/common/database/lookout" "github.com/armadaproject/armada/internal/common/ingest/testfixtures" "github.com/armadaproject/armada/internal/common/pulsarutils" + "github.com/armadaproject/armada/internal/lookoutingester/instructions" "github.com/armadaproject/armada/internal/lookoutingester/metrics" "github.com/armadaproject/armada/internal/lookoutingester/model" ) @@ -56,6 +57,7 @@ var ( } testFailureCategory = "infrastructure" testFailureSubcategory = "oom" + testTerminationReason = "test termination reason" ) var ( @@ -100,20 +102,21 @@ type JobSpecRow struct { } type JobRunRow struct { - RunId string - JobId string - Cluster string - Node *string - Pending time.Time - Started *time.Time - Finished *time.Time - JobRunState int32 - Error []byte - Debug []byte - ExitCode *int32 - IngressAddresses map[int32]string - FailureCategory *string - FailureSubcategory *string + RunId string + JobId string + Cluster string + Node *string + Pending time.Time + Started *time.Time + Finished *time.Time + JobRunState int32 + Error []byte + Debug []byte + ExitCode *int32 + IngressAddresses map[int32]string + FailureCategory *string + FailureSubcategory *string + SchedulerTerminationReason map[string]any } type JobErrorRow struct { @@ -141,16 +144,17 @@ func defaultInstructionSet() *model.InstructionSet { IngressAddresses: cloneIngressAddresses(initialIngressAddresses), }}, JobRunsToUpdate: []*model.UpdateJobRunInstruction{{ - RunId: RunId, - Node: pointer.String(nodeName), - Started: &startTime, - Finished: &finishedTime, - Debug: []byte(testfixtures.DebugMsg), - JobRunState: pointer.Int32(lookout.JobRunSucceededOrdinal), - ExitCode: pointer.Int32(0), - IngressAddresses: cloneIngressAddresses(updatedIngressAddresses), - FailureCategory: pointer.String(testFailureCategory), - FailureSubcategory: pointer.String(testFailureSubcategory), + RunId: RunId, + Node: pointer.String(nodeName), + Started: &startTime, + Finished: &finishedTime, + Debug: []byte(testfixtures.DebugMsg), + JobRunState: pointer.Int32(lookout.JobRunSucceededOrdinal), + ExitCode: pointer.Int32(0), + IngressAddresses: cloneIngressAddresses(updatedIngressAddresses), + FailureCategory: pointer.String(testFailureCategory), + FailureSubcategory: pointer.String(testFailureSubcategory), + SchedulerTerminationReason: instructions.BuildTerminationReason(testTerminationReason, nil), }}, JobErrorsToCreate: []*model.CreateJobErrorInstruction{{ JobId: JobId, @@ -217,19 +221,20 @@ var expectedJobError = JobErrorRow{ } var expectedJobRunAfterUpdate = JobRunRow{ - RunId: RunId, - JobId: JobId, - Cluster: executorId, - Node: pointer.String(nodeName), - Pending: updateTime, - Started: &startTime, - Finished: &finishedTime, - JobRunState: lookout.JobRunSucceededOrdinal, - ExitCode: pointer.Int32(0), - Debug: []byte(testfixtures.DebugMsg), - IngressAddresses: cloneIngressAddresses(updatedIngressAddresses), - FailureCategory: pointer.String(testFailureCategory), - FailureSubcategory: pointer.String(testFailureSubcategory), + RunId: RunId, + JobId: JobId, + Cluster: executorId, + Node: pointer.String(nodeName), + Pending: updateTime, + Started: &startTime, + Finished: &finishedTime, + JobRunState: lookout.JobRunSucceededOrdinal, + ExitCode: pointer.Int32(0), + Debug: []byte(testfixtures.DebugMsg), + IngressAddresses: cloneIngressAddresses(updatedIngressAddresses), + FailureCategory: pointer.String(testFailureCategory), + FailureSubcategory: pointer.String(testFailureSubcategory), + SchedulerTerminationReason: instructions.BuildTerminationReason(testTerminationReason, nil), } func TestCreateJobsBatch(t *testing.T) { @@ -393,7 +398,7 @@ func TestUpdateJobsWithTerminal(t *testing.T) { JobId: JobId, State: pointer.Int32(lookout.JobCancelledOrdinal), Cancelled: &baseTime, - CancelReason: pointer.String("some reason"), + CancelReason: pointer.String(testfixtures.CancelReason), CancelUser: pointer.String(userId), LastTransitionTime: &baseTime, LastTransitionTimeSeconds: pointer.Int64(baseTime.Unix()), @@ -448,7 +453,7 @@ func TestUpdateJobsWithTerminal(t *testing.T) { // Assert the states are still terminal job := getJob(t, db, JobId) assert.Equal(t, lookout.JobCancelledOrdinal, int(job.State)) - assert.Equal(t, "some reason", *job.CancelReason) + assert.Equal(t, testfixtures.CancelReason, *job.CancelReason) assert.Equal(t, testfixtures.UserId, *job.CancelUser) job2 := getJob(t, db, "job2") @@ -717,6 +722,45 @@ func TestStore(t *testing.T) { assert.NoError(t, err) } +// ensure executor update doesn't write over scheduler termination reason update +func TestSchedulerTerminationReasonNotOverwritten(t *testing.T) { + err := lookout.WithLookoutDb(func(db *pgxpool.Pool) error { + ldb := NewLookoutDb(db, fatalErrors, m, 10, 10) + + err := ldb.CreateJobsBatch(armadacontext.Background(), defaultInstructionSet().JobsToCreate) + assert.Nil(t, err) + err = ldb.CreateJobRunsBatch(armadacontext.Background(), defaultInstructionSet().JobRunsToCreate) + assert.Nil(t, err) + + // scheduler writes the preemption reason + schedulerUpdate := []*model.UpdateJobRunInstruction{{ + RunId: RunId, + JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), + SchedulerTerminationReason: instructions.BuildTerminationReason(testfixtures.PreemptionReason, nil), + }} + err = ldb.UpdateJobRunsBatch(armadacontext.Background(), schedulerUpdate) + assert.Nil(t, err) + + run := getJobRun(t, db, RunId) + assert.Equal(t, instructions.BuildTerminationReason(testfixtures.PreemptionReason, nil), run.SchedulerTerminationReason) + + // executor writes run errors without a termination reason (nil) + executorUpdate := []*model.UpdateJobRunInstruction{{ + RunId: RunId, + JobRunState: pointer.Int32(lookout.JobRunFailedOrdinal), + SchedulerTerminationReason: nil, + }} + err = ldb.UpdateJobRunsBatch(armadacontext.Background(), executorUpdate) + assert.Nil(t, err) + + // scheduler termination reason must be unchanged + run = getJobRun(t, db, RunId) + assert.Equal(t, instructions.BuildTerminationReason(testfixtures.PreemptionReason, nil), run.SchedulerTerminationReason) + return nil + }) + assert.NoError(t, err) +} + func TestConflateJobUpdates(t *testing.T) { // Empty updates := conflateJobUpdates([]*model.UpdateJobInstruction{}) @@ -1098,10 +1142,12 @@ func getJobRun(t *testing.T, db *pgxpool.Pool, runId string) JobRunRow { debug, ingress_addresses, failure_category, - failure_subcategory + failure_subcategory, + scheduler_termination_reason FROM job_run WHERE run_id = $1`, runId) var ingressJSON []byte + var schedulerTerminationReasonJSON []byte err := r.Scan( &run.RunId, &run.JobId, @@ -1117,12 +1163,17 @@ func getJobRun(t *testing.T, db *pgxpool.Pool, runId string) JobRunRow { &ingressJSON, &run.FailureCategory, &run.FailureSubcategory, + &schedulerTerminationReasonJSON, ) assert.NoError(t, err) if len(ingressJSON) > 0 { err = json.Unmarshal(ingressJSON, &run.IngressAddresses) assert.NoError(t, err) } + if len(schedulerTerminationReasonJSON) > 0 { + err = json.Unmarshal(schedulerTerminationReasonJSON, &run.SchedulerTerminationReason) + assert.NoError(t, err) + } return run } From 268041c92dfc08da4d68ca7700ef22e2164502fa Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:44 -0500 Subject: [PATCH 10/16] fix: add getJobRunSchedulerTerminationReason API endpoint Signed-off-by: William Vega --- internal/lookout/application.go | 14 ++ internal/lookout/gen/restapi/embedded_spec.go | 114 ++++++++++++ ...et_job_run_scheduler_termination_reason.go | 155 +++++++++++++++++ ...scheduler_termination_reason_parameters.go | 84 +++++++++ ..._scheduler_termination_reason_responses.go | 163 ++++++++++++++++++ ...scheduler_termination_reason_urlbuilder.go | 84 +++++++++ .../gen/restapi/operations/lookout_api.go | 15 ++ .../getjobrunschedulerterminationreason.go | 36 ++++ internal/lookout/swagger.yaml | 38 ++++ 9 files changed, 703 insertions(+) create mode 100644 internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason.go create mode 100644 internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_parameters.go create mode 100644 internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_responses.go create mode 100644 internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_urlbuilder.go create mode 100644 internal/lookout/repository/getjobrunschedulerterminationreason.go diff --git a/internal/lookout/application.go b/internal/lookout/application.go index ae649c00165..1f9ee40ca3d 100644 --- a/internal/lookout/application.go +++ b/internal/lookout/application.go @@ -47,6 +47,7 @@ func Serve(configuration configuration.LookoutConfig) error { getJobRunErrorRepo := repository.NewSqlGetJobRunErrorRepository(db, decompressor) getJobRunDebugMessageRepo := repository.NewSqlGetJobRunDebugMessageRepository(db, decompressor) getJobSpecRepo := repository.NewSqlGetJobSpecRepository(db, decompressor) + getJobRunSchedulerTerminationReasonRepo := repository.NewSqlGetJobRunSchedulerTerminationReasonRepository(db) // create new service API api := operations.NewLookoutAPI(swaggerSpec) @@ -131,6 +132,19 @@ func Serve(configuration configuration.LookoutConfig) error { }, ) + api.GetJobRunSchedulerTerminationReasonHandler = operations.GetJobRunSchedulerTerminationReasonHandlerFunc( + func(params operations.GetJobRunSchedulerTerminationReasonParams) middleware.Responder { + ctx := armadacontext.New(params.HTTPRequest.Context(), logger) + result, err := getJobRunSchedulerTerminationReasonRepo.GetJobRunSchedulerTerminationReason(ctx, params.GetJobRunSchedulerTerminationReasonRequest.RunID) + if err != nil { + return operations.NewGetJobRunSchedulerTerminationReasonBadRequest().WithPayload(conversions.ToSwaggerError(err.Error())) + } + return operations.NewGetJobRunSchedulerTerminationReasonOK().WithPayload(&operations.GetJobRunSchedulerTerminationReasonOKBody{ + SchedulerTerminationReason: result, + }) + }, + ) + api.GetJobErrorHandler = operations.GetJobErrorHandlerFunc( func(params operations.GetJobErrorParams) middleware.Responder { ctx := armadacontext.New(params.HTTPRequest.Context(), logger) diff --git a/internal/lookout/gen/restapi/embedded_spec.go b/internal/lookout/gen/restapi/embedded_spec.go index 44bd54b0ea1..ab12ce543c3 100644 --- a/internal/lookout/gen/restapi/embedded_spec.go +++ b/internal/lookout/gen/restapi/embedded_spec.go @@ -323,6 +323,63 @@ func init() { } } }, + "/api/v1/jobRunSchedulerTerminationReason": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "operationId": "getJobRunSchedulerTerminationReason", + "parameters": [ + { + "name": "getJobRunSchedulerTerminationReasonRequest", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "runId" + ], + "properties": { + "runId": { + "type": "string", + "x-nullable": false + } + } + } + } + ], + "responses": { + "200": { + "description": "Returns scheduler termination reason for specific job run (if present)", + "schema": { + "type": "object", + "properties": { + "schedulerTerminationReason": { + "description": "Scheduler termination reason for individual job run", + "type": "string", + "x-nullable": false + } + } + } + }, + "400": { + "description": "Error response", + "schema": { + "$ref": "#/definitions/error" + } + }, + "default": { + "description": "Error response", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/api/v1/jobSpec": { "post": { "consumes": [ @@ -1158,6 +1215,63 @@ func init() { } } }, + "/api/v1/jobRunSchedulerTerminationReason": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "operationId": "getJobRunSchedulerTerminationReason", + "parameters": [ + { + "name": "getJobRunSchedulerTerminationReasonRequest", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "runId" + ], + "properties": { + "runId": { + "type": "string", + "x-nullable": false + } + } + } + } + ], + "responses": { + "200": { + "description": "Returns scheduler termination reason for specific job run (if present)", + "schema": { + "type": "object", + "properties": { + "schedulerTerminationReason": { + "description": "Scheduler termination reason for individual job run", + "type": "string", + "x-nullable": false + } + } + } + }, + "400": { + "description": "Error response", + "schema": { + "$ref": "#/definitions/error" + } + }, + "default": { + "description": "Error response", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/api/v1/jobSpec": { "post": { "consumes": [ diff --git a/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason.go b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason.go new file mode 100644 index 00000000000..4207b8883a4 --- /dev/null +++ b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason.go @@ -0,0 +1,155 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "context" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// GetJobRunSchedulerTerminationReasonHandlerFunc turns a function with the right signature into a get job run scheduler termination reason handler +type GetJobRunSchedulerTerminationReasonHandlerFunc func(GetJobRunSchedulerTerminationReasonParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetJobRunSchedulerTerminationReasonHandlerFunc) Handle(params GetJobRunSchedulerTerminationReasonParams) middleware.Responder { + return fn(params) +} + +// GetJobRunSchedulerTerminationReasonHandler interface for that can handle valid get job run scheduler termination reason params +type GetJobRunSchedulerTerminationReasonHandler interface { + Handle(GetJobRunSchedulerTerminationReasonParams) middleware.Responder +} + +// NewGetJobRunSchedulerTerminationReason creates a new http.Handler for the get job run scheduler termination reason operation +func NewGetJobRunSchedulerTerminationReason(ctx *middleware.Context, handler GetJobRunSchedulerTerminationReasonHandler) *GetJobRunSchedulerTerminationReason { + return &GetJobRunSchedulerTerminationReason{Context: ctx, Handler: handler} +} + +/* + GetJobRunSchedulerTerminationReason swagger:route POST /api/v1/jobRunSchedulerTerminationReason getJobRunSchedulerTerminationReason + +GetJobRunSchedulerTerminationReason get job run scheduler termination reason API +*/ +type GetJobRunSchedulerTerminationReason struct { + Context *middleware.Context + Handler GetJobRunSchedulerTerminationReasonHandler +} + +func (o *GetJobRunSchedulerTerminationReason) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewGetJobRunSchedulerTerminationReasonParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} + +// GetJobRunSchedulerTerminationReasonBody get job run scheduler termination reason body +// +// swagger:model GetJobRunSchedulerTerminationReasonBody +type GetJobRunSchedulerTerminationReasonBody struct { + + // run Id + // Required: true + RunID string `json:"runId"` +} + +// Validate validates this get job run scheduler termination reason body +func (o *GetJobRunSchedulerTerminationReasonBody) Validate(formats strfmt.Registry) error { + var res []error + + if err := o.validateRunID(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (o *GetJobRunSchedulerTerminationReasonBody) validateRunID(formats strfmt.Registry) error { + + if err := validate.RequiredString("getJobRunSchedulerTerminationReasonRequest"+"."+"runId", "body", o.RunID); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this get job run scheduler termination reason body based on context it is used +func (o *GetJobRunSchedulerTerminationReasonBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *GetJobRunSchedulerTerminationReasonBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetJobRunSchedulerTerminationReasonBody) UnmarshalBinary(b []byte) error { + var res GetJobRunSchedulerTerminationReasonBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} + +// GetJobRunSchedulerTerminationReasonOKBody get job run scheduler termination reason o k body +// +// swagger:model GetJobRunSchedulerTerminationReasonOKBody +type GetJobRunSchedulerTerminationReasonOKBody struct { + + // Scheduler termination reason for individual job run + SchedulerTerminationReason string `json:"schedulerTerminationReason,omitempty"` +} + +// Validate validates this get job run scheduler termination reason o k body +func (o *GetJobRunSchedulerTerminationReasonOKBody) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this get job run scheduler termination reason o k body based on context it is used +func (o *GetJobRunSchedulerTerminationReasonOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (o *GetJobRunSchedulerTerminationReasonOKBody) MarshalBinary() ([]byte, error) { + if o == nil { + return nil, nil + } + return swag.WriteJSON(o) +} + +// UnmarshalBinary interface implementation +func (o *GetJobRunSchedulerTerminationReasonOKBody) UnmarshalBinary(b []byte) error { + var res GetJobRunSchedulerTerminationReasonOKBody + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *o = res + return nil +} diff --git a/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_parameters.go b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_parameters.go new file mode 100644 index 00000000000..090c053c523 --- /dev/null +++ b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_parameters.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + stderrors "errors" + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/validate" +) + +// NewGetJobRunSchedulerTerminationReasonParams creates a new GetJobRunSchedulerTerminationReasonParams object +// +// There are no default values defined in the spec. +func NewGetJobRunSchedulerTerminationReasonParams() GetJobRunSchedulerTerminationReasonParams { + + return GetJobRunSchedulerTerminationReasonParams{} +} + +// GetJobRunSchedulerTerminationReasonParams contains all the bound params for the get job run scheduler termination reason operation +// typically these are obtained from a http.Request +// +// swagger:parameters getJobRunSchedulerTerminationReason +type GetJobRunSchedulerTerminationReasonParams struct { + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: body + */ + GetJobRunSchedulerTerminationReasonRequest GetJobRunSchedulerTerminationReasonBody +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetJobRunSchedulerTerminationReasonParams() beforehand. +func (o *GetJobRunSchedulerTerminationReasonParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer func() { + _ = r.Body.Close() + }() + var body GetJobRunSchedulerTerminationReasonBody + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if stderrors.Is(err, io.EOF) { + res = append(res, errors.Required("getJobRunSchedulerTerminationReasonRequest", "body", "")) + } else { + res = append(res, errors.NewParseError("getJobRunSchedulerTerminationReasonRequest", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + ctx := validate.WithOperationRequest(r.Context()) + if err := body.ContextValidate(ctx, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.GetJobRunSchedulerTerminationReasonRequest = body + } + } + } else { + res = append(res, errors.Required("getJobRunSchedulerTerminationReasonRequest", "body", "")) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_responses.go b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_responses.go new file mode 100644 index 00000000000..f7eebdb11b9 --- /dev/null +++ b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_responses.go @@ -0,0 +1,163 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/armadaproject/armada/internal/lookout/gen/models" +) + +// GetJobRunSchedulerTerminationReasonOKCode is the HTTP code returned for type GetJobRunSchedulerTerminationReasonOK +const GetJobRunSchedulerTerminationReasonOKCode int = 200 + +/* +GetJobRunSchedulerTerminationReasonOK Returns scheduler termination reason for specific job run (if present) + +swagger:response getJobRunSchedulerTerminationReasonOK +*/ +type GetJobRunSchedulerTerminationReasonOK struct { + + /* + In: Body + */ + Payload *GetJobRunSchedulerTerminationReasonOKBody `json:"body,omitempty"` +} + +// NewGetJobRunSchedulerTerminationReasonOK creates GetJobRunSchedulerTerminationReasonOK with default headers values +func NewGetJobRunSchedulerTerminationReasonOK() *GetJobRunSchedulerTerminationReasonOK { + + return &GetJobRunSchedulerTerminationReasonOK{} +} + +// WithPayload adds the payload to the get job run scheduler termination reason o k response +func (o *GetJobRunSchedulerTerminationReasonOK) WithPayload(payload *GetJobRunSchedulerTerminationReasonOKBody) *GetJobRunSchedulerTerminationReasonOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get job run scheduler termination reason o k response +func (o *GetJobRunSchedulerTerminationReasonOK) SetPayload(payload *GetJobRunSchedulerTerminationReasonOKBody) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetJobRunSchedulerTerminationReasonOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +// GetJobRunSchedulerTerminationReasonBadRequestCode is the HTTP code returned for type GetJobRunSchedulerTerminationReasonBadRequest +const GetJobRunSchedulerTerminationReasonBadRequestCode int = 400 + +/* +GetJobRunSchedulerTerminationReasonBadRequest Error response + +swagger:response getJobRunSchedulerTerminationReasonBadRequest +*/ +type GetJobRunSchedulerTerminationReasonBadRequest struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetJobRunSchedulerTerminationReasonBadRequest creates GetJobRunSchedulerTerminationReasonBadRequest with default headers values +func NewGetJobRunSchedulerTerminationReasonBadRequest() *GetJobRunSchedulerTerminationReasonBadRequest { + + return &GetJobRunSchedulerTerminationReasonBadRequest{} +} + +// WithPayload adds the payload to the get job run scheduler termination reason bad request response +func (o *GetJobRunSchedulerTerminationReasonBadRequest) WithPayload(payload *models.Error) *GetJobRunSchedulerTerminationReasonBadRequest { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get job run scheduler termination reason bad request response +func (o *GetJobRunSchedulerTerminationReasonBadRequest) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetJobRunSchedulerTerminationReasonBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(400) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +/* +GetJobRunSchedulerTerminationReasonDefault Error response + +swagger:response getJobRunSchedulerTerminationReasonDefault +*/ +type GetJobRunSchedulerTerminationReasonDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetJobRunSchedulerTerminationReasonDefault creates GetJobRunSchedulerTerminationReasonDefault with default headers values +func NewGetJobRunSchedulerTerminationReasonDefault(code int) *GetJobRunSchedulerTerminationReasonDefault { + if code <= 0 { + code = 500 + } + + return &GetJobRunSchedulerTerminationReasonDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the get job run scheduler termination reason default response +func (o *GetJobRunSchedulerTerminationReasonDefault) WithStatusCode(code int) *GetJobRunSchedulerTerminationReasonDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the get job run scheduler termination reason default response +func (o *GetJobRunSchedulerTerminationReasonDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the get job run scheduler termination reason default response +func (o *GetJobRunSchedulerTerminationReasonDefault) WithPayload(payload *models.Error) *GetJobRunSchedulerTerminationReasonDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get job run scheduler termination reason default response +func (o *GetJobRunSchedulerTerminationReasonDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetJobRunSchedulerTerminationReasonDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_urlbuilder.go new file mode 100644 index 00000000000..80f36efe4d1 --- /dev/null +++ b/internal/lookout/gen/restapi/operations/get_job_run_scheduler_termination_reason_urlbuilder.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// GetJobRunSchedulerTerminationReasonURL generates an URL for the get job run scheduler termination reason operation +type GetJobRunSchedulerTerminationReasonURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetJobRunSchedulerTerminationReasonURL) WithBasePath(bp string) *GetJobRunSchedulerTerminationReasonURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetJobRunSchedulerTerminationReasonURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetJobRunSchedulerTerminationReasonURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/api/v1/jobRunSchedulerTerminationReason" + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetJobRunSchedulerTerminationReasonURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetJobRunSchedulerTerminationReasonURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetJobRunSchedulerTerminationReasonURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetJobRunSchedulerTerminationReasonURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetJobRunSchedulerTerminationReasonURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetJobRunSchedulerTerminationReasonURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/internal/lookout/gen/restapi/operations/lookout_api.go b/internal/lookout/gen/restapi/operations/lookout_api.go index cfe6b3aa00f..19eb83417e5 100644 --- a/internal/lookout/gen/restapi/operations/lookout_api.go +++ b/internal/lookout/gen/restapi/operations/lookout_api.go @@ -67,6 +67,12 @@ func NewLookoutAPI(spec *loads.Document) *LookoutAPI { return middleware.NotImplemented("operation GetJobRunError has not yet been implemented") }), + GetJobRunSchedulerTerminationReasonHandler: GetJobRunSchedulerTerminationReasonHandlerFunc(func(params GetJobRunSchedulerTerminationReasonParams) middleware.Responder { + _ = params + + return middleware.NotImplemented("operation GetJobRunSchedulerTerminationReason has not yet been implemented") + }), + GetJobSpecHandler: GetJobSpecHandlerFunc(func(params GetJobSpecParams) middleware.Responder { _ = params @@ -131,6 +137,8 @@ type LookoutAPI struct { GetJobRunDebugMessageHandler GetJobRunDebugMessageHandler // GetJobRunErrorHandler sets the operation handler for the get job run error operation GetJobRunErrorHandler GetJobRunErrorHandler + // GetJobRunSchedulerTerminationReasonHandler sets the operation handler for the get job run scheduler termination reason operation + GetJobRunSchedulerTerminationReasonHandler GetJobRunSchedulerTerminationReasonHandler // GetJobSpecHandler sets the operation handler for the get job spec operation GetJobSpecHandler GetJobSpecHandler // GetJobsHandler sets the operation handler for the get jobs operation @@ -229,6 +237,9 @@ func (o *LookoutAPI) Validate() error { if o.GetJobRunErrorHandler == nil { unregistered = append(unregistered, "GetJobRunErrorHandler") } + if o.GetJobRunSchedulerTerminationReasonHandler == nil { + unregistered = append(unregistered, "GetJobRunSchedulerTerminationReasonHandler") + } if o.GetJobSpecHandler == nil { unregistered = append(unregistered, "GetJobSpecHandler") } @@ -350,6 +361,10 @@ func (o *LookoutAPI) initHandlerCache() { if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } + o.handlers["POST"]["/api/v1/jobRunSchedulerTerminationReason"] = NewGetJobRunSchedulerTerminationReason(o.context, o.GetJobRunSchedulerTerminationReasonHandler) + if o.handlers["POST"] == nil { + o.handlers["POST"] = make(map[string]http.Handler) + } o.handlers["POST"]["/api/v1/jobSpec"] = NewGetJobSpec(o.context, o.GetJobSpecHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) diff --git a/internal/lookout/repository/getjobrunschedulerterminationreason.go b/internal/lookout/repository/getjobrunschedulerterminationreason.go new file mode 100644 index 00000000000..80624c59134 --- /dev/null +++ b/internal/lookout/repository/getjobrunschedulerterminationreason.go @@ -0,0 +1,36 @@ +package repository + +import ( + "errors" + "fmt" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" + + "github.com/armadaproject/armada/internal/common/armadacontext" +) + +type GetJobRunSchedulerTerminationReasonRepository interface { + GetJobRunSchedulerTerminationReason(ctx *armadacontext.Context, runId string) (string, error) +} + +type SqlGetJobRunSchedulerTerminationReasonRepository struct { + db *pgxpool.Pool +} + +func NewSqlGetJobRunSchedulerTerminationReasonRepository(db *pgxpool.Pool) *SqlGetJobRunSchedulerTerminationReasonRepository { + return &SqlGetJobRunSchedulerTerminationReasonRepository{db: db} +} + +func (r *SqlGetJobRunSchedulerTerminationReasonRepository) GetJobRunSchedulerTerminationReason(ctx *armadacontext.Context, runId string) (string, error) { + var result string + err := r.db.QueryRow(ctx, "SELECT scheduler_termination_reason FROM job_run WHERE run_id = $1 AND scheduler_termination_reason IS NOT NULL", + runId).Scan(&result) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return "", fmt.Errorf("no scheduler termination reason found for run with id %s: %w", runId, ErrNotFound) + } + return "", err + } + return result, nil +} diff --git a/internal/lookout/swagger.yaml b/internal/lookout/swagger.yaml index 7f8584c7604..48f241b7d5b 100644 --- a/internal/lookout/swagger.yaml +++ b/internal/lookout/swagger.yaml @@ -600,3 +600,41 @@ paths: description: Error response schema: $ref: "#/definitions/error" + + /api/v1/jobRunSchedulerTerminationReason: + post: + operationId: getJobRunSchedulerTerminationReason + consumes: + - application/json + parameters: + - name: getJobRunSchedulerTerminationReasonRequest + required: true + in: body + schema: + type: object + required: + - runId + properties: + runId: + type: string + x-nullable: false + produces: + - application/json + responses: + 200: + description: Returns scheduler termination reason for specific job run (if present) + schema: + type: object + properties: + schedulerTerminationReason: + type: string + description: Scheduler termination reason for individual job run + x-nullable: false + 400: + description: Error response + schema: + $ref: "#/definitions/error" + default: + description: Error response + schema: + $ref: "#/definitions/error" \ No newline at end of file From 9412096f8ef1f37d8f16ec39e228652301f49e17 Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 12 May 2026 15:26:48 -0500 Subject: [PATCH 11/16] feat: lookoutui display scheduler termination reason in job run details Signed-off-by: William Vega --- .../jobs/components/sidebar/JobRunDetails.tsx | 33 ++++++++++ .../useGetJobRunSchedulerTerminationReason.ts | 62 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts diff --git a/internal/lookoutui/src/pages/jobs/components/sidebar/JobRunDetails.tsx b/internal/lookoutui/src/pages/jobs/components/sidebar/JobRunDetails.tsx index bedf52612a1..cbf109ec079 100644 --- a/internal/lookoutui/src/pages/jobs/components/sidebar/JobRunDetails.tsx +++ b/internal/lookoutui/src/pages/jobs/components/sidebar/JobRunDetails.tsx @@ -28,6 +28,7 @@ import { JobRun } from "../../../../models/lookoutModels" import { useCordonNode } from "../../../../services/lookout/useCordonNode" import { useGetJobRunDebugMessage } from "../../../../services/lookout/useGetJobRunDebugMessage" import { useGetJobRunError } from "../../../../services/lookout/useGetJobRunError" +import { useGetJobRunSchedulerTerminationReason } from "../../../../services/lookout/useGetJobRunSchedulerTerminationReason" import { KeyValuePairTable } from "./KeyValuePairTable" import { SidebarTabSubheading } from "./sidebarTabContentComponents" @@ -182,6 +183,17 @@ export const JobRunDetails = ({ // Ignore any errors from this call - the API returns an error if there is no debug message, which is happy-path const { data: debugMessage, status: debugMessageStatus } = useGetJobRunDebugMessage(runId) + // Ignore any errors from this call - the API returns an error if there is no scheduler termination reason, which is happy-path + const { data: schedulerTerminationReason, status: schedulerTerminationReasonStatus } = + useGetJobRunSchedulerTerminationReason(runId) + const prettyTerminationReason = useMemo(() => { + try { + return JSON.stringify(JSON.parse(schedulerTerminationReason ?? ""), undefined, 2) + } catch { + return schedulerTerminationReason ?? "" + } + }, [schedulerTerminationReason]) + const headingTextParts = ["Run", (runIndex + 1).toString()] const runIndicativeTimestamp = started || pending || leased || "" if (runIndicativeTimestamp) { @@ -325,6 +337,27 @@ export const JobRunDetails = ({ )} + {schedulerTerminationReasonStatus === "pending" && ( + + + + + + )} + {schedulerTerminationReasonStatus === "success" && schedulerTerminationReason && ( + + Scheduler Termination Reason + + + + + )} diff --git a/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts b/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts new file mode 100644 index 00000000000..3a095e55445 --- /dev/null +++ b/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts @@ -0,0 +1,62 @@ +import { useMemo } from "react" + +import { QueryFunction, QueryKey, useQueries, useQuery } from "@tanstack/react-query" + +import { getErrorMessage } from "../../common/utils" +import { getConfig } from "../../config" +import { useAuthenticatedFetch } from "../../oidcAuth" + +const getQueryFn = + (runId: string, fetchFunc: GlobalFetch["fetch"], fakeDataEnabled: boolean): QueryFunction => + async ({ signal }) => { + try { + if (fakeDataEnabled) { + return "" + } + + const response = await fetchFunc("/api/v1/jobRunSchedulerTerminationReason", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ runId }), + signal, + }) + + const json = await response.json() + return json.schedulerTerminationReason ?? "" + } catch (e) { + throw await getErrorMessage(e) + } + } + +export const useGetJobRunSchedulerTerminationReason = (runId: string, enabled = true) => { + const config = getConfig() + const authenticatedFetch = useAuthenticatedFetch() + + const queryFn = useMemo( + () => getQueryFn(runId, authenticatedFetch, config.fakeDataEnabled), + [runId, authenticatedFetch, config.fakeDataEnabled], + ) + + return useQuery({ + queryKey: ["getJobRunSchedulerTerminationReason", runId], + queryFn, + enabled, + refetchOnMount: false, + staleTime: 30_000, + }) +} + +export const useBatchGetJobRunSchedulerTerminationReasons = (runIds: string[], enabled = true) => { + const config = getConfig() + const authenticatedFetch = useAuthenticatedFetch() + + return useQueries({ + queries: runIds.map((runId) => ({ + queryKey: ["getJobRunSchedulerTerminationReason", runId], + queryFn: getQueryFn(runId, authenticatedFetch, config.fakeDataEnabled), + enabled, + refetchOnMount: false, + staleTime: 30_000, + })), + }) +} From e5447ce109498ccc8838480897c414bcb551db68 Mon Sep 17 00:00:00 2001 From: William Vega Date: Wed, 13 May 2026 16:14:17 -0500 Subject: [PATCH 12/16] fix: refactoring Signed-off-by: William Vega --- client/rust/src/gen/api.rs | 2 +- internal/common/ingest/testfixtures/event.go | 2 +- .../034_add_scheduler_termination_reason.sql | 2 +- .../instructions/instructions.go | 4 +- .../useGetJobRunSchedulerTerminationReason.ts | 17 +- internal/scheduler/scheduler.go | 4 +- internal/scheduler/scheduler_test.go | 40 ++- .../server/event/conversion/conversions.go | 2 +- .../event/conversion/conversions_test.go | 6 +- internal/server/queryapi/database/models.go | 33 +- .../server/queryapi/database/query.sql.go | 6 +- pkg/api/api.swagger.go | 2 +- pkg/api/api.swagger.json | 2 +- pkg/api/event.pb.go | 312 +++++++++--------- pkg/api/event.proto | 2 +- pkg/armadaevents/events.pb.go | 24 +- pkg/armadaevents/events.proto | 2 +- 17 files changed, 243 insertions(+), 219 deletions(-) diff --git a/client/rust/src/gen/api.rs b/client/rust/src/gen/api.rs index 63a99a34787..e240f1f9031 100644 --- a/client/rust/src/gen/api.rs +++ b/client/rust/src/gen/api.rs @@ -1499,7 +1499,7 @@ pub struct JobPreemptedEvent { #[prost(string, tag = "6")] pub run_id: ::prost::alloc::string::String, #[prost(string, tag = "7")] - pub preemptive_job_id: ::prost::alloc::string::String, + pub preempting_job_id: ::prost::alloc::string::String, #[prost(string, tag = "8")] pub preemptive_run_id: ::prost::alloc::string::String, #[prost(string, tag = "9")] diff --git a/internal/common/ingest/testfixtures/event.go b/internal/common/ingest/testfixtures/event.go index 0e6e2eef731..cd290658870 100644 --- a/internal/common/ingest/testfixtures/event.go +++ b/internal/common/ingest/testfixtures/event.go @@ -476,7 +476,7 @@ var JobRunPreemptedFairShare = &armadaevents.EventSequence_Event{ JobRunPreempted: &armadaevents.JobRunPreempted{ PreemptedJobId: JobId, PreemptedRunId: RunId, - PreemptiveJobId: PreemptingJobId, + PreemptingJobId: PreemptingJobId, Reason: PreemptionReason, }, }, diff --git a/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql b/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql index 5806a876f85..8d0869125eb 100644 --- a/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql +++ b/internal/lookout/schema/migrations/034_add_scheduler_termination_reason.sql @@ -1 +1 @@ -ALTER TABLE job_run ADD COLUMN scheduler_termination_reason JSONB; \ No newline at end of file +ALTER TABLE job_run ADD COLUMN scheduler_termination_reason JSONB; diff --git a/internal/lookoutingester/instructions/instructions.go b/internal/lookoutingester/instructions/instructions.go index a1da2fd086c..ce01a26afb6 100644 --- a/internal/lookoutingester/instructions/instructions.go +++ b/internal/lookoutingester/instructions/instructions.go @@ -477,8 +477,8 @@ func (c *InstructionConverter) handleJobRunErrors(ts time.Time, event *armadaeve func (c *InstructionConverter) handleJobRunPreempted(ts time.Time, event *armadaevents.JobRunPreempted, update *model.InstructionSet) error { terminationReasonArgs := map[string]any{} - if event.PreemptiveJobId != "" { - terminationReasonArgs["preemptingJobId"] = event.PreemptiveJobId + if event.PreemptingJobId != "" { + terminationReasonArgs["preemptingJobId"] = event.PreemptingJobId } jobRun := model.UpdateJobRunInstruction{ RunId: event.PreemptedRunId, diff --git a/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts b/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts index 3a095e55445..e9be3308ffb 100644 --- a/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts +++ b/internal/lookoutui/src/services/lookout/useGetJobRunSchedulerTerminationReason.ts @@ -1,6 +1,6 @@ import { useMemo } from "react" -import { QueryFunction, QueryKey, useQueries, useQuery } from "@tanstack/react-query" +import { QueryFunction, QueryKey, useQuery } from "@tanstack/react-query" import { getErrorMessage } from "../../common/utils" import { getConfig } from "../../config" @@ -45,18 +45,3 @@ export const useGetJobRunSchedulerTerminationReason = (runId: string, enabled = staleTime: 30_000, }) } - -export const useBatchGetJobRunSchedulerTerminationReasons = (runIds: string[], enabled = true) => { - const config = getConfig() - const authenticatedFetch = useAuthenticatedFetch() - - return useQueries({ - queries: runIds.map((runId) => ({ - queryKey: ["getJobRunSchedulerTerminationReason", runId], - queryFn: getQueryFn(runId, authenticatedFetch, config.fakeDataEnabled), - enabled, - refetchOnMount: false, - staleTime: 30_000, - })), - }) -} diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index 31f28d30f6e..2e2e120f20a 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -681,7 +681,7 @@ func preemptingJobId(preemptingJob *jobdb.Job) string { return preemptingJob.Id() } -func createEventsForPreemptedJob(jobId string, runId string, preemptiveJobId string, reason string, time time.Time) []*armadaevents.EventSequence_Event { +func createEventsForPreemptedJob(jobId string, runId string, preemptingJobId string, reason string, time time.Time) []*armadaevents.EventSequence_Event { return []*armadaevents.EventSequence_Event{ { Created: protoutil.ToTimestamp(time), @@ -690,7 +690,7 @@ func createEventsForPreemptedJob(jobId string, runId string, preemptiveJobId str PreemptedRunId: runId, PreemptedJobId: jobId, Reason: reason, - PreemptiveJobId: preemptiveJobId, + PreemptingJobId: preemptingJobId, }, }, }, diff --git a/internal/scheduler/scheduler_test.go b/internal/scheduler/scheduler_test.go index f591d88f2aa..a77240691c5 100644 --- a/internal/scheduler/scheduler_test.go +++ b/internal/scheduler/scheduler_test.go @@ -3547,7 +3547,7 @@ func TestPreemptingJobId(t *testing.T) { assert.Equal(t, job.Id(), preemptingJobId(job)) } -func TestAppendEventSequencesFromPreemptedJobs_PopulatesPreemptiveJobId(t *testing.T) { +func TestAppendEventSequencesFromPreemptedJobs_PopulatesPreemptingJobId(t *testing.T) { preemptingJob := testfixtures.NewJob( util.NewULID(), "testJobset", @@ -3596,5 +3596,41 @@ func TestAppendEventSequencesFromPreemptedJobs_PopulatesPreemptiveJobId(t *testi preemptedEvent := events[0].GetJobRunPreempted() assert.NotNil(t, preemptedEvent) assert.Equal(t, preemptedRun.Id(), preemptedEvent.PreemptedRunId) - assert.Equal(t, preemptingJobId, preemptedEvent.PreemptiveJobId) + assert.Equal(t, preemptingJobId, preemptedEvent.PreemptingJobId) +} + +func TestAppendEventSequencesFromPreemptedJobs_NilPreemptingJob(t *testing.T) { + preemptedJob := testfixtures.NewJob( + util.NewULID(), + "testJobset", + "testQueue", + 0, + toInternalSchedulingInfo(preemptibleGangSchedulingInfo), + false, + 1, + false, + false, + false, + 1, + true, + ).WithNewRun("testExecutor", "test-node", "node", "pool", 5) + preemptedRun := preemptedJob.LatestRun() + + jctx := &schedulercontext.JobSchedulingContext{ + Job: preemptedJob, + PreemptingJob: nil, + PreemptionDescription: "preempted due to node resource change", + } + + sequences, err := AppendEventSequencesFromPreemptedJobs(nil, []*schedulercontext.JobSchedulingContext{jctx}, time.Now()) + assert.NoError(t, err) + assert.Len(t, sequences, 1) + + events := sequences[0].Events + assert.Len(t, events, 3) // JobRunPreempted + JobRunErrors + JobErrors + + preemptedEvent := events[0].GetJobRunPreempted() + assert.NotNil(t, preemptedEvent) + assert.Equal(t, preemptedRun.Id(), preemptedEvent.PreemptedRunId) + assert.Equal(t, "", preemptedEvent.PreemptingJobId) } diff --git a/internal/server/event/conversion/conversions.go b/internal/server/event/conversion/conversions.go index a6c2c1a83af..de52e660cfb 100644 --- a/internal/server/event/conversion/conversions.go +++ b/internal/server/event/conversion/conversions.go @@ -446,7 +446,7 @@ func FromInternalJobRunPreempted(queueName string, jobSetName string, time time. Created: protoutil.ToTimestamp(time), RunId: e.PreemptedRunId, Reason: e.Reason, - PreemptiveJobId: e.PreemptiveJobId, + PreemptingJobId: e.PreemptingJobId, } return []*api.EventMessage{ diff --git a/internal/server/event/conversion/conversions_test.go b/internal/server/event/conversion/conversions_test.go index 5122ece005e..cb9103c4de1 100644 --- a/internal/server/event/conversion/conversions_test.go +++ b/internal/server/event/conversion/conversions_test.go @@ -872,7 +872,7 @@ func TestConvertJobPreemptionRequested(t *testing.T) { } func TestConvertJobRunPreempted(t *testing.T) { - preemptiveJobId := "456e7890-e89b-12d3-a456-426614174001" + preemptingJobId := "456e7890-e89b-12d3-a456-426614174001" preempted := &armadaevents.EventSequence_Event{ Created: baseTimeProto, @@ -880,7 +880,7 @@ func TestConvertJobRunPreempted(t *testing.T) { JobRunPreempted: &armadaevents.JobRunPreempted{ PreemptedJobId: jobId, PreemptedRunId: runId, - PreemptiveJobId: preemptiveJobId, + PreemptingJobId: preemptingJobId, Reason: "Preempted reason", }, }, @@ -896,7 +896,7 @@ func TestConvertJobRunPreempted(t *testing.T) { Created: protoutil.ToTimestamp(baseTime), RunId: runId, Reason: "Preempted reason", - PreemptiveJobId: preemptiveJobId, + PreemptingJobId: preemptingJobId, }, }, }, diff --git a/internal/server/queryapi/database/models.go b/internal/server/queryapi/database/models.go index 9aca2755812..69ea05982e3 100644 --- a/internal/server/queryapi/database/models.go +++ b/internal/server/queryapi/database/models.go @@ -46,22 +46,23 @@ type JobError struct { } type JobRun struct { - RunID string `db:"run_id"` - JobID string `db:"job_id"` - Cluster string `db:"cluster"` - Node *string `db:"node"` - Pending pgtype.Timestamp `db:"pending"` - Started pgtype.Timestamp `db:"started"` - Finished pgtype.Timestamp `db:"finished"` - JobRunState int16 `db:"job_run_state"` - Error []byte `db:"error"` - ExitCode *int32 `db:"exit_code"` - Leased pgtype.Timestamp `db:"leased"` - Debug []byte `db:"debug"` - Pool *string `db:"pool"` - IngressAddresses []byte `db:"ingress_addresses"` - FailureCategory *string `db:"failure_category"` - FailureSubcategory *string `db:"failure_subcategory"` + RunID string `db:"run_id"` + JobID string `db:"job_id"` + Cluster string `db:"cluster"` + Node *string `db:"node"` + Pending pgtype.Timestamp `db:"pending"` + Started pgtype.Timestamp `db:"started"` + Finished pgtype.Timestamp `db:"finished"` + JobRunState int16 `db:"job_run_state"` + Error []byte `db:"error"` + ExitCode *int32 `db:"exit_code"` + Leased pgtype.Timestamp `db:"leased"` + Debug []byte `db:"debug"` + Pool *string `db:"pool"` + IngressAddresses []byte `db:"ingress_addresses"` + FailureCategory *string `db:"failure_category"` + FailureSubcategory *string `db:"failure_subcategory"` + SchedulerTerminationReason []byte `db:"scheduler_termination_reason"` } type JobSpec struct { diff --git a/internal/server/queryapi/database/query.sql.go b/internal/server/queryapi/database/query.sql.go index fd8d26da00e..d4e8a69429c 100644 --- a/internal/server/queryapi/database/query.sql.go +++ b/internal/server/queryapi/database/query.sql.go @@ -126,7 +126,7 @@ func (q *Queries) GetJobErrorsByJobIds(ctx context.Context, jobIds []string) ([] } const getJobRunsByJobIds = `-- name: GetJobRunsByJobIds :many -SELECT run_id, job_id, cluster, node, pending, started, finished, job_run_state, error, exit_code, leased, debug, pool, ingress_addresses, failure_category, failure_subcategory FROM job_run WHERE job_id = ANY($1::text[]) order by leased desc +SELECT run_id, job_id, cluster, node, pending, started, finished, job_run_state, error, exit_code, leased, debug, pool, ingress_addresses, failure_category, failure_subcategory, scheduler_termination_reason FROM job_run WHERE job_id = ANY($1::text[]) order by leased desc ` func (q *Queries) GetJobRunsByJobIds(ctx context.Context, jobIds []string) ([]JobRun, error) { @@ -155,6 +155,7 @@ func (q *Queries) GetJobRunsByJobIds(ctx context.Context, jobIds []string) ([]Jo &i.IngressAddresses, &i.FailureCategory, &i.FailureSubcategory, + &i.SchedulerTerminationReason, ); err != nil { return nil, err } @@ -167,7 +168,7 @@ func (q *Queries) GetJobRunsByJobIds(ctx context.Context, jobIds []string) ([]Jo } const getJobRunsByRunIds = `-- name: GetJobRunsByRunIds :many -SELECT run_id, job_id, cluster, node, pending, started, finished, job_run_state, error, exit_code, leased, debug, pool, ingress_addresses, failure_category, failure_subcategory FROM job_run WHERE run_id = ANY($1::text[]) +SELECT run_id, job_id, cluster, node, pending, started, finished, job_run_state, error, exit_code, leased, debug, pool, ingress_addresses, failure_category, failure_subcategory, scheduler_termination_reason FROM job_run WHERE run_id = ANY($1::text[]) ` func (q *Queries) GetJobRunsByRunIds(ctx context.Context, runIds []string) ([]JobRun, error) { @@ -196,6 +197,7 @@ func (q *Queries) GetJobRunsByRunIds(ctx context.Context, runIds []string) ([]Jo &i.IngressAddresses, &i.FailureCategory, &i.FailureSubcategory, + &i.SchedulerTerminationReason, ); err != nil { return nil, err } diff --git a/pkg/api/api.swagger.go b/pkg/api/api.swagger.go index 9cda2ebda25..888d283d4bb 100644 --- a/pkg/api/api.swagger.go +++ b/pkg/api/api.swagger.go @@ -1483,7 +1483,7 @@ func SwaggerJsonTemplate() string { " \"jobSetId\": {\n" + " \"type\": \"string\"\n" + " },\n" + - " \"preemptiveJobId\": {\n" + + " \"preemptingJobId\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"preemptiveRunId\": {\n" + diff --git a/pkg/api/api.swagger.json b/pkg/api/api.swagger.json index d47f797d833..0ec05f433bd 100644 --- a/pkg/api/api.swagger.json +++ b/pkg/api/api.swagger.json @@ -1472,7 +1472,7 @@ "jobSetId": { "type": "string" }, - "preemptiveJobId": { + "preemptingJobId": { "type": "string" }, "preemptiveRunId": { diff --git a/pkg/api/event.pb.go b/pkg/api/event.pb.go index 284dc453a0e..f0b1f34ee66 100644 --- a/pkg/api/event.pb.go +++ b/pkg/api/event.pb.go @@ -1089,7 +1089,7 @@ type JobPreemptedEvent struct { Created *types.Timestamp `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"` ClusterId string `protobuf:"bytes,5,opt,name=cluster_id,json=clusterId,proto3" json:"clusterId,omitempty"` RunId string `protobuf:"bytes,6,opt,name=run_id,json=runId,proto3" json:"runId,omitempty"` - PreemptiveJobId string `protobuf:"bytes,7,opt,name=preemptive_job_id,json=preemptiveJobId,proto3" json:"preemptiveJobId,omitempty"` + PreemptingJobId string `protobuf:"bytes,7,opt,name=preempting_job_id,json=preemptingJobId,proto3" json:"preemptingJobId,omitempty"` PreemptiveRunId string `protobuf:"bytes,8,opt,name=preemptive_run_id,json=preemptiveRunId,proto3" json:"preemptiveRunId,omitempty"` Reason string `protobuf:"bytes,9,opt,name=reason,proto3" json:"reason,omitempty"` } @@ -1169,9 +1169,9 @@ func (m *JobPreemptedEvent) GetRunId() string { return "" } -func (m *JobPreemptedEvent) GetPreemptiveJobId() string { +func (m *JobPreemptedEvent) GetPreemptingJobId() string { if m != nil { - return m.PreemptiveJobId + return m.PreemptingJobId } return "" } @@ -2479,156 +2479,156 @@ func init() { func init() { proto.RegisterFile("pkg/api/event.proto", fileDescriptor_7758595c3bb8cf56) } var fileDescriptor_7758595c3bb8cf56 = []byte{ - // 2373 bytes of a gzipped FileDescriptorProto + // 2375 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4d, 0x6c, 0x1b, 0xc7, - 0xf5, 0xf7, 0x52, 0xfc, 0x58, 0x0e, 0x25, 0x91, 0x1a, 0x7d, 0x98, 0xa6, 0x1d, 0x51, 0xa0, 0x81, - 0xfc, 0x15, 0x23, 0x26, 0xf3, 0x97, 0x93, 0x22, 0x30, 0x0a, 0x14, 0x96, 0xa2, 0xc4, 0x62, 0xe3, - 0xda, 0xa6, 0x1c, 0x24, 0x2d, 0x02, 0xb0, 0xcb, 0xdd, 0x11, 0xb5, 0x12, 0xb9, 0xb3, 0xd9, 0x0f, + 0xf5, 0xf7, 0x52, 0xfc, 0x58, 0x0e, 0x25, 0x91, 0x1a, 0x7d, 0x98, 0xa6, 0x1d, 0xad, 0x40, 0x03, + 0xf9, 0x2b, 0x46, 0x4c, 0xe6, 0x2f, 0x27, 0x45, 0x60, 0x14, 0x28, 0x2c, 0x45, 0x89, 0xc5, 0xc6, + 0xb5, 0x4d, 0x39, 0x48, 0x5a, 0x04, 0x60, 0x97, 0xbb, 0x23, 0x6a, 0x25, 0x72, 0x87, 0xd9, 0x0f, 0xd9, 0x8a, 0x91, 0x4b, 0x7b, 0xe9, 0xa1, 0x28, 0xfa, 0x81, 0xde, 0x8a, 0xb6, 0xe7, 0x1e, 0x7b, 0xe9, 0xad, 0xe8, 0xa9, 0x28, 0x7a, 0x0a, 0x9a, 0x4b, 0x4f, 0x44, 0x6b, 0x17, 0x29, 0x40, 0xf4, - 0xd0, 0x4b, 0xef, 0xc5, 0xbc, 0x99, 0x5d, 0xce, 0xac, 0x28, 0x48, 0x56, 0x3e, 0x6a, 0x28, 0x3c, - 0xd9, 0xfa, 0xbd, 0x79, 0x6f, 0xde, 0xbc, 0xf9, 0xcd, 0xcc, 0x9b, 0x7d, 0x43, 0x34, 0xef, 0xee, - 0x77, 0x1b, 0x86, 0x6b, 0x37, 0xc8, 0x01, 0x71, 0x82, 0xba, 0xeb, 0xd1, 0x80, 0xe2, 0x29, 0xc3, - 0xb5, 0x2b, 0xd5, 0x2e, 0xa5, 0xdd, 0x1e, 0x69, 0x00, 0xd4, 0x09, 0x77, 0x1a, 0x81, 0xdd, 0x27, - 0x7e, 0x60, 0xf4, 0x5d, 0xde, 0xaa, 0xb2, 0x10, 0xa9, 0xfa, 0x61, 0xa7, 0x6f, 0x07, 0x49, 0x74, - 0x97, 0x18, 0xbd, 0x60, 0x57, 0xa0, 0x97, 0x93, 0xc6, 0x48, 0xdf, 0x0d, 0x0e, 0x85, 0xf0, 0x8a, - 0x10, 0x32, 0x2d, 0xc3, 0x71, 0x68, 0x60, 0x04, 0x36, 0x75, 0x7c, 0x21, 0x7d, 0x75, 0xff, 0x75, - 0xbf, 0x6e, 0x53, 0x26, 0xed, 0x1b, 0xe6, 0xae, 0xed, 0x10, 0xef, 0xb0, 0x11, 0x75, 0xe2, 0x11, - 0x9f, 0x86, 0x9e, 0x49, 0x1a, 0x5d, 0xe2, 0x10, 0xcf, 0x08, 0x88, 0xc5, 0xb5, 0x6a, 0xbf, 0x48, - 0xa1, 0xb9, 0x26, 0xed, 0x6c, 0x83, 0x6b, 0x01, 0xb1, 0x36, 0xd9, 0xf0, 0xf0, 0x35, 0x94, 0xdd, - 0xa3, 0x9d, 0xb6, 0x6d, 0x95, 0xb5, 0x15, 0x6d, 0x35, 0xbf, 0x3e, 0x3f, 0x1c, 0x54, 0x8b, 0x7b, - 0xb4, 0xb3, 0x65, 0xbd, 0x4c, 0xfb, 0x76, 0x00, 0x4e, 0xb5, 0x32, 0x00, 0xe0, 0x57, 0x11, 0x62, - 0x6d, 0x7d, 0x12, 0xb0, 0xf6, 0x29, 0x68, 0xbf, 0x34, 0x1c, 0x54, 0xf1, 0x1e, 0xed, 0x6c, 0x93, - 0x40, 0x51, 0xd1, 0x23, 0x0c, 0xbf, 0x84, 0x32, 0x1f, 0x84, 0x24, 0x24, 0xe5, 0xa9, 0x51, 0x07, - 0x00, 0xc8, 0x1d, 0x00, 0x80, 0xbf, 0x89, 0x72, 0xa6, 0x47, 0x98, 0xcf, 0xe5, 0xf4, 0x8a, 0xb6, - 0x5a, 0x58, 0xab, 0xd4, 0x79, 0x20, 0xea, 0x51, 0x94, 0xea, 0x0f, 0xa2, 0x90, 0xaf, 0x2f, 0x0e, - 0x07, 0xd5, 0x39, 0xd1, 0x5c, 0x32, 0x15, 0x59, 0xc0, 0xd7, 0xd1, 0xd4, 0x1e, 0xed, 0x94, 0x33, - 0x60, 0x48, 0xaf, 0x1b, 0xae, 0x5d, 0x6f, 0xd2, 0xce, 0xfa, 0xdc, 0x70, 0x50, 0x9d, 0xd9, 0xa3, - 0x1d, 0x49, 0x85, 0xb5, 0xab, 0x0d, 0x35, 0x34, 0xdb, 0xa4, 0x9d, 0xfb, 0xcc, 0x91, 0xf3, 0x1e, - 0x9b, 0xda, 0x9f, 0x53, 0x30, 0xd8, 0xb7, 0x89, 0xe1, 0x9f, 0x7f, 0x22, 0x7c, 0x0d, 0x21, 0xb3, - 0x17, 0xfa, 0x01, 0xf1, 0x98, 0xb7, 0x19, 0xe8, 0xfc, 0xe2, 0x70, 0x50, 0x9d, 0x17, 0xa8, 0xe2, - 0x6e, 0x3e, 0x06, 0xf1, 0x8b, 0x28, 0xed, 0x52, 0xda, 0x2b, 0x67, 0x41, 0x03, 0x0f, 0x07, 0xd5, - 0x59, 0xf6, 0xb7, 0xd4, 0x18, 0xe4, 0xb5, 0x9f, 0xa4, 0xd1, 0x62, 0x14, 0xcc, 0x16, 0x09, 0x42, - 0xcf, 0x99, 0xc4, 0xf4, 0xb8, 0x98, 0xbe, 0x8c, 0xb2, 0x1e, 0x31, 0x7c, 0xea, 0x88, 0xa8, 0x2e, - 0x0c, 0x07, 0xd5, 0x12, 0x47, 0x24, 0x05, 0xd1, 0x06, 0x7f, 0x03, 0xcd, 0xec, 0x87, 0x1d, 0xe2, - 0x39, 0x24, 0x20, 0x3e, 0xeb, 0x28, 0x07, 0x4a, 0x95, 0xe1, 0xa0, 0xba, 0x34, 0x12, 0x28, 0x7d, - 0x4d, 0xcb, 0x38, 0x73, 0xd3, 0xa5, 0x56, 0xdb, 0x09, 0xfb, 0x1d, 0xe2, 0x95, 0xf5, 0x15, 0x6d, - 0x35, 0xc3, 0xdd, 0x74, 0xa9, 0xf5, 0x2d, 0x00, 0x65, 0x37, 0x63, 0x90, 0x75, 0xec, 0x85, 0x4e, - 0xdb, 0x08, 0x40, 0x44, 0xac, 0x72, 0x7e, 0x45, 0x5b, 0xd5, 0x79, 0xc7, 0x5e, 0xe8, 0xdc, 0x8a, - 0x70, 0xb9, 0x63, 0x19, 0xaf, 0xfd, 0x5b, 0x43, 0x0b, 0x11, 0x27, 0x36, 0x1f, 0xb9, 0xb6, 0x77, - 0xfe, 0xf7, 0x94, 0xdf, 0xa5, 0x51, 0xb1, 0x49, 0x3b, 0xf7, 0x88, 0x63, 0xd9, 0x4e, 0x77, 0xb2, - 0x00, 0xc6, 0x2f, 0x80, 0x23, 0x94, 0xce, 0x7e, 0x26, 0x4a, 0xe7, 0x4e, 0x4d, 0xe9, 0x57, 0x90, - 0x0e, 0x7a, 0x46, 0x9f, 0xc0, 0x42, 0xc8, 0xf3, 0x21, 0xb2, 0x06, 0x46, 0x5f, 0x8e, 0x56, 0x4e, - 0x40, 0xcc, 0xd5, 0x48, 0xc3, 0x77, 0x0d, 0x93, 0xc0, 0x22, 0x10, 0xae, 0x8a, 0x36, 0x80, 0xcb, - 0xae, 0xca, 0x78, 0xbc, 0x81, 0xa2, 0x13, 0x36, 0xd0, 0x7f, 0x71, 0xe6, 0xb4, 0x42, 0xc7, 0x99, - 0x30, 0xe7, 0x8b, 0x63, 0xce, 0x0d, 0x94, 0x77, 0xa8, 0x45, 0x38, 0x05, 0x72, 0xa3, 0x28, 0x31, - 0x30, 0xc1, 0x01, 0x3d, 0xc2, 0xce, 0xbc, 0x83, 0xca, 0x74, 0xcb, 0x9f, 0x8d, 0x6e, 0xe8, 0x8c, - 0x74, 0x2b, 0x9c, 0x40, 0xb7, 0xdf, 0x66, 0xd1, 0x7c, 0x93, 0x76, 0xb6, 0x9c, 0xae, 0x47, 0x7c, - 0x7f, 0xcb, 0xd9, 0xa1, 0x13, 0xca, 0x9d, 0x37, 0xca, 0xa1, 0xb3, 0x51, 0xae, 0xf0, 0x8c, 0x94, - 0x7b, 0x8c, 0xe6, 0x6c, 0x4e, 0xa3, 0xb6, 0x61, 0x59, 0xec, 0x5f, 0xe2, 0x97, 0xf3, 0x2b, 0x53, - 0xab, 0x85, 0xb5, 0x7a, 0x74, 0xe3, 0x48, 0xf2, 0xac, 0x2e, 0x80, 0x5b, 0x91, 0xc2, 0xa6, 0x13, - 0x78, 0x87, 0xeb, 0xcb, 0xc3, 0x41, 0xb5, 0x62, 0x27, 0x44, 0x52, 0xc7, 0xa5, 0xa4, 0xac, 0xb2, - 0x8f, 0x16, 0xc7, 0x9a, 0xc2, 0x57, 0xd1, 0xd4, 0x3e, 0x39, 0x04, 0x16, 0x67, 0xf8, 0x7d, 0x67, - 0x9f, 0x1c, 0xca, 0xf7, 0x9d, 0x7d, 0x72, 0xc8, 0xb8, 0x78, 0x60, 0xf4, 0x42, 0x22, 0xc8, 0x0b, - 0x5c, 0x04, 0x40, 0xe6, 0x22, 0x00, 0x37, 0x53, 0xaf, 0x6b, 0xb5, 0xff, 0xe8, 0x70, 0x63, 0x78, - 0xd3, 0xb0, 0x7b, 0x93, 0xec, 0xf6, 0xf3, 0xc9, 0x6e, 0xdf, 0x47, 0x88, 0x3c, 0xb2, 0x83, 0xb6, - 0x49, 0x2d, 0xe2, 0x97, 0x73, 0xc0, 0x9a, 0x5a, 0xc4, 0x1a, 0x29, 0xd0, 0xf5, 0xcd, 0x47, 0x76, - 0xb0, 0xc1, 0x1a, 0x71, 0xa6, 0x5c, 0x62, 0x9e, 0x90, 0x08, 0x1b, 0x19, 0x2e, 0x6b, 0xad, 0x7c, - 0x0c, 0x1f, 0x5d, 0xbb, 0xfa, 0x67, 0x59, 0xbb, 0xf9, 0x33, 0xad, 0x5d, 0x74, 0xa6, 0xb5, 0x3b, - 0x73, 0xb6, 0xb5, 0x3b, 0xfb, 0x8c, 0x6b, 0xd7, 0x42, 0xd8, 0xa4, 0x4e, 0x60, 0xd8, 0x0e, 0xf1, - 0xda, 0x7e, 0x60, 0x04, 0x21, 0x5b, 0xbc, 0x05, 0x98, 0x86, 0x05, 0x98, 0x86, 0x8d, 0x48, 0xbc, - 0x0d, 0xd2, 0xf5, 0xea, 0x70, 0x50, 0xbd, 0x6c, 0xaa, 0xa0, 0xb2, 0x46, 0xe7, 0x8e, 0x08, 0xf1, - 0x6b, 0x28, 0x63, 0x1a, 0xa1, 0x4f, 0xca, 0xd3, 0x2b, 0xda, 0xea, 0xec, 0x1a, 0xe2, 0x86, 0x19, - 0xc2, 0xe9, 0x0c, 0x42, 0x99, 0xce, 0x00, 0xe0, 0xdb, 0xa8, 0xb4, 0x63, 0xd8, 0xbd, 0xd0, 0x23, - 0x6d, 0xd3, 0x08, 0x48, 0x97, 0x7a, 0x87, 0xe5, 0x12, 0x0c, 0xf0, 0x85, 0xe1, 0xa0, 0x7a, 0x49, - 0xc8, 0x36, 0x84, 0x48, 0xd2, 0x2f, 0x26, 0x44, 0xf8, 0x3e, 0x9a, 0x8f, 0x2c, 0xf9, 0x61, 0x27, - 0x36, 0x36, 0x07, 0xc6, 0x56, 0x86, 0x83, 0xea, 0x15, 0x21, 0xde, 0x1e, 0x49, 0x25, 0x7b, 0xf8, - 0xa8, 0xb4, 0x62, 0xa1, 0x59, 0x95, 0x92, 0xf2, 0x8e, 0x93, 0x3f, 0xdd, 0x8e, 0x93, 0x39, 0x69, - 0xc7, 0x69, 0xa6, 0xf5, 0x62, 0xa9, 0x54, 0xfb, 0x24, 0x85, 0x30, 0xbb, 0x55, 0x78, 0x84, 0x35, + 0xd0, 0x4b, 0xef, 0xc5, 0xbc, 0x99, 0xdd, 0x9d, 0xa1, 0x28, 0x48, 0x56, 0x3e, 0x6a, 0x28, 0x3c, + 0xd9, 0xfa, 0xbd, 0x79, 0x6f, 0xde, 0xbc, 0xf9, 0xcd, 0xcc, 0x9b, 0x7d, 0x43, 0x34, 0xdf, 0xdf, + 0xef, 0xd4, 0xcd, 0xbe, 0x53, 0x27, 0x07, 0xc4, 0x0d, 0x6a, 0x7d, 0x8f, 0x06, 0x14, 0x4f, 0x99, + 0x7d, 0xa7, 0x62, 0x74, 0x28, 0xed, 0x74, 0x49, 0x1d, 0xa0, 0x76, 0xb8, 0x53, 0x0f, 0x9c, 0x1e, + 0xf1, 0x03, 0xb3, 0xd7, 0xe7, 0xad, 0x2a, 0x0b, 0x91, 0xaa, 0x1f, 0xb6, 0x7b, 0x4e, 0x30, 0x8a, + 0xee, 0x12, 0xb3, 0x1b, 0xec, 0x0a, 0xf4, 0xf2, 0xa8, 0x31, 0xd2, 0xeb, 0x07, 0x87, 0x42, 0x78, + 0x45, 0x08, 0x99, 0x96, 0xe9, 0xba, 0x34, 0x30, 0x03, 0x87, 0xba, 0xbe, 0x90, 0xbe, 0xba, 0xff, + 0xba, 0x5f, 0x73, 0x28, 0x93, 0xf6, 0x4c, 0x6b, 0xd7, 0x71, 0x89, 0x77, 0x58, 0x8f, 0x3a, 0xf1, + 0x88, 0x4f, 0x43, 0xcf, 0x22, 0xf5, 0x0e, 0x71, 0x89, 0x67, 0x06, 0xc4, 0xe6, 0x5a, 0xd5, 0x5f, + 0xa4, 0xd0, 0x5c, 0x83, 0xb6, 0xb7, 0xc1, 0xb5, 0x80, 0xd8, 0x9b, 0x6c, 0x78, 0xf8, 0x1a, 0xca, + 0xee, 0xd1, 0x76, 0xcb, 0xb1, 0xcb, 0xda, 0x8a, 0xb6, 0x9a, 0x5f, 0x9f, 0x1f, 0x0e, 0x8c, 0xe2, + 0x1e, 0x6d, 0x6f, 0xd9, 0x2f, 0xd3, 0x9e, 0x13, 0x80, 0x53, 0xcd, 0x0c, 0x00, 0xf8, 0x55, 0x84, + 0x58, 0x5b, 0x9f, 0x04, 0xac, 0x7d, 0x0a, 0xda, 0x2f, 0x0d, 0x07, 0x06, 0xde, 0xa3, 0xed, 0x6d, + 0x12, 0x28, 0x2a, 0x7a, 0x84, 0xe1, 0x97, 0x50, 0xe6, 0x83, 0x90, 0x84, 0xa4, 0x3c, 0x95, 0x74, + 0x00, 0x80, 0xdc, 0x01, 0x00, 0xf8, 0x9b, 0x28, 0x67, 0x79, 0x84, 0xf9, 0x5c, 0x4e, 0xaf, 0x68, + 0xab, 0x85, 0xb5, 0x4a, 0x8d, 0x07, 0xa2, 0x16, 0x45, 0xa9, 0xf6, 0x20, 0x0a, 0xf9, 0xfa, 0xe2, + 0x70, 0x60, 0xcc, 0x89, 0xe6, 0x92, 0xa9, 0xc8, 0x02, 0xbe, 0x8e, 0xa6, 0xf6, 0x68, 0xbb, 0x9c, + 0x01, 0x43, 0x7a, 0xcd, 0xec, 0x3b, 0xb5, 0x06, 0x6d, 0xaf, 0xcf, 0x0d, 0x07, 0xc6, 0xcc, 0x1e, + 0x6d, 0x4b, 0x2a, 0xac, 0x5d, 0x75, 0xa8, 0xa1, 0xd9, 0x06, 0x6d, 0xdf, 0x67, 0x8e, 0x9c, 0xf7, + 0xd8, 0x54, 0xff, 0x9c, 0x82, 0xc1, 0xbe, 0x4d, 0x4c, 0xff, 0xfc, 0x13, 0xe1, 0x6b, 0x08, 0x59, + 0xdd, 0xd0, 0x0f, 0x88, 0xc7, 0xbc, 0xcd, 0x40, 0xe7, 0x17, 0x87, 0x03, 0x63, 0x5e, 0xa0, 0x8a, + 0xbb, 0xf9, 0x18, 0xc4, 0x2f, 0xa2, 0x74, 0x9f, 0xd2, 0x6e, 0x39, 0x0b, 0x1a, 0x78, 0x38, 0x30, + 0x66, 0xd9, 0xdf, 0x52, 0x63, 0x90, 0x57, 0x7f, 0x92, 0x46, 0x8b, 0x51, 0x30, 0x9b, 0x24, 0x08, + 0x3d, 0x77, 0x12, 0xd3, 0xe3, 0x62, 0xfa, 0x32, 0xca, 0x7a, 0xc4, 0xf4, 0xa9, 0x2b, 0xa2, 0xba, + 0x30, 0x1c, 0x18, 0x25, 0x8e, 0x48, 0x0a, 0xa2, 0x0d, 0xfe, 0x06, 0x9a, 0xd9, 0x0f, 0xdb, 0xc4, + 0x73, 0x49, 0x40, 0x7c, 0xd6, 0x51, 0x0e, 0x94, 0x2a, 0xc3, 0x81, 0xb1, 0x94, 0x08, 0x94, 0xbe, + 0xa6, 0x65, 0x9c, 0xb9, 0xd9, 0xa7, 0x76, 0xcb, 0x0d, 0x7b, 0x6d, 0xe2, 0x95, 0xf5, 0x15, 0x6d, + 0x35, 0xc3, 0xdd, 0xec, 0x53, 0xfb, 0x5b, 0x00, 0xca, 0x6e, 0xc6, 0x20, 0xeb, 0xd8, 0x0b, 0xdd, + 0x96, 0x19, 0x80, 0x88, 0xd8, 0xe5, 0xfc, 0x8a, 0xb6, 0xaa, 0xf3, 0x8e, 0xbd, 0xd0, 0xbd, 0x15, + 0xe1, 0x72, 0xc7, 0x32, 0x5e, 0xfd, 0xb7, 0x86, 0x16, 0x22, 0x4e, 0x6c, 0x3e, 0xea, 0x3b, 0xde, + 0xf9, 0xdf, 0x53, 0x7e, 0x97, 0x46, 0xc5, 0x06, 0x6d, 0xdf, 0x23, 0xae, 0xed, 0xb8, 0x9d, 0xc9, + 0x02, 0x18, 0xbf, 0x00, 0x8e, 0x50, 0x3a, 0xfb, 0x99, 0x28, 0x9d, 0x3b, 0x35, 0xa5, 0x5f, 0x41, + 0x3a, 0xe8, 0x99, 0x3d, 0x02, 0x0b, 0x21, 0xcf, 0x87, 0xc8, 0x1a, 0x98, 0x3d, 0x39, 0x5a, 0x39, + 0x01, 0x31, 0x57, 0x23, 0x0d, 0xbf, 0x6f, 0x5a, 0x04, 0x16, 0x81, 0x70, 0x55, 0xb4, 0x01, 0x5c, + 0x76, 0x55, 0xc6, 0xe3, 0x0d, 0x14, 0x9d, 0xb0, 0x81, 0xfe, 0x8b, 0x33, 0xa7, 0x19, 0xba, 0xee, + 0x84, 0x39, 0x5f, 0x1c, 0x73, 0x6e, 0xa0, 0xbc, 0x4b, 0x6d, 0xc2, 0x29, 0x90, 0x4b, 0xa2, 0xc4, + 0xc0, 0x11, 0x0e, 0xe8, 0x11, 0x76, 0xe6, 0x1d, 0x54, 0xa6, 0x5b, 0xfe, 0x6c, 0x74, 0x43, 0x67, + 0xa4, 0x5b, 0xe1, 0x04, 0xba, 0xfd, 0x36, 0x8b, 0xe6, 0x1b, 0xb4, 0xbd, 0xe5, 0x76, 0x3c, 0xe2, + 0xfb, 0x5b, 0xee, 0x0e, 0x9d, 0x50, 0xee, 0xbc, 0x51, 0x0e, 0x9d, 0x8d, 0x72, 0x85, 0x67, 0xa4, + 0xdc, 0x63, 0x34, 0xe7, 0x70, 0x1a, 0xb5, 0x4c, 0xdb, 0x66, 0xff, 0x12, 0xbf, 0x9c, 0x5f, 0x99, + 0x5a, 0x2d, 0xac, 0xd5, 0xa2, 0x1b, 0xc7, 0x28, 0xcf, 0x6a, 0x02, 0xb8, 0x15, 0x29, 0x6c, 0xba, + 0x81, 0x77, 0xb8, 0xbe, 0x3c, 0x1c, 0x18, 0x15, 0x67, 0x44, 0x24, 0x75, 0x5c, 0x1a, 0x95, 0x55, + 0xf6, 0xd1, 0xe2, 0x58, 0x53, 0xf8, 0x2a, 0x9a, 0xda, 0x27, 0x87, 0xc0, 0xe2, 0x0c, 0xbf, 0xef, + 0xec, 0x93, 0x43, 0xf9, 0xbe, 0xb3, 0x4f, 0x0e, 0x19, 0x17, 0x0f, 0xcc, 0x6e, 0x48, 0x04, 0x79, + 0x81, 0x8b, 0x00, 0xc8, 0x5c, 0x04, 0xe0, 0x66, 0xea, 0x75, 0xad, 0xfa, 0x1f, 0x1d, 0x6e, 0x0c, + 0x6f, 0x9a, 0x4e, 0x77, 0x92, 0xdd, 0x7e, 0x3e, 0xd9, 0xed, 0xfb, 0x08, 0x91, 0x47, 0x4e, 0xd0, + 0xb2, 0xa8, 0x4d, 0xfc, 0x72, 0x0e, 0x58, 0x53, 0x8d, 0x58, 0x23, 0x05, 0xba, 0xb6, 0xf9, 0xc8, + 0x09, 0x36, 0x58, 0x23, 0xce, 0x94, 0x4b, 0xcc, 0x13, 0x12, 0x61, 0x89, 0xe1, 0xb2, 0xd6, 0xcc, + 0xc7, 0xf0, 0xd1, 0xb5, 0xab, 0x7f, 0x96, 0xb5, 0x9b, 0x3f, 0xd3, 0xda, 0x45, 0x67, 0x5a, 0xbb, + 0x33, 0x67, 0x5b, 0xbb, 0xb3, 0xcf, 0xb8, 0x76, 0x6d, 0x84, 0x2d, 0xea, 0x06, 0xa6, 0xe3, 0x12, + 0xaf, 0xe5, 0x07, 0x66, 0x10, 0xb2, 0xc5, 0x5b, 0x80, 0x69, 0x58, 0x80, 0x69, 0xd8, 0x88, 0xc4, + 0xdb, 0x20, 0x5d, 0x37, 0x86, 0x03, 0xe3, 0xb2, 0xa5, 0x82, 0xca, 0x1a, 0x9d, 0x3b, 0x22, 0xc4, + 0xaf, 0xa1, 0x8c, 0x65, 0x86, 0x3e, 0x29, 0x4f, 0xaf, 0x68, 0xab, 0xb3, 0x6b, 0x88, 0x1b, 0x66, + 0x08, 0xa7, 0x33, 0x08, 0x65, 0x3a, 0x03, 0x80, 0x6f, 0xa3, 0xd2, 0x8e, 0xe9, 0x74, 0x43, 0x8f, + 0xb4, 0x2c, 0x33, 0x20, 0x1d, 0xea, 0x1d, 0x96, 0x4b, 0x30, 0xc0, 0x17, 0x86, 0x03, 0xe3, 0x92, + 0x90, 0x6d, 0x08, 0x91, 0xa4, 0x5f, 0x1c, 0x11, 0xe1, 0xfb, 0x68, 0x3e, 0xb2, 0xe4, 0x87, 0xed, + 0xd8, 0xd8, 0x1c, 0x18, 0x5b, 0x19, 0x0e, 0x8c, 0x2b, 0x42, 0xbc, 0x9d, 0x48, 0x25, 0x7b, 0xf8, + 0xa8, 0xb4, 0x62, 0xa3, 0x59, 0x95, 0x92, 0xf2, 0x8e, 0x93, 0x3f, 0xdd, 0x8e, 0x93, 0x39, 0x69, + 0xc7, 0x69, 0xa4, 0xf5, 0x62, 0xa9, 0x54, 0xfd, 0x24, 0x85, 0x30, 0xbb, 0x55, 0x78, 0x84, 0x35, 0xf8, 0x0a, 0xa4, 0x87, 0xaf, 0xa1, 0xbc, 0x47, 0x3e, 0x08, 0x89, 0x1f, 0x50, 0x4f, 0xde, 0x7a, - 0x62, 0x50, 0x5e, 0x40, 0x31, 0xf8, 0x6c, 0x5b, 0x4f, 0xed, 0xe7, 0x69, 0xf8, 0x16, 0x28, 0xa2, - 0x3a, 0xd9, 0xd0, 0x8f, 0xdb, 0xd0, 0xaf, 0xa1, 0xac, 0x17, 0x3a, 0xa3, 0xcc, 0x07, 0x1c, 0xf6, - 0x42, 0x47, 0x8d, 0x08, 0x00, 0x78, 0x0b, 0xcd, 0xb9, 0x82, 0xa5, 0x07, 0xa4, 0x2d, 0x02, 0x99, - 0x1b, 0xad, 0xd9, 0x91, 0xb0, 0x99, 0x08, 0x69, 0x31, 0x21, 0x4a, 0x98, 0x12, 0x1e, 0xe8, 0xe3, - 0x4c, 0xb5, 0x12, 0xbe, 0x14, 0x13, 0x22, 0x89, 0x17, 0xf9, 0x53, 0xf0, 0xe2, 0x8f, 0x69, 0xf1, - 0x8d, 0xd8, 0x34, 0x09, 0xb1, 0x26, 0xbc, 0x98, 0xdc, 0xc5, 0xce, 0x76, 0x17, 0xab, 0xfd, 0xbd, - 0x00, 0x77, 0xac, 0x77, 0x02, 0xbb, 0x67, 0xfb, 0x50, 0xbc, 0x98, 0x50, 0xe9, 0x0b, 0xa2, 0xd2, - 0x8f, 0x34, 0xb4, 0x78, 0xc7, 0x78, 0xd4, 0x12, 0x75, 0x1f, 0xff, 0x4d, 0xea, 0xdd, 0x23, 0x9e, - 0x4d, 0x2d, 0x91, 0x52, 0xde, 0x88, 0x52, 0xca, 0xe4, 0x64, 0xd4, 0xc7, 0x6a, 0xf1, 0x1c, 0xf3, - 0xea, 0x70, 0x50, 0xad, 0x8e, 0x95, 0x4b, 0x7e, 0x8c, 0xef, 0x56, 0xe5, 0xb6, 0x7e, 0x26, 0x6e, - 0xe7, 0x9f, 0xe7, 0x4b, 0xdf, 0x0f, 0x35, 0xb4, 0x14, 0xd0, 0xc0, 0xe8, 0xb5, 0xcd, 0xb0, 0x1f, - 0xf6, 0x0c, 0xd8, 0xa4, 0x43, 0xdf, 0xe8, 0xb2, 0x24, 0x8f, 0x45, 0x7c, 0xed, 0xd8, 0x88, 0x3f, - 0x60, 0x6a, 0x1b, 0xb1, 0xd6, 0x3b, 0x4c, 0x89, 0x07, 0xbc, 0x36, 0x1c, 0x54, 0x97, 0x83, 0x31, - 0x62, 0xc9, 0x8d, 0x85, 0x71, 0x72, 0x98, 0xff, 0x5b, 0x07, 0xdd, 0x31, 0xf3, 0x3f, 0x73, 0xc2, - 0xfc, 0x8f, 0xd5, 0x92, 0xe6, 0x7f, 0xac, 0x5c, 0x9e, 0xff, 0xb1, 0x0d, 0x2a, 0xbf, 0xd6, 0x50, - 0xe5, 0x78, 0x6a, 0x9d, 0x2e, 0x57, 0xfc, 0xb6, 0x9c, 0x2b, 0xb2, 0xcb, 0x34, 0x2f, 0x79, 0xd6, - 0xe5, 0x92, 0x67, 0xdd, 0xdd, 0xef, 0xc2, 0xd8, 0xa2, 0x92, 0x67, 0xfd, 0x7e, 0x68, 0x38, 0x81, - 0x1d, 0x1c, 0x9e, 0x94, 0x5b, 0x56, 0x7e, 0xa5, 0xa1, 0x4b, 0xc7, 0xce, 0xc5, 0x73, 0xe1, 0x21, - 0x0b, 0xe2, 0xf1, 0xf3, 0xf3, 0x3c, 0xb8, 0x58, 0xfb, 0x67, 0x0a, 0x2d, 0x35, 0x69, 0xa7, 0x45, - 0x5c, 0xcf, 0xa6, 0x9e, 0x1d, 0xd8, 0x1f, 0x7e, 0x05, 0xd2, 0xf3, 0xaf, 0xa3, 0x69, 0x87, 0x3c, - 0x6c, 0x8b, 0x21, 0x1f, 0xc2, 0x46, 0xaf, 0xc1, 0x95, 0x7c, 0xd1, 0x21, 0x0f, 0xef, 0x09, 0x58, - 0xd2, 0x2c, 0x48, 0xb0, 0x9a, 0xdc, 0x67, 0x4f, 0x9b, 0xdc, 0xd7, 0x3e, 0x4d, 0x41, 0x85, 0x51, - 0x8a, 0xf4, 0xf9, 0x4f, 0xcd, 0xfe, 0x27, 0x81, 0x16, 0xb7, 0xcd, 0x0d, 0xc3, 0x31, 0x49, 0xaf, - 0x37, 0xb9, 0x6d, 0x7e, 0x3e, 0xb7, 0xcd, 0xbf, 0xf0, 0x97, 0x27, 0x22, 0xaa, 0xe7, 0x9f, 0xba, - 0x5f, 0x4a, 0x50, 0xff, 0x90, 0x06, 0xaa, 0x3e, 0x20, 0x5e, 0xdf, 0x76, 0x8c, 0xc9, 0x1d, 0xfe, - 0xf9, 0xae, 0xb8, 0x7e, 0x49, 0x25, 0xb0, 0x11, 0x85, 0xf4, 0x53, 0x50, 0xe8, 0xf7, 0x05, 0x34, - 0x0d, 0xac, 0xb9, 0x43, 0x7c, 0x48, 0x25, 0xef, 0xa2, 0xbc, 0x1f, 0x3d, 0x0f, 0x03, 0xfe, 0x14, - 0xd6, 0x96, 0xa2, 0xec, 0x51, 0x7d, 0x37, 0xc6, 0x03, 0x10, 0x37, 0x1e, 0x19, 0xbf, 0x7d, 0xa1, - 0x35, 0xb2, 0x81, 0x37, 0x50, 0x16, 0x98, 0x60, 0x89, 0x14, 0x64, 0x3e, 0xb2, 0x26, 0x3d, 0xb3, - 0xe2, 0x4e, 0xf2, 0x66, 0x8a, 0x1d, 0xa1, 0xca, 0x8c, 0xf4, 0xe0, 0xa1, 0x12, 0x30, 0x4e, 0x32, - 0x22, 0x3d, 0x5f, 0xe2, 0x46, 0x78, 0x33, 0xd5, 0x08, 0xc7, 0xf0, 0x77, 0xd1, 0x2c, 0xfc, 0xaf, - 0xed, 0x89, 0x17, 0x3a, 0x31, 0x23, 0x65, 0x63, 0xca, 0xf3, 0x9d, 0xf5, 0xcb, 0xc3, 0x41, 0xf5, - 0x62, 0x4f, 0xc6, 0x15, 0xd3, 0x33, 0x8a, 0x08, 0xbf, 0x8f, 0x38, 0xd0, 0x26, 0xfc, 0xbd, 0x87, - 0x78, 0x79, 0x76, 0x49, 0xe9, 0x40, 0x7e, 0x0b, 0xc2, 0xe7, 0xb5, 0x27, 0xc1, 0x8a, 0xf9, 0x69, - 0x59, 0x82, 0xdf, 0x42, 0x39, 0x97, 0xbf, 0xac, 0x00, 0xfe, 0x46, 0x9f, 0xa8, 0x13, 0x0f, 0x2e, - 0x04, 0xc3, 0x38, 0xa2, 0x58, 0x8b, 0xb4, 0x99, 0x21, 0x8f, 0x17, 0xda, 0x81, 0xca, 0x92, 0x21, - 0xb9, 0xfe, 0xce, 0x0d, 0x89, 0x86, 0xaa, 0x21, 0x01, 0xb2, 0x69, 0xd9, 0x81, 0x22, 0x05, 0x90, - 0x5b, 0x9a, 0x16, 0xa9, 0x74, 0xc1, 0xa7, 0x85, 0x37, 0x53, 0xa7, 0x85, 0x63, 0x9c, 0x71, 0xe2, - 0x63, 0x13, 0xb0, 0x5d, 0x61, 0x9c, 0xfc, 0x15, 0x2a, 0x62, 0x9c, 0xc0, 0x92, 0x8c, 0x13, 0x30, - 0x6e, 0xa3, 0x19, 0x4f, 0x4e, 0x93, 0xe0, 0x76, 0x27, 0x4d, 0xf3, 0xd1, 0x1c, 0x8a, 0x4f, 0xb3, - 0xa2, 0xa4, 0x4e, 0xb3, 0x22, 0xc2, 0xdb, 0x08, 0x99, 0x71, 0x7a, 0x00, 0x5f, 0xf5, 0x0b, 0x6b, - 0x17, 0x23, 0xeb, 0x89, 0xc4, 0x61, 0xbd, 0x3c, 0x1c, 0x54, 0x17, 0x46, 0xcd, 0x15, 0xbb, 0x92, - 0x19, 0x16, 0x06, 0x33, 0x3a, 0x1d, 0xa1, 0xfe, 0x21, 0x85, 0x41, 0x3d, 0x36, 0xc5, 0x96, 0x17, - 0x61, 0x6a, 0x18, 0x62, 0x18, 0xbf, 0x8b, 0x0a, 0xe1, 0xe8, 0xba, 0x57, 0x2e, 0x82, 0xc9, 0xf2, - 0x71, 0x37, 0x41, 0x9e, 0x56, 0x49, 0x0a, 0x8a, 0x59, 0xd9, 0x12, 0x7e, 0x0f, 0x4d, 0x47, 0x15, - 0x4f, 0xdb, 0xd9, 0xa1, 0x50, 0x47, 0x90, 0x2c, 0x27, 0x8b, 0x9d, 0xdc, 0xb2, 0x3d, 0x42, 0x55, - 0xcb, 0x92, 0x00, 0x9b, 0x68, 0xd6, 0x53, 0xae, 0x12, 0x65, 0x0c, 0xb6, 0x2f, 0x8f, 0x99, 0xba, - 0x38, 0xc0, 0x57, 0x86, 0x83, 0x6a, 0x59, 0x55, 0x53, 0x7a, 0x48, 0x98, 0x64, 0x81, 0x76, 0xa3, - 0x8f, 0xde, 0xe5, 0x45, 0x35, 0xd0, 0xea, 0xd7, 0x70, 0xb1, 0xc5, 0x47, 0x98, 0x1a, 0xe8, 0x18, - 0x66, 0x74, 0x70, 0xe3, 0xda, 0x44, 0x79, 0x49, 0xa5, 0x43, 0xa2, 0x6a, 0xc1, 0xe9, 0x30, 0x6a, - 0xae, 0xd2, 0x61, 0x84, 0xaf, 0xeb, 0x28, 0x0b, 0x8f, 0x8f, 0xfd, 0x66, 0x5a, 0xd7, 0x4b, 0xf9, - 0x66, 0x5a, 0x9f, 0x2d, 0x15, 0x9b, 0x69, 0xbd, 0x54, 0x9a, 0x6b, 0xa6, 0xf5, 0xf9, 0xd2, 0x42, - 0x33, 0xad, 0x2f, 0x94, 0x16, 0x6b, 0xdf, 0x4f, 0xa1, 0x62, 0xa2, 0x48, 0x85, 0x5f, 0x44, 0x69, - 0x38, 0x71, 0xb4, 0xd1, 0x2b, 0x08, 0x47, 0x3d, 0x6e, 0x40, 0x8e, 0xd7, 0x90, 0x1e, 0x15, 0x0b, - 0x45, 0x41, 0x06, 0x8e, 0xfe, 0x08, 0x93, 0x8f, 0xfe, 0x08, 0xc3, 0x0d, 0x94, 0xeb, 0xf3, 0xa3, - 0x42, 0x1c, 0xfe, 0xb0, 0x4b, 0x08, 0x48, 0x3e, 0xd0, 0x04, 0x24, 0x9d, 0x47, 0xe9, 0x53, 0x14, - 0x44, 0xe3, 0x5a, 0x59, 0xe6, 0x59, 0x6a, 0x65, 0xb5, 0x0f, 0x11, 0x86, 0xf0, 0x6e, 0x07, 0x1e, - 0x31, 0xfa, 0xd1, 0x59, 0xb6, 0x82, 0x52, 0x71, 0x12, 0x54, 0x1a, 0x0e, 0xaa, 0xd3, 0xb6, 0x7c, - 0xc2, 0xa7, 0x6c, 0x0b, 0xaf, 0x8f, 0x46, 0xc3, 0x4f, 0xa7, 0x39, 0xe8, 0x50, 0x3e, 0x11, 0x4f, - 0x1a, 0x60, 0xed, 0xa7, 0x29, 0x34, 0xd3, 0x84, 0xcc, 0xa8, 0xc5, 0xf3, 0xb8, 0x53, 0xf4, 0xfb, - 0x12, 0xca, 0x3c, 0x34, 0x02, 0x73, 0x17, 0x7a, 0xd5, 0xf9, 0xd0, 0x00, 0x90, 0x87, 0x06, 0x00, - 0xde, 0x40, 0xc5, 0x1d, 0x8f, 0xf6, 0xdb, 0xa2, 0x3b, 0x96, 0xbd, 0xf0, 0xc0, 0xc3, 0x9e, 0xc5, - 0x44, 0xc2, 0x51, 0x25, 0x7d, 0x99, 0x51, 0x04, 0xa3, 0x84, 0x2d, 0x7d, 0x62, 0xc2, 0xf6, 0x06, - 0x9a, 0x25, 0x9e, 0x47, 0xbd, 0xad, 0x9d, 0x3b, 0xb6, 0xef, 0x33, 0x46, 0x67, 0xc0, 0x47, 0x58, - 0x66, 0xaa, 0x44, 0x52, 0x4e, 0xe8, 0xd4, 0x7e, 0xa9, 0xa1, 0xe9, 0x77, 0x99, 0xff, 0x51, 0x4c, - 0x62, 0x0f, 0xb4, 0x13, 0x3d, 0x38, 0x5b, 0x4e, 0x7a, 0x1d, 0xe5, 0x20, 0x4e, 0x71, 0x7c, 0xf8, - 0xb9, 0xe3, 0xd1, 0xbe, 0xa2, 0x90, 0xe5, 0xc8, 0xb5, 0xb7, 0x51, 0x06, 0x68, 0x85, 0xf3, 0x28, - 0xb3, 0xc9, 0x7c, 0x2f, 0x5d, 0xc0, 0x05, 0x94, 0xdb, 0x3c, 0xb0, 0xcd, 0x80, 0x58, 0x25, 0x0d, - 0xe7, 0xd0, 0xd4, 0xdd, 0xbb, 0x77, 0x4a, 0x29, 0xbc, 0x80, 0x4a, 0x6f, 0x10, 0xc3, 0xea, 0xd9, - 0x0e, 0xd9, 0x7c, 0xc4, 0x8f, 0x98, 0xd2, 0x14, 0x9e, 0x46, 0x7a, 0x8b, 0xec, 0x11, 0x68, 0x9c, - 0x5e, 0xfb, 0x54, 0x43, 0x19, 0x9e, 0x7c, 0x13, 0x54, 0x7c, 0x8b, 0x04, 0x9c, 0x0f, 0x80, 0xf8, - 0x18, 0xc7, 0xa7, 0x59, 0x4c, 0x91, 0xca, 0xc5, 0x11, 0xcf, 0x14, 0xce, 0xd6, 0xae, 0x7e, 0xef, - 0x93, 0x7f, 0xfc, 0x2c, 0xf5, 0x42, 0xad, 0xdc, 0x38, 0xf8, 0xff, 0xc6, 0x1e, 0xed, 0x5c, 0xf7, - 0x49, 0xd0, 0x78, 0x0c, 0x81, 0xf9, 0xa8, 0xf1, 0xd8, 0xb6, 0x3e, 0xba, 0xa9, 0x5d, 0x7b, 0x45, - 0xc3, 0x37, 0x51, 0x06, 0xc2, 0x8b, 0x39, 0x61, 0xe5, 0x50, 0x1f, 0x6f, 0x7b, 0xea, 0x07, 0x29, - 0x0d, 0x74, 0xb3, 0xb7, 0xe1, 0x67, 0x08, 0x78, 0xe9, 0x48, 0x2e, 0xbe, 0xc9, 0x82, 0x54, 0xe1, - 0x7b, 0x39, 0x6f, 0xb4, 0xb1, 0x4b, 0xcc, 0xfd, 0x16, 0xf1, 0x5d, 0xea, 0xf8, 0x64, 0xfd, 0xbd, - 0x3f, 0x3d, 0x59, 0xd6, 0x3e, 0x7e, 0xb2, 0xac, 0xfd, 0xed, 0xc9, 0xb2, 0xf6, 0xe3, 0xa7, 0xcb, - 0x17, 0x3e, 0x7e, 0xba, 0x7c, 0xe1, 0xaf, 0x4f, 0x97, 0x2f, 0x7c, 0xe7, 0xff, 0xba, 0x76, 0xb0, - 0x1b, 0x76, 0xea, 0x26, 0xed, 0x37, 0x0c, 0xaf, 0x6f, 0x58, 0x86, 0xeb, 0x51, 0x16, 0x20, 0xf1, - 0x57, 0xf4, 0xeb, 0x84, 0xdf, 0xa4, 0x16, 0x6e, 0x01, 0x70, 0x8f, 0x8b, 0xeb, 0x5b, 0xb4, 0x7e, - 0xcb, 0xb5, 0x3b, 0x59, 0xf0, 0xe1, 0xc6, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x01, 0x18, 0xb1, - 0x7b, 0x7c, 0x31, 0x00, 0x00, + 0x62, 0x50, 0x5e, 0x40, 0x31, 0xf8, 0x6c, 0x5b, 0x4f, 0xf5, 0xe7, 0x69, 0xf8, 0x16, 0x28, 0xa2, + 0x3a, 0xd9, 0xd0, 0x8f, 0xdb, 0xd0, 0xaf, 0xa1, 0xac, 0x17, 0xba, 0x49, 0xe6, 0x03, 0x0e, 0x7b, + 0xa1, 0xab, 0x46, 0x04, 0x00, 0xbc, 0x85, 0xe6, 0xfa, 0x31, 0x4b, 0x5b, 0x22, 0x90, 0xb9, 0x64, + 0xcd, 0x26, 0xc2, 0xc6, 0x48, 0x48, 0x8b, 0x23, 0x22, 0xd9, 0xd4, 0x01, 0x69, 0x09, 0x0f, 0xf4, + 0xa3, 0xa6, 0x0e, 0x48, 0x73, 0xc4, 0x97, 0xe2, 0x88, 0x48, 0xe2, 0x45, 0xfe, 0x14, 0xbc, 0xf8, + 0x63, 0x5a, 0x7c, 0x23, 0xb6, 0x2c, 0x42, 0xec, 0x09, 0x2f, 0x26, 0x77, 0xb1, 0xb3, 0xdd, 0xc5, + 0xaa, 0x7f, 0x2f, 0xc0, 0x1d, 0xeb, 0x9d, 0xc0, 0xe9, 0x3a, 0x3e, 0x14, 0x2f, 0x26, 0x54, 0xfa, + 0x82, 0xa8, 0xf4, 0x23, 0x0d, 0x2d, 0xde, 0x31, 0x1f, 0x35, 0x45, 0xdd, 0xc7, 0x7f, 0x93, 0x7a, + 0xf7, 0x88, 0xe7, 0x50, 0x5b, 0xa4, 0x94, 0x37, 0xa2, 0x94, 0x72, 0x74, 0x32, 0x6a, 0x63, 0xb5, + 0x78, 0x8e, 0x79, 0x75, 0x38, 0x30, 0x8c, 0xb1, 0x72, 0xc9, 0x8f, 0xf1, 0xdd, 0xaa, 0xdc, 0xd6, + 0xcf, 0xc4, 0xed, 0xfc, 0xf3, 0x7c, 0xe9, 0xfb, 0xa1, 0x86, 0x96, 0x02, 0x1a, 0x98, 0xdd, 0x96, + 0x15, 0xf6, 0xc2, 0xae, 0x09, 0x9b, 0x74, 0xe8, 0x9b, 0x1d, 0x96, 0xe4, 0xb1, 0x88, 0xaf, 0x1d, + 0x1b, 0xf1, 0x07, 0x4c, 0x6d, 0x23, 0xd6, 0x7a, 0x87, 0x29, 0xf1, 0x80, 0x57, 0x87, 0x03, 0x63, + 0x39, 0x18, 0x23, 0x96, 0xdc, 0x58, 0x18, 0x27, 0x87, 0xf9, 0xbf, 0x75, 0xd0, 0x19, 0x33, 0xff, + 0x33, 0x27, 0xcc, 0xff, 0x58, 0x2d, 0x69, 0xfe, 0xc7, 0xca, 0xe5, 0xf9, 0x1f, 0xdb, 0xa0, 0xf2, + 0x6b, 0x0d, 0x55, 0x8e, 0xa7, 0xd6, 0xe9, 0x72, 0xc5, 0x6f, 0xcb, 0xb9, 0x22, 0xbb, 0x4c, 0xf3, + 0x92, 0x67, 0x4d, 0x2e, 0x79, 0xd6, 0xfa, 0xfb, 0x1d, 0x18, 0x5b, 0x54, 0xf2, 0xac, 0xdd, 0x0f, + 0x4d, 0x37, 0x70, 0x82, 0xc3, 0x93, 0x72, 0xcb, 0xca, 0xaf, 0x34, 0x74, 0xe9, 0xd8, 0xb9, 0x78, + 0x2e, 0x3c, 0x64, 0x41, 0x3c, 0x7e, 0x7e, 0x9e, 0x07, 0x17, 0xab, 0xff, 0x4c, 0xa1, 0xa5, 0x06, + 0x6d, 0x37, 0x49, 0xdf, 0x73, 0xa8, 0xe7, 0x04, 0xce, 0x87, 0x5f, 0x81, 0xf4, 0xfc, 0xeb, 0x68, + 0xda, 0x25, 0x0f, 0x5b, 0x62, 0xc8, 0x87, 0xb0, 0xd1, 0x6b, 0x70, 0x25, 0x5f, 0x74, 0xc9, 0xc3, + 0x7b, 0x02, 0x96, 0x34, 0x0b, 0x12, 0xac, 0x26, 0xf7, 0xd9, 0xd3, 0x26, 0xf7, 0xd5, 0x4f, 0x53, + 0x50, 0x61, 0x94, 0x22, 0x7d, 0xfe, 0x53, 0xb3, 0xff, 0x49, 0xa0, 0xc5, 0x6d, 0x73, 0xc3, 0x74, + 0x2d, 0xd2, 0xed, 0x4e, 0x6e, 0x9b, 0x9f, 0xcf, 0x6d, 0xf3, 0x2f, 0xfc, 0xe5, 0x89, 0x88, 0xea, + 0xf9, 0xa7, 0xee, 0x97, 0x12, 0xd4, 0x3f, 0xa4, 0x81, 0xaa, 0x0f, 0x88, 0xd7, 0x73, 0x5c, 0x73, + 0x72, 0x87, 0x7f, 0xbe, 0x2b, 0xae, 0x5f, 0x52, 0x09, 0x2c, 0xa1, 0x90, 0x7e, 0x0a, 0x0a, 0xfd, + 0xbe, 0x80, 0xa6, 0x81, 0x35, 0x77, 0x88, 0x0f, 0xa9, 0xe4, 0x5d, 0x94, 0xf7, 0xa3, 0xe7, 0x61, + 0xc0, 0x9f, 0xc2, 0xda, 0x52, 0x94, 0x3d, 0xaa, 0xef, 0xc6, 0x78, 0x00, 0xe2, 0xc6, 0x89, 0xf1, + 0xdb, 0x17, 0x9a, 0x89, 0x0d, 0xbc, 0x81, 0xb2, 0xc0, 0x04, 0x5b, 0xa4, 0x20, 0xf3, 0x91, 0x35, + 0xe9, 0x99, 0x15, 0x77, 0x92, 0x37, 0x53, 0xec, 0x08, 0x55, 0x66, 0xa4, 0x0b, 0x0f, 0x95, 0x80, + 0x71, 0x92, 0x11, 0xe9, 0xf9, 0x12, 0x37, 0xc2, 0x9b, 0xa9, 0x46, 0x38, 0x86, 0xbf, 0x8b, 0x66, + 0xe1, 0x7f, 0x2d, 0x4f, 0xbc, 0xd0, 0x89, 0x19, 0x29, 0x1b, 0x53, 0x9e, 0xef, 0xac, 0x5f, 0x1e, + 0x0e, 0x8c, 0x8b, 0x5d, 0x19, 0x57, 0x4c, 0xcf, 0x28, 0x22, 0xfc, 0x3e, 0xe2, 0x40, 0x8b, 0xf0, + 0xf7, 0x1e, 0xe2, 0xe5, 0xd9, 0x25, 0xa5, 0x03, 0xf9, 0x2d, 0x08, 0x9f, 0xd7, 0xae, 0x04, 0x2b, + 0xe6, 0xa7, 0x65, 0x09, 0x7e, 0x0b, 0xe5, 0xfa, 0xfc, 0x65, 0x05, 0xf0, 0x37, 0xfa, 0x44, 0x3d, + 0xf2, 0xe0, 0x42, 0x30, 0x8c, 0x23, 0x8a, 0xb5, 0x48, 0x9b, 0x19, 0xf2, 0x78, 0xa1, 0x1d, 0xa8, + 0x2c, 0x19, 0x92, 0xeb, 0xef, 0xdc, 0x90, 0x68, 0xa8, 0x1a, 0x12, 0x20, 0x9b, 0x96, 0x1d, 0x28, + 0x52, 0x00, 0xb9, 0xa5, 0x69, 0x91, 0x4a, 0x17, 0x7c, 0x5a, 0x78, 0x33, 0x75, 0x5a, 0x38, 0xc6, + 0x19, 0x27, 0x3e, 0x36, 0x01, 0xdb, 0x15, 0xc6, 0xc9, 0x5f, 0xa1, 0x22, 0xc6, 0x09, 0x6c, 0x94, + 0x71, 0x02, 0xc6, 0x2d, 0x34, 0xe3, 0xc9, 0x69, 0x12, 0xdc, 0xee, 0xa4, 0x69, 0x3e, 0x9a, 0x43, + 0xf1, 0x69, 0x56, 0x94, 0xd4, 0x69, 0x56, 0x44, 0x78, 0x1b, 0x21, 0x2b, 0x4e, 0x0f, 0xe0, 0xab, + 0x7e, 0x61, 0xed, 0x62, 0x64, 0x7d, 0x24, 0x71, 0x58, 0x2f, 0x0f, 0x07, 0xc6, 0x42, 0xd2, 0x5c, + 0xb1, 0x2b, 0x99, 0x61, 0x61, 0xb0, 0xa2, 0xd3, 0x11, 0xea, 0x1f, 0x52, 0x18, 0xd4, 0x63, 0x53, + 0x6c, 0x79, 0x11, 0xa6, 0x86, 0x21, 0x86, 0xf1, 0xbb, 0xa8, 0x10, 0x26, 0xd7, 0xbd, 0x72, 0x11, + 0x4c, 0x96, 0x8f, 0xbb, 0x09, 0xf2, 0xb4, 0x4a, 0x52, 0x50, 0xcc, 0xca, 0x96, 0xf0, 0x7b, 0x68, + 0x3a, 0xaa, 0x78, 0x3a, 0xee, 0x0e, 0x85, 0x3a, 0x82, 0x64, 0x79, 0xb4, 0xd8, 0xc9, 0x2d, 0x3b, + 0x09, 0xaa, 0x5a, 0x96, 0x04, 0xd8, 0x42, 0xb3, 0x9e, 0x72, 0x95, 0x28, 0x63, 0xb0, 0x7d, 0x79, + 0xcc, 0xd4, 0xc5, 0x01, 0xbe, 0x32, 0x1c, 0x18, 0x65, 0x55, 0x4d, 0xe9, 0x61, 0xc4, 0x24, 0x0b, + 0x74, 0x3f, 0xfa, 0xe8, 0x5d, 0x5e, 0x54, 0x03, 0xad, 0x7e, 0x0d, 0x17, 0x5b, 0x7c, 0x84, 0xa9, + 0x81, 0x8e, 0x61, 0x46, 0x87, 0xe4, 0xeb, 0x6d, 0x79, 0x49, 0xa5, 0xc3, 0x48, 0xd5, 0x82, 0xd3, + 0x21, 0x69, 0xae, 0xd2, 0x21, 0xc1, 0xd7, 0x75, 0x94, 0x85, 0xc7, 0xc7, 0x7e, 0x23, 0xad, 0xeb, + 0xa5, 0x7c, 0x23, 0xad, 0xcf, 0x96, 0x8a, 0x8d, 0xb4, 0x5e, 0x2a, 0xcd, 0x35, 0xd2, 0xfa, 0x7c, + 0x69, 0xa1, 0x91, 0xd6, 0x17, 0x4a, 0x8b, 0xd5, 0xef, 0xa7, 0x50, 0x71, 0xa4, 0x48, 0x85, 0x5f, + 0x44, 0x69, 0x38, 0x71, 0xb4, 0xe4, 0x15, 0x84, 0xab, 0x1e, 0x37, 0x20, 0xc7, 0x6b, 0x48, 0x8f, + 0x8a, 0x85, 0xa2, 0x20, 0x03, 0x47, 0x7f, 0x84, 0xc9, 0x47, 0x7f, 0x84, 0xe1, 0x3a, 0xca, 0xf5, + 0xf8, 0x51, 0x21, 0x0e, 0x7f, 0xd8, 0x25, 0x04, 0x24, 0x1f, 0x68, 0x02, 0x92, 0xce, 0xa3, 0xf4, + 0x29, 0x0a, 0xa2, 0x71, 0xad, 0x2c, 0xf3, 0x2c, 0xb5, 0xb2, 0xea, 0x87, 0x08, 0x43, 0x78, 0xb7, + 0x03, 0x8f, 0x98, 0xbd, 0xe8, 0x2c, 0x5b, 0x41, 0xa9, 0x38, 0x09, 0x2a, 0x0d, 0x07, 0xc6, 0xb4, + 0x23, 0x9f, 0xf0, 0x29, 0xc7, 0xc6, 0xeb, 0xc9, 0x68, 0xf8, 0xe9, 0x34, 0x07, 0x1d, 0xca, 0x27, + 0xe2, 0x49, 0x03, 0xac, 0xfe, 0x34, 0x85, 0x66, 0x1a, 0x90, 0x19, 0x35, 0x79, 0x1e, 0x77, 0x8a, + 0x7e, 0x5f, 0x42, 0x99, 0x87, 0x66, 0x60, 0xed, 0x42, 0xaf, 0x3a, 0x1f, 0x1a, 0x00, 0xf2, 0xd0, + 0x00, 0xc0, 0x1b, 0xa8, 0xb8, 0xe3, 0xd1, 0x5e, 0x4b, 0x74, 0xc7, 0xb2, 0x17, 0x1e, 0x78, 0xd8, + 0xb3, 0x98, 0x48, 0x38, 0xaa, 0xa4, 0x2f, 0x33, 0x8a, 0x20, 0x49, 0xd8, 0xd2, 0x27, 0x26, 0x6c, + 0x6f, 0xa0, 0x59, 0xe2, 0x79, 0xd4, 0xdb, 0xda, 0xb9, 0xe3, 0xf8, 0x3e, 0x63, 0x74, 0x06, 0x7c, + 0x84, 0x65, 0xa6, 0x4a, 0x24, 0xe5, 0x11, 0x9d, 0xea, 0x2f, 0x35, 0x34, 0xfd, 0x2e, 0xf3, 0x3f, + 0x8a, 0x49, 0xec, 0x81, 0x76, 0xa2, 0x07, 0x67, 0xcb, 0x49, 0xaf, 0xa3, 0x1c, 0xc4, 0x29, 0x8e, + 0x0f, 0x3f, 0x77, 0x3c, 0xda, 0x53, 0x14, 0xb2, 0x1c, 0xb9, 0xf6, 0x36, 0xca, 0x00, 0xad, 0x70, + 0x1e, 0x65, 0x36, 0x99, 0xef, 0xa5, 0x0b, 0xb8, 0x80, 0x72, 0x9b, 0x07, 0x8e, 0x15, 0x10, 0xbb, + 0xa4, 0xe1, 0x1c, 0x9a, 0xba, 0x7b, 0xf7, 0x4e, 0x29, 0x85, 0x17, 0x50, 0xe9, 0x0d, 0x62, 0xda, + 0x5d, 0xc7, 0x25, 0x9b, 0x8f, 0xf8, 0x11, 0x53, 0x9a, 0xc2, 0xd3, 0x48, 0x6f, 0x92, 0x3d, 0x02, + 0x8d, 0xd3, 0x6b, 0x9f, 0x6a, 0x28, 0xc3, 0x93, 0x6f, 0x82, 0x8a, 0x6f, 0x91, 0x80, 0xf3, 0x01, + 0x10, 0x1f, 0xe3, 0xf8, 0x34, 0x8b, 0x29, 0x52, 0xb9, 0x98, 0xf0, 0x4c, 0xe1, 0x6c, 0xf5, 0xea, + 0xf7, 0x3e, 0xf9, 0xc7, 0xcf, 0x52, 0x2f, 0x54, 0xcb, 0xf5, 0x83, 0xff, 0xaf, 0xef, 0xd1, 0xf6, + 0x75, 0x9f, 0x04, 0xf5, 0xc7, 0x10, 0x98, 0x8f, 0xea, 0x8f, 0x1d, 0xfb, 0xa3, 0x9b, 0xda, 0xb5, + 0x57, 0x34, 0x7c, 0x13, 0x65, 0x20, 0xbc, 0x98, 0x13, 0x56, 0x0e, 0xf5, 0xf1, 0xb6, 0xa7, 0x7e, + 0x90, 0xd2, 0x40, 0x37, 0x7b, 0x1b, 0x7e, 0x86, 0x80, 0x97, 0x8e, 0xe4, 0xe2, 0x9b, 0x2c, 0x48, + 0x15, 0xbe, 0x97, 0xf3, 0x46, 0x1b, 0xbb, 0xc4, 0xda, 0x6f, 0x12, 0xbf, 0x4f, 0x5d, 0x9f, 0xac, + 0xbf, 0xf7, 0xa7, 0x27, 0xcb, 0xda, 0xc7, 0x4f, 0x96, 0xb5, 0xbf, 0x3d, 0x59, 0xd6, 0x7e, 0xfc, + 0x74, 0xf9, 0xc2, 0xc7, 0x4f, 0x97, 0x2f, 0xfc, 0xf5, 0xe9, 0xf2, 0x85, 0xef, 0xfc, 0x5f, 0xc7, + 0x09, 0x76, 0xc3, 0x76, 0xcd, 0xa2, 0xbd, 0xba, 0xe9, 0xf5, 0x4c, 0xdb, 0xec, 0x7b, 0x94, 0x05, + 0x48, 0xfc, 0x15, 0xfd, 0x3a, 0xe1, 0x37, 0xa9, 0x85, 0x5b, 0x00, 0xdc, 0xe3, 0xe2, 0xda, 0x16, + 0xad, 0xdd, 0xea, 0x3b, 0xed, 0x2c, 0xf8, 0x70, 0xe3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe2, + 0x06, 0x5e, 0x18, 0x7c, 0x31, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3754,10 +3754,10 @@ func (m *JobPreemptedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x42 } - if len(m.PreemptiveJobId) > 0 { - i -= len(m.PreemptiveJobId) - copy(dAtA[i:], m.PreemptiveJobId) - i = encodeVarintEvent(dAtA, i, uint64(len(m.PreemptiveJobId))) + if len(m.PreemptingJobId) > 0 { + i -= len(m.PreemptingJobId) + copy(dAtA[i:], m.PreemptingJobId) + i = encodeVarintEvent(dAtA, i, uint64(len(m.PreemptingJobId))) i-- dAtA[i] = 0x3a } @@ -5518,7 +5518,7 @@ func (m *JobPreemptedEvent) Size() (n int) { if l > 0 { n += 1 + l + sovEvent(uint64(l)) } - l = len(m.PreemptiveJobId) + l = len(m.PreemptingJobId) if l > 0 { n += 1 + l + sovEvent(uint64(l)) } @@ -9629,7 +9629,7 @@ func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreemptiveJobId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreemptingJobId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9657,7 +9657,7 @@ func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PreemptiveJobId = string(dAtA[iNdEx:postIndex]) + m.PreemptingJobId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 8: if wireType != 2 { diff --git a/pkg/api/event.proto b/pkg/api/event.proto index 8a8e09de313..79d0ec176e9 100644 --- a/pkg/api/event.proto +++ b/pkg/api/event.proto @@ -131,7 +131,7 @@ message JobPreemptedEvent { google.protobuf.Timestamp created = 4; string cluster_id = 5; string run_id = 6; - string preemptive_job_id = 7; + string preempting_job_id = 7; string preemptive_run_id = 8; string reason = 9; } diff --git a/pkg/armadaevents/events.pb.go b/pkg/armadaevents/events.pb.go index 528652f2503..c7839b6e68c 100644 --- a/pkg/armadaevents/events.pb.go +++ b/pkg/armadaevents/events.pb.go @@ -3365,7 +3365,7 @@ type JobRunPreempted struct { PreemptedJobId string `protobuf:"bytes,5,opt,name=preempted_job_id,json=preemptedJobId,proto3" json:"preemptedJobId,omitempty"` PreemptedRunId string `protobuf:"bytes,6,opt,name=preempted_run_id,json=preemptedRunId,proto3" json:"preemptedRunId,omitempty"` Reason string `protobuf:"bytes,7,opt,name=reason,proto3" json:"reason,omitempty"` - PreemptiveJobId string `protobuf:"bytes,8,opt,name=preemptive_job_id,json=preemptiveJobId,proto3" json:"preemptiveJobId,omitempty"` + PreemptingJobId string `protobuf:"bytes,8,opt,name=preempting_job_id,json=preemptingJobId,proto3" json:"preemptingJobId,omitempty"` } func (m *JobRunPreempted) Reset() { *m = JobRunPreempted{} } @@ -3422,9 +3422,9 @@ func (m *JobRunPreempted) GetReason() string { return "" } -func (m *JobRunPreempted) GetPreemptiveJobId() string { +func (m *JobRunPreempted) GetPreemptingJobId() string { if m != nil { - return m.PreemptiveJobId + return m.PreemptingJobId } return "" } @@ -3978,7 +3978,7 @@ var fileDescriptor_6aab92ca59e015f8 = []byte{ 0xc7, 0xe6, 0xbf, 0x0e, 0xb3, 0x8a, 0x4c, 0xeb, 0xf8, 0x72, 0xbe, 0x4e, 0x04, 0x0d, 0x84, 0x68, 0xb8, 0xff, 0x3a, 0x94, 0xfa, 0xc1, 0x43, 0x93, 0x97, 0xa9, 0xe9, 0x68, 0xda, 0x2a, 0xc4, 0xad, 0xc7, 0xea, 0xd5, 0xa2, 0x8c, 0x91, 0xe5, 0xf0, 0x12, 0x36, 0xa3, 0x90, 0xd3, 0x88, 0xd5, 0xb2, - 0x45, 0x19, 0x23, 0x98, 0x28, 0x3b, 0xc1, 0x87, 0xe1, 0x16, 0x9c, 0x0e, 0x66, 0xe4, 0xf6, 0x71, + 0x45, 0x19, 0x23, 0x98, 0x28, 0x3b, 0xc1, 0x87, 0xe1, 0x16, 0x9c, 0x0e, 0x66, 0xe4, 0xac, 0x4e, 0xb0, 0xfc, 0x5c, 0x94, 0x33, 0x46, 0xc8, 0xf8, 0xfa, 0x67, 0x62, 0x28, 0x5a, 0x4d, 0xa7, 0xab, 0x9f, 0x69, 0x30, 0x13, 0xfb, 0x1d, 0x03, 0xba, 0x0c, 0x39, 0xfa, 0x23, 0xc3, 0xa8, 0x8f, 0x40, 0x37, 0x9a, 0xc2, 0x24, 0x99, 0x59, 0x0e, 0x42, 0x6f, 0x40, 0x3e, 0xfc, 0x69, 0x03, 0xbf, 0xcd, @@ -3997,7 +3997,7 @@ var fileDescriptor_6aab92ca59e015f8 = []byte{ 0xcb, 0x1d, 0xd3, 0xdb, 0xf5, 0x5b, 0xb5, 0xb6, 0xdd, 0xe3, 0xbf, 0x96, 0xee, 0x3b, 0x36, 0x89, 0x59, 0xfc, 0x69, 0x25, 0xfe, 0x33, 0xea, 0x3f, 0x24, 0xce, 0xad, 0xd2, 0xc7, 0x4d, 0x46, 0x57, 0xbb, 0x65, 0xd7, 0x18, 0x80, 0xfe, 0x70, 0xd6, 0x6d, 0x65, 0xe8, 0x0f, 0x64, 0x5f, 0xff, 0x4f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xd1, 0x6a, 0x53, 0x7f, 0x81, 0x3d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x73, 0x3b, 0x04, 0xd8, 0x81, 0x3d, 0x00, 0x00, } func (m *EventSequence) Marshal() (dAtA []byte, err error) { @@ -7027,10 +7027,10 @@ func (m *JobRunPreempted) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.PreemptiveJobId) > 0 { - i -= len(m.PreemptiveJobId) - copy(dAtA[i:], m.PreemptiveJobId) - i = encodeVarintEvents(dAtA, i, uint64(len(m.PreemptiveJobId))) + if len(m.PreemptingJobId) > 0 { + i -= len(m.PreemptingJobId) + copy(dAtA[i:], m.PreemptingJobId) + i = encodeVarintEvents(dAtA, i, uint64(len(m.PreemptingJobId))) i-- dAtA[i] = 0x42 } @@ -8695,7 +8695,7 @@ func (m *JobRunPreempted) Size() (n int) { if l > 0 { n += 1 + l + sovEvents(uint64(l)) } - l = len(m.PreemptiveJobId) + l = len(m.PreemptingJobId) if l > 0 { n += 1 + l + sovEvents(uint64(l)) } @@ -16900,7 +16900,7 @@ func (m *JobRunPreempted) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreemptiveJobId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreemptingJobId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -16928,7 +16928,7 @@ func (m *JobRunPreempted) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PreemptiveJobId = string(dAtA[iNdEx:postIndex]) + m.PreemptingJobId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/pkg/armadaevents/events.proto b/pkg/armadaevents/events.proto index f99d5fb1f60..ab6588c487e 100644 --- a/pkg/armadaevents/events.proto +++ b/pkg/armadaevents/events.proto @@ -545,7 +545,7 @@ message JobRunPreempted{ string preempted_job_id = 5; string preempted_run_id = 6; string reason = 7; - string preemptive_job_id = 8; + string preempting_job_id = 8; } // Message used internally by Armada to see if messages can be propagated through a pulsar partition From 4e6bc0ccadb52e69db1850177b89a8b7ec1446c5 Mon Sep 17 00:00:00 2001 From: William Vega Date: Thu, 14 May 2026 09:16:38 -0500 Subject: [PATCH 13/16] fix: add test Signed-off-by: William Vega --- ...etjobrunschedulerterminationreason_test.go | 108 ++++++++++++++++++ internal/lookout/repository/util.go | 39 +++++++ 2 files changed, 147 insertions(+) create mode 100644 internal/lookout/repository/getjobrunschedulerterminationreason_test.go diff --git a/internal/lookout/repository/getjobrunschedulerterminationreason_test.go b/internal/lookout/repository/getjobrunschedulerterminationreason_test.go new file mode 100644 index 00000000000..215b7e967a3 --- /dev/null +++ b/internal/lookout/repository/getjobrunschedulerterminationreason_test.go @@ -0,0 +1,108 @@ +package repository + +import ( + "encoding/json" + "testing" + + "github.com/jackc/pgx/v5/pgxpool" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/armadaproject/armada/internal/common/armadacontext" + "github.com/armadaproject/armada/internal/common/compress" + "github.com/armadaproject/armada/internal/common/database/lookout" + "github.com/armadaproject/armada/internal/lookoutingester/instructions" + "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb" + "github.com/armadaproject/armada/internal/lookoutingester/metrics" +) + +func TestGetJobRunSchedulerTerminationReason(t *testing.T) { + err := lookout.WithLookoutDb(func(db *pgxpool.Pool) error { + converter := instructions.NewInstructionConverter(metrics.Get().Metrics, userAnnotationPrefix, []string{}, &compress.NoOpCompressor{}) + store := lookoutdb.NewLookoutDb(db, nil, metrics.Get(), 10, 10) + + _ = NewJobSimulator(converter, store). + Submit(queue, jobSet, owner, namespace, baseTime, basicJobOpts). + Lease(runId, cluster, node, pool, baseTime). + Pending(runId, cluster, baseTime). + Running(runId, node, baseTime). + PreemptedWithRunId(runId, "job preempted by fair-share", "preempting-job-id-123", baseTime). + Build(). + ApiJob() + + repo := NewSqlGetJobRunSchedulerTerminationReasonRepository(db) + result, err := repo.GetJobRunSchedulerTerminationReason(armadacontext.TODO(), runId) + require.NoError(t, err) + + var parsed map[string]any + require.NoError(t, json.Unmarshal([]byte(result), &parsed)) + assert.Equal(t, "job preempted by fair-share", parsed["reason"]) + args, ok := parsed["args"].(map[string]any) + require.True(t, ok, "expected args field in scheduler termination reason") + assert.Equal(t, "preempting-job-id-123", args["preemptingJobId"]) + + return nil + }) + assert.NoError(t, err) +} + +func TestGetJobRunSchedulerTerminationReasonNoPreemptingJob(t *testing.T) { + err := lookout.WithLookoutDb(func(db *pgxpool.Pool) error { + converter := instructions.NewInstructionConverter(metrics.Get().Metrics, userAnnotationPrefix, []string{}, &compress.NoOpCompressor{}) + store := lookoutdb.NewLookoutDb(db, nil, metrics.Get(), 10, 10) + + _ = NewJobSimulator(converter, store). + Submit(queue, jobSet, owner, namespace, baseTime, basicJobOpts). + Lease(runId, cluster, node, pool, baseTime). + Pending(runId, cluster, baseTime). + Running(runId, node, baseTime). + PreemptedWithRunId(runId, "job preempted", "", baseTime). + Build(). + ApiJob() + + repo := NewSqlGetJobRunSchedulerTerminationReasonRepository(db) + result, err := repo.GetJobRunSchedulerTerminationReason(armadacontext.TODO(), runId) + require.NoError(t, err) + + var parsed map[string]any + require.NoError(t, json.Unmarshal([]byte(result), &parsed)) + assert.Equal(t, "job preempted", parsed["reason"]) + assert.Nil(t, parsed["args"]) + + return nil + }) + assert.NoError(t, err) +} + +func TestGetJobRunSchedulerTerminationReasonNotFound(t *testing.T) { + err := lookout.WithLookoutDb(func(db *pgxpool.Pool) error { + repo := NewSqlGetJobRunSchedulerTerminationReasonRepository(db) + _, err := repo.GetJobRunSchedulerTerminationReason(armadacontext.TODO(), runId) + assert.ErrorIs(t, err, ErrNotFound) + return nil + }) + assert.NoError(t, err) +} + +func TestGetJobRunSchedulerTerminationReasonNullForNonPreemptedRun(t *testing.T) { + err := lookout.WithLookoutDb(func(db *pgxpool.Pool) error { + converter := instructions.NewInstructionConverter(metrics.Get().Metrics, userAnnotationPrefix, []string{}, &compress.NoOpCompressor{}) + store := lookoutdb.NewLookoutDb(db, nil, metrics.Get(), 10, 10) + + _ = NewJobSimulator(converter, store). + Submit(queue, jobSet, owner, namespace, baseTime, basicJobOpts). + Lease(runId, cluster, node, pool, baseTime). + Pending(runId, cluster, baseTime). + Running(runId, node, baseTime). + RunFailed(runId, node, 137, "oom killed", "", baseTime). + Failed(node, 137, "", baseTime). + Build(). + ApiJob() + + repo := NewSqlGetJobRunSchedulerTerminationReasonRepository(db) + _, err := repo.GetJobRunSchedulerTerminationReason(armadacontext.TODO(), runId) + assert.ErrorIs(t, err, ErrNotFound) + return nil + }) + assert.NoError(t, err) +} diff --git a/internal/lookout/repository/util.go b/internal/lookout/repository/util.go index 777276315ea..fcbf2c43502 100644 --- a/internal/lookout/repository/util.go +++ b/internal/lookout/repository/util.go @@ -577,6 +577,45 @@ func (js *JobSimulator) Preempted(timestamp time.Time) *JobSimulator { return js } +func (js *JobSimulator) PreemptedWithRunId(runId string, reason string, preemptingJobId string, timestamp time.Time) *JobSimulator { + ts := timestampOrNow(timestamp) + preemptedTime := protoutil.ToStdTime(ts) + + preemptedJob := &armadaevents.EventSequence_Event{ + Created: ts, + Event: &armadaevents.EventSequence_Event_JobErrors{ + JobErrors: &armadaevents.JobErrors{ + JobId: js.jobId, + Errors: []*armadaevents.Error{ + { + Terminal: true, + Reason: &armadaevents.Error_JobRunPreemptedError{ + JobRunPreemptedError: &armadaevents.JobRunPreemptedError{}, + }, + }, + }, + }, + }, + } + + preemptedRun := &armadaevents.EventSequence_Event{ + Created: ts, + Event: &armadaevents.EventSequence_Event_JobRunPreempted{ + JobRunPreempted: &armadaevents.JobRunPreempted{ + PreemptedJobId: js.jobId, + PreemptedRunId: runId, + PreemptingJobId: preemptingJobId, + Reason: reason, + }, + }, + } + js.events = append(js.events, preemptedJob, preemptedRun) + + js.job.LastTransitionTime = preemptedTime + js.job.State = string(lookout.JobPreempted) + return js +} + func (js *JobSimulator) LeaseExpired(runId string, timestamp time.Time, _ clock.Clock) *JobSimulator { ts := timestampOrNow(timestamp) leaseExpiredTime := protoutil.ToStdTime(ts) From 06af2b122b2ae77f1426897b9a2772ee763688fe Mon Sep 17 00:00:00 2001 From: William Vega Date: Thu, 14 May 2026 09:17:59 -0500 Subject: [PATCH 14/16] fix: col nil if all args empty Signed-off-by: William Vega --- internal/lookoutingester/instructions/instructions.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/lookoutingester/instructions/instructions.go b/internal/lookoutingester/instructions/instructions.go index ce01a26afb6..c55a966a1d9 100644 --- a/internal/lookoutingester/instructions/instructions.go +++ b/internal/lookoutingester/instructions/instructions.go @@ -476,16 +476,20 @@ func (c *InstructionConverter) handleJobRunErrors(ts time.Time, event *armadaeve } func (c *InstructionConverter) handleJobRunPreempted(ts time.Time, event *armadaevents.JobRunPreempted, update *model.InstructionSet) error { - terminationReasonArgs := map[string]any{} + var terminationReasonArgs map[string]any if event.PreemptingJobId != "" { - terminationReasonArgs["preemptingJobId"] = event.PreemptingJobId + terminationReasonArgs = map[string]any{"preemptingJobId": event.PreemptingJobId} + } + var terminationReason map[string]any + if event.Reason != "" || terminationReasonArgs != nil { + terminationReason = BuildTerminationReason(event.Reason, terminationReasonArgs) } jobRun := model.UpdateJobRunInstruction{ RunId: event.PreemptedRunId, JobRunState: pointer.Int32(lookout.JobRunPreemptedOrdinal), Finished: &ts, Error: tryCompressError(event.PreemptedJobId, event.Reason, c.compressor), - SchedulerTerminationReason: BuildTerminationReason(event.Reason, terminationReasonArgs), + SchedulerTerminationReason: terminationReason, } update.JobRunsToUpdate = append(update.JobRunsToUpdate, &jobRun) return nil From 7a2dbdf174f59aa4058df9fc71d21c5b1255d46f Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 19 May 2026 11:42:58 -0500 Subject: [PATCH 15/16] fix: preemptive_job_id was not used but we will use preempting_job_id Signed-off-by: William Vega --- pkg/api/event.pb.go | 348 ++++++++++++++++++++++---------------------- pkg/api/event.proto | 3 +- 2 files changed, 176 insertions(+), 175 deletions(-) diff --git a/pkg/api/event.pb.go b/pkg/api/event.pb.go index f0b1f34ee66..a687b82b867 100644 --- a/pkg/api/event.pb.go +++ b/pkg/api/event.pb.go @@ -1089,9 +1089,9 @@ type JobPreemptedEvent struct { Created *types.Timestamp `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"` ClusterId string `protobuf:"bytes,5,opt,name=cluster_id,json=clusterId,proto3" json:"clusterId,omitempty"` RunId string `protobuf:"bytes,6,opt,name=run_id,json=runId,proto3" json:"runId,omitempty"` - PreemptingJobId string `protobuf:"bytes,7,opt,name=preempting_job_id,json=preemptingJobId,proto3" json:"preemptingJobId,omitempty"` PreemptiveRunId string `protobuf:"bytes,8,opt,name=preemptive_run_id,json=preemptiveRunId,proto3" json:"preemptiveRunId,omitempty"` Reason string `protobuf:"bytes,9,opt,name=reason,proto3" json:"reason,omitempty"` + PreemptingJobId string `protobuf:"bytes,10,opt,name=preempting_job_id,json=preemptingJobId,proto3" json:"preemptingJobId,omitempty"` } func (m *JobPreemptedEvent) Reset() { *m = JobPreemptedEvent{} } @@ -1169,23 +1169,23 @@ func (m *JobPreemptedEvent) GetRunId() string { return "" } -func (m *JobPreemptedEvent) GetPreemptingJobId() string { +func (m *JobPreemptedEvent) GetPreemptiveRunId() string { if m != nil { - return m.PreemptingJobId + return m.PreemptiveRunId } return "" } -func (m *JobPreemptedEvent) GetPreemptiveRunId() string { +func (m *JobPreemptedEvent) GetReason() string { if m != nil { - return m.PreemptiveRunId + return m.Reason } return "" } -func (m *JobPreemptedEvent) GetReason() string { +func (m *JobPreemptedEvent) GetPreemptingJobId() string { if m != nil { - return m.Reason + return m.PreemptingJobId } return "" } @@ -2479,156 +2479,156 @@ func init() { func init() { proto.RegisterFile("pkg/api/event.proto", fileDescriptor_7758595c3bb8cf56) } var fileDescriptor_7758595c3bb8cf56 = []byte{ - // 2375 bytes of a gzipped FileDescriptorProto + // 2383 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4d, 0x6c, 0x1b, 0xc7, - 0xf5, 0xf7, 0x52, 0xfc, 0x58, 0x0e, 0x25, 0x91, 0x1a, 0x7d, 0x98, 0xa6, 0x1d, 0xad, 0x40, 0x03, - 0xf9, 0x2b, 0x46, 0x4c, 0xe6, 0x2f, 0x27, 0x45, 0x60, 0x14, 0x28, 0x2c, 0x45, 0x89, 0xc5, 0xc6, - 0xb5, 0x4d, 0x39, 0x48, 0x5a, 0x04, 0x60, 0x97, 0xbb, 0x23, 0x6a, 0x25, 0x72, 0x87, 0xd9, 0x0f, - 0xd9, 0x8a, 0x91, 0x4b, 0x7b, 0xe9, 0xa1, 0x28, 0xfa, 0x81, 0xde, 0x8a, 0xb6, 0xe7, 0x1e, 0x7b, + 0xf5, 0xf7, 0x52, 0xfc, 0x58, 0x0e, 0x25, 0x91, 0x1a, 0x7d, 0x98, 0xa6, 0x1d, 0x51, 0xa0, 0x81, + 0xfc, 0x15, 0x23, 0x26, 0xf3, 0x97, 0x93, 0x22, 0x30, 0x0a, 0x14, 0x96, 0xa2, 0xc4, 0x62, 0xe3, + 0xda, 0xa6, 0x1c, 0x24, 0x2d, 0x02, 0xb0, 0xcb, 0xdd, 0x11, 0xb5, 0x12, 0xb9, 0xc3, 0xcc, 0xee, + 0xca, 0x56, 0x8c, 0x5c, 0xda, 0x4b, 0x0f, 0x45, 0xd1, 0x8f, 0x63, 0x8b, 0xb6, 0xe7, 0x1e, 0x7b, 0xe9, 0xad, 0xe8, 0xa9, 0x28, 0x7a, 0x0a, 0x9a, 0x4b, 0x4f, 0x44, 0x6b, 0x17, 0x29, 0x40, 0xf4, - 0xd0, 0x4b, 0xef, 0xc5, 0xbc, 0x99, 0xdd, 0x9d, 0xa1, 0x28, 0x48, 0x56, 0x3e, 0x6a, 0x28, 0x3c, - 0xd9, 0xfa, 0xbd, 0x79, 0x6f, 0xde, 0xbc, 0xf9, 0xcd, 0xcc, 0x9b, 0x7d, 0x43, 0x34, 0xdf, 0xdf, - 0xef, 0xd4, 0xcd, 0xbe, 0x53, 0x27, 0x07, 0xc4, 0x0d, 0x6a, 0x7d, 0x8f, 0x06, 0x14, 0x4f, 0x99, - 0x7d, 0xa7, 0x62, 0x74, 0x28, 0xed, 0x74, 0x49, 0x1d, 0xa0, 0x76, 0xb8, 0x53, 0x0f, 0x9c, 0x1e, - 0xf1, 0x03, 0xb3, 0xd7, 0xe7, 0xad, 0x2a, 0x0b, 0x91, 0xaa, 0x1f, 0xb6, 0x7b, 0x4e, 0x30, 0x8a, - 0xee, 0x12, 0xb3, 0x1b, 0xec, 0x0a, 0xf4, 0xf2, 0xa8, 0x31, 0xd2, 0xeb, 0x07, 0x87, 0x42, 0x78, - 0x45, 0x08, 0x99, 0x96, 0xe9, 0xba, 0x34, 0x30, 0x03, 0x87, 0xba, 0xbe, 0x90, 0xbe, 0xba, 0xff, - 0xba, 0x5f, 0x73, 0x28, 0x93, 0xf6, 0x4c, 0x6b, 0xd7, 0x71, 0x89, 0x77, 0x58, 0x8f, 0x3a, 0xf1, - 0x88, 0x4f, 0x43, 0xcf, 0x22, 0xf5, 0x0e, 0x71, 0x89, 0x67, 0x06, 0xc4, 0xe6, 0x5a, 0xd5, 0x5f, - 0xa4, 0xd0, 0x5c, 0x83, 0xb6, 0xb7, 0xc1, 0xb5, 0x80, 0xd8, 0x9b, 0x6c, 0x78, 0xf8, 0x1a, 0xca, - 0xee, 0xd1, 0x76, 0xcb, 0xb1, 0xcb, 0xda, 0x8a, 0xb6, 0x9a, 0x5f, 0x9f, 0x1f, 0x0e, 0x8c, 0xe2, - 0x1e, 0x6d, 0x6f, 0xd9, 0x2f, 0xd3, 0x9e, 0x13, 0x80, 0x53, 0xcd, 0x0c, 0x00, 0xf8, 0x55, 0x84, - 0x58, 0x5b, 0x9f, 0x04, 0xac, 0x7d, 0x0a, 0xda, 0x2f, 0x0d, 0x07, 0x06, 0xde, 0xa3, 0xed, 0x6d, - 0x12, 0x28, 0x2a, 0x7a, 0x84, 0xe1, 0x97, 0x50, 0xe6, 0x83, 0x90, 0x84, 0xa4, 0x3c, 0x95, 0x74, - 0x00, 0x80, 0xdc, 0x01, 0x00, 0xf8, 0x9b, 0x28, 0x67, 0x79, 0x84, 0xf9, 0x5c, 0x4e, 0xaf, 0x68, - 0xab, 0x85, 0xb5, 0x4a, 0x8d, 0x07, 0xa2, 0x16, 0x45, 0xa9, 0xf6, 0x20, 0x0a, 0xf9, 0xfa, 0xe2, - 0x70, 0x60, 0xcc, 0x89, 0xe6, 0x92, 0xa9, 0xc8, 0x02, 0xbe, 0x8e, 0xa6, 0xf6, 0x68, 0xbb, 0x9c, - 0x01, 0x43, 0x7a, 0xcd, 0xec, 0x3b, 0xb5, 0x06, 0x6d, 0xaf, 0xcf, 0x0d, 0x07, 0xc6, 0xcc, 0x1e, - 0x6d, 0x4b, 0x2a, 0xac, 0x5d, 0x75, 0xa8, 0xa1, 0xd9, 0x06, 0x6d, 0xdf, 0x67, 0x8e, 0x9c, 0xf7, - 0xd8, 0x54, 0xff, 0x9c, 0x82, 0xc1, 0xbe, 0x4d, 0x4c, 0xff, 0xfc, 0x13, 0xe1, 0x6b, 0x08, 0x59, - 0xdd, 0xd0, 0x0f, 0x88, 0xc7, 0xbc, 0xcd, 0x40, 0xe7, 0x17, 0x87, 0x03, 0x63, 0x5e, 0xa0, 0x8a, - 0xbb, 0xf9, 0x18, 0xc4, 0x2f, 0xa2, 0x74, 0x9f, 0xd2, 0x6e, 0x39, 0x0b, 0x1a, 0x78, 0x38, 0x30, - 0x66, 0xd9, 0xdf, 0x52, 0x63, 0x90, 0x57, 0x7f, 0x92, 0x46, 0x8b, 0x51, 0x30, 0x9b, 0x24, 0x08, - 0x3d, 0x77, 0x12, 0xd3, 0xe3, 0x62, 0xfa, 0x32, 0xca, 0x7a, 0xc4, 0xf4, 0xa9, 0x2b, 0xa2, 0xba, - 0x30, 0x1c, 0x18, 0x25, 0x8e, 0x48, 0x0a, 0xa2, 0x0d, 0xfe, 0x06, 0x9a, 0xd9, 0x0f, 0xdb, 0xc4, - 0x73, 0x49, 0x40, 0x7c, 0xd6, 0x51, 0x0e, 0x94, 0x2a, 0xc3, 0x81, 0xb1, 0x94, 0x08, 0x94, 0xbe, - 0xa6, 0x65, 0x9c, 0xb9, 0xd9, 0xa7, 0x76, 0xcb, 0x0d, 0x7b, 0x6d, 0xe2, 0x95, 0xf5, 0x15, 0x6d, - 0x35, 0xc3, 0xdd, 0xec, 0x53, 0xfb, 0x5b, 0x00, 0xca, 0x6e, 0xc6, 0x20, 0xeb, 0xd8, 0x0b, 0xdd, - 0x96, 0x19, 0x80, 0x88, 0xd8, 0xe5, 0xfc, 0x8a, 0xb6, 0xaa, 0xf3, 0x8e, 0xbd, 0xd0, 0xbd, 0x15, - 0xe1, 0x72, 0xc7, 0x32, 0x5e, 0xfd, 0xb7, 0x86, 0x16, 0x22, 0x4e, 0x6c, 0x3e, 0xea, 0x3b, 0xde, - 0xf9, 0xdf, 0x53, 0x7e, 0x97, 0x46, 0xc5, 0x06, 0x6d, 0xdf, 0x23, 0xae, 0xed, 0xb8, 0x9d, 0xc9, - 0x02, 0x18, 0xbf, 0x00, 0x8e, 0x50, 0x3a, 0xfb, 0x99, 0x28, 0x9d, 0x3b, 0x35, 0xa5, 0x5f, 0x41, - 0x3a, 0xe8, 0x99, 0x3d, 0x02, 0x0b, 0x21, 0xcf, 0x87, 0xc8, 0x1a, 0x98, 0x3d, 0x39, 0x5a, 0x39, - 0x01, 0x31, 0x57, 0x23, 0x0d, 0xbf, 0x6f, 0x5a, 0x04, 0x16, 0x81, 0x70, 0x55, 0xb4, 0x01, 0x5c, - 0x76, 0x55, 0xc6, 0xe3, 0x0d, 0x14, 0x9d, 0xb0, 0x81, 0xfe, 0x8b, 0x33, 0xa7, 0x19, 0xba, 0xee, - 0x84, 0x39, 0x5f, 0x1c, 0x73, 0x6e, 0xa0, 0xbc, 0x4b, 0x6d, 0xc2, 0x29, 0x90, 0x4b, 0xa2, 0xc4, - 0xc0, 0x11, 0x0e, 0xe8, 0x11, 0x76, 0xe6, 0x1d, 0x54, 0xa6, 0x5b, 0xfe, 0x6c, 0x74, 0x43, 0x67, - 0xa4, 0x5b, 0xe1, 0x04, 0xba, 0xfd, 0x36, 0x8b, 0xe6, 0x1b, 0xb4, 0xbd, 0xe5, 0x76, 0x3c, 0xe2, - 0xfb, 0x5b, 0xee, 0x0e, 0x9d, 0x50, 0xee, 0xbc, 0x51, 0x0e, 0x9d, 0x8d, 0x72, 0x85, 0x67, 0xa4, - 0xdc, 0x63, 0x34, 0xe7, 0x70, 0x1a, 0xb5, 0x4c, 0xdb, 0x66, 0xff, 0x12, 0xbf, 0x9c, 0x5f, 0x99, - 0x5a, 0x2d, 0xac, 0xd5, 0xa2, 0x1b, 0xc7, 0x28, 0xcf, 0x6a, 0x02, 0xb8, 0x15, 0x29, 0x6c, 0xba, - 0x81, 0x77, 0xb8, 0xbe, 0x3c, 0x1c, 0x18, 0x15, 0x67, 0x44, 0x24, 0x75, 0x5c, 0x1a, 0x95, 0x55, - 0xf6, 0xd1, 0xe2, 0x58, 0x53, 0xf8, 0x2a, 0x9a, 0xda, 0x27, 0x87, 0xc0, 0xe2, 0x0c, 0xbf, 0xef, - 0xec, 0x93, 0x43, 0xf9, 0xbe, 0xb3, 0x4f, 0x0e, 0x19, 0x17, 0x0f, 0xcc, 0x6e, 0x48, 0x04, 0x79, - 0x81, 0x8b, 0x00, 0xc8, 0x5c, 0x04, 0xe0, 0x66, 0xea, 0x75, 0xad, 0xfa, 0x1f, 0x1d, 0x6e, 0x0c, - 0x6f, 0x9a, 0x4e, 0x77, 0x92, 0xdd, 0x7e, 0x3e, 0xd9, 0xed, 0xfb, 0x08, 0x91, 0x47, 0x4e, 0xd0, - 0xb2, 0xa8, 0x4d, 0xfc, 0x72, 0x0e, 0x58, 0x53, 0x8d, 0x58, 0x23, 0x05, 0xba, 0xb6, 0xf9, 0xc8, - 0x09, 0x36, 0x58, 0x23, 0xce, 0x94, 0x4b, 0xcc, 0x13, 0x12, 0x61, 0x89, 0xe1, 0xb2, 0xd6, 0xcc, - 0xc7, 0xf0, 0xd1, 0xb5, 0xab, 0x7f, 0x96, 0xb5, 0x9b, 0x3f, 0xd3, 0xda, 0x45, 0x67, 0x5a, 0xbb, - 0x33, 0x67, 0x5b, 0xbb, 0xb3, 0xcf, 0xb8, 0x76, 0x6d, 0x84, 0x2d, 0xea, 0x06, 0xa6, 0xe3, 0x12, - 0xaf, 0xe5, 0x07, 0x66, 0x10, 0xb2, 0xc5, 0x5b, 0x80, 0x69, 0x58, 0x80, 0x69, 0xd8, 0x88, 0xc4, - 0xdb, 0x20, 0x5d, 0x37, 0x86, 0x03, 0xe3, 0xb2, 0xa5, 0x82, 0xca, 0x1a, 0x9d, 0x3b, 0x22, 0xc4, - 0xaf, 0xa1, 0x8c, 0x65, 0x86, 0x3e, 0x29, 0x4f, 0xaf, 0x68, 0xab, 0xb3, 0x6b, 0x88, 0x1b, 0x66, - 0x08, 0xa7, 0x33, 0x08, 0x65, 0x3a, 0x03, 0x80, 0x6f, 0xa3, 0xd2, 0x8e, 0xe9, 0x74, 0x43, 0x8f, - 0xb4, 0x2c, 0x33, 0x20, 0x1d, 0xea, 0x1d, 0x96, 0x4b, 0x30, 0xc0, 0x17, 0x86, 0x03, 0xe3, 0x92, - 0x90, 0x6d, 0x08, 0x91, 0xa4, 0x5f, 0x1c, 0x11, 0xe1, 0xfb, 0x68, 0x3e, 0xb2, 0xe4, 0x87, 0xed, - 0xd8, 0xd8, 0x1c, 0x18, 0x5b, 0x19, 0x0e, 0x8c, 0x2b, 0x42, 0xbc, 0x9d, 0x48, 0x25, 0x7b, 0xf8, - 0xa8, 0xb4, 0x62, 0xa3, 0x59, 0x95, 0x92, 0xf2, 0x8e, 0x93, 0x3f, 0xdd, 0x8e, 0x93, 0x39, 0x69, - 0xc7, 0x69, 0xa4, 0xf5, 0x62, 0xa9, 0x54, 0xfd, 0x24, 0x85, 0x30, 0xbb, 0x55, 0x78, 0x84, 0x35, - 0xf8, 0x0a, 0xa4, 0x87, 0xaf, 0xa1, 0xbc, 0x47, 0x3e, 0x08, 0x89, 0x1f, 0x50, 0x4f, 0xde, 0x7a, - 0x62, 0x50, 0x5e, 0x40, 0x31, 0xf8, 0x6c, 0x5b, 0x4f, 0xf5, 0xe7, 0x69, 0xf8, 0x16, 0x28, 0xa2, - 0x3a, 0xd9, 0xd0, 0x8f, 0xdb, 0xd0, 0xaf, 0xa1, 0xac, 0x17, 0xba, 0x49, 0xe6, 0x03, 0x0e, 0x7b, - 0xa1, 0xab, 0x46, 0x04, 0x00, 0xbc, 0x85, 0xe6, 0xfa, 0x31, 0x4b, 0x5b, 0x22, 0x90, 0xb9, 0x64, - 0xcd, 0x26, 0xc2, 0xc6, 0x48, 0x48, 0x8b, 0x23, 0x22, 0xd9, 0xd4, 0x01, 0x69, 0x09, 0x0f, 0xf4, - 0xa3, 0xa6, 0x0e, 0x48, 0x73, 0xc4, 0x97, 0xe2, 0x88, 0x48, 0xe2, 0x45, 0xfe, 0x14, 0xbc, 0xf8, - 0x63, 0x5a, 0x7c, 0x23, 0xb6, 0x2c, 0x42, 0xec, 0x09, 0x2f, 0x26, 0x77, 0xb1, 0xb3, 0xdd, 0xc5, - 0xaa, 0x7f, 0x2f, 0xc0, 0x1d, 0xeb, 0x9d, 0xc0, 0xe9, 0x3a, 0x3e, 0x14, 0x2f, 0x26, 0x54, 0xfa, - 0x82, 0xa8, 0xf4, 0x23, 0x0d, 0x2d, 0xde, 0x31, 0x1f, 0x35, 0x45, 0xdd, 0xc7, 0x7f, 0x93, 0x7a, - 0xf7, 0x88, 0xe7, 0x50, 0x5b, 0xa4, 0x94, 0x37, 0xa2, 0x94, 0x72, 0x74, 0x32, 0x6a, 0x63, 0xb5, - 0x78, 0x8e, 0x79, 0x75, 0x38, 0x30, 0x8c, 0xb1, 0x72, 0xc9, 0x8f, 0xf1, 0xdd, 0xaa, 0xdc, 0xd6, - 0xcf, 0xc4, 0xed, 0xfc, 0xf3, 0x7c, 0xe9, 0xfb, 0xa1, 0x86, 0x96, 0x02, 0x1a, 0x98, 0xdd, 0x96, - 0x15, 0xf6, 0xc2, 0xae, 0x09, 0x9b, 0x74, 0xe8, 0x9b, 0x1d, 0x96, 0xe4, 0xb1, 0x88, 0xaf, 0x1d, - 0x1b, 0xf1, 0x07, 0x4c, 0x6d, 0x23, 0xd6, 0x7a, 0x87, 0x29, 0xf1, 0x80, 0x57, 0x87, 0x03, 0x63, - 0x39, 0x18, 0x23, 0x96, 0xdc, 0x58, 0x18, 0x27, 0x87, 0xf9, 0xbf, 0x75, 0xd0, 0x19, 0x33, 0xff, - 0x33, 0x27, 0xcc, 0xff, 0x58, 0x2d, 0x69, 0xfe, 0xc7, 0xca, 0xe5, 0xf9, 0x1f, 0xdb, 0xa0, 0xf2, - 0x6b, 0x0d, 0x55, 0x8e, 0xa7, 0xd6, 0xe9, 0x72, 0xc5, 0x6f, 0xcb, 0xb9, 0x22, 0xbb, 0x4c, 0xf3, - 0x92, 0x67, 0x4d, 0x2e, 0x79, 0xd6, 0xfa, 0xfb, 0x1d, 0x18, 0x5b, 0x54, 0xf2, 0xac, 0xdd, 0x0f, - 0x4d, 0x37, 0x70, 0x82, 0xc3, 0x93, 0x72, 0xcb, 0xca, 0xaf, 0x34, 0x74, 0xe9, 0xd8, 0xb9, 0x78, - 0x2e, 0x3c, 0x64, 0x41, 0x3c, 0x7e, 0x7e, 0x9e, 0x07, 0x17, 0xab, 0xff, 0x4c, 0xa1, 0xa5, 0x06, - 0x6d, 0x37, 0x49, 0xdf, 0x73, 0xa8, 0xe7, 0x04, 0xce, 0x87, 0x5f, 0x81, 0xf4, 0xfc, 0xeb, 0x68, - 0xda, 0x25, 0x0f, 0x5b, 0x62, 0xc8, 0x87, 0xb0, 0xd1, 0x6b, 0x70, 0x25, 0x5f, 0x74, 0xc9, 0xc3, - 0x7b, 0x02, 0x96, 0x34, 0x0b, 0x12, 0xac, 0x26, 0xf7, 0xd9, 0xd3, 0x26, 0xf7, 0xd5, 0x4f, 0x53, - 0x50, 0x61, 0x94, 0x22, 0x7d, 0xfe, 0x53, 0xb3, 0xff, 0x49, 0xa0, 0xc5, 0x6d, 0x73, 0xc3, 0x74, - 0x2d, 0xd2, 0xed, 0x4e, 0x6e, 0x9b, 0x9f, 0xcf, 0x6d, 0xf3, 0x2f, 0xfc, 0xe5, 0x89, 0x88, 0xea, - 0xf9, 0xa7, 0xee, 0x97, 0x12, 0xd4, 0x3f, 0xa4, 0x81, 0xaa, 0x0f, 0x88, 0xd7, 0x73, 0x5c, 0x73, - 0x72, 0x87, 0x7f, 0xbe, 0x2b, 0xae, 0x5f, 0x52, 0x09, 0x2c, 0xa1, 0x90, 0x7e, 0x0a, 0x0a, 0xfd, - 0xbe, 0x80, 0xa6, 0x81, 0x35, 0x77, 0x88, 0x0f, 0xa9, 0xe4, 0x5d, 0x94, 0xf7, 0xa3, 0xe7, 0x61, - 0xc0, 0x9f, 0xc2, 0xda, 0x52, 0x94, 0x3d, 0xaa, 0xef, 0xc6, 0x78, 0x00, 0xe2, 0xc6, 0x89, 0xf1, - 0xdb, 0x17, 0x9a, 0x89, 0x0d, 0xbc, 0x81, 0xb2, 0xc0, 0x04, 0x5b, 0xa4, 0x20, 0xf3, 0x91, 0x35, - 0xe9, 0x99, 0x15, 0x77, 0x92, 0x37, 0x53, 0xec, 0x08, 0x55, 0x66, 0xa4, 0x0b, 0x0f, 0x95, 0x80, - 0x71, 0x92, 0x11, 0xe9, 0xf9, 0x12, 0x37, 0xc2, 0x9b, 0xa9, 0x46, 0x38, 0x86, 0xbf, 0x8b, 0x66, - 0xe1, 0x7f, 0x2d, 0x4f, 0xbc, 0xd0, 0x89, 0x19, 0x29, 0x1b, 0x53, 0x9e, 0xef, 0xac, 0x5f, 0x1e, - 0x0e, 0x8c, 0x8b, 0x5d, 0x19, 0x57, 0x4c, 0xcf, 0x28, 0x22, 0xfc, 0x3e, 0xe2, 0x40, 0x8b, 0xf0, - 0xf7, 0x1e, 0xe2, 0xe5, 0xd9, 0x25, 0xa5, 0x03, 0xf9, 0x2d, 0x08, 0x9f, 0xd7, 0xae, 0x04, 0x2b, - 0xe6, 0xa7, 0x65, 0x09, 0x7e, 0x0b, 0xe5, 0xfa, 0xfc, 0x65, 0x05, 0xf0, 0x37, 0xfa, 0x44, 0x3d, - 0xf2, 0xe0, 0x42, 0x30, 0x8c, 0x23, 0x8a, 0xb5, 0x48, 0x9b, 0x19, 0xf2, 0x78, 0xa1, 0x1d, 0xa8, - 0x2c, 0x19, 0x92, 0xeb, 0xef, 0xdc, 0x90, 0x68, 0xa8, 0x1a, 0x12, 0x20, 0x9b, 0x96, 0x1d, 0x28, - 0x52, 0x00, 0xb9, 0xa5, 0x69, 0x91, 0x4a, 0x17, 0x7c, 0x5a, 0x78, 0x33, 0x75, 0x5a, 0x38, 0xc6, - 0x19, 0x27, 0x3e, 0x36, 0x01, 0xdb, 0x15, 0xc6, 0xc9, 0x5f, 0xa1, 0x22, 0xc6, 0x09, 0x6c, 0x94, - 0x71, 0x02, 0xc6, 0x2d, 0x34, 0xe3, 0xc9, 0x69, 0x12, 0xdc, 0xee, 0xa4, 0x69, 0x3e, 0x9a, 0x43, - 0xf1, 0x69, 0x56, 0x94, 0xd4, 0x69, 0x56, 0x44, 0x78, 0x1b, 0x21, 0x2b, 0x4e, 0x0f, 0xe0, 0xab, - 0x7e, 0x61, 0xed, 0x62, 0x64, 0x7d, 0x24, 0x71, 0x58, 0x2f, 0x0f, 0x07, 0xc6, 0x42, 0xd2, 0x5c, - 0xb1, 0x2b, 0x99, 0x61, 0x61, 0xb0, 0xa2, 0xd3, 0x11, 0xea, 0x1f, 0x52, 0x18, 0xd4, 0x63, 0x53, - 0x6c, 0x79, 0x11, 0xa6, 0x86, 0x21, 0x86, 0xf1, 0xbb, 0xa8, 0x10, 0x26, 0xd7, 0xbd, 0x72, 0x11, - 0x4c, 0x96, 0x8f, 0xbb, 0x09, 0xf2, 0xb4, 0x4a, 0x52, 0x50, 0xcc, 0xca, 0x96, 0xf0, 0x7b, 0x68, - 0x3a, 0xaa, 0x78, 0x3a, 0xee, 0x0e, 0x85, 0x3a, 0x82, 0x64, 0x79, 0xb4, 0xd8, 0xc9, 0x2d, 0x3b, - 0x09, 0xaa, 0x5a, 0x96, 0x04, 0xd8, 0x42, 0xb3, 0x9e, 0x72, 0x95, 0x28, 0x63, 0xb0, 0x7d, 0x79, - 0xcc, 0xd4, 0xc5, 0x01, 0xbe, 0x32, 0x1c, 0x18, 0x65, 0x55, 0x4d, 0xe9, 0x61, 0xc4, 0x24, 0x0b, - 0x74, 0x3f, 0xfa, 0xe8, 0x5d, 0x5e, 0x54, 0x03, 0xad, 0x7e, 0x0d, 0x17, 0x5b, 0x7c, 0x84, 0xa9, - 0x81, 0x8e, 0x61, 0x46, 0x87, 0xe4, 0xeb, 0x6d, 0x79, 0x49, 0xa5, 0xc3, 0x48, 0xd5, 0x82, 0xd3, - 0x21, 0x69, 0xae, 0xd2, 0x21, 0xc1, 0xd7, 0x75, 0x94, 0x85, 0xc7, 0xc7, 0x7e, 0x23, 0xad, 0xeb, - 0xa5, 0x7c, 0x23, 0xad, 0xcf, 0x96, 0x8a, 0x8d, 0xb4, 0x5e, 0x2a, 0xcd, 0x35, 0xd2, 0xfa, 0x7c, - 0x69, 0xa1, 0x91, 0xd6, 0x17, 0x4a, 0x8b, 0xd5, 0xef, 0xa7, 0x50, 0x71, 0xa4, 0x48, 0x85, 0x5f, - 0x44, 0x69, 0x38, 0x71, 0xb4, 0xe4, 0x15, 0x84, 0xab, 0x1e, 0x37, 0x20, 0xc7, 0x6b, 0x48, 0x8f, - 0x8a, 0x85, 0xa2, 0x20, 0x03, 0x47, 0x7f, 0x84, 0xc9, 0x47, 0x7f, 0x84, 0xe1, 0x3a, 0xca, 0xf5, - 0xf8, 0x51, 0x21, 0x0e, 0x7f, 0xd8, 0x25, 0x04, 0x24, 0x1f, 0x68, 0x02, 0x92, 0xce, 0xa3, 0xf4, - 0x29, 0x0a, 0xa2, 0x71, 0xad, 0x2c, 0xf3, 0x2c, 0xb5, 0xb2, 0xea, 0x87, 0x08, 0x43, 0x78, 0xb7, - 0x03, 0x8f, 0x98, 0xbd, 0xe8, 0x2c, 0x5b, 0x41, 0xa9, 0x38, 0x09, 0x2a, 0x0d, 0x07, 0xc6, 0xb4, - 0x23, 0x9f, 0xf0, 0x29, 0xc7, 0xc6, 0xeb, 0xc9, 0x68, 0xf8, 0xe9, 0x34, 0x07, 0x1d, 0xca, 0x27, - 0xe2, 0x49, 0x03, 0xac, 0xfe, 0x34, 0x85, 0x66, 0x1a, 0x90, 0x19, 0x35, 0x79, 0x1e, 0x77, 0x8a, - 0x7e, 0x5f, 0x42, 0x99, 0x87, 0x66, 0x60, 0xed, 0x42, 0xaf, 0x3a, 0x1f, 0x1a, 0x00, 0xf2, 0xd0, - 0x00, 0xc0, 0x1b, 0xa8, 0xb8, 0xe3, 0xd1, 0x5e, 0x4b, 0x74, 0xc7, 0xb2, 0x17, 0x1e, 0x78, 0xd8, - 0xb3, 0x98, 0x48, 0x38, 0xaa, 0xa4, 0x2f, 0x33, 0x8a, 0x20, 0x49, 0xd8, 0xd2, 0x27, 0x26, 0x6c, - 0x6f, 0xa0, 0x59, 0xe2, 0x79, 0xd4, 0xdb, 0xda, 0xb9, 0xe3, 0xf8, 0x3e, 0x63, 0x74, 0x06, 0x7c, - 0x84, 0x65, 0xa6, 0x4a, 0x24, 0xe5, 0x11, 0x9d, 0xea, 0x2f, 0x35, 0x34, 0xfd, 0x2e, 0xf3, 0x3f, - 0x8a, 0x49, 0xec, 0x81, 0x76, 0xa2, 0x07, 0x67, 0xcb, 0x49, 0xaf, 0xa3, 0x1c, 0xc4, 0x29, 0x8e, - 0x0f, 0x3f, 0x77, 0x3c, 0xda, 0x53, 0x14, 0xb2, 0x1c, 0xb9, 0xf6, 0x36, 0xca, 0x00, 0xad, 0x70, - 0x1e, 0x65, 0x36, 0x99, 0xef, 0xa5, 0x0b, 0xb8, 0x80, 0x72, 0x9b, 0x07, 0x8e, 0x15, 0x10, 0xbb, - 0xa4, 0xe1, 0x1c, 0x9a, 0xba, 0x7b, 0xf7, 0x4e, 0x29, 0x85, 0x17, 0x50, 0xe9, 0x0d, 0x62, 0xda, - 0x5d, 0xc7, 0x25, 0x9b, 0x8f, 0xf8, 0x11, 0x53, 0x9a, 0xc2, 0xd3, 0x48, 0x6f, 0x92, 0x3d, 0x02, - 0x8d, 0xd3, 0x6b, 0x9f, 0x6a, 0x28, 0xc3, 0x93, 0x6f, 0x82, 0x8a, 0x6f, 0x91, 0x80, 0xf3, 0x01, - 0x10, 0x1f, 0xe3, 0xf8, 0x34, 0x8b, 0x29, 0x52, 0xb9, 0x98, 0xf0, 0x4c, 0xe1, 0x6c, 0xf5, 0xea, - 0xf7, 0x3e, 0xf9, 0xc7, 0xcf, 0x52, 0x2f, 0x54, 0xcb, 0xf5, 0x83, 0xff, 0xaf, 0xef, 0xd1, 0xf6, - 0x75, 0x9f, 0x04, 0xf5, 0xc7, 0x10, 0x98, 0x8f, 0xea, 0x8f, 0x1d, 0xfb, 0xa3, 0x9b, 0xda, 0xb5, - 0x57, 0x34, 0x7c, 0x13, 0x65, 0x20, 0xbc, 0x98, 0x13, 0x56, 0x0e, 0xf5, 0xf1, 0xb6, 0xa7, 0x7e, - 0x90, 0xd2, 0x40, 0x37, 0x7b, 0x1b, 0x7e, 0x86, 0x80, 0x97, 0x8e, 0xe4, 0xe2, 0x9b, 0x2c, 0x48, - 0x15, 0xbe, 0x97, 0xf3, 0x46, 0x1b, 0xbb, 0xc4, 0xda, 0x6f, 0x12, 0xbf, 0x4f, 0x5d, 0x9f, 0xac, - 0xbf, 0xf7, 0xa7, 0x27, 0xcb, 0xda, 0xc7, 0x4f, 0x96, 0xb5, 0xbf, 0x3d, 0x59, 0xd6, 0x7e, 0xfc, - 0x74, 0xf9, 0xc2, 0xc7, 0x4f, 0x97, 0x2f, 0xfc, 0xf5, 0xe9, 0xf2, 0x85, 0xef, 0xfc, 0x5f, 0xc7, - 0x09, 0x76, 0xc3, 0x76, 0xcd, 0xa2, 0xbd, 0xba, 0xe9, 0xf5, 0x4c, 0xdb, 0xec, 0x7b, 0x94, 0x05, - 0x48, 0xfc, 0x15, 0xfd, 0x3a, 0xe1, 0x37, 0xa9, 0x85, 0x5b, 0x00, 0xdc, 0xe3, 0xe2, 0xda, 0x16, - 0xad, 0xdd, 0xea, 0x3b, 0xed, 0x2c, 0xf8, 0x70, 0xe3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe2, - 0x06, 0x5e, 0x18, 0x7c, 0x31, 0x00, 0x00, + 0xd0, 0x4b, 0xef, 0xc5, 0xbc, 0x99, 0xe5, 0xce, 0x50, 0x14, 0x24, 0x2b, 0x1f, 0x35, 0x14, 0x9e, + 0x6c, 0xfd, 0xde, 0xbc, 0x37, 0x6f, 0xdf, 0xfc, 0x66, 0xe6, 0xcd, 0xbc, 0x21, 0x9a, 0xef, 0xed, + 0xb7, 0x6b, 0x56, 0xcf, 0xad, 0x91, 0x03, 0xe2, 0x05, 0xd5, 0x1e, 0xa3, 0x01, 0xc5, 0x53, 0x56, + 0xcf, 0x2d, 0x95, 0xdb, 0x94, 0xb6, 0x3b, 0xa4, 0x06, 0x50, 0x2b, 0xdc, 0xa9, 0x05, 0x6e, 0x97, + 0xf8, 0x81, 0xd5, 0xed, 0x89, 0x56, 0xa5, 0x85, 0x48, 0xd5, 0x0f, 0x5b, 0x5d, 0x37, 0x18, 0x45, + 0x77, 0x89, 0xd5, 0x09, 0x76, 0x25, 0x7a, 0x79, 0xd4, 0x18, 0xe9, 0xf6, 0x82, 0x43, 0x29, 0xbc, + 0x22, 0x85, 0x5c, 0xcb, 0xf2, 0x3c, 0x1a, 0x58, 0x81, 0x4b, 0x3d, 0x5f, 0x4a, 0x5f, 0xdd, 0x7f, + 0xdd, 0xaf, 0xba, 0x94, 0x4b, 0xbb, 0x96, 0xbd, 0xeb, 0x7a, 0x84, 0x1d, 0xd6, 0xa2, 0x4e, 0x18, + 0xf1, 0x69, 0xc8, 0x6c, 0x52, 0x6b, 0x13, 0x8f, 0x30, 0x2b, 0x20, 0x8e, 0xd0, 0xaa, 0xfc, 0x22, + 0x81, 0xe6, 0xea, 0xb4, 0xb5, 0x0d, 0xae, 0x05, 0xc4, 0xd9, 0xe4, 0x9f, 0x87, 0xaf, 0xa1, 0xf4, + 0x1e, 0x6d, 0x35, 0x5d, 0xa7, 0x68, 0xac, 0x18, 0xab, 0xd9, 0xf5, 0xf9, 0x41, 0xbf, 0x9c, 0xdf, + 0xa3, 0xad, 0x2d, 0xe7, 0x65, 0xda, 0x75, 0x03, 0x70, 0xaa, 0x91, 0x02, 0x00, 0xbf, 0x8a, 0x10, + 0x6f, 0xeb, 0x93, 0x80, 0xb7, 0x4f, 0x40, 0xfb, 0xa5, 0x41, 0xbf, 0x8c, 0xf7, 0x68, 0x6b, 0x9b, + 0x04, 0x9a, 0x8a, 0x19, 0x61, 0xf8, 0x25, 0x94, 0xfa, 0x20, 0x24, 0x21, 0x29, 0x4e, 0xc5, 0x1d, + 0x00, 0xa0, 0x76, 0x00, 0x00, 0xfe, 0x26, 0xca, 0xd8, 0x8c, 0x70, 0x9f, 0x8b, 0xc9, 0x15, 0x63, + 0x35, 0xb7, 0x56, 0xaa, 0x8a, 0x40, 0x54, 0xa3, 0x28, 0x55, 0x1f, 0x44, 0x21, 0x5f, 0x5f, 0x1c, + 0xf4, 0xcb, 0x73, 0xb2, 0xb9, 0x62, 0x2a, 0xb2, 0x80, 0xaf, 0xa3, 0xa9, 0x3d, 0xda, 0x2a, 0xa6, + 0xc0, 0x90, 0x59, 0xb5, 0x7a, 0x6e, 0xb5, 0x4e, 0x5b, 0xeb, 0x73, 0x83, 0x7e, 0x79, 0x66, 0x8f, + 0xb6, 0x14, 0x15, 0xde, 0xae, 0x32, 0x30, 0xd0, 0x6c, 0x9d, 0xb6, 0xee, 0x73, 0x47, 0xce, 0x7b, + 0x6c, 0x2a, 0x7f, 0x4e, 0xc0, 0xc7, 0xbe, 0x4d, 0x2c, 0xff, 0xfc, 0x13, 0xe1, 0x6b, 0x08, 0xd9, + 0x9d, 0xd0, 0x0f, 0x08, 0xe3, 0xde, 0xa6, 0xa0, 0xf3, 0x8b, 0x83, 0x7e, 0x79, 0x5e, 0xa2, 0x9a, + 0xbb, 0xd9, 0x21, 0x88, 0x5f, 0x44, 0xc9, 0x1e, 0xa5, 0x9d, 0x62, 0x1a, 0x34, 0xf0, 0xa0, 0x5f, + 0x9e, 0xe5, 0x7f, 0x2b, 0x8d, 0x41, 0x5e, 0xf9, 0x49, 0x12, 0x2d, 0x46, 0xc1, 0x6c, 0x90, 0x20, + 0x64, 0xde, 0x24, 0xa6, 0xc7, 0xc5, 0xf4, 0x65, 0x94, 0x66, 0xc4, 0xf2, 0xa9, 0x27, 0xa3, 0xba, + 0x30, 0xe8, 0x97, 0x0b, 0x02, 0x51, 0x14, 0x64, 0x1b, 0xfc, 0x0d, 0x34, 0xb3, 0x1f, 0xb6, 0x08, + 0xf3, 0x48, 0x40, 0x7c, 0xde, 0x51, 0x06, 0x94, 0x4a, 0x83, 0x7e, 0x79, 0x29, 0x16, 0x68, 0x7d, + 0x4d, 0xab, 0x38, 0x77, 0xb3, 0x47, 0x9d, 0xa6, 0x17, 0x76, 0x5b, 0x84, 0x15, 0xcd, 0x15, 0x63, + 0x35, 0x25, 0xdc, 0xec, 0x51, 0xe7, 0x5b, 0x00, 0xaa, 0x6e, 0x0e, 0x41, 0xde, 0x31, 0x0b, 0xbd, + 0xa6, 0x15, 0x80, 0x88, 0x38, 0xc5, 0xec, 0x8a, 0xb1, 0x6a, 0x8a, 0x8e, 0x59, 0xe8, 0xdd, 0x8a, + 0x70, 0xb5, 0x63, 0x15, 0xaf, 0xfc, 0xdb, 0x40, 0x0b, 0x11, 0x27, 0x36, 0x1f, 0xf5, 0x5c, 0x76, + 0xfe, 0xd7, 0x94, 0xdf, 0x25, 0x51, 0xbe, 0x4e, 0x5b, 0xf7, 0x88, 0xe7, 0xb8, 0x5e, 0x7b, 0x32, + 0x01, 0xc6, 0x4f, 0x80, 0x23, 0x94, 0x4e, 0x7f, 0x26, 0x4a, 0x67, 0x4e, 0x4d, 0xe9, 0x57, 0x90, + 0x09, 0x7a, 0x56, 0x97, 0xc0, 0x44, 0xc8, 0x8a, 0x4f, 0xe4, 0x0d, 0xac, 0xae, 0x1a, 0xad, 0x8c, + 0x84, 0xb8, 0xab, 0x91, 0x86, 0xdf, 0xb3, 0x6c, 0x02, 0x93, 0x40, 0xba, 0x2a, 0xdb, 0x00, 0xae, + 0xba, 0xaa, 0xe2, 0xc3, 0x05, 0x14, 0x9d, 0xb0, 0x80, 0xfe, 0x4b, 0x30, 0xa7, 0x11, 0x7a, 0xde, + 0x84, 0x39, 0x5f, 0x1c, 0x73, 0x6e, 0xa0, 0xac, 0x47, 0x1d, 0x22, 0x28, 0x90, 0x89, 0xa3, 0xc4, + 0xc1, 0x11, 0x0e, 0x98, 0x11, 0x76, 0xe6, 0x15, 0x54, 0xa5, 0x5b, 0xf6, 0x6c, 0x74, 0x43, 0x67, + 0xa4, 0x5b, 0xee, 0x04, 0xba, 0xfd, 0x36, 0x8d, 0xe6, 0xeb, 0xb4, 0xb5, 0xe5, 0xb5, 0x19, 0xf1, + 0xfd, 0x2d, 0x6f, 0x87, 0x4e, 0x28, 0x77, 0xde, 0x28, 0x87, 0xce, 0x46, 0xb9, 0xdc, 0x33, 0x52, + 0xee, 0x31, 0x9a, 0x73, 0x05, 0x8d, 0x9a, 0x96, 0xe3, 0xf0, 0x7f, 0x89, 0x5f, 0xcc, 0xae, 0x4c, + 0xad, 0xe6, 0xd6, 0xaa, 0xd1, 0x89, 0x63, 0x94, 0x67, 0x55, 0x09, 0xdc, 0x8a, 0x14, 0x36, 0xbd, + 0x80, 0x1d, 0xae, 0x2f, 0x0f, 0xfa, 0xe5, 0x92, 0x3b, 0x22, 0x52, 0x3a, 0x2e, 0x8c, 0xca, 0x4a, + 0xfb, 0x68, 0x71, 0xac, 0x29, 0x7c, 0x15, 0x4d, 0xed, 0x93, 0x43, 0x60, 0x71, 0x4a, 0x9c, 0x77, + 0xf6, 0xc9, 0xa1, 0x7a, 0xde, 0xd9, 0x27, 0x87, 0x9c, 0x8b, 0x07, 0x56, 0x27, 0x24, 0x92, 0xbc, + 0xc0, 0x45, 0x00, 0x54, 0x2e, 0x02, 0x70, 0x33, 0xf1, 0xba, 0x51, 0xf9, 0x8f, 0x09, 0x27, 0x86, + 0x37, 0x2d, 0xb7, 0x33, 0xc9, 0x6e, 0x3f, 0x9f, 0xec, 0xf6, 0x7d, 0x84, 0xc8, 0x23, 0x37, 0x68, + 0xda, 0xd4, 0x21, 0x7e, 0x31, 0x03, 0xac, 0xa9, 0x44, 0xac, 0x51, 0x02, 0x5d, 0xdd, 0x7c, 0xe4, + 0x06, 0x1b, 0xbc, 0x91, 0x60, 0xca, 0x25, 0xee, 0x09, 0x89, 0xb0, 0xd8, 0x70, 0xd1, 0x68, 0x64, + 0x87, 0xf0, 0xd1, 0xb9, 0x6b, 0x7e, 0x96, 0xb9, 0x9b, 0x3d, 0xd3, 0xdc, 0x45, 0x67, 0x9a, 0xbb, + 0x33, 0x67, 0x9b, 0xbb, 0xb3, 0xcf, 0x38, 0x77, 0x1d, 0x84, 0x6d, 0xea, 0x05, 0x96, 0xeb, 0x11, + 0xd6, 0xf4, 0x03, 0x2b, 0x08, 0xf9, 0xe4, 0xcd, 0xc1, 0x30, 0x2c, 0xc0, 0x30, 0x6c, 0x44, 0xe2, + 0x6d, 0x90, 0xae, 0x97, 0x07, 0xfd, 0xf2, 0x65, 0x5b, 0x07, 0xb5, 0x39, 0x3a, 0x77, 0x44, 0x88, + 0x5f, 0x43, 0x29, 0xdb, 0x0a, 0x7d, 0x52, 0x9c, 0x5e, 0x31, 0x56, 0x67, 0xd7, 0x90, 0x30, 0xcc, + 0x11, 0x41, 0x67, 0x10, 0xaa, 0x74, 0x06, 0x00, 0xdf, 0x46, 0x85, 0x1d, 0xcb, 0xed, 0x84, 0x8c, + 0x34, 0x6d, 0x2b, 0x20, 0x6d, 0xca, 0x0e, 0x8b, 0x05, 0xf8, 0xc0, 0x17, 0x06, 0xfd, 0xf2, 0x25, + 0x29, 0xdb, 0x90, 0x22, 0x45, 0x3f, 0x3f, 0x22, 0xc2, 0xf7, 0xd1, 0x7c, 0x64, 0xc9, 0x0f, 0x5b, + 0x43, 0x63, 0x73, 0x60, 0x6c, 0x65, 0xd0, 0x2f, 0x5f, 0x91, 0xe2, 0xed, 0x58, 0xaa, 0xd8, 0xc3, + 0x47, 0xa5, 0x25, 0x07, 0xcd, 0xea, 0x94, 0x54, 0x57, 0x9c, 0xec, 0xe9, 0x56, 0x9c, 0xd4, 0x49, + 0x2b, 0x4e, 0x3d, 0x69, 0xe6, 0x0b, 0x85, 0xca, 0x27, 0x09, 0x84, 0xf9, 0xa9, 0x82, 0x11, 0xde, + 0xe0, 0x2b, 0x90, 0x1e, 0xbe, 0x86, 0xb2, 0x8c, 0x7c, 0x10, 0x12, 0x3f, 0xa0, 0x4c, 0x5d, 0x7a, + 0x86, 0xa0, 0x3a, 0x81, 0x86, 0xe0, 0xb3, 0x2d, 0x3d, 0x95, 0x9f, 0x27, 0xe1, 0x2e, 0x50, 0x46, + 0x75, 0xb2, 0xa0, 0x1f, 0xb7, 0xa0, 0x5f, 0x43, 0x69, 0x16, 0x7a, 0x71, 0xe6, 0x03, 0x0e, 0xb3, + 0xd0, 0xd3, 0x23, 0x02, 0x00, 0xde, 0x42, 0x73, 0x3d, 0xc9, 0xd2, 0x03, 0xd2, 0x94, 0x6a, 0x66, + 0x3c, 0x67, 0x63, 0x61, 0x63, 0xc4, 0x40, 0x7e, 0x44, 0xa4, 0x0c, 0x66, 0xf6, 0x14, 0xfb, 0x88, + 0xd2, 0xb1, 0xd7, 0x6e, 0xca, 0x11, 0x44, 0x47, 0x3b, 0xf6, 0xda, 0xf5, 0x91, 0xb1, 0xcc, 0x8f, + 0x88, 0xea, 0x49, 0x33, 0x53, 0x30, 0x2b, 0x7f, 0x4c, 0xca, 0x9b, 0x62, 0xdb, 0x26, 0xc4, 0x99, + 0xb0, 0x63, 0x72, 0x22, 0x3b, 0xdb, 0x89, 0xac, 0xf2, 0xf7, 0x1c, 0x9c, 0xb4, 0xde, 0x09, 0xdc, + 0x8e, 0xeb, 0x43, 0x09, 0x63, 0x42, 0xa5, 0x2f, 0x88, 0x4a, 0x3f, 0x32, 0xd0, 0xe2, 0x1d, 0xeb, + 0x51, 0x43, 0x56, 0x7f, 0xfc, 0x37, 0x29, 0xbb, 0x47, 0x98, 0x4b, 0x1d, 0x99, 0x58, 0xde, 0x88, + 0x12, 0xcb, 0xd1, 0xc1, 0xa8, 0x8e, 0xd5, 0x12, 0x99, 0xe6, 0xd5, 0x41, 0xbf, 0x5c, 0x1e, 0x2b, + 0x57, 0xfc, 0x18, 0xdf, 0xad, 0xce, 0x6d, 0xf3, 0x4c, 0xdc, 0xce, 0x3e, 0xcf, 0x47, 0xbf, 0x1f, + 0x1a, 0x68, 0x29, 0xa0, 0x81, 0xd5, 0x69, 0xda, 0x61, 0x37, 0xec, 0x58, 0xb0, 0xea, 0x87, 0xbe, + 0xd5, 0xe6, 0xa9, 0x1e, 0x8f, 0xf8, 0xda, 0xb1, 0x11, 0x7f, 0xc0, 0xd5, 0x36, 0x86, 0x5a, 0xef, + 0x70, 0x25, 0x11, 0xf0, 0xca, 0xa0, 0x5f, 0x5e, 0x0e, 0xc6, 0x88, 0x15, 0x37, 0x16, 0xc6, 0xc9, + 0x61, 0xfc, 0x6f, 0x1d, 0xb4, 0xc7, 0x8c, 0xff, 0xcc, 0x09, 0xe3, 0x3f, 0x56, 0x4b, 0x19, 0xff, + 0xb1, 0x72, 0x75, 0xfc, 0xc7, 0x36, 0x28, 0xfd, 0xda, 0x40, 0xa5, 0xe3, 0xa9, 0x75, 0xba, 0x8c, + 0xf1, 0xdb, 0x6a, 0xc6, 0xc8, 0x8f, 0xd4, 0xa2, 0xf0, 0x59, 0x55, 0x0b, 0x9f, 0xd5, 0xde, 0x7e, + 0x1b, 0xbe, 0x2d, 0x2a, 0x7c, 0x56, 0xef, 0x87, 0x96, 0x17, 0xb8, 0xc1, 0xe1, 0x49, 0x19, 0x66, + 0xe9, 0x57, 0x06, 0xba, 0x74, 0xec, 0x58, 0x3c, 0x17, 0x1e, 0xf2, 0x20, 0x1e, 0x3f, 0x3e, 0xcf, + 0x83, 0x8b, 0x95, 0x7f, 0x26, 0xd0, 0x52, 0x9d, 0xb6, 0x1a, 0xa4, 0xc7, 0x5c, 0xca, 0xdc, 0xc0, + 0xfd, 0xf0, 0x2b, 0x90, 0xa4, 0x7f, 0x1d, 0x4d, 0x7b, 0xe4, 0x61, 0x53, 0x7e, 0xf2, 0x21, 0x2c, + 0xf4, 0x06, 0x1c, 0xcc, 0x17, 0x3d, 0xf2, 0xf0, 0x9e, 0x84, 0x15, 0xcd, 0x9c, 0x02, 0xeb, 0x29, + 0x7e, 0xfa, 0xb4, 0x29, 0x7e, 0xe5, 0xd3, 0x04, 0xd4, 0x19, 0x95, 0x48, 0x9f, 0xff, 0xd4, 0xec, + 0x7f, 0x12, 0x68, 0x79, 0xe6, 0xdc, 0xb0, 0x3c, 0x9b, 0x74, 0x3a, 0x93, 0x33, 0xe7, 0xe7, 0x73, + 0xe6, 0xfc, 0x8b, 0x78, 0x7f, 0x22, 0xa3, 0x7a, 0xfe, 0xa9, 0xfb, 0xa5, 0x04, 0xf5, 0x0f, 0x49, + 0xa0, 0xea, 0x03, 0xc2, 0xba, 0xae, 0x67, 0x4d, 0x4e, 0xf2, 0xcf, 0x77, 0xdd, 0xf5, 0x4b, 0x2a, + 0x84, 0xc5, 0x14, 0x32, 0x4f, 0x41, 0xa1, 0xdf, 0xe7, 0xd0, 0x34, 0xb0, 0xe6, 0x0e, 0xf1, 0x21, + 0x95, 0xbc, 0x8b, 0xb2, 0x7e, 0xf4, 0x48, 0x0c, 0xf8, 0x93, 0x5b, 0x5b, 0x8a, 0xb2, 0x47, 0xfd, + 0xf5, 0x98, 0x08, 0xc0, 0xb0, 0x71, 0x6c, 0xfc, 0xf6, 0x85, 0x46, 0x6c, 0x03, 0x6f, 0xa0, 0x34, + 0x30, 0xc1, 0x91, 0x29, 0xc8, 0x7c, 0x64, 0x4d, 0x79, 0x6c, 0x25, 0x9c, 0x14, 0xcd, 0x34, 0x3b, + 0x52, 0x95, 0x1b, 0xe9, 0xc0, 0x73, 0x25, 0x60, 0x9c, 0x62, 0x44, 0x79, 0xc4, 0x24, 0x8c, 0x88, + 0x66, 0xba, 0x11, 0x81, 0xe1, 0xef, 0xa2, 0x59, 0xf8, 0x5f, 0x93, 0xc9, 0x77, 0x3a, 0x43, 0x46, + 0xaa, 0xc6, 0xb4, 0x47, 0x3c, 0xeb, 0x97, 0x07, 0xfd, 0xf2, 0xc5, 0x8e, 0x8a, 0x6b, 0xa6, 0x67, + 0x34, 0x11, 0x7e, 0x1f, 0x09, 0xa0, 0x49, 0xc4, 0xab, 0x0f, 0xf9, 0xfe, 0xec, 0x92, 0xd6, 0x81, + 0xfa, 0x22, 0x44, 0x8c, 0x6b, 0x47, 0x81, 0x35, 0xf3, 0xd3, 0xaa, 0x04, 0xbf, 0x85, 0x32, 0x3d, + 0xf1, 0xbe, 0x02, 0xf8, 0x1b, 0x5d, 0x54, 0x8f, 0x3c, 0xbb, 0x90, 0x0c, 0x13, 0x88, 0x66, 0x2d, + 0xd2, 0xe6, 0x86, 0x98, 0x28, 0xb7, 0x03, 0x95, 0x15, 0x43, 0x6a, 0x15, 0x5e, 0x18, 0x92, 0x0d, + 0x75, 0x43, 0x12, 0xe4, 0xc3, 0xb2, 0x03, 0xa5, 0x0a, 0x20, 0xb7, 0x32, 0x2c, 0x4a, 0x01, 0x43, + 0x0c, 0x8b, 0x68, 0xa6, 0x0f, 0x8b, 0xc0, 0x04, 0xe3, 0xe4, 0x65, 0x13, 0xb0, 0x5d, 0x63, 0x9c, + 0x7a, 0x0b, 0x15, 0x31, 0x4e, 0x62, 0xa3, 0x8c, 0x93, 0x30, 0x6e, 0xa2, 0x19, 0xa6, 0xa6, 0x49, + 0x70, 0xba, 0x53, 0x86, 0xf9, 0x68, 0x0e, 0x25, 0x86, 0x59, 0x53, 0xd2, 0x87, 0x59, 0x13, 0xe1, + 0x6d, 0x84, 0xec, 0x61, 0x7a, 0x00, 0x77, 0xfb, 0xb9, 0xb5, 0x8b, 0x91, 0xf5, 0x91, 0xc4, 0x61, + 0xbd, 0x38, 0xe8, 0x97, 0x17, 0xe2, 0xe6, 0x9a, 0x5d, 0xc5, 0x0c, 0x0f, 0x83, 0x1d, 0xed, 0x8e, + 0x50, 0x05, 0x51, 0xc2, 0xa0, 0x6f, 0x9b, 0x72, 0xc9, 0x8b, 0x30, 0x3d, 0x0c, 0x43, 0x18, 0xbf, + 0x8b, 0x72, 0x61, 0x7c, 0xdc, 0x2b, 0xe6, 0xc1, 0x64, 0xf1, 0xb8, 0x93, 0xa0, 0x48, 0xab, 0x14, + 0x05, 0xcd, 0xac, 0x6a, 0x09, 0xbf, 0x87, 0xa6, 0xa3, 0xba, 0xa7, 0xeb, 0xed, 0x50, 0xa8, 0x26, + 0x28, 0x96, 0x47, 0x4b, 0x9e, 0xc2, 0xb2, 0x1b, 0xa3, 0xba, 0x65, 0x45, 0x80, 0x6d, 0x34, 0xcb, + 0xb4, 0xa3, 0x44, 0x11, 0x83, 0xed, 0xcb, 0x63, 0x86, 0x6e, 0x18, 0xe0, 0x2b, 0x83, 0x7e, 0xb9, + 0xa8, 0xab, 0x69, 0x3d, 0x8c, 0x98, 0xe4, 0x81, 0xee, 0x45, 0x57, 0xdf, 0xc5, 0x45, 0x3d, 0xd0, + 0xfa, 0x9d, 0xb8, 0x5c, 0xe2, 0x23, 0x4c, 0x0f, 0xf4, 0x10, 0xe6, 0x74, 0x88, 0xaf, 0x52, 0x8b, + 0x4b, 0x3a, 0x1d, 0x46, 0x6a, 0x17, 0x82, 0x0e, 0x71, 0x73, 0x9d, 0x0e, 0x31, 0xbe, 0x6e, 0xa2, + 0x34, 0x3c, 0x41, 0xf6, 0xeb, 0x49, 0xd3, 0x2c, 0x64, 0xeb, 0x49, 0x73, 0xb6, 0x90, 0xaf, 0x27, + 0xcd, 0x42, 0x61, 0xae, 0x9e, 0x34, 0xe7, 0x0b, 0x0b, 0xf5, 0xa4, 0xb9, 0x50, 0x58, 0xac, 0x7c, + 0x3f, 0x81, 0xf2, 0x23, 0xa5, 0x2a, 0xfc, 0x22, 0x4a, 0xc2, 0x8e, 0x63, 0xc4, 0x6f, 0x21, 0x3c, + 0x7d, 0xbb, 0x01, 0x39, 0x5e, 0x43, 0x66, 0x54, 0x32, 0x94, 0x65, 0x19, 0xd8, 0xfa, 0x23, 0x4c, + 0xdd, 0xfa, 0x23, 0x0c, 0xd7, 0x50, 0xa6, 0x2b, 0xb6, 0x0a, 0xb9, 0xf9, 0xc3, 0x2a, 0x21, 0x21, + 0x75, 0x43, 0x93, 0x90, 0xb2, 0x1f, 0x25, 0x4f, 0x71, 0x9d, 0x3d, 0xac, 0x98, 0xa5, 0x9e, 0xa5, + 0x62, 0x56, 0xf9, 0x10, 0x61, 0x08, 0xef, 0x76, 0xc0, 0x88, 0xd5, 0x8d, 0xf6, 0xb2, 0x15, 0x94, + 0x18, 0x26, 0x41, 0x85, 0x41, 0xbf, 0x3c, 0xed, 0xaa, 0x3b, 0x7c, 0xc2, 0x75, 0xf0, 0x7a, 0xfc, + 0x35, 0x62, 0x77, 0x9a, 0x83, 0x0e, 0xd5, 0x1d, 0xf1, 0xa4, 0x0f, 0xac, 0xfc, 0x34, 0x81, 0x66, + 0xea, 0x90, 0x19, 0x35, 0x44, 0x1e, 0x77, 0x8a, 0x7e, 0x5f, 0x42, 0xa9, 0x87, 0x56, 0x60, 0xef, + 0x42, 0xaf, 0xa6, 0xf8, 0x34, 0x00, 0xd4, 0x4f, 0x03, 0x00, 0x6f, 0xa0, 0xfc, 0x0e, 0xa3, 0xdd, + 0xa6, 0xec, 0x8e, 0x67, 0x2f, 0x22, 0xf0, 0xb0, 0x66, 0x71, 0x91, 0x74, 0x54, 0x4b, 0x5f, 0x66, + 0x34, 0x41, 0x9c, 0xb0, 0x25, 0x4f, 0x4c, 0xd8, 0xde, 0x40, 0xb3, 0x84, 0x31, 0xca, 0xb6, 0x76, + 0xee, 0xb8, 0xbe, 0xcf, 0x19, 0x9d, 0x02, 0x1f, 0x61, 0x9a, 0xe9, 0x12, 0x45, 0x79, 0x44, 0xa7, + 0xf2, 0x4b, 0x03, 0x4d, 0xbf, 0xcb, 0xfd, 0x8f, 0x62, 0x32, 0xf4, 0xc0, 0x38, 0xd1, 0x83, 0xb3, + 0xe5, 0xa4, 0xd7, 0x51, 0x06, 0xe2, 0x34, 0x8c, 0x8f, 0xd8, 0x77, 0x18, 0xed, 0x6a, 0x0a, 0x69, + 0x81, 0x5c, 0x7b, 0x1b, 0xa5, 0x80, 0x56, 0x38, 0x8b, 0x52, 0x9b, 0xdc, 0xf7, 0xc2, 0x05, 0x9c, + 0x43, 0x99, 0xcd, 0x03, 0xd7, 0x0e, 0x88, 0x53, 0x30, 0x70, 0x06, 0x4d, 0xdd, 0xbd, 0x7b, 0xa7, + 0x90, 0xc0, 0x0b, 0xa8, 0xf0, 0x06, 0xb1, 0x9c, 0x8e, 0xeb, 0x91, 0xcd, 0x47, 0x62, 0x8b, 0x29, + 0x4c, 0xe1, 0x69, 0x64, 0x36, 0xc8, 0x1e, 0x81, 0xc6, 0xc9, 0xb5, 0x4f, 0x0d, 0x94, 0x12, 0xc9, + 0x37, 0x41, 0xf9, 0xb7, 0x48, 0x20, 0xf8, 0x00, 0x88, 0x8f, 0xf1, 0x70, 0x37, 0x1b, 0x52, 0xa4, + 0x74, 0x31, 0xe6, 0x99, 0xc6, 0xd9, 0xca, 0xd5, 0xef, 0x7d, 0xf2, 0x8f, 0x9f, 0x25, 0x5e, 0xa8, + 0x14, 0x6b, 0x07, 0xff, 0x5f, 0xdb, 0xa3, 0xad, 0xeb, 0x3e, 0x09, 0x6a, 0x8f, 0x21, 0x30, 0x1f, + 0xd5, 0x1e, 0xbb, 0xce, 0x47, 0x37, 0x8d, 0x6b, 0xaf, 0x18, 0xf8, 0x26, 0x4a, 0x41, 0x78, 0xb1, + 0x20, 0xac, 0x1a, 0xea, 0xe3, 0x6d, 0x4f, 0xfd, 0x20, 0x61, 0x80, 0x6e, 0xfa, 0x36, 0xfc, 0x18, + 0x01, 0x2f, 0x1d, 0xc9, 0xc5, 0x37, 0x79, 0x90, 0x4a, 0x62, 0x2d, 0x17, 0x8d, 0x36, 0x76, 0x89, + 0xbd, 0xdf, 0x20, 0x7e, 0x8f, 0x7a, 0x3e, 0x59, 0x7f, 0xef, 0x4f, 0x4f, 0x96, 0x8d, 0x8f, 0x9f, + 0x2c, 0x1b, 0x7f, 0x7b, 0xb2, 0x6c, 0xfc, 0xf8, 0xe9, 0xf2, 0x85, 0x8f, 0x9f, 0x2e, 0x5f, 0xf8, + 0xeb, 0xd3, 0xe5, 0x0b, 0xdf, 0xf9, 0xbf, 0xb6, 0x1b, 0xec, 0x86, 0xad, 0xaa, 0x4d, 0xbb, 0x35, + 0x8b, 0x75, 0x2d, 0xc7, 0xea, 0x31, 0xca, 0x03, 0x24, 0xff, 0x8a, 0x7e, 0xa3, 0xf0, 0x9b, 0xc4, + 0xc2, 0x2d, 0x00, 0xee, 0x09, 0x71, 0x75, 0x8b, 0x56, 0x6f, 0xf5, 0xdc, 0x56, 0x1a, 0x7c, 0xb8, + 0xf1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x87, 0x95, 0xbd, 0x34, 0x82, 0x31, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3740,6 +3740,13 @@ func (m *JobPreemptedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PreemptingJobId) > 0 { + i -= len(m.PreemptingJobId) + copy(dAtA[i:], m.PreemptingJobId) + i = encodeVarintEvent(dAtA, i, uint64(len(m.PreemptingJobId))) + i-- + dAtA[i] = 0x52 + } if len(m.Reason) > 0 { i -= len(m.Reason) copy(dAtA[i:], m.Reason) @@ -3754,13 +3761,6 @@ func (m *JobPreemptedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x42 } - if len(m.PreemptingJobId) > 0 { - i -= len(m.PreemptingJobId) - copy(dAtA[i:], m.PreemptingJobId) - i = encodeVarintEvent(dAtA, i, uint64(len(m.PreemptingJobId))) - i-- - dAtA[i] = 0x3a - } if len(m.RunId) > 0 { i -= len(m.RunId) copy(dAtA[i:], m.RunId) @@ -5518,15 +5518,15 @@ func (m *JobPreemptedEvent) Size() (n int) { if l > 0 { n += 1 + l + sovEvent(uint64(l)) } - l = len(m.PreemptingJobId) + l = len(m.PreemptiveRunId) if l > 0 { n += 1 + l + sovEvent(uint64(l)) } - l = len(m.PreemptiveRunId) + l = len(m.Reason) if l > 0 { n += 1 + l + sovEvent(uint64(l)) } - l = len(m.Reason) + l = len(m.PreemptingJobId) if l > 0 { n += 1 + l + sovEvent(uint64(l)) } @@ -9627,9 +9627,9 @@ func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error { } m.RunId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreemptingJobId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreemptiveRunId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9657,11 +9657,11 @@ func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PreemptingJobId = string(dAtA[iNdEx:postIndex]) + m.PreemptiveRunId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreemptiveRunId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9689,11 +9689,11 @@ func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PreemptiveRunId = string(dAtA[iNdEx:postIndex]) + m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreemptingJobId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9721,7 +9721,7 @@ func (m *JobPreemptedEvent) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Reason = string(dAtA[iNdEx:postIndex]) + m.PreemptingJobId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/pkg/api/event.proto b/pkg/api/event.proto index 79d0ec176e9..aacc6036ba3 100644 --- a/pkg/api/event.proto +++ b/pkg/api/event.proto @@ -131,9 +131,10 @@ message JobPreemptedEvent { google.protobuf.Timestamp created = 4; string cluster_id = 5; string run_id = 6; - string preempting_job_id = 7; + reserved 7; string preemptive_run_id = 8; string reason = 9; + string preempting_job_id = 10; } message JobSucceededEvent { From 374695677e1a6a2a43ec626338addcb9eee5996e Mon Sep 17 00:00:00 2001 From: William Vega Date: Tue, 19 May 2026 11:49:22 -0500 Subject: [PATCH 16/16] fix: rust client Signed-off-by: William Vega --- client/rust/src/gen/api.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/rust/src/gen/api.rs b/client/rust/src/gen/api.rs index e240f1f9031..3f4ae0486db 100644 --- a/client/rust/src/gen/api.rs +++ b/client/rust/src/gen/api.rs @@ -1498,12 +1498,12 @@ pub struct JobPreemptedEvent { pub cluster_id: ::prost::alloc::string::String, #[prost(string, tag = "6")] pub run_id: ::prost::alloc::string::String, - #[prost(string, tag = "7")] - pub preempting_job_id: ::prost::alloc::string::String, #[prost(string, tag = "8")] pub preemptive_run_id: ::prost::alloc::string::String, #[prost(string, tag = "9")] pub reason: ::prost::alloc::string::String, + #[prost(string, tag = "10")] + pub preempting_job_id: ::prost::alloc::string::String, } #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct JobSucceededEvent {