diff --git a/pkg/sql/alter_type.go b/pkg/sql/alter_type.go index 8b65303072cd..f497a35b2761 100644 --- a/pkg/sql/alter_type.go +++ b/pkg/sql/alter_type.go @@ -77,6 +77,12 @@ func (p *planner) AlterType(ctx context.Context, n *tree.AlterType) (planNode, e } case descpb.TypeDescriptor_ENUM: sqltelemetry.IncrementEnumCounter(sqltelemetry.EnumAlter) + case descpb.TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE: + return nil, pgerror.Newf( + pgcode.WrongObjectType, + "%q is a table's record type and cannot be modified", + tree.AsStringWithFQNames(n.Type, &p.semaCtx.Annotations), + ) } return &alterTypeNode{ diff --git a/pkg/sql/catalog/descpb/structured.pb.go b/pkg/sql/catalog/descpb/structured.pb.go index 8beda13adc97..801b08d74b96 100644 --- a/pkg/sql/catalog/descpb/structured.pb.go +++ b/pkg/sql/catalog/descpb/structured.pb.go @@ -719,18 +719,24 @@ const ( // Represents a special multi-region enum type which tracks available regions // as its enum values. TypeDescriptor_MULTIREGION_ENUM TypeDescriptor_Kind = 2 + // Represents the implicit record type created on behalf of each table. This + // kind of TypeDescriptor is *never* persisted to disk! If you are here, + // thinking about using or persisting this value, you should *not* do that! + TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE TypeDescriptor_Kind = 3 ) var TypeDescriptor_Kind_name = map[int32]string{ 0: "ENUM", 1: "ALIAS", 2: "MULTIREGION_ENUM", + 3: "TABLE_IMPLICIT_RECORD_TYPE", } var TypeDescriptor_Kind_value = map[string]int32{ - "ENUM": 0, - "ALIAS": 1, - "MULTIREGION_ENUM": 2, + "ENUM": 0, + "ALIAS": 1, + "MULTIREGION_ENUM": 2, + "TABLE_IMPLICIT_RECORD_TYPE": 3, } func (x TypeDescriptor_Kind) Enum() *TypeDescriptor_Kind { @@ -3885,358 +3891,360 @@ func init() { } var fileDescriptor_12dcc21c3bcc9571 = []byte{ - // 5612 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3c, 0x4d, 0x73, 0x23, 0xc7, - 0x75, 0xc4, 0x37, 0xf0, 0xf0, 0x35, 0xec, 0xe5, 0xee, 0x42, 0xf4, 0x8a, 0xe4, 0x62, 0xb5, 0x12, - 0xb5, 0x92, 0xb8, 0x2b, 0x4a, 0xb6, 0x57, 0x92, 0xed, 0x08, 0x20, 0xc0, 0x25, 0x76, 0x49, 0x80, - 0x1a, 0x82, 0xbb, 0x92, 0x9d, 0x78, 0x3c, 0xc4, 0x34, 0xc1, 0x11, 0x07, 0x33, 0xd8, 0x99, 0xc1, - 0x72, 0xe1, 0xca, 0x21, 0xe5, 0x53, 0x4e, 0x49, 0x0e, 0xb9, 0xa5, 0x5c, 0x71, 0xa5, 0x5c, 0x89, - 0x6f, 0x2e, 0x57, 0xaa, 0x92, 0xaa, 0x1c, 0x72, 0x8d, 0x8f, 0x4e, 0xa5, 0xca, 0xe5, 0x13, 0x2b, - 0xa1, 0x2f, 0xf9, 0x01, 0x39, 0xe9, 0x92, 0x54, 0x7f, 0xcd, 0x07, 0x3e, 0x28, 0x90, 0xdc, 0xf8, - 0x20, 0x15, 0xe7, 0xf5, 0x7b, 0xaf, 0xbb, 0x5f, 0xbf, 0xef, 0x6e, 0x2c, 0xdc, 0x71, 0x9e, 0x1b, - 0xf7, 0x3b, 0xaa, 0xab, 0x1a, 0x56, 0xf7, 0xbe, 0x86, 0x9d, 0x4e, 0xff, 0xe0, 0xbe, 0xe3, 0xda, - 0x83, 0x8e, 0x3b, 0xb0, 0xb1, 0xb6, 0xd6, 0xb7, 0x2d, 0xd7, 0x42, 0xd7, 0x3b, 0x56, 0xe7, 0xd8, - 0xb6, 0xd4, 0xce, 0xd1, 0x9a, 0xf3, 0xdc, 0x20, 0xff, 0x1d, 0xa8, 0x0e, 0x5e, 0x2c, 0x0d, 0x5c, - 0xdd, 0xb8, 0x7f, 0x64, 0x74, 0xee, 0xbb, 0x7a, 0x0f, 0x3b, 0xae, 0xda, 0xeb, 0x33, 0x82, 0xc5, - 0xf2, 0x04, 0xae, 0x7d, 0x5b, 0x7f, 0xa1, 0x1b, 0xb8, 0x8b, 0x39, 0xce, 0x75, 0x82, 0xe3, 0x0e, - 0xfb, 0xd8, 0x61, 0xff, 0xe7, 0xe0, 0xd7, 0xba, 0xd8, 0xba, 0xdf, 0xc5, 0x96, 0x6e, 0x6a, 0xf8, - 0xe5, 0xfd, 0x8e, 0x65, 0x1e, 0xea, 0x5d, 0x3e, 0xb4, 0xd0, 0xb5, 0xba, 0x16, 0xfd, 0xf3, 0x3e, - 0xf9, 0x8b, 0x41, 0xcb, 0x3f, 0x49, 0xc0, 0xb5, 0x4d, 0xcb, 0xc6, 0x7a, 0xd7, 0x7c, 0x82, 0x87, - 0x32, 0x3e, 0xc4, 0x36, 0x36, 0x3b, 0x18, 0xad, 0x40, 0xc2, 0x55, 0x0f, 0x0c, 0x5c, 0x8a, 0xac, - 0x44, 0x56, 0xf3, 0x55, 0xf8, 0xf5, 0xe9, 0xf2, 0xdc, 0x57, 0xa7, 0xcb, 0xd1, 0x46, 0x4d, 0x66, - 0x03, 0xe8, 0x2e, 0x24, 0xe8, 0x2c, 0xa5, 0x28, 0xc5, 0x28, 0x72, 0x8c, 0x54, 0x83, 0x00, 0x09, - 0x1a, 0x1d, 0x45, 0x25, 0x88, 0x9b, 0x6a, 0x0f, 0x97, 0x62, 0x2b, 0x91, 0xd5, 0x4c, 0x35, 0x4e, - 0xb0, 0x64, 0x0a, 0x41, 0x4f, 0x20, 0xfd, 0x42, 0x35, 0x74, 0x4d, 0x77, 0x87, 0xa5, 0xf8, 0x4a, - 0x64, 0xb5, 0xb0, 0xfe, 0xf6, 0xda, 0x44, 0x51, 0xad, 0x6d, 0x58, 0xa6, 0xe3, 0xda, 0xaa, 0x6e, - 0xba, 0x4f, 0x39, 0x01, 0x67, 0xe4, 0x31, 0x40, 0x0f, 0x60, 0xde, 0x39, 0x52, 0x6d, 0xac, 0x29, - 0x7d, 0x1b, 0x1f, 0xea, 0x2f, 0x15, 0x03, 0x9b, 0xa5, 0xc4, 0x4a, 0x64, 0x35, 0xc1, 0x51, 0x8b, - 0x6c, 0x78, 0x97, 0x8e, 0x6e, 0x63, 0x13, 0xb5, 0x21, 0x63, 0x99, 0x8a, 0x86, 0x0d, 0xec, 0xe2, - 0x52, 0x92, 0xce, 0xff, 0xfe, 0x94, 0xf9, 0x27, 0x08, 0x68, 0xad, 0xd2, 0x71, 0x75, 0xcb, 0x14, - 0xeb, 0xb0, 0xcc, 0x1a, 0x65, 0xc4, 0xb9, 0x0e, 0xfa, 0x9a, 0xea, 0xe2, 0x52, 0xea, 0xca, 0x5c, - 0xf7, 0x29, 0x23, 0xb4, 0x0d, 0x89, 0x9e, 0xea, 0x76, 0x8e, 0x4a, 0x69, 0xca, 0xf1, 0xc1, 0x05, - 0x38, 0xee, 0x10, 0x3a, 0xce, 0x90, 0x31, 0x29, 0x3f, 0x83, 0x24, 0x9b, 0x07, 0xe5, 0x21, 0xd3, - 0x6c, 0x29, 0x95, 0x8d, 0x76, 0xa3, 0xd5, 0x94, 0xe6, 0x50, 0x0e, 0xd2, 0x72, 0x7d, 0xaf, 0x2d, - 0x37, 0x36, 0xda, 0x52, 0x84, 0x7c, 0xed, 0xd5, 0xdb, 0x4a, 0x73, 0x7f, 0x7b, 0x5b, 0x8a, 0xa2, - 0x22, 0x64, 0xc9, 0x57, 0xad, 0xbe, 0x59, 0xd9, 0xdf, 0x6e, 0x4b, 0x31, 0x94, 0x85, 0xd4, 0x46, - 0x65, 0x6f, 0xa3, 0x52, 0xab, 0x4b, 0xf1, 0xc5, 0xf8, 0x2f, 0x7e, 0xbe, 0x34, 0x57, 0x7e, 0x00, - 0x09, 0x3a, 0x1d, 0x02, 0x48, 0xee, 0x35, 0x76, 0x76, 0xb7, 0xeb, 0xd2, 0x1c, 0x4a, 0x43, 0x7c, - 0x93, 0xb0, 0x88, 0x10, 0x8a, 0xdd, 0x8a, 0xdc, 0x6e, 0x54, 0xb6, 0xa5, 0x28, 0xa3, 0xf8, 0x38, - 0xfe, 0xdf, 0x3f, 0x5b, 0x8e, 0x94, 0xff, 0x3d, 0x01, 0x0b, 0xfe, 0xda, 0xfd, 0xd3, 0x46, 0x1b, - 0x50, 0xb4, 0x6c, 0xbd, 0xab, 0x9b, 0x0a, 0xd5, 0x39, 0x45, 0xd7, 0xb8, 0x3e, 0x7e, 0x83, 0xec, - 0xe7, 0xec, 0x74, 0x39, 0xdf, 0xa2, 0xc3, 0x6d, 0x32, 0xda, 0xa8, 0x71, 0x05, 0xcd, 0x5b, 0x01, - 0xa0, 0x86, 0x9e, 0xc0, 0x3c, 0x67, 0xd2, 0xb1, 0x8c, 0x41, 0xcf, 0x54, 0x74, 0xcd, 0x29, 0x45, - 0x57, 0x62, 0xab, 0xf9, 0xea, 0xf2, 0xd9, 0xe9, 0x72, 0x91, 0xb1, 0xd8, 0xa0, 0x63, 0x8d, 0x9a, - 0xf3, 0xd5, 0xe9, 0x72, 0x5a, 0x7c, 0xc8, 0x7c, 0x7a, 0xfe, 0xad, 0x39, 0xe8, 0x19, 0x5c, 0xb7, - 0x85, 0x6c, 0xb5, 0x20, 0xc3, 0x18, 0x65, 0x78, 0xe7, 0xec, 0x74, 0xf9, 0x9a, 0x27, 0x7c, 0x6d, - 0x32, 0xd3, 0x6b, 0xf6, 0x28, 0x82, 0xe6, 0xa0, 0x16, 0x04, 0xc0, 0xfe, 0x76, 0xe3, 0x74, 0xbb, - 0xcb, 0x7c, 0xbb, 0xf3, 0x3e, 0xeb, 0xf0, 0x96, 0xe7, 0xed, 0x91, 0x01, 0xcd, 0x33, 0xbc, 0xc4, - 0xb9, 0x86, 0x97, 0xbc, 0xaa, 0xe1, 0x85, 0xcc, 0x28, 0xf5, 0xff, 0x62, 0x46, 0xe9, 0x57, 0x6e, - 0x46, 0x99, 0x57, 0x60, 0x46, 0x4c, 0x77, 0x1f, 0xc7, 0xd3, 0x20, 0x65, 0x1f, 0xc7, 0xd3, 0x59, - 0x29, 0xf7, 0x38, 0x9e, 0xce, 0x49, 0xf9, 0xc7, 0xf1, 0x74, 0x5e, 0x2a, 0x94, 0xff, 0x26, 0x0a, - 0xb7, 0xf6, 0x4d, 0xfd, 0xf9, 0x00, 0x3f, 0xd3, 0xdd, 0x23, 0x6b, 0xe0, 0x52, 0xbf, 0x18, 0xd0, - 0xed, 0x07, 0x90, 0x1e, 0x51, 0xea, 0xeb, 0xfc, 0x94, 0x53, 0xe1, 0xb3, 0x4d, 0xb9, 0xfc, 0x44, - 0x1f, 0x02, 0x8c, 0x69, 0xf0, 0x6b, 0x67, 0xa7, 0xcb, 0x99, 0xc9, 0x6a, 0x96, 0xe9, 0x78, 0xca, - 0xf5, 0x07, 0x72, 0xc2, 0x65, 0xc8, 0xf4, 0x6d, 0xac, 0xe9, 0x1d, 0x72, 0x6a, 0x41, 0xbd, 0xf3, - 0xc1, 0xdc, 0xe2, 0xff, 0x3e, 0x05, 0x12, 0x5b, 0x68, 0x0d, 0x3b, 0x1d, 0x5b, 0xef, 0xbb, 0x96, - 0xed, 0xad, 0x32, 0x32, 0xb6, 0xca, 0x37, 0x21, 0xaa, 0x6b, 0x3c, 0xd0, 0xdc, 0xe0, 0x52, 0x8a, - 0x52, 0x01, 0xf9, 0xdb, 0x8d, 0xea, 0x1a, 0x5a, 0x83, 0x38, 0x89, 0x86, 0x74, 0x9f, 0xd9, 0xf5, - 0xc5, 0xd1, 0x9d, 0xe0, 0xde, 0x1a, 0x0b, 0x96, 0x6d, 0x99, 0xe2, 0xa1, 0x15, 0x48, 0x9b, 0x03, - 0xc3, 0xa0, 0x81, 0x8e, 0xec, 0x3e, 0x2d, 0xb6, 0x24, 0xa0, 0xe8, 0x36, 0xe4, 0x34, 0x7c, 0xa8, - 0x0e, 0x0c, 0x57, 0xc1, 0x2f, 0xfb, 0x36, 0xdb, 0x95, 0x9c, 0xe5, 0xb0, 0xfa, 0xcb, 0xbe, 0x8d, - 0xde, 0x80, 0x82, 0xa7, 0xab, 0x0c, 0x09, 0x51, 0xa4, 0x9c, 0xd0, 0x3b, 0x8a, 0x75, 0x0b, 0x92, - 0x47, 0xba, 0xa6, 0x61, 0x93, 0x9a, 0x9c, 0x98, 0x88, 0xc3, 0xd0, 0x2a, 0xe4, 0x74, 0x53, 0xed, - 0x74, 0xb0, 0xe3, 0xe8, 0x64, 0x31, 0xf3, 0x01, 0x9c, 0xd0, 0x08, 0x7a, 0x0e, 0x8b, 0x5d, 0x6c, - 0x62, 0x5b, 0x75, 0xb1, 0xa6, 0xa8, 0x8e, 0xa2, 0x6b, 0xd8, 0x74, 0x75, 0x77, 0xa8, 0xd0, 0x8d, - 0x5f, 0xa3, 0x47, 0xb8, 0x36, 0xe5, 0x08, 0x1f, 0x09, 0xc2, 0x8a, 0xd3, 0xe0, 0x64, 0xed, 0x61, - 0x1f, 0xf3, 0x79, 0x6e, 0x76, 0x27, 0x0f, 0xa3, 0x5d, 0xb8, 0x3b, 0x79, 0x4a, 0x07, 0x3f, 0x1f, - 0x10, 0xeb, 0x50, 0xac, 0x3e, 0xb1, 0xb7, 0xd2, 0x02, 0xdd, 0xf7, 0xed, 0x09, 0x7c, 0xf6, 0x38, - 0x66, 0x8b, 0x22, 0xa2, 0x75, 0x98, 0x1f, 0x38, 0xd8, 0xf1, 0x19, 0x10, 0x85, 0x06, 0xaa, 0xd0, - 0x49, 0xae, 0xf5, 0x45, 0x82, 0x20, 0xc8, 0x88, 0x0e, 0xaf, 0xc3, 0xbc, 0x75, 0x62, 0x8e, 0xd0, - 0xe4, 0xc2, 0x34, 0x04, 0x21, 0x48, 0x73, 0x1b, 0x72, 0x1d, 0xab, 0xd7, 0x1f, 0x88, 0x83, 0xc9, - 0xb2, 0xd3, 0xe3, 0x30, 0x7a, 0x2e, 0x4b, 0x90, 0x7a, 0xa1, 0xdb, 0xee, 0x40, 0x35, 0x4a, 0x52, - 0x40, 0xe8, 0x02, 0x88, 0x3e, 0x05, 0xa9, 0xdf, 0x55, 0x54, 0xd7, 0xb5, 0xf5, 0x03, 0xc2, 0xc7, - 0x1c, 0xf4, 0x4a, 0xf9, 0x90, 0x22, 0x16, 0x76, 0x1f, 0x55, 0xc4, 0x70, 0x73, 0xd0, 0x93, 0x0b, - 0xfd, 0x6e, 0xf0, 0x1b, 0x6d, 0xc2, 0xeb, 0xaa, 0xe1, 0x62, 0x5b, 0x44, 0x0b, 0x72, 0x50, 0x8a, - 0x6e, 0x2a, 0x7d, 0xdb, 0xea, 0xda, 0xd8, 0x71, 0x4a, 0x85, 0xc0, 0xbc, 0xaf, 0x51, 0x54, 0xa6, - 0xd4, 0x44, 0xf8, 0x0d, 0x73, 0x97, 0xa3, 0xa1, 0x1f, 0x00, 0x72, 0x86, 0x8e, 0x8b, 0x7b, 0x82, - 0xd1, 0xb1, 0x6e, 0x6a, 0xa5, 0x22, 0x3d, 0xf1, 0xb7, 0xa6, 0x9c, 0xf8, 0x1e, 0x25, 0x60, 0xec, - 0x9e, 0xe8, 0xa6, 0xc6, 0x67, 0x91, 0x9c, 0x11, 0xb8, 0xe7, 0xcc, 0xd2, 0x52, 0xe6, 0x71, 0x3c, - 0x9d, 0x91, 0xe0, 0x71, 0x3c, 0x9d, 0x92, 0xd2, 0xe5, 0xbf, 0x88, 0xc2, 0x0d, 0x86, 0xb6, 0xa9, - 0xf6, 0x74, 0x63, 0x78, 0x55, 0x73, 0x65, 0x5c, 0xb8, 0xb9, 0xd2, 0xe3, 0xa1, 0x5b, 0x21, 0x64, - 0x2c, 0x86, 0xd2, 0xe3, 0x21, 0xb0, 0x26, 0x01, 0x8d, 0xf8, 0xbc, 0xf8, 0x05, 0x7c, 0x5e, 0x0b, - 0xe6, 0x85, 0xe5, 0x7a, 0x1c, 0xa8, 0xf9, 0xe6, 0xab, 0x77, 0xf8, 0x9a, 0x8a, 0x35, 0x86, 0x20, - 0xc8, 0xc3, 0xa1, 0x5f, 0x0b, 0x0d, 0x72, 0x11, 0x95, 0xff, 0x39, 0x0a, 0x0b, 0x0d, 0xd3, 0xc5, - 0xb6, 0x81, 0xd5, 0x17, 0x38, 0x20, 0x8e, 0xcf, 0x21, 0xa3, 0x9a, 0x1d, 0xec, 0xb8, 0x96, 0xed, - 0x94, 0x22, 0x2b, 0xb1, 0xd5, 0xec, 0xfa, 0x87, 0x53, 0x4e, 0x65, 0x12, 0xfd, 0x5a, 0x85, 0x13, - 0x0b, 0x97, 0xe9, 0x31, 0x5b, 0xfc, 0xd7, 0x08, 0xa4, 0xc5, 0xe8, 0x25, 0xc2, 0xc6, 0x37, 0x21, - 0x4d, 0x53, 0x71, 0xc5, 0x3b, 0x93, 0x45, 0x41, 0xc1, 0x73, 0xf5, 0x60, 0xda, 0x9e, 0xa2, 0xb8, - 0x0d, 0x0d, 0x6d, 0x4c, 0xca, 0xa8, 0x63, 0x94, 0xfe, 0xa6, 0x90, 0xdf, 0x5e, 0x38, 0xa7, 0x1e, - 0x4b, 0xb2, 0x99, 0xcc, 0xb8, 0xe4, 0xfe, 0x29, 0x02, 0xf3, 0x84, 0x40, 0xc3, 0x5a, 0x40, 0x6c, - 0x77, 0x00, 0x74, 0x47, 0x71, 0x18, 0x9c, 0xee, 0x48, 0x98, 0x42, 0x46, 0x77, 0x38, 0xba, 0xa7, - 0x6a, 0xd1, 0x31, 0x55, 0xfb, 0x08, 0xf2, 0x94, 0x56, 0x39, 0x18, 0x74, 0x8e, 0xb1, 0xeb, 0xd0, - 0x15, 0x26, 0xaa, 0x0b, 0x7c, 0x85, 0x39, 0xca, 0xa1, 0xca, 0xc6, 0xe4, 0x9c, 0x13, 0xf8, 0x1a, - 0xd3, 0xbe, 0xf8, 0x98, 0xf6, 0xf1, 0x85, 0xff, 0x32, 0x0e, 0x37, 0x76, 0x55, 0xdb, 0xd5, 0x89, - 0xef, 0xd2, 0xcd, 0x6e, 0x60, 0xf5, 0x77, 0x21, 0x6b, 0x0e, 0x84, 0x41, 0x3a, 0xfc, 0x40, 0xd8, - 0xfa, 0xc0, 0x1c, 0x70, 0x03, 0x73, 0xd0, 0xb7, 0x60, 0x81, 0xa0, 0xe9, 0xbd, 0xbe, 0xa1, 0x77, - 0x74, 0xd7, 0xc3, 0x8f, 0x07, 0xf0, 0x91, 0x39, 0xe8, 0x35, 0x38, 0x82, 0xa0, 0xdb, 0x86, 0xb8, - 0xa1, 0x3b, 0x2e, 0x8d, 0xf5, 0xd9, 0xf5, 0xf5, 0x29, 0xea, 0x34, 0x79, 0x6d, 0x6b, 0xdb, 0xba, - 0xe3, 0x0a, 0x59, 0x11, 0x2e, 0xa8, 0x05, 0x09, 0x5b, 0x35, 0xbb, 0x98, 0xda, 0x59, 0x76, 0xfd, - 0x83, 0x8b, 0xb1, 0x93, 0x09, 0xa9, 0xc8, 0x80, 0x28, 0x9f, 0xc5, 0x9f, 0x46, 0x20, 0x4e, 0x66, - 0x39, 0xc7, 0x15, 0xdc, 0x80, 0xe4, 0x0b, 0xd5, 0x18, 0x60, 0x96, 0xaf, 0xe4, 0x64, 0xfe, 0x85, - 0xfe, 0x04, 0x8a, 0xce, 0xe0, 0xa0, 0x1f, 0x98, 0x8a, 0x07, 0xed, 0xf7, 0x2e, 0xb4, 0x2a, 0xaf, - 0xb8, 0x0b, 0xf3, 0x62, 0x07, 0xb7, 0xf8, 0x1c, 0x12, 0x74, 0xd5, 0xe7, 0xac, 0xef, 0x2e, 0x14, - 0x0e, 0x6d, 0xab, 0xa7, 0xe8, 0x66, 0xc7, 0x18, 0x38, 0xfa, 0x0b, 0x96, 0x3b, 0xe4, 0xe4, 0x3c, - 0x81, 0x36, 0x04, 0x90, 0xe8, 0x8a, 0x6b, 0x29, 0xf8, 0xa5, 0x40, 0x8a, 0x52, 0xa4, 0xac, 0x6b, - 0xd5, 0x05, 0x28, 0xa4, 0xea, 0xff, 0x92, 0x83, 0x22, 0x35, 0xa8, 0x99, 0xdc, 0xe5, 0xdd, 0x80, - 0xbb, 0xbc, 0x1e, 0x72, 0x97, 0x9e, 0x55, 0x12, 0x6f, 0x79, 0x0b, 0x92, 0x03, 0x9a, 0x50, 0xd2, - 0x25, 0x7a, 0x19, 0x04, 0x83, 0xa1, 0x87, 0x90, 0x7a, 0x81, 0x6d, 0x87, 0x84, 0x61, 0x44, 0x39, - 0x2d, 0xf1, 0x82, 0xfc, 0xc6, 0xc8, 0x42, 0x9e, 0x32, 0x2c, 0x59, 0xa0, 0xa3, 0x55, 0x90, 0x8e, - 0xf1, 0x50, 0x99, 0x60, 0x0b, 0x85, 0x63, 0x52, 0x8d, 0xf9, 0xce, 0x58, 0x83, 0xeb, 0x01, 0x4c, - 0x4d, 0xb7, 0x31, 0xcd, 0xb3, 0x9d, 0x52, 0x7a, 0x25, 0x76, 0x4e, 0x3e, 0x3d, 0xb2, 0x80, 0xb5, - 0x9a, 0x20, 0x94, 0xaf, 0x79, 0x13, 0x78, 0x30, 0x07, 0xbd, 0x0b, 0x88, 0x78, 0x3a, 0x1c, 0x5e, - 0x51, 0x82, 0xae, 0x48, 0xa2, 0x23, 0xc1, 0x35, 0x55, 0xa1, 0x10, 0x58, 0x13, 0x09, 0x12, 0x49, - 0x1a, 0x24, 0x6e, 0x11, 0xeb, 0x7f, 0x22, 0xd8, 0x8f, 0xc6, 0x89, 0x9c, 0x37, 0x31, 0x09, 0x15, - 0xfb, 0x6c, 0x5f, 0xce, 0xe0, 0x90, 0xf8, 0xb9, 0x00, 0xab, 0x14, 0x65, 0x55, 0x3e, 0x3b, 0x5d, - 0x46, 0x4f, 0xf0, 0x70, 0x8f, 0x8e, 0x4f, 0x66, 0x88, 0x8e, 0x47, 0xc6, 0x35, 0x07, 0x6d, 0x81, - 0x14, 0xda, 0x08, 0xe1, 0x58, 0xa0, 0x1c, 0x97, 0x48, 0xda, 0xb0, 0xe7, 0x6f, 0x65, 0x94, 0x5b, - 0x21, 0xb0, 0x4d, 0xc2, 0xa9, 0x0d, 0x0b, 0x24, 0x67, 0xb1, 0x1c, 0xdd, 0x0d, 0x71, 0xcb, 0xfb, - 0xeb, 0xdb, 0x10, 0xe3, 0x53, 0xd6, 0xd7, 0x19, 0x19, 0xd7, 0x1c, 0xb4, 0x07, 0xd9, 0x43, 0x56, - 0xea, 0x28, 0xc7, 0x78, 0x48, 0x8b, 0xa2, 0xec, 0xfa, 0xbd, 0xd9, 0x8b, 0xa2, 0x6a, 0x92, 0xa8, - 0x58, 0x29, 0x22, 0xc3, 0xa1, 0x37, 0x88, 0x9e, 0x41, 0x3e, 0x50, 0xc7, 0x1e, 0x0c, 0x69, 0x5a, - 0x77, 0x39, 0xb6, 0x39, 0x9f, 0x51, 0x75, 0x88, 0x3e, 0x03, 0xd0, 0xbd, 0xb8, 0x49, 0x33, 0xb9, - 0xec, 0xfa, 0x3b, 0x17, 0x08, 0xb0, 0xc2, 0x2d, 0xfb, 0x4c, 0xd0, 0x33, 0x28, 0xf8, 0x5f, 0x74, - 0xb1, 0xb9, 0x0b, 0x2f, 0x96, 0x71, 0xcd, 0x07, 0xf8, 0x54, 0x89, 0x10, 0x72, 0x21, 0xd7, 0x56, - 0xbc, 0xbc, 0x6b, 0x0b, 0x31, 0x42, 0x75, 0x5e, 0xe0, 0x48, 0x34, 0xeb, 0x7b, 0x67, 0x46, 0x83, - 0x0b, 0x24, 0xf9, 0xac, 0xee, 0xf9, 0x00, 0x50, 0xc7, 0xc6, 0x34, 0x9f, 0xc7, 0x2f, 0x59, 0xc8, - 0x31, 0x86, 0xa1, 0xa2, 0x63, 0x9e, 0x8f, 0xd7, 0xbd, 0x61, 0xb4, 0x05, 0x79, 0x6c, 0x76, 0x2c, - 0x4d, 0x37, 0xbb, 0x7e, 0xb1, 0xc1, 0x93, 0xa9, 0xaf, 0x4e, 0x97, 0xbf, 0x31, 0x32, 0x6b, 0x9d, - 0xe3, 0x92, 0xc9, 0xe5, 0x1c, 0x0e, 0x7c, 0xa1, 0x2d, 0x48, 0x89, 0x80, 0xbf, 0x40, 0x25, 0xb3, - 0x3a, 0x2d, 0x7d, 0x1d, 0x4d, 0x17, 0x44, 0x76, 0xce, 0xc9, 0x49, 0x01, 0xa7, 0xe9, 0x0e, 0x49, - 0x74, 0xb4, 0xd2, 0xf5, 0x60, 0x01, 0x27, 0xa0, 0x68, 0x03, 0xa0, 0x8b, 0x2d, 0x85, 0xb5, 0x42, - 0x4b, 0x37, 0xe8, 0x74, 0x4b, 0x81, 0xe9, 0xba, 0xd8, 0x5a, 0x13, 0x0d, 0x53, 0x52, 0xe3, 0x1e, - 0xea, 0x5d, 0x91, 0x7f, 0x74, 0xb1, 0xc5, 0x00, 0xe1, 0xc2, 0xf6, 0xe6, 0xc4, 0xc2, 0xb6, 0xbc, - 0x04, 0x19, 0xcf, 0x89, 0xa1, 0x14, 0xc4, 0x2a, 0x7b, 0x1b, 0xac, 0xfb, 0x55, 0xab, 0xef, 0x6d, - 0x48, 0x91, 0xf2, 0x6d, 0x88, 0xd3, 0xcd, 0x67, 0x21, 0xb5, 0xd9, 0x92, 0x9f, 0x55, 0xe4, 0x1a, - 0xeb, 0xb8, 0x35, 0x9a, 0x4f, 0xeb, 0x72, 0xbb, 0x5e, 0x93, 0x44, 0xf0, 0x38, 0x8d, 0x03, 0xf2, - 0x8b, 0xed, 0xb6, 0xc5, 0x9b, 0x17, 0x5d, 0x28, 0x76, 0x3c, 0x28, 0x3b, 0x80, 0xc8, 0x4a, 0x74, - 0xb5, 0xb0, 0xfe, 0xf0, 0x6b, 0x0b, 0x76, 0xc1, 0x23, 0x08, 0xf2, 0x55, 0xa2, 0xd0, 0x09, 0x41, - 0x03, 0xc9, 0x56, 0x74, 0x24, 0x50, 0xc9, 0x90, 0xe8, 0x1c, 0xe1, 0xce, 0x31, 0x0f, 0xd5, 0xdf, - 0x9a, 0x32, 0x31, 0xcd, 0x43, 0x03, 0xea, 0xb7, 0x41, 0x68, 0xfc, 0xa9, 0x45, 0x0e, 0x41, 0x59, - 0x21, 0x39, 0xec, 0x84, 0xe2, 0xe7, 0xda, 0xf5, 0xa4, 0x26, 0xa1, 0xb0, 0xeb, 0x80, 0x0f, 0x7a, - 0x08, 0x45, 0xd3, 0x72, 0x15, 0x52, 0xc4, 0x73, 0x6f, 0x49, 0x8b, 0xee, 0x7c, 0x55, 0xe2, 0xba, - 0xea, 0xfb, 0xc5, 0xbc, 0x69, 0xb9, 0xcd, 0x81, 0x61, 0x30, 0x00, 0xfa, 0xb3, 0x08, 0x2c, 0xb3, - 0x80, 0xaa, 0x9c, 0xb0, 0xb6, 0x8d, 0xc2, 0x72, 0x67, 0x5f, 0x46, 0xb4, 0xc9, 0x35, 0x3d, 0x7b, - 0x3a, 0xaf, 0xe7, 0xc3, 0x97, 0x7a, 0x6b, 0x70, 0x0e, 0x4e, 0xb9, 0x0d, 0x85, 0xf0, 0x31, 0xa1, - 0x0c, 0x24, 0x36, 0xb6, 0xea, 0x1b, 0x4f, 0xa4, 0x39, 0x54, 0x84, 0xec, 0x66, 0x4b, 0xae, 0x37, - 0x1e, 0x35, 0x95, 0x27, 0xf5, 0x2f, 0x58, 0x93, 0xb6, 0xd9, 0xf2, 0x9a, 0xb4, 0x25, 0x58, 0xd8, - 0x6f, 0x36, 0x3e, 0xdb, 0xaf, 0x2b, 0xcf, 0x1a, 0xed, 0xad, 0xd6, 0x7e, 0x5b, 0x69, 0x34, 0x6b, - 0xf5, 0xcf, 0xa5, 0x98, 0x57, 0xdf, 0x25, 0xa4, 0x64, 0xf9, 0x3f, 0x92, 0x50, 0xd8, 0xb5, 0xf5, - 0x9e, 0x6a, 0x0f, 0x49, 0x54, 0x3b, 0x51, 0xfb, 0xe8, 0x53, 0x58, 0xb0, 0x0c, 0x92, 0xe9, 0x53, - 0xa8, 0xe2, 0xd5, 0x0b, 0xf1, 0xc9, 0xbd, 0xfd, 0x79, 0xcb, 0xd0, 0x38, 0x87, 0x06, 0x2f, 0x17, - 0x3e, 0x85, 0x05, 0x13, 0x9f, 0x8c, 0x73, 0x88, 0x4c, 0xe1, 0x60, 0xe2, 0x93, 0x11, 0x0e, 0xef, - 0x42, 0x96, 0xac, 0x81, 0x52, 0x62, 0xd1, 0xdf, 0xca, 0x06, 0x89, 0xc0, 0x32, 0xb4, 0x06, 0x1b, - 0x26, 0xd8, 0x64, 0x3e, 0x81, 0x1d, 0x9b, 0x80, 0x6d, 0xe2, 0x13, 0x81, 0xfd, 0x11, 0xdc, 0x18, - 0x5f, 0xdd, 0x58, 0x7b, 0xf4, 0xda, 0xc8, 0xa2, 0x48, 0x86, 0x81, 0xbe, 0x84, 0x05, 0xc3, 0xea, - 0xa8, 0x86, 0xee, 0x0e, 0xb9, 0x17, 0x51, 0x9c, 0x13, 0xb5, 0x4f, 0x35, 0x2a, 0x3b, 0xd5, 0xf8, - 0xc2, 0xf2, 0x5d, 0xdb, 0xe6, 0x1c, 0x98, 0x3f, 0x21, 0x20, 0x19, 0x19, 0x63, 0xb0, 0xc5, 0x7f, - 0x8c, 0x01, 0x1a, 0x47, 0x45, 0xc7, 0x70, 0x8d, 0x48, 0x66, 0x64, 0x19, 0x54, 0xb4, 0xd9, 0xf5, - 0x6f, 0xce, 0x68, 0x85, 0x61, 0xbe, 0xc2, 0xcd, 0x5b, 0x86, 0x16, 0x1e, 0x20, 0x93, 0x11, 0x51, - 0x8d, 0x4e, 0x16, 0x7d, 0x05, 0x93, 0x99, 0xf8, 0x64, 0x64, 0x32, 0x1d, 0x5e, 0x27, 0x93, 0xd9, - 0xb8, 0xab, 0x5b, 0xa6, 0x6a, 0x28, 0x07, 0x43, 0xc5, 0xb6, 0x4e, 0x02, 0x05, 0x3b, 0x2b, 0x38, - 0x57, 0xcf, 0x4e, 0x97, 0x4b, 0x4d, 0x7c, 0x22, 0x73, 0xbc, 0xea, 0x50, 0xb6, 0x4e, 0x26, 0x56, - 0xed, 0x25, 0x73, 0x32, 0x96, 0x86, 0x64, 0x78, 0xeb, 0x9c, 0xa9, 0x42, 0x4d, 0xbe, 0x38, 0xeb, - 0x63, 0x4d, 0x66, 0x55, 0xf3, 0x5b, 0x7f, 0xa1, 0x9c, 0xff, 0x97, 0x11, 0xa0, 0x49, 0xd8, 0xc0, - 0x15, 0x6d, 0x7d, 0x7a, 0x76, 0x1f, 0x42, 0x9e, 0x4c, 0xeb, 0xef, 0x28, 0x32, 0xc5, 0x13, 0x11, - 0x75, 0xf6, 0x16, 0xfb, 0x21, 0xe4, 0xc9, 0x89, 0xfb, 0x54, 0xd1, 0x69, 0x54, 0x96, 0xe1, 0x5d, - 0x22, 0xa0, 0xb7, 0x20, 0xa7, 0x9b, 0x24, 0xad, 0xe7, 0xed, 0xae, 0x60, 0xbb, 0x37, 0xcb, 0x47, - 0xfc, 0x75, 0x97, 0x7f, 0x15, 0x85, 0x9b, 0x3b, 0xaa, 0x8b, 0x6d, 0x5d, 0x35, 0xf4, 0x1f, 0x63, - 0xed, 0xa9, 0x4e, 0x36, 0x7c, 0x68, 0x63, 0xe7, 0x08, 0x7d, 0x0e, 0xf3, 0x63, 0x06, 0xc3, 0x15, - 0xee, 0xcd, 0xd9, 0xb2, 0x0e, 0x51, 0x9a, 0x8d, 0xd8, 0x14, 0xda, 0x09, 0x1b, 0x2e, 0x2b, 0x6d, - 0x2f, 0xc6, 0x33, 0x68, 0xd9, 0x0f, 0x21, 0xa1, 0x3a, 0x8a, 0x75, 0xc8, 0x63, 0xd2, 0xeb, 0x01, - 0x46, 0x03, 0x57, 0x37, 0xd6, 0x8e, 0x8c, 0xce, 0x5a, 0x5b, 0x5c, 0xb0, 0x8a, 0x68, 0xa6, 0x3a, - 0xad, 0x43, 0xf4, 0x1e, 0x14, 0x9d, 0x23, 0x6b, 0x60, 0x68, 0xca, 0x81, 0xda, 0x39, 0x3e, 0xd4, - 0x0d, 0x23, 0xd4, 0x03, 0x2e, 0xb0, 0xc1, 0x2a, 0x1f, 0xe3, 0x32, 0xfb, 0xcb, 0x14, 0x20, 0x7f, - 0x3d, 0x3b, 0x03, 0x57, 0xa5, 0xf1, 0xbe, 0x02, 0x49, 0x1e, 0x68, 0x98, 0x8c, 0xde, 0x9a, 0x1a, - 0x93, 0xc3, 0x3d, 0xef, 0xad, 0x39, 0x99, 0x13, 0xa2, 0xef, 0x05, 0xef, 0x53, 0x67, 0x96, 0xc8, - 0xd6, 0x9c, 0xb8, 0x68, 0x7d, 0x02, 0x10, 0x08, 0x52, 0x69, 0xca, 0xe4, 0xed, 0x99, 0x53, 0x83, - 0xad, 0x39, 0x39, 0x40, 0x8e, 0x5a, 0x50, 0xe8, 0x87, 0x3c, 0x18, 0xaf, 0x0e, 0xee, 0xce, 0xe4, - 0xee, 0xb6, 0xe6, 0xe4, 0x11, 0x72, 0xf4, 0x03, 0x40, 0x9d, 0x31, 0xe3, 0x28, 0xc1, 0xd7, 0xac, - 0x72, 0x94, 0x60, 0x6b, 0x4e, 0x9e, 0xc0, 0x06, 0x7d, 0x09, 0x37, 0x7b, 0x93, 0xf5, 0x98, 0xd7, - 0x09, 0xd3, 0x1a, 0xe2, 0x53, 0xb4, 0x7f, 0x6b, 0x4e, 0x9e, 0xc6, 0x10, 0x3d, 0x81, 0x84, 0xe3, - 0x92, 0x34, 0x30, 0x46, 0x53, 0xf0, 0xfb, 0x53, 0x38, 0x8f, 0xeb, 0xc8, 0xda, 0x1e, 0x21, 0x13, - 0xc9, 0x0f, 0xe5, 0x81, 0x9e, 0x41, 0xc6, 0xab, 0xa2, 0xf9, 0xf5, 0xcb, 0x07, 0xb3, 0x33, 0xf4, - 0xd2, 0x4d, 0x91, 0x8c, 0x7a, 0xbc, 0x50, 0x05, 0xb2, 0x3d, 0x8e, 0xe6, 0xb7, 0x3d, 0x57, 0x78, - 0x6f, 0x01, 0x04, 0x07, 0xea, 0x3b, 0x03, 0x5f, 0x32, 0x08, 0xa2, 0x06, 0x4d, 0xad, 0x6d, 0xcb, - 0x30, 0x88, 0x6d, 0xd0, 0x94, 0xc7, 0x4b, 0xad, 0x05, 0xb4, 0xfc, 0x29, 0x24, 0xe8, 0x9e, 0x48, - 0x4a, 0xbb, 0xdf, 0x7c, 0xd2, 0x6c, 0x3d, 0x6b, 0xb2, 0x14, 0xa5, 0x56, 0xdf, 0xae, 0xb7, 0xeb, - 0x4a, 0xab, 0xb9, 0x4d, 0x52, 0x94, 0xd7, 0xe0, 0x3a, 0x07, 0x54, 0x9a, 0x35, 0xe5, 0x99, 0xdc, - 0x10, 0x43, 0xd1, 0xf2, 0x6a, 0x30, 0x67, 0x4e, 0x43, 0xbc, 0xd9, 0x6a, 0xd6, 0xa5, 0x39, 0x9a, - 0x3d, 0xd7, 0x6a, 0x52, 0x84, 0x66, 0xcf, 0x72, 0x6b, 0x57, 0x8a, 0x32, 0xeb, 0xab, 0xe6, 0x00, - 0x34, 0x4f, 0x0e, 0x8f, 0xe3, 0xe9, 0xa4, 0x94, 0x2a, 0xff, 0x43, 0x04, 0xd2, 0x24, 0x50, 0x37, - 0xcc, 0x43, 0x0b, 0x7d, 0x00, 0x99, 0xbe, 0x6a, 0x63, 0xd3, 0xf5, 0x3d, 0xad, 0x68, 0x40, 0xa7, - 0x77, 0xe9, 0x80, 0xd7, 0x1f, 0x4d, 0x33, 0xc4, 0x86, 0x86, 0x36, 0x41, 0xe2, 0x44, 0x4e, 0xe7, - 0x08, 0xf7, 0x54, 0x3f, 0xee, 0xdc, 0xf2, 0x5a, 0xfc, 0x74, 0x7c, 0x8f, 0x0e, 0x7b, 0x1c, 0x0a, - 0xfd, 0x20, 0xf4, 0x9c, 0x2e, 0x25, 0xf7, 0x1d, 0x7f, 0xfd, 0x36, 0x14, 0x47, 0x02, 0xe5, 0x39, - 0x5d, 0xa1, 0x15, 0xda, 0x15, 0x8a, 0xf9, 0x7e, 0xdf, 0xeb, 0x0a, 0x45, 0x79, 0x43, 0xe8, 0x03, - 0xbf, 0xe5, 0x43, 0x0e, 0x38, 0x5e, 0x7d, 0x8d, 0x87, 0x87, 0xf9, 0x73, 0xba, 0x3d, 0xbb, 0x30, - 0xdf, 0xb3, 0x34, 0xfd, 0x90, 0x14, 0x2d, 0x44, 0x3b, 0x5c, 0xbd, 0x87, 0x79, 0x4a, 0x3b, 0x93, - 0xef, 0x94, 0x82, 0xd4, 0x64, 0x10, 0x6d, 0x43, 0x41, 0x23, 0x5e, 0x83, 0xd4, 0x85, 0xac, 0x57, - 0x73, 0x9d, 0xfa, 0xf4, 0xe5, 0x29, 0x9a, 0x2c, 0x0e, 0x4b, 0x94, 0xce, 0x82, 0x98, 0xf5, 0x73, - 0x42, 0x27, 0x18, 0x9f, 0xf1, 0x04, 0x0f, 0x60, 0x71, 0x60, 0xe2, 0x97, 0x7d, 0xcb, 0xc1, 0x9a, - 0x32, 0x76, 0x96, 0xab, 0x94, 0xcb, 0x5d, 0xce, 0xe5, 0xe6, 0xbe, 0xc0, 0x9c, 0x78, 0xa8, 0x37, - 0x07, 0x13, 0x87, 0x35, 0xf4, 0x08, 0x52, 0xa2, 0x6d, 0x9b, 0xa6, 0xfb, 0x9b, 0xd5, 0xc7, 0x8b, - 0x9a, 0x95, 0x53, 0xa3, 0x4d, 0x28, 0x98, 0xf8, 0x65, 0xf0, 0x56, 0x22, 0x13, 0x32, 0xcf, 0x5c, - 0x13, 0xbf, 0x9c, 0x7c, 0x25, 0x91, 0x33, 0xfd, 0x11, 0x0d, 0xb5, 0x20, 0x7d, 0xa8, 0xf6, 0x74, - 0x43, 0xc7, 0x4e, 0xe9, 0x06, 0x5d, 0xd1, 0x7b, 0xe7, 0xae, 0x68, 0xf4, 0x02, 0x47, 0xd8, 0xb3, - 0x60, 0xe2, 0x2d, 0x8c, 0x02, 0x86, 0x64, 0x61, 0x37, 0xc7, 0x17, 0x26, 0x2e, 0x70, 0x42, 0x97, - 0x39, 0x74, 0x61, 0xfc, 0x4b, 0x43, 0x9f, 0x41, 0x3e, 0x9c, 0x37, 0xc0, 0x25, 0xf2, 0x86, 0x5c, - 0x3f, 0x98, 0x34, 0x6c, 0x42, 0x4a, 0x24, 0x0c, 0xd9, 0x4b, 0x24, 0x0c, 0x82, 0x18, 0x55, 0x49, - 0x36, 0xf6, 0xd2, 0xf5, 0xcb, 0x93, 0x9c, 0xdf, 0x2b, 0x3d, 0x3b, 0x5d, 0xce, 0x92, 0x1d, 0x4e, - 0xb8, 0x14, 0xc9, 0x9a, 0x1e, 0x5c, 0x43, 0x8f, 0x01, 0xbc, 0xd7, 0x58, 0x0e, 0xbd, 0x0b, 0x9c, - 0xde, 0x31, 0xda, 0x15, 0x88, 0xfe, 0x92, 0xe4, 0x00, 0x35, 0xda, 0x81, 0x8c, 0x70, 0xb9, 0xac, - 0x37, 0x38, 0x3d, 0x1a, 0x8e, 0x07, 0x00, 0xe1, 0xf6, 0x3d, 0x0e, 0xa4, 0x40, 0x37, 0xb0, 0xea, - 0x60, 0xde, 0x70, 0x7a, 0x38, 0x63, 0xb6, 0xce, 0x74, 0x7c, 0xe3, 0x48, 0x35, 0xbb, 0x78, 0x9b, - 0xd0, 0x57, 0xa3, 0xa5, 0x88, 0xcc, 0x58, 0xa1, 0x26, 0x48, 0x54, 0x64, 0xc1, 0x78, 0x22, 0x51, - 0xa9, 0xbd, 0x21, 0xbc, 0x23, 0x91, 0xda, 0xd4, 0x98, 0x42, 0x75, 0x6a, 0xc7, 0x8f, 0x2b, 0xdf, - 0x81, 0xc2, 0xa1, 0x65, 0xf7, 0x54, 0x57, 0x11, 0xce, 0x6b, 0xde, 0xef, 0x7c, 0x7f, 0x75, 0xba, - 0x9c, 0xdf, 0xa4, 0xa3, 0xc2, 0x71, 0xe5, 0x0f, 0x83, 0x9f, 0xa8, 0x2a, 0xc2, 0x2f, 0xbb, 0xe9, - 0x7e, 0xf3, 0x6b, 0x85, 0x35, 0x21, 0xea, 0xbe, 0x03, 0x05, 0xeb, 0xf0, 0xd0, 0xd0, 0x4d, 0xac, - 0xd8, 0x58, 0x75, 0x2c, 0xb3, 0xf4, 0x66, 0xc0, 0xfb, 0xe6, 0xf9, 0x98, 0x4c, 0x87, 0x50, 0x13, - 0x92, 0xb4, 0x51, 0xe1, 0x94, 0x16, 0xe8, 0xf1, 0x5c, 0xb2, 0xe9, 0x21, 0x73, 0x2e, 0xe8, 0x0e, - 0xc0, 0x0b, 0x1d, 0x9f, 0x28, 0xcf, 0x07, 0xd8, 0x1e, 0x96, 0x4a, 0xc1, 0x5e, 0x12, 0x81, 0x7f, - 0x46, 0xc0, 0xe8, 0x5b, 0xb0, 0xa0, 0x3b, 0x4a, 0x30, 0x05, 0x51, 0xc8, 0x60, 0xe9, 0xed, 0x40, - 0x1c, 0x46, 0xba, 0x33, 0x9a, 0xbe, 0xa0, 0xf7, 0x21, 0xa3, 0xe1, 0x3e, 0x36, 0x35, 0xa7, 0x65, - 0x96, 0x5e, 0xa3, 0x25, 0xf1, 0xb5, 0xb3, 0xd3, 0xe5, 0x4c, 0x4d, 0x00, 0xb9, 0x93, 0xf3, 0xb1, - 0xd0, 0xa7, 0x50, 0xf0, 0x3e, 0xda, 0xc3, 0x3e, 0x76, 0x4a, 0xef, 0x51, 0xba, 0x12, 0x39, 0xd8, - 0x5a, 0x68, 0x44, 0x84, 0xbd, 0x30, 0x3e, 0xfa, 0x12, 0x72, 0x0c, 0x82, 0xb5, 0x96, 0x59, 0x1d, - 0x96, 0x16, 0xa9, 0x9c, 0x1e, 0xcc, 0x28, 0x27, 0xbf, 0x93, 0xea, 0xdd, 0xd9, 0xd5, 0x02, 0xdc, - 0xe4, 0x10, 0x6f, 0xf4, 0xc7, 0x90, 0x13, 0x7a, 0xf8, 0xd8, 0x3a, 0x70, 0x4a, 0xdf, 0x38, 0xf7, - 0x62, 0x6c, 0x74, 0xae, 0x1d, 0x9f, 0x54, 0x78, 0x99, 0x20, 0x37, 0xd4, 0x06, 0x52, 0x3e, 0x8a, - 0xc8, 0xd1, 0xa1, 0xf6, 0xa0, 0x7c, 0x69, 0x1d, 0x10, 0x95, 0x5f, 0x5b, 0x89, 0xac, 0xc6, 0xbc, - 0x84, 0x60, 0xa1, 0x89, 0x4f, 0x82, 0x56, 0xf3, 0xd8, 0x3a, 0x68, 0xd4, 0xe4, 0x05, 0x73, 0x1c, - 0xaa, 0xa1, 0xcf, 0x21, 0x1f, 0x7c, 0x28, 0xe1, 0x94, 0x6e, 0x9d, 0xdb, 0x40, 0x1a, 0x33, 0x4e, - 0xff, 0xe9, 0x84, 0x23, 0xe7, 0x9c, 0xc0, 0x17, 0xba, 0x0d, 0x19, 0xcd, 0xb6, 0xfa, 0x2c, 0x86, - 0xbf, 0x4e, 0x17, 0x28, 0xda, 0x9f, 0xb6, 0xd5, 0xa7, 0xc1, 0x59, 0x81, 0x82, 0x8d, 0xfb, 0x86, - 0xda, 0xc1, 0x3d, 0x12, 0x14, 0xad, 0xc3, 0xd2, 0x12, 0x9d, 0x7d, 0x7d, 0xe6, 0xe3, 0xf1, 0x88, - 0x85, 0x7d, 0x04, 0xf8, 0xb5, 0x0e, 0xd1, 0x3e, 0x80, 0x3a, 0xd0, 0x74, 0x57, 0xe9, 0x59, 0x1a, - 0x2e, 0x2d, 0x9f, 0xfb, 0xb0, 0x6a, 0x94, 0x79, 0x85, 0x10, 0xee, 0x58, 0x1a, 0xf6, 0xee, 0xbc, - 0x05, 0x00, 0xbd, 0x0f, 0x59, 0xba, 0x35, 0x2e, 0xfd, 0x15, 0xba, 0xb9, 0x79, 0x2e, 0xfd, 0x4c, - 0xcd, 0xb6, 0xfa, 0x4c, 0xe4, 0x54, 0x00, 0x4c, 0xce, 0x0e, 0xe4, 0xba, 0x1d, 0xc5, 0x77, 0xa7, - 0xb7, 0xa9, 0x6e, 0x7c, 0x32, 0xe3, 0x5a, 0x1e, 0x6d, 0x4c, 0x70, 0xb0, 0xd7, 0x44, 0x5c, 0x78, - 0xb4, 0x21, 0x60, 0x8e, 0x9c, 0xed, 0x76, 0xbc, 0x0f, 0x52, 0x72, 0xb3, 0x4e, 0x39, 0x37, 0xe8, - 0x72, 0xb0, 0xe4, 0x66, 0x23, 0xcc, 0xa4, 0x9b, 0xc0, 0x5b, 0xea, 0x0a, 0x2d, 0x57, 0xd9, 0x99, - 0xdd, 0x99, 0x3d, 0xef, 0x2a, 0x30, 0xea, 0x8a, 0xd3, 0x3a, 0xa4, 0x07, 0xdb, 0x81, 0x9c, 0x35, - 0x70, 0x0f, 0xac, 0x81, 0xa9, 0x29, 0x87, 0xc7, 0x4e, 0xe9, 0x0d, 0xba, 0xdb, 0x0b, 0x35, 0x4e, - 0xbd, 0xdd, 0xb5, 0x38, 0xa3, 0xcd, 0x27, 0x8e, 0x9c, 0x15, 0x5c, 0x37, 0x8f, 0x1d, 0xf4, 0x23, - 0xc8, 0xea, 0xa6, 0x3f, 0xc7, 0xdd, 0x8b, 0xcf, 0x81, 0x44, 0xcd, 0xd1, 0x30, 0xbd, 0x29, 0x80, - 0xf3, 0x24, 0x33, 0xfc, 0x24, 0x02, 0x2b, 0x5f, 0xd3, 0x70, 0x75, 0x4a, 0xef, 0x9c, 0x7b, 0x5f, - 0x3d, 0x43, 0xc7, 0xf5, 0xf5, 0xf3, 0x3a, 0xae, 0x0e, 0x2a, 0x43, 0xc6, 0xc5, 0xbd, 0xbe, 0x65, - 0xab, 0xf6, 0xb0, 0xf4, 0x56, 0xf0, 0x09, 0x82, 0x07, 0x46, 0x3f, 0x84, 0xe2, 0x68, 0x4b, 0xec, - 0xde, 0x15, 0x5a, 0x62, 0x72, 0x21, 0xdc, 0xfe, 0x43, 0x6b, 0xb4, 0x08, 0x61, 0x37, 0x3d, 0x8a, - 0x6a, 0x18, 0xca, 0xc1, 0xb0, 0xf4, 0x6e, 0xb0, 0x1d, 0xe1, 0x8d, 0x56, 0x0c, 0xa3, 0x3a, 0x5c, - 0xfc, 0x45, 0x04, 0xe6, 0xc7, 0xe2, 0x36, 0xfa, 0x21, 0xa4, 0x4c, 0x4b, 0x0b, 0x3c, 0x0e, 0xa9, - 0x73, 0xf9, 0x27, 0x9b, 0x96, 0xc6, 0xde, 0x86, 0x7c, 0xd0, 0xd5, 0xdd, 0xa3, 0xc1, 0xc1, 0x5a, - 0xc7, 0xea, 0xdd, 0xf7, 0x56, 0xae, 0x1d, 0xf8, 0x7f, 0xdf, 0xef, 0x1f, 0x77, 0xef, 0xd3, 0xbf, - 0xfa, 0x07, 0x6b, 0x8c, 0x4c, 0x4e, 0x12, 0xae, 0x0d, 0x0d, 0xbd, 0x07, 0x45, 0xfc, 0xb2, 0xaf, - 0xdb, 0x81, 0xda, 0x21, 0x1a, 0xf0, 0x3b, 0x05, 0x7f, 0x90, 0x28, 0x29, 0xbf, 0x86, 0xff, 0x55, - 0x14, 0x8a, 0x23, 0xe1, 0x90, 0xd4, 0x3d, 0xb4, 0x45, 0x15, 0xaa, 0x7b, 0x08, 0xe4, 0x9c, 0xb7, - 0x1e, 0xc1, 0xb7, 0x8a, 0xb1, 0xab, 0xbe, 0x55, 0x0c, 0x3f, 0x2c, 0x4a, 0x5c, 0xe0, 0x61, 0xd1, - 0x47, 0x70, 0x43, 0x77, 0x14, 0xd3, 0x32, 0xc5, 0x05, 0x83, 0xd7, 0x74, 0x09, 0xbe, 0xec, 0xbb, - 0xa6, 0x3b, 0x4d, 0xcb, 0x64, 0x57, 0x0b, 0xde, 0xae, 0xfd, 0x47, 0x80, 0xa9, 0xf1, 0x47, 0x80, - 0x5e, 0x8f, 0x3e, 0x2e, 0x25, 0x16, 0xff, 0x2d, 0x02, 0x99, 0xe0, 0x6b, 0xfc, 0x68, 0xb8, 0x73, - 0x38, 0x56, 0x0b, 0x5e, 0xf2, 0x91, 0x4f, 0x58, 0x0a, 0xb1, 0x0b, 0x48, 0xe1, 0x36, 0x24, 0x0e, - 0x86, 0xa2, 0x46, 0x4b, 0x57, 0x73, 0x7c, 0xb6, 0x78, 0x95, 0xd4, 0x03, 0xf1, 0x83, 0xa1, 0x78, - 0x30, 0xb5, 0xf8, 0xa7, 0x90, 0x0d, 0xc4, 0xdd, 0xd1, 0xce, 0x44, 0xe4, 0x12, 0x9d, 0x89, 0x37, - 0x20, 0xc9, 0xc3, 0x02, 0xd3, 0xbd, 0x3c, 0xa7, 0x4e, 0xb0, 0x90, 0x90, 0xf8, 0x92, 0x84, 0x03, - 0x3e, 0xfb, 0xff, 0xc4, 0x20, 0x17, 0x8c, 0xa0, 0xc4, 0xd6, 0x75, 0xb3, 0x63, 0xd3, 0xf0, 0x45, - 0x67, 0x8f, 0x79, 0xcf, 0x8d, 0x04, 0x98, 0xc4, 0xd5, 0x9e, 0x6e, 0x2a, 0xf4, 0xa9, 0x4a, 0x48, - 0xbf, 0xd3, 0x3d, 0xdd, 0x7c, 0x4a, 0xa0, 0x14, 0x45, 0x7d, 0xc9, 0x51, 0x62, 0x21, 0x14, 0xf5, - 0x25, 0x43, 0x59, 0xa4, 0xa9, 0xaa, 0xed, 0x52, 0x09, 0xc5, 0x02, 0x29, 0xa8, 0xed, 0x06, 0x5f, - 0x1d, 0x26, 0x26, 0xbd, 0x3a, 0x34, 0xa1, 0xe0, 0xe7, 0x0c, 0x27, 0x26, 0xb6, 0xf9, 0x75, 0x43, - 0xe5, 0x12, 0x49, 0x83, 0xff, 0x41, 0x18, 0x89, 0x28, 0xee, 0x04, 0x81, 0x24, 0x2b, 0xed, 0xa8, - 0x9d, 0x23, 0xac, 0x38, 0xfa, 0x8f, 0x59, 0x3b, 0xc0, 0x13, 0x0b, 0x85, 0xef, 0xe9, 0x3f, 0xc6, - 0x8b, 0x7f, 0x17, 0x81, 0x7c, 0x88, 0x17, 0x6a, 0x40, 0x91, 0xae, 0x6e, 0xac, 0xbd, 0x7d, 0xdb, - 0x7b, 0x9f, 0x4f, 0x86, 0x27, 0x16, 0xb3, 0x79, 0x2b, 0x30, 0xa4, 0x91, 0x3c, 0x94, 0xb1, 0xf2, - 0x5e, 0xb7, 0x85, 0xd5, 0x38, 0x47, 0x39, 0x85, 0x9f, 0xb8, 0xe5, 0x2c, 0x1f, 0xa6, 0x05, 0x9b, - 0xf1, 0x8b, 0x26, 0x64, 0x03, 0x99, 0xcb, 0x0c, 0xf6, 0xf3, 0x6d, 0x88, 0x7b, 0xde, 0x6c, 0xd6, - 0x2e, 0xb2, 0xeb, 0xbb, 0xb8, 0x9f, 0x45, 0x60, 0x61, 0x52, 0x06, 0x11, 0xb2, 0x4b, 0xa6, 0x6d, - 0x33, 0xd9, 0xe5, 0x9d, 0x60, 0x66, 0xc7, 0x34, 0x50, 0xbc, 0x8a, 0xf0, 0x73, 0xbb, 0x37, 0x3d, - 0x3b, 0x60, 0x0a, 0x58, 0x0c, 0xd9, 0x01, 0xa9, 0xe0, 0x82, 0x96, 0xf0, 0xdb, 0x18, 0x14, 0x46, - 0x6e, 0x5f, 0x9e, 0x42, 0xb2, 0x6b, 0x58, 0x07, 0xaa, 0xc1, 0xbb, 0xd6, 0xdf, 0xb9, 0x54, 0x28, - 0x5b, 0x7b, 0x44, 0x79, 0x6c, 0xcd, 0xc9, 0x9c, 0x1b, 0x72, 0x60, 0x3e, 0x78, 0xcd, 0xc2, 0x7e, - 0x48, 0xc4, 0x24, 0x5b, 0xbf, 0xdc, 0x14, 0xfe, 0x3d, 0x0c, 0x45, 0xdc, 0x9a, 0x93, 0x8b, 0x76, - 0x18, 0x84, 0x7a, 0x50, 0x1c, 0xb9, 0xdb, 0xe1, 0x57, 0x02, 0x1b, 0x57, 0x9d, 0x52, 0xb6, 0x4e, - 0xb6, 0x68, 0xde, 0x1b, 0x00, 0x2c, 0xfe, 0x11, 0x14, 0x47, 0x16, 0x45, 0xce, 0x83, 0xe1, 0xf0, - 0xa8, 0x56, 0x20, 0x3e, 0x8c, 0x21, 0x35, 0xd5, 0x1e, 0x96, 0xf9, 0x28, 0x3f, 0x8f, 0xbb, 0x90, - 0x0f, 0x4d, 0x81, 0x0a, 0x10, 0x55, 0xd9, 0x13, 0xc2, 0x8c, 0x1c, 0x55, 0xf9, 0xe3, 0xc3, 0xc5, - 0x02, 0x24, 0x99, 0x7c, 0x83, 0xfa, 0x5d, 0x05, 0x48, 0x8b, 0xfc, 0xa1, 0xbc, 0x0a, 0x19, 0x2f, - 0x91, 0x46, 0x39, 0x48, 0xd7, 0x1a, 0x7b, 0x95, 0xea, 0x76, 0xbd, 0x26, 0xcd, 0xa1, 0x3c, 0x64, - 0xe4, 0x7a, 0xa5, 0x46, 0x7b, 0xae, 0x52, 0xe4, 0xe3, 0xf4, 0x9f, 0xff, 0x6c, 0x39, 0xc2, 0x83, - 0x4c, 0x52, 0x4a, 0x3d, 0x8e, 0xa7, 0x91, 0x74, 0xad, 0xfc, 0xbf, 0x19, 0x40, 0x35, 0xd5, 0x55, - 0x89, 0x50, 0x2e, 0xd0, 0x99, 0x8c, 0x9e, 0x63, 0x4d, 0x13, 0x9b, 0x8c, 0xf1, 0xab, 0x34, 0x19, - 0x2f, 0xd5, 0xeb, 0x1c, 0xef, 0x4c, 0x26, 0xaf, 0xd0, 0x99, 0x0c, 0xf7, 0x7d, 0x62, 0x57, 0xea, - 0xfb, 0x3c, 0x85, 0x14, 0xab, 0x32, 0xd9, 0x1b, 0xb3, 0xe9, 0x6d, 0x85, 0xf1, 0x83, 0xe1, 0xdd, - 0x1a, 0xa7, 0x6e, 0xba, 0xf6, 0xd0, 0x7b, 0x0f, 0xc3, 0x60, 0x7e, 0x7b, 0x24, 0xfd, 0x2a, 0xdb, - 0x23, 0x99, 0xe9, 0xed, 0x91, 0x1f, 0x00, 0xb7, 0x0b, 0x91, 0x14, 0xc3, 0xb9, 0x4f, 0x43, 0x26, - 0x6c, 0x87, 0x19, 0x01, 0xcf, 0x8a, 0x73, 0x76, 0xe0, 0x0b, 0xfd, 0x08, 0x90, 0xb8, 0x97, 0x0d, - 0x48, 0x9e, 0x5d, 0xe9, 0xbc, 0x3f, 0x75, 0x6b, 0x94, 0x60, 0xd2, 0x01, 0x88, 0xf7, 0xe0, 0xde, - 0x98, 0xb3, 0xd8, 0x06, 0xe0, 0x0d, 0x5e, 0xf3, 0xd0, 0x9a, 0x21, 0x4c, 0x2c, 0x41, 0x8a, 0xb8, - 0xdf, 0x3e, 0x66, 0xfa, 0xef, 0xc5, 0x6d, 0x0e, 0xe4, 0x36, 0xdb, 0x87, 0x5c, 0xf0, 0x90, 0x90, - 0x04, 0xb1, 0x63, 0x3c, 0xe4, 0xa6, 0x4d, 0xfe, 0x44, 0x8f, 0x21, 0xe1, 0x67, 0x17, 0xd3, 0x1f, - 0x8a, 0x4f, 0x3d, 0x7d, 0xb2, 0x5c, 0x99, 0xb1, 0xf8, 0x38, 0xfa, 0x90, 0xa6, 0xd8, 0xb9, 0xa0, - 0x20, 0x51, 0x13, 0xf2, 0xce, 0xc0, 0x7e, 0xa1, 0xbf, 0x50, 0x0d, 0xa5, 0x6b, 0xa9, 0x06, 0x9d, - 0xa8, 0xb0, 0x7e, 0x67, 0xda, 0x43, 0x2b, 0x8e, 0xfb, 0xc8, 0x52, 0x0d, 0xd1, 0x1a, 0x71, 0x02, - 0x30, 0xf4, 0x91, 0x77, 0x21, 0xc8, 0x6f, 0xd0, 0xf9, 0xe5, 0x32, 0xe2, 0x66, 0x18, 0xf4, 0x73, - 0xa2, 0xfb, 0xcb, 0x40, 0x24, 0xb2, 0x73, 0x15, 0xc1, 0xf4, 0x11, 0xb4, 0x68, 0xeb, 0x7b, 0x91, - 0x9d, 0xe1, 0xd5, 0xcd, 0x41, 0xcf, 0x8f, 0xec, 0xb6, 0x0f, 0xd3, 0xd0, 0x16, 0x64, 0xbc, 0x58, - 0x4e, 0xcd, 0xbf, 0xb0, 0xfe, 0xc6, 0x39, 0x12, 0xdb, 0x1d, 0xe9, 0x58, 0xf8, 0xc4, 0x5e, 0x8a, - 0x1d, 0x91, 0xa2, 0xbe, 0x37, 0x2c, 0xff, 0x36, 0x07, 0x85, 0xf6, 0xb0, 0x3f, 0xc9, 0xfb, 0xc5, - 0xa6, 0x78, 0xbf, 0xf8, 0x6c, 0xf7, 0x32, 0x99, 0xab, 0xdd, 0xcb, 0xc0, 0xab, 0xbd, 0x97, 0xc9, - 0xbe, 0x32, 0xef, 0x57, 0xb8, 0x92, 0xf7, 0x7b, 0x65, 0xb7, 0x74, 0xd1, 0x4b, 0xdc, 0xd2, 0x7d, - 0x17, 0xf2, 0xaa, 0x6d, 0xab, 0x43, 0xfe, 0x3b, 0x1c, 0x8d, 0xba, 0xca, 0x3c, 0x3b, 0xa3, 0xb3, - 0xd3, 0xe5, 0x6c, 0x85, 0x0c, 0xd2, 0x9f, 0xde, 0x08, 0x0e, 0x59, 0xd5, 0x03, 0x69, 0xbe, 0x87, - 0xcd, 0xbf, 0x4a, 0x0f, 0x5b, 0x9c, 0xee, 0x61, 0x6b, 0x10, 0xa7, 0x3f, 0xf4, 0x61, 0x7a, 0x3f, - 0x4d, 0xe4, 0x61, 0xf5, 0x5d, 0x0b, 0xfc, 0xd6, 0x87, 0x52, 0xa3, 0x1f, 0xc1, 0xa2, 0x78, 0x4d, - 0x4b, 0xf4, 0xc1, 0xbf, 0x45, 0x0d, 0xfc, 0x8c, 0xaa, 0x7c, 0x76, 0xba, 0x5c, 0x92, 0x7d, 0x2c, - 0x9f, 0x1f, 0xab, 0x03, 0x89, 0x2c, 0x4a, 0xf6, 0xc4, 0x71, 0xcd, 0x41, 0x5f, 0x40, 0x8e, 0xda, - 0x77, 0x0f, 0xf7, 0x0e, 0xb0, 0x2d, 0x42, 0xed, 0x83, 0xd9, 0xd6, 0x4b, 0x0c, 0x7d, 0x87, 0x12, - 0x8a, 0xde, 0x19, 0xf6, 0x20, 0x0e, 0x7a, 0x00, 0x09, 0xd5, 0xd0, 0x69, 0xac, 0xfc, 0xba, 0xdf, - 0xf5, 0x31, 0x44, 0xf6, 0x0a, 0x39, 0x18, 0x96, 0xa4, 0xf3, 0xbb, 0x9e, 0xe1, 0xd5, 0x4c, 0x0f, - 0x49, 0x8b, 0x3f, 0x8d, 0x01, 0xf8, 0x8b, 0x45, 0xdf, 0x86, 0x9b, 0xfd, 0xa3, 0xa1, 0xa3, 0x77, - 0x54, 0x43, 0xb1, 0x71, 0xdf, 0xc6, 0x0e, 0x36, 0x59, 0xe6, 0x4f, 0xf5, 0x3a, 0x27, 0xdf, 0x10, - 0xc3, 0x72, 0x68, 0x14, 0x7d, 0x02, 0x37, 0x0c, 0xab, 0x3b, 0x89, 0x2e, 0xd8, 0xf7, 0xb8, 0xce, - 0x71, 0x46, 0x88, 0x55, 0x52, 0xad, 0xf5, 0xd5, 0x03, 0xdd, 0xf0, 0x5b, 0x21, 0x9f, 0x5c, 0x54, - 0xd0, 0x6b, 0x1b, 0x1e, 0x0b, 0xf1, 0xac, 0xc6, 0x67, 0x8a, 0x7e, 0x38, 0xfe, 0x32, 0xe1, 0xe3, - 0x0b, 0xcf, 0x30, 0xfd, 0x81, 0x42, 0xf9, 0x0d, 0x00, 0x7f, 0x7e, 0x7a, 0xe1, 0xbf, 0xbd, 0xed, - 0x27, 0xac, 0xfc, 0xe9, 0x40, 0xf9, 0xde, 0xd7, 0xbc, 0x0f, 0x00, 0x48, 0xca, 0xf5, 0x9d, 0xd6, - 0xd3, 0xba, 0x78, 0x21, 0xb0, 0xd8, 0x1a, 0x89, 0x83, 0xe3, 0x71, 0x2b, 0x32, 0x63, 0xdc, 0xe2, - 0x97, 0xf6, 0xef, 0x43, 0x9c, 0x18, 0x13, 0x99, 0xbd, 0xde, 0xdc, 0xdf, 0x91, 0xe6, 0x50, 0x06, - 0x12, 0x95, 0xed, 0x46, 0x65, 0x4f, 0x8a, 0xa0, 0x05, 0x90, 0x76, 0xf6, 0xb7, 0xdb, 0x0d, 0xb9, - 0xfe, 0xa8, 0xd1, 0x6a, 0x2a, 0x14, 0x21, 0x18, 0x58, 0xfe, 0x36, 0x0e, 0x12, 0x73, 0x3c, 0x13, - 0x42, 0x4b, 0xf4, 0x12, 0x57, 0xfe, 0x7f, 0xf0, 0xfc, 0x6e, 0x62, 0x58, 0x4a, 0xbc, 0xa2, 0x4c, - 0x3e, 0x79, 0x85, 0x4c, 0x3e, 0xf5, 0xaa, 0xde, 0x18, 0xcc, 0x1a, 0x7f, 0xc2, 0x01, 0x30, 0x7e, - 0x95, 0x00, 0x18, 0xd0, 0x90, 0x9f, 0x47, 0x01, 0x02, 0xba, 0xf1, 0xbd, 0xe0, 0x3f, 0xbb, 0x31, - 0xfd, 0x96, 0x7b, 0xa4, 0x74, 0xdd, 0x9a, 0x13, 0xff, 0x28, 0xc7, 0x23, 0x48, 0x6b, 0x3c, 0x67, - 0xe4, 0xa9, 0xe5, 0xdb, 0x33, 0xa7, 0x96, 0x5b, 0x73, 0xb2, 0x47, 0x8c, 0x3e, 0x09, 0xfd, 0x92, - 0xfa, 0xee, 0x4c, 0xa6, 0xbf, 0x25, 0x7e, 0x5e, 0x50, 0x81, 0x24, 0x8b, 0xd1, 0x5c, 0x4c, 0x53, - 0x7f, 0x9d, 0x3a, 0x62, 0x1a, 0x5b, 0x73, 0x32, 0x27, 0xe4, 0x65, 0x6e, 0x0a, 0x12, 0x03, 0x53, - 0xb7, 0xcc, 0x7b, 0x72, 0xf0, 0x49, 0xbc, 0xe8, 0xe9, 0x12, 0x6f, 0x41, 0xff, 0x56, 0x5d, 0xac, - 0xb1, 0x97, 0x47, 0xfb, 0xe6, 0x0b, 0x0f, 0x10, 0x41, 0x05, 0x00, 0x3e, 0xae, 0x9b, 0x5d, 0x29, - 0x4a, 0x8b, 0x63, 0x92, 0xa8, 0x93, 0xaf, 0xd8, 0xbd, 0xef, 0x82, 0x34, 0xfa, 0xf3, 0xd8, 0x80, - 0x8f, 0x99, 0x87, 0xfc, 0xce, 0xd3, 0x8d, 0x8d, 0x76, 0x63, 0xa7, 0xbe, 0xd7, 0xae, 0xec, 0xec, - 0xb2, 0xb7, 0xd6, 0x6d, 0x52, 0x59, 0xb7, 0x1a, 0x35, 0x29, 0x7a, 0xef, 0x00, 0x6e, 0x4e, 0xf9, - 0x3d, 0x35, 0xba, 0x09, 0xd7, 0x9a, 0xad, 0xb6, 0xd2, 0xa8, 0xd5, 0x9b, 0xed, 0x46, 0xfb, 0x0b, - 0x65, 0xa3, 0xb5, 0xbd, 0xbf, 0xd3, 0x94, 0xe6, 0x88, 0xbf, 0x78, 0x54, 0x6f, 0xd6, 0xe5, 0x4a, - 0xbb, 0x5e, 0x53, 0x2a, 0xdb, 0xcf, 0x2a, 0x5f, 0x10, 0x2f, 0x52, 0x82, 0x05, 0x1f, 0x5a, 0xfd, - 0xc2, 0xfb, 0x37, 0x36, 0xa2, 0xf7, 0xbe, 0x0b, 0xc5, 0x11, 0x53, 0x26, 0x2e, 0x6f, 0x77, 0xbf, - 0xba, 0xdd, 0xd8, 0x98, 0xf8, 0x4e, 0x0a, 0x65, 0x21, 0xd5, 0xda, 0xdc, 0xdc, 0x6e, 0x34, 0xeb, - 0x52, 0xec, 0xde, 0x87, 0x90, 0x0b, 0x26, 0xf6, 0x48, 0x82, 0xdc, 0xf7, 0x5b, 0xcd, 0xba, 0xb2, - 0x59, 0x69, 0x6c, 0xef, 0xcb, 0x64, 0x97, 0x08, 0x0a, 0xdc, 0x77, 0x09, 0x58, 0xe4, 0xde, 0xbb, - 0x90, 0x0f, 0x65, 0xd1, 0x84, 0xa7, 0x58, 0xd2, 0x1c, 0x91, 0xa9, 0xf8, 0x37, 0x42, 0xea, 0x35, - 0x29, 0x52, 0x5d, 0xfd, 0xf5, 0x7f, 0x2d, 0xcd, 0xfd, 0xfa, 0x6c, 0x29, 0xf2, 0x9b, 0xb3, 0xa5, - 0xc8, 0xef, 0xce, 0x96, 0x22, 0xff, 0x79, 0xb6, 0x14, 0xf9, 0xab, 0xdf, 0x2f, 0xcd, 0xfd, 0xe6, - 0xf7, 0x4b, 0x73, 0xbf, 0xfb, 0xfd, 0xd2, 0xdc, 0xf7, 0x93, 0xec, 0x9f, 0xb0, 0xf9, 0xbf, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x66, 0xb7, 0x5a, 0x27, 0x2d, 0x47, 0x00, 0x00, + // 5640 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3c, 0x4b, 0x73, 0x1c, 0xc7, + 0x79, 0xd8, 0x17, 0x76, 0xf7, 0xdb, 0xd7, 0xa0, 0x09, 0x92, 0x2b, 0x98, 0x02, 0xc0, 0xa5, 0x28, + 0x41, 0x94, 0x04, 0x52, 0x90, 0x6c, 0x53, 0x92, 0xed, 0x68, 0x5f, 0x20, 0x96, 0x04, 0x76, 0xa1, + 0xc1, 0x82, 0x94, 0xec, 0xc4, 0xe3, 0xc1, 0x4e, 0x63, 0x31, 0xc2, 0xec, 0xcc, 0x72, 0x66, 0x96, + 0xe0, 0xba, 0x72, 0x48, 0xf9, 0x94, 0x53, 0x92, 0x43, 0x6e, 0x29, 0x57, 0x5c, 0x29, 0x57, 0xe2, + 0x9b, 0xcb, 0x95, 0xaa, 0xa4, 0x2a, 0x87, 0x5c, 0xe3, 0xa3, 0x53, 0xa9, 0x4a, 0xf9, 0x84, 0x4a, + 0xe0, 0x4b, 0x7e, 0x40, 0x2a, 0x07, 0x5d, 0x92, 0xea, 0xd7, 0x3c, 0xf6, 0x01, 0x2d, 0x00, 0xc6, + 0x07, 0xa9, 0x30, 0x5f, 0x7f, 0xdf, 0xd7, 0xdd, 0x5f, 0x7f, 0xef, 0xee, 0x25, 0xdc, 0x71, 0x9e, + 0x1b, 0xf7, 0x3b, 0xaa, 0xab, 0x1a, 0x56, 0xf7, 0xbe, 0x86, 0x9d, 0x4e, 0xff, 0xe0, 0xbe, 0xe3, + 0xda, 0x83, 0x8e, 0x3b, 0xb0, 0xb1, 0xb6, 0xde, 0xb7, 0x2d, 0xd7, 0x42, 0xd7, 0x3b, 0x56, 0xe7, + 0xd8, 0xb6, 0xd4, 0xce, 0xd1, 0xba, 0xf3, 0xdc, 0x20, 0xff, 0x1d, 0xa8, 0x0e, 0x5e, 0x2a, 0x0e, + 0x5c, 0xdd, 0xb8, 0x7f, 0x64, 0x74, 0xee, 0xbb, 0x7a, 0x0f, 0x3b, 0xae, 0xda, 0xeb, 0x33, 0x82, + 0xa5, 0xd2, 0x04, 0xae, 0x7d, 0x5b, 0x7f, 0xa1, 0x1b, 0xb8, 0x8b, 0x39, 0xce, 0x75, 0x82, 0xe3, + 0x0e, 0xfb, 0xd8, 0x61, 0xff, 0xe7, 0xe0, 0xd7, 0xba, 0xd8, 0xba, 0xdf, 0xc5, 0x96, 0x6e, 0x6a, + 0xf8, 0xe5, 0xfd, 0x8e, 0x65, 0x1e, 0xea, 0x5d, 0x3e, 0xb4, 0xd8, 0xb5, 0xba, 0x16, 0xfd, 0xf3, + 0x3e, 0xf9, 0x8b, 0x41, 0x4b, 0x3f, 0x49, 0xc0, 0xb5, 0x4d, 0xcb, 0xc6, 0x7a, 0xd7, 0x7c, 0x82, + 0x87, 0x32, 0x3e, 0xc4, 0x36, 0x36, 0x3b, 0x18, 0xad, 0x42, 0xc2, 0x55, 0x0f, 0x0c, 0x5c, 0x8c, + 0xac, 0x46, 0xd6, 0x72, 0x15, 0xf8, 0xf5, 0xe9, 0xca, 0xdc, 0x57, 0xa7, 0x2b, 0xd1, 0x46, 0x4d, + 0x66, 0x03, 0xe8, 0x2e, 0x24, 0xe8, 0x2c, 0xc5, 0x28, 0xc5, 0x28, 0x70, 0x8c, 0x64, 0x83, 0x00, + 0x09, 0x1a, 0x1d, 0x45, 0x45, 0x88, 0x9b, 0x6a, 0x0f, 0x17, 0x63, 0xab, 0x91, 0xb5, 0x74, 0x25, + 0x4e, 0xb0, 0x64, 0x0a, 0x41, 0x4f, 0x20, 0xf5, 0x42, 0x35, 0x74, 0x4d, 0x77, 0x87, 0xc5, 0xf8, + 0x6a, 0x64, 0x2d, 0xbf, 0xf1, 0xf6, 0xfa, 0x44, 0x51, 0xad, 0x57, 0x2d, 0xd3, 0x71, 0x6d, 0x55, + 0x37, 0xdd, 0xa7, 0x9c, 0x80, 0x33, 0xf2, 0x18, 0xa0, 0x07, 0xb0, 0xe0, 0x1c, 0xa9, 0x36, 0xd6, + 0x94, 0xbe, 0x8d, 0x0f, 0xf5, 0x97, 0x8a, 0x81, 0xcd, 0x62, 0x62, 0x35, 0xb2, 0x96, 0xe0, 0xa8, + 0x05, 0x36, 0xbc, 0x4b, 0x47, 0xb7, 0xb1, 0x89, 0xda, 0x90, 0xb6, 0x4c, 0x45, 0xc3, 0x06, 0x76, + 0x71, 0x71, 0x9e, 0xce, 0xff, 0xfe, 0x94, 0xf9, 0x27, 0x08, 0x68, 0xbd, 0xdc, 0x71, 0x75, 0xcb, + 0x14, 0xeb, 0xb0, 0xcc, 0x1a, 0x65, 0xc4, 0xb9, 0x0e, 0xfa, 0x9a, 0xea, 0xe2, 0x62, 0xf2, 0xca, + 0x5c, 0xf7, 0x29, 0x23, 0xb4, 0x0d, 0x89, 0x9e, 0xea, 0x76, 0x8e, 0x8a, 0x29, 0xca, 0xf1, 0xc1, + 0x05, 0x38, 0xee, 0x10, 0x3a, 0xce, 0x90, 0x31, 0x29, 0x3d, 0x83, 0x79, 0x36, 0x0f, 0xca, 0x41, + 0xba, 0xd9, 0x52, 0xca, 0xd5, 0x76, 0xa3, 0xd5, 0x94, 0xe6, 0x50, 0x16, 0x52, 0x72, 0x7d, 0xaf, + 0x2d, 0x37, 0xaa, 0x6d, 0x29, 0x42, 0xbe, 0xf6, 0xea, 0x6d, 0xa5, 0xb9, 0xbf, 0xbd, 0x2d, 0x45, + 0x51, 0x01, 0x32, 0xe4, 0xab, 0x56, 0xdf, 0x2c, 0xef, 0x6f, 0xb7, 0xa5, 0x18, 0xca, 0x40, 0xb2, + 0x5a, 0xde, 0xab, 0x96, 0x6b, 0x75, 0x29, 0xbe, 0x14, 0xff, 0xc5, 0xcf, 0x97, 0xe7, 0x4a, 0x0f, + 0x20, 0x41, 0xa7, 0x43, 0x00, 0xf3, 0x7b, 0x8d, 0x9d, 0xdd, 0xed, 0xba, 0x34, 0x87, 0x52, 0x10, + 0xdf, 0x24, 0x2c, 0x22, 0x84, 0x62, 0xb7, 0x2c, 0xb7, 0x1b, 0xe5, 0x6d, 0x29, 0xca, 0x28, 0x3e, + 0x8e, 0xff, 0xd7, 0xcf, 0x56, 0x22, 0xa5, 0x7f, 0x4d, 0xc0, 0xa2, 0xbf, 0x76, 0xff, 0xb4, 0x51, + 0x15, 0x0a, 0x96, 0xad, 0x77, 0x75, 0x53, 0xa1, 0x3a, 0xa7, 0xe8, 0x1a, 0xd7, 0xc7, 0x6f, 0x90, + 0xfd, 0x9c, 0x9d, 0xae, 0xe4, 0x5a, 0x74, 0xb8, 0x4d, 0x46, 0x1b, 0x35, 0xae, 0xa0, 0x39, 0x2b, + 0x00, 0xd4, 0xd0, 0x13, 0x58, 0xe0, 0x4c, 0x3a, 0x96, 0x31, 0xe8, 0x99, 0x8a, 0xae, 0x39, 0xc5, + 0xe8, 0x6a, 0x6c, 0x2d, 0x57, 0x59, 0x39, 0x3b, 0x5d, 0x29, 0x30, 0x16, 0x55, 0x3a, 0xd6, 0xa8, + 0x39, 0x5f, 0x9d, 0xae, 0xa4, 0xc4, 0x87, 0xcc, 0xa7, 0xe7, 0xdf, 0x9a, 0x83, 0x9e, 0xc1, 0x75, + 0x5b, 0xc8, 0x56, 0x0b, 0x32, 0x8c, 0x51, 0x86, 0x77, 0xce, 0x4e, 0x57, 0xae, 0x79, 0xc2, 0xd7, + 0x26, 0x33, 0xbd, 0x66, 0x8f, 0x22, 0x68, 0x0e, 0x6a, 0x41, 0x00, 0xec, 0x6f, 0x37, 0x4e, 0xb7, + 0xbb, 0xc2, 0xb7, 0xbb, 0xe0, 0xb3, 0x0e, 0x6f, 0x79, 0xc1, 0x1e, 0x19, 0xd0, 0x3c, 0xc3, 0x4b, + 0x9c, 0x6b, 0x78, 0xf3, 0x57, 0x35, 0xbc, 0x90, 0x19, 0x25, 0xff, 0x5f, 0xcc, 0x28, 0xf5, 0xca, + 0xcd, 0x28, 0xfd, 0x0a, 0xcc, 0x88, 0xe9, 0xee, 0xe3, 0x78, 0x0a, 0xa4, 0xcc, 0xe3, 0x78, 0x2a, + 0x23, 0x65, 0x1f, 0xc7, 0x53, 0x59, 0x29, 0xf7, 0x38, 0x9e, 0xca, 0x49, 0xf9, 0xd2, 0x5f, 0x45, + 0xe1, 0xd6, 0xbe, 0xa9, 0x3f, 0x1f, 0xe0, 0x67, 0xba, 0x7b, 0x64, 0x0d, 0x5c, 0xea, 0x17, 0x03, + 0xba, 0xfd, 0x00, 0x52, 0x23, 0x4a, 0x7d, 0x9d, 0x9f, 0x72, 0x32, 0x7c, 0xb6, 0x49, 0x97, 0x9f, + 0xe8, 0x43, 0x80, 0x31, 0x0d, 0x7e, 0xed, 0xec, 0x74, 0x25, 0x3d, 0x59, 0xcd, 0xd2, 0x1d, 0x4f, + 0xb9, 0x7e, 0x4f, 0x4e, 0xb8, 0x04, 0xe9, 0xbe, 0x8d, 0x35, 0xbd, 0x43, 0x4e, 0x2d, 0xa8, 0x77, + 0x3e, 0x98, 0x5b, 0xfc, 0xdf, 0x26, 0x41, 0x62, 0x0b, 0xad, 0x61, 0xa7, 0x63, 0xeb, 0x7d, 0xd7, + 0xb2, 0xbd, 0x55, 0x46, 0xc6, 0x56, 0xf9, 0x26, 0x44, 0x75, 0x8d, 0x07, 0x9a, 0x1b, 0x5c, 0x4a, + 0x51, 0x2a, 0x20, 0x7f, 0xbb, 0x51, 0x5d, 0x43, 0xeb, 0x10, 0x27, 0xd1, 0x90, 0xee, 0x33, 0xb3, + 0xb1, 0x34, 0xba, 0x13, 0xdc, 0x5b, 0x67, 0xc1, 0xb2, 0x2d, 0x53, 0x3c, 0xb4, 0x0a, 0x29, 0x73, + 0x60, 0x18, 0x34, 0xd0, 0x91, 0xdd, 0xa7, 0xc4, 0x96, 0x04, 0x14, 0xdd, 0x86, 0xac, 0x86, 0x0f, + 0xd5, 0x81, 0xe1, 0x2a, 0xf8, 0x65, 0xdf, 0x66, 0xbb, 0x92, 0x33, 0x1c, 0x56, 0x7f, 0xd9, 0xb7, + 0xd1, 0x1b, 0x90, 0xf7, 0x74, 0x95, 0x21, 0x21, 0x8a, 0x94, 0x15, 0x7a, 0x47, 0xb1, 0x6e, 0xc1, + 0xfc, 0x91, 0xae, 0x69, 0xd8, 0xa4, 0x26, 0x27, 0x26, 0xe2, 0x30, 0xb4, 0x06, 0x59, 0xdd, 0x54, + 0x3b, 0x1d, 0xec, 0x38, 0x3a, 0x59, 0xcc, 0x42, 0x00, 0x27, 0x34, 0x82, 0x9e, 0xc3, 0x52, 0x17, + 0x9b, 0xd8, 0x56, 0x5d, 0xac, 0x29, 0xaa, 0xa3, 0xe8, 0x1a, 0x36, 0x5d, 0xdd, 0x1d, 0x2a, 0x74, + 0xe3, 0xd7, 0xe8, 0x11, 0xae, 0x4f, 0x39, 0xc2, 0x47, 0x82, 0xb0, 0xec, 0x34, 0x38, 0x59, 0x7b, + 0xd8, 0xc7, 0x7c, 0x9e, 0x9b, 0xdd, 0xc9, 0xc3, 0x68, 0x17, 0xee, 0x4e, 0x9e, 0xd2, 0xc1, 0xcf, + 0x07, 0xc4, 0x3a, 0x14, 0xab, 0x4f, 0xec, 0xad, 0xb8, 0x48, 0xf7, 0x7d, 0x7b, 0x02, 0x9f, 0x3d, + 0x8e, 0xd9, 0xa2, 0x88, 0x68, 0x03, 0x16, 0x06, 0x0e, 0x76, 0x7c, 0x06, 0x44, 0xa1, 0x81, 0x2a, + 0xf4, 0x3c, 0xd7, 0xfa, 0x02, 0x41, 0x10, 0x64, 0x44, 0x87, 0x37, 0x60, 0xc1, 0x3a, 0x31, 0x47, + 0x68, 0xb2, 0x61, 0x1a, 0x82, 0x10, 0xa4, 0xb9, 0x0d, 0xd9, 0x8e, 0xd5, 0xeb, 0x0f, 0xc4, 0xc1, + 0x64, 0xd8, 0xe9, 0x71, 0x18, 0x3d, 0x97, 0x65, 0x48, 0xbe, 0xd0, 0x6d, 0x77, 0xa0, 0x1a, 0x45, + 0x29, 0x20, 0x74, 0x01, 0x44, 0x9f, 0x82, 0xd4, 0xef, 0x2a, 0xaa, 0xeb, 0xda, 0xfa, 0x01, 0xe1, + 0x63, 0x0e, 0x7a, 0xc5, 0x5c, 0x48, 0x11, 0xf3, 0xbb, 0x8f, 0xca, 0x62, 0xb8, 0x39, 0xe8, 0xc9, + 0xf9, 0x7e, 0x37, 0xf8, 0x8d, 0x36, 0xe1, 0x75, 0xd5, 0x70, 0xb1, 0x2d, 0xa2, 0x05, 0x39, 0x28, + 0x45, 0x37, 0x95, 0xbe, 0x6d, 0x75, 0x6d, 0xec, 0x38, 0xc5, 0x7c, 0x60, 0xde, 0xd7, 0x28, 0x2a, + 0x53, 0x6a, 0x22, 0xfc, 0x86, 0xb9, 0xcb, 0xd1, 0xd0, 0x0f, 0x00, 0x39, 0x43, 0xc7, 0xc5, 0x3d, + 0xc1, 0xe8, 0x58, 0x37, 0xb5, 0x62, 0x81, 0x9e, 0xf8, 0x5b, 0x53, 0x4e, 0x7c, 0x8f, 0x12, 0x30, + 0x76, 0x4f, 0x74, 0x53, 0xe3, 0xb3, 0x48, 0xce, 0x08, 0xdc, 0x73, 0x66, 0x29, 0x29, 0xfd, 0x38, + 0x9e, 0x4a, 0x4b, 0xf0, 0x38, 0x9e, 0x4a, 0x4a, 0xa9, 0xd2, 0x9f, 0x45, 0xe1, 0x06, 0x43, 0xdb, + 0x54, 0x7b, 0xba, 0x31, 0xbc, 0xaa, 0xb9, 0x32, 0x2e, 0xdc, 0x5c, 0xe9, 0xf1, 0xd0, 0xad, 0x10, + 0x32, 0x16, 0x43, 0xe9, 0xf1, 0x10, 0x58, 0x93, 0x80, 0x46, 0x7c, 0x5e, 0xfc, 0x02, 0x3e, 0xaf, + 0x05, 0x0b, 0xc2, 0x72, 0x3d, 0x0e, 0xd4, 0x7c, 0x73, 0x95, 0x3b, 0x7c, 0x4d, 0x85, 0x1a, 0x43, + 0x10, 0xe4, 0xe1, 0xd0, 0xaf, 0x85, 0x06, 0xb9, 0x88, 0x4a, 0xff, 0x18, 0x85, 0xc5, 0x86, 0xe9, + 0x62, 0xdb, 0xc0, 0xea, 0x0b, 0x1c, 0x10, 0xc7, 0xe7, 0x90, 0x56, 0xcd, 0x0e, 0x76, 0x5c, 0xcb, + 0x76, 0x8a, 0x91, 0xd5, 0xd8, 0x5a, 0x66, 0xe3, 0xc3, 0x29, 0xa7, 0x32, 0x89, 0x7e, 0xbd, 0xcc, + 0x89, 0x85, 0xcb, 0xf4, 0x98, 0x2d, 0xfd, 0x73, 0x04, 0x52, 0x62, 0xf4, 0x12, 0x61, 0xe3, 0x9b, + 0x90, 0xa2, 0xa9, 0xb8, 0xe2, 0x9d, 0xc9, 0x92, 0xa0, 0xe0, 0xb9, 0x7a, 0x30, 0x6d, 0x4f, 0x52, + 0xdc, 0x86, 0x86, 0xaa, 0x93, 0x32, 0xea, 0x18, 0xa5, 0xbf, 0x29, 0xe4, 0xb7, 0x17, 0xce, 0xa9, + 0xc7, 0x92, 0x6c, 0x26, 0x33, 0x2e, 0xb9, 0x7f, 0x88, 0xc0, 0x02, 0x21, 0xd0, 0xb0, 0x16, 0x10, + 0xdb, 0x1d, 0x00, 0xdd, 0x51, 0x1c, 0x06, 0xa7, 0x3b, 0x12, 0xa6, 0x90, 0xd6, 0x1d, 0x8e, 0xee, + 0xa9, 0x5a, 0x74, 0x4c, 0xd5, 0x3e, 0x82, 0x1c, 0xa5, 0x55, 0x0e, 0x06, 0x9d, 0x63, 0xec, 0x3a, + 0x74, 0x85, 0x89, 0xca, 0x22, 0x5f, 0x61, 0x96, 0x72, 0xa8, 0xb0, 0x31, 0x39, 0xeb, 0x04, 0xbe, + 0xc6, 0xb4, 0x2f, 0x3e, 0xa6, 0x7d, 0x7c, 0xe1, 0xbf, 0x8c, 0xc3, 0x8d, 0x5d, 0xd5, 0x76, 0x75, + 0xe2, 0xbb, 0x74, 0xb3, 0x1b, 0x58, 0xfd, 0x5d, 0xc8, 0x98, 0x03, 0x61, 0x90, 0x0e, 0x3f, 0x10, + 0xb6, 0x3e, 0x30, 0x07, 0xdc, 0xc0, 0x1c, 0xf4, 0x2d, 0x58, 0x24, 0x68, 0x7a, 0xaf, 0x6f, 0xe8, + 0x1d, 0xdd, 0xf5, 0xf0, 0xe3, 0x01, 0x7c, 0x64, 0x0e, 0x7a, 0x0d, 0x8e, 0x20, 0xe8, 0xb6, 0x21, + 0x6e, 0xe8, 0x8e, 0x4b, 0x63, 0x7d, 0x66, 0x63, 0x63, 0x8a, 0x3a, 0x4d, 0x5e, 0xdb, 0xfa, 0xb6, + 0xee, 0xb8, 0x42, 0x56, 0x84, 0x0b, 0x6a, 0x41, 0xc2, 0x56, 0xcd, 0x2e, 0xa6, 0x76, 0x96, 0xd9, + 0xf8, 0xe0, 0x62, 0xec, 0x64, 0x42, 0x2a, 0x32, 0x20, 0xca, 0x67, 0xe9, 0xa7, 0x11, 0x88, 0x93, + 0x59, 0xce, 0x71, 0x05, 0x37, 0x60, 0xfe, 0x85, 0x6a, 0x0c, 0x30, 0xcb, 0x57, 0xb2, 0x32, 0xff, + 0x42, 0x7f, 0x04, 0x05, 0x67, 0x70, 0xd0, 0x0f, 0x4c, 0xc5, 0x83, 0xf6, 0x7b, 0x17, 0x5a, 0x95, + 0x57, 0xdc, 0x85, 0x79, 0xb1, 0x83, 0x5b, 0x7a, 0x0e, 0x09, 0xba, 0xea, 0x73, 0xd6, 0x77, 0x17, + 0xf2, 0x87, 0xb6, 0xd5, 0x53, 0x74, 0xb3, 0x63, 0x0c, 0x1c, 0xfd, 0x05, 0xcb, 0x1d, 0xb2, 0x72, + 0x8e, 0x40, 0x1b, 0x02, 0x48, 0x74, 0xc5, 0xb5, 0x14, 0xfc, 0x52, 0x20, 0x45, 0x29, 0x52, 0xc6, + 0xb5, 0xea, 0x02, 0x14, 0x52, 0xf5, 0x7f, 0xca, 0x42, 0x81, 0x1a, 0xd4, 0x4c, 0xee, 0xf2, 0x6e, + 0xc0, 0x5d, 0x5e, 0x0f, 0xb9, 0x4b, 0xcf, 0x2a, 0x89, 0xb7, 0xbc, 0x05, 0xf3, 0x03, 0x9a, 0x50, + 0xd2, 0x25, 0x7a, 0x19, 0x04, 0x83, 0xa1, 0x87, 0x90, 0x7c, 0x81, 0x6d, 0x87, 0x84, 0x61, 0x44, + 0x39, 0x2d, 0xf3, 0x82, 0xfc, 0xc6, 0xc8, 0x42, 0x9e, 0x32, 0x2c, 0x59, 0xa0, 0xa3, 0x35, 0x90, + 0x8e, 0xf1, 0x50, 0x99, 0x60, 0x0b, 0xf9, 0x63, 0x52, 0x8d, 0xf9, 0xce, 0x58, 0x83, 0xeb, 0x01, + 0x4c, 0x4d, 0xb7, 0x31, 0xcd, 0xb3, 0x9d, 0x62, 0x6a, 0x35, 0x76, 0x4e, 0x3e, 0x3d, 0xb2, 0x80, + 0xf5, 0x9a, 0x20, 0x94, 0xaf, 0x79, 0x13, 0x78, 0x30, 0x07, 0xbd, 0x0b, 0x88, 0x78, 0x3a, 0x1c, + 0x5e, 0x51, 0x82, 0xae, 0x48, 0xa2, 0x23, 0xc1, 0x35, 0x55, 0x20, 0x1f, 0x58, 0x13, 0x09, 0x12, + 0xf3, 0x34, 0x48, 0xdc, 0x22, 0xd6, 0xff, 0x44, 0xb0, 0x1f, 0x8d, 0x13, 0x59, 0x6f, 0x62, 0x12, + 0x2a, 0xf6, 0xd9, 0xbe, 0x9c, 0xc1, 0x21, 0xf1, 0x73, 0x01, 0x56, 0x49, 0xca, 0xaa, 0x74, 0x76, + 0xba, 0x82, 0x9e, 0xe0, 0xe1, 0x1e, 0x1d, 0x9f, 0xcc, 0x10, 0x1d, 0x8f, 0x8c, 0x6b, 0x0e, 0xda, + 0x02, 0x29, 0xb4, 0x11, 0xc2, 0x31, 0x4f, 0x39, 0x2e, 0x93, 0xb4, 0x61, 0xcf, 0xdf, 0xca, 0x28, + 0xb7, 0x7c, 0x60, 0x9b, 0x84, 0x53, 0x1b, 0x16, 0x49, 0xce, 0x62, 0x39, 0xba, 0x1b, 0xe2, 0x96, + 0xf3, 0xd7, 0x57, 0x15, 0xe3, 0x53, 0xd6, 0xd7, 0x19, 0x19, 0xd7, 0x1c, 0xb4, 0x07, 0x99, 0x43, + 0x56, 0xea, 0x28, 0xc7, 0x78, 0x48, 0x8b, 0xa2, 0xcc, 0xc6, 0xbd, 0xd9, 0x8b, 0xa2, 0xca, 0x3c, + 0x51, 0xb1, 0x62, 0x44, 0x86, 0x43, 0x6f, 0x10, 0x3d, 0x83, 0x5c, 0xa0, 0x8e, 0x3d, 0x18, 0xd2, + 0xb4, 0xee, 0x72, 0x6c, 0xb3, 0x3e, 0xa3, 0xca, 0x10, 0x7d, 0x06, 0xa0, 0x7b, 0x71, 0x93, 0x66, + 0x72, 0x99, 0x8d, 0x77, 0x2e, 0x10, 0x60, 0x85, 0x5b, 0xf6, 0x99, 0xa0, 0x67, 0x90, 0xf7, 0xbf, + 0xe8, 0x62, 0xb3, 0x17, 0x5e, 0x2c, 0xe3, 0x9a, 0x0b, 0xf0, 0xa9, 0x10, 0x21, 0x64, 0x43, 0xae, + 0xad, 0x70, 0x79, 0xd7, 0x16, 0x62, 0x84, 0xea, 0xbc, 0xc0, 0x91, 0x68, 0xd6, 0xf7, 0xce, 0x8c, + 0x06, 0x17, 0x48, 0xf2, 0x59, 0xdd, 0xf3, 0x01, 0xa0, 0x8e, 0x8d, 0x69, 0x3e, 0x8f, 0x5f, 0xb2, + 0x90, 0x63, 0x0c, 0x43, 0x45, 0xc7, 0x02, 0x1f, 0xaf, 0x7b, 0xc3, 0x68, 0x0b, 0x72, 0xd8, 0xec, + 0x58, 0x9a, 0x6e, 0x76, 0xfd, 0x62, 0x83, 0x27, 0x53, 0x5f, 0x9d, 0xae, 0x7c, 0x63, 0x64, 0xd6, + 0x3a, 0xc7, 0x25, 0x93, 0xcb, 0x59, 0x1c, 0xf8, 0x42, 0x5b, 0x90, 0x14, 0x01, 0x7f, 0x91, 0x4a, + 0x66, 0x6d, 0x5a, 0xfa, 0x3a, 0x9a, 0x2e, 0x88, 0xec, 0x9c, 0x93, 0x93, 0x02, 0x4e, 0xd3, 0x1d, + 0x92, 0xe8, 0x68, 0xc5, 0xeb, 0xc1, 0x02, 0x4e, 0x40, 0x51, 0x15, 0xa0, 0x8b, 0x2d, 0x85, 0xb5, + 0x42, 0x8b, 0x37, 0xe8, 0x74, 0xcb, 0x81, 0xe9, 0xba, 0xd8, 0x5a, 0x17, 0x0d, 0x53, 0x52, 0xe3, + 0x1e, 0xea, 0x5d, 0x91, 0x7f, 0x74, 0xb1, 0xc5, 0x00, 0xe1, 0xc2, 0xf6, 0xe6, 0xc4, 0xc2, 0xb6, + 0xb4, 0x0c, 0x69, 0xcf, 0x89, 0xa1, 0x24, 0xc4, 0xca, 0x7b, 0x55, 0xd6, 0xfd, 0xaa, 0xd5, 0xf7, + 0xaa, 0x52, 0xa4, 0x74, 0x1b, 0xe2, 0x74, 0xf3, 0x19, 0x48, 0x6e, 0xb6, 0xe4, 0x67, 0x65, 0xb9, + 0xc6, 0x3a, 0x6e, 0x8d, 0xe6, 0xd3, 0xba, 0xdc, 0xae, 0xd7, 0x24, 0x11, 0x3c, 0x4e, 0xe3, 0x80, + 0xfc, 0x62, 0xbb, 0x6d, 0xf1, 0xe6, 0x45, 0x17, 0x0a, 0x1d, 0x0f, 0xca, 0x0e, 0x20, 0xb2, 0x1a, + 0x5d, 0xcb, 0x6f, 0x3c, 0xfc, 0xda, 0x82, 0x5d, 0xf0, 0x08, 0x82, 0x7c, 0x95, 0xc8, 0x77, 0x42, + 0xd0, 0x40, 0xb2, 0x15, 0x1d, 0x09, 0x54, 0x32, 0x24, 0x3a, 0x47, 0xb8, 0x73, 0xcc, 0x43, 0xf5, + 0xb7, 0xa6, 0x4c, 0x4c, 0xf3, 0xd0, 0x80, 0xfa, 0x55, 0x09, 0x8d, 0x3f, 0xb5, 0xc8, 0x21, 0x28, + 0x2b, 0x24, 0x87, 0x9d, 0x50, 0xfc, 0x5c, 0xbb, 0x9e, 0xd4, 0x24, 0x14, 0x76, 0x1d, 0xf0, 0x41, + 0x0f, 0xa1, 0x60, 0x5a, 0xae, 0x42, 0x8a, 0x78, 0xee, 0x2d, 0x69, 0xd1, 0x9d, 0xab, 0x48, 0x5c, + 0x57, 0x7d, 0xbf, 0x98, 0x33, 0x2d, 0xb7, 0x39, 0x30, 0x0c, 0x06, 0x40, 0x7f, 0x12, 0x81, 0x15, + 0x16, 0x50, 0x95, 0x13, 0xd6, 0xb6, 0x51, 0x58, 0xee, 0xec, 0xcb, 0x88, 0x36, 0xb9, 0xa6, 0x67, + 0x4f, 0xe7, 0xf5, 0x7c, 0xf8, 0x52, 0x6f, 0x0d, 0xce, 0xc1, 0x29, 0xb5, 0x21, 0x1f, 0x3e, 0x26, + 0x94, 0x86, 0x44, 0x75, 0xab, 0x5e, 0x7d, 0x22, 0xcd, 0xa1, 0x02, 0x64, 0x36, 0x5b, 0x72, 0xbd, + 0xf1, 0xa8, 0xa9, 0x3c, 0xa9, 0x7f, 0xc1, 0x9a, 0xb4, 0xcd, 0x96, 0xd7, 0xa4, 0x2d, 0xc2, 0xe2, + 0x7e, 0xb3, 0xf1, 0xd9, 0x7e, 0x5d, 0x79, 0xd6, 0x68, 0x6f, 0xb5, 0xf6, 0xdb, 0x4a, 0xa3, 0x59, + 0xab, 0x7f, 0x2e, 0xc5, 0xbc, 0xfa, 0x2e, 0x21, 0xcd, 0x97, 0xfe, 0x6d, 0x1e, 0xf2, 0xbb, 0xb6, + 0xde, 0x53, 0xed, 0x21, 0x89, 0x6a, 0x27, 0x6a, 0x1f, 0x7d, 0x0a, 0x8b, 0x96, 0x41, 0x32, 0x7d, + 0x0a, 0x55, 0xbc, 0x7a, 0x21, 0x3e, 0xb9, 0xb7, 0xbf, 0x60, 0x19, 0x1a, 0xe7, 0xd0, 0xe0, 0xe5, + 0xc2, 0xa7, 0xb0, 0x68, 0xe2, 0x93, 0x71, 0x0e, 0x91, 0x29, 0x1c, 0x4c, 0x7c, 0x32, 0xc2, 0xe1, + 0x5d, 0xc8, 0x90, 0x35, 0x50, 0x4a, 0x2c, 0xfa, 0x5b, 0x99, 0x20, 0x11, 0x58, 0x86, 0xd6, 0x60, + 0xc3, 0x04, 0x9b, 0xcc, 0x27, 0xb0, 0x63, 0x13, 0xb0, 0x4d, 0x7c, 0x22, 0xb0, 0x3f, 0x82, 0x1b, + 0xe3, 0xab, 0x1b, 0x6b, 0x8f, 0x5e, 0x1b, 0x59, 0x14, 0xc9, 0x30, 0xd0, 0x97, 0xb0, 0x68, 0x58, + 0x1d, 0xd5, 0xd0, 0xdd, 0x21, 0xf7, 0x22, 0x8a, 0x73, 0xa2, 0xf6, 0xa9, 0x46, 0x65, 0xa6, 0x1a, + 0x5f, 0x58, 0xbe, 0xeb, 0xdb, 0x9c, 0x03, 0xf3, 0x27, 0x04, 0x24, 0x23, 0x63, 0x0c, 0xb6, 0xf4, + 0xf7, 0x31, 0x40, 0xe3, 0xa8, 0xe8, 0x18, 0xae, 0x11, 0xc9, 0x8c, 0x2c, 0x83, 0x8a, 0x36, 0xb3, + 0xf1, 0xcd, 0x19, 0xad, 0x30, 0xcc, 0x57, 0xb8, 0x79, 0xcb, 0xd0, 0xc2, 0x03, 0x64, 0x32, 0x22, + 0xaa, 0xd1, 0xc9, 0xa2, 0xaf, 0x60, 0x32, 0x13, 0x9f, 0x8c, 0x4c, 0xa6, 0xc3, 0xeb, 0x64, 0x32, + 0x1b, 0x77, 0x75, 0xcb, 0x54, 0x0d, 0xe5, 0x60, 0xa8, 0xd8, 0xd6, 0x49, 0xa0, 0x60, 0x67, 0x05, + 0xe7, 0xda, 0xd9, 0xe9, 0x4a, 0xb1, 0x89, 0x4f, 0x64, 0x8e, 0x57, 0x19, 0xca, 0xd6, 0xc9, 0xc4, + 0xaa, 0xbd, 0x68, 0x4e, 0xc6, 0xd2, 0x90, 0x0c, 0x6f, 0x9d, 0x33, 0x55, 0xa8, 0xc9, 0x17, 0x67, + 0x7d, 0xac, 0xc9, 0xac, 0x6a, 0x7e, 0xeb, 0x2f, 0x94, 0xf3, 0xff, 0x32, 0x02, 0x34, 0x09, 0x1b, + 0xb8, 0xa2, 0xad, 0x4f, 0xcf, 0xee, 0x43, 0xc8, 0x91, 0x69, 0xfd, 0x1d, 0x45, 0xa6, 0x78, 0x22, + 0xa2, 0xce, 0xde, 0x62, 0x3f, 0x84, 0x1c, 0x39, 0x71, 0x9f, 0x2a, 0x3a, 0x8d, 0xca, 0x32, 0xbc, + 0x4b, 0x04, 0xf4, 0x16, 0x64, 0x75, 0x93, 0xa4, 0xf5, 0xbc, 0xdd, 0x15, 0x6c, 0xf7, 0x66, 0xf8, + 0x88, 0xbf, 0xee, 0xd2, 0xaf, 0xa2, 0x70, 0x73, 0x47, 0x75, 0xb1, 0xad, 0xab, 0x86, 0xfe, 0x63, + 0xac, 0x3d, 0xd5, 0xc9, 0x86, 0x0f, 0x6d, 0xec, 0x1c, 0xa1, 0xcf, 0x61, 0x61, 0xcc, 0x60, 0xb8, + 0xc2, 0xbd, 0x39, 0x5b, 0xd6, 0x21, 0x4a, 0xb3, 0x11, 0x9b, 0x42, 0x3b, 0x61, 0xc3, 0x65, 0xa5, + 0xed, 0xc5, 0x78, 0x06, 0x2d, 0xfb, 0x21, 0x24, 0x54, 0x47, 0xb1, 0x0e, 0x79, 0x4c, 0x7a, 0x3d, + 0xc0, 0x68, 0xe0, 0xea, 0xc6, 0xfa, 0x91, 0xd1, 0x59, 0x6f, 0x8b, 0x0b, 0x56, 0x11, 0xcd, 0x54, + 0xa7, 0x75, 0x88, 0xde, 0x83, 0x82, 0x73, 0x64, 0x0d, 0x0c, 0x4d, 0x39, 0x50, 0x3b, 0xc7, 0x87, + 0xba, 0x61, 0x84, 0x7a, 0xc0, 0x79, 0x36, 0x58, 0xe1, 0x63, 0x5c, 0x66, 0x7f, 0x9e, 0x04, 0xe4, + 0xaf, 0x67, 0x67, 0xe0, 0xaa, 0x34, 0xde, 0x97, 0x61, 0x9e, 0x07, 0x1a, 0x26, 0xa3, 0xb7, 0xa6, + 0xc6, 0xe4, 0x70, 0xcf, 0x7b, 0x6b, 0x4e, 0xe6, 0x84, 0xe8, 0x7b, 0xc1, 0xfb, 0xd4, 0x99, 0x25, + 0xb2, 0x35, 0x27, 0x2e, 0x5a, 0x9f, 0x00, 0x04, 0x82, 0x54, 0x8a, 0x32, 0x79, 0x7b, 0xe6, 0xd4, + 0x60, 0x6b, 0x4e, 0x0e, 0x90, 0xa3, 0x16, 0xe4, 0xfb, 0x21, 0x0f, 0xc6, 0xab, 0x83, 0xbb, 0x33, + 0xb9, 0xbb, 0xad, 0x39, 0x79, 0x84, 0x1c, 0xfd, 0x00, 0x50, 0x67, 0xcc, 0x38, 0x8a, 0xf0, 0x35, + 0xab, 0x1c, 0x25, 0xd8, 0x9a, 0x93, 0x27, 0xb0, 0x41, 0x5f, 0xc2, 0xcd, 0xde, 0x64, 0x3d, 0xe6, + 0x75, 0xc2, 0xb4, 0x86, 0xf8, 0x14, 0xed, 0xdf, 0x9a, 0x93, 0xa7, 0x31, 0x44, 0x4f, 0x20, 0xe1, + 0xb8, 0x24, 0x0d, 0x8c, 0xd1, 0x14, 0xfc, 0xfe, 0x14, 0xce, 0xe3, 0x3a, 0xb2, 0xbe, 0x47, 0xc8, + 0x44, 0xf2, 0x43, 0x79, 0xa0, 0x67, 0x90, 0xf6, 0xaa, 0x68, 0x7e, 0xfd, 0xf2, 0xc1, 0xec, 0x0c, + 0xbd, 0x74, 0x53, 0x24, 0xa3, 0x1e, 0x2f, 0x54, 0x86, 0x4c, 0x8f, 0xa3, 0xf9, 0x6d, 0xcf, 0x55, + 0xde, 0x5b, 0x00, 0xc1, 0x81, 0xfa, 0xce, 0xc0, 0x97, 0x0c, 0x82, 0xa8, 0x41, 0x53, 0x6b, 0xdb, + 0x32, 0x0c, 0x62, 0x1b, 0x34, 0xe5, 0xf1, 0x52, 0x6b, 0x01, 0x2d, 0x7d, 0x0a, 0x09, 0xba, 0x27, + 0x92, 0xd2, 0xee, 0x37, 0x9f, 0x34, 0x5b, 0xcf, 0x9a, 0x2c, 0x45, 0xa9, 0xd5, 0xb7, 0xeb, 0xed, + 0xba, 0xd2, 0x6a, 0x6e, 0x93, 0x14, 0xe5, 0x35, 0xb8, 0xce, 0x01, 0xe5, 0x66, 0x4d, 0x79, 0x26, + 0x37, 0xc4, 0x50, 0xb4, 0xb4, 0x16, 0xcc, 0x99, 0x53, 0x10, 0x6f, 0xb6, 0x9a, 0x75, 0x69, 0x8e, + 0x66, 0xcf, 0xb5, 0x9a, 0x14, 0xa1, 0xd9, 0xb3, 0xdc, 0xda, 0x95, 0xa2, 0xcc, 0xfa, 0x2a, 0x59, + 0x00, 0xcd, 0x93, 0xc3, 0xe3, 0x78, 0x6a, 0x5e, 0x4a, 0x96, 0xfe, 0x2e, 0x02, 0x29, 0x12, 0xa8, + 0x1b, 0xe6, 0xa1, 0x85, 0x3e, 0x80, 0x74, 0x5f, 0xb5, 0xb1, 0xe9, 0xfa, 0x9e, 0x56, 0x34, 0xa0, + 0x53, 0xbb, 0x74, 0xc0, 0xeb, 0x8f, 0xa6, 0x18, 0x62, 0x43, 0x43, 0x9b, 0x20, 0x71, 0x22, 0xa7, + 0x73, 0x84, 0x7b, 0xaa, 0x1f, 0x77, 0x6e, 0x79, 0x2d, 0x7e, 0x3a, 0xbe, 0x47, 0x87, 0x3d, 0x0e, + 0xf9, 0x7e, 0x10, 0x7a, 0x4e, 0x97, 0x92, 0xfb, 0x8e, 0xbf, 0x7c, 0x1b, 0x0a, 0x23, 0x81, 0xf2, + 0x9c, 0xae, 0xd0, 0x2a, 0xed, 0x0a, 0xc5, 0x7c, 0xbf, 0xef, 0x75, 0x85, 0xa2, 0xbc, 0x21, 0xf4, + 0x81, 0xdf, 0xf2, 0x21, 0x07, 0x1c, 0xaf, 0xbc, 0xc6, 0xc3, 0xc3, 0xc2, 0x39, 0xdd, 0x9e, 0x5d, + 0x58, 0xe8, 0x59, 0x9a, 0x7e, 0x48, 0x8a, 0x16, 0xa2, 0x1d, 0xae, 0xde, 0xc3, 0x3c, 0xa5, 0x9d, + 0xc9, 0x77, 0x4a, 0x41, 0x6a, 0x32, 0x88, 0xb6, 0x21, 0xaf, 0x11, 0xaf, 0x41, 0xea, 0x42, 0xd6, + 0xab, 0xb9, 0x4e, 0x7d, 0xfa, 0xca, 0x14, 0x4d, 0x16, 0x87, 0x25, 0x4a, 0x67, 0x41, 0xcc, 0xfa, + 0x39, 0xa1, 0x13, 0x8c, 0xcf, 0x78, 0x82, 0x07, 0xb0, 0x34, 0x30, 0xf1, 0xcb, 0xbe, 0xe5, 0x60, + 0x4d, 0x19, 0x3b, 0xcb, 0x35, 0xca, 0xe5, 0x2e, 0xe7, 0x72, 0x73, 0x5f, 0x60, 0x4e, 0x3c, 0xd4, + 0x9b, 0x83, 0x89, 0xc3, 0x1a, 0x7a, 0x04, 0x49, 0xd1, 0xb6, 0x4d, 0xd1, 0xfd, 0xcd, 0xea, 0xe3, + 0x45, 0xcd, 0xca, 0xa9, 0xd1, 0x26, 0xe4, 0x4d, 0xfc, 0x32, 0x78, 0x2b, 0x91, 0x0e, 0x99, 0x67, + 0xb6, 0x89, 0x5f, 0x4e, 0xbe, 0x92, 0xc8, 0x9a, 0xfe, 0x88, 0x86, 0x5a, 0x90, 0x3a, 0x54, 0x7b, + 0xba, 0xa1, 0x63, 0xa7, 0x78, 0x83, 0xae, 0xe8, 0xbd, 0x73, 0x57, 0x34, 0x7a, 0x81, 0x23, 0xec, + 0x59, 0x30, 0xf1, 0x16, 0x46, 0x01, 0x43, 0xb2, 0xb0, 0x9b, 0xe3, 0x0b, 0x13, 0x17, 0x38, 0xa1, + 0xcb, 0x1c, 0xba, 0x30, 0xfe, 0xa5, 0xa1, 0xcf, 0x20, 0x17, 0xce, 0x1b, 0xe0, 0x12, 0x79, 0x43, + 0xb6, 0x1f, 0x4c, 0x1a, 0x36, 0x21, 0x29, 0x12, 0x86, 0xcc, 0x25, 0x12, 0x06, 0x41, 0x8c, 0x2a, + 0x24, 0x1b, 0x7b, 0xe9, 0xfa, 0xe5, 0x49, 0xd6, 0xef, 0x95, 0x9e, 0x9d, 0xae, 0x64, 0xc8, 0x0e, + 0x27, 0x5c, 0x8a, 0x64, 0x4c, 0x0f, 0xae, 0xa1, 0xc7, 0x00, 0xde, 0x6b, 0x2c, 0x87, 0xde, 0x05, + 0x4e, 0xef, 0x18, 0xed, 0x0a, 0x44, 0x7f, 0x49, 0x72, 0x80, 0x1a, 0xed, 0x40, 0x5a, 0xb8, 0x5c, + 0xd6, 0x1b, 0x9c, 0x1e, 0x0d, 0xc7, 0x03, 0x80, 0x70, 0xfb, 0x1e, 0x07, 0x52, 0xa0, 0x1b, 0x58, + 0x75, 0x30, 0x6f, 0x38, 0x3d, 0x9c, 0x31, 0x5b, 0x67, 0x3a, 0x5e, 0x3d, 0x52, 0xcd, 0x2e, 0xde, + 0x26, 0xf4, 0x95, 0x68, 0x31, 0x22, 0x33, 0x56, 0xa8, 0x09, 0x12, 0x15, 0x59, 0x30, 0x9e, 0x48, + 0x54, 0x6a, 0x6f, 0x08, 0xef, 0x48, 0xa4, 0x36, 0x35, 0xa6, 0x50, 0x9d, 0xda, 0xf1, 0xe3, 0xca, + 0x77, 0x20, 0x7f, 0x68, 0xd9, 0x3d, 0xd5, 0x55, 0x84, 0xf3, 0x5a, 0xf0, 0x3b, 0xdf, 0x5f, 0x9d, + 0xae, 0xe4, 0x36, 0xe9, 0xa8, 0x70, 0x5c, 0xb9, 0xc3, 0xe0, 0x27, 0xaa, 0x88, 0xf0, 0xcb, 0x6e, + 0xba, 0xdf, 0xfc, 0x5a, 0x61, 0x4d, 0x88, 0xba, 0xef, 0x40, 0xde, 0x3a, 0x3c, 0x34, 0x74, 0x13, + 0x2b, 0x36, 0x56, 0x1d, 0xcb, 0x2c, 0xbe, 0x19, 0xf0, 0xbe, 0x39, 0x3e, 0x26, 0xd3, 0x21, 0xd4, + 0x84, 0x79, 0xda, 0xa8, 0x70, 0x8a, 0x8b, 0xf4, 0x78, 0x2e, 0xd9, 0xf4, 0x90, 0x39, 0x17, 0x74, + 0x07, 0xe0, 0x85, 0x8e, 0x4f, 0x94, 0xe7, 0x03, 0x6c, 0x0f, 0x8b, 0xc5, 0x60, 0x2f, 0x89, 0xc0, + 0x3f, 0x23, 0x60, 0xf4, 0x2d, 0x58, 0xd4, 0x1d, 0x25, 0x98, 0x82, 0x28, 0x64, 0xb0, 0xf8, 0x76, + 0x20, 0x0e, 0x23, 0xdd, 0x19, 0x4d, 0x5f, 0xd0, 0xfb, 0x90, 0xd6, 0x70, 0x1f, 0x9b, 0x9a, 0xd3, + 0x32, 0x8b, 0xaf, 0xd1, 0x92, 0xf8, 0xda, 0xd9, 0xe9, 0x4a, 0xba, 0x26, 0x80, 0xdc, 0xc9, 0xf9, + 0x58, 0xe8, 0x53, 0xc8, 0x7b, 0x1f, 0xed, 0x61, 0x1f, 0x3b, 0xc5, 0xf7, 0x28, 0x5d, 0x91, 0x1c, + 0x6c, 0x2d, 0x34, 0x22, 0xc2, 0x5e, 0x18, 0x1f, 0x7d, 0x09, 0x59, 0x06, 0xc1, 0x5a, 0xcb, 0xac, + 0x0c, 0x8b, 0x4b, 0x54, 0x4e, 0x0f, 0x66, 0x94, 0x93, 0xdf, 0x49, 0xf5, 0xee, 0xec, 0x6a, 0x01, + 0x6e, 0x72, 0x88, 0x37, 0xfa, 0x43, 0xc8, 0x0a, 0x3d, 0x7c, 0x6c, 0x1d, 0x38, 0xc5, 0x6f, 0x9c, + 0x7b, 0x31, 0x36, 0x3a, 0xd7, 0x8e, 0x4f, 0x2a, 0xbc, 0x4c, 0x90, 0x1b, 0x6a, 0x03, 0x29, 0x1f, + 0x45, 0xe4, 0xe8, 0x50, 0x7b, 0x50, 0xbe, 0xb4, 0x0e, 0x88, 0xca, 0xaf, 0xaf, 0x46, 0xd6, 0x62, + 0x5e, 0x42, 0xb0, 0xd8, 0xc4, 0x27, 0x41, 0xab, 0x79, 0x6c, 0x1d, 0x34, 0x6a, 0xf2, 0xa2, 0x39, + 0x0e, 0xd5, 0xd0, 0xe7, 0x90, 0x0b, 0x3e, 0x94, 0x70, 0x8a, 0xb7, 0xce, 0x6d, 0x20, 0x8d, 0x19, + 0xa7, 0xff, 0x74, 0xc2, 0x91, 0xb3, 0x4e, 0xe0, 0x0b, 0xdd, 0x86, 0xb4, 0x66, 0x5b, 0x7d, 0x16, + 0xc3, 0x5f, 0xa7, 0x0b, 0x14, 0xed, 0x4f, 0xdb, 0xea, 0xd3, 0xe0, 0xac, 0x40, 0xde, 0xc6, 0x7d, + 0x43, 0xed, 0xe0, 0x1e, 0x09, 0x8a, 0xd6, 0x61, 0x71, 0x99, 0xce, 0xbe, 0x31, 0xf3, 0xf1, 0x78, + 0xc4, 0xc2, 0x3e, 0x02, 0xfc, 0x5a, 0x87, 0x68, 0x1f, 0x40, 0x1d, 0x68, 0xba, 0xab, 0xf4, 0x2c, + 0x0d, 0x17, 0x57, 0xce, 0x7d, 0x58, 0x35, 0xca, 0xbc, 0x4c, 0x08, 0x77, 0x2c, 0x0d, 0x7b, 0x77, + 0xde, 0x02, 0x80, 0xde, 0x87, 0x0c, 0xdd, 0x1a, 0x97, 0xfe, 0x2a, 0xdd, 0xdc, 0x02, 0x97, 0x7e, + 0xba, 0x66, 0x5b, 0x7d, 0x26, 0x72, 0x2a, 0x00, 0x26, 0x67, 0x07, 0xb2, 0xdd, 0x8e, 0xe2, 0xbb, + 0xd3, 0xdb, 0x54, 0x37, 0x3e, 0x99, 0x71, 0x2d, 0x8f, 0xaa, 0x13, 0x1c, 0xec, 0x35, 0x11, 0x17, + 0x1e, 0x55, 0x05, 0xcc, 0x91, 0x33, 0xdd, 0x8e, 0xf7, 0x41, 0x4a, 0x6e, 0xd6, 0x29, 0xe7, 0x06, + 0x5d, 0x0a, 0x96, 0xdc, 0x6c, 0x84, 0x99, 0x74, 0x13, 0x78, 0x4b, 0x5d, 0xa1, 0xe5, 0x2a, 0x3b, + 0xb3, 0x3b, 0xb3, 0xe7, 0x5d, 0x79, 0x46, 0x5d, 0x76, 0x5a, 0x87, 0xf4, 0x60, 0x3b, 0x90, 0xb5, + 0x06, 0xee, 0x81, 0x35, 0x30, 0x35, 0xe5, 0xf0, 0xd8, 0x29, 0xbe, 0x41, 0x77, 0x7b, 0xa1, 0xc6, + 0xa9, 0xb7, 0xbb, 0x16, 0x67, 0xb4, 0xf9, 0xc4, 0x91, 0x33, 0x82, 0xeb, 0xe6, 0xb1, 0x83, 0x7e, + 0x04, 0x19, 0xdd, 0xf4, 0xe7, 0xb8, 0x7b, 0xf1, 0x39, 0x90, 0xa8, 0x39, 0x1a, 0xa6, 0x37, 0x05, + 0x70, 0x9e, 0x64, 0x86, 0x9f, 0x44, 0x60, 0xf5, 0x6b, 0x1a, 0xae, 0x4e, 0xf1, 0x9d, 0x73, 0xef, + 0xab, 0x67, 0xe8, 0xb8, 0xbe, 0x7e, 0x5e, 0xc7, 0xd5, 0x41, 0x25, 0x48, 0xbb, 0xb8, 0xd7, 0xb7, + 0x6c, 0xd5, 0x1e, 0x16, 0xdf, 0x0a, 0x3e, 0x41, 0xf0, 0xc0, 0xe8, 0x87, 0x50, 0x18, 0x6d, 0x89, + 0xdd, 0xbb, 0x42, 0x4b, 0x4c, 0xce, 0x87, 0xdb, 0x7f, 0x68, 0x9d, 0x16, 0x21, 0xec, 0xa6, 0x47, + 0x51, 0x0d, 0x43, 0x39, 0x18, 0x16, 0xdf, 0x0d, 0xb6, 0x23, 0xbc, 0xd1, 0xb2, 0x61, 0x54, 0x86, + 0x4b, 0xbf, 0x88, 0xc0, 0xc2, 0x58, 0xdc, 0x46, 0x3f, 0x84, 0xa4, 0x69, 0x69, 0x81, 0xc7, 0x21, + 0x75, 0x2e, 0xff, 0xf9, 0xa6, 0xa5, 0xb1, 0xb7, 0x21, 0x1f, 0x74, 0x75, 0xf7, 0x68, 0x70, 0xb0, + 0xde, 0xb1, 0x7a, 0xf7, 0xbd, 0x95, 0x6b, 0x07, 0xfe, 0xdf, 0xf7, 0xfb, 0xc7, 0xdd, 0xfb, 0xf4, + 0xaf, 0xfe, 0xc1, 0x3a, 0x23, 0x93, 0xe7, 0x09, 0xd7, 0x86, 0x86, 0xde, 0x83, 0x02, 0x7e, 0xd9, + 0xd7, 0xed, 0x40, 0xed, 0x10, 0x0d, 0xf8, 0x9d, 0xbc, 0x3f, 0x48, 0x94, 0x94, 0x5f, 0xc3, 0xff, + 0x2a, 0x0a, 0x85, 0x91, 0x70, 0x48, 0xea, 0x1e, 0xda, 0xa2, 0x0a, 0xd5, 0x3d, 0x04, 0x72, 0xce, + 0x5b, 0x8f, 0xe0, 0x5b, 0xc5, 0xd8, 0x55, 0xdf, 0x2a, 0x86, 0x1f, 0x16, 0x25, 0x2e, 0xf0, 0xb0, + 0xe8, 0x23, 0xb8, 0xa1, 0x3b, 0x8a, 0x69, 0x99, 0xe2, 0x82, 0xc1, 0x6b, 0xba, 0x04, 0x5f, 0xf6, + 0x5d, 0xd3, 0x9d, 0xa6, 0x65, 0xb2, 0xab, 0x05, 0x6f, 0xd7, 0xfe, 0x23, 0xc0, 0xe4, 0xf8, 0x23, + 0x40, 0xaf, 0x47, 0x1f, 0x97, 0x12, 0x4b, 0xff, 0x12, 0x81, 0x74, 0xf0, 0x35, 0x7e, 0x34, 0xdc, + 0x39, 0x1c, 0xab, 0x05, 0x2f, 0xf9, 0xc8, 0x27, 0x2c, 0x85, 0xd8, 0x05, 0xa4, 0x70, 0x1b, 0x12, + 0x07, 0x43, 0x51, 0xa3, 0xa5, 0x2a, 0x59, 0x3e, 0x5b, 0xbc, 0x42, 0xea, 0x81, 0xf8, 0xc1, 0x50, + 0x3c, 0x98, 0x5a, 0xfa, 0x63, 0xc8, 0x04, 0xe2, 0xee, 0x68, 0x67, 0x22, 0x72, 0x89, 0xce, 0xc4, + 0x1b, 0x30, 0xcf, 0xc3, 0x02, 0xd3, 0xbd, 0x1c, 0xa7, 0x4e, 0xb0, 0x90, 0x90, 0xf8, 0x92, 0x84, + 0x03, 0x3e, 0xfb, 0x7f, 0xc7, 0x20, 0x1b, 0x8c, 0xa0, 0xc4, 0xd6, 0x75, 0xb3, 0x63, 0xd3, 0xf0, + 0x45, 0x67, 0x8f, 0x79, 0xcf, 0x8d, 0x04, 0x98, 0xc4, 0xd5, 0x9e, 0x6e, 0x2a, 0xf4, 0xa9, 0x4a, + 0x48, 0xbf, 0x53, 0x3d, 0xdd, 0x7c, 0x4a, 0xa0, 0x14, 0x45, 0x7d, 0xc9, 0x51, 0x62, 0x21, 0x14, + 0xf5, 0x25, 0x43, 0x59, 0xa2, 0xa9, 0xaa, 0xed, 0x52, 0x09, 0xc5, 0x02, 0x29, 0xa8, 0xed, 0x06, + 0x5f, 0x1d, 0x26, 0x26, 0xbd, 0x3a, 0x34, 0x21, 0xef, 0xe7, 0x0c, 0x27, 0x26, 0xb6, 0xf9, 0x75, + 0x43, 0xf9, 0x12, 0x49, 0x83, 0xff, 0x41, 0x18, 0x89, 0x28, 0xee, 0x04, 0x81, 0x24, 0x2b, 0xed, + 0xa8, 0x9d, 0x23, 0xac, 0x38, 0xfa, 0x8f, 0x59, 0x3b, 0xc0, 0x13, 0x0b, 0x85, 0xef, 0xe9, 0x3f, + 0xc6, 0x4b, 0x7f, 0x13, 0x81, 0x5c, 0x88, 0x17, 0x6a, 0x40, 0x81, 0xae, 0x6e, 0xac, 0xbd, 0x7d, + 0xdb, 0x7b, 0x9f, 0x4f, 0x86, 0x27, 0x16, 0xb3, 0x39, 0x2b, 0x30, 0xa4, 0x91, 0x3c, 0x94, 0xb1, + 0xf2, 0x5e, 0xb7, 0x85, 0xd5, 0x38, 0x4b, 0x39, 0x85, 0x9f, 0xb8, 0x65, 0x2d, 0x1f, 0xa6, 0x05, + 0x9b, 0xf1, 0x4b, 0x26, 0x64, 0x02, 0x99, 0xcb, 0x0c, 0xf6, 0xf3, 0x6d, 0x88, 0x7b, 0xde, 0x6c, + 0xd6, 0x2e, 0xb2, 0xeb, 0xbb, 0xb8, 0x9f, 0x45, 0x60, 0x71, 0x52, 0x06, 0x11, 0xb2, 0x4b, 0xa6, + 0x6d, 0x33, 0xd9, 0xe5, 0x9d, 0x60, 0x66, 0xc7, 0x34, 0x50, 0xbc, 0x8a, 0xf0, 0x73, 0xbb, 0x37, + 0x3d, 0x3b, 0x60, 0x0a, 0x58, 0x08, 0xd9, 0x01, 0xa9, 0xe0, 0x82, 0x96, 0xf0, 0xef, 0x31, 0xc8, + 0x8f, 0xdc, 0xbe, 0x3c, 0x85, 0xf9, 0xae, 0x61, 0x1d, 0xa8, 0x06, 0xef, 0x5a, 0x7f, 0xe7, 0x52, + 0xa1, 0x6c, 0xfd, 0x11, 0xe5, 0xb1, 0x35, 0x27, 0x73, 0x6e, 0xc8, 0x81, 0x85, 0xe0, 0x35, 0x0b, + 0xfb, 0x21, 0x11, 0x93, 0x6c, 0xfd, 0x72, 0x53, 0xf8, 0xf7, 0x30, 0x14, 0x71, 0x6b, 0x4e, 0x2e, + 0xd8, 0x61, 0x10, 0xea, 0x41, 0x61, 0xe4, 0x6e, 0x87, 0x5f, 0x09, 0x54, 0xaf, 0x3a, 0xa5, 0x6c, + 0x9d, 0x6c, 0xd1, 0xbc, 0x37, 0x00, 0x58, 0xfa, 0x03, 0x28, 0x8c, 0x2c, 0x8a, 0x9c, 0x07, 0xc3, + 0xe1, 0x51, 0x2d, 0x4f, 0x7c, 0x18, 0x43, 0x6a, 0xaa, 0x3d, 0x2c, 0xf3, 0x51, 0x7e, 0x1e, 0x77, + 0x21, 0x17, 0x9a, 0x02, 0xe5, 0x21, 0xaa, 0xb2, 0x27, 0x84, 0x69, 0x39, 0xaa, 0xf2, 0xc7, 0x87, + 0x4b, 0x79, 0x98, 0x67, 0xf2, 0x0d, 0xea, 0x77, 0x05, 0x20, 0x25, 0xf2, 0x87, 0xd2, 0x1a, 0xa4, + 0xbd, 0x44, 0x1a, 0x65, 0x21, 0x55, 0x6b, 0xec, 0x95, 0x2b, 0xdb, 0xf5, 0x9a, 0x34, 0x87, 0x72, + 0x90, 0x96, 0xeb, 0xe5, 0x1a, 0xed, 0xb9, 0x4a, 0x91, 0x8f, 0x53, 0x7f, 0xfa, 0xb3, 0x95, 0x08, + 0x0f, 0x32, 0xf3, 0x52, 0xf2, 0x71, 0x3c, 0x85, 0xa4, 0x6b, 0xa5, 0xff, 0x4d, 0x03, 0xaa, 0xa9, + 0xae, 0x4a, 0x84, 0x72, 0x81, 0xce, 0x64, 0xf4, 0x1c, 0x6b, 0x9a, 0xd8, 0x64, 0x8c, 0x5f, 0xa5, + 0xc9, 0x78, 0xa9, 0x5e, 0xe7, 0x78, 0x67, 0x72, 0xfe, 0x0a, 0x9d, 0xc9, 0x70, 0xdf, 0x27, 0x76, + 0xa5, 0xbe, 0xcf, 0x53, 0x48, 0xb2, 0x2a, 0x93, 0xbd, 0x31, 0x9b, 0xde, 0x56, 0x18, 0x3f, 0x18, + 0xde, 0xad, 0x71, 0xea, 0xa6, 0x6b, 0x0f, 0xbd, 0xf7, 0x30, 0x0c, 0xe6, 0xb7, 0x47, 0x52, 0xaf, + 0xb2, 0x3d, 0x92, 0x9e, 0xde, 0x1e, 0xf9, 0x01, 0x70, 0xbb, 0x10, 0x49, 0x31, 0x9c, 0xfb, 0x34, + 0x64, 0xc2, 0x76, 0x98, 0x11, 0xf0, 0xac, 0x38, 0x6b, 0x07, 0xbe, 0xd0, 0x8f, 0x00, 0x89, 0x7b, + 0xd9, 0x80, 0xe4, 0xd9, 0x95, 0xce, 0xfb, 0x53, 0xb7, 0x46, 0x09, 0x26, 0x1d, 0x80, 0x78, 0x0f, + 0xee, 0x8d, 0x39, 0x4b, 0x6d, 0x00, 0xde, 0xe0, 0x35, 0x0f, 0xad, 0x19, 0xc2, 0xc4, 0x32, 0x24, + 0x89, 0xfb, 0xed, 0x63, 0xa6, 0xff, 0x5e, 0xdc, 0xe6, 0x40, 0x6e, 0xb3, 0x7d, 0xc8, 0x06, 0x0f, + 0x09, 0x49, 0x10, 0x3b, 0xc6, 0x43, 0x6e, 0xda, 0xe4, 0x4f, 0xf4, 0x18, 0x12, 0x7e, 0x76, 0x31, + 0xfd, 0xa1, 0xf8, 0xd4, 0xd3, 0x27, 0xcb, 0x95, 0x19, 0x8b, 0x8f, 0xa3, 0x0f, 0x69, 0x8a, 0x9d, + 0x0d, 0x0a, 0x12, 0x35, 0x21, 0xe7, 0x0c, 0xec, 0x17, 0xfa, 0x0b, 0xd5, 0x50, 0xba, 0x96, 0x6a, + 0xd0, 0x89, 0xf2, 0x1b, 0x77, 0xa6, 0x3d, 0xb4, 0xe2, 0xb8, 0x8f, 0x2c, 0xd5, 0x10, 0xad, 0x11, + 0x27, 0x00, 0x43, 0x1f, 0x79, 0x17, 0x82, 0xfc, 0x06, 0x9d, 0x5f, 0x2e, 0x23, 0x6e, 0x86, 0x41, + 0x3f, 0x27, 0xba, 0xbf, 0x0c, 0x44, 0x22, 0x3b, 0x57, 0x11, 0x4c, 0x1f, 0x41, 0x8b, 0xb6, 0xbe, + 0x17, 0xd9, 0x19, 0x5e, 0xdd, 0x1c, 0xf4, 0xfc, 0xc8, 0x6e, 0xfb, 0x30, 0x0d, 0x6d, 0x41, 0xda, + 0x8b, 0xe5, 0xd4, 0xfc, 0xf3, 0x1b, 0x6f, 0x9c, 0x23, 0xb1, 0xdd, 0x91, 0x8e, 0x85, 0x4f, 0xec, + 0xa5, 0xd8, 0x11, 0x29, 0xea, 0x7b, 0xc3, 0xd2, 0xff, 0x64, 0x21, 0xdf, 0x1e, 0xf6, 0x27, 0x79, + 0xbf, 0xd8, 0x14, 0xef, 0x17, 0x9f, 0xed, 0x5e, 0x26, 0x7d, 0xb5, 0x7b, 0x19, 0x78, 0xb5, 0xf7, + 0x32, 0x99, 0x57, 0xe6, 0xfd, 0xf2, 0x57, 0xf2, 0x7e, 0xaf, 0xec, 0x96, 0x2e, 0x7a, 0x89, 0x5b, + 0xba, 0xef, 0x42, 0x4e, 0xb5, 0x6d, 0x75, 0xc8, 0x7f, 0x87, 0xa3, 0x51, 0x57, 0x99, 0x63, 0x67, + 0x74, 0x76, 0xba, 0x92, 0x29, 0x93, 0x41, 0xfa, 0xd3, 0x1b, 0xc1, 0x21, 0xa3, 0x7a, 0x20, 0xcd, + 0xf7, 0xb0, 0xb9, 0x57, 0xe9, 0x61, 0x0b, 0xd3, 0x3d, 0x6c, 0x0d, 0xe2, 0xf4, 0x87, 0x3e, 0x4c, + 0xef, 0xa7, 0x89, 0x3c, 0xac, 0xbe, 0xeb, 0x81, 0xdf, 0xfa, 0x50, 0x6a, 0xf4, 0x23, 0x58, 0x12, + 0xaf, 0x69, 0x89, 0x3e, 0xf8, 0xb7, 0xa8, 0x81, 0x9f, 0x51, 0x95, 0xce, 0x4e, 0x57, 0x8a, 0xb2, + 0x8f, 0xe5, 0xf3, 0x63, 0x75, 0x20, 0x91, 0x45, 0xd1, 0x9e, 0x38, 0xae, 0x39, 0xe8, 0x0b, 0xc8, + 0x52, 0xfb, 0xee, 0xe1, 0xde, 0x01, 0xb6, 0x45, 0xa8, 0x7d, 0x30, 0xdb, 0x7a, 0x89, 0xa1, 0xef, + 0x50, 0x42, 0xd1, 0x3b, 0xc3, 0x1e, 0xc4, 0x41, 0x0f, 0x20, 0xa1, 0x1a, 0x3a, 0x8d, 0x95, 0x5f, + 0xf7, 0xbb, 0x3e, 0x86, 0xc8, 0x5e, 0x21, 0x07, 0xc3, 0x92, 0x74, 0x7e, 0xd7, 0x33, 0xbc, 0x9a, + 0xe9, 0x21, 0x69, 0xe9, 0xa7, 0x31, 0x00, 0x7f, 0xb1, 0xe8, 0xdb, 0x70, 0xb3, 0x7f, 0x34, 0x74, + 0xf4, 0x8e, 0x6a, 0x28, 0x36, 0xee, 0xdb, 0xd8, 0xc1, 0x26, 0xcb, 0xfc, 0xa9, 0x5e, 0x67, 0xe5, + 0x1b, 0x62, 0x58, 0x0e, 0x8d, 0xa2, 0x4f, 0xe0, 0x86, 0x61, 0x75, 0x27, 0xd1, 0x05, 0xfb, 0x1e, + 0xd7, 0x39, 0xce, 0x08, 0xb1, 0x4a, 0xaa, 0xb5, 0xbe, 0x7a, 0xa0, 0x1b, 0x7e, 0x2b, 0xe4, 0x93, + 0x8b, 0x0a, 0x7a, 0xbd, 0xea, 0xb1, 0x10, 0xcf, 0x6a, 0x7c, 0xa6, 0xe8, 0x87, 0xe3, 0x2f, 0x13, + 0x3e, 0xbe, 0xf0, 0x0c, 0xd3, 0x1f, 0x28, 0x94, 0xde, 0x00, 0xf0, 0xe7, 0xa7, 0x17, 0xfe, 0xdb, + 0xdb, 0x7e, 0xc2, 0xca, 0x9f, 0x0e, 0x94, 0xee, 0x7d, 0xcd, 0xfb, 0x00, 0x80, 0x79, 0xb9, 0xbe, + 0xd3, 0x7a, 0x5a, 0x17, 0x2f, 0x04, 0x96, 0x5a, 0x23, 0x71, 0x70, 0x3c, 0x6e, 0x45, 0x66, 0x8c, + 0x5b, 0xfc, 0xd2, 0xfe, 0x33, 0x88, 0x13, 0x63, 0x22, 0xb3, 0xd7, 0x9b, 0xfb, 0x3b, 0xd2, 0x1c, + 0x4a, 0x43, 0xa2, 0xbc, 0xdd, 0x28, 0xef, 0x49, 0x11, 0xb4, 0x08, 0xd2, 0xce, 0xfe, 0x76, 0xbb, + 0x21, 0xd7, 0x1f, 0x35, 0x5a, 0x4d, 0x85, 0x22, 0x44, 0xd1, 0x32, 0x2c, 0xb5, 0x49, 0x06, 0xae, + 0x34, 0x76, 0x76, 0xb7, 0x1b, 0xd5, 0x46, 0x5b, 0x91, 0xeb, 0xd5, 0x96, 0x5c, 0x53, 0xda, 0x5f, + 0xec, 0xd6, 0xa5, 0x58, 0x20, 0xf0, 0xfc, 0x75, 0x1c, 0x24, 0xe6, 0x98, 0x26, 0x84, 0x9e, 0xe8, + 0x25, 0x9e, 0x04, 0xfc, 0xde, 0xf3, 0xbf, 0x89, 0x61, 0x2b, 0xf1, 0x8a, 0x32, 0xfd, 0xf9, 0x2b, + 0x64, 0xfa, 0xc9, 0x57, 0xf5, 0x06, 0x61, 0xd6, 0xf8, 0x14, 0x0e, 0x90, 0xf1, 0xab, 0x04, 0xc8, + 0x80, 0x86, 0xfc, 0x3c, 0x0a, 0x10, 0xd0, 0x8d, 0xef, 0x05, 0xff, 0x59, 0x8e, 0xe9, 0xb7, 0xe0, + 0x23, 0xa5, 0xed, 0xd6, 0x9c, 0xf8, 0x47, 0x3b, 0x1e, 0x41, 0x4a, 0xe3, 0x39, 0x25, 0x4f, 0x3d, + 0xdf, 0x9e, 0x39, 0xf5, 0xdc, 0x9a, 0x93, 0x3d, 0x62, 0xf4, 0x49, 0xe8, 0x97, 0xd6, 0x77, 0x67, + 0x72, 0x0d, 0x5b, 0xe2, 0xe7, 0x07, 0x65, 0x98, 0x67, 0x31, 0x9c, 0x8b, 0x69, 0xea, 0xaf, 0x57, + 0x47, 0x4c, 0x63, 0x6b, 0x4e, 0xe6, 0x84, 0xbc, 0x0c, 0x4e, 0x42, 0x62, 0x60, 0xea, 0x96, 0x79, + 0x4f, 0x0e, 0x3e, 0x99, 0x17, 0x3d, 0x5f, 0xe2, 0x4d, 0xe8, 0xdf, 0xaa, 0x8b, 0x35, 0xf6, 0x32, + 0x69, 0xdf, 0x7c, 0xe1, 0x01, 0x22, 0x28, 0x0f, 0xc0, 0xc7, 0x75, 0xb3, 0x2b, 0x45, 0x69, 0xf1, + 0x4c, 0x12, 0x79, 0xf2, 0x15, 0xbb, 0xf7, 0x5d, 0x90, 0x46, 0x7f, 0x3e, 0x1b, 0xf0, 0x41, 0x0b, + 0x90, 0xdb, 0x79, 0x5a, 0xad, 0xb6, 0x1b, 0x3b, 0xf5, 0xbd, 0x76, 0x79, 0x67, 0x97, 0xbd, 0xc5, + 0xa6, 0x76, 0xdf, 0x6a, 0xd4, 0xa4, 0xe8, 0xbd, 0x03, 0xb8, 0x39, 0xe5, 0xf7, 0xd6, 0xe8, 0x26, + 0x5c, 0x6b, 0xb6, 0xda, 0x4a, 0xa3, 0x56, 0x6f, 0xb6, 0x1b, 0xed, 0x2f, 0x94, 0x6a, 0x6b, 0x7b, + 0x7f, 0xa7, 0x29, 0xcd, 0x11, 0x7f, 0xf2, 0xa8, 0xde, 0xac, 0xcb, 0xe5, 0x76, 0xbd, 0xa6, 0x94, + 0xb7, 0x9f, 0x95, 0xbf, 0x20, 0x5e, 0xa6, 0x08, 0x8b, 0x3e, 0xb4, 0xf2, 0x85, 0xf7, 0x6f, 0x70, + 0x44, 0xef, 0x7d, 0x17, 0x0a, 0x23, 0xa6, 0x4c, 0x5c, 0xe2, 0xee, 0x7e, 0x65, 0xbb, 0x51, 0x9d, + 0xf8, 0x8e, 0x0a, 0x65, 0x20, 0xd9, 0xda, 0xdc, 0xdc, 0x6e, 0x34, 0xeb, 0x52, 0xec, 0xde, 0x87, + 0x90, 0x0d, 0x26, 0xfe, 0x48, 0x82, 0xec, 0xf7, 0x5b, 0xcd, 0xba, 0xb2, 0x59, 0x6e, 0x6c, 0xef, + 0xcb, 0x64, 0x97, 0x08, 0xf2, 0xdc, 0xb7, 0x09, 0x58, 0xe4, 0xde, 0xbb, 0x90, 0x0b, 0x65, 0xd9, + 0x84, 0xa7, 0x58, 0xd2, 0x1c, 0x91, 0xa9, 0xf8, 0x37, 0x44, 0xea, 0x35, 0x29, 0x52, 0x59, 0xfb, + 0xf5, 0x7f, 0x2e, 0xcf, 0xfd, 0xfa, 0x6c, 0x39, 0xf2, 0x9b, 0xb3, 0xe5, 0xc8, 0x6f, 0xcf, 0x96, + 0x23, 0xff, 0x71, 0xb6, 0x1c, 0xf9, 0x8b, 0xdf, 0x2d, 0xcf, 0xfd, 0xe6, 0x77, 0xcb, 0x73, 0xbf, + 0xfd, 0xdd, 0xf2, 0xdc, 0xf7, 0xe7, 0xd9, 0x3f, 0x71, 0xf3, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0x1e, 0xc5, 0x86, 0xa6, 0x4d, 0x47, 0x00, 0x00, } func (this *ForeignKeyReference) Equal(that interface{}) bool { diff --git a/pkg/sql/catalog/descpb/structured.proto b/pkg/sql/catalog/descpb/structured.proto index bb7cb968be03..b3ea3d449cfa 100644 --- a/pkg/sql/catalog/descpb/structured.proto +++ b/pkg/sql/catalog/descpb/structured.proto @@ -1365,6 +1365,10 @@ message TypeDescriptor { // Represents a special multi-region enum type which tracks available regions // as its enum values. MULTIREGION_ENUM = 2; + // Represents the implicit record type created on behalf of each table. This + // kind of TypeDescriptor is *never* persisted to disk! If you are here, + // thinking about using or persisting this value, you should *not* do that! + TABLE_IMPLICIT_RECORD_TYPE = 3; // Add more entries as we support more user defined types. } optional Kind kind = 5 [(gogoproto.nullable) = false]; diff --git a/pkg/sql/catalog/descriptor.go b/pkg/sql/catalog/descriptor.go index 3e46bfef2c19..ce7f7bcb2df3 100644 --- a/pkg/sql/catalog/descriptor.go +++ b/pkg/sql/catalog/descriptor.go @@ -678,7 +678,9 @@ type TypeDescriptor interface { // types.T. Implementers of tree.TypeReferenceResolver should implement this // interface as well. type TypeDescriptorResolver interface { - // GetTypeDescriptor returns the type descriptor for the input ID. + // GetTypeDescriptor returns the type descriptor for the input ID. Note that + // the returned type descriptor may be the implicitly-defined record type for + // a table, if the input ID points to a table descriptor. GetTypeDescriptor(ctx context.Context, id descpb.ID) (tree.TypeName, TypeDescriptor, error) } diff --git a/pkg/sql/catalog/descs/BUILD.bazel b/pkg/sql/catalog/descs/BUILD.bazel index 7a35ad873c29..b1c0a52f163b 100644 --- a/pkg/sql/catalog/descs/BUILD.bazel +++ b/pkg/sql/catalog/descs/BUILD.bazel @@ -90,8 +90,6 @@ go_test( "//pkg/sql/catalog/descpb", "//pkg/sql/catalog/lease", "//pkg/sql/catalog/tabledesc", - "//pkg/sql/pgwire/pgcode", - "//pkg/sql/pgwire/pgerror", "//pkg/sql/privilege", "//pkg/sql/sem/tree", "//pkg/sql/tests", @@ -102,6 +100,7 @@ go_test( "//pkg/util/leaktest", "//pkg/util/log", "//pkg/util/randutil", + "@com_github_lib_pq//oid", "@com_github_stretchr_testify//require", ], ) diff --git a/pkg/sql/catalog/descs/collection_test.go b/pkg/sql/catalog/descs/collection_test.go index 9d0e62b28f7d..35331fde89c8 100644 --- a/pkg/sql/catalog/descs/collection_test.go +++ b/pkg/sql/catalog/descs/collection_test.go @@ -27,8 +27,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog/descs" "github.com/cockroachdb/cockroach/pkg/sql/catalog/lease" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" - "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" - "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/tests" @@ -38,6 +36,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/lib/pq/oid" "github.com/stretchr/testify/require" ) @@ -422,7 +421,7 @@ func TestSyntheticDescriptorResolution(t *testing.T) { // Regression test to ensure that resolving a type descriptor which is not a // type using the DistSQLTypeResolver is properly handled. -func TestDistSQLTypeResolver_GetTypeDescriptor_WrongType(t *testing.T) { +func TestDistSQLTypeResolver_GetTypeDescriptor_FromTable(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -433,20 +432,31 @@ func TestDistSQLTypeResolver_GetTypeDescriptor_WrongType(t *testing.T) { s := tc.Server(0) tdb := sqlutils.MakeSQLRunner(tc.ServerConn(0)) - tdb.Exec(t, `CREATE TABLE t()`) + tdb.Exec(t, `CREATE TABLE t(a INT PRIMARY KEY, b STRING)`) var id descpb.ID tdb.QueryRow(t, "SELECT $1::regclass::int", "t").Scan(&id) execCfg := s.ExecutorConfig().(sql.ExecutorConfig) + var name tree.TypeName + var typedesc catalog.TypeDescriptor err := sql.DescsTxn(ctx, &execCfg, func( ctx context.Context, txn *kv.Txn, descriptors *descs.Collection, ) error { tr := descs.NewDistSQLTypeResolver(descriptors, txn) - _, _, err := tr.GetTypeDescriptor(ctx, id) + var err error + name, typedesc, err = tr.GetTypeDescriptor(ctx, id) return err }) - require.Regexp(t, `descriptor \d+ is a relation not a type`, err) - require.Equal(t, pgcode.WrongObjectType, pgerror.GetPGCode(err)) + require.NoError(t, err) + require.Equal(t, "t", name.ObjectName.String()) + typ, err := typedesc.MakeTypesT(ctx, &name, nil) + require.NoError(t, err) + require.Equal(t, types.TupleFamily, typ.Family()) + require.Equal(t, "t", typ.TypeMeta.Name.Name) + require.Equal(t, []string{"a", "b"}, typ.TupleLabels()) + require.Equal(t, types.IntFamily, typ.TupleContents()[0].Family()) + require.Equal(t, types.StringFamily, typ.TupleContents()[1].Family()) + require.Equal(t, oid.Oid(id+100000), typ.Oid()) } // TestMaybeFixSchemaPrivilegesIntegration ensures that schemas that have diff --git a/pkg/sql/catalog/descs/dist_sql_type_resolver.go b/pkg/sql/catalog/descs/dist_sql_type_resolver.go index 0ba08ef28c82..eb56027ae021 100644 --- a/pkg/sql/catalog/descs/dist_sql_type_resolver.go +++ b/pkg/sql/catalog/descs/dist_sql_type_resolver.go @@ -102,8 +102,25 @@ func (dt DistSQLTypeResolver) GetTypeDescriptor( if err != nil { return tree.TypeName{}, nil, err } - typeDesc, isType := desc.(catalog.TypeDescriptor) - if !isType { + var typeDesc catalog.TypeDescriptor + switch t := desc.(type) { + case catalog.TypeDescriptor: + // User-defined type. + typeDesc = t + case catalog.TableDescriptor: + // If we find a table descriptor when we were expecting a type descriptor, + // we return the implicitly-created type descriptor that is created for each + // table. Make sure that we hydrate the table ahead of time, since we expect + // that the table's types are fully hydrated below. + t, err = dt.descriptors.hydrateTypesInTableDesc(ctx, dt.txn, t) + if err != nil { + return tree.TypeName{}, nil, err + } + typeDesc, err = typedesc.CreateImplicitRecordTypeFromTableDesc(t) + if err != nil { + return tree.TypeName{}, nil, err + } + default: return tree.TypeName{}, nil, pgerror.Newf(pgcode.WrongObjectType, "descriptor %d is a %s not a %s", id, desc.DescriptorType(), catalog.Type) } diff --git a/pkg/sql/catalog/descs/object.go b/pkg/sql/catalog/descs/object.go index 8a387d31a060..9977e84f146c 100644 --- a/pkg/sql/catalog/descs/object.go +++ b/pkg/sql/catalog/descs/object.go @@ -15,6 +15,9 @@ import ( "github.com/cockroachdb/cockroach/pkg/kv" "github.com/cockroachdb/cockroach/pkg/sql/catalog" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/typedesc" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqlerrors" "github.com/cockroachdb/errors" @@ -86,13 +89,36 @@ func (tc *Collection) getObjectByName( } switch t := desc.(type) { case catalog.TableDescriptor: - if flags.DesiredObjectKind != tree.TableObject { + // A given table name can resolve to either a type descriptor or a table + // descriptor, because every table descriptor also defines an implicit + // record type with the same name as the table. Thus, depending on the + // requested descriptor type, we return either the table descriptor itself, + // or the table descriptor's implicit record type. + switch flags.DesiredObjectKind { + case tree.TableObject, tree.TypeObject: + default: return prefix, nil, nil } - desc, err = tc.hydrateTypesInTableDesc(ctx, txn, t) + tableDesc, err := tc.hydrateTypesInTableDesc(ctx, txn, t) if err != nil { return prefix, nil, err } + desc = tableDesc + if flags.DesiredObjectKind == tree.TypeObject { + // Since a type descriptor was requested, we need to return the implicitly + // created record type for the table that we found. + if flags.RequireMutable { + // ... but, we can't do it if we need a mutable descriptor - we don't + // have the capability of returning a mutable type descriptor for a + // table's implicit record type. + return prefix, nil, pgerror.Newf(pgcode.InsufficientPrivilege, + "cannot modify table record type %q", objectName) + } + desc, err = typedesc.CreateImplicitRecordTypeFromTableDesc(tableDesc) + if err != nil { + return prefix, nil, err + } + } case catalog.TypeDescriptor: if flags.DesiredObjectKind != tree.TypeObject { return prefix, nil, nil diff --git a/pkg/sql/catalog/descs/type.go b/pkg/sql/catalog/descs/type.go index 9f1ea62a1267..3fae24e54b65 100644 --- a/pkg/sql/catalog/descs/type.go +++ b/pkg/sql/catalog/descs/type.go @@ -87,7 +87,14 @@ func (tc *Collection) GetMutableTypeByID( if err != nil { return nil, err } - return desc.(*typedesc.Mutable), nil + switch t := desc.(type) { + case *typedesc.Mutable: + return t, nil + case *typedesc.TableImplicitRecordType: + return nil, pgerror.Newf(pgcode.DependentObjectsStillExist, "cannot modify table record type %q", desc.GetName()) + } + return nil, + errors.AssertionFailedf("unhandled type descriptor type %T during GetMutableTypeByID", desc) } // GetImmutableTypeByID returns an immutable type descriptor with @@ -112,10 +119,18 @@ func (tc *Collection) getTypeByID( } return nil, err } - typ, ok := desc.(catalog.TypeDescriptor) - if !ok { - return nil, pgerror.Newf( - pgcode.UndefinedObject, "type with ID %d does not exist", typeID) + switch t := desc.(type) { + case catalog.TypeDescriptor: + // User-defined type. + return t, nil + case catalog.TableDescriptor: + // Table record type. + t, err = tc.hydrateTypesInTableDesc(ctx, txn, t) + if err != nil { + return nil, err + } + return typedesc.CreateImplicitRecordTypeFromTableDesc(t) } - return typ, nil + return nil, pgerror.Newf( + pgcode.UndefinedObject, "type with ID %d does not exist", typeID) } diff --git a/pkg/sql/catalog/resolver/resolver.go b/pkg/sql/catalog/resolver/resolver.go index 760e21837a83..bf794237aaca 100644 --- a/pkg/sql/catalog/resolver/resolver.go +++ b/pkg/sql/catalog/resolver/resolver.go @@ -171,7 +171,16 @@ func ResolveMutableType( if err != nil || desc == nil { return catalog.ResolvedObjectPrefix{}, nil, err } - return prefix, desc.(*typedesc.Mutable), nil + switch t := desc.(type) { + case *typedesc.Mutable: + return prefix, t, nil + case *typedesc.TableImplicitRecordType: + return catalog.ResolvedObjectPrefix{}, nil, pgerror.Newf(pgcode.DependentObjectsStillExist, + "cannot modify table record type %q", desc.GetName()) + default: + return catalog.ResolvedObjectPrefix{}, nil, + errors.AssertionFailedf("unhandled type descriptor type %T during resolve mutable desc", t) + } } // ResolveExistingObject resolves an object with the given flags. @@ -214,9 +223,6 @@ func ResolveExistingObject( if !isType { return nil, prefix, sqlerrors.NewUndefinedTypeError(&resolvedTn) } - if lookupFlags.RequireMutable { - return obj.(*typedesc.Mutable), prefix, nil - } return typ, prefix, nil case tree.TableObject: table, ok := obj.(catalog.TableDescriptor) diff --git a/pkg/sql/catalog/table_elements.go b/pkg/sql/catalog/table_elements.go index 7bec492b4856..7e4bdea464a0 100644 --- a/pkg/sql/catalog/table_elements.go +++ b/pkg/sql/catalog/table_elements.go @@ -174,7 +174,7 @@ type Index interface { GetCompositeColumnID(compositeColumnOrdinal int) descpb.ColumnID } -// Column is an interface around the index descriptor types. +// Column is an interface around the column descriptor types. type Column interface { TableElementMaybeMutation diff --git a/pkg/sql/catalog/typedesc/BUILD.bazel b/pkg/sql/catalog/typedesc/BUILD.bazel index d1db1f1defb2..4b58c76d5928 100644 --- a/pkg/sql/catalog/typedesc/BUILD.bazel +++ b/pkg/sql/catalog/typedesc/BUILD.bazel @@ -4,6 +4,7 @@ go_library( name = "typedesc", srcs = [ "safe_format.go", + "table_implicit_record_type.go", "type_desc.go", "type_desc_builder.go", ], diff --git a/pkg/sql/catalog/typedesc/table_implicit_record_type.go b/pkg/sql/catalog/typedesc/table_implicit_record_type.go new file mode 100644 index 000000000000..bfca4c3d0aa5 --- /dev/null +++ b/pkg/sql/catalog/typedesc/table_implicit_record_type.go @@ -0,0 +1,318 @@ +// Copyright 2021 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package typedesc + +import ( + "context" + + "github.com/cockroachdb/cockroach/pkg/sql/catalog" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/privilege" + "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/sql/types" + "github.com/cockroachdb/cockroach/pkg/util/hlc" + "github.com/cockroachdb/errors" +) + +// TableImplicitRecordType is an implementation of catalog.TypeDescriptor that +// represents a record type for a particular table: meaning, the composite type +// that contains, in order, all of the visible columns for the table. +type TableImplicitRecordType struct { + // desc is the TableDescriptor that this implicit record type is created from. + desc catalog.TableDescriptor + + // typ is the fully-hydrated types.T that is represented by this + // TypeDescriptor. It'll always be a tuple. The elements of the tuple will + // be the visible column types of the table, in order, and the labels will + // be the names of those columns. + typ *types.T + // privs holds the privileges for this implicit record type. It's calculated + // by examining the privileges for the table that the record type corresponds + // to, and providing the USAGE privilege if the table had the SELECT + // privilege. + privs *descpb.PrivilegeDescriptor +} + +// CreateImplicitRecordTypeFromTableDesc creates a TypeDescriptor that represents +// the implicit record type for a table, which has 1 field for every visible +// column in the table. +func CreateImplicitRecordTypeFromTableDesc( + descriptor catalog.TableDescriptor, +) (catalog.TypeDescriptor, error) { + + cols := descriptor.VisibleColumns() + typs := make([]*types.T, len(cols)) + names := make([]string, len(cols)) + for i, col := range cols { + if col.GetType().UserDefined() && !col.GetType().IsHydrated() { + return nil, errors.AssertionFailedf("encountered unhydrated col %s while creating implicit record type from"+ + " table %s", col.ColName(), descriptor.GetName()) + } + typs[i] = col.GetType() + names[i] = col.GetName() + } + // The TypeDescriptor will be an alias to this Tuple type, which contains + // all of the table's visible columns in order, labeled by the table's column + // names. + typ := types.MakeLabeledTuple(typs, names) + tableID := descriptor.GetID() + typeOID := TypeIDToOID(tableID) + // Setting the type's OID allows us to properly report and display this type + // as having ID + 100000 in the pg_type table and ::REGTYPE casts. + // It will also be used to serialize expressions casted to this type for + // distribution with DistSQL. The receiver of such a serialized expression + // will then be able to look up and rehydrate this type via the type cache. + typ.InternalType.Oid = typeOID + typ.TypeMeta = types.UserDefinedTypeMetadata{ + Name: &types.UserDefinedTypeName{ + Name: descriptor.GetName(), + }, + Version: uint32(descriptor.GetVersion()), + } + + tablePrivs := descriptor.GetPrivileges() + newPrivs := make([]descpb.UserPrivileges, len(tablePrivs.Users)) + for i := range tablePrivs.Users { + newPrivs[i].UserProto = tablePrivs.Users[i].UserProto + // A table's record type has USAGE privs if a user has SELECT on the table. + if privilege.SELECT.IsSetIn(tablePrivs.Users[i].Privileges) { + newPrivs[i].Privileges = privilege.USAGE.Mask() + } + } + + return &TableImplicitRecordType{ + desc: descriptor, + typ: typ, + privs: &descpb.PrivilegeDescriptor{ + Users: newPrivs, + OwnerProto: tablePrivs.OwnerProto, + Version: tablePrivs.Version, + }, + }, nil +} + +// GetName implements the NameKey interface. +func (v TableImplicitRecordType) GetName() string { return v.desc.GetName() } + +// GetParentID implements the NameKey interface. +func (v TableImplicitRecordType) GetParentID() descpb.ID { return v.desc.GetParentID() } + +// GetParentSchemaID implements the NameKey interface. +func (v TableImplicitRecordType) GetParentSchemaID() descpb.ID { return v.desc.GetParentSchemaID() } + +// GetID implements the NameEntry interface. +func (v TableImplicitRecordType) GetID() descpb.ID { return v.desc.GetID() } + +// IsUncommittedVersion implements the Descriptor interface. +func (v TableImplicitRecordType) IsUncommittedVersion() bool { return v.desc.IsUncommittedVersion() } + +// GetVersion implements the Descriptor interface. +func (v TableImplicitRecordType) GetVersion() descpb.DescriptorVersion { return v.desc.GetVersion() } + +// GetModificationTime implements the Descriptor interface. +func (v TableImplicitRecordType) GetModificationTime() hlc.Timestamp { + return v.desc.GetModificationTime() +} + +// GetDrainingNames implements the Descriptor interface. +func (v TableImplicitRecordType) GetDrainingNames() []descpb.NameInfo { + // Implicit record types don't have draining names. + return nil +} + +// GetPrivileges implements the Descriptor interface. +func (v TableImplicitRecordType) GetPrivileges() *descpb.PrivilegeDescriptor { + return v.privs +} + +// DescriptorType implements the Descriptor interface. +func (v TableImplicitRecordType) DescriptorType() catalog.DescriptorType { + return catalog.Type +} + +// GetAuditMode implements the Descriptor interface. +func (v TableImplicitRecordType) GetAuditMode() descpb.TableDescriptor_AuditMode { + return descpb.TableDescriptor_DISABLED +} + +// Public implements the Descriptor interface. +func (v TableImplicitRecordType) Public() bool { return v.desc.Public() } + +// Adding implements the Descriptor interface. +func (v TableImplicitRecordType) Adding() bool { + v.panicNotSupported("Adding") + return false +} + +// Dropped implements the Descriptor interface. +func (v TableImplicitRecordType) Dropped() bool { + v.panicNotSupported("Dropped") + return false +} + +// Offline implements the Descriptor interface. +func (v TableImplicitRecordType) Offline() bool { + v.panicNotSupported("Offline") + return false +} + +// GetOfflineReason implements the Descriptor interface. +func (v TableImplicitRecordType) GetOfflineReason() string { + v.panicNotSupported("GetOfflineReason") + return "" +} + +// DescriptorProto implements the Descriptor interface. +func (v TableImplicitRecordType) DescriptorProto() *descpb.Descriptor { + v.panicNotSupported("DescriptorProto") + return nil +} + +// GetReferencedDescIDs implements the Descriptor interface. +func (v TableImplicitRecordType) GetReferencedDescIDs() (catalog.DescriptorIDSet, error) { + return catalog.DescriptorIDSet{}, errors.AssertionFailedf( + "GetReferencedDescIDs are unsupported for implicit table record types") +} + +// ValidateSelf implements the Descriptor interface. +func (v TableImplicitRecordType) ValidateSelf(_ catalog.ValidationErrorAccumulator) {} + +// ValidateCrossReferences implements the Descriptor interface. +func (v TableImplicitRecordType) ValidateCrossReferences( + _ catalog.ValidationErrorAccumulator, _ catalog.ValidationDescGetter, +) { +} + +// ValidateTxnCommit implements the Descriptor interface. +func (v TableImplicitRecordType) ValidateTxnCommit( + _ catalog.ValidationErrorAccumulator, _ catalog.ValidationDescGetter, +) { +} + +// TypeDesc implements the TypeDescriptor interface. +func (v TableImplicitRecordType) TypeDesc() *descpb.TypeDescriptor { + v.panicNotSupported("TypeDesc") + return nil +} + +// HydrateTypeInfoWithName implements the TypeDescriptor interface. +func (v TableImplicitRecordType) HydrateTypeInfoWithName( + ctx context.Context, typ *types.T, name *tree.TypeName, res catalog.TypeDescriptorResolver, +) error { + if typ.IsHydrated() { + return nil + } + if typ.Family() != types.TupleFamily { + return errors.AssertionFailedf("unexpected hydration of non-tuple type %s with table implicit record type %d", + typ, v.GetID()) + } + if typ.Oid() != TypeIDToOID(v.GetID()) { + return errors.AssertionFailedf("unexpected mismatch during table implicit record type hydration: "+ + "type %s has id %d, descriptor has id %d", typ, typ.Oid(), v.GetID()) + } + typ.TypeMeta.Name = &types.UserDefinedTypeName{ + Catalog: name.Catalog(), + ExplicitSchema: name.ExplicitSchema, + Schema: name.Schema(), + Name: name.Object(), + } + typ.TypeMeta.Version = uint32(v.desc.GetVersion()) + for _, t := range typ.TupleContents() { + if t.UserDefined() { + if err := hydrateElementType(ctx, t, res); err != nil { + return err + } + } + } + return nil +} + +// MakeTypesT implements the TypeDescriptor interface. +func (v TableImplicitRecordType) MakeTypesT( + _ context.Context, _ *tree.TypeName, _ catalog.TypeDescriptorResolver, +) (*types.T, error) { + return v.typ, nil +} + +// HasPendingSchemaChanges implements the TypeDescriptor interface. +func (v TableImplicitRecordType) HasPendingSchemaChanges() bool { return false } + +// GetIDClosure implements the TypeDescriptor interface. +func (v TableImplicitRecordType) GetIDClosure() (map[descpb.ID]struct{}, error) { + return nil, errors.AssertionFailedf("IDClosure unsupported for implicit table record types") +} + +// IsCompatibleWith implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) IsCompatibleWith(_ catalog.TypeDescriptor) error { + return errors.AssertionFailedf("compatibility comparison unsupported for implicit table record types") +} + +// PrimaryRegionName implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) PrimaryRegionName() (descpb.RegionName, error) { + return "", errors.AssertionFailedf( + "can not get primary region of a implicit table record type") +} + +// RegionNames implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) RegionNames() (descpb.RegionNames, error) { + return nil, errors.AssertionFailedf( + "can not get region names of a implicit table record type") +} + +// RegionNamesIncludingTransitioning implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) RegionNamesIncludingTransitioning() (descpb.RegionNames, error) { + return nil, errors.AssertionFailedf( + "can not get region names of a implicit table record type") +} + +// RegionNamesForValidation implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) RegionNamesForValidation() (descpb.RegionNames, error) { + return nil, errors.AssertionFailedf( + "can not get region names of a implicit table record type") +} + +// TransitioningRegionNames implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) TransitioningRegionNames() (descpb.RegionNames, error) { + return nil, errors.AssertionFailedf( + "can not get region names of a implicit table record type") +} + +// GetArrayTypeID implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) GetArrayTypeID() descpb.ID { + return 0 +} + +// GetKind implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) GetKind() descpb.TypeDescriptor_Kind { + return descpb.TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE +} + +// NumEnumMembers implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) NumEnumMembers() int { return 0 } + +// GetMemberPhysicalRepresentation implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) GetMemberPhysicalRepresentation(_ int) []byte { return nil } + +// GetMemberLogicalRepresentation implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) GetMemberLogicalRepresentation(_ int) string { return "" } + +// IsMemberReadOnly implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) IsMemberReadOnly(_ int) bool { return false } + +// NumReferencingDescriptors implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) NumReferencingDescriptors() int { return 0 } + +// GetReferencingDescriptorID implements the TypeDescriptorInterface. +func (v TableImplicitRecordType) GetReferencingDescriptorID(_ int) descpb.ID { return 0 } + +func (v TableImplicitRecordType) panicNotSupported(message string) { + panic(errors.AssertionFailedf("implicit table record type for table %q: not supported: %s", v.GetName(), message)) +} diff --git a/pkg/sql/catalog/typedesc/type_desc.go b/pkg/sql/catalog/typedesc/type_desc.go index 9e7dc8208f5b..2202af962144 100644 --- a/pkg/sql/catalog/typedesc/type_desc.go +++ b/pkg/sql/catalog/typedesc/type_desc.go @@ -502,6 +502,8 @@ func (desc *immutable) ValidateSelf(vea catalog.ValidationErrorAccumulator) { if desc.GetArrayTypeID() != descpb.InvalidID { vea.Report(errors.AssertionFailedf("ALIAS type desc has array type ID %d", desc.GetArrayTypeID())) } + case descpb.TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE: + vea.Report(errors.AssertionFailedf("invalid type descriptor: kind %s should never be serialized or validated", desc.Kind.String())) default: vea.Report(errors.AssertionFailedf("invalid type descriptor kind %s", desc.Kind.String())) } @@ -790,20 +792,17 @@ func (desc *immutable) HydrateTypeInfoWithName( case types.ArrayFamily: // Hydrate the element type. elemType := typ.ArrayContents() - id, err := GetUserDefinedTypeDescID(elemType) - if err != nil { - return err - } - elemTypName, elemTypDesc, err := res.GetTypeDescriptor(ctx, id) - if err != nil { - return err - } - if err := elemTypDesc.HydrateTypeInfoWithName(ctx, elemType, &elemTypName, res); err != nil { - return err + return hydrateElementType(ctx, elemType, res) + case types.TupleFamily: + for _, t := range typ.TupleContents() { + if t.UserDefined() { + if err := hydrateElementType(ctx, t, res); err != nil { + return err + } + } } - return nil default: - return errors.AssertionFailedf("only array types aliases can be user defined") + return errors.AssertionFailedf("unhandled alias type family %s", typ.Family()) } } return nil @@ -812,6 +811,21 @@ func (desc *immutable) HydrateTypeInfoWithName( } } +func hydrateElementType(ctx context.Context, t *types.T, res catalog.TypeDescriptorResolver) error { + id, err := GetUserDefinedTypeDescID(t) + if err != nil { + return err + } + elemTypName, elemTypDesc, err := res.GetTypeDescriptor(ctx, id) + if err != nil { + return err + } + if err := elemTypDesc.HydrateTypeInfoWithName(ctx, t, &elemTypName, res); err != nil { + return err + } + return nil +} + // NumEnumMembers implements the TypeDescriptor interface. func (desc *immutable) NumEnumMembers() int { return len(desc.EnumMembers) @@ -933,7 +947,8 @@ func GetTypeDescriptorClosure(typ *types.T) (map[descpb.ID]struct{}, error) { ret := map[descpb.ID]struct{}{ id: {}, } - if typ.Family() == types.ArrayFamily { + switch typ.Family() { + case types.ArrayFamily: // If we have an array type, then collect all types in the contents. children, err := GetTypeDescriptorClosure(typ.ArrayContents()) if err != nil { @@ -942,7 +957,18 @@ func GetTypeDescriptorClosure(typ *types.T) (map[descpb.ID]struct{}, error) { for id := range children { ret[id] = struct{}{} } - } else { + case types.TupleFamily: + // If we have a tuple type, collect all types in the contents. + for _, elt := range typ.TupleContents() { + children, err := GetTypeDescriptorClosure(elt) + if err != nil { + return nil, err + } + for id := range children { + ret[id] = struct{}{} + } + } + default: // Otherwise, take the array type ID. id, err := GetUserDefinedArrayTypeDescID(typ) if err != nil { diff --git a/pkg/sql/catalog/typedesc/type_desc_test.go b/pkg/sql/catalog/typedesc/type_desc_test.go index aa1a724a9cd0..1f3bd7ed2071 100644 --- a/pkg/sql/catalog/typedesc/type_desc_test.go +++ b/pkg/sql/catalog/typedesc/type_desc_test.go @@ -812,3 +812,19 @@ func TestOIDToIDConversion(t *testing.T) { }) } } + +func TestTableImplicitTypeDescCannotBeSerializedOrValidated(t *testing.T) { + td := &descpb.TypeDescriptor{ + Name: "foo", + ID: 10, + ParentID: 1, + ParentSchemaID: 1, + Kind: descpb.TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE, + } + + desc := typedesc.NewBuilder(td).BuildImmutable() + + ctx := context.Background() + err := catalog.Validate(ctx, nil, catalog.NoValidationTelemetry, catalog.ValidationLevelSelfOnly, desc).CombinedError() + require.Contains(t, err.Error(), "kind TABLE_IMPLICIT_RECORD_TYPE should never be serialized") +} diff --git a/pkg/sql/catalog/validate.go b/pkg/sql/catalog/validate.go index c21c5ac1bd1d..64f629d844fb 100644 --- a/pkg/sql/catalog/validate.go +++ b/pkg/sql/catalog/validate.go @@ -395,7 +395,11 @@ func (vdg *validationDescGetterImpl) GetTypeDescriptor(id descpb.ID) (TypeDescri if !found || desc == nil { return nil, WrapTypeDescRefErr(id, ErrDescriptorNotFound) } - return AsTypeDescriptor(desc) + descriptor, err := AsTypeDescriptor(desc) + if err != nil { + return nil, err + } + return descriptor, err } func (vdg *validationDescGetterImpl) addNamespaceEntries( diff --git a/pkg/sql/distsql_physical_planner.go b/pkg/sql/distsql_physical_planner.go index 5b1dc79b165c..9d4619cadaf9 100644 --- a/pkg/sql/distsql_physical_planner.go +++ b/pkg/sql/distsql_physical_planner.go @@ -239,9 +239,12 @@ func (v *distSQLExprCheckVisitor) VisitPre(expr tree.Expr) (recurse bool, newExp case *tree.CastExpr: // TODO (rohany): I'm not sure why this CastExpr doesn't have a type // annotation at this stage of processing... - if typ, ok := tree.GetStaticallyKnownType(t.Type); ok && typ.Family() == types.OidFamily { - v.err = newQueryNotSupportedErrorf("cast to %s is not supported by distsql", t.Type) - return false, expr + if typ, ok := tree.GetStaticallyKnownType(t.Type); ok { + switch typ.Family() { + case types.OidFamily: + v.err = newQueryNotSupportedErrorf("cast to %s is not supported by distsql", t.Type) + return false, expr + } } case *tree.DArray: // We need to check for arrays of untyped tuples here since constant-folding diff --git a/pkg/sql/drop_type.go b/pkg/sql/drop_type.go index 674248912bf9..99b11fec4fc1 100644 --- a/pkg/sql/drop_type.go +++ b/pkg/sql/drop_type.go @@ -84,6 +84,12 @@ func (p *planner) DropType(ctx context.Context, n *tree.DropType) (planNode, err "try ALTER DATABASE DROP REGION %s", name) case descpb.TypeDescriptor_ENUM: sqltelemetry.IncrementEnumCounter(sqltelemetry.EnumDrop) + case descpb.TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE: + return nil, pgerror.Newf( + pgcode.DependentObjectsStillExist, + "cannot drop type %q because table %q requires it", + name, name, + ) } // Check if we can drop the type. diff --git a/pkg/sql/logictest/testdata/logic_test/enums b/pkg/sql/logictest/testdata/logic_test/enums index 40d3ee0a1ab5..3f35a32e1af6 100644 --- a/pkg/sql/logictest/testdata/logic_test/enums +++ b/pkg/sql/logictest/testdata/logic_test/enums @@ -1287,7 +1287,9 @@ CREATE TYPE IF NOT EXISTS ifne AS ENUM ('hi') statement ok CREATE TABLE table_ifne (x INT) -statement error pq: relation "test_57196.public.table_ifne" already exists +# This doesn't fail because there *is* already type with this name, which is +# the implicit type with the same name as the table. +statement ok CREATE TYPE IF NOT EXISTS table_ifne AS ENUM ('hi') # Regression test for incorrectly serializing NULL expression type annotation in diff --git a/pkg/sql/logictest/testdata/logic_test/json b/pkg/sql/logictest/testdata/logic_test/json index 9b9bceb8c9f0..199f1391ad4b 100644 --- a/pkg/sql/logictest/testdata/logic_test/json +++ b/pkg/sql/logictest/testdata/logic_test/json @@ -852,97 +852,3 @@ query T SELECT '{}'::JSONB[] ---- {} - -# json_populate_record -query FIII colnames -SELECT *, c FROM json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}') ----- -d c a c -11.001 10 3 10 - -query BTT colnames -SELECT * FROM json_populate_record(((true, ARRAY[1], ARRAY['f']) AS a, b, c), '{"a": true, "b": [1,2], "c": ["a", "b"]}') ----- -a b c -true {1,2} {a,b} - -query BT colnames -SELECT * FROM json_populate_record(((true, ((1, 'bar', ARRAY['a']) AS x, y, z)) AS a, b), '{"a": true, "b": {"x": "3", "y": "foo", "z": ["a", "b"]}}') ----- -a b -true (3,foo,"{a,b}") - -query BI colnames -SELECT * FROM json_populate_record(((true, 3) AS a, b), '{"a": null, "b": null}') ----- -a b -NULL NULL - -query T colnames -SELECT json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}') ----- -json_populate_record -(11.001,10,3) - -query T colnames -SELECT json_populate_record(((1.01, 2) AS a, b), '{"a": "1.2345", "b": "33"}') ----- -json_populate_record -(1.2345,33) - -query F colnames -SELECT (json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}')).d ----- -d -11.001 - -query error could not parse \"foo\" as type int -SELECT json_populate_record(((3,) AS a), '{"a": "foo"}') - -query error anonymous records cannot be used with json{b}_populate_record{set} -SELECT * FROM json_populate_record((1,2,3,4), '{"a": 3, "c": 10, "d": 11.001}') - -query error anonymous records cannot be used with json{b}_populate_record{set} -SELECT * FROM json_populate_record(NULL, '{"a": 3, "c": 10, "d": 11.001}') - -query error first argument of json{b}_populate_record{set} must be a record type -SELECT * FROM json_populate_record(1, '{"a": 3, "c": 10, "d": 11.001}') - -query error first argument of json{b}_populate_record{set} must be a record type -SELECT * FROM json_populate_record(NULL::INT, '{"a": 3, "c": 10, "d": 11.001}') - -query error anonymous records cannot be used with json{b}_populate_record{set} -SELECT * FROM json_populate_record(NULL::record, '{"a": 3, "c": 10, "d": 11.001}') - -query error anonymous records cannot be used with json{b}_populate_record{set} -SELECT * FROM json_populate_recordset(NULL, '[{"a": 3, "c": 10, "d": 11.001}, {}]') - -query error first argument of json{b}_populate_record{set} must be a record type -SELECT * FROM json_populate_recordset(NULL::INT, '[{"a": 3, "c": 10, "d": 11.001}, {}]') - -query I -SELECT * FROM json_populate_record(((3,) AS a), NULL) ----- -3 - -query FIII colnames -SELECT *, c FROM json_populate_recordset(((1.01, 2, 3) AS d, c, a), '[{"a": 3, "c": 10, "d": 11.001}, {}]') ----- -d c a c -11.001 10 3 10 -1.01 2 3 2 - -query FITI colnames -SELECT *, c FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[{"a": 3, "c": 10, "d": 11.001}, {}]') ----- -d c a c -11.001 10 3 10 -NULL 2 3 2 - -query FIT -SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), NULL) ----- - -query FIT -SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[]') ----- diff --git a/pkg/sql/logictest/testdata/logic_test/json_builtins b/pkg/sql/logictest/testdata/logic_test/json_builtins index 0cb378ee9b40..1125c9fb8bfc 100644 --- a/pkg/sql/logictest/testdata/logic_test/json_builtins +++ b/pkg/sql/logictest/testdata/logic_test/json_builtins @@ -1218,3 +1218,146 @@ select query error pq: jsonb_exists_any\(\): could not parse "id" as type int: strconv\.ParseInt: parsing "id": invalid syntax select jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb, array['id',1]); + +# json_populate_record +query FIII colnames +SELECT *, c FROM json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}') +---- +d c a c +11.001 10 3 10 + +query BTT colnames +SELECT * FROM json_populate_record(((true, ARRAY[1], ARRAY['f']) AS a, b, c), '{"a": true, "b": [1,2], "c": ["a", "b"]}') +---- +a b c +true {1,2} {a,b} + +query BT colnames +SELECT * FROM json_populate_record(((true, ((1, 'bar', ARRAY['a']) AS x, y, z)) AS a, b), '{"a": true, "b": {"x": "3", "y": "foo", "z": ["a", "b"]}}') +---- +a b +true (3,foo,"{a,b}") + +query BI colnames +SELECT * FROM json_populate_record(((true, 3) AS a, b), '{"a": null, "b": null}') +---- +a b +NULL NULL + +query T colnames +SELECT json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}') +---- +json_populate_record +(11.001,10,3) + +query T colnames +SELECT json_populate_record(((1.01, 2) AS a, b), '{"a": "1.2345", "b": "33"}') +---- +json_populate_record +(1.2345,33) + +query F colnames +SELECT (json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}')).d +---- +d +11.001 + +statement ok +CREATE TABLE testtab ( + i int, + ia int[], + t text, + ta text[], + ts timestamp, + j jsonb +) + +query ITTTTT +SELECT * FROM json_populate_record(NULL::testtab, '{"i": 3, "ia": [1,2,3], "t": "foo", "ta": ["a", "b"], "ts": "2017-01-01 00:00", "j": {"a": "b", "c": 3, "d": [1,false,true,null,{"1":"2"}]}}'::JSON) +---- +3 {1,2,3} foo {a,b} 2017-01-01 00:00:00 +0000 +0000 {"a": "b", "c": 3, "d": [1, false, true, null, {"1": "2"}]} + +query T +SELECT json_populate_record(NULL::testtab, '{"i": 3, "ia": [1,2,3], "t": "foo", "ta": ["a", "b"], "ts": "2017-01-01 00:00", "j": {"a": "b", "c": 3, "d": [1,false,true,null,{"1":"2"}]}}'::JSON) +---- +(3,"{1,2,3}",foo,"{a,b}","2017-01-01 00:00:00","{""a"": ""b"", ""c"": 3, ""d"": [1, false, true, null, {""1"": ""2""}]}") + +query ITTTTT +SELECT * FROM json_populate_record(NULL::testtab, NULL) +---- +NULL NULL NULL NULL NULL NULL + +query error could not parse \"foo\" as type int +SELECT json_populate_record(((3,) AS a), '{"a": "foo"}') + +query error anonymous records cannot be used with json{b}_populate_record{set} +SELECT * FROM json_populate_record((1,2,3,4), '{"a": 3, "c": 10, "d": 11.001}') + +query error anonymous records cannot be used with json{b}_populate_record{set} +SELECT * FROM json_populate_record(NULL, '{"a": 3, "c": 10, "d": 11.001}') + +query error first argument of json{b}_populate_record{set} must be a record type +SELECT * FROM json_populate_record(1, '{"a": 3, "c": 10, "d": 11.001}') + +query error first argument of json{b}_populate_record{set} must be a record type +SELECT * FROM json_populate_record(NULL::INT, '{"a": 3, "c": 10, "d": 11.001}') + +query error anonymous records cannot be used with json{b}_populate_record{set} +SELECT * FROM json_populate_record(NULL::record, '{"a": 3, "c": 10, "d": 11.001}') + +query error anonymous records cannot be used with json{b}_populate_record{set} +SELECT * FROM json_populate_recordset(NULL, '[{"a": 3, "c": 10, "d": 11.001}, {}]') + +query error first argument of json{b}_populate_record{set} must be a record type +SELECT * FROM json_populate_recordset(NULL::INT, '[{"a": 3, "c": 10, "d": 11.001}, {}]') + +query I +SELECT * FROM json_populate_record(((3,) AS a), NULL) +---- +3 + +query FIII colnames +SELECT *, c FROM json_populate_recordset(((1.01, 2, 3) AS d, c, a), '[{"a": 3, "c": 10, "d": 11.001}, {}]') +---- +d c a c +11.001 10 3 10 +1.01 2 3 2 + +query FITI colnames +SELECT *, c FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[{"a": 3, "c": 10, "d": 11.001}, {}]') +---- +d c a c +11.001 10 3 10 +NULL 2 3 2 + +query FIT +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), NULL) +---- + +query FIT +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[]') +---- + +query error argument of json_populate_recordset must be an array +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '{"foo": "bar"}') + +query error argument of json_populate_recordset must be an array +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), 'true') + +query error argument of json_populate_recordset must be an array +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '0') + +query error argument of json_populate_recordset must be an array +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), 'null') + +query error argument of json_populate_recordset must be an array of objects +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[null]') + +query error argument of json_populate_recordset must be an array of objects +SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[{"foo":"bar"}, 3]') + +query ITTTTT +SELECT * FROM json_populate_recordset(NULL::testtab, '[{"i": 3, "ia": [1,2,3], "t": "foo", "ta": ["a", "b"], "ts": "2017-01-01 00:00", "j": {"a": "b", "c": 3, "d": [1,false,true,null,{"1":"2"}]}}, {}]'::JSON) +---- +3 {1,2,3} foo {a,b} 2017-01-01 00:00:00 +0000 +0000 {"a": "b", "c": 3, "d": [1, false, true, null, {"1": "2"}]} +NULL NULL NULL NULL NULL NULL diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index e8e5e76f717e..879ead30685f 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -3433,6 +3433,35 @@ WHERE oid = 1 ---- oid typname typnamespace typowner typlen typbyval typtype +query OTOOIBT colnames +SELECT oid, typname, typnamespace, typowner, typlen, typbyval, typtype +FROM pg_catalog.pg_type +WHERE oid = 9999999 +---- +oid typname typnamespace typowner typlen typbyval typtype + +query OTOOIBT colnames +SELECT oid, typname, typnamespace, typowner, typlen, typbyval, typtype +FROM pg_catalog.pg_type +WHERE typname = 'source_table' +---- +oid typname typnamespace typowner typlen typbyval typtype +100070 source_table 2332901747 1546506610 -1 false c + +let $sourceid +SELECT oid +FROM pg_catalog.pg_type +WHERE typname = 'source_table' + +## Exercise the virtual index on pg_type.oid. +query OTOOIBT colnames +SELECT oid, typname, typnamespace, typowner, typlen, typbyval, typtype +FROM pg_catalog.pg_type +WHERE oid = $sourceid +---- +oid typname typnamespace typowner typlen typbyval typtype +100070 source_table 2332901747 1546506610 -1 false c + ## pg_catalog.pg_proc query TOOOTTO colnames diff --git a/pkg/sql/logictest/testdata/logic_test/record b/pkg/sql/logictest/testdata/logic_test/record new file mode 100644 index 000000000000..eebae774f655 --- /dev/null +++ b/pkg/sql/logictest/testdata/logic_test/record @@ -0,0 +1,150 @@ +statement ok +CREATE TABLE a(a INT PRIMARY KEY, b TEXT); +INSERT INTO a VALUES(1,'2') + +query TITIT colnames +SELECT t, t.a, t.b, t.* FROM a AS t +---- +t a b a b +(1,2) 1 2 1 2 + +query TT +SELECT (1, 'foo')::a, ((1, 'foo')::a).b +---- +(1,foo) foo + +# Can't cast if wrong element length. +query error invalid cast: tuple{int} -> tuple{int AS a, string AS b} +SELECT (1,)::a + +query error invalid cast: tuple{int, int, int} -> tuple{int AS a, string AS b} +SELECT (1,3,5)::a + +# Types within a tuple auto-cast to each other when possible +query TT +SELECT (1, 3)::a, ('3', 'blah')::a +---- +(1,3) (3,blah) + +# ... but fail when not possible. +query error could not parse \"blah\" as type int +SELECT ('blah', 'blah')::a + +# You can resolve types with schemas and dbs attached. +query TT +SELECT (1, 'foo')::public.a, (1, 'foo')::test.public.a +---- +(1,foo) (1,foo) + +statement ok +SET experimental_enable_hash_sharded_indexes=true + +# The tuple type doesn't contain implicit columns like rowid or hash columns. +statement ok +CREATE TABLE implicit_col(d INT, e TEXT, INDEX (e) USING HASH WITH BUCKET_COUNT = 8) + +query T +SELECT (1, 'foo')::implicit_col +---- +(1,foo) + +# You can cast between tuple types and their labels change. +query TITIT colnames +SELECT t::implicit_col, (t::implicit_col).d, (t::implicit_col).e, (t::implicit_col).* FROM a AS t +---- +t d e d e +(1,2) 1 2 1 2 + +# You can't use a table type as a column type. +statement error value type tuple\{int AS d, string AS e\} cannot be used for table columns +CREATE TABLE fail (a implicit_col) + +# REGTYPE works, and returns the type ID. +query TB +SELECT 'a'::REGTYPE, 'a'::REGTYPE::INT = 'a'::REGCLASS::INT + 100000 +---- +a true + +let $tabletypeid +SELECT 'a'::REGTYPE::INT + +query T +SELECT $tabletypeid::REGTYPE::TEXT +---- +a + +query T +SELECT pg_typeof((1,3)::a) +---- +a + +# You can create arrays of tuples of the table type. +query T +SELECT ARRAY[(1, 3)::a, (1, 2)::a] +---- +{"(1,3)","(1,2)"} + +# Their pg_type looks like a[]. +query T +SELECT pg_typeof(ARRAY[(1, 3)::a, (1, 2)::a]) +---- +a[] + +# But getting the OID for the array type gives back the same thing as +# generic record[]. +query T +SELECT pg_typeof(ARRAY[(1, 3)::a, (1, 2)::a])::regtype::oid::regtype +---- +_record + +# You can't drop the type descriptor. +statement error cannot modify table record type \"a\" +DROP TYPE a + +# User-defined types in table defs work fine. +statement ok +CREATE TYPE e AS ENUM ('a', 'b'); +CREATE TABLE b (a INT PRIMARY KEY, e e) + +query T +SELECT (1, 'a')::b +---- +(1,a) + + +# Can't use a table record type in a persisted descriptor. +statement error cannot modify table record type +CREATE TABLE fail (b INT DEFAULT (((1,'a')::b).a)) + +statement error cannot modify table record type +ALTER TABLE b ADD COLUMN b INT DEFAULT (((1,'a')::b).a) + +statement error cannot modify table record type +CREATE TABLE fail (b INT AS (((1,'a')::b).a) VIRTUAL) + +statement error cannot modify table record type +ALTER TABLE b ADD COLUMN b INT AS (((1,'a')::b).a) VIRTUAL + +statement error cannot modify table record type +CREATE TABLE fail (b INT AS (((1,'a')::b).a) STORED) + +statement error cannot modify table record type +ALTER TABLE b ADD COLUMN b INT AS (((1,'a')::b).a) STORED + +statement error cannot modify table record type +CREATE TABLE fail (b INT, INDEX(b) WHERE b > (((1,'a')::b).a)) + +statement error cannot modify table record type +CREATE INDEX ON a(a) WHERE a > (((1,'a')::b).a) + +statement error cannot modify table record type +CREATE TABLE fail (b INT, INDEX((b + (((1,'a')::b).a)))) + +statement error cannot modify table record type +CREATE INDEX ON a((a + (((1,'a')::b).a))) + +statement error value type tuple{int AS a, e AS e} cannot be used for table columns +CREATE VIEW v AS SELECT (1,'a')::b + +statement error cannot modify table record type +CREATE VIEW v AS SELECT ((1,'a')::b).a diff --git a/pkg/sql/opt/exec/execbuilder/scalar.go b/pkg/sql/opt/exec/execbuilder/scalar.go index 790c893cb782..e79dec8e890a 100644 --- a/pkg/sql/opt/exec/execbuilder/scalar.go +++ b/pkg/sql/opt/exec/execbuilder/scalar.go @@ -112,7 +112,7 @@ func (b *Builder) buildTypedExpr( } func (b *Builder) buildNull(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) { - if scalar.DataType().Family() == types.TupleFamily { + if scalar.DataType().Family() == types.TupleFamily && !scalar.DataType().UserDefined() { // See comment in buildCast. return tree.DNull, nil } @@ -337,11 +337,13 @@ func (b *Builder) buildCast(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.Ty if err != nil { return nil, err } - if cast.Typ.Family() == types.TupleFamily { + if cast.Typ.Family() == types.TupleFamily && !cast.Typ.UserDefined() { // TODO(radu): casts to Tuple are not supported (they can't be serialized - // for distsql). This should only happen when the input is always NULL so - // the expression should still be valid without the cast (though there could - // be cornercases where the type does matter). + // for distsql) unless they are user-defined, in which case they have an + // OID and can be serialized with the ::@ syntax. This should only + // happen when the input is always NULL so the expression should still be + // valid without the cast (though there could be cornercases where the type + // does matter). return input, nil } return tree.NewTypedCastExpr(input, cast.Typ), nil diff --git a/pkg/sql/pg_catalog.go b/pkg/sql/pg_catalog.go index 473e6d14e75f..9b978d54989d 100644 --- a/pkg/sql/pg_catalog.go +++ b/pkg/sql/pg_catalog.go @@ -2943,8 +2943,13 @@ https://www.postgresql.org/docs/9.5/catalog-pg-type.html`, typDesc = nil } - // If it is not a type, it has to be a table. if typDesc == nil { + return false, nil + } + + // It's an entry for the implicit record type created on behalf of each + // table. We have special logic for this case. + if typDesc.GetKind() == descpb.TypeDescriptor_TABLE_IMPLICIT_RECORD_TYPE { table, err := p.Descriptors().GetImmutableTableByID(ctx, p.txn, id, tree.ObjectLookupFlags{}) if err != nil { if errors.Is(err, catalog.ErrDescriptorNotFound) || pgerror.GetPGCode(err) == pgcode.UndefinedObject { diff --git a/pkg/sql/sem/builtins/generator_builtins.go b/pkg/sql/sem/builtins/generator_builtins.go index cf3af142b82c..a2b0e7498cd0 100644 --- a/pkg/sql/sem/builtins/generator_builtins.go +++ b/pkg/sql/sem/builtins/generator_builtins.go @@ -1441,6 +1441,9 @@ func (j *jsonPopulateRecordSetGenerator) Values() (tree.Datums, error) { if err != nil { return nil, err } + if obj.Type() != json.ObjectJSONType { + return nil, pgerror.Newf(pgcode.InvalidParameterValue, "argument of json_populate_recordset must be an array of objects") + } output := tree.NewDTupleWithLen(j.input.ResolvedType(), j.input.D.Len()) for i := range j.input.D { output.D[i] = j.input.D[i] diff --git a/pkg/sql/sem/tree/cast.go b/pkg/sql/sem/tree/cast.go index aafa04487f22..0533aef50c09 100644 --- a/pkg/sql/sem/tree/cast.go +++ b/pkg/sql/sem/tree/cast.go @@ -1215,6 +1215,7 @@ var validCasts = []castInfo{ // Casts to TupleFamily. {from: types.UnknownFamily, to: types.TupleFamily, volatility: VolatilityImmutable}, + {from: types.TupleFamily, to: types.TupleFamily, volatility: VolatilityStable}, } type castsMapKey struct { @@ -2346,6 +2347,26 @@ func performCastWithoutPrecisionTruncation( case *DString: return ParseDOid(ctx, string(*v), t) } + case types.TupleFamily: + switch v := d.(type) { + case *DTuple: + // To cast a Tuple to a Tuple, the lengths must be the same on both sides. + // Then, each element is casted to the other element type. The labels of + // the target type are kept. + if len(v.D) != len(t.TupleContents()) { + return nil, pgerror.New( + pgcode.CannotCoerce, "cannot cast tuple; wrong number of columns") + } + ret := NewDTupleWithLen(t, len(v.D)) + for i := range v.D { + var err error + ret.D[i], err = PerformCast(ctx, v.D[i], t.TupleContents()[i]) + if err != nil { + return nil, err + } + } + return ret, nil + } } return nil, pgerror.Newf( diff --git a/pkg/sql/sem/tree/type_check.go b/pkg/sql/sem/tree/type_check.go index f86be3eb800f..b1e45a387ae7 100644 --- a/pkg/sql/sem/tree/type_check.go +++ b/pkg/sql/sem/tree/type_check.go @@ -417,6 +417,10 @@ func (expr *CaseExpr) TypeCheck( return expr, nil } +func invalidCastError(castFrom, castTo *types.T) error { + return pgerror.Newf(pgcode.CannotCoerce, "invalid cast: %s -> %s", castFrom, castTo) +} + // resolveCast checks that the cast from the two types is valid. If allowStable // is false, it also checks that the cast has VolatilityImmutable. // @@ -450,16 +454,42 @@ func resolveCast( // Casts from ENUM to ENUM type can only succeed if the two types are the // same. if !castFrom.Equivalent(castTo) { - return pgerror.Newf(pgcode.CannotCoerce, "invalid cast: %s -> %s", castFrom, castTo) + return invalidCastError(castFrom, castTo) } telemetry.Inc(sqltelemetry.EnumCastCounter) return nil + case toFamily == types.TupleFamily && fromFamily == types.TupleFamily: + // Casts from tuple to tuple type succeed if the lengths of the tuples are + // the same, and if there are casts resolvable across all of the elements + // pointwise. + fromTuple := castFrom.TupleContents() + toTuple := castTo.TupleContents() + if len(fromTuple) != len(toTuple) { + return invalidCastError(castFrom, castTo) + } + for i, from := range fromTuple { + to := toTuple[i] + err := resolveCast( + context, + from, + to, + allowStable, + intervalStyleEnabled, + dateStyleEnabled, + ) + if err != nil { + return err + } + } + telemetry.Inc(sqltelemetry.TupleCastCounter) + return nil + default: // TODO(mgartner): Use OID cast map. cast := lookupCastInfo(fromFamily, toFamily, intervalStyleEnabled, dateStyleEnabled) if cast == nil { - return pgerror.Newf(pgcode.CannotCoerce, "invalid cast: %s -> %s", castFrom, castTo) + return invalidCastError(castFrom, castTo) } if !allowStable && cast.volatility >= VolatilityStable { err := NewContextDependentOpsNotAllowedError(context) diff --git a/pkg/sql/sqltelemetry/scalar.go b/pkg/sql/sqltelemetry/scalar.go index 68279462dd09..b7030d706e7d 100644 --- a/pkg/sql/sqltelemetry/scalar.go +++ b/pkg/sql/sqltelemetry/scalar.go @@ -52,6 +52,10 @@ func CastOpCounter(ftyp, ttyp string) telemetry.Counter { // counter for the element type. var ArrayCastCounter = telemetry.GetCounterOnce("sql.plan.ops.cast.arrays") +// TupleCastCounter is to be incremented when type checking all casts +// that involve tuples. +var TupleCastCounter = telemetry.GetCounterOnce("sql.plan.ops.cast.tuples") + // EnumCastCounter is to be incremented when typechecking casts that // are between enums. var EnumCastCounter = telemetry.GetCounterOnce("sql.plan.ops.cast.enums") diff --git a/pkg/sql/types/oid.go b/pkg/sql/types/oid.go index 2e567e4c42fe..b9521ca05377 100644 --- a/pkg/sql/types/oid.go +++ b/pkg/sql/types/oid.go @@ -211,6 +211,14 @@ func CalcArrayOid(elemTyp *T) oid.Oid { case EnumFamily: return elemTyp.UserDefinedArrayOID() + + case TupleFamily: + if elemTyp.UserDefined() { + // We're currently not creating array types for implicitly-defined + // per-table record types. So, we cheat a little, and return, as the OID + // for an array of these things, the OID for a generic array of records. + return oid.T__record + } } // Map the OID of the array element type to the corresponding array OID. diff --git a/pkg/sql/types/types.go b/pkg/sql/types/types.go index 2c7dd628db82..e7b6f27c37d7 100644 --- a/pkg/sql/types/types.go +++ b/pkg/sql/types/types.go @@ -1675,6 +1675,10 @@ func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string { } return fmt.Sprintf("timestamp(%d) with time zone", typmod) case TupleFamily: + if t.UserDefined() { + // If we have a user-defined tuple type, use its user-defined name. + return t.TypeMeta.Name.Basename() + } return "record" case UnknownFamily: return "unknown"