From 6fb3a9d33c08069cd9b5182b70b403a671385ed2 Mon Sep 17 00:00:00 2001 From: Yong Tang Date: Wed, 8 Feb 2017 11:58:22 -0800 Subject: [PATCH] Update SwarmKit to ed384f3b3957f65e3111bd020f9815f3d4296fa2 This fix updates SwarmKit to ed384f3b3957f65e3111bd020f9815f3d4296fa2. Notable changes since last update (3ca4775ba4a5519e2225c3337c7db8901ec39d26): 1. Fix duplicated ports allocation with restarted swarm. (Docker issue #29247) 2. Topology-aware scheduling (Docker PR #30725) Docker issue #29247 was labeled 1.13.1, though it is advised that related SwarmKit changes only to be merged to master (based on the feedback https://github.com/docker/swarmkit/pull/1802#issuecomment-274143500) This fix fixes #29247 (master only). This fix is related to #30725. Signed-off-by: Yong Tang --- vendor.conf | 2 +- .../docker/swarmkit/api/types.pb.go | 1032 ++++++++++++----- .../docker/swarmkit/api/types.proto | 21 +- .../swarmkit/manager/allocator/network.go | 2 +- .../networkallocator/networkallocator.go | 21 +- .../networkallocator/portallocator.go | 11 + .../swarmkit/manager/constraint/constraint.go | 14 +- .../manager/scheduler/decision_tree.go | 55 + .../swarmkit/manager/scheduler/nodeheap.go | 31 + .../swarmkit/manager/scheduler/nodeset.go | 121 +- .../swarmkit/manager/scheduler/scheduler.go | 88 +- 11 files changed, 1047 insertions(+), 351 deletions(-) create mode 100644 vendor/github.com/docker/swarmkit/manager/scheduler/decision_tree.go create mode 100644 vendor/github.com/docker/swarmkit/manager/scheduler/nodeheap.go diff --git a/vendor.conf b/vendor.conf index c63a646d54..c5de531a74 100644 --- a/vendor.conf +++ b/vendor.conf @@ -102,7 +102,7 @@ github.com/docker/containerd 78fb8f45890a601e0fd9051cf9f9f74923e950fd github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 # cluster -github.com/docker/swarmkit 3ca4775ba4a5519e2225c3337c7db8901ec39d26 +github.com/docker/swarmkit ed384f3b3957f65e3111bd020f9815f3d4296fa2 github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9 github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a diff --git a/vendor/github.com/docker/swarmkit/api/types.pb.go b/vendor/github.com/docker/swarmkit/api/types.pb.go index ae15ca7f2a..3138e9c1d9 100644 --- a/vendor/github.com/docker/swarmkit/api/types.pb.go +++ b/vendor/github.com/docker/swarmkit/api/types.pb.go @@ -53,6 +53,8 @@ DispatcherConfig RaftConfig EncryptionConfig + SpreadOver + PlacementPreference Placement JoinTokens RootCA @@ -667,7 +669,7 @@ func (x EncryptionKey_Algorithm) String() string { return proto.EnumName(EncryptionKey_Algorithm_name, int32(x)) } func (EncryptionKey_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{38, 0} + return fileDescriptorTypes, []int{40, 0} } type MaybeEncryptedRecord_Algorithm int32 @@ -690,7 +692,7 @@ func (x MaybeEncryptedRecord_Algorithm) String() string { return proto.EnumName(MaybeEncryptedRecord_Algorithm_name, int32(x)) } func (MaybeEncryptedRecord_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{43, 0} + return fileDescriptorTypes, []int{45, 0} } // Version tracks the last time an object in the store was updated. @@ -1383,15 +1385,118 @@ func (m *EncryptionConfig) Reset() { *m = EncryptionConfig{} func (*EncryptionConfig) ProtoMessage() {} func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } +type SpreadOver struct { + SpreadDescriptor string `protobuf:"bytes,1,opt,name=spread_descriptor,json=spreadDescriptor,proto3" json:"spread_descriptor,omitempty"` +} + +func (m *SpreadOver) Reset() { *m = SpreadOver{} } +func (*SpreadOver) ProtoMessage() {} +func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } + +type PlacementPreference struct { + // Types that are valid to be assigned to Preference: + // *PlacementPreference_Spread + Preference isPlacementPreference_Preference `protobuf_oneof:"Preference"` +} + +func (m *PlacementPreference) Reset() { *m = PlacementPreference{} } +func (*PlacementPreference) ProtoMessage() {} +func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } + +type isPlacementPreference_Preference interface { + isPlacementPreference_Preference() + MarshalTo([]byte) (int, error) + Size() int +} + +type PlacementPreference_Spread struct { + Spread *SpreadOver `protobuf:"bytes,1,opt,name=spread,oneof"` +} + +func (*PlacementPreference_Spread) isPlacementPreference_Preference() {} + +func (m *PlacementPreference) GetPreference() isPlacementPreference_Preference { + if m != nil { + return m.Preference + } + return nil +} + +func (m *PlacementPreference) GetSpread() *SpreadOver { + if x, ok := m.GetPreference().(*PlacementPreference_Spread); ok { + return x.Spread + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*PlacementPreference) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _PlacementPreference_OneofMarshaler, _PlacementPreference_OneofUnmarshaler, _PlacementPreference_OneofSizer, []interface{}{ + (*PlacementPreference_Spread)(nil), + } +} + +func _PlacementPreference_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*PlacementPreference) + // Preference + switch x := m.Preference.(type) { + case *PlacementPreference_Spread: + _ = b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Spread); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("PlacementPreference.Preference has unexpected type %T", x) + } + return nil +} + +func _PlacementPreference_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*PlacementPreference) + switch tag { + case 1: // Preference.spread + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(SpreadOver) + err := b.DecodeMessage(msg) + m.Preference = &PlacementPreference_Spread{msg} + return true, err + default: + return false, nil + } +} + +func _PlacementPreference_OneofSizer(msg proto.Message) (n int) { + m := msg.(*PlacementPreference) + // Preference + switch x := m.Preference.(type) { + case *PlacementPreference_Spread: + s := proto.Size(x.Spread) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + // Placement specifies task distribution constraints. type Placement struct { - // constraints specifies a set of requirements a node should meet for a task. + // Constraints specifies a set of requirements a node should meet for a task. Constraints []string `protobuf:"bytes,1,rep,name=constraints" json:"constraints,omitempty"` + // Preferences provide a way to make the scheduler aware of factors + // such as topology. They are provided in order from highest to lowest + // precedence. + Preferences []*PlacementPreference `protobuf:"bytes,2,rep,name=preferences" json:"preferences,omitempty"` } func (m *Placement) Reset() { *m = Placement{} } func (*Placement) ProtoMessage() {} -func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } +func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } // JoinToken contains the join tokens for workers and managers. type JoinTokens struct { @@ -1403,7 +1508,7 @@ type JoinTokens struct { func (m *JoinTokens) Reset() { *m = JoinTokens{} } func (*JoinTokens) ProtoMessage() {} -func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } +func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } type RootCA struct { // CAKey is the root CA private key. @@ -1418,7 +1523,7 @@ type RootCA struct { func (m *RootCA) Reset() { *m = RootCA{} } func (*RootCA) ProtoMessage() {} -func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } +func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } type Certificate struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1431,7 +1536,7 @@ type Certificate struct { func (m *Certificate) Reset() { *m = Certificate{} } func (*Certificate) ProtoMessage() {} -func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } +func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } // Symmetric keys to encrypt inter-agent communication. type EncryptionKey struct { @@ -1447,7 +1552,7 @@ type EncryptionKey struct { func (m *EncryptionKey) Reset() { *m = EncryptionKey{} } func (*EncryptionKey) ProtoMessage() {} -func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } +func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } // ManagerStatus provides informations about the state of a manager in the cluster. type ManagerStatus struct { @@ -1464,7 +1569,7 @@ type ManagerStatus struct { func (m *ManagerStatus) Reset() { *m = ManagerStatus{} } func (*ManagerStatus) ProtoMessage() {} -func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } +func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } // SecretReference is the linkage between a service and a secret that it uses. type SecretReference struct { @@ -1484,7 +1589,7 @@ type SecretReference struct { func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} -func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } +func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } type isSecretReference_Target interface { isSecretReference_Target() @@ -1582,7 +1687,7 @@ type SecretReference_FileTarget struct { func (m *SecretReference_FileTarget) Reset() { *m = SecretReference_FileTarget{} } func (*SecretReference_FileTarget) ProtoMessage() {} func (*SecretReference_FileTarget) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{40, 0} + return fileDescriptorTypes, []int{42, 0} } // BlacklistedCertificate is a record for a blacklisted certificate. It does not @@ -1596,7 +1701,7 @@ type BlacklistedCertificate struct { func (m *BlacklistedCertificate) Reset() { *m = BlacklistedCertificate{} } func (*BlacklistedCertificate) ProtoMessage() {} -func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } +func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } // HealthConfig holds configuration settings for the HEALTHCHECK feature. type HealthConfig struct { @@ -1622,7 +1727,7 @@ type HealthConfig struct { func (m *HealthConfig) Reset() { *m = HealthConfig{} } func (*HealthConfig) ProtoMessage() {} -func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } +func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } type MaybeEncryptedRecord struct { Algorithm MaybeEncryptedRecord_Algorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=docker.swarmkit.v1.MaybeEncryptedRecord_Algorithm" json:"algorithm,omitempty"` @@ -1632,7 +1737,7 @@ type MaybeEncryptedRecord struct { func (m *MaybeEncryptedRecord) Reset() { *m = MaybeEncryptedRecord{} } func (*MaybeEncryptedRecord) ProtoMessage() {} -func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } +func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } func init() { proto.RegisterType((*Version)(nil), "docker.swarmkit.v1.Version") @@ -1674,6 +1779,8 @@ func init() { proto.RegisterType((*DispatcherConfig)(nil), "docker.swarmkit.v1.DispatcherConfig") proto.RegisterType((*RaftConfig)(nil), "docker.swarmkit.v1.RaftConfig") proto.RegisterType((*EncryptionConfig)(nil), "docker.swarmkit.v1.EncryptionConfig") + proto.RegisterType((*SpreadOver)(nil), "docker.swarmkit.v1.SpreadOver") + proto.RegisterType((*PlacementPreference)(nil), "docker.swarmkit.v1.PlacementPreference") proto.RegisterType((*Placement)(nil), "docker.swarmkit.v1.Placement") proto.RegisterType((*JoinTokens)(nil), "docker.swarmkit.v1.JoinTokens") proto.RegisterType((*RootCA)(nil), "docker.swarmkit.v1.RootCA") @@ -2479,6 +2586,47 @@ func (m *EncryptionConfig) CopyFrom(src interface{}) { *m = *o } +func (m *SpreadOver) Copy() *SpreadOver { + if m == nil { + return nil + } + o := &SpreadOver{} + o.CopyFrom(m) + return o +} + +func (m *SpreadOver) CopyFrom(src interface{}) { + + o := src.(*SpreadOver) + *m = *o +} + +func (m *PlacementPreference) Copy() *PlacementPreference { + if m == nil { + return nil + } + o := &PlacementPreference{} + o.CopyFrom(m) + return o +} + +func (m *PlacementPreference) CopyFrom(src interface{}) { + + o := src.(*PlacementPreference) + *m = *o + if o.Preference != nil { + switch o.Preference.(type) { + case *PlacementPreference_Spread: + v := PlacementPreference_Spread{ + Spread: &SpreadOver{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Spread, o.GetSpread()) + m.Preference = &v + } + } + +} + func (m *Placement) Copy() *Placement { if m == nil { return nil @@ -2497,6 +2645,14 @@ func (m *Placement) CopyFrom(src interface{}) { copy(m.Constraints, o.Constraints) } + if o.Preferences != nil { + m.Preferences = make([]*PlacementPreference, len(o.Preferences)) + for i := range m.Preferences { + m.Preferences[i] = &PlacementPreference{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Preferences[i], o.Preferences[i]) + } + } + } func (m *JoinTokens) Copy() *JoinTokens { @@ -4211,6 +4367,69 @@ func (m *EncryptionConfig) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *SpreadOver) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SpreadOver) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.SpreadDescriptor) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.SpreadDescriptor))) + i += copy(dAtA[i:], m.SpreadDescriptor) + } + return i, nil +} + +func (m *PlacementPreference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PlacementPreference) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Preference != nil { + nn26, err := m.Preference.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += nn26 + } + return i, nil +} + +func (m *PlacementPreference_Spread) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Spread != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Spread.Size())) + n27, err := m.Spread.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n27 + } + return i, nil +} func (m *Placement) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4241,6 +4460,18 @@ func (m *Placement) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], s) } } + if len(m.Preferences) > 0 { + for _, msg := range m.Preferences { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -4310,11 +4541,11 @@ func (m *RootCA) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.JoinTokens.Size())) - n26, err := m.JoinTokens.MarshalTo(dAtA[i:]) + n28, err := m.JoinTokens.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n28 return i, nil } @@ -4347,11 +4578,11 @@ func (m *Certificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size())) - n27, err := m.Status.MarshalTo(dAtA[i:]) + n29, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n29 if len(m.Certificate) > 0 { dAtA[i] = 0x22 i++ @@ -4479,11 +4710,11 @@ func (m *SecretReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.SecretName) } if m.Target != nil { - nn28, err := m.Target.MarshalTo(dAtA[i:]) + nn30, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn28 + i += nn30 } return i, nil } @@ -4494,11 +4725,11 @@ func (m *SecretReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n29, err := m.File.MarshalTo(dAtA[i:]) + n31, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n31 } return i, nil } @@ -4562,11 +4793,11 @@ func (m *BlacklistedCertificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Expiry.Size())) - n30, err := m.Expiry.MarshalTo(dAtA[i:]) + n32, err := m.Expiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n32 } return i, nil } @@ -4605,21 +4836,21 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Interval.Size())) - n31, err := m.Interval.MarshalTo(dAtA[i:]) + n33, err := m.Interval.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n33 } if m.Timeout != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timeout.Size())) - n32, err := m.Timeout.MarshalTo(dAtA[i:]) + n34, err := m.Timeout.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n34 } if m.Retries != 0 { dAtA[i] = 0x20 @@ -5348,6 +5579,34 @@ func (m *EncryptionConfig) Size() (n int) { return n } +func (m *SpreadOver) Size() (n int) { + var l int + _ = l + l = len(m.SpreadDescriptor) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *PlacementPreference) Size() (n int) { + var l int + _ = l + if m.Preference != nil { + n += m.Preference.Size() + } + return n +} + +func (m *PlacementPreference_Spread) Size() (n int) { + var l int + _ = l + if m.Spread != nil { + l = m.Spread.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *Placement) Size() (n int) { var l int _ = l @@ -5357,6 +5616,12 @@ func (m *Placement) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) } } + if len(m.Preferences) > 0 { + for _, e := range m.Preferences { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } return n } @@ -6091,12 +6356,43 @@ func (this *EncryptionConfig) String() string { }, "") return s } +func (this *SpreadOver) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SpreadOver{`, + `SpreadDescriptor:` + fmt.Sprintf("%v", this.SpreadDescriptor) + `,`, + `}`, + }, "") + return s +} +func (this *PlacementPreference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PlacementPreference{`, + `Preference:` + fmt.Sprintf("%v", this.Preference) + `,`, + `}`, + }, "") + return s +} +func (this *PlacementPreference_Spread) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PlacementPreference_Spread{`, + `Spread:` + strings.Replace(fmt.Sprintf("%v", this.Spread), "SpreadOver", "SpreadOver", 1) + `,`, + `}`, + }, "") + return s +} func (this *Placement) String() string { if this == nil { return "nil" } s := strings.Join([]string{`&Placement{`, `Constraints:` + fmt.Sprintf("%v", this.Constraints) + `,`, + `Preferences:` + strings.Replace(fmt.Sprintf("%v", this.Preferences), "PlacementPreference", "PlacementPreference", 1) + `,`, `}`, }, "") return s @@ -11455,6 +11751,167 @@ func (m *EncryptionConfig) Unmarshal(dAtA []byte) error { } return nil } +func (m *SpreadOver) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SpreadOver: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SpreadOver: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpreadDescriptor", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpreadDescriptor = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PlacementPreference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PlacementPreference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PlacementPreference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spread", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SpreadOver{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Preference = &PlacementPreference_Spread{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Placement) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -11513,6 +11970,37 @@ func (m *Placement) Unmarshal(dAtA []byte) error { } m.Constraints = append(m.Constraints, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Preferences", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Preferences = append(m.Preferences, &PlacementPreference{}) + if err := m.Preferences[len(m.Preferences)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -13070,255 +13558,259 @@ var ( func init() { proto.RegisterFile("types.proto", fileDescriptorTypes) } var fileDescriptorTypes = []byte{ - // 3991 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x59, 0x4d, 0x6c, 0x1b, 0x49, + // 4064 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x5a, 0x4d, 0x6c, 0x1b, 0x49, 0x76, 0x16, 0x7f, 0x45, 0x3e, 0x52, 0x52, 0xbb, 0xec, 0xf5, 0xca, 0x1c, 0x8f, 0xc4, 0xe9, 0x19, - 0xef, 0x78, 0xbc, 0x0e, 0xc7, 0x96, 0x77, 0x16, 0x9e, 0x31, 0x76, 0x3d, 0xcd, 0x1f, 0x5b, 0x5c, - 0x4b, 0x24, 0x51, 0xa4, 0xec, 0x9d, 0x4b, 0x88, 0x52, 0x77, 0x89, 0xea, 0x51, 0xb3, 0x8b, 0xe9, - 0x6e, 0x4a, 0x66, 0x82, 0x20, 0x46, 0x0e, 0x49, 0xa0, 0x53, 0x8e, 0x01, 0x02, 0x21, 0x08, 0x36, - 0x87, 0x20, 0x87, 0x5c, 0x72, 0x08, 0x90, 0x4b, 0xe6, 0x38, 0xc7, 0x4d, 0x02, 0x04, 0x8b, 0x2c, - 0xe0, 0x64, 0x95, 0x73, 0x90, 0x5c, 0x16, 0xb9, 0x24, 0x40, 0x50, 0x3f, 0xdd, 0x6c, 0xd2, 0xb4, - 0xec, 0xc9, 0xee, 0x85, 0xec, 0x7a, 0xf5, 0xbd, 0x57, 0x7f, 0xaf, 0xaa, 0xbe, 0xf7, 0x0a, 0x0a, - 0xc1, 0x64, 0x44, 0xfd, 0xca, 0xc8, 0x63, 0x01, 0x43, 0xc8, 0x62, 0xe6, 0x11, 0xf5, 0x2a, 0xfe, - 0x09, 0xf1, 0x86, 0x47, 0x76, 0x50, 0x39, 0xbe, 0x5b, 0xda, 0x1c, 0x30, 0x36, 0x70, 0xe8, 0xc7, - 0x02, 0xb1, 0x3f, 0x3e, 0xf8, 0x38, 0xb0, 0x87, 0xd4, 0x0f, 0xc8, 0x70, 0x24, 0x95, 0x4a, 0x1b, - 0xf3, 0x00, 0x6b, 0xec, 0x91, 0xc0, 0x66, 0xae, 0xaa, 0xbf, 0x32, 0x60, 0x03, 0x26, 0x3e, 0x3f, - 0xe6, 0x5f, 0x52, 0xaa, 0x6f, 0xc2, 0xf2, 0x53, 0xea, 0xf9, 0x36, 0x73, 0xd1, 0x15, 0xc8, 0xd8, - 0xae, 0x45, 0x9f, 0xaf, 0x27, 0xca, 0x89, 0x9b, 0x69, 0x2c, 0x0b, 0xfa, 0x9f, 0x27, 0xa0, 0x60, - 0xb8, 0x2e, 0x0b, 0x84, 0x2d, 0x1f, 0x21, 0x48, 0xbb, 0x64, 0x48, 0x05, 0x28, 0x8f, 0xc5, 0x37, - 0xaa, 0x41, 0xd6, 0x21, 0xfb, 0xd4, 0xf1, 0xd7, 0x93, 0xe5, 0xd4, 0xcd, 0xc2, 0xd6, 0x77, 0x2b, - 0xaf, 0x0e, 0xa0, 0x12, 0x33, 0x52, 0xd9, 0x11, 0xe8, 0x86, 0x1b, 0x78, 0x13, 0xac, 0x54, 0x4b, - 0x9f, 0x42, 0x21, 0x26, 0x46, 0x1a, 0xa4, 0x8e, 0xe8, 0x44, 0x35, 0xc3, 0x3f, 0x79, 0xff, 0x8e, - 0x89, 0x33, 0xa6, 0xeb, 0x49, 0x21, 0x93, 0x85, 0xcf, 0x92, 0xf7, 0x13, 0xfa, 0x17, 0x90, 0xc7, - 0xd4, 0x67, 0x63, 0xcf, 0xa4, 0x3e, 0xfa, 0x08, 0xf2, 0x2e, 0x71, 0x59, 0xdf, 0x1c, 0x8d, 0x7d, - 0xa1, 0x9e, 0xaa, 0x16, 0xcf, 0x5f, 0x6e, 0xe6, 0x5a, 0xc4, 0x65, 0xb5, 0xce, 0x9e, 0x8f, 0x73, - 0xbc, 0xba, 0x36, 0x1a, 0xfb, 0xe8, 0x3d, 0x28, 0x0e, 0xe9, 0x90, 0x79, 0x93, 0xfe, 0xfe, 0x24, - 0xa0, 0xbe, 0x30, 0x9c, 0xc2, 0x05, 0x29, 0xab, 0x72, 0x91, 0xfe, 0xc7, 0x09, 0xb8, 0x12, 0xda, - 0xc6, 0xf4, 0xb7, 0xc6, 0xb6, 0x47, 0x87, 0xd4, 0x0d, 0x7c, 0xf4, 0x09, 0x64, 0x1d, 0x7b, 0x68, - 0x07, 0xb2, 0x8d, 0xc2, 0xd6, 0xbb, 0x8b, 0xc6, 0x1c, 0xf5, 0x0a, 0x2b, 0x30, 0x32, 0xa0, 0xe8, - 0x51, 0x9f, 0x7a, 0xc7, 0x72, 0x26, 0x44, 0x93, 0x6f, 0x54, 0x9e, 0x51, 0xd1, 0x1f, 0x41, 0xae, - 0xe3, 0x90, 0xe0, 0x80, 0x79, 0x43, 0xa4, 0x43, 0x91, 0x78, 0xe6, 0xa1, 0x1d, 0x50, 0x33, 0x18, - 0x7b, 0xe1, 0xaa, 0xcc, 0xc8, 0xd0, 0x55, 0x48, 0x32, 0xd9, 0x50, 0xbe, 0x9a, 0x3d, 0x7f, 0xb9, - 0x99, 0x6c, 0x77, 0x71, 0x92, 0xf9, 0xfa, 0x03, 0xb8, 0xd4, 0x71, 0xc6, 0x03, 0xdb, 0xad, 0x53, - 0xdf, 0xf4, 0xec, 0x11, 0xb7, 0xce, 0x97, 0x97, 0x7b, 0x62, 0xb8, 0xbc, 0xfc, 0x3b, 0x5a, 0xf2, - 0xe4, 0x74, 0xc9, 0xf5, 0x3f, 0x4c, 0xc2, 0xa5, 0x86, 0x3b, 0xb0, 0x5d, 0x1a, 0xd7, 0xbe, 0x01, - 0xab, 0x54, 0x08, 0xfb, 0xc7, 0xd2, 0xa9, 0x94, 0x9d, 0x15, 0x29, 0x0d, 0x3d, 0xad, 0x39, 0xe7, - 0x2f, 0x77, 0x17, 0x0d, 0xff, 0x15, 0xeb, 0x8b, 0xbc, 0x06, 0x35, 0x60, 0x79, 0x24, 0x06, 0xe1, - 0xaf, 0xa7, 0x84, 0xad, 0x1b, 0x8b, 0x6c, 0xbd, 0x32, 0xce, 0x6a, 0xfa, 0xeb, 0x97, 0x9b, 0x4b, - 0x38, 0xd4, 0xfd, 0x55, 0x9c, 0xef, 0xdf, 0x13, 0xb0, 0xd6, 0x62, 0xd6, 0xcc, 0x3c, 0x94, 0x20, - 0x77, 0xc8, 0xfc, 0x20, 0xb6, 0x51, 0xa2, 0x32, 0xba, 0x0f, 0xb9, 0x91, 0x5a, 0x3e, 0xb5, 0xfa, - 0xd7, 0x17, 0x77, 0x59, 0x62, 0x70, 0x84, 0x46, 0x0f, 0x20, 0xef, 0x85, 0x3e, 0xb1, 0x9e, 0x7a, - 0x1b, 0xc7, 0x99, 0xe2, 0xd1, 0x0f, 0x20, 0x2b, 0x17, 0x61, 0x3d, 0x2d, 0x34, 0x6f, 0xbc, 0xd5, - 0x9c, 0x63, 0xa5, 0xa4, 0xff, 0x2c, 0x01, 0x1a, 0x26, 0x07, 0xc1, 0x2e, 0x1d, 0xee, 0x53, 0xaf, - 0x1b, 0x90, 0x60, 0xec, 0xa3, 0xab, 0x90, 0x75, 0x28, 0xb1, 0xa8, 0x27, 0x06, 0x99, 0xc3, 0xaa, - 0x84, 0xf6, 0xb8, 0x93, 0x13, 0xf3, 0x90, 0xec, 0xdb, 0x8e, 0x1d, 0x4c, 0xc4, 0x30, 0x57, 0x17, - 0xaf, 0xf2, 0xbc, 0xcd, 0x0a, 0x8e, 0x29, 0xe2, 0x19, 0x33, 0x68, 0x1d, 0x96, 0x87, 0xd4, 0xf7, - 0xc9, 0x80, 0x8a, 0xd1, 0xe7, 0x71, 0x58, 0xd4, 0x1f, 0x40, 0x31, 0xae, 0x87, 0x0a, 0xb0, 0xbc, - 0xd7, 0x7a, 0xd2, 0x6a, 0x3f, 0x6b, 0x69, 0x4b, 0x68, 0x0d, 0x0a, 0x7b, 0x2d, 0xdc, 0x30, 0x6a, - 0xdb, 0x46, 0x75, 0xa7, 0xa1, 0x25, 0xd0, 0x0a, 0xe4, 0xa7, 0xc5, 0xa4, 0xfe, 0x37, 0x09, 0x00, - 0xbe, 0x80, 0x6a, 0x50, 0x9f, 0x41, 0xc6, 0x0f, 0x48, 0x20, 0x17, 0x6e, 0x75, 0xeb, 0x83, 0x45, - 0xbd, 0x9e, 0xc2, 0x2b, 0xfc, 0x8f, 0x62, 0xa9, 0x12, 0xef, 0x61, 0x72, 0xa6, 0x87, 0x7c, 0x0f, + 0xef, 0x78, 0xbc, 0x06, 0xc7, 0x96, 0x77, 0x16, 0x9e, 0x31, 0x76, 0x3d, 0xcd, 0x1f, 0x5b, 0x5c, + 0x4b, 0x24, 0x51, 0xa4, 0xec, 0x9d, 0x43, 0x42, 0x94, 0xba, 0x4b, 0x54, 0x8f, 0x9a, 0x5d, 0x4c, + 0x77, 0x53, 0x32, 0x13, 0x04, 0x31, 0x72, 0x48, 0x02, 0x9d, 0x72, 0x0c, 0x10, 0x08, 0x41, 0xb0, + 0x39, 0x04, 0x39, 0xe4, 0x92, 0x43, 0x80, 0x5c, 0x32, 0xc7, 0x39, 0x6e, 0x12, 0x20, 0x58, 0x64, + 0x01, 0x27, 0xab, 0x9c, 0x83, 0xe4, 0xb2, 0xc8, 0x25, 0x01, 0x82, 0xfa, 0xe9, 0x66, 0x93, 0xa6, + 0x65, 0x4f, 0x76, 0x2f, 0x52, 0xd7, 0xab, 0xef, 0xbd, 0xfa, 0x79, 0xaf, 0xaa, 0xbe, 0x57, 0x45, + 0x28, 0x04, 0x93, 0x11, 0xf5, 0x2b, 0x23, 0x8f, 0x05, 0x0c, 0x21, 0x8b, 0x99, 0x47, 0xd4, 0xab, + 0xf8, 0x27, 0xc4, 0x1b, 0x1e, 0xd9, 0x41, 0xe5, 0xf8, 0x6e, 0x69, 0x73, 0xc0, 0xd8, 0xc0, 0xa1, + 0x1f, 0x0b, 0xc4, 0xfe, 0xf8, 0xe0, 0xe3, 0xc0, 0x1e, 0x52, 0x3f, 0x20, 0xc3, 0x91, 0x54, 0x2a, + 0x6d, 0xcc, 0x03, 0xac, 0xb1, 0x47, 0x02, 0x9b, 0xb9, 0xaa, 0xfe, 0xca, 0x80, 0x0d, 0x98, 0xf8, + 0xfc, 0x98, 0x7f, 0x49, 0xa9, 0xbe, 0x09, 0xcb, 0x4f, 0xa9, 0xe7, 0xdb, 0xcc, 0x45, 0x57, 0x20, + 0x63, 0xbb, 0x16, 0x7d, 0xbe, 0x9e, 0x28, 0x27, 0x6e, 0xa6, 0xb1, 0x2c, 0xe8, 0x7f, 0x9e, 0x80, + 0x82, 0xe1, 0xba, 0x2c, 0x10, 0xb6, 0x7c, 0x84, 0x20, 0xed, 0x92, 0x21, 0x15, 0xa0, 0x3c, 0x16, + 0xdf, 0xa8, 0x06, 0x59, 0x87, 0xec, 0x53, 0xc7, 0x5f, 0x4f, 0x96, 0x53, 0x37, 0x0b, 0x5b, 0xdf, + 0xad, 0xbc, 0x3a, 0x80, 0x4a, 0xcc, 0x48, 0x65, 0x47, 0xa0, 0x1b, 0x6e, 0xe0, 0x4d, 0xb0, 0x52, + 0x2d, 0x7d, 0x0a, 0x85, 0x98, 0x18, 0x69, 0x90, 0x3a, 0xa2, 0x13, 0xd5, 0x0c, 0xff, 0xe4, 0xfd, + 0x3b, 0x26, 0xce, 0x98, 0xae, 0x27, 0x85, 0x4c, 0x16, 0x3e, 0x4b, 0xde, 0x4f, 0xe8, 0x5f, 0x40, + 0x1e, 0x53, 0x9f, 0x8d, 0x3d, 0x93, 0xfa, 0xe8, 0x23, 0xc8, 0xbb, 0xc4, 0x65, 0x7d, 0x73, 0x34, + 0xf6, 0x85, 0x7a, 0xaa, 0x5a, 0x3c, 0x7f, 0xb9, 0x99, 0x6b, 0x11, 0x97, 0xd5, 0x3a, 0x7b, 0x3e, + 0xce, 0xf1, 0xea, 0xda, 0x68, 0xec, 0xa3, 0xf7, 0xa0, 0x38, 0xa4, 0x43, 0xe6, 0x4d, 0xfa, 0xfb, + 0x93, 0x80, 0xfa, 0xc2, 0x70, 0x0a, 0x17, 0xa4, 0xac, 0xca, 0x45, 0xfa, 0x1f, 0x27, 0xe0, 0x4a, + 0x68, 0x1b, 0xd3, 0xdf, 0x1a, 0xdb, 0x1e, 0x1d, 0x52, 0x37, 0xf0, 0xd1, 0x27, 0x90, 0x75, 0xec, + 0xa1, 0x1d, 0xc8, 0x36, 0x0a, 0x5b, 0xef, 0x2e, 0x1a, 0x73, 0xd4, 0x2b, 0xac, 0xc0, 0xc8, 0x80, + 0xa2, 0x47, 0x7d, 0xea, 0x1d, 0xcb, 0x99, 0x10, 0x4d, 0xbe, 0x51, 0x79, 0x46, 0x45, 0x7f, 0x04, + 0xb9, 0x8e, 0x43, 0x82, 0x03, 0xe6, 0x0d, 0x91, 0x0e, 0x45, 0xe2, 0x99, 0x87, 0x76, 0x40, 0xcd, + 0x60, 0xec, 0x85, 0x5e, 0x99, 0x91, 0xa1, 0xab, 0x90, 0x64, 0xb2, 0xa1, 0x7c, 0x35, 0x7b, 0xfe, + 0x72, 0x33, 0xd9, 0xee, 0xe2, 0x24, 0xf3, 0xf5, 0x07, 0x70, 0xa9, 0xe3, 0x8c, 0x07, 0xb6, 0x5b, + 0xa7, 0xbe, 0xe9, 0xd9, 0x23, 0x6e, 0x9d, 0xbb, 0x97, 0x47, 0x62, 0xe8, 0x5e, 0xfe, 0x1d, 0xb9, + 0x3c, 0x39, 0x75, 0xb9, 0xfe, 0x87, 0x49, 0xb8, 0xd4, 0x70, 0x07, 0xb6, 0x4b, 0xe3, 0xda, 0x37, + 0x60, 0x95, 0x0a, 0x61, 0xff, 0x58, 0x06, 0x95, 0xb2, 0xb3, 0x22, 0xa5, 0x61, 0xa4, 0x35, 0xe7, + 0xe2, 0xe5, 0xee, 0xa2, 0xe1, 0xbf, 0x62, 0x7d, 0x51, 0xd4, 0xa0, 0x06, 0x2c, 0x8f, 0xc4, 0x20, + 0xfc, 0xf5, 0x94, 0xb0, 0x75, 0x63, 0x91, 0xad, 0x57, 0xc6, 0x59, 0x4d, 0x7f, 0xfd, 0x72, 0x73, + 0x09, 0x87, 0xba, 0xbf, 0x4a, 0xf0, 0xfd, 0x7b, 0x02, 0xd6, 0x5a, 0xcc, 0x9a, 0x99, 0x87, 0x12, + 0xe4, 0x0e, 0x99, 0x1f, 0xc4, 0x16, 0x4a, 0x54, 0x46, 0xf7, 0x21, 0x37, 0x52, 0xee, 0x53, 0xde, + 0xbf, 0xbe, 0xb8, 0xcb, 0x12, 0x83, 0x23, 0x34, 0x7a, 0x00, 0x79, 0x2f, 0x8c, 0x89, 0xf5, 0xd4, + 0xdb, 0x04, 0xce, 0x14, 0x8f, 0x7e, 0x00, 0x59, 0xe9, 0x84, 0xf5, 0xb4, 0xd0, 0xbc, 0xf1, 0x56, + 0x73, 0x8e, 0x95, 0x92, 0xfe, 0xb3, 0x04, 0x68, 0x98, 0x1c, 0x04, 0xbb, 0x74, 0xb8, 0x4f, 0xbd, + 0x6e, 0x40, 0x82, 0xb1, 0x8f, 0xae, 0x42, 0xd6, 0xa1, 0xc4, 0xa2, 0x9e, 0x18, 0x64, 0x0e, 0xab, + 0x12, 0xda, 0xe3, 0x41, 0x4e, 0xcc, 0x43, 0xb2, 0x6f, 0x3b, 0x76, 0x30, 0x11, 0xc3, 0x5c, 0x5d, + 0xec, 0xe5, 0x79, 0x9b, 0x15, 0x1c, 0x53, 0xc4, 0x33, 0x66, 0xd0, 0x3a, 0x2c, 0x0f, 0xa9, 0xef, + 0x93, 0x01, 0x15, 0xa3, 0xcf, 0xe3, 0xb0, 0xa8, 0x3f, 0x80, 0x62, 0x5c, 0x0f, 0x15, 0x60, 0x79, + 0xaf, 0xf5, 0xa4, 0xd5, 0x7e, 0xd6, 0xd2, 0x96, 0xd0, 0x1a, 0x14, 0xf6, 0x5a, 0xb8, 0x61, 0xd4, + 0xb6, 0x8d, 0xea, 0x4e, 0x43, 0x4b, 0xa0, 0x15, 0xc8, 0x4f, 0x8b, 0x49, 0xfd, 0x6f, 0x12, 0x00, + 0xdc, 0x81, 0x6a, 0x50, 0x9f, 0x41, 0xc6, 0x0f, 0x48, 0x20, 0x1d, 0xb7, 0xba, 0xf5, 0xc1, 0xa2, + 0x5e, 0x4f, 0xe1, 0x15, 0xfe, 0x8f, 0x62, 0xa9, 0x12, 0xef, 0x61, 0x72, 0xa6, 0x87, 0x7c, 0x0d, 0x11, 0xcb, 0xf2, 0x54, 0xc7, 0xc5, 0xb7, 0xfe, 0x00, 0x32, 0x42, 0x7b, 0xb6, 0xbb, 0x39, 0x48, 0xd7, 0xf9, 0x57, 0x02, 0xe5, 0x21, 0x83, 0x1b, 0x46, 0xfd, 0x0b, 0x2d, 0x89, 0x34, 0x28, 0xd6, 0x9b, 0xdd, 0x5a, 0xbb, 0xd5, 0x6a, 0xd4, 0x7a, 0x8d, 0xba, 0x96, 0xd2, 0x6f, 0x40, 0xa6, 0x39, - 0xe4, 0x96, 0xaf, 0x73, 0xaf, 0x38, 0xa0, 0x1e, 0x75, 0xcd, 0xd0, 0xd9, 0xa6, 0x02, 0xfd, 0xa7, - 0x79, 0xc8, 0xec, 0xb2, 0xb1, 0x1b, 0xa0, 0xad, 0xd8, 0xce, 0x5e, 0xdd, 0xda, 0x58, 0x34, 0x2c, - 0x01, 0xac, 0xf4, 0x26, 0x23, 0xaa, 0x76, 0xfe, 0x55, 0xc8, 0x4a, 0xff, 0x51, 0xc3, 0x51, 0x25, + 0xe4, 0x96, 0xaf, 0xf3, 0xa8, 0x38, 0xa0, 0x1e, 0x75, 0xcd, 0x30, 0xd8, 0xa6, 0x02, 0xfd, 0xa7, + 0x79, 0xc8, 0xec, 0xb2, 0xb1, 0x1b, 0xa0, 0xad, 0xd8, 0xca, 0x5e, 0xdd, 0xda, 0x58, 0x34, 0x2c, + 0x01, 0xac, 0xf4, 0x26, 0x23, 0xaa, 0x56, 0xfe, 0x55, 0xc8, 0xca, 0xf8, 0x51, 0xc3, 0x51, 0x25, 0x2e, 0x0f, 0x88, 0x37, 0xa0, 0x81, 0x1a, 0x8f, 0x2a, 0xa1, 0x9b, 0x90, 0xf3, 0x28, 0xb1, 0x98, - 0xeb, 0x4c, 0x84, 0x9b, 0xe5, 0xe4, 0xd1, 0x8b, 0x29, 0xb1, 0xda, 0xae, 0x33, 0xc1, 0x51, 0x2d, - 0xda, 0x86, 0xe2, 0xbe, 0xed, 0x5a, 0x7d, 0x36, 0x92, 0xe7, 0x60, 0xe6, 0xf5, 0x4e, 0x29, 0x7b, + 0xeb, 0x4c, 0x44, 0x98, 0xe5, 0xe4, 0xd6, 0x8b, 0x29, 0xb1, 0xda, 0xae, 0x33, 0xc1, 0x51, 0x2d, + 0xda, 0x86, 0xe2, 0xbe, 0xed, 0x5a, 0x7d, 0x36, 0x92, 0xfb, 0x60, 0xe6, 0xf5, 0x41, 0x29, 0x7b, 0x55, 0xb5, 0x5d, 0xab, 0x2d, 0xc1, 0xb8, 0xb0, 0x3f, 0x2d, 0xa0, 0x16, 0xac, 0x1e, 0x33, 0x67, 0x3c, 0xa4, 0x91, 0xad, 0xac, 0xb0, 0xf5, 0xe1, 0xeb, 0x6d, 0x3d, 0x15, 0xf8, 0xd0, 0xda, 0xca, 0x71, 0xbc, 0x88, 0x9e, 0xc0, 0x4a, 0x30, 0x1c, 0x1d, 0xf8, 0x91, 0xb9, 0x65, 0x61, 0xee, 0x3b, 0x17, 0x4c, 0x18, 0x87, 0x87, 0xd6, 0x8a, 0x41, 0xac, 0x54, 0xfa, 0xfd, 0x14, 0x14, 0x62, 0x3d, - 0x47, 0x5d, 0x28, 0x8c, 0x3c, 0x36, 0x22, 0x03, 0x71, 0x96, 0xab, 0xb5, 0xb8, 0xfb, 0x56, 0xa3, - 0xae, 0x74, 0xa6, 0x8a, 0x38, 0x6e, 0x45, 0x3f, 0x4b, 0x42, 0x21, 0x56, 0x89, 0x6e, 0x41, 0x0e, - 0x77, 0x70, 0xf3, 0xa9, 0xd1, 0x6b, 0x68, 0x4b, 0xa5, 0xeb, 0xa7, 0x67, 0xe5, 0x75, 0x61, 0x2d, - 0x6e, 0xa0, 0xe3, 0xd9, 0xc7, 0xdc, 0xf5, 0x6e, 0xc2, 0x72, 0x08, 0x4d, 0x94, 0xde, 0x39, 0x3d, - 0x2b, 0x7f, 0x7b, 0x1e, 0x1a, 0x43, 0xe2, 0xee, 0xb6, 0x81, 0x1b, 0x75, 0x2d, 0xb9, 0x18, 0x89, - 0xbb, 0x87, 0xc4, 0xa3, 0x16, 0xfa, 0x0e, 0x64, 0x15, 0x30, 0x55, 0x2a, 0x9d, 0x9e, 0x95, 0xaf, - 0xce, 0x03, 0xa7, 0x38, 0xdc, 0xdd, 0x31, 0x9e, 0x36, 0xb4, 0xf4, 0x62, 0x1c, 0xee, 0x3a, 0xe4, - 0x98, 0xa2, 0x0f, 0x20, 0x23, 0x61, 0x99, 0xd2, 0xb5, 0xd3, 0xb3, 0xf2, 0xb7, 0x5e, 0x31, 0xc7, - 0x51, 0xa5, 0xf5, 0x3f, 0xfa, 0xc9, 0xc6, 0xd2, 0xdf, 0xfd, 0xc5, 0x86, 0x36, 0x5f, 0x5d, 0xfa, - 0x9f, 0x04, 0xac, 0xcc, 0x2c, 0x39, 0xd2, 0x21, 0xeb, 0x32, 0x93, 0x8d, 0xe4, 0x11, 0x9f, 0xab, - 0xc2, 0xf9, 0xcb, 0xcd, 0x6c, 0x8b, 0xd5, 0xd8, 0x68, 0x82, 0x55, 0x0d, 0x7a, 0x32, 0x77, 0x49, - 0xdd, 0x7b, 0x4b, 0x7f, 0x5a, 0x78, 0x4d, 0x3d, 0x84, 0x15, 0xcb, 0xb3, 0x8f, 0xa9, 0xd7, 0x37, - 0x99, 0x7b, 0x60, 0x0f, 0xd4, 0xf1, 0x5d, 0x5a, 0x64, 0xb3, 0x2e, 0x80, 0xb8, 0x28, 0x15, 0x6a, - 0x02, 0xff, 0x2b, 0x5c, 0x50, 0xa5, 0xa7, 0x50, 0x8c, 0x7b, 0x28, 0x7a, 0x17, 0xc0, 0xb7, 0x7f, - 0x9b, 0x2a, 0xce, 0x23, 0x18, 0x12, 0xce, 0x73, 0x89, 0x60, 0x3c, 0xe8, 0x43, 0x48, 0x0f, 0x99, - 0x25, 0xed, 0xac, 0x54, 0x2f, 0xf3, 0x7b, 0xf2, 0x5f, 0x5e, 0x6e, 0x16, 0x98, 0x5f, 0x79, 0x64, - 0x3b, 0x74, 0x97, 0x59, 0x14, 0x0b, 0x80, 0x7e, 0x0c, 0x69, 0x7e, 0x54, 0xa0, 0x77, 0x20, 0x5d, - 0x6d, 0xb6, 0xea, 0xda, 0x52, 0xe9, 0xd2, 0xe9, 0x59, 0x79, 0x45, 0x4c, 0x09, 0xaf, 0xe0, 0xbe, - 0x8b, 0x36, 0x21, 0xfb, 0xb4, 0xbd, 0xb3, 0xb7, 0xcb, 0xdd, 0xeb, 0xf2, 0xe9, 0x59, 0x79, 0x2d, - 0xaa, 0x96, 0x93, 0x86, 0xde, 0x85, 0x4c, 0x6f, 0xb7, 0xf3, 0xa8, 0xab, 0x25, 0x4b, 0xe8, 0xf4, - 0xac, 0xbc, 0x1a, 0xd5, 0x8b, 0x3e, 0x97, 0x2e, 0xa9, 0x55, 0xcd, 0x47, 0x72, 0xfd, 0x97, 0x49, - 0x58, 0xc1, 0x9c, 0xfa, 0x7a, 0x41, 0x87, 0x39, 0xb6, 0x39, 0x41, 0x1d, 0xc8, 0x9b, 0xcc, 0xb5, - 0xec, 0xd8, 0x9e, 0xda, 0x7a, 0xcd, 0xc5, 0x38, 0xd5, 0x0a, 0x4b, 0xb5, 0x50, 0x13, 0x4f, 0x8d, - 0xa0, 0x8f, 0x21, 0x63, 0x51, 0x87, 0x4c, 0xd4, 0x0d, 0x7d, 0xad, 0x22, 0xc9, 0x75, 0x25, 0x24, - 0xd7, 0x95, 0xba, 0x22, 0xd7, 0x58, 0xe2, 0x04, 0x95, 0x24, 0xcf, 0xfb, 0x24, 0x08, 0xe8, 0x70, - 0x14, 0xc8, 0xeb, 0x39, 0x8d, 0x0b, 0x43, 0xf2, 0xdc, 0x50, 0x22, 0x74, 0x17, 0xb2, 0x27, 0xb6, - 0x6b, 0xb1, 0x13, 0x75, 0x03, 0x5f, 0x60, 0x54, 0x01, 0xf5, 0x53, 0x7e, 0xeb, 0xce, 0x75, 0x93, - 0xcf, 0x77, 0xab, 0xdd, 0x6a, 0x84, 0xf3, 0xad, 0xea, 0xdb, 0x6e, 0x8b, 0xb9, 0x7c, 0xaf, 0x40, - 0xbb, 0xd5, 0x7f, 0x64, 0x34, 0x77, 0xf6, 0x30, 0x9f, 0xf3, 0x2b, 0xa7, 0x67, 0x65, 0x2d, 0x82, - 0x3c, 0x22, 0xb6, 0xc3, 0x29, 0xe1, 0x35, 0x48, 0x19, 0xad, 0x2f, 0xb4, 0x64, 0x49, 0x3b, 0x3d, - 0x2b, 0x17, 0xa3, 0x6a, 0xc3, 0x9d, 0x4c, 0xb7, 0xd1, 0x7c, 0xbb, 0xfa, 0xcf, 0x93, 0x50, 0xdc, - 0x1b, 0x59, 0x24, 0xa0, 0xd2, 0x27, 0x51, 0x19, 0x0a, 0x23, 0xe2, 0x11, 0xc7, 0xa1, 0x8e, 0xed, - 0x0f, 0x55, 0xd8, 0x10, 0x17, 0xa1, 0x4f, 0xdf, 0x76, 0x1a, 0xab, 0x39, 0xee, 0x67, 0x7f, 0xf2, - 0xaf, 0x9b, 0x89, 0x70, 0x42, 0xf7, 0x60, 0xf5, 0x40, 0xf6, 0xb6, 0x4f, 0x4c, 0xb1, 0xb0, 0x29, - 0xb1, 0xb0, 0x95, 0x45, 0x0b, 0x1b, 0xef, 0x56, 0x45, 0x0d, 0xd2, 0x10, 0x5a, 0x78, 0xe5, 0x20, - 0x5e, 0x44, 0xf7, 0x60, 0x79, 0xc8, 0x5c, 0x3b, 0x60, 0xde, 0x9b, 0x57, 0x21, 0x44, 0xa2, 0x5b, - 0x70, 0x89, 0x2f, 0x6e, 0xd8, 0x1f, 0x51, 0x2d, 0x6e, 0xac, 0x24, 0x5e, 0x1b, 0x92, 0xe7, 0xaa, - 0x41, 0xcc, 0xc5, 0xfa, 0xf7, 0x61, 0x65, 0xa6, 0x03, 0xfc, 0x16, 0xef, 0x18, 0x7b, 0xdd, 0x86, - 0xb6, 0x84, 0x8a, 0x90, 0xab, 0xb5, 0x5b, 0xbd, 0x66, 0x6b, 0x8f, 0xd3, 0x90, 0x22, 0xe4, 0x70, - 0x7b, 0x67, 0xa7, 0x6a, 0xd4, 0x9e, 0x68, 0x49, 0xfd, 0x3f, 0xa3, 0xd9, 0x55, 0x3c, 0xa4, 0x3a, - 0xcb, 0x43, 0x6e, 0xbf, 0x7e, 0xdc, 0x8a, 0x89, 0x4c, 0x0b, 0x11, 0x1f, 0xf9, 0x14, 0x40, 0x2c, - 0x22, 0xb5, 0xfa, 0x24, 0x50, 0x8b, 0x50, 0x7a, 0x65, 0xc0, 0xbd, 0x30, 0x92, 0xc4, 0x79, 0x85, - 0x36, 0x02, 0xf4, 0x03, 0x28, 0x9a, 0x6c, 0x38, 0x72, 0xa8, 0x52, 0x4e, 0xbd, 0x51, 0xb9, 0x10, - 0xe1, 0x8d, 0x20, 0xce, 0x84, 0xd2, 0xb3, 0x5c, 0xed, 0x0f, 0x12, 0x50, 0x88, 0x75, 0x75, 0x96, - 0xfc, 0x14, 0x21, 0xb7, 0xd7, 0xa9, 0x1b, 0xbd, 0x66, 0xeb, 0xb1, 0x96, 0x40, 0x00, 0x59, 0x31, - 0x75, 0x75, 0x2d, 0xc9, 0x49, 0x5b, 0xad, 0xbd, 0xdb, 0xd9, 0x69, 0x08, 0xfa, 0x83, 0xae, 0x80, - 0x16, 0x4e, 0x5e, 0xbf, 0xdb, 0x33, 0x30, 0x97, 0xa6, 0xd1, 0x65, 0x58, 0x8b, 0xa4, 0x4a, 0x33, - 0x83, 0xae, 0x02, 0x8a, 0x84, 0x53, 0x13, 0x59, 0xfd, 0x77, 0x61, 0xad, 0xc6, 0xdc, 0x80, 0xd8, - 0x6e, 0x44, 0x68, 0xb7, 0xf8, 0xa0, 0x95, 0xa8, 0x6f, 0x5b, 0xf2, 0x7c, 0xad, 0xae, 0x9d, 0xbf, - 0xdc, 0x2c, 0x44, 0xd0, 0x66, 0x9d, 0x8f, 0x34, 0x2c, 0x58, 0x7c, 0x2f, 0x8d, 0x6c, 0x4b, 0x4c, - 0x6e, 0xa6, 0xba, 0x7c, 0xfe, 0x72, 0x33, 0xd5, 0x69, 0xd6, 0x31, 0x97, 0xa1, 0x77, 0x20, 0x4f, - 0x9f, 0xdb, 0x41, 0xdf, 0xe4, 0xe7, 0x29, 0x9f, 0xc0, 0x0c, 0xce, 0x71, 0x41, 0x8d, 0x1f, 0x9f, - 0x55, 0x80, 0x0e, 0xf3, 0x02, 0xd5, 0xf2, 0xf7, 0x20, 0x33, 0x62, 0x9e, 0x88, 0x26, 0xf9, 0x65, - 0xb3, 0x90, 0x9e, 0x71, 0xb8, 0xf4, 0x71, 0x2c, 0xc1, 0xfa, 0xdf, 0x27, 0x01, 0x7a, 0xc4, 0x3f, - 0x52, 0x46, 0xee, 0x43, 0x3e, 0xca, 0x0a, 0xa8, 0xb0, 0xf4, 0xc2, 0xd5, 0x8e, 0xc0, 0xe8, 0x5e, - 0xe8, 0x6c, 0x92, 0xaa, 0x2f, 0x0c, 0x2b, 0xc2, 0x86, 0x16, 0xb1, 0xdd, 0x59, 0x3e, 0xce, 0xaf, - 0x27, 0xea, 0x79, 0x6a, 0xe5, 0xf9, 0x27, 0xaa, 0x89, 0x23, 0x5a, 0x4e, 0x9a, 0x22, 0x7b, 0xef, - 0x2f, 0x6a, 0x64, 0x6e, 0x45, 0xb6, 0x97, 0xf0, 0x54, 0x0f, 0x3d, 0x84, 0x02, 0x1f, 0x77, 0xdf, - 0x17, 0x75, 0x8a, 0xe7, 0xbd, 0x76, 0xaa, 0xa4, 0x05, 0x0c, 0xa3, 0xe8, 0xbb, 0xaa, 0xc1, 0xaa, - 0x37, 0x76, 0xf9, 0xb0, 0x95, 0x0d, 0xdd, 0x86, 0x6f, 0xb7, 0x68, 0x70, 0xc2, 0xbc, 0x23, 0x23, - 0x08, 0x88, 0x79, 0xc8, 0x83, 0x7b, 0x75, 0xbc, 0x4d, 0x49, 0x6e, 0x62, 0x86, 0xe4, 0xae, 0xc3, - 0x32, 0x71, 0x6c, 0xe2, 0x53, 0xc9, 0x0c, 0xf2, 0x38, 0x2c, 0x72, 0x2a, 0xce, 0x89, 0x3d, 0xf5, - 0x7d, 0x2a, 0xc3, 0xd1, 0x3c, 0x9e, 0x0a, 0xf4, 0x7f, 0x4a, 0x02, 0x34, 0x3b, 0xc6, 0xae, 0x32, - 0x5f, 0x87, 0xec, 0x01, 0x19, 0xda, 0xce, 0xe4, 0xa2, 0x0d, 0x3e, 0xc5, 0x57, 0x0c, 0x69, 0xe8, - 0x91, 0xd0, 0xc1, 0x4a, 0x57, 0x30, 0xf4, 0xf1, 0xbe, 0x4b, 0x83, 0x88, 0xa1, 0x8b, 0x12, 0xa7, - 0x03, 0x1e, 0x71, 0xa3, 0x95, 0x91, 0x05, 0xde, 0xf5, 0x01, 0x09, 0xe8, 0x09, 0x99, 0x84, 0xbb, - 0x52, 0x15, 0xd1, 0x36, 0x67, 0xee, 0x3e, 0xf5, 0x8e, 0xa9, 0xb5, 0x9e, 0x11, 0x2e, 0xf8, 0xa6, - 0xfe, 0x60, 0x05, 0x97, 0x44, 0x27, 0xd2, 0x2e, 0x3d, 0x10, 0xb7, 0xf3, 0xb4, 0xea, 0x1b, 0x05, - 0xd3, 0x77, 0x60, 0x65, 0x66, 0x9c, 0xaf, 0x84, 0x46, 0xcd, 0xce, 0xd3, 0xef, 0x69, 0x69, 0xf5, - 0xf5, 0x7d, 0x2d, 0xab, 0xff, 0x55, 0x4a, 0xee, 0x23, 0x35, 0xab, 0x8b, 0xd3, 0x53, 0x39, 0xe1, - 0xfd, 0x26, 0x73, 0x94, 0x7f, 0x7f, 0x78, 0xf1, 0xf6, 0xe2, 0x54, 0x5b, 0xc0, 0x71, 0xa4, 0x88, - 0x36, 0xa1, 0x20, 0xd7, 0xbf, 0xcf, 0xfd, 0x49, 0x4c, 0xeb, 0x0a, 0x06, 0x29, 0xe2, 0x9a, 0xe8, - 0x06, 0xac, 0x8e, 0xc6, 0xfb, 0x8e, 0xed, 0x1f, 0x52, 0x4b, 0x62, 0xd2, 0x02, 0xb3, 0x12, 0x49, - 0x05, 0x6c, 0x17, 0x8a, 0x4a, 0xd0, 0x17, 0x34, 0x2b, 0x23, 0x3a, 0x74, 0xeb, 0x4d, 0x1d, 0x92, - 0x2a, 0x82, 0x7d, 0x15, 0x46, 0xd3, 0x82, 0x5e, 0x87, 0x5c, 0xd8, 0x59, 0xb4, 0x0e, 0xa9, 0x5e, - 0xad, 0xa3, 0x2d, 0x95, 0xd6, 0x4e, 0xcf, 0xca, 0x85, 0x50, 0xdc, 0xab, 0x75, 0x78, 0xcd, 0x5e, - 0xbd, 0xa3, 0x25, 0x66, 0x6b, 0xf6, 0xea, 0x9d, 0x52, 0x9a, 0x5f, 0xf7, 0xfa, 0x01, 0x14, 0x62, - 0x2d, 0xa0, 0xf7, 0x61, 0xb9, 0xd9, 0x7a, 0x8c, 0x1b, 0xdd, 0xae, 0xb6, 0x54, 0xba, 0x7a, 0x7a, - 0x56, 0x46, 0xb1, 0xda, 0xa6, 0x3b, 0xe0, 0xeb, 0x83, 0xde, 0x85, 0xf4, 0x76, 0xbb, 0xdb, 0x0b, - 0x79, 0x5d, 0x0c, 0xb1, 0xcd, 0xfc, 0xa0, 0x74, 0x59, 0xf1, 0x88, 0xb8, 0x61, 0xfd, 0x4f, 0x13, - 0x90, 0x95, 0xf4, 0x76, 0xe1, 0x42, 0x19, 0xb0, 0x1c, 0x06, 0x5d, 0x92, 0x73, 0x7f, 0xf8, 0x7a, - 0x7e, 0x5c, 0x51, 0x74, 0x56, 0xba, 0x5f, 0xa8, 0x57, 0xfa, 0x0c, 0x8a, 0xf1, 0x8a, 0x6f, 0xe4, - 0x7c, 0xbf, 0x03, 0x05, 0xee, 0xdf, 0x21, 0x4f, 0xde, 0x82, 0xac, 0xa4, 0xe0, 0xd1, 0x51, 0xfa, - 0x7a, 0xb2, 0xae, 0x90, 0xe8, 0x3e, 0x2c, 0x4b, 0x82, 0x1f, 0xa6, 0xa3, 0x36, 0x2e, 0xde, 0x45, - 0x38, 0x84, 0xeb, 0x0f, 0x21, 0xdd, 0xa1, 0xd4, 0xe3, 0x73, 0xef, 0x32, 0x8b, 0x4e, 0x6f, 0x1f, - 0x15, 0x9b, 0x58, 0xb4, 0x59, 0xe7, 0xb1, 0x89, 0x45, 0x9b, 0x56, 0x94, 0x4d, 0x48, 0xc6, 0xb2, - 0x09, 0x3d, 0x28, 0x3e, 0xa3, 0xf6, 0xe0, 0x30, 0xa0, 0x96, 0x30, 0x74, 0x1b, 0xd2, 0x23, 0x1a, - 0x75, 0x7e, 0x7d, 0xa1, 0x83, 0x51, 0xea, 0x61, 0x81, 0xe2, 0xe7, 0xc8, 0x89, 0xd0, 0x56, 0x49, - 0x50, 0x55, 0xd2, 0xff, 0x31, 0x09, 0xab, 0x4d, 0xdf, 0x1f, 0x13, 0xd7, 0x0c, 0x89, 0xc9, 0x0f, - 0x67, 0x89, 0xc9, 0xcd, 0x85, 0x23, 0x9c, 0x51, 0x99, 0x4d, 0x92, 0xa8, 0xcb, 0x21, 0x19, 0x5d, - 0x0e, 0xfa, 0x7f, 0x24, 0xc2, 0x4c, 0xc8, 0x8d, 0xd8, 0x76, 0x2f, 0xad, 0x9f, 0x9e, 0x95, 0xaf, - 0xc4, 0x2d, 0xd1, 0x3d, 0xf7, 0xc8, 0x65, 0x27, 0x2e, 0x7a, 0x0f, 0x32, 0xb8, 0xd1, 0x6a, 0x3c, - 0xd3, 0x12, 0xd2, 0x3d, 0x67, 0x40, 0x98, 0xba, 0xf4, 0x84, 0x5b, 0xea, 0x34, 0x5a, 0x75, 0x4e, - 0x24, 0x92, 0x0b, 0x2c, 0x75, 0xa8, 0x6b, 0xd9, 0xee, 0x00, 0xbd, 0x0f, 0xd9, 0x66, 0xb7, 0xbb, - 0x27, 0x62, 0xd5, 0x6f, 0x9f, 0x9e, 0x95, 0x2f, 0xcf, 0xa0, 0x78, 0x81, 0x5a, 0x1c, 0xc4, 0x19, - 0x35, 0xa7, 0x18, 0x0b, 0x40, 0x9c, 0xee, 0x49, 0x10, 0x6e, 0xf7, 0x78, 0x20, 0x9d, 0x59, 0x00, - 0xc2, 0x8c, 0xff, 0xaa, 0xed, 0xf6, 0xf3, 0x24, 0x68, 0x86, 0x69, 0xd2, 0x51, 0xc0, 0xeb, 0x55, - 0x10, 0xd3, 0x83, 0xdc, 0x88, 0x7f, 0xd9, 0x34, 0x24, 0x01, 0xf7, 0x17, 0xa6, 0xd1, 0xe7, 0xf4, - 0x2a, 0x98, 0x39, 0xd4, 0xb0, 0x86, 0xb6, 0xef, 0xf3, 0x60, 0x5d, 0xc8, 0x70, 0x64, 0xa9, 0xf4, - 0x5f, 0x09, 0xb8, 0xbc, 0x00, 0x81, 0xee, 0x40, 0xda, 0x63, 0x4e, 0xb8, 0x86, 0xd7, 0x5f, 0x97, - 0xe4, 0xe2, 0xaa, 0x58, 0x20, 0xd1, 0x06, 0x00, 0x19, 0x07, 0x8c, 0x88, 0xf6, 0xc5, 0xea, 0xe5, - 0x70, 0x4c, 0x82, 0x9e, 0x41, 0xd6, 0xa7, 0xa6, 0x47, 0x43, 0xaa, 0xf8, 0xf0, 0xff, 0xdb, 0xfb, - 0x4a, 0x57, 0x98, 0xc1, 0xca, 0x5c, 0xa9, 0x02, 0x59, 0x29, 0xe1, 0x6e, 0x6f, 0x91, 0x80, 0x88, - 0x4e, 0x17, 0xb1, 0xf8, 0xe6, 0xde, 0x44, 0x9c, 0x41, 0xe8, 0x4d, 0xc4, 0x19, 0xe8, 0x7f, 0x96, - 0x04, 0x68, 0x3c, 0x0f, 0xa8, 0xe7, 0x12, 0xa7, 0x66, 0xa0, 0x46, 0xec, 0xf4, 0x97, 0xa3, 0xfd, - 0x68, 0x61, 0xea, 0x33, 0xd2, 0xa8, 0xd4, 0x8c, 0x05, 0xe7, 0xff, 0x35, 0x48, 0x8d, 0x3d, 0x47, - 0xa5, 0xd1, 0x05, 0xcd, 0xdb, 0xc3, 0x3b, 0x98, 0xcb, 0x50, 0x63, 0x7a, 0x6c, 0xa5, 0x5e, 0xff, - 0xfe, 0x11, 0x6b, 0xe0, 0xd7, 0x7f, 0x74, 0xdd, 0x06, 0x98, 0xf6, 0x1a, 0x6d, 0x40, 0xa6, 0xf6, - 0xa8, 0xdb, 0xdd, 0xd1, 0x96, 0xe4, 0xd9, 0x3c, 0xad, 0x12, 0x62, 0xfd, 0x27, 0x09, 0xc8, 0xd5, - 0x0c, 0x75, 0x63, 0xd6, 0x40, 0x13, 0x07, 0x8e, 0x49, 0xbd, 0xa0, 0x4f, 0x9f, 0x8f, 0x6c, 0x6f, - 0xa2, 0xce, 0x8c, 0x0b, 0x42, 0xa3, 0x55, 0xae, 0x52, 0xa3, 0x5e, 0xd0, 0x10, 0x0a, 0x08, 0x43, - 0x91, 0xaa, 0xf1, 0xf5, 0x4d, 0x12, 0x1e, 0xdf, 0x1b, 0x17, 0xcf, 0x83, 0x24, 0xd6, 0xd3, 0xb2, - 0x8f, 0x0b, 0xa1, 0x91, 0x1a, 0xf1, 0xf5, 0xa7, 0x70, 0xb9, 0xed, 0x99, 0x87, 0xd4, 0x0f, 0x64, - 0xa3, 0xaa, 0xbf, 0x0f, 0xe1, 0x7a, 0x40, 0xfc, 0xa3, 0xfe, 0xa1, 0xed, 0x07, 0xcc, 0x9b, 0xf4, - 0x3d, 0x1a, 0x50, 0x97, 0xd7, 0xf7, 0xc5, 0x13, 0x8b, 0x4a, 0x68, 0x5c, 0xe3, 0x98, 0x6d, 0x09, - 0xc1, 0x21, 0x62, 0x87, 0x03, 0xf4, 0x26, 0x14, 0x39, 0x95, 0xad, 0xd3, 0x03, 0x32, 0x76, 0x02, - 0x9f, 0x07, 0x49, 0x0e, 0x1b, 0xf4, 0xdf, 0xfa, 0xac, 0xcf, 0x3b, 0x6c, 0x20, 0x3f, 0xf5, 0x1f, - 0x83, 0x56, 0xb7, 0xfd, 0x11, 0x09, 0xcc, 0xc3, 0x30, 0x53, 0x83, 0xea, 0xa0, 0x1d, 0x52, 0xe2, - 0x05, 0xfb, 0x94, 0x04, 0xfd, 0x11, 0xf5, 0x6c, 0x66, 0xbd, 0x79, 0x3e, 0xd7, 0x22, 0x95, 0x8e, - 0xd0, 0xd0, 0xff, 0x3b, 0x01, 0x80, 0xc9, 0x41, 0x48, 0x6b, 0xbe, 0x0b, 0x97, 0x7c, 0x97, 0x8c, - 0xfc, 0x43, 0x16, 0xf4, 0x6d, 0x37, 0xa0, 0xde, 0x31, 0x71, 0x54, 0xc0, 0xad, 0x85, 0x15, 0x4d, - 0x25, 0x47, 0xb7, 0x01, 0x1d, 0x51, 0x3a, 0xea, 0x33, 0xc7, 0xea, 0x87, 0x95, 0xf2, 0x01, 0x28, - 0x8d, 0x35, 0x5e, 0xd3, 0x76, 0xac, 0x6e, 0x28, 0x47, 0x55, 0xd8, 0xe0, 0xc3, 0xa7, 0x6e, 0xe0, - 0xd9, 0xd4, 0xef, 0x1f, 0x30, 0xaf, 0xef, 0x3b, 0xec, 0xa4, 0x7f, 0xc0, 0x1c, 0x87, 0x9d, 0x50, - 0x2f, 0xcc, 0x65, 0x94, 0x1c, 0x36, 0x68, 0x48, 0xd0, 0x23, 0xe6, 0x75, 0x1d, 0x76, 0xf2, 0x28, - 0x44, 0x70, 0xee, 0x33, 0x1d, 0x73, 0x60, 0x9b, 0x47, 0x21, 0xf7, 0x89, 0xa4, 0x3d, 0xdb, 0x3c, - 0x42, 0xef, 0xc3, 0x0a, 0x75, 0xa8, 0x08, 0x8b, 0x25, 0x2a, 0x23, 0x50, 0xc5, 0x50, 0xc8, 0x41, - 0xfa, 0xe7, 0xa0, 0x35, 0x5c, 0xd3, 0x9b, 0x8c, 0x62, 0x6b, 0x7e, 0x1b, 0x10, 0x3f, 0x69, 0xfa, - 0x0e, 0x33, 0x8f, 0xfa, 0x43, 0xe2, 0x92, 0x01, 0xef, 0x97, 0x7c, 0x74, 0xd0, 0x78, 0xcd, 0x0e, - 0x33, 0x8f, 0x76, 0x95, 0x5c, 0xff, 0x0d, 0xc8, 0x77, 0x1c, 0x62, 0x8a, 0x87, 0x3a, 0x54, 0x06, - 0x1e, 0xad, 0x71, 0x1f, 0xb2, 0x5d, 0x15, 0x5e, 0xe5, 0x71, 0x5c, 0xa4, 0xff, 0x10, 0xe0, 0x47, - 0xcc, 0x76, 0x7b, 0xec, 0x88, 0xba, 0xe2, 0x4d, 0x83, 0x47, 0x03, 0xca, 0x13, 0xf2, 0x58, 0x95, - 0x44, 0xb0, 0x23, 0x1b, 0x88, 0x52, 0xfb, 0xb2, 0xa8, 0x7f, 0x9d, 0x80, 0x2c, 0x66, 0x2c, 0xa8, - 0x19, 0xa8, 0x0c, 0x59, 0x93, 0xf4, 0xc3, 0x5d, 0x5b, 0xac, 0xe6, 0xcf, 0x5f, 0x6e, 0x66, 0x6a, - 0xc6, 0x13, 0x3a, 0xc1, 0x19, 0x93, 0x3c, 0xa1, 0x13, 0x7e, 0xbd, 0x9b, 0x44, 0xec, 0x35, 0x61, - 0xa6, 0x28, 0xaf, 0xf7, 0x9a, 0xc1, 0xf7, 0x12, 0xce, 0x9a, 0x84, 0xff, 0xa3, 0x3b, 0x50, 0x54, - 0xa0, 0xfe, 0x21, 0xf1, 0x0f, 0x25, 0x87, 0xaf, 0xae, 0x9e, 0xbf, 0xdc, 0x04, 0x89, 0xdc, 0x26, - 0xfe, 0x21, 0x06, 0x89, 0xe6, 0xdf, 0xa8, 0x01, 0x85, 0x2f, 0x99, 0xed, 0xf6, 0x03, 0x31, 0x08, - 0x95, 0xda, 0x58, 0xb8, 0xfd, 0xa6, 0x43, 0x55, 0x6f, 0x60, 0xf0, 0x65, 0x24, 0xd1, 0xff, 0x39, - 0x01, 0x05, 0x6e, 0xd3, 0x3e, 0xb0, 0x4d, 0x7e, 0x1d, 0x7f, 0xf3, 0x5b, 0xe2, 0x1a, 0xa4, 0x4c, - 0xdf, 0x53, 0x63, 0x13, 0xc7, 0x64, 0xad, 0x8b, 0x31, 0x97, 0xa1, 0xcf, 0x21, 0xab, 0x02, 0x37, - 0x79, 0x41, 0xe8, 0x6f, 0x26, 0x0e, 0xaa, 0x8b, 0x4a, 0x4f, 0xac, 0xe5, 0xb4, 0x77, 0x62, 0x94, - 0x45, 0x1c, 0x17, 0xa1, 0xab, 0x90, 0x34, 0x5d, 0xe1, 0x56, 0xea, 0xad, 0xb3, 0xd6, 0xc2, 0x49, - 0xd3, 0xd5, 0xff, 0x21, 0x01, 0x2b, 0x53, 0xaf, 0xe2, 0x0b, 0x71, 0x1d, 0xf2, 0xfe, 0x78, 0xdf, - 0x9f, 0xf8, 0x01, 0x1d, 0x86, 0xcf, 0x26, 0x91, 0x00, 0x35, 0x21, 0x4f, 0x9c, 0x01, 0xf3, 0xec, - 0xe0, 0x70, 0xa8, 0x62, 0x86, 0xc5, 0x87, 0x7a, 0xdc, 0x66, 0xc5, 0x08, 0x55, 0xf0, 0x54, 0x3b, - 0x3c, 0xc6, 0x53, 0xa2, 0xb3, 0xe2, 0x18, 0x7f, 0x0f, 0x8a, 0x0e, 0x19, 0x8a, 0x48, 0x96, 0x87, - 0xa2, 0x62, 0x1c, 0x69, 0x5c, 0x50, 0x32, 0x1e, 0x9f, 0xeb, 0x3a, 0xe4, 0x23, 0x63, 0x68, 0x0d, - 0x0a, 0x46, 0xa3, 0xdb, 0xbf, 0xbb, 0x75, 0xbf, 0xff, 0xb8, 0xb6, 0xab, 0x2d, 0x29, 0x16, 0xf1, - 0xb7, 0x09, 0x58, 0x51, 0x3e, 0xaf, 0x98, 0xd9, 0xfb, 0xb0, 0xec, 0x91, 0x83, 0x20, 0xe4, 0x8e, - 0x69, 0xe9, 0x5c, 0xfc, 0x18, 0xe1, 0xdc, 0x91, 0x57, 0x2d, 0xe6, 0x8e, 0xb1, 0x87, 0xbc, 0xd4, - 0x85, 0x0f, 0x79, 0xe9, 0x5f, 0xcb, 0x43, 0x9e, 0xfe, 0xd7, 0x49, 0x58, 0x53, 0x97, 0x7c, 0xf8, - 0x50, 0x85, 0x3e, 0x82, 0xbc, 0xbc, 0xef, 0xa7, 0xcc, 0x57, 0xbc, 0x1d, 0x49, 0x5c, 0xb3, 0x8e, - 0x73, 0xb2, 0xba, 0x69, 0xf1, 0x50, 0x4c, 0x41, 0x63, 0xcf, 0xd2, 0x20, 0x45, 0x2d, 0x1e, 0x47, - 0xd4, 0x21, 0x7d, 0x60, 0x3b, 0x54, 0xf9, 0xd9, 0xc2, 0x8c, 0xe1, 0x5c, 0xf3, 0x22, 0xb7, 0xdd, - 0x13, 0xc1, 0xdc, 0xf6, 0x12, 0x16, 0xda, 0xa5, 0xdf, 0x03, 0x98, 0x4a, 0x17, 0xc6, 0x2b, 0x9c, - 0x13, 0xa8, 0xd4, 0x4f, 0xc8, 0x09, 0x9a, 0x75, 0xcc, 0x65, 0xbc, 0x6a, 0x60, 0x5b, 0x6a, 0xe7, - 0x8a, 0xaa, 0xc7, 0xbc, 0x6a, 0x60, 0x5b, 0x51, 0x82, 0x3d, 0xfd, 0x86, 0x04, 0x7b, 0x35, 0x17, - 0x26, 0x20, 0xf4, 0x1d, 0xb8, 0x5a, 0x75, 0x88, 0x79, 0xe4, 0xd8, 0x7e, 0x40, 0xad, 0xf8, 0x0e, - 0xdd, 0x82, 0xec, 0xcc, 0x9d, 0x7d, 0x51, 0xbe, 0x47, 0x21, 0xf5, 0xbf, 0x4c, 0x40, 0x71, 0x9b, - 0x12, 0x27, 0x38, 0x9c, 0x06, 0xcd, 0x01, 0xf5, 0x03, 0x75, 0x38, 0x8a, 0x6f, 0xf4, 0x09, 0xe4, - 0xa2, 0x8b, 0xe6, 0x8d, 0x49, 0xf0, 0x08, 0x8a, 0xee, 0xc1, 0x32, 0xf7, 0x69, 0x36, 0x0e, 0x69, - 0xe0, 0x45, 0xf9, 0x55, 0x85, 0xe4, 0x67, 0xab, 0x47, 0xc5, 0xcd, 0x22, 0x26, 0x25, 0x83, 0xc3, - 0xa2, 0xfe, 0xbf, 0x09, 0xb8, 0xb2, 0x4b, 0x26, 0xfb, 0x54, 0x6d, 0x34, 0x6a, 0x61, 0x6a, 0x32, - 0xcf, 0x42, 0x9d, 0xf8, 0x06, 0xbd, 0x20, 0xe5, 0xbf, 0x48, 0x79, 0xf1, 0x3e, 0x0d, 0xc9, 0x65, - 0x32, 0x46, 0x2e, 0xaf, 0x40, 0xc6, 0x65, 0xae, 0x49, 0xd5, 0xee, 0x95, 0x05, 0xdd, 0x8e, 0x6f, - 0xce, 0x52, 0x94, 0x8d, 0x17, 0xb9, 0xf4, 0x16, 0x0b, 0xa2, 0xd6, 0xd0, 0xe7, 0x50, 0xea, 0x36, - 0x6a, 0xb8, 0xd1, 0xab, 0xb6, 0x7f, 0xdc, 0xef, 0x1a, 0x3b, 0x5d, 0x63, 0xeb, 0x4e, 0xbf, 0xd3, - 0xde, 0xf9, 0xe2, 0xee, 0xbd, 0x3b, 0x9f, 0x68, 0x89, 0x52, 0xf9, 0xf4, 0xac, 0x7c, 0xbd, 0x65, - 0xd4, 0x76, 0xa4, 0x37, 0xee, 0xb3, 0xe7, 0x5d, 0xe2, 0xf8, 0x64, 0xeb, 0x4e, 0x87, 0x39, 0x13, - 0x8e, 0xb9, 0xf5, 0xcb, 0x14, 0xe4, 0xa3, 0xbc, 0x1b, 0x77, 0x2a, 0x1e, 0xf4, 0xa8, 0xa6, 0x22, - 0x79, 0x8b, 0x9e, 0xa0, 0xf7, 0xa6, 0xe1, 0xce, 0xe7, 0x32, 0xe9, 0x1f, 0x55, 0x87, 0xa1, 0xce, - 0x07, 0x90, 0x33, 0xba, 0xdd, 0xe6, 0xe3, 0x56, 0xa3, 0xae, 0x7d, 0x95, 0x28, 0x7d, 0xeb, 0xf4, - 0xac, 0x7c, 0x29, 0x02, 0x19, 0xbe, 0x6f, 0x0f, 0x5c, 0x6a, 0x09, 0x54, 0xad, 0xd6, 0xe8, 0xf4, - 0x1a, 0x75, 0xed, 0x45, 0x72, 0x1e, 0x25, 0xe8, 0xbb, 0x78, 0xba, 0xcb, 0x77, 0x70, 0xa3, 0x63, - 0x60, 0xde, 0xe0, 0x57, 0x49, 0x19, 0x85, 0x4d, 0x5b, 0xf4, 0xe8, 0x88, 0x78, 0xbc, 0xcd, 0x8d, - 0xf0, 0x09, 0xfb, 0x45, 0x4a, 0x3e, 0xef, 0x4c, 0x93, 0x88, 0x94, 0x58, 0x13, 0xde, 0x9a, 0xc8, - 0xde, 0x0a, 0x33, 0xa9, 0xb9, 0xd6, 0xba, 0x01, 0xf1, 0x02, 0x6e, 0x45, 0x87, 0x65, 0xbc, 0xd7, - 0x6a, 0x71, 0xd0, 0x8b, 0xf4, 0xdc, 0xe8, 0xf0, 0xd8, 0x75, 0x39, 0xe6, 0x06, 0xe4, 0xc2, 0xe4, - 0xae, 0xf6, 0x55, 0x7a, 0xae, 0x43, 0xb5, 0x30, 0x33, 0x2d, 0x1a, 0xdc, 0xde, 0xeb, 0x89, 0x17, - 0xf6, 0x17, 0x99, 0xf9, 0x06, 0x0f, 0xc7, 0x81, 0xc5, 0xe3, 0xcb, 0x72, 0x14, 0xf0, 0x7d, 0x95, - 0x91, 0x14, 0x3a, 0xc2, 0xa8, 0x68, 0xef, 0x03, 0xc8, 0xe1, 0xc6, 0x8f, 0xe4, 0x63, 0xfc, 0x8b, - 0xec, 0x9c, 0x1d, 0x4c, 0xbf, 0xa4, 0xa6, 0x6a, 0xad, 0x8d, 0x3b, 0xdb, 0x86, 0x98, 0xf2, 0x79, - 0x54, 0xdb, 0x1b, 0x1d, 0x12, 0x97, 0x5a, 0xd3, 0x37, 0xae, 0xa8, 0xea, 0xd6, 0x6f, 0x42, 0x2e, - 0xbc, 0x58, 0xd1, 0x06, 0x64, 0x9f, 0xb5, 0xf1, 0x93, 0x06, 0xd6, 0x96, 0xe4, 0x1c, 0x86, 0x35, - 0xcf, 0x24, 0x33, 0x29, 0xc3, 0xf2, 0xae, 0xd1, 0x32, 0x1e, 0x37, 0x70, 0x98, 0x8b, 0x09, 0x01, - 0xea, 0x76, 0x28, 0x69, 0xaa, 0x81, 0xc8, 0x66, 0x75, 0xfd, 0xeb, 0x5f, 0x6c, 0x2c, 0xfd, 0xec, - 0x17, 0x1b, 0x4b, 0x2f, 0xce, 0x37, 0x12, 0x5f, 0x9f, 0x6f, 0x24, 0x7e, 0x7a, 0xbe, 0x91, 0xf8, - 0xb7, 0xf3, 0x8d, 0xc4, 0x7e, 0x56, 0xec, 0xd3, 0x7b, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x4e, - 0xa0, 0xa0, 0x52, 0x91, 0x26, 0x00, 0x00, + 0x47, 0x5d, 0x28, 0x8c, 0x3c, 0x36, 0x22, 0x03, 0xb1, 0x97, 0x2b, 0x5f, 0xdc, 0x7d, 0xab, 0x51, + 0x57, 0x3a, 0x53, 0x45, 0x1c, 0xb7, 0xa2, 0x9f, 0x25, 0xa1, 0x10, 0xab, 0x44, 0xb7, 0x20, 0x87, + 0x3b, 0xb8, 0xf9, 0xd4, 0xe8, 0x35, 0xb4, 0xa5, 0xd2, 0xf5, 0xd3, 0xb3, 0xf2, 0xba, 0xb0, 0x16, + 0x37, 0xd0, 0xf1, 0xec, 0x63, 0x1e, 0x7a, 0x37, 0x61, 0x39, 0x84, 0x26, 0x4a, 0xef, 0x9c, 0x9e, + 0x95, 0xbf, 0x3d, 0x0f, 0x8d, 0x21, 0x71, 0x77, 0xdb, 0xc0, 0x8d, 0xba, 0x96, 0x5c, 0x8c, 0xc4, + 0xdd, 0x43, 0xe2, 0x51, 0x0b, 0x7d, 0x07, 0xb2, 0x0a, 0x98, 0x2a, 0x95, 0x4e, 0xcf, 0xca, 0x57, + 0xe7, 0x81, 0x53, 0x1c, 0xee, 0xee, 0x18, 0x4f, 0x1b, 0x5a, 0x7a, 0x31, 0x0e, 0x77, 0x1d, 0x72, + 0x4c, 0xd1, 0x07, 0x90, 0x91, 0xb0, 0x4c, 0xe9, 0xda, 0xe9, 0x59, 0xf9, 0x5b, 0xaf, 0x98, 0xe3, + 0xa8, 0xd2, 0xfa, 0x1f, 0xfd, 0x64, 0x63, 0xe9, 0xef, 0xfe, 0x62, 0x43, 0x9b, 0xaf, 0x2e, 0xfd, + 0x4f, 0x02, 0x56, 0x66, 0x5c, 0x8e, 0x74, 0xc8, 0xba, 0xcc, 0x64, 0x23, 0xb9, 0xc5, 0xe7, 0xaa, + 0x70, 0xfe, 0x72, 0x33, 0xdb, 0x62, 0x35, 0x36, 0x9a, 0x60, 0x55, 0x83, 0x9e, 0xcc, 0x1d, 0x52, + 0xf7, 0xde, 0x32, 0x9e, 0x16, 0x1e, 0x53, 0x0f, 0x61, 0xc5, 0xf2, 0xec, 0x63, 0xea, 0xf5, 0x4d, + 0xe6, 0x1e, 0xd8, 0x03, 0xb5, 0x7d, 0x97, 0x16, 0xd9, 0xac, 0x0b, 0x20, 0x2e, 0x4a, 0x85, 0x9a, + 0xc0, 0xff, 0x0a, 0x07, 0x54, 0xe9, 0x29, 0x14, 0xe3, 0x11, 0x8a, 0xde, 0x05, 0xf0, 0xed, 0xdf, + 0xa6, 0x8a, 0xf3, 0x08, 0x86, 0x84, 0xf3, 0x5c, 0x22, 0x18, 0x0f, 0xfa, 0x10, 0xd2, 0x43, 0x66, + 0x49, 0x3b, 0x2b, 0xd5, 0xcb, 0xfc, 0x9c, 0xfc, 0x97, 0x97, 0x9b, 0x05, 0xe6, 0x57, 0x1e, 0xd9, + 0x0e, 0xdd, 0x65, 0x16, 0xc5, 0x02, 0xa0, 0x1f, 0x43, 0x9a, 0x6f, 0x15, 0xe8, 0x1d, 0x48, 0x57, + 0x9b, 0xad, 0xba, 0xb6, 0x54, 0xba, 0x74, 0x7a, 0x56, 0x5e, 0x11, 0x53, 0xc2, 0x2b, 0x78, 0xec, + 0xa2, 0x4d, 0xc8, 0x3e, 0x6d, 0xef, 0xec, 0xed, 0xf2, 0xf0, 0xba, 0x7c, 0x7a, 0x56, 0x5e, 0x8b, + 0xaa, 0xe5, 0xa4, 0xa1, 0x77, 0x21, 0xd3, 0xdb, 0xed, 0x3c, 0xea, 0x6a, 0xc9, 0x12, 0x3a, 0x3d, + 0x2b, 0xaf, 0x46, 0xf5, 0xa2, 0xcf, 0xa5, 0x4b, 0xca, 0xab, 0xf9, 0x48, 0xae, 0xff, 0x32, 0x09, + 0x2b, 0x98, 0x53, 0x5f, 0x2f, 0xe8, 0x30, 0xc7, 0x36, 0x27, 0xa8, 0x03, 0x79, 0x93, 0xb9, 0x96, + 0x1d, 0x5b, 0x53, 0x5b, 0xaf, 0x39, 0x18, 0xa7, 0x5a, 0x61, 0xa9, 0x16, 0x6a, 0xe2, 0xa9, 0x11, + 0xf4, 0x31, 0x64, 0x2c, 0xea, 0x90, 0x89, 0x3a, 0xa1, 0xaf, 0x55, 0x24, 0xb9, 0xae, 0x84, 0xe4, + 0xba, 0x52, 0x57, 0xe4, 0x1a, 0x4b, 0x9c, 0xa0, 0x92, 0xe4, 0x79, 0x9f, 0x04, 0x01, 0x1d, 0x8e, + 0x02, 0x79, 0x3c, 0xa7, 0x71, 0x61, 0x48, 0x9e, 0x1b, 0x4a, 0x84, 0xee, 0x42, 0xf6, 0xc4, 0x76, + 0x2d, 0x76, 0xa2, 0x4e, 0xe0, 0x0b, 0x8c, 0x2a, 0xa0, 0x7e, 0xca, 0x4f, 0xdd, 0xb9, 0x6e, 0xf2, + 0xf9, 0x6e, 0xb5, 0x5b, 0x8d, 0x70, 0xbe, 0x55, 0x7d, 0xdb, 0x6d, 0x31, 0x97, 0xaf, 0x15, 0x68, + 0xb7, 0xfa, 0x8f, 0x8c, 0xe6, 0xce, 0x1e, 0xe6, 0x73, 0x7e, 0xe5, 0xf4, 0xac, 0xac, 0x45, 0x90, + 0x47, 0xc4, 0x76, 0x38, 0x25, 0xbc, 0x06, 0x29, 0xa3, 0xf5, 0x85, 0x96, 0x2c, 0x69, 0xa7, 0x67, + 0xe5, 0x62, 0x54, 0x6d, 0xb8, 0x93, 0xe9, 0x32, 0x9a, 0x6f, 0x57, 0xff, 0x79, 0x12, 0x8a, 0x7b, + 0x23, 0x8b, 0x04, 0x54, 0xc6, 0x24, 0x2a, 0x43, 0x61, 0x44, 0x3c, 0xe2, 0x38, 0xd4, 0xb1, 0xfd, + 0xa1, 0x4a, 0x1b, 0xe2, 0x22, 0xf4, 0xe9, 0xdb, 0x4e, 0x63, 0x35, 0xc7, 0xe3, 0xec, 0x4f, 0xfe, + 0x75, 0x33, 0x11, 0x4e, 0xe8, 0x1e, 0xac, 0x1e, 0xc8, 0xde, 0xf6, 0x89, 0x29, 0x1c, 0x9b, 0x12, + 0x8e, 0xad, 0x2c, 0x72, 0x6c, 0xbc, 0x5b, 0x15, 0x35, 0x48, 0x43, 0x68, 0xe1, 0x95, 0x83, 0x78, + 0x11, 0xdd, 0x83, 0xe5, 0x21, 0x73, 0xed, 0x80, 0x79, 0x6f, 0xf6, 0x42, 0x88, 0x44, 0xb7, 0xe0, + 0x12, 0x77, 0x6e, 0xd8, 0x1f, 0x51, 0x2d, 0x4e, 0xac, 0x24, 0x5e, 0x1b, 0x92, 0xe7, 0xaa, 0x41, + 0xcc, 0xc5, 0xfa, 0xf7, 0x61, 0x65, 0xa6, 0x03, 0xfc, 0x14, 0xef, 0x18, 0x7b, 0xdd, 0x86, 0xb6, + 0x84, 0x8a, 0x90, 0xab, 0xb5, 0x5b, 0xbd, 0x66, 0x6b, 0x8f, 0xd3, 0x90, 0x22, 0xe4, 0x70, 0x7b, + 0x67, 0xa7, 0x6a, 0xd4, 0x9e, 0x68, 0x49, 0xfd, 0x3f, 0xa3, 0xd9, 0x55, 0x3c, 0xa4, 0x3a, 0xcb, + 0x43, 0x6e, 0xbf, 0x7e, 0xdc, 0x8a, 0x89, 0x4c, 0x0b, 0x11, 0x1f, 0xf9, 0x14, 0x40, 0x38, 0x91, + 0x5a, 0x7d, 0x12, 0x28, 0x27, 0x94, 0x5e, 0x19, 0x70, 0x2f, 0xcc, 0x24, 0x71, 0x5e, 0xa1, 0x8d, + 0x00, 0xfd, 0x00, 0x8a, 0x26, 0x1b, 0x8e, 0x1c, 0xaa, 0x94, 0x53, 0x6f, 0x54, 0x2e, 0x44, 0x78, + 0x23, 0x88, 0x33, 0xa1, 0xf4, 0x2c, 0x57, 0xfb, 0x83, 0x04, 0x14, 0x62, 0x5d, 0x9d, 0x25, 0x3f, + 0x45, 0xc8, 0xed, 0x75, 0xea, 0x46, 0xaf, 0xd9, 0x7a, 0xac, 0x25, 0x10, 0x40, 0x56, 0x4c, 0x5d, + 0x5d, 0x4b, 0x72, 0xd2, 0x56, 0x6b, 0xef, 0x76, 0x76, 0x1a, 0x82, 0xfe, 0xa0, 0x2b, 0xa0, 0x85, + 0x93, 0xd7, 0xef, 0xf6, 0x0c, 0xcc, 0xa5, 0x69, 0x74, 0x19, 0xd6, 0x22, 0xa9, 0xd2, 0xcc, 0xa0, + 0xab, 0x80, 0x22, 0xe1, 0xd4, 0x44, 0x56, 0xff, 0x5d, 0x58, 0xab, 0x31, 0x37, 0x20, 0xb6, 0x1b, + 0x11, 0xda, 0x2d, 0x3e, 0x68, 0x25, 0xea, 0xdb, 0x96, 0xdc, 0x5f, 0xab, 0x6b, 0xe7, 0x2f, 0x37, + 0x0b, 0x11, 0xb4, 0x59, 0xe7, 0x23, 0x0d, 0x0b, 0x16, 0x5f, 0x4b, 0x23, 0xdb, 0x12, 0x93, 0x9b, + 0xa9, 0x2e, 0x9f, 0xbf, 0xdc, 0x4c, 0x75, 0x9a, 0x75, 0xcc, 0x65, 0xe8, 0x1d, 0xc8, 0xd3, 0xe7, + 0x76, 0xd0, 0x37, 0xf9, 0x7e, 0xca, 0x27, 0x30, 0x83, 0x73, 0x5c, 0x50, 0xe3, 0xdb, 0x67, 0x15, + 0xa0, 0xc3, 0xbc, 0x40, 0xb5, 0xfc, 0x3d, 0xc8, 0x8c, 0x98, 0x27, 0xb2, 0x49, 0x7e, 0xd8, 0x2c, + 0xa4, 0x67, 0x1c, 0x2e, 0x63, 0x1c, 0x4b, 0xb0, 0xfe, 0xf7, 0x49, 0x80, 0x1e, 0xf1, 0x8f, 0x94, + 0x91, 0xfb, 0x90, 0x8f, 0x6e, 0x05, 0x54, 0x5a, 0x7a, 0xa1, 0xb7, 0x23, 0x30, 0xba, 0x17, 0x06, + 0x9b, 0xa4, 0xea, 0x0b, 0xd3, 0x8a, 0xb0, 0xa1, 0x45, 0x6c, 0x77, 0x96, 0x8f, 0xf3, 0xe3, 0x89, + 0x7a, 0x9e, 0xf2, 0x3c, 0xff, 0x44, 0x35, 0xb1, 0x45, 0xcb, 0x49, 0x53, 0x64, 0xef, 0xfd, 0x45, + 0x8d, 0xcc, 0x79, 0x64, 0x7b, 0x09, 0x4f, 0xf5, 0xd0, 0x43, 0x28, 0xf0, 0x71, 0xf7, 0x7d, 0x51, + 0xa7, 0x78, 0xde, 0x6b, 0xa7, 0x4a, 0x5a, 0xc0, 0x30, 0x8a, 0xbe, 0xab, 0x1a, 0xac, 0x7a, 0x63, + 0x97, 0x0f, 0x5b, 0xd9, 0xd0, 0x6d, 0xf8, 0x76, 0x8b, 0x06, 0x27, 0xcc, 0x3b, 0x32, 0x82, 0x80, + 0x98, 0x87, 0x3c, 0xb9, 0x57, 0xdb, 0xdb, 0x94, 0xe4, 0x26, 0x66, 0x48, 0xee, 0x3a, 0x2c, 0x13, + 0xc7, 0x26, 0x3e, 0x95, 0xcc, 0x20, 0x8f, 0xc3, 0x22, 0xa7, 0xe2, 0x9c, 0xd8, 0x53, 0xdf, 0xa7, + 0x32, 0x1d, 0xcd, 0xe3, 0xa9, 0x40, 0xff, 0xa7, 0x24, 0x40, 0xb3, 0x63, 0xec, 0x2a, 0xf3, 0x75, + 0xc8, 0x1e, 0x90, 0xa1, 0xed, 0x4c, 0x2e, 0x5a, 0xe0, 0x53, 0x7c, 0xc5, 0x90, 0x86, 0x1e, 0x09, + 0x1d, 0xac, 0x74, 0x05, 0x43, 0x1f, 0xef, 0xbb, 0x34, 0x88, 0x18, 0xba, 0x28, 0x71, 0x3a, 0xe0, + 0x11, 0x37, 0xf2, 0x8c, 0x2c, 0xf0, 0xae, 0x0f, 0x48, 0x40, 0x4f, 0xc8, 0x24, 0x5c, 0x95, 0xaa, + 0x88, 0xb6, 0x39, 0x73, 0xf7, 0xa9, 0x77, 0x4c, 0xad, 0xf5, 0x8c, 0x08, 0xc1, 0x37, 0xf5, 0x07, + 0x2b, 0xb8, 0x24, 0x3a, 0x91, 0x76, 0xe9, 0x81, 0x38, 0x9d, 0xa7, 0x55, 0xdf, 0x28, 0x99, 0xbe, + 0x03, 0x2b, 0x33, 0xe3, 0x7c, 0x25, 0x35, 0x6a, 0x76, 0x9e, 0x7e, 0x4f, 0x4b, 0xab, 0xaf, 0xef, + 0x6b, 0x59, 0xfd, 0xaf, 0x52, 0x72, 0x1d, 0xa9, 0x59, 0x5d, 0x7c, 0x3d, 0x95, 0x13, 0xd1, 0x6f, + 0x32, 0x47, 0xc5, 0xf7, 0x87, 0x17, 0x2f, 0x2f, 0x4e, 0xb5, 0x05, 0x1c, 0x47, 0x8a, 0x68, 0x13, + 0x0a, 0xd2, 0xff, 0x7d, 0x1e, 0x4f, 0x62, 0x5a, 0x57, 0x30, 0x48, 0x11, 0xd7, 0x44, 0x37, 0x60, + 0x75, 0x34, 0xde, 0x77, 0x6c, 0xff, 0x90, 0x5a, 0x12, 0x93, 0x16, 0x98, 0x95, 0x48, 0x2a, 0x60, + 0xbb, 0x50, 0x54, 0x82, 0xbe, 0xa0, 0x59, 0x19, 0xd1, 0xa1, 0x5b, 0x6f, 0xea, 0x90, 0x54, 0x11, + 0xec, 0xab, 0x30, 0x9a, 0x16, 0xf4, 0x3a, 0xe4, 0xc2, 0xce, 0xa2, 0x75, 0x48, 0xf5, 0x6a, 0x1d, + 0x6d, 0xa9, 0xb4, 0x76, 0x7a, 0x56, 0x2e, 0x84, 0xe2, 0x5e, 0xad, 0xc3, 0x6b, 0xf6, 0xea, 0x1d, + 0x2d, 0x31, 0x5b, 0xb3, 0x57, 0xef, 0x94, 0xd2, 0xfc, 0xb8, 0xd7, 0x0f, 0xa0, 0x10, 0x6b, 0x01, + 0xbd, 0x0f, 0xcb, 0xcd, 0xd6, 0x63, 0xdc, 0xe8, 0x76, 0xb5, 0xa5, 0xd2, 0xd5, 0xd3, 0xb3, 0x32, + 0x8a, 0xd5, 0x36, 0xdd, 0x01, 0xf7, 0x0f, 0x7a, 0x17, 0xd2, 0xdb, 0xed, 0x6e, 0x2f, 0xe4, 0x75, + 0x31, 0xc4, 0x36, 0xf3, 0x83, 0xd2, 0x65, 0xc5, 0x23, 0xe2, 0x86, 0xf5, 0x3f, 0x4d, 0x40, 0x56, + 0xd2, 0xdb, 0x85, 0x8e, 0x32, 0x60, 0x39, 0x4c, 0xba, 0x24, 0xe7, 0xfe, 0xf0, 0xf5, 0xfc, 0xb8, + 0xa2, 0xe8, 0xac, 0x0c, 0xbf, 0x50, 0xaf, 0xf4, 0x19, 0x14, 0xe3, 0x15, 0xdf, 0x28, 0xf8, 0x7e, + 0x07, 0x0a, 0x3c, 0xbe, 0x43, 0x9e, 0xbc, 0x05, 0x59, 0x49, 0xc1, 0xa3, 0xad, 0xf4, 0xf5, 0x64, + 0x5d, 0x21, 0xd1, 0x7d, 0x58, 0x96, 0x04, 0x3f, 0xbc, 0x8e, 0xda, 0xb8, 0x78, 0x15, 0xe1, 0x10, + 0xae, 0x3f, 0x84, 0x74, 0x87, 0x52, 0x8f, 0xcf, 0xbd, 0xcb, 0x2c, 0x3a, 0x3d, 0x7d, 0x54, 0x6e, + 0x62, 0xd1, 0x66, 0x9d, 0xe7, 0x26, 0x16, 0x6d, 0x5a, 0xd1, 0x6d, 0x42, 0x32, 0x76, 0x9b, 0xd0, + 0x83, 0xe2, 0x33, 0x6a, 0x0f, 0x0e, 0x03, 0x6a, 0x09, 0x43, 0xb7, 0x21, 0x3d, 0xa2, 0x51, 0xe7, + 0xd7, 0x17, 0x06, 0x18, 0xa5, 0x1e, 0x16, 0x28, 0xbe, 0x8f, 0x9c, 0x08, 0x6d, 0x75, 0x09, 0xaa, + 0x4a, 0xfa, 0x3f, 0x26, 0x61, 0xb5, 0xe9, 0xfb, 0x63, 0xe2, 0x9a, 0x21, 0x31, 0xf9, 0xe1, 0x2c, + 0x31, 0xb9, 0xb9, 0x70, 0x84, 0x33, 0x2a, 0xb3, 0x97, 0x24, 0xea, 0x70, 0x48, 0x46, 0x87, 0x83, + 0xfe, 0x1f, 0x89, 0xf0, 0x26, 0xe4, 0x46, 0x6c, 0xb9, 0x97, 0xd6, 0x4f, 0xcf, 0xca, 0x57, 0xe2, + 0x96, 0xe8, 0x9e, 0x7b, 0xe4, 0xb2, 0x13, 0x17, 0xbd, 0x07, 0x19, 0xdc, 0x68, 0x35, 0x9e, 0x69, + 0x09, 0x19, 0x9e, 0x33, 0x20, 0x4c, 0x5d, 0x7a, 0xc2, 0x2d, 0x75, 0x1a, 0xad, 0x3a, 0x27, 0x12, + 0xc9, 0x05, 0x96, 0x3a, 0xd4, 0xb5, 0x6c, 0x77, 0x80, 0xde, 0x87, 0x6c, 0xb3, 0xdb, 0xdd, 0x13, + 0xb9, 0xea, 0xb7, 0x4f, 0xcf, 0xca, 0x97, 0x67, 0x50, 0xbc, 0x40, 0x2d, 0x0e, 0xe2, 0x8c, 0x9a, + 0x53, 0x8c, 0x05, 0x20, 0x4e, 0xf7, 0x24, 0x08, 0xb7, 0x7b, 0x3c, 0x91, 0xce, 0x2c, 0x00, 0x61, + 0xc6, 0xff, 0xaa, 0xe5, 0xf6, 0xf3, 0x24, 0x68, 0x86, 0x69, 0xd2, 0x51, 0xc0, 0xeb, 0x55, 0x12, + 0xd3, 0x83, 0xdc, 0x88, 0x7f, 0xd9, 0x34, 0x24, 0x01, 0xf7, 0x17, 0x5e, 0xa3, 0xcf, 0xe9, 0x55, + 0x30, 0x73, 0xa8, 0x61, 0x0d, 0x6d, 0xdf, 0xe7, 0xc9, 0xba, 0x90, 0xe1, 0xc8, 0x52, 0xe9, 0xbf, + 0x12, 0x70, 0x79, 0x01, 0x02, 0xdd, 0x81, 0xb4, 0xc7, 0x9c, 0xd0, 0x87, 0xd7, 0x5f, 0x77, 0xc9, + 0xc5, 0x55, 0xb1, 0x40, 0xa2, 0x0d, 0x00, 0x32, 0x0e, 0x18, 0x11, 0xed, 0x0b, 0xef, 0xe5, 0x70, + 0x4c, 0x82, 0x9e, 0x41, 0xd6, 0xa7, 0xa6, 0x47, 0x43, 0xaa, 0xf8, 0xf0, 0xff, 0xdb, 0xfb, 0x4a, + 0x57, 0x98, 0xc1, 0xca, 0x5c, 0xa9, 0x02, 0x59, 0x29, 0xe1, 0x61, 0x6f, 0x91, 0x80, 0x88, 0x4e, + 0x17, 0xb1, 0xf8, 0xe6, 0xd1, 0x44, 0x9c, 0x41, 0x18, 0x4d, 0xc4, 0x19, 0xe8, 0x7f, 0x96, 0x04, + 0x68, 0x3c, 0x0f, 0xa8, 0xe7, 0x12, 0xa7, 0x66, 0xa0, 0x46, 0x6c, 0xf7, 0x97, 0xa3, 0xfd, 0x68, + 0xe1, 0xd5, 0x67, 0xa4, 0x51, 0xa9, 0x19, 0x0b, 0xf6, 0xff, 0x6b, 0x90, 0x1a, 0x7b, 0x8e, 0xba, + 0x46, 0x17, 0x34, 0x6f, 0x0f, 0xef, 0x60, 0x2e, 0x43, 0x8d, 0xe9, 0xb6, 0x95, 0x7a, 0xfd, 0xfb, + 0x47, 0xac, 0x81, 0x5f, 0xff, 0xd6, 0x75, 0x1b, 0x60, 0xda, 0x6b, 0xb4, 0x01, 0x99, 0xda, 0xa3, + 0x6e, 0x77, 0x47, 0x5b, 0x92, 0x7b, 0xf3, 0xb4, 0x4a, 0x88, 0xf5, 0x9f, 0x24, 0x20, 0x57, 0x33, + 0xd4, 0x89, 0x59, 0x03, 0x4d, 0x6c, 0x38, 0x26, 0xf5, 0x82, 0x3e, 0x7d, 0x3e, 0xb2, 0xbd, 0x89, + 0xda, 0x33, 0x2e, 0x48, 0x8d, 0x56, 0xb9, 0x4a, 0x8d, 0x7a, 0x41, 0x43, 0x28, 0x20, 0x0c, 0x45, + 0xaa, 0xc6, 0xd7, 0x37, 0x49, 0xb8, 0x7d, 0x6f, 0x5c, 0x3c, 0x0f, 0x92, 0x58, 0x4f, 0xcb, 0x3e, + 0x2e, 0x84, 0x46, 0x6a, 0xc4, 0xd7, 0x9f, 0xc2, 0xe5, 0xb6, 0x67, 0x1e, 0x52, 0x3f, 0x90, 0x8d, + 0xaa, 0xfe, 0x3e, 0x84, 0xeb, 0x01, 0xf1, 0x8f, 0xfa, 0x87, 0xb6, 0x1f, 0x30, 0x6f, 0xd2, 0xf7, + 0x68, 0x40, 0x5d, 0x5e, 0xdf, 0x17, 0x4f, 0x2c, 0xea, 0x42, 0xe3, 0x1a, 0xc7, 0x6c, 0x4b, 0x08, + 0x0e, 0x11, 0x3b, 0x1c, 0xa0, 0x37, 0xa1, 0xc8, 0xa9, 0x6c, 0x9d, 0x1e, 0x90, 0xb1, 0x13, 0xf8, + 0x3c, 0x49, 0x72, 0xd8, 0xa0, 0xff, 0xd6, 0x7b, 0x7d, 0xde, 0x61, 0x03, 0xf9, 0xa9, 0xff, 0x18, + 0xb4, 0xba, 0xed, 0x8f, 0x48, 0x60, 0x1e, 0x86, 0x37, 0x35, 0xa8, 0x0e, 0xda, 0x21, 0x25, 0x5e, + 0xb0, 0x4f, 0x49, 0xd0, 0x1f, 0x51, 0xcf, 0x66, 0xd6, 0x9b, 0xe7, 0x73, 0x2d, 0x52, 0xe9, 0x08, + 0x0d, 0xfd, 0xbf, 0x13, 0x00, 0x98, 0x1c, 0x84, 0xb4, 0xe6, 0xbb, 0x70, 0xc9, 0x77, 0xc9, 0xc8, + 0x3f, 0x64, 0x41, 0xdf, 0x76, 0x03, 0xea, 0x1d, 0x13, 0x47, 0x25, 0xdc, 0x5a, 0x58, 0xd1, 0x54, + 0x72, 0x74, 0x1b, 0xd0, 0x11, 0xa5, 0xa3, 0x3e, 0x73, 0xac, 0x7e, 0x58, 0x29, 0x1f, 0x80, 0xd2, + 0x58, 0xe3, 0x35, 0x6d, 0xc7, 0xea, 0x86, 0x72, 0x54, 0x85, 0x0d, 0x3e, 0x7c, 0xea, 0x06, 0x9e, + 0x4d, 0xfd, 0xfe, 0x01, 0xf3, 0xfa, 0xbe, 0xc3, 0x4e, 0xfa, 0x07, 0xcc, 0x71, 0xd8, 0x09, 0xf5, + 0xc2, 0xbb, 0x8c, 0x92, 0xc3, 0x06, 0x0d, 0x09, 0x7a, 0xc4, 0xbc, 0xae, 0xc3, 0x4e, 0x1e, 0x85, + 0x08, 0xce, 0x7d, 0xa6, 0x63, 0x0e, 0x6c, 0xf3, 0x28, 0xe4, 0x3e, 0x91, 0xb4, 0x67, 0x9b, 0x47, + 0xe8, 0x7d, 0x58, 0xa1, 0x0e, 0x15, 0x69, 0xb1, 0x44, 0x65, 0x04, 0xaa, 0x18, 0x0a, 0x39, 0x48, + 0xff, 0x1c, 0xb4, 0x86, 0x6b, 0x7a, 0x93, 0x51, 0xcc, 0xe7, 0xb7, 0x01, 0xf1, 0x9d, 0xa6, 0xef, + 0x30, 0xf3, 0xa8, 0x3f, 0x24, 0x2e, 0x19, 0xf0, 0x7e, 0xc9, 0x47, 0x07, 0x8d, 0xd7, 0xec, 0x30, + 0xf3, 0x68, 0x57, 0xc9, 0xf5, 0x4f, 0x01, 0xba, 0x23, 0x8f, 0x12, 0xab, 0xcd, 0x8f, 0x64, 0x3e, + 0x75, 0xa2, 0xd4, 0xb7, 0xd4, 0xbb, 0x06, 0xf3, 0xd4, 0xa2, 0xd2, 0x64, 0x45, 0x3d, 0x92, 0xeb, + 0xbf, 0x01, 0x97, 0x3b, 0x0e, 0x31, 0xc5, 0x1b, 0x5f, 0x27, 0xba, 0x45, 0x47, 0xf7, 0x21, 0x2b, + 0xa1, 0xca, 0x93, 0x0b, 0x03, 0x7b, 0xda, 0xe6, 0xf6, 0x12, 0x56, 0xf8, 0x6a, 0x11, 0x60, 0x6a, + 0x47, 0x7f, 0x0e, 0xf9, 0xc8, 0x3c, 0x2a, 0x03, 0xcf, 0x23, 0x79, 0x74, 0xdb, 0xae, 0x4a, 0xfc, + 0xf2, 0x38, 0x2e, 0x42, 0x4d, 0x28, 0x8c, 0x22, 0xe5, 0x0b, 0x39, 0xd1, 0x82, 0x4e, 0xe3, 0xb8, + 0xae, 0xfe, 0x43, 0x80, 0x1f, 0x31, 0xdb, 0xed, 0xb1, 0x23, 0xea, 0x8a, 0x87, 0x1b, 0x9e, 0xf2, + 0xd0, 0x70, 0x22, 0x54, 0x49, 0x64, 0x74, 0x72, 0x16, 0xa3, 0xf7, 0x0b, 0x59, 0xd4, 0xbf, 0x4e, + 0x40, 0x16, 0x33, 0x16, 0xd4, 0x0c, 0x54, 0x86, 0xac, 0x49, 0xfa, 0xe1, 0xd6, 0x54, 0xac, 0xe6, + 0xcf, 0x5f, 0x6e, 0x66, 0x6a, 0xc6, 0x13, 0x3a, 0xc1, 0x19, 0x93, 0x3c, 0xa1, 0x13, 0xce, 0x61, + 0x4c, 0x22, 0x36, 0x14, 0x61, 0xa6, 0x28, 0x39, 0x4c, 0xcd, 0xe0, 0x1b, 0x06, 0xce, 0x9a, 0x84, + 0xff, 0x47, 0x77, 0xa0, 0xa8, 0x40, 0xfd, 0x43, 0xe2, 0x1f, 0xca, 0x44, 0xa5, 0xba, 0x7a, 0xfe, + 0x72, 0x13, 0x24, 0x72, 0x9b, 0xf8, 0x87, 0x18, 0x24, 0x9a, 0x7f, 0xa3, 0x06, 0x14, 0xbe, 0x64, + 0xb6, 0xdb, 0x0f, 0xc4, 0x20, 0xd4, 0xfd, 0xcd, 0x42, 0x57, 0x4c, 0x87, 0xaa, 0x1e, 0xfa, 0xe0, + 0xcb, 0x48, 0xa2, 0xff, 0x73, 0x02, 0x0a, 0xdc, 0xa6, 0x7d, 0x60, 0x9b, 0x9c, 0x73, 0x7c, 0xf3, + 0xa3, 0xf0, 0x1a, 0xa4, 0x4c, 0xdf, 0x53, 0x63, 0x13, 0x67, 0x41, 0xad, 0x8b, 0x31, 0x97, 0xa1, + 0xcf, 0x21, 0xab, 0xb2, 0x53, 0x79, 0x0a, 0xea, 0x6f, 0x66, 0x47, 0xaa, 0x8b, 0x4a, 0x4f, 0x84, + 0xc5, 0xb4, 0x77, 0x62, 0x94, 0x45, 0x1c, 0x17, 0xa1, 0xab, 0x90, 0x34, 0x5d, 0xb1, 0x76, 0xd4, + 0x83, 0x6e, 0xad, 0x85, 0x93, 0xa6, 0xab, 0xff, 0x43, 0x02, 0x56, 0xa6, 0x4b, 0x87, 0x3b, 0xe2, + 0x3a, 0xe4, 0xfd, 0xf1, 0xbe, 0x3f, 0xf1, 0x03, 0x3a, 0x0c, 0xdf, 0x86, 0x22, 0x01, 0x6a, 0x42, + 0x9e, 0x38, 0x03, 0xe6, 0xd9, 0xc1, 0xe1, 0x50, 0x25, 0x46, 0x8b, 0x4f, 0xae, 0xb8, 0xcd, 0x8a, + 0x11, 0xaa, 0xe0, 0xa9, 0x76, 0x78, 0x56, 0xa5, 0x44, 0x67, 0xc5, 0x59, 0xf5, 0x1e, 0x14, 0x1d, + 0x32, 0x14, 0xe9, 0x3a, 0xcf, 0xb7, 0xc5, 0x38, 0xd2, 0xb8, 0xa0, 0x64, 0x3d, 0x7b, 0x48, 0x75, + 0x1d, 0xf2, 0x91, 0x31, 0xb4, 0x06, 0x05, 0xa3, 0xd1, 0xed, 0xdf, 0xdd, 0xba, 0xdf, 0x7f, 0x5c, + 0xdb, 0xd5, 0x96, 0x14, 0x55, 0xfa, 0xdb, 0x04, 0xac, 0xa8, 0x85, 0xad, 0xe8, 0xe7, 0xfb, 0xb0, + 0xec, 0x91, 0x83, 0x20, 0x24, 0xc8, 0x69, 0x19, 0x5c, 0x7c, 0xaf, 0xe4, 0x04, 0x99, 0x57, 0x2d, + 0x26, 0xc8, 0xb1, 0xd7, 0xca, 0xd4, 0x85, 0xaf, 0x95, 0xe9, 0x5f, 0xcb, 0x6b, 0xa5, 0xfe, 0xd7, + 0x49, 0x58, 0x53, 0x4c, 0x26, 0xda, 0x47, 0x3e, 0x82, 0xbc, 0x24, 0x35, 0x53, 0x7a, 0x2f, 0x1e, + 0xc8, 0x24, 0xae, 0x59, 0xc7, 0x39, 0x59, 0xdd, 0xb4, 0x78, 0xbe, 0xa9, 0xa0, 0xb1, 0xb7, 0x77, + 0x90, 0xa2, 0x16, 0x4f, 0x96, 0xea, 0x90, 0x3e, 0xb0, 0x1d, 0xaa, 0xe2, 0x6c, 0xe1, 0xb5, 0xe8, + 0x5c, 0xf3, 0xe2, 0x02, 0xbf, 0x27, 0x32, 0xd6, 0xed, 0x25, 0x2c, 0xb4, 0x4b, 0xbf, 0x07, 0x30, + 0x95, 0x2e, 0x4c, 0xca, 0x38, 0xf1, 0x51, 0xf7, 0x5b, 0x21, 0xf1, 0x69, 0xd6, 0x31, 0x97, 0xf1, + 0xaa, 0x81, 0x6d, 0xa9, 0x95, 0x2b, 0xaa, 0x1e, 0xf3, 0xaa, 0x81, 0x6d, 0x45, 0xaf, 0x08, 0xe9, + 0x37, 0xbc, 0x22, 0x54, 0x73, 0xe1, 0x2d, 0x8b, 0xbe, 0x03, 0x57, 0xab, 0x0e, 0x31, 0x8f, 0x1c, + 0xdb, 0x0f, 0xa8, 0x15, 0x5f, 0xa1, 0x5b, 0x90, 0x9d, 0x21, 0x26, 0x17, 0x5d, 0x6a, 0x29, 0xa4, + 0xfe, 0x97, 0x09, 0x28, 0x6e, 0x53, 0xe2, 0x04, 0x87, 0xd3, 0x9b, 0x81, 0x80, 0xfa, 0x81, 0xda, + 0x67, 0xc5, 0x37, 0xfa, 0x04, 0x72, 0xd1, 0x69, 0xfa, 0xc6, 0x9b, 0xfe, 0x08, 0x8a, 0xee, 0xc1, + 0x32, 0x8f, 0x69, 0x36, 0x0e, 0xb9, 0xee, 0x45, 0x97, 0xc8, 0x0a, 0xc9, 0xf7, 0x56, 0x8f, 0x8a, + 0xe3, 0x53, 0x4c, 0x4a, 0x06, 0x87, 0x45, 0xfd, 0x7f, 0x13, 0x70, 0x65, 0x97, 0x4c, 0xf6, 0xa9, + 0x5a, 0x68, 0xd4, 0xc2, 0xd4, 0x64, 0x9e, 0x85, 0x3a, 0xf1, 0x05, 0x7a, 0xc1, 0xbb, 0xc6, 0x22, + 0xe5, 0xc5, 0xeb, 0x34, 0x64, 0xd0, 0xc9, 0x18, 0x83, 0xbe, 0x02, 0x19, 0x97, 0xb9, 0x26, 0x55, + 0xab, 0x57, 0x16, 0x74, 0x3b, 0xbe, 0x38, 0x4b, 0xd1, 0x93, 0x83, 0x78, 0x30, 0x68, 0xb1, 0x20, + 0x6a, 0x0d, 0x7d, 0x0e, 0xa5, 0x6e, 0xa3, 0x86, 0x1b, 0xbd, 0x6a, 0xfb, 0xc7, 0xfd, 0xae, 0xb1, + 0xd3, 0x35, 0xb6, 0xee, 0xf4, 0x3b, 0xed, 0x9d, 0x2f, 0xee, 0xde, 0xbb, 0xf3, 0x89, 0x96, 0x28, + 0x95, 0x4f, 0xcf, 0xca, 0xd7, 0x5b, 0x46, 0x6d, 0x47, 0x46, 0xe3, 0x3e, 0x7b, 0xde, 0x25, 0x8e, + 0x4f, 0xb6, 0xee, 0x74, 0x98, 0x33, 0xe1, 0x98, 0x5b, 0xbf, 0x4c, 0x41, 0x3e, 0xba, 0x5c, 0xe4, + 0x41, 0xc5, 0x33, 0x3b, 0xd5, 0x54, 0x24, 0x6f, 0xd1, 0x13, 0xf4, 0xde, 0x34, 0xa7, 0xfb, 0x5c, + 0xbe, 0x6c, 0x44, 0xd5, 0x61, 0x3e, 0xf7, 0x01, 0xe4, 0x8c, 0x6e, 0xb7, 0xf9, 0xb8, 0xd5, 0xa8, + 0x6b, 0x5f, 0x25, 0x4a, 0xdf, 0x3a, 0x3d, 0x2b, 0x5f, 0x8a, 0x40, 0x86, 0xef, 0xdb, 0x03, 0x97, + 0x5a, 0x02, 0x55, 0xab, 0x35, 0x3a, 0xbd, 0x46, 0x5d, 0x7b, 0x91, 0x9c, 0x47, 0x89, 0x1c, 0x45, + 0xbc, 0x4f, 0xe6, 0x3b, 0xb8, 0xd1, 0x31, 0x30, 0x6f, 0xf0, 0xab, 0xa4, 0x4c, 0x35, 0xa7, 0x2d, + 0x7a, 0x74, 0x44, 0x3c, 0xde, 0xe6, 0x46, 0xf8, 0x4e, 0xff, 0x22, 0x25, 0xdf, 0xb0, 0xa6, 0x37, + 0xa5, 0x94, 0x58, 0x13, 0xde, 0x9a, 0xb8, 0xa2, 0x16, 0x66, 0x52, 0x73, 0xad, 0x75, 0x03, 0xe2, + 0x05, 0xdc, 0x8a, 0x0e, 0xcb, 0x78, 0xaf, 0xd5, 0xe2, 0xa0, 0x17, 0xe9, 0xb9, 0xd1, 0xe1, 0xb1, + 0xeb, 0x72, 0xcc, 0x0d, 0xc8, 0x85, 0x37, 0xd8, 0xda, 0x57, 0xe9, 0xb9, 0x0e, 0xd5, 0xc2, 0xeb, + 0x77, 0xd1, 0xe0, 0xf6, 0x5e, 0x4f, 0xfc, 0x8c, 0xe0, 0x45, 0x66, 0xbe, 0xc1, 0xc3, 0x71, 0x60, + 0xf1, 0x24, 0xba, 0x1c, 0x65, 0xb5, 0x5f, 0x65, 0x64, 0x9e, 0x10, 0x61, 0x54, 0x4a, 0xfb, 0x01, + 0xe4, 0x70, 0xe3, 0x47, 0xf2, 0x17, 0x07, 0x2f, 0xb2, 0x73, 0x76, 0x30, 0xfd, 0x92, 0x9a, 0xaa, + 0xb5, 0x36, 0xee, 0x6c, 0x1b, 0x62, 0xca, 0xe7, 0x51, 0x6d, 0x6f, 0x74, 0x48, 0x5c, 0x6a, 0x4d, + 0x1f, 0xf2, 0xa2, 0xaa, 0x5b, 0xbf, 0x09, 0xb9, 0xf0, 0x60, 0x45, 0x1b, 0x90, 0x7d, 0xd6, 0xc6, + 0x4f, 0x1a, 0x58, 0x5b, 0x92, 0x73, 0x18, 0xd6, 0x3c, 0x93, 0xcc, 0xa4, 0x0c, 0xcb, 0xbb, 0x46, + 0xcb, 0x78, 0xdc, 0xc0, 0xe1, 0x85, 0x53, 0x08, 0x50, 0xa7, 0x43, 0x49, 0x53, 0x0d, 0x44, 0x36, + 0xab, 0xeb, 0x5f, 0xff, 0x62, 0x63, 0xe9, 0x67, 0xbf, 0xd8, 0x58, 0x7a, 0x71, 0xbe, 0x91, 0xf8, + 0xfa, 0x7c, 0x23, 0xf1, 0xd3, 0xf3, 0x8d, 0xc4, 0xbf, 0x9d, 0x6f, 0x24, 0xf6, 0xb3, 0x62, 0x9d, + 0xde, 0xfb, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc8, 0xe3, 0x0e, 0xba, 0x76, 0x27, 0x00, 0x00, } diff --git a/vendor/github.com/docker/swarmkit/api/types.proto b/vendor/github.com/docker/swarmkit/api/types.proto index fd7d6253e5..dd34fd0d3b 100644 --- a/vendor/github.com/docker/swarmkit/api/types.proto +++ b/vendor/github.com/docker/swarmkit/api/types.proto @@ -709,10 +709,29 @@ message EncryptionConfig { bool auto_lock_managers = 1; } +message SpreadOver { + string spread_descriptor = 1; // label descriptor, such as engine.labels.az + // TODO: support node information beyond engine and node labels + + // TODO: in the future, add a map that provides weights for weighted + // spreading. +} + +message PlacementPreference { + oneof Preference { + SpreadOver spread = 1; + } +} + // Placement specifies task distribution constraints. message Placement { - // constraints specifies a set of requirements a node should meet for a task. + // Constraints specifies a set of requirements a node should meet for a task. repeated string constraints = 1; + + // Preferences provide a way to make the scheduler aware of factors + // such as topology. They are provided in order from highest to lowest + // precedence. + repeated PlacementPreference preferences = 2; } // JoinToken contains the join tokens for workers and managers. diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/network.go b/vendor/github.com/docker/swarmkit/manager/allocator/network.go index b30de9ad8f..8fee7d945e 100644 --- a/vendor/github.com/docker/swarmkit/manager/allocator/network.go +++ b/vendor/github.com/docker/swarmkit/manager/allocator/network.go @@ -231,7 +231,7 @@ func (a *Allocator) doNetworkInit(ctx context.Context) (err error) { var allocatedServices []*api.Service for _, s := range services { - if nc.nwkAllocator.IsServiceAllocated(s) { + if nc.nwkAllocator.IsServiceAllocated(s, networkallocator.OnInit) { continue } diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go b/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go index cee402921e..8662b09df3 100644 --- a/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go +++ b/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go @@ -289,8 +289,25 @@ func (na *NetworkAllocator) PortsAllocatedInHostPublishMode(s *api.Service) bool return na.portAllocator.portsAllocatedInHostPublishMode(s) } +// ServiceAllocationOpts is struct used for functional options in IsServiceAllocated +type ServiceAllocationOpts struct { + OnInit bool +} + +// OnInit is called for allocator initialization stage +func OnInit(options *ServiceAllocationOpts) { + options.OnInit = true +} + // IsServiceAllocated returns if the passed service has its network resources allocated or not. -func (na *NetworkAllocator) IsServiceAllocated(s *api.Service) bool { +// init bool indicates if the func is called during allocator initialization stage. +func (na *NetworkAllocator) IsServiceAllocated(s *api.Service, flags ...func(*ServiceAllocationOpts)) bool { + var options ServiceAllocationOpts + + for _, flag := range flags { + flag(&options) + } + // If endpoint mode is VIP and allocator does not have the // service in VIP allocated set then it is not allocated. if (len(s.Spec.Task.Networks) != 0 || len(s.Spec.Networks) != 0) && @@ -313,7 +330,7 @@ func (na *NetworkAllocator) IsServiceAllocated(s *api.Service) bool { if (s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0) || (s.Endpoint != nil && len(s.Endpoint.Ports) != 0) { - return na.portAllocator.isPortsAllocated(s) + return na.portAllocator.isPortsAllocatedOnInit(s, options.OnInit) } return true diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go b/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go index eef193dfd1..5dacb69dd3 100644 --- a/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go +++ b/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/portallocator.go @@ -297,6 +297,10 @@ func (pa *portAllocator) portsAllocatedInHostPublishMode(s *api.Service) bool { } func (pa *portAllocator) isPortsAllocated(s *api.Service) bool { + return pa.isPortsAllocatedOnInit(s, false) +} + +func (pa *portAllocator) isPortsAllocatedOnInit(s *api.Service, onInit bool) bool { // If service has no user-defined endpoint and allocated endpoint, // we assume it is allocated and return true. if s.Endpoint == nil && s.Spec.Endpoint == nil { @@ -345,6 +349,13 @@ func (pa *portAllocator) isPortsAllocated(s *api.Service) bool { if portConfig.PublishedPort == 0 && portStates.delState(portConfig) == nil { return false } + + // If SwarmPort was not defined by user and the func + // is called during allocator initialization state then + // we are not allocated. + if portConfig.PublishedPort == 0 && onInit { + return false + } } return true diff --git a/vendor/github.com/docker/swarmkit/manager/constraint/constraint.go b/vendor/github.com/docker/swarmkit/manager/constraint/constraint.go index cb00215223..9f13217ae4 100644 --- a/vendor/github.com/docker/swarmkit/manager/constraint/constraint.go +++ b/vendor/github.com/docker/swarmkit/manager/constraint/constraint.go @@ -13,8 +13,10 @@ const ( eq = iota noteq - nodeLabelPrefix = "node.labels." - engineLabelPrefix = "engine.labels." + // NodeLabelPrefix is the constraint key prefix for node labels. + NodeLabelPrefix = "node.labels." + // EngineLabelPrefix is the constraint key prefix for engine labels. + EngineLabelPrefix = "engine.labels." ) var ( @@ -168,14 +170,14 @@ func NodeMatches(constraints []Constraint, n *api.Node) bool { } // node labels constraint in form like 'node.labels.key==value' - case len(constraint.key) > len(nodeLabelPrefix) && strings.EqualFold(constraint.key[:len(nodeLabelPrefix)], nodeLabelPrefix): + case len(constraint.key) > len(NodeLabelPrefix) && strings.EqualFold(constraint.key[:len(NodeLabelPrefix)], NodeLabelPrefix): if n.Spec.Annotations.Labels == nil { if !constraint.Match("") { return false } continue } - label := constraint.key[len(nodeLabelPrefix):] + label := constraint.key[len(NodeLabelPrefix):] // label itself is case sensitive val := n.Spec.Annotations.Labels[label] if !constraint.Match(val) { @@ -183,14 +185,14 @@ func NodeMatches(constraints []Constraint, n *api.Node) bool { } // engine labels constraint in form like 'engine.labels.key!=value' - case len(constraint.key) > len(engineLabelPrefix) && strings.EqualFold(constraint.key[:len(engineLabelPrefix)], engineLabelPrefix): + case len(constraint.key) > len(EngineLabelPrefix) && strings.EqualFold(constraint.key[:len(EngineLabelPrefix)], EngineLabelPrefix): if n.Description == nil || n.Description.Engine == nil || n.Description.Engine.Labels == nil { if !constraint.Match("") { return false } continue } - label := constraint.key[len(engineLabelPrefix):] + label := constraint.key[len(EngineLabelPrefix):] val := n.Description.Engine.Labels[label] if !constraint.Match(val) { return false diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/decision_tree.go b/vendor/github.com/docker/swarmkit/manager/scheduler/decision_tree.go new file mode 100644 index 0000000000..4567753704 --- /dev/null +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/decision_tree.go @@ -0,0 +1,55 @@ +package scheduler + +import ( + "container/heap" +) + +type decisionTree struct { + // Count of tasks for the service scheduled to this subtree + tasks int + + // Non-leaf point to the next level of the tree. The key is the + // value that the subtree covers. + next map[string]*decisionTree + + // Leaf nodes contain a list of nodes + nodeHeap nodeMaxHeap +} + +// orderedNodes returns the nodes in this decision tree entry, sorted best +// (lowest) first according to the sorting function. Must be called on a leaf +// of the decision tree. +// +// The caller may modify the nodes in the returned slice. This has the effect +// of changing the nodes in the decision tree entry. The next node to +// findBestNodes on this decisionTree entry will take into account the changes +// that were made to the nodes. +func (dt *decisionTree) orderedNodes(meetsConstraints func(*NodeInfo) bool, nodeLess func(*NodeInfo, *NodeInfo) bool) []NodeInfo { + if dt.nodeHeap.length != len(dt.nodeHeap.nodes) { + // We already collapsed the heap into a sorted slice, so + // re-heapify. There may have been modifications to the nodes + // so we can't return dt.nodeHeap.nodes as-is. We also need to + // reevaluate constraints because of the possible modifications. + for i := 0; i < len(dt.nodeHeap.nodes); { + if meetsConstraints(&dt.nodeHeap.nodes[i]) { + i++ + } else { + last := len(dt.nodeHeap.nodes) - 1 + dt.nodeHeap.nodes[i] = dt.nodeHeap.nodes[last] + dt.nodeHeap.nodes = dt.nodeHeap.nodes[:last] + } + } + dt.nodeHeap.length = len(dt.nodeHeap.nodes) + heap.Init(&dt.nodeHeap) + } + + // Popping every element orders the nodes from best to worst. The + // first pop gets the worst node (since this a max-heap), and puts it + // at position n-1. Then the next pop puts the next-worst at n-2, and + // so on. + for dt.nodeHeap.Len() > 0 { + heap.Pop(&dt.nodeHeap) + } + + return dt.nodeHeap.nodes +} diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeheap.go b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeheap.go new file mode 100644 index 0000000000..ca6db8e5ca --- /dev/null +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeheap.go @@ -0,0 +1,31 @@ +package scheduler + +type nodeMaxHeap struct { + nodes []NodeInfo + lessFunc func(*NodeInfo, *NodeInfo) bool + length int +} + +func (h nodeMaxHeap) Len() int { + return h.length +} + +func (h nodeMaxHeap) Swap(i, j int) { + h.nodes[i], h.nodes[j] = h.nodes[j], h.nodes[i] +} + +func (h nodeMaxHeap) Less(i, j int) bool { + // reversed to make a max-heap + return h.lessFunc(&h.nodes[j], &h.nodes[i]) +} + +func (h *nodeMaxHeap) Push(x interface{}) { + h.nodes = append(h.nodes, x.(NodeInfo)) + h.length++ +} + +func (h *nodeMaxHeap) Pop() interface{} { + h.length-- + // return value is never used + return nil +} diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go index 89571ce535..2f8ae51ca1 100644 --- a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go @@ -3,9 +3,11 @@ package scheduler import ( "container/heap" "errors" + "strings" "time" "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/manager/constraint" ) var errNodeNotFound = errors.New("node not found in scheduler dataset") @@ -56,73 +58,74 @@ func (ns *nodeSet) remove(nodeID string) { delete(ns.nodes, nodeID) } -type nodeMaxHeap struct { - nodes []NodeInfo - lessFunc func(*NodeInfo, *NodeInfo) bool - length int -} +func (ns *nodeSet) tree(serviceID string, preferences []*api.PlacementPreference, maxAssignments int, meetsConstraints func(*NodeInfo) bool, nodeLess func(*NodeInfo, *NodeInfo) bool) decisionTree { + var root decisionTree -func (h nodeMaxHeap) Len() int { - return h.length -} - -func (h nodeMaxHeap) Swap(i, j int) { - h.nodes[i], h.nodes[j] = h.nodes[j], h.nodes[i] -} - -func (h nodeMaxHeap) Less(i, j int) bool { - // reversed to make a max-heap - return h.lessFunc(&h.nodes[j], &h.nodes[i]) -} - -func (h *nodeMaxHeap) Push(x interface{}) { - h.nodes = append(h.nodes, x.(NodeInfo)) - h.length++ -} - -func (h *nodeMaxHeap) Pop() interface{} { - h.length-- - // return value is never used - return nil -} - -// findBestNodes returns n nodes (or < n if fewer nodes are available) that -// rank best (lowest) according to the sorting function. -func (ns *nodeSet) findBestNodes(n int, meetsConstraints func(*NodeInfo) bool, nodeLess func(*NodeInfo, *NodeInfo) bool) []NodeInfo { - if n == 0 { - return []NodeInfo{} + if maxAssignments == 0 { + return root } - nodeHeap := nodeMaxHeap{lessFunc: nodeLess} - - // TODO(aaronl): Is is possible to avoid checking constraints on every - // node? Perhaps we should try to schedule with n*2 nodes that weren't - // prescreened, and repeat the selection if there weren't enough nodes - // meeting the constraints. for _, node := range ns.nodes { - // If there are fewer then n nodes in the heap, we add this - // node if it meets the constraints. Otherwise, the heap has - // n nodes, and if this node is better than the worst node in - // the heap, we replace the worst node and then fix the heap. - if nodeHeap.Len() < n { - if meetsConstraints(&node) { - heap.Push(&nodeHeap, node) + tree := &root + for _, pref := range preferences { + // Only spread is supported so far + spread := pref.GetSpread() + if spread == nil { + continue } - } else if nodeLess(&node, &nodeHeap.nodes[0]) { + + descriptor := spread.SpreadDescriptor + var value string + switch { + case len(descriptor) > len(constraint.NodeLabelPrefix) && strings.EqualFold(descriptor[:len(constraint.NodeLabelPrefix)], constraint.NodeLabelPrefix): + if node.Spec.Annotations.Labels != nil { + value = node.Spec.Annotations.Labels[descriptor[len(constraint.NodeLabelPrefix):]] + } + case len(descriptor) > len(constraint.EngineLabelPrefix) && strings.EqualFold(descriptor[:len(constraint.EngineLabelPrefix)], constraint.EngineLabelPrefix): + if node.Description != nil && node.Description.Engine != nil && node.Description.Engine.Labels != nil { + value = node.Description.Engine.Labels[descriptor[len(constraint.EngineLabelPrefix):]] + } + // TODO(aaronl): Support other items from constraint + // syntax like node ID, hostname, os/arch, etc? + default: + continue + } + + // If value is still uninitialized, the value used for + // the node at this level of the tree is "". This makes + // sure that the tree structure is not affected by + // which properties nodes have and don't have. + + if node.DesiredRunningTasksCountByService != nil { + tree.tasks += node.DesiredRunningTasksCountByService[serviceID] + } + + if tree.next == nil { + tree.next = make(map[string]*decisionTree) + } + next := tree.next[value] + if next == nil { + next = &decisionTree{} + tree.next[value] = next + } + tree = next + } + + if tree.nodeHeap.lessFunc == nil { + tree.nodeHeap.lessFunc = nodeLess + } + + if tree.nodeHeap.Len() < maxAssignments { if meetsConstraints(&node) { - nodeHeap.nodes[0] = node - heap.Fix(&nodeHeap, 0) + heap.Push(&tree.nodeHeap, node) + } + } else if nodeLess(&node, &tree.nodeHeap.nodes[0]) { + if meetsConstraints(&node) { + tree.nodeHeap.nodes[0] = node + heap.Fix(&tree.nodeHeap, 0) } } } - // Popping every element orders the nodes from best to worst. The - // first pop gets the worst node (since this a max-heap), and puts it - // at position n-1. Then the next pop puts the next-worst at n-2, and - // so on. - for nodeHeap.Len() > 0 { - heap.Pop(&nodeHeap) - } - - return nodeHeap.nodes + return root } diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go b/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go index 67f4d4a7b1..c790ee8f47 100644 --- a/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go @@ -531,21 +531,82 @@ func (s *Scheduler) scheduleTaskGroup(ctx context.Context, taskGroup map[string] return a.DesiredRunningTasksCount < b.DesiredRunningTasksCount } - nodes := s.nodeSet.findBestNodes(len(taskGroup), s.pipeline.Process, nodeLess) - nodeCount := len(nodes) - if nodeCount == 0 { - s.noSuitableNode(ctx, taskGroup, schedulingDecisions) - return + var prefs []*api.PlacementPreference + if t.Spec.Placement != nil { + prefs = t.Spec.Placement.Preferences } + tree := s.nodeSet.tree(t.ServiceID, prefs, len(taskGroup), s.pipeline.Process, nodeLess) + + s.scheduleNTasksOnSubtree(ctx, len(taskGroup), taskGroup, &tree, schedulingDecisions, nodeLess) + if len(taskGroup) != 0 { + s.noSuitableNode(ctx, taskGroup, schedulingDecisions) + } +} + +func (s *Scheduler) scheduleNTasksOnSubtree(ctx context.Context, n int, taskGroup map[string]*api.Task, tree *decisionTree, schedulingDecisions map[string]schedulingDecision, nodeLess func(a *NodeInfo, b *NodeInfo) bool) int { + if tree.next == nil { + nodes := tree.orderedNodes(s.pipeline.Process, nodeLess) + if len(nodes) == 0 { + return 0 + } + + return s.scheduleNTasksOnNodes(ctx, n, taskGroup, nodes, schedulingDecisions, nodeLess) + } + + // Walk the tree and figure out how the tasks should be split at each + // level. + tasksScheduled := 0 + tasksInUsableBranches := tree.tasks + var noRoom map[*decisionTree]struct{} + + // Try to make branches even until either all branches are + // full, or all tasks have been scheduled. + for tasksScheduled != n && len(noRoom) != len(tree.next) { + desiredTasksPerBranch := (tasksInUsableBranches + n - tasksScheduled) / (len(tree.next) - len(noRoom)) + remainder := (tasksInUsableBranches + n - tasksScheduled) % (len(tree.next) - len(noRoom)) + + for _, subtree := range tree.next { + if noRoom != nil { + if _, ok := noRoom[subtree]; ok { + continue + } + } + subtreeTasks := subtree.tasks + if subtreeTasks < desiredTasksPerBranch || (subtreeTasks == desiredTasksPerBranch && remainder > 0) { + tasksToAssign := desiredTasksPerBranch - subtreeTasks + if remainder > 0 { + tasksToAssign++ + } + res := s.scheduleNTasksOnSubtree(ctx, tasksToAssign, taskGroup, subtree, schedulingDecisions, nodeLess) + if res < tasksToAssign { + if noRoom == nil { + noRoom = make(map[*decisionTree]struct{}) + } + noRoom[subtree] = struct{}{} + tasksInUsableBranches -= subtreeTasks + } else if remainder > 0 { + remainder-- + } + tasksScheduled += res + } + } + } + + return tasksScheduled +} + +func (s *Scheduler) scheduleNTasksOnNodes(ctx context.Context, n int, taskGroup map[string]*api.Task, nodes []NodeInfo, schedulingDecisions map[string]schedulingDecision, nodeLess func(a *NodeInfo, b *NodeInfo) bool) int { + tasksScheduled := 0 failedConstraints := make(map[int]bool) // key is index in nodes slice nodeIter := 0 + nodeCount := len(nodes) for taskID, t := range taskGroup { - n := &nodes[nodeIter%nodeCount] + node := &nodes[nodeIter%nodeCount] - log.G(ctx).WithField("task.id", t.ID).Debugf("assigning to node %s", n.ID) + log.G(ctx).WithField("task.id", t.ID).Debugf("assigning to node %s", node.ID) newT := *t - newT.NodeID = n.ID + newT.NodeID = node.ID newT.Status = api.TaskStatus{ State: api.TaskStateAssigned, Timestamp: ptypes.MustTimestampProto(time.Now()), @@ -553,7 +614,7 @@ func (s *Scheduler) scheduleTaskGroup(ctx context.Context, taskGroup map[string] } s.allTasks[t.ID] = &newT - nodeInfo, err := s.nodeSet.nodeInfo(n.ID) + nodeInfo, err := s.nodeSet.nodeInfo(node.ID) if err == nil && nodeInfo.addTask(&newT) { s.nodeSet.updateNode(nodeInfo) nodes[nodeIter%nodeCount] = nodeInfo @@ -561,6 +622,10 @@ func (s *Scheduler) scheduleTaskGroup(ctx context.Context, taskGroup map[string] schedulingDecisions[taskID] = schedulingDecision{old: t, new: &newT} delete(taskGroup, taskID) + tasksScheduled++ + if tasksScheduled == n { + return tasksScheduled + } if nodeIter+1 < nodeCount { // First pass fills the nodes until they have the same @@ -581,11 +646,12 @@ func (s *Scheduler) scheduleTaskGroup(ctx context.Context, taskGroup map[string] nodeIter++ if nodeIter-origNodeIter == nodeCount { // None of the nodes meet the constraints anymore. - s.noSuitableNode(ctx, taskGroup, schedulingDecisions) - return + return tasksScheduled } } } + + return tasksScheduled } func (s *Scheduler) noSuitableNode(ctx context.Context, taskGroup map[string]*api.Task, schedulingDecisions map[string]schedulingDecision) {