diff --git a/api/gen/proto/go/usageevents/v1/usageevents.pb.go b/api/gen/proto/go/usageevents/v1/usageevents.pb.go index b35faa89c1f..48d71b07f38 100644 --- a/api/gen/proto/go/usageevents/v1/usageevents.pb.go +++ b/api/gen/proto/go/usageevents/v1/usageevents.pb.go @@ -423,6 +423,7 @@ const ( IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB IntegrationEnrollStep = 9 IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS IntegrationEnrollStep = 10 IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW IntegrationEnrollStep = 11 + IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME IntegrationEnrollStep = 12 ) var IntegrationEnrollStep_name = map[int32]string{ @@ -438,6 +439,7 @@ var IntegrationEnrollStep_name = map[int32]string{ 9: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB", 10: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS", 11: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW", + 12: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME", } var IntegrationEnrollStep_value = map[string]int32{ @@ -453,6 +455,7 @@ var IntegrationEnrollStep_value = map[string]int32{ "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB": 9, "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS": 10, "INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW": 11, + "INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME": 12, } func (x IntegrationEnrollStep) String() string { @@ -6317,413 +6320,413 @@ func init() { } var fileDescriptor_94cf2ca1c69fd564 = []byte{ - // 6482 bytes of a gzipped FileDescriptorProto + // 6496 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x5b, 0x6c, 0x1c, 0xc9, 0x75, 0xe8, 0xf4, 0x90, 0x94, 0xc8, 0x92, 0x44, 0xb5, 0x5a, 0x12, 0x35, 0x22, 0x45, 0x3d, 0x46, 0x6f, 0xee, 0x2e, 0xb5, 0xd2, 0x6a, 0xbd, 0xda, 0x87, 0xbd, 0xdb, 0xec, 0x69, 0xce, 0xb4, 0x38, 0x33, 0x3d, 0x5b, 0xdd, 0x23, 0x9a, 0x6b, 0x18, 0x75, 0x9b, 0xd3, 0x45, 0xb2, 0x2f, 0x87, 0xd3, 0xe3, 0xee, 0x1e, 0x72, 0x89, 0x0b, 0xc3, 0xbe, 0xbe, 0xf7, 0x1a, 0x17, 0xd7, 0xf6, 0x75, 0x02, - 0x24, 0x46, 0x80, 0x0d, 0xf2, 0x40, 0x9e, 0x80, 0x03, 0xe4, 0xcb, 0xf0, 0x57, 0x3e, 0xf2, 0x17, - 0x20, 0xf9, 0x30, 0x90, 0xbf, 0xe4, 0x27, 0xf0, 0x57, 0xfe, 0xfc, 0x95, 0x00, 0x89, 0xf3, 0x42, - 0x3d, 0x7a, 0xa6, 0x67, 0xa6, 0x7b, 0xba, 0xb5, 0xd1, 0xc6, 0x86, 0xf6, 0x8f, 0x53, 0x75, 0x5e, - 0x75, 0xea, 0xd4, 0x39, 0xa7, 0xaa, 0x4e, 0x35, 0xc1, 0xfd, 0x00, 0xb7, 0x71, 0xd7, 0xf5, 0x82, - 0x07, 0x3d, 0xdf, 0xda, 0xc5, 0xf8, 0x10, 0x77, 0x02, 0xff, 0xc1, 0xe1, 0xc3, 0xe8, 0xcf, 0xd5, - 0xae, 0xe7, 0x06, 0xae, 0x74, 0x29, 0x04, 0x5d, 0x8d, 0xf6, 0x1d, 0x3e, 0x5c, 0xbc, 0xdb, 0xa7, - 0x61, 0xb5, 0x5a, 0xd8, 0xf7, 0xdb, 0x8e, 0x1f, 0x10, 0x12, 0x83, 0x5f, 0x8c, 0x42, 0x71, 0x05, - 0x48, 0x4d, 0x6d, 0xcd, 0xea, 0x74, 0xb0, 0xa7, 0xb4, 0x9d, 0xd6, 0xbe, 0x4a, 0x48, 0x48, 0x17, - 0xc0, 0x8c, 0xd5, 0xc6, 0x5e, 0x50, 0x10, 0xae, 0x0b, 0xf7, 0xe6, 0x20, 0xfb, 0x51, 0x5c, 0x07, - 0xf7, 0x9a, 0x9a, 0xde, 0xd9, 0x76, 0x2d, 0xcf, 0x56, 0xdc, 0x83, 0x6e, 0x1b, 0x07, 0xb8, 0xec, - 0x9a, 0x6e, 0xc9, 0xf2, 0xf7, 0x58, 0xe3, 0x80, 0xc2, 0x22, 0x98, 0xed, 0xf9, 0xd8, 0xeb, 0x58, - 0x07, 0x98, 0x13, 0xe9, 0xff, 0x2e, 0xde, 0x06, 0x37, 0xfb, 0x74, 0x64, 0xdb, 0x5e, 0x77, 0x3c, - 0x3f, 0x80, 0xd8, 0x77, 0x7b, 0x5e, 0x0b, 0x0f, 0x48, 0x14, 0x57, 0x22, 0xec, 0x46, 0xc1, 0xaa, - 0x56, 0x10, 0x15, 0xb8, 0xf8, 0x3e, 0xb8, 0xd1, 0x87, 0x35, 0x70, 0xa0, 0x78, 0xd8, 0xc6, 0x9d, - 0xc0, 0xb1, 0xda, 0x46, 0x6f, 0xfb, 0xc0, 0x09, 0xd2, 0x65, 0x8a, 0x12, 0xf8, 0xb0, 0x87, 0xfd, - 0xc0, 0x71, 0x3b, 0x1d, 0xcb, 0xf1, 0x70, 0x56, 0x02, 0x5f, 0x07, 0xb7, 0xfb, 0x04, 0x20, 0xde, - 0x75, 0x7c, 0x22, 0xe0, 0x9e, 0xd5, 0x6e, 0xe3, 0xce, 0x6e, 0x56, 0x22, 0xd2, 0x65, 0x30, 0x7b, - 0xb0, 0x63, 0xa1, 0xe0, 0xb8, 0x8b, 0x0b, 0x79, 0xda, 0x77, 0xf2, 0x60, 0xc7, 0x32, 0x8f, 0xbb, - 0x58, 0x5a, 0x06, 0xa0, 0xed, 0xee, 0x3a, 0x1d, 0xb4, 0xd3, 0x76, 0x8f, 0x0a, 0x53, 0xb4, 0x73, - 0x8e, 0xb6, 0xac, 0xb7, 0xdd, 0x23, 0x26, 0x3f, 0xc4, 0x2d, 0xf7, 0x10, 0x7b, 0xc7, 0x8a, 0x6b, - 0x63, 0x5f, 0x71, 0x3b, 0x81, 0xd3, 0xe9, 0xe1, 0x8c, 0x93, 0xf2, 0x2e, 0x58, 0x1e, 0x23, 0xd0, - 0x3d, 0xce, 0x88, 0xfc, 0x1e, 0xb8, 0x3a, 0x82, 0xdc, 0xf0, 0x9c, 0x4e, 0x90, 0x11, 0xbb, 0x08, - 0xc4, 0x92, 0xe3, 0x53, 0xe4, 0x1a, 0x0e, 0x2c, 0xdb, 0x0a, 0x2c, 0x69, 0x1e, 0xe4, 0x1d, 0x9b, - 0x43, 0xe6, 0x1d, 0xbb, 0x68, 0x81, 0x42, 0x08, 0x13, 0xda, 0x40, 0x1f, 0x56, 0x05, 0xb3, 0x1e, - 0x6f, 0xa3, 0x18, 0xf3, 0x8f, 0xee, 0xaf, 0x26, 0x2c, 0x8c, 0xd5, 0x51, 0x22, 0xb0, 0x8f, 0x5a, - 0xdc, 0x07, 0x52, 0xd8, 0x6b, 0x04, 0xb8, 0x6b, 0x04, 0x56, 0xd0, 0xf3, 0xa5, 0xf7, 0xc1, 0x09, - 0x9f, 0xfe, 0xc5, 0x49, 0xdf, 0x4d, 0x25, 0xcd, 0x10, 0x21, 0x47, 0x23, 0x6b, 0x09, 0x7b, 0x9e, - 0xeb, 0xf1, 0x09, 0x65, 0x3f, 0x8a, 0xbf, 0x2f, 0x80, 0x85, 0xa6, 0x16, 0x41, 0xf1, 0x02, 0x6c, - 0x33, 0x55, 0xa9, 0x60, 0xf6, 0x80, 0x0f, 0x8d, 0xf2, 0x3c, 0x95, 0x61, 0x38, 0xa1, 0x2e, 0x60, - 0x1f, 0x55, 0x52, 0xfa, 0x82, 0xe7, 0x29, 0x91, 0x57, 0x32, 0x08, 0x1e, 0x8e, 0x3a, 0x14, 0xbe, - 0xf8, 0xaf, 0x02, 0xb8, 0x3e, 0x10, 0x33, 0x54, 0x9a, 0x81, 0xdb, 0xb8, 0x45, 0x56, 0xc8, 0x0b, - 0x15, 0xb8, 0x16, 0x99, 0x46, 0x26, 0xf2, 0xc3, 0xcc, 0xd3, 0x38, 0x20, 0x17, 0x92, 0x88, 0x8c, - 0x7f, 0xea, 0xd3, 0x8f, 0xff, 0xff, 0xe4, 0x89, 0x13, 0x0a, 0x01, 0xb4, 0x4e, 0x80, 0x77, 0x3d, - 0x8b, 0x8c, 0x5c, 0xde, 0x34, 0x74, 0xad, 0xa4, 0x28, 0x6e, 0xa7, 0x83, 0x5b, 0xc1, 0x4b, 0xaf, - 0x87, 0x1f, 0xe7, 0xa3, 0x76, 0x50, 0xb2, 0x02, 0x6b, 0xdb, 0xf2, 0x31, 0x2c, 0x19, 0x6a, 0xc7, - 0x73, 0xdb, 0xed, 0x97, 0x7d, 0xfc, 0xd2, 0x13, 0x50, 0xf0, 0xa9, 0xd1, 0x63, 0x1b, 0x85, 0x94, - 0x7d, 0xd4, 0x72, 0x7b, 0x9d, 0xa0, 0x30, 0x7d, 0x5d, 0xb8, 0x37, 0x05, 0x17, 0xc2, 0xfe, 0x50, - 0x14, 0x5f, 0x21, 0xbd, 0xc5, 0x7f, 0x12, 0xc0, 0x95, 0x81, 0xe6, 0x36, 0x7a, 0xdb, 0x58, 0xdd, - 0xf8, 0x9c, 0x68, 0xad, 0xf8, 0x14, 0x14, 0x9a, 0x9a, 0x62, 0xb5, 0xdb, 0xa6, 0x2b, 0x53, 0x7f, - 0x11, 0x09, 0x08, 0xab, 0x60, 0xaa, 0xc5, 0x47, 0x3c, 0xff, 0xe8, 0x4a, 0x22, 0x75, 0xc5, 0x94, - 0x21, 0x01, 0x2c, 0x7e, 0x6f, 0x26, 0xaa, 0xc7, 0x12, 0xee, 0xb6, 0xdd, 0x63, 0x03, 0x7b, 0x87, - 0x4e, 0x0b, 0xbf, 0xf4, 0xd6, 0xb7, 0x0b, 0xce, 0xd8, 0x74, 0xc0, 0xe8, 0x00, 0x07, 0x7b, 0xae, - 0x4d, 0x4d, 0x6e, 0xfe, 0xd1, 0x5a, 0x22, 0xad, 0x49, 0x8a, 0x5a, 0x65, 0x4d, 0x35, 0x4a, 0x09, - 0x9e, 0xb6, 0x23, 0xbf, 0x24, 0x0b, 0x9c, 0xe2, 0x8c, 0x68, 0x0a, 0x32, 0x43, 0xd9, 0x7c, 0xf0, - 0x9f, 0x61, 0x43, 0x72, 0x17, 0x08, 0xec, 0xfe, 0xdf, 0x45, 0x04, 0x4e, 0x47, 0x05, 0x90, 0x96, - 0xc1, 0xe5, 0x92, 0xda, 0xa8, 0xea, 0x5b, 0xa8, 0xa6, 0x9a, 0x15, 0xbd, 0x84, 0x9a, 0x75, 0xa3, - 0xa1, 0x2a, 0xda, 0xba, 0xa6, 0x96, 0xc4, 0x9c, 0xb4, 0x00, 0xa4, 0xe1, 0x6e, 0xb9, 0x69, 0xea, - 0xa2, 0x20, 0x15, 0xc0, 0x85, 0xe1, 0xf6, 0x9a, 0x5c, 0x6f, 0xca, 0x55, 0x31, 0x5f, 0xc4, 0x00, - 0x0c, 0x58, 0x4b, 0x4b, 0xe0, 0x12, 0x87, 0x33, 0xb7, 0x1a, 0xea, 0x08, 0xf1, 0xab, 0x60, 0x31, - 0xda, 0xa9, 0xd5, 0x0d, 0x53, 0xae, 0x56, 0x91, 0xa1, 0x40, 0xad, 0x61, 0x8a, 0x82, 0xb4, 0x08, - 0x16, 0xa2, 0xfd, 0x72, 0x4d, 0xfe, 0x48, 0xaf, 0x23, 0x55, 0x31, 0xc4, 0x7c, 0xf1, 0x93, 0x69, - 0x70, 0x6b, 0x30, 0x7e, 0xc5, 0xc3, 0x56, 0x80, 0xc3, 0x5f, 0xc7, 0x8a, 0xdb, 0xd9, 0x71, 0x76, - 0x5f, 0x7a, 0xbb, 0x74, 0xc1, 0x99, 0x16, 0x1d, 0xe9, 0xb0, 0x5d, 0x3e, 0xcd, 0x60, 0x30, 0xc9, - 0x0a, 0x5b, 0x65, 0x7f, 0x87, 0xf6, 0xd9, 0x8a, 0xfc, 0x2a, 0xfe, 0xa1, 0x00, 0x4e, 0x47, 0xbb, - 0x89, 0xf5, 0x28, 0x7a, 0x7d, 0x5d, 0x2b, 0xc7, 0x5b, 0xcf, 0x58, 0xb7, 0xbc, 0x69, 0x20, 0x55, - 0x79, 0x84, 0x0c, 0xa3, 0x26, 0x0a, 0x64, 0xfe, 0xe3, 0xbb, 0x55, 0x4d, 0x51, 0xc5, 0x7c, 0x3c, - 0x3a, 0x2c, 0x19, 0xd4, 0x04, 0xa6, 0xa4, 0xcb, 0xe0, 0x62, 0x0c, 0xfa, 0x86, 0x21, 0x4e, 0x17, - 0xff, 0x45, 0x00, 0xd7, 0x62, 0xe2, 0x25, 0xdf, 0x17, 0xbc, 0xf4, 0x8e, 0xff, 0x7f, 0xe6, 0xa3, - 0x8b, 0x23, 0x1c, 0x3e, 0x9b, 0xb9, 0x9e, 0x87, 0x6b, 0x66, 0xd5, 0x78, 0xe9, 0x75, 0xf0, 0xff, - 0xf3, 0xe0, 0x61, 0xd4, 0x41, 0xfa, 0xfb, 0x81, 0xdb, 0x25, 0x61, 0xf0, 0x10, 0x97, 0x1c, 0x0f, - 0xb7, 0x02, 0xd7, 0x3b, 0x36, 0x5d, 0xb7, 0xed, 0x6b, 0x1d, 0x3f, 0xb0, 0x3e, 0x07, 0xd9, 0xc0, - 0x77, 0xf2, 0x60, 0x35, 0x4d, 0x21, 0x7d, 0x13, 0x79, 0xe9, 0xb5, 0xf1, 0x27, 0x79, 0x70, 0x67, - 0xa0, 0x0d, 0xb9, 0x17, 0xb8, 0xe1, 0xdf, 0x91, 0x14, 0xf2, 0xa5, 0x8f, 0x20, 0x77, 0xc1, 0xd9, - 0xf8, 0x74, 0x7a, 0xde, 0x1b, 0x4e, 0xa3, 0xbf, 0x99, 0x07, 0x37, 0x07, 0xea, 0x52, 0x95, 0x47, - 0x74, 0xd5, 0x74, 0x3e, 0x4f, 0x7b, 0xd1, 0x7f, 0x14, 0xc0, 0xe5, 0xd1, 0x8c, 0x8b, 0x04, 0xaa, - 0xcf, 0xd9, 0xc0, 0x59, 0xe6, 0x50, 0x77, 0xed, 0x97, 0xdf, 0x47, 0xfc, 0x5c, 0x00, 0x57, 0x47, - 0x07, 0x2e, 0x77, 0xbb, 0x24, 0xcd, 0xfe, 0x1c, 0x24, 0x11, 0xdf, 0xce, 0x83, 0xfb, 0x13, 0x92, - 0x08, 0x4d, 0xae, 0x35, 0xdc, 0xb6, 0xd3, 0x3a, 0x7e, 0xe9, 0x15, 0xf1, 0xef, 0x02, 0x28, 0x0e, - 0x14, 0xd1, 0xf0, 0x9c, 0x4e, 0xcb, 0xe9, 0x5a, 0x6d, 0xff, 0xf3, 0x13, 0x2c, 0xff, 0x59, 0x00, - 0xcb, 0x03, 0x0d, 0x98, 0xd8, 0x0f, 0xf8, 0xc1, 0xdb, 0xe7, 0xc1, 0xef, 0xff, 0x83, 0x00, 0x0a, - 0x11, 0x2f, 0xc0, 0x2f, 0x5e, 0xec, 0x97, 0x7e, 0xdc, 0x4b, 0xc4, 0xeb, 0x73, 0x6f, 0x8f, 0x8f, - 0xa0, 0xdb, 0x8e, 0x5e, 0x0e, 0xfd, 0x15, 0xb5, 0x88, 0xa1, 0x5e, 0xc3, 0x3a, 0x8c, 0x5e, 0x76, - 0xdc, 0x04, 0x67, 0x48, 0x86, 0x60, 0x5b, 0x9e, 0x8d, 0x7a, 0x3e, 0x66, 0x97, 0x09, 0xb3, 0xf0, - 0x74, 0xd8, 0xd8, 0xf4, 0xb1, 0x2d, 0x2d, 0x81, 0xb9, 0x63, 0xeb, 0xa0, 0xcd, 0x00, 0xf2, 0x14, - 0x60, 0x96, 0x34, 0xd0, 0xce, 0x3b, 0xe0, 0xec, 0x81, 0x6b, 0x63, 0x74, 0xb4, 0x87, 0x3b, 0xc8, - 0xb7, 0x0e, 0xb1, 0xcd, 0xef, 0x5d, 0xce, 0x90, 0xe6, 0xcd, 0x3d, 0xdc, 0x21, 0x2c, 0x6d, 0x49, - 0x06, 0xcb, 0x3b, 0x0e, 0x6e, 0xdb, 0x3e, 0x3a, 0x72, 0x82, 0x3d, 0xd4, 0x72, 0x3b, 0x87, 0xd8, - 0xf3, 0x1d, 0xb7, 0x83, 0xe8, 0x59, 0xbf, 0x5f, 0x98, 0xbe, 0x3e, 0x75, 0x6f, 0x0e, 0x2e, 0x32, - 0xa0, 0x4d, 0x27, 0xd8, 0x53, 0xfa, 0x20, 0x2a, 0x85, 0x28, 0xde, 0x20, 0xdb, 0xc5, 0xe1, 0xb1, - 0x92, 0xe4, 0xa6, 0x1d, 0x19, 0xf1, 0xab, 0x60, 0x65, 0x04, 0xe4, 0x99, 0x83, 0x8f, 0x4a, 0x6e, - 0xab, 0x77, 0x80, 0x3b, 0x81, 0x35, 0x7c, 0xbc, 0x56, 0xfc, 0x91, 0x00, 0x2e, 0xca, 0xbe, 0xef, - 0x90, 0x95, 0x42, 0x0d, 0xa6, 0xbf, 0x52, 0xee, 0x82, 0xb3, 0x5c, 0x42, 0x8a, 0x83, 0xfa, 0xd7, - 0x2c, 0xf3, 0xd1, 0x66, 0xcd, 0x96, 0x6e, 0x80, 0xd3, 0x81, 0x1b, 0x58, 0x6d, 0x14, 0xb8, 0xfb, - 0xb8, 0xc3, 0xae, 0x11, 0xa6, 0xe0, 0x29, 0xda, 0x66, 0xd2, 0x26, 0xa2, 0xe3, 0xae, 0xe7, 0x1e, - 0x74, 0x83, 0x10, 0x66, 0x8a, 0xc2, 0x9c, 0x66, 0x8d, 0x1c, 0xe8, 0x15, 0x70, 0xae, 0xd5, 0x97, - 0x21, 0x04, 0x64, 0x59, 0x9e, 0x38, 0xe8, 0x60, 0xc0, 0xc5, 0xbf, 0x16, 0xc0, 0x05, 0x26, 0xb7, - 0xfa, 0x31, 0x6e, 0xf5, 0x3e, 0x85, 0xd8, 0xcb, 0x00, 0x74, 0xc8, 0xac, 0xb1, 0x6c, 0x92, 0x09, - 0x3d, 0x47, 0x5a, 0x68, 0x22, 0x39, 0x36, 0xaa, 0xa9, 0x0c, 0xa3, 0x9a, 0xce, 0x3a, 0xaa, 0x99, - 0x84, 0x51, 0x3d, 0x01, 0x8b, 0x6c, 0x50, 0x75, 0x7c, 0xa4, 0x44, 0xc4, 0xed, 0xdf, 0x8d, 0xb5, - 0xac, 0x00, 0xef, 0xba, 0xde, 0x71, 0x78, 0x37, 0x16, 0xfe, 0x2e, 0xfe, 0xa9, 0x00, 0xce, 0x33, - 0x54, 0x99, 0x5e, 0xdd, 0x42, 0xfc, 0xb5, 0x1e, 0xf6, 0xa9, 0x75, 0x87, 0xab, 0x8d, 0x9d, 0xd5, - 0x31, 0xc4, 0xd3, 0x61, 0x23, 0x3d, 0xfc, 0xfa, 0x85, 0xcc, 0xe0, 0x27, 0x02, 0x38, 0x1d, 0x4a, - 0x4c, 0x9a, 0xa5, 0x05, 0x70, 0xc2, 0xa2, 0x7f, 0x71, 0x19, 0xf9, 0xaf, 0x5f, 0x8c, 0x74, 0xb7, - 0x80, 0xc4, 0x14, 0x59, 0x75, 0xfc, 0x20, 0xf1, 0xb6, 0xf1, 0x1b, 0xa0, 0x10, 0x85, 0x3a, 0xd8, - 0x8e, 0xdc, 0x4c, 0x4a, 0x60, 0x3a, 0x72, 0x8b, 0x49, 0xff, 0x96, 0x74, 0x70, 0xf6, 0x80, 0x42, - 0xf9, 0x7b, 0x4e, 0x17, 0xed, 0x3b, 0x1d, 0xe6, 0x4c, 0xe6, 0x1f, 0xdd, 0x19, 0x38, 0xbe, 0xc8, - 0xd5, 0xfb, 0xe1, 0xc3, 0xd5, 0x5a, 0x1f, 0x7c, 0xc3, 0xe9, 0xd8, 0x70, 0xfe, 0x60, 0xe8, 0x77, - 0xf1, 0x2b, 0x40, 0x1c, 0x08, 0xc0, 0x16, 0xbd, 0x54, 0x1e, 0x73, 0xf5, 0xc9, 0x6e, 0x75, 0x7c, - 0x8c, 0x03, 0x67, 0x3f, 0x4c, 0xbc, 0xd9, 0xb5, 0x3f, 0x3b, 0xe2, 0x25, 0x4c, 0x42, 0xd5, 0x8b, - 0x23, 0xfe, 0x67, 0x02, 0x58, 0x18, 0x9d, 0x98, 0x17, 0xac, 0x1d, 0xe9, 0xa3, 0x70, 0x2e, 0x51, - 0x9f, 0x5e, 0x5a, 0x44, 0x4c, 0xb2, 0x95, 0x70, 0x5a, 0x6b, 0x93, 0xe4, 0x7f, 0xc1, 0x13, 0xf0, - 0x5f, 0x2e, 0xff, 0x0b, 0x9e, 0xe3, 0xcf, 0x54, 0xfe, 0xdf, 0xce, 0x47, 0xe5, 0x2f, 0x7b, 0x56, - 0x27, 0xf0, 0x4d, 0xb7, 0xe9, 0x63, 0x4f, 0x5a, 0x05, 0xe7, 0x69, 0xc4, 0x40, 0x9e, 0xdb, 0xc6, - 0x3e, 0xda, 0x25, 0x7d, 0x3c, 0x69, 0x98, 0x81, 0xe7, 0x68, 0x17, 0x89, 0xb9, 0x7e, 0x99, 0x75, - 0x90, 0xa0, 0xcf, 0xe0, 0x9d, 0xce, 0x1e, 0xf6, 0x1c, 0x7a, 0x31, 0x38, 0x84, 0x39, 0x45, 0x31, - 0x17, 0x29, 0x90, 0x16, 0xc2, 0x0c, 0x91, 0x78, 0x1d, 0x5c, 0x60, 0x24, 0x02, 0xcf, 0x72, 0x82, - 0x01, 0x66, 0x9e, 0x62, 0x4a, 0xb4, 0xcf, 0xa4, 0x5d, 0x21, 0x86, 0x02, 0xae, 0x8e, 0x32, 0x1d, - 0xc1, 0x9d, 0xa6, 0xb8, 0x4b, 0xc3, 0x5c, 0x87, 0x89, 0x2c, 0x81, 0xb9, 0x9e, 0x8f, 0x3d, 0x44, - 0xbd, 0xd8, 0xcc, 0xa0, 0x16, 0xa3, 0x6e, 0x1d, 0xe0, 0xe2, 0x0f, 0xa6, 0xa2, 0x1a, 0x82, 0xf8, - 0xd0, 0xc1, 0x47, 0x2f, 0x7a, 0x85, 0x3d, 0x01, 0x97, 0x6d, 0xeb, 0xd8, 0x47, 0x5d, 0xcb, 0x0f, - 0x50, 0x07, 0x7f, 0x1c, 0x20, 0xab, 0x67, 0x3b, 0x01, 0x22, 0xeb, 0x80, 0x0f, 0xfe, 0x22, 0x01, - 0x68, 0x58, 0x24, 0x60, 0x7e, 0x1c, 0xc8, 0xa4, 0xb7, 0x44, 0x44, 0x58, 0x07, 0xd7, 0x22, 0x7e, - 0xd6, 0xc3, 0x5f, 0xeb, 0x39, 0x1e, 0x26, 0xe9, 0x8f, 0x8f, 0x5a, 0x7b, 0x56, 0x67, 0x97, 0xab, - 0x7d, 0x16, 0x2e, 0x0f, 0xc0, 0x60, 0x04, 0x4a, 0x61, 0x40, 0xd2, 0x13, 0x50, 0xf0, 0xe8, 0xd0, - 0xd0, 0x0e, 0x21, 0x82, 0x3b, 0xad, 0xe3, 0x3e, 0x81, 0x69, 0x4a, 0x60, 0x81, 0xf5, 0xaf, 0x87, - 0xdd, 0x21, 0xe6, 0x7b, 0x60, 0x89, 0x63, 0xda, 0xd6, 0x31, 0x72, 0x77, 0xd0, 0x81, 0xdb, 0x21, - 0x39, 0x1f, 0x47, 0x9e, 0xa1, 0xc8, 0x97, 0x18, 0x48, 0xc9, 0x3a, 0xd6, 0x77, 0x6a, 0xa4, 0x3f, - 0xc4, 0x7e, 0x1b, 0x5c, 0xee, 0xf4, 0xa8, 0x6d, 0xbb, 0x3b, 0xc8, 0xc3, 0x07, 0xee, 0x21, 0xb6, - 0x11, 0x17, 0xb5, 0x70, 0x82, 0x8e, 0x7c, 0x81, 0x01, 0xe8, 0x3b, 0x90, 0x75, 0xf3, 0x40, 0x51, - 0xfc, 0x35, 0x61, 0x7c, 0x62, 0x5e, 0xf4, 0xd2, 0x7b, 0x08, 0x2e, 0xb2, 0x28, 0x85, 0x48, 0x98, - 0x42, 0x7c, 0xa0, 0x8e, 0xcd, 0x4b, 0x57, 0x24, 0x6b, 0x84, 0xbf, 0x66, 0x17, 0xbf, 0x2b, 0x80, - 0xcb, 0x91, 0xb2, 0x08, 0x76, 0xb1, 0x9d, 0x14, 0x57, 0xa5, 0x35, 0x30, 0x1d, 0x09, 0x8e, 0xab, - 0x89, 0x52, 0x8e, 0x51, 0xa4, 0x41, 0x92, 0xe2, 0x0e, 0x9b, 0xef, 0xd4, 0x88, 0xf9, 0xba, 0x64, - 0x57, 0x30, 0x86, 0x4d, 0xcb, 0x6b, 0x58, 0xae, 0x55, 0x1f, 0xd3, 0xd5, 0xa3, 0xec, 0x52, 0xc4, - 0x44, 0x24, 0x0f, 0x5c, 0x8f, 0x61, 0x18, 0x6e, 0xd2, 0x3e, 0x1b, 0x9e, 0x5f, 0x07, 0x4b, 0x31, - 0x43, 0xec, 0x57, 0x2c, 0x55, 0xc0, 0x74, 0xcb, 0xb5, 0xc3, 0x52, 0xa8, 0xc7, 0xd9, 0x59, 0x31, - 0x7c, 0xc5, 0xb5, 0x31, 0xa4, 0x14, 0x12, 0x4a, 0x97, 0xbe, 0x99, 0x07, 0x57, 0x62, 0x95, 0x8c, - 0xbb, 0x9f, 0xc9, 0x78, 0x89, 0xd5, 0xf8, 0x01, 0xee, 0x3e, 0xbf, 0xd5, 0x10, 0x91, 0x20, 0xc5, - 0x95, 0xaa, 0x23, 0x3b, 0xd2, 0xc7, 0xcf, 0x47, 0x65, 0xfc, 0x68, 0xea, 0x66, 0x9c, 0x0a, 0xd8, - 0x89, 0x84, 0xde, 0xc5, 0x9d, 0x5f, 0x5e, 0x4d, 0x6c, 0x80, 0x93, 0x3e, 0x93, 0x93, 0xaa, 0x62, - 0x7e, 0x42, 0x5c, 0x4d, 0x1a, 0x20, 0x0c, 0x29, 0x14, 0xbf, 0x95, 0x07, 0xb7, 0x63, 0x14, 0xb1, - 0x4e, 0x76, 0xba, 0x9f, 0xe9, 0x22, 0x78, 0x21, 0xaa, 0x50, 0xc1, 0x0c, 0xdd, 0x93, 0x73, 0x45, - 0x3c, 0xc8, 0x4e, 0x84, 0x0e, 0x10, 0x32, 0xec, 0xe2, 0xbf, 0x09, 0x09, 0x4e, 0x80, 0xec, 0x39, - 0xbb, 0xc7, 0xbf, 0xbc, 0xe3, 0x5f, 0x07, 0xd3, 0x74, 0xef, 0xc8, 0x86, 0xff, 0x1c, 0xf2, 0x90, - 0xa1, 0xd1, 0xca, 0x0e, 0x8a, 0x5f, 0xfc, 0x4b, 0x01, 0xdc, 0x88, 0x51, 0x40, 0xd5, 0xe9, 0xec, - 0x47, 0x0e, 0x64, 0x7e, 0x19, 0x35, 0x20, 0x81, 0xe9, 0xb6, 0xd3, 0xd9, 0xe7, 0x71, 0x84, 0xfe, - 0x5d, 0xfc, 0x5b, 0x01, 0x9c, 0xef, 0x97, 0x23, 0xd3, 0xd4, 0xa7, 0x7f, 0xa0, 0x94, 0xbe, 0xe5, - 0x8e, 0x5c, 0x68, 0x21, 0xd7, 0x73, 0x76, 0x9d, 0x0e, 0x77, 0x9e, 0xfd, 0x0b, 0x2d, 0x9d, 0xb6, - 0x4a, 0xb7, 0xc1, 0x7c, 0xab, 0xed, 0xf6, 0x6c, 0xd4, 0xf5, 0xdc, 0x43, 0xc7, 0xc6, 0x5e, 0x78, - 0xb6, 0x44, 0x5b, 0x1b, 0xbc, 0x51, 0xd2, 0xc1, 0xac, 0xcd, 0x4f, 0xbe, 0x69, 0x66, 0x72, 0xea, - 0xd1, 0x1b, 0xa9, 0x67, 0x69, 0xd8, 0x0e, 0x0f, 0xcb, 0x07, 0x5a, 0x0b, 0x89, 0x14, 0x9f, 0x81, - 0xc5, 0x64, 0x38, 0xe9, 0x12, 0x38, 0x69, 0x6f, 0x47, 0x47, 0x77, 0xc2, 0xde, 0xa6, 0xe3, 0xba, - 0x06, 0x4e, 0xd9, 0xdb, 0x88, 0xd6, 0x8c, 0xb7, 0xdc, 0x36, 0x1f, 0x13, 0xb0, 0xb7, 0x1b, 0xbc, - 0xa5, 0xf8, 0x33, 0x01, 0x2c, 0xae, 0x63, 0x2b, 0xe8, 0x79, 0x18, 0xe2, 0x96, 0x7b, 0x70, 0x80, - 0x3b, 0x76, 0xe4, 0x8c, 0x63, 0x28, 0x6a, 0x0b, 0xc3, 0x51, 0x5b, 0x7a, 0x07, 0x9c, 0xdc, 0x61, - 0xa8, 0x7c, 0x32, 0xaf, 0x27, 0x8e, 0x31, 0x64, 0x11, 0x22, 0x48, 0x1f, 0x83, 0x65, 0xfe, 0x27, - 0xf2, 0x86, 0xf8, 0xa2, 0x88, 0xbf, 0x9f, 0x14, 0x06, 0x63, 0x85, 0xe6, 0xfe, 0x7e, 0x69, 0x27, - 0xb9, 0xb3, 0x78, 0x04, 0x2e, 0x98, 0x72, 0x99, 0x1d, 0x53, 0xe1, 0x0f, 0x7b, 0xd8, 0xe3, 0x2b, - 0xfd, 0x1a, 0x60, 0x67, 0x18, 0xa8, 0xe3, 0xda, 0x98, 0x95, 0x0d, 0x4f, 0x41, 0x40, 0x9b, 0xea, - 0xa4, 0x65, 0x00, 0x80, 0xed, 0x5d, 0x1c, 0x9e, 0x7b, 0x30, 0x00, 0x95, 0xb4, 0x48, 0xcb, 0x00, - 0x38, 0x3e, 0xf2, 0x7b, 0x34, 0xdd, 0xe2, 0x19, 0xed, 0x9c, 0xe3, 0x1b, 0xac, 0xa1, 0xf8, 0xf7, - 0x53, 0xe0, 0x12, 0xcb, 0xe3, 0xca, 0x9e, 0xd5, 0xdd, 0x93, 0x37, 0x0d, 0xa3, 0x65, 0x75, 0xc2, - 0xb2, 0xba, 0xf3, 0x9c, 0x76, 0xeb, 0x11, 0x72, 0xf8, 0x1d, 0x29, 0x13, 0x62, 0x1a, 0x9e, 0x63, - 0x3c, 0x5a, 0xfd, 0xcb, 0xd3, 0x88, 0x2c, 0x64, 0x32, 0x98, 0x2c, 0xd3, 0x5c, 0x16, 0xb2, 0x2d, - 0xf2, 0x07, 0xa7, 0x34, 0xbb, 0x9e, 0xdb, 0xeb, 0x32, 0x69, 0xa6, 0xf9, 0x29, 0x4d, 0x99, 0x36, - 0x0d, 0x68, 0xd0, 0x0d, 0x10, 0x35, 0xd3, 0x90, 0x06, 0xdd, 0xef, 0x10, 0x5b, 0x67, 0x00, 0x5d, - 0xb7, 0xed, 0xb4, 0x1c, 0xcc, 0x0e, 0xca, 0xa6, 0xe1, 0x19, 0xda, 0xda, 0xe0, 0x8d, 0xd2, 0xab, - 0x40, 0xe2, 0xb2, 0xef, 0xfb, 0xa8, 0xd5, 0xee, 0xf9, 0x41, 0x98, 0x16, 0x4f, 0x43, 0x91, 0x89, - 0xbe, 0xef, 0x2b, 0xbc, 0x7d, 0x30, 0x52, 0xcf, 0xf6, 0x23, 0x23, 0x3d, 0x19, 0x19, 0x29, 0xb4, - 0xfd, 0xc1, 0x48, 0xef, 0x01, 0x46, 0x03, 0xf9, 0x6f, 0xa0, 0xed, 0x5e, 0x6b, 0x1f, 0x07, 0x7e, - 0x61, 0x96, 0x02, 0x33, 0xe1, 0x8c, 0x37, 0xd6, 0x58, 0x2b, 0xd9, 0x97, 0x71, 0x48, 0xeb, 0xa0, - 0xdd, 0x5f, 0x9f, 0x7e, 0x61, 0x8e, 0x42, 0x33, 0x19, 0x0d, 0xeb, 0xa0, 0x1d, 0x2e, 0xd2, 0x08, - 0x86, 0xeb, 0xd8, 0xad, 0x08, 0x06, 0x88, 0x60, 0xe8, 0x8e, 0xdd, 0x1a, 0x60, 0xf4, 0x55, 0x62, - 0xb5, 0xe8, 0x5e, 0xcd, 0x2f, 0x9c, 0x8a, 0xa8, 0x44, 0xe6, 0x8d, 0xc5, 0x1f, 0x08, 0xe0, 0x56, - 0x53, 0x8b, 0x4c, 0xb6, 0xe2, 0xb9, 0x47, 0x9d, 0xa7, 0xf8, 0x08, 0xb7, 0x4b, 0xce, 0xce, 0xce, - 0x33, 0x07, 0x1f, 0xb1, 0x79, 0x7f, 0x02, 0x0a, 0xd6, 0xce, 0xce, 0x70, 0x81, 0x2a, 0x8a, 0xd4, - 0xc4, 0xcf, 0xc1, 0x85, 0xb0, 0xbf, 0x5f, 0xc5, 0xcd, 0xce, 0xea, 0x1f, 0x83, 0x85, 0x71, 0xcc, - 0xc8, 0x0b, 0x84, 0x0b, 0xa3, 0x78, 0xb4, 0x8c, 0x6f, 0x1d, 0x5c, 0x31, 0x70, 0xab, 0xe7, 0x39, - 0xc1, 0x31, 0xa4, 0xcb, 0xaa, 0x8c, 0x03, 0x88, 0xfd, 0x5e, 0x9b, 0xe7, 0xd9, 0x71, 0xa7, 0x64, - 0x12, 0x98, 0x26, 0xdb, 0x3a, 0xbe, 0xc5, 0xa3, 0x7f, 0x17, 0x2d, 0x70, 0xbe, 0x5f, 0x04, 0xb6, - 0x8e, 0x83, 0xd6, 0x1e, 0x43, 0x1f, 0xf7, 0x8e, 0x42, 0x9c, 0x77, 0x1c, 0x73, 0xc9, 0xf9, 0x71, - 0x97, 0x5c, 0xfc, 0xbe, 0x00, 0x24, 0x62, 0xcb, 0xa6, 0xe5, 0xef, 0x93, 0xa5, 0x8b, 0xfb, 0x1e, - 0x29, 0xb0, 0xfc, 0xfd, 0xa8, 0xb3, 0x9b, 0x25, 0x0d, 0xe1, 0x6b, 0x0b, 0xc7, 0xf7, 0x7b, 0x43, - 0x54, 0xe7, 0x68, 0x0b, 0xed, 0xbe, 0x00, 0x66, 0x88, 0x77, 0x09, 0xf7, 0x1f, 0xec, 0x07, 0xf1, - 0xfd, 0x7d, 0x3b, 0x8c, 0x14, 0x33, 0xcc, 0xc0, 0xf9, 0x7e, 0x33, 0x2b, 0x66, 0xf8, 0xcd, 0x0f, - 0xc0, 0xd9, 0x26, 0xf1, 0x42, 0x54, 0x12, 0xbd, 0x83, 0xf5, 0x1d, 0xa9, 0x09, 0xce, 0xf6, 0x1c, - 0xb4, 0x4d, 0x5f, 0xe2, 0xa0, 0x16, 0x89, 0x9a, 0xa9, 0x7b, 0xb9, 0xf1, 0x87, 0x3b, 0x95, 0x1c, - 0x3c, 0xd3, 0x73, 0x22, 0xad, 0xd2, 0x27, 0x02, 0xb8, 0xdf, 0x73, 0x90, 0xcb, 0x1e, 0xa6, 0x20, - 0x7e, 0x1e, 0x8a, 0xd1, 0xae, 0x8b, 0x02, 0x17, 0xd9, 0xe1, 0xcb, 0x1d, 0xce, 0x91, 0xe5, 0xc6, - 0xf2, 0x04, 0x8e, 0xd9, 0x9e, 0xff, 0x54, 0x72, 0xf0, 0x66, 0xcf, 0x49, 0x85, 0x95, 0xbe, 0x23, - 0x80, 0x9b, 0x11, 0xe9, 0x2c, 0xdb, 0x46, 0x3b, 0x8e, 0x47, 0xb7, 0x9e, 0x7c, 0x56, 0x99, 0x5c, - 0x2c, 0xf2, 0xbd, 0x97, 0x2e, 0x57, 0xf2, 0x73, 0xa2, 0x4a, 0x0e, 0x5e, 0xed, 0x8b, 0x14, 0x0b, - 0x36, 0xaa, 0xab, 0x18, 0x69, 0xda, 0x56, 0xd0, 0x9f, 0x9d, 0x99, 0xac, 0xba, 0x4a, 0x79, 0xbb, - 0x34, 0xa4, 0xab, 0x64, 0x58, 0xe9, 0x7f, 0x0b, 0xe0, 0x7a, 0x44, 0x3a, 0x1f, 0x07, 0xa8, 0xd5, - 0x7f, 0xe6, 0x84, 0x7c, 0xfa, 0xc2, 0x88, 0x3a, 0xcb, 0x53, 0x8f, 0xde, 0x49, 0x17, 0x2a, 0xe9, - 0x91, 0x54, 0x25, 0x07, 0xaf, 0xf4, 0xa5, 0x89, 0x01, 0x92, 0x7e, 0x45, 0x00, 0xb7, 0x22, 0x62, - 0x78, 0xbc, 0xa4, 0x11, 0xb5, 0xc2, 0xb7, 0x4e, 0xa1, 0x28, 0x27, 0xa9, 0x28, 0x5f, 0x4a, 0x17, - 0x65, 0xd2, 0x6b, 0xa9, 0x4a, 0x0e, 0x5e, 0xef, 0x8b, 0x93, 0x00, 0x18, 0x6a, 0xc6, 0xe3, 0xef, - 0x8f, 0x10, 0xd9, 0xbb, 0x92, 0x05, 0xc8, 0xde, 0x3f, 0xf1, 0xe9, 0x9a, 0x4d, 0xd5, 0x4c, 0xca, - 0xeb, 0x29, 0xa6, 0x99, 0x64, 0x20, 0xe9, 0x63, 0x70, 0x25, 0x4e, 0x8a, 0xee, 0x31, 0x97, 0x60, - 0x8e, 0x4a, 0xf0, 0x85, 0xec, 0x12, 0x44, 0x9f, 0x5f, 0x55, 0x72, 0xb0, 0x30, 0xc6, 0x9d, 0x03, - 0x48, 0xff, 0x03, 0x2c, 0x8f, 0x73, 0xee, 0x7a, 0x4e, 0x27, 0xe0, 0xac, 0x01, 0x65, 0xfd, 0x56, - 0x56, 0xd6, 0x23, 0x8f, 0xb7, 0x2a, 0x39, 0x78, 0x79, 0x84, 0xf7, 0x00, 0x42, 0x6a, 0x83, 0xcb, - 0x3d, 0x07, 0xd9, 0xdc, 0x89, 0x93, 0xac, 0xcb, 0x23, 0xa1, 0x84, 0x12, 0xa7, 0x41, 0xed, 0xd4, - 0x84, 0x8d, 0x55, 0xfc, 0x13, 0xa8, 0x4a, 0x0e, 0x2e, 0xf4, 0x9c, 0xd8, 0xc7, 0x51, 0xdf, 0x61, - 0xe6, 0xd7, 0x67, 0x37, 0x88, 0x75, 0x61, 0x1d, 0x18, 0xe7, 0x7c, 0x9a, 0x72, 0x7e, 0x3b, 0x03, - 0xe7, 0xf8, 0x57, 0x4d, 0xcc, 0xf2, 0x52, 0x5e, 0x3e, 0x7d, 0x83, 0x1a, 0x5e, 0x5f, 0x18, 0x5e, - 0x3b, 0xef, 0xb3, 0x32, 0x78, 0x2e, 0xc8, 0x19, 0x2a, 0xc8, 0x9b, 0x9f, 0xaa, 0x88, 0x9e, 0xd9, - 0xdc, 0x84, 0x47, 0x0f, 0xff, 0x97, 0x39, 0xd0, 0x81, 0x04, 0x3c, 0xa1, 0x1f, 0xac, 0x4b, 0x26, - 0xc4, 0x3c, 0x15, 0xe2, 0x49, 0x16, 0x21, 0xe2, 0x6a, 0x95, 0x2b, 0x39, 0x78, 0x2d, 0x22, 0x47, - 0x6c, 0x39, 0xf3, 0x6f, 0x30, 0xef, 0x39, 0x2e, 0x4a, 0x2b, 0x2c, 0x53, 0x41, 0x07, 0x41, 0xdb, - 0xe7, 0x02, 0x9d, 0xa5, 0x02, 0x7d, 0xf1, 0x39, 0x04, 0x1a, 0xaf, 0x1e, 0xae, 0xe4, 0xe0, 0xad, - 0x71, 0xa9, 0x06, 0x70, 0x41, 0x9b, 0x17, 0x50, 0xfe, 0xb9, 0x00, 0x9e, 0x0c, 0xcf, 0x13, 0xad, - 0x3d, 0x45, 0x16, 0x2d, 0x3e, 0x45, 0x76, 0x58, 0x7d, 0x8a, 0x02, 0xd7, 0x6d, 0xf3, 0x64, 0xb2, - 0xdd, 0xe6, 0x92, 0x8a, 0x54, 0xd2, 0xa7, 0x99, 0xe6, 0x2f, 0x53, 0x8d, 0x6f, 0x25, 0x07, 0x1f, - 0x46, 0x27, 0x35, 0x5b, 0x61, 0xf0, 0x8f, 0x05, 0xf0, 0x38, 0xd3, 0x18, 0x06, 0xea, 0x66, 0xf2, - 0x9f, 0xa3, 0xf2, 0x97, 0x3f, 0xb5, 0xfc, 0xc3, 0x55, 0x46, 0x95, 0x1c, 0x5c, 0x4d, 0x13, 0x7e, - 0xa4, 0x2e, 0xe9, 0xb7, 0x04, 0xf0, 0x4a, 0x54, 0x72, 0xab, 0x47, 0x32, 0x8f, 0xfe, 0x1e, 0x34, - 0xf2, 0x9e, 0x8a, 0x09, 0x2c, 0x51, 0x81, 0xdf, 0xcf, 0x20, 0xf0, 0xa4, 0xaa, 0xd9, 0x4a, 0x0e, - 0xde, 0x19, 0x08, 0x3a, 0xb1, 0xbe, 0xf6, 0x8f, 0x05, 0xf0, 0x20, 0xc5, 0x72, 0x1d, 0xeb, 0x80, - 0x6d, 0x5e, 0x8e, 0xb9, 0x90, 0xe7, 0xa9, 0x90, 0x6b, 0x9f, 0xc6, 0x7e, 0x87, 0x0b, 0xd7, 0x2a, - 0x39, 0x78, 0x7f, 0x82, 0x11, 0x6b, 0xd6, 0x41, 0xb4, 0xca, 0xed, 0x57, 0x05, 0x70, 0x27, 0x2a, - 0x6a, 0xb7, 0x5f, 0x0c, 0x36, 0x36, 0xef, 0x17, 0xa8, 0x84, 0xef, 0x66, 0x90, 0x30, 0xa9, 0xa2, - 0xac, 0x92, 0x83, 0xc5, 0x81, 0x68, 0x89, 0x75, 0x67, 0xdf, 0x12, 0xc0, 0x8d, 0xa8, 0x4c, 0x01, - 0xf6, 0x03, 0x22, 0x4d, 0x67, 0xc8, 0x1f, 0x5f, 0x4c, 0x8d, 0x7e, 0x13, 0xca, 0xbb, 0x2a, 0x39, - 0xb8, 0x3c, 0x90, 0x24, 0xae, 0xfe, 0xcb, 0x03, 0x4b, 0x51, 0x19, 0xc2, 0x3c, 0x37, 0x8c, 0x43, - 0x0b, 0x29, 0x37, 0x88, 0x49, 0xf5, 0x55, 0x2c, 0xec, 0x26, 0xd4, 0x5e, 0xb5, 0x41, 0xa1, 0xe7, - 0x90, 0x24, 0xcc, 0x0a, 0x30, 0xea, 0xe0, 0x23, 0xba, 0xff, 0xe5, 0x11, 0xf7, 0x52, 0xca, 0x01, - 0x57, 0x62, 0x65, 0x53, 0x25, 0x07, 0x2f, 0xf4, 0x9c, 0xf1, 0x4e, 0xe9, 0x98, 0x06, 0xf9, 0x51, - 0x6e, 0xbe, 0x75, 0x18, 0xb2, 0x2c, 0xa4, 0x6a, 0x78, 0x42, 0xb9, 0x14, 0x1b, 0x68, 0x3c, 0x80, - 0xf4, 0x0d, 0x70, 0x2d, 0x6e, 0xa0, 0xb4, 0x42, 0x89, 0x33, 0xbf, 0x9c, 0x1a, 0x60, 0x26, 0x56, - 0x37, 0x55, 0x72, 0x70, 0x71, 0x74, 0xd4, 0x03, 0x10, 0xe9, 0x77, 0x99, 0x0b, 0x19, 0x95, 0x80, - 0xdd, 0xc3, 0x45, 0x2b, 0xa0, 0xb8, 0x34, 0x8b, 0x54, 0x1a, 0x25, 0xab, 0x34, 0x13, 0x0a, 0xa9, - 0x2a, 0x39, 0x78, 0x7b, 0x44, 0xb0, 0x78, 0x68, 0xe9, 0x0f, 0x04, 0xb0, 0x1a, 0x35, 0x41, 0x67, - 0x70, 0xec, 0x88, 0xac, 0x23, 0x9f, 0x1d, 0x0d, 0xf0, 0x65, 0xc1, 0xad, 0x72, 0x29, 0x75, 0x0b, - 0x91, 0xed, 0xe5, 0x71, 0x25, 0x07, 0xef, 0x0d, 0xac, 0x34, 0x0a, 0x7b, 0xe4, 0xeb, 0x8e, 0xdd, - 0x1a, 0x7a, 0xa5, 0xfc, 0x5d, 0x01, 0xdc, 0x8e, 0x4f, 0x19, 0x6c, 0x1f, 0x61, 0x7a, 0x40, 0xca, - 0xc5, 0xbb, 0x92, 0x39, 0x85, 0x8a, 0x7f, 0x10, 0x3c, 0x9c, 0x42, 0xf5, 0x61, 0x6c, 0x3f, 0xfa, - 0xfc, 0x35, 0x60, 0x66, 0x4d, 0xe2, 0x6d, 0xe0, 0x22, 0x56, 0x1a, 0xc4, 0x66, 0x91, 0x4b, 0xb1, - 0x9c, 0xba, 0x74, 0xe3, 0x5f, 0x98, 0x72, 0x8b, 0x8e, 0x7f, 0x7d, 0xfa, 0x55, 0x70, 0xce, 0xa2, - 0x35, 0x4a, 0x68, 0x50, 0x21, 0x54, 0xb8, 0x4a, 0x39, 0x25, 0x1f, 0x24, 0xc7, 0xd6, 0xd3, 0x55, - 0x72, 0x50, 0xb4, 0x46, 0x3a, 0x42, 0x97, 0x18, 0x35, 0x01, 0xae, 0x59, 0x9a, 0x1e, 0xf3, 0x91, - 0x5d, 0x4b, 0x5d, 0xb0, 0x13, 0x6e, 0x32, 0x99, 0x4b, 0x9c, 0x74, 0xd5, 0xc9, 0x53, 0xe5, 0x18, - 0x21, 0xfa, 0xa7, 0x00, 0x4c, 0x8e, 0xeb, 0xa9, 0xf3, 0x3c, 0xf9, 0x82, 0x93, 0xcd, 0x73, 0xca, - 0x25, 0xe8, 0xff, 0x12, 0xa8, 0x13, 0x09, 0xf7, 0x8d, 0x5f, 0x8b, 0x7e, 0x63, 0x23, 0xdc, 0x32, - 0xde, 0xc8, 0xba, 0x7b, 0x4d, 0xfa, 0x42, 0xc7, 0xd0, 0xee, 0x35, 0x06, 0x48, 0xfa, 0x08, 0xf0, - 0xc9, 0x42, 0x38, 0x2c, 0x2f, 0x2c, 0x14, 0x29, 0xd7, 0xd7, 0x52, 0xa6, 0x7d, 0xb8, 0x1c, 0xb1, - 0x92, 0x83, 0x67, 0xad, 0xe1, 0x76, 0xe9, 0x00, 0x5c, 0xe2, 0xb4, 0x89, 0x83, 0x8a, 0x56, 0x25, - 0x16, 0x6e, 0xa6, 0x9c, 0xdc, 0x27, 0x17, 0x07, 0x56, 0x72, 0xf0, 0xa2, 0x15, 0xd7, 0x2b, 0x6d, - 0x83, 0x8b, 0x83, 0x53, 0x12, 0xe6, 0x18, 0xd9, 0x74, 0xde, 0xa2, 0xcc, 0x5e, 0x4d, 0x64, 0x16, - 0x73, 0xb7, 0x51, 0xc9, 0xc1, 0xf3, 0x5e, 0xcc, 0x95, 0xc7, 0x11, 0xb8, 0x92, 0x70, 0xb8, 0xce, - 0x58, 0xdd, 0x4e, 0x19, 0x57, 0xf2, 0x85, 0x00, 0x71, 0xf8, 0x3b, 0xc9, 0xd7, 0x05, 0xdb, 0x80, - 0x8f, 0x1a, 0xf1, 0x82, 0x04, 0x8f, 0xd5, 0x3d, 0x16, 0xee, 0xa4, 0x0c, 0x2e, 0xa6, 0x56, 0x92, - 0x0c, 0xce, 0x8a, 0x29, 0xa1, 0xac, 0x82, 0x33, 0x7d, 0x1e, 0x74, 0x96, 0xee, 0x52, 0xda, 0xb7, - 0x53, 0x69, 0x13, 0xe0, 0x4a, 0x0e, 0x9e, 0xb6, 0xa2, 0x55, 0x8e, 0x5b, 0x40, 0x8a, 0xd6, 0x4e, - 0xb0, 0x19, 0x29, 0xdc, 0x4b, 0x29, 0xc9, 0x1e, 0x2d, 0xf2, 0xa3, 0xde, 0x64, 0xb4, 0xf0, 0x6f, - 0x84, 0x74, 0x8f, 0x16, 0x8c, 0x15, 0xee, 0x67, 0x26, 0xcd, 0x2a, 0xcc, 0x86, 0x49, 0xf3, 0xaa, - 0xb3, 0x11, 0xd2, 0x36, 0x2d, 0x28, 0x29, 0xac, 0x64, 0x26, 0xcd, 0x2a, 0x50, 0x86, 0x49, 0xf3, - 0xaa, 0x94, 0x36, 0xb8, 0x1c, 0x25, 0xcd, 0x6b, 0xba, 0xb8, 0x5e, 0x5e, 0x49, 0x39, 0x17, 0x88, - 0x2f, 0xf2, 0xab, 0xe4, 0xe0, 0x82, 0x15, 0x5f, 0xfe, 0x17, 0xcf, 0x8d, 0xab, 0xea, 0xd5, 0xe7, - 0xe4, 0xd6, 0x57, 0xd8, 0x18, 0x37, 0xae, 0xb6, 0x78, 0x6e, 0x5c, 0x7b, 0xaf, 0x3d, 0x27, 0xb7, - 0xbe, 0x0e, 0xc7, 0xb8, 0x71, 0x4d, 0x1e, 0x80, 0xc5, 0x28, 0x37, 0x5a, 0xea, 0xe5, 0x93, 0x68, - 0xd9, 0xf3, 0xb1, 0x57, 0x58, 0xcd, 0xcc, 0x2e, 0x5a, 0xef, 0x36, 0xcc, 0x6e, 0xa8, 0x12, 0xee, - 0xff, 0x09, 0xa0, 0x18, 0x4d, 0x10, 0xa2, 0x37, 0x49, 0x83, 0x63, 0x96, 0xc2, 0x83, 0xd4, 0x33, - 0xd9, 0xd4, 0xd7, 0x7a, 0xec, 0x4c, 0xb6, 0x0f, 0xd6, 0x1a, 0x07, 0x93, 0xf6, 0xc1, 0xa5, 0x98, - 0x13, 0x16, 0xec, 0xb4, 0x70, 0xe1, 0xf5, 0xd4, 0x14, 0x3b, 0xe1, 0xad, 0x1c, 0x4b, 0xb1, 0x47, - 0x3a, 0x9d, 0x16, 0x1e, 0x65, 0x16, 0xa6, 0x9b, 0xae, 0x8d, 0x0b, 0x0f, 0x33, 0x33, 0x1b, 0x79, - 0x9f, 0x36, 0xcc, 0x6c, 0xd0, 0x29, 0x7d, 0x05, 0x9c, 0x0b, 0xac, 0x5d, 0x1e, 0x87, 0x30, 0x09, - 0x88, 0xde, 0x71, 0xe1, 0x51, 0x4a, 0x2c, 0x8a, 0xbb, 0x70, 0x24, 0xb1, 0x28, 0xb0, 0x76, 0xa3, - 0xed, 0x52, 0x00, 0x16, 0x7d, 0x7e, 0x3d, 0x83, 0x3c, 0x4a, 0x09, 0xed, 0x62, 0x7a, 0x90, 0xdd, - 0x6b, 0x07, 0x85, 0x37, 0x52, 0x8e, 0xa4, 0x26, 0xdd, 0xec, 0x54, 0x72, 0xf0, 0x92, 0x1f, 0xdf, - 0x3f, 0xba, 0x2c, 0x78, 0xfd, 0x18, 0x5f, 0xf2, 0x8f, 0x33, 0xdb, 0x69, 0xb4, 0xea, 0x70, 0xd8, - 0x4e, 0x87, 0xea, 0x11, 0xe3, 0xb9, 0xf1, 0x45, 0xf8, 0xe6, 0x73, 0x72, 0x8b, 0x5b, 0x84, 0x43, - 0x45, 0x76, 0xdb, 0xe0, 0x62, 0x68, 0x18, 0xc7, 0x68, 0x07, 0x07, 0xad, 0x3d, 0x1e, 0x03, 0xbf, - 0x90, 0x12, 0x91, 0x62, 0xae, 0xb7, 0x48, 0x44, 0xb2, 0x63, 0x6e, 0xbd, 0xbe, 0x37, 0x72, 0x9a, - 0xc7, 0x0d, 0x70, 0xc0, 0x97, 0xed, 0xf1, 0x0b, 0x6f, 0x65, 0x3e, 0x3c, 0x4b, 0xfe, 0xcc, 0xc2, - 0xf0, 0x91, 0x5e, 0x2c, 0x9c, 0xf4, 0xcd, 0x91, 0x9d, 0xfd, 0x7e, 0x6f, 0x1b, 0xd3, 0xcb, 0xd9, - 0xa1, 0x6d, 0xc2, 0x93, 0xcc, 0x07, 0x9c, 0xe3, 0x5f, 0xbf, 0x19, 0x3e, 0xe0, 0xa4, 0xfd, 0xfb, - 0x43, 0xdb, 0x83, 0x6f, 0xc7, 0xab, 0xc4, 0xea, 0x76, 0xe9, 0x31, 0x6b, 0xff, 0x80, 0xf3, 0xed, - 0xd4, 0x13, 0xee, 0x49, 0xcf, 0x28, 0x87, 0x1d, 0x51, 0xec, 0x43, 0xcb, 0x2e, 0x58, 0xe2, 0xd6, - 0xb6, 0xeb, 0x59, 0xdd, 0x3d, 0xba, 0xa5, 0xf3, 0x5b, 0x56, 0x98, 0x09, 0xbd, 0x43, 0xf9, 0xbf, - 0x9e, 0x62, 0x6f, 0x63, 0xf7, 0xf5, 0x64, 0x35, 0x59, 0x91, 0xae, 0x23, 0x7f, 0x70, 0x95, 0xff, - 0x7d, 0xb6, 0x51, 0x1b, 0xe2, 0xda, 0xf2, 0xdc, 0xa3, 0x0e, 0xfa, 0xef, 0xf8, 0x08, 0xb7, 0x91, - 0xed, 0xec, 0xec, 0xd0, 0x2d, 0x70, 0xe1, 0xdd, 0x54, 0x7b, 0x48, 0xbf, 0x41, 0x66, 0xf6, 0x30, - 0x11, 0x4e, 0xfa, 0x6f, 0xe0, 0x22, 0x2d, 0xe2, 0xa0, 0xf7, 0xa6, 0xf4, 0xce, 0x93, 0x8f, 0xfe, - 0xbd, 0xb4, 0x9b, 0xca, 0xb1, 0xeb, 0xd7, 0x4a, 0x0e, 0x4a, 0xbd, 0xf1, 0x4b, 0x59, 0x76, 0xa0, - 0x1e, 0xbb, 0x6f, 0xc2, 0x5d, 0xce, 0xec, 0x8b, 0xa9, 0xf6, 0x96, 0x5c, 0x9b, 0xc8, 0xec, 0x6d, - 0x42, 0xed, 0xe2, 0xaf, 0x0b, 0xe0, 0x5e, 0x82, 0x04, 0xfc, 0x38, 0xcb, 0xed, 0xe2, 0x70, 0xd2, - 0xbf, 0x94, 0x1a, 0x02, 0x53, 0x4b, 0x04, 0xd9, 0xed, 0x5f, 0x7a, 0x25, 0xe1, 0x27, 0x02, 0x58, - 0x89, 0x97, 0x8b, 0xd6, 0xa0, 0x8d, 0x6e, 0xe9, 0xde, 0x4f, 0xbd, 0x7c, 0xcb, 0x50, 0xb3, 0xc7, - 0xce, 0x3e, 0xb2, 0x14, 0xf7, 0xf1, 0x33, 0x85, 0xd8, 0xad, 0x26, 0x7d, 0x8a, 0xd5, 0x0d, 0xcf, - 0x4d, 0x3f, 0xf8, 0x34, 0x7b, 0xcd, 0x48, 0x1d, 0x5d, 0xe2, 0x5e, 0x33, 0x5a, 0x6b, 0xf7, 0x7d, - 0x76, 0x4a, 0x1a, 0x23, 0x4e, 0xdb, 0xe9, 0xec, 0x0f, 0x9d, 0x2e, 0xc8, 0xa9, 0x5b, 0xce, 0x94, - 0xb2, 0xb6, 0x4a, 0x0e, 0xde, 0x88, 0x11, 0x68, 0x18, 0x68, 0xed, 0x24, 0x98, 0xa1, 0x34, 0x9f, - 0x4e, 0xcf, 0xe6, 0xc5, 0x29, 0x62, 0x83, 0xfd, 0x9d, 0x30, 0x89, 0xcb, 0xe1, 0xa5, 0x19, 0x95, - 0x6c, 0xe5, 0x87, 0xe2, 0xe0, 0x83, 0x88, 0xe1, 0x66, 0x4d, 0xba, 0x01, 0x96, 0x4b, 0x9a, 0xa1, - 0xe8, 0xcf, 0x54, 0x88, 0xa0, 0x6a, 0xe8, 0x4d, 0xa8, 0x8c, 0x7e, 0xce, 0xe8, 0x0a, 0x28, 0x8c, - 0x83, 0x18, 0x2a, 0x7c, 0xa6, 0x42, 0x51, 0x90, 0xae, 0x83, 0x2b, 0xe3, 0xbd, 0x1b, 0xcd, 0x35, - 0x15, 0xd6, 0x55, 0x53, 0x35, 0xc4, 0xbc, 0xf4, 0x06, 0x78, 0x30, 0x0e, 0x51, 0x92, 0x4d, 0x79, - 0x4d, 0x36, 0x54, 0xd4, 0xd0, 0x0d, 0xb3, 0x0c, 0x55, 0x03, 0x19, 0x6a, 0x75, 0x1d, 0x55, 0x74, - 0xc3, 0x54, 0x4b, 0xe2, 0x94, 0xf4, 0x3a, 0x78, 0x75, 0x02, 0x52, 0x6d, 0xcb, 0xf8, 0xb0, 0x3a, - 0x84, 0x31, 0x2d, 0x3d, 0x02, 0xab, 0x93, 0x30, 0xf4, 0x7a, 0x59, 0x2f, 0xad, 0x0d, 0xe1, 0xcc, - 0x48, 0xaf, 0x80, 0xbb, 0x59, 0x44, 0x83, 0x25, 0x43, 0x3c, 0x21, 0xdd, 0x03, 0xb7, 0x52, 0x45, - 0x22, 0x90, 0x27, 0xa5, 0x3b, 0xa0, 0x38, 0x0e, 0x29, 0x37, 0x1a, 0x55, 0x4d, 0x91, 0x4d, 0x4d, - 0xaf, 0xa3, 0x8a, 0x69, 0x36, 0xc4, 0x59, 0xe9, 0x36, 0xb8, 0x31, 0x19, 0xce, 0x54, 0x1a, 0xe2, - 0x5c, 0x3c, 0xd8, 0xa6, 0x56, 0x2f, 0xe9, 0x9b, 0x06, 0x2a, 0xa9, 0xc6, 0x86, 0xa9, 0x37, 0x44, - 0x20, 0xbd, 0x0a, 0xee, 0x4d, 0x90, 0xcf, 0xf8, 0xb0, 0xca, 0xe6, 0x8c, 0xca, 0x78, 0x2a, 0x45, - 0xc1, 0x83, 0xa1, 0xab, 0x25, 0xa3, 0xa2, 0xad, 0x9b, 0xe2, 0x69, 0xe9, 0x31, 0x78, 0x3d, 0x13, - 0xfd, 0xa8, 0x8a, 0xcf, 0xa4, 0xf0, 0x81, 0x6a, 0x49, 0x1b, 0x9e, 0xfa, 0xf9, 0xac, 0x93, 0x52, - 0x56, 0x1a, 0xe2, 0xd9, 0x4c, 0x93, 0x42, 0x20, 0xc5, 0xcc, 0xea, 0x21, 0xd0, 0xe7, 0xa4, 0x77, - 0xc1, 0x5b, 0xcf, 0xa3, 0x1e, 0xbe, 0x1e, 0xaa, 0xaa, 0x61, 0x88, 0x92, 0xf4, 0x1a, 0xb8, 0x9f, - 0x05, 0x59, 0xfe, 0xa8, 0x09, 0x55, 0xf1, 0xbc, 0x74, 0x17, 0xdc, 0x9c, 0x00, 0x5e, 0xda, 0xaa, - 0xcb, 0x35, 0xbd, 0xb4, 0x26, 0x5e, 0x48, 0x31, 0x71, 0x45, 0x36, 0x0c, 0xb9, 0x5e, 0x82, 0x32, - 0xda, 0x50, 0xb7, 0x8c, 0x86, 0xac, 0xa8, 0x86, 0x78, 0x31, 0x65, 0xd6, 0x06, 0x38, 0xd1, 0x39, - 0x58, 0x90, 0x9e, 0x80, 0xc7, 0x13, 0xb0, 0xd4, 0xaa, 0x6c, 0x98, 0x9a, 0x62, 0xa8, 0x32, 0x54, - 0x2a, 0x43, 0x98, 0x97, 0x32, 0xcd, 0x37, 0xc7, 0x97, 0x95, 0x8a, 0x2a, 0x16, 0x52, 0xb4, 0xc5, - 0x30, 0x6a, 0x6a, 0x4d, 0x87, 0x5b, 0xa5, 0x35, 0xf1, 0x72, 0x26, 0x06, 0x54, 0xb3, 0x88, 0x31, - 0x58, 0x4c, 0x19, 0x0c, 0xc3, 0x50, 0xaa, 0x4d, 0xc3, 0x1c, 0x31, 0xde, 0x25, 0x69, 0x05, 0xdc, - 0x49, 0xb5, 0x2e, 0x36, 0x8b, 0x57, 0xa4, 0x55, 0xb0, 0x92, 0xc9, 0xbe, 0x18, 0xfc, 0x72, 0xca, - 0x64, 0x0e, 0xe0, 0x6b, 0x9a, 0x02, 0x75, 0x43, 0x5f, 0x37, 0xc5, 0xab, 0xd2, 0x17, 0xc0, 0xa3, - 0x49, 0x93, 0xa9, 0x2b, 0x1b, 0x50, 0x97, 0x95, 0xca, 0x88, 0x9f, 0xbb, 0x96, 0x62, 0xfb, 0xa1, - 0x6f, 0x94, 0xcd, 0xaa, 0x6c, 0x88, 0xd7, 0x53, 0xd6, 0x94, 0x51, 0xd7, 0x37, 0xd7, 0xab, 0xf2, - 0x86, 0x2a, 0xde, 0x48, 0xa0, 0xab, 0x2b, 0x11, 0xed, 0x96, 0x0c, 0xd4, 0x80, 0xfa, 0x97, 0xb7, - 0xc4, 0x62, 0x82, 0x29, 0x46, 0xa1, 0x2b, 0x5a, 0xb9, 0x82, 0xe4, 0x67, 0xb2, 0x56, 0x95, 0xd7, - 0xb4, 0xaa, 0x66, 0x6e, 0x89, 0x37, 0xa5, 0xb7, 0xc0, 0x1b, 0x29, 0x58, 0x74, 0x85, 0x68, 0x0a, - 0x82, 0x6a, 0x59, 0x33, 0x4c, 0x48, 0x5d, 0xa7, 0x78, 0x2b, 0xde, 0x0b, 0x1b, 0x72, 0xad, 0x1a, - 0x75, 0xb1, 0xe2, 0x6d, 0xa9, 0x08, 0xae, 0x8e, 0xc3, 0xa9, 0xca, 0x23, 0xf6, 0xe1, 0xbe, 0xba, - 0xa2, 0x8a, 0x77, 0x12, 0x8c, 0x4e, 0x57, 0x46, 0xdd, 0x30, 0xaa, 0xeb, 0x75, 0x24, 0x97, 0xc4, - 0xbb, 0xd2, 0x2d, 0x70, 0x7d, 0x52, 0x5c, 0xa4, 0x1f, 0x74, 0xbb, 0x17, 0x6f, 0xfb, 0xd1, 0x08, - 0x20, 0x6f, 0x1a, 0x48, 0xd1, 0xeb, 0x86, 0x5e, 0x55, 0xc5, 0xfb, 0xd2, 0x35, 0xb0, 0x34, 0x0e, - 0x5e, 0x53, 0x1a, 0xc8, 0x30, 0x4b, 0x9a, 0x2e, 0xae, 0xd0, 0xcf, 0x1e, 0xc6, 0x03, 0x18, 0xaa, - 0xf8, 0x8a, 0x74, 0x1f, 0xdc, 0x4e, 0xc2, 0x87, 0xaa, 0x5c, 0x93, 0xd7, 0xaa, 0x2a, 0x8b, 0x4d, - 0xaf, 0xae, 0xfc, 0x9e, 0x00, 0xe6, 0x87, 0x3f, 0x3d, 0x3c, 0xc4, 0xdd, 0x30, 0x65, 0xb3, 0x69, - 0x8c, 0x64, 0x0a, 0x4b, 0xe0, 0xd2, 0x28, 0x80, 0xd1, 0x54, 0x14, 0xe2, 0x14, 0x85, 0xd8, 0xce, - 0x0d, 0xad, 0xd1, 0x50, 0x4b, 0x62, 0x5e, 0xba, 0x0c, 0x2e, 0x8e, 0x76, 0xaa, 0x10, 0xea, 0x50, - 0x9c, 0x8a, 0xc3, 0x93, 0xd7, 0x74, 0x48, 0x83, 0xfe, 0xca, 0xcf, 0xf2, 0x60, 0x4a, 0x31, 0x65, - 0xe9, 0x3c, 0x38, 0xab, 0x98, 0xf2, 0xf8, 0x47, 0x1e, 0x49, 0xa3, 0xdc, 0x34, 0x2b, 0x44, 0x87, - 0x75, 0x55, 0x31, 0x75, 0x92, 0xb2, 0x5c, 0x02, 0xe7, 0x69, 0xbb, 0x62, 0x6a, 0xcf, 0x48, 0x26, - 0x63, 0x18, 0x9a, 0x5e, 0x27, 0x99, 0x4a, 0xbf, 0x83, 0x88, 0x8c, 0xa0, 0xfa, 0x61, 0x53, 0x35, - 0x4c, 0x43, 0x9c, 0x0a, 0x3b, 0x1a, 0x50, 0xad, 0x69, 0xcd, 0x1a, 0x32, 0x9a, 0x8d, 0x86, 0x0e, - 0x4d, 0x71, 0x3a, 0xec, 0x30, 0x21, 0xf1, 0x1e, 0x25, 0x54, 0x52, 0x9f, 0x69, 0xc4, 0xed, 0xce, - 0x84, 0xbc, 0x9b, 0x8d, 0x32, 0x94, 0x4b, 0x2a, 0x5a, 0x93, 0xeb, 0x75, 0x15, 0x8a, 0x27, 0x42, - 0x84, 0x35, 0xad, 0x5a, 0xd5, 0xea, 0x65, 0x64, 0x34, 0x6b, 0x35, 0x19, 0x6e, 0x89, 0x27, 0xc3, - 0x11, 0x70, 0xde, 0x55, 0xcd, 0x30, 0xc5, 0x59, 0xfa, 0x29, 0xc0, 0x41, 0x63, 0x4d, 0xaf, 0x6b, - 0xa6, 0x0e, 0xb5, 0x7a, 0x59, 0x9c, 0xa3, 0x1f, 0x19, 0x34, 0x65, 0xa4, 0x7e, 0xd9, 0x54, 0x61, - 0x5d, 0xae, 0x22, 0xb9, 0x59, 0xd2, 0x4c, 0x64, 0x98, 0x3a, 0x94, 0xcb, 0xaa, 0x08, 0x42, 0x01, - 0xf4, 0x0d, 0x22, 0x85, 0x41, 0x74, 0xb7, 0x55, 0x57, 0xc4, 0x53, 0x92, 0x08, 0x4e, 0x53, 0xbc, - 0xba, 0x09, 0x65, 0xa4, 0x95, 0xc4, 0xd3, 0xd2, 0x39, 0x70, 0xa6, 0x0f, 0x69, 0x28, 0x5a, 0x4d, - 0x3c, 0x13, 0xf2, 0xd5, 0x4a, 0x6a, 0xdd, 0xd4, 0xcc, 0x2d, 0x64, 0xa8, 0x4a, 0x13, 0x92, 0xe5, - 0x38, 0xbf, 0xf2, 0x23, 0x00, 0x2e, 0xc6, 0xbe, 0xa3, 0x23, 0x61, 0x4c, 0xab, 0x9b, 0x6a, 0x99, - 0x2d, 0x40, 0xa4, 0xd6, 0xa1, 0x5e, 0xad, 0xa2, 0x0d, 0xad, 0x3e, 0xfa, 0xf9, 0xc4, 0x1b, 0x60, - 0x39, 0x09, 0xd0, 0xa8, 0xca, 0xca, 0x86, 0x28, 0x90, 0xd5, 0x93, 0x04, 0x42, 0x56, 0x84, 0xae, - 0x95, 0x14, 0x31, 0x4f, 0x12, 0xa3, 0x24, 0xa8, 0x86, 0x5c, 0x56, 0x61, 0xa9, 0x69, 0x6e, 0x89, - 0x53, 0x93, 0xf8, 0xa9, 0x35, 0x59, 0xab, 0x8a, 0xd3, 0x24, 0x8b, 0x4d, 0x02, 0x79, 0xaa, 0x41, - 0x59, 0x9c, 0x91, 0x6e, 0x82, 0x6b, 0x49, 0x10, 0xd4, 0x3c, 0x61, 0x49, 0x3c, 0x41, 0x5c, 0x4e, - 0x12, 0x50, 0x4d, 0x36, 0x4d, 0x15, 0xd6, 0x74, 0xc3, 0x14, 0x4f, 0x4e, 0x1a, 0x5e, 0xcd, 0x40, - 0xa6, 0x2a, 0xd7, 0x0c, 0x71, 0x76, 0x12, 0x94, 0xde, 0x30, 0xca, 0x6a, 0x5d, 0x53, 0xc5, 0xb9, - 0x49, 0xa2, 0x93, 0x29, 0x15, 0xc1, 0xc4, 0xc1, 0xc9, 0xb5, 0x75, 0xf1, 0xd4, 0x64, 0xb9, 0x95, - 0x8a, 0x56, 0x57, 0x99, 0xa9, 0xbc, 0x09, 0x1e, 0xa6, 0xc3, 0xa1, 0xb2, 0x66, 0x56, 0x9a, 0x6b, - 0x74, 0x7d, 0x91, 0x75, 0x75, 0x46, 0x7a, 0x00, 0x5e, 0xc9, 0x80, 0xa6, 0x68, 0x50, 0xa9, 0xaa, - 0x8a, 0x26, 0xce, 0x13, 0xb7, 0x98, 0x8d, 0x4f, 0x55, 0x5e, 0x13, 0xcf, 0x92, 0xd0, 0x9b, 0x01, - 0xfc, 0xa9, 0x5a, 0xdf, 0xd0, 0xea, 0x86, 0x28, 0x66, 0x84, 0x97, 0xeb, 0x86, 0xb6, 0x56, 0x55, - 0xc5, 0x73, 0x93, 0xd4, 0x43, 0x82, 0xb4, 0xa6, 0xa8, 0x75, 0x7d, 0x53, 0x94, 0x26, 0x4d, 0x58, - 0x7f, 0xbd, 0x9d, 0x27, 0x01, 0x2d, 0xd1, 0x92, 0x64, 0x53, 0x2e, 0xe9, 0x65, 0xa4, 0xd5, 0x15, - 0xba, 0xf6, 0x50, 0x4d, 0xae, 0xcb, 0x65, 0xb5, 0xa6, 0xd6, 0x4d, 0xf1, 0x02, 0xc9, 0x46, 0xb2, - 0x88, 0xbd, 0x49, 0xd2, 0xbe, 0x6c, 0xb0, 0x24, 0xd7, 0x5d, 0x20, 0x51, 0x3c, 0x0b, 0x5d, 0x9a, - 0xb7, 0xd0, 0x04, 0x2f, 0x03, 0x34, 0xcd, 0x3f, 0xab, 0x64, 0xe3, 0x50, 0x90, 0x1e, 0x82, 0xd7, - 0x32, 0x60, 0x44, 0xf6, 0x8c, 0x97, 0x27, 0x59, 0x0c, 0x59, 0xff, 0x7d, 0xc7, 0xa4, 0xa8, 0x75, - 0x53, 0x85, 0xe2, 0xe2, 0xa4, 0x29, 0xe5, 0xe6, 0x08, 0xd5, 0x86, 0xce, 0x3d, 0xa9, 0xb8, 0x94, - 0xd1, 0xc2, 0x64, 0x58, 0xd6, 0x95, 0x92, 0x78, 0x45, 0xfa, 0x00, 0xbc, 0xf7, 0xdc, 0x86, 0x1f, - 0x1d, 0xd1, 0xf2, 0xca, 0x1f, 0xcd, 0xc4, 0xf8, 0x4d, 0x23, 0xc0, 0xdd, 0x04, 0xbf, 0x69, 0x98, - 0x6a, 0x63, 0xc4, 0x6f, 0xc6, 0x8f, 0x91, 0x02, 0xca, 0x9b, 0x86, 0xa6, 0x84, 0x41, 0x8e, 0xb9, - 0x47, 0x41, 0xfa, 0x12, 0x78, 0x67, 0x32, 0xbc, 0xa1, 0x9a, 0x5c, 0x23, 0x24, 0xde, 0xa0, 0x92, - 0xba, 0x2e, 0x37, 0xab, 0x26, 0xd2, 0x37, 0x49, 0xac, 0xca, 0x4b, 0x5f, 0x04, 0x6f, 0x4f, 0xc6, - 0x6f, 0x36, 0xaa, 0xba, 0xcc, 0x66, 0x84, 0xe6, 0x55, 0x46, 0x03, 0xd5, 0x54, 0x53, 0x26, 0x56, - 0x2c, 0x4e, 0x91, 0x64, 0x75, 0x32, 0xba, 0xa9, 0x1a, 0x26, 0x8d, 0x38, 0xa1, 0xe0, 0x24, 0x1f, - 0x9b, 0x4e, 0x58, 0x1f, 0x14, 0x8f, 0x29, 0x18, 0xca, 0x48, 0x81, 0xaa, 0x6c, 0xaa, 0x28, 0x02, - 0x27, 0xce, 0x4c, 0x62, 0x38, 0x8a, 0x58, 0xd6, 0xc2, 0x2d, 0x9b, 0x78, 0x22, 0x1b, 0x43, 0xfa, - 0x45, 0x5e, 0xb2, 0xab, 0x30, 0x8c, 0x0a, 0x52, 0x54, 0x48, 0xdc, 0x78, 0xfc, 0x52, 0x88, 0x65, - 0x08, 0x49, 0x02, 0x37, 0x4b, 0x52, 0xe0, 0x24, 0x8c, 0xda, 0xa6, 0x56, 0xae, 0xc8, 0x1b, 0x4f, - 0x8c, 0xfe, 0x34, 0x32, 0x1a, 0xe2, 0xdc, 0xa4, 0x81, 0x0d, 0x61, 0x71, 0x09, 0xb9, 0x91, 0x83, - 0x6c, 0xdc, 0x0c, 0xd5, 0x6c, 0x36, 0xd0, 0xa6, 0x0e, 0x37, 0xd6, 0xab, 0xfa, 0xa6, 0x78, 0x6a, - 0xe5, 0xe7, 0x42, 0xec, 0x43, 0xf0, 0xf0, 0x11, 0x77, 0xa2, 0x19, 0xd2, 0xd4, 0x4c, 0xd1, 0x4b, - 0xa3, 0xe7, 0x47, 0xf1, 0xae, 0x28, 0x0a, 0x3f, 0x48, 0x12, 0x33, 0xc0, 0xf6, 0x73, 0xc6, 0x7b, - 0xe0, 0x56, 0x0a, 0x6c, 0x98, 0x42, 0xa6, 0x53, 0x1d, 0x64, 0x94, 0x7f, 0x93, 0x07, 0x85, 0xa4, - 0x73, 0xd3, 0x24, 0x42, 0xcc, 0x74, 0x47, 0x86, 0x1d, 0xef, 0x32, 0x42, 0xd8, 0x81, 0xfe, 0x43, - 0xa7, 0x51, 0x7a, 0x46, 0xf6, 0x1a, 0x24, 0xb4, 0xb3, 0xb0, 0x29, 0x64, 0xa6, 0x10, 0xd9, 0x55, - 0x54, 0xe5, 0x35, 0xb5, 0x8a, 0x1a, 0x9a, 0xb2, 0x41, 0x57, 0x70, 0x09, 0x7c, 0xf0, 0xbc, 0x14, - 0xc6, 0xe4, 0x98, 0x92, 0x2a, 0xa0, 0xf4, 0xbc, 0x54, 0xfa, 0x9b, 0x0b, 0xd8, 0xac, 0xaa, 0xa1, - 0x3c, 0xd3, 0x2b, 0x3f, 0x99, 0x01, 0x0b, 0xf1, 0x07, 0xbf, 0x09, 0xb3, 0xb9, 0xae, 0xa9, 0xd5, - 0xd1, 0xf4, 0xf1, 0x3d, 0xf0, 0x24, 0x11, 0x72, 0x4c, 0xad, 0xc4, 0xeb, 0x1b, 0x24, 0x6b, 0xde, - 0x42, 0x4d, 0x58, 0x15, 0x85, 0x84, 0x35, 0x91, 0x80, 0xbd, 0x06, 0xe5, 0xba, 0x52, 0x11, 0xf3, - 0x09, 0x2b, 0x30, 0x01, 0xab, 0xbf, 0x96, 0xa6, 0xa4, 0xb7, 0xc1, 0x9b, 0xd9, 0xf1, 0xd4, 0xfa, - 0x33, 0x0d, 0xea, 0x75, 0x1a, 0xed, 0xa7, 0x13, 0xa2, 0x66, 0xe2, 0x30, 0xd7, 0xc5, 0x99, 0x04, - 0x87, 0x9d, 0xc8, 0xcd, 0x54, 0x61, 0x03, 0x6a, 0x64, 0x4b, 0x5f, 0x6d, 0x96, 0xc5, 0x13, 0x09, - 0xd6, 0x92, 0x01, 0xdd, 0x94, 0x4d, 0x4d, 0x41, 0x4f, 0x37, 0x37, 0x0c, 0xf1, 0xa4, 0xf4, 0x04, - 0x3c, 0xce, 0x40, 0x65, 0xd4, 0x66, 0x49, 0xbe, 0xfb, 0xdc, 0x98, 0x65, 0xa8, 0x37, 0x1b, 0x86, - 0x38, 0x97, 0xe0, 0xc1, 0x27, 0x60, 0x92, 0x1d, 0x11, 0xf1, 0x90, 0xf1, 0x4b, 0x6c, 0x02, 0xe2, - 0x90, 0x61, 0x1b, 0xe2, 0xa9, 0x95, 0x1f, 0xc6, 0x7d, 0xa9, 0x24, 0x7c, 0xc8, 0x9e, 0x90, 0x5a, - 0x51, 0x97, 0x13, 0xf3, 0x8f, 0x03, 0xe2, 0xdd, 0xcb, 0x00, 0xda, 0x54, 0x21, 0x94, 0xd7, 0x75, - 0x58, 0x4b, 0xb4, 0xe3, 0x01, 0xec, 0x48, 0x2e, 0xb2, 0x25, 0xd7, 0xaa, 0x62, 0x7e, 0xe5, 0x7d, - 0x70, 0x92, 0x17, 0x4f, 0x91, 0x9d, 0xe8, 0xba, 0x2a, 0x9b, 0x24, 0x60, 0x8c, 0xed, 0xe2, 0xc3, - 0x8e, 0xd1, 0x7d, 0xad, 0xb0, 0xf2, 0x3b, 0x02, 0x58, 0x9a, 0xf0, 0xb4, 0x99, 0xe4, 0x55, 0x21, - 0x32, 0x54, 0x15, 0xbd, 0x56, 0x53, 0xeb, 0x25, 0x26, 0x61, 0xec, 0x89, 0xc1, 0x0a, 0xb8, 0x33, - 0x19, 0xbc, 0xae, 0x9b, 0x0c, 0x56, 0x20, 0x59, 0xf8, 0x64, 0xd8, 0x92, 0x5e, 0x57, 0xc5, 0xfc, - 0xda, 0x57, 0xff, 0xe2, 0xa7, 0x57, 0x85, 0x9f, 0xfc, 0xf4, 0xaa, 0xf0, 0x77, 0x3f, 0xbd, 0x2a, - 0x7c, 0xa4, 0xef, 0x3a, 0xc1, 0x5e, 0x6f, 0x7b, 0xb5, 0xe5, 0x1e, 0x3c, 0xd8, 0xf5, 0xac, 0x43, - 0x87, 0x15, 0xd7, 0x5a, 0xed, 0x07, 0x83, 0xff, 0x65, 0xd6, 0x75, 0x1e, 0xec, 0xe2, 0xce, 0x03, - 0xfa, 0x0c, 0xfd, 0xc1, 0xae, 0x3b, 0xf2, 0x0f, 0xd2, 0xde, 0x8d, 0xfc, 0x3c, 0x7c, 0xb8, 0x7d, - 0x82, 0x82, 0xbd, 0xf1, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x27, 0xe9, 0x48, 0xd2, 0x50, 0x6d, - 0x00, 0x00, + 0x24, 0x46, 0x80, 0x0d, 0xf2, 0x40, 0x1e, 0x08, 0xe0, 0x00, 0xf9, 0x32, 0xfc, 0x95, 0x8f, 0xfc, + 0x05, 0x48, 0x3e, 0x0c, 0x04, 0xc8, 0x47, 0xf2, 0x13, 0xf8, 0x2b, 0x7f, 0xfe, 0x4a, 0x80, 0xc4, + 0x79, 0xa1, 0x1e, 0x3d, 0xd3, 0x33, 0xd3, 0x3d, 0xdd, 0xda, 0x68, 0x63, 0x43, 0xfb, 0xc7, 0xa9, + 0x3a, 0xaf, 0x3a, 0x75, 0xea, 0x9c, 0x53, 0x55, 0xa7, 0x9a, 0xe0, 0x7e, 0x80, 0xdb, 0xb8, 0xeb, + 0x7a, 0xc1, 0x83, 0x9e, 0x6f, 0xed, 0x62, 0x7c, 0x88, 0x3b, 0x81, 0xff, 0xe0, 0xf0, 0x61, 0xf4, + 0xe7, 0x6a, 0xd7, 0x73, 0x03, 0x57, 0xba, 0x14, 0x82, 0xae, 0x46, 0xfb, 0x0e, 0x1f, 0x2e, 0xde, + 0xed, 0xd3, 0xb0, 0x5a, 0x2d, 0xec, 0xfb, 0x6d, 0xc7, 0x0f, 0x08, 0x89, 0xc1, 0x2f, 0x46, 0xa1, + 0xb8, 0x02, 0xa4, 0xa6, 0xb6, 0x66, 0x75, 0x3a, 0xd8, 0x53, 0xda, 0x4e, 0x6b, 0x5f, 0x25, 0x24, + 0xa4, 0x0b, 0x60, 0xc6, 0x6a, 0x63, 0x2f, 0x28, 0x08, 0xd7, 0x85, 0x7b, 0x73, 0x90, 0xfd, 0x28, + 0xae, 0x83, 0x7b, 0x4d, 0x4d, 0xef, 0x6c, 0xbb, 0x96, 0x67, 0x2b, 0xee, 0x41, 0xb7, 0x8d, 0x03, + 0x5c, 0x76, 0x4d, 0xb7, 0x64, 0xf9, 0x7b, 0xac, 0x71, 0x40, 0x61, 0x11, 0xcc, 0xf6, 0x7c, 0xec, + 0x75, 0xac, 0x03, 0xcc, 0x89, 0xf4, 0x7f, 0x17, 0x6f, 0x83, 0x9b, 0x7d, 0x3a, 0xb2, 0x6d, 0xaf, + 0x3b, 0x9e, 0x1f, 0x40, 0xec, 0xbb, 0x3d, 0xaf, 0x85, 0x07, 0x24, 0x8a, 0x2b, 0x11, 0x76, 0xa3, + 0x60, 0x55, 0x2b, 0x88, 0x0a, 0x5c, 0x7c, 0x1f, 0xdc, 0xe8, 0xc3, 0x1a, 0x38, 0x50, 0x3c, 0x6c, + 0xe3, 0x4e, 0xe0, 0x58, 0x6d, 0xa3, 0xb7, 0x7d, 0xe0, 0x04, 0xe9, 0x32, 0x45, 0x09, 0x7c, 0xd8, + 0xc3, 0x7e, 0xe0, 0xb8, 0x9d, 0x8e, 0xe5, 0x78, 0x38, 0x2b, 0x81, 0xaf, 0x83, 0xdb, 0x7d, 0x02, + 0x10, 0xef, 0x3a, 0x3e, 0x11, 0x70, 0xcf, 0x6a, 0xb7, 0x71, 0x67, 0x37, 0x2b, 0x11, 0xe9, 0x32, + 0x98, 0x3d, 0xd8, 0xb1, 0x50, 0x70, 0xdc, 0xc5, 0x85, 0x3c, 0xed, 0x3b, 0x79, 0xb0, 0x63, 0x99, + 0xc7, 0x5d, 0x2c, 0x2d, 0x03, 0xd0, 0x76, 0x77, 0x9d, 0x0e, 0xda, 0x69, 0xbb, 0x47, 0x85, 0x29, + 0xda, 0x39, 0x47, 0x5b, 0xd6, 0xdb, 0xee, 0x11, 0x93, 0x1f, 0xe2, 0x96, 0x7b, 0x88, 0xbd, 0x63, + 0xc5, 0xb5, 0xb1, 0xaf, 0xb8, 0x9d, 0xc0, 0xe9, 0xf4, 0x70, 0xc6, 0x49, 0x79, 0x17, 0x2c, 0x8f, + 0x11, 0xe8, 0x1e, 0x67, 0x44, 0x7e, 0x0f, 0x5c, 0x1d, 0x41, 0x6e, 0x78, 0x4e, 0x27, 0xc8, 0x88, + 0x5d, 0x04, 0x62, 0xc9, 0xf1, 0x29, 0x72, 0x0d, 0x07, 0x96, 0x6d, 0x05, 0x96, 0x34, 0x0f, 0xf2, + 0x8e, 0xcd, 0x21, 0xf3, 0x8e, 0x5d, 0xb4, 0x40, 0x21, 0x84, 0x09, 0x6d, 0xa0, 0x0f, 0xab, 0x82, + 0x59, 0x8f, 0xb7, 0x51, 0x8c, 0xf9, 0x47, 0xf7, 0x57, 0x13, 0x16, 0xc6, 0xea, 0x28, 0x11, 0xd8, + 0x47, 0x2d, 0xee, 0x03, 0x29, 0xec, 0x35, 0x02, 0xdc, 0x35, 0x02, 0x2b, 0xe8, 0xf9, 0xd2, 0xfb, + 0xe0, 0x84, 0x4f, 0xff, 0xe2, 0xa4, 0xef, 0xa6, 0x92, 0x66, 0x88, 0x90, 0xa3, 0x91, 0xb5, 0x84, + 0x3d, 0xcf, 0xf5, 0xf8, 0x84, 0xb2, 0x1f, 0xc5, 0xdf, 0x17, 0xc0, 0x42, 0x53, 0x8b, 0xa0, 0x78, + 0x01, 0xb6, 0x99, 0xaa, 0x54, 0x30, 0x7b, 0xc0, 0x87, 0x46, 0x79, 0x9e, 0xca, 0x30, 0x9c, 0x50, + 0x17, 0xb0, 0x8f, 0x2a, 0x29, 0x7d, 0xc1, 0xf3, 0x94, 0xc8, 0x2b, 0x19, 0x04, 0x0f, 0x47, 0x1d, + 0x0a, 0x5f, 0xfc, 0x57, 0x01, 0x5c, 0x1f, 0x88, 0x19, 0x2a, 0xcd, 0xc0, 0x6d, 0xdc, 0x22, 0x2b, + 0xe4, 0x85, 0x0a, 0x5c, 0x8b, 0x4c, 0x23, 0x13, 0xf9, 0x61, 0xe6, 0x69, 0x1c, 0x90, 0x0b, 0x49, + 0x44, 0xc6, 0x3f, 0xf5, 0xe9, 0xc7, 0xff, 0x7f, 0xf2, 0xc4, 0x09, 0x85, 0x00, 0x5a, 0x27, 0xc0, + 0xbb, 0x9e, 0x45, 0x46, 0x2e, 0x6f, 0x1a, 0xba, 0x56, 0x52, 0x14, 0xb7, 0xd3, 0xc1, 0xad, 0xe0, + 0xa5, 0xd7, 0xc3, 0x8f, 0xf3, 0x51, 0x3b, 0x28, 0x59, 0x81, 0xb5, 0x6d, 0xf9, 0x18, 0x96, 0x0c, + 0xb5, 0xe3, 0xb9, 0xed, 0xf6, 0xcb, 0x3e, 0x7e, 0xe9, 0x09, 0x28, 0xf8, 0xd4, 0xe8, 0xb1, 0x8d, + 0x42, 0xca, 0x3e, 0x6a, 0xb9, 0xbd, 0x4e, 0x50, 0x98, 0xbe, 0x2e, 0xdc, 0x9b, 0x82, 0x0b, 0x61, + 0x7f, 0x28, 0x8a, 0xaf, 0x90, 0xde, 0xe2, 0x3f, 0x09, 0xe0, 0xca, 0x40, 0x73, 0x1b, 0xbd, 0x6d, + 0xac, 0x6e, 0x7c, 0x4e, 0xb4, 0x56, 0x7c, 0x0a, 0x0a, 0x4d, 0x4d, 0xb1, 0xda, 0x6d, 0xd3, 0x95, + 0xa9, 0xbf, 0x88, 0x04, 0x84, 0x55, 0x30, 0xd5, 0xe2, 0x23, 0x9e, 0x7f, 0x74, 0x25, 0x91, 0xba, + 0x62, 0xca, 0x90, 0x00, 0x16, 0xbf, 0x37, 0x13, 0xd5, 0x63, 0x09, 0x77, 0xdb, 0xee, 0xb1, 0x81, + 0xbd, 0x43, 0xa7, 0x85, 0x5f, 0x7a, 0xeb, 0xdb, 0x05, 0x67, 0x6c, 0x3a, 0x60, 0x74, 0x80, 0x83, + 0x3d, 0xd7, 0xa6, 0x26, 0x37, 0xff, 0x68, 0x2d, 0x91, 0xd6, 0x24, 0x45, 0xad, 0xb2, 0xa6, 0x1a, + 0xa5, 0x04, 0x4f, 0xdb, 0x91, 0x5f, 0x92, 0x05, 0x4e, 0x71, 0x46, 0x34, 0x05, 0x99, 0xa1, 0x6c, + 0x3e, 0xf8, 0xcf, 0xb0, 0x21, 0xb9, 0x0b, 0x04, 0x76, 0xff, 0xef, 0x22, 0x02, 0xa7, 0xa3, 0x02, + 0x48, 0xcb, 0xe0, 0x72, 0x49, 0x6d, 0x54, 0xf5, 0x2d, 0x54, 0x53, 0xcd, 0x8a, 0x5e, 0x42, 0xcd, + 0xba, 0xd1, 0x50, 0x15, 0x6d, 0x5d, 0x53, 0x4b, 0x62, 0x4e, 0x5a, 0x00, 0xd2, 0x70, 0xb7, 0xdc, + 0x34, 0x75, 0x51, 0x90, 0x0a, 0xe0, 0xc2, 0x70, 0x7b, 0x4d, 0xae, 0x37, 0xe5, 0xaa, 0x98, 0x2f, + 0x62, 0x00, 0x06, 0xac, 0xa5, 0x25, 0x70, 0x89, 0xc3, 0x99, 0x5b, 0x0d, 0x75, 0x84, 0xf8, 0x55, + 0xb0, 0x18, 0xed, 0xd4, 0xea, 0x86, 0x29, 0x57, 0xab, 0xc8, 0x50, 0xa0, 0xd6, 0x30, 0x45, 0x41, + 0x5a, 0x04, 0x0b, 0xd1, 0x7e, 0xb9, 0x26, 0x7f, 0xa4, 0xd7, 0x91, 0xaa, 0x18, 0x62, 0xbe, 0xf8, + 0xc9, 0x34, 0xb8, 0x35, 0x18, 0xbf, 0xe2, 0x61, 0x2b, 0xc0, 0xe1, 0xaf, 0x63, 0xc5, 0xed, 0xec, + 0x38, 0xbb, 0x2f, 0xbd, 0x5d, 0xba, 0xe0, 0x4c, 0x8b, 0x8e, 0x74, 0xd8, 0x2e, 0x9f, 0x66, 0x30, + 0x98, 0x64, 0x85, 0xad, 0xb2, 0xbf, 0x43, 0xfb, 0x6c, 0x45, 0x7e, 0x15, 0xff, 0x50, 0x00, 0xa7, + 0xa3, 0xdd, 0xc4, 0x7a, 0x14, 0xbd, 0xbe, 0xae, 0x95, 0xe3, 0xad, 0x67, 0xac, 0x5b, 0xde, 0x34, + 0x90, 0xaa, 0x3c, 0x42, 0x86, 0x51, 0x13, 0x05, 0x32, 0xff, 0xf1, 0xdd, 0xaa, 0xa6, 0xa8, 0x62, + 0x3e, 0x1e, 0x1d, 0x96, 0x0c, 0x6a, 0x02, 0x53, 0xd2, 0x65, 0x70, 0x31, 0x06, 0x7d, 0xc3, 0x10, + 0xa7, 0x8b, 0xff, 0x22, 0x80, 0x6b, 0x31, 0xf1, 0x92, 0xef, 0x0b, 0x5e, 0x7a, 0xc7, 0xff, 0x3f, + 0xf3, 0xd1, 0xc5, 0x11, 0x0e, 0x9f, 0xcd, 0x5c, 0xcf, 0xc3, 0x35, 0xb3, 0x6a, 0xbc, 0xf4, 0x3a, + 0xf8, 0xff, 0x79, 0xf0, 0x30, 0xea, 0x20, 0xfd, 0xfd, 0xc0, 0xed, 0x92, 0x30, 0x78, 0x88, 0x4b, + 0x8e, 0x87, 0x5b, 0x81, 0xeb, 0x1d, 0x9b, 0xae, 0xdb, 0xf6, 0xb5, 0x8e, 0x1f, 0x58, 0x9f, 0x83, + 0x6c, 0xe0, 0x3b, 0x79, 0xb0, 0x9a, 0xa6, 0x90, 0xbe, 0x89, 0xbc, 0xf4, 0xda, 0xf8, 0xe3, 0x3c, + 0xb8, 0x33, 0xd0, 0x86, 0xdc, 0x0b, 0xdc, 0xf0, 0xef, 0x48, 0x0a, 0xf9, 0xd2, 0x47, 0x90, 0xbb, + 0xe0, 0x6c, 0x7c, 0x3a, 0x3d, 0xef, 0x0d, 0xa7, 0xd1, 0xdf, 0xcc, 0x83, 0x9b, 0x03, 0x75, 0xa9, + 0xca, 0x23, 0xba, 0x6a, 0x3a, 0x9f, 0xa7, 0xbd, 0xe8, 0x3f, 0x0a, 0xe0, 0xf2, 0x68, 0xc6, 0x45, + 0x02, 0xd5, 0xe7, 0x6c, 0xe0, 0x2c, 0x73, 0xa8, 0xbb, 0xf6, 0xcb, 0xef, 0x23, 0x7e, 0x2e, 0x80, + 0xab, 0xa3, 0x03, 0x97, 0xbb, 0x5d, 0x92, 0x66, 0x7f, 0x0e, 0x92, 0x88, 0x6f, 0xe7, 0xc1, 0xfd, + 0x09, 0x49, 0x84, 0x26, 0xd7, 0x1a, 0x6e, 0xdb, 0x69, 0x1d, 0xbf, 0xf4, 0x8a, 0xf8, 0x77, 0x01, + 0x14, 0x07, 0x8a, 0x68, 0x78, 0x4e, 0xa7, 0xe5, 0x74, 0xad, 0xb6, 0xff, 0xf9, 0x09, 0x96, 0xff, + 0x2c, 0x80, 0xe5, 0x81, 0x06, 0x4c, 0xec, 0x07, 0xfc, 0xe0, 0xed, 0xf3, 0xe0, 0xf7, 0xff, 0x41, + 0x00, 0x85, 0x88, 0x17, 0xe0, 0x17, 0x2f, 0xf6, 0x4b, 0x3f, 0xee, 0x25, 0xe2, 0xf5, 0xb9, 0xb7, + 0xc7, 0x47, 0xd0, 0x6d, 0x47, 0x2f, 0x87, 0xfe, 0x92, 0x5a, 0xc4, 0x50, 0xaf, 0x61, 0x1d, 0x46, + 0x2f, 0x3b, 0x6e, 0x82, 0x33, 0x24, 0x43, 0xb0, 0x2d, 0xcf, 0x46, 0x3d, 0x1f, 0xb3, 0xcb, 0x84, + 0x59, 0x78, 0x3a, 0x6c, 0x6c, 0xfa, 0xd8, 0x96, 0x96, 0xc0, 0xdc, 0xb1, 0x75, 0xd0, 0x66, 0x00, + 0x79, 0x0a, 0x30, 0x4b, 0x1a, 0x68, 0xe7, 0x1d, 0x70, 0xf6, 0xc0, 0xb5, 0x31, 0x3a, 0xda, 0xc3, + 0x1d, 0xe4, 0x5b, 0x87, 0xd8, 0xe6, 0xf7, 0x2e, 0x67, 0x48, 0xf3, 0xe6, 0x1e, 0xee, 0x10, 0x96, + 0xb6, 0x24, 0x83, 0xe5, 0x1d, 0x07, 0xb7, 0x6d, 0x1f, 0x1d, 0x39, 0xc1, 0x1e, 0x6a, 0xb9, 0x9d, + 0x43, 0xec, 0xf9, 0x8e, 0xdb, 0x41, 0xf4, 0xac, 0xdf, 0x2f, 0x4c, 0x5f, 0x9f, 0xba, 0x37, 0x07, + 0x17, 0x19, 0xd0, 0xa6, 0x13, 0xec, 0x29, 0x7d, 0x10, 0x95, 0x42, 0x14, 0x6f, 0x90, 0xed, 0xe2, + 0xf0, 0x58, 0x49, 0x72, 0xd3, 0x8e, 0x8c, 0xf8, 0x55, 0xb0, 0x32, 0x02, 0xf2, 0xcc, 0xc1, 0x47, + 0x25, 0xb7, 0xd5, 0x3b, 0xc0, 0x9d, 0xc0, 0x1a, 0x3e, 0x5e, 0x2b, 0xfe, 0x48, 0x00, 0x17, 0x65, + 0xdf, 0x77, 0xc8, 0x4a, 0xa1, 0x06, 0xd3, 0x5f, 0x29, 0x77, 0xc1, 0x59, 0x2e, 0x21, 0xc5, 0x41, + 0xfd, 0x6b, 0x96, 0xf9, 0x68, 0xb3, 0x66, 0x4b, 0x37, 0xc0, 0xe9, 0xc0, 0x0d, 0xac, 0x36, 0x0a, + 0xdc, 0x7d, 0xdc, 0x61, 0xd7, 0x08, 0x53, 0xf0, 0x14, 0x6d, 0x33, 0x69, 0x13, 0xd1, 0x71, 0xd7, + 0x73, 0x0f, 0xba, 0x41, 0x08, 0x33, 0x45, 0x61, 0x4e, 0xb3, 0x46, 0x0e, 0xf4, 0x0a, 0x38, 0xd7, + 0xea, 0xcb, 0x10, 0x02, 0xb2, 0x2c, 0x4f, 0x1c, 0x74, 0x30, 0xe0, 0xe2, 0x5f, 0x09, 0xe0, 0x02, + 0x93, 0x5b, 0xfd, 0x18, 0xb7, 0x7a, 0x9f, 0x42, 0xec, 0x65, 0x00, 0x3a, 0x64, 0xd6, 0x58, 0x36, + 0xc9, 0x84, 0x9e, 0x23, 0x2d, 0x34, 0x91, 0x1c, 0x1b, 0xd5, 0x54, 0x86, 0x51, 0x4d, 0x67, 0x1d, + 0xd5, 0x4c, 0xc2, 0xa8, 0x9e, 0x80, 0x45, 0x36, 0xa8, 0x3a, 0x3e, 0x52, 0x22, 0xe2, 0xf6, 0xef, + 0xc6, 0x5a, 0x56, 0x80, 0x77, 0x5d, 0xef, 0x38, 0xbc, 0x1b, 0x0b, 0x7f, 0x17, 0xff, 0x44, 0x00, + 0xe7, 0x19, 0xaa, 0x4c, 0xaf, 0x6e, 0x21, 0xfe, 0x5a, 0x0f, 0xfb, 0xd4, 0xba, 0xc3, 0xd5, 0xc6, + 0xce, 0xea, 0x18, 0xe2, 0xe9, 0xb0, 0x91, 0x1e, 0x7e, 0xfd, 0x42, 0x66, 0xf0, 0x13, 0x01, 0x9c, + 0x0e, 0x25, 0x26, 0xcd, 0xd2, 0x02, 0x38, 0x61, 0xd1, 0xbf, 0xb8, 0x8c, 0xfc, 0xd7, 0x2f, 0x46, + 0xba, 0x5b, 0x40, 0x62, 0x8a, 0xac, 0x3a, 0x7e, 0x90, 0x78, 0xdb, 0xf8, 0x0d, 0x50, 0x88, 0x42, + 0x1d, 0x6c, 0x47, 0x6e, 0x26, 0x25, 0x30, 0x1d, 0xb9, 0xc5, 0xa4, 0x7f, 0x4b, 0x3a, 0x38, 0x7b, + 0x40, 0xa1, 0xfc, 0x3d, 0xa7, 0x8b, 0xf6, 0x9d, 0x0e, 0x73, 0x26, 0xf3, 0x8f, 0xee, 0x0c, 0x1c, + 0x5f, 0xe4, 0xea, 0xfd, 0xf0, 0xe1, 0x6a, 0xad, 0x0f, 0xbe, 0xe1, 0x74, 0x6c, 0x38, 0x7f, 0x30, + 0xf4, 0xbb, 0xf8, 0x15, 0x20, 0x0e, 0x04, 0x60, 0x8b, 0x5e, 0x2a, 0x8f, 0xb9, 0xfa, 0x64, 0xb7, + 0x3a, 0x3e, 0xc6, 0x81, 0xb3, 0x1f, 0x26, 0xde, 0xec, 0xda, 0x9f, 0x1d, 0xf1, 0x12, 0x26, 0xa1, + 0xea, 0xc5, 0x11, 0xff, 0x53, 0x01, 0x2c, 0x8c, 0x4e, 0xcc, 0x0b, 0xd6, 0x8e, 0xf4, 0x51, 0x38, + 0x97, 0xa8, 0x4f, 0x2f, 0x2d, 0x22, 0x26, 0xd9, 0x4a, 0x38, 0xad, 0xb5, 0x49, 0xf2, 0xbf, 0xe0, + 0x09, 0xf8, 0x2f, 0x97, 0xff, 0x05, 0xcf, 0xf1, 0x67, 0x2a, 0xff, 0x6f, 0xe7, 0xa3, 0xf2, 0x97, + 0x3d, 0xab, 0x13, 0xf8, 0xa6, 0xdb, 0xf4, 0xb1, 0x27, 0xad, 0x82, 0xf3, 0x34, 0x62, 0x20, 0xcf, + 0x6d, 0x63, 0x1f, 0xed, 0x92, 0x3e, 0x9e, 0x34, 0xcc, 0xc0, 0x73, 0xb4, 0x8b, 0xc4, 0x5c, 0xbf, + 0xcc, 0x3a, 0x48, 0xd0, 0x67, 0xf0, 0x4e, 0x67, 0x0f, 0x7b, 0x0e, 0xbd, 0x18, 0x1c, 0xc2, 0x9c, + 0xa2, 0x98, 0x8b, 0x14, 0x48, 0x0b, 0x61, 0x86, 0x48, 0xbc, 0x0e, 0x2e, 0x30, 0x12, 0x81, 0x67, + 0x39, 0xc1, 0x00, 0x33, 0x4f, 0x31, 0x25, 0xda, 0x67, 0xd2, 0xae, 0x10, 0x43, 0x01, 0x57, 0x47, + 0x99, 0x8e, 0xe0, 0x4e, 0x53, 0xdc, 0xa5, 0x61, 0xae, 0xc3, 0x44, 0x96, 0xc0, 0x5c, 0xcf, 0xc7, + 0x1e, 0xa2, 0x5e, 0x6c, 0x66, 0x50, 0x8b, 0x51, 0xb7, 0x0e, 0x70, 0xf1, 0x07, 0x53, 0x51, 0x0d, + 0x41, 0x7c, 0xe8, 0xe0, 0xa3, 0x17, 0xbd, 0xc2, 0x9e, 0x80, 0xcb, 0xb6, 0x75, 0xec, 0xa3, 0xae, + 0xe5, 0x07, 0xa8, 0x83, 0x3f, 0x0e, 0x90, 0xd5, 0xb3, 0x9d, 0x00, 0x91, 0x75, 0xc0, 0x07, 0x7f, + 0x91, 0x00, 0x34, 0x2c, 0x12, 0x30, 0x3f, 0x0e, 0x64, 0xd2, 0x5b, 0x22, 0x22, 0xac, 0x83, 0x6b, + 0x11, 0x3f, 0xeb, 0xe1, 0xaf, 0xf5, 0x1c, 0x0f, 0x93, 0xf4, 0xc7, 0x47, 0xad, 0x3d, 0xab, 0xb3, + 0xcb, 0xd5, 0x3e, 0x0b, 0x97, 0x07, 0x60, 0x30, 0x02, 0xa5, 0x30, 0x20, 0xe9, 0x09, 0x28, 0x78, + 0x74, 0x68, 0x68, 0x87, 0x10, 0xc1, 0x9d, 0xd6, 0x71, 0x9f, 0xc0, 0x34, 0x25, 0xb0, 0xc0, 0xfa, + 0xd7, 0xc3, 0xee, 0x10, 0xf3, 0x3d, 0xb0, 0xc4, 0x31, 0x6d, 0xeb, 0x18, 0xb9, 0x3b, 0xe8, 0xc0, + 0xed, 0x90, 0x9c, 0x8f, 0x23, 0xcf, 0x50, 0xe4, 0x4b, 0x0c, 0xa4, 0x64, 0x1d, 0xeb, 0x3b, 0x35, + 0xd2, 0x1f, 0x62, 0xbf, 0x0d, 0x2e, 0x77, 0x7a, 0xd4, 0xb6, 0xdd, 0x1d, 0xe4, 0xe1, 0x03, 0xf7, + 0x10, 0xdb, 0x88, 0x8b, 0x5a, 0x38, 0x41, 0x47, 0xbe, 0xc0, 0x00, 0xf4, 0x1d, 0xc8, 0xba, 0x79, + 0xa0, 0x28, 0xfe, 0x9a, 0x30, 0x3e, 0x31, 0x2f, 0x7a, 0xe9, 0x3d, 0x04, 0x17, 0x59, 0x94, 0x42, + 0x24, 0x4c, 0x21, 0x3e, 0x50, 0xc7, 0xe6, 0xa5, 0x2b, 0x92, 0x35, 0xc2, 0x5f, 0xb3, 0x8b, 0xdf, + 0x15, 0xc0, 0xe5, 0x48, 0x59, 0x04, 0xbb, 0xd8, 0x4e, 0x8a, 0xab, 0xd2, 0x1a, 0x98, 0x8e, 0x04, + 0xc7, 0xd5, 0x44, 0x29, 0xc7, 0x28, 0xd2, 0x20, 0x49, 0x71, 0x87, 0xcd, 0x77, 0x6a, 0xc4, 0x7c, + 0x5d, 0xb2, 0x2b, 0x18, 0xc3, 0xa6, 0xe5, 0x35, 0x2c, 0xd7, 0xaa, 0x8f, 0xe9, 0xea, 0x51, 0x76, + 0x29, 0x62, 0x22, 0x92, 0x07, 0xae, 0xc7, 0x30, 0x0c, 0x37, 0x69, 0x9f, 0x0d, 0xcf, 0xaf, 0x83, + 0xa5, 0x98, 0x21, 0xf6, 0x2b, 0x96, 0x2a, 0x60, 0xba, 0xe5, 0xda, 0x61, 0x29, 0xd4, 0xe3, 0xec, + 0xac, 0x18, 0xbe, 0xe2, 0xda, 0x18, 0x52, 0x0a, 0x09, 0xa5, 0x4b, 0xdf, 0xcc, 0x83, 0x2b, 0xb1, + 0x4a, 0xc6, 0xdd, 0xcf, 0x64, 0xbc, 0xc4, 0x6a, 0xfc, 0x00, 0x77, 0x9f, 0xdf, 0x6a, 0x88, 0x48, + 0x90, 0xe2, 0x4a, 0xd5, 0x91, 0x1d, 0xe9, 0xe3, 0xe7, 0xa3, 0x32, 0x7e, 0x34, 0x75, 0x33, 0x4e, + 0x05, 0xec, 0x44, 0x42, 0xef, 0xe2, 0xce, 0x2f, 0xaf, 0x26, 0x36, 0xc0, 0x49, 0x9f, 0xc9, 0x49, + 0x55, 0x31, 0x3f, 0x21, 0xae, 0x26, 0x0d, 0x10, 0x86, 0x14, 0x8a, 0xdf, 0xca, 0x83, 0xdb, 0x31, + 0x8a, 0x58, 0x27, 0x3b, 0xdd, 0xcf, 0x74, 0x11, 0xbc, 0x10, 0x55, 0xa8, 0x60, 0x86, 0xee, 0xc9, + 0xb9, 0x22, 0x1e, 0x64, 0x27, 0x42, 0x07, 0x08, 0x19, 0x76, 0xf1, 0xdf, 0x84, 0x04, 0x27, 0x40, + 0xf6, 0x9c, 0xdd, 0xe3, 0x5f, 0xde, 0xf1, 0xaf, 0x83, 0x69, 0xba, 0x77, 0x64, 0xc3, 0x7f, 0x0e, + 0x79, 0xc8, 0xd0, 0x68, 0x65, 0x07, 0xc5, 0x2f, 0xfe, 0x85, 0x00, 0x6e, 0xc4, 0x28, 0xa0, 0xea, + 0x74, 0xf6, 0x23, 0x07, 0x32, 0xbf, 0x8c, 0x1a, 0x90, 0xc0, 0x74, 0xdb, 0xe9, 0xec, 0xf3, 0x38, + 0x42, 0xff, 0x2e, 0xfe, 0xad, 0x00, 0xce, 0xf7, 0xcb, 0x91, 0x69, 0xea, 0xd3, 0x3f, 0x50, 0x4a, + 0xdf, 0x72, 0x47, 0x2e, 0xb4, 0x90, 0xeb, 0x39, 0xbb, 0x4e, 0x87, 0x3b, 0xcf, 0xfe, 0x85, 0x96, + 0x4e, 0x5b, 0xa5, 0xdb, 0x60, 0xbe, 0xd5, 0x76, 0x7b, 0x36, 0xea, 0x7a, 0xee, 0xa1, 0x63, 0x63, + 0x2f, 0x3c, 0x5b, 0xa2, 0xad, 0x0d, 0xde, 0x28, 0xe9, 0x60, 0xd6, 0xe6, 0x27, 0xdf, 0x34, 0x33, + 0x39, 0xf5, 0xe8, 0x8d, 0xd4, 0xb3, 0x34, 0x6c, 0x87, 0x87, 0xe5, 0x03, 0xad, 0x85, 0x44, 0x8a, + 0xcf, 0xc0, 0x62, 0x32, 0x9c, 0x74, 0x09, 0x9c, 0xb4, 0xb7, 0xa3, 0xa3, 0x3b, 0x61, 0x6f, 0xd3, + 0x71, 0x5d, 0x03, 0xa7, 0xec, 0x6d, 0x44, 0x6b, 0xc6, 0x5b, 0x6e, 0x9b, 0x8f, 0x09, 0xd8, 0xdb, + 0x0d, 0xde, 0x52, 0xfc, 0x99, 0x00, 0x16, 0xd7, 0xb1, 0x15, 0xf4, 0x3c, 0x0c, 0x71, 0xcb, 0x3d, + 0x38, 0xc0, 0x1d, 0x3b, 0x72, 0xc6, 0x31, 0x14, 0xb5, 0x85, 0xe1, 0xa8, 0x2d, 0xbd, 0x03, 0x4e, + 0xee, 0x30, 0x54, 0x3e, 0x99, 0xd7, 0x13, 0xc7, 0x18, 0xb2, 0x08, 0x11, 0xa4, 0x8f, 0xc1, 0x32, + 0xff, 0x13, 0x79, 0x43, 0x7c, 0x51, 0xc4, 0xdf, 0x4f, 0x0a, 0x83, 0xb1, 0x42, 0x73, 0x7f, 0xbf, + 0xb4, 0x93, 0xdc, 0x59, 0x3c, 0x02, 0x17, 0x4c, 0xb9, 0xcc, 0x8e, 0xa9, 0xf0, 0x87, 0x3d, 0xec, + 0xf1, 0x95, 0x7e, 0x0d, 0xb0, 0x33, 0x0c, 0xd4, 0x71, 0x6d, 0xcc, 0xca, 0x86, 0xa7, 0x20, 0xa0, + 0x4d, 0x75, 0xd2, 0x32, 0x00, 0xc0, 0xf6, 0x2e, 0x0e, 0xcf, 0x3d, 0x18, 0x80, 0x4a, 0x5a, 0xa4, + 0x65, 0x00, 0x1c, 0x1f, 0xf9, 0x3d, 0x9a, 0x6e, 0xf1, 0x8c, 0x76, 0xce, 0xf1, 0x0d, 0xd6, 0x50, + 0xfc, 0xfb, 0x29, 0x70, 0x89, 0xe5, 0x71, 0x65, 0xcf, 0xea, 0xee, 0xc9, 0x9b, 0x86, 0xd1, 0xb2, + 0x3a, 0x61, 0x59, 0xdd, 0x79, 0x4e, 0xbb, 0xf5, 0x08, 0x39, 0xfc, 0x8e, 0x94, 0x09, 0x31, 0x0d, + 0xcf, 0x31, 0x1e, 0xad, 0xfe, 0xe5, 0x69, 0x44, 0x16, 0x32, 0x19, 0x4c, 0x96, 0x69, 0x2e, 0x0b, + 0xd9, 0x16, 0xf9, 0x83, 0x53, 0x9a, 0x5d, 0xcf, 0xed, 0x75, 0x99, 0x34, 0xd3, 0xfc, 0x94, 0xa6, + 0x4c, 0x9b, 0x06, 0x34, 0xe8, 0x06, 0x88, 0x9a, 0x69, 0x48, 0x83, 0xee, 0x77, 0x88, 0xad, 0x33, + 0x80, 0xae, 0xdb, 0x76, 0x5a, 0x0e, 0x66, 0x07, 0x65, 0xd3, 0xf0, 0x0c, 0x6d, 0x6d, 0xf0, 0x46, + 0xe9, 0x55, 0x20, 0x71, 0xd9, 0xf7, 0x7d, 0xd4, 0x6a, 0xf7, 0xfc, 0x20, 0x4c, 0x8b, 0xa7, 0xa1, + 0xc8, 0x44, 0xdf, 0xf7, 0x15, 0xde, 0x3e, 0x18, 0xa9, 0x67, 0xfb, 0x91, 0x91, 0x9e, 0x8c, 0x8c, + 0x14, 0xda, 0xfe, 0x60, 0xa4, 0xf7, 0x00, 0xa3, 0x81, 0xfc, 0x37, 0xd0, 0x76, 0xaf, 0xb5, 0x8f, + 0x03, 0xbf, 0x30, 0x4b, 0x81, 0x99, 0x70, 0xc6, 0x1b, 0x6b, 0xac, 0x95, 0xec, 0xcb, 0x38, 0xa4, + 0x75, 0xd0, 0xee, 0xaf, 0x4f, 0xbf, 0x30, 0x47, 0xa1, 0x99, 0x8c, 0x86, 0x75, 0xd0, 0x0e, 0x17, + 0x69, 0x04, 0xc3, 0x75, 0xec, 0x56, 0x04, 0x03, 0x44, 0x30, 0x74, 0xc7, 0x6e, 0x0d, 0x30, 0xfa, + 0x2a, 0xb1, 0x5a, 0x74, 0xaf, 0xe6, 0x17, 0x4e, 0x45, 0x54, 0x22, 0xf3, 0xc6, 0xe2, 0x0f, 0x04, + 0x70, 0xab, 0xa9, 0x45, 0x26, 0x5b, 0xf1, 0xdc, 0xa3, 0xce, 0x53, 0x7c, 0x84, 0xdb, 0x25, 0x67, + 0x67, 0xe7, 0x99, 0x83, 0x8f, 0xd8, 0xbc, 0x3f, 0x01, 0x05, 0x6b, 0x67, 0x67, 0xb8, 0x40, 0x15, + 0x45, 0x6a, 0xe2, 0xe7, 0xe0, 0x42, 0xd8, 0xdf, 0xaf, 0xe2, 0x66, 0x67, 0xf5, 0x8f, 0xc1, 0xc2, + 0x38, 0x66, 0xe4, 0x05, 0xc2, 0x85, 0x51, 0x3c, 0x5a, 0xc6, 0xb7, 0x0e, 0xae, 0x18, 0xb8, 0xd5, + 0xf3, 0x9c, 0xe0, 0x18, 0xd2, 0x65, 0x55, 0xc6, 0x01, 0xc4, 0x7e, 0xaf, 0xcd, 0xf3, 0xec, 0xb8, + 0x53, 0x32, 0x09, 0x4c, 0x93, 0x6d, 0x1d, 0xdf, 0xe2, 0xd1, 0xbf, 0x8b, 0x16, 0x38, 0xdf, 0x2f, + 0x02, 0x5b, 0xc7, 0x41, 0x6b, 0x8f, 0xa1, 0x8f, 0x7b, 0x47, 0x21, 0xce, 0x3b, 0x8e, 0xb9, 0xe4, + 0xfc, 0xb8, 0x4b, 0x2e, 0x7e, 0x5f, 0x00, 0x12, 0xb1, 0x65, 0xd3, 0xf2, 0xf7, 0xc9, 0xd2, 0xc5, + 0x7d, 0x8f, 0x14, 0x58, 0xfe, 0x7e, 0xd4, 0xd9, 0xcd, 0x92, 0x86, 0xf0, 0xb5, 0x85, 0xe3, 0xfb, + 0xbd, 0x21, 0xaa, 0x73, 0xb4, 0x85, 0x76, 0x5f, 0x00, 0x33, 0xc4, 0xbb, 0x84, 0xfb, 0x0f, 0xf6, + 0x83, 0xf8, 0xfe, 0xbe, 0x1d, 0x46, 0x8a, 0x19, 0x66, 0xe0, 0x7c, 0xbf, 0x99, 0x15, 0x33, 0xfc, + 0xe6, 0x07, 0xe0, 0x6c, 0x93, 0x78, 0x21, 0x2a, 0x89, 0xde, 0xc1, 0xfa, 0x8e, 0xd4, 0x04, 0x67, + 0x7b, 0x0e, 0xda, 0xa6, 0x2f, 0x71, 0x50, 0x8b, 0x44, 0xcd, 0xd4, 0xbd, 0xdc, 0xf8, 0xc3, 0x9d, + 0x4a, 0x0e, 0x9e, 0xe9, 0x39, 0x91, 0x56, 0xe9, 0x13, 0x01, 0xdc, 0xef, 0x39, 0xc8, 0x65, 0x0f, + 0x53, 0x10, 0x3f, 0x0f, 0xc5, 0x68, 0xd7, 0x45, 0x81, 0x8b, 0xec, 0xf0, 0xe5, 0x0e, 0xe7, 0xc8, + 0x72, 0x63, 0x79, 0x02, 0xc7, 0x6c, 0xcf, 0x7f, 0x2a, 0x39, 0x78, 0xb3, 0xe7, 0xa4, 0xc2, 0x4a, + 0xdf, 0x11, 0xc0, 0xcd, 0x88, 0x74, 0x96, 0x6d, 0xa3, 0x1d, 0xc7, 0xa3, 0x5b, 0x4f, 0x3e, 0xab, + 0x4c, 0x2e, 0x16, 0xf9, 0xde, 0x4b, 0x97, 0x2b, 0xf9, 0x39, 0x51, 0x25, 0x07, 0xaf, 0xf6, 0x45, + 0x8a, 0x05, 0x1b, 0xd5, 0x55, 0x8c, 0x34, 0x6d, 0x2b, 0xe8, 0xcf, 0xce, 0x4c, 0x56, 0x5d, 0xa5, + 0xbc, 0x5d, 0x1a, 0xd2, 0x55, 0x32, 0xac, 0xf4, 0xbf, 0x05, 0x70, 0x3d, 0x22, 0x9d, 0x8f, 0x03, + 0xd4, 0xea, 0x3f, 0x73, 0x42, 0x3e, 0x7d, 0x61, 0x44, 0x9d, 0xe5, 0xa9, 0x47, 0xef, 0xa4, 0x0b, + 0x95, 0xf4, 0x48, 0xaa, 0x92, 0x83, 0x57, 0xfa, 0xd2, 0xc4, 0x00, 0x49, 0xbf, 0x22, 0x80, 0x5b, + 0x11, 0x31, 0x3c, 0x5e, 0xd2, 0x88, 0x5a, 0xe1, 0x5b, 0xa7, 0x50, 0x94, 0x93, 0x54, 0x94, 0x2f, + 0xa5, 0x8b, 0x32, 0xe9, 0xb5, 0x54, 0x25, 0x07, 0xaf, 0xf7, 0xc5, 0x49, 0x00, 0x0c, 0x35, 0xe3, + 0xf1, 0xf7, 0x47, 0x88, 0xec, 0x5d, 0xc9, 0x02, 0x64, 0xef, 0x9f, 0xf8, 0x74, 0xcd, 0xa6, 0x6a, + 0x26, 0xe5, 0xf5, 0x14, 0xd3, 0x4c, 0x32, 0x90, 0xf4, 0x31, 0xb8, 0x12, 0x27, 0x45, 0xf7, 0x98, + 0x4b, 0x30, 0x47, 0x25, 0xf8, 0x42, 0x76, 0x09, 0xa2, 0xcf, 0xaf, 0x2a, 0x39, 0x58, 0x18, 0xe3, + 0xce, 0x01, 0xa4, 0xff, 0x01, 0x96, 0xc7, 0x39, 0x77, 0x3d, 0xa7, 0x13, 0x70, 0xd6, 0x80, 0xb2, + 0x7e, 0x2b, 0x2b, 0xeb, 0x91, 0xc7, 0x5b, 0x95, 0x1c, 0xbc, 0x3c, 0xc2, 0x7b, 0x00, 0x21, 0xb5, + 0xc1, 0xe5, 0x9e, 0x83, 0x6c, 0xee, 0xc4, 0x49, 0xd6, 0xe5, 0x91, 0x50, 0x42, 0x89, 0xd3, 0xa0, + 0x76, 0x6a, 0xc2, 0xc6, 0x2a, 0xfe, 0x09, 0x54, 0x25, 0x07, 0x17, 0x7a, 0x4e, 0xec, 0xe3, 0xa8, + 0xef, 0x30, 0xf3, 0xeb, 0xb3, 0x1b, 0xc4, 0xba, 0xb0, 0x0e, 0x8c, 0x73, 0x3e, 0x4d, 0x39, 0xbf, + 0x9d, 0x81, 0x73, 0xfc, 0xab, 0x26, 0x66, 0x79, 0x29, 0x2f, 0x9f, 0xbe, 0x41, 0x0d, 0xaf, 0x2f, + 0x0c, 0xaf, 0x9d, 0xf7, 0x59, 0x19, 0x3c, 0x17, 0xe4, 0x0c, 0x15, 0xe4, 0xcd, 0x4f, 0x55, 0x44, + 0xcf, 0x6c, 0x6e, 0xc2, 0xa3, 0x87, 0xff, 0xcb, 0x1c, 0xe8, 0x40, 0x02, 0x9e, 0xd0, 0x0f, 0xd6, + 0x25, 0x13, 0x62, 0x9e, 0x0a, 0xf1, 0x24, 0x8b, 0x10, 0x71, 0xb5, 0xca, 0x95, 0x1c, 0xbc, 0x16, + 0x91, 0x23, 0xb6, 0x9c, 0xf9, 0x37, 0x98, 0xf7, 0x1c, 0x17, 0xa5, 0x15, 0x96, 0xa9, 0xa0, 0x83, + 0xa0, 0xed, 0x73, 0x81, 0xce, 0x52, 0x81, 0xbe, 0xf8, 0x1c, 0x02, 0x8d, 0x57, 0x0f, 0x57, 0x72, + 0xf0, 0xd6, 0xb8, 0x54, 0x03, 0xb8, 0xa0, 0xcd, 0x0b, 0x28, 0xff, 0x4c, 0x00, 0x4f, 0x86, 0xe7, + 0x89, 0xd6, 0x9e, 0x22, 0x8b, 0x16, 0x9f, 0x22, 0x3b, 0xac, 0x3e, 0x45, 0x81, 0xeb, 0xb6, 0x79, + 0x32, 0xd9, 0x6e, 0x73, 0x49, 0x45, 0x2a, 0xe9, 0xd3, 0x4c, 0xf3, 0x97, 0xa9, 0xc6, 0xb7, 0x92, + 0x83, 0x0f, 0xa3, 0x93, 0x9a, 0xad, 0x30, 0xf8, 0xc7, 0x02, 0x78, 0x9c, 0x69, 0x0c, 0x03, 0x75, + 0x33, 0xf9, 0xcf, 0x51, 0xf9, 0xcb, 0x9f, 0x5a, 0xfe, 0xe1, 0x2a, 0xa3, 0x4a, 0x0e, 0xae, 0xa6, + 0x09, 0x3f, 0x52, 0x97, 0xf4, 0x5b, 0x02, 0x78, 0x25, 0x2a, 0xb9, 0xd5, 0x23, 0x99, 0x47, 0x7f, + 0x0f, 0x1a, 0x79, 0x4f, 0xc5, 0x04, 0x96, 0xa8, 0xc0, 0xef, 0x67, 0x10, 0x78, 0x52, 0xd5, 0x6c, + 0x25, 0x07, 0xef, 0x0c, 0x04, 0x9d, 0x58, 0x5f, 0xfb, 0x47, 0x02, 0x78, 0x90, 0x62, 0xb9, 0x8e, + 0x75, 0xc0, 0x36, 0x2f, 0xc7, 0x5c, 0xc8, 0xf3, 0x54, 0xc8, 0xb5, 0x4f, 0x63, 0xbf, 0xc3, 0x85, + 0x6b, 0x95, 0x1c, 0xbc, 0x3f, 0xc1, 0x88, 0x35, 0xeb, 0x20, 0x5a, 0xe5, 0xf6, 0xab, 0x02, 0xb8, + 0x13, 0x15, 0xb5, 0xdb, 0x2f, 0x06, 0x1b, 0x9b, 0xf7, 0x0b, 0x54, 0xc2, 0x77, 0x33, 0x48, 0x98, + 0x54, 0x51, 0x56, 0xc9, 0xc1, 0xe2, 0x40, 0xb4, 0xc4, 0xba, 0xb3, 0x6f, 0x09, 0xe0, 0x46, 0x54, + 0xa6, 0x00, 0xfb, 0x01, 0x91, 0xa6, 0x33, 0xe4, 0x8f, 0x2f, 0xa6, 0x46, 0xbf, 0x09, 0xe5, 0x5d, + 0x95, 0x1c, 0x5c, 0x1e, 0x48, 0x12, 0x57, 0xff, 0xe5, 0x81, 0xa5, 0xa8, 0x0c, 0x61, 0x9e, 0x1b, + 0xc6, 0xa1, 0x85, 0x94, 0x1b, 0xc4, 0xa4, 0xfa, 0x2a, 0x16, 0x76, 0x13, 0x6a, 0xaf, 0xda, 0xa0, + 0xd0, 0x73, 0x48, 0x12, 0x66, 0x05, 0x18, 0x75, 0xf0, 0x11, 0xdd, 0xff, 0xf2, 0x88, 0x7b, 0x29, + 0xe5, 0x80, 0x2b, 0xb1, 0xb2, 0xa9, 0x92, 0x83, 0x17, 0x7a, 0xce, 0x78, 0xa7, 0x74, 0x4c, 0x83, + 0xfc, 0x28, 0x37, 0xdf, 0x3a, 0x0c, 0x59, 0x16, 0x52, 0x35, 0x3c, 0xa1, 0x5c, 0x8a, 0x0d, 0x34, + 0x1e, 0x40, 0xfa, 0x06, 0xb8, 0x16, 0x37, 0x50, 0x5a, 0xa1, 0xc4, 0x99, 0x5f, 0x4e, 0x0d, 0x30, + 0x13, 0xab, 0x9b, 0x2a, 0x39, 0xb8, 0x38, 0x3a, 0xea, 0x01, 0x88, 0xf4, 0xbb, 0xcc, 0x85, 0x8c, + 0x4a, 0xc0, 0xee, 0xe1, 0xa2, 0x15, 0x50, 0x5c, 0x9a, 0x45, 0x2a, 0x8d, 0x92, 0x55, 0x9a, 0x09, + 0x85, 0x54, 0x95, 0x1c, 0xbc, 0x3d, 0x22, 0x58, 0x3c, 0xb4, 0xf4, 0x07, 0x02, 0x58, 0x8d, 0x9a, + 0xa0, 0x33, 0x38, 0x76, 0x44, 0xd6, 0x91, 0xcf, 0x8e, 0x06, 0xf8, 0xb2, 0xe0, 0x56, 0xb9, 0x94, + 0xba, 0x85, 0xc8, 0xf6, 0xf2, 0xb8, 0x92, 0x83, 0xf7, 0x06, 0x56, 0x1a, 0x85, 0x3d, 0xf2, 0x75, + 0xc7, 0x6e, 0x0d, 0xbd, 0x52, 0xfe, 0xae, 0x00, 0x6e, 0xc7, 0xa7, 0x0c, 0xb6, 0x8f, 0x30, 0x3d, + 0x20, 0xe5, 0xe2, 0x5d, 0xc9, 0x9c, 0x42, 0xc5, 0x3f, 0x08, 0x1e, 0x4e, 0xa1, 0xfa, 0x30, 0xb6, + 0x1f, 0x7d, 0xfe, 0x1a, 0x30, 0xb3, 0x26, 0xf1, 0x36, 0x70, 0x11, 0x2b, 0x0d, 0x62, 0xb3, 0xc8, + 0xa5, 0x58, 0x4e, 0x5d, 0xba, 0xf1, 0x2f, 0x4c, 0xb9, 0x45, 0xc7, 0xbf, 0x3e, 0xfd, 0x2a, 0x38, + 0x67, 0xd1, 0x1a, 0x25, 0x34, 0xa8, 0x10, 0x2a, 0x5c, 0xa5, 0x9c, 0x92, 0x0f, 0x92, 0x63, 0xeb, + 0xe9, 0x2a, 0x39, 0x28, 0x5a, 0x23, 0x1d, 0xa1, 0x4b, 0x8c, 0x9a, 0x00, 0xd7, 0x2c, 0x4d, 0x8f, + 0xf9, 0xc8, 0xae, 0xa5, 0x2e, 0xd8, 0x09, 0x37, 0x99, 0xcc, 0x25, 0x4e, 0xba, 0xea, 0xe4, 0xa9, + 0x72, 0x8c, 0x10, 0xfd, 0x53, 0x00, 0x26, 0xc7, 0xf5, 0xd4, 0x79, 0x9e, 0x7c, 0xc1, 0xc9, 0xe6, + 0x39, 0xe5, 0x12, 0xf4, 0x7f, 0x09, 0xd4, 0x89, 0x84, 0xfb, 0xc6, 0xaf, 0x45, 0xbf, 0xb1, 0x11, + 0x6e, 0x19, 0x6f, 0x64, 0xdd, 0xbd, 0x26, 0x7d, 0xa1, 0x63, 0x68, 0xf7, 0x1a, 0x03, 0x24, 0x7d, + 0x04, 0xf8, 0x64, 0x21, 0x1c, 0x96, 0x17, 0x16, 0x8a, 0x94, 0xeb, 0x6b, 0x29, 0xd3, 0x3e, 0x5c, + 0x8e, 0x58, 0xc9, 0xc1, 0xb3, 0xd6, 0x70, 0xbb, 0x74, 0x00, 0x2e, 0x71, 0xda, 0xc4, 0x41, 0x45, + 0xab, 0x12, 0x0b, 0x37, 0x53, 0x4e, 0xee, 0x93, 0x8b, 0x03, 0x2b, 0x39, 0x78, 0xd1, 0x8a, 0xeb, + 0x95, 0xb6, 0xc1, 0xc5, 0xc1, 0x29, 0x09, 0x73, 0x8c, 0x6c, 0x3a, 0x6f, 0x51, 0x66, 0xaf, 0x26, + 0x32, 0x8b, 0xb9, 0xdb, 0xa8, 0xe4, 0xe0, 0x79, 0x2f, 0xe6, 0xca, 0xe3, 0x08, 0x5c, 0x49, 0x38, + 0x5c, 0x67, 0xac, 0x6e, 0xa7, 0x8c, 0x2b, 0xf9, 0x42, 0x80, 0x38, 0xfc, 0x9d, 0xe4, 0xeb, 0x82, + 0x6d, 0xc0, 0x47, 0x8d, 0x78, 0x41, 0x82, 0xc7, 0xea, 0x1e, 0x0b, 0x77, 0x52, 0x06, 0x17, 0x53, + 0x2b, 0x49, 0x06, 0x67, 0xc5, 0x94, 0x50, 0x56, 0xc1, 0x99, 0x3e, 0x0f, 0x3a, 0x4b, 0x77, 0x29, + 0xed, 0xdb, 0xa9, 0xb4, 0x09, 0x70, 0x25, 0x07, 0x4f, 0x5b, 0xd1, 0x2a, 0xc7, 0x2d, 0x20, 0x45, + 0x6b, 0x27, 0xd8, 0x8c, 0x14, 0xee, 0xa5, 0x94, 0x64, 0x8f, 0x16, 0xf9, 0x51, 0x6f, 0x32, 0x5a, + 0xf8, 0x37, 0x42, 0xba, 0x47, 0x0b, 0xc6, 0x0a, 0xf7, 0x33, 0x93, 0x66, 0x15, 0x66, 0xc3, 0xa4, + 0x79, 0xd5, 0xd9, 0x08, 0x69, 0x9b, 0x16, 0x94, 0x14, 0x56, 0x32, 0x93, 0x66, 0x15, 0x28, 0xc3, + 0xa4, 0x79, 0x55, 0x4a, 0x1b, 0x5c, 0x8e, 0x92, 0xe6, 0x35, 0x5d, 0x5c, 0x2f, 0xaf, 0xa4, 0x9c, + 0x0b, 0xc4, 0x17, 0xf9, 0x55, 0x72, 0x70, 0xc1, 0x8a, 0x2f, 0xff, 0x8b, 0xe7, 0xc6, 0x55, 0xf5, + 0xea, 0x73, 0x72, 0xeb, 0x2b, 0x6c, 0x8c, 0x1b, 0x57, 0x5b, 0x3c, 0x37, 0xae, 0xbd, 0xd7, 0x9e, + 0x93, 0x5b, 0x5f, 0x87, 0x63, 0xdc, 0xb8, 0x26, 0x0f, 0xc0, 0x62, 0x94, 0x1b, 0x2d, 0xf5, 0xf2, + 0x49, 0xb4, 0xec, 0xf9, 0xd8, 0x2b, 0xac, 0x66, 0x66, 0x17, 0xad, 0x77, 0x1b, 0x66, 0x37, 0x54, + 0x09, 0xf7, 0xff, 0x04, 0x50, 0x8c, 0x26, 0x08, 0xd1, 0x9b, 0xa4, 0xc1, 0x31, 0x4b, 0xe1, 0x41, + 0xea, 0x99, 0x6c, 0xea, 0x6b, 0x3d, 0x76, 0x26, 0xdb, 0x07, 0x6b, 0x8d, 0x83, 0x49, 0xfb, 0xe0, + 0x52, 0xcc, 0x09, 0x0b, 0x76, 0x5a, 0xb8, 0xf0, 0x7a, 0x6a, 0x8a, 0x9d, 0xf0, 0x56, 0x8e, 0xa5, + 0xd8, 0x23, 0x9d, 0x4e, 0x0b, 0x8f, 0x32, 0x0b, 0xd3, 0x4d, 0xd7, 0xc6, 0x85, 0x87, 0x99, 0x99, + 0x8d, 0xbc, 0x4f, 0x1b, 0x66, 0x36, 0xe8, 0x94, 0xbe, 0x02, 0xce, 0x05, 0xd6, 0x2e, 0x8f, 0x43, + 0x98, 0x04, 0x44, 0xef, 0xb8, 0xf0, 0x28, 0x25, 0x16, 0xc5, 0x5d, 0x38, 0x92, 0x58, 0x14, 0x58, + 0xbb, 0xd1, 0x76, 0x29, 0x00, 0x8b, 0x3e, 0xbf, 0x9e, 0x41, 0x1e, 0xa5, 0x84, 0x76, 0x31, 0x3d, + 0xc8, 0xee, 0xb5, 0x83, 0xc2, 0x1b, 0x29, 0x47, 0x52, 0x93, 0x6e, 0x76, 0x2a, 0x39, 0x78, 0xc9, + 0x8f, 0xef, 0x1f, 0x5d, 0x16, 0xbc, 0x7e, 0x8c, 0x2f, 0xf9, 0xc7, 0x99, 0xed, 0x34, 0x5a, 0x75, + 0x38, 0x6c, 0xa7, 0x43, 0xf5, 0x88, 0xf1, 0xdc, 0xf8, 0x22, 0x7c, 0xf3, 0x39, 0xb9, 0xc5, 0x2d, + 0xc2, 0xa1, 0x22, 0xbb, 0x6d, 0x70, 0x31, 0x34, 0x8c, 0x63, 0xb4, 0x83, 0x83, 0xd6, 0x1e, 0x8f, + 0x81, 0x5f, 0x48, 0x89, 0x48, 0x31, 0xd7, 0x5b, 0x24, 0x22, 0xd9, 0x31, 0xb7, 0x5e, 0xdf, 0x1b, + 0x39, 0xcd, 0xe3, 0x06, 0x38, 0xe0, 0xcb, 0xf6, 0xf8, 0x85, 0xb7, 0x32, 0x1f, 0x9e, 0x25, 0x7f, + 0x66, 0x61, 0xf8, 0x48, 0x2f, 0x16, 0x4e, 0xfa, 0xe6, 0xc8, 0xce, 0x7e, 0xbf, 0xb7, 0x8d, 0xe9, + 0xe5, 0xec, 0xd0, 0x36, 0xe1, 0x49, 0xe6, 0x03, 0xce, 0xf1, 0xaf, 0xdf, 0x0c, 0x1f, 0x70, 0xd2, + 0xfe, 0xfd, 0xa1, 0xed, 0xc1, 0xb7, 0xe3, 0x55, 0x62, 0x75, 0xbb, 0xf4, 0x98, 0xb5, 0x7f, 0xc0, + 0xf9, 0x76, 0xea, 0x09, 0xf7, 0xa4, 0x67, 0x94, 0xc3, 0x8e, 0x28, 0xf6, 0xa1, 0x65, 0x17, 0x2c, + 0x71, 0x6b, 0xdb, 0xf5, 0xac, 0xee, 0x1e, 0xdd, 0xd2, 0xf9, 0x2d, 0x2b, 0xcc, 0x84, 0xde, 0xa1, + 0xfc, 0x5f, 0x4f, 0xb1, 0xb7, 0xb1, 0xfb, 0x7a, 0xb2, 0x9a, 0xac, 0x48, 0xd7, 0x91, 0x3f, 0xb8, + 0xca, 0xff, 0x3e, 0xdb, 0xa8, 0x0d, 0x71, 0x6d, 0x79, 0xee, 0x51, 0x07, 0xfd, 0x77, 0x7c, 0x84, + 0xdb, 0xc8, 0x76, 0x76, 0x76, 0xe8, 0x16, 0xb8, 0xf0, 0x6e, 0xaa, 0x3d, 0xa4, 0xdf, 0x20, 0x33, + 0x7b, 0x98, 0x08, 0x27, 0xfd, 0x37, 0x70, 0x91, 0x16, 0x71, 0xd0, 0x7b, 0x53, 0x7a, 0xe7, 0xc9, + 0x47, 0xff, 0x5e, 0xda, 0x4d, 0xe5, 0xd8, 0xf5, 0x6b, 0x25, 0x07, 0xa5, 0xde, 0xf8, 0xa5, 0x2c, + 0x3b, 0x50, 0x8f, 0xdd, 0x37, 0xe1, 0x2e, 0x67, 0xf6, 0xc5, 0x54, 0x7b, 0x4b, 0xae, 0x4d, 0x64, + 0xf6, 0x36, 0xa1, 0x76, 0xf1, 0xd7, 0x05, 0x70, 0x2f, 0x41, 0x02, 0x7e, 0x9c, 0xe5, 0x76, 0x71, + 0x38, 0xe9, 0x5f, 0x4a, 0x0d, 0x81, 0xa9, 0x25, 0x82, 0xec, 0xf6, 0x2f, 0xbd, 0x92, 0xf0, 0x13, + 0x01, 0xac, 0xc4, 0xcb, 0x45, 0x6b, 0xd0, 0x46, 0xb7, 0x74, 0xef, 0xa7, 0x5e, 0xbe, 0x65, 0xa8, + 0xd9, 0x63, 0x67, 0x1f, 0x59, 0x8a, 0xfb, 0xf8, 0x99, 0x42, 0xec, 0x56, 0x93, 0x3e, 0xc5, 0xea, + 0x86, 0xe7, 0xa6, 0x1f, 0x7c, 0x9a, 0xbd, 0x66, 0xa4, 0x8e, 0x2e, 0x71, 0xaf, 0x19, 0xad, 0xb5, + 0xfb, 0x3e, 0x3b, 0x25, 0x8d, 0x11, 0xa7, 0xed, 0x74, 0xf6, 0x87, 0x4e, 0x17, 0xe4, 0xd4, 0x2d, + 0x67, 0x4a, 0x59, 0x5b, 0x25, 0x07, 0x6f, 0xc4, 0x08, 0x34, 0x0c, 0xb4, 0x76, 0x12, 0xcc, 0x50, + 0x9a, 0x4f, 0xa7, 0x67, 0xf3, 0xe2, 0x14, 0xb1, 0xc1, 0xfe, 0x4e, 0x98, 0xc4, 0xe5, 0xf0, 0xd2, + 0x8c, 0x4a, 0xb6, 0xf2, 0x43, 0x71, 0xf0, 0x41, 0xc4, 0x70, 0xb3, 0x26, 0xdd, 0x00, 0xcb, 0x25, + 0xcd, 0x50, 0xf4, 0x67, 0x2a, 0x44, 0x50, 0x35, 0xf4, 0x26, 0x54, 0x46, 0x3f, 0x67, 0x74, 0x05, + 0x14, 0xc6, 0x41, 0x0c, 0x15, 0x3e, 0x53, 0xa1, 0x28, 0x48, 0xd7, 0xc1, 0x95, 0xf1, 0xde, 0x8d, + 0xe6, 0x9a, 0x0a, 0xeb, 0xaa, 0xa9, 0x1a, 0x62, 0x5e, 0x7a, 0x03, 0x3c, 0x18, 0x87, 0x28, 0xc9, + 0xa6, 0xbc, 0x26, 0x1b, 0x2a, 0x6a, 0xe8, 0x86, 0x59, 0x86, 0xaa, 0x81, 0x0c, 0xb5, 0xba, 0x8e, + 0x2a, 0xba, 0x61, 0xaa, 0x25, 0x71, 0x4a, 0x7a, 0x1d, 0xbc, 0x3a, 0x01, 0xa9, 0xb6, 0x65, 0x7c, + 0x58, 0x1d, 0xc2, 0x98, 0x96, 0x1e, 0x81, 0xd5, 0x49, 0x18, 0x7a, 0xbd, 0xac, 0x97, 0xd6, 0x86, + 0x70, 0x66, 0xa4, 0x57, 0xc0, 0xdd, 0x2c, 0xa2, 0xc1, 0x92, 0x21, 0x9e, 0x90, 0xee, 0x81, 0x5b, + 0xa9, 0x22, 0x11, 0xc8, 0x93, 0xd2, 0x1d, 0x50, 0x1c, 0x87, 0x94, 0x1b, 0x8d, 0xaa, 0xa6, 0xc8, + 0xa6, 0xa6, 0xd7, 0x51, 0xc5, 0x34, 0x1b, 0xe2, 0xac, 0x74, 0x1b, 0xdc, 0x98, 0x0c, 0x67, 0x2a, + 0x0d, 0x71, 0x2e, 0x1e, 0x6c, 0x53, 0xab, 0x97, 0xf4, 0x4d, 0x03, 0x95, 0x54, 0x63, 0xc3, 0xd4, + 0x1b, 0x22, 0x90, 0x5e, 0x05, 0xf7, 0x26, 0xc8, 0x67, 0x7c, 0x58, 0x65, 0x73, 0x46, 0x65, 0x3c, + 0x95, 0xa2, 0xe0, 0xc1, 0xd0, 0xd5, 0x92, 0x51, 0xd1, 0xd6, 0x4d, 0xf1, 0xb4, 0xf4, 0x18, 0xbc, + 0x9e, 0x89, 0x7e, 0x54, 0xc5, 0x67, 0x52, 0xf8, 0x40, 0xb5, 0xa4, 0x0d, 0x4f, 0xfd, 0x7c, 0xd6, + 0x49, 0x29, 0x2b, 0x0d, 0xf1, 0x6c, 0xa6, 0x49, 0x21, 0x90, 0x62, 0x66, 0xf5, 0x10, 0xe8, 0x73, + 0xd2, 0xbb, 0xe0, 0xad, 0xe7, 0x51, 0x0f, 0x5f, 0x0f, 0x55, 0xd5, 0x30, 0x44, 0x49, 0x7a, 0x0d, + 0xdc, 0xcf, 0x82, 0x2c, 0x7f, 0xd4, 0x84, 0xaa, 0x78, 0x5e, 0xba, 0x0b, 0x6e, 0x4e, 0x00, 0x2f, + 0x6d, 0xd5, 0xe5, 0x9a, 0x5e, 0x5a, 0x13, 0x2f, 0xa4, 0x98, 0xb8, 0x22, 0x1b, 0x86, 0x5c, 0x2f, + 0x41, 0x19, 0x6d, 0xa8, 0x5b, 0x46, 0x43, 0x56, 0x54, 0x43, 0xbc, 0x98, 0x32, 0x6b, 0x03, 0x9c, + 0xe8, 0x1c, 0x2c, 0x48, 0x4f, 0xc0, 0xe3, 0x09, 0x58, 0x6a, 0x55, 0x36, 0x4c, 0x4d, 0x31, 0x54, + 0x19, 0x2a, 0x95, 0x21, 0xcc, 0x4b, 0x99, 0xe6, 0x9b, 0xe3, 0xcb, 0x4a, 0x45, 0x15, 0x0b, 0x29, + 0xda, 0x62, 0x18, 0x35, 0xb5, 0xa6, 0xc3, 0xad, 0xd2, 0x9a, 0x78, 0x39, 0x13, 0x03, 0xaa, 0x59, + 0xc4, 0x18, 0x2c, 0xa6, 0x0c, 0x86, 0x61, 0x28, 0xd5, 0xa6, 0x61, 0x8e, 0x18, 0xef, 0x92, 0xb4, + 0x02, 0xee, 0xa4, 0x5a, 0x17, 0x9b, 0xc5, 0x2b, 0xd2, 0x2a, 0x58, 0xc9, 0x64, 0x5f, 0x0c, 0x7e, + 0x39, 0x65, 0x32, 0x07, 0xf0, 0x35, 0x4d, 0x81, 0xba, 0xa1, 0xaf, 0x9b, 0xe2, 0x55, 0xe9, 0x0b, + 0xe0, 0xd1, 0xa4, 0xc9, 0xd4, 0x95, 0x0d, 0xa8, 0xcb, 0x4a, 0x65, 0xc4, 0xcf, 0x5d, 0x4b, 0xb1, + 0xfd, 0xd0, 0x37, 0xca, 0x66, 0x55, 0x36, 0xc4, 0xeb, 0x29, 0x6b, 0xca, 0xa8, 0xeb, 0x9b, 0xeb, + 0x55, 0x79, 0x43, 0x15, 0x6f, 0x24, 0xd0, 0xd5, 0x95, 0x88, 0x76, 0x4b, 0x06, 0x6a, 0x40, 0xfd, + 0xcb, 0x5b, 0x62, 0x31, 0xc1, 0x14, 0xa3, 0xd0, 0x15, 0xad, 0x5c, 0x41, 0xf2, 0x33, 0x59, 0xab, + 0xca, 0x6b, 0x5a, 0x55, 0x33, 0xb7, 0xc4, 0x9b, 0xd2, 0x5b, 0xe0, 0x8d, 0x14, 0x2c, 0xba, 0x42, + 0x34, 0x05, 0x41, 0xb5, 0xac, 0x19, 0x26, 0xa4, 0xae, 0x53, 0xbc, 0x15, 0xef, 0x85, 0x0d, 0xb9, + 0x56, 0x8d, 0xba, 0x58, 0xf1, 0xb6, 0x54, 0x04, 0x57, 0xc7, 0xe1, 0x54, 0xe5, 0x11, 0xfb, 0x70, + 0x5f, 0x5d, 0x51, 0xc5, 0x3b, 0x09, 0x46, 0xa7, 0x2b, 0xa3, 0x6e, 0x18, 0xd5, 0xf5, 0x3a, 0x92, + 0x4b, 0xe2, 0x5d, 0xe9, 0x16, 0xb8, 0x3e, 0x29, 0x2e, 0xd2, 0x0f, 0xba, 0xdd, 0x8b, 0xb7, 0xfd, + 0x68, 0x04, 0x90, 0x37, 0x0d, 0xa4, 0xe8, 0x75, 0x43, 0xaf, 0xaa, 0xe2, 0x7d, 0xe9, 0x1a, 0x58, + 0x1a, 0x07, 0xaf, 0x29, 0x0d, 0x64, 0x98, 0x25, 0x4d, 0x17, 0x57, 0xe8, 0x67, 0x0f, 0xe3, 0x01, + 0x0c, 0x55, 0x7c, 0x45, 0xba, 0x0f, 0x6e, 0x27, 0xe1, 0x43, 0x55, 0xae, 0xc9, 0x6b, 0x55, 0x95, + 0xc5, 0xa6, 0x57, 0x57, 0x7e, 0x4f, 0x00, 0xf3, 0xc3, 0x9f, 0x1e, 0x1e, 0xe2, 0x6e, 0x98, 0xb2, + 0xd9, 0x34, 0x46, 0x32, 0x85, 0x25, 0x70, 0x69, 0x14, 0xc0, 0x68, 0x2a, 0x0a, 0x71, 0x8a, 0x42, + 0x6c, 0xe7, 0x86, 0xd6, 0x68, 0xa8, 0x25, 0x31, 0x2f, 0x5d, 0x06, 0x17, 0x47, 0x3b, 0x55, 0x08, + 0x75, 0x28, 0x4e, 0xc5, 0xe1, 0xc9, 0x6b, 0x3a, 0xa4, 0x41, 0x7f, 0xe5, 0x67, 0x79, 0x30, 0xa5, + 0x98, 0xb2, 0x74, 0x1e, 0x9c, 0x55, 0x4c, 0x79, 0xfc, 0x23, 0x8f, 0xa4, 0x51, 0x6e, 0x9a, 0x15, + 0xa2, 0xc3, 0xba, 0xaa, 0x98, 0x3a, 0x49, 0x59, 0x2e, 0x81, 0xf3, 0xb4, 0x5d, 0x31, 0xb5, 0x67, + 0x24, 0x93, 0x31, 0x0c, 0x4d, 0xaf, 0x93, 0x4c, 0xa5, 0xdf, 0x41, 0x44, 0x46, 0x50, 0xfd, 0xb0, + 0xa9, 0x1a, 0xa6, 0x21, 0x4e, 0x85, 0x1d, 0x0d, 0xa8, 0xd6, 0xb4, 0x66, 0x0d, 0x19, 0xcd, 0x46, + 0x43, 0x87, 0xa6, 0x38, 0x1d, 0x76, 0x98, 0x90, 0x78, 0x8f, 0x12, 0x2a, 0xa9, 0xcf, 0x34, 0xe2, + 0x76, 0x67, 0x42, 0xde, 0xcd, 0x46, 0x19, 0xca, 0x25, 0x15, 0xad, 0xc9, 0xf5, 0xba, 0x0a, 0xc5, + 0x13, 0x21, 0xc2, 0x9a, 0x56, 0xad, 0x6a, 0xf5, 0x32, 0x32, 0x9a, 0xb5, 0x9a, 0x0c, 0xb7, 0xc4, + 0x93, 0xe1, 0x08, 0x38, 0xef, 0xaa, 0x66, 0x98, 0xe2, 0x2c, 0xfd, 0x14, 0xe0, 0xa0, 0xb1, 0xa6, + 0xd7, 0x35, 0x53, 0x87, 0x5a, 0xbd, 0x2c, 0xce, 0xd1, 0x8f, 0x0c, 0x9a, 0x32, 0x52, 0xbf, 0x6c, + 0xaa, 0xb0, 0x2e, 0x57, 0x91, 0xdc, 0x2c, 0x69, 0x26, 0x32, 0x4c, 0x1d, 0xca, 0x65, 0x55, 0x04, + 0xa1, 0x00, 0xfa, 0x06, 0x91, 0xc2, 0x20, 0xba, 0xdb, 0xaa, 0x2b, 0xe2, 0x29, 0x49, 0x04, 0xa7, + 0x29, 0x5e, 0xdd, 0x84, 0x32, 0xd2, 0x4a, 0xe2, 0x69, 0xe9, 0x1c, 0x38, 0xd3, 0x87, 0x34, 0x14, + 0xad, 0x26, 0x9e, 0x09, 0xf9, 0x6a, 0x25, 0xb5, 0x6e, 0x6a, 0xe6, 0x16, 0x32, 0x54, 0xa5, 0x09, + 0xc9, 0x72, 0x9c, 0x5f, 0xf9, 0x11, 0x00, 0x17, 0x63, 0xdf, 0xd1, 0x91, 0x30, 0xa6, 0xd5, 0x4d, + 0xb5, 0xcc, 0x16, 0x20, 0x52, 0xeb, 0x50, 0xaf, 0x56, 0xd1, 0x86, 0x56, 0x1f, 0xfd, 0x7c, 0xe2, + 0x0d, 0xb0, 0x9c, 0x04, 0x68, 0x54, 0x65, 0x65, 0x43, 0x14, 0xc8, 0xea, 0x49, 0x02, 0x21, 0x2b, + 0x42, 0xd7, 0x4a, 0x8a, 0x98, 0x27, 0x89, 0x51, 0x12, 0x54, 0x43, 0x2e, 0xab, 0xb0, 0xd4, 0x34, + 0xb7, 0xc4, 0xa9, 0x49, 0xfc, 0xd4, 0x9a, 0xac, 0x55, 0xc5, 0x69, 0x92, 0xc5, 0x26, 0x81, 0x3c, + 0xd5, 0xa0, 0x2c, 0xce, 0x48, 0x37, 0xc1, 0xb5, 0x24, 0x08, 0x6a, 0x9e, 0xb0, 0x24, 0x9e, 0x20, + 0x2e, 0x27, 0x09, 0xa8, 0x26, 0x9b, 0xa6, 0x0a, 0x6b, 0xba, 0x61, 0x8a, 0x27, 0x27, 0x0d, 0xaf, + 0x66, 0x20, 0x53, 0x95, 0x6b, 0x86, 0x38, 0x3b, 0x09, 0x4a, 0x6f, 0x18, 0x65, 0xb5, 0xae, 0xa9, + 0xe2, 0xdc, 0x24, 0xd1, 0xc9, 0x94, 0x8a, 0x60, 0xe2, 0xe0, 0xe4, 0xda, 0xba, 0x78, 0x6a, 0xb2, + 0xdc, 0x4a, 0x45, 0xab, 0xab, 0xcc, 0x54, 0xde, 0x04, 0x0f, 0xd3, 0xe1, 0x50, 0x59, 0x33, 0x2b, + 0xcd, 0x35, 0xba, 0xbe, 0xc8, 0xba, 0x3a, 0x23, 0x3d, 0x00, 0xaf, 0x64, 0x40, 0x53, 0x34, 0xa8, + 0x54, 0x55, 0x45, 0x13, 0xe7, 0x89, 0x5b, 0xcc, 0xc6, 0xa7, 0x2a, 0xaf, 0x89, 0x67, 0x49, 0xe8, + 0xcd, 0x00, 0xfe, 0x54, 0xad, 0x6f, 0x68, 0x75, 0x43, 0x14, 0x33, 0xc2, 0xcb, 0x75, 0x43, 0x5b, + 0xab, 0xaa, 0xe2, 0xb9, 0x49, 0xea, 0x21, 0x41, 0x5a, 0x53, 0xd4, 0xba, 0xbe, 0x29, 0x4a, 0x93, + 0x26, 0xac, 0xbf, 0xde, 0xce, 0x93, 0x80, 0x96, 0x68, 0x49, 0xb2, 0x29, 0x97, 0xf4, 0x32, 0xd2, + 0xea, 0x0a, 0x5d, 0x7b, 0xa8, 0x26, 0xd7, 0xe5, 0xb2, 0x5a, 0x53, 0xeb, 0xa6, 0x78, 0x81, 0x64, + 0x23, 0x59, 0xc4, 0xde, 0x24, 0x69, 0x5f, 0x36, 0x58, 0x92, 0xeb, 0x2e, 0x90, 0x28, 0x9e, 0x85, + 0x2e, 0xcd, 0x5b, 0x68, 0x82, 0x97, 0x01, 0x9a, 0xe6, 0x9f, 0x55, 0xb2, 0x71, 0x28, 0x48, 0x0f, + 0xc1, 0x6b, 0x19, 0x30, 0x22, 0x7b, 0xc6, 0xcb, 0x93, 0x2c, 0x86, 0xac, 0xff, 0xbe, 0x63, 0x52, + 0xd4, 0xba, 0xa9, 0x42, 0x71, 0x71, 0xd2, 0x94, 0x72, 0x73, 0x84, 0x6a, 0x43, 0xe7, 0x9e, 0x54, + 0x5c, 0xca, 0x68, 0x61, 0x32, 0x2c, 0xeb, 0x4a, 0x49, 0xbc, 0x22, 0x7d, 0x00, 0xde, 0x7b, 0x6e, + 0xc3, 0x8f, 0x8e, 0x68, 0x79, 0xe5, 0xaf, 0x67, 0x62, 0xfc, 0xa6, 0x11, 0xe0, 0x6e, 0x82, 0xdf, + 0x34, 0x4c, 0xb5, 0x31, 0xe2, 0x37, 0xe3, 0xc7, 0x48, 0x01, 0xe5, 0x4d, 0x43, 0x53, 0xc2, 0x20, + 0xc7, 0xdc, 0xa3, 0x20, 0x7d, 0x09, 0xbc, 0x33, 0x19, 0xde, 0x50, 0x4d, 0xae, 0x11, 0x12, 0x6f, + 0x50, 0x49, 0x5d, 0x97, 0x9b, 0x55, 0x13, 0xe9, 0x9b, 0x24, 0x56, 0xe5, 0xa5, 0x2f, 0x82, 0xb7, + 0x27, 0xe3, 0x37, 0x1b, 0x55, 0x5d, 0x66, 0x33, 0x42, 0xf3, 0x2a, 0xa3, 0x81, 0x6a, 0xaa, 0x29, + 0x13, 0x2b, 0x16, 0xa7, 0x48, 0xb2, 0x3a, 0x19, 0xdd, 0x54, 0x0d, 0x93, 0x46, 0x9c, 0x50, 0x70, + 0x92, 0x8f, 0x4d, 0x27, 0xac, 0x0f, 0x8a, 0xc7, 0x14, 0x0c, 0x65, 0xa4, 0x40, 0x55, 0x36, 0x55, + 0x14, 0x81, 0x13, 0x67, 0x26, 0x31, 0x1c, 0x45, 0x2c, 0x6b, 0xe1, 0x96, 0x4d, 0x3c, 0x91, 0x8d, + 0x21, 0xfd, 0x22, 0x2f, 0xd9, 0x55, 0x18, 0x46, 0x05, 0x29, 0x2a, 0x24, 0x6e, 0x3c, 0x7e, 0x29, + 0xc4, 0x32, 0x84, 0x24, 0x81, 0x9b, 0x25, 0x29, 0x70, 0x12, 0x46, 0x6d, 0x53, 0x2b, 0x57, 0xe4, + 0x8d, 0x27, 0x46, 0x7f, 0x1a, 0x19, 0x0d, 0x71, 0x6e, 0xd2, 0xc0, 0x86, 0xb0, 0xb8, 0x84, 0xdc, + 0xc8, 0x41, 0x36, 0x6e, 0x86, 0x6a, 0x36, 0x1b, 0x68, 0x53, 0x87, 0x1b, 0xeb, 0x55, 0x7d, 0x53, + 0x3c, 0x95, 0xb0, 0x34, 0x46, 0xb0, 0x36, 0xd5, 0xaa, 0xa2, 0xd7, 0x54, 0xf1, 0xf4, 0xca, 0xcf, + 0x85, 0xd8, 0x77, 0xe3, 0xe1, 0x9b, 0xef, 0x44, 0xab, 0xa5, 0x99, 0x9c, 0xa2, 0x97, 0x46, 0x8f, + 0x9b, 0xe2, 0x3d, 0x57, 0x14, 0x7e, 0x90, 0x53, 0x66, 0x80, 0xed, 0xa7, 0x98, 0xf7, 0xc0, 0xad, + 0x14, 0xd8, 0x30, 0xe3, 0x4c, 0xa7, 0x3a, 0x48, 0x40, 0xff, 0x26, 0x0f, 0x0a, 0x49, 0xc7, 0xac, + 0x49, 0x84, 0x98, 0xa5, 0x8f, 0x0c, 0x3b, 0xde, 0xc3, 0x84, 0xb0, 0x03, 0xc5, 0x87, 0x3e, 0xa6, + 0xf4, 0x8c, 0x6c, 0x4d, 0x48, 0x26, 0xc0, 0xa2, 0xac, 0x90, 0x99, 0x42, 0x64, 0x13, 0x52, 0x95, + 0xd7, 0xd4, 0x2a, 0x6a, 0x68, 0xca, 0x06, 0x5d, 0xf0, 0x25, 0xf0, 0xc1, 0xf3, 0x52, 0x18, 0x93, + 0x63, 0x4a, 0xaa, 0x80, 0xd2, 0xf3, 0x52, 0xe9, 0xef, 0x45, 0x60, 0xb3, 0xaa, 0x86, 0xf2, 0x4c, + 0xaf, 0xfc, 0x64, 0x06, 0x2c, 0xc4, 0x9f, 0x13, 0x27, 0xcc, 0xe6, 0xba, 0xa6, 0x56, 0x47, 0xb3, + 0xcd, 0xf7, 0xc0, 0x93, 0x44, 0xc8, 0x31, 0xb5, 0x92, 0x20, 0x61, 0x90, 0x24, 0x7b, 0x0b, 0x35, + 0x61, 0x55, 0x14, 0x12, 0x96, 0x50, 0x02, 0xf6, 0x1a, 0x94, 0xeb, 0x4a, 0x45, 0xcc, 0x27, 0x2c, + 0xd8, 0x04, 0xac, 0xfe, 0xd2, 0x9b, 0x92, 0xde, 0x06, 0x6f, 0x66, 0xc7, 0x53, 0xeb, 0xcf, 0x34, + 0xa8, 0xd7, 0x69, 0x72, 0x30, 0x9d, 0x10, 0x64, 0x13, 0x87, 0xb9, 0x2e, 0xce, 0x24, 0xf8, 0xf7, + 0x44, 0x6e, 0xa6, 0x0a, 0x1b, 0x50, 0x33, 0x54, 0x64, 0x54, 0x9b, 0x65, 0xf1, 0x44, 0x82, 0xb5, + 0x64, 0x40, 0x37, 0x65, 0x53, 0x53, 0xd0, 0xd3, 0xcd, 0x0d, 0x43, 0x3c, 0x29, 0x3d, 0x01, 0x8f, + 0x33, 0x50, 0x19, 0xb5, 0x59, 0x92, 0x1e, 0x3f, 0x37, 0x66, 0x19, 0xea, 0xcd, 0x86, 0x21, 0xce, + 0x25, 0x38, 0xfc, 0x09, 0x98, 0x64, 0x03, 0x45, 0x1c, 0x6a, 0xfc, 0x12, 0x9b, 0x80, 0x38, 0x64, + 0xd8, 0x86, 0x78, 0x6a, 0xe5, 0x87, 0x71, 0x1f, 0x36, 0x09, 0xdf, 0xbd, 0x27, 0x64, 0x62, 0xd4, + 0xe5, 0xc4, 0xfc, 0x9f, 0x81, 0x78, 0xf7, 0x32, 0x80, 0x36, 0x55, 0x08, 0xe5, 0x75, 0x1d, 0xd6, + 0x12, 0xed, 0x78, 0x00, 0x3b, 0x92, 0xba, 0x6c, 0xc9, 0xb5, 0xaa, 0x98, 0x5f, 0x79, 0x1f, 0x9c, + 0xe4, 0xb5, 0x56, 0x64, 0xe3, 0xba, 0xae, 0xca, 0x26, 0x89, 0x2f, 0x63, 0x9b, 0xfe, 0xb0, 0x63, + 0x74, 0x1b, 0x2c, 0xac, 0xfc, 0x8e, 0x00, 0x96, 0x26, 0xbc, 0x84, 0x26, 0xb1, 0x26, 0x44, 0x86, + 0xaa, 0xa2, 0xd7, 0x6a, 0x6a, 0xbd, 0xc4, 0x24, 0x8c, 0x3d, 0x60, 0x58, 0x01, 0x77, 0x26, 0x83, + 0xd7, 0x75, 0x93, 0xc1, 0x0a, 0x24, 0x69, 0x9f, 0x0c, 0x5b, 0xd2, 0xeb, 0xaa, 0x98, 0x5f, 0xfb, + 0xea, 0x9f, 0xff, 0xf4, 0xaa, 0xf0, 0x93, 0x9f, 0x5e, 0x15, 0xfe, 0xee, 0xa7, 0x57, 0x85, 0x8f, + 0xf4, 0x5d, 0x27, 0xd8, 0xeb, 0x6d, 0xaf, 0xb6, 0xdc, 0x83, 0x07, 0xbb, 0x9e, 0x75, 0xe8, 0xb0, + 0x5a, 0x5c, 0xab, 0xfd, 0x60, 0xf0, 0xaf, 0xcf, 0xba, 0xce, 0x83, 0x5d, 0xdc, 0x79, 0x40, 0x5f, + 0xad, 0x3f, 0xd8, 0x75, 0x47, 0xfe, 0x9f, 0xda, 0xbb, 0x91, 0x9f, 0x87, 0x0f, 0xb7, 0x4f, 0x50, + 0xb0, 0x37, 0xfe, 0x23, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xc7, 0x14, 0xee, 0x7f, 0x6d, 0x00, 0x00, } func (m *UIBannerClickEvent) Marshal() (dAtA []byte, err error) { diff --git a/api/proto/teleport/usageevents/v1/usageevents.proto b/api/proto/teleport/usageevents/v1/usageevents.proto index b868e152cfd..592b37578e1 100644 --- a/api/proto/teleport/usageevents/v1/usageevents.proto +++ b/api/proto/teleport/usageevents/v1/usageevents.proto @@ -666,6 +666,7 @@ enum IntegrationEnrollStep { INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB = 9; INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS = 10; INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW = 11; + INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME = 12; } // IntegrationEnrollStatusCode defines status code for an integration enroll step. diff --git a/gen/proto/go/prehog/v1alpha/teleport.pb.go b/gen/proto/go/prehog/v1alpha/teleport.pb.go index ede8792ca71..6d55bb61354 100644 --- a/gen/proto/go/prehog/v1alpha/teleport.pb.go +++ b/gen/proto/go/prehog/v1alpha/teleport.pb.go @@ -732,6 +732,7 @@ const ( IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB IntegrationEnrollStep = 9 IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS IntegrationEnrollStep = 10 IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW IntegrationEnrollStep = 11 + IntegrationEnrollStep_INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME IntegrationEnrollStep = 12 ) // Enum value maps for IntegrationEnrollStep. @@ -749,6 +750,7 @@ var ( 9: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB", 10: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS", 11: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW", + 12: "INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME", } IntegrationEnrollStep_value = map[string]int32{ "INTEGRATION_ENROLL_STEP_UNSPECIFIED": 0, @@ -763,6 +765,7 @@ var ( "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB": 9, "INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS": 10, "INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW": 11, + "INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME": 12, } ) @@ -11354,7 +11357,7 @@ const file_prehog_v1alpha_teleport_proto_rawDesc = "" + "+INTEGRATION_ENROLL_KIND_AWS_IDENTITY_CENTER\x10\x1a\x12.\n" + "*INTEGRATION_ENROLL_KIND_GITHUB_REPO_ACCESS\x10\x1b\x12-\n" + ")INTEGRATION_ENROLL_KIND_MACHINE_ID_ARGOCD\x10\x1c\x12@\n" + - "\n" + @@ -11368,7 +11371,8 @@ const file_prehog_v1alpha_teleport_proto_rawDesc = "" + "0INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB\x10\t\x126\n" + "2INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS\x10\n" + "\x124\n" + - "0INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW\x10\v*\xfb\x01\n" + + "0INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW\x10\v\x12-\n" + + ")INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME\x10\f*\xfb\x01\n" + "\x1bIntegrationEnrollStatusCode\x12.\n" + "*INTEGRATION_ENROLL_STATUS_CODE_UNSPECIFIED\x10\x00\x12*\n" + "&INTEGRATION_ENROLL_STATUS_CODE_SUCCESS\x10\x01\x12*\n" + diff --git a/gen/proto/ts/prehog/v1alpha/teleport_pb.ts b/gen/proto/ts/prehog/v1alpha/teleport_pb.ts index 0c6a01d453d..9568a6e952a 100644 --- a/gen/proto/ts/prehog/v1alpha/teleport_pb.ts +++ b/gen/proto/ts/prehog/v1alpha/teleport_pb.ts @@ -4344,7 +4344,11 @@ export enum IntegrationEnrollStep { /** * @generated from protobuf enum value: INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW = 11; */ - MWIGHAK8S_SETUP_WORKFLOW = 11 + MWIGHAK8S_SETUP_WORKFLOW = 11, + /** + * @generated from protobuf enum value: INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME = 12; + */ + MWIGHAK8S_WELCOME = 12 } /** * IntegrationEnrollStatusCode defines status code for an integration enroll step. diff --git a/proto/prehog/v1alpha/teleport.proto b/proto/prehog/v1alpha/teleport.proto index a6b97246846..3155da7c58b 100644 --- a/proto/prehog/v1alpha/teleport.proto +++ b/proto/prehog/v1alpha/teleport.proto @@ -1202,6 +1202,7 @@ enum IntegrationEnrollStep { INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB = 9; INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS = 10; INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW = 11; + INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME = 12; } // IntegrationEnrollStatusCode defines status code for an integration enroll step. diff --git a/web/packages/shared/components/TextEditor/TextEditor.jsx b/web/packages/shared/components/TextEditor/TextEditor.jsx index c561c5d31ae..f5afd04096d 100644 --- a/web/packages/shared/components/TextEditor/TextEditor.jsx +++ b/web/packages/shared/components/TextEditor/TextEditor.jsx @@ -127,6 +127,16 @@ class TextEditor extends Component { this.session = null; } + handleCopy() { + copyToClipboard(this.editor.session.getValue()); + this.props.onCopy?.(); + } + + handleDownload() { + downloadObject(this.props.downloadFileName, this.editor.session.getValue()); + this.props.onDownload?.(); + } + render() { const { bg = 'levels.sunken' } = this.props; const hasButton = this.props.copyButton || this.props.downloadButton; @@ -139,7 +149,7 @@ class TextEditor extends Component { {this.props.copyButton && ( copyToClipboard(this.editor.session.getValue())} + onClick={() => this.handleCopy()} > @@ -147,12 +157,7 @@ class TextEditor extends Component { {this.props.downloadButton && ( - downloadObject( - this.props.downloadFileName, - this.editor.session.getValue() - ) - } + onClick={() => this.handleDownload()} > diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/CodePanel.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/CodePanel.tsx index 5671e54a09e..8eb030f59b4 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/CodePanel.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/CodePanel.tsx @@ -21,13 +21,22 @@ import { useState } from 'react'; import { Tabs } from 'shared/components/Editor/Tabs'; import TextEditor from 'shared/components/TextEditor/TextEditor'; +import { + IntegrationEnrollCodeType, + IntegrationEnrollStep, +} from 'teleport/services/userEvent'; + +import { useTracking } from '../Shared/useTracking'; import { useGitHubK8sFlow } from './useGitHubK8sFlow'; -export function CodePanel() { +export function CodePanel(props: { trackingStep: IntegrationEnrollStep }) { + const { trackingStep } = props; const [activeCodeTab, setActiveCodeTab] = useState(0); const { template } = useGitHubK8sFlow(); + const tracking = useTracking(); + return ( <> { + tracking.codeCopy(trackingStep, trackingTypes[activeCodeTab]); + }} + onDownload={() => { + tracking.codeCopy(trackingStep, trackingTypes[activeCodeTab]); + }} /> ); } const files = ['main.tf', 'gha-workflow.yaml']; +const trackingTypes = [ + IntegrationEnrollCodeType.Terraform, + IntegrationEnrollCodeType.GitHubActionsYAML, +]; function makeTerraformContent( template: ReturnType['template'] diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.story.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.story.tsx index df90ca45d33..b3cb2866ca7 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.story.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.story.tsx @@ -30,7 +30,9 @@ import { genWizardCiCdSuccess, } from 'teleport/test/helpers/bots'; import { fetchUnifiedResourcesSuccess } from 'teleport/test/helpers/resources'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; +import { TrackingProvider } from '../Shared/useTracking'; import { ConfigureAccess } from './ConfigureAccess'; import { GitHubK8sFlowProvider } from './useGitHubK8sFlow'; @@ -49,7 +51,11 @@ export default meta; export const Happy: Story = { parameters: { msw: { - handlers: [genWizardCiCdSuccess(), fetchUnifiedResourcesSuccess()], + handlers: [ + genWizardCiCdSuccess(), + fetchUnifiedResourcesSuccess(), + userEventCaptureSuccess(), + ], }, }, }; @@ -60,6 +66,7 @@ export const TemplateFetchFailed: Story = { handlers: [ genWizardCiCdError(500, 'something went wrong'), fetchUnifiedResourcesSuccess(), + userEventCaptureSuccess(), ], }, }, @@ -68,7 +75,11 @@ export const TemplateFetchFailed: Story = { export const TemplateFetching: Story = { parameters: { msw: { - handlers: [genWizardCiCdForever(), fetchUnifiedResourcesSuccess()], + handlers: [ + genWizardCiCdForever(), + fetchUnifiedResourcesSuccess(), + userEventCaptureSuccess(), + ], }, }, }; @@ -87,11 +98,13 @@ function Wrapper() { return ( - - - - - + + + + + + + ); diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.test.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.test.tsx index ea42c6b7168..6f11dc2ff45 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.test.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.test.tsx @@ -24,6 +24,7 @@ import selectEvent from 'react-select-event'; import darkTheme from 'design/theme/themes/darkTheme'; import { ConfiguredThemeProvider } from 'design/ThemeProvider'; import { + act, render, screen, testQueryClient, @@ -35,7 +36,10 @@ import { ContextProvider } from 'teleport/index'; import { createTeleportContext } from 'teleport/mocks/contexts'; import { genWizardCiCdSuccess } from 'teleport/test/helpers/bots'; import { fetchUnifiedResourcesSuccess } from 'teleport/test/helpers/resources'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; +import { trackingTester } from '../Shared/trackingTester'; +import { TrackingProvider } from '../Shared/useTracking'; import { ConfigureAccess } from './ConfigureAccess'; import { GitHubK8sFlowProvider, useGitHubK8sFlow } from './useGitHubK8sFlow'; @@ -47,9 +51,17 @@ beforeAll(() => { // Basic mock for all tests server.use(genWizardCiCdSuccess()); server.use(fetchUnifiedResourcesSuccess()); + server.use(userEventCaptureSuccess()); + + jest.useFakeTimers(); }); -afterAll(() => server.close()); +afterAll(() => { + server.close(); + + jest.useRealTimers(); + jest.resetAllMocks(); +}); describe('ConfigureAccess', () => { test('renders', async () => { @@ -109,6 +121,8 @@ describe('ConfigureAccess', () => { }); test('input groups', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Kubernetes Groups'); @@ -117,9 +131,22 @@ describe('ConfigureAccess', () => { expect(screen.getByText('system:masters')).toBeInTheDocument(); expect(screen.getByText('viewers')).toBeInTheDocument(); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_KUBERNETES_GROUPS' + ); }); test('input labels', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Labels'); @@ -132,9 +159,24 @@ describe('ConfigureAccess', () => { expect(modal).not.toBeInTheDocument(); expect(screen.getByText('foo: bar')).toBeInTheDocument(); + + // Skip start event + tracking.skip(); + // Skip section event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_KUBERNETES_LABELS' + ); }); test('input users', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Kubernetes Users'); @@ -143,13 +185,27 @@ describe('ConfigureAccess', () => { expect(screen.getByText('user1@example.com')).toBeInTheDocument(); expect(screen.getByText('user2@example.com')).toBeInTheDocument(); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_KUBERNETES_USERS' + ); }); }); function renderComponent(opts?: { initialState?: ReturnType['state']; + disableTracking?: boolean; }) { - const user = userEvent.setup(); + const user = userEvent.setup({ + advanceTimers: t => jest.advanceTimersByTime(t), + }); const onNextStep = jest.fn(); const onPrevStep = jest.fn(); return { @@ -164,8 +220,9 @@ function renderComponent(opts?: { function makeWrapper(opts?: { initialState?: ReturnType['state']; + disableTracking?: boolean; }) { - const { initialState } = opts ?? {}; + const { initialState, disableTracking = false } = opts ?? {}; const ctx = createTeleportContext(); return ({ children }: PropsWithChildren) => { @@ -173,9 +230,11 @@ function makeWrapper(opts?: { - - {children} - + + + {children} + + diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.tsx index 2129143dc88..84e2be6650c 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConfigureAccess.tsx @@ -27,8 +27,15 @@ import { FieldSelectCreatable } from 'shared/components/FieldSelect/FieldSelectC import Validator, { Validation } from 'shared/components/Validation/Validation'; import { SectionBox } from 'teleport/Roles/RoleEditor/StandardEditor/sections'; +import { + IntegrationEnrollField, + IntegrationEnrollSection, + IntegrationEnrollStatusCode, + IntegrationEnrollStep, +} from 'teleport/services/userEvent'; import { FlowStepProps } from '../Shared/GuidedFlow'; +import { useTracking } from '../Shared/useTracking'; import { CodePanel } from './CodePanel'; import { KubernetesLabelsSelect } from './KubernetesLabelsSelect'; import { useGitHubK8sFlow } from './useGitHubK8sFlow'; @@ -37,12 +44,22 @@ export function ConfigureAccess(props: FlowStepProps) { const { nextStep, prevStep } = props; const { dispatch, state } = useGitHubK8sFlow(); + const tracking = useTracking(); const handleNext = (validator: Validator) => { if (!validator.validate()) { + tracking.error( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + 'validation error' + ); return; } + tracking.step( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + IntegrationEnrollStatusCode.Success + ); + nextStep?.(); }; @@ -68,19 +85,29 @@ export function ConfigureAccess(props: FlowStepProps) { + onChange={labels => { dispatch({ type: 'kubernetes-labels-changed', value: labels, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + IntegrationEnrollField.MWIGHAK8SKubernetesLabels + ); + }} /> Your workflow will have access to Kubernetes clusters which satisfy the labels you specify. Visit the{' '} { + tracking.link( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + K8S_RBAC_LINK + ); + }} > Teleport Kubernetes Access Controls {' '} @@ -101,6 +128,10 @@ export function ConfigureAccess(props: FlowStepProps) { type: 'kubernetes-groups-changed', value: e.map(g => g.value), }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + IntegrationEnrollField.MWIGHAK8SKubernetesGroups + ); }} createOptionPosition="last" /> @@ -109,7 +140,13 @@ export function ConfigureAccess(props: FlowStepProps) { ClusterRoleBinding resources. See the{' '} { + tracking.link( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + K8S_RBAC_LINK + ); + }} > Teleport Kubernetes Access Controls {' '} @@ -124,6 +161,12 @@ export function ConfigureAccess(props: FlowStepProps) { validation={{ valid: true, }} + onExpand={() => { + tracking.section( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + IntegrationEnrollSection.MWIGHAK8SKubernetesAdvancedOptions + ); + }} > g.value), }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + IntegrationEnrollField.MWIGHAK8SKubernetesUsers + ); }} createOptionPosition="last" /> @@ -167,7 +214,9 @@ export function ConfigureAccess(props: FlowStepProps) { - + ); @@ -191,3 +240,6 @@ const CodeContainer = styled(Flex)` flex-direction: column; overflow: auto; `; + +const K8S_RBAC_LINK = + 'https://goteleport.com/docs/enroll-resources/kubernetes-access/controls/'; diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.story.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.story.tsx index f5de87ff1a5..ad1f828a17c 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.story.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.story.tsx @@ -29,7 +29,9 @@ import { genWizardCiCdForever, genWizardCiCdSuccess, } from 'teleport/test/helpers/bots'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; +import { TrackingProvider } from '../Shared/useTracking'; import { ConnectGitHub } from './ConnectGitHub'; import { GitHubK8sFlowProvider } from './useGitHubK8sFlow'; @@ -48,7 +50,7 @@ export default meta; export const Happy: Story = { parameters: { msw: { - handlers: [genWizardCiCdSuccess()], + handlers: [genWizardCiCdSuccess(), userEventCaptureSuccess()], }, }, }; @@ -56,7 +58,10 @@ export const Happy: Story = { export const TemplateFetchFailed: Story = { parameters: { msw: { - handlers: [genWizardCiCdError(500, 'something went wrong')], + handlers: [ + genWizardCiCdError(500, 'something went wrong'), + userEventCaptureSuccess(), + ], }, }, }; @@ -64,7 +69,7 @@ export const TemplateFetchFailed: Story = { export const TemplateFetching: Story = { parameters: { msw: { - handlers: [genWizardCiCdForever()], + handlers: [genWizardCiCdForever(), userEventCaptureSuccess()], }, }, }; @@ -83,11 +88,13 @@ function Wrapper() { return ( - - - - - + + + + + + + ); diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.test.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.test.tsx index 662c868d04c..d34c325a00b 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.test.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.test.tsx @@ -24,6 +24,7 @@ import selectEvent from 'react-select-event'; import darkTheme from 'design/theme/themes/darkTheme'; import { ConfiguredThemeProvider } from 'design/ThemeProvider'; import { + act, render, screen, testQueryClient, @@ -34,7 +35,10 @@ import cfg from 'teleport/config'; import { ContextProvider } from 'teleport/index'; import { createTeleportContext } from 'teleport/mocks/contexts'; import { genWizardCiCdSuccess } from 'teleport/test/helpers/bots'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; +import { trackingTester } from '../Shared/trackingTester'; +import { TrackingProvider } from '../Shared/useTracking'; import { ConnectGitHub } from './ConnectGitHub'; import { GitHubK8sFlowProvider } from './useGitHubK8sFlow'; @@ -45,9 +49,17 @@ beforeAll(() => { // Basic mock for all tests server.use(genWizardCiCdSuccess()); + server.use(userEventCaptureSuccess()); + + jest.useFakeTimers(); }); -afterAll(() => server.close()); +afterAll(() => { + server.close(); + + jest.useRealTimers(); + jest.resetAllMocks(); +}); describe('ConnectGitHub', () => { test('renders', async () => { @@ -125,15 +137,30 @@ describe('ConnectGitHub', () => { }); test('input github url', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Repository URL'); await user.type(input, 'https://github.com/foo/bar'); expect(input).toHaveValue('https://github.com/foo/bar'); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_REPOSITORY_URL' + ); }); test('input branch', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Branch'); @@ -141,10 +168,21 @@ describe('ConnectGitHub', () => { expect(input).toHaveValue('main'); expect(screen.getByLabelText('Git Ref')).toHaveValue('main'); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_BRANCH' + ); }); test('toggle allow any branch', async () => { - const { user } = renderComponent(); + const { user } = renderComponent({ disableTracking: true }); const input = screen.getByLabelText('Branch'); await user.type(input, 'main'); @@ -156,24 +194,52 @@ describe('ConnectGitHub', () => { }); test('input workflow', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Workflow'); await user.type(input, 'my-workflow'); expect(input).toHaveValue('my-workflow'); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_WORKFLOW' + ); }); test('input environment', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Environment'); await user.type(input, 'production'); expect(input).toHaveValue('production'); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_ENVIRONMENT' + ); }); test('input ref and type', async () => { + const tracking = trackingTester(); + const { user } = renderComponent(); const input = screen.getByLabelText('Git Ref'); @@ -182,11 +248,30 @@ describe('ConnectGitHub', () => { expect(input).toHaveValue('release-*'); expect(screen.getByLabelText('Branch')).toHaveValue('release-*'); + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_REF' + ); + const select = screen.getByLabelText('Ref Type'); await selectEvent.select(select, ['Tag']); expect(input).toHaveValue('release-*'); expect(screen.getByLabelText('Branch')).toHaveValue(''); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_REF' + ); }); test('input slug disabled', async () => { @@ -197,6 +282,8 @@ describe('ConnectGitHub', () => { }); test('input slug', async () => { + const tracking = trackingTester(); + const { user } = renderComponent({ isEnterprise: true, }); @@ -205,6 +292,17 @@ describe('ConnectGitHub', () => { await user.type(input, 'octo-enterprise'); expect(input).toHaveValue('octo-enterprise'); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_ENTERPRISE_SLUG' + ); }); test('input jwks disabled', async () => { @@ -215,6 +313,8 @@ describe('ConnectGitHub', () => { }); test('input jwks', async () => { + const tracking = trackingTester(); + const { user } = renderComponent({ isEnterprise: true, initialState: { @@ -231,14 +331,28 @@ describe('ConnectGitHub', () => { await user.type(input, '{{"keys":[[]}'); // Note escaping of "{" and "[" expect(input).toHaveValue('{"keys":[]}'); + + // Skip start event + tracking.skip(); + + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_ENTERPRISE_STATIC_JWKS' + ); }); }); function renderComponent(opts?: { initialState?: ComponentProps['intitialState']; isEnterprise?: boolean; + disableTracking?: boolean; }) { - const user = userEvent.setup(); + const user = userEvent.setup({ + advanceTimers: t => jest.advanceTimersByTime(t), + }); const onNextStep = jest.fn(); const onPrevStep = jest.fn(); return { @@ -254,8 +368,9 @@ function renderComponent(opts?: { function makeWrapper(opts?: { initialState?: ComponentProps['intitialState']; isEnterprise?: boolean; + disableTracking?: boolean; }) { - const { initialState, isEnterprise = false } = opts ?? {}; + const { initialState, isEnterprise = false, disableTracking } = opts ?? {}; cfg.isEnterprise = isEnterprise; cfg.edition = isEnterprise ? 'ent' : 'oss'; @@ -267,9 +382,11 @@ function makeWrapper(opts?: { - - {children} - + + + {children} + + diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.tsx index a90c4d8b45a..142e75d2397 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/ConnectGitHub.tsx @@ -30,6 +30,12 @@ import { requiredField } from 'shared/components/Validation/rules'; import cfg from 'teleport/config'; import { SectionBox } from 'teleport/Roles/RoleEditor/StandardEditor/sections'; +import { + IntegrationEnrollField, + IntegrationEnrollSection, + IntegrationEnrollStatusCode, + IntegrationEnrollStep, +} from 'teleport/services/userEvent'; import { GITHUB_HOST, @@ -38,6 +44,7 @@ import { requireValidRepository, } from '../Shared/github'; import { FlowStepProps } from '../Shared/GuidedFlow'; +import { useTracking } from '../Shared/useTracking'; import { CodePanel } from './CodePanel'; import { useGitHubK8sFlow } from './useGitHubK8sFlow'; @@ -46,11 +53,23 @@ export function ConnectGitHub(props: FlowStepProps) { const { dispatch, state } = useGitHubK8sFlow(); + const tracking = useTracking(); + const handleNext = (validator: Validator) => { if (!validator.validate()) { + tracking.error( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + 'validation error' + ); + return; } + tracking.step( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollStatusCode.Success + ); + nextStep?.(); }; @@ -80,12 +99,17 @@ export function ConnectGitHub(props: FlowStepProps) { label="Repository URL" placeholder="https://github.com/gravitational/teleport" value={state.gitHubUrl} - onChange={e => + onChange={e => { dispatch({ type: 'github-url-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubRepositoryURL, + !e.target.value.length + ); + }} /> + onChange={e => { dispatch({ type: 'branch-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubBranch, + !e.target.value.length + ); + }} /> { + tracking.section( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollSection.MWIGHAK8SGitHubAdvancedOptions + ); + }} > + onChange={e => { dispatch({ type: 'workflow-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubWorkflow, + !e.target.value.length + ); + }} /> + onChange={e => { dispatch({ type: 'environment-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubEnvironment, + !e.target.value.length + ); + }} /> @@ -167,12 +212,17 @@ export function ConnectGitHub(props: FlowStepProps) { label={'Git Ref'} placeholder="ref/heads/main" value={state.ref} - onChange={e => + onChange={e => { dispatch({ type: 'ref-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubRef, + !e.target.value.length + ); + }} borderTopRightRadius={0} borderBottomRightRadius={0} /> @@ -181,12 +231,16 @@ export function ConnectGitHub(props: FlowStepProps) { label="Ref Type" isMulti={false} value={refTypeValue} - onChange={o => + onChange={o => { dispatch({ type: 'ref-type-changed', value: o?.value ?? '', - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubRef + ); + }} options={refTypeOptions} menuPlacement="auto" /> @@ -221,12 +275,17 @@ export function ConnectGitHub(props: FlowStepProps) { disabled={cfg.edition !== 'ent' || hasGHEHost} placeholder="octo-enterprise" value={state.enterpriseSlug} - onChange={e => + onChange={e => { dispatch({ type: 'slug-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubEnterpriseSlug, + !e.target.value.length + ); + }} toolTipContent="Allows the slug of a GitHub Enterprise (GHE) organisation to be included in the expected issuer of the OIDC tokens. This is for compatibility with the include_enterprise_slug option in GHE." helperText={ hasGHEHost @@ -240,12 +299,17 @@ export function ConnectGitHub(props: FlowStepProps) { disabled={cfg.edition !== 'ent' || !hasGHEHost} placeholder='{"keys":[ --snip-- ]}' value={state.enterpriseJwks} - onChange={e => + onChange={e => { dispatch({ type: 'jwks-changed', value: e.target.value, - }) - } + }); + tracking.field( + IntegrationEnrollStep.MWIGHAK8SConnectGitHub, + IntegrationEnrollField.MWIGHAK8SGitHubEnterpriseStaticJWKS, + !e.target.value.length + ); + }} toolTipContent="When using GitHub Enterprise Server (GHES), allows the JSON Web Key Set (JWKS) used to verify the token issued by GitHub Actions to be overridden. This can be used in scenarios where the Teleport Auth Service is unable to reach a GHE server." helperText={ hasGHEHost @@ -267,7 +331,9 @@ export function ConnectGitHub(props: FlowStepProps) { - + ); diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Finish.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Finish.tsx index 20a0ffc46e9..08bef18c113 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Finish.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Finish.tsx @@ -35,8 +35,13 @@ import Link from 'design/Link/Link'; import { H2, P2 } from 'design/Text/Text'; import cfg from 'teleport/config'; +import { + IntegrationEnrollStatusCode, + IntegrationEnrollStep, +} from 'teleport/services/userEvent'; import { FlowStepProps } from '../Shared/GuidedFlow'; +import { useTracking } from '../Shared/useTracking'; import { CodePanel } from './CodePanel'; export function Finish(props: FlowStepProps) { @@ -45,8 +50,14 @@ export function Finish(props: FlowStepProps) { const [showDoneCheck, setShowDoneCheck] = useState(false); const history = useHistory(); + const tracking = useTracking(); const handleDone = () => { + tracking.step( + IntegrationEnrollStep.MWIGHAK8SSetupWorkflow, + IntegrationEnrollStatusCode.Success + ); + history.replace(cfg.getBotsRoute()); }; @@ -69,7 +80,13 @@ export function Finish(props: FlowStepProps) { See the{' '} { + tracking.link( + IntegrationEnrollStep.MWIGHAK8SSetupWorkflow, + IAC_LINK + ); + }} > Infrastructure as Code {' '} @@ -80,7 +97,13 @@ export function Finish(props: FlowStepProps) { See the{' '} { + tracking.link( + IntegrationEnrollStep.MWIGHAK8SSetupWorkflow, + TBOT_GHA_LINK + ); + }} > Deploying tbot on GitHub Actions {' '} @@ -96,7 +119,9 @@ export function Finish(props: FlowStepProps) { - + setShowDoneCheck(false)}> @@ -140,3 +165,8 @@ const CodeContainer = styled(Flex)` flex-direction: column; overflow: auto; `; + +const IAC_LINK = + 'https://goteleport.com/docs/zero-trust-access/infrastructure-as-code/'; +const TBOT_GHA_LINK = + '"https://goteleport.com/docs/machine-workload-identity/deployment/github-actions/"'; diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.test.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.test.tsx index a87c15d6fac..6f37c811709 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.test.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.test.tsx @@ -25,6 +25,7 @@ import { Router } from 'react-router'; import darkTheme from 'design/theme/themes/darkTheme'; import { ConfiguredThemeProvider } from 'design/ThemeProvider'; import { + act, render, screen, testQueryClient, @@ -38,36 +39,65 @@ import { ContextProvider } from 'teleport/index'; import { ContentMinWidth } from 'teleport/Main/Main'; import { createTeleportContext } from 'teleport/mocks/contexts'; import { genWizardCiCdSuccess } from 'teleport/test/helpers/bots'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; -import { GitHubActionsK8s } from './GitHubActionsK8s'; +import { trackingTester } from '../Shared/trackingTester'; +import { TrackingProvider } from '../Shared/useTracking'; +import { GitHubActionsK8sWithoutTracking } from './GitHubActionsK8s'; const server = setupServer(); beforeAll(() => { server.listen(); + + server.use(genWizardCiCdSuccess()); + server.use(userEventCaptureSuccess()); + + jest.useFakeTimers(); }); -afterAll(() => server.close()); +afterAll(() => { + server.close(); + + jest.useRealTimers(); + jest.resetAllMocks(); +}); describe('GitHubActionsK8s', () => { test('complete flow: minimal', async () => { - server.use(genWizardCiCdSuccess()); + const tracking = trackingTester(); - const { user, history } = renderComponent(); + const { user, history, unmount } = renderComponent({ + trackingEventId: 'test-tracking-event-id', + }); const replaceMock = jest.spyOn(history, 'replace'); + tracking.assertStart('test-tracking-event-id'); + expect( screen.getByRole('heading', { name: 'GitHub Actions + Kubernetes' }) ).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'Start' })); + tracking.assertStep( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME', + 'INTEGRATION_ENROLL_STATUS_CODE_SUCCESS' + ); + expect( screen.getByRole('heading', { name: 'Connect to GitHub' }) ).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'Next' })); + tracking.assertError( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'validation error' + ); + expect(screen.getByText('Repository is required')).toBeInTheDocument(); expect(screen.getByText('A branch is required')).toBeInTheDocument(); @@ -76,16 +106,43 @@ describe('GitHubActionsK8s', () => { 'https://github.com/gravitational/teleport' ); + // Field tracking is debounced, so move time along to send the event + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_REPOSITORY_URL' + ); + await user.type(screen.getByLabelText('Branch'), 'main'); + await act(() => jest.advanceTimersByTimeAsync(1000)); + tracking.assertField( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_FIELD_MWIGHAK8S_GITHUB_BRANCH' + ); + await user.click(screen.getByRole('button', { name: 'Next' })); + tracking.assertStep( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', + 'INTEGRATION_ENROLL_STATUS_CODE_SUCCESS' + ); + expect( screen.getByRole('heading', { name: 'Configure Access' }) ).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: 'Next' })); + tracking.assertStep( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', + 'INTEGRATION_ENROLL_STATUS_CODE_SUCCESS' + ); + expect( screen.getByRole('heading', { name: 'Setup Workflow' }) ).toBeInTheDocument(); @@ -94,18 +151,31 @@ describe('GitHubActionsK8s', () => { await user.click(screen.getByRole('button', { name: 'Confirm' })); + tracking.assertStep( + 'test-tracking-event-id', + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW', + 'INTEGRATION_ENROLL_STATUS_CODE_SUCCESS' + ); + expect(replaceMock).toHaveBeenLastCalledWith('/web/bots'); + + unmount(); + + tracking.assertComplete('test-tracking-event-id'); }); }); -function renderComponent() { - const user = userEvent.setup(); +function renderComponent(opts?: { trackingEventId?: string }) { + const { trackingEventId } = opts ?? {}; + const user = userEvent.setup({ + advanceTimers: t => jest.advanceTimersByTime(t), + }); const history = createMemoryHistory({ initialEntries: [cfg.getBotsNewRoute(BotFlowType.GitHubActionsSsh)], }); return { - ...render(, { - wrapper: makeWrapper({ history }), + ...render(, { + wrapper: makeWrapper({ history, trackingEventId }), }), user, history, @@ -114,8 +184,9 @@ function renderComponent() { function makeWrapper(opts: { history: ReturnType; + trackingEventId?: string; }) { - const { history } = opts; + const { history, trackingEventId } = opts; const ctx = createTeleportContext(); return ({ children }: PropsWithChildren) => { @@ -125,7 +196,9 @@ function makeWrapper(opts: { - {children} + + {children} + diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.tsx index 3ecd9ea207f..e699f2e0904 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/GitHubActionsK8s.tsx @@ -21,6 +21,7 @@ import { ResourceIcon } from 'design/ResourceIcon'; import { useNoMinWidth } from 'teleport/Main'; import { GuidedFlow, View } from '../Shared/GuidedFlow'; +import { TrackingProvider } from '../Shared/useTracking'; import { ConfigureAccess } from './ConfigureAccess'; import { ConnectGitHub } from './ConnectGitHub'; import { Finish } from './Finish'; @@ -49,6 +50,16 @@ const views: View[] = [ export function GitHubActionsK8s() { useNoMinWidth(); + return ( + + + + ); +} + +export function GitHubActionsK8sWithoutTracking() { + useNoMinWidth(); + return ( - - {({ validator }) => ( - - handleLabelsChanged(labels, validator)} - /> - - )} - + + + {({ validator }) => ( + + handleLabelsChanged(labels, validator)} + /> + + )} + + ); diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.test.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.test.tsx index 1616b9003f3..a061777fae2 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.test.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.test.tsx @@ -36,7 +36,10 @@ import { createTeleportContext } from 'teleport/mocks/contexts'; import { ResourcesResponse, UnifiedResource } from 'teleport/services/agents'; import { defaultAccess, makeAcl } from 'teleport/services/user/makeAcl'; import { fetchUnifiedResourcesSuccess } from 'teleport/test/helpers/resources'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; +import { trackingTester } from '../Shared/trackingTester'; +import { TrackingProvider } from '../Shared/useTracking'; import { KubernetesLabelsSelect } from './KubernetesLabelsSelect'; const server = setupServer(); @@ -45,14 +48,23 @@ beforeAll(() => { server.listen(); }); +beforeEach(() => { + server.use(userEventCaptureSuccess()); +}); + afterEach(async () => { server.resetHandlers(); + await testQueryClient.resetQueries(); jest.clearAllMocks(); }); -afterAll(() => server.close()); +afterAll(() => { + server.close(); + + jest.resetAllMocks(); +}); describe('KubernetesLabelsSelect', () => { test('renders', async () => { @@ -82,6 +94,8 @@ describe('KubernetesLabelsSelect', () => { }); test('edit action', async () => { + const tracking = trackingTester(); + withListUnifiedResourcesSuccess(); const { user } = renderComponent(); @@ -94,6 +108,12 @@ describe('KubernetesLabelsSelect', () => { expect( within(modal).getByText('Select one or more labels to configure access.') ).toBeInTheDocument(); + + tracking.assertSection( + expect.any(String), + 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', + 'INTEGRATION_ENROLL_SECTION_MWIGHAK8S_KUBERNETES_LABEL_PICKER' + ); }); test('cluster list empty', async () => { @@ -351,8 +371,10 @@ describe('KubernetesLabelsSelect', () => { function renderComponent(opts?: { props?: Partial>; + customAcl?: ReturnType; + disableTracking?: boolean; }) { - const { props } = opts ?? {}; + const { props, customAcl, disableTracking } = opts ?? {}; const { selected = [], onChange = () => {} } = props ?? {}; const user = userEvent.setup(); @@ -361,14 +383,20 @@ function renderComponent(opts?: { ...render( , { - wrapper: makeWrapper(), + wrapper: makeWrapper({ + customAcl, + disableTracking, + }), } ), user, }; } -function makeWrapper(opts?: { customAcl?: ReturnType }) { +function makeWrapper(opts?: { + customAcl?: ReturnType; + disableTracking?: boolean; +}) { const { customAcl = makeAcl({ kubeServers: { @@ -377,6 +405,7 @@ function makeWrapper(opts?: { customAcl?: ReturnType }) { list: true, }, }), + disableTracking, } = opts ?? {}; const ctx = createTeleportContext({ @@ -388,7 +417,9 @@ function makeWrapper(opts?: { customAcl?: ReturnType }) { - {children} + + {children} + diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.tsx index e705738fec6..c4e6863bd87 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/KubernetesLabelsSelect.tsx @@ -17,7 +17,7 @@ */ import { keepPreviousData, useInfiniteQuery } from '@tanstack/react-query'; -import { ReactNode, useMemo, useState } from 'react'; +import { ReactNode, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { Alert } from 'design/Alert/Alert'; @@ -49,12 +49,17 @@ import { Rule } from 'shared/components/Validation/rules'; import cfg from 'teleport/config'; import { ResourceLabel } from 'teleport/services/agents'; import { Kube } from 'teleport/services/kube'; +import { + IntegrationEnrollSection, + IntegrationEnrollStep, +} from 'teleport/services/userEvent'; import useTeleport from 'teleport/useTeleport'; import { KubernetesLabel, makeKubernetesAccessChecker, } from '../Shared/kubernetes'; +import { useTracking } from '../Shared/useTracking'; export function KubernetesLabelsSelect( props: { @@ -154,6 +159,16 @@ function Picker(props: { const flags = ctx.getFeatureFlags(); const hasListPermission = flags.kubernetes; + const tracking = useTracking(); + + // This effect sends a tracking event when the component mounts + useEffect(() => { + tracking.section( + IntegrationEnrollStep.MWIGHAK8SConfigureAccess, + IntegrationEnrollSection.MWIGHAK8SKubernetesLabelPicker + ); + }, [tracking]); + const { data, isLoading, diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Welcome.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Welcome.tsx index b21f85281e4..80026540257 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Welcome.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/Welcome.tsx @@ -26,7 +26,13 @@ import Link from 'design/Link/Link'; import { H2, P2 } from 'design/Text/Text'; import { Theme } from 'design/theme/themes/types'; +import { + IntegrationEnrollStatusCode, + IntegrationEnrollStep, +} from 'teleport/services/userEvent'; + import { FlowStepProps } from '../Shared/GuidedFlow'; +import { useTracking } from '../Shared/useTracking'; import welcomeDark from './gha-k8s-welcome-dark.svg'; import welcomeLight from './gha-k8s-welcome-light.svg'; @@ -34,12 +40,22 @@ export function Welcome(props: FlowStepProps) { const { nextStep } = props; const theme = useTheme(); + const tracking = useTracking(); const welcomeImage: ImageSpec = { light: welcomeLight, dark: welcomeDark, }; + const handleNext = () => { + tracking.step( + IntegrationEnrollStep.MWIGHAK8SWelcome, + IntegrationEnrollStatusCode.Success + ); + + nextStep?.(); + }; + return ( @@ -62,7 +78,10 @@ export function Welcome(props: FlowStepProps) { See the{' '} { + tracking.link(IntegrationEnrollStep.MWIGHAK8SWelcome, IAC_LINK); + }} > Infrastructure as Code {' '} @@ -70,7 +89,7 @@ export function Welcome(props: FlowStepProps) { - Start + Start @@ -89,3 +108,6 @@ const Container = styled(Flex)` type ImageSpec = { [K in Theme['type']]: string; }; + +const IAC_LINK = + 'https://goteleport.com/docs/zero-trust-access/infrastructure-as-code/'; diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.test.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.test.tsx index 20ffb44bdc5..3288713f88f 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.test.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.test.tsx @@ -27,7 +27,9 @@ import { testQueryClient } from 'design/utils/testing'; import { ContextProvider } from 'teleport/index'; import { createTeleportContext } from 'teleport/mocks/contexts'; import { genWizardCiCdSuccess } from 'teleport/test/helpers/bots'; +import { userEventCaptureSuccess } from 'teleport/test/helpers/userEvents'; +import { TrackingProvider } from '../Shared/useTracking'; import { GitHubK8sFlowProvider, useGitHubK8sFlow } from './useGitHubK8sFlow'; const server = setupServer(); @@ -37,7 +39,9 @@ beforeAll(() => { }); beforeEach(() => { - // The API call is debounced, so we'll need to time travel a little. + server.use(userEventCaptureSuccess()); + + // The templates API call is debounced, so we'll need to time travel a little. jest.useFakeTimers(); }); @@ -486,7 +490,9 @@ function Wrapper(props: PropsWithChildren) { return ( - {props.children} + + {props.children} + ); diff --git a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.tsx b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.tsx index c873da76301..900f68ccd1c 100644 --- a/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.tsx +++ b/web/packages/teleport/src/Bots/Add/GitHubActionsK8s/useGitHubK8sFlow.tsx @@ -31,6 +31,7 @@ import useTeleport from 'teleport/useTeleport'; import { GITHUB_HOST, parseRepoAddress } from '../Shared/github'; import { KubernetesLabel } from '../Shared/kubernetes'; +import { useTracking } from '../Shared/useTracking'; import { makeGhaWorkflow } from './templates'; export function useGitHubK8sFlow() { @@ -52,6 +53,16 @@ export function GitHubK8sFlowProvider( const ctx = useTeleport(); const cluster = ctx.storeUser.state.cluster; + const tracking = useTracking(); + + // This effect sends a user event when the flow starts and ends + useEffect(() => { + tracking.start(); + return () => { + tracking.complete(); + }; + }, [tracking]); + const { mutate, data, isPending, error } = useMutation({ mutationFn: (vars: Parameters[0]) => generateGhaK8sTemplates(vars), diff --git a/web/packages/teleport/src/Bots/Add/Shared/trackingTester.ts b/web/packages/teleport/src/Bots/Add/Shared/trackingTester.ts new file mode 100644 index 00000000000..7026e76a9a6 --- /dev/null +++ b/web/packages/teleport/src/Bots/Add/Shared/trackingTester.ts @@ -0,0 +1,119 @@ +/** + * Teleport + * Copyright (C) 2025 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { userEventService } from 'teleport/services/userEvent'; + +beforeAll(() => { + jest.spyOn(userEventService, 'captureIntegrationEnrollEvent'); +}); + +afterEach(() => { + jest.mocked(userEventService.captureIntegrationEnrollEvent).mockClear(); +}); + +export function trackingTester() { + let nextIndex = 0; + + const assertTracking = (data: unknown) => { + const { calls } = jest.mocked( + userEventService.captureIntegrationEnrollEvent + ).mock; + + const call = calls[nextIndex]; + if (!call) { + throw new Error('expected a tracking call but received none'); + } + + expect(call[0]).toStrictEqual(data); + + nextIndex += 1; + }; + + return { + skip: (count: number = 1) => { + nextIndex += count; + }, + assertStart(eventId: string) { + assertTracking({ + event: 'tp.ui.integrationEnroll.start', + eventData: { + id: eventId, + kind: 'INTEGRATION_ENROLL_KIND_MACHINE_ID_GITHUB_ACTIONS_KUBERNETES', + }, + }); + }, + assertComplete(eventId: string) { + assertTracking({ + event: 'tp.ui.integrationEnroll.complete', + eventData: { + id: eventId, + kind: 'INTEGRATION_ENROLL_KIND_MACHINE_ID_GITHUB_ACTIONS_KUBERNETES', + }, + }); + }, + assertStep(eventId: string, step: string, status: string) { + assertTracking({ + event: 'tp.ui.integrationEnroll.step', + eventData: { + id: eventId, + kind: 'INTEGRATION_ENROLL_KIND_MACHINE_ID_GITHUB_ACTIONS_KUBERNETES', + step, + status: { + code: status, + }, + }, + }); + }, + assertError(eventId: string, step: string, error: string) { + assertTracking({ + event: 'tp.ui.integrationEnroll.step', + eventData: { + id: eventId, + kind: 'INTEGRATION_ENROLL_KIND_MACHINE_ID_GITHUB_ACTIONS_KUBERNETES', + step, + status: { + code: 'INTEGRATION_ENROLL_STATUS_CODE_ERROR', + error, + }, + }, + }); + }, + assertField(eventId: string, step: string, field: string) { + assertTracking({ + event: 'tp.ui.integrationEnroll.fieldComplete', + eventData: { + id: eventId, + kind: 'INTEGRATION_ENROLL_KIND_MACHINE_ID_GITHUB_ACTIONS_KUBERNETES', + step, + field, + }, + }); + }, + assertSection(eventId: string, step: string, section: string) { + assertTracking({ + event: 'tp.ui.integrationEnroll.sectionOpen', + eventData: { + id: eventId, + kind: 'INTEGRATION_ENROLL_KIND_MACHINE_ID_GITHUB_ACTIONS_KUBERNETES', + step, + section, + }, + }); + }, + }; +} diff --git a/web/packages/teleport/src/Bots/Add/Shared/useTracking.tsx b/web/packages/teleport/src/Bots/Add/Shared/useTracking.tsx new file mode 100644 index 00000000000..7033102535a --- /dev/null +++ b/web/packages/teleport/src/Bots/Add/Shared/useTracking.tsx @@ -0,0 +1,212 @@ +/** + * Teleport + * Copyright (C) 2025 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { + createContext, + PropsWithChildren, + useContext, + useMemo, + useRef, +} from 'react'; + +import { debounce } from 'shared/utils/highbar'; + +import { + IntegrationEnrollCodeType, + IntegrationEnrollEvent, + IntegrationEnrollEventData, + IntegrationEnrollField, + IntegrationEnrollKind, + IntegrationEnrollSection, + IntegrationEnrollStatusCode, + IntegrationEnrollStep, +} from 'teleport/services/userEvent/types'; +import { userEventService } from 'teleport/services/userEvent/userEvent'; + +export function useTracking() { + const ctx = useContext(context); + if (!ctx) { + throw new Error( + 'Tracking not implemented, do you need to add a TrackingProvider?' + ); + } + return ctx; +} + +export function TrackingProvider( + props: { initialEventId?: string; disabled?: boolean } & PropsWithChildren +) { + const { initialEventId = crypto.randomUUID(), disabled = false } = props; + + // Changes to the eventId should not cause a re-render. + const eventId = useRef(initialEventId); + + const debouncedField = useRef( + debounce( + ( + eventId: string, + step: IntegrationEnrollStep, + field: IntegrationEnrollField + ) => { + return sendEvent(IntegrationEnrollEvent.FieldComplete, { + id: eventId, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + step, + field, + }); + }, + 1000 + ) + ); + + // Keep a stable value as this is likely to be used in effects + const value = useMemo( + () => ({ + reset(newId?: string) { + eventId.current = newId || crypto.randomUUID(); + }, + start() { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.Started, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + }); + }, + complete() { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.Complete, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + }); + }, + step( + step: IntegrationEnrollStep, + status: Exclude< + IntegrationEnrollStatusCode, + IntegrationEnrollStatusCode.Error + > + ) { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.Step, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + step, + status: { + code: status, + }, + }); + }, + error(step: IntegrationEnrollStep, error: string) { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.Step, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + step, + status: { + code: IntegrationEnrollStatusCode.Error, + error, + }, + }); + }, + field( + step: IntegrationEnrollStep, + field: IntegrationEnrollField, + isEmpty?: boolean + ) { + if (disabled || isEmpty) return; + return debouncedField.current(eventId.current, step, field); + }, + section(step: IntegrationEnrollStep, section: IntegrationEnrollSection) { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.SectionOpen, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + step, + section, + }); + }, + link(step: IntegrationEnrollStep, link: string) { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.LinkClick, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + step, + link, + }); + }, + codeCopy( + step: IntegrationEnrollStep, + codeType: IntegrationEnrollCodeType + ) { + if (disabled) return; + return sendEvent(IntegrationEnrollEvent.CodeCopy, { + id: eventId.current, + kind: IntegrationEnrollKind.MachineIDGitHubActionsKubernetes, + step, + codeType, + }); + }, + }), + [disabled] + ); + + return {props.children}; +} + +function sendEvent( + event: IntegrationEnrollEvent, + eventData: IntegrationEnrollEventData +) { + userEventService.captureIntegrationEnrollEvent({ + event, + eventData, + }); +} + +type Context = { + start: () => void; + complete: () => void; + step: ( + step: IntegrationEnrollStep, + statusCode: IntegrationEnrollStatusCode + ) => void; + error: (step: IntegrationEnrollStep, error: string) => void; + /** + * Track when a field's value changes. This call is debounced across all + * fields. + * @param step The step in the guide where the field appears + * @param field The field's identifier + * @param isEmpty If the field has no input + */ + field: ( + step: IntegrationEnrollStep, + field: IntegrationEnrollField, + isEmpty?: boolean + ) => void; + section: ( + step: IntegrationEnrollStep, + section: IntegrationEnrollSection + ) => void; + link: (step: IntegrationEnrollStep, link: string) => void; + codeCopy: ( + step: IntegrationEnrollStep, + codeType: IntegrationEnrollCodeType + ) => void; +}; + +const context = createContext(null); diff --git a/web/packages/teleport/src/Roles/RoleEditor/StandardEditor/sections.tsx b/web/packages/teleport/src/Roles/RoleEditor/StandardEditor/sections.tsx index ac3f7a65a1d..bb21c80339a 100644 --- a/web/packages/teleport/src/Roles/RoleEditor/StandardEditor/sections.tsx +++ b/web/packages/teleport/src/Roles/RoleEditor/StandardEditor/sections.tsx @@ -94,6 +94,7 @@ export const SectionBox = ({ removable, isProcessing = false, validation, + onExpand, onRemove, initiallyCollapsed = false, }: React.PropsWithChildren<{ @@ -102,6 +103,7 @@ export const SectionBox = ({ removable?: boolean; isProcessing?: boolean; validation?: ValidationResult; + onExpand?(): void; onRemove?(): void; initiallyCollapsed?: boolean; }>) => { @@ -140,6 +142,8 @@ export const SectionBox = ({ ? ExpansionState.Collapsing : ExpansionState.Measuring ); + + onExpand?.(); }; // Triggered when the collapse animation is finished and we can finally make diff --git a/web/packages/teleport/src/services/userEvent/types.ts b/web/packages/teleport/src/services/userEvent/types.ts index f68bc4028b3..149ebc0bf93 100644 --- a/web/packages/teleport/src/services/userEvent/types.ts +++ b/web/packages/teleport/src/services/userEvent/types.ts @@ -112,8 +112,9 @@ export enum IntegrationEnrollStep { /** * MWIGHAK8S denotes the MWI GitHub Actions + Kubernetes wizard. */ + MWIGHAK8SWelcome = 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_WELCOME', MWIGHAK8SConnectGitHub = 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONNECT_GITHUB', - MWIGHAK8SConnectConfigureAccess = 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', + MWIGHAK8SConfigureAccess = 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_CONFIGURE_ACCESS', MWIGHAK8SSetupWorkflow = 'INTEGRATION_ENROLL_STEP_MWIGHAK8S_SETUP_WORKFLOW', } diff --git a/web/packages/teleport/src/test/helpers/userEvents.ts b/web/packages/teleport/src/test/helpers/userEvents.ts new file mode 100644 index 00000000000..525a8c97c9b --- /dev/null +++ b/web/packages/teleport/src/test/helpers/userEvents.ts @@ -0,0 +1,49 @@ +/** + * Teleport + * Copyright (C) 2025 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { http, HttpResponse } from 'msw'; + +import cfg from 'teleport/config'; +import { JsonObject } from 'teleport/types'; + +export const userEventCaptureSuccess = () => { + return http.post(cfg.api.captureUserEventPath, async () => { + return HttpResponse.json(); + }); +}; + +export const userEventCaptureError = ( + status: number, + error: string | null = null, + extras: JsonObject = {} +) => + http.post(cfg.api.captureUserEventPath, () => { + return HttpResponse.json( + { error: { message: `${status} - ${error}` }, extras }, + { status } + ); + }); + +export const userEventCaptureForever = () => + http.post( + cfg.api.captureUserEventPath, + () => + new Promise(() => { + /* never resolved */ + }) + );