diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 16283f468a..76673e5f83 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -128,6 +128,10 @@ "Comment": "v0.8.1-6-gab50d12", "Rev": "ab50d12e88f57788bf84b83fef2be236eb1fcc0b" }, + { + "ImportPath": "github.com/armon/circbuf", + "Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d" + }, { "ImportPath": "github.com/asaskevich/govalidator", "Comment": "v4-12-g593d645", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index 199cc3d8bd..beccada108 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -1546,6 +1546,34 @@ Apache License ================================================================================ +================================================================================ += vendor/github.com/armon/circbuf licensed under: = + +The MIT License (MIT) + +Copyright (c) 2013 Armon Dadgar + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + += vendor/github.com/armon/circbuf/LICENSE d2d77030c0183e3d1e66d26dc1f243be - +================================================================================ + + ================================================================================ = vendor/github.com/asaskevich/govalidator licensed under: = diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 1cc5462cff..da949fcd63 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -35061,7 +35061,11 @@ "type": "boolean" }, "terminationMessagePath": { - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.", + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "type": "string" + }, + "terminationMessagePolicy": { + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", "type": "string" }, "tty": { diff --git a/api/swagger-spec/apps_v1beta1.json b/api/swagger-spec/apps_v1beta1.json index 60a8f8b883..19c728ef56 100644 --- a/api/swagger-spec/apps_v1beta1.json +++ b/api/swagger-spec/apps_v1beta1.json @@ -2191,7 +2191,11 @@ }, "terminationMessagePath": { "type": "string", - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated." + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated." + }, + "terminationMessagePolicy": { + "type": "string", + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated." }, "imagePullPolicy": { "type": "string", diff --git a/api/swagger-spec/batch_v1.json b/api/swagger-spec/batch_v1.json index b02f553226..7b149beac2 100644 --- a/api/swagger-spec/batch_v1.json +++ b/api/swagger-spec/batch_v1.json @@ -2196,7 +2196,11 @@ }, "terminationMessagePath": { "type": "string", - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated." + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated." + }, + "terminationMessagePolicy": { + "type": "string", + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated." }, "imagePullPolicy": { "type": "string", diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index eaf55f7778..d415a29c6c 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -8568,7 +8568,11 @@ }, "terminationMessagePath": { "type": "string", - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated." + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated." + }, + "terminationMessagePolicy": { + "type": "string", + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated." }, "imagePullPolicy": { "type": "string", diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json index 054e6fe39f..6c7c6be407 100644 --- a/api/swagger-spec/v1.json +++ b/api/swagger-spec/v1.json @@ -18660,7 +18660,11 @@ }, "terminationMessagePath": { "type": "string", - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated." + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated." + }, + "terminationMessagePolicy": { + "type": "string", + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated." }, "imagePullPolicy": { "type": "string", diff --git a/docs/api-reference/apps/v1beta1/definitions.html b/docs/api-reference/apps/v1beta1/definitions.html index 1f757f1221..a83ceba29e 100755 --- a/docs/api-reference/apps/v1beta1/definitions.html +++ b/docs/api-reference/apps/v1beta1/definitions.html @@ -1803,7 +1803,14 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }

terminationMessagePath

-

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.

+

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

+

false

+

string

+ + + +

terminationMessagePolicy

+

Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

false

string

@@ -5011,7 +5018,7 @@ Examples:
diff --git a/docs/api-reference/batch/v1/definitions.html b/docs/api-reference/batch/v1/definitions.html index 9b73ea0574..6d8bb400c6 100755 --- a/docs/api-reference/batch/v1/definitions.html +++ b/docs/api-reference/batch/v1/definitions.html @@ -1707,7 +1707,14 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }

terminationMessagePath

-

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.

+

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

+

false

+

string

+ + + +

terminationMessagePolicy

+

Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

false

string

@@ -4943,7 +4950,7 @@ Examples:
diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index 3b4fac0054..98455db29e 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -5765,7 +5765,14 @@ Both these may change in the future. Incoming requests are matched against the h

terminationMessagePath

-

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.

+

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

+

false

+

string

+ + + +

terminationMessagePolicy

+

Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

false

string

@@ -7560,7 +7567,7 @@ Both these may change in the future. Incoming requests are matched against the h diff --git a/docs/api-reference/v1/definitions.html b/docs/api-reference/v1/definitions.html index 3c2df4ee5a..9152833a2c 100755 --- a/docs/api-reference/v1/definitions.html +++ b/docs/api-reference/v1/definitions.html @@ -6380,7 +6380,14 @@ Examples:

terminationMessagePath

-

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.

+

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

+

false

+

string

+ + + +

terminationMessagePolicy

+

Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

false

string

@@ -9187,7 +9194,7 @@ Examples:
diff --git a/federation/apis/openapi-spec/swagger.json b/federation/apis/openapi-spec/swagger.json index beb7516ddf..1c0d8ca0f5 100644 --- a/federation/apis/openapi-spec/swagger.json +++ b/federation/apis/openapi-spec/swagger.json @@ -10895,7 +10895,11 @@ "type": "boolean" }, "terminationMessagePath": { - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.", + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "type": "string" + }, + "terminationMessagePolicy": { + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", "type": "string" }, "tty": { diff --git a/federation/apis/swagger-spec/extensions_v1beta1.json b/federation/apis/swagger-spec/extensions_v1beta1.json index e9bb1abc2d..bde311d12d 100644 --- a/federation/apis/swagger-spec/extensions_v1beta1.json +++ b/federation/apis/swagger-spec/extensions_v1beta1.json @@ -5474,7 +5474,11 @@ }, "terminationMessagePath": { "type": "string", - "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated." + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated." + }, + "terminationMessagePolicy": { + "type": "string", + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated." }, "imagePullPolicy": { "type": "string", diff --git a/federation/docs/api-reference/extensions/v1beta1/definitions.html b/federation/docs/api-reference/extensions/v1beta1/definitions.html index c15cf0274b..821137d7a8 100755 --- a/federation/docs/api-reference/extensions/v1beta1/definitions.html +++ b/federation/docs/api-reference/extensions/v1beta1/definitions.html @@ -4923,7 +4923,14 @@ Both these may change in the future. Incoming requests are matched against the h

terminationMessagePath

-

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.

+

Optional: Path at which the file to which the container’s termination message will be written is mounted into the container’s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.

+

false

+

string

+ + + +

terminationMessagePolicy

+

Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.

false

string

@@ -6263,7 +6270,7 @@ Both these may change in the future. Incoming requests are matched against the h diff --git a/hack/.linted_packages b/hack/.linted_packages index cecfd019d3..a1d4546aaa 100644 --- a/hack/.linted_packages +++ b/hack/.linted_packages @@ -289,6 +289,7 @@ pkg/util/replicaset pkg/util/restoptions pkg/util/runtime pkg/util/sets +pkg/util/tail pkg/util/validation pkg/util/validation/field pkg/util/version diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index 133dc97994..c9af9a2ac9 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -358,6 +358,7 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz func(ct *api.Container, c fuzz.Continue) { c.FuzzNoCustom(ct) // fuzz self without calling this function again ct.TerminationMessagePath = "/" + ct.TerminationMessagePath // Must be non-empty + ct.TerminationMessagePolicy = "File" }, func(p *api.Probe, c fuzz.Continue) { c.FuzzNoCustom(p) diff --git a/pkg/api/types.go b/pkg/api/types.go index 1d4a8f70c7..bb7074b932 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -1257,6 +1257,19 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// TerminationMessagePolicy describes how termination messages are retrieved from a container. +type TerminationMessagePolicy string + +const ( + // TerminationMessageReadFile is the default behavior and will set the container status message to + // the contents of the container's terminationMessagePath when the container exits. + TerminationMessageReadFile TerminationMessagePolicy = "File" + // TerminationMessageFallbackToLogsOnError will read the most recent contents of the container logs + // for the container status message when the container exits with an error and the + // terminationMessagePath has no contents. + TerminationMessageFallbackToLogsOnError TerminationMessagePolicy = "FallbackToLogsOnError" +) + // Capability represent POSIX capabilities type type Capability string @@ -1332,6 +1345,8 @@ type Container struct { // Required. // +optional TerminationMessagePath string + // +optional + TerminationMessagePolicy TerminationMessagePolicy // Required: Policy for pulling images for this container ImagePullPolicy PullPolicy // Optional: SecurityContext defines the security options the container should be run with. diff --git a/pkg/api/v1/defaults.go b/pkg/api/v1/defaults.go index e6de1be9d8..cb14c5e418 100644 --- a/pkg/api/v1/defaults.go +++ b/pkg/api/v1/defaults.go @@ -121,6 +121,9 @@ func SetDefaults_Container(obj *Container) { if obj.TerminationMessagePath == "" { obj.TerminationMessagePath = TerminationMessagePathDefault } + if obj.TerminationMessagePolicy == "" { + obj.TerminationMessagePolicy = TerminationMessageReadFile + } } func SetDefaults_ServiceSpec(obj *ServiceSpec) { if obj.SessionAffinity == "" { diff --git a/pkg/api/v1/generated.pb.go b/pkg/api/v1/generated.pb.go index bc0c1194eb..eb2219801f 100644 --- a/pkg/api/v1/generated.pb.go +++ b/pkg/api/v1/generated.pb.go @@ -1935,6 +1935,12 @@ func (m *Container) MarshalTo(data []byte) (int, error) { i += n } } + data[i] = 0xa2 + i++ + data[i] = 0x1 + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.TerminationMessagePolicy))) + i += copy(data[i:], m.TerminationMessagePolicy) return i, nil } @@ -8733,6 +8739,8 @@ func (m *Container) Size() (n int) { n += 2 + l + sovGenerated(uint64(l)) } } + l = len(m.TerminationMessagePolicy) + n += 2 + l + sovGenerated(uint64(l)) return n } @@ -11383,6 +11391,7 @@ func (this *Container) String() string { `StdinOnce:` + fmt.Sprintf("%v", this.StdinOnce) + `,`, `TTY:` + fmt.Sprintf("%v", this.TTY) + `,`, `EnvFrom:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.EnvFrom), "EnvFromSource", "EnvFromSource", 1), `&`, ``, 1) + `,`, + `TerminationMessagePolicy:` + fmt.Sprintf("%v", this.TerminationMessagePolicy) + `,`, `}`, }, "") return s @@ -16355,6 +16364,35 @@ func (m *Container) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminationMessagePolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TerminationMessagePolicy = TerminationMessagePolicy(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(data[iNdEx:]) @@ -39924,646 +39962,647 @@ var ( ) var fileDescriptorGenerated = []byte{ - // 10242 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x24, 0xc7, - 0x75, 0x98, 0x66, 0x17, 0x5f, 0xfb, 0xf0, 0x79, 0x7d, 0x1f, 0x04, 0x21, 0xf2, 0x70, 0x1c, 0x8a, - 0xd4, 0x91, 0x3c, 0x02, 0xba, 0x23, 0x29, 0x9e, 0x44, 0x85, 0x12, 0x80, 0x05, 0xee, 0xa0, 0x3b, - 0xdc, 0x2d, 0x7b, 0x71, 0x77, 0x94, 0xc4, 0x88, 0x1c, 0xec, 0x34, 0x80, 0xe1, 0xcd, 0xce, 0x2c, - 0x67, 0x66, 0x71, 0x07, 0x2a, 0xaa, 0xb2, 0x65, 0x96, 0x5d, 0xa9, 0x28, 0x89, 0x52, 0x2e, 0x55, - 0xb9, 0xe2, 0xa4, 0xec, 0xa4, 0xca, 0x29, 0x25, 0xae, 0x7c, 0x28, 0x8a, 0x2d, 0xb9, 0xac, 0x24, - 0x95, 0xc4, 0x56, 0xe4, 0x7c, 0xb8, 0x94, 0x72, 0x55, 0xec, 0x58, 0x55, 0x88, 0x09, 0xa7, 0xf2, - 0x33, 0x3f, 0x92, 0x7f, 0x97, 0x54, 0x92, 0xea, 0xcf, 0xe9, 0x9e, 0xdd, 0xc5, 0xcc, 0x82, 0x07, - 0x88, 0x72, 0xf9, 0xdf, 0xee, 0x7b, 0xaf, 0x5f, 0x7f, 0x4c, 0xf7, 0xeb, 0xf7, 0x5e, 0xbf, 0x7e, - 0x0d, 0x17, 0xee, 0x5e, 0x8e, 0xe7, 0xbc, 0x70, 0xfe, 0x6e, 0x7b, 0x83, 0x44, 0x01, 0x49, 0x48, - 0x3c, 0xdf, 0xba, 0xbb, 0x35, 0xef, 0xb4, 0xbc, 0xf9, 0x9d, 0x8b, 0xf3, 0x5b, 0x24, 0x20, 0x91, - 0x93, 0x10, 0x77, 0xae, 0x15, 0x85, 0x49, 0x88, 0x1e, 0xe3, 0xd4, 0x73, 0x29, 0xf5, 0x5c, 0xeb, - 0xee, 0xd6, 0x9c, 0xd3, 0xf2, 0xe6, 0x76, 0x2e, 0xce, 0x3c, 0xbf, 0xe5, 0x25, 0xdb, 0xed, 0x8d, - 0xb9, 0x46, 0xd8, 0x9c, 0xdf, 0x0a, 0xb7, 0xc2, 0x79, 0x56, 0x68, 0xa3, 0xbd, 0xc9, 0xfe, 0xb1, - 0x3f, 0xec, 0x17, 0x67, 0x36, 0xf3, 0xa2, 0xa8, 0xda, 0x69, 0x79, 0x4d, 0xa7, 0xb1, 0xed, 0x05, - 0x24, 0xda, 0x95, 0x95, 0xc7, 0xf3, 0x4d, 0x92, 0x38, 0x5d, 0x9a, 0x30, 0x33, 0xdf, 0xab, 0x54, - 0xd4, 0x0e, 0x12, 0xaf, 0x49, 0x3a, 0x0a, 0x7c, 0x32, 0xaf, 0x40, 0xdc, 0xd8, 0x26, 0x4d, 0xa7, - 0xa3, 0xdc, 0xa5, 0xde, 0x23, 0x13, 0x91, 0x38, 0x6c, 0x47, 0x8d, 0xce, 0xba, 0x2e, 0x76, 0x2f, - 0xd3, 0x4e, 0x3c, 0x7f, 0xde, 0x0b, 0x92, 0x38, 0x89, 0xb2, 0x45, 0xec, 0x3f, 0xb4, 0xe0, 0xdc, - 0xc2, 0x9d, 0xfa, 0xb2, 0xef, 0xc4, 0x89, 0xd7, 0x58, 0xf4, 0xc3, 0xc6, 0xdd, 0x7a, 0x12, 0x46, - 0xe4, 0x76, 0xe8, 0xb7, 0x9b, 0xa4, 0xce, 0xea, 0x41, 0x17, 0x60, 0x64, 0x87, 0xfd, 0x5f, 0xad, - 0x4e, 0x5b, 0xe7, 0xac, 0xf3, 0x95, 0xc5, 0xa9, 0x1f, 0xee, 0xcd, 0x7e, 0x64, 0x7f, 0x6f, 0x76, - 0xe4, 0xb6, 0x80, 0x63, 0x45, 0x81, 0x9e, 0x86, 0xa1, 0xcd, 0x78, 0x7d, 0xb7, 0x45, 0xa6, 0x4b, - 0x8c, 0x76, 0x42, 0xd0, 0x0e, 0xad, 0xd4, 0x29, 0x14, 0x0b, 0x2c, 0x9a, 0x87, 0x4a, 0xcb, 0x89, - 0x12, 0x2f, 0xf1, 0xc2, 0x60, 0xba, 0x7c, 0xce, 0x3a, 0x3f, 0xb8, 0x78, 0x42, 0x90, 0x56, 0x6a, - 0x12, 0x81, 0x53, 0x1a, 0xda, 0x8c, 0x88, 0x38, 0xee, 0xcd, 0xc0, 0xdf, 0x9d, 0x1e, 0x38, 0x67, - 0x9d, 0x1f, 0x49, 0x9b, 0x81, 0x05, 0x1c, 0x2b, 0x0a, 0xfb, 0x7b, 0x25, 0x18, 0x59, 0xd8, 0xdc, - 0xf4, 0x02, 0x2f, 0xd9, 0x45, 0x6f, 0xc1, 0x58, 0x10, 0xba, 0x44, 0xfe, 0x67, 0xbd, 0x18, 0xbd, - 0xf4, 0xec, 0xdc, 0x41, 0x13, 0x6a, 0xee, 0x86, 0x56, 0x62, 0x71, 0x6a, 0x7f, 0x6f, 0x76, 0x4c, - 0x87, 0x60, 0x83, 0x23, 0x7a, 0x03, 0x46, 0x5b, 0xa1, 0xab, 0x2a, 0x28, 0xb1, 0x0a, 0x9e, 0x39, - 0xb8, 0x82, 0x5a, 0x5a, 0x60, 0x71, 0x72, 0x7f, 0x6f, 0x76, 0x54, 0x03, 0x60, 0x9d, 0x1d, 0xf2, - 0x61, 0x92, 0xfe, 0x0d, 0x12, 0x4f, 0xd5, 0x50, 0x66, 0x35, 0x3c, 0x9f, 0x5f, 0x83, 0x56, 0x68, - 0xf1, 0xe4, 0xfe, 0xde, 0xec, 0x64, 0x06, 0x88, 0xb3, 0xac, 0xed, 0x77, 0x61, 0x62, 0x21, 0x49, - 0x9c, 0xc6, 0x36, 0x71, 0xf9, 0xf7, 0x45, 0x2f, 0xc2, 0x40, 0xe0, 0x34, 0x89, 0xf8, 0xfa, 0xe7, - 0xc4, 0xb0, 0x0f, 0xdc, 0x70, 0x9a, 0xe4, 0xc1, 0xde, 0xec, 0xd4, 0xad, 0xc0, 0x7b, 0xa7, 0x2d, - 0xe6, 0x0c, 0x85, 0x61, 0x46, 0x8d, 0x2e, 0x01, 0xb8, 0x64, 0xc7, 0x6b, 0x90, 0x9a, 0x93, 0x6c, - 0x8b, 0xd9, 0x80, 0x44, 0x59, 0xa8, 0x2a, 0x0c, 0xd6, 0xa8, 0xec, 0xaf, 0x59, 0x50, 0x59, 0xd8, - 0x09, 0x3d, 0xb7, 0x16, 0xba, 0x31, 0x6a, 0xc3, 0x64, 0x2b, 0x22, 0x9b, 0x24, 0x52, 0xa0, 0x69, - 0xeb, 0x5c, 0xf9, 0xfc, 0xe8, 0xa5, 0x4b, 0x39, 0xfd, 0x36, 0x0b, 0x2d, 0x07, 0x49, 0xb4, 0xbb, - 0xf8, 0x88, 0xa8, 0x7a, 0x32, 0x83, 0xc5, 0xd9, 0x3a, 0xec, 0xbf, 0x51, 0x82, 0xd3, 0x0b, 0xef, - 0xb6, 0x23, 0x52, 0xf5, 0xe2, 0xbb, 0xd9, 0xa5, 0xe0, 0x7a, 0xf1, 0xdd, 0x1b, 0xe9, 0x60, 0xa8, - 0x39, 0x58, 0x15, 0x70, 0xac, 0x28, 0xd0, 0xf3, 0x30, 0x4c, 0x7f, 0xdf, 0xc2, 0xab, 0xa2, 0xf7, - 0x27, 0x05, 0xf1, 0x68, 0xd5, 0x49, 0x9c, 0x2a, 0x47, 0x61, 0x49, 0x83, 0xd6, 0x60, 0xb4, 0xc1, - 0x64, 0xc4, 0xd6, 0x5a, 0xe8, 0x12, 0xf6, 0x85, 0x2b, 0x8b, 0xcf, 0x51, 0xf2, 0xa5, 0x14, 0xfc, - 0x60, 0x6f, 0x76, 0x9a, 0xb7, 0x4d, 0xb0, 0xd0, 0x70, 0x58, 0x2f, 0x8f, 0x6c, 0xb5, 0x10, 0x07, - 0x18, 0x27, 0xe8, 0xb2, 0x08, 0xcf, 0x6b, 0x6b, 0x6a, 0x90, 0xad, 0xa9, 0xb1, 0x1e, 0xeb, 0xe9, - 0x1f, 0x58, 0x62, 0x4c, 0x56, 0x3c, 0xdf, 0x14, 0x0f, 0x97, 0x00, 0x62, 0xd2, 0x88, 0x48, 0xa2, - 0x8d, 0x8a, 0xfa, 0xcc, 0x75, 0x85, 0xc1, 0x1a, 0x15, 0x5d, 0xfc, 0xf1, 0xb6, 0x13, 0xb1, 0xd9, - 0x22, 0xc6, 0x46, 0x2d, 0xfe, 0xba, 0x44, 0xe0, 0x94, 0xc6, 0x58, 0xfc, 0xe5, 0xdc, 0xc5, 0xff, - 0xaf, 0x2d, 0x18, 0x5e, 0xf4, 0x02, 0xd7, 0x0b, 0xb6, 0xd0, 0x5b, 0x30, 0x42, 0xa5, 0xb9, 0xeb, - 0x24, 0x8e, 0x58, 0xf7, 0x9f, 0x90, 0x93, 0x47, 0x17, 0xca, 0x72, 0xfa, 0xc4, 0x73, 0x94, 0x9a, - 0x4e, 0xa2, 0x9b, 0x1b, 0x6f, 0x93, 0x46, 0xb2, 0x46, 0x12, 0x27, 0xed, 0x4e, 0x0a, 0xc3, 0x8a, - 0x2b, 0xba, 0x05, 0x43, 0x89, 0x13, 0x6d, 0x91, 0x44, 0x2c, 0xfb, 0x9c, 0x45, 0xc9, 0x79, 0x60, - 0x3a, 0xe5, 0x48, 0xd0, 0x20, 0xa9, 0x80, 0x5c, 0x67, 0x4c, 0xb0, 0x60, 0x66, 0x37, 0x60, 0x6c, - 0xc9, 0x69, 0x39, 0x1b, 0x9e, 0xef, 0x25, 0x1e, 0x89, 0xd1, 0xc7, 0xa1, 0xec, 0xb8, 0x2e, 0x5b, - 0x00, 0x95, 0xc5, 0xd3, 0xfb, 0x7b, 0xb3, 0xe5, 0x05, 0xd7, 0x7d, 0xb0, 0x37, 0x0b, 0x8a, 0x6a, - 0x17, 0x53, 0x0a, 0xf4, 0x2c, 0x0c, 0xb8, 0x51, 0xd8, 0x9a, 0x2e, 0x31, 0xca, 0x33, 0x74, 0xa5, - 0x56, 0xa3, 0xb0, 0x95, 0x21, 0x65, 0x34, 0xf6, 0xef, 0x96, 0x00, 0x2d, 0x91, 0xd6, 0xf6, 0x4a, - 0xdd, 0xf8, 0xa6, 0xe7, 0x61, 0xa4, 0x19, 0x06, 0x5e, 0x12, 0x46, 0xb1, 0xa8, 0x90, 0xcd, 0x8b, - 0x35, 0x01, 0xc3, 0x0a, 0x8b, 0xce, 0xc1, 0x40, 0x2b, 0x5d, 0xde, 0x63, 0x52, 0x34, 0xb0, 0x85, - 0xcd, 0x30, 0x94, 0xa2, 0x1d, 0x93, 0x48, 0xcc, 0x67, 0x45, 0x71, 0x2b, 0x26, 0x11, 0x66, 0x98, - 0x74, 0x06, 0xd1, 0xb9, 0x25, 0x66, 0x6b, 0x66, 0x06, 0x51, 0x0c, 0xd6, 0xa8, 0xd0, 0x9b, 0x50, - 0xe1, 0xff, 0x30, 0xd9, 0x64, 0x53, 0x37, 0x57, 0x28, 0x5c, 0x0f, 0x1b, 0x8e, 0x9f, 0x1d, 0xfc, - 0x71, 0x36, 0xe3, 0x24, 0x23, 0x9c, 0xf2, 0x34, 0x66, 0xdc, 0x50, 0xee, 0x8c, 0xfb, 0x25, 0x0b, - 0xd0, 0x92, 0x17, 0xb8, 0x24, 0x3a, 0x86, 0xad, 0xb3, 0xbf, 0xc5, 0xf0, 0x63, 0xda, 0xb4, 0xb0, - 0xd9, 0x0a, 0x03, 0x12, 0x24, 0x4b, 0x61, 0xe0, 0xf2, 0xed, 0xf4, 0xd3, 0x30, 0x90, 0xd0, 0xaa, - 0x78, 0xb3, 0x9e, 0x96, 0x9f, 0x85, 0x56, 0xf0, 0x60, 0x6f, 0xf6, 0x4c, 0x67, 0x09, 0xd6, 0x04, - 0x56, 0x06, 0x7d, 0x0a, 0x86, 0xe2, 0xc4, 0x49, 0xda, 0xb1, 0x68, 0xe8, 0x13, 0xb2, 0xa1, 0x75, - 0x06, 0x7d, 0xb0, 0x37, 0x3b, 0xa9, 0x8a, 0x71, 0x10, 0x16, 0x05, 0xd0, 0x33, 0x30, 0xdc, 0x24, - 0x71, 0xec, 0x6c, 0x49, 0x01, 0x37, 0x29, 0xca, 0x0e, 0xaf, 0x71, 0x30, 0x96, 0x78, 0xf4, 0x24, - 0x0c, 0x92, 0x28, 0x0a, 0x23, 0x31, 0x23, 0xc6, 0x05, 0xe1, 0xe0, 0x32, 0x05, 0x62, 0x8e, 0xb3, - 0xff, 0x8b, 0x05, 0x93, 0xaa, 0xad, 0xbc, 0xae, 0x63, 0x58, 0xf2, 0x2e, 0x40, 0x43, 0x76, 0x30, - 0x66, 0x0b, 0x4d, 0xab, 0xa3, 0xfb, 0xf4, 0xeb, 0x1c, 0xd0, 0xb4, 0x0e, 0x05, 0x8a, 0xb1, 0xc6, - 0xd7, 0xfe, 0xb7, 0x16, 0x9c, 0xcc, 0xf4, 0xed, 0xba, 0x17, 0x27, 0xe8, 0x8d, 0x8e, 0xfe, 0xcd, - 0x15, 0xeb, 0x1f, 0x2d, 0xcd, 0x7a, 0xa7, 0xe6, 0x8b, 0x84, 0x68, 0x7d, 0xc3, 0x30, 0xe8, 0x25, - 0xa4, 0x29, 0xbb, 0xf5, 0x7c, 0xc1, 0x6e, 0xf1, 0xf6, 0xa5, 0x5f, 0x69, 0x95, 0xf2, 0xc0, 0x9c, - 0x95, 0xfd, 0xbf, 0x2d, 0xa8, 0x2c, 0x85, 0xc1, 0xa6, 0xb7, 0xb5, 0xe6, 0xb4, 0x8e, 0xe1, 0xfb, - 0xd4, 0x61, 0x80, 0x71, 0xe7, 0x5d, 0xb8, 0x98, 0xd7, 0x05, 0xd1, 0xb0, 0x39, 0xba, 0xa7, 0x72, - 0x65, 0x41, 0x89, 0x29, 0x0a, 0xc2, 0x8c, 0xd9, 0xcc, 0xcb, 0x50, 0x51, 0x04, 0x68, 0x0a, 0xca, - 0x77, 0x09, 0xd7, 0x24, 0x2b, 0x98, 0xfe, 0x44, 0xa7, 0x60, 0x70, 0xc7, 0xf1, 0xdb, 0x62, 0xf1, - 0x62, 0xfe, 0xe7, 0xd3, 0xa5, 0xcb, 0x96, 0xfd, 0xcb, 0x6c, 0x05, 0x8a, 0x4a, 0x96, 0x83, 0x1d, - 0x21, 0x1c, 0xde, 0xb3, 0xe0, 0x94, 0xdf, 0x45, 0x28, 0x89, 0x31, 0x39, 0x8c, 0x38, 0x7b, 0x4c, - 0x34, 0xfb, 0x54, 0x37, 0x2c, 0xee, 0x5a, 0x9b, 0xfd, 0x7d, 0x0b, 0x4e, 0xa9, 0xd6, 0x5d, 0x23, - 0xbb, 0x75, 0xe2, 0x93, 0x46, 0x12, 0x46, 0x1f, 0x92, 0xf6, 0xa1, 0xc7, 0xf9, 0x48, 0x73, 0x49, - 0x33, 0x2a, 0x18, 0x94, 0xaf, 0x91, 0x5d, 0x36, 0xec, 0xf6, 0x6f, 0x5b, 0x30, 0xae, 0x9a, 0x7f, - 0x0c, 0xcb, 0xe3, 0xba, 0xb9, 0x3c, 0x3e, 0x5e, 0x70, 0x6e, 0xf5, 0x58, 0x18, 0xbf, 0x52, 0x82, - 0xd3, 0x8a, 0xc6, 0xd8, 0x3a, 0x3e, 0x24, 0xa3, 0xdf, 0x5f, 0x77, 0xaf, 0x91, 0xdd, 0xf5, 0x90, - 0xee, 0xfd, 0xdd, 0xbb, 0x8b, 0x2e, 0xc2, 0xa8, 0x4b, 0x36, 0x9d, 0xb6, 0x9f, 0x28, 0x15, 0x77, - 0x90, 0xdb, 0x3e, 0xd5, 0x14, 0x8c, 0x75, 0x1a, 0xfb, 0xd7, 0x80, 0x89, 0x8e, 0xc4, 0xa1, 0x1f, - 0x8d, 0x2a, 0x13, 0x9a, 0x25, 0x32, 0xa6, 0x5b, 0x22, 0xc2, 0xea, 0x78, 0x12, 0x06, 0xbd, 0x26, - 0xdd, 0x5e, 0x4a, 0xe6, 0xae, 0xb1, 0x4a, 0x81, 0x98, 0xe3, 0xd0, 0x53, 0x30, 0xdc, 0x08, 0x9b, - 0x4d, 0x27, 0x70, 0xa7, 0xcb, 0x4c, 0xbd, 0x19, 0xa5, 0x3b, 0xd0, 0x12, 0x07, 0x61, 0x89, 0x43, - 0x8f, 0xc1, 0x80, 0x13, 0x6d, 0xc5, 0xd3, 0x03, 0x8c, 0x66, 0x84, 0xd6, 0xb4, 0x10, 0x6d, 0xc5, - 0x98, 0x41, 0xa9, 0xda, 0x72, 0x2f, 0x8c, 0xee, 0x7a, 0xc1, 0x56, 0xd5, 0x8b, 0x98, 0x0e, 0xa2, - 0xa9, 0x2d, 0x77, 0x14, 0x06, 0x6b, 0x54, 0xa8, 0x06, 0x83, 0xad, 0x30, 0x4a, 0xe2, 0xe9, 0x21, - 0x36, 0x9c, 0xcf, 0xe5, 0xce, 0x1e, 0xde, 0xef, 0x5a, 0x18, 0x25, 0x69, 0x57, 0xe8, 0xbf, 0x18, - 0x73, 0x46, 0x68, 0x09, 0xca, 0x24, 0xd8, 0x99, 0x1e, 0x66, 0xfc, 0x3e, 0x76, 0x30, 0xbf, 0xe5, - 0x60, 0xe7, 0xb6, 0x13, 0xa5, 0x8b, 0x68, 0x39, 0xd8, 0xc1, 0xb4, 0x34, 0x6a, 0x40, 0x45, 0xba, - 0x15, 0xe2, 0xe9, 0x91, 0x22, 0x13, 0x0c, 0x0b, 0x72, 0x4c, 0xde, 0x69, 0x7b, 0x11, 0x69, 0x92, - 0x20, 0x89, 0x53, 0x1d, 0x5e, 0x62, 0x63, 0x9c, 0xf2, 0x45, 0x0d, 0x18, 0xe3, 0xaa, 0xce, 0x5a, - 0xd8, 0x0e, 0x92, 0x78, 0xba, 0xc2, 0x9a, 0x9c, 0x63, 0x24, 0xdf, 0x4e, 0x4b, 0x2c, 0x9e, 0x12, - 0xec, 0xc7, 0x34, 0x60, 0x8c, 0x0d, 0xa6, 0xe8, 0x0d, 0x18, 0xf7, 0xbd, 0x1d, 0x12, 0x90, 0x38, - 0xae, 0x45, 0xe1, 0x06, 0x99, 0x06, 0xd6, 0x9b, 0x27, 0xf3, 0x0c, 0xc6, 0x70, 0x83, 0x2c, 0x9e, - 0xd8, 0xdf, 0x9b, 0x1d, 0xbf, 0xae, 0x97, 0xc6, 0x26, 0x33, 0xf4, 0x26, 0x4c, 0x50, 0xbd, 0xca, - 0x4b, 0xd9, 0x8f, 0x16, 0x67, 0x8f, 0xf6, 0xf7, 0x66, 0x27, 0xb0, 0x51, 0x1c, 0x67, 0xd8, 0xa1, - 0x75, 0xa8, 0xf8, 0xde, 0x26, 0x69, 0xec, 0x36, 0x7c, 0x32, 0x3d, 0xc6, 0x78, 0xe7, 0x2c, 0xb9, - 0xeb, 0x92, 0x9c, 0xeb, 0xb2, 0xea, 0x2f, 0x4e, 0x19, 0xa1, 0xdb, 0x70, 0x26, 0x21, 0x51, 0xd3, - 0x0b, 0x1c, 0xaa, 0x58, 0x08, 0x45, 0x8b, 0x59, 0xe5, 0xe3, 0x6c, 0xd6, 0x9e, 0x15, 0x03, 0x7b, - 0x66, 0xbd, 0x2b, 0x15, 0xee, 0x51, 0x1a, 0xdd, 0x84, 0x49, 0xb6, 0x9e, 0x6a, 0x6d, 0xdf, 0xaf, - 0x85, 0xbe, 0xd7, 0xd8, 0x9d, 0x9e, 0x60, 0x0c, 0x9f, 0x92, 0xb6, 0xf6, 0xaa, 0x89, 0xa6, 0x36, - 0x48, 0xfa, 0x0f, 0x67, 0x4b, 0x23, 0x1f, 0x26, 0x63, 0xd2, 0x68, 0x47, 0x5e, 0xb2, 0x4b, 0xe7, - 0x3e, 0xb9, 0x9f, 0x4c, 0x4f, 0x16, 0xb1, 0xa9, 0xea, 0x66, 0x21, 0xee, 0xe8, 0xc8, 0x00, 0x71, - 0x96, 0x35, 0x15, 0x15, 0x71, 0xe2, 0x7a, 0xc1, 0xf4, 0x14, 0x53, 0xa2, 0xd5, 0xfa, 0xaa, 0x53, - 0x20, 0xe6, 0x38, 0x66, 0xaa, 0xd2, 0x1f, 0x37, 0xa9, 0xec, 0x3d, 0xc1, 0x08, 0x53, 0x53, 0x55, - 0x22, 0x70, 0x4a, 0x43, 0xf7, 0xab, 0x24, 0xd9, 0x9d, 0x46, 0x8c, 0x54, 0x2d, 0xb5, 0xf5, 0xf5, - 0x2f, 0x60, 0x0a, 0x47, 0xb7, 0x61, 0x98, 0x04, 0x3b, 0x2b, 0x51, 0xd8, 0x9c, 0x3e, 0x59, 0x44, - 0x06, 0x2c, 0x73, 0x62, 0xbe, 0x2b, 0xa4, 0xda, 0xb2, 0x00, 0x63, 0xc9, 0xcc, 0xde, 0x80, 0x09, - 0x25, 0x2e, 0xd8, 0xa8, 0xa3, 0x59, 0x18, 0xa4, 0x12, 0x51, 0x5a, 0x70, 0x15, 0xda, 0x35, 0x2a, - 0x28, 0x63, 0xcc, 0xe1, 0xac, 0x6b, 0xde, 0xbb, 0x64, 0x71, 0x37, 0x21, 0x5c, 0x93, 0x2f, 0x6b, - 0x5d, 0x93, 0x08, 0x9c, 0xd2, 0xd8, 0xff, 0x97, 0xef, 0xb5, 0xa9, 0x4c, 0x2a, 0x20, 0x8f, 0x2f, - 0xc0, 0xc8, 0x76, 0x18, 0x27, 0x94, 0x9a, 0xd5, 0x31, 0x98, 0xee, 0xae, 0x57, 0x05, 0x1c, 0x2b, - 0x0a, 0xf4, 0x0a, 0x8c, 0x37, 0xf4, 0x0a, 0xc4, 0x16, 0x71, 0x5a, 0x14, 0x31, 0x6b, 0xc7, 0x26, - 0x2d, 0xba, 0x0c, 0x23, 0xcc, 0xad, 0xd9, 0x08, 0x7d, 0x61, 0x33, 0xc8, 0x1d, 0x6f, 0xa4, 0x26, - 0xe0, 0x0f, 0xb4, 0xdf, 0x58, 0x51, 0x53, 0xcb, 0x8b, 0x36, 0x61, 0xb5, 0x26, 0xc4, 0xb8, 0xb2, - 0xbc, 0xae, 0x32, 0x28, 0x16, 0x58, 0xfb, 0x9f, 0x94, 0xb4, 0x51, 0xa6, 0x1a, 0x2f, 0x41, 0x5f, - 0x84, 0xe1, 0x7b, 0x8e, 0x97, 0x78, 0xc1, 0x96, 0xd8, 0x99, 0x5f, 0x28, 0x28, 0xd3, 0x59, 0xf1, - 0x3b, 0xbc, 0x28, 0xdf, 0x7f, 0xc4, 0x1f, 0x2c, 0x19, 0x52, 0xde, 0x51, 0x3b, 0x08, 0x28, 0xef, - 0x52, 0xff, 0xbc, 0x31, 0x2f, 0xca, 0x79, 0x8b, 0x3f, 0x58, 0x32, 0x44, 0x9b, 0x00, 0x72, 0x55, - 0x13, 0x57, 0xb8, 0x13, 0x3f, 0xd9, 0x0f, 0xfb, 0x75, 0x55, 0x7a, 0x71, 0x82, 0xee, 0x78, 0xe9, - 0x7f, 0xac, 0x71, 0xb6, 0x13, 0xa6, 0xe0, 0x74, 0x36, 0x0b, 0x7d, 0x89, 0x2e, 0x2c, 0x27, 0x4a, - 0x88, 0xbb, 0x90, 0x64, 0x3d, 0xb2, 0x07, 0xeb, 0x69, 0xeb, 0x5e, 0x93, 0xe8, 0x8b, 0x50, 0x30, - 0xc1, 0x29, 0x3f, 0xfb, 0xbb, 0x65, 0x98, 0xee, 0xd5, 0x5c, 0x3a, 0x25, 0xc9, 0x7d, 0x2f, 0x59, - 0xa2, 0x2a, 0x88, 0x65, 0x4e, 0xc9, 0x65, 0x01, 0xc7, 0x8a, 0x82, 0xce, 0x8d, 0xd8, 0xdb, 0x0a, - 0x1c, 0x5f, 0x4c, 0x5f, 0x35, 0x37, 0xea, 0x0c, 0x8a, 0x05, 0x96, 0xd2, 0x45, 0xc4, 0x89, 0x85, - 0x37, 0x5b, 0x9b, 0x43, 0x98, 0x41, 0xb1, 0xc0, 0xea, 0x16, 0xf0, 0x40, 0x8e, 0x05, 0x6c, 0x0c, - 0xd1, 0xe0, 0xc3, 0x1d, 0x22, 0xf4, 0x65, 0x80, 0x4d, 0x2f, 0xf0, 0xe2, 0x6d, 0xc6, 0x7d, 0xa8, - 0x6f, 0xee, 0x4a, 0xd5, 0x59, 0x51, 0x5c, 0xb0, 0xc6, 0x11, 0xbd, 0x04, 0xa3, 0x6a, 0x79, 0xae, - 0x56, 0xa7, 0x87, 0x4d, 0x0f, 0x68, 0x2a, 0xab, 0xaa, 0x58, 0xa7, 0xb3, 0xdf, 0xce, 0xce, 0x17, - 0xb1, 0x2a, 0xb4, 0xf1, 0xb5, 0x8a, 0x8e, 0x6f, 0xe9, 0xe0, 0xf1, 0xb5, 0xff, 0x73, 0x19, 0x26, - 0x8d, 0xca, 0xda, 0x71, 0x01, 0x89, 0xf6, 0x1a, 0xdd, 0x36, 0x9c, 0x84, 0x88, 0x35, 0x79, 0xa1, - 0x9f, 0x45, 0xa3, 0x6f, 0x32, 0x74, 0x2d, 0x70, 0x4e, 0x68, 0x1b, 0x2a, 0xbe, 0x13, 0x33, 0x1b, - 0x9a, 0x88, 0xb5, 0xd8, 0x1f, 0xdb, 0x54, 0xb5, 0x77, 0xe2, 0x44, 0xdb, 0xc5, 0x79, 0x2d, 0x29, - 0x73, 0xba, 0xe7, 0x51, 0x95, 0x43, 0x1e, 0xa1, 0xa8, 0xe6, 0x50, 0xbd, 0x64, 0x17, 0x73, 0x1c, - 0xba, 0x0c, 0x63, 0x11, 0x61, 0x33, 0x65, 0x89, 0x6a, 0x55, 0x6c, 0xea, 0x0d, 0xa6, 0xea, 0x17, - 0xd6, 0x70, 0xd8, 0xa0, 0x4c, 0xb5, 0xef, 0xa1, 0x03, 0xb4, 0xef, 0x67, 0x60, 0x98, 0xfd, 0x50, - 0xb3, 0x42, 0x7d, 0xa1, 0x55, 0x0e, 0xc6, 0x12, 0x9f, 0x9d, 0x44, 0x23, 0x05, 0x27, 0xd1, 0xb3, - 0x30, 0x51, 0x75, 0x48, 0x33, 0x0c, 0x96, 0x03, 0xb7, 0x15, 0x7a, 0x41, 0x82, 0xa6, 0x61, 0x80, - 0xed, 0x27, 0x7c, 0xbd, 0x0f, 0x50, 0x0e, 0x78, 0x80, 0x6a, 0xd0, 0xf6, 0xff, 0xb3, 0x60, 0xbc, - 0x4a, 0x7c, 0x92, 0x90, 0x9b, 0x2d, 0xe6, 0x77, 0x41, 0x2b, 0x80, 0xb6, 0x22, 0xa7, 0x41, 0x6a, - 0x24, 0xf2, 0x42, 0xb7, 0x4e, 0x1a, 0x61, 0xc0, 0x4e, 0x1e, 0xe8, 0x06, 0x79, 0x66, 0x7f, 0x6f, - 0x16, 0x5d, 0xe9, 0xc0, 0xe2, 0x2e, 0x25, 0x90, 0x0b, 0xe3, 0xad, 0x88, 0x18, 0x8e, 0x22, 0x2b, - 0x7f, 0xc3, 0xaf, 0xe9, 0x45, 0xb8, 0x4e, 0x6a, 0x80, 0xb0, 0xc9, 0x14, 0x7d, 0x0e, 0xa6, 0xc2, - 0xa8, 0xb5, 0xed, 0x04, 0x55, 0xd2, 0x22, 0x81, 0x4b, 0x15, 0x71, 0xe1, 0x15, 0x3c, 0xb5, 0xbf, - 0x37, 0x3b, 0x75, 0x33, 0x83, 0xc3, 0x1d, 0xd4, 0xf6, 0xaf, 0x97, 0xe0, 0x74, 0x35, 0xbc, 0x17, - 0xdc, 0x73, 0x22, 0x77, 0xa1, 0xb6, 0xca, 0xb5, 0x6b, 0xe6, 0x65, 0x95, 0xde, 0x5d, 0xab, 0xa7, - 0x77, 0xf7, 0x4b, 0x30, 0xb2, 0xe9, 0x11, 0xdf, 0xc5, 0x64, 0x53, 0x74, 0xef, 0x62, 0x11, 0xf7, - 0xf7, 0x0a, 0x2d, 0x23, 0x3d, 0x0d, 0xdc, 0xb9, 0xbc, 0x22, 0xd8, 0x60, 0xc5, 0x10, 0xb5, 0x61, - 0x4a, 0x9a, 0x0f, 0x12, 0x2b, 0x56, 0xc7, 0x0b, 0xc5, 0xac, 0x13, 0xb3, 0x1a, 0x36, 0x1e, 0x38, - 0xc3, 0x10, 0x77, 0x54, 0x41, 0xcd, 0xbe, 0x26, 0xdd, 0x1b, 0x06, 0xd8, 0x5c, 0x61, 0x66, 0x1f, - 0xb3, 0x4b, 0x19, 0xd4, 0xfe, 0x7b, 0x16, 0x3c, 0xd2, 0x31, 0x5a, 0xc2, 0x68, 0x7f, 0x5d, 0x5a, - 0xcb, 0xfc, 0x98, 0x2a, 0xa7, 0x95, 0x5d, 0xc7, 0xbc, 0x98, 0xe5, 0x5c, 0x2a, 0x60, 0x39, 0xdf, - 0x84, 0x53, 0xcb, 0xcd, 0x56, 0xb2, 0x5b, 0xf5, 0x4c, 0xa7, 0xf4, 0xcb, 0x30, 0xd4, 0x24, 0xae, - 0xd7, 0x6e, 0x8a, 0xcf, 0x3a, 0x2b, 0x05, 0xe9, 0x1a, 0x83, 0x3e, 0xd8, 0x9b, 0x1d, 0xaf, 0x27, - 0x61, 0xe4, 0x6c, 0x11, 0x0e, 0xc0, 0x82, 0xdc, 0x7e, 0xdf, 0x82, 0x49, 0xb9, 0xa0, 0x16, 0x5c, - 0x37, 0x22, 0x71, 0x8c, 0x66, 0xa0, 0xe4, 0xb5, 0x04, 0x23, 0x10, 0x8c, 0x4a, 0xab, 0x35, 0x5c, - 0xf2, 0x5a, 0xe8, 0x8b, 0x50, 0xe1, 0x67, 0x19, 0xe9, 0xe4, 0xe8, 0xf3, 0x6c, 0x84, 0x99, 0x34, - 0xeb, 0x92, 0x07, 0x4e, 0xd9, 0x49, 0xb5, 0x92, 0x89, 0xea, 0xb2, 0xe9, 0x59, 0xbf, 0x2a, 0xe0, - 0x58, 0x51, 0xa0, 0xf3, 0x30, 0x12, 0x84, 0x2e, 0x3f, 0x6e, 0xe2, 0x9b, 0x2e, 0x9b, 0x72, 0x37, - 0x04, 0x0c, 0x2b, 0xac, 0xfd, 0x75, 0x0b, 0xc6, 0x64, 0x1f, 0x0b, 0x6a, 0xb8, 0x74, 0x91, 0xa4, - 0xda, 0x6d, 0xba, 0x48, 0xa8, 0x86, 0xca, 0x30, 0x86, 0x62, 0x5a, 0xee, 0x47, 0x31, 0xb5, 0x7f, - 0xab, 0x04, 0x13, 0xb2, 0x39, 0xf5, 0xf6, 0x46, 0x4c, 0xe8, 0xbe, 0x5d, 0x71, 0xf8, 0xe0, 0x13, - 0x39, 0xcf, 0x9e, 0xcf, 0x33, 0x21, 0x8c, 0x6f, 0x96, 0xea, 0x05, 0x0b, 0x92, 0x0f, 0x4e, 0x59, - 0xa2, 0x1d, 0x38, 0x11, 0x84, 0x09, 0xdb, 0x0f, 0x14, 0xbe, 0x98, 0x2f, 0x38, 0x5b, 0xcf, 0xa3, - 0xa2, 0x9e, 0x13, 0x37, 0xb2, 0xfc, 0x70, 0x67, 0x15, 0xe8, 0xa6, 0x74, 0x8d, 0x94, 0x59, 0x5d, - 0xcf, 0x16, 0xab, 0xab, 0xb7, 0x67, 0xc4, 0xfe, 0x81, 0x05, 0x15, 0x49, 0x76, 0x1c, 0x87, 0x02, - 0x77, 0x60, 0x38, 0x66, 0x9f, 0x48, 0x0e, 0xd7, 0x85, 0x62, 0x5d, 0xe0, 0xdf, 0x35, 0xdd, 0x04, - 0xf9, 0xff, 0x18, 0x4b, 0x6e, 0xcc, 0xc5, 0xa9, 0x3a, 0xf2, 0xa1, 0x73, 0x71, 0xaa, 0x96, 0xf5, - 0xf6, 0xfd, 0x8f, 0x1b, 0x46, 0x2c, 0xd5, 0xe4, 0x5a, 0x11, 0xd9, 0xf4, 0xee, 0x67, 0x35, 0xb9, - 0x1a, 0x83, 0x62, 0x81, 0x45, 0x9b, 0x30, 0xd6, 0x90, 0xbe, 0xd1, 0x54, 0x84, 0x7c, 0xa2, 0xa0, - 0xc7, 0x55, 0x39, 0xda, 0x79, 0xf0, 0xc6, 0x92, 0xc6, 0x09, 0x1b, 0x7c, 0xa9, 0x9c, 0x4a, 0xcf, - 0x12, 0xcb, 0x05, 0xfd, 0x0d, 0x11, 0x49, 0xd2, 0x1a, 0x7a, 0x1e, 0x23, 0xda, 0xdf, 0xb2, 0x60, - 0x88, 0xbb, 0xdd, 0x8a, 0xf9, 0x2e, 0xb5, 0x23, 0x84, 0x74, 0x3c, 0x6f, 0x53, 0xa0, 0x38, 0x51, - 0x40, 0x77, 0xa0, 0xc2, 0x7e, 0x30, 0x17, 0x42, 0xb9, 0x48, 0x24, 0x0b, 0xaf, 0x5f, 0x6f, 0xea, - 0x6d, 0xc9, 0x00, 0xa7, 0xbc, 0xec, 0xef, 0x97, 0xa9, 0xe8, 0x4b, 0x49, 0x8d, 0xbd, 0xdd, 0x3a, - 0x8e, 0xbd, 0xbd, 0x74, 0xf4, 0x7b, 0xfb, 0x3b, 0x30, 0xd9, 0xd0, 0x0e, 0x3b, 0xd2, 0x2f, 0x7e, - 0xa9, 0xe0, 0xb4, 0xd2, 0x4e, 0x48, 0xb8, 0x9b, 0x69, 0xc9, 0x64, 0x87, 0xb3, 0xfc, 0x11, 0x81, - 0x31, 0x3e, 0x1f, 0x44, 0x7d, 0x03, 0xac, 0xbe, 0xf9, 0x22, 0x33, 0x4c, 0xaf, 0x8c, 0xcd, 0xe2, - 0xba, 0xc6, 0x08, 0x1b, 0x6c, 0xed, 0xbf, 0x39, 0x08, 0x83, 0xcb, 0x3b, 0x24, 0x48, 0x8e, 0x41, - 0xd4, 0x35, 0x61, 0xc2, 0x0b, 0x76, 0x42, 0x7f, 0x87, 0xb8, 0x1c, 0x7f, 0xb8, 0xed, 0xfd, 0x8c, - 0xa8, 0x64, 0x62, 0xd5, 0x60, 0x86, 0x33, 0xcc, 0x8f, 0xc2, 0xb4, 0x7e, 0x0d, 0x86, 0xf8, 0xcc, - 0x10, 0x76, 0x75, 0x8e, 0x1b, 0x9a, 0x0d, 0xac, 0x58, 0x41, 0xa9, 0x03, 0x80, 0x7b, 0xc0, 0x05, - 0x23, 0xf4, 0x36, 0x4c, 0x6c, 0x7a, 0x51, 0x9c, 0x50, 0xeb, 0x38, 0x4e, 0x9c, 0x66, 0xeb, 0x10, - 0x46, 0xb5, 0x1a, 0x91, 0x15, 0x83, 0x13, 0xce, 0x70, 0x46, 0x5b, 0x30, 0x4e, 0x6d, 0xba, 0xb4, - 0xaa, 0xe1, 0xbe, 0xab, 0x52, 0x3e, 0xb5, 0xeb, 0x3a, 0x23, 0x6c, 0xf2, 0xa5, 0x22, 0xa9, 0xc1, - 0x6c, 0xc0, 0x11, 0xa6, 0xdd, 0x28, 0x91, 0xc4, 0x8d, 0x3f, 0x8e, 0xa3, 0x92, 0x8d, 0xc5, 0x12, - 0x54, 0x4c, 0xc9, 0x96, 0x46, 0x0c, 0xd8, 0xdf, 0xa1, 0x7b, 0x31, 0x1d, 0xc3, 0x63, 0xd8, 0xbe, - 0xae, 0x9a, 0xdb, 0xd7, 0x93, 0x05, 0xbe, 0x6c, 0x8f, 0xad, 0xeb, 0x2d, 0x18, 0xd5, 0x3e, 0x3c, - 0x9a, 0x87, 0x4a, 0x43, 0x1e, 0x77, 0x0b, 0x29, 0xae, 0x54, 0x29, 0x75, 0x0e, 0x8e, 0x53, 0x1a, - 0x3a, 0x2e, 0x54, 0x05, 0xcd, 0x06, 0xc7, 0x50, 0x05, 0x15, 0x33, 0x8c, 0xfd, 0x02, 0xc0, 0xf2, - 0x7d, 0xd2, 0x58, 0x68, 0xb0, 0x98, 0x0c, 0xed, 0x58, 0xca, 0xea, 0x7d, 0x2c, 0x65, 0x7f, 0xdb, - 0x82, 0x89, 0x95, 0x25, 0x43, 0xa7, 0x9f, 0x03, 0xe0, 0xba, 0xf1, 0x9d, 0x3b, 0x37, 0xa4, 0xc3, - 0x97, 0x7b, 0xe5, 0x14, 0x14, 0x6b, 0x14, 0xe8, 0x51, 0x28, 0xfb, 0xed, 0x40, 0xa8, 0xac, 0xc3, - 0xfb, 0x7b, 0xb3, 0xe5, 0xeb, 0xed, 0x00, 0x53, 0x98, 0x16, 0x85, 0x52, 0x2e, 0x1c, 0x85, 0x92, - 0x1f, 0x8f, 0xf9, 0xcd, 0x32, 0x4c, 0xad, 0xf8, 0xe4, 0xbe, 0xd1, 0xea, 0xa7, 0x61, 0xc8, 0x8d, - 0xbc, 0x1d, 0x12, 0x65, 0x15, 0x81, 0x2a, 0x83, 0x62, 0x81, 0x2d, 0x1c, 0x18, 0xf3, 0x66, 0xe7, - 0x46, 0x7e, 0x74, 0x41, 0x41, 0xb9, 0x7d, 0x46, 0x9b, 0x30, 0x1c, 0x72, 0x97, 0xc2, 0xf4, 0x20, - 0x9b, 0x8a, 0xaf, 0x1c, 0xdc, 0x98, 0xec, 0xf8, 0xcc, 0x09, 0x87, 0x04, 0x0f, 0x49, 0x50, 0xb2, - 0x4c, 0x40, 0xb1, 0x64, 0x3e, 0xf3, 0x69, 0x18, 0xd3, 0x29, 0xfb, 0x8a, 0x4d, 0xf8, 0x39, 0x0b, - 0x4e, 0xae, 0xf8, 0x61, 0xe3, 0x6e, 0x26, 0x72, 0xe9, 0x25, 0x18, 0xa5, 0x8b, 0x29, 0x36, 0xc2, - 0xfa, 0x8c, 0xf8, 0x45, 0x81, 0xc2, 0x3a, 0x9d, 0x56, 0xec, 0xd6, 0xad, 0xd5, 0x6a, 0xb7, 0xb0, - 0x47, 0x81, 0xc2, 0x3a, 0x9d, 0xfd, 0xfb, 0x16, 0x3c, 0x7e, 0x65, 0x69, 0xb9, 0x46, 0xa2, 0xd8, - 0x8b, 0x13, 0x12, 0x24, 0x1d, 0x91, 0x97, 0x54, 0x67, 0x74, 0xb5, 0xa6, 0xa4, 0x3a, 0x63, 0x95, - 0xb5, 0x42, 0x60, 0x3f, 0x2c, 0xe1, 0xc7, 0xdf, 0xb2, 0xe0, 0xe4, 0x15, 0x2f, 0xc1, 0xa4, 0x15, - 0x66, 0x83, 0x25, 0x23, 0xd2, 0x0a, 0x63, 0x2f, 0x09, 0xa3, 0xdd, 0x6c, 0xb0, 0x24, 0x56, 0x18, - 0xac, 0x51, 0xf1, 0x9a, 0x77, 0xbc, 0x98, 0xb6, 0xb4, 0x64, 0x9a, 0xba, 0x58, 0xc0, 0xb1, 0xa2, - 0xa0, 0x1d, 0x73, 0xbd, 0x88, 0xa9, 0x0c, 0xbb, 0x62, 0x05, 0xab, 0x8e, 0x55, 0x25, 0x02, 0xa7, - 0x34, 0xf6, 0xdf, 0xb2, 0xe0, 0xf4, 0x15, 0xbf, 0x1d, 0x27, 0x24, 0xda, 0x8c, 0x8d, 0xc6, 0xbe, - 0x00, 0x15, 0x22, 0x95, 0x7b, 0xd1, 0x56, 0xb5, 0x69, 0x28, 0xad, 0x9f, 0x47, 0x6a, 0x2a, 0xba, - 0x02, 0x01, 0x81, 0xfd, 0x85, 0xaf, 0xfd, 0x76, 0x09, 0xc6, 0xaf, 0xae, 0xaf, 0xd7, 0xae, 0x90, - 0x44, 0x48, 0xc9, 0x7c, 0xa7, 0x54, 0x4d, 0xb3, 0xc8, 0xb5, 0xbd, 0x25, 0xb3, 0xea, 0xda, 0x89, - 0xe7, 0xcf, 0xf1, 0xc0, 0xf8, 0xb9, 0xd5, 0x20, 0xb9, 0x19, 0xd5, 0x93, 0xc8, 0x0b, 0xb6, 0xba, - 0x5a, 0xf0, 0x52, 0x92, 0x97, 0x7b, 0x49, 0x72, 0xf4, 0x02, 0x0c, 0xb1, 0x58, 0x7e, 0xa9, 0x7a, - 0x7c, 0x54, 0x69, 0x09, 0x0c, 0xfa, 0x60, 0x6f, 0xb6, 0x72, 0x0b, 0xaf, 0xf2, 0x3f, 0x58, 0x90, - 0xa2, 0x37, 0x61, 0x74, 0x3b, 0x49, 0x5a, 0x57, 0x89, 0xe3, 0x92, 0x48, 0x4a, 0x89, 0xf3, 0x07, - 0x4b, 0x09, 0x3a, 0x18, 0xbc, 0x40, 0xba, 0xb0, 0x52, 0x58, 0x8c, 0x75, 0x8e, 0x76, 0x1d, 0x20, - 0xc5, 0x3d, 0x24, 0x0b, 0xc4, 0xfe, 0xd9, 0x12, 0x0c, 0x5f, 0x75, 0x02, 0xd7, 0x27, 0x11, 0x5a, - 0x81, 0x01, 0x72, 0x9f, 0x34, 0xc4, 0x36, 0x9e, 0xd3, 0xf4, 0x74, 0xab, 0xe3, 0x5e, 0x35, 0xfa, - 0x1f, 0xb3, 0xf2, 0x08, 0xc3, 0x30, 0x6d, 0xf7, 0x15, 0x15, 0x45, 0xfb, 0x5c, 0xfe, 0x28, 0xa8, - 0x29, 0xc1, 0xf7, 0x49, 0x01, 0xc2, 0x92, 0x11, 0xf3, 0x3f, 0x35, 0x5a, 0x75, 0x2a, 0xdc, 0x92, - 0x62, 0x76, 0xdd, 0xfa, 0x52, 0x8d, 0x93, 0x0b, 0xbe, 0xdc, 0xff, 0x24, 0x81, 0x38, 0x65, 0x67, - 0x5f, 0x86, 0x53, 0xec, 0xf8, 0xd2, 0x49, 0xb6, 0x8d, 0x35, 0x93, 0x3b, 0x39, 0xed, 0xbf, 0x53, - 0x82, 0x13, 0xab, 0xf5, 0xa5, 0xba, 0xe9, 0x39, 0xbc, 0x0c, 0x63, 0x7c, 0x7b, 0xa6, 0x93, 0xce, - 0xf1, 0x45, 0x79, 0xe5, 0x72, 0x5f, 0xd7, 0x70, 0xd8, 0xa0, 0x44, 0x8f, 0x43, 0xd9, 0x7b, 0x27, - 0xc8, 0xc6, 0x47, 0xad, 0xbe, 0x76, 0x03, 0x53, 0x38, 0x45, 0xd3, 0x9d, 0x9e, 0x8b, 0x38, 0x85, - 0x56, 0xbb, 0xfd, 0xab, 0x30, 0xe1, 0xc5, 0x8d, 0xd8, 0x5b, 0x0d, 0xe8, 0xfa, 0x77, 0x1a, 0x72, - 0xfa, 0xa6, 0xaa, 0x39, 0x6d, 0xaa, 0xc2, 0xe2, 0x0c, 0xb5, 0x26, 0x6f, 0x07, 0x0b, 0x6b, 0x0b, - 0xf9, 0xe1, 0xb4, 0x6f, 0x43, 0x45, 0x85, 0x12, 0xc9, 0x00, 0x30, 0xab, 0x7b, 0x00, 0x58, 0x01, - 0x81, 0x23, 0xfd, 0xb9, 0xe5, 0xae, 0xfe, 0xdc, 0x7f, 0x68, 0x41, 0x1a, 0x35, 0x81, 0x30, 0x54, - 0x5a, 0x21, 0x3b, 0x2c, 0x89, 0xe4, 0xa9, 0xe4, 0x53, 0x39, 0x33, 0x91, 0xaf, 0x04, 0x3e, 0x57, - 0x6a, 0xb2, 0x2c, 0x4e, 0xd9, 0xa0, 0xeb, 0x30, 0xdc, 0x8a, 0x48, 0x3d, 0x61, 0x31, 0xd9, 0x7d, - 0x70, 0x64, 0xb3, 0xba, 0xc6, 0x4b, 0x62, 0xc9, 0xc2, 0xfe, 0x17, 0x16, 0xc0, 0x75, 0xaf, 0xe9, - 0x25, 0xd8, 0x09, 0xb6, 0xc8, 0x31, 0x18, 0x7b, 0x37, 0x60, 0x20, 0x6e, 0x91, 0x46, 0xb1, 0xe3, - 0xae, 0xb4, 0x65, 0xf5, 0x16, 0x69, 0xa4, 0x9f, 0x83, 0xfe, 0xc3, 0x8c, 0x8f, 0xfd, 0x8f, 0x00, - 0x26, 0x52, 0x32, 0xaa, 0x70, 0xa3, 0xe7, 0x8d, 0x60, 0xe4, 0x47, 0x33, 0xc1, 0xc8, 0x15, 0x46, - 0xad, 0xc5, 0x1f, 0x27, 0x50, 0x6e, 0x3a, 0xf7, 0x85, 0x7e, 0xff, 0x52, 0xd1, 0x06, 0xd1, 0x9a, - 0xe6, 0xd6, 0x9c, 0xfb, 0x5c, 0x9d, 0x7a, 0x4e, 0x4e, 0xa4, 0x35, 0xe7, 0xfe, 0x03, 0x7e, 0xa8, - 0xc5, 0x56, 0x22, 0x35, 0x28, 0xbe, 0xf6, 0x5f, 0xd3, 0xff, 0x4c, 0x38, 0xd2, 0xea, 0x58, 0xad, - 0x5e, 0x20, 0xdc, 0x93, 0x7d, 0xd6, 0xea, 0x05, 0xd9, 0x5a, 0xbd, 0xa0, 0x40, 0xad, 0x5e, 0x80, - 0xde, 0xb3, 0x60, 0x58, 0x78, 0xf5, 0x59, 0x1c, 0xda, 0xe8, 0xa5, 0x4f, 0xf5, 0x55, 0xb5, 0x38, - 0x1e, 0xe0, 0xd5, 0xcf, 0x4b, 0x1d, 0x52, 0x40, 0x73, 0x9b, 0x20, 0xab, 0x46, 0xbf, 0x6a, 0xc1, - 0x84, 0xf8, 0x8d, 0xc9, 0x3b, 0x6d, 0x12, 0x27, 0x62, 0xb7, 0xfa, 0xdc, 0x61, 0x5a, 0x23, 0x58, - 0xf0, 0x46, 0x7d, 0x52, 0x8a, 0x1a, 0x13, 0x99, 0xdb, 0xb6, 0x4c, 0x7b, 0xd0, 0xf7, 0x2c, 0x38, - 0xd5, 0x74, 0xee, 0xf3, 0x1a, 0x39, 0x0c, 0x3b, 0x89, 0x17, 0x8a, 0x58, 0xbb, 0x95, 0x7e, 0xe7, - 0x49, 0x07, 0x23, 0xde, 0xdc, 0xcf, 0xc8, 0xa3, 0xd6, 0x6e, 0x24, 0xb9, 0x8d, 0xee, 0xda, 0xc2, - 0x19, 0x17, 0x46, 0xe4, 0xc4, 0xec, 0xa2, 0xbd, 0x2f, 0xea, 0x9b, 0xf2, 0xc1, 0x2b, 0x50, 0xfa, - 0xbb, 0xe6, 0x5e, 0x6b, 0x3b, 0x41, 0xe2, 0x25, 0xbb, 0x9a, 0xae, 0xcf, 0x6a, 0x11, 0x13, 0xf1, - 0x08, 0x6b, 0xd9, 0x86, 0x31, 0x7d, 0xce, 0x1d, 0x61, 0x4d, 0x21, 0x9c, 0xec, 0x32, 0x9f, 0x8e, - 0xb0, 0xc2, 0x36, 0x3c, 0xda, 0x73, 0x5e, 0x1c, 0x5d, 0xb5, 0xf6, 0x3f, 0xb7, 0x74, 0x81, 0x79, - 0x0c, 0x1e, 0x94, 0x35, 0xd3, 0x83, 0x72, 0xbe, 0xe8, 0xca, 0xe9, 0xe1, 0x46, 0xd9, 0xd4, 0x9b, - 0x4f, 0x37, 0x02, 0xb4, 0x0e, 0x43, 0x3e, 0x85, 0xc8, 0x03, 0xac, 0x0b, 0xfd, 0xac, 0xcd, 0x54, - 0xc7, 0x60, 0xf0, 0x18, 0x0b, 0x5e, 0xf6, 0xf7, 0x2c, 0x18, 0xf8, 0x09, 0x5e, 0x90, 0xe8, 0x60, - 0x2d, 0xee, 0xf8, 0xce, 0x61, 0xe7, 0xde, 0xf2, 0xfd, 0x84, 0x04, 0x31, 0x53, 0x29, 0xbb, 0x0e, - 0xd1, 0xaf, 0x97, 0x60, 0x94, 0x56, 0x25, 0x43, 0x10, 0x5e, 0x81, 0x71, 0xdf, 0xd9, 0x20, 0xbe, - 0xf4, 0xfe, 0x66, 0xcd, 0xaf, 0xeb, 0x3a, 0x12, 0x9b, 0xb4, 0xb4, 0xf0, 0xa6, 0xee, 0x1c, 0x17, - 0xaa, 0x91, 0x2a, 0x6c, 0x78, 0xce, 0xb1, 0x49, 0x4b, 0x2d, 0x80, 0x7b, 0x4e, 0xd2, 0xd8, 0x16, - 0xa6, 0x99, 0x6a, 0xee, 0x1d, 0x0a, 0xc4, 0x1c, 0x87, 0x16, 0x60, 0x52, 0xce, 0xd8, 0xdb, 0xd4, - 0x66, 0x0f, 0x03, 0xa1, 0x36, 0xaa, 0x4b, 0x96, 0xd8, 0x44, 0xe3, 0x2c, 0x3d, 0xfa, 0x34, 0x4c, - 0xd0, 0xc1, 0x09, 0xdb, 0x89, 0x0c, 0xb0, 0x18, 0x64, 0x01, 0x16, 0x2c, 0x4a, 0x76, 0xdd, 0xc0, - 0xe0, 0x0c, 0xa5, 0xfd, 0x26, 0x9c, 0xbc, 0x1e, 0x3a, 0xee, 0xa2, 0xe3, 0x3b, 0x41, 0x83, 0x44, - 0xab, 0xc1, 0x56, 0xee, 0x59, 0xb4, 0x7e, 0x5e, 0x5c, 0xca, 0x3b, 0x2f, 0xb6, 0x23, 0x40, 0x7a, - 0x05, 0x22, 0x34, 0xe8, 0x0d, 0x18, 0xf6, 0x78, 0x55, 0x62, 0xda, 0x5e, 0xcc, 0x73, 0x2e, 0x75, - 0xb4, 0x51, 0x0b, 0x75, 0xe1, 0x00, 0x2c, 0x59, 0x52, 0x8b, 0xa2, 0x9b, 0x37, 0x2a, 0xdf, 0x68, - 0xb3, 0xff, 0xb2, 0x05, 0x93, 0x37, 0x32, 0x37, 0xf8, 0x9e, 0x86, 0xa1, 0x98, 0x44, 0x5d, 0x5c, - 0x6b, 0x75, 0x06, 0xc5, 0x02, 0xfb, 0xd0, 0xcd, 0xf5, 0x5f, 0x2c, 0x41, 0x85, 0x05, 0x99, 0xb6, - 0xa8, 0x75, 0x70, 0xf4, 0xca, 0xe9, 0x9a, 0xa1, 0x9c, 0xe6, 0x18, 0x8d, 0xaa, 0x61, 0xbd, 0x74, - 0x53, 0x74, 0x4b, 0xdd, 0x6c, 0x2b, 0x64, 0x2f, 0xa6, 0x0c, 0xf9, 0xed, 0xa7, 0x09, 0xf3, 0x22, - 0x9c, 0xbc, 0xf5, 0xc6, 0x4e, 0x70, 0x15, 0xed, 0x87, 0xee, 0x04, 0x57, 0xb5, 0xac, 0x87, 0x70, - 0xaa, 0x69, 0x8d, 0x67, 0xe2, 0xfb, 0xb3, 0x2c, 0x74, 0xd0, 0xf1, 0xbd, 0x77, 0x89, 0xba, 0x20, - 0x3a, 0x2b, 0x42, 0x01, 0x05, 0xf4, 0x01, 0x93, 0x33, 0xe2, 0x1f, 0xbf, 0xff, 0x9b, 0x16, 0xb1, - 0xaf, 0xc2, 0x64, 0x66, 0xe8, 0xd0, 0x4b, 0x30, 0xd8, 0xda, 0x76, 0x62, 0x92, 0x09, 0x4a, 0x19, - 0xac, 0x51, 0xe0, 0x83, 0xbd, 0xd9, 0x09, 0x55, 0x80, 0x41, 0x30, 0xa7, 0xb6, 0xdf, 0x2b, 0xc1, - 0xc0, 0x8d, 0xd0, 0x3d, 0x8e, 0xa9, 0x76, 0xd5, 0x98, 0x6a, 0x4f, 0xe7, 0x67, 0x0f, 0xe8, 0x39, - 0xcb, 0x6a, 0x99, 0x59, 0x76, 0xbe, 0x00, 0xaf, 0x83, 0x27, 0x58, 0x13, 0x46, 0x59, 0x76, 0x02, - 0x11, 0x95, 0xf3, 0x82, 0x61, 0x4f, 0xcd, 0x66, 0xec, 0xa9, 0x49, 0x8d, 0x54, 0xb3, 0xaa, 0x9e, - 0x81, 0x61, 0x11, 0x05, 0x92, 0x0d, 0x9c, 0x14, 0xb4, 0x58, 0xe2, 0xed, 0x7f, 0x5a, 0x06, 0x23, - 0x1b, 0x02, 0xfa, 0x81, 0x05, 0x73, 0x11, 0xbf, 0x0a, 0xe2, 0x56, 0xdb, 0x91, 0x17, 0x6c, 0xd5, - 0x1b, 0xdb, 0xc4, 0x6d, 0xfb, 0x5e, 0xb0, 0xb5, 0xba, 0x15, 0x84, 0x0a, 0xbc, 0x7c, 0x9f, 0x34, - 0xda, 0xcc, 0xe9, 0x5a, 0x38, 0x09, 0x83, 0x3a, 0x01, 0xbd, 0xb4, 0xbf, 0x37, 0x3b, 0x87, 0xfb, - 0xaa, 0x05, 0xf7, 0xd9, 0x2a, 0xf4, 0x47, 0x16, 0xcc, 0xf3, 0x7c, 0x00, 0xc5, 0x7b, 0x52, 0xc8, - 0x0e, 0xad, 0x49, 0xa6, 0x29, 0xbb, 0x75, 0x12, 0x35, 0x17, 0x5f, 0x16, 0x83, 0x3c, 0x5f, 0xeb, - 0xaf, 0x56, 0xdc, 0x6f, 0x33, 0xed, 0x7f, 0x55, 0x86, 0x71, 0x3a, 0x9e, 0xe9, 0x1d, 0xe0, 0x97, - 0x8c, 0x69, 0xf2, 0x44, 0x66, 0x9a, 0x9c, 0x30, 0x88, 0x1f, 0xce, 0xf5, 0xdf, 0x18, 0x4e, 0xf8, - 0x4e, 0x9c, 0x5c, 0x25, 0x4e, 0x94, 0x6c, 0x10, 0x87, 0x1d, 0x34, 0x66, 0x83, 0x18, 0x0a, 0x9c, - 0x5d, 0xaa, 0xc8, 0xa2, 0xeb, 0x59, 0x66, 0xb8, 0x93, 0x3f, 0xda, 0x01, 0xc4, 0x0e, 0x35, 0x23, - 0x27, 0x88, 0x79, 0x5f, 0x3c, 0xe1, 0xa6, 0xed, 0xaf, 0xd6, 0x19, 0x51, 0x2b, 0xba, 0xde, 0xc1, - 0x0d, 0x77, 0xa9, 0x41, 0x3b, 0xb6, 0x1e, 0x2c, 0x7a, 0x6c, 0x3d, 0x94, 0x13, 0xb1, 0xfc, 0xf3, - 0x16, 0x9c, 0xa4, 0x9f, 0xc5, 0x8c, 0x6e, 0x8d, 0x51, 0x08, 0x93, 0x74, 0xda, 0xf9, 0x24, 0x91, - 0x30, 0xb1, 0xbe, 0x72, 0x34, 0x6b, 0x93, 0x4f, 0xaa, 0xbe, 0x5d, 0x33, 0x99, 0xe1, 0x2c, 0x77, - 0xfb, 0xdb, 0x16, 0xb0, 0xf0, 0xb9, 0x63, 0xd8, 0xcc, 0xae, 0x98, 0x9b, 0x99, 0x9d, 0x2f, 0x31, - 0x7a, 0xec, 0x63, 0x2f, 0xc2, 0x14, 0xc5, 0xd6, 0xa2, 0xf0, 0xfe, 0xae, 0x54, 0xb4, 0xf3, 0xfd, - 0xb5, 0xef, 0x95, 0xf8, 0xb2, 0x51, 0x77, 0xda, 0xd0, 0x2f, 0x58, 0x30, 0xd2, 0x70, 0x5a, 0x4e, - 0x83, 0xe7, 0x92, 0x29, 0xe0, 0x93, 0x31, 0xca, 0xcf, 0x2d, 0x89, 0xb2, 0xdc, 0x9f, 0xf0, 0x09, - 0xd9, 0x75, 0x09, 0xce, 0xf5, 0x21, 0xa8, 0xca, 0x67, 0x3c, 0x18, 0x37, 0x98, 0x1d, 0xa1, 0x11, - 0xfa, 0x0b, 0x16, 0x17, 0xf9, 0xca, 0x50, 0xb8, 0x07, 0x27, 0x02, 0xed, 0x3f, 0x15, 0x66, 0x52, - 0x2f, 0x9e, 0x2b, 0x2e, 0xd4, 0x99, 0x0c, 0xd4, 0x02, 0x05, 0x33, 0x0c, 0x71, 0x67, 0x1d, 0xf6, - 0xdf, 0xb5, 0xe0, 0x11, 0x9d, 0x50, 0xbb, 0x82, 0x98, 0xe7, 0x2b, 0xae, 0xc2, 0x48, 0xd8, 0x22, - 0x91, 0x93, 0x1a, 0x45, 0xe7, 0xe5, 0xe8, 0xdf, 0x14, 0xf0, 0x07, 0x7b, 0xb3, 0xa7, 0x74, 0xee, - 0x12, 0x8e, 0x55, 0x49, 0x64, 0xc3, 0x10, 0x1b, 0x97, 0x58, 0x5c, 0x1e, 0x65, 0x99, 0x55, 0xd8, - 0x09, 0x49, 0x8c, 0x05, 0xc6, 0xfe, 0xeb, 0x16, 0x9f, 0x6c, 0x7a, 0xd3, 0xd1, 0x57, 0x60, 0xaa, - 0x49, 0xed, 0xa7, 0xe5, 0xfb, 0x2d, 0xba, 0x8d, 0xb2, 0x93, 0x61, 0xab, 0xc8, 0xe6, 0xd1, 0xa3, - 0xbb, 0x8b, 0xd3, 0xa2, 0xf5, 0x53, 0x6b, 0x19, 0xb6, 0xb8, 0xa3, 0x22, 0xfb, 0x8f, 0xc5, 0x8a, - 0x65, 0x1a, 0xdc, 0x33, 0x30, 0xdc, 0x0a, 0xdd, 0xa5, 0xd5, 0x2a, 0x16, 0x63, 0xa5, 0x44, 0x4e, - 0x8d, 0x83, 0xb1, 0xc4, 0xa3, 0x4b, 0x00, 0xe4, 0x7e, 0x42, 0xa2, 0xc0, 0xf1, 0xd5, 0x89, 0xae, - 0x52, 0x94, 0x96, 0x15, 0x06, 0x6b, 0x54, 0xb4, 0x4c, 0x2b, 0x0a, 0x77, 0x3c, 0x97, 0x45, 0xed, - 0x97, 0xcd, 0x32, 0x35, 0x85, 0xc1, 0x1a, 0x15, 0xb5, 0x5a, 0xdb, 0x41, 0xcc, 0x37, 0x31, 0x67, - 0x43, 0x24, 0x02, 0x19, 0x49, 0xad, 0xd6, 0x5b, 0x3a, 0x12, 0x9b, 0xb4, 0xf6, 0x7f, 0xaa, 0x00, - 0xa4, 0x6a, 0x12, 0x7a, 0xaf, 0x73, 0x85, 0x7e, 0xb2, 0xa8, 0x8e, 0xf5, 0xf0, 0x96, 0x27, 0xfa, - 0x86, 0x05, 0xa3, 0x8e, 0xef, 0x87, 0x0d, 0x27, 0x61, 0x3d, 0x2a, 0x15, 0x95, 0x15, 0xa2, 0x25, - 0x0b, 0x69, 0x59, 0xde, 0x98, 0x17, 0xe4, 0x81, 0x9f, 0x86, 0xc9, 0x6d, 0x8f, 0xde, 0x04, 0xf4, - 0x09, 0xa9, 0x66, 0xf3, 0x8f, 0x32, 0x93, 0x55, 0xb3, 0x2b, 0x4c, 0x42, 0x6a, 0x1a, 0x36, 0x7a, - 0xd3, 0xc8, 0x75, 0x31, 0x50, 0xe4, 0xce, 0xa2, 0xa1, 0x38, 0xe4, 0xa5, 0xb9, 0x40, 0x5f, 0xd4, - 0x03, 0x9a, 0x07, 0x8b, 0x5c, 0x0a, 0xd6, 0xf4, 0xd7, 0x9c, 0x60, 0xe6, 0x04, 0x26, 0x5d, 0x73, - 0xab, 0x14, 0x41, 0x59, 0x17, 0xf3, 0x6b, 0xc8, 0xec, 0xb1, 0xe9, 0xe6, 0x98, 0x41, 0xe0, 0x6c, - 0x15, 0xe8, 0x8b, 0x3c, 0xdc, 0x7c, 0x35, 0xd8, 0x0c, 0x45, 0x60, 0xd6, 0x85, 0x02, 0xdf, 0x7c, - 0x37, 0x4e, 0x48, 0x93, 0x96, 0x49, 0x77, 0xc3, 0x1b, 0x82, 0x0b, 0x56, 0xfc, 0xd0, 0x3a, 0x0c, - 0xb1, 0xcb, 0x31, 0xf1, 0xf4, 0x48, 0x11, 0xd7, 0x99, 0x79, 0x27, 0x34, 0x55, 0x41, 0xd8, 0xdf, - 0x18, 0x0b, 0x5e, 0xe8, 0xaa, 0xbc, 0x9b, 0x1d, 0xaf, 0x06, 0xb7, 0x62, 0xc2, 0xee, 0x66, 0x57, - 0x16, 0x3f, 0x96, 0x5e, 0xb6, 0xe6, 0xf0, 0xae, 0xd9, 0xbe, 0x8c, 0x92, 0x54, 0x13, 0x11, 0xff, - 0x65, 0x12, 0xb1, 0x69, 0x28, 0xd2, 0x50, 0x33, 0xe5, 0x58, 0x3a, 0xd8, 0xb7, 0x4d, 0x66, 0x38, - 0xcb, 0xfd, 0x18, 0xf7, 0xc0, 0x19, 0x1f, 0xa6, 0xb2, 0x4b, 0xf2, 0x08, 0x77, 0xdc, 0x3f, 0x1d, - 0x80, 0x09, 0x73, 0x62, 0xa0, 0x79, 0xa8, 0x08, 0x6d, 0x4a, 0x25, 0x14, 0x52, 0xf3, 0x7f, 0x4d, - 0x22, 0x70, 0x4a, 0xc3, 0x52, 0x2b, 0xb1, 0xe2, 0x5a, 0x38, 0x4e, 0x9a, 0x5a, 0x49, 0x61, 0xb0, - 0x46, 0x45, 0xd5, 0xd6, 0x8d, 0x30, 0x4c, 0x94, 0xe0, 0x56, 0x73, 0x66, 0x91, 0x41, 0xb1, 0xc0, - 0x52, 0x81, 0x7d, 0x97, 0x76, 0xc8, 0x37, 0x5d, 0x80, 0x4a, 0x60, 0x5f, 0xd3, 0x91, 0xd8, 0xa4, - 0xa5, 0x1b, 0x50, 0x18, 0xb3, 0x49, 0x28, 0x94, 0xe3, 0x34, 0xbc, 0xa9, 0xce, 0x2f, 0x8b, 0x49, - 0x3c, 0xfa, 0x02, 0x3c, 0xa2, 0xee, 0x76, 0x61, 0xee, 0x52, 0x95, 0x35, 0x0e, 0x19, 0xf6, 0xed, - 0x23, 0x4b, 0xdd, 0xc9, 0x70, 0xaf, 0xf2, 0xe8, 0x55, 0x98, 0x10, 0x8a, 0xad, 0xe4, 0x38, 0x6c, - 0x9e, 0x7e, 0x5f, 0x33, 0xb0, 0x38, 0x43, 0x8d, 0xaa, 0x30, 0x45, 0x21, 0x4c, 0xa3, 0x94, 0x1c, - 0xf8, 0x1d, 0x35, 0xb5, 0x33, 0x5f, 0xcb, 0xe0, 0x71, 0x47, 0x09, 0xb4, 0x00, 0x93, 0x5c, 0xb7, - 0xa0, 0x56, 0x1c, 0xfb, 0x0e, 0x22, 0x92, 0x52, 0x2d, 0x82, 0x9b, 0x26, 0x1a, 0x67, 0xe9, 0xd1, - 0x65, 0x18, 0x73, 0xa2, 0xc6, 0xb6, 0x97, 0x90, 0x46, 0xd2, 0x8e, 0x78, 0xd6, 0x03, 0x2d, 0x7c, - 0x60, 0x41, 0xc3, 0x61, 0x83, 0xd2, 0x7e, 0x17, 0x4e, 0x76, 0x09, 0xdb, 0xa6, 0x13, 0xc7, 0x69, - 0x79, 0xb2, 0x4f, 0x99, 0x40, 0xa5, 0x85, 0xda, 0xaa, 0xec, 0x8d, 0x46, 0x45, 0x67, 0x27, 0xf3, - 0x25, 0x6b, 0xf9, 0xfe, 0xd4, 0xec, 0x5c, 0x91, 0x08, 0x9c, 0xd2, 0xd8, 0xff, 0xab, 0x02, 0x9a, - 0xab, 0xa5, 0x40, 0x78, 0xca, 0x65, 0x18, 0x93, 0x29, 0x2c, 0xb5, 0xd4, 0x71, 0xaa, 0x9b, 0x57, - 0x34, 0x1c, 0x36, 0x28, 0x69, 0xdb, 0x02, 0xe9, 0x40, 0xca, 0x86, 0x45, 0x29, 0xcf, 0x12, 0x4e, - 0x69, 0xd0, 0x05, 0x18, 0x89, 0x89, 0xbf, 0x79, 0xdd, 0x0b, 0xee, 0x8a, 0x89, 0xad, 0xa4, 0x72, - 0x5d, 0xc0, 0xb1, 0xa2, 0x40, 0x8b, 0x50, 0x6e, 0x7b, 0xae, 0x98, 0xca, 0x52, 0x65, 0x28, 0xdf, - 0x5a, 0xad, 0x3e, 0xd8, 0x9b, 0x7d, 0xa2, 0x57, 0x0e, 0x50, 0x6a, 0x4c, 0xc7, 0x73, 0x74, 0xf9, - 0xd1, 0xc2, 0xdd, 0x9c, 0xea, 0x43, 0x7d, 0x3a, 0xd5, 0x2f, 0x01, 0x88, 0x5e, 0xcb, 0xb9, 0x5c, - 0x4e, 0xbf, 0xda, 0x15, 0x85, 0xc1, 0x1a, 0x15, 0x35, 0xc9, 0x1b, 0x11, 0x71, 0xa4, 0xd5, 0xca, - 0xc3, 0x89, 0x47, 0x0e, 0x6f, 0x92, 0x2f, 0x65, 0x99, 0xe1, 0x4e, 0xfe, 0x28, 0x84, 0x13, 0x2e, - 0x5d, 0x48, 0x46, 0xa5, 0x95, 0xfe, 0x63, 0x98, 0x69, 0x85, 0xd5, 0x2c, 0x23, 0xdc, 0xc9, 0x1b, - 0x7d, 0x19, 0x66, 0x24, 0xb0, 0xf3, 0xf6, 0x26, 0x5b, 0x2e, 0xe5, 0xc5, 0xb3, 0xfb, 0x7b, 0xb3, - 0x33, 0xd5, 0x9e, 0x54, 0xf8, 0x00, 0x0e, 0xe8, 0x0d, 0x18, 0x62, 0x87, 0x30, 0xf1, 0xf4, 0x28, - 0xdb, 0xed, 0x5e, 0x2c, 0x12, 0x09, 0x4f, 0x67, 0xfd, 0x1c, 0x3b, 0xca, 0x11, 0x31, 0x9e, 0xe9, - 0xc9, 0x16, 0x03, 0x62, 0xc1, 0x13, 0xb5, 0x60, 0xd4, 0x09, 0x82, 0x30, 0x71, 0xb8, 0x12, 0x36, - 0x56, 0x44, 0x8f, 0xd4, 0xaa, 0x58, 0x48, 0xcb, 0xf2, 0x7a, 0x54, 0xe0, 0x98, 0x86, 0xc1, 0x7a, - 0x15, 0xe8, 0x1e, 0x4c, 0x86, 0xf7, 0xa8, 0xc0, 0x94, 0xe7, 0x10, 0xf1, 0xf4, 0xb8, 0xd9, 0xb1, - 0x1c, 0xaf, 0xaa, 0x51, 0x58, 0x93, 0x64, 0x26, 0x53, 0x9c, 0xad, 0x05, 0xcd, 0x19, 0xbe, 0xe5, - 0x89, 0x34, 0x92, 0x39, 0xf5, 0x2d, 0xeb, 0xae, 0x64, 0x76, 0x43, 0x98, 0x47, 0x2f, 0x32, 0x89, - 0x30, 0x99, 0xb9, 0x21, 0x9c, 0xa2, 0xb0, 0x4e, 0x37, 0xf3, 0x29, 0x18, 0xd5, 0x06, 0xbe, 0x9f, - 0x90, 0xd9, 0x99, 0x57, 0x61, 0x2a, 0x3b, 0xa0, 0x7d, 0x85, 0xdc, 0xfe, 0xcf, 0x12, 0x4c, 0x76, - 0x39, 0xe4, 0xb9, 0xeb, 0xb1, 0xb0, 0x6f, 0x43, 0xf4, 0x5d, 0xf3, 0x02, 0x17, 0x33, 0x8c, 0x29, - 0xc0, 0x4a, 0x05, 0x04, 0x98, 0x94, 0xa6, 0xe5, 0x9e, 0xd2, 0x54, 0x08, 0xad, 0x81, 0x0f, 0x22, - 0xb4, 0xcc, 0x7d, 0x62, 0xb0, 0xd0, 0x3e, 0xf1, 0x10, 0x04, 0x9d, 0xb1, 0xd5, 0x0c, 0x17, 0xd8, - 0x6a, 0xbe, 0x55, 0x82, 0xa9, 0x34, 0xbc, 0x58, 0xe4, 0xb5, 0x3d, 0xfa, 0x33, 0x83, 0x75, 0xe3, - 0xcc, 0x20, 0x2f, 0x6d, 0x6d, 0xa6, 0x7d, 0x3d, 0xcf, 0x0f, 0xde, 0xc8, 0x9c, 0x1f, 0xbc, 0xd8, - 0x27, 0xdf, 0x83, 0xcf, 0x12, 0xbe, 0x5b, 0x82, 0xd3, 0xd9, 0x22, 0x4b, 0xbe, 0xe3, 0x35, 0x8f, - 0x61, 0xbc, 0xbe, 0x60, 0x8c, 0xd7, 0xcb, 0xfd, 0xf5, 0x8b, 0x35, 0xb2, 0xe7, 0xa0, 0x39, 0x99, - 0x41, 0xfb, 0xd4, 0x61, 0x98, 0x1f, 0x3c, 0x72, 0x7f, 0x60, 0xc1, 0xa3, 0x5d, 0xcb, 0x1d, 0x83, - 0x97, 0xf4, 0x75, 0xd3, 0x4b, 0xfa, 0xc2, 0x21, 0x7a, 0xd7, 0xc3, 0x6d, 0xfa, 0xdf, 0x4a, 0x3d, - 0x7a, 0xc5, 0x3c, 0x49, 0x37, 0x61, 0xd4, 0x69, 0x34, 0x48, 0x1c, 0xaf, 0x85, 0xae, 0xca, 0x35, - 0xf4, 0x3c, 0xdb, 0x5b, 0x52, 0xf0, 0x83, 0xbd, 0xd9, 0x99, 0x2c, 0x8b, 0x14, 0x8d, 0x75, 0x0e, - 0x66, 0x2e, 0xb2, 0xd2, 0x11, 0xe5, 0x22, 0xbb, 0x04, 0xb0, 0xa3, 0x2c, 0xd8, 0xac, 0x83, 0x4a, - 0xb3, 0x6d, 0x35, 0x2a, 0xf4, 0x17, 0x99, 0x46, 0xc8, 0x23, 0x2a, 0x06, 0xcc, 0x9b, 0x8a, 0x39, - 0xdf, 0x4f, 0x8f, 0xce, 0xe0, 0x17, 0x22, 0x95, 0x33, 0x4f, 0xb1, 0xb4, 0xff, 0x59, 0x19, 0x3e, - 0x7a, 0xc0, 0xa4, 0x43, 0x0b, 0xe6, 0x01, 0xe9, 0x73, 0x59, 0xcf, 0xcd, 0x4c, 0xd7, 0xc2, 0x86, - 0x2b, 0x27, 0xf3, 0xad, 0x4a, 0x1f, 0xf8, 0x5b, 0x7d, 0x53, 0xf7, 0xb3, 0xf1, 0xc0, 0xc8, 0x2b, - 0x87, 0x5e, 0x56, 0x3f, 0x9d, 0x7e, 0xf1, 0xaf, 0x59, 0xf0, 0x44, 0xd7, 0x4e, 0x19, 0xe1, 0x18, - 0xf3, 0x50, 0x69, 0x50, 0xa0, 0x76, 0x83, 0x25, 0xbd, 0x3a, 0x26, 0x11, 0x38, 0xa5, 0x31, 0xa2, - 0x2e, 0x4a, 0xb9, 0x51, 0x17, 0xbf, 0x67, 0xc1, 0xa9, 0x6c, 0x23, 0x8e, 0x41, 0xe6, 0xd4, 0x4d, - 0x99, 0x33, 0xd7, 0xdf, 0xa7, 0xef, 0x21, 0x6e, 0x7e, 0x75, 0x1c, 0xce, 0x74, 0xec, 0x58, 0x7c, - 0x14, 0x7f, 0xc6, 0x82, 0x13, 0x5b, 0x4c, 0xf3, 0xd6, 0xae, 0x09, 0x89, 0x7e, 0xe5, 0xdc, 0xad, - 0x3a, 0xf0, 0x76, 0x11, 0xb7, 0x23, 0x3a, 0x48, 0x70, 0x67, 0x65, 0xe8, 0xeb, 0x16, 0x9c, 0x72, - 0xee, 0xc5, 0x1d, 0x2f, 0x26, 0x88, 0x69, 0xf4, 0x6a, 0x8e, 0x93, 0x2b, 0xe7, 0xad, 0x85, 0xc5, - 0xe9, 0xfd, 0xbd, 0xd9, 0x53, 0xdd, 0xa8, 0x70, 0xd7, 0x5a, 0xe9, 0xf7, 0xdd, 0x16, 0xd7, 0x10, - 0x8a, 0x5d, 0x78, 0xeb, 0x76, 0x69, 0x81, 0x8b, 0x24, 0x89, 0xc1, 0x8a, 0x23, 0x7a, 0x0b, 0x2a, - 0x5b, 0xf2, 0x66, 0x50, 0x56, 0xe4, 0xf5, 0x18, 0xe6, 0x6e, 0x17, 0x89, 0x78, 0x68, 0xbc, 0x42, - 0xe1, 0x94, 0x29, 0xba, 0x0a, 0xe5, 0x60, 0x33, 0x16, 0x77, 0x70, 0xf3, 0x82, 0x6d, 0xcc, 0x10, - 0x27, 0x7e, 0x6d, 0xf1, 0xc6, 0x4a, 0x1d, 0x53, 0x16, 0x94, 0x53, 0xb4, 0xe1, 0x0a, 0xef, 0x6e, - 0x0e, 0x27, 0xbc, 0x58, 0xed, 0xe4, 0x84, 0x17, 0xab, 0x98, 0xb2, 0x40, 0x35, 0x18, 0x64, 0x97, - 0x1c, 0x84, 0xeb, 0x36, 0xe7, 0xa2, 0x76, 0xc7, 0x55, 0x0e, 0x9e, 0x68, 0x8f, 0x81, 0x31, 0x67, - 0x84, 0xd6, 0x61, 0xa8, 0xc1, 0x92, 0x83, 0x0b, 0xbb, 0x3a, 0x2f, 0x85, 0x41, 0x47, 0x22, 0x71, - 0x7e, 0xc4, 0xc4, 0xe1, 0x58, 0xf0, 0x62, 0x5c, 0x49, 0x6b, 0x7b, 0x33, 0x16, 0x86, 0x73, 0x1e, - 0xd7, 0x8e, 0x34, 0xef, 0x82, 0x2b, 0x83, 0x63, 0xc1, 0x0b, 0x55, 0xa1, 0xb4, 0xd9, 0x10, 0x59, - 0x33, 0x73, 0x5c, 0xb6, 0xe6, 0x1d, 0xd4, 0xc5, 0xa1, 0xfd, 0xbd, 0xd9, 0xd2, 0xca, 0x12, 0x2e, - 0x6d, 0x36, 0xd0, 0xeb, 0x30, 0xbc, 0xc9, 0x6f, 0x15, 0x8a, 0x0c, 0x99, 0x17, 0xf3, 0xae, 0x3e, - 0x76, 0x5c, 0x41, 0xe4, 0xd7, 0x1f, 0x04, 0x02, 0x4b, 0x76, 0x2c, 0x6d, 0x99, 0xba, 0x27, 0x29, - 0x52, 0x64, 0xce, 0xf5, 0x77, 0xaf, 0x52, 0xd8, 0x93, 0x0a, 0x8a, 0x35, 0x8e, 0x74, 0xce, 0x3b, - 0xf2, 0x9d, 0x03, 0x96, 0x1e, 0x33, 0x77, 0xce, 0x77, 0x7d, 0x16, 0x81, 0xcf, 0x79, 0x85, 0xc2, - 0x29, 0x53, 0xd4, 0x86, 0xf1, 0x9d, 0xb8, 0xb5, 0x4d, 0xe4, 0xd2, 0x67, 0x39, 0x33, 0x47, 0x2f, - 0x7d, 0x26, 0x27, 0x11, 0xaa, 0x28, 0xe2, 0x45, 0x49, 0xdb, 0xf1, 0x3b, 0x24, 0x18, 0xcb, 0x13, - 0x75, 0x5b, 0x67, 0x8b, 0xcd, 0x5a, 0xe8, 0x27, 0x79, 0xa7, 0x1d, 0x6e, 0xec, 0x26, 0x44, 0xe4, - 0xd4, 0xcc, 0xf9, 0x24, 0xaf, 0x71, 0xe2, 0xce, 0x4f, 0x22, 0x10, 0x58, 0xb2, 0x53, 0x43, 0xc6, - 0xa4, 0xf1, 0x54, 0xe1, 0x21, 0xeb, 0xe8, 0x43, 0x3a, 0x64, 0x4c, 0xfa, 0xa6, 0x4c, 0x99, 0xd4, - 0x6d, 0x6d, 0x87, 0x49, 0x18, 0x64, 0x64, 0xff, 0x89, 0x22, 0x52, 0xb7, 0xd6, 0xa5, 0x64, 0xa7, - 0xd4, 0xed, 0x46, 0x85, 0xbb, 0xd6, 0x6a, 0xff, 0xf1, 0x60, 0xe7, 0x76, 0xcb, 0x94, 0xe1, 0xbf, - 0xd6, 0x79, 0xee, 0xf8, 0xb9, 0xfe, 0x6d, 0xbe, 0x87, 0x78, 0x02, 0xf9, 0x75, 0x0b, 0xce, 0xb4, - 0xba, 0x6e, 0xa6, 0x62, 0xc3, 0xea, 0xd7, 0x74, 0xe4, 0x03, 0xa6, 0x12, 0xc6, 0x76, 0xc7, 0xe3, - 0x1e, 0x75, 0x66, 0x15, 0xd0, 0xf2, 0x07, 0x56, 0x40, 0xef, 0xc0, 0x08, 0xd3, 0x99, 0xd2, 0xbc, - 0x1a, 0x7d, 0xa6, 0xa0, 0x60, 0x5b, 0xdf, 0x92, 0x60, 0x81, 0x15, 0x33, 0x3a, 0x70, 0x8f, 0x67, - 0x3b, 0x81, 0x09, 0x43, 0x8b, 0x4c, 0xb7, 0xdc, 0xd7, 0xb1, 0x22, 0x46, 0xe2, 0xf1, 0xda, 0x41, - 0xc4, 0x0f, 0xf2, 0x08, 0xf0, 0xc1, 0x95, 0x1d, 0xa7, 0x42, 0xfb, 0xf7, 0xad, 0x2e, 0xfa, 0x17, - 0x37, 0x41, 0x3e, 0x63, 0x9a, 0x20, 0x4f, 0x67, 0x4d, 0x90, 0x0e, 0xb7, 0x81, 0x61, 0x7d, 0x14, - 0x4f, 0xcc, 0x58, 0x34, 0xe1, 0x87, 0xed, 0xc3, 0xb9, 0xbc, 0xc5, 0xcd, 0x22, 0x7c, 0x5c, 0x75, - 0x5c, 0x96, 0x46, 0xf8, 0xb8, 0xab, 0x55, 0xcc, 0x30, 0x45, 0xef, 0x8c, 0xdb, 0x3f, 0x5b, 0x82, - 0x72, 0x2d, 0x74, 0x8f, 0xc1, 0x0d, 0x72, 0xc5, 0x70, 0x83, 0x3c, 0x95, 0xfb, 0xca, 0x53, 0x4f, - 0xa7, 0xc7, 0xcd, 0x8c, 0xd3, 0xe3, 0xe3, 0xf9, 0xac, 0x0e, 0x76, 0x71, 0x7c, 0xaf, 0x0c, 0xfa, - 0x3b, 0x55, 0xe8, 0x3f, 0x1e, 0x26, 0xf0, 0xb3, 0x5c, 0xec, 0xe9, 0x2a, 0x51, 0x07, 0x0b, 0x11, - 0x92, 0x97, 0xc4, 0x7e, 0x6a, 0xe3, 0x3f, 0xef, 0x10, 0x6f, 0x6b, 0x3b, 0x21, 0x6e, 0xb6, 0x63, - 0xc7, 0x17, 0xff, 0xf9, 0xdf, 0x2d, 0x98, 0xcc, 0xd4, 0x8e, 0xfc, 0x6e, 0xf7, 0x4c, 0x0e, 0xe9, - 0xd8, 0x38, 0x91, 0x7b, 0x31, 0x65, 0x0e, 0x40, 0xf9, 0xa7, 0xa5, 0xfb, 0x81, 0xe9, 0x62, 0xca, - 0x81, 0x1d, 0x63, 0x8d, 0x02, 0xbd, 0x04, 0xa3, 0x49, 0xd8, 0x0a, 0xfd, 0x70, 0x6b, 0xf7, 0x1a, - 0x91, 0xd9, 0x0c, 0x94, 0x6f, 0x7f, 0x3d, 0x45, 0x61, 0x9d, 0xce, 0xfe, 0x7e, 0x19, 0xb2, 0xaf, - 0x9c, 0xfd, 0xf9, 0x3c, 0xfd, 0xe9, 0x99, 0xa7, 0x7f, 0x68, 0xc1, 0x14, 0xad, 0x9d, 0x05, 0x78, - 0xc8, 0x38, 0x4d, 0x95, 0xab, 0xdd, 0x3a, 0x20, 0x57, 0xfb, 0xd3, 0x54, 0xda, 0xb9, 0x61, 0x3b, - 0x11, 0x2e, 0x13, 0x4d, 0x88, 0x51, 0x28, 0x16, 0x58, 0x41, 0x47, 0xa2, 0x48, 0x5c, 0x68, 0xd1, - 0xe9, 0x48, 0x14, 0x61, 0x81, 0x95, 0xa9, 0xdc, 0x07, 0x7a, 0xa4, 0x72, 0x67, 0xf9, 0x80, 0x44, - 0x60, 0x81, 0x50, 0x07, 0xb4, 0x7c, 0x40, 0x32, 0xe2, 0x20, 0xa5, 0xb1, 0xbf, 0x53, 0x86, 0xb1, - 0x5a, 0xe8, 0xa6, 0x01, 0xd8, 0x2f, 0x1a, 0x01, 0xd8, 0xe7, 0x32, 0x01, 0xd8, 0x53, 0x3a, 0xed, - 0xc3, 0x89, 0xbf, 0x16, 0x79, 0xa3, 0xd8, 0x63, 0x03, 0x87, 0x8c, 0xbd, 0x36, 0xf2, 0x46, 0x29, - 0x46, 0xd8, 0xe4, 0xfb, 0x67, 0x29, 0xe6, 0xfa, 0xff, 0x58, 0x30, 0x51, 0x0b, 0x5d, 0x3a, 0x41, - 0xff, 0x2c, 0xcd, 0x46, 0x3d, 0xdb, 0xd4, 0xd0, 0x01, 0xd9, 0xa6, 0xfe, 0xb1, 0x05, 0xc3, 0xb5, - 0xd0, 0x3d, 0x06, 0x77, 0xe2, 0x8a, 0xe9, 0x4e, 0x7c, 0x22, 0x57, 0xf2, 0xf6, 0xf0, 0x20, 0xfe, - 0x66, 0x19, 0xc6, 0x69, 0x8b, 0xc3, 0x2d, 0xf9, 0xbd, 0x8c, 0xb1, 0xb1, 0x0a, 0x8c, 0x0d, 0x55, - 0x09, 0x43, 0xdf, 0x0f, 0xef, 0x65, 0xbf, 0xdd, 0x0a, 0x83, 0x62, 0x81, 0x45, 0x17, 0x60, 0xa4, - 0x15, 0x91, 0x1d, 0x2f, 0x6c, 0xc7, 0xd9, 0xcb, 0x71, 0x35, 0x01, 0xc7, 0x8a, 0x02, 0xbd, 0x08, - 0x63, 0xb1, 0x17, 0x34, 0x88, 0x0c, 0x3b, 0x18, 0x60, 0x61, 0x07, 0x3c, 0xb1, 0x9f, 0x06, 0xc7, - 0x06, 0x15, 0xba, 0x03, 0x15, 0xf6, 0x9f, 0xad, 0xa0, 0xfe, 0xb3, 0xc0, 0xf3, 0x6c, 0x56, 0x92, - 0x01, 0x4e, 0x79, 0xa1, 0x4b, 0x00, 0x89, 0x0c, 0x90, 0x88, 0x45, 0x56, 0x0e, 0xa5, 0x97, 0xaa, - 0xd0, 0x89, 0x18, 0x6b, 0x54, 0xe8, 0x39, 0xa8, 0x24, 0x8e, 0xe7, 0x5f, 0xf7, 0x02, 0x12, 0x8b, - 0x00, 0x13, 0x91, 0xa4, 0x57, 0x00, 0x71, 0x8a, 0xa7, 0xfb, 0x3d, 0xbb, 0x9a, 0xcb, 0x5f, 0x98, - 0x18, 0x61, 0xd4, 0x6c, 0xbf, 0xbf, 0xae, 0xa0, 0x58, 0xa3, 0xb0, 0x2f, 0xc3, 0xe9, 0x5a, 0xe8, - 0xd6, 0xc2, 0x28, 0x59, 0x09, 0xa3, 0x7b, 0x4e, 0xe4, 0xca, 0xef, 0x37, 0x2b, 0x73, 0xc3, 0xd2, - 0x3d, 0x79, 0x90, 0x7b, 0xd8, 0x8c, 0x5c, 0xaf, 0x2f, 0xb0, 0x1d, 0xbf, 0xcf, 0xc8, 0xfe, 0x1f, - 0x95, 0x00, 0xd5, 0x58, 0x08, 0x87, 0xf1, 0x2c, 0xc8, 0x36, 0x4c, 0xc4, 0xe4, 0xba, 0x17, 0xb4, - 0xef, 0x0b, 0x56, 0xc5, 0xae, 0x52, 0xd4, 0x97, 0xf5, 0x32, 0xfc, 0x1e, 0xab, 0x09, 0xc3, 0x19, - 0xbe, 0x74, 0x30, 0xa3, 0x76, 0xb0, 0x10, 0xdf, 0x8a, 0x49, 0x24, 0x1e, 0xe0, 0x60, 0x83, 0x89, - 0x25, 0x10, 0xa7, 0x78, 0x3a, 0x79, 0xd8, 0x9f, 0x1b, 0x61, 0x80, 0xc3, 0x30, 0x91, 0xd3, 0x8d, - 0x25, 0x64, 0xd7, 0xe0, 0xd8, 0xa0, 0x42, 0x2b, 0x80, 0xe2, 0x76, 0xab, 0xe5, 0xb3, 0x53, 0x31, - 0xc7, 0xbf, 0x12, 0x85, 0xed, 0x16, 0x8f, 0xe2, 0x15, 0xb9, 0xcc, 0xeb, 0x1d, 0x58, 0xdc, 0xa5, - 0x04, 0x15, 0x16, 0x9b, 0x31, 0xfb, 0x2d, 0xee, 0xe9, 0x72, 0xef, 0x5c, 0x9d, 0x81, 0xb0, 0xc4, - 0xd9, 0x5f, 0x65, 0x1b, 0x1c, 0x7b, 0x19, 0x21, 0x69, 0x47, 0x04, 0x35, 0x61, 0xbc, 0xc5, 0x36, - 0xb1, 0x24, 0x0a, 0x7d, 0x9f, 0x48, 0xfd, 0xf2, 0x70, 0x41, 0x24, 0x3c, 0x17, 0xba, 0xce, 0x0e, - 0x9b, 0xdc, 0xed, 0x1f, 0x8f, 0x32, 0x59, 0x25, 0x0e, 0x26, 0x87, 0x45, 0xa8, 0xa8, 0xd0, 0xe4, - 0x3e, 0x56, 0xe4, 0xa5, 0xa1, 0x74, 0x1f, 0x10, 0x81, 0xa7, 0x58, 0x72, 0x41, 0x5f, 0x62, 0x81, - 0xd0, 0x5c, 0x40, 0x14, 0x7f, 0xfe, 0x8b, 0xd3, 0x1b, 0x41, 0xd0, 0x82, 0x05, 0xd6, 0xd8, 0xa1, - 0xeb, 0x30, 0x2e, 0x12, 0xe9, 0x0b, 0xf7, 0x42, 0xd9, 0x30, 0xb1, 0xc7, 0xb1, 0x8e, 0x7c, 0x90, - 0x05, 0x60, 0xb3, 0x30, 0xda, 0x82, 0xc7, 0xb5, 0x27, 0x7b, 0xba, 0x04, 0x3c, 0x71, 0xc9, 0xf3, - 0xc4, 0xfe, 0xde, 0xec, 0xe3, 0xeb, 0x07, 0x11, 0xe2, 0x83, 0xf9, 0xa0, 0x9b, 0x70, 0xda, 0x69, - 0x24, 0xde, 0x0e, 0xa9, 0x12, 0xc7, 0xf5, 0xbd, 0x80, 0x98, 0x97, 0xb9, 0x1f, 0xdd, 0xdf, 0x9b, - 0x3d, 0xbd, 0xd0, 0x8d, 0x00, 0x77, 0x2f, 0x87, 0x3e, 0x03, 0x15, 0x37, 0x88, 0xc5, 0x18, 0x0c, - 0x19, 0xaf, 0x13, 0x55, 0xaa, 0x37, 0xea, 0xaa, 0xff, 0xe9, 0x1f, 0x9c, 0x16, 0x40, 0xef, 0xf0, - 0x87, 0x9e, 0x95, 0x35, 0xc3, 0x5f, 0xc5, 0x7a, 0xb9, 0x90, 0xfd, 0x6c, 0x5c, 0xb2, 0xe0, 0x9e, - 0x37, 0x15, 0x58, 0x68, 0xdc, 0xbf, 0x30, 0xaa, 0x40, 0x9f, 0x07, 0x14, 0x93, 0x68, 0xc7, 0x6b, - 0x90, 0x85, 0x06, 0xcb, 0x86, 0xc9, 0x8e, 0xf8, 0x46, 0x8c, 0xe8, 0x7a, 0x54, 0xef, 0xa0, 0xc0, - 0x5d, 0x4a, 0xa1, 0xab, 0x54, 0xf2, 0xe8, 0x50, 0x11, 0x07, 0x2a, 0x15, 0xc3, 0xe9, 0x2a, 0x69, - 0x45, 0xa4, 0xe1, 0x24, 0xc4, 0x35, 0x39, 0xe2, 0x4c, 0x39, 0xba, 0x2f, 0xa9, 0x84, 0xe7, 0x60, - 0x46, 0x2f, 0x76, 0x26, 0x3d, 0xa7, 0x76, 0xd6, 0x76, 0x18, 0x27, 0x37, 0x48, 0x72, 0x2f, 0x8c, - 0xee, 0x32, 0x8f, 0xfd, 0x88, 0x96, 0x5c, 0x2c, 0x45, 0x61, 0x9d, 0x8e, 0xea, 0x50, 0xec, 0xa8, - 0x68, 0xb5, 0xca, 0xfc, 0xf0, 0x23, 0xe9, 0xda, 0xb9, 0xca, 0xc1, 0x58, 0xe2, 0x25, 0xe9, 0x6a, - 0x6d, 0x89, 0xf9, 0xd4, 0x33, 0xa4, 0xab, 0xb5, 0x25, 0x2c, 0xf1, 0x28, 0xec, 0x7c, 0x03, 0x6a, - 0xa2, 0xc8, 0xf9, 0x46, 0xa7, 0x24, 0x2f, 0xf8, 0x0c, 0xd4, 0x7d, 0x98, 0x52, 0xef, 0x50, 0xf1, - 0xac, 0x8f, 0xf1, 0xf4, 0x64, 0x91, 0x67, 0xa6, 0xbb, 0x26, 0x8f, 0x54, 0x81, 0xbf, 0xab, 0x19, - 0x9e, 0xb8, 0xa3, 0x16, 0x23, 0x29, 0xc1, 0x54, 0x6e, 0x12, 0xfb, 0x79, 0xa8, 0xc4, 0xed, 0x0d, - 0x37, 0x6c, 0x3a, 0x5e, 0xc0, 0x1c, 0xdf, 0xfa, 0xa3, 0xc9, 0x12, 0x81, 0x53, 0x1a, 0x54, 0x83, - 0x11, 0x47, 0xbe, 0x17, 0x8e, 0x8a, 0x5c, 0x5a, 0x56, 0x0f, 0x85, 0x33, 0xaf, 0xa8, 0x7a, 0x21, - 0x5c, 0x71, 0x41, 0xaf, 0xc0, 0xb8, 0xb8, 0x75, 0x43, 0x22, 0xd6, 0xea, 0x93, 0x66, 0xc8, 0x77, - 0x5d, 0x22, 0xd9, 0x04, 0x33, 0x69, 0x67, 0x3e, 0x0b, 0x27, 0x3a, 0x96, 0x58, 0x5f, 0x81, 0x73, - 0xff, 0x6e, 0x00, 0x2a, 0xca, 0x43, 0x85, 0xe6, 0x4d, 0x67, 0xe4, 0xa3, 0x59, 0x67, 0xe4, 0x08, - 0x55, 0x08, 0x74, 0xff, 0xe3, 0x97, 0xbb, 0x3c, 0xda, 0xfa, 0x6c, 0xee, 0x9c, 0x2a, 0x7e, 0x8f, - 0xa5, 0x8f, 0xa7, 0x6d, 0x53, 0x2b, 0x65, 0xe0, 0x40, 0x2b, 0xa5, 0xe0, 0xbb, 0x54, 0xd4, 0x1e, - 0x69, 0x85, 0xee, 0x6a, 0x2d, 0xfb, 0xec, 0x4a, 0x8d, 0x02, 0x31, 0xc7, 0x31, 0x3d, 0x92, 0xee, - 0x11, 0x4c, 0x8f, 0x1c, 0x3e, 0xa4, 0x1e, 0x29, 0x19, 0xe0, 0x94, 0x17, 0xda, 0x81, 0x13, 0x0d, - 0xf3, 0x15, 0x1d, 0x75, 0x3b, 0xe5, 0xf9, 0x3e, 0x5e, 0xb1, 0x69, 0x6b, 0x2f, 0x06, 0x2c, 0x65, - 0xf9, 0xe1, 0xce, 0x2a, 0xd0, 0x2b, 0x30, 0xf2, 0x4e, 0x18, 0x2f, 0xf9, 0x4e, 0x1c, 0x0b, 0x41, - 0x29, 0x6f, 0x02, 0x8c, 0xbc, 0x76, 0xb3, 0xce, 0xe0, 0x0f, 0xf8, 0xb3, 0xfa, 0xf2, 0x2f, 0x56, - 0x05, 0xec, 0xdf, 0xe1, 0xde, 0x30, 0x61, 0x1f, 0x93, 0xb8, 0xed, 0x1f, 0x47, 0xe2, 0xec, 0x9b, - 0x86, 0xe9, 0xfe, 0x10, 0xfc, 0xb1, 0xff, 0xc1, 0x62, 0xfe, 0xd8, 0x75, 0xd2, 0x6c, 0xf9, 0x4e, - 0x72, 0x1c, 0x21, 0x8d, 0x5f, 0x82, 0x91, 0x44, 0xd4, 0x56, 0x2c, 0xeb, 0xb7, 0xd6, 0x3c, 0xe6, - 0xa7, 0x56, 0x32, 0x4e, 0x42, 0xb1, 0x62, 0x68, 0xff, 0x4b, 0xfe, 0x55, 0x24, 0xe6, 0x18, 0x8c, - 0xce, 0x1b, 0xa6, 0xd1, 0xf9, 0x4c, 0xe1, 0xbe, 0xf4, 0x30, 0x3e, 0xbf, 0x6f, 0xf6, 0x80, 0xa9, - 0xa2, 0x3f, 0x3d, 0x07, 0x06, 0xf6, 0x4d, 0x30, 0x5f, 0x1b, 0x42, 0xaf, 0xf2, 0x20, 0x61, 0x2e, - 0x64, 0x2f, 0xf4, 0x1d, 0x20, 0x6c, 0xff, 0x46, 0x09, 0x4e, 0x71, 0x97, 0xe1, 0xc2, 0x4e, 0xe8, - 0xb9, 0xb5, 0xd0, 0x15, 0x21, 0xd3, 0x2e, 0x8c, 0xb5, 0x34, 0x53, 0xa1, 0x58, 0x3e, 0x08, 0xdd, - 0xb8, 0x48, 0xd5, 0x33, 0x1d, 0x8a, 0x0d, 0xae, 0xb4, 0x16, 0xb2, 0xe3, 0x35, 0x94, 0x07, 0xaa, - 0xd4, 0xb7, 0xdc, 0x53, 0xb5, 0x2c, 0x6b, 0x7c, 0xb0, 0xc1, 0xf5, 0x08, 0x12, 0xd4, 0xdb, 0xbf, - 0x66, 0xc1, 0x23, 0x3d, 0x72, 0x46, 0xd0, 0xea, 0xee, 0x31, 0x37, 0xad, 0x78, 0xce, 0x4a, 0x55, - 0xc7, 0x9d, 0xb7, 0x58, 0x60, 0xd1, 0x06, 0x00, 0x77, 0xbe, 0xb2, 0x87, 0x83, 0x4b, 0x45, 0x62, - 0x25, 0x3a, 0xee, 0x66, 0x6b, 0xd7, 0x76, 0xd5, 0x53, 0xc1, 0x1a, 0x57, 0xfb, 0xdb, 0x65, 0x18, - 0xe4, 0x6f, 0x97, 0xd6, 0x60, 0x78, 0x9b, 0x67, 0xae, 0xec, 0x2f, 0x71, 0x66, 0xaa, 0x0a, 0x72, - 0x00, 0x96, 0x6c, 0xd0, 0x1a, 0x9c, 0xa4, 0x7a, 0x87, 0xe7, 0xf8, 0x55, 0xe2, 0x3b, 0xbb, 0xd2, - 0xb6, 0xe0, 0x59, 0xcb, 0x65, 0x82, 0xdd, 0x93, 0xab, 0x9d, 0x24, 0xb8, 0x5b, 0x39, 0xf4, 0x6a, - 0x47, 0xca, 0x29, 0x9e, 0x11, 0x54, 0xdd, 0xf6, 0x3a, 0x38, 0xed, 0x14, 0xd5, 0x7e, 0x5a, 0x1d, - 0x56, 0x94, 0xf6, 0x38, 0xa5, 0x69, 0x39, 0x99, 0xb4, 0xa8, 0x0a, 0x53, 0x71, 0x9b, 0x9d, 0x5c, - 0xaf, 0x6f, 0x47, 0x24, 0xde, 0x0e, 0x7d, 0x57, 0xbc, 0xab, 0xa6, 0x34, 0xc6, 0x7a, 0x06, 0x8f, - 0x3b, 0x4a, 0x50, 0x2e, 0x9b, 0x8e, 0xe7, 0xb7, 0x23, 0x92, 0x72, 0x19, 0x32, 0xb9, 0xac, 0x64, - 0xf0, 0xb8, 0xa3, 0x84, 0xfd, 0x27, 0x16, 0x9c, 0xec, 0x12, 0xde, 0xc1, 0x83, 0x0e, 0xb7, 0xbc, - 0x38, 0x51, 0xb9, 0xa9, 0xb5, 0xa0, 0x43, 0x0e, 0xc7, 0x8a, 0x82, 0xce, 0x42, 0x6e, 0x1a, 0x67, - 0x8f, 0x4d, 0xc5, 0x01, 0xb6, 0xc0, 0xf6, 0x97, 0x40, 0x0a, 0x9d, 0x83, 0x81, 0x76, 0x4c, 0xe4, - 0xa3, 0xff, 0x4a, 0x44, 0x31, 0x6f, 0x08, 0xc3, 0x50, 0x65, 0x67, 0x4b, 0x39, 0x22, 0x34, 0x65, - 0x87, 0xbb, 0x22, 0x38, 0xce, 0xfe, 0x66, 0x19, 0x26, 0x33, 0x61, 0x5e, 0xb4, 0x21, 0xcd, 0x30, - 0xf0, 0x92, 0x50, 0x25, 0x2d, 0xe2, 0x2f, 0xc3, 0x90, 0xd6, 0xf6, 0x9a, 0x80, 0x63, 0x45, 0x81, - 0x9e, 0x36, 0x1f, 0x92, 0x4e, 0xdb, 0xbc, 0x58, 0x35, 0x5e, 0xb3, 0x2b, 0x9a, 0x2f, 0xff, 0x49, - 0x18, 0x68, 0x85, 0xea, 0x65, 0x52, 0x35, 0xe9, 0xf1, 0x62, 0xb5, 0x16, 0x86, 0x3e, 0x66, 0x48, - 0xf4, 0x94, 0xe8, 0x7d, 0xc6, 0x7f, 0x8b, 0x1d, 0x37, 0x8c, 0xb5, 0x21, 0x78, 0x06, 0x86, 0xef, - 0x92, 0xdd, 0xc8, 0x0b, 0xb6, 0xb2, 0xde, 0xeb, 0x6b, 0x1c, 0x8c, 0x25, 0xde, 0xcc, 0x89, 0x3f, - 0x7c, 0xc4, 0x39, 0xf1, 0x47, 0x72, 0x23, 0x55, 0x7f, 0xd3, 0x82, 0x49, 0x96, 0xc9, 0x4f, 0x5c, - 0xa4, 0xf5, 0xc2, 0xe0, 0x18, 0xb6, 0xc7, 0x27, 0x61, 0x30, 0xa2, 0x95, 0x66, 0xd3, 0x5a, 0xb3, - 0x96, 0x60, 0x8e, 0x43, 0x8f, 0x01, 0x7b, 0xe7, 0x9f, 0x7d, 0xc6, 0x31, 0x9e, 0x26, 0x38, 0x7d, - 0xfd, 0x9f, 0xdd, 0x8a, 0xc0, 0xa4, 0xe5, 0x7b, 0xbc, 0xd1, 0xa9, 0xd3, 0xe9, 0xc3, 0x76, 0x2b, - 0xa2, 0x6b, 0x23, 0x1f, 0xd6, 0xad, 0x88, 0xee, 0xcc, 0x0f, 0x56, 0x51, 0xff, 0x47, 0x09, 0xce, - 0x76, 0x2d, 0x97, 0x9e, 0x83, 0xad, 0x18, 0xe7, 0x60, 0x97, 0x32, 0xe7, 0x60, 0xf6, 0xc1, 0xa5, - 0x1f, 0xce, 0xc9, 0x58, 0xf7, 0x03, 0xab, 0xf2, 0x31, 0x1e, 0x58, 0x0d, 0x14, 0x55, 0x1d, 0x06, - 0x73, 0x54, 0x87, 0x3f, 0xb0, 0xe0, 0xd1, 0xae, 0x43, 0xf6, 0xa1, 0xbb, 0x86, 0xd2, 0xb5, 0x95, - 0x3d, 0x14, 0xeb, 0x5f, 0x2c, 0xf7, 0xe8, 0x15, 0x53, 0xb1, 0xcf, 0x53, 0x29, 0xc4, 0x90, 0xb1, - 0x50, 0x8a, 0xc6, 0xb8, 0x04, 0xe2, 0x30, 0xac, 0xb0, 0x28, 0xd6, 0xae, 0x71, 0xf0, 0x46, 0x2e, - 0x1f, 0x72, 0x41, 0xcd, 0x99, 0xde, 0x42, 0xfd, 0x7e, 0x70, 0xe6, 0x72, 0x07, 0xba, 0xa3, 0x19, - 0x4d, 0xe5, 0xc3, 0x18, 0x4d, 0x63, 0xdd, 0x0d, 0x26, 0xb4, 0x00, 0x93, 0x4d, 0x2f, 0x60, 0x4f, - 0xe9, 0x99, 0x5a, 0x89, 0xba, 0x4b, 0xb7, 0x66, 0xa2, 0x71, 0x96, 0x7e, 0xe6, 0x15, 0x18, 0x3f, - 0xbc, 0x4f, 0xe6, 0xfd, 0x32, 0x7c, 0xf4, 0x00, 0xa1, 0xc0, 0x77, 0x07, 0xe3, 0xbb, 0x68, 0xbb, - 0x43, 0xc7, 0xb7, 0xa9, 0xc1, 0xa9, 0xcd, 0xb6, 0xef, 0xef, 0xb2, 0x28, 0x12, 0xe2, 0x4a, 0x0a, - 0xa1, 0xf1, 0xa9, 0x47, 0x6e, 0x57, 0xba, 0xd0, 0xe0, 0xae, 0x25, 0xd1, 0xe7, 0x01, 0x85, 0x1b, - 0x2c, 0xd7, 0xa5, 0x9b, 0xde, 0x7f, 0x66, 0x9f, 0xa0, 0x9c, 0x2e, 0xd5, 0x9b, 0x1d, 0x14, 0xb8, - 0x4b, 0x29, 0xaa, 0xff, 0xb1, 0xf7, 0x71, 0x55, 0xb3, 0x32, 0xfa, 0x1f, 0xd6, 0x91, 0xd8, 0xa4, - 0x45, 0x57, 0xe0, 0x84, 0xb3, 0xe3, 0x78, 0x3c, 0x7b, 0x8d, 0x64, 0xc0, 0x15, 0x40, 0xe5, 0xf5, - 0x58, 0xc8, 0x12, 0xe0, 0xce, 0x32, 0xa8, 0x65, 0xb8, 0xb1, 0x78, 0x6e, 0xeb, 0xcf, 0x1c, 0x62, - 0x06, 0x17, 0x76, 0x6c, 0xd9, 0x3f, 0xb6, 0xe8, 0xd6, 0xd7, 0xe5, 0xd5, 0x35, 0xe3, 0xb9, 0x76, - 0xed, 0x6a, 0x4b, 0xe7, 0x73, 0xed, 0xdc, 0x1f, 0x68, 0xd0, 0xf2, 0xa9, 0x11, 0xa7, 0xc1, 0xa8, - 0x86, 0xb6, 0x29, 0x6e, 0x74, 0x29, 0x0a, 0x74, 0x07, 0x86, 0x5d, 0x6f, 0xc7, 0x8b, 0xc3, 0xa8, - 0xc0, 0x03, 0xc9, 0x1d, 0x01, 0x8e, 0xa9, 0xb4, 0xac, 0x72, 0x26, 0x58, 0x72, 0xb3, 0x7f, 0xa5, - 0x04, 0xe3, 0xb2, 0xbe, 0xd7, 0xda, 0x61, 0xe2, 0x1c, 0xc3, 0x86, 0xfe, 0x9a, 0xb1, 0xa1, 0xcf, - 0x17, 0xbb, 0xde, 0xc6, 0x1a, 0xd7, 0x73, 0x23, 0xff, 0x42, 0x66, 0x23, 0xbf, 0xd8, 0x0f, 0xd3, - 0x83, 0x37, 0xf0, 0x7f, 0x63, 0xc1, 0x09, 0x83, 0xfe, 0x18, 0xf6, 0x91, 0x9a, 0xb9, 0x8f, 0x3c, - 0xd7, 0x47, 0x6f, 0x7a, 0xec, 0x1f, 0xdf, 0x2e, 0x65, 0x7a, 0xc1, 0xf6, 0x8d, 0xaf, 0xc0, 0xc0, - 0xb6, 0x13, 0xb9, 0xc5, 0xd2, 0xb8, 0x75, 0x14, 0x9f, 0xbb, 0xea, 0x44, 0x2e, 0x97, 0xfe, 0x17, - 0xd4, 0x9b, 0x30, 0x4e, 0xe4, 0xe6, 0x46, 0x68, 0xb3, 0x4a, 0xd1, 0x65, 0x18, 0x8a, 0x1b, 0x61, - 0x4b, 0xc5, 0xc2, 0x9d, 0xe3, 0xef, 0xc5, 0x50, 0xc8, 0x83, 0xbd, 0x59, 0x64, 0x56, 0x47, 0xc1, - 0x58, 0xd0, 0xcf, 0x10, 0xa8, 0xa8, 0xaa, 0x8f, 0x30, 0x16, 0xf8, 0xfd, 0x32, 0x9c, 0xec, 0x32, - 0x53, 0xd0, 0x57, 0x8d, 0x51, 0x7b, 0xa5, 0xef, 0xa9, 0xf6, 0x01, 0xc7, 0xed, 0xab, 0xcc, 0x4a, - 0x72, 0xc5, 0xdc, 0x38, 0x44, 0xf5, 0xb7, 0x62, 0x92, 0xad, 0x9e, 0x82, 0xf2, 0xab, 0xa7, 0xd5, - 0x1e, 0xd3, 0xe0, 0xd3, 0x6a, 0x54, 0x3b, 0x8f, 0xf0, 0x1b, 0xbf, 0x37, 0x00, 0xa7, 0xba, 0xdd, - 0xa0, 0x45, 0x3f, 0x6f, 0x65, 0xb2, 0xb4, 0xbf, 0xda, 0xff, 0x35, 0x5c, 0x9e, 0xba, 0x5d, 0x64, - 0x9d, 0x98, 0x33, 0xf3, 0xb6, 0xe7, 0x8e, 0xb6, 0xa8, 0x9d, 0xdd, 0xaa, 0x88, 0x78, 0xbe, 0x7d, - 0x29, 0x0f, 0x3e, 0x77, 0x88, 0xa6, 0x88, 0x94, 0xfd, 0x71, 0xe6, 0x56, 0x85, 0x04, 0xe7, 0xdf, - 0xaa, 0x90, 0x6d, 0x98, 0xd9, 0x82, 0x51, 0xad, 0x5f, 0x47, 0x38, 0x05, 0x3c, 0xba, 0x35, 0x69, - 0xad, 0x3e, 0xc2, 0x69, 0xf0, 0xcb, 0x16, 0x64, 0xc2, 0x55, 0x94, 0x2b, 0xc6, 0xea, 0xe9, 0x8a, - 0x39, 0x07, 0x03, 0x51, 0xe8, 0x93, 0x6c, 0xf6, 0x70, 0x1c, 0xfa, 0x04, 0x33, 0x8c, 0x7a, 0x1a, - 0xb2, 0xdc, 0xeb, 0x69, 0x48, 0x6a, 0x9b, 0xfb, 0x64, 0x87, 0x48, 0xc7, 0x88, 0x12, 0xde, 0xd7, - 0x29, 0x10, 0x73, 0x9c, 0xfd, 0xfb, 0x65, 0x18, 0xe2, 0xde, 0x87, 0x63, 0xd8, 0x9d, 0x6b, 0xc2, - 0x11, 0x50, 0xe8, 0x56, 0x2b, 0x6f, 0xd5, 0x5c, 0xd5, 0x49, 0x1c, 0x3e, 0xb1, 0x54, 0x1f, 0x53, - 0xe7, 0x01, 0x9a, 0x33, 0x46, 0x61, 0x26, 0x63, 0xdf, 0x02, 0xe7, 0xa1, 0x8d, 0xc9, 0x36, 0x40, - 0xcc, 0x1e, 0x23, 0xa3, 0x3c, 0x44, 0xce, 0xbd, 0x17, 0x0b, 0xb5, 0xa3, 0xae, 0x8a, 0xf1, 0xd6, - 0xa4, 0xc9, 0xbe, 0x14, 0x02, 0x6b, 0xbc, 0x67, 0x5e, 0x86, 0x8a, 0x22, 0xce, 0x53, 0xfc, 0xc7, - 0xf4, 0xa9, 0xf9, 0x17, 0x60, 0x32, 0x53, 0x57, 0x5f, 0x76, 0xc3, 0x2f, 0x59, 0x30, 0x99, 0x79, - 0x45, 0x19, 0xbd, 0x67, 0xc1, 0x29, 0xbf, 0x8b, 0xf3, 0x49, 0x7c, 0xe6, 0xc3, 0xb8, 0xad, 0x94, - 0xc9, 0xd0, 0x0d, 0x8b, 0xbb, 0xd6, 0x66, 0xff, 0x96, 0x05, 0x27, 0x3a, 0x9e, 0xdf, 0xfd, 0x90, - 0x34, 0x4e, 0x26, 0x38, 0x2d, 0x75, 0x4f, 0x70, 0x6a, 0xff, 0x86, 0x05, 0x62, 0x36, 0x1d, 0x83, - 0x8e, 0xb6, 0x6a, 0xea, 0x68, 0x1f, 0x2b, 0x32, 0x41, 0x7b, 0x28, 0x67, 0xbf, 0x67, 0x01, 0xe2, - 0x04, 0xd9, 0xe7, 0x12, 0xb9, 0xa3, 0x51, 0x33, 0x2e, 0xd2, 0x19, 0xad, 0x30, 0x58, 0xa3, 0xea, - 0x33, 0xf7, 0xbd, 0x7a, 0x66, 0xac, 0x7b, 0xc3, 0xd0, 0x45, 0x18, 0x15, 0xcf, 0x0c, 0xad, 0xa5, - 0x4f, 0x88, 0x4d, 0xb2, 0xc7, 0x2c, 0x53, 0x30, 0xd6, 0x69, 0xec, 0xdf, 0x29, 0x43, 0x36, 0xe8, - 0x04, 0xbd, 0x05, 0x63, 0x0d, 0xa7, 0xe5, 0x6c, 0x78, 0xbe, 0x97, 0x78, 0x24, 0x2e, 0x76, 0xd8, - 0xb5, 0xa4, 0x95, 0x10, 0xae, 0x6a, 0x0d, 0x82, 0x0d, 0x8e, 0x68, 0x0e, 0xa0, 0x15, 0x79, 0x3b, - 0x9e, 0x4f, 0xb6, 0x98, 0x66, 0xc4, 0xa2, 0x56, 0xf9, 0xb9, 0x8d, 0x84, 0x62, 0x8d, 0xa2, 0x4b, - 0x94, 0x63, 0xf9, 0x38, 0xa2, 0x1c, 0x07, 0xfa, 0x8c, 0x72, 0x1c, 0x2c, 0x14, 0xe5, 0x88, 0xe1, - 0x8c, 0xf4, 0x30, 0xd3, 0xff, 0x2b, 0x9e, 0x4f, 0x78, 0x42, 0x43, 0x11, 0xd5, 0x3a, 0xb3, 0xbf, - 0x37, 0x7b, 0x06, 0x77, 0xa5, 0xc0, 0x3d, 0x4a, 0xda, 0x6d, 0x38, 0x59, 0x27, 0x91, 0xc7, 0xf2, - 0x4c, 0xb9, 0xe9, 0x02, 0xfc, 0x32, 0x54, 0xa2, 0xcc, 0xda, 0xef, 0xf3, 0xca, 0xa1, 0x96, 0x99, - 0x44, 0xae, 0xf5, 0x94, 0xa5, 0xfd, 0x57, 0x4b, 0x30, 0x2c, 0x82, 0xbb, 0x8e, 0x61, 0xab, 0xbb, - 0x66, 0x18, 0xa2, 0xcf, 0xe4, 0xad, 0x60, 0xd6, 0xac, 0x9e, 0x26, 0x68, 0x3d, 0x63, 0x82, 0x3e, - 0x57, 0x8c, 0xdd, 0xc1, 0xc6, 0xe7, 0x0f, 0x4a, 0x30, 0x61, 0x06, 0xbb, 0x1d, 0xc3, 0xb0, 0xbc, - 0x0e, 0xc3, 0xb1, 0x88, 0x04, 0x2b, 0x15, 0x89, 0x63, 0xc9, 0x7e, 0x62, 0xe5, 0x6d, 0x90, 0xb1, - 0x5f, 0x92, 0x5d, 0xd7, 0x60, 0xb3, 0xf2, 0x71, 0x04, 0x9b, 0xd9, 0xbf, 0xcb, 0x44, 0xac, 0x3e, - 0x90, 0xc7, 0xb0, 0x45, 0xbc, 0x66, 0x0a, 0xe3, 0x0b, 0x85, 0x66, 0x84, 0x68, 0x5e, 0x8f, 0xad, - 0xe2, 0xbb, 0x16, 0x8c, 0x0a, 0xc2, 0x63, 0xe8, 0xc0, 0xe7, 0xcd, 0x0e, 0x3c, 0x55, 0xa8, 0x03, - 0x3d, 0x5a, 0xfe, 0xb7, 0x4b, 0xaa, 0xe5, 0x35, 0xf1, 0xa8, 0x6c, 0x6e, 0xbe, 0xcb, 0x91, 0x56, - 0x14, 0x26, 0x61, 0x23, 0xf4, 0xc5, 0x96, 0xff, 0x58, 0x7a, 0xbd, 0x80, 0xc3, 0x1f, 0x68, 0xbf, - 0xb1, 0xa2, 0x66, 0xd1, 0xef, 0x61, 0x94, 0x88, 0x0d, 0xab, 0xdb, 0x93, 0xb6, 0x1b, 0xf2, 0xc9, - 0x70, 0x0a, 0x13, 0x37, 0x73, 0xfa, 0x7d, 0x2a, 0x37, 0xbd, 0x2d, 0xa0, 0x38, 0x61, 0x8d, 0xab, - 0x0c, 0x43, 0x65, 0x35, 0x0c, 0x9a, 0xde, 0xdf, 0x1b, 0x02, 0x8e, 0x15, 0x85, 0xfd, 0x32, 0x93, - 0xb8, 0x6c, 0x78, 0xfa, 0x0b, 0xe4, 0xff, 0x2b, 0x43, 0x6a, 0x60, 0x99, 0x53, 0xe7, 0x86, 0x7e, - 0x5d, 0xa0, 0xa8, 0x58, 0xa3, 0x4d, 0xd0, 0x23, 0xe7, 0xd2, 0xdb, 0x05, 0x88, 0x74, 0x1c, 0x19, - 0xbc, 0x5c, 0x58, 0x52, 0xf6, 0x71, 0x48, 0xc0, 0x92, 0x04, 0xb1, 0xcc, 0x28, 0xab, 0xb5, 0x6c, - 0x8e, 0xd2, 0x25, 0x89, 0xc0, 0x29, 0x0d, 0x9a, 0x17, 0x66, 0x85, 0xf9, 0xe2, 0xb0, 0x34, 0x2b, - 0xe4, 0x90, 0x68, 0x76, 0xc5, 0x45, 0x18, 0x55, 0x59, 0xda, 0x6b, 0x3c, 0xd9, 0x76, 0x85, 0x6b, - 0x33, 0xcb, 0x29, 0x18, 0xeb, 0x34, 0x68, 0x15, 0x4e, 0xba, 0x2a, 0xea, 0xb8, 0xd6, 0xde, 0xf0, - 0xbd, 0x06, 0x2d, 0xca, 0x6f, 0x0c, 0x3d, 0xb2, 0xbf, 0x37, 0x7b, 0xb2, 0xda, 0x89, 0xc6, 0xdd, - 0xca, 0xa0, 0x75, 0x98, 0x8c, 0x79, 0x36, 0x7a, 0x19, 0x5a, 0x2a, 0x52, 0xf7, 0x3d, 0x2b, 0xcf, - 0x2a, 0xea, 0x26, 0xfa, 0x01, 0x03, 0x71, 0x99, 0x20, 0x83, 0x51, 0xb3, 0x2c, 0xd0, 0xab, 0x30, - 0xe1, 0xeb, 0x0f, 0x6d, 0xd5, 0x44, 0xf0, 0xb5, 0x8a, 0xea, 0x30, 0x9e, 0xe1, 0xaa, 0xe1, 0x0c, - 0x35, 0x7a, 0x1d, 0xa6, 0x75, 0x88, 0xc8, 0x60, 0xe0, 0x04, 0x5b, 0x24, 0x16, 0x69, 0xb0, 0x1f, - 0xdb, 0xdf, 0x9b, 0x9d, 0xbe, 0xde, 0x83, 0x06, 0xf7, 0x2c, 0x8d, 0x2e, 0xc3, 0x98, 0x1c, 0x49, - 0x2d, 0x10, 0x3b, 0x8d, 0x27, 0xd2, 0x70, 0xd8, 0xa0, 0xfc, 0x60, 0x47, 0x32, 0x5f, 0xa1, 0x85, - 0xb5, 0xad, 0x15, 0xbd, 0x0d, 0x63, 0x7a, 0x1b, 0xb3, 0x7b, 0x66, 0xfe, 0xe3, 0x65, 0x62, 0x8b, - 0x56, 0x2d, 0xd7, 0x71, 0xd8, 0xe0, 0x6d, 0xdf, 0x84, 0xa1, 0xfa, 0x6e, 0xdc, 0x48, 0xfc, 0x87, - 0xf5, 0xd8, 0x74, 0x03, 0x26, 0x33, 0xaf, 0x32, 0xab, 0xe7, 0xbd, 0xad, 0x87, 0xf5, 0xbc, 0xb7, - 0xfd, 0x35, 0x0b, 0x06, 0xd7, 0x1d, 0x2f, 0xff, 0x01, 0x89, 0x22, 0x4d, 0x46, 0x2f, 0xc1, 0x10, - 0xd9, 0xdc, 0x24, 0x0d, 0xf9, 0x5c, 0xf8, 0xe3, 0x52, 0xb5, 0x59, 0x66, 0x50, 0xba, 0x34, 0x59, - 0x65, 0xfc, 0x2f, 0x16, 0xc4, 0xf6, 0xbf, 0xb7, 0x00, 0xd6, 0x43, 0x5f, 0x9e, 0x36, 0xe5, 0xb4, - 0x64, 0xb1, 0xe3, 0x29, 0x8b, 0xa7, 0xbb, 0x3c, 0x65, 0x81, 0x52, 0x86, 0x5d, 0x1e, 0xb2, 0x50, - 0xbd, 0x29, 0x17, 0xea, 0xcd, 0x40, 0x3f, 0xbd, 0xf9, 0x86, 0x05, 0x22, 0x10, 0xa8, 0xc0, 0x4c, - 0x70, 0x65, 0xfa, 0x79, 0x23, 0x37, 0xc9, 0xb3, 0x45, 0x2e, 0xec, 0x88, 0x8c, 0x24, 0x6a, 0x6e, - 0x1a, 0x79, 0x48, 0x0c, 0xae, 0xd4, 0xb0, 0x1f, 0xe5, 0xe8, 0x35, 0xa6, 0x47, 0xe6, 0xb7, 0xab, - 0xaf, 0x2c, 0x6c, 0x2c, 0x3b, 0x3b, 0x65, 0xac, 0xb2, 0x71, 0xe9, 0xd9, 0xd9, 0x25, 0x02, 0xa7, - 0x34, 0xe8, 0x19, 0x18, 0x8e, 0xdb, 0x1b, 0x8c, 0x3c, 0x13, 0x15, 0x54, 0xe7, 0x60, 0x2c, 0xf1, - 0xf6, 0xcf, 0x21, 0x30, 0xba, 0x66, 0x64, 0xfe, 0xb2, 0x1e, 0x7a, 0xe6, 0xaf, 0x37, 0x60, 0x84, - 0x34, 0x5b, 0xc9, 0x6e, 0xd5, 0x8b, 0x8a, 0xe5, 0x60, 0x5c, 0x16, 0xd4, 0x9d, 0xdc, 0x25, 0x06, - 0x2b, 0x8e, 0x3d, 0xf2, 0xb8, 0x95, 0x3f, 0x14, 0x79, 0xdc, 0x06, 0x7e, 0x22, 0x79, 0xdc, 0x5e, - 0x87, 0xe1, 0x2d, 0x2f, 0xc1, 0xa4, 0x15, 0x8a, 0x1b, 0x9e, 0x39, 0xc7, 0x77, 0x57, 0x38, 0x71, - 0x67, 0x72, 0x26, 0x81, 0xc0, 0x92, 0x1d, 0x5a, 0x87, 0x21, 0x6e, 0x7b, 0x88, 0xd4, 0x68, 0x9f, - 0x28, 0xe2, 0xa5, 0xe9, 0xcc, 0x12, 0x26, 0x42, 0xbf, 0x04, 0x2f, 0x99, 0xb7, 0x6d, 0xf8, 0x83, - 0xe7, 0x6d, 0x53, 0xd9, 0xd6, 0x46, 0x1e, 0x56, 0xb6, 0x35, 0x23, 0x6b, 0x5d, 0xe5, 0x28, 0xb2, - 0xd6, 0x7d, 0xc3, 0x82, 0xd3, 0xad, 0x6e, 0x39, 0x1f, 0x45, 0xde, 0xb4, 0xcf, 0x1e, 0x22, 0x07, - 0xa6, 0x51, 0x35, 0xbb, 0x37, 0xd7, 0x95, 0x0c, 0x77, 0xaf, 0x58, 0xa6, 0xbf, 0x1b, 0xfd, 0xe0, - 0xe9, 0xef, 0x8e, 0x3a, 0xc1, 0x5a, 0x9a, 0x0c, 0x6f, 0xfc, 0x48, 0x92, 0xe1, 0x4d, 0x3c, 0xc4, - 0x64, 0x78, 0x5a, 0x1a, 0xbb, 0xc9, 0x87, 0x9b, 0xc6, 0x6e, 0x1b, 0x46, 0xdd, 0xf0, 0x5e, 0x70, - 0xcf, 0x89, 0xdc, 0x85, 0xda, 0xaa, 0xc8, 0x9a, 0x96, 0x93, 0x9a, 0xa3, 0x9a, 0x16, 0x30, 0x6a, - 0xe0, 0xee, 0xc8, 0x14, 0x89, 0x75, 0xd6, 0x22, 0xa1, 0xdf, 0x89, 0x0f, 0x98, 0xd0, 0xcf, 0x48, - 0x8b, 0x87, 0x8e, 0x22, 0x2d, 0xde, 0x5b, 0xec, 0x8e, 0xfe, 0xa6, 0xb7, 0xb5, 0xe6, 0xb4, 0xd8, - 0xbd, 0xb2, 0xdc, 0x1a, 0x96, 0x24, 0x79, 0x67, 0x0d, 0x0a, 0x85, 0x53, 0xa6, 0x9d, 0x89, 0xf7, - 0x4e, 0x1d, 0x77, 0xe2, 0xbd, 0xd3, 0x47, 0x98, 0x78, 0xef, 0xcc, 0xb1, 0x26, 0xde, 0x7b, 0xe4, - 0x27, 0x92, 0x78, 0xef, 0x2f, 0xc1, 0xd9, 0x83, 0x3f, 0x47, 0x9a, 0xd8, 0xb9, 0x96, 0xba, 0x0c, - 0x32, 0x89, 0x9d, 0x99, 0xaa, 0xa3, 0x51, 0x15, 0xce, 0xff, 0xf5, 0x1d, 0x0b, 0x1e, 0xe9, 0x91, - 0x1e, 0xa7, 0xf0, 0x95, 0x8c, 0x16, 0x4c, 0xb6, 0xcc, 0xa2, 0x85, 0x2f, 0x51, 0x19, 0xe9, 0x78, - 0x54, 0x78, 0x5f, 0x06, 0x81, 0xb3, 0xec, 0x17, 0x3f, 0xf6, 0xc3, 0xf7, 0xcf, 0x7e, 0xe4, 0x47, - 0xef, 0x9f, 0xfd, 0xc8, 0x1f, 0xbd, 0x7f, 0xf6, 0x23, 0x3f, 0xb3, 0x7f, 0xd6, 0xfa, 0xe1, 0xfe, - 0x59, 0xeb, 0x47, 0xfb, 0x67, 0xad, 0x3f, 0xd9, 0x3f, 0x6b, 0x7d, 0xe3, 0x4f, 0xcf, 0x7e, 0xe4, - 0x8b, 0xa5, 0x9d, 0x8b, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xab, 0xdd, 0x46, 0x9b, 0x8b, 0xb9, - 0x00, 0x00, + // 10271 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x24, 0xc7, + 0x95, 0x98, 0x7b, 0x86, 0x5f, 0xf3, 0xf8, 0xb9, 0xb5, 0x1f, 0xa2, 0x68, 0x69, 0xb9, 0x6a, 0x59, + 0xf2, 0x4a, 0x5a, 0x91, 0xde, 0x95, 0x64, 0xad, 0x2d, 0x47, 0x36, 0xc9, 0x21, 0x77, 0xe9, 0x25, + 0x77, 0x47, 0x35, 0xdc, 0x5d, 0xd9, 0x56, 0x2c, 0x35, 0xa7, 0x8b, 0x64, 0x6b, 0x9b, 0xdd, 0xa3, + 0xee, 0x1e, 0xee, 0x52, 0x8e, 0x81, 0x3b, 0x9f, 0x70, 0x87, 0x20, 0x4e, 0xe2, 0xe0, 0x60, 0xe0, + 0x90, 0x4b, 0xe0, 0x4b, 0x80, 0x04, 0x4e, 0x0e, 0xf9, 0x70, 0x9c, 0x3b, 0xfb, 0x70, 0x4e, 0x82, + 0x24, 0x77, 0x8e, 0x2f, 0x1f, 0x07, 0x07, 0x07, 0xe4, 0x2e, 0x67, 0x80, 0x39, 0xf1, 0x82, 0xfc, + 0xcc, 0x8f, 0xe4, 0x1f, 0x13, 0x24, 0x41, 0x7d, 0x76, 0x55, 0xcf, 0x0c, 0xbb, 0x87, 0x5a, 0xd2, + 0xf2, 0x21, 0xff, 0x66, 0xde, 0x7b, 0xf5, 0xea, 0xa3, 0x5f, 0x55, 0xbd, 0xf7, 0xea, 0xd5, 0x2b, + 0xb8, 0x74, 0xef, 0x6a, 0x3c, 0xe3, 0x85, 0xb3, 0xf7, 0x5a, 0xeb, 0x24, 0x0a, 0x48, 0x42, 0xe2, + 0xd9, 0xe6, 0xbd, 0xcd, 0x59, 0xa7, 0xe9, 0xcd, 0xee, 0x5c, 0x9e, 0xdd, 0x24, 0x01, 0x89, 0x9c, + 0x84, 0xb8, 0x33, 0xcd, 0x28, 0x4c, 0x42, 0xf4, 0x18, 0xa7, 0x9e, 0x49, 0xa9, 0x67, 0x9a, 0xf7, + 0x36, 0x67, 0x9c, 0xa6, 0x37, 0xb3, 0x73, 0x79, 0xea, 0xf9, 0x4d, 0x2f, 0xd9, 0x6a, 0xad, 0xcf, + 0x34, 0xc2, 0xed, 0xd9, 0xcd, 0x70, 0x33, 0x9c, 0x65, 0x85, 0xd6, 0x5b, 0x1b, 0xec, 0x1f, 0xfb, + 0xc3, 0x7e, 0x71, 0x66, 0x53, 0x2f, 0x8a, 0xaa, 0x9d, 0xa6, 0xb7, 0xed, 0x34, 0xb6, 0xbc, 0x80, + 0x44, 0xbb, 0xb2, 0xf2, 0x78, 0x76, 0x9b, 0x24, 0x4e, 0x87, 0x26, 0x4c, 0xcd, 0x76, 0x2b, 0x15, + 0xb5, 0x82, 0xc4, 0xdb, 0x26, 0x6d, 0x05, 0x3e, 0x99, 0x57, 0x20, 0x6e, 0x6c, 0x91, 0x6d, 0xa7, + 0xad, 0xdc, 0x95, 0xee, 0x23, 0x13, 0x91, 0x38, 0x6c, 0x45, 0x8d, 0xf6, 0xba, 0x2e, 0x77, 0x2e, + 0xd3, 0x4a, 0x3c, 0x7f, 0xd6, 0x0b, 0x92, 0x38, 0x89, 0xb2, 0x45, 0xec, 0x3f, 0xb4, 0xe0, 0xc2, + 0xdc, 0xdd, 0xfa, 0xa2, 0xef, 0xc4, 0x89, 0xd7, 0x98, 0xf7, 0xc3, 0xc6, 0xbd, 0x7a, 0x12, 0x46, + 0xe4, 0x4e, 0xe8, 0xb7, 0xb6, 0x49, 0x9d, 0xd5, 0x83, 0x2e, 0xc1, 0xd0, 0x0e, 0xfb, 0xbf, 0x5c, + 0x9d, 0xb4, 0x2e, 0x58, 0x17, 0x2b, 0xf3, 0x13, 0x3f, 0xda, 0x9b, 0xfe, 0xc8, 0xfe, 0xde, 0xf4, + 0xd0, 0x1d, 0x01, 0xc7, 0x8a, 0x02, 0x3d, 0x0d, 0x03, 0x1b, 0xf1, 0xda, 0x6e, 0x93, 0x4c, 0x96, + 0x18, 0xed, 0x98, 0xa0, 0x1d, 0x58, 0xaa, 0x53, 0x28, 0x16, 0x58, 0x34, 0x0b, 0x95, 0xa6, 0x13, + 0x25, 0x5e, 0xe2, 0x85, 0xc1, 0x64, 0xf9, 0x82, 0x75, 0xb1, 0x7f, 0xfe, 0x94, 0x20, 0xad, 0xd4, + 0x24, 0x02, 0xa7, 0x34, 0xb4, 0x19, 0x11, 0x71, 0xdc, 0x5b, 0x81, 0xbf, 0x3b, 0xd9, 0x77, 0xc1, + 0xba, 0x38, 0x94, 0x36, 0x03, 0x0b, 0x38, 0x56, 0x14, 0xf6, 0xf7, 0x4b, 0x30, 0x34, 0xb7, 0xb1, + 0xe1, 0x05, 0x5e, 0xb2, 0x8b, 0xde, 0x82, 0x91, 0x20, 0x74, 0x89, 0xfc, 0xcf, 0x7a, 0x31, 0x7c, + 0xe5, 0xd9, 0x99, 0xc3, 0x04, 0x6a, 0xe6, 0xa6, 0x56, 0x62, 0x7e, 0x62, 0x7f, 0x6f, 0x7a, 0x44, + 0x87, 0x60, 0x83, 0x23, 0x7a, 0x03, 0x86, 0x9b, 0xa1, 0xab, 0x2a, 0x28, 0xb1, 0x0a, 0x9e, 0x39, + 0xbc, 0x82, 0x5a, 0x5a, 0x60, 0x7e, 0x7c, 0x7f, 0x6f, 0x7a, 0x58, 0x03, 0x60, 0x9d, 0x1d, 0xf2, + 0x61, 0x9c, 0xfe, 0x0d, 0x12, 0x4f, 0xd5, 0x50, 0x66, 0x35, 0x3c, 0x9f, 0x5f, 0x83, 0x56, 0x68, + 0xfe, 0xf4, 0xfe, 0xde, 0xf4, 0x78, 0x06, 0x88, 0xb3, 0xac, 0xed, 0x77, 0x61, 0x6c, 0x2e, 0x49, + 0x9c, 0xc6, 0x16, 0x71, 0xf9, 0xf7, 0x45, 0x2f, 0x42, 0x5f, 0xe0, 0x6c, 0x13, 0xf1, 0xf5, 0x2f, + 0x88, 0x61, 0xef, 0xbb, 0xe9, 0x6c, 0x93, 0x83, 0xbd, 0xe9, 0x89, 0xdb, 0x81, 0xf7, 0x4e, 0x4b, + 0xc8, 0x0c, 0x85, 0x61, 0x46, 0x8d, 0xae, 0x00, 0xb8, 0x64, 0xc7, 0x6b, 0x90, 0x9a, 0x93, 0x6c, + 0x09, 0x69, 0x40, 0xa2, 0x2c, 0x54, 0x15, 0x06, 0x6b, 0x54, 0xf6, 0xd7, 0x2c, 0xa8, 0xcc, 0xed, + 0x84, 0x9e, 0x5b, 0x0b, 0xdd, 0x18, 0xb5, 0x60, 0xbc, 0x19, 0x91, 0x0d, 0x12, 0x29, 0xd0, 0xa4, + 0x75, 0xa1, 0x7c, 0x71, 0xf8, 0xca, 0x95, 0x9c, 0x7e, 0x9b, 0x85, 0x16, 0x83, 0x24, 0xda, 0x9d, + 0x7f, 0x44, 0x54, 0x3d, 0x9e, 0xc1, 0xe2, 0x6c, 0x1d, 0xf6, 0x5f, 0x2b, 0xc1, 0xd9, 0xb9, 0x77, + 0x5b, 0x11, 0xa9, 0x7a, 0xf1, 0xbd, 0xec, 0x54, 0x70, 0xbd, 0xf8, 0xde, 0xcd, 0x74, 0x30, 0x94, + 0x0c, 0x56, 0x05, 0x1c, 0x2b, 0x0a, 0xf4, 0x3c, 0x0c, 0xd2, 0xdf, 0xb7, 0xf1, 0xb2, 0xe8, 0xfd, + 0x69, 0x41, 0x3c, 0x5c, 0x75, 0x12, 0xa7, 0xca, 0x51, 0x58, 0xd2, 0xa0, 0x55, 0x18, 0x6e, 0xb0, + 0x35, 0x62, 0x73, 0x35, 0x74, 0x09, 0xfb, 0xc2, 0x95, 0xf9, 0xe7, 0x28, 0xf9, 0x42, 0x0a, 0x3e, + 0xd8, 0x9b, 0x9e, 0xe4, 0x6d, 0x13, 0x2c, 0x34, 0x1c, 0xd6, 0xcb, 0x23, 0x5b, 0x4d, 0xc4, 0x3e, + 0xc6, 0x09, 0x3a, 0x4c, 0xc2, 0x8b, 0xda, 0x9c, 0xea, 0x67, 0x73, 0x6a, 0xa4, 0xcb, 0x7c, 0xfa, + 0xfb, 0x96, 0x18, 0x93, 0x25, 0xcf, 0x37, 0x97, 0x87, 0x2b, 0x00, 0x31, 0x69, 0x44, 0x24, 0xd1, + 0x46, 0x45, 0x7d, 0xe6, 0xba, 0xc2, 0x60, 0x8d, 0x8a, 0x4e, 0xfe, 0x78, 0xcb, 0x89, 0x98, 0xb4, + 0x88, 0xb1, 0x51, 0x93, 0xbf, 0x2e, 0x11, 0x38, 0xa5, 0x31, 0x26, 0x7f, 0x39, 0x77, 0xf2, 0xff, + 0x2b, 0x0b, 0x06, 0xe7, 0xbd, 0xc0, 0xf5, 0x82, 0x4d, 0xf4, 0x16, 0x0c, 0xd1, 0xd5, 0xdc, 0x75, + 0x12, 0x47, 0xcc, 0xfb, 0x4f, 0x48, 0xe1, 0xd1, 0x17, 0x65, 0x29, 0x3e, 0xf1, 0x0c, 0xa5, 0xa6, + 0x42, 0x74, 0x6b, 0xfd, 0x6d, 0xd2, 0x48, 0x56, 0x49, 0xe2, 0xa4, 0xdd, 0x49, 0x61, 0x58, 0x71, + 0x45, 0xb7, 0x61, 0x20, 0x71, 0xa2, 0x4d, 0x92, 0x88, 0x69, 0x9f, 0x33, 0x29, 0x39, 0x0f, 0x4c, + 0x45, 0x8e, 0x04, 0x0d, 0x92, 0x2e, 0x90, 0x6b, 0x8c, 0x09, 0x16, 0xcc, 0xec, 0x06, 0x8c, 0x2c, + 0x38, 0x4d, 0x67, 0xdd, 0xf3, 0xbd, 0xc4, 0x23, 0x31, 0xfa, 0x38, 0x94, 0x1d, 0xd7, 0x65, 0x13, + 0xa0, 0x32, 0x7f, 0x76, 0x7f, 0x6f, 0xba, 0x3c, 0xe7, 0xba, 0x07, 0x7b, 0xd3, 0xa0, 0xa8, 0x76, + 0x31, 0xa5, 0x40, 0xcf, 0x42, 0x9f, 0x1b, 0x85, 0xcd, 0xc9, 0x12, 0xa3, 0x3c, 0x47, 0x67, 0x6a, + 0x35, 0x0a, 0x9b, 0x19, 0x52, 0x46, 0x63, 0xff, 0x6e, 0x09, 0xd0, 0x02, 0x69, 0x6e, 0x2d, 0xd5, + 0x8d, 0x6f, 0x7a, 0x11, 0x86, 0xb6, 0xc3, 0xc0, 0x4b, 0xc2, 0x28, 0x16, 0x15, 0x32, 0xb9, 0x58, + 0x15, 0x30, 0xac, 0xb0, 0xe8, 0x02, 0xf4, 0x35, 0xd3, 0xe9, 0x3d, 0x22, 0x97, 0x06, 0x36, 0xb1, + 0x19, 0x86, 0x52, 0xb4, 0x62, 0x12, 0x09, 0x79, 0x56, 0x14, 0xb7, 0x63, 0x12, 0x61, 0x86, 0x49, + 0x25, 0x88, 0xca, 0x96, 0x90, 0xd6, 0x8c, 0x04, 0x51, 0x0c, 0xd6, 0xa8, 0xd0, 0x9b, 0x50, 0xe1, + 0xff, 0x30, 0xd9, 0x60, 0xa2, 0x9b, 0xbb, 0x28, 0xac, 0x84, 0x0d, 0xc7, 0xcf, 0x0e, 0xfe, 0x28, + 0x93, 0x38, 0xc9, 0x08, 0xa7, 0x3c, 0x0d, 0x89, 0x1b, 0xc8, 0x95, 0xb8, 0x5f, 0xb1, 0x00, 0x2d, + 0x78, 0x81, 0x4b, 0xa2, 0x13, 0xd8, 0x3a, 0x7b, 0x9b, 0x0c, 0x3f, 0xa1, 0x4d, 0x0b, 0xb7, 0x9b, + 0x61, 0x40, 0x82, 0x64, 0x21, 0x0c, 0x5c, 0xbe, 0x9d, 0x7e, 0x1a, 0xfa, 0x12, 0x5a, 0x15, 0x6f, + 0xd6, 0xd3, 0xf2, 0xb3, 0xd0, 0x0a, 0x0e, 0xf6, 0xa6, 0xcf, 0xb5, 0x97, 0x60, 0x4d, 0x60, 0x65, + 0xd0, 0xa7, 0x60, 0x20, 0x4e, 0x9c, 0xa4, 0x15, 0x8b, 0x86, 0x3e, 0x21, 0x1b, 0x5a, 0x67, 0xd0, + 0x83, 0xbd, 0xe9, 0x71, 0x55, 0x8c, 0x83, 0xb0, 0x28, 0x80, 0x9e, 0x81, 0xc1, 0x6d, 0x12, 0xc7, + 0xce, 0xa6, 0x5c, 0xe0, 0xc6, 0x45, 0xd9, 0xc1, 0x55, 0x0e, 0xc6, 0x12, 0x8f, 0x9e, 0x84, 0x7e, + 0x12, 0x45, 0x61, 0x24, 0x24, 0x62, 0x54, 0x10, 0xf6, 0x2f, 0x52, 0x20, 0xe6, 0x38, 0xfb, 0x3f, + 0x5b, 0x30, 0xae, 0xda, 0xca, 0xeb, 0x3a, 0x81, 0x29, 0xef, 0x02, 0x34, 0x64, 0x07, 0x63, 0x36, + 0xd1, 0xb4, 0x3a, 0x3a, 0x8b, 0x5f, 0xfb, 0x80, 0xa6, 0x75, 0x28, 0x50, 0x8c, 0x35, 0xbe, 0xf6, + 0xbf, 0xb1, 0xe0, 0x74, 0xa6, 0x6f, 0x2b, 0x5e, 0x9c, 0xa0, 0x37, 0xda, 0xfa, 0x37, 0x53, 0xac, + 0x7f, 0xb4, 0x34, 0xeb, 0x9d, 0x92, 0x17, 0x09, 0xd1, 0xfa, 0x86, 0xa1, 0xdf, 0x4b, 0xc8, 0xb6, + 0xec, 0xd6, 0xf3, 0x05, 0xbb, 0xc5, 0xdb, 0x97, 0x7e, 0xa5, 0x65, 0xca, 0x03, 0x73, 0x56, 0xf6, + 0xff, 0xb2, 0xa0, 0xb2, 0x10, 0x06, 0x1b, 0xde, 0xe6, 0xaa, 0xd3, 0x3c, 0x81, 0xef, 0x53, 0x87, + 0x3e, 0xc6, 0x9d, 0x77, 0xe1, 0x72, 0x5e, 0x17, 0x44, 0xc3, 0x66, 0xe8, 0x9e, 0xca, 0x95, 0x05, + 0xb5, 0x4c, 0x51, 0x10, 0x66, 0xcc, 0xa6, 0x5e, 0x86, 0x8a, 0x22, 0x40, 0x13, 0x50, 0xbe, 0x47, + 0xb8, 0x26, 0x59, 0xc1, 0xf4, 0x27, 0x3a, 0x03, 0xfd, 0x3b, 0x8e, 0xdf, 0x12, 0x93, 0x17, 0xf3, + 0x3f, 0x9f, 0x2e, 0x5d, 0xb5, 0xec, 0x5f, 0x65, 0x33, 0x50, 0x54, 0xb2, 0x18, 0xec, 0x88, 0xc5, + 0xe1, 0x3d, 0x0b, 0xce, 0xf8, 0x1d, 0x16, 0x25, 0x31, 0x26, 0x47, 0x59, 0xce, 0x1e, 0x13, 0xcd, + 0x3e, 0xd3, 0x09, 0x8b, 0x3b, 0xd6, 0x66, 0xff, 0xc0, 0x82, 0x33, 0xaa, 0x75, 0x37, 0xc8, 0x6e, + 0x9d, 0xf8, 0xa4, 0x91, 0x84, 0xd1, 0x87, 0xa4, 0x7d, 0xe8, 0x71, 0x3e, 0xd2, 0x7c, 0xa5, 0x19, + 0x16, 0x0c, 0xca, 0x37, 0xc8, 0x2e, 0x1b, 0x76, 0xfb, 0xb7, 0x2d, 0x18, 0x55, 0xcd, 0x3f, 0x81, + 0xe9, 0xb1, 0x62, 0x4e, 0x8f, 0x8f, 0x17, 0x94, 0xad, 0x2e, 0x13, 0xe3, 0x5b, 0x25, 0x38, 0xab, + 0x68, 0x8c, 0xad, 0xe3, 0x43, 0x32, 0xfa, 0xbd, 0x75, 0xf7, 0x06, 0xd9, 0x5d, 0x0b, 0xe9, 0xde, + 0xdf, 0xb9, 0xbb, 0xe8, 0x32, 0x0c, 0xbb, 0x64, 0xc3, 0x69, 0xf9, 0x89, 0x52, 0x71, 0xfb, 0xb9, + 0xed, 0x53, 0x4d, 0xc1, 0x58, 0xa7, 0xb1, 0xbf, 0x35, 0xcc, 0x96, 0x8e, 0xc4, 0xa1, 0x1f, 0x8d, + 0x2a, 0x13, 0x9a, 0x25, 0x32, 0xa2, 0x5b, 0x22, 0xc2, 0xea, 0x78, 0x12, 0xfa, 0xbd, 0x6d, 0xba, + 0xbd, 0x94, 0xcc, 0x5d, 0x63, 0x99, 0x02, 0x31, 0xc7, 0xa1, 0xa7, 0x60, 0xb0, 0x11, 0x6e, 0x6f, + 0x3b, 0x81, 0x3b, 0x59, 0x66, 0xea, 0xcd, 0x30, 0xdd, 0x81, 0x16, 0x38, 0x08, 0x4b, 0x1c, 0x7a, + 0x0c, 0xfa, 0x9c, 0x68, 0x33, 0x9e, 0xec, 0x63, 0x34, 0x43, 0xb4, 0xa6, 0xb9, 0x68, 0x33, 0xc6, + 0x0c, 0x4a, 0xd5, 0x96, 0xfb, 0x61, 0x74, 0xcf, 0x0b, 0x36, 0xab, 0x5e, 0xc4, 0x74, 0x10, 0x4d, + 0x6d, 0xb9, 0xab, 0x30, 0x58, 0xa3, 0x42, 0x35, 0xe8, 0x6f, 0x86, 0x51, 0x12, 0x4f, 0x0e, 0xb0, + 0xe1, 0x7c, 0x2e, 0x57, 0x7a, 0x78, 0xbf, 0x6b, 0x61, 0x94, 0xa4, 0x5d, 0xa1, 0xff, 0x62, 0xcc, + 0x19, 0xa1, 0x05, 0x28, 0x93, 0x60, 0x67, 0x72, 0x90, 0xf1, 0xfb, 0xd8, 0xe1, 0xfc, 0x16, 0x83, + 0x9d, 0x3b, 0x4e, 0x94, 0x4e, 0xa2, 0xc5, 0x60, 0x07, 0xd3, 0xd2, 0xa8, 0x01, 0x15, 0xe9, 0x56, + 0x88, 0x27, 0x87, 0x8a, 0x08, 0x18, 0x16, 0xe4, 0x98, 0xbc, 0xd3, 0xf2, 0x22, 0xb2, 0x4d, 0x82, + 0x24, 0x4e, 0x75, 0x78, 0x89, 0x8d, 0x71, 0xca, 0x17, 0x35, 0x60, 0x84, 0xab, 0x3a, 0xab, 0x61, + 0x2b, 0x48, 0xe2, 0xc9, 0x0a, 0x6b, 0x72, 0x8e, 0x91, 0x7c, 0x27, 0x2d, 0x31, 0x7f, 0x46, 0xb0, + 0x1f, 0xd1, 0x80, 0x31, 0x36, 0x98, 0xa2, 0x37, 0x60, 0xd4, 0xf7, 0x76, 0x48, 0x40, 0xe2, 0xb8, + 0x16, 0x85, 0xeb, 0x64, 0x12, 0x58, 0x6f, 0x9e, 0xcc, 0x33, 0x18, 0xc3, 0x75, 0x32, 0x7f, 0x6a, + 0x7f, 0x6f, 0x7a, 0x74, 0x45, 0x2f, 0x8d, 0x4d, 0x66, 0xe8, 0x4d, 0x18, 0xa3, 0x7a, 0x95, 0x97, + 0xb2, 0x1f, 0x2e, 0xce, 0x1e, 0xed, 0xef, 0x4d, 0x8f, 0x61, 0xa3, 0x38, 0xce, 0xb0, 0x43, 0x6b, + 0x50, 0xf1, 0xbd, 0x0d, 0xd2, 0xd8, 0x6d, 0xf8, 0x64, 0x72, 0x84, 0xf1, 0xce, 0x99, 0x72, 0x2b, + 0x92, 0x9c, 0xeb, 0xb2, 0xea, 0x2f, 0x4e, 0x19, 0xa1, 0x3b, 0x70, 0x2e, 0x21, 0xd1, 0xb6, 0x17, + 0x38, 0x54, 0xb1, 0x10, 0x8a, 0x16, 0xb3, 0xca, 0x47, 0x99, 0xd4, 0x9e, 0x17, 0x03, 0x7b, 0x6e, + 0xad, 0x23, 0x15, 0xee, 0x52, 0x1a, 0xdd, 0x82, 0x71, 0x36, 0x9f, 0x6a, 0x2d, 0xdf, 0xaf, 0x85, + 0xbe, 0xd7, 0xd8, 0x9d, 0x1c, 0x63, 0x0c, 0x9f, 0x92, 0xb6, 0xf6, 0xb2, 0x89, 0xa6, 0x36, 0x48, + 0xfa, 0x0f, 0x67, 0x4b, 0x23, 0x1f, 0xc6, 0x63, 0xd2, 0x68, 0x45, 0x5e, 0xb2, 0x4b, 0x65, 0x9f, + 0x3c, 0x48, 0x26, 0xc7, 0x8b, 0xd8, 0x54, 0x75, 0xb3, 0x10, 0x77, 0x74, 0x64, 0x80, 0x38, 0xcb, + 0x9a, 0x2e, 0x15, 0x71, 0xe2, 0x7a, 0xc1, 0xe4, 0x04, 0x53, 0xa2, 0xd5, 0xfc, 0xaa, 0x53, 0x20, + 0xe6, 0x38, 0x66, 0xaa, 0xd2, 0x1f, 0xb7, 0xe8, 0xda, 0x7b, 0x8a, 0x11, 0xa6, 0xa6, 0xaa, 0x44, + 0xe0, 0x94, 0x86, 0xee, 0x57, 0x49, 0xb2, 0x3b, 0x89, 0x18, 0xa9, 0x9a, 0x6a, 0x6b, 0x6b, 0x5f, + 0xc0, 0x14, 0x8e, 0xee, 0xc0, 0x20, 0x09, 0x76, 0x96, 0xa2, 0x70, 0x7b, 0xf2, 0x74, 0x91, 0x35, + 0x60, 0x91, 0x13, 0xf3, 0x5d, 0x21, 0xd5, 0x96, 0x05, 0x18, 0x4b, 0x66, 0xe8, 0x01, 0x4c, 0x76, + 0xf8, 0x4a, 0xfc, 0xa3, 0x9c, 0x61, 0x1f, 0xe5, 0x33, 0xa2, 0xec, 0xe4, 0x5a, 0x17, 0xba, 0x83, + 0x43, 0x70, 0xb8, 0x2b, 0x77, 0x7b, 0x1d, 0xc6, 0xd4, 0x42, 0xc5, 0xbe, 0x37, 0x9a, 0x86, 0x7e, + 0xba, 0x16, 0x4b, 0xdb, 0xb1, 0x42, 0x07, 0x95, 0x2e, 0xd1, 0x31, 0xe6, 0x70, 0x36, 0xa8, 0xde, + 0xbb, 0x64, 0x7e, 0x37, 0x21, 0xdc, 0x86, 0x28, 0x6b, 0x83, 0x2a, 0x11, 0x38, 0xa5, 0xb1, 0xff, + 0x0f, 0xdf, 0xe5, 0xd3, 0xd5, 0xb0, 0xc0, 0x4e, 0x70, 0x09, 0x86, 0xb6, 0xc2, 0x38, 0xa1, 0xd4, + 0xac, 0x8e, 0xfe, 0x74, 0x5f, 0xbf, 0x2e, 0xe0, 0x58, 0x51, 0xa0, 0x57, 0x60, 0xb4, 0xa1, 0x57, + 0x20, 0x36, 0xa7, 0xb3, 0xa2, 0x88, 0x59, 0x3b, 0x36, 0x69, 0xd1, 0x55, 0x18, 0x62, 0x0e, 0xd5, + 0x46, 0xe8, 0x0b, 0x6b, 0x45, 0xee, 0xb5, 0x43, 0x35, 0x01, 0x3f, 0xd0, 0x7e, 0x63, 0x45, 0x4d, + 0x6d, 0x3e, 0xda, 0x84, 0xe5, 0x9a, 0xd8, 0x40, 0x94, 0xcd, 0x77, 0x9d, 0x41, 0xb1, 0xc0, 0xda, + 0xff, 0xb8, 0xa4, 0x8d, 0x32, 0xd5, 0xb5, 0x09, 0xfa, 0x22, 0x0c, 0xde, 0x77, 0xbc, 0xc4, 0x0b, + 0x36, 0x85, 0x4e, 0xf0, 0x42, 0xc1, 0xdd, 0x84, 0x15, 0xbf, 0xcb, 0x8b, 0xf2, 0x9d, 0x4f, 0xfc, + 0xc1, 0x92, 0x21, 0xe5, 0x1d, 0xb5, 0x82, 0x80, 0xf2, 0x2e, 0xf5, 0xce, 0x1b, 0xf3, 0xa2, 0x9c, + 0xb7, 0xf8, 0x83, 0x25, 0x43, 0xb4, 0x01, 0x20, 0x65, 0x89, 0xb8, 0xc2, 0x91, 0xf9, 0xc9, 0x5e, + 0xd8, 0xaf, 0xa9, 0xd2, 0xf3, 0x63, 0x74, 0xaf, 0x4d, 0xff, 0x63, 0x8d, 0xb3, 0x9d, 0x30, 0xd5, + 0xaa, 0xbd, 0x59, 0xe8, 0x4b, 0x74, 0x4a, 0x3b, 0x51, 0x42, 0xdc, 0xb9, 0x24, 0xeb, 0x0b, 0x3e, + 0x5c, 0x43, 0x5c, 0xf3, 0xb6, 0x89, 0x3e, 0xfd, 0x05, 0x13, 0x9c, 0xf2, 0xb3, 0xbf, 0x57, 0x86, + 0xc9, 0x6e, 0xcd, 0xa5, 0x22, 0x49, 0x1e, 0x78, 0xc9, 0x02, 0x55, 0x7e, 0x2c, 0x53, 0x24, 0x17, + 0x05, 0x1c, 0x2b, 0x0a, 0x2a, 0x1b, 0xb1, 0xb7, 0x19, 0x38, 0xbe, 0x10, 0x5f, 0x25, 0x1b, 0x75, + 0x06, 0xc5, 0x02, 0x4b, 0xe9, 0x22, 0xe2, 0xc4, 0xc2, 0x8f, 0xae, 0xc9, 0x10, 0x66, 0x50, 0x2c, + 0xb0, 0xba, 0xed, 0xdd, 0x97, 0x63, 0x7b, 0x1b, 0x43, 0xd4, 0xff, 0x70, 0x87, 0x08, 0x7d, 0x19, + 0x60, 0xc3, 0x0b, 0xbc, 0x78, 0x8b, 0x71, 0x1f, 0xe8, 0x99, 0xbb, 0x52, 0xb2, 0x96, 0x14, 0x17, + 0xac, 0x71, 0x44, 0x2f, 0xc1, 0xb0, 0x9a, 0x9e, 0xcb, 0xd5, 0xc9, 0x41, 0xd3, 0xf7, 0x9a, 0xae, + 0x55, 0x55, 0xac, 0xd3, 0xd9, 0x6f, 0x67, 0xe5, 0x45, 0xcc, 0x0a, 0x6d, 0x7c, 0xad, 0xa2, 0xe3, + 0x5b, 0x3a, 0x7c, 0x7c, 0xed, 0xff, 0x54, 0x86, 0x71, 0xa3, 0xb2, 0x56, 0x5c, 0x60, 0x45, 0x7b, + 0x8d, 0x6e, 0x58, 0x4e, 0x42, 0xc4, 0x9c, 0xbc, 0xd4, 0xcb, 0xa4, 0xd1, 0xb7, 0x37, 0x3a, 0x17, + 0x38, 0x27, 0xb4, 0x05, 0x15, 0xdf, 0x89, 0x99, 0xf5, 0x4e, 0xc4, 0x5c, 0xec, 0x8d, 0x6d, 0x6a, + 0x54, 0x38, 0x71, 0xa2, 0xed, 0x1e, 0xbc, 0x96, 0x94, 0x39, 0xdd, 0x6d, 0xa9, 0xb2, 0x23, 0x0f, + 0x6f, 0x54, 0x73, 0xa8, 0x46, 0xb4, 0x8b, 0x39, 0x0e, 0x5d, 0x85, 0x91, 0x88, 0x30, 0x49, 0x59, + 0xa0, 0xfa, 0x1c, 0x13, 0xbd, 0xfe, 0x54, 0xf1, 0xc3, 0x1a, 0x0e, 0x1b, 0x94, 0xa9, 0xde, 0x3f, + 0x70, 0x88, 0xde, 0xff, 0x0c, 0x0c, 0xb2, 0x1f, 0x4a, 0x2a, 0xd4, 0x17, 0x5a, 0xe6, 0x60, 0x2c, + 0xf1, 0x59, 0x21, 0x1a, 0x2a, 0x28, 0x44, 0xcf, 0xc2, 0x58, 0xd5, 0x21, 0xdb, 0x61, 0xb0, 0x18, + 0xb8, 0xcd, 0xd0, 0x0b, 0x12, 0x34, 0x09, 0x7d, 0x6c, 0x3f, 0xe1, 0xf3, 0xbd, 0x8f, 0x72, 0xc0, + 0x7d, 0x54, 0x77, 0xb7, 0xff, 0xaf, 0x05, 0xa3, 0x55, 0xe2, 0x93, 0x84, 0xdc, 0x6a, 0x32, 0x8f, + 0x0f, 0x5a, 0x02, 0xb4, 0x19, 0x39, 0x0d, 0x52, 0x23, 0x91, 0x17, 0xba, 0x75, 0xd2, 0x08, 0x03, + 0x76, 0xe6, 0x41, 0x37, 0xc8, 0x73, 0xfb, 0x7b, 0xd3, 0xe8, 0x5a, 0x1b, 0x16, 0x77, 0x28, 0x81, + 0x5c, 0x18, 0x6d, 0x46, 0xc4, 0x70, 0x51, 0x59, 0xf9, 0xaa, 0x46, 0x4d, 0x2f, 0xc2, 0xb5, 0x61, + 0x03, 0x84, 0x4d, 0xa6, 0xe8, 0x73, 0x30, 0x11, 0x46, 0xcd, 0x2d, 0x27, 0xa8, 0x92, 0x26, 0x09, + 0x5c, 0x6a, 0x02, 0x08, 0x7f, 0xe4, 0x99, 0xfd, 0xbd, 0xe9, 0x89, 0x5b, 0x19, 0x1c, 0x6e, 0xa3, + 0xb6, 0x7f, 0xbd, 0x04, 0x67, 0xab, 0xe1, 0xfd, 0xe0, 0xbe, 0x13, 0xb9, 0x73, 0xb5, 0x65, 0xae, + 0xd7, 0x33, 0xff, 0xae, 0xf4, 0x2b, 0x5b, 0x5d, 0xfd, 0xca, 0x5f, 0x82, 0xa1, 0x0d, 0x8f, 0xf8, + 0x2e, 0x26, 0x1b, 0xa2, 0x7b, 0x97, 0x8b, 0x38, 0xde, 0x97, 0x68, 0x19, 0xe9, 0xe3, 0xe0, 0x6e, + 0xed, 0x25, 0xc1, 0x06, 0x2b, 0x86, 0xa8, 0x05, 0x13, 0xd2, 0x70, 0x91, 0x58, 0x31, 0x3b, 0x5e, + 0x28, 0x66, 0x17, 0x99, 0xd5, 0xb0, 0xf1, 0xc0, 0x19, 0x86, 0xb8, 0xad, 0x0a, 0x6a, 0x70, 0x6e, + 0xd3, 0xbd, 0xa1, 0x8f, 0xc9, 0x0a, 0x33, 0x38, 0x99, 0x45, 0xcc, 0xa0, 0xf6, 0xdf, 0xb5, 0xe0, + 0x91, 0xb6, 0xd1, 0x12, 0xee, 0x82, 0xd7, 0xa5, 0x9d, 0xce, 0x0f, 0xc8, 0x72, 0x5a, 0xd9, 0x71, + 0xcc, 0x8b, 0xd9, 0xec, 0xa5, 0x02, 0x36, 0xfb, 0x2d, 0x38, 0xb3, 0xb8, 0xdd, 0x4c, 0x76, 0xab, + 0x9e, 0xe9, 0x0e, 0x7f, 0x19, 0x06, 0xb6, 0x89, 0xeb, 0xb5, 0xb6, 0xc5, 0x67, 0x9d, 0x96, 0x0b, + 0xe9, 0x2a, 0x83, 0x1e, 0xec, 0x4d, 0x8f, 0xd6, 0x93, 0x30, 0x72, 0x36, 0x09, 0x07, 0x60, 0x41, + 0x6e, 0xbf, 0x6f, 0xc1, 0xb8, 0x9c, 0x50, 0x73, 0xae, 0x1b, 0x91, 0x38, 0x46, 0x53, 0x50, 0xf2, + 0x9a, 0x82, 0x11, 0x08, 0x46, 0xa5, 0xe5, 0x1a, 0x2e, 0x79, 0x4d, 0xf4, 0x45, 0xa8, 0xf0, 0x53, + 0x94, 0x54, 0x38, 0x7a, 0x3c, 0x95, 0x61, 0xc6, 0xd4, 0x9a, 0xe4, 0x81, 0x53, 0x76, 0x52, 0xad, + 0x64, 0x4b, 0x75, 0xd9, 0xf4, 0xe9, 0x5f, 0x17, 0x70, 0xac, 0x28, 0xd0, 0x45, 0x18, 0x0a, 0x42, + 0x97, 0x1f, 0x74, 0xf1, 0x4d, 0x97, 0x89, 0xdc, 0x4d, 0x01, 0xc3, 0x0a, 0x6b, 0x7f, 0xdd, 0x82, + 0x11, 0xd9, 0xc7, 0x82, 0x1a, 0x2e, 0x9d, 0x24, 0xa9, 0x76, 0x9b, 0x4e, 0x12, 0xaa, 0xa1, 0x32, + 0x8c, 0xa1, 0x98, 0x96, 0x7b, 0x51, 0x4c, 0xed, 0xdf, 0x2a, 0xc1, 0x98, 0x6c, 0x4e, 0xbd, 0xb5, + 0x1e, 0x13, 0xba, 0x6f, 0x57, 0x1c, 0x3e, 0xf8, 0x44, 0xca, 0xd9, 0xf3, 0x79, 0xc6, 0x8b, 0xf1, + 0xcd, 0x52, 0xbd, 0x60, 0x4e, 0xf2, 0xc1, 0x29, 0x4b, 0xb4, 0x03, 0xa7, 0x82, 0x30, 0x61, 0xfb, + 0x81, 0xc2, 0x17, 0xf3, 0x42, 0x67, 0xeb, 0x79, 0x54, 0xd4, 0x73, 0xea, 0x66, 0x96, 0x1f, 0x6e, + 0xaf, 0x02, 0xdd, 0x92, 0x4e, 0x99, 0x32, 0xab, 0xeb, 0xd9, 0x62, 0x75, 0x75, 0xf7, 0xc9, 0xd8, + 0x3f, 0xb4, 0xa0, 0x22, 0xc9, 0x4e, 0xe2, 0x38, 0xe2, 0x2e, 0x0c, 0xc6, 0xec, 0x13, 0xc9, 0xe1, + 0xba, 0x54, 0xac, 0x0b, 0xfc, 0xbb, 0xa6, 0x9b, 0x20, 0xff, 0x1f, 0x63, 0xc9, 0x8d, 0x39, 0x57, + 0x55, 0x47, 0x3e, 0x74, 0xce, 0x55, 0xd5, 0xb2, 0xee, 0xa7, 0x0e, 0xa3, 0x86, 0xf9, 0x4c, 0x35, + 0xb9, 0x66, 0x44, 0x36, 0xbc, 0x07, 0x59, 0x4d, 0xae, 0xc6, 0xa0, 0x58, 0x60, 0xd1, 0x06, 0x8c, + 0x34, 0xa4, 0x57, 0x36, 0x5d, 0x42, 0x3e, 0x51, 0xd0, 0xd7, 0xab, 0x5c, 0xfc, 0x3c, 0x6c, 0x64, + 0x41, 0xe3, 0x84, 0x0d, 0xbe, 0x74, 0x9d, 0x4a, 0x4f, 0x31, 0xcb, 0x05, 0x3d, 0x1d, 0x11, 0x49, + 0xd2, 0x1a, 0xba, 0x1e, 0x60, 0xda, 0xdf, 0xb6, 0x60, 0x80, 0x3b, 0xfc, 0x8a, 0x79, 0x4d, 0xb5, + 0xc3, 0x8b, 0x74, 0x3c, 0xef, 0x50, 0xa0, 0x38, 0xcb, 0x40, 0x77, 0xa1, 0xc2, 0x7e, 0x30, 0xe7, + 0x45, 0xb9, 0x48, 0x0c, 0x0d, 0xaf, 0x5f, 0x6f, 0xea, 0x1d, 0xc9, 0x00, 0xa7, 0xbc, 0xec, 0x1f, + 0x94, 0xe9, 0xd2, 0x97, 0x92, 0x1a, 0x7b, 0xbb, 0x75, 0x12, 0x7b, 0x7b, 0xe9, 0xf8, 0xf7, 0xf6, + 0x77, 0x60, 0xbc, 0xa1, 0x1d, 0xb3, 0xa4, 0x5f, 0xfc, 0x4a, 0x41, 0xb1, 0xd2, 0xce, 0x66, 0xb8, + 0x83, 0x6b, 0xc1, 0x64, 0x87, 0xb3, 0xfc, 0x11, 0x81, 0x11, 0x2e, 0x0f, 0xa2, 0xbe, 0x3e, 0x56, + 0xdf, 0x6c, 0x11, 0x09, 0xd3, 0x2b, 0x63, 0x52, 0x5c, 0xd7, 0x18, 0x61, 0x83, 0xad, 0xfd, 0xd7, + 0xfb, 0xa1, 0x7f, 0x71, 0x87, 0x04, 0xc9, 0x09, 0x2c, 0x75, 0xdb, 0x30, 0xe6, 0x05, 0x3b, 0xa1, + 0xbf, 0x43, 0x5c, 0x8e, 0x3f, 0xda, 0xf6, 0x7e, 0x4e, 0x54, 0x32, 0xb6, 0x6c, 0x30, 0xc3, 0x19, + 0xe6, 0xc7, 0x61, 0x5a, 0xbf, 0x06, 0x03, 0x5c, 0x32, 0x84, 0x5d, 0x9d, 0xe3, 0x00, 0x67, 0x03, + 0x2b, 0x66, 0x50, 0xea, 0x00, 0xe0, 0xbe, 0x77, 0xc1, 0x08, 0xbd, 0x0d, 0x63, 0x1b, 0x5e, 0x14, + 0x27, 0xd4, 0x3a, 0x8e, 0x13, 0x67, 0xbb, 0x79, 0x04, 0xa3, 0x5a, 0x8d, 0xc8, 0x92, 0xc1, 0x09, + 0x67, 0x38, 0xa3, 0x4d, 0x18, 0xa5, 0x36, 0x5d, 0x5a, 0xd5, 0x60, 0xcf, 0x55, 0x29, 0x9f, 0xda, + 0x8a, 0xce, 0x08, 0x9b, 0x7c, 0xe9, 0x92, 0xd4, 0x60, 0x36, 0xe0, 0x10, 0xd3, 0x6e, 0xd4, 0x92, + 0xc4, 0x8d, 0x3f, 0x8e, 0xa3, 0x2b, 0x1b, 0x8b, 0x62, 0xa8, 0x98, 0x2b, 0x5b, 0x1a, 0xab, 0x60, + 0x7f, 0x97, 0xee, 0xc5, 0x74, 0x0c, 0x4f, 0x60, 0xfb, 0xba, 0x6e, 0x6e, 0x5f, 0x4f, 0x16, 0xf8, + 0xb2, 0x5d, 0xb6, 0xae, 0xb7, 0x60, 0x58, 0xfb, 0xf0, 0x68, 0x16, 0x2a, 0x0d, 0x79, 0xd0, 0x2e, + 0x56, 0x71, 0xa5, 0x4a, 0xa9, 0x13, 0x78, 0x9c, 0xd2, 0xd0, 0x71, 0xa1, 0x2a, 0x68, 0x36, 0x2c, + 0x87, 0x2a, 0xa8, 0x98, 0x61, 0xec, 0x17, 0x00, 0x16, 0x1f, 0x90, 0xc6, 0x5c, 0x83, 0x45, 0x83, + 0x68, 0x07, 0x62, 0x56, 0xf7, 0x03, 0x31, 0xfb, 0x3b, 0x16, 0x8c, 0x2d, 0x2d, 0x18, 0x3a, 0xfd, + 0x0c, 0x00, 0xd7, 0x8d, 0xef, 0xde, 0xbd, 0x29, 0x1d, 0xbe, 0xdc, 0x2b, 0xa7, 0xa0, 0x58, 0xa3, + 0x40, 0x8f, 0x42, 0xd9, 0x6f, 0x05, 0x42, 0x65, 0x1d, 0xdc, 0xdf, 0x9b, 0x2e, 0xaf, 0xb4, 0x02, + 0x4c, 0x61, 0x5a, 0xfc, 0x4b, 0xb9, 0x70, 0xfc, 0x4b, 0x7e, 0x24, 0xe8, 0x37, 0xcb, 0x30, 0xb1, + 0xe4, 0x93, 0x07, 0x46, 0xab, 0x9f, 0x86, 0x01, 0x37, 0xf2, 0x76, 0x48, 0x94, 0x55, 0x04, 0xaa, + 0x0c, 0x8a, 0x05, 0xb6, 0x70, 0x48, 0xce, 0x9b, 0xed, 0x1b, 0xf9, 0xf1, 0x85, 0x23, 0xe5, 0xf6, + 0x19, 0x6d, 0xc0, 0x60, 0xc8, 0x5d, 0x0a, 0x93, 0xfd, 0x4c, 0x14, 0x5f, 0x39, 0xbc, 0x31, 0xd9, + 0xf1, 0x99, 0x11, 0x0e, 0x09, 0x1e, 0x0c, 0xa1, 0xd6, 0x32, 0x01, 0xc5, 0x92, 0xf9, 0xd4, 0xa7, + 0x61, 0x44, 0xa7, 0xec, 0x29, 0x2a, 0xe2, 0x17, 0x2c, 0x38, 0xbd, 0xe4, 0x87, 0x8d, 0x7b, 0x99, + 0x98, 0xa9, 0x97, 0x60, 0x98, 0x4e, 0xa6, 0xd8, 0x08, 0x28, 0x34, 0x22, 0x27, 0x05, 0x0a, 0xeb, + 0x74, 0x5a, 0xb1, 0xdb, 0xb7, 0x97, 0xab, 0x9d, 0x02, 0x2e, 0x05, 0x0a, 0xeb, 0x74, 0xf6, 0xef, + 0x5b, 0xf0, 0xf8, 0xb5, 0x85, 0xc5, 0x1a, 0x89, 0x62, 0x2f, 0x4e, 0x48, 0x90, 0xb4, 0xc5, 0x7c, + 0x52, 0x9d, 0xd1, 0xd5, 0x9a, 0x92, 0xea, 0x8c, 0x55, 0xd6, 0x0a, 0x81, 0xfd, 0xb0, 0x04, 0x3e, + 0x7f, 0xdb, 0x82, 0xd3, 0xd7, 0xbc, 0x04, 0x93, 0x66, 0x98, 0x0d, 0xd3, 0x8c, 0x48, 0x33, 0x8c, + 0xbd, 0x24, 0x8c, 0x76, 0xb3, 0x61, 0x9a, 0x58, 0x61, 0xb0, 0x46, 0xc5, 0x6b, 0xde, 0xf1, 0x62, + 0xda, 0xd2, 0x92, 0x69, 0xea, 0x62, 0x01, 0xc7, 0x8a, 0x82, 0x76, 0xcc, 0xf5, 0x22, 0xa6, 0x32, + 0xec, 0x8a, 0x19, 0xac, 0x3a, 0x56, 0x95, 0x08, 0x9c, 0xd2, 0xd8, 0x7f, 0xc3, 0x82, 0xb3, 0xd7, + 0xfc, 0x56, 0x9c, 0x90, 0x68, 0x23, 0x36, 0x1a, 0xfb, 0x02, 0x54, 0x88, 0x54, 0xee, 0x45, 0x5b, + 0xd5, 0xa6, 0xa1, 0xb4, 0x7e, 0x1e, 0x23, 0xaa, 0xe8, 0x0a, 0x84, 0x22, 0xf6, 0x16, 0x38, 0xf7, + 0xdb, 0x25, 0x18, 0xbd, 0xbe, 0xb6, 0x56, 0xbb, 0x46, 0x12, 0xb1, 0x4a, 0xe6, 0x3b, 0xa5, 0x6a, + 0x9a, 0x45, 0xae, 0xed, 0x2d, 0x99, 0x59, 0xd7, 0x4a, 0x3c, 0x7f, 0x86, 0x87, 0xe4, 0xcf, 0x2c, + 0x07, 0xc9, 0xad, 0xa8, 0x9e, 0x44, 0x5e, 0xb0, 0xd9, 0xd1, 0x82, 0x97, 0x2b, 0x79, 0xb9, 0xdb, + 0x4a, 0x8e, 0x5e, 0x80, 0x01, 0x76, 0x8b, 0x40, 0xaa, 0x1e, 0x1f, 0x55, 0x5a, 0x02, 0x83, 0x1e, + 0xec, 0x4d, 0x57, 0x6e, 0xe3, 0x65, 0xfe, 0x07, 0x0b, 0x52, 0xf4, 0x26, 0x0c, 0x6f, 0x25, 0x49, + 0xf3, 0x3a, 0x71, 0x5c, 0x12, 0xc9, 0x55, 0xe2, 0xe2, 0xe1, 0xab, 0x04, 0x1d, 0x0c, 0x5e, 0x20, + 0x9d, 0x58, 0x29, 0x2c, 0xc6, 0x3a, 0x47, 0xbb, 0x0e, 0x90, 0xe2, 0x1e, 0x92, 0x05, 0x62, 0xff, + 0x7c, 0x09, 0x06, 0xaf, 0x3b, 0x81, 0xeb, 0x93, 0x08, 0x2d, 0x41, 0x1f, 0x79, 0x40, 0x1a, 0x62, + 0x1b, 0xcf, 0x69, 0x7a, 0xba, 0xd5, 0x71, 0xaf, 0x1a, 0xfd, 0x8f, 0x59, 0x79, 0x84, 0x61, 0x90, + 0xb6, 0xfb, 0x9a, 0x8a, 0xdf, 0x7d, 0x2e, 0x7f, 0x14, 0x94, 0x48, 0xf0, 0x7d, 0x52, 0x80, 0xb0, + 0x64, 0xc4, 0xfc, 0x4f, 0x8d, 0x66, 0x9d, 0x2e, 0x6e, 0x49, 0x31, 0xbb, 0x6e, 0x6d, 0xa1, 0xc6, + 0xc9, 0x05, 0x5f, 0xee, 0x7f, 0x92, 0x40, 0x9c, 0xb2, 0xb3, 0xaf, 0xc2, 0x19, 0x76, 0x7c, 0xe9, + 0x24, 0x5b, 0xc6, 0x9c, 0xc9, 0x15, 0x4e, 0xfb, 0x6f, 0x95, 0xe0, 0xd4, 0x72, 0x7d, 0xa1, 0x6e, + 0x7a, 0x0e, 0xaf, 0xc2, 0x08, 0xdf, 0x9e, 0xa9, 0xd0, 0x39, 0xbe, 0x28, 0xaf, 0x5c, 0xee, 0x6b, + 0x1a, 0x0e, 0x1b, 0x94, 0xe8, 0x71, 0x28, 0x7b, 0xef, 0x04, 0xd9, 0xc8, 0xac, 0xe5, 0xd7, 0x6e, + 0x62, 0x0a, 0xa7, 0x68, 0xba, 0xd3, 0xf3, 0x25, 0x4e, 0xa1, 0xd5, 0x6e, 0xff, 0x2a, 0x8c, 0x79, + 0x71, 0x23, 0xf6, 0x96, 0x03, 0x3a, 0xff, 0x9d, 0x86, 0x14, 0xdf, 0x54, 0x35, 0xa7, 0x4d, 0x55, + 0x58, 0x9c, 0xa1, 0xd6, 0xd6, 0xdb, 0xfe, 0xc2, 0xda, 0x42, 0x7e, 0x20, 0xef, 0xdb, 0x50, 0x51, + 0x41, 0x4c, 0x32, 0xf4, 0xcc, 0xea, 0x1c, 0x7a, 0x56, 0x60, 0xc1, 0x91, 0xfe, 0xdc, 0x72, 0x47, + 0x7f, 0xee, 0x3f, 0xb0, 0x20, 0x8d, 0xd7, 0x40, 0x18, 0x2a, 0xcd, 0x90, 0x1d, 0x96, 0x44, 0xf2, + 0x54, 0xf2, 0xa9, 0x1c, 0x49, 0xe4, 0x33, 0x81, 0xcb, 0x4a, 0x4d, 0x96, 0xc5, 0x29, 0x1b, 0xb4, + 0x02, 0x83, 0xcd, 0x88, 0xd4, 0x13, 0x16, 0x0d, 0xde, 0x03, 0x47, 0x26, 0xd5, 0x35, 0x5e, 0x12, + 0x4b, 0x16, 0xf6, 0x3f, 0xb7, 0x00, 0x56, 0xbc, 0x6d, 0x2f, 0xc1, 0x4e, 0xb0, 0x49, 0x4e, 0xc0, + 0xd8, 0xbb, 0x09, 0x7d, 0x71, 0x93, 0x34, 0x8a, 0x1d, 0x77, 0xa5, 0x2d, 0xab, 0x37, 0x49, 0x23, + 0xfd, 0x1c, 0xf4, 0x1f, 0x66, 0x7c, 0xec, 0x7f, 0x08, 0x30, 0x96, 0x92, 0x51, 0x85, 0x1b, 0x3d, + 0x6f, 0x84, 0x41, 0x3f, 0x9a, 0x09, 0x83, 0xae, 0x30, 0x6a, 0x2d, 0xf2, 0x39, 0x81, 0xf2, 0xb6, + 0xf3, 0x40, 0xe8, 0xf7, 0x2f, 0x15, 0x6d, 0x10, 0xad, 0x69, 0x66, 0xd5, 0x79, 0xc0, 0xd5, 0xa9, + 0xe7, 0xa4, 0x20, 0xad, 0x3a, 0x0f, 0x0e, 0xf8, 0xa1, 0x16, 0x9b, 0x89, 0xd4, 0xa0, 0xf8, 0xda, + 0x7f, 0x49, 0xff, 0xb3, 0xc5, 0x91, 0x56, 0xc7, 0x6a, 0xf5, 0x02, 0xe1, 0x9e, 0xec, 0xb1, 0x56, + 0x2f, 0xc8, 0xd6, 0xea, 0x05, 0x05, 0x6a, 0xf5, 0x02, 0xf4, 0x9e, 0x05, 0x83, 0xc2, 0xab, 0xcf, + 0x22, 0xe0, 0x86, 0xaf, 0x7c, 0xaa, 0xa7, 0xaa, 0xc5, 0xf1, 0x00, 0xaf, 0x7e, 0x56, 0xea, 0x90, + 0x02, 0x9a, 0xdb, 0x04, 0x59, 0x35, 0xfa, 0x35, 0x0b, 0xc6, 0xc4, 0x6f, 0x4c, 0xde, 0x69, 0x91, + 0x38, 0x11, 0xbb, 0xd5, 0xe7, 0x8e, 0xd2, 0x1a, 0xc1, 0x82, 0x37, 0xea, 0x93, 0x72, 0xa9, 0x31, + 0x91, 0xb9, 0x6d, 0xcb, 0xb4, 0x07, 0x7d, 0xdf, 0x82, 0x33, 0xdb, 0xce, 0x03, 0x5e, 0x23, 0x87, + 0x61, 0x27, 0xf1, 0x42, 0x11, 0xe5, 0xb7, 0xd4, 0xab, 0x9c, 0xb4, 0x31, 0xe2, 0xcd, 0x95, 0x01, + 0x3c, 0x67, 0x3a, 0x91, 0xe4, 0x36, 0xba, 0x63, 0x0b, 0xa7, 0x5c, 0x18, 0x92, 0x82, 0xd9, 0x41, + 0x7b, 0x9f, 0xd7, 0x37, 0xe5, 0xc3, 0x67, 0xa0, 0xf4, 0x77, 0xcd, 0xbc, 0xd6, 0x72, 0x82, 0xc4, + 0x4b, 0x76, 0x35, 0x5d, 0x9f, 0xd5, 0x22, 0x04, 0xf1, 0x18, 0x6b, 0xd9, 0x82, 0x11, 0x5d, 0xe6, + 0x8e, 0xb1, 0xa6, 0x10, 0x4e, 0x77, 0x90, 0xa7, 0x63, 0xac, 0xb0, 0x05, 0x8f, 0x76, 0x95, 0x8b, + 0xe3, 0xab, 0xd6, 0xfe, 0x67, 0x96, 0xbe, 0x60, 0x9e, 0x80, 0x07, 0x65, 0xd5, 0xf4, 0xa0, 0x5c, + 0x2c, 0x3a, 0x73, 0xba, 0xb8, 0x51, 0x36, 0xf4, 0xe6, 0xd3, 0x8d, 0x00, 0xad, 0xc1, 0x80, 0x4f, + 0x21, 0xf2, 0x00, 0xeb, 0x52, 0x2f, 0x73, 0x33, 0xd5, 0x31, 0x18, 0x3c, 0xc6, 0x82, 0x97, 0xfd, + 0x7d, 0x0b, 0xfa, 0x7e, 0x8a, 0x57, 0x33, 0xda, 0x58, 0x8b, 0xdb, 0xc5, 0x33, 0xd8, 0xb9, 0xbf, + 0xf8, 0x20, 0x21, 0x41, 0xcc, 0x54, 0xca, 0x8e, 0x43, 0xf4, 0xeb, 0x25, 0x18, 0xa6, 0x55, 0xc9, + 0x10, 0x84, 0x57, 0x60, 0xd4, 0x77, 0xd6, 0x89, 0x2f, 0xbd, 0xbf, 0x59, 0xf3, 0x6b, 0x45, 0x47, + 0x62, 0x93, 0x96, 0x16, 0xde, 0xd0, 0x9d, 0xe3, 0x42, 0x35, 0x52, 0x85, 0x0d, 0xcf, 0x39, 0x36, + 0x69, 0xa9, 0x05, 0x70, 0xdf, 0x49, 0x1a, 0x5b, 0xc2, 0x34, 0x53, 0xcd, 0xbd, 0x4b, 0x81, 0x98, + 0xe3, 0xd0, 0x1c, 0x8c, 0x4b, 0x89, 0xbd, 0x43, 0x6d, 0xf6, 0x30, 0x10, 0x6a, 0xa3, 0xba, 0xde, + 0x89, 0x4d, 0x34, 0xce, 0xd2, 0xa3, 0x4f, 0xc3, 0x18, 0x1d, 0x9c, 0xb0, 0x95, 0xc8, 0x00, 0x8b, + 0x7e, 0x16, 0x60, 0xc1, 0xe2, 0x73, 0xd7, 0x0c, 0x0c, 0xce, 0x50, 0xda, 0x6f, 0xc2, 0xe9, 0x95, + 0xd0, 0x71, 0xe7, 0x1d, 0xdf, 0x09, 0x1a, 0x24, 0x5a, 0x0e, 0x36, 0x73, 0xcf, 0xa2, 0xf5, 0xf3, + 0xe2, 0x52, 0xde, 0x79, 0xb1, 0x1d, 0x01, 0xd2, 0x2b, 0x10, 0xa1, 0x41, 0x6f, 0xc0, 0xa0, 0xc7, + 0xab, 0x12, 0x62, 0x7b, 0x39, 0xcf, 0xb9, 0xd4, 0xd6, 0x46, 0x2d, 0xd4, 0x85, 0x03, 0xb0, 0x64, + 0x49, 0x2d, 0x8a, 0x4e, 0xde, 0xa8, 0x7c, 0xa3, 0xcd, 0xfe, 0x8b, 0x16, 0x8c, 0xdf, 0xcc, 0xdc, + 0x1d, 0x7c, 0x1a, 0x06, 0x62, 0x12, 0x75, 0x70, 0xad, 0xd5, 0x19, 0x14, 0x0b, 0xec, 0x43, 0x37, + 0xd7, 0x7f, 0xb9, 0x04, 0x15, 0x16, 0x64, 0xda, 0xa4, 0xd6, 0xc1, 0xf1, 0x2b, 0xa7, 0xab, 0x86, + 0x72, 0x9a, 0x63, 0x34, 0xaa, 0x86, 0x75, 0xd3, 0x4d, 0xd1, 0x6d, 0x75, 0xa7, 0xae, 0x90, 0xbd, + 0x98, 0x32, 0xe4, 0xf7, 0xae, 0xc6, 0xcc, 0x2b, 0x78, 0xf2, 0xbe, 0x1d, 0x3b, 0xc1, 0x55, 0xb4, + 0x1f, 0xba, 0x13, 0x5c, 0xd5, 0xb2, 0x2e, 0x8b, 0x53, 0x4d, 0x6b, 0x3c, 0x5b, 0xbe, 0x3f, 0xcb, + 0x42, 0x07, 0x1d, 0xdf, 0x7b, 0x97, 0xa8, 0xab, 0xa9, 0xd3, 0x22, 0x14, 0x50, 0x40, 0x0f, 0xd8, + 0x3a, 0x23, 0xfe, 0xf1, 0x9b, 0xc7, 0x69, 0x11, 0xfb, 0x3a, 0x8c, 0x67, 0x86, 0x0e, 0xbd, 0x04, + 0xfd, 0xcd, 0x2d, 0x27, 0x26, 0x99, 0xa0, 0x94, 0xfe, 0x1a, 0x05, 0x1e, 0xec, 0x4d, 0x8f, 0xa9, + 0x02, 0x0c, 0x82, 0x39, 0xb5, 0xfd, 0x5e, 0x09, 0xfa, 0x6e, 0x86, 0xee, 0x49, 0x88, 0xda, 0x75, + 0x43, 0xd4, 0x9e, 0xce, 0xcf, 0x5b, 0xd0, 0x55, 0xca, 0x6a, 0x19, 0x29, 0xbb, 0x58, 0x80, 0xd7, + 0xe1, 0x02, 0xb6, 0x0d, 0xc3, 0x2c, 0x2f, 0x82, 0x88, 0xca, 0x79, 0xc1, 0xb0, 0xa7, 0xa6, 0x33, + 0xf6, 0xd4, 0xb8, 0x46, 0xaa, 0x59, 0x55, 0xcf, 0xc0, 0xa0, 0x88, 0x02, 0xc9, 0x06, 0x4e, 0x0a, + 0x5a, 0x2c, 0xf1, 0xf6, 0x3f, 0x29, 0x83, 0x91, 0x87, 0x01, 0xfd, 0xd0, 0x82, 0x99, 0x88, 0x5f, + 0x42, 0x71, 0xab, 0xad, 0xc8, 0x0b, 0x36, 0xeb, 0x8d, 0x2d, 0xe2, 0xb6, 0x7c, 0x2f, 0xd8, 0x5c, + 0xde, 0x0c, 0x42, 0x05, 0x5e, 0x7c, 0x40, 0x1a, 0x2d, 0xe6, 0x74, 0x2d, 0x9c, 0xfe, 0x41, 0x9d, + 0x80, 0x5e, 0xd9, 0xdf, 0x9b, 0x9e, 0xc1, 0x3d, 0xd5, 0x82, 0x7b, 0x6c, 0x15, 0xfa, 0x23, 0x0b, + 0x66, 0x79, 0x26, 0x82, 0xe2, 0x3d, 0x29, 0x64, 0x87, 0xd6, 0x24, 0xd3, 0x94, 0xdd, 0x1a, 0x89, + 0xb6, 0xe7, 0x5f, 0x16, 0x83, 0x3c, 0x5b, 0xeb, 0xad, 0x56, 0xdc, 0x6b, 0x33, 0xed, 0x7f, 0x59, + 0x86, 0x51, 0x3a, 0x9e, 0xe9, 0xed, 0xe3, 0x97, 0x0c, 0x31, 0x79, 0x22, 0x23, 0x26, 0xa7, 0x0c, + 0xe2, 0x87, 0x73, 0xf1, 0x38, 0x86, 0x53, 0xbe, 0x13, 0x27, 0xd7, 0x89, 0x13, 0x25, 0xeb, 0xc4, + 0x61, 0x07, 0x8d, 0xd9, 0x20, 0x86, 0x02, 0x67, 0x97, 0x2a, 0xb2, 0x68, 0x25, 0xcb, 0x0c, 0xb7, + 0xf3, 0x47, 0x3b, 0x80, 0xd8, 0xa1, 0x66, 0xe4, 0x04, 0x31, 0xef, 0x8b, 0x27, 0xdc, 0xb4, 0xbd, + 0xd5, 0x3a, 0x25, 0x6a, 0x45, 0x2b, 0x6d, 0xdc, 0x70, 0x87, 0x1a, 0xb4, 0x63, 0xeb, 0xfe, 0xa2, + 0xc7, 0xd6, 0x03, 0x39, 0x11, 0xcb, 0xbf, 0x68, 0xc1, 0x69, 0xfa, 0x59, 0xcc, 0xe8, 0xd6, 0x18, + 0x85, 0x30, 0x4e, 0xc5, 0xce, 0x27, 0x89, 0x84, 0x89, 0xf9, 0x95, 0xa3, 0x59, 0x9b, 0x7c, 0x52, + 0xf5, 0xed, 0x86, 0xc9, 0x0c, 0x67, 0xb9, 0xdb, 0xdf, 0xb1, 0x80, 0x85, 0xcf, 0x9d, 0xc0, 0x66, + 0x76, 0xcd, 0xdc, 0xcc, 0xec, 0xfc, 0x15, 0xa3, 0xcb, 0x3e, 0xf6, 0x22, 0x4c, 0x50, 0x6c, 0x2d, + 0x0a, 0x1f, 0xec, 0x4a, 0x45, 0x3b, 0xdf, 0x5f, 0xfb, 0x5e, 0x89, 0x4f, 0x1b, 0x75, 0x9b, 0x0e, + 0xfd, 0x92, 0x05, 0x43, 0x0d, 0xa7, 0xe9, 0x34, 0x78, 0x16, 0x9b, 0x02, 0x3e, 0x19, 0xa3, 0xfc, + 0xcc, 0x82, 0x28, 0xcb, 0xfd, 0x09, 0x9f, 0x90, 0x5d, 0x97, 0xe0, 0x5c, 0x1f, 0x82, 0xaa, 0x7c, + 0xca, 0x83, 0x51, 0x83, 0xd9, 0x31, 0x1a, 0xa1, 0xbf, 0x64, 0xf1, 0x25, 0x5f, 0x19, 0x0a, 0xf7, + 0xe1, 0x54, 0xa0, 0xfd, 0xa7, 0x8b, 0x99, 0xd4, 0x8b, 0x67, 0x8a, 0x2f, 0xea, 0x6c, 0x0d, 0xd4, + 0x02, 0x05, 0x33, 0x0c, 0x71, 0x7b, 0x1d, 0xf6, 0xdf, 0xb6, 0xe0, 0x11, 0x9d, 0x50, 0xbb, 0xfc, + 0x98, 0xe7, 0x2b, 0xae, 0xc2, 0x50, 0xd8, 0x24, 0x91, 0x93, 0x1a, 0x45, 0x17, 0xe5, 0xe8, 0xdf, + 0x12, 0xf0, 0x83, 0xbd, 0xe9, 0x33, 0x3a, 0x77, 0x09, 0xc7, 0xaa, 0x24, 0xb2, 0x61, 0x80, 0x8d, + 0x4b, 0x2c, 0xae, 0xad, 0xb2, 0x9c, 0x2e, 0xec, 0x84, 0x24, 0xc6, 0x02, 0x63, 0xff, 0x55, 0x8b, + 0x0b, 0x9b, 0xde, 0x74, 0xf4, 0x15, 0x98, 0xd8, 0xa6, 0xf6, 0xd3, 0xe2, 0x83, 0x26, 0xdd, 0x46, + 0xd9, 0xc9, 0xb0, 0x55, 0x64, 0xf3, 0xe8, 0xd2, 0xdd, 0xf9, 0x49, 0xd1, 0xfa, 0x89, 0xd5, 0x0c, + 0x5b, 0xdc, 0x56, 0x91, 0xfd, 0xc7, 0x62, 0xc6, 0x32, 0x0d, 0xee, 0x19, 0x18, 0x6c, 0x86, 0xee, + 0xc2, 0x72, 0x15, 0x8b, 0xb1, 0x52, 0x4b, 0x4e, 0x8d, 0x83, 0xb1, 0xc4, 0xa3, 0x2b, 0x00, 0xe4, + 0x41, 0x42, 0xa2, 0xc0, 0xf1, 0xd5, 0x89, 0xae, 0x52, 0x94, 0x16, 0x15, 0x06, 0x6b, 0x54, 0xb4, + 0x4c, 0x33, 0x0a, 0x77, 0x3c, 0x97, 0x45, 0xed, 0x97, 0xcd, 0x32, 0x35, 0x85, 0xc1, 0x1a, 0x15, + 0xb5, 0x5a, 0x5b, 0x41, 0xcc, 0x37, 0x31, 0x67, 0x5d, 0xa4, 0x20, 0x19, 0x4a, 0xad, 0xd6, 0xdb, + 0x3a, 0x12, 0x9b, 0xb4, 0xf6, 0x7f, 0xac, 0x00, 0xa4, 0x6a, 0x12, 0x7a, 0xaf, 0x7d, 0x86, 0x7e, + 0xb2, 0xa8, 0x8e, 0xf5, 0xf0, 0xa6, 0x27, 0xfa, 0x86, 0x05, 0xc3, 0x8e, 0xef, 0x87, 0x0d, 0x27, + 0x61, 0x3d, 0x2a, 0x15, 0x5d, 0x2b, 0x44, 0x4b, 0xe6, 0xd2, 0xb2, 0xbc, 0x31, 0x2f, 0xc8, 0x03, + 0x3f, 0x0d, 0x93, 0xdb, 0x1e, 0xbd, 0x09, 0xe8, 0x13, 0x52, 0xcd, 0xe6, 0x1f, 0x65, 0x2a, 0xab, + 0x66, 0x57, 0xd8, 0x0a, 0xa9, 0x69, 0xd8, 0xe8, 0x4d, 0x23, 0xcb, 0x46, 0x5f, 0x91, 0xdb, 0x92, + 0x86, 0xe2, 0x90, 0x97, 0x60, 0x03, 0x7d, 0x51, 0x0f, 0x68, 0xee, 0x2f, 0x72, 0x1d, 0x59, 0xd3, + 0x5f, 0x73, 0x82, 0x99, 0x13, 0x18, 0x77, 0xcd, 0xad, 0x52, 0x04, 0x65, 0x5d, 0xce, 0xaf, 0x21, + 0xb3, 0xc7, 0xa6, 0x9b, 0x63, 0x06, 0x81, 0xb3, 0x55, 0xa0, 0x2f, 0xf2, 0x70, 0xf3, 0xe5, 0x60, + 0x23, 0x14, 0x81, 0x59, 0x97, 0x0a, 0x7c, 0xf3, 0xdd, 0x38, 0x21, 0xdb, 0xb4, 0x4c, 0xba, 0x1b, + 0xde, 0x14, 0x5c, 0xb0, 0xe2, 0x87, 0xd6, 0x60, 0x80, 0x5d, 0x8e, 0x89, 0x27, 0x87, 0x8a, 0xb8, + 0xce, 0xcc, 0x3b, 0xa1, 0xa9, 0x0a, 0xc2, 0xfe, 0xc6, 0x58, 0xf0, 0x42, 0xd7, 0xe5, 0xad, 0xf0, + 0x78, 0x39, 0xb8, 0x1d, 0x13, 0x76, 0x2b, 0xbc, 0x32, 0xff, 0xb1, 0xf4, 0x9a, 0x37, 0x87, 0x77, + 0xcc, 0x33, 0x66, 0x94, 0xa4, 0x9a, 0x88, 0xf8, 0x2f, 0xd3, 0x97, 0x4d, 0x42, 0x91, 0x86, 0x9a, + 0xc9, 0xce, 0xd2, 0xc1, 0xbe, 0x63, 0x32, 0xc3, 0x59, 0xee, 0x27, 0xb8, 0x07, 0x4e, 0xf9, 0x30, + 0x91, 0x9d, 0x92, 0xc7, 0xb8, 0xe3, 0xfe, 0x69, 0x1f, 0x8c, 0x99, 0x82, 0x81, 0x66, 0xa1, 0x22, + 0xb4, 0x29, 0x95, 0xca, 0x48, 0xc9, 0xff, 0xaa, 0x44, 0xe0, 0x94, 0x86, 0x25, 0x75, 0x62, 0xc5, + 0xb5, 0x70, 0x9c, 0x34, 0xa9, 0x93, 0xc2, 0x60, 0x8d, 0x8a, 0xaa, 0xad, 0xeb, 0x61, 0x98, 0xa8, + 0x85, 0x5b, 0xc9, 0xcc, 0x3c, 0x83, 0x62, 0x81, 0xa5, 0x0b, 0xf6, 0x3d, 0xda, 0x21, 0xdf, 0x74, + 0x01, 0xaa, 0x05, 0xfb, 0x86, 0x8e, 0xc4, 0x26, 0x2d, 0xdd, 0x80, 0xc2, 0x98, 0x09, 0xa1, 0x50, + 0x8e, 0xd3, 0xf0, 0xa6, 0x3a, 0xbf, 0x2c, 0x26, 0xf1, 0xe8, 0x0b, 0xf0, 0x88, 0xba, 0xdb, 0x85, + 0xb9, 0x4b, 0x55, 0xd6, 0x38, 0x60, 0xd8, 0xb7, 0x8f, 0x2c, 0x74, 0x26, 0xc3, 0xdd, 0xca, 0xa3, + 0x57, 0x61, 0x4c, 0x28, 0xb6, 0x92, 0xe3, 0xa0, 0x79, 0xfa, 0x7d, 0xc3, 0xc0, 0xe2, 0x0c, 0x35, + 0xaa, 0xc2, 0x04, 0x85, 0x30, 0x8d, 0x52, 0x72, 0xe0, 0x77, 0xd4, 0xd4, 0xce, 0x7c, 0x23, 0x83, + 0xc7, 0x6d, 0x25, 0xd0, 0x1c, 0x8c, 0x73, 0xdd, 0x82, 0x5a, 0x71, 0xec, 0x3b, 0x88, 0x48, 0x4a, + 0x35, 0x09, 0x6e, 0x99, 0x68, 0x9c, 0xa5, 0x47, 0x57, 0x61, 0xc4, 0x89, 0x1a, 0x5b, 0x5e, 0x42, + 0x1a, 0x49, 0x2b, 0xe2, 0xf9, 0x16, 0xb4, 0xf0, 0x81, 0x39, 0x0d, 0x87, 0x0d, 0x4a, 0xfb, 0x5d, + 0x38, 0xdd, 0x21, 0x6c, 0x9b, 0x0a, 0x8e, 0xd3, 0xf4, 0x64, 0x9f, 0x32, 0x81, 0x4a, 0x73, 0xb5, + 0x65, 0xd9, 0x1b, 0x8d, 0x8a, 0x4a, 0x27, 0xf3, 0x25, 0x6b, 0x99, 0x06, 0x95, 0x74, 0x2e, 0x49, + 0x04, 0x4e, 0x69, 0xec, 0xff, 0x59, 0x01, 0xcd, 0xd5, 0x52, 0x20, 0x3c, 0xe5, 0x2a, 0x8c, 0xc8, + 0xe4, 0x99, 0x5a, 0xd2, 0x3a, 0xd5, 0xcd, 0x6b, 0x1a, 0x0e, 0x1b, 0x94, 0xb4, 0x6d, 0x81, 0x74, + 0x20, 0x65, 0xc3, 0xa2, 0x94, 0x67, 0x09, 0xa7, 0x34, 0xe8, 0x12, 0x0c, 0xc5, 0xc4, 0xdf, 0x58, + 0xf1, 0x82, 0x7b, 0x42, 0xb0, 0xd5, 0xaa, 0x5c, 0x17, 0x70, 0xac, 0x28, 0xd0, 0x3c, 0x94, 0x5b, + 0x9e, 0x2b, 0x44, 0x59, 0xaa, 0x0c, 0xe5, 0xdb, 0xcb, 0xd5, 0x83, 0xbd, 0xe9, 0x27, 0xba, 0x65, + 0x1f, 0xa5, 0xc6, 0x74, 0x3c, 0x43, 0xa7, 0x1f, 0x2d, 0xdc, 0xc9, 0xa9, 0x3e, 0xd0, 0xa3, 0x53, + 0xfd, 0x0a, 0x80, 0xe8, 0xb5, 0x94, 0xe5, 0x72, 0xfa, 0xd5, 0xae, 0x29, 0x0c, 0xd6, 0xa8, 0xa8, + 0x49, 0xde, 0x88, 0x88, 0x23, 0xad, 0x56, 0x1e, 0x4e, 0x3c, 0x74, 0x74, 0x93, 0x7c, 0x21, 0xcb, + 0x0c, 0xb7, 0xf3, 0x47, 0x21, 0x9c, 0x72, 0xe9, 0x44, 0x32, 0x2a, 0xad, 0xf4, 0x1e, 0xc3, 0x4c, + 0x2b, 0xac, 0x66, 0x19, 0xe1, 0x76, 0xde, 0xe8, 0xcb, 0x30, 0x25, 0x81, 0xed, 0xb7, 0x37, 0xd9, + 0x74, 0x29, 0xcf, 0x9f, 0xdf, 0xdf, 0x9b, 0x9e, 0xaa, 0x76, 0xa5, 0xc2, 0x87, 0x70, 0x40, 0x6f, + 0xc0, 0x00, 0x3b, 0x84, 0x89, 0x27, 0x87, 0xd9, 0x6e, 0xf7, 0x62, 0x91, 0x48, 0x78, 0x2a, 0xf5, + 0x33, 0xec, 0x28, 0x47, 0xc4, 0x78, 0xa6, 0x27, 0x5b, 0x0c, 0x88, 0x05, 0x4f, 0xd4, 0x84, 0x61, + 0x27, 0x08, 0xc2, 0xc4, 0xe1, 0x4a, 0xd8, 0x48, 0x11, 0x3d, 0x52, 0xab, 0x62, 0x2e, 0x2d, 0xcb, + 0xeb, 0x51, 0x81, 0x63, 0x1a, 0x06, 0xeb, 0x55, 0xa0, 0xfb, 0x30, 0x1e, 0xde, 0xa7, 0x0b, 0xa6, + 0x3c, 0x87, 0x88, 0x27, 0x47, 0xcd, 0x8e, 0xe5, 0x78, 0x55, 0x8d, 0xc2, 0xda, 0x4a, 0x66, 0x32, + 0xc5, 0xd9, 0x5a, 0xd0, 0x8c, 0xe1, 0x5b, 0x1e, 0x4b, 0x23, 0x99, 0x53, 0xdf, 0xb2, 0xee, 0x4a, + 0x66, 0x37, 0x84, 0x79, 0xf4, 0x22, 0x5b, 0x11, 0xc6, 0x33, 0x37, 0x84, 0x53, 0x14, 0xd6, 0xe9, + 0xa6, 0x3e, 0x05, 0xc3, 0xda, 0xc0, 0xf7, 0x12, 0x32, 0x3b, 0xf5, 0x2a, 0x4c, 0x64, 0x07, 0xb4, + 0xa7, 0x90, 0xdb, 0xff, 0x51, 0x82, 0xf1, 0x0e, 0x87, 0x3c, 0xf7, 0x3c, 0x16, 0xf6, 0x6d, 0x2c, + 0x7d, 0x37, 0xbc, 0xc0, 0xc5, 0x0c, 0x63, 0x2e, 0x60, 0xa5, 0x02, 0x0b, 0x98, 0x5c, 0x4d, 0xcb, + 0x5d, 0x57, 0x53, 0xb1, 0x68, 0xf5, 0x7d, 0x90, 0x45, 0xcb, 0xdc, 0x27, 0xfa, 0x0b, 0xed, 0x13, + 0x0f, 0x61, 0xa1, 0x33, 0xb6, 0x9a, 0xc1, 0x02, 0x5b, 0xcd, 0xb7, 0x4b, 0x30, 0x91, 0x86, 0x17, + 0x8b, 0x8c, 0xba, 0xc7, 0x7f, 0x66, 0xb0, 0x66, 0x9c, 0x19, 0xe4, 0x25, 0xcc, 0xcd, 0xb4, 0xaf, + 0xeb, 0xf9, 0xc1, 0x1b, 0x99, 0xf3, 0x83, 0x17, 0x7b, 0xe4, 0x7b, 0xf8, 0x59, 0xc2, 0xf7, 0x4a, + 0x70, 0x36, 0x5b, 0x64, 0xc1, 0x77, 0xbc, 0xed, 0x13, 0x18, 0xaf, 0x2f, 0x18, 0xe3, 0xf5, 0x72, + 0x6f, 0xfd, 0x62, 0x8d, 0xec, 0x3a, 0x68, 0x4e, 0x66, 0xd0, 0x3e, 0x75, 0x14, 0xe6, 0x87, 0x8f, + 0xdc, 0x1f, 0x58, 0xf0, 0x68, 0xc7, 0x72, 0x27, 0xe0, 0x25, 0x7d, 0xdd, 0xf4, 0x92, 0xbe, 0x70, + 0x84, 0xde, 0x75, 0x71, 0x9b, 0xfe, 0xd7, 0x52, 0x97, 0x5e, 0x31, 0x4f, 0xd2, 0x2d, 0x18, 0x76, + 0x1a, 0x0d, 0x12, 0xc7, 0xab, 0xa1, 0xab, 0x72, 0x0d, 0x3d, 0xcf, 0xf6, 0x96, 0x14, 0x7c, 0xb0, + 0x37, 0x3d, 0x95, 0x65, 0x91, 0xa2, 0xb1, 0xce, 0xc1, 0xcc, 0x82, 0x56, 0x3a, 0xa6, 0x2c, 0x68, + 0x57, 0x00, 0x76, 0x94, 0x05, 0x9b, 0x75, 0x50, 0x69, 0xb6, 0xad, 0x46, 0x85, 0xfe, 0x3c, 0xd3, + 0x08, 0x79, 0x44, 0x45, 0x9f, 0x79, 0x53, 0x31, 0xe7, 0xfb, 0xe9, 0xd1, 0x19, 0xfc, 0x42, 0xa4, + 0x72, 0xe6, 0x29, 0x96, 0xf6, 0x3f, 0x2d, 0xc3, 0x47, 0x0f, 0x11, 0x3a, 0x34, 0x67, 0x1e, 0x90, + 0x3e, 0x97, 0xf5, 0xdc, 0x4c, 0x75, 0x2c, 0x6c, 0xb8, 0x72, 0x32, 0xdf, 0xaa, 0xf4, 0x81, 0xbf, + 0xd5, 0x37, 0x75, 0x3f, 0x1b, 0x0f, 0x8c, 0xbc, 0x76, 0xe4, 0x69, 0xf5, 0xb3, 0xe9, 0x17, 0xff, + 0x9a, 0x05, 0x4f, 0x74, 0xec, 0x94, 0x11, 0x8e, 0x31, 0x0b, 0x95, 0x06, 0x05, 0x6a, 0x37, 0x58, + 0xd2, 0xab, 0x63, 0x12, 0x81, 0x53, 0x1a, 0x23, 0xea, 0xa2, 0x94, 0x1b, 0x75, 0xf1, 0x7b, 0x16, + 0x9c, 0xc9, 0x36, 0xe2, 0x04, 0xd6, 0x9c, 0xba, 0xb9, 0xe6, 0xcc, 0xf4, 0xf6, 0xe9, 0xbb, 0x2c, + 0x37, 0xbf, 0x36, 0x0a, 0xe7, 0xda, 0x76, 0x2c, 0x3e, 0x8a, 0x3f, 0x67, 0xc1, 0xa9, 0x4d, 0xa6, + 0x79, 0x6b, 0xd7, 0x84, 0x44, 0xbf, 0x72, 0xee, 0x56, 0x1d, 0x7a, 0xbb, 0x88, 0xdb, 0x11, 0x6d, + 0x24, 0xb8, 0xbd, 0x32, 0xf4, 0x75, 0x0b, 0xce, 0x38, 0xf7, 0xe3, 0xb6, 0xb7, 0x1a, 0x84, 0x18, + 0xbd, 0x9a, 0xe3, 0xe4, 0xca, 0x79, 0xe5, 0x61, 0x7e, 0x72, 0x7f, 0x6f, 0xfa, 0x4c, 0x27, 0x2a, + 0xdc, 0xb1, 0x56, 0xfa, 0x7d, 0xb7, 0xc4, 0x35, 0x84, 0x62, 0x17, 0xde, 0x3a, 0x5d, 0x5a, 0xe0, + 0x4b, 0x92, 0xc4, 0x60, 0xc5, 0x11, 0xbd, 0x05, 0x95, 0x4d, 0x79, 0x33, 0x28, 0xbb, 0xe4, 0x75, + 0x19, 0xe6, 0x4e, 0x17, 0x89, 0x78, 0x68, 0xbc, 0x42, 0xe1, 0x94, 0x29, 0xba, 0x0e, 0xe5, 0x60, + 0x23, 0x16, 0x77, 0x70, 0xf3, 0x82, 0x6d, 0xcc, 0x10, 0x27, 0x7e, 0x6d, 0xf1, 0xe6, 0x52, 0x1d, + 0x53, 0x16, 0x94, 0x53, 0xb4, 0xee, 0x0a, 0xef, 0x6e, 0x0e, 0x27, 0x3c, 0x5f, 0x6d, 0xe7, 0x84, + 0xe7, 0xab, 0x98, 0xb2, 0x40, 0x35, 0xe8, 0x67, 0x97, 0x1c, 0x84, 0xeb, 0x36, 0xe7, 0xa2, 0x76, + 0xdb, 0x55, 0x0e, 0x9e, 0x68, 0x8f, 0x81, 0x31, 0x67, 0x84, 0xd6, 0x60, 0xa0, 0xc1, 0xd2, 0x92, + 0x0b, 0xbb, 0x3a, 0x2f, 0x85, 0x41, 0x5b, 0x0a, 0x73, 0x7e, 0xc4, 0xc4, 0xe1, 0x58, 0xf0, 0x62, + 0x5c, 0x49, 0x73, 0x6b, 0x23, 0x16, 0x86, 0x73, 0x1e, 0xd7, 0xb6, 0x04, 0xf3, 0x82, 0x2b, 0x83, + 0x63, 0xc1, 0x0b, 0x55, 0xa1, 0xb4, 0xd1, 0x10, 0xf9, 0x3a, 0x73, 0x5c, 0xb6, 0xe6, 0x1d, 0xd4, + 0xf9, 0x81, 0xfd, 0xbd, 0xe9, 0xd2, 0xd2, 0x02, 0x2e, 0x6d, 0x34, 0xd0, 0xeb, 0x30, 0xb8, 0xc1, + 0x6f, 0x15, 0x8a, 0xdc, 0x9c, 0x97, 0xf3, 0xae, 0x3e, 0xb6, 0x5d, 0x41, 0xe4, 0xd7, 0x1f, 0x04, + 0x02, 0x4b, 0x76, 0x2c, 0x6d, 0x99, 0xba, 0x27, 0x29, 0x92, 0x73, 0xce, 0xf4, 0x76, 0xaf, 0x52, + 0xd8, 0x93, 0x0a, 0x8a, 0x35, 0x8e, 0x54, 0xe6, 0x1d, 0xf9, 0xc2, 0x02, 0x4b, 0xcc, 0x99, 0x2b, + 0xf3, 0x1d, 0x1f, 0x64, 0xe0, 0x32, 0xaf, 0x50, 0x38, 0x65, 0x8a, 0x5a, 0x30, 0xba, 0x13, 0x37, + 0xb7, 0x88, 0x9c, 0xfa, 0x2c, 0x5b, 0xe7, 0xf0, 0x95, 0xcf, 0xe4, 0xa4, 0x60, 0x15, 0x45, 0xbc, + 0x28, 0x69, 0x39, 0x7e, 0xdb, 0x0a, 0xc6, 0xf2, 0x44, 0xdd, 0xd1, 0xd9, 0x62, 0xb3, 0x16, 0xfa, + 0x49, 0xde, 0x69, 0x85, 0xeb, 0xbb, 0x09, 0x11, 0xd9, 0x3c, 0x73, 0x3e, 0xc9, 0x6b, 0x9c, 0xb8, + 0xfd, 0x93, 0x08, 0x04, 0x96, 0xec, 0xd4, 0x90, 0xb1, 0xd5, 0x78, 0xa2, 0xf0, 0x90, 0xb5, 0xf5, + 0x21, 0x1d, 0x32, 0xb6, 0xfa, 0xa6, 0x4c, 0xd9, 0xaa, 0xdb, 0xdc, 0x0a, 0x93, 0x30, 0xc8, 0xac, + 0xfd, 0xa7, 0x8a, 0xac, 0xba, 0xb5, 0x0e, 0x25, 0xdb, 0x57, 0xdd, 0x4e, 0x54, 0xb8, 0x63, 0xad, + 0xf6, 0x1f, 0xf7, 0xb7, 0x6f, 0xb7, 0x4c, 0x19, 0xfe, 0x2b, 0xed, 0xe7, 0x8e, 0x9f, 0xeb, 0xdd, + 0xe6, 0x7b, 0x88, 0x27, 0x90, 0x5f, 0xb7, 0xe0, 0x5c, 0xb3, 0xe3, 0x66, 0x2a, 0x36, 0xac, 0x5e, + 0x4d, 0x47, 0x3e, 0x60, 0x2a, 0x55, 0x6d, 0x67, 0x3c, 0xee, 0x52, 0x67, 0x56, 0x01, 0x2d, 0x7f, + 0x60, 0x05, 0xf4, 0x2e, 0x0c, 0x31, 0x9d, 0x29, 0xcd, 0xab, 0xd1, 0x63, 0x0a, 0x0a, 0xb6, 0xf5, + 0x2d, 0x08, 0x16, 0x58, 0x31, 0xa3, 0x03, 0xf7, 0x78, 0xb6, 0x13, 0x98, 0x30, 0xb4, 0x48, 0xe7, + 0xca, 0x7d, 0x1d, 0x4b, 0x62, 0x24, 0x1e, 0xaf, 0x1d, 0x46, 0x7c, 0x90, 0x47, 0x80, 0x0f, 0xaf, + 0xec, 0x24, 0x15, 0xda, 0xbf, 0x67, 0x75, 0xd0, 0xbf, 0xb8, 0x09, 0xf2, 0x19, 0xd3, 0x04, 0x79, + 0x3a, 0x6b, 0x82, 0xb4, 0xb9, 0x0d, 0x0c, 0xeb, 0xa3, 0x78, 0x62, 0xc6, 0xa2, 0x09, 0x3f, 0x6c, + 0x1f, 0x2e, 0xe4, 0x4d, 0x6e, 0x16, 0xe1, 0xe3, 0xaa, 0xe3, 0xb2, 0x34, 0xc2, 0xc7, 0x5d, 0xae, + 0x62, 0x86, 0x29, 0x7a, 0x67, 0xdc, 0xfe, 0xf9, 0x12, 0x94, 0x6b, 0xa1, 0x7b, 0x02, 0x6e, 0x90, + 0x6b, 0x86, 0x1b, 0xe4, 0xa9, 0xdc, 0xf7, 0xa5, 0xba, 0x3a, 0x3d, 0x6e, 0x65, 0x9c, 0x1e, 0x1f, + 0xcf, 0x67, 0x75, 0xb8, 0x8b, 0xe3, 0xfb, 0x65, 0xd0, 0x5f, 0xc8, 0x42, 0xff, 0xe1, 0x28, 0x81, + 0x9f, 0xe5, 0x62, 0x8f, 0x66, 0x89, 0x3a, 0x58, 0x88, 0x90, 0xbc, 0x24, 0xf6, 0x33, 0x1b, 0xff, + 0x79, 0x97, 0x78, 0x9b, 0x5b, 0x09, 0x71, 0xb3, 0x1d, 0x3b, 0xb9, 0xf8, 0xcf, 0xff, 0x66, 0xc1, + 0x78, 0xa6, 0x76, 0xe4, 0x77, 0xba, 0x67, 0x72, 0x44, 0xc7, 0xc6, 0xa9, 0xdc, 0x8b, 0x29, 0x33, + 0x00, 0xca, 0x3f, 0x2d, 0xdd, 0x0f, 0x4c, 0x17, 0x53, 0x0e, 0xec, 0x18, 0x6b, 0x14, 0xe8, 0x25, + 0x18, 0x4e, 0xc2, 0x66, 0xe8, 0x87, 0x9b, 0xbb, 0x37, 0x88, 0xcc, 0x66, 0xa0, 0x7c, 0xfb, 0x6b, + 0x29, 0x0a, 0xeb, 0x74, 0xf6, 0x0f, 0xca, 0x90, 0x7d, 0x5f, 0xed, 0xff, 0xcb, 0xe9, 0xcf, 0x8e, + 0x9c, 0xfe, 0xa1, 0x05, 0x13, 0xb4, 0x76, 0x16, 0xe0, 0x21, 0xe3, 0x34, 0x55, 0x96, 0x78, 0xeb, + 0x90, 0x2c, 0xf1, 0x4f, 0xd3, 0xd5, 0xce, 0x0d, 0x5b, 0x89, 0x70, 0x99, 0x68, 0x8b, 0x18, 0x85, + 0x62, 0x81, 0x15, 0x74, 0x24, 0x8a, 0xc4, 0x85, 0x16, 0x9d, 0x8e, 0x44, 0x11, 0x16, 0x58, 0x99, + 0x44, 0xbe, 0xaf, 0x4b, 0x12, 0x79, 0x96, 0x0f, 0x48, 0x04, 0x16, 0x08, 0x75, 0x40, 0xcb, 0x07, + 0x24, 0x23, 0x0e, 0x52, 0x1a, 0xfb, 0xbb, 0x65, 0x18, 0xa9, 0x85, 0x6e, 0x1a, 0x80, 0xfd, 0xa2, + 0x11, 0x80, 0x7d, 0x21, 0x13, 0x80, 0x3d, 0xa1, 0xd3, 0x3e, 0x9c, 0xf8, 0x6b, 0x91, 0x37, 0x8a, + 0x3d, 0x73, 0x70, 0xc4, 0xd8, 0x6b, 0x23, 0x6f, 0x94, 0x62, 0x84, 0x4d, 0xbe, 0x7f, 0x96, 0x62, + 0xae, 0xff, 0xb7, 0x05, 0x63, 0xb5, 0xd0, 0xa5, 0x02, 0xfa, 0x67, 0x49, 0x1a, 0xf5, 0x6c, 0x53, + 0x03, 0x87, 0x64, 0x9b, 0xfa, 0x47, 0x16, 0x0c, 0xd6, 0x42, 0xf7, 0x04, 0xdc, 0x89, 0x4b, 0xa6, + 0x3b, 0xf1, 0x89, 0xdc, 0x95, 0xb7, 0x8b, 0x07, 0xf1, 0x37, 0xcb, 0x30, 0x4a, 0x5b, 0x1c, 0x6e, + 0xca, 0xef, 0x65, 0x8c, 0x8d, 0x55, 0x60, 0x6c, 0xa8, 0x4a, 0x18, 0xfa, 0x7e, 0x78, 0x3f, 0xfb, + 0xed, 0x96, 0x18, 0x14, 0x0b, 0x2c, 0xba, 0x04, 0x43, 0xcd, 0x88, 0xec, 0x78, 0x61, 0x2b, 0xce, + 0x5e, 0x8e, 0xab, 0x09, 0x38, 0x56, 0x14, 0xe8, 0x45, 0x18, 0x89, 0xbd, 0xa0, 0x41, 0x64, 0xd8, + 0x41, 0x1f, 0x0b, 0x3b, 0xe0, 0x89, 0xfd, 0x34, 0x38, 0x36, 0xa8, 0xd0, 0x5d, 0xa8, 0xb0, 0xff, + 0x6c, 0x06, 0xf5, 0x9e, 0x05, 0x9e, 0x67, 0xb3, 0x92, 0x0c, 0x70, 0xca, 0x0b, 0x5d, 0x01, 0x48, + 0x64, 0x80, 0x44, 0x2c, 0xb2, 0x72, 0x28, 0xbd, 0x54, 0x85, 0x4e, 0xc4, 0x58, 0xa3, 0x42, 0xcf, + 0x41, 0x25, 0x71, 0x3c, 0x7f, 0xc5, 0x0b, 0x48, 0x2c, 0x02, 0x4c, 0x44, 0x92, 0x5e, 0x01, 0xc4, + 0x29, 0x9e, 0xee, 0xf7, 0xec, 0x6a, 0x2e, 0x7f, 0x61, 0x62, 0x88, 0x51, 0xb3, 0xfd, 0x7e, 0x45, + 0x41, 0xb1, 0x46, 0x61, 0x5f, 0x85, 0xb3, 0xb5, 0xd0, 0xad, 0x85, 0x51, 0xb2, 0x14, 0x46, 0xf7, + 0x9d, 0xc8, 0x95, 0xdf, 0x6f, 0x5a, 0xe6, 0x86, 0xa5, 0x7b, 0x72, 0x3f, 0xf7, 0xb0, 0x19, 0xb9, + 0x5e, 0x5f, 0x60, 0x3b, 0x7e, 0x8f, 0x91, 0xfd, 0x3f, 0x2e, 0x01, 0xaa, 0xb1, 0x10, 0x0e, 0xe3, + 0x41, 0x92, 0x2d, 0x18, 0x8b, 0xc9, 0x8a, 0x17, 0xb4, 0x1e, 0x08, 0x56, 0xc5, 0xae, 0x52, 0xd4, + 0x17, 0xf5, 0x32, 0xfc, 0x1e, 0xab, 0x09, 0xc3, 0x19, 0xbe, 0x74, 0x30, 0xa3, 0x56, 0x30, 0x17, + 0xdf, 0x8e, 0x49, 0x24, 0x1e, 0xe0, 0x60, 0x83, 0x89, 0x25, 0x10, 0xa7, 0x78, 0x2a, 0x3c, 0xec, + 0xcf, 0xcd, 0x30, 0xc0, 0x61, 0x98, 0x48, 0x71, 0x63, 0x09, 0xd9, 0x35, 0x38, 0x36, 0xa8, 0xd0, + 0x12, 0xa0, 0xb8, 0xd5, 0x6c, 0xfa, 0xec, 0x54, 0xcc, 0xf1, 0xaf, 0x45, 0x61, 0xab, 0xc9, 0xa3, + 0x78, 0x45, 0x2e, 0xf3, 0x7a, 0x1b, 0x16, 0x77, 0x28, 0x41, 0x17, 0x8b, 0x8d, 0x98, 0xfd, 0x16, + 0xf7, 0x74, 0xb9, 0x77, 0xae, 0xce, 0x40, 0x58, 0xe2, 0xec, 0xaf, 0xb2, 0x0d, 0x8e, 0xbd, 0x8c, + 0x90, 0xb4, 0x22, 0x82, 0xb6, 0x61, 0xb4, 0xc9, 0x36, 0xb1, 0x24, 0x0a, 0x7d, 0x9f, 0x48, 0xfd, + 0xf2, 0x68, 0x41, 0x24, 0x3c, 0x17, 0xba, 0xce, 0x0e, 0x9b, 0xdc, 0xed, 0x9f, 0x0c, 0xb3, 0xb5, + 0x4a, 0x1c, 0x4c, 0x0e, 0x8a, 0x50, 0x51, 0xa1, 0xc9, 0x7d, 0xac, 0xc8, 0x1b, 0x47, 0xe9, 0x3e, + 0x20, 0x02, 0x4f, 0xb1, 0xe4, 0x82, 0xbe, 0xc4, 0x02, 0xa1, 0xf9, 0x02, 0x51, 0xfc, 0xe1, 0x31, + 0x4e, 0x6f, 0x04, 0x41, 0x0b, 0x16, 0x58, 0x63, 0x87, 0x56, 0x60, 0x54, 0x24, 0xd2, 0x17, 0xee, + 0x85, 0xb2, 0x61, 0x62, 0x8f, 0x62, 0x1d, 0x79, 0x90, 0x05, 0x60, 0xb3, 0x30, 0xda, 0x84, 0xc7, + 0xb5, 0x87, 0x62, 0x3a, 0x04, 0x3c, 0xf1, 0x95, 0xe7, 0x89, 0xfd, 0xbd, 0xe9, 0xc7, 0xd7, 0x0e, + 0x23, 0xc4, 0x87, 0xf3, 0x41, 0xb7, 0xe0, 0xac, 0xd3, 0x48, 0xbc, 0x1d, 0x52, 0x25, 0x8e, 0xeb, + 0x7b, 0x01, 0x31, 0x2f, 0x73, 0x3f, 0xba, 0xbf, 0x37, 0x7d, 0x76, 0xae, 0x13, 0x01, 0xee, 0x5c, + 0x0e, 0x7d, 0x06, 0x2a, 0x6e, 0x10, 0x8b, 0x31, 0x18, 0x30, 0xde, 0x45, 0xaa, 0x54, 0x6f, 0xd6, + 0x55, 0xff, 0xd3, 0x3f, 0x38, 0x2d, 0x80, 0xde, 0xe1, 0x4f, 0x4c, 0x2b, 0x6b, 0x86, 0xbf, 0xc7, + 0xf5, 0x72, 0x21, 0xfb, 0xd9, 0xb8, 0x64, 0xc1, 0x3d, 0x6f, 0x2a, 0xb0, 0xd0, 0xb8, 0x7f, 0x61, + 0x54, 0x81, 0x3e, 0x0f, 0x28, 0x26, 0xd1, 0x8e, 0xd7, 0x20, 0x73, 0x0d, 0x96, 0x0d, 0x93, 0x1d, + 0xf1, 0x0d, 0x19, 0xd1, 0xf5, 0xa8, 0xde, 0x46, 0x81, 0x3b, 0x94, 0x42, 0xd7, 0xe9, 0xca, 0xa3, + 0x43, 0x45, 0x1c, 0xa8, 0x54, 0x0c, 0x27, 0xab, 0xa4, 0x19, 0x91, 0x86, 0x93, 0x10, 0xd7, 0xe4, + 0x88, 0x33, 0xe5, 0xe8, 0xbe, 0xa4, 0x12, 0x9e, 0x83, 0x19, 0xbd, 0xd8, 0x9e, 0xf4, 0x9c, 0xda, + 0x59, 0x5b, 0x61, 0x9c, 0xdc, 0x24, 0xc9, 0xfd, 0x30, 0xba, 0xc7, 0x3c, 0xf6, 0x43, 0x5a, 0x72, + 0xb1, 0x14, 0x85, 0x75, 0x3a, 0xaa, 0x43, 0xb1, 0xa3, 0xa2, 0xe5, 0x2a, 0xf3, 0xc3, 0x0f, 0xa5, + 0x73, 0xe7, 0x3a, 0x07, 0x63, 0x89, 0x97, 0xa4, 0xcb, 0xb5, 0x05, 0xe6, 0x53, 0xcf, 0x90, 0x2e, + 0xd7, 0x16, 0xb0, 0xc4, 0xa3, 0xb0, 0xfd, 0xf5, 0xa9, 0xb1, 0x22, 0xe7, 0x1b, 0xed, 0x2b, 0x79, + 0xc1, 0x07, 0xa8, 0x1e, 0xc0, 0x84, 0x7a, 0x01, 0x8b, 0x67, 0x7d, 0x8c, 0x27, 0xc7, 0x8b, 0x3c, + 0x70, 0xdd, 0x31, 0x79, 0xa4, 0x0a, 0xfc, 0x5d, 0xce, 0xf0, 0xc4, 0x6d, 0xb5, 0x18, 0x49, 0x09, + 0x26, 0x72, 0x93, 0xd8, 0xcf, 0x42, 0x25, 0x6e, 0xad, 0xbb, 0xe1, 0xb6, 0xe3, 0x05, 0xcc, 0xf1, + 0xad, 0x3f, 0xd7, 0x2c, 0x11, 0x38, 0xa5, 0x41, 0x35, 0x18, 0x72, 0xe4, 0x4b, 0xe5, 0xa8, 0xc8, + 0xa5, 0x65, 0xf5, 0x44, 0x39, 0xf3, 0x8a, 0xaa, 0xb7, 0xc9, 0x15, 0x17, 0xf4, 0x0a, 0x8c, 0x8a, + 0x5b, 0x37, 0x24, 0x62, 0xad, 0x3e, 0x6d, 0x86, 0x7c, 0xd7, 0x25, 0x92, 0x09, 0x98, 0x49, 0x3b, + 0xf5, 0x59, 0x38, 0xd5, 0x36, 0xc5, 0x7a, 0x0a, 0x9c, 0xfb, 0xb7, 0x7d, 0x50, 0x51, 0x1e, 0x2a, + 0x34, 0x6b, 0x3a, 0x23, 0x1f, 0xcd, 0x3a, 0x23, 0x87, 0xa8, 0x42, 0xa0, 0xfb, 0x1f, 0xbf, 0xdc, + 0xe1, 0xb9, 0xd8, 0x67, 0x73, 0x65, 0xaa, 0xf8, 0x3d, 0x96, 0x1e, 0x1e, 0xd5, 0x4d, 0xad, 0x94, + 0xbe, 0x43, 0xad, 0x94, 0x82, 0xef, 0x52, 0x51, 0x7b, 0xa4, 0x19, 0xba, 0xcb, 0xb5, 0xec, 0xb3, + 0x2b, 0x35, 0x0a, 0xc4, 0x1c, 0xc7, 0xf4, 0x48, 0xba, 0x47, 0x30, 0x3d, 0x72, 0xf0, 0x88, 0x7a, + 0xa4, 0x64, 0x80, 0x53, 0x5e, 0x68, 0x07, 0x4e, 0x35, 0xcc, 0x57, 0x74, 0xd4, 0xed, 0x94, 0xe7, + 0x7b, 0x78, 0xc5, 0xa6, 0xa5, 0xbd, 0x18, 0xb0, 0x90, 0xe5, 0x87, 0xdb, 0xab, 0x40, 0xaf, 0xc0, + 0xd0, 0x3b, 0x61, 0xbc, 0xe0, 0x3b, 0x71, 0x2c, 0x16, 0x4a, 0x79, 0x13, 0x60, 0xe8, 0xb5, 0x5b, + 0x75, 0x06, 0x3f, 0xe0, 0x0f, 0xfa, 0xcb, 0xbf, 0x58, 0x15, 0xb0, 0x7f, 0x87, 0x7b, 0xc3, 0x84, + 0x7d, 0x4c, 0xe2, 0x96, 0x7f, 0x12, 0x89, 0xb3, 0x6f, 0x19, 0xa6, 0xfb, 0x43, 0xf0, 0xc7, 0xfe, + 0x7b, 0x8b, 0xf9, 0x63, 0xd7, 0xc8, 0x76, 0xd3, 0x77, 0x92, 0x93, 0x08, 0x69, 0xfc, 0x12, 0x0c, + 0x25, 0xa2, 0xb6, 0x62, 0x59, 0xbf, 0xb5, 0xe6, 0x31, 0x3f, 0xb5, 0x5a, 0xe3, 0x24, 0x14, 0x2b, + 0x86, 0xf6, 0xbf, 0xe0, 0x5f, 0x45, 0x62, 0x4e, 0xc0, 0xe8, 0xbc, 0x69, 0x1a, 0x9d, 0xcf, 0x14, + 0xee, 0x4b, 0x17, 0xe3, 0xf3, 0x07, 0x66, 0x0f, 0x98, 0x2a, 0xfa, 0xb3, 0x73, 0x60, 0x60, 0xdf, + 0x02, 0xf3, 0xb5, 0x21, 0xf4, 0x2a, 0x0f, 0x12, 0xe6, 0x8b, 0xec, 0xa5, 0x9e, 0x03, 0x84, 0xed, + 0xdf, 0x28, 0xc1, 0x19, 0xee, 0x32, 0x9c, 0xdb, 0x09, 0x3d, 0xb7, 0x16, 0xba, 0x22, 0x64, 0xda, + 0x85, 0x91, 0xa6, 0x66, 0x2a, 0x14, 0xcb, 0x07, 0xa1, 0x1b, 0x17, 0xa9, 0x7a, 0xa6, 0x43, 0xb1, + 0xc1, 0x95, 0xd6, 0x42, 0x76, 0xbc, 0x86, 0xf2, 0x40, 0x95, 0x7a, 0x5e, 0xf7, 0x54, 0x2d, 0x8b, + 0x1a, 0x1f, 0x6c, 0x70, 0x3d, 0x86, 0x04, 0xf5, 0xf6, 0xdf, 0xb1, 0xe0, 0x91, 0x2e, 0x39, 0x23, + 0x68, 0x75, 0xf7, 0x99, 0x9b, 0x56, 0x3c, 0x67, 0xa5, 0xaa, 0xe3, 0xce, 0x5b, 0x2c, 0xb0, 0x68, + 0x1d, 0x80, 0x3b, 0x5f, 0xd9, 0x93, 0xc5, 0xa5, 0x22, 0xb1, 0x12, 0x6d, 0x77, 0xb3, 0xb5, 0x6b, + 0xbb, 0xea, 0x91, 0x62, 0x8d, 0xab, 0xfd, 0x9d, 0x32, 0xf4, 0xf3, 0x57, 0x53, 0x6b, 0x30, 0xb8, + 0xc5, 0x33, 0x57, 0xf6, 0x96, 0x38, 0x33, 0x55, 0x05, 0x39, 0x00, 0x4b, 0x36, 0x68, 0x15, 0x4e, + 0x53, 0xbd, 0xc3, 0x73, 0xfc, 0x2a, 0xf1, 0x9d, 0x5d, 0x69, 0x5b, 0xf0, 0xac, 0xe5, 0x32, 0xc1, + 0xee, 0xe9, 0xe5, 0x76, 0x12, 0xdc, 0xa9, 0x1c, 0x7a, 0xb5, 0x2d, 0xe5, 0x14, 0xcf, 0x08, 0xaa, + 0x6e, 0x7b, 0x1d, 0x9e, 0x76, 0x8a, 0x6a, 0x3f, 0xcd, 0x36, 0x2b, 0x4a, 0x7b, 0x9c, 0xd2, 0xb4, + 0x9c, 0x4c, 0x5a, 0x54, 0x85, 0x89, 0xb8, 0xc5, 0x4e, 0xae, 0xd7, 0xb6, 0x22, 0x12, 0x6f, 0x85, + 0xbe, 0x2b, 0xde, 0x55, 0x53, 0x1a, 0x63, 0x3d, 0x83, 0xc7, 0x6d, 0x25, 0x28, 0x97, 0x0d, 0xc7, + 0xf3, 0x5b, 0x11, 0x49, 0xb9, 0x0c, 0x98, 0x5c, 0x96, 0x32, 0x78, 0xdc, 0x56, 0xc2, 0xfe, 0x13, + 0x0b, 0x4e, 0x77, 0x08, 0xef, 0xe0, 0x41, 0x87, 0x9b, 0x5e, 0x9c, 0xa8, 0xdc, 0xd4, 0x5a, 0xd0, + 0x21, 0x87, 0x63, 0x45, 0x41, 0xa5, 0x90, 0x9b, 0xc6, 0xd9, 0x63, 0x53, 0x71, 0x80, 0x2d, 0xb0, + 0xbd, 0x25, 0x90, 0x42, 0x17, 0xa0, 0xaf, 0x15, 0x93, 0x48, 0x3e, 0xd3, 0x24, 0x97, 0x28, 0xe6, + 0x0d, 0x61, 0x18, 0xaa, 0xec, 0x6c, 0x2a, 0x47, 0x84, 0xa6, 0xec, 0x70, 0x57, 0x04, 0xc7, 0xd9, + 0xdf, 0x2c, 0xc3, 0x78, 0x26, 0xcc, 0x8b, 0x36, 0x64, 0x3b, 0x0c, 0xbc, 0x24, 0x54, 0x49, 0x8b, + 0xf8, 0xcb, 0x30, 0xa4, 0xb9, 0xb5, 0x2a, 0xe0, 0x58, 0x51, 0xa0, 0xa7, 0xcd, 0x27, 0xac, 0xd3, + 0x36, 0xcf, 0x57, 0x8d, 0xd7, 0xec, 0x8a, 0xe6, 0xcb, 0x7f, 0x12, 0xfa, 0x9a, 0xa1, 0x7a, 0x99, + 0x54, 0x09, 0x3d, 0x9e, 0xaf, 0xd6, 0xc2, 0xd0, 0xc7, 0x0c, 0x89, 0x9e, 0x12, 0xbd, 0xcf, 0xf8, + 0x6f, 0xb1, 0xe3, 0x86, 0xb1, 0x36, 0x04, 0xcf, 0xc0, 0xe0, 0x3d, 0xb2, 0x1b, 0x79, 0xc1, 0x66, + 0xd6, 0x7b, 0x7d, 0x83, 0x83, 0xb1, 0xc4, 0x9b, 0x39, 0xf1, 0x07, 0x8f, 0x39, 0x27, 0xfe, 0x50, + 0x6e, 0xa4, 0xea, 0x6f, 0x5a, 0x30, 0xce, 0x32, 0xf9, 0x89, 0x8b, 0xb4, 0x5e, 0x18, 0x9c, 0xc0, + 0xf6, 0xf8, 0x24, 0xf4, 0x47, 0xb4, 0xd2, 0x6c, 0x5a, 0x6b, 0xd6, 0x12, 0xcc, 0x71, 0xe8, 0x31, + 0xe8, 0x63, 0x4d, 0xa0, 0x9f, 0x71, 0x84, 0xa7, 0x09, 0xae, 0x3a, 0x89, 0x83, 0x19, 0x94, 0xdd, + 0x8a, 0xc0, 0xa4, 0xe9, 0x7b, 0xbc, 0xd1, 0xa9, 0xd3, 0xe9, 0xc3, 0x76, 0x2b, 0xa2, 0x63, 0x23, + 0x1f, 0xd6, 0xad, 0x88, 0xce, 0xcc, 0x0f, 0x57, 0x51, 0xff, 0x7b, 0x09, 0xce, 0x77, 0x2c, 0x97, + 0x9e, 0x83, 0x2d, 0x19, 0xe7, 0x60, 0x57, 0x32, 0xe7, 0x60, 0xf6, 0xe1, 0xa5, 0x1f, 0xce, 0xc9, + 0x58, 0xe7, 0x03, 0xab, 0xf2, 0x09, 0x1e, 0x58, 0xf5, 0x15, 0x55, 0x1d, 0xfa, 0x73, 0x54, 0x87, + 0x3f, 0xb0, 0xe0, 0xd1, 0x8e, 0x43, 0xf6, 0xa1, 0xbb, 0x86, 0xd2, 0xb1, 0x95, 0x5d, 0x14, 0xeb, + 0x5f, 0x2e, 0x77, 0xe9, 0x15, 0x53, 0xb1, 0x2f, 0xd2, 0x55, 0x88, 0x21, 0x63, 0xa1, 0x14, 0x8d, + 0xf0, 0x15, 0x88, 0xc3, 0xb0, 0xc2, 0xa2, 0x58, 0xbb, 0xc6, 0xc1, 0x1b, 0xb9, 0x78, 0xc4, 0x09, + 0x35, 0x63, 0x7a, 0x0b, 0xf5, 0xfb, 0xc1, 0x99, 0xcb, 0x1d, 0xe8, 0xae, 0x66, 0x34, 0x95, 0x8f, + 0x62, 0x34, 0x8d, 0x74, 0x36, 0x98, 0xd0, 0x1c, 0x8c, 0x6f, 0x7b, 0x01, 0x7b, 0x4a, 0xcf, 0xd4, + 0x4a, 0xd4, 0x5d, 0xba, 0x55, 0x13, 0x8d, 0xb3, 0xf4, 0x53, 0xaf, 0xc0, 0xe8, 0xd1, 0x7d, 0x32, + 0xef, 0x97, 0xe1, 0xa3, 0x87, 0x2c, 0x0a, 0x7c, 0x77, 0x30, 0xbe, 0x8b, 0xb6, 0x3b, 0xb4, 0x7d, + 0x9b, 0x1a, 0x9c, 0xd9, 0x68, 0xf9, 0xfe, 0x2e, 0x8b, 0x22, 0x21, 0xae, 0xa4, 0x10, 0x1a, 0x9f, + 0x7a, 0xe4, 0x76, 0xa9, 0x03, 0x0d, 0xee, 0x58, 0x12, 0x7d, 0x1e, 0x50, 0xb8, 0xce, 0x72, 0x5d, + 0xba, 0xe9, 0xfd, 0x67, 0xf6, 0x09, 0xca, 0xe9, 0x54, 0xbd, 0xd5, 0x46, 0x81, 0x3b, 0x94, 0xa2, + 0xfa, 0x1f, 0x7b, 0x1f, 0x57, 0x35, 0x2b, 0xa3, 0xff, 0x61, 0x1d, 0x89, 0x4d, 0x5a, 0x74, 0x0d, + 0x4e, 0x39, 0x3b, 0x8e, 0xc7, 0xb3, 0xd7, 0x48, 0x06, 0x5c, 0x01, 0x54, 0x5e, 0x8f, 0xb9, 0x2c, + 0x01, 0x6e, 0x2f, 0x83, 0x9a, 0x86, 0x1b, 0x8b, 0xe7, 0xb6, 0xfe, 0xcc, 0x11, 0x24, 0xb8, 0xb0, + 0x63, 0xcb, 0xfe, 0x89, 0x45, 0xb7, 0xbe, 0x0e, 0xaf, 0xae, 0x19, 0xcf, 0xb5, 0x6b, 0x57, 0x5b, + 0xda, 0x9f, 0x6b, 0xe7, 0xfe, 0x40, 0x83, 0x96, 0x8b, 0x46, 0x9c, 0x06, 0xa3, 0x1a, 0xda, 0xa6, + 0xb8, 0xd1, 0xa5, 0x28, 0xd0, 0x5d, 0x18, 0x74, 0xbd, 0x1d, 0x2f, 0x0e, 0xa3, 0x02, 0x0f, 0x24, + 0xb7, 0x05, 0x38, 0xa6, 0xab, 0x65, 0x95, 0x33, 0xc1, 0x92, 0x9b, 0xfd, 0xad, 0x12, 0x8c, 0xca, + 0xfa, 0x5e, 0x6b, 0x85, 0x89, 0x73, 0x02, 0x1b, 0xfa, 0x6b, 0xc6, 0x86, 0x3e, 0x5b, 0xec, 0x7a, + 0x1b, 0x6b, 0x5c, 0xd7, 0x8d, 0xfc, 0x0b, 0x99, 0x8d, 0xfc, 0x72, 0x2f, 0x4c, 0x0f, 0xdf, 0xc0, + 0xff, 0xb5, 0x05, 0xa7, 0x0c, 0xfa, 0x13, 0xd8, 0x47, 0x6a, 0xe6, 0x3e, 0xf2, 0x5c, 0x0f, 0xbd, + 0xe9, 0xb2, 0x7f, 0x7c, 0xa7, 0x94, 0xe9, 0x05, 0xdb, 0x37, 0xbe, 0x02, 0x7d, 0x5b, 0x4e, 0xe4, + 0x16, 0x4b, 0xe3, 0xd6, 0x56, 0x7c, 0xe6, 0xba, 0x13, 0xb9, 0x7c, 0xf5, 0xbf, 0xa4, 0xde, 0x84, + 0x71, 0x22, 0x37, 0x37, 0x42, 0x9b, 0x55, 0x8a, 0xae, 0xc2, 0x40, 0xdc, 0x08, 0x9b, 0x2a, 0x16, + 0xee, 0x02, 0x7f, 0x2f, 0x86, 0x42, 0x0e, 0xf6, 0xa6, 0x91, 0x59, 0x1d, 0x05, 0x63, 0x41, 0x3f, + 0x45, 0xa0, 0xa2, 0xaa, 0x3e, 0xc6, 0x58, 0xe0, 0xf7, 0xcb, 0x70, 0xba, 0x83, 0xa4, 0xa0, 0xaf, + 0x1a, 0xa3, 0xf6, 0x4a, 0xcf, 0xa2, 0xf6, 0x01, 0xc7, 0xed, 0xab, 0xcc, 0x4a, 0x72, 0x85, 0x6c, + 0x1c, 0xa1, 0xfa, 0xdb, 0x31, 0xc9, 0x56, 0x4f, 0x41, 0xf9, 0xd5, 0xd3, 0x6a, 0x4f, 0x68, 0xf0, + 0x69, 0x35, 0xaa, 0x9d, 0xc7, 0xf8, 0x8d, 0xdf, 0xeb, 0x83, 0x33, 0x9d, 0x6e, 0xd0, 0xa2, 0x5f, + 0xb4, 0x32, 0x59, 0xda, 0x5f, 0xed, 0xfd, 0x1a, 0x2e, 0x4f, 0xdd, 0x2e, 0xb2, 0x4e, 0xcc, 0x98, + 0x79, 0xdb, 0x73, 0x47, 0x5b, 0xd4, 0xce, 0x6e, 0x55, 0x44, 0x3c, 0xdf, 0xbe, 0x5c, 0x0f, 0x3e, + 0x77, 0x84, 0xa6, 0x88, 0x94, 0xfd, 0x71, 0xe6, 0x56, 0x85, 0x04, 0xe7, 0xdf, 0xaa, 0x90, 0x6d, + 0x98, 0xda, 0x84, 0x61, 0xad, 0x5f, 0xc7, 0x28, 0x02, 0x1e, 0xdd, 0x9a, 0xb4, 0x56, 0x1f, 0xa3, + 0x18, 0xfc, 0xaa, 0x05, 0x99, 0x70, 0x15, 0xe5, 0x8a, 0xb1, 0xba, 0xba, 0x62, 0x2e, 0x40, 0x5f, + 0x14, 0xfa, 0x24, 0x9b, 0x3d, 0x1c, 0x87, 0x3e, 0xc1, 0x0c, 0xa3, 0x9e, 0x86, 0x2c, 0x77, 0x7b, + 0x1a, 0x92, 0xda, 0xe6, 0x3e, 0xd9, 0x21, 0xd2, 0x31, 0xa2, 0x16, 0xef, 0x15, 0x0a, 0xc4, 0x1c, + 0x67, 0xff, 0x7e, 0x19, 0x06, 0xb8, 0xf7, 0xe1, 0x04, 0x76, 0xe7, 0x9a, 0x70, 0x04, 0x14, 0xba, + 0xd5, 0xca, 0x5b, 0x35, 0x53, 0x75, 0x12, 0x87, 0x0b, 0x96, 0xea, 0x63, 0xea, 0x3c, 0x40, 0x33, + 0xc6, 0x28, 0x4c, 0x65, 0xec, 0x5b, 0xe0, 0x3c, 0xb4, 0x31, 0xd9, 0x02, 0x88, 0xd9, 0x63, 0x64, + 0x94, 0x87, 0xc8, 0xb9, 0xf7, 0x62, 0xa1, 0x76, 0xd4, 0x55, 0x31, 0xde, 0x9a, 0x34, 0xd9, 0x97, + 0x42, 0x60, 0x8d, 0xf7, 0xd4, 0xcb, 0x50, 0x51, 0xc4, 0x79, 0x8a, 0xff, 0x88, 0x2e, 0x9a, 0x7f, + 0x0e, 0xc6, 0x33, 0x75, 0xf5, 0x64, 0x37, 0xfc, 0x8a, 0x05, 0xe3, 0x99, 0x57, 0x94, 0xd1, 0x7b, + 0x16, 0x9c, 0xf1, 0x3b, 0x38, 0x9f, 0xc4, 0x67, 0x3e, 0x8a, 0xdb, 0x4a, 0x99, 0x0c, 0x9d, 0xb0, + 0xb8, 0x63, 0x6d, 0xf6, 0x6f, 0x59, 0x70, 0xaa, 0xed, 0xf9, 0xdd, 0x0f, 0x49, 0xe3, 0x64, 0x82, + 0xd3, 0x52, 0xe7, 0x04, 0xa7, 0xf6, 0x6f, 0x58, 0x20, 0xa4, 0xe9, 0x04, 0x74, 0xb4, 0x65, 0x53, + 0x47, 0xfb, 0x58, 0x11, 0x01, 0xed, 0xa2, 0x9c, 0xfd, 0x9e, 0x05, 0x88, 0x13, 0x64, 0x9f, 0x4b, + 0xe4, 0x8e, 0x46, 0xcd, 0xb8, 0x48, 0x25, 0x5a, 0x61, 0xb0, 0x46, 0xd5, 0x63, 0xee, 0x7b, 0xf5, + 0xcc, 0x58, 0xe7, 0x86, 0xa1, 0xcb, 0x30, 0x2c, 0x9e, 0x19, 0x5a, 0x4d, 0x9f, 0x10, 0x1b, 0x67, + 0x8f, 0x59, 0xa6, 0x60, 0xac, 0xd3, 0xd8, 0xbf, 0x53, 0x86, 0x6c, 0xd0, 0x09, 0x7a, 0x0b, 0x46, + 0x1a, 0x4e, 0xd3, 0x59, 0xf7, 0x7c, 0x2f, 0xf1, 0x48, 0x5c, 0xec, 0xb0, 0x6b, 0x41, 0x2b, 0x21, + 0x5c, 0xd5, 0x1a, 0x04, 0x1b, 0x1c, 0xd1, 0x0c, 0x40, 0x33, 0xf2, 0x76, 0x3c, 0x9f, 0x6c, 0x32, + 0xcd, 0x88, 0x45, 0xad, 0xf2, 0x73, 0x1b, 0x09, 0xc5, 0x1a, 0x45, 0x87, 0x28, 0xc7, 0xf2, 0x49, + 0x44, 0x39, 0xf6, 0xf5, 0x18, 0xe5, 0xd8, 0x5f, 0x28, 0xca, 0x11, 0xc3, 0x39, 0xe9, 0x61, 0xa6, + 0xff, 0x97, 0x3c, 0x9f, 0xf0, 0x84, 0x86, 0x22, 0xaa, 0x75, 0x6a, 0x7f, 0x6f, 0xfa, 0x1c, 0xee, + 0x48, 0x81, 0xbb, 0x94, 0xb4, 0x5b, 0x70, 0xba, 0x4e, 0x22, 0x8f, 0xe5, 0x99, 0x72, 0xd3, 0x09, + 0xf8, 0x65, 0xa8, 0x44, 0x99, 0xb9, 0xdf, 0xe3, 0x95, 0x43, 0x2d, 0x33, 0x89, 0x9c, 0xeb, 0x29, + 0x4b, 0xfb, 0x2f, 0x97, 0x60, 0x50, 0x04, 0x77, 0x9d, 0xc0, 0x56, 0x77, 0xc3, 0x30, 0x44, 0x9f, + 0xc9, 0x9b, 0xc1, 0xac, 0x59, 0x5d, 0x4d, 0xd0, 0x7a, 0xc6, 0x04, 0x7d, 0xae, 0x18, 0xbb, 0xc3, + 0x8d, 0xcf, 0x1f, 0x96, 0x60, 0xcc, 0x0c, 0x76, 0x3b, 0x81, 0x61, 0x79, 0x1d, 0x06, 0x63, 0x11, + 0x09, 0x56, 0x2a, 0x12, 0xc7, 0x92, 0xfd, 0xc4, 0xca, 0xdb, 0x20, 0x63, 0xbf, 0x24, 0xbb, 0x8e, + 0xc1, 0x66, 0xe5, 0x93, 0x08, 0x36, 0xb3, 0x7f, 0x97, 0x2d, 0xb1, 0xfa, 0x40, 0x9e, 0xc0, 0x16, + 0xf1, 0x9a, 0xb9, 0x18, 0x5f, 0x2a, 0x24, 0x11, 0xa2, 0x79, 0x5d, 0xb6, 0x8a, 0xef, 0x59, 0x30, + 0x2c, 0x08, 0x4f, 0xa0, 0x03, 0x9f, 0x37, 0x3b, 0xf0, 0x54, 0xa1, 0x0e, 0x74, 0x69, 0xf9, 0xdf, + 0x2c, 0xa9, 0x96, 0xd7, 0xc4, 0xa3, 0xb2, 0xb9, 0xf9, 0x2e, 0x87, 0x9a, 0x51, 0x98, 0x84, 0x8d, + 0xd0, 0x17, 0x5b, 0xfe, 0x63, 0xe9, 0xf5, 0x02, 0x0e, 0x3f, 0xd0, 0x7e, 0x63, 0x45, 0xcd, 0xa2, + 0xdf, 0xc3, 0x28, 0x11, 0x1b, 0x56, 0xa7, 0x27, 0x6d, 0xd7, 0xe5, 0x93, 0xe1, 0x14, 0x26, 0x6e, + 0xe6, 0xf4, 0xfa, 0x54, 0x6e, 0x7a, 0x5b, 0x40, 0x71, 0xc2, 0x1a, 0x57, 0x19, 0x86, 0xca, 0x6a, + 0xe8, 0x37, 0xbd, 0xbf, 0x37, 0x05, 0x1c, 0x2b, 0x0a, 0xfb, 0x65, 0xb6, 0xe2, 0xb2, 0xe1, 0xe9, + 0x2d, 0x90, 0xff, 0x2f, 0x0d, 0xa8, 0x81, 0x65, 0x4e, 0x9d, 0x9b, 0xfa, 0x75, 0x81, 0xa2, 0xcb, + 0x1a, 0x6d, 0x82, 0x1e, 0x39, 0x97, 0xde, 0x2e, 0x40, 0xa4, 0xed, 0xc8, 0xe0, 0xe5, 0xc2, 0x2b, + 0x65, 0x0f, 0x87, 0x04, 0x2c, 0x49, 0x10, 0xcb, 0x8c, 0xb2, 0x5c, 0xcb, 0xe6, 0x28, 0x5d, 0x90, + 0x08, 0x9c, 0xd2, 0xa0, 0x59, 0x61, 0x56, 0x98, 0x2f, 0x0e, 0x4b, 0xb3, 0x42, 0x0e, 0x89, 0x66, + 0x57, 0x5c, 0x86, 0x61, 0x95, 0xa5, 0xbd, 0xc6, 0x93, 0x6d, 0x57, 0xb8, 0x36, 0xb3, 0x98, 0x82, + 0xb1, 0x4e, 0x83, 0x96, 0xe1, 0xb4, 0xab, 0xa2, 0x8e, 0x6b, 0xad, 0x75, 0xdf, 0x6b, 0xd0, 0xa2, + 0xfc, 0xc6, 0xd0, 0x23, 0xfb, 0x7b, 0xd3, 0xa7, 0xab, 0xed, 0x68, 0xdc, 0xa9, 0x0c, 0x5a, 0x83, + 0xf1, 0x98, 0x67, 0xa3, 0x97, 0xa1, 0xa5, 0x22, 0x75, 0xdf, 0xb3, 0xf2, 0xac, 0xa2, 0x6e, 0xa2, + 0x0f, 0x18, 0x88, 0xaf, 0x09, 0x32, 0x18, 0x35, 0xcb, 0x02, 0xbd, 0x0a, 0x63, 0xbe, 0xfe, 0xd0, + 0x56, 0x4d, 0x04, 0x5f, 0xab, 0xa8, 0x0e, 0xe3, 0x19, 0xae, 0x1a, 0xce, 0x50, 0xa3, 0xd7, 0x61, + 0x52, 0x87, 0x88, 0x0c, 0x06, 0x4e, 0xb0, 0x49, 0x62, 0x91, 0x06, 0xfb, 0xb1, 0xfd, 0xbd, 0xe9, + 0xc9, 0x95, 0x2e, 0x34, 0xb8, 0x6b, 0x69, 0x74, 0x15, 0x46, 0xe4, 0x48, 0x6a, 0x81, 0xd8, 0x69, + 0x3c, 0x91, 0x86, 0xc3, 0x06, 0xe5, 0x07, 0x3b, 0x92, 0xf9, 0x0a, 0x2d, 0xac, 0x6d, 0xad, 0xe8, + 0x6d, 0x18, 0xd1, 0xdb, 0x98, 0xdd, 0x33, 0xf3, 0x1f, 0x2f, 0x13, 0x5b, 0xb4, 0x6a, 0xb9, 0x8e, + 0xc3, 0x06, 0x6f, 0xfb, 0x16, 0x0c, 0xd4, 0x77, 0xe3, 0x46, 0xe2, 0x3f, 0xac, 0xc7, 0xa6, 0x1b, + 0x30, 0x9e, 0x79, 0x95, 0x59, 0x3d, 0xef, 0x6d, 0x3d, 0xac, 0xe7, 0xbd, 0xed, 0xaf, 0x59, 0xd0, + 0xbf, 0xe6, 0x78, 0xf9, 0x0f, 0x48, 0x14, 0x69, 0x32, 0x7a, 0x09, 0x06, 0xc8, 0xc6, 0x06, 0x69, + 0xc8, 0xe7, 0xc2, 0x1f, 0x97, 0xaa, 0xcd, 0x22, 0x83, 0xd2, 0xa9, 0xc9, 0x2a, 0xe3, 0x7f, 0xb1, + 0x20, 0xb6, 0xff, 0x9d, 0x05, 0xb0, 0x16, 0xfa, 0xf2, 0xb4, 0x29, 0xa7, 0x25, 0xf3, 0x6d, 0x4f, + 0x59, 0x3c, 0xdd, 0xe1, 0x29, 0x0b, 0x94, 0x32, 0xec, 0xf0, 0x90, 0x85, 0xea, 0x4d, 0xb9, 0x50, + 0x6f, 0xfa, 0x7a, 0xe9, 0xcd, 0x37, 0x2c, 0x10, 0x81, 0x40, 0x05, 0x24, 0xc1, 0x95, 0xe9, 0xe7, + 0x8d, 0xdc, 0x24, 0xcf, 0x16, 0xb9, 0xb0, 0x23, 0x32, 0x92, 0x28, 0xd9, 0x34, 0xf2, 0x90, 0x18, + 0x5c, 0xa9, 0x61, 0x3f, 0xcc, 0xd1, 0xab, 0x4c, 0x8f, 0xcc, 0x6f, 0x57, 0x4f, 0x59, 0xd8, 0x58, + 0x76, 0x76, 0xca, 0x58, 0x65, 0xe3, 0xd2, 0xb3, 0xb3, 0x4b, 0x04, 0x4e, 0x69, 0xd0, 0x33, 0x30, + 0x18, 0xb7, 0xd6, 0x19, 0x79, 0x26, 0x2a, 0xa8, 0xce, 0xc1, 0x58, 0xe2, 0xed, 0x5f, 0x40, 0x60, + 0x74, 0xcd, 0xc8, 0xfc, 0x65, 0x3d, 0xf4, 0xcc, 0x5f, 0x6f, 0xc0, 0x10, 0xd9, 0x6e, 0x26, 0xbb, + 0x55, 0x2f, 0x2a, 0x96, 0x83, 0x71, 0x51, 0x50, 0xb7, 0x73, 0x97, 0x18, 0xac, 0x38, 0x76, 0xc9, + 0xe3, 0x56, 0xfe, 0x50, 0xe4, 0x71, 0xeb, 0xfb, 0xa9, 0xe4, 0x71, 0x7b, 0x1d, 0x06, 0x37, 0xbd, + 0x04, 0x93, 0x66, 0x28, 0x6e, 0x78, 0xe6, 0x1c, 0xdf, 0x5d, 0xe3, 0xc4, 0xed, 0xc9, 0x99, 0x04, + 0x02, 0x4b, 0x76, 0x68, 0x0d, 0x06, 0xb8, 0xed, 0x21, 0x52, 0xa3, 0x7d, 0xa2, 0x88, 0x97, 0xa6, + 0x3d, 0x4b, 0x98, 0x08, 0xfd, 0x12, 0xbc, 0x64, 0xde, 0xb6, 0xc1, 0x0f, 0x9e, 0xb7, 0x4d, 0x65, + 0x5b, 0x1b, 0x7a, 0x58, 0xd9, 0xd6, 0x8c, 0xac, 0x75, 0x95, 0xe3, 0xc8, 0x5a, 0xf7, 0x0d, 0x0b, + 0xce, 0x36, 0x3b, 0xe5, 0x7c, 0x14, 0x79, 0xd3, 0x3e, 0x7b, 0x84, 0x1c, 0x98, 0x46, 0xd5, 0xec, + 0xde, 0x5c, 0x47, 0x32, 0xdc, 0xb9, 0x62, 0x99, 0xfe, 0x6e, 0xf8, 0x83, 0xa7, 0xbf, 0x3b, 0xee, + 0x04, 0x6b, 0x69, 0x32, 0xbc, 0xd1, 0x63, 0x49, 0x86, 0x37, 0xf6, 0x10, 0x93, 0xe1, 0x69, 0x69, + 0xec, 0xc6, 0x1f, 0x6e, 0x1a, 0xbb, 0x2d, 0x18, 0x76, 0xc3, 0xfb, 0xc1, 0x7d, 0x27, 0x72, 0xe7, + 0x6a, 0xcb, 0x22, 0x6b, 0x5a, 0x4e, 0x6a, 0x8e, 0x6a, 0x5a, 0xc0, 0xa8, 0x81, 0xbb, 0x23, 0x53, + 0x24, 0xd6, 0x59, 0x8b, 0x84, 0x7e, 0xa7, 0x3e, 0x60, 0x42, 0x3f, 0x23, 0x2d, 0x1e, 0x3a, 0x8e, + 0xb4, 0x78, 0x6f, 0xb1, 0x3b, 0xfa, 0x1b, 0xde, 0xe6, 0xaa, 0xd3, 0x64, 0xf7, 0xca, 0x72, 0x6b, + 0x58, 0x90, 0xe4, 0xed, 0x35, 0x28, 0x14, 0x4e, 0x99, 0xb6, 0x27, 0xde, 0x3b, 0x73, 0xd2, 0x89, + 0xf7, 0xce, 0x1e, 0x63, 0xe2, 0xbd, 0x73, 0x27, 0x9a, 0x78, 0xef, 0x91, 0x9f, 0x4a, 0xe2, 0xbd, + 0xbf, 0x00, 0xe7, 0x0f, 0xff, 0x1c, 0x69, 0x62, 0xe7, 0x5a, 0xea, 0x32, 0xc8, 0x24, 0x76, 0x66, + 0xaa, 0x8e, 0x46, 0x55, 0x38, 0xff, 0xd7, 0x77, 0x2d, 0x78, 0xa4, 0x4b, 0x7a, 0x9c, 0xc2, 0x57, + 0x32, 0x9a, 0x30, 0xde, 0x34, 0x8b, 0x16, 0xbe, 0x44, 0x65, 0xa4, 0xe3, 0x51, 0xe1, 0x7d, 0x19, + 0x04, 0xce, 0xb2, 0x9f, 0xff, 0xd8, 0x8f, 0xde, 0x3f, 0xff, 0x91, 0x1f, 0xbf, 0x7f, 0xfe, 0x23, + 0x7f, 0xf4, 0xfe, 0xf9, 0x8f, 0xfc, 0xdc, 0xfe, 0x79, 0xeb, 0x47, 0xfb, 0xe7, 0xad, 0x1f, 0xef, + 0x9f, 0xb7, 0xfe, 0x64, 0xff, 0xbc, 0xf5, 0x8d, 0x3f, 0x3d, 0xff, 0x91, 0x2f, 0x96, 0x76, 0x2e, + 0xff, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0x41, 0x6d, 0xd5, 0x05, 0xba, 0x00, 0x00, } diff --git a/pkg/api/v1/generated.proto b/pkg/api/v1/generated.proto index a7f0bd64d2..d990885fa4 100644 --- a/pkg/api/v1/generated.proto +++ b/pkg/api/v1/generated.proto @@ -426,11 +426,23 @@ message Container { // Optional: Path at which the file to which the container's termination message // will be written is mounted into the container's filesystem. // Message written is intended to be brief final status, such as an assertion failure message. + // Will be truncated by the node if greater than 4096 bytes. The total message length across + // all containers will be limited to 12kb. // Defaults to /dev/termination-log. // Cannot be updated. // +optional optional string terminationMessagePath = 13; + // Indicate how the termination message should be populated. File will use the contents of + // terminationMessagePath to populate the container status message on both success and failure. + // FallbackToLogsOnError will use the last chunk of container log output if the termination + // message file is empty and the container exited with an error. + // The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + // Defaults to File. + // Cannot be updated. + // +optional + optional string terminationMessagePolicy = 20; + // Image pull policy. // One of Always, Never, IfNotPresent. // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. diff --git a/pkg/api/v1/types.generated.go b/pkg/api/v1/types.generated.go index cabbffac74..f30cd923fa 100644 --- a/pkg/api/v1/types.generated.go +++ b/pkg/api/v1/types.generated.go @@ -22190,6 +22190,32 @@ func (x *PullPolicy) CodecDecodeSelf(d *codec1978.Decoder) { } } +func (x TerminationMessagePolicy) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x)) + } +} + +func (x *TerminationMessagePolicy) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + *((*string)(x)) = r.DecodeString() + } +} + func (x Capability) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -22704,7 +22730,7 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [19]bool + var yyq2 [20]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[1] = x.Image != "" @@ -22720,14 +22746,15 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[11] = x.ReadinessProbe != nil yyq2[12] = x.Lifecycle != nil yyq2[13] = x.TerminationMessagePath != "" - yyq2[14] = x.ImagePullPolicy != "" - yyq2[15] = x.SecurityContext != nil - yyq2[16] = x.Stdin != false - yyq2[17] = x.StdinOnce != false - yyq2[18] = x.TTY != false + yyq2[14] = x.TerminationMessagePolicy != "" + yyq2[15] = x.ImagePullPolicy != "" + yyq2[16] = x.SecurityContext != nil + yyq2[17] = x.Stdin != false + yyq2[18] = x.StdinOnce != false + yyq2[19] = x.TTY != false var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(19) + r.EncodeArrayStart(20) } else { yynn2 = 1 for _, b := range yyq2 { @@ -23119,12 +23146,27 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[14] { - x.ImagePullPolicy.CodecEncodeSelf(e) + x.TerminationMessagePolicy.CodecEncodeSelf(e) } else { r.EncodeString(codecSelferC_UTF81234, "") } } else { if yyq2[14] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("terminationMessagePolicy")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.TerminationMessagePolicy.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[15] { + x.ImagePullPolicy.CodecEncodeSelf(e) + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[15] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("imagePullPolicy")) z.EncSendContainerState(codecSelfer_containerMapValue1234) @@ -23133,7 +23175,7 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[15] { + if yyq2[16] { if x.SecurityContext == nil { r.EncodeNil() } else { @@ -23143,7 +23185,7 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeNil() } } else { - if yyq2[15] { + if yyq2[16] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("securityContext")) z.EncSendContainerState(codecSelfer_containerMapValue1234) @@ -23154,31 +23196,6 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { } } } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[16] { - yym54 := z.EncBinary() - _ = yym54 - if false { - } else { - r.EncodeBool(bool(x.Stdin)) - } - } else { - r.EncodeBool(false) - } - } else { - if yyq2[16] { - z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("stdin")) - z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym55 := z.EncBinary() - _ = yym55 - if false { - } else { - r.EncodeBool(bool(x.Stdin)) - } - } - } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[17] { @@ -23186,7 +23203,7 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym57 if false { } else { - r.EncodeBool(bool(x.StdinOnce)) + r.EncodeBool(bool(x.Stdin)) } } else { r.EncodeBool(false) @@ -23194,13 +23211,13 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[17] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("stdinOnce")) + r.EncodeString(codecSelferC_UTF81234, string("stdin")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym58 := z.EncBinary() _ = yym58 if false { } else { - r.EncodeBool(bool(x.StdinOnce)) + r.EncodeBool(bool(x.Stdin)) } } } @@ -23211,7 +23228,7 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym60 if false { } else { - r.EncodeBool(bool(x.TTY)) + r.EncodeBool(bool(x.StdinOnce)) } } else { r.EncodeBool(false) @@ -23219,11 +23236,36 @@ func (x *Container) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[18] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("tty")) + r.EncodeString(codecSelferC_UTF81234, string("stdinOnce")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym61 := z.EncBinary() _ = yym61 if false { + } else { + r.EncodeBool(bool(x.StdinOnce)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[19] { + yym63 := z.EncBinary() + _ = yym63 + if false { + } else { + r.EncodeBool(bool(x.TTY)) + } + } else { + r.EncodeBool(false) + } + } else { + if yyq2[19] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("tty")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym64 := z.EncBinary() + _ = yym64 + if false { } else { r.EncodeBool(bool(x.TTY)) } @@ -23450,12 +23492,19 @@ func (x *Container) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { *((*string)(yyv26)) = r.DecodeString() } } + case "terminationMessagePolicy": + if r.TryDecodeAsNil() { + x.TerminationMessagePolicy = "" + } else { + yyv28 := &x.TerminationMessagePolicy + yyv28.CodecDecodeSelf(d) + } case "imagePullPolicy": if r.TryDecodeAsNil() { x.ImagePullPolicy = "" } else { - yyv28 := &x.ImagePullPolicy - yyv28.CodecDecodeSelf(d) + yyv29 := &x.ImagePullPolicy + yyv29.CodecDecodeSelf(d) } case "securityContext": if r.TryDecodeAsNil() { @@ -23472,36 +23521,36 @@ func (x *Container) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Stdin = false } else { - yyv30 := &x.Stdin - yym31 := z.DecBinary() - _ = yym31 + yyv31 := &x.Stdin + yym32 := z.DecBinary() + _ = yym32 if false { } else { - *((*bool)(yyv30)) = r.DecodeBool() + *((*bool)(yyv31)) = r.DecodeBool() } } case "stdinOnce": if r.TryDecodeAsNil() { x.StdinOnce = false } else { - yyv32 := &x.StdinOnce - yym33 := z.DecBinary() - _ = yym33 + yyv33 := &x.StdinOnce + yym34 := z.DecBinary() + _ = yym34 if false { } else { - *((*bool)(yyv32)) = r.DecodeBool() + *((*bool)(yyv33)) = r.DecodeBool() } } case "tty": if r.TryDecodeAsNil() { x.TTY = false } else { - yyv34 := &x.TTY - yym35 := z.DecBinary() - _ = yym35 + yyv35 := &x.TTY + yym36 := z.DecBinary() + _ = yym36 if false { } else { - *((*bool)(yyv34)) = r.DecodeBool() + *((*bool)(yyv35)) = r.DecodeBool() } } default: @@ -23515,16 +23564,16 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj36 int - var yyb36 bool - var yyhl36 bool = l >= 0 - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + var yyj37 int + var yyb37 bool + var yyhl37 bool = l >= 0 + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23532,21 +23581,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Name = "" } else { - yyv37 := &x.Name - yym38 := z.DecBinary() - _ = yym38 + yyv38 := &x.Name + yym39 := z.DecBinary() + _ = yym39 if false { } else { - *((*string)(yyv37)) = r.DecodeString() + *((*string)(yyv38)) = r.DecodeString() } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23554,21 +23603,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Image = "" } else { - yyv39 := &x.Image - yym40 := z.DecBinary() - _ = yym40 + yyv40 := &x.Image + yym41 := z.DecBinary() + _ = yym41 if false { } else { - *((*string)(yyv39)) = r.DecodeString() + *((*string)(yyv40)) = r.DecodeString() } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23576,21 +23625,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Command = nil } else { - yyv41 := &x.Command - yym42 := z.DecBinary() - _ = yym42 + yyv42 := &x.Command + yym43 := z.DecBinary() + _ = yym43 if false { } else { - z.F.DecSliceStringX(yyv41, false, d) + z.F.DecSliceStringX(yyv42, false, d) } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23598,21 +23647,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Args = nil } else { - yyv43 := &x.Args - yym44 := z.DecBinary() - _ = yym44 + yyv44 := &x.Args + yym45 := z.DecBinary() + _ = yym45 if false { } else { - z.F.DecSliceStringX(yyv43, false, d) + z.F.DecSliceStringX(yyv44, false, d) } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23620,21 +23669,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.WorkingDir = "" } else { - yyv45 := &x.WorkingDir - yym46 := z.DecBinary() - _ = yym46 + yyv46 := &x.WorkingDir + yym47 := z.DecBinary() + _ = yym47 if false { } else { - *((*string)(yyv45)) = r.DecodeString() + *((*string)(yyv46)) = r.DecodeString() } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23642,21 +23691,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Ports = nil } else { - yyv47 := &x.Ports - yym48 := z.DecBinary() - _ = yym48 + yyv48 := &x.Ports + yym49 := z.DecBinary() + _ = yym49 if false { } else { - h.decSliceContainerPort((*[]ContainerPort)(yyv47), d) + h.decSliceContainerPort((*[]ContainerPort)(yyv48), d) } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23664,21 +23713,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.EnvFrom = nil } else { - yyv49 := &x.EnvFrom - yym50 := z.DecBinary() - _ = yym50 + yyv50 := &x.EnvFrom + yym51 := z.DecBinary() + _ = yym51 if false { } else { - h.decSliceEnvFromSource((*[]EnvFromSource)(yyv49), d) + h.decSliceEnvFromSource((*[]EnvFromSource)(yyv50), d) } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23686,21 +23735,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Env = nil } else { - yyv51 := &x.Env - yym52 := z.DecBinary() - _ = yym52 + yyv52 := &x.Env + yym53 := z.DecBinary() + _ = yym53 if false { } else { - h.decSliceEnvVar((*[]EnvVar)(yyv51), d) + h.decSliceEnvVar((*[]EnvVar)(yyv52), d) } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23708,16 +23757,16 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Resources = ResourceRequirements{} } else { - yyv53 := &x.Resources - yyv53.CodecDecodeSelf(d) + yyv54 := &x.Resources + yyv54.CodecDecodeSelf(d) } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23725,21 +23774,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.VolumeMounts = nil } else { - yyv54 := &x.VolumeMounts - yym55 := z.DecBinary() - _ = yym55 + yyv55 := &x.VolumeMounts + yym56 := z.DecBinary() + _ = yym56 if false { } else { - h.decSliceVolumeMount((*[]VolumeMount)(yyv54), d) + h.decSliceVolumeMount((*[]VolumeMount)(yyv55), d) } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23754,13 +23803,13 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.LivenessProbe.CodecDecodeSelf(d) } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23775,13 +23824,13 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ReadinessProbe.CodecDecodeSelf(d) } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23796,13 +23845,13 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Lifecycle.CodecDecodeSelf(d) } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23810,21 +23859,38 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.TerminationMessagePath = "" } else { - yyv59 := &x.TerminationMessagePath - yym60 := z.DecBinary() - _ = yym60 + yyv60 := &x.TerminationMessagePath + yym61 := z.DecBinary() + _ = yym61 if false { } else { - *((*string)(yyv59)) = r.DecodeString() + *((*string)(yyv60)) = r.DecodeString() } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.TerminationMessagePolicy = "" + } else { + yyv62 := &x.TerminationMessagePolicy + yyv62.CodecDecodeSelf(d) + } + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l + } else { + yyb37 = r.CheckBreak() + } + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23832,16 +23898,16 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.ImagePullPolicy = "" } else { - yyv61 := &x.ImagePullPolicy - yyv61.CodecDecodeSelf(d) + yyv63 := &x.ImagePullPolicy + yyv63.CodecDecodeSelf(d) } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23856,13 +23922,13 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.SecurityContext.CodecDecodeSelf(d) } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -23870,29 +23936,7 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Stdin = false } else { - yyv63 := &x.Stdin - yym64 := z.DecBinary() - _ = yym64 - if false { - } else { - *((*bool)(yyv63)) = r.DecodeBool() - } - } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l - } else { - yyb36 = r.CheckBreak() - } - if yyb36 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.StdinOnce = false - } else { - yyv65 := &x.StdinOnce + yyv65 := &x.Stdin yym66 := z.DecBinary() _ = yym66 if false { @@ -23900,21 +23944,21 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { *((*bool)(yyv65)) = r.DecodeBool() } } - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l } else { - yyb36 = r.CheckBreak() + yyb37 = r.CheckBreak() } - if yyb36 { + if yyb37 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.TTY = false + x.StdinOnce = false } else { - yyv67 := &x.TTY + yyv67 := &x.StdinOnce yym68 := z.DecBinary() _ = yym68 if false { @@ -23922,18 +23966,40 @@ func (x *Container) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { *((*bool)(yyv67)) = r.DecodeBool() } } - for { - yyj36++ - if yyhl36 { - yyb36 = yyj36 > l + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l + } else { + yyb37 = r.CheckBreak() + } + if yyb37 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.TTY = false + } else { + yyv69 := &x.TTY + yym70 := z.DecBinary() + _ = yym70 + if false { } else { - yyb36 = r.CheckBreak() + *((*bool)(yyv69)) = r.DecodeBool() } - if yyb36 { + } + for { + yyj37++ + if yyhl37 { + yyb37 = yyj37 > l + } else { + yyb37 = r.CheckBreak() + } + if yyb37 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj36-1, "") + z.DecStructFieldNotFound(yyj37-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -64355,7 +64421,7 @@ func (x codecSelfer1234) decSliceContainer(v *[]Container, d *codec1978.Decoder) yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 280) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 8323657191..b38a55c6f0 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -1367,6 +1367,19 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// TerminationMessagePolicy describes how termination messages are retrieved from a container. +type TerminationMessagePolicy string + +const ( + // TerminationMessageReadFile is the default behavior and will set the container status message to + // the contents of the container's terminationMessagePath when the container exits. + TerminationMessageReadFile TerminationMessagePolicy = "File" + // TerminationMessageFallbackToLogsOnError will read the most recent contents of the container logs + // for the container status message when the container exits with an error and the + // terminationMessagePath has no contents. + TerminationMessageFallbackToLogsOnError TerminationMessagePolicy = "FallbackToLogsOnError" +) + // Capability represent POSIX capabilities type type Capability string @@ -1484,10 +1497,21 @@ type Container struct { // Optional: Path at which the file to which the container's termination message // will be written is mounted into the container's filesystem. // Message written is intended to be brief final status, such as an assertion failure message. + // Will be truncated by the node if greater than 4096 bytes. The total message length across + // all containers will be limited to 12kb. // Defaults to /dev/termination-log. // Cannot be updated. // +optional TerminationMessagePath string `json:"terminationMessagePath,omitempty" protobuf:"bytes,13,opt,name=terminationMessagePath"` + // Indicate how the termination message should be populated. File will use the contents of + // terminationMessagePath to populate the container status message on both success and failure. + // FallbackToLogsOnError will use the last chunk of container log output if the termination + // message file is empty and the container exited with an error. + // The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + // Defaults to File. + // Cannot be updated. + // +optional + TerminationMessagePolicy TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty" protobuf:"bytes,20,opt,name=terminationMessagePolicy,casttype=TerminationMessagePolicy"` // Image pull policy. // One of Always, Never, IfNotPresent. // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. diff --git a/pkg/api/v1/types_swagger_doc_generated.go b/pkg/api/v1/types_swagger_doc_generated.go index cc1a7071d6..e0c9e0cb07 100644 --- a/pkg/api/v1/types_swagger_doc_generated.go +++ b/pkg/api/v1/types_swagger_doc_generated.go @@ -218,26 +218,27 @@ func (ConfigMapVolumeSource) SwaggerDoc() map[string]string { } var map_Container = map[string]string{ - "": "A single application container that you want to run within a pod.", - "name": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", - "image": "Docker image name. More info: http://kubernetes.io/docs/user-guide/images", - "command": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/containers#containers-and-commands", - "args": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/containers#containers-and-commands", - "workingDir": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", - "ports": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", - "envFrom": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. An invalid key will prevent the container from starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", - "env": "List of environment variables to set in the container. Cannot be updated.", - "resources": "Compute Resources required by this container. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#resources", - "volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.", - "livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/pod-states#container-probes", - "readinessProbe": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/pod-states#container-probes", - "lifecycle": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", - "terminationMessagePath": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.", - "imagePullPolicy": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/images#updating-images", - "securityContext": "Security options the pod should run with. More info: http://releases.k8s.io/HEAD/docs/design/security_context.md", - "stdin": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", - "stdinOnce": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", - "tty": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + "": "A single application container that you want to run within a pod.", + "name": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + "image": "Docker image name. More info: http://kubernetes.io/docs/user-guide/images", + "command": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/containers#containers-and-commands", + "args": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/containers#containers-and-commands", + "workingDir": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + "ports": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + "envFrom": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. An invalid key will prevent the container from starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + "env": "List of environment variables to set in the container. Cannot be updated.", + "resources": "Compute Resources required by this container. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/persistent-volumes#resources", + "volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.", + "livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/pod-states#container-probes", + "readinessProbe": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/pod-states#container-probes", + "lifecycle": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", + "terminationMessagePath": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "terminationMessagePolicy": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + "imagePullPolicy": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/images#updating-images", + "securityContext": "Security options the pod should run with. More info: http://releases.k8s.io/HEAD/docs/design/security_context.md", + "stdin": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + "stdinOnce": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + "tty": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", } func (Container) SwaggerDoc() map[string]string { diff --git a/pkg/api/v1/zz_generated.conversion.go b/pkg/api/v1/zz_generated.conversion.go index 0b62266b41..161f607c05 100644 --- a/pkg/api/v1/zz_generated.conversion.go +++ b/pkg/api/v1/zz_generated.conversion.go @@ -779,6 +779,7 @@ func autoConvert_v1_Container_To_api_Container(in *Container, out *api.Container out.ReadinessProbe = (*api.Probe)(unsafe.Pointer(in.ReadinessProbe)) out.Lifecycle = (*api.Lifecycle)(unsafe.Pointer(in.Lifecycle)) out.TerminationMessagePath = in.TerminationMessagePath + out.TerminationMessagePolicy = api.TerminationMessagePolicy(in.TerminationMessagePolicy) out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) out.SecurityContext = (*api.SecurityContext)(unsafe.Pointer(in.SecurityContext)) out.Stdin = in.Stdin @@ -808,6 +809,7 @@ func autoConvert_api_Container_To_v1_Container(in *api.Container, out *Container out.ReadinessProbe = (*Probe)(unsafe.Pointer(in.ReadinessProbe)) out.Lifecycle = (*Lifecycle)(unsafe.Pointer(in.Lifecycle)) out.TerminationMessagePath = in.TerminationMessagePath + out.TerminationMessagePolicy = TerminationMessagePolicy(in.TerminationMessagePolicy) out.ImagePullPolicy = PullPolicy(in.ImagePullPolicy) out.SecurityContext = (*SecurityContext)(unsafe.Pointer(in.SecurityContext)) out.Stdin = in.Stdin diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index a17ee9639e..eefc981e3f 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -1597,6 +1597,14 @@ func validateContainers(containers []api.Container, volumes sets.String, fldPath allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1")) } + switch ctr.TerminationMessagePolicy { + case api.TerminationMessageReadFile, api.TerminationMessageFallbackToLogsOnError: + case "": + allErrs = append(allErrs, field.Required(idxPath.Child("terminationMessagePolicy"), "must be 'File' or 'FallbackToLogsOnError'")) + default: + allErrs = append(allErrs, field.Invalid(idxPath.Child("terminationMessagePolicy"), ctr.TerminationMessagePolicy, "must be 'File' or 'FallbackToLogsOnError'")) + } + allErrs = append(allErrs, validateProbe(ctr.ReadinessProbe, idxPath.Child("readinessProbe"))...) allErrs = append(allErrs, validateContainerPorts(ctr.Ports, idxPath.Child("ports"))...) allErrs = append(allErrs, validateEnv(ctr.Env, idxPath.Child("env"))...) diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index c9dbad7583..3a0e3854c6 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -2484,11 +2484,11 @@ func TestValidatePullPolicy(t *testing.T) { } testCases := map[string]T{ "NotPresent1": { - api.Container{Name: "abc", Image: "image:latest", ImagePullPolicy: "IfNotPresent"}, + api.Container{Name: "abc", Image: "image:latest", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, api.PullIfNotPresent, }, "NotPresent2": { - api.Container{Name: "abc1", Image: "image", ImagePullPolicy: "IfNotPresent"}, + api.Container{Name: "abc1", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, api.PullIfNotPresent, }, "Always1": { @@ -2534,9 +2534,9 @@ func TestValidateContainers(t *testing.T) { }) successCase := []api.Container{ - {Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}, - {Name: "123", Image: "image", ImagePullPolicy: "IfNotPresent"}, - {Name: "abc-123", Image: "image", ImagePullPolicy: "IfNotPresent"}, + {Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, + {Name: "123", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, + {Name: "abc-123", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, { Name: "life-123", Image: "image", @@ -2545,7 +2545,8 @@ func TestValidateContainers(t *testing.T) { Exec: &api.ExecAction{Command: []string{"ls", "-l"}}, }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-test", @@ -2557,7 +2558,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName("my.org/resource"): resource.MustParse("10m"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-test-with-gpu-with-request", @@ -2574,7 +2576,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName(api.ResourceNvidiaGPU): resource.MustParse("1"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-test-with-gpu-without-request", @@ -2590,7 +2593,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName(api.ResourceNvidiaGPU): resource.MustParse("1"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-request-limit-simple", @@ -2603,7 +2607,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName(api.ResourceCPU): resource.MustParse("10"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-request-limit-edge", @@ -2620,7 +2625,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName("my.org/resource"): resource.MustParse("10m"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-request-limit-partials", @@ -2635,7 +2641,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName("my.org/resource"): resource.MustParse("10m"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "resources-request", @@ -2646,7 +2653,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName(api.ResourceMemory): resource.MustParse("10G"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, { Name: "same-host-port-different-protocol", @@ -2655,9 +2663,22 @@ func TestValidateContainers(t *testing.T) { {ContainerPort: 80, HostPort: 80, Protocol: "TCP"}, {ContainerPort: 80, HostPort: 80, Protocol: "UDP"}, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, - {Name: "abc-1234", Image: "image", ImagePullPolicy: "IfNotPresent", SecurityContext: fakeValidSecurityContext(true)}, + { + Name: "fallback-to-logs-termination-message", + Image: "image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "FallbackToLogsOnError", + }, + { + Name: "file-termination-message", + Image: "image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", + }, + {Name: "abc-1234", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", SecurityContext: fakeValidSecurityContext(true)}, } if errs := validateContainers(successCase, volumes, field.NewPath("field")); len(errs) != 0 { t.Errorf("expected success: %v", errs) @@ -2667,26 +2688,26 @@ func TestValidateContainers(t *testing.T) { AllowPrivileged: false, }) errorCases := map[string][]api.Container{ - "zero-length name": {{Name: "", Image: "image", ImagePullPolicy: "IfNotPresent"}}, - "name > 63 characters": {{Name: strings.Repeat("a", 64), Image: "image", ImagePullPolicy: "IfNotPresent"}}, - "name not a DNS label": {{Name: "a.b.c", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + "zero-length name": {{Name: "", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, + "name > 63 characters": {{Name: strings.Repeat("a", 64), Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, + "name not a DNS label": {{Name: "a.b.c", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, "name not unique": { - {Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}, - {Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}, + {Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, + {Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, }, - "zero-length image": {{Name: "abc", Image: "", ImagePullPolicy: "IfNotPresent"}}, + "zero-length image": {{Name: "abc", Image: "", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, "host port not unique": { {Name: "abc", Image: "image", Ports: []api.ContainerPort{{ContainerPort: 80, HostPort: 80, Protocol: "TCP"}}, - ImagePullPolicy: "IfNotPresent"}, + ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, {Name: "def", Image: "image", Ports: []api.ContainerPort{{ContainerPort: 81, HostPort: 80, Protocol: "TCP"}}, - ImagePullPolicy: "IfNotPresent"}, + ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, }, "invalid env var name": { - {Name: "abc", Image: "image", Env: []api.EnvVar{{Name: "ev.1"}}, ImagePullPolicy: "IfNotPresent"}, + {Name: "abc", Image: "image", Env: []api.EnvVar{{Name: "ev.1"}}, ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, }, "unknown volume name": { {Name: "abc", Image: "image", VolumeMounts: []api.VolumeMount{{Name: "anything", MountPath: "/foo"}}, - ImagePullPolicy: "IfNotPresent"}, + ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}, }, "invalid lifecycle, no exec command.": { { @@ -2697,7 +2718,8 @@ func TestValidateContainers(t *testing.T) { Exec: &api.ExecAction{}, }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "invalid lifecycle, no http path.": { @@ -2709,7 +2731,8 @@ func TestValidateContainers(t *testing.T) { HTTPGet: &api.HTTPGetAction{}, }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "invalid lifecycle, no tcp socket port.": { @@ -2721,7 +2744,8 @@ func TestValidateContainers(t *testing.T) { TCPSocket: &api.TCPSocketAction{}, }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "invalid lifecycle, zero tcp socket port.": { @@ -2735,7 +2759,8 @@ func TestValidateContainers(t *testing.T) { }, }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "invalid lifecycle, no action.": { @@ -2745,7 +2770,8 @@ func TestValidateContainers(t *testing.T) { Lifecycle: &api.Lifecycle{ PreStop: &api.Handler{}, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "invalid liveness probe, no tcp socket port.": { @@ -2757,7 +2783,8 @@ func TestValidateContainers(t *testing.T) { TCPSocket: &api.TCPSocketAction{}, }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "invalid liveness probe, no action.": { @@ -2767,7 +2794,24 @@ func TestValidateContainers(t *testing.T) { LivenessProbe: &api.Probe{ Handler: api.Handler{}, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", + }, + }, + "invalid message termination policy": { + { + Name: "life-123", + Image: "image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "Unknown", + }, + }, + "empty message termination policy": { + { + Name: "life-123", + Image: "image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "", }, }, "privilege disabled": { @@ -2782,7 +2826,8 @@ func TestValidateContainers(t *testing.T) { "disk": resource.MustParse("10G"), }, }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "Resource CPU invalid": { @@ -2792,7 +2837,8 @@ func TestValidateContainers(t *testing.T) { Resources: api.ResourceRequirements{ Limits: getResourceLimits("-10", "0"), }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "Resource Requests CPU invalid": { @@ -2802,7 +2848,8 @@ func TestValidateContainers(t *testing.T) { Resources: api.ResourceRequirements{ Requests: getResourceLimits("-10", "0"), }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "Resource Memory invalid": { @@ -2812,7 +2859,8 @@ func TestValidateContainers(t *testing.T) { Resources: api.ResourceRequirements{ Limits: getResourceLimits("0", "-10"), }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "Resource GPU limit must match request": { @@ -2831,7 +2879,8 @@ func TestValidateContainers(t *testing.T) { api.ResourceName(api.ResourceNvidiaGPU): resource.MustParse("1"), }, }, - ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", + ImagePullPolicy: "IfNotPresent", }, }, "Request limit simple invalid": { @@ -2842,7 +2891,8 @@ func TestValidateContainers(t *testing.T) { Limits: getResourceLimits("5", "3"), Requests: getResourceLimits("6", "3"), }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, "Request limit multiple invalid": { @@ -2853,7 +2903,8 @@ func TestValidateContainers(t *testing.T) { Limits: getResourceLimits("5", "3"), Requests: getResourceLimits("6", "4"), }, - ImagePullPolicy: "IfNotPresent", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", }, }, } @@ -2908,7 +2959,7 @@ func TestValidatePodSpec(t *testing.T) { successCases := []api.PodSpec{ { // Populate basic fields, leave defaults for most. Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -2916,8 +2967,8 @@ func TestValidatePodSpec(t *testing.T) { Volumes: []api.Volume{ {Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}, }, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, - InitContainers: []api.Container{{Name: "ictr", Image: "iimage", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, + InitContainers: []api.Container{{Name: "ictr", Image: "iimage", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, NodeSelector: map[string]string{ "key": "value", @@ -2929,8 +2980,9 @@ func TestValidatePodSpec(t *testing.T) { }, { // Populate HostNetwork. Containers: []api.Container{ - {Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", Ports: []api.ContainerPort{ - {HostPort: 8080, ContainerPort: 8080, Protocol: "TCP"}}, + {Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", + Ports: []api.ContainerPort{ + {HostPort: 8080, ContainerPort: 8080, Protocol: "TCP"}}, }, }, SecurityContext: &api.PodSecurityContext{ @@ -2940,7 +2992,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, { // Populate RunAsUser SupplementalGroups FSGroup with minID 0 - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ SupplementalGroups: []int64{minID}, RunAsUser: &minID, @@ -2950,7 +3002,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, { // Populate RunAsUser SupplementalGroups FSGroup with maxID 2147483647 - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ SupplementalGroups: []int64{maxID}, RunAsUser: &maxID, @@ -2964,7 +3016,7 @@ func TestValidatePodSpec(t *testing.T) { HostIPC: true, }, Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -2973,13 +3025,13 @@ func TestValidatePodSpec(t *testing.T) { HostPID: true, }, Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, { // Populate Affinity. Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -2998,7 +3050,7 @@ func TestValidatePodSpec(t *testing.T) { Volumes: []api.Volume{{}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, "no containers": { RestartPolicy: api.RestartPolicyAlways, @@ -3010,7 +3062,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad init container": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, InitContainers: []api.Container{{}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, @@ -3018,10 +3070,10 @@ func TestValidatePodSpec(t *testing.T) { "bad DNS policy": { DNSPolicy: api.DNSPolicy("invalid"), RestartPolicy: api.RestartPolicyAlways, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, "bad service account name": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, ServiceAccountName: "invalidName", @@ -3029,7 +3081,7 @@ func TestValidatePodSpec(t *testing.T) { "bad restart policy": { RestartPolicy: "UnknowPolicy", DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, "with hostNetwork hostPort not equal to containerPort": { Containers: []api.Container{ @@ -3044,7 +3096,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad supplementalGroups large than math.MaxInt32": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ HostNetwork: false, SupplementalGroups: []int64{maxID, 1234}, @@ -3053,7 +3105,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad supplementalGroups less than 0": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ HostNetwork: false, SupplementalGroups: []int64{minID, 1234}, @@ -3062,7 +3114,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad runAsUser large than math.MaxInt32": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ HostNetwork: false, RunAsUser: &maxID, @@ -3071,7 +3123,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad runAsUser less than 0": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ HostNetwork: false, RunAsUser: &minID, @@ -3080,7 +3132,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad fsGroup large than math.MaxInt32": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ HostNetwork: false, FSGroup: &maxID, @@ -3089,7 +3141,7 @@ func TestValidatePodSpec(t *testing.T) { DNSPolicy: api.DNSClusterFirst, }, "bad fsGroup less than 0": { - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, SecurityContext: &api.PodSecurityContext{ HostNetwork: false, FSGroup: &minID, @@ -3101,7 +3153,7 @@ func TestValidatePodSpec(t *testing.T) { Volumes: []api.Volume{ {Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}, }, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, NodeSelector: map[string]string{ "key": "value", @@ -3113,7 +3165,7 @@ func TestValidatePodSpec(t *testing.T) { "bad nodeName": { NodeName: "node name", Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -3128,7 +3180,7 @@ func TestValidatePodSpec(t *testing.T) { func TestValidatePod(t *testing.T) { validPodSpec := func(affinity *api.Affinity) api.PodSpec { spec := api.PodSpec{ - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, } @@ -3143,7 +3195,7 @@ func TestValidatePod(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "123", Namespace: "ns"}, Spec: api.PodSpec{ Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -3154,7 +3206,7 @@ func TestValidatePod(t *testing.T) { Volumes: []api.Volume{ {Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}, }, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, NodeSelector: map[string]string{ @@ -3446,8 +3498,8 @@ func TestValidatePod(t *testing.T) { }, }, Spec: api.PodSpec{ - InitContainers: []api.Container{{Name: "init-ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + InitContainers: []api.Container{{Name: "init-ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -3489,9 +3541,10 @@ func TestValidatePod(t *testing.T) { api.OpaqueIntResourceName("A"): resource.MustParse("20"), }, }, + TerminationMessagePolicy: "File", }, }, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -3499,7 +3552,7 @@ func TestValidatePod(t *testing.T) { { // valid opaque integer resources for regular container ObjectMeta: metav1.ObjectMeta{Name: "valid-opaque-int", Namespace: "ns"}, Spec: api.PodSpec{ - InitContainers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + InitContainers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, Containers: []api.Container{ { Name: "valid-opaque-int", @@ -3513,6 +3566,7 @@ func TestValidatePod(t *testing.T) { api.OpaqueIntResourceName("A"): resource.MustParse("20"), }, }, + TerminationMessagePolicy: "File", }, }, RestartPolicy: api.RestartPolicyAlways, @@ -3532,7 +3586,7 @@ func TestValidatePod(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, "bad namespace": { @@ -3540,7 +3594,7 @@ func TestValidatePod(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, "bad spec": { @@ -3560,7 +3614,7 @@ func TestValidatePod(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, "invalid node selector requirement in node affinity, operator can't be null": { @@ -3575,7 +3629,6 @@ func TestValidatePod(t *testing.T) { { MatchExpressions: []api.NodeSelectorRequirement{ { - Key: "key1", }, }, @@ -3916,8 +3969,8 @@ func TestValidatePod(t *testing.T) { }, }, Spec: api.PodSpec{ - InitContainers: []api.Container{{Name: "init-ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + InitContainers: []api.Container{{Name: "init-ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -4039,7 +4092,7 @@ func TestValidatePod(t *testing.T) { }, }, }, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -4084,7 +4137,7 @@ func TestValidatePod(t *testing.T) { }, }, }, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, }, @@ -5179,7 +5232,7 @@ func TestValidateReplicationControllerStatusUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, } @@ -5262,7 +5315,7 @@ func TestValidateReplicationControllerUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, } @@ -5274,7 +5327,7 @@ func TestValidateReplicationControllerUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, }, }, @@ -5425,7 +5478,7 @@ func TestValidateReplicationController(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, } @@ -5438,7 +5491,7 @@ func TestValidateReplicationController(t *testing.T) { Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, } @@ -5582,7 +5635,7 @@ func TestValidateReplicationController(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, ObjectMeta: metav1.ObjectMeta{ Labels: validSelector, @@ -5601,7 +5654,7 @@ func TestValidateReplicationController(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyNever, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, ObjectMeta: metav1.ObjectMeta{ Labels: validSelector, diff --git a/pkg/apis/batch/validation/validation_test.go b/pkg/apis/batch/validation/validation_test.go index bd687642aa..b28ddd30d2 100644 --- a/pkg/apis/batch/validation/validation_test.go +++ b/pkg/apis/batch/validation/validation_test.go @@ -40,7 +40,7 @@ func getValidPodTemplateSpecForManual(selector *metav1.LabelSelector) api.PodTem Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } } @@ -59,7 +59,7 @@ func getValidPodTemplateSpecForGenerated(selector *metav1.LabelSelector) api.Pod Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } } @@ -165,7 +165,7 @@ func TestValidateJob(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, }, @@ -186,7 +186,7 @@ func TestValidateJob(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, }, @@ -207,7 +207,7 @@ func TestValidateJob(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, }, @@ -518,7 +518,7 @@ func TestValidateCronJob(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, }, diff --git a/pkg/apis/extensions/validation/validation_test.go b/pkg/apis/extensions/validation/validation_test.go index 915a0289b3..4ee028c4ce 100644 --- a/pkg/apis/extensions/validation/validation_test.go +++ b/pkg/apis/extensions/validation/validation_test.go @@ -265,25 +265,25 @@ func TestValidateDaemonSetUpdate(t *testing.T) { validPodSpecAbc := api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, } validPodSpecDef := api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, } validPodSpecNodeSelector := api.PodSpec{ NodeSelector: validSelector, NodeName: "xyz", RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, } validPodSpecVolume := api.PodSpec{ Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, } validPodTemplateAbc := api.PodTemplate{ @@ -514,7 +514,7 @@ func TestValidateDaemonSet(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } @@ -642,7 +642,7 @@ func TestValidateDaemonSet(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, ObjectMeta: metav1.ObjectMeta{ Labels: validSelector, @@ -661,7 +661,7 @@ func TestValidateDaemonSet(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyNever, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, ObjectMeta: metav1.ObjectMeta{ Labels: validSelector, @@ -725,9 +725,10 @@ func validDeployment() *extensions.Deployment { DNSPolicy: api.DNSDefault, Containers: []api.Container{ { - Name: "nginx", - Image: "image", - ImagePullPolicy: api.PullNever, + Name: "nginx", + Image: "image", + ImagePullPolicy: api.PullNever, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, }, @@ -1217,7 +1218,7 @@ func TestValidateReplicaSetStatusUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } @@ -1300,7 +1301,7 @@ func TestValidateReplicaSetUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } @@ -1312,7 +1313,7 @@ func TestValidateReplicaSetUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, }, }, @@ -1463,7 +1464,7 @@ func TestValidateReplicaSet(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } @@ -1476,7 +1477,7 @@ func TestValidateReplicaSet(t *testing.T) { Volumes: []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } @@ -1620,7 +1621,7 @@ func TestValidateReplicaSet(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, ObjectMeta: metav1.ObjectMeta{ Labels: validLabels, @@ -1639,7 +1640,7 @@ func TestValidateReplicaSet(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyNever, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, ObjectMeta: metav1.ObjectMeta{ Labels: validLabels, diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 7dc90ad2a1..242270003f 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -1178,7 +1178,14 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions }, "terminationMessagePath": { SchemaProps: spec.SchemaProps{ - Description: "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.", + Description: "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "terminationMessagePolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", Type: []string{"string"}, Format: "", }, diff --git a/pkg/kubelet/config/common_test.go b/pkg/kubelet/config/common_test.go index 18556b1517..47774f91b7 100644 --- a/pkg/kubelet/config/common_test.go +++ b/pkg/kubelet/config/common_test.go @@ -46,11 +46,12 @@ func TestDecodeSinglePod(t *testing.T) { DNSPolicy: v1.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []v1.Container{{ - Name: "image", - Image: "test/image", - ImagePullPolicy: "IfNotPresent", - TerminationMessagePath: "/dev/termination-log", - SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), + Name: "image", + Image: "test/image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: v1.TerminationMessageReadFile, + SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, @@ -107,11 +108,13 @@ func TestDecodePodList(t *testing.T) { DNSPolicy: v1.DNSClusterFirst, TerminationGracePeriodSeconds: &grace, Containers: []v1.Container{{ - Name: "image", - Image: "test/image", - ImagePullPolicy: "IfNotPresent", - TerminationMessagePath: "/dev/termination-log", - SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), + Name: "image", + Image: "test/image", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: v1.TerminationMessageReadFile, + + SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), }}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, diff --git a/pkg/kubelet/config/config_test.go b/pkg/kubelet/config/config_test.go index a09a2c88a8..92de495cac 100644 --- a/pkg/kubelet/config/config_test.go +++ b/pkg/kubelet/config/config_test.go @@ -69,10 +69,11 @@ func CreateValidPod(name, namespace string) *v1.Pod { DNSPolicy: v1.DNSClusterFirst, Containers: []v1.Container{ { - Name: "ctr", - Image: "image", - ImagePullPolicy: "IfNotPresent", - SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), + Name: "ctr", + Image: "image", + ImagePullPolicy: "IfNotPresent", + SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), + TerminationMessagePolicy: v1.TerminationMessageReadFile, }, }, }, @@ -204,7 +205,7 @@ func TestNewPodAddedSnapshotAndUpdates(t *testing.T) { // container updates are separated as UPDATE pod := *podUpdate.Pods[0] - pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent}} + pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent, TerminationMessagePolicy: v1.TerminationMessageReadFile}} channel <- CreatePodUpdate(kubetypes.ADD, TestSource, &pod) expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, &pod)) } @@ -222,7 +223,7 @@ func TestNewPodAddedSnapshot(t *testing.T) { // container updates are separated as UPDATE pod := *podUpdate.Pods[0] - pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent}} + pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent, TerminationMessagePolicy: v1.TerminationMessageReadFile}} channel <- CreatePodUpdate(kubetypes.ADD, TestSource, &pod) expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, TestSource, &pod)) } @@ -240,7 +241,7 @@ func TestNewPodAddedUpdatedRemoved(t *testing.T) { // an kubetypes.ADD should be converted to kubetypes.UPDATE pod := CreateValidPod("foo", "new") - pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent}} + pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent, TerminationMessagePolicy: v1.TerminationMessageReadFile}} podUpdate = CreatePodUpdate(kubetypes.ADD, TestSource, pod) channel <- podUpdate expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.UPDATE, TestSource, pod)) @@ -282,7 +283,7 @@ func TestNewPodAddedUpdatedSet(t *testing.T) { // should be converted to an kubetypes.ADD, kubetypes.REMOVE, and kubetypes.UPDATE pod := CreateValidPod("foo2", "new") - pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent}} + pod.Spec.Containers = []v1.Container{{Name: "bar", Image: "test", ImagePullPolicy: v1.PullIfNotPresent, TerminationMessagePolicy: v1.TerminationMessageReadFile}} podUpdate = CreatePodUpdate(kubetypes.SET, TestSource, pod, CreateValidPod("foo3", "new"), CreateValidPod("foo4", "new")) channel <- podUpdate expectPodUpdate(t, ch, diff --git a/pkg/kubelet/config/file_linux_test.go b/pkg/kubelet/config/file_linux_test.go index 9473349a23..6ecf128e7c 100644 --- a/pkg/kubelet/config/file_linux_test.go +++ b/pkg/kubelet/config/file_linux_test.go @@ -210,9 +210,11 @@ func getTestCases(hostname types.NodeName) []*testCase { Containers: []v1.Container{{ Name: "image", Image: "test/image", - TerminationMessagePath: "/dev/termination-log", - ImagePullPolicy: "Always", - SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, + TerminationMessagePath: "/dev/termination-log", + ImagePullPolicy: "Always", + SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(), + TerminationMessagePolicy: v1.TerminationMessageReadFile, + }}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, diff --git a/pkg/kubelet/config/http_test.go b/pkg/kubelet/config/http_test.go index d637cb9c0b..8c38bddf6f 100644 --- a/pkg/kubelet/config/http_test.go +++ b/pkg/kubelet/config/http_test.go @@ -145,7 +145,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { }, Spec: v1.PodSpec{ NodeName: string(nodeName), - Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, + Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways, TerminationMessagePolicy: v1.TerminationMessageReadFile}}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, @@ -174,8 +174,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { Containers: []v1.Container{{ Name: "1", Image: "foo", - TerminationMessagePath: "/dev/termination-log", - ImagePullPolicy: "Always", + TerminationMessagePath: "/dev/termination-log", + ImagePullPolicy: "Always", + TerminationMessagePolicy: v1.TerminationMessageReadFile, }}, }, Status: v1.PodStatus{ @@ -198,7 +199,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { }, Spec: v1.PodSpec{ NodeName: nodeName, - Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, + Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways, TerminationMessagePolicy: v1.TerminationMessageReadFile}}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, @@ -213,7 +214,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { }, Spec: v1.PodSpec{ NodeName: nodeName, - Containers: []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}}, + Containers: []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: "", TerminationMessagePolicy: v1.TerminationMessageReadFile}}, SecurityContext: &v1.PodSecurityContext{}, SchedulerName: api.DefaultSchedulerName, }, @@ -244,8 +245,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { Containers: []v1.Container{{ Name: "1", Image: "foo", - TerminationMessagePath: "/dev/termination-log", - ImagePullPolicy: "Always", + TerminationMessagePath: "/dev/termination-log", + ImagePullPolicy: "Always", + TerminationMessagePolicy: v1.TerminationMessageReadFile, }}, }, Status: v1.PodStatus{ @@ -271,8 +273,9 @@ func TestExtractPodsFromHTTP(t *testing.T) { Containers: []v1.Container{{ Name: "2", Image: "bar:bartag", - TerminationMessagePath: "/dev/termination-log", - ImagePullPolicy: "IfNotPresent", + TerminationMessagePath: "/dev/termination-log", + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: v1.TerminationMessageReadFile, }}, }, Status: v1.PodStatus{ diff --git a/pkg/kubelet/container/os.go b/pkg/kubelet/container/os.go index 18e5221e12..6126063b30 100644 --- a/pkg/kubelet/container/os.go +++ b/pkg/kubelet/container/os.go @@ -32,6 +32,7 @@ type OSInterface interface { Remove(path string) error RemoveAll(path string) error Create(path string) (*os.File, error) + Chmod(path string, perm os.FileMode) error Hostname() (name string, err error) Chtimes(path string, atime time.Time, mtime time.Time) error Pipe() (r *os.File, w *os.File, err error) @@ -73,6 +74,12 @@ func (RealOS) Create(path string) (*os.File, error) { return os.Create(path) } +// Chmod will change the permissions on the specified path or return +// an error. +func (RealOS) Chmod(path string, perm os.FileMode) error { + return os.Chmod(path, perm) +} + // Hostname will call os.Hostname to return the hostname. func (RealOS) Hostname() (name string, err error) { return os.Hostname() diff --git a/pkg/kubelet/container/runtime.go b/pkg/kubelet/container/runtime.go index 3a3650dbbe..dab4f4ec21 100644 --- a/pkg/kubelet/container/runtime.go +++ b/pkg/kubelet/container/runtime.go @@ -626,3 +626,19 @@ func (s SortContainerStatusesByCreationTime) Swap(i, j int) { s[i], s[j] = s[j], func (s SortContainerStatusesByCreationTime) Less(i, j int) bool { return s[i].CreatedAt.Before(s[j].CreatedAt) } + +const ( + // MaxPodTerminationMessageLogLength is the maximum bytes any one pod may have written + // as termination message output across all containers. Containers will be evenly truncated + // until output is below this limit. + MaxPodTerminationMessageLogLength = 1024 * 12 + // MaxContainerTerminationMessageLength is the upper bound any one container may write to + // its termination message path. Contents above this length will be truncated. + MaxContainerTerminationMessageLength = 1024 * 4 + // MaxContainerTerminationMessageLogLength is the maximum bytes any one container will + // have written to its termination message when the message is read from the logs. + MaxContainerTerminationMessageLogLength = 1024 * 2 + // MaxContainerTerminationMessageLogLines is the maximum number of previous lines of + // log output that the termination message can contain. + MaxContainerTerminationMessageLogLines = 80 +) diff --git a/pkg/kubelet/container/testing/os.go b/pkg/kubelet/container/testing/os.go index e70c2809f8..ee8d255b08 100644 --- a/pkg/kubelet/container/testing/os.go +++ b/pkg/kubelet/container/testing/os.go @@ -83,6 +83,11 @@ func (FakeOS) Create(path string) (*os.File, error) { return nil, nil } +// Chmod is a fake call that returns nil. +func (FakeOS) Chmod(path string, perm os.FileMode) error { + return nil +} + // Hostname is a fake call that returns nil. func (f *FakeOS) Hostname() (name string, err error) { return f.HostName, nil diff --git a/pkg/kubelet/dockertools/BUILD b/pkg/kubelet/dockertools/BUILD index d574b11243..25bf8539af 100644 --- a/pkg/kubelet/dockertools/BUILD +++ b/pkg/kubelet/dockertools/BUILD @@ -52,8 +52,10 @@ go_library( "//pkg/util/procfs:go_default_library", "//pkg/util/selinux:go_default_library", "//pkg/util/strings:go_default_library", + "//pkg/util/tail:go_default_library", "//pkg/util/term:go_default_library", "//pkg/util/version:go_default_library", + "//vendor:github.com/armon/circbuf", "//vendor:github.com/docker/distribution/digest", "//vendor:github.com/docker/distribution/reference", "//vendor:github.com/docker/docker/pkg/jsonmessage", diff --git a/pkg/kubelet/dockertools/docker_manager.go b/pkg/kubelet/dockertools/docker_manager.go index 5c1ac78e62..d972dea199 100644 --- a/pkg/kubelet/dockertools/docker_manager.go +++ b/pkg/kubelet/dockertools/docker_manager.go @@ -33,6 +33,7 @@ import ( "sync" "time" + "github.com/armon/circbuf" dockertypes "github.com/docker/engine-api/types" dockercontainer "github.com/docker/engine-api/types/container" dockerstrslice "github.com/docker/engine-api/types/strslice" @@ -70,6 +71,7 @@ import ( "k8s.io/kubernetes/pkg/util/procfs" "k8s.io/kubernetes/pkg/util/selinux" utilstrings "k8s.io/kubernetes/pkg/util/strings" + "k8s.io/kubernetes/pkg/util/tail" "k8s.io/kubernetes/pkg/util/term" utilversion "k8s.io/kubernetes/pkg/util/version" ) @@ -482,19 +484,12 @@ func (dm *DockerManager) inspectContainer(id string, podName, podNamespace strin startedAt = createdAt } - terminationMessagePath := containerInfo.TerminationMessagePath - if terminationMessagePath != "" { - for _, mount := range iResult.Mounts { - if mount.Destination == terminationMessagePath { - path := mount.Source - if data, err := ioutil.ReadFile(path); err != nil { - message = fmt.Sprintf("Error on reading termination-log %s: %v", path, err) - } else { - message = string(data) - } - } - } + // retrieve the termination message from logs, file, or file with fallback to logs in case of failure + fallbackToLogs := containerInfo.TerminationMessagePolicy == v1.TerminationMessageFallbackToLogsOnError && (iResult.State.ExitCode != 0 || iResult.State.OOMKilled) + if msg := getTerminationMessage(dm.c, iResult, containerInfo.TerminationMessagePath, fallbackToLogs); len(msg) > 0 { + message = msg } + status.State = kubecontainer.ContainerStateExited status.Message = message status.Reason = reason @@ -508,6 +503,49 @@ func (dm *DockerManager) inspectContainer(id string, podName, podNamespace strin return &status, "", nil } +func getTerminationMessage(c DockerInterface, iResult *dockertypes.ContainerJSON, terminationMessagePath string, fallbackToLogs bool) string { + if len(terminationMessagePath) != 0 { + for _, mount := range iResult.Mounts { + if mount.Destination != terminationMessagePath { + continue + } + path := mount.Source + data, _, err := tail.ReadAtMost(path, kubecontainer.MaxContainerTerminationMessageLength) + if err != nil { + return fmt.Sprintf("Error on reading termination log %s: %v", path, err) + } + if !fallbackToLogs || len(data) != 0 { + return string(data) + } + } + } + if !fallbackToLogs { + return "" + } + + return readLastStringFromContainerLogs(c, iResult.Name) +} + +// readLastStringFromContainerLogs attempts to a certain amount from the end of the logs for containerName. +// It will attempt to avoid reading excessive logs from the server, which may result in underestimating the amount +// of logs to fetch (such that the length of the response message is < max). +func readLastStringFromContainerLogs(c DockerInterface, containerName string) string { + logOptions := dockertypes.ContainerLogsOptions{ + ShowStdout: true, + ShowStderr: true, + } + buf, _ := circbuf.NewBuffer(kubecontainer.MaxContainerTerminationMessageLogLength) + streamOptions := StreamOptions{ + ErrorStream: buf, + OutputStream: buf, + } + logOptions.Tail = strconv.FormatInt(kubecontainer.MaxContainerTerminationMessageLogLines, 10) + if err := c.Logs(containerName, logOptions, streamOptions); err != nil { + return fmt.Sprintf("Error on reading termination message from logs: %v", err) + } + return buf.String() +} + // makeEnvList converts EnvVar list to a list of strings, in the form of // '=', which can be understood by docker. func makeEnvList(envs []kubecontainer.EnvVar) (result []string) { @@ -672,17 +710,24 @@ func (dm *DockerManager) runContainer( fs, err := os.Create(containerLogPath) if err != nil { // TODO: Clean up the previously created dir? return the error? - glog.Errorf("Error on creating termination-log file %q: %v", containerLogPath, err) + utilruntime.HandleError(fmt.Errorf("error creating termination-log file %q: %v", containerLogPath, err)) } else { fs.Close() // Close immediately; we're just doing a `touch` here - b := fmt.Sprintf("%s:%s", containerLogPath, container.TerminationMessagePath) + + // Chmod is needed because ioutil.WriteFile() ends up calling + // open(2) to create the file, so the final mode used is "mode & + // ~umask". But we want to make sure the specified mode is used + // in the file no matter what the umask is. + if err := os.Chmod(containerLogPath, 0666); err != nil { + utilruntime.HandleError(fmt.Errorf("unable to set termination-log file permissions %q: %v", containerLogPath, err)) + } // Have docker relabel the termination log path if SELinux is // enabled. + b := fmt.Sprintf("%s:%s", containerLogPath, container.TerminationMessagePath) if selinux.SELinuxEnabled() { b += ":Z" } - binds = append(binds, b) } } diff --git a/pkg/kubelet/dockertools/labels.go b/pkg/kubelet/dockertools/labels.go index 3e453cbfae..37edd50fde 100644 --- a/pkg/kubelet/dockertools/labels.go +++ b/pkg/kubelet/dockertools/labels.go @@ -39,11 +39,12 @@ const ( kubernetesPodDeletionGracePeriodLabel = "io.kubernetes.pod.deletionGracePeriod" kubernetesPodTerminationGracePeriodLabel = "io.kubernetes.pod.terminationGracePeriod" - kubernetesContainerHashLabel = "io.kubernetes.container.hash" - kubernetesContainerRestartCountLabel = "io.kubernetes.container.restartCount" - kubernetesContainerTerminationMessagePathLabel = "io.kubernetes.container.terminationMessagePath" - kubernetesContainerPreStopHandlerLabel = "io.kubernetes.container.preStopHandler" - kubernetesContainerPortsLabel = "io.kubernetes.container.ports" // Added in 1.4 + kubernetesContainerHashLabel = "io.kubernetes.container.hash" + kubernetesContainerRestartCountLabel = "io.kubernetes.container.restartCount" + kubernetesContainerTerminationMessagePathLabel = "io.kubernetes.container.terminationMessagePath" + kubernetesContainerTerminationMessagePolicyLabel = "io.kubernetes.container.terminationMessagePolicy" + kubernetesContainerPreStopHandlerLabel = "io.kubernetes.container.preStopHandler" + kubernetesContainerPortsLabel = "io.kubernetes.container.ports" // Added in 1.4 // TODO(random-liu): Keep this for old containers, remove this when we drop support for v1.1. kubernetesPodLabel = "io.kubernetes.pod.data" @@ -63,6 +64,7 @@ type labelledContainerInfo struct { Hash string RestartCount int TerminationMessagePath string + TerminationMessagePolicy v1.TerminationMessagePolicy PreStopHandler *v1.Handler Ports []v1.ContainerPort } @@ -83,6 +85,7 @@ func newLabels(container *v1.Container, pod *v1.Pod, restartCount int, enableCus labels[kubernetesContainerHashLabel] = strconv.FormatUint(kubecontainer.HashContainer(container), 16) labels[kubernetesContainerRestartCountLabel] = strconv.Itoa(restartCount) labels[kubernetesContainerTerminationMessagePathLabel] = container.TerminationMessagePath + labels[kubernetesContainerTerminationMessagePolicyLabel] = string(container.TerminationMessagePolicy) if container.Lifecycle != nil && container.Lifecycle.PreStop != nil { // Using json enconding so that the PreStop handler object is readable after writing as a label rawPreStop, err := json.Marshal(container.Lifecycle.PreStop) @@ -118,7 +121,8 @@ func getContainerInfoFromLabel(labels map[string]string) *labelledContainerInfo PodUID: kubetypes.UID(getStringValueFromLabel(labels, types.KubernetesPodUIDLabel)), Name: getStringValueFromLabel(labels, types.KubernetesContainerNameLabel), Hash: getStringValueFromLabel(labels, kubernetesContainerHashLabel), - TerminationMessagePath: getStringValueFromLabel(labels, kubernetesContainerTerminationMessagePathLabel), + TerminationMessagePath: getStringValueFromLabel(labels, kubernetesContainerTerminationMessagePathLabel), + TerminationMessagePolicy: v1.TerminationMessagePolicy(getStringValueFromLabel(labels, kubernetesContainerTerminationMessagePolicyLabel)), } if containerInfo.RestartCount, err = getIntValueFromLabel(labels, kubernetesContainerRestartCountLabel); err != nil { logError(containerInfo, kubernetesContainerRestartCountLabel, err) diff --git a/pkg/kubelet/kuberuntime/BUILD b/pkg/kubelet/kuberuntime/BUILD index 25619ef2b3..6861064cfe 100644 --- a/pkg/kubelet/kuberuntime/BUILD +++ b/pkg/kubelet/kuberuntime/BUILD @@ -47,7 +47,9 @@ go_library( "//pkg/securitycontext:go_default_library", "//pkg/util/parsers:go_default_library", "//pkg/util/selinux:go_default_library", + "//pkg/util/tail:go_default_library", "//pkg/util/version:go_default_library", + "//vendor:github.com/armon/circbuf", "//vendor:github.com/docker/docker/pkg/jsonlog", "//vendor:github.com/fsnotify/fsnotify", "//vendor:github.com/golang/glog", diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index e823362427..128d52292f 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -19,7 +19,6 @@ package kuberuntime import ( "fmt" "io" - "io/ioutil" "math/rand" "net/url" "os" @@ -28,7 +27,9 @@ import ( "sync" "time" + "github.com/armon/circbuf" "github.com/golang/glog" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubetypes "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -41,6 +42,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" "k8s.io/kubernetes/pkg/util/selinux" + "k8s.io/kubernetes/pkg/util/tail" ) // startContainer starts a container and returns a message indicates why it is failed on error. @@ -272,9 +274,18 @@ func (m *kubeGenericRuntimeManager) makeMounts(opts *kubecontainer.RunContainerO containerLogPath := filepath.Join(opts.PodContainerDir, cid) fs, err := m.osInterface.Create(containerLogPath) if err != nil { - glog.Errorf("Error on creating termination-log file %q: %v", containerLogPath, err) + utilruntime.HandleError(fmt.Errorf("error on creating termination-log file %q: %v", containerLogPath, err)) } else { fs.Close() + + // Chmod is needed because ioutil.WriteFile() ends up calling + // open(2) to create the file, so the final mode used is "mode & + // ~umask". But we want to make sure the specified mode is used + // in the file no matter what the umask is. + if err := m.osInterface.Chmod(containerLogPath, 0666); err != nil { + utilruntime.HandleError(fmt.Errorf("unable to set termination-log file permissions %q: %v", containerLogPath, err)) + } + selinuxRelabel := selinux.SELinuxEnabled() volumeMounts = append(volumeMounts, &runtimeapi.Mount{ HostPath: containerLogPath, @@ -325,29 +336,36 @@ func makeUID() string { return fmt.Sprintf("%08x", rand.Uint32()) } -// getTerminationMessage gets termination message of the container. -func getTerminationMessage(status *runtimeapi.ContainerStatus, kubeStatus *kubecontainer.ContainerStatus, terminationMessagePath string) string { - message := "" - - if !kubeStatus.FinishedAt.IsZero() || kubeStatus.ExitCode != 0 { - if terminationMessagePath == "" { - return "" - } - +// getTerminationMessage looks on the filesystem for the provided termination message path, returning a limited +// amount of those bytes, or returns true if the logs should be checked. +func getTerminationMessage(status *runtimeapi.ContainerStatus, terminationMessagePath string, fallbackToLogs bool) (string, bool) { + if len(terminationMessagePath) != 0 { for _, mount := range status.Mounts { - if mount.ContainerPath == terminationMessagePath { - path := mount.HostPath - if data, err := ioutil.ReadFile(path); err != nil { - message = fmt.Sprintf("Error on reading termination-log %s: %v", path, err) - } else { - message = string(data) - } - break + if mount.ContainerPath != terminationMessagePath { + continue + } + path := mount.HostPath + data, _, err := tail.ReadAtMost(path, kubecontainer.MaxContainerTerminationMessageLength) + if err != nil { + return fmt.Sprintf("Error on reading termination log %s: %v", path, err), false + } + if !fallbackToLogs || len(data) != 0 { + return string(data), false } } } + return "", fallbackToLogs +} - return message +// readLastStringFromContainerLogs attempts to read up to the max log length from the end of the CRI log represented +// by path. It reads up to max log lines. +func readLastStringFromContainerLogs(path string) string { + value := int64(kubecontainer.MaxContainerTerminationMessageLogLines) + buf, _ := circbuf.NewBuffer(kubecontainer.MaxContainerTerminationMessageLogLength) + if err := ReadLogs(path, &v1.PodLogOptions{TailLines: &value}, buf, buf); err != nil { + return fmt.Sprintf("Error on reading termination message from logs: %v", err) + } + return buf.String() } // getPodContainerStatuses gets all containers' statuses for the pod. @@ -393,13 +411,19 @@ func (m *kubeGenericRuntimeManager) getPodContainerStatuses(uid kubetypes.UID, n cStatus.Message = status.Message cStatus.ExitCode = int(status.ExitCode) cStatus.FinishedAt = time.Unix(0, status.FinishedAt) + + fallbackToLogs := annotatedInfo.TerminationMessagePolicy == v1.TerminationMessageFallbackToLogsOnError && (cStatus.ExitCode != 0 || cStatus.Reason == "OOMKilled") + tMessage, checkLogs := getTerminationMessage(status, annotatedInfo.TerminationMessagePath, fallbackToLogs) + if checkLogs { + path := buildFullContainerLogsPath(uid, labeledInfo.ContainerName, annotatedInfo.RestartCount) + tMessage = readLastStringFromContainerLogs(path) + } + // Use the termination message written by the application is not empty + if len(tMessage) != 0 { + cStatus.Message = tMessage + } } - tMessage := getTerminationMessage(status, cStatus, annotatedInfo.TerminationMessagePath) - // Use the termination message written by the application is not empty - if len(tMessage) != 0 { - cStatus.Message = tMessage - } statuses[i] = cStatus } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_logs.go b/pkg/kubelet/kuberuntime/kuberuntime_logs.go index 3cc0eb1764..21d81bc6a0 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_logs.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_logs.go @@ -32,6 +32,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/util/tail" ) // Notice that the current kuberuntime logs implementation doesn't handle @@ -120,7 +121,7 @@ func ReadLogs(path string, apiOpts *v1.PodLogOptions, stdout, stderr io.Writer) opts := newLogOptions(apiOpts, time.Now()) // Search start point based on tail line. - start, err := tail(f, opts.tail) + start, err := tail.FindTailLineStartIndex(f, opts.tail) if err != nil { return fmt.Errorf("failed to tail %d lines of log file %q: %v", opts.tail, path, err) } @@ -347,40 +348,3 @@ func (w *logWriter) write(msg *logMessage) error { } return nil } - -// tail returns the start of last nth line. -// * If n < 0, return the beginning of the file. -// * If n >= 0, return the beginning of last nth line. -// Notice that if the last line is incomplete (no end-of-line), it will not be counted -// as one line. -func tail(f io.ReadSeeker, n int64) (int64, error) { - if n < 0 { - return 0, nil - } - size, err := f.Seek(0, os.SEEK_END) - if err != nil { - return 0, err - } - var left, cnt int64 - buf := make([]byte, blockSize) - for right := size; right > 0 && cnt <= n; right -= blockSize { - left = right - blockSize - if left < 0 { - left = 0 - buf = make([]byte, right) - } - if _, err := f.Seek(left, os.SEEK_SET); err != nil { - return 0, err - } - if _, err := f.Read(buf); err != nil { - return 0, err - } - cnt += int64(bytes.Count(buf, eol)) - } - for ; cnt > n; cnt-- { - idx := bytes.Index(buf, eol) + 1 - buf = buf[idx:] - left += int64(idx) - } - return left, nil -} diff --git a/pkg/kubelet/kuberuntime/kuberuntime_logs_test.go b/pkg/kubelet/kuberuntime/kuberuntime_logs_test.go index 9fb07d6aad..1602827a83 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_logs_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_logs_test.go @@ -18,7 +18,6 @@ package kuberuntime import ( "bytes" - "strings" "testing" "time" @@ -242,28 +241,3 @@ func TestWriteLogsWithBytesLimit(t *testing.T) { assert.Equal(t, test.expectStderr, stderrBuf.String()) } } - -func TestTail(t *testing.T) { - line := strings.Repeat("a", blockSize) - testBytes := []byte(line + "\n" + - line + "\n" + - line + "\n" + - line + "\n" + - line[blockSize/2:]) // incomplete line - - for c, test := range []struct { - n int64 - start int64 - }{ - {n: -1, start: 0}, - {n: 0, start: int64(len(line)+1) * 4}, - {n: 1, start: int64(len(line)+1) * 3}, - {n: 9999, start: 0}, - } { - t.Logf("TestCase #%d: %+v", c, test) - r := bytes.NewReader(testBytes) - s, err := tail(r, test.n) - assert.NoError(t, err) - assert.Equal(t, s, test.start) - } -} diff --git a/pkg/kubelet/kuberuntime/labels.go b/pkg/kubelet/kuberuntime/labels.go index 462442b909..ccd0dc99b0 100644 --- a/pkg/kubelet/kuberuntime/labels.go +++ b/pkg/kubelet/kuberuntime/labels.go @@ -33,11 +33,12 @@ const ( podDeletionGracePeriodLabel = "io.kubernetes.pod.deletionGracePeriod" podTerminationGracePeriodLabel = "io.kubernetes.pod.terminationGracePeriod" - containerHashLabel = "io.kubernetes.container.hash" - containerRestartCountLabel = "io.kubernetes.container.restartCount" - containerTerminationMessagePathLabel = "io.kubernetes.container.terminationMessagePath" - containerPreStopHandlerLabel = "io.kubernetes.container.preStopHandler" - containerPortsLabel = "io.kubernetes.container.ports" + containerHashLabel = "io.kubernetes.container.hash" + containerRestartCountLabel = "io.kubernetes.container.restartCount" + containerTerminationMessagePathLabel = "io.kubernetes.container.terminationMessagePath" + containerTerminationMessagePolicyLabel = "io.kubernetes.container.terminationMessagePolicy" + containerPreStopHandlerLabel = "io.kubernetes.container.preStopHandler" + containerPortsLabel = "io.kubernetes.container.ports" // kubernetesManagedLabel is used to distinguish whether a container/sandbox is managed by kubelet or not kubernetesManagedLabel = "io.kubernetes.managed" @@ -69,6 +70,7 @@ type annotatedContainerInfo struct { PodDeletionGracePeriod *int64 PodTerminationGracePeriod *int64 TerminationMessagePath string + TerminationMessagePolicy v1.TerminationMessagePolicy PreStopHandler *v1.Handler ContainerPorts []v1.ContainerPort } @@ -113,6 +115,7 @@ func newContainerAnnotations(container *v1.Container, pod *v1.Pod, restartCount annotations[containerHashLabel] = strconv.FormatUint(kubecontainer.HashContainer(container), 16) annotations[containerRestartCountLabel] = strconv.Itoa(restartCount) annotations[containerTerminationMessagePathLabel] = container.TerminationMessagePath + annotations[containerTerminationMessagePolicyLabel] = string(container.TerminationMessagePolicy) if pod.DeletionGracePeriodSeconds != nil { annotations[podDeletionGracePeriodLabel] = strconv.FormatInt(*pod.DeletionGracePeriodSeconds, 10) @@ -192,7 +195,8 @@ func isManagedByKubelet(labels map[string]string) bool { func getContainerInfoFromAnnotations(annotations map[string]string) *annotatedContainerInfo { var err error containerInfo := &annotatedContainerInfo{ - TerminationMessagePath: getStringValueFromLabel(annotations, containerTerminationMessagePathLabel), + TerminationMessagePath: getStringValueFromLabel(annotations, containerTerminationMessagePathLabel), + TerminationMessagePolicy: v1.TerminationMessagePolicy(getStringValueFromLabel(annotations, containerTerminationMessagePolicyLabel)), } if containerInfo.Hash, err = getUint64ValueFromLabel(annotations, containerHashLabel); err != nil { diff --git a/pkg/kubelet/status/status_manager.go b/pkg/kubelet/status/status_manager.go index bcb8161375..47a5f3a632 100644 --- a/pkg/kubelet/status/status_manager.go +++ b/pkg/kubelet/status/status_manager.go @@ -513,6 +513,10 @@ func (m *manager) needsReconcile(uid types.UID, status v1.PodStatus) bool { // kubelet temporarily. // TODO(random-liu): Remove timestamp related logic after apiserver supports nanosecond or makes it consistent. func normalizeStatus(pod *v1.Pod, status *v1.PodStatus) *v1.PodStatus { + bytesPerStatus := kubecontainer.MaxPodTerminationMessageLogLength + if containers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers); containers > 0 { + bytesPerStatus = bytesPerStatus / containers + } normalizeTimeStamp := func(t *metav1.Time) { *t = t.Rfc3339Copy() } @@ -523,6 +527,9 @@ func normalizeStatus(pod *v1.Pod, status *v1.PodStatus) *v1.PodStatus { if c.Terminated != nil { normalizeTimeStamp(&c.Terminated.StartedAt) normalizeTimeStamp(&c.Terminated.FinishedAt) + if len(c.Terminated.Message) > bytesPerStatus { + c.Terminated.Message = c.Terminated.Message[:bytesPerStatus] + } } } diff --git a/pkg/kubelet/status/status_manager_test.go b/pkg/kubelet/status/status_manager_test.go index c4b5a2b759..9540a3a9d8 100644 --- a/pkg/kubelet/status/status_manager_test.go +++ b/pkg/kubelet/status/status_manager_test.go @@ -20,21 +20,21 @@ import ( "fmt" "math/rand" "strconv" + "strings" "testing" "time" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" - "k8s.io/kubernetes/pkg/client/testing/core" - "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" + "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" + "k8s.io/kubernetes/pkg/client/testing/core" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubepod "k8s.io/kubernetes/pkg/kubelet/pod" podtest "k8s.io/kubernetes/pkg/kubelet/pod/testing" @@ -480,6 +480,40 @@ func TestStatusEquality(t *testing.T) { } } +func TestStatusNormalizationEnforcesMaxBytes(t *testing.T) { + pod := v1.Pod{ + Spec: v1.PodSpec{}, + } + containerStatus := []v1.ContainerStatus{} + for i := 0; i < 48; i++ { + s := v1.ContainerStatus{ + Name: fmt.Sprintf("container%d", i), + LastTerminationState: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + Message: strings.Repeat("abcdefgh", int(24+i%3)), + }, + }, + } + containerStatus = append(containerStatus, s) + } + podStatus := v1.PodStatus{ + InitContainerStatuses: containerStatus[:24], + ContainerStatuses: containerStatus[24:], + } + result := normalizeStatus(&pod, &podStatus) + count := 0 + for _, s := range result.InitContainerStatuses { + l := len(s.LastTerminationState.Terminated.Message) + if l < 192 || l > 256 { + t.Errorf("container message had length %d", l) + } + count += l + } + if count > kubecontainer.MaxPodTerminationMessageLogLength { + t.Errorf("message length not truncated") + } +} + func TestStaticPod(t *testing.T) { staticPod := getTestPod() staticPod.Annotations = map[string]string{kubetypes.ConfigSourceAnnotationKey: "file"} diff --git a/pkg/registry/batch/cronjob/strategy_test.go b/pkg/registry/batch/cronjob/strategy_test.go index 2ad31e8b39..244bcf7aa0 100644 --- a/pkg/registry/batch/cronjob/strategy_test.go +++ b/pkg/registry/batch/cronjob/strategy_test.go @@ -45,7 +45,7 @@ func TestCronJobStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } scheduledJob := &batch.CronJob{ @@ -106,7 +106,7 @@ func TestCronJobStatusStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } oldSchedule := "* * * * ?" diff --git a/pkg/registry/batch/job/storage/storage_test.go b/pkg/registry/batch/job/storage/storage_test.go index 9cf567c4f4..467c574bc3 100644 --- a/pkg/registry/batch/job/storage/storage_test.go +++ b/pkg/registry/batch/job/storage/storage_test.go @@ -64,9 +64,10 @@ func validNewJob() *batch.Job { Spec: api.PodSpec{ Containers: []api.Container{ { - Name: "test", - Image: "test_image", - ImagePullPolicy: api.PullIfNotPresent, + Name: "test", + Image: "test_image", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, RestartPolicy: api.RestartPolicyOnFailure, diff --git a/pkg/registry/batch/job/strategy_test.go b/pkg/registry/batch/job/strategy_test.go index 5c67d570a5..7fd7511e24 100644 --- a/pkg/registry/batch/job/strategy_test.go +++ b/pkg/registry/batch/job/strategy_test.go @@ -54,7 +54,7 @@ func TestJobStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } job := &batch.Job{ @@ -111,7 +111,7 @@ func TestJobStrategyWithGeneration(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } job := &batch.Job{ @@ -170,7 +170,7 @@ func TestJobStatusStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyOnFailure, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, } oldParallelism := int32(10) diff --git a/pkg/registry/core/controller/storage/storage_test.go b/pkg/registry/core/controller/storage/storage_test.go index bbdc854c80..f23934b12e 100644 --- a/pkg/registry/core/controller/storage/storage_test.go +++ b/pkg/registry/core/controller/storage/storage_test.go @@ -77,9 +77,10 @@ func validNewController() *api.ReplicationController { Spec: api.PodSpec{ Containers: []api.Container{ { - Name: "test", - Image: "test_image", - ImagePullPolicy: api.PullIfNotPresent, + Name: "test", + Image: "test_image", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, RestartPolicy: api.RestartPolicyAlways, diff --git a/pkg/registry/core/controller/strategy_test.go b/pkg/registry/core/controller/strategy_test.go index fc2c526ca1..51368005e6 100644 --- a/pkg/registry/core/controller/strategy_test.go +++ b/pkg/registry/core/controller/strategy_test.go @@ -44,7 +44,7 @@ func TestControllerStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } @@ -102,7 +102,7 @@ func TestControllerStatusStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, } @@ -163,7 +163,7 @@ func TestValidateUpdate(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, }, }, } diff --git a/pkg/registry/core/pod/storage/storage_test.go b/pkg/registry/core/pod/storage/storage_test.go index 053020af40..9449797d9e 100644 --- a/pkg/registry/core/pod/storage/storage_test.go +++ b/pkg/registry/core/pod/storage/storage_test.go @@ -68,8 +68,9 @@ func validNewPod() *api.Pod { Image: "test", ImagePullPolicy: api.PullAlways, - TerminationMessagePath: api.TerminationMessagePathDefault, - SecurityContext: securitycontext.ValidInternalSecurityContextWithContainerDefaults(), + TerminationMessagePath: api.TerminationMessagePathDefault, + TerminationMessagePolicy: api.TerminationMessageReadFile, + SecurityContext: securitycontext.ValidInternalSecurityContextWithContainerDefaults(), }, }, SecurityContext: &api.PodSecurityContext{}, @@ -678,11 +679,12 @@ func TestEtcdUpdateScheduled(t *testing.T) { Spec: api.PodSpec{ NodeName: "machine", Containers: []api.Container{{ - Name: "foobar", - Image: "foo:v2", - ImagePullPolicy: api.PullIfNotPresent, - TerminationMessagePath: api.TerminationMessagePathDefault, - SecurityContext: securitycontext.ValidInternalSecurityContextWithContainerDefaults(), + Name: "foobar", + Image: "foo:v2", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePath: api.TerminationMessagePathDefault, + TerminationMessagePolicy: api.TerminationMessageReadFile, + SecurityContext: securitycontext.ValidInternalSecurityContextWithContainerDefaults(), }}, RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, @@ -772,6 +774,7 @@ func TestEtcdUpdateStatus(t *testing.T) { expected.Spec.DNSPolicy = api.DNSClusterFirst expected.Spec.Containers[0].ImagePullPolicy = api.PullIfNotPresent expected.Spec.Containers[0].TerminationMessagePath = api.TerminationMessagePathDefault + expected.Spec.Containers[0].TerminationMessagePolicy = api.TerminationMessageReadFile expected.Labels = podIn.Labels expected.Status = podIn.Status diff --git a/pkg/registry/core/podtemplate/storage/storage_test.go b/pkg/registry/core/podtemplate/storage/storage_test.go index 799052586e..5116399c32 100644 --- a/pkg/registry/core/podtemplate/storage/storage_test.go +++ b/pkg/registry/core/podtemplate/storage/storage_test.go @@ -59,7 +59,8 @@ func validNewPodTemplate(name string) *api.PodTemplate { Image: "test", ImagePullPolicy: api.PullAlways, - TerminationMessagePath: api.TerminationMessagePathDefault, + TerminationMessagePath: api.TerminationMessagePathDefault, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, }, diff --git a/pkg/registry/extensions/daemonset/storage/storage_test.go b/pkg/registry/extensions/daemonset/storage/storage_test.go index 04946bfd74..0d2de6aad0 100644 --- a/pkg/registry/extensions/daemonset/storage/storage_test.go +++ b/pkg/registry/extensions/daemonset/storage/storage_test.go @@ -57,9 +57,10 @@ func newValidDaemonSet() *extensions.DaemonSet { Spec: api.PodSpec{ Containers: []api.Container{ { - Name: "test", - Image: "test_image", - ImagePullPolicy: api.PullIfNotPresent, + Name: "test", + Image: "test_image", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, RestartPolicy: api.RestartPolicyAlways, diff --git a/pkg/registry/extensions/deployment/storage/storage_test.go b/pkg/registry/extensions/deployment/storage/storage_test.go index e9b97528a1..c60dca5195 100644 --- a/pkg/registry/extensions/deployment/storage/storage_test.go +++ b/pkg/registry/extensions/deployment/storage/storage_test.go @@ -71,9 +71,10 @@ func validNewDeployment() *extensions.Deployment { Spec: api.PodSpec{ Containers: []api.Container{ { - Name: "test", - Image: "test_image", - ImagePullPolicy: api.PullIfNotPresent, + Name: "test", + Image: "test_image", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, RestartPolicy: api.RestartPolicyAlways, diff --git a/pkg/registry/extensions/replicaset/storage/storage_test.go b/pkg/registry/extensions/replicaset/storage/storage_test.go index efd3347a15..3b49b56704 100644 --- a/pkg/registry/extensions/replicaset/storage/storage_test.go +++ b/pkg/registry/extensions/replicaset/storage/storage_test.go @@ -69,9 +69,10 @@ func validNewReplicaSet() *extensions.ReplicaSet { Spec: api.PodSpec{ Containers: []api.Container{ { - Name: "test", - Image: "test_image", - ImagePullPolicy: api.PullIfNotPresent, + Name: "test", + Image: "test_image", + ImagePullPolicy: api.PullIfNotPresent, + TerminationMessagePolicy: api.TerminationMessageReadFile, }, }, RestartPolicy: api.RestartPolicyAlways, diff --git a/pkg/registry/extensions/replicaset/strategy_test.go b/pkg/registry/extensions/replicaset/strategy_test.go index 927a9a2860..fa611df088 100644 --- a/pkg/registry/extensions/replicaset/strategy_test.go +++ b/pkg/registry/extensions/replicaset/strategy_test.go @@ -43,7 +43,7 @@ func TestReplicaSetStrategy(t *testing.T) { Spec: api.PodSpec{ RestartPolicy: api.RestartPolicyAlways, DNSPolicy: api.DNSClusterFirst, - Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}}, + Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, }, }, } diff --git a/pkg/util/BUILD b/pkg/util/BUILD index 78e2d8ea05..45dbcf9c24 100644 --- a/pkg/util/BUILD +++ b/pkg/util/BUILD @@ -97,6 +97,7 @@ filegroup( "//pkg/util/strings:all-srcs", "//pkg/util/sysctl:all-srcs", "//pkg/util/system:all-srcs", + "//pkg/util/tail:all-srcs", "//pkg/util/taints:all-srcs", "//pkg/util/term:all-srcs", "//pkg/util/threading:all-srcs", diff --git a/pkg/util/tail/BUILD b/pkg/util/tail/BUILD new file mode 100644 index 0000000000..5d7a1b54c4 --- /dev/null +++ b/pkg/util/tail/BUILD @@ -0,0 +1,35 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", + "go_test", +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) + +go_test( + name = "go_default_test", + srcs = ["tail_test.go"], + library = ":go_default_library", + tags = ["automanaged"], +) + +go_library( + name = "go_default_library", + srcs = ["tail.go"], + tags = ["automanaged"], +) diff --git a/pkg/util/tail/tail.go b/pkg/util/tail/tail.go new file mode 100644 index 0000000000..23ad4ae791 --- /dev/null +++ b/pkg/util/tail/tail.go @@ -0,0 +1,99 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tail + +import ( + "bytes" + "io" + "io/ioutil" + "os" +) + +const ( + // blockSize is the block size used in tail. + blockSize = 1024 +) + +var ( + // eol is the end-of-line sign in the log. + eol = []byte{'\n'} +) + +// ReadAtMost reads at most max bytes from the end of the file identified by path or +// returns an error. It returns true if the file was longer than max. It will +// allocate up to max bytes. +func ReadAtMost(path string, max int64) ([]byte, bool, error) { + f, err := os.Open(path) + if err != nil { + return nil, false, err + } + defer f.Close() + fi, err := f.Stat() + if err != nil { + return nil, false, err + } + size := fi.Size() + if size == 0 { + return nil, false, nil + } + if size < max { + max = size + } + offset, err := f.Seek(-max, os.SEEK_END) + if err != nil { + return nil, false, err + } + data, err := ioutil.ReadAll(f) + return data, offset > 0, err +} + +// FindTailLineStartIndex returns the start of last nth line. +// * If n < 0, return the beginning of the file. +// * If n >= 0, return the beginning of last nth line. +// Notice that if the last line is incomplete (no end-of-line), it will not be counted +// as one line. +func FindTailLineStartIndex(f io.ReadSeeker, n int64) (int64, error) { + if n < 0 { + return 0, nil + } + size, err := f.Seek(0, os.SEEK_END) + if err != nil { + return 0, err + } + var left, cnt int64 + buf := make([]byte, blockSize) + for right := size; right > 0 && cnt <= n; right -= blockSize { + left = right - blockSize + if left < 0 { + left = 0 + buf = make([]byte, right) + } + if _, err := f.Seek(left, os.SEEK_SET); err != nil { + return 0, err + } + if _, err := f.Read(buf); err != nil { + return 0, err + } + cnt += int64(bytes.Count(buf, eol)) + } + for ; cnt > n; cnt-- { + idx := bytes.Index(buf, eol) + 1 + buf = buf[idx:] + left += int64(idx) + } + return left, nil +} diff --git a/pkg/util/tail/tail_test.go b/pkg/util/tail/tail_test.go new file mode 100644 index 0000000000..18d3f90c21 --- /dev/null +++ b/pkg/util/tail/tail_test.go @@ -0,0 +1,52 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tail + +import ( + "bytes" + "strings" + "testing" +) + +func TestTail(t *testing.T) { + line := strings.Repeat("a", blockSize) + testBytes := []byte(line + "\n" + + line + "\n" + + line + "\n" + + line + "\n" + + line[blockSize/2:]) // incomplete line + + for c, test := range []struct { + n int64 + start int64 + }{ + {n: -1, start: 0}, + {n: 0, start: int64(len(line)+1) * 4}, + {n: 1, start: int64(len(line)+1) * 3}, + {n: 9999, start: 0}, + } { + t.Logf("TestCase #%d: %+v", c, test) + r := bytes.NewReader(testBytes) + s, err := FindTailLineStartIndex(r, test.n) + if err != nil { + t.Error(err) + } + if s != test.start { + t.Errorf("%d != %d", s, test.start) + } + } +} diff --git a/test/e2e_node/runtime_conformance_test.go b/test/e2e_node/runtime_conformance_test.go index b9aa852a15..1e3471e31a 100644 --- a/test/e2e_node/runtime_conformance_test.go +++ b/test/e2e_node/runtime_conformance_test.go @@ -28,6 +28,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + gomegatypes "github.com/onsi/gomega/types" ) const ( @@ -128,46 +129,112 @@ while true; do sleep 1; done } }) - It("should report termination message if TerminationMessagePath is set [Conformance]", func() { - name := "termination-message-container" - terminationMessage := "DONE" - terminationMessagePath := "/dev/termination-log" - priv := true - c := ConformanceContainer{ - PodClient: f.PodClient(), - Container: v1.Container{ + rootUser := int64(0) + nonRootUser := int64(10000) + for _, testCase := range []struct { + name string + container v1.Container + phase v1.PodPhase + message gomegatypes.GomegaMatcher + }{ + { + name: "if TerminationMessagePath is set [Conformance]", + container: v1.Container{ Image: "gcr.io/google_containers/busybox:1.24", - Name: name, Command: []string{"/bin/sh", "-c"}, - Args: []string{fmt.Sprintf("/bin/echo -n %s > %s", terminationMessage, terminationMessagePath)}, - TerminationMessagePath: terminationMessagePath, + Args: []string{"/bin/echo -n DONE > /dev/termination-log"}, + TerminationMessagePath: "/dev/termination-log", SecurityContext: &v1.SecurityContext{ - Privileged: &priv, + RunAsUser: &rootUser, }, }, - RestartPolicy: v1.RestartPolicyNever, - } + phase: v1.PodSucceeded, + message: Equal("DONE"), + }, - By("create the container") - c.Create() - defer c.Delete() + { + name: "if TerminationMessagePath is set as non-root user and at a non-default path [Conformance]", + container: v1.Container{ + Image: "gcr.io/google_containers/busybox:1.24", + Command: []string{"/bin/sh", "-c"}, + Args: []string{"/bin/echo -n DONE > /dev/termination-custom-log"}, + TerminationMessagePath: "/dev/termination-custom-log", + SecurityContext: &v1.SecurityContext{ + RunAsUser: &nonRootUser, + }, + }, + phase: v1.PodSucceeded, + message: Equal("DONE"), + }, - By("wait for the container to succeed") - Eventually(c.GetPhase, retryTimeout, pollInterval).Should(Equal(v1.PodSucceeded)) + { + name: "from log output if TerminationMessagePolicy FallbackToLogOnError is set [Conformance]", + container: v1.Container{ + Image: "gcr.io/google_containers/busybox:1.24", + Command: []string{"/bin/sh", "-c"}, + Args: []string{"/bin/echo -n DONE; /bin/false"}, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError, + }, + phase: v1.PodFailed, + message: Equal("DONE\n"), + }, - By("get the container status") - status, err := c.GetStatus() - Expect(err).NotTo(HaveOccurred()) + { + name: "as empty when pod succeeds and TerminationMessagePolicy FallbackToLogOnError is set", + container: v1.Container{ + Image: "gcr.io/google_containers/busybox:1.24", + Command: []string{"/bin/sh", "-c"}, + Args: []string{"/bin/echo DONE; /bin/true"}, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError, + }, + phase: v1.PodSucceeded, + message: Equal(""), + }, - By("the container should be terminated") - Expect(GetContainerState(status.State)).To(Equal(ContainerStateTerminated)) + { + name: "from file when pod succeeds and TerminationMessagePolicy FallbackToLogOnError is set [Conformance]", + container: v1.Container{ + Image: "gcr.io/google_containers/busybox:1.24", + Command: []string{"/bin/sh", "-c"}, + Args: []string{"/bin/echo -n OK > /dev/termination-log; /bin/echo DONE; /bin/true"}, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: v1.TerminationMessageFallbackToLogsOnError, + }, + phase: v1.PodSucceeded, + message: Equal("OK"), + }, + } { + It(fmt.Sprintf("should report termination message %s", testCase.name), func() { + testCase.container.Name = "termination-message-container" + c := ConformanceContainer{ + PodClient: f.PodClient(), + Container: testCase.container, + RestartPolicy: v1.RestartPolicyNever, + } - By("the termination message should be set") - Expect(status.State.Terminated.Message).Should(Equal(terminationMessage)) + By("create the container") + c.Create() + defer c.Delete() - By("delete the container") - Expect(c.Delete()).To(Succeed()) - }) + By(fmt.Sprintf("wait for the container to reach %s", testCase.phase)) + Eventually(c.GetPhase, retryTimeout, pollInterval).Should(Equal(testCase.phase)) + + By("get the container status") + status, err := c.GetStatus() + Expect(err).NotTo(HaveOccurred()) + + By("the container should be terminated") + Expect(GetContainerState(status.State)).To(Equal(ContainerStateTerminated)) + + By("the termination message should be set") + Expect(status.State.Terminated.Message).Should(testCase.message) + + By("delete the container") + Expect(c.Delete()).To(Succeed()) + }) + } }) Context("when running a container with a new image", func() { diff --git a/vendor/BUILD b/vendor/BUILD index cadadb315d..037217c856 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -13718,3 +13718,9 @@ go_library( srcs = ["k8s.io/client-go/third_party/forked/golang/netutil/addr.go"], tags = ["automanaged"], ) + +go_library( + name = "github.com/armon/circbuf", + srcs = ["github.com/armon/circbuf/circbuf.go"], + tags = ["automanaged"], +) diff --git a/vendor/github.com/armon/circbuf/.gitignore b/vendor/github.com/armon/circbuf/.gitignore new file mode 100755 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/armon/circbuf/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/armon/circbuf/LICENSE b/vendor/github.com/armon/circbuf/LICENSE new file mode 100755 index 0000000000..106569e542 --- /dev/null +++ b/vendor/github.com/armon/circbuf/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Armon Dadgar + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/armon/circbuf/README.md b/vendor/github.com/armon/circbuf/README.md new file mode 100644 index 0000000000..f2e356b8d7 --- /dev/null +++ b/vendor/github.com/armon/circbuf/README.md @@ -0,0 +1,28 @@ +circbuf +======= + +This repository provides the `circbuf` package. This provides a `Buffer` object +which is a circular (or ring) buffer. It has a fixed size, but can be written +to infinitely. Only the last `size` bytes are ever retained. The buffer implements +the `io.Writer` interface. + +Documentation +============= + +Full documentation can be found on [Godoc](http://godoc.org/github.com/armon/circbuf) + +Usage +===== + +The `circbuf` package is very easy to use: + +```go +buf, _ := NewBuffer(6) +buf.Write([]byte("hello world")) + +if string(buf.Bytes()) != " world" { + panic("should only have last 6 bytes!") +} + +``` + diff --git a/vendor/github.com/armon/circbuf/circbuf.go b/vendor/github.com/armon/circbuf/circbuf.go new file mode 100644 index 0000000000..de3cb94a39 --- /dev/null +++ b/vendor/github.com/armon/circbuf/circbuf.go @@ -0,0 +1,92 @@ +package circbuf + +import ( + "fmt" +) + +// Buffer implements a circular buffer. It is a fixed size, +// and new writes overwrite older data, such that for a buffer +// of size N, for any amount of writes, only the last N bytes +// are retained. +type Buffer struct { + data []byte + size int64 + writeCursor int64 + written int64 +} + +// NewBuffer creates a new buffer of a given size. The size +// must be greater than 0. +func NewBuffer(size int64) (*Buffer, error) { + if size <= 0 { + return nil, fmt.Errorf("Size must be positive") + } + + b := &Buffer{ + size: size, + data: make([]byte, size), + } + return b, nil +} + +// Write writes up to len(buf) bytes to the internal ring, +// overriding older data if necessary. +func (b *Buffer) Write(buf []byte) (int, error) { + // Account for total bytes written + n := len(buf) + b.written += int64(n) + + // If the buffer is larger than ours, then we only care + // about the last size bytes anyways + if int64(n) > b.size { + buf = buf[int64(n)-b.size:] + } + + // Copy in place + remain := b.size - b.writeCursor + copy(b.data[b.writeCursor:], buf) + if int64(len(buf)) > remain { + copy(b.data, buf[remain:]) + } + + // Update location of the cursor + b.writeCursor = ((b.writeCursor + int64(len(buf))) % b.size) + return n, nil +} + +// Size returns the size of the buffer +func (b *Buffer) Size() int64 { + return b.size +} + +// TotalWritten provides the total number of bytes written +func (b *Buffer) TotalWritten() int64 { + return b.written +} + +// Bytes provides a slice of the bytes written. This +// slice should not be written to. +func (b *Buffer) Bytes() []byte { + switch { + case b.written >= b.size && b.writeCursor == 0: + return b.data + case b.written > b.size: + out := make([]byte, b.size) + copy(out, b.data[b.writeCursor:]) + copy(out[b.size-b.writeCursor:], b.data[:b.writeCursor]) + return out + default: + return b.data[:b.writeCursor] + } +} + +// Reset resets the buffer so it has no content. +func (b *Buffer) Reset() { + b.writeCursor = 0 + b.written = 0 +} + +// String returns the contents of the buffer as a string +func (b *Buffer) String() string { + return string(b.Bytes()) +}