diff --git a/api/json-schema/schema.json b/api/json-schema/schema.json index 9669aa913d..23386c6a7a 100644 --- a/api/json-schema/schema.json +++ b/api/json-schema/schema.json @@ -21298,6 +21298,10 @@ "source": { "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Source" }, + "streaming": { + "description": "Streaming enables per-message, out-of-order source acknowledgement instead of the default whole-batch barrier. When true, the source reads continuously bounded by `spec.limits.concurrency` (in-flight messages) rather than one batch at a time. This is off by default.", + "type": "boolean" + }, "tolerations": { "description": "If specified, the pod's tolerations.", "items": { diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 09d5aaf9fd..2309491a4e 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -21294,6 +21294,10 @@ "source": { "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Source" }, + "streaming": { + "description": "Streaming enables per-message, out-of-order source acknowledgement instead of the default whole-batch barrier. When true, the source reads continuously bounded by `spec.limits.concurrency` (in-flight messages) rather than one batch at a time. This is off by default.", + "type": "boolean" + }, "tolerations": { "description": "If specified, the pod's tolerations.", "type": "array", diff --git a/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml b/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml index 939df7e26b..05d1deb826 100644 --- a/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml +++ b/config/base/crds/full/numaflow.numaproj.io_monovertices.yaml @@ -6986,6 +6986,8 @@ spec: - container type: object type: object + streaming: + type: boolean tolerations: items: properties: diff --git a/config/install.yaml b/config/install.yaml index 7a8d7a39bc..1c259bab00 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -8512,6 +8512,8 @@ spec: - container type: object type: object + streaming: + type: boolean tolerations: items: properties: diff --git a/config/namespace-install.yaml b/config/namespace-install.yaml index e23495e61b..bf5af122f4 100644 --- a/config/namespace-install.yaml +++ b/config/namespace-install.yaml @@ -8512,6 +8512,8 @@ spec: - container type: object type: object + streaming: + type: boolean tolerations: items: properties: diff --git a/docs/APIs.md b/docs/APIs.md index 88ab9abee3..1baf9a9f1c 100644 --- a/docs/APIs.md +++ b/docs/APIs.md @@ -6381,6 +6381,28 @@ trigger the said bypass. + + + + +streaming
bool + + + + +(Optional) +

+ +Streaming enables per-message, out-of-order source acknowledgement +instead of the default whole-batch barrier. When true, the source reads +continuously bounded by spec.limits.concurrency (in-flight +messages) rather than one batch at a time. This is off by default. +

+ + + + + @@ -7063,6 +7085,28 @@ trigger the said bypass. + + + + +streaming
bool + + + + +(Optional) +

+ +Streaming enables per-message, out-of-order source acknowledgement +instead of the default whole-batch barrier. When true, the source reads +continuously bounded by spec.limits.concurrency (in-flight +messages) rather than one batch at a time. This is off by default. +

+ + + + + diff --git a/docs/user-guide/reference/mvtx-streaming.md b/docs/user-guide/reference/mvtx-streaming.md new file mode 100644 index 0000000000..9169598f64 --- /dev/null +++ b/docs/user-guide/reference/mvtx-streaming.md @@ -0,0 +1,171 @@ +# MonoVertex Streaming Mode + +> **Opt-in, off by default.** +> Streaming mode makes the **source side** fully per-message. +> The sink still micro-batches, in a follow-up PR will complete the sink side. + +## Overview + +By default, a MonoVertex advances **one batch at a time**: it reads up to +`readBatchSize` messages, waits for the entire batch to finish processing and be +acknowledged by the sink, then reads the next batch. + +Setting `spec.streaming: true` switches the source side to **per-message, +continuous reading**: + +- Messages are read and acknowledged individually rather than as a whole batch. +- Reading continues without waiting for a batch boundary — new messages are + admitted as soon as an in-flight slot becomes free. +- The number of in-flight (read-but-unacked) messages is bounded by + `spec.limits.concurrency`. + +This eliminates the source-side micro-batching stall and allows the pipeline to +stay full up to the `concurrency` ceiling rather than draining a complete batch +before proceeding. + +### What changes in PR1 + +| Aspect | Default (batch) mode | Streaming mode | +|---------------|-----------------------------------|---------------------------| +| Source read | Whole batch, then wait | Continuous, per-message | +| Source ack | One batched ack per batch | Per-message, out-of-order | +| Sink write | Micro-batched | Micro-batched (currently) | +| In-flight cap | `min(concurrency, readBatchSize)` | `concurrency` (see below) | + +## Enabling streaming mode + +Add `streaming: true` under the MonoVertex spec: + +```yaml +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + name: my-mvtx +spec: + streaming: true + limits: + concurrency: 200 + source: + # ... + sink: + # ... +``` + +## Guarantees + +- **At-least-once delivery.** A message is acknowledged at the source only after + its terminal disposition (sink write) succeeds. On failure or crash, unacked + messages are redelivered. +- **No ordering guarantee.** Messages are processed concurrently and may be + acknowledged out of order. This matches the existing behavior of concurrent + unary map inside a MonoVertex. +- **Backpressure cap = `spec.limits.concurrency`.** When all `concurrency` slots + are occupied the data plane stops reading until a slot frees up. + +## In-flight ceiling semantics + +The data plane targets a maximum of `concurrency` messages in flight at any +instant. Because reads happen in batches at the source level (up to +`readBatchSize` messages per read call), there is a transient over-read of at +most one `readBatchSize` before the cap takes effect. The practical peak +in-flight count is therefore approximately: + +``` +peak in-flight ≈ concurrency + readBatchSize +``` + +Set `readBatchSize` low (e.g., `1`) if you need a hard ceiling, or rely on +`concurrency` alone for a soft cap with a one-batch overshoot. + +See [MonoVertex Tuning](./mvtx-tuning.md) for full documentation of `concurrency` +and `readBatchSize`. + +## Source compatibility + +Streaming mode uses **per-message, out-of-order acking** at the source. Sources +whose ack API commits offsets cumulatively (highest-seen + 1) are **not safe** +under this model: a crash after acking a later message but before acking an +earlier one can permanently skip the earlier message. + +| Source | Ack model | Compatible with `streaming: true`? | +|---------------------|------------------------------------------|---------------------------------------------------------------------| +| Built-in Kafka | Cumulative commit (`highest_offset + 1`) | **No — rejected at validation time** (see warning below) | +| Built-in Pulsar | Individual `ack_with_id` | Yes — see [Pulsar constraint](#pulsar-concurrency-constraint) below | +| Built-in JetStream | Per-message | Yes | +| Built-in SQS | Per-message | Yes | +| Built-in Generator | Per-message | Yes | +| User-defined source | Depends on implementation | **User's responsibility** (see note below) | + +> **Note — User-defined sources:** A UD-source that wraps a cumulative-commit +> system (such as a Kafka consumer library) has the same data-loss risk as the +> built-in Kafka source. Do **not** enable `streaming: true` if your UD-source +> commits offsets cumulatively. The validation gate only covers the built-in +> Kafka source; UD-source compatibility cannot be detected automatically. + +--- + +> **Warning — Kafka data loss** +> +> **Do not use `streaming: true` with the built-in Kafka source.** +> +> The built-in Kafka source commits offsets cumulatively: it always commits +> `highest_acked_offset + 1`. Under per-message, out-of-order acking, a later +> offset can be acked (and committed) before an earlier offset is acked. If the +> pod crashes at that point, the committed offset causes the earlier, un-acked +> message to be **silently skipped** — resulting in **message loss** with no +> error or warning. +> +> **Numaflow rejects this combination at validation time.** A MonoVertex spec +> with both `streaming: true` and a built-in Kafka source will fail admission +> with an explicit validation error. You must remove one or the other before the +> resource can be created or updated. + +--- + +## Pulsar concurrency constraint + +The built-in Pulsar source tracks unacknowledged messages using a Pulsar +`MaxUnacknowledgedMessages` policy. This is configured on the Pulsar source via +the `maxUnack` CRD field (default **1000**). + +When `streaming: true` is enabled and `spec.limits.concurrency` exceeds +`maxUnack`, the Pulsar broker raises an `AckPendingExceeded` error and the +source stops delivering messages. + +**Operator constraint (not enforced at runtime in PR1):** Keep +`spec.limits.concurrency` ≤ the Pulsar source's `maxUnack`. Example: + +```yaml +spec: + streaming: true + limits: + concurrency: 800 # must be <= pulsar source maxUnack (default 1000) + source: + pulsar: + maxUnack: 1000 + # ... +``` + +No other built-in source has an equivalent cap. This constraint is +Pulsar-specific. + +## Example spec + +```yaml +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + name: streaming-mvtx +spec: + streaming: true + limits: + readBatchSize: 50 + concurrency: 200 + source: + jetstream: + # ... + sink: + udsink: + container: + image: my-sink:latest +``` diff --git a/mkdocs.yml b/mkdocs.yml index 60136a9c11..7e5d7bd0c7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -119,6 +119,7 @@ nav: - user-guide/reference/side-inputs.md - user-guide/reference/mvtx-tuning.md - user-guide/reference/mvtx-operations.md + - "MonoVertex Streaming Mode": user-guide/reference/mvtx-streaming.md - user-guide/reference/distributed-throttling.md - user-guide/reference/monovertex-bypass.md - Configuration: diff --git a/pkg/apis/numaflow/v1alpha1/generated.pb.go b/pkg/apis/numaflow/v1alpha1/generated.pb.go index c3fa64084e..c5dee4d4e4 100644 --- a/pkg/apis/numaflow/v1alpha1/generated.pb.go +++ b/pkg/apis/numaflow/v1alpha1/generated.pb.go @@ -3602,607 +3602,608 @@ func init() { } var fileDescriptor_9d0d1b17d3865563 = []byte{ - // 9600 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5b, 0x8c, 0x1c, 0x57, - 0x76, 0xd8, 0xf6, 0xbb, 0xfb, 0xf4, 0x3c, 0xc8, 0x4b, 0x8a, 0x1a, 0x72, 0x29, 0x0e, 0x5d, 0xb2, - 0x64, 0x6d, 0x56, 0x9e, 0x09, 0xb9, 0x92, 0x56, 0xbb, 0x5a, 0xad, 0xd4, 0x3d, 0xc3, 0x21, 0x47, - 0x9c, 0xe1, 0x8c, 0x4e, 0xcf, 0x90, 0xda, 0x55, 0x76, 0x95, 0x9a, 0xea, 0x3b, 0x3d, 0xa5, 0xa9, - 0xae, 0x6a, 0x56, 0x55, 0x0f, 0x39, 0x72, 0x04, 0xad, 0x6d, 0x38, 0x5a, 0x27, 0x06, 0x12, 0x24, - 0x08, 0x6c, 0x24, 0x08, 0x0c, 0x03, 0x06, 0xfc, 0x11, 0x18, 0x08, 0x92, 0xd8, 0x1f, 0x36, 0x90, - 0xc7, 0x7e, 0x38, 0x8b, 0x78, 0x1d, 0x6f, 0x36, 0x01, 0xb2, 0x41, 0x92, 0x49, 0x76, 0x92, 0x7c, - 0x24, 0x5f, 0x8e, 0x91, 0x27, 0x13, 0xc4, 0xc1, 0x7d, 0xd5, 0xab, 0xab, 0xa9, 0x99, 0xae, 0xe6, - 0x88, 0xb2, 0xf5, 0xd5, 0x5d, 0xe7, 0x9c, 0x7b, 0xce, 0xad, 0x5b, 0xf7, 0x71, 0xee, 0x39, 0xe7, - 0x9e, 0x0b, 0xd7, 0x3b, 0xa6, 0xbf, 0xd3, 0xdf, 0x9a, 0x33, 0x9c, 0xee, 0xbc, 0xdd, 0xef, 0xea, - 0x3d, 0xd7, 0x79, 0x97, 0xff, 0xd9, 0xb6, 0x9c, 0x7b, 0xf3, 0xbd, 0xdd, 0xce, 0xbc, 0xde, 0x33, - 0xbd, 0x10, 0xb2, 0x77, 0x45, 0xb7, 0x7a, 0x3b, 0xfa, 0x95, 0xf9, 0x0e, 0xb5, 0xa9, 0xab, 0xfb, - 0xb4, 0x3d, 0xd7, 0x73, 0x1d, 0xdf, 0x21, 0x5f, 0x0c, 0x19, 0xcd, 0x29, 0x46, 0x73, 0xaa, 0xd8, - 0x5c, 0x6f, 0xb7, 0x33, 0xc7, 0x18, 0x85, 0x10, 0xc5, 0xe8, 0xc2, 0x4f, 0x46, 0x6a, 0xd0, 0x71, - 0x3a, 0xce, 0x3c, 0xe7, 0xb7, 0xd5, 0xdf, 0xe6, 0x4f, 0xfc, 0x81, 0xff, 0x13, 0x72, 0x2e, 0x68, - 0xbb, 0x2f, 0x7b, 0x73, 0xa6, 0xc3, 0xaa, 0x35, 0x6f, 0x38, 0x2e, 0x9d, 0xdf, 0x1b, 0xa8, 0xcb, - 0x85, 0x17, 0x42, 0x9a, 0xae, 0x6e, 0xec, 0x98, 0x36, 0x75, 0xf7, 0xd5, 0xbb, 0xcc, 0xbb, 0xd4, - 0x73, 0xfa, 0xae, 0x41, 0x8f, 0x55, 0xca, 0x9b, 0xef, 0x52, 0x5f, 0x4f, 0x93, 0x35, 0x3f, 0xac, - 0x94, 0xdb, 0xb7, 0x7d, 0xb3, 0x3b, 0x28, 0xe6, 0xa5, 0x8f, 0x2a, 0xe0, 0x19, 0x3b, 0xb4, 0xab, - 0x0f, 0x94, 0xfb, 0xc2, 0xb0, 0x72, 0x7d, 0xdf, 0xb4, 0xe6, 0x4d, 0xdb, 0xf7, 0x7c, 0x37, 0x59, - 0x48, 0xfb, 0xdb, 0x79, 0x98, 0x6c, 0xdc, 0x69, 0x35, 0x3c, 0xaf, 0xdf, 0xa5, 0xe8, 0x58, 0x94, - 0x7c, 0x0e, 0x2a, 0xae, 0x63, 0xd1, 0x86, 0x6b, 0xcf, 0xe4, 0x2e, 0xe7, 0x9e, 0xab, 0x35, 0xa7, - 0xbf, 0x7b, 0x30, 0xfb, 0x99, 0xc3, 0x83, 0xd9, 0x0a, 0x43, 0x37, 0xf0, 0x16, 0x2a, 0x3c, 0xb9, - 0x02, 0x75, 0x8f, 0x7a, 0x9e, 0xe9, 0xd8, 0xb7, 0xf4, 0x2e, 0x9d, 0xc9, 0x0b, 0xf2, 0xc3, 0x83, - 0xd9, 0x7a, 0x2b, 0x04, 0x63, 0x94, 0x86, 0xbc, 0x0a, 0xd3, 0xed, 0xbe, 0xab, 0xfb, 0xa6, 0x63, - 0xb7, 0xa8, 0xe1, 0xd8, 0x6d, 0x6f, 0xa6, 0x70, 0x39, 0xf7, 0x5c, 0xa9, 0x79, 0xe6, 0xf0, 0x60, - 0x76, 0x7a, 0x31, 0x8e, 0xc2, 0x24, 0x2d, 0x99, 0x03, 0xa0, 0xf7, 0x7d, 0xea, 0xda, 0xba, 0xb5, - 0xbc, 0x38, 0x53, 0xe4, 0x02, 0xa7, 0x0e, 0x0f, 0x66, 0xe1, 0x5a, 0x00, 0xc5, 0x08, 0x05, 0xd1, - 0xa0, 0xdc, 0x73, 0x2c, 0xd3, 0xd8, 0x9f, 0x29, 0x71, 0x5a, 0x38, 0x3c, 0x98, 0x2d, 0xaf, 0x73, - 0x08, 0x4a, 0x0c, 0xe3, 0x29, 0xfe, 0x35, 0x5c, 0xdb, 0x9b, 0x29, 0x5f, 0x2e, 0x28, 0x9e, 0x82, - 0xae, 0x81, 0xb7, 0x3c, 0x8c, 0x50, 0x68, 0xff, 0x08, 0xe0, 0x4c, 0x63, 0xcb, 0xf3, 0x5d, 0xdd, - 0xf0, 0xd7, 0x9d, 0xf6, 0x06, 0xed, 0xf6, 0x2c, 0xdd, 0xa7, 0x64, 0x17, 0xaa, 0xac, 0x0f, 0xb4, - 0x75, 0x5f, 0xe7, 0x2d, 0x57, 0xbf, 0xda, 0x98, 0x1b, 0xb1, 0xcf, 0xcf, 0xad, 0x4a, 0x46, 0xcd, - 0x89, 0xc3, 0x83, 0xd9, 0xaa, 0x7a, 0xc2, 0x40, 0x00, 0xf9, 0xa5, 0x1c, 0x4c, 0xd8, 0x4e, 0x9b, - 0xb6, 0xa8, 0x45, 0x0d, 0xdf, 0x71, 0x67, 0xf2, 0x97, 0x0b, 0xcf, 0xd5, 0xaf, 0x7e, 0x73, 0x64, - 0x89, 0x29, 0x6f, 0x34, 0x77, 0x2b, 0x22, 0xe0, 0x9a, 0xed, 0xbb, 0xfb, 0xcd, 0xb3, 0xb2, 0x2f, - 0x4c, 0x44, 0x51, 0x18, 0xab, 0x09, 0xd9, 0x84, 0xba, 0xef, 0x58, 0x54, 0x7c, 0x38, 0xf6, 0x79, - 0x59, 0xc5, 0x2e, 0xcd, 0x89, 0xde, 0xc9, 0xc4, 0xcf, 0xb1, 0x61, 0x39, 0xb7, 0x77, 0x65, 0x6e, - 0x23, 0x20, 0x6b, 0x9e, 0x91, 0x8c, 0xeb, 0x21, 0xcc, 0xc3, 0x28, 0x1f, 0x42, 0x61, 0xda, 0xa3, - 0x46, 0xdf, 0x35, 0xfd, 0xfd, 0x05, 0xc7, 0xf6, 0xe9, 0x7d, 0x9f, 0x7f, 0xff, 0xfa, 0xd5, 0x67, - 0xd3, 0x58, 0xaf, 0x3b, 0xed, 0x56, 0x9c, 0x5a, 0xf4, 0xb0, 0x04, 0x10, 0x93, 0x3c, 0x89, 0x0d, - 0xa7, 0xcc, 0xae, 0xde, 0xa1, 0xeb, 0x7d, 0xcb, 0x6a, 0x51, 0xc3, 0xa5, 0xbe, 0x37, 0x53, 0xe2, - 0xaf, 0xf0, 0x5c, 0x9a, 0x9c, 0x15, 0xc7, 0xd0, 0xad, 0xb5, 0xad, 0x77, 0xa9, 0xe1, 0x23, 0xdd, - 0xa6, 0x2e, 0xb5, 0x0d, 0xda, 0x9c, 0x91, 0x2f, 0x73, 0x6a, 0x39, 0xc1, 0x09, 0x07, 0x78, 0x93, - 0xeb, 0x70, 0xba, 0xe7, 0x9a, 0x0e, 0xaf, 0x82, 0xa5, 0x7b, 0x1e, 0x1f, 0x49, 0x65, 0xde, 0x59, - 0xcf, 0x4b, 0x36, 0xa7, 0xd7, 0x93, 0x04, 0x38, 0x58, 0x86, 0x3c, 0x07, 0x55, 0x05, 0x9c, 0xa9, - 0xf0, 0x21, 0xc5, 0xfb, 0x8e, 0x2a, 0x8b, 0x01, 0x96, 0x2c, 0x41, 0x55, 0xdf, 0xde, 0x36, 0x6d, - 0x46, 0x59, 0xe5, 0x4d, 0x78, 0x31, 0xed, 0xd5, 0x1a, 0x92, 0x46, 0xf0, 0x51, 0x4f, 0x18, 0x94, - 0x25, 0x6f, 0x00, 0xf1, 0xa8, 0xbb, 0x67, 0x1a, 0xb4, 0x61, 0x18, 0x4e, 0xdf, 0xf6, 0x79, 0xdd, - 0x6b, 0xbc, 0xee, 0x17, 0x64, 0xdd, 0x49, 0x6b, 0x80, 0x02, 0x53, 0x4a, 0x91, 0xd7, 0xe1, 0x94, - 0x9c, 0xde, 0xc2, 0x56, 0x00, 0xce, 0xe9, 0x2c, 0x6b, 0x48, 0x4c, 0xe0, 0x70, 0x80, 0x9a, 0xb4, - 0xe1, 0xa2, 0xde, 0xf7, 0x9d, 0x2e, 0x63, 0x19, 0x17, 0xba, 0xe1, 0xec, 0x52, 0x7b, 0xa6, 0x7e, - 0x39, 0xf7, 0x5c, 0xb5, 0x79, 0xf9, 0xf0, 0x60, 0xf6, 0x62, 0xe3, 0x21, 0x74, 0xf8, 0x50, 0x2e, - 0x64, 0x0d, 0x6a, 0x6d, 0xdb, 0x13, 0x33, 0xc3, 0xcc, 0x04, 0xaf, 0xe0, 0x15, 0xf9, 0xaa, 0xb5, - 0xc5, 0x5b, 0x2d, 0x81, 0x78, 0x70, 0x30, 0x7b, 0x71, 0x70, 0x15, 0x9a, 0x0b, 0xf0, 0x18, 0xf2, - 0x20, 0xab, 0x9c, 0xe1, 0x82, 0x63, 0x6f, 0x9b, 0x9d, 0x99, 0x49, 0xfe, 0x35, 0x2e, 0x0f, 0xe9, - 0xd0, 0x8b, 0xb7, 0x5a, 0x82, 0xae, 0x39, 0x29, 0xc5, 0x89, 0x47, 0x0c, 0x39, 0x90, 0x36, 0x4c, - 0xa9, 0xf5, 0x6b, 0xc1, 0xd2, 0xcd, 0xae, 0x37, 0x33, 0xc5, 0x3b, 0xef, 0x8f, 0x0f, 0xe1, 0x89, - 0x51, 0xe2, 0xe6, 0x39, 0xf9, 0x2a, 0x53, 0x31, 0xb0, 0x87, 0x09, 0x9e, 0x17, 0x5e, 0x83, 0xd3, - 0x03, 0x73, 0x03, 0x39, 0x05, 0x85, 0x5d, 0xba, 0x2f, 0x16, 0x0d, 0x64, 0x7f, 0xc9, 0x59, 0x28, - 0xed, 0xe9, 0x56, 0x5f, 0xae, 0x0c, 0x28, 0x1e, 0xbe, 0x9c, 0x7f, 0x39, 0xa7, 0xfd, 0x5e, 0x09, - 0x26, 0xd4, 0x8c, 0xd3, 0x32, 0xed, 0x5d, 0x72, 0x07, 0x0a, 0x96, 0xd3, 0x91, 0xf3, 0xe6, 0x57, - 0x46, 0x9e, 0xc5, 0x56, 0x9c, 0x4e, 0xb3, 0x72, 0x78, 0x30, 0x5b, 0x58, 0x71, 0x3a, 0xc8, 0x38, - 0x12, 0x03, 0x4a, 0xbb, 0xfa, 0xf6, 0xae, 0xce, 0xeb, 0x50, 0xbf, 0xda, 0x1c, 0x99, 0xf5, 0x4d, - 0xc6, 0x85, 0xd5, 0xb5, 0x59, 0x3b, 0x3c, 0x98, 0x2d, 0xf1, 0x47, 0x14, 0xbc, 0x89, 0x03, 0xb5, - 0x2d, 0x4b, 0x37, 0x76, 0x77, 0x1c, 0x8b, 0xf2, 0xf5, 0x2c, 0x8b, 0xa0, 0xa6, 0xe2, 0x24, 0x3e, - 0x73, 0xf0, 0x88, 0xa1, 0x0c, 0x62, 0x40, 0xb9, 0xdf, 0xf6, 0x4c, 0x7b, 0x57, 0xce, 0x81, 0xaf, - 0x8d, 0x2c, 0x6d, 0x73, 0x91, 0xbf, 0x13, 0x5f, 0x18, 0xc5, 0x7f, 0x94, 0xac, 0x59, 0xd3, 0xb1, - 0x91, 0x4a, 0xf9, 0xda, 0x99, 0xe5, 0x8d, 0xd8, 0x40, 0xa2, 0x61, 0xd3, 0xf1, 0x47, 0x14, 0xbc, - 0xc9, 0xdb, 0x50, 0xf0, 0xee, 0x7a, 0x7c, 0xc6, 0xab, 0x5f, 0x7d, 0x7d, 0x74, 0x11, 0x77, 0x3d, - 0x2e, 0x80, 0x7f, 0xfc, 0xd6, 0x5d, 0x0f, 0x19, 0x57, 0xd2, 0x81, 0x72, 0xaf, 0x6f, 0x79, 0xba, - 0xcb, 0x67, 0xc4, 0xfa, 0xd5, 0x85, 0x91, 0xf9, 0xaf, 0x73, 0x36, 0x61, 0x53, 0x89, 0x67, 0x94, - 0xec, 0xb5, 0x1f, 0x4d, 0xc2, 0x94, 0xea, 0xcf, 0xb7, 0xa9, 0xeb, 0xd3, 0xfb, 0xe4, 0x32, 0x14, - 0x6d, 0x36, 0x8b, 0x09, 0x25, 0x6a, 0x42, 0x8e, 0xac, 0x22, 0x9f, 0xbd, 0x38, 0x86, 0x7d, 0x44, - 0x31, 0xaa, 0x64, 0xdf, 0x1c, 0xfd, 0x23, 0xb6, 0x38, 0x1b, 0x51, 0x33, 0xf1, 0x1f, 0x25, 0x6b, - 0xf2, 0x36, 0x14, 0x79, 0x3f, 0x11, 0xbd, 0xf2, 0xd5, 0xd1, 0x45, 0xb0, 0x57, 0xaf, 0xb2, 0x37, - 0xe0, 0x7d, 0x84, 0x33, 0x65, 0xa3, 0xb6, 0xdf, 0xde, 0x96, 0x7d, 0xf0, 0x2b, 0x19, 0xfa, 0xe0, - 0x92, 0xf8, 0x70, 0x9b, 0x8b, 0x4b, 0xc8, 0x38, 0x92, 0xbf, 0x94, 0x83, 0xd3, 0x86, 0x63, 0xfb, - 0x3a, 0xd3, 0x62, 0x95, 0x3e, 0x22, 0xfb, 0xe1, 0x1b, 0x23, 0xcb, 0x59, 0x48, 0x72, 0x6c, 0x3e, - 0xc1, 0x96, 0xd7, 0x01, 0x30, 0x0e, 0xca, 0x26, 0x7f, 0x23, 0x07, 0x4f, 0xb0, 0x65, 0x6f, 0x80, - 0x58, 0x76, 0xdd, 0x71, 0xd6, 0xea, 0xfc, 0xe1, 0xc1, 0xec, 0x13, 0xcb, 0x69, 0xc2, 0x30, 0xbd, - 0x0e, 0xac, 0x76, 0x67, 0xf4, 0x41, 0x0d, 0x4e, 0x76, 0xfb, 0x95, 0x71, 0x6a, 0x85, 0xcd, 0xcf, - 0xca, 0xae, 0x9c, 0xa6, 0x04, 0x63, 0x5a, 0x2d, 0xc8, 0x35, 0xa8, 0xec, 0x39, 0x56, 0xbf, 0x4b, - 0xbd, 0x99, 0x2a, 0x5f, 0x8d, 0x2e, 0xa4, 0xad, 0x46, 0xb7, 0x39, 0x49, 0xb8, 0xdd, 0x10, 0xcf, - 0x1e, 0xaa, 0xb2, 0xc4, 0x84, 0xb2, 0x65, 0x76, 0x4d, 0xdf, 0xe3, 0x3a, 0x46, 0xfd, 0xea, 0xb5, - 0x91, 0x5f, 0x4b, 0x0c, 0xd1, 0x15, 0xce, 0x4c, 0x8c, 0x1a, 0xf1, 0x1f, 0xa5, 0x00, 0x3e, 0xf5, - 0x19, 0xba, 0x25, 0x74, 0x90, 0xfa, 0xd5, 0xaf, 0x8e, 0x3e, 0x6c, 0x18, 0x97, 0xe6, 0xa4, 0x7c, - 0xa7, 0x12, 0x7f, 0x44, 0xc1, 0x9b, 0x7c, 0x03, 0xa6, 0x62, 0x5f, 0xd3, 0x9b, 0xa9, 0xf3, 0xd6, - 0x79, 0x2a, 0xad, 0x75, 0x02, 0xaa, 0x70, 0x91, 0x8e, 0xf5, 0x10, 0x0f, 0x13, 0xcc, 0xc8, 0x4d, - 0xa8, 0x7a, 0x66, 0x9b, 0x1a, 0xba, 0xeb, 0xcd, 0x4c, 0x1c, 0x85, 0xf1, 0x29, 0xc9, 0xb8, 0xda, - 0x92, 0xc5, 0x30, 0x60, 0xc0, 0x37, 0x49, 0xba, 0xeb, 0x9b, 0x42, 0xa7, 0x9f, 0xe4, 0xfa, 0xa5, - 0xd8, 0x24, 0x05, 0x50, 0x8c, 0x50, 0x30, 0x7a, 0x56, 0x76, 0xd9, 0xee, 0xf5, 0x7d, 0xa1, 0x83, - 0xc8, 0x4d, 0x55, 0x2b, 0x80, 0x62, 0x84, 0x82, 0xfc, 0x7a, 0x0e, 0x3e, 0x1b, 0x3e, 0x0e, 0x0e, - 0xb2, 0xe9, 0xb1, 0x0f, 0xb2, 0xd9, 0xc3, 0x83, 0xd9, 0xcf, 0xb6, 0x86, 0x8b, 0xc4, 0x87, 0xd5, - 0x87, 0x7c, 0x98, 0x83, 0xa9, 0x7e, 0xaf, 0xad, 0xfb, 0xb4, 0xe5, 0xb3, 0xfd, 0x74, 0x67, 0x7f, - 0xe6, 0x14, 0xaf, 0xe2, 0xf5, 0xd1, 0x67, 0xc1, 0x18, 0xbb, 0xf0, 0x33, 0xc7, 0xe1, 0x98, 0x10, - 0x4b, 0x3a, 0x50, 0x71, 0xdc, 0x36, 0x75, 0x69, 0x7b, 0xe6, 0x74, 0xc6, 0x45, 0x74, 0x4d, 0xf0, - 0x69, 0xd6, 0xd9, 0xf0, 0x93, 0x0f, 0xa8, 0xb8, 0x6b, 0xef, 0xc2, 0xe9, 0x86, 0x61, 0xf4, 0xbb, - 0x7d, 0x4b, 0xf7, 0x1d, 0xf7, 0x8e, 0x69, 0xb7, 0x9d, 0x7b, 0x64, 0x13, 0x2a, 0x4c, 0x0d, 0x77, - 0xfa, 0xbe, 0xd4, 0xdd, 0xe6, 0x22, 0x7d, 0x2c, 0x30, 0x43, 0x84, 0x42, 0xd9, 0x06, 0x96, 0xf5, - 0x3a, 0xb5, 0xd3, 0x17, 0xb2, 0x36, 0x04, 0x0b, 0x54, 0xbc, 0xb4, 0x3b, 0x30, 0xd9, 0xe8, 0xfb, - 0x3b, 0x8e, 0x6b, 0xbe, 0xc7, 0xc9, 0xc8, 0x12, 0x94, 0x7c, 0xae, 0xc6, 0x0b, 0x29, 0xcf, 0xa4, - 0xf5, 0x64, 0xb1, 0xa5, 0xba, 0x49, 0xf7, 0x95, 0x5e, 0x2a, 0xd4, 0x0d, 0xa1, 0xd6, 0x8b, 0xe2, - 0xda, 0x2f, 0xe6, 0xa1, 0xd2, 0xd4, 0x8d, 0x5d, 0x67, 0x7b, 0x9b, 0xbc, 0x05, 0x55, 0xd3, 0xf6, - 0xa9, 0xbb, 0xa7, 0x5b, 0x23, 0x56, 0x9e, 0xef, 0x8c, 0x96, 0x25, 0x0f, 0x0c, 0xb8, 0x91, 0x59, - 0x28, 0x79, 0x3e, 0xed, 0x79, 0x7c, 0x61, 0x9f, 0x94, 0x5a, 0x0f, 0x03, 0xa0, 0x80, 0x13, 0x0d, - 0xca, 0xdb, 0x3a, 0xdf, 0xb7, 0xb3, 0x75, 0x39, 0x27, 0xe6, 0xa0, 0x25, 0x0e, 0x41, 0x89, 0x21, - 0xcb, 0x50, 0x30, 0xf4, 0x9e, 0x5c, 0x5c, 0x8f, 0x5b, 0x33, 0xbe, 0x9c, 0x2e, 0xe8, 0x3d, 0x64, - 0x3c, 0x98, 0xb8, 0x77, 0x4d, 0xdf, 0xa7, 0x2e, 0x5f, 0x42, 0xa5, 0xb8, 0x37, 0x38, 0x04, 0x25, - 0x46, 0xfb, 0x95, 0x1c, 0xd4, 0x9a, 0xba, 0x67, 0x1a, 0xac, 0xe1, 0xc9, 0x02, 0x14, 0xfb, 0x1e, - 0x75, 0x8f, 0xd7, 0xdc, 0x5c, 0x3d, 0xd8, 0xf4, 0xa8, 0x8b, 0xbc, 0x30, 0x59, 0x83, 0x6a, 0x4f, - 0xf7, 0xbc, 0x7b, 0x8e, 0xdb, 0x96, 0x2a, 0xce, 0x11, 0x19, 0x89, 0x9d, 0xab, 0x2c, 0x8a, 0x01, - 0x13, 0xad, 0x0e, 0xa1, 0x3a, 0xac, 0xfd, 0x42, 0x0e, 0xce, 0x34, 0xfb, 0xdb, 0xdb, 0xd4, 0x95, - 0x1b, 0x35, 0xb9, 0x05, 0xea, 0x43, 0xed, 0x5d, 0xea, 0x7b, 0xbe, 0x4b, 0xf5, 0xae, 0x14, 0x7b, - 0x63, 0xe4, 0x21, 0xf1, 0x06, 0xf5, 0x5b, 0x9c, 0x53, 0x74, 0xe7, 0x15, 0x00, 0x31, 0x94, 0xa4, - 0x7d, 0xa7, 0x0c, 0x13, 0x0b, 0x4e, 0x77, 0xcb, 0xb4, 0x69, 0xfb, 0x5a, 0xbb, 0x43, 0xc9, 0x3b, - 0x50, 0xa4, 0xed, 0x0e, 0x95, 0x4d, 0x38, 0xba, 0xe6, 0xc5, 0x98, 0x85, 0xfa, 0x23, 0x7b, 0x42, - 0xce, 0x98, 0xac, 0xc0, 0xd4, 0xb6, 0xeb, 0x74, 0xc5, 0x62, 0xb6, 0xb1, 0xdf, 0x53, 0x16, 0xb8, - 0x1f, 0x57, 0x33, 0xc7, 0x52, 0x0c, 0xfb, 0xe0, 0x60, 0x16, 0xc2, 0x27, 0x4c, 0x94, 0x25, 0x6f, - 0xc1, 0x4c, 0x08, 0x09, 0x66, 0xf5, 0x05, 0xb6, 0xf5, 0x95, 0x26, 0xba, 0x8b, 0x87, 0x07, 0xb3, - 0x33, 0x4b, 0x43, 0x68, 0x70, 0x68, 0x69, 0x36, 0x57, 0x9e, 0x0a, 0x91, 0x62, 0xa5, 0x95, 0xdd, - 0x7a, 0x4c, 0x4b, 0x38, 0xb7, 0x11, 0x2c, 0x25, 0x44, 0xe0, 0x80, 0x50, 0xb2, 0x04, 0x13, 0xbe, - 0x13, 0x69, 0x2f, 0x61, 0x14, 0xd4, 0x94, 0x51, 0x6b, 0xc3, 0x19, 0xda, 0x5a, 0xb1, 0x72, 0x04, - 0xe1, 0x9c, 0x7a, 0x4e, 0xb4, 0x54, 0x99, 0xb7, 0xd4, 0x85, 0xc3, 0x83, 0xd9, 0x73, 0x1b, 0xa9, - 0x14, 0x38, 0xa4, 0x24, 0xf9, 0xe9, 0x1c, 0x4c, 0x29, 0x94, 0x6c, 0xa3, 0xca, 0x38, 0xdb, 0x88, - 0xb0, 0x1e, 0xb1, 0x11, 0x13, 0x80, 0x09, 0x81, 0xe4, 0x03, 0x98, 0x56, 0x10, 0x39, 0xfd, 0x4b, - 0x03, 0x51, 0xf6, 0x35, 0x85, 0x5b, 0xdf, 0x36, 0xe2, 0xcc, 0x31, 0x29, 0x4d, 0x6b, 0x42, 0x7d, - 0xc1, 0xe9, 0xf6, 0x5c, 0x61, 0x31, 0x26, 0x5f, 0x80, 0xa2, 0xcf, 0xbe, 0x93, 0xd8, 0x43, 0xcd, - 0xaa, 0x31, 0x20, 0xbf, 0xcf, 0x74, 0x84, 0x94, 0x7f, 0x24, 0x4e, 0xac, 0xfd, 0x46, 0x05, 0x6a, - 0xc1, 0x82, 0x4d, 0x9e, 0x86, 0x12, 0xb7, 0xb9, 0x49, 0x1e, 0x81, 0x26, 0xc6, 0x4d, 0x73, 0x28, - 0x70, 0xe4, 0x19, 0xa8, 0x18, 0x4e, 0xb7, 0xab, 0xdb, 0x6d, 0x6e, 0x47, 0xad, 0x89, 0x55, 0x69, - 0x41, 0x80, 0x50, 0xe1, 0xc8, 0x45, 0x28, 0xea, 0x6e, 0x47, 0x98, 0x34, 0x6b, 0x62, 0xb6, 0x6b, - 0xb8, 0x1d, 0x0f, 0x39, 0x94, 0x7c, 0x09, 0x0a, 0xd4, 0xde, 0x9b, 0x29, 0x0e, 0xd7, 0x70, 0xaf, - 0xd9, 0x7b, 0xb7, 0x75, 0xb7, 0x59, 0x97, 0x75, 0x28, 0x5c, 0xb3, 0xf7, 0x90, 0x95, 0x21, 0x2b, - 0x50, 0xa1, 0xf6, 0x1e, 0xeb, 0xc0, 0xd2, 0xd6, 0xf8, 0x63, 0x43, 0x8a, 0x33, 0x12, 0xb9, 0xd9, - 0x0b, 0xf4, 0x64, 0x09, 0x46, 0xc5, 0x82, 0x7c, 0x0d, 0x26, 0x84, 0xca, 0xbc, 0xca, 0x3a, 0x96, - 0x30, 0x69, 0xd7, 0xaf, 0xce, 0x0e, 0xd7, 0xb9, 0x39, 0x5d, 0x68, 0xdb, 0x8d, 0x00, 0x3d, 0x8c, - 0xb1, 0x22, 0x5f, 0x83, 0x9a, 0x32, 0x05, 0xa9, 0xee, 0x99, 0x6a, 0x16, 0x55, 0xf6, 0x23, 0xa4, - 0x77, 0xfb, 0xa6, 0x4b, 0xbb, 0xd4, 0xf6, 0xbd, 0xe6, 0x69, 0x65, 0x28, 0x53, 0x58, 0x0f, 0x43, - 0x6e, 0x64, 0x6b, 0xd0, 0xbe, 0x2b, 0xfa, 0xde, 0xd3, 0x43, 0xd6, 0x8c, 0x11, 0x8c, 0xbb, 0xdf, - 0x84, 0xe9, 0xc0, 0x00, 0x2b, 0x6d, 0x78, 0xc2, 0x5c, 0xf9, 0x02, 0x2b, 0xbe, 0x1c, 0x47, 0x3d, - 0x38, 0x98, 0x7d, 0x2a, 0xc5, 0x8a, 0x17, 0x12, 0x60, 0x92, 0x19, 0x79, 0x0f, 0xa6, 0x5c, 0xaa, - 0xb7, 0x4d, 0x9b, 0x7a, 0xde, 0xba, 0xeb, 0x6c, 0x65, 0xdf, 0x3f, 0x70, 0x2e, 0x62, 0xec, 0x62, - 0x8c, 0x33, 0x26, 0x24, 0x91, 0x7b, 0x30, 0x69, 0x99, 0x7b, 0x34, 0x14, 0x5d, 0x1f, 0x8b, 0xe8, - 0xd3, 0x87, 0x07, 0xb3, 0x93, 0x2b, 0x51, 0xc6, 0x18, 0x97, 0xc3, 0x54, 0xb3, 0x9e, 0xe3, 0xfa, - 0x6a, 0x93, 0xf1, 0x63, 0x0f, 0xdd, 0x64, 0xac, 0x3b, 0xae, 0x1f, 0x0e, 0x42, 0xf6, 0xe4, 0xa1, - 0x28, 0xae, 0xfd, 0xbd, 0x12, 0x0c, 0x6e, 0xc5, 0xe3, 0x3d, 0x2e, 0x37, 0xee, 0x1e, 0x97, 0xec, - 0x0d, 0x62, 0x01, 0x7d, 0x59, 0x16, 0x1b, 0x43, 0x8f, 0x48, 0xe9, 0xd5, 0x85, 0x71, 0xf7, 0xea, - 0xc7, 0x66, 0xe2, 0x19, 0xec, 0xfe, 0xe5, 0x8f, 0xaf, 0xfb, 0x57, 0x4e, 0xa6, 0xfb, 0x6b, 0xdf, - 0x2e, 0xc2, 0xd4, 0xa2, 0x4e, 0xbb, 0x8e, 0xfd, 0x91, 0xd6, 0x98, 0xdc, 0x63, 0x61, 0x8d, 0x79, - 0x0e, 0xaa, 0x2e, 0xed, 0x59, 0xa6, 0xa1, 0x8b, 0xfd, 0x89, 0x74, 0x14, 0xa1, 0x84, 0x61, 0x80, - 0x1d, 0x62, 0x85, 0x2b, 0x3c, 0x96, 0x56, 0xb8, 0xe2, 0xc7, 0x6f, 0x85, 0xd3, 0x7e, 0x3a, 0x0f, - 0x5c, 0x3f, 0x27, 0x97, 0xa1, 0xc8, 0x74, 0xcf, 0xa4, 0xed, 0x97, 0x8f, 0x16, 0x8e, 0x21, 0x17, - 0x20, 0xef, 0x3b, 0x72, 0xba, 0x01, 0x89, 0xcf, 0x6f, 0x38, 0x98, 0xf7, 0x1d, 0xf2, 0x1e, 0x80, - 0xe1, 0xd8, 0x6d, 0x53, 0xf9, 0x4f, 0xb3, 0xbd, 0xd8, 0x92, 0xe3, 0xde, 0xd3, 0xdd, 0xf6, 0x42, - 0xc0, 0x51, 0xd8, 0x61, 0xc2, 0x67, 0x8c, 0x48, 0x23, 0xaf, 0x41, 0xd9, 0xb1, 0x97, 0xfa, 0x96, - 0x25, 0x9d, 0xeb, 0x3f, 0xc1, 0x76, 0x8a, 0x6b, 0x1c, 0xf2, 0xe0, 0x60, 0xf6, 0xbc, 0xd8, 0x6f, - 0xb1, 0xa7, 0x3b, 0xae, 0xe9, 0x9b, 0x76, 0x27, 0x30, 0x4b, 0xc8, 0x62, 0xda, 0x5f, 0xc9, 0x41, - 0x7d, 0xc9, 0xbc, 0x4f, 0xdb, 0xd2, 0x40, 0x80, 0x50, 0xb6, 0xa8, 0xdd, 0xf1, 0x77, 0x46, 0xdc, - 0x62, 0x0b, 0xeb, 0x1c, 0xe7, 0x80, 0x92, 0x13, 0x99, 0x87, 0x9a, 0xd8, 0x74, 0x99, 0x76, 0x87, - 0xb7, 0x61, 0x35, 0x9c, 0xe9, 0x5b, 0x0a, 0x81, 0x21, 0x8d, 0xf6, 0x3e, 0x9c, 0x1e, 0x68, 0x06, - 0xb2, 0x03, 0x45, 0x5f, 0xef, 0xa8, 0x45, 0x65, 0x69, 0xe4, 0x06, 0xde, 0xd0, 0x3b, 0x91, 0xc6, - 0x0d, 0x3e, 0xf6, 0x86, 0xce, 0x34, 0x43, 0x26, 0x41, 0xfb, 0xcd, 0x22, 0x94, 0xaf, 0xb7, 0x5a, - 0x8d, 0xf5, 0x65, 0xf2, 0x22, 0xd4, 0xa5, 0xf7, 0xf3, 0x56, 0xe8, 0x1c, 0x08, 0x9c, 0xdf, 0xad, - 0x10, 0x85, 0x51, 0x3a, 0xa6, 0xc5, 0xba, 0x54, 0xb7, 0xba, 0xb2, 0xc7, 0x04, 0x0b, 0x28, 0x32, - 0x20, 0x0a, 0x1c, 0xd1, 0x61, 0x8a, 0x6d, 0xbb, 0x6d, 0xbd, 0x4b, 0xc5, 0x96, 0x5a, 0xf6, 0x9d, - 0x23, 0x6e, 0xba, 0xf9, 0x2c, 0xbb, 0x19, 0x63, 0x80, 0x09, 0x86, 0xe4, 0x65, 0xa8, 0xea, 0x7d, - 0x7f, 0x87, 0x6f, 0x9e, 0x44, 0x07, 0xb9, 0xc8, 0x9d, 0xc3, 0x12, 0xf6, 0xe0, 0x60, 0x76, 0xe2, - 0x26, 0x36, 0x5f, 0x54, 0xcf, 0x18, 0x50, 0xb3, 0xca, 0xa9, 0x6d, 0xbc, 0xac, 0x5c, 0xe9, 0xd8, - 0x95, 0x5b, 0x8f, 0x31, 0xc0, 0x04, 0x43, 0xf2, 0x36, 0x4c, 0xec, 0xd2, 0x7d, 0x5f, 0xdf, 0x92, - 0x02, 0xca, 0xc7, 0x11, 0x70, 0x8a, 0x69, 0xbe, 0x37, 0x23, 0xc5, 0x31, 0xc6, 0x8c, 0x78, 0x70, - 0x76, 0x97, 0xba, 0x5b, 0xd4, 0x75, 0xa4, 0xab, 0x55, 0x0a, 0xa9, 0x1c, 0x47, 0xc8, 0xcc, 0xe1, - 0xc1, 0xec, 0xd9, 0x9b, 0x29, 0x6c, 0x30, 0x95, 0xb9, 0xf6, 0xbf, 0xf3, 0x30, 0x7d, 0x5d, 0x44, - 0xec, 0x38, 0xae, 0x58, 0x7e, 0xc9, 0x79, 0x28, 0xb8, 0xbd, 0x3e, 0xef, 0x39, 0x05, 0x61, 0xe6, - 0xc1, 0xf5, 0x4d, 0x64, 0x30, 0xf2, 0x16, 0x54, 0x55, 0xc0, 0x8c, 0x34, 0x7c, 0x8c, 0x64, 0xd0, - 0x52, 0x4f, 0x18, 0x70, 0x63, 0x1b, 0xa4, 0xae, 0xd7, 0x69, 0x99, 0xef, 0x51, 0x69, 0x0b, 0xe0, - 0x1b, 0xa4, 0x55, 0x01, 0x42, 0x85, 0x63, 0x4b, 0xcb, 0x2e, 0xdd, 0x17, 0x3b, 0xe1, 0x62, 0xb8, - 0xb4, 0xdc, 0x94, 0x30, 0x0c, 0xb0, 0x64, 0x56, 0xb9, 0x86, 0x59, 0x2f, 0x28, 0x0a, 0x0b, 0xd9, - 0x6d, 0x06, 0x90, 0x5e, 0x62, 0x36, 0x6f, 0x48, 0x93, 0x55, 0x79, 0xf4, 0x79, 0x23, 0x6e, 0xe2, - 0x22, 0x9f, 0x87, 0x1a, 0x67, 0xde, 0xb4, 0x9c, 0x2d, 0xfe, 0xe1, 0x6a, 0xc2, 0x9e, 0x73, 0x5b, - 0x01, 0x31, 0xc4, 0x6b, 0x7f, 0x94, 0x87, 0x73, 0xd7, 0xa9, 0x2f, 0x96, 0xf6, 0x45, 0xda, 0xb3, - 0x9c, 0x7d, 0xa6, 0x54, 0x22, 0xbd, 0x4b, 0x5e, 0x07, 0x30, 0xbd, 0xad, 0xd6, 0x9e, 0xb1, 0x11, - 0x6e, 0x4e, 0x2f, 0xcb, 0x21, 0x09, 0xcb, 0xad, 0xa6, 0xc4, 0x3c, 0x88, 0x3d, 0x61, 0xa4, 0x4c, - 0xb8, 0x2b, 0xcd, 0x3f, 0x64, 0x57, 0xda, 0x02, 0xe8, 0x85, 0xaa, 0x69, 0x81, 0x53, 0x7e, 0x41, - 0x89, 0x39, 0x8e, 0x56, 0x1a, 0x61, 0x93, 0x45, 0x59, 0xb4, 0xe1, 0x54, 0x9b, 0x6e, 0xeb, 0x7d, - 0xcb, 0x0f, 0xd4, 0x69, 0x39, 0x88, 0x8f, 0xae, 0x91, 0x07, 0xa1, 0x31, 0x8b, 0x09, 0x4e, 0x38, - 0xc0, 0x5b, 0xfb, 0xad, 0x02, 0x5c, 0xb8, 0x4e, 0xfd, 0xc0, 0xda, 0x26, 0x67, 0xc7, 0x56, 0x8f, - 0x1a, 0xec, 0x2b, 0x7c, 0x98, 0x83, 0xb2, 0xa5, 0x6f, 0x51, 0x8b, 0x4d, 0xe1, 0xec, 0x6d, 0xde, - 0x19, 0x79, 0x0a, 0x1f, 0x2e, 0x65, 0x6e, 0x85, 0x4b, 0x10, 0xd1, 0x4f, 0x53, 0xb2, 0xf2, 0x65, - 0x01, 0x44, 0x29, 0x9e, 0x4d, 0xea, 0x86, 0xd5, 0xf7, 0x7c, 0xb1, 0xbd, 0x91, 0x4a, 0x55, 0x30, - 0xa9, 0x2f, 0x84, 0x28, 0x8c, 0xd2, 0x91, 0xab, 0x00, 0x86, 0x65, 0x52, 0xdb, 0xe7, 0xa5, 0xc4, - 0xb8, 0x22, 0xea, 0xfb, 0x2e, 0x04, 0x18, 0x8c, 0x50, 0x31, 0x51, 0x5d, 0xc7, 0x36, 0x7d, 0x47, - 0x88, 0x2a, 0xc6, 0x45, 0xad, 0x86, 0x28, 0x8c, 0xd2, 0xf1, 0x62, 0xd4, 0x77, 0x4d, 0xc3, 0xe3, - 0xc5, 0x4a, 0x89, 0x62, 0x21, 0x0a, 0xa3, 0x74, 0x17, 0xbe, 0x04, 0xf5, 0xc8, 0xfb, 0x1f, 0x2b, - 0xc2, 0xe3, 0x6f, 0xd5, 0xe0, 0x52, 0xac, 0x59, 0x7d, 0xdd, 0xa7, 0xdb, 0x7d, 0xab, 0x45, 0x7d, - 0xf5, 0x01, 0x47, 0x5c, 0x0b, 0xff, 0x62, 0xf8, 0xdd, 0x45, 0xd0, 0x9b, 0x31, 0x9e, 0xef, 0x3e, - 0x50, 0xc1, 0x23, 0x7d, 0xfb, 0x79, 0xa8, 0xd9, 0xba, 0xef, 0xf1, 0x81, 0x2b, 0xc7, 0x68, 0xa0, - 0x8b, 0xdc, 0x52, 0x08, 0x0c, 0x69, 0xc8, 0x3a, 0x9c, 0x95, 0x4d, 0x7c, 0xed, 0x3e, 0xdb, 0xf8, - 0x52, 0x57, 0x94, 0x95, 0xcb, 0xa9, 0x2c, 0x7b, 0x76, 0x35, 0x85, 0x06, 0x53, 0x4b, 0x92, 0x55, - 0x38, 0x63, 0x88, 0x40, 0x20, 0x6a, 0x39, 0x7a, 0x5b, 0x31, 0x14, 0xc6, 0xcd, 0x60, 0x7f, 0xb0, - 0x30, 0x48, 0x82, 0x69, 0xe5, 0x92, 0xbd, 0xb9, 0x3c, 0x52, 0x6f, 0xae, 0x8c, 0xd2, 0x9b, 0xab, - 0xa3, 0xf5, 0xe6, 0xda, 0xd1, 0x7a, 0x33, 0x6b, 0x79, 0x1e, 0x73, 0xe2, 0x32, 0xf5, 0x44, 0xac, - 0xb0, 0x91, 0x38, 0xb3, 0xa0, 0xe5, 0x5b, 0x29, 0x34, 0x98, 0x5a, 0x92, 0x6c, 0xc1, 0x05, 0x01, - 0xbf, 0x66, 0x1b, 0xee, 0x7e, 0x4f, 0x46, 0xaa, 0x2a, 0xbe, 0xf5, 0x98, 0x75, 0xf9, 0x42, 0x6b, - 0x28, 0x25, 0x3e, 0x84, 0x0b, 0x79, 0x05, 0x26, 0xc5, 0x57, 0x5a, 0xd5, 0x7b, 0x9c, 0xad, 0x88, - 0x3a, 0x7b, 0x42, 0xb2, 0x9d, 0x5c, 0x88, 0x22, 0x31, 0x4e, 0x4b, 0x1a, 0x30, 0xdd, 0xdb, 0x33, - 0xd8, 0xdf, 0xe5, 0xed, 0x5b, 0x94, 0xb6, 0x69, 0x9b, 0xfb, 0x6e, 0x6b, 0xcd, 0x27, 0x95, 0x89, - 0x63, 0x3d, 0x8e, 0xc6, 0x24, 0x3d, 0x79, 0x19, 0x26, 0x3c, 0x5f, 0x77, 0x7d, 0x69, 0x0d, 0x9d, - 0x99, 0x12, 0x51, 0x79, 0xca, 0x58, 0xd8, 0x8a, 0xe0, 0x30, 0x46, 0x99, 0xba, 0x5e, 0x4c, 0x3f, - 0xba, 0xf5, 0x22, 0xcb, 0x6c, 0xf5, 0x8f, 0xf3, 0x70, 0xf9, 0x3a, 0xf5, 0x57, 0x1d, 0x5b, 0x1a, - 0xa4, 0xd3, 0x96, 0xfd, 0x23, 0x99, 0x92, 0xe3, 0x8b, 0x76, 0x7e, 0xac, 0x8b, 0x76, 0x61, 0x4c, - 0x8b, 0x76, 0xf1, 0x11, 0x2e, 0xda, 0x7f, 0x3f, 0x0f, 0x4f, 0xc6, 0x5a, 0x72, 0xdd, 0x69, 0xab, - 0x09, 0xff, 0xd3, 0x06, 0x3c, 0x42, 0x03, 0xfe, 0x5e, 0x01, 0x9e, 0xba, 0x4e, 0x45, 0xf0, 0xa9, - 0xdd, 0x59, 0x37, 0x7b, 0xd4, 0x32, 0x6d, 0x1a, 0x61, 0x4b, 0xfe, 0x7c, 0x0e, 0x26, 0x84, 0x2e, - 0x29, 0xc3, 0x46, 0xb3, 0xda, 0x95, 0x52, 0xbc, 0xa8, 0xe1, 0x00, 0x17, 0x1a, 0xac, 0x5c, 0x3d, - 0x62, 0x72, 0x3f, 0xd5, 0x62, 0x8f, 0xf2, 0x3d, 0x7f, 0xa6, 0x00, 0xe7, 0xd9, 0xf7, 0x54, 0xc1, - 0x24, 0x9f, 0x6e, 0x25, 0x3e, 0x86, 0x8f, 0xf0, 0x6b, 0x25, 0x38, 0x73, 0x9d, 0xfa, 0x03, 0x33, - 0xd2, 0x9f, 0xd0, 0xe6, 0x5f, 0x85, 0x33, 0x61, 0x70, 0x53, 0xcb, 0x77, 0x5c, 0xa1, 0x81, 0x27, - 0x34, 0xc6, 0xd6, 0x20, 0x09, 0xa6, 0x95, 0x23, 0x5f, 0x83, 0x27, 0x3d, 0x31, 0x5d, 0x09, 0x1b, - 0x85, 0x50, 0xa8, 0x23, 0x27, 0x19, 0x94, 0xe7, 0xf6, 0xc9, 0x56, 0x3a, 0x19, 0x0e, 0x2b, 0x4f, - 0x3e, 0x80, 0x89, 0x9e, 0x9c, 0x02, 0xd9, 0x37, 0xcb, 0xec, 0x12, 0x5f, 0x8f, 0x30, 0x0b, 0xe7, - 0xb8, 0x28, 0x14, 0x63, 0x02, 0x53, 0x7b, 0x6a, 0xf5, 0x11, 0xf6, 0xd4, 0x3f, 0xcc, 0x43, 0xe5, - 0xba, 0xeb, 0xf4, 0x7b, 0xcd, 0x7d, 0xd2, 0x81, 0xf2, 0x3d, 0x6e, 0x45, 0x95, 0x33, 0xfc, 0xe8, - 0x01, 0xc2, 0xc2, 0x18, 0x1b, 0x6e, 0x62, 0xc4, 0x33, 0x4a, 0xf6, 0xac, 0x13, 0xef, 0xd2, 0x7d, - 0xda, 0x96, 0xc6, 0xd4, 0xa0, 0x13, 0xdf, 0x64, 0x40, 0x14, 0x38, 0xd2, 0x85, 0x69, 0xdd, 0xb2, - 0x9c, 0x7b, 0xb4, 0xbd, 0xa2, 0xfb, 0xdc, 0x01, 0x22, 0xed, 0x8b, 0xc7, 0x35, 0xcd, 0x70, 0xaf, - 0x56, 0x23, 0xce, 0x0a, 0x93, 0xbc, 0xc9, 0xbb, 0x50, 0xf1, 0x7c, 0xc7, 0x55, 0x5b, 0xa3, 0x4c, - 0xc1, 0xdb, 0xcd, 0x37, 0x5b, 0x82, 0x95, 0xb0, 0x5b, 0xc9, 0x07, 0x54, 0x02, 0xb4, 0xff, 0x97, - 0x03, 0xb8, 0xb1, 0xb1, 0xb1, 0x2e, 0x4d, 0x6c, 0x6d, 0x28, 0xea, 0xfd, 0xc0, 0x62, 0x3d, 0xba, - 0x65, 0x38, 0x16, 0xc2, 0x26, 0xe3, 0x05, 0xfa, 0xfe, 0x0e, 0x72, 0xee, 0xe4, 0x73, 0x50, 0x91, - 0xdb, 0x5a, 0xd9, 0xec, 0x81, 0x63, 0x4d, 0xae, 0xc4, 0xa8, 0xf0, 0xe4, 0x1d, 0xe5, 0x62, 0x2d, - 0x64, 0x75, 0x6a, 0x31, 0x2e, 0xc2, 0xda, 0x16, 0xf3, 0xbd, 0xfe, 0x4a, 0x01, 0x60, 0xb9, 0x6d, - 0xd1, 0x96, 0x0a, 0x1a, 0xaf, 0xf9, 0x3b, 0x2e, 0xf5, 0x76, 0x1c, 0xab, 0x3d, 0xa2, 0xdd, 0x9e, - 0x1b, 0xd6, 0x36, 0x14, 0x13, 0x0c, 0xf9, 0x91, 0x36, 0xdb, 0x50, 0xd0, 0x9e, 0x0a, 0x9b, 0x1b, - 0xd1, 0x52, 0x79, 0x4a, 0x6c, 0x3e, 0x42, 0x3e, 0x18, 0xe3, 0x4a, 0x74, 0xa8, 0x9b, 0xb6, 0x21, - 0x46, 0x60, 0x73, 0x7f, 0xc4, 0x9e, 0xca, 0xcf, 0x32, 0x2e, 0x87, 0x6c, 0x30, 0xca, 0x93, 0x0d, - 0x08, 0xd3, 0x36, 0x7d, 0xd1, 0x66, 0x8b, 0xd4, 0xd2, 0xf7, 0x47, 0x0c, 0xd6, 0xe3, 0x03, 0x62, - 0x39, 0xce, 0x0a, 0x93, 0xbc, 0xb5, 0xbf, 0x90, 0x83, 0x69, 0xfe, 0x7a, 0xec, 0xad, 0x85, 0xca, - 0x46, 0xee, 0x41, 0xdd, 0x08, 0x83, 0x60, 0x64, 0x53, 0x2e, 0x66, 0x70, 0x82, 0x05, 0xbc, 0xc4, - 0xbb, 0x47, 0x00, 0x18, 0x95, 0xa4, 0xfd, 0x41, 0x1e, 0xce, 0x25, 0x2a, 0x23, 0x7b, 0x2d, 0xf9, - 0xb3, 0x03, 0xe7, 0x20, 0xff, 0xf4, 0xd1, 0xda, 0x43, 0x1c, 0xa3, 0x5b, 0xa5, 0xbe, 0x1e, 0x1a, - 0x0e, 0x42, 0x58, 0xe4, 0xf0, 0x63, 0x1f, 0x8a, 0x1e, 0x5b, 0x0c, 0xc4, 0xeb, 0xb6, 0x46, 0x7e, - 0xdd, 0xf4, 0x17, 0xe0, 0x4b, 0x43, 0xe0, 0xc6, 0xe1, 0x4b, 0x02, 0x17, 0x47, 0xde, 0x87, 0xb2, - 0xe7, 0xeb, 0x7e, 0x5f, 0x0d, 0xc3, 0xcd, 0x71, 0x0b, 0xe6, 0xcc, 0xc3, 0x49, 0x5a, 0x3c, 0xa3, - 0x14, 0xaa, 0xfd, 0x41, 0x0e, 0x2e, 0xa4, 0x17, 0x5c, 0x31, 0x3d, 0x9f, 0xfc, 0x99, 0x81, 0x66, - 0x3f, 0x62, 0x37, 0x64, 0xa5, 0x79, 0xa3, 0x07, 0xf1, 0xdf, 0x0a, 0x12, 0x69, 0x72, 0x1f, 0x4a, - 0xa6, 0x4f, 0xbb, 0xca, 0xe4, 0xb6, 0x36, 0xe6, 0x57, 0x8f, 0xe8, 0x4d, 0x4c, 0x0a, 0x0a, 0x61, - 0xda, 0x5f, 0x1f, 0xfa, 0xca, 0x7c, 0x6d, 0xfe, 0x73, 0x83, 0x91, 0x9e, 0x6b, 0xd9, 0x23, 0x3d, - 0x13, 0x15, 0x1b, 0x1a, 0xf0, 0xf9, 0xc3, 0x02, 0x5c, 0x7c, 0xd8, 0x87, 0x64, 0xcb, 0xb7, 0xec, - 0x2f, 0x59, 0x97, 0xef, 0x87, 0xf7, 0x0c, 0x72, 0x15, 0x4a, 0xbd, 0x1d, 0xdd, 0x53, 0x3a, 0xe8, - 0xc5, 0x20, 0xbc, 0x86, 0x01, 0x1f, 0xb0, 0x29, 0x8c, 0xeb, 0xae, 0xfc, 0x11, 0x05, 0x29, 0x5b, - 0x7d, 0xba, 0xd4, 0xf3, 0x42, 0xab, 0x65, 0xb0, 0xfa, 0xac, 0x0a, 0x30, 0x2a, 0x3c, 0xf1, 0xa1, - 0x2c, 0xac, 0x4a, 0x72, 0x7a, 0x1b, 0xef, 0x46, 0x33, 0x78, 0x29, 0xb9, 0xc5, 0x94, 0xb2, 0xc8, - 0x9c, 0x8c, 0xfd, 0x2b, 0xc5, 0xce, 0x93, 0x16, 0x53, 0xd4, 0x71, 0x4e, 0x47, 0xde, 0x00, 0xe2, - 0x6c, 0x71, 0x3b, 0x5a, 0x5b, 0xba, 0xcc, 0xd8, 0x8c, 0x58, 0xe6, 0x6e, 0xb2, 0xe0, 0x34, 0xea, - 0xda, 0x00, 0x05, 0xa6, 0x94, 0xd2, 0x7e, 0xbf, 0x0a, 0xe7, 0xd2, 0xfb, 0x03, 0x6b, 0xb7, 0x3d, - 0xea, 0xf2, 0xd9, 0x36, 0x71, 0x3c, 0xfe, 0xb6, 0x00, 0xa3, 0xc2, 0x7f, 0xa2, 0x03, 0x2d, 0x7e, - 0x2d, 0x07, 0xe7, 0x5d, 0x69, 0x16, 0x3e, 0x89, 0x60, 0x8b, 0xa7, 0x0e, 0x0f, 0x66, 0xcf, 0xe3, - 0x30, 0x81, 0x38, 0xbc, 0x2e, 0xe4, 0x57, 0x73, 0x30, 0x23, 0xad, 0xbc, 0x0b, 0x27, 0x70, 0x62, - 0x8c, 0x07, 0x41, 0xaf, 0x0e, 0x91, 0x87, 0x43, 0x6b, 0x42, 0x3e, 0x80, 0x7a, 0x8f, 0xf5, 0x0b, - 0xcf, 0xa7, 0xb6, 0xa1, 0x02, 0xa3, 0x46, 0x1f, 0x49, 0xeb, 0x21, 0xaf, 0xe0, 0xc4, 0x08, 0x5f, - 0xb1, 0x23, 0x08, 0x8c, 0x4a, 0x7c, 0xcc, 0x8f, 0x88, 0x3d, 0x07, 0x55, 0x8f, 0xfa, 0xbe, 0x69, - 0x77, 0xc4, 0xf6, 0xaa, 0x26, 0xc6, 0x4a, 0x4b, 0xc2, 0x30, 0xc0, 0x92, 0xcf, 0x43, 0x8d, 0x5b, - 0x99, 0x1b, 0x6e, 0xc7, 0x9b, 0xa9, 0xf1, 0x48, 0xdc, 0x49, 0x11, 0xf8, 0x21, 0x81, 0x18, 0xe2, - 0xc9, 0x0b, 0x30, 0xb1, 0xc5, 0x87, 0xaf, 0xb4, 0x94, 0x09, 0x53, 0x3f, 0xd7, 0x1d, 0x9b, 0x11, - 0x38, 0xc6, 0xa8, 0xc8, 0x55, 0x00, 0x1a, 0x98, 0xe2, 0xe5, 0xc1, 0xf1, 0x40, 0x23, 0x09, 0x8d, - 0xf4, 0x18, 0xa1, 0x22, 0x4f, 0x41, 0xc1, 0xb7, 0x3c, 0x6e, 0x9c, 0xaf, 0x86, 0x3b, 0xee, 0x8d, - 0x95, 0x16, 0x32, 0xb8, 0xf6, 0x47, 0x39, 0x98, 0x4e, 0x9c, 0x25, 0x60, 0x45, 0xfa, 0xae, 0x25, - 0xa7, 0x91, 0xa0, 0xc8, 0x26, 0xae, 0x20, 0x83, 0x93, 0x77, 0xe4, 0x2e, 0x24, 0x9f, 0x31, 0x97, - 0xc4, 0x2d, 0xdd, 0xf7, 0xd8, 0xb6, 0x63, 0x60, 0x03, 0xc2, 0x2d, 0xfb, 0x61, 0x7d, 0xe4, 0x3a, - 0x10, 0xb1, 0xec, 0x87, 0x38, 0x8c, 0x51, 0xb2, 0x06, 0xf2, 0x2d, 0xef, 0x9a, 0xad, 0x6f, 0x59, - 0xb4, 0xcd, 0x67, 0x83, 0x48, 0x03, 0x6d, 0xac, 0xb4, 0x24, 0x06, 0x23, 0x54, 0xda, 0x6f, 0x17, - 0x22, 0x2d, 0x20, 0xf7, 0x19, 0x1f, 0xd1, 0x02, 0xcf, 0xb2, 0x05, 0x34, 0x58, 0xdc, 0x6b, 0xd1, - 0xf5, 0x8f, 0x2f, 0xc6, 0x12, 0x4b, 0x9e, 0x87, 0xaa, 0xe1, 0xd8, 0x5e, 0xbf, 0x4b, 0x5d, 0xf9, - 0x12, 0x81, 0x2a, 0xb3, 0x20, 0xe1, 0x18, 0x50, 0x90, 0xaf, 0xc0, 0x54, 0x9b, 0x5a, 0xe6, 0x1e, - 0x75, 0xdf, 0x91, 0xb9, 0x41, 0x8a, 0x71, 0x8f, 0xca, 0xa2, 0xc0, 0x4a, 0x93, 0xcb, 0x64, 0x3b, - 0xfa, 0x48, 0x5e, 0x81, 0xe9, 0x6d, 0xd3, 0xf2, 0xa9, 0xfb, 0x8e, 0xd7, 0xe7, 0xba, 0xa9, 0x48, - 0x0f, 0x51, 0x13, 0x11, 0x2a, 0x4b, 0x1c, 0xd5, 0x92, 0x18, 0x9c, 0xda, 0x8e, 0x3d, 0x93, 0x3b, - 0xa2, 0x93, 0x94, 0x33, 0x9e, 0x97, 0xdd, 0x58, 0x69, 0x89, 0xc8, 0x0f, 0xd5, 0xbd, 0x82, 0xbe, - 0x52, 0x79, 0x44, 0x7d, 0x45, 0xfb, 0x27, 0x05, 0xa8, 0xbf, 0xe1, 0x6c, 0x7d, 0x42, 0x42, 0x1c, - 0xd3, 0xd7, 0xd3, 0xfc, 0xc7, 0xb8, 0x9e, 0x6e, 0xc2, 0x93, 0xbe, 0x6f, 0xc9, 0x34, 0x36, 0x8d, - 0x6d, 0x9f, 0xba, 0x4b, 0xa6, 0x6d, 0x7a, 0x3b, 0xb4, 0x2d, 0x1d, 0xff, 0x9f, 0x3d, 0x3c, 0x98, - 0x7d, 0x72, 0x63, 0x63, 0x25, 0x8d, 0x04, 0x87, 0x95, 0xe5, 0xf3, 0x9b, 0x38, 0xcd, 0xc6, 0x4f, - 0x70, 0xc8, 0x78, 0x00, 0x31, 0xbf, 0x45, 0xe0, 0x18, 0xa3, 0xd2, 0xfe, 0x6d, 0x1e, 0x6a, 0x41, - 0x3a, 0x03, 0xf2, 0x0c, 0x54, 0xb6, 0x5c, 0x67, 0x97, 0xba, 0x22, 0x8e, 0x42, 0x1e, 0x7e, 0x68, - 0x0a, 0x10, 0x2a, 0x1c, 0x79, 0x1a, 0x4a, 0xbe, 0xd3, 0x33, 0x8d, 0xa4, 0xa1, 0x73, 0x83, 0x01, - 0x51, 0xe0, 0xf8, 0x88, 0xe5, 0x21, 0x4f, 0xfc, 0xad, 0xaa, 0x91, 0x11, 0xcb, 0xa1, 0x28, 0xb1, - 0x6a, 0x20, 0x14, 0xc7, 0x3e, 0x10, 0x9e, 0x0d, 0x74, 0xd5, 0x52, 0x7c, 0xca, 0x48, 0x68, 0x97, - 0x6f, 0x43, 0xd1, 0xd3, 0x3d, 0x4b, 0x0e, 0xc5, 0x0c, 0xc7, 0xe2, 0x1b, 0xad, 0x15, 0x79, 0x2c, - 0xbe, 0xd1, 0x5a, 0x41, 0xce, 0x54, 0xfb, 0x3b, 0x05, 0xa8, 0x8b, 0xf6, 0x15, 0xd3, 0xdc, 0x38, - 0x5b, 0xf8, 0x35, 0xee, 0x0e, 0xe6, 0x33, 0x19, 0x37, 0x13, 0xca, 0x09, 0x2f, 0xc8, 0x15, 0xb3, - 0x10, 0x45, 0x06, 0x2e, 0xe1, 0x10, 0xf4, 0xc7, 0xbb, 0xe9, 0xd9, 0x9a, 0xc6, 0x53, 0x72, 0x48, - 0x65, 0x5c, 0x46, 0x79, 0x05, 0x6b, 0xda, 0xcd, 0x08, 0x0e, 0x63, 0x94, 0xda, 0x7f, 0xcd, 0x43, - 0x6d, 0xc5, 0xdc, 0xa6, 0xc6, 0xbe, 0x61, 0x51, 0xf2, 0x4d, 0xb8, 0xd0, 0xa6, 0x16, 0x65, 0x4b, - 0xfb, 0x75, 0x57, 0x37, 0xe8, 0x3a, 0x75, 0x4d, 0x9e, 0x52, 0x88, 0xa7, 0xac, 0x12, 0xc1, 0x77, - 0x97, 0x0e, 0x0f, 0x66, 0x2f, 0x2c, 0x0e, 0xa5, 0xc2, 0x87, 0x70, 0x20, 0xcb, 0x30, 0xd1, 0xa6, - 0x9e, 0xe9, 0xd2, 0xf6, 0x7a, 0x64, 0xe7, 0xf6, 0x8c, 0xaa, 0xe7, 0x62, 0x04, 0xf7, 0xe0, 0x60, - 0x76, 0x52, 0x19, 0xa8, 0xc5, 0x16, 0x2e, 0x56, 0x94, 0x4d, 0x2d, 0x3d, 0xbd, 0xef, 0xd1, 0x94, - 0x7a, 0x16, 0x78, 0x3d, 0xf9, 0xd4, 0xb2, 0x9e, 0x4e, 0x82, 0xc3, 0xca, 0x92, 0x2d, 0x98, 0xe1, - 0xf5, 0x4f, 0xe3, 0x5b, 0xe4, 0x7c, 0x9f, 0x3d, 0x3c, 0x98, 0xd5, 0x16, 0x69, 0xcf, 0xa5, 0x86, - 0xee, 0xd3, 0xf6, 0xe2, 0x10, 0x6a, 0x1c, 0xca, 0x47, 0x2b, 0x41, 0x61, 0xc5, 0xe9, 0x68, 0xdf, - 0x2e, 0x40, 0x90, 0xe3, 0x8a, 0xfc, 0x7c, 0x0e, 0xea, 0xba, 0x6d, 0x3b, 0xbe, 0xcc, 0x1f, 0x25, - 0x62, 0xbb, 0x30, 0x73, 0x2a, 0xad, 0xb9, 0x46, 0xc8, 0x54, 0x84, 0xf4, 0x04, 0x11, 0x23, 0x11, - 0x0c, 0x46, 0x65, 0x93, 0x7e, 0x22, 0xd2, 0x68, 0x35, 0x7b, 0x2d, 0x8e, 0x10, 0x53, 0x74, 0xe1, - 0xab, 0x70, 0x2a, 0x59, 0xd9, 0xe3, 0x44, 0x33, 0x64, 0x09, 0x84, 0xf8, 0x5e, 0x1e, 0x20, 0xf4, - 0xdd, 0x9f, 0x80, 0x2d, 0xcf, 0x8c, 0xd9, 0xf2, 0x46, 0x3f, 0x3d, 0x1f, 0x56, 0x7a, 0xa8, 0xfd, - 0xee, 0x6e, 0xc2, 0x7e, 0xb7, 0x3c, 0x0e, 0x61, 0x0f, 0xb7, 0xd9, 0xfd, 0xb7, 0x3c, 0x9c, 0x0f, - 0x89, 0x9b, 0xfb, 0x3d, 0xdd, 0xf3, 0x82, 0x60, 0x71, 0xb2, 0x23, 0x73, 0xb3, 0xe4, 0xc6, 0x1e, - 0xe2, 0x9f, 0x4c, 0xd4, 0xe2, 0x43, 0x75, 0x5b, 0xb7, 0x2c, 0xa6, 0x05, 0x64, 0x56, 0x83, 0x06, - 0xa5, 0xf1, 0xad, 0xda, 0x92, 0xe4, 0x8f, 0x81, 0x24, 0x72, 0x0f, 0x6a, 0x8e, 0xdd, 0xea, 0x1b, - 0x46, 0xe8, 0x2b, 0x1a, 0xa7, 0x58, 0xbe, 0xed, 0x5b, 0x53, 0x02, 0x30, 0x94, 0xa5, 0x6d, 0xc1, - 0x99, 0xb0, 0xd5, 0xc3, 0x49, 0xfd, 0x66, 0x62, 0xd2, 0x15, 0xfb, 0x8e, 0x9f, 0x18, 0x32, 0xe9, - 0x4e, 0x47, 0x62, 0x58, 0x06, 0xa7, 0x5d, 0xed, 0x07, 0x79, 0x38, 0x15, 0x15, 0xc2, 0x0f, 0xd0, - 0x7e, 0x11, 0x26, 0x5d, 0xaa, 0xb7, 0x9b, 0xba, 0x6f, 0xec, 0xf0, 0x68, 0xe9, 0x1c, 0x0f, 0x6f, - 0xe6, 0xa7, 0x88, 0x30, 0x8a, 0xc0, 0x38, 0x1d, 0xd1, 0xa1, 0xce, 0x00, 0x32, 0x11, 0xc2, 0x88, - 0x3e, 0x11, 0x6e, 0x00, 0xc0, 0x90, 0x0d, 0x46, 0x79, 0x12, 0x07, 0x6a, 0xae, 0xee, 0x53, 0xa1, - 0x28, 0x66, 0x4d, 0x52, 0x85, 0x8a, 0x93, 0xf8, 0x0a, 0xc1, 0x23, 0x86, 0x32, 0xc8, 0x15, 0xa8, - 0x1b, 0x8e, 0x6d, 0xf4, 0x5d, 0x97, 0xda, 0x72, 0x97, 0x55, 0x54, 0x6e, 0x85, 0x00, 0x8c, 0x51, - 0x1a, 0xed, 0x87, 0x39, 0x98, 0x8a, 0x36, 0xea, 0x23, 0xb7, 0x6b, 0xef, 0xc4, 0xed, 0xda, 0x0b, - 0x63, 0x98, 0x12, 0x86, 0xd8, 0xb2, 0xff, 0xf9, 0x44, 0xf4, 0xd5, 0xb8, 0xfd, 0x3a, 0x6a, 0x20, - 0xcc, 0x3d, 0xd4, 0x40, 0xf8, 0x69, 0xaa, 0xa8, 0xa1, 0xa9, 0xa2, 0x86, 0xed, 0x44, 0x4b, 0x8f, - 0xf1, 0x4e, 0xb4, 0xfc, 0x31, 0xee, 0x44, 0x23, 0xc9, 0x98, 0x2a, 0x19, 0x92, 0x31, 0x75, 0x83, - 0x64, 0x4c, 0xd5, 0xb1, 0x2d, 0xa6, 0x47, 0x49, 0xc8, 0x54, 0x3b, 0xd1, 0x84, 0x4c, 0xf0, 0xa8, - 0x12, 0x32, 0xd5, 0xb3, 0x26, 0x64, 0xfa, 0xd9, 0x1c, 0x4c, 0xb5, 0x63, 0xc7, 0x4e, 0xb9, 0xed, - 0x31, 0x8b, 0x0a, 0x15, 0x3f, 0xc5, 0x2a, 0x0c, 0x5a, 0x71, 0x18, 0x26, 0x44, 0xa6, 0xa5, 0x41, - 0x9a, 0xfc, 0x78, 0xd2, 0x20, 0xbd, 0x0f, 0x35, 0x4b, 0x2d, 0xf4, 0x3c, 0x46, 0x39, 0xcb, 0xd8, - 0x4f, 0x51, 0x1e, 0xc2, 0xa8, 0xfe, 0x00, 0x84, 0xa1, 0x44, 0xb2, 0x07, 0xe5, 0x2d, 0xae, 0xdd, - 0xc9, 0x08, 0x67, 0x1c, 0xc7, 0x42, 0x12, 0x57, 0x17, 0xc5, 0xb8, 0x10, 0x40, 0x94, 0xd2, 0xb4, - 0xff, 0x59, 0x89, 0x6a, 0x21, 0x27, 0xed, 0x78, 0x7c, 0x29, 0xee, 0x78, 0xbc, 0x9c, 0x74, 0x3c, - 0x0e, 0xa8, 0x50, 0xd2, 0xf9, 0xf8, 0x7c, 0x64, 0xe1, 0x2b, 0xf0, 0x14, 0x49, 0x41, 0x57, 0x4f, - 0x59, 0xfc, 0x1a, 0x30, 0x2d, 0x35, 0x2f, 0x85, 0xe4, 0xcb, 0xc8, 0x64, 0x18, 0xc4, 0xbe, 0x18, - 0x47, 0x63, 0x92, 0x9e, 0x09, 0xf4, 0x54, 0xa6, 0xe4, 0x52, 0xdc, 0x42, 0x1c, 0x64, 0x31, 0x0e, - 0x28, 0xc8, 0xb3, 0x50, 0x76, 0xa9, 0xee, 0x49, 0xf7, 0x61, 0xc4, 0x92, 0x81, 0x1c, 0x8a, 0x12, - 0x1b, 0xf5, 0xa1, 0x56, 0x3e, 0xc2, 0x87, 0xaa, 0x43, 0xdd, 0xd2, 0x3d, 0x5f, 0x74, 0x62, 0x95, - 0x55, 0xe5, 0x4f, 0x1d, 0x4d, 0x91, 0x61, 0x0a, 0x5c, 0xb8, 0x59, 0x5d, 0x09, 0xd9, 0x60, 0x94, - 0x27, 0x69, 0xc3, 0x04, 0x7b, 0xe4, 0x33, 0x5a, 0xbb, 0xe1, 0xcb, 0x99, 0xf2, 0x38, 0x32, 0x02, - 0x33, 0xc9, 0x4a, 0x84, 0x0f, 0xc6, 0xb8, 0x0e, 0x71, 0xb3, 0xc2, 0x28, 0x6e, 0x56, 0xf2, 0x8a, - 0xd0, 0x96, 0xf7, 0x83, 0xcf, 0x5a, 0xe7, 0x9f, 0x35, 0x30, 0xc4, 0x63, 0x14, 0x89, 0x71, 0x5a, - 0xd6, 0x2b, 0xfa, 0xb2, 0x19, 0x54, 0xf1, 0x89, 0x78, 0xaf, 0xd8, 0x8c, 0xa3, 0x31, 0x49, 0x4f, - 0xd6, 0xe1, 0x6c, 0x00, 0x8a, 0x56, 0x63, 0x92, 0xf3, 0x09, 0x0e, 0x84, 0x6c, 0xa6, 0xd0, 0x60, - 0x6a, 0x49, 0x7e, 0x76, 0x86, 0xeb, 0xb2, 0xfe, 0x0d, 0xdd, 0xdb, 0x91, 0x67, 0x25, 0xc2, 0xb3, - 0x33, 0x21, 0x0a, 0xa3, 0x74, 0xe4, 0x2a, 0x80, 0x60, 0xc7, 0x4b, 0x4d, 0xf3, 0x52, 0xc1, 0xb6, - 0x79, 0x33, 0xc0, 0x60, 0x84, 0x4a, 0xfb, 0xbf, 0x39, 0xa8, 0x2a, 0x73, 0x3d, 0x5b, 0x1e, 0xb7, - 0x74, 0xcf, 0x34, 0xe4, 0x80, 0xcf, 0x90, 0x7c, 0x56, 0x65, 0x00, 0x13, 0x41, 0x62, 0xfc, 0x11, - 0x05, 0xef, 0x30, 0x07, 0x5b, 0x3e, 0x53, 0x0e, 0x36, 0xb2, 0x00, 0x45, 0x7b, 0x97, 0xee, 0x1f, - 0xef, 0x74, 0x32, 0xd7, 0x27, 0x6f, 0xdd, 0xa4, 0xfb, 0xc8, 0x0b, 0x6b, 0xbf, 0x91, 0x07, 0x60, - 0xaf, 0x7f, 0x34, 0x4f, 0xd2, 0xe7, 0xa0, 0x22, 0xdd, 0x35, 0x2a, 0x4b, 0x7d, 0x10, 0x6b, 0x27, - 0xc0, 0xa8, 0xf0, 0xe4, 0x69, 0x28, 0xdd, 0xed, 0xd3, 0xbe, 0x0a, 0x8b, 0x08, 0x34, 0x85, 0x37, - 0x19, 0x10, 0x05, 0xee, 0xd1, 0x19, 0x51, 0x95, 0x23, 0xa7, 0xf4, 0xa8, 0x1c, 0x39, 0x35, 0xa8, - 0xdc, 0x72, 0x78, 0xe8, 0xae, 0xf6, 0x02, 0xa8, 0x24, 0x7f, 0xac, 0x7d, 0xa8, 0xf4, 0xe6, 0xe5, - 0xe2, 0xb1, 0x88, 0xca, 0x95, 0xa7, 0xf0, 0xda, 0x7f, 0xc9, 0x03, 0x84, 0x01, 0x95, 0xe4, 0x6f, - 0xe6, 0xe0, 0x89, 0xc0, 0xcd, 0xec, 0x0b, 0x35, 0x91, 0x67, 0x89, 0xce, 0xec, 0x0a, 0x4a, 0x73, - 0x71, 0xf3, 0x9c, 0x0c, 0xeb, 0x69, 0xe2, 0x30, 0xbd, 0x16, 0x04, 0xa1, 0x4a, 0xbb, 0x3d, 0x7f, - 0x7f, 0xd1, 0x74, 0x65, 0xbf, 0x4d, 0x8d, 0xdb, 0xbd, 0x26, 0x69, 0x44, 0x51, 0xb9, 0x49, 0xe2, - 0xbb, 0x31, 0x85, 0xc1, 0x80, 0x0f, 0xd9, 0x81, 0xaa, 0xed, 0xbc, 0xe3, 0xb1, 0x46, 0x94, 0x9d, - 0x78, 0xf4, 0xfc, 0x58, 0xf2, 0x63, 0x08, 0x97, 0x80, 0x7c, 0xc0, 0x8a, 0x2d, 0x3f, 0xd1, 0x2f, - 0xe5, 0xe1, 0x4c, 0x4a, 0x3b, 0x90, 0xd7, 0xe1, 0x94, 0x8c, 0x5d, 0x0d, 0xd3, 0xa5, 0xe7, 0xc2, - 0x74, 0xe9, 0xad, 0x04, 0x0e, 0x07, 0xa8, 0xc9, 0x3b, 0x00, 0x3a, 0x37, 0x96, 0xac, 0x3a, 0x6d, - 0xb5, 0x7e, 0xbf, 0xc6, 0xa6, 0x9b, 0x46, 0x00, 0x7d, 0x70, 0x30, 0xfb, 0x93, 0x69, 0xe1, 0xe8, - 0x89, 0x76, 0x0e, 0x0b, 0x60, 0x84, 0x25, 0xf9, 0x26, 0x80, 0xd8, 0x2b, 0x04, 0xa7, 0xc6, 0x3f, - 0x62, 0xe7, 0x3e, 0xa7, 0x32, 0xf3, 0xcc, 0xbd, 0xd9, 0xd7, 0x6d, 0xdf, 0xf4, 0xf7, 0x45, 0xa6, - 0x8a, 0xdb, 0x01, 0x17, 0x8c, 0x70, 0xd4, 0x7e, 0x27, 0x0f, 0x55, 0x65, 0x16, 0x3f, 0x01, 0x3b, - 0x65, 0x27, 0x66, 0xa7, 0x1c, 0x53, 0x00, 0x7a, 0x9a, 0x95, 0xd2, 0x49, 0x58, 0x29, 0xaf, 0x67, - 0x17, 0xf5, 0x70, 0x1b, 0xe5, 0x3f, 0x2b, 0xc0, 0x94, 0x22, 0xcd, 0x6a, 0xc6, 0x7a, 0x15, 0xa6, - 0x45, 0x24, 0xc5, 0xaa, 0x7e, 0x5f, 0x24, 0xed, 0xe0, 0x0d, 0x56, 0x14, 0x21, 0xae, 0xcd, 0x38, - 0x0a, 0x93, 0xb4, 0xac, 0x5b, 0x0b, 0xd0, 0x26, 0x53, 0x9a, 0x42, 0x4b, 0xd5, 0xa4, 0xe8, 0xd6, - 0xcd, 0x04, 0x0e, 0x07, 0xa8, 0x93, 0x76, 0xb4, 0xe2, 0xa3, 0xb6, 0xa3, 0x95, 0x4e, 0xde, 0x8e, - 0x56, 0x3e, 0x82, 0x1d, 0xed, 0x5f, 0xe4, 0x60, 0x22, 0xfc, 0xa6, 0x8f, 0xdc, 0x8a, 0xb6, 0x1d, - 0xb7, 0xa2, 0x35, 0x32, 0x77, 0xd9, 0x21, 0x36, 0xb4, 0x6f, 0xd5, 0x20, 0x76, 0x56, 0x83, 0x6c, - 0xc1, 0x05, 0x33, 0x35, 0x04, 0x33, 0x32, 0x23, 0x06, 0x07, 0x70, 0x97, 0x87, 0x52, 0xe2, 0x43, - 0xb8, 0x90, 0x3e, 0x54, 0xf7, 0xa8, 0xeb, 0x9b, 0x06, 0x55, 0xef, 0x77, 0x3d, 0xb3, 0x51, 0x49, - 0x6e, 0xf0, 0x82, 0x36, 0xbd, 0x2d, 0x05, 0x60, 0x20, 0x8a, 0x6c, 0x41, 0x89, 0xb6, 0x3b, 0x54, - 0x5d, 0xa0, 0x92, 0x31, 0x7f, 0x68, 0xd0, 0x9e, 0xec, 0xc9, 0x43, 0xc1, 0x9a, 0x78, 0xd1, 0x4d, - 0x73, 0x31, 0x63, 0x57, 0x3e, 0xea, 0x56, 0x79, 0x37, 0xb0, 0x1c, 0x95, 0xc6, 0x34, 0xc1, 0x3d, - 0xc4, 0x6e, 0xe4, 0x41, 0xed, 0x9e, 0xee, 0x53, 0xb7, 0xab, 0xbb, 0xbb, 0xd2, 0xec, 0x36, 0xfa, - 0x1b, 0xde, 0x51, 0x9c, 0xc2, 0x37, 0x0c, 0x40, 0x18, 0xca, 0x61, 0x33, 0x84, 0x2f, 0x2d, 0x24, - 0x2a, 0x4b, 0xe2, 0xe8, 0x42, 0x95, 0xad, 0x45, 0xfa, 0x3b, 0x82, 0x47, 0x0c, 0x65, 0x90, 0xbd, - 0x58, 0xb6, 0x6d, 0x91, 0x63, 0x3d, 0xc3, 0x75, 0x0d, 0x8a, 0x55, 0xb8, 0x24, 0x0e, 0xc9, 0xda, - 0xfd, 0x61, 0x0e, 0xa6, 0x13, 0x23, 0x47, 0x6e, 0x3b, 0x6f, 0x8c, 0x2b, 0x40, 0x5c, 0x1d, 0x8e, - 0x88, 0x01, 0x31, 0x29, 0x35, 0x9a, 0x05, 0x1b, 0x1e, 0x69, 0x16, 0xec, 0xff, 0x5e, 0x0a, 0x57, - 0xcb, 0x93, 0x36, 0xb7, 0xbc, 0x10, 0x37, 0xb7, 0x5c, 0x4a, 0x9a, 0x5b, 0x12, 0x61, 0x02, 0xc7, - 0x8f, 0xf4, 0x4e, 0x58, 0x29, 0x8a, 0x8f, 0xc0, 0x4a, 0x71, 0x05, 0xea, 0x7b, 0x7c, 0xf2, 0x13, - 0x59, 0x82, 0x4a, 0x7c, 0x75, 0xe7, 0x8b, 0xd9, 0xed, 0x10, 0x8c, 0x51, 0x1a, 0x7e, 0xcd, 0x98, - 0xb8, 0x7d, 0x26, 0x48, 0xb1, 0x2b, 0x8b, 0xb4, 0x42, 0x30, 0x46, 0x69, 0x78, 0x90, 0xa8, 0x69, - 0xef, 0x8a, 0x02, 0x15, 0x5e, 0x40, 0x04, 0x89, 0x2a, 0x20, 0x86, 0x78, 0xf2, 0x1c, 0x54, 0xfb, - 0xed, 0x6d, 0x41, 0x5b, 0xe5, 0xb4, 0x5c, 0xf1, 0xdf, 0x5c, 0x5c, 0x92, 0x59, 0x8b, 0x14, 0x96, - 0xd5, 0xa4, 0xab, 0xf7, 0x14, 0x82, 0x77, 0x75, 0x59, 0x93, 0xd5, 0x10, 0x8c, 0x51, 0x1a, 0xf2, - 0x65, 0x98, 0x72, 0x69, 0xbb, 0x6f, 0xd0, 0xa0, 0x14, 0xf0, 0x52, 0x32, 0xa7, 0x61, 0x14, 0x83, - 0x09, 0xca, 0x21, 0xb6, 0x96, 0xfa, 0x48, 0xb6, 0x96, 0xaf, 0xc2, 0x54, 0xdb, 0xd5, 0x4d, 0x9b, - 0xb6, 0xd7, 0x6c, 0x1e, 0x0b, 0x22, 0x43, 0x55, 0x03, 0xfb, 0xea, 0x62, 0x0c, 0x8b, 0x09, 0x6a, - 0x6d, 0x09, 0xc4, 0x89, 0x31, 0x32, 0x0b, 0xa5, 0x1d, 0xdf, 0xef, 0x29, 0x8f, 0x15, 0xdf, 0xde, - 0xf3, 0xb3, 0x73, 0x28, 0xe0, 0xe4, 0x22, 0x14, 0xd9, 0x1f, 0x19, 0xf2, 0xce, 0xf7, 0x9f, 0x0c, - 0x8f, 0x1c, 0xaa, 0xfd, 0x6e, 0x1e, 0x4a, 0x22, 0x63, 0xe3, 0x32, 0x9c, 0x31, 0x6d, 0xd3, 0x37, - 0x75, 0x8b, 0x9f, 0x6f, 0x8a, 0xc6, 0xd6, 0x94, 0x9a, 0x4f, 0x1e, 0x1e, 0xcc, 0x9e, 0x59, 0x1e, - 0x44, 0x63, 0x5a, 0x19, 0xd6, 0xc8, 0x32, 0x73, 0xbc, 0xe2, 0x22, 0x84, 0x8b, 0x9c, 0xc7, 0x31, - 0x0c, 0x26, 0x28, 0x99, 0xae, 0xdb, 0x1b, 0x08, 0x9a, 0x29, 0x09, 0x5d, 0x37, 0x1e, 0xc7, 0x12, - 0xa7, 0xe3, 0x7b, 0x30, 0xe1, 0x6f, 0x0e, 0x8e, 0xb9, 0xc9, 0xf8, 0x3b, 0xb1, 0x07, 0x4b, 0xe0, - 0x70, 0x80, 0x9a, 0x71, 0xd8, 0xd6, 0x4d, 0xab, 0xef, 0xd2, 0x90, 0x43, 0x29, 0xe4, 0xb0, 0x94, - 0xc0, 0xe1, 0x00, 0xb5, 0xf6, 0xbb, 0x39, 0x00, 0x71, 0x15, 0x0d, 0x37, 0x03, 0x8d, 0x29, 0x4b, - 0x3e, 0xe9, 0x43, 0x6d, 0x4b, 0x19, 0x82, 0x32, 0xa7, 0x50, 0x17, 0xf5, 0x0b, 0x0d, 0x4b, 0xe2, - 0x56, 0x23, 0xf5, 0x88, 0xa1, 0x24, 0xed, 0xef, 0xe6, 0x60, 0x3a, 0x41, 0x4d, 0xd6, 0xa0, 0xaa, - 0x72, 0xd0, 0x1d, 0xef, 0xad, 0xc4, 0x18, 0x96, 0x45, 0x31, 0x60, 0x32, 0xfe, 0xa4, 0xf4, 0x3f, - 0x93, 0x57, 0xdf, 0x80, 0x87, 0x53, 0x5e, 0x05, 0x90, 0xb9, 0x62, 0xda, 0x6d, 0x57, 0xaa, 0xa0, - 0xe1, 0x3a, 0x1a, 0x60, 0x30, 0x42, 0x75, 0xb4, 0xc8, 0xbf, 0x97, 0x61, 0xa2, 0xe7, 0x3a, 0x6c, - 0x82, 0x70, 0xb9, 0x76, 0x9b, 0x08, 0xd7, 0x5e, 0x8f, 0xe0, 0x30, 0x46, 0x49, 0x74, 0x69, 0x54, - 0x2a, 0x8f, 0xe5, 0x12, 0xa4, 0x54, 0xb3, 0xd2, 0xff, 0xca, 0xc3, 0x84, 0x6c, 0x04, 0x61, 0x90, - 0x7b, 0x94, 0xcd, 0xa0, 0x02, 0x1a, 0xd3, 0x9a, 0x61, 0x21, 0x82, 0xc3, 0x18, 0x25, 0x59, 0x64, - 0x03, 0x76, 0xcb, 0x33, 0x5c, 0x93, 0x87, 0xec, 0xf3, 0xd2, 0x22, 0xf4, 0x3b, 0x38, 0xa0, 0xdd, - 0x4a, 0xe0, 0x71, 0xa0, 0x04, 0x79, 0x1e, 0xaa, 0x5d, 0xfd, 0xfe, 0xa6, 0xad, 0x1b, 0xbb, 0x72, - 0xf5, 0x0a, 0xb4, 0xf8, 0x55, 0x09, 0xc7, 0x80, 0xe2, 0x24, 0x9a, 0xfe, 0x97, 0x8b, 0x10, 0xee, - 0x1b, 0xc9, 0x79, 0x28, 0x74, 0xf5, 0xfb, 0x72, 0xc3, 0xce, 0x6d, 0x8b, 0xab, 0xfa, 0x7d, 0x64, - 0x30, 0x8e, 0x32, 0x6d, 0xb9, 0x21, 0x17, 0x28, 0xd3, 0x46, 0x06, 0x23, 0xef, 0xc2, 0x94, 0xab, - 0x77, 0x7b, 0x9b, 0x3d, 0xb5, 0x07, 0x1e, 0xf1, 0xc0, 0xac, 0x58, 0xd5, 0x62, 0x9c, 0x30, 0xc1, - 0x99, 0xf4, 0xa1, 0x24, 0x4c, 0x67, 0xc5, 0x8c, 0x8e, 0xe3, 0xe0, 0xa5, 0x99, 0x26, 0xe8, 0xb8, - 0x54, 0x5e, 0x15, 0x98, 0x80, 0xa2, 0x90, 0xc6, 0xc4, 0x76, 0x9d, 0x76, 0x90, 0x67, 0x62, 0x2c, - 0x62, 0x57, 0x19, 0xc3, 0x01, 0xb1, 0x1c, 0x8a, 0x42, 0x9a, 0x30, 0xa5, 0xb0, 0x3e, 0xd8, 0x16, - 0xcd, 0xc2, 0x7b, 0x42, 0x55, 0x99, 0x52, 0x22, 0x08, 0x8c, 0xd3, 0x91, 0x65, 0x28, 0xf8, 0xbe, - 0x25, 0xb7, 0x0f, 0x23, 0x5d, 0xff, 0xb1, 0xb1, 0xb1, 0x82, 0x8c, 0x87, 0xf6, 0x57, 0xf3, 0x40, - 0x22, 0xf5, 0xbb, 0xee, 0x34, 0x75, 0x63, 0xf7, 0x16, 0xfb, 0xe8, 0x86, 0xe3, 0x58, 0x8b, 0xce, - 0x3d, 0x5b, 0x2c, 0x74, 0x23, 0x1e, 0xf5, 0xe6, 0x1f, 0x7d, 0x21, 0xc6, 0x09, 0x13, 0x9c, 0xc9, - 0x12, 0x10, 0xd6, 0x0d, 0x24, 0xc4, 0xa0, 0xb6, 0xaf, 0x72, 0x66, 0x4c, 0x36, 0xcf, 0x31, 0x35, - 0x06, 0x07, 0xb0, 0x98, 0x52, 0x82, 0x29, 0x0d, 0xc1, 0x49, 0xf2, 0x08, 0x23, 0x61, 0x24, 0xe2, - 0x4a, 0xc3, 0xc6, 0x20, 0x1a, 0xd3, 0xca, 0x68, 0x17, 0x60, 0x26, 0xd2, 0x28, 0xcb, 0xf6, 0x2a, - 0xed, 0x3a, 0xee, 0xbe, 0xb0, 0xbb, 0xfe, 0x6a, 0x11, 0x06, 0xbe, 0x28, 0xf9, 0xb9, 0x1c, 0xd4, - 0x3c, 0x63, 0x87, 0xb6, 0xfb, 0x16, 0x55, 0x6b, 0xc7, 0xea, 0x58, 0x7a, 0xaf, 0x62, 0x2a, 0x12, - 0x84, 0xa6, 0x61, 0x30, 0x94, 0x4c, 0xde, 0x87, 0x8a, 0x4b, 0x2d, 0xfd, 0x3e, 0x55, 0x1f, 0xec, - 0xe6, 0x38, 0x2a, 0x81, 0x82, 0xa5, 0xfa, 0x1a, 0x49, 0x38, 0x2a, 0x99, 0xe4, 0xe7, 0x73, 0x00, - 0x8e, 0x6d, 0xed, 0x2f, 0x6f, 0x6f, 0x7a, 0xf2, 0xf8, 0x42, 0xfd, 0xea, 0xad, 0x71, 0x54, 0x61, - 0x2d, 0xe0, 0x2a, 0x0c, 0xfd, 0xa9, 0x28, 0x8c, 0x08, 0x67, 0x4d, 0xd1, 0x11, 0xbd, 0x59, 0xce, - 0x26, 0x63, 0x69, 0x0a, 0x39, 0x40, 0x06, 0x9a, 0x42, 0xc2, 0x51, 0xc9, 0xd4, 0xb6, 0x20, 0xbd, - 0x8e, 0xc3, 0xba, 0x69, 0x6e, 0x84, 0x6e, 0xfa, 0x1f, 0x73, 0x31, 0x21, 0x48, 0xdb, 0xa6, 0x48, - 0xbd, 0x42, 0x2e, 0x43, 0x91, 0xcd, 0x31, 0xc9, 0x2c, 0xd3, 0xdc, 0x12, 0xcf, 0x31, 0x6c, 0xc6, - 0xef, 0xbb, 0x96, 0x5c, 0x4e, 0x2b, 0x31, 0x8f, 0xd8, 0x1e, 0x54, 0x3d, 0x6a, 0xfb, 0xa6, 0x4d, - 0x2d, 0xf9, 0x09, 0x47, 0xf7, 0xd4, 0x88, 0x3a, 0x49, 0x6e, 0xf2, 0x58, 0xaf, 0x3c, 0xbe, 0x27, - 0x60, 0x18, 0xc8, 0x22, 0xe7, 0x20, 0xdf, 0xde, 0x92, 0x7a, 0x72, 0xf9, 0xf0, 0x60, 0x36, 0xbf, - 0xd8, 0xc4, 0x7c, 0x7b, 0x4b, 0x3b, 0x0b, 0x29, 0x9d, 0x4e, 0x3b, 0x07, 0xa9, 0xa3, 0x41, 0xfb, - 0xcd, 0x3c, 0x0c, 0x4c, 0xf4, 0xbc, 0x63, 0xba, 0x41, 0xf3, 0xc8, 0xb1, 0x71, 0x6b, 0x3c, 0x63, - 0x43, 0x71, 0x1d, 0xe8, 0x98, 0x21, 0x0a, 0x23, 0xc2, 0xc9, 0x5f, 0xcb, 0xc1, 0xa4, 0x19, 0x9d, - 0x52, 0xe4, 0x7c, 0xf1, 0xe6, 0x38, 0xaa, 0x13, 0x9b, 0xab, 0xc4, 0x89, 0xd4, 0x61, 0x58, 0x8c, - 0xd7, 0x42, 0xfb, 0xf5, 0x1c, 0xd4, 0x78, 0x95, 0x3f, 0x21, 0xca, 0xf5, 0x6f, 0x15, 0xe1, 0x4c, - 0x4a, 0xf7, 0x62, 0xea, 0x65, 0x57, 0xf7, 0x7c, 0xa9, 0x03, 0x26, 0xd4, 0xcb, 0xd5, 0x00, 0x83, - 0x11, 0x2a, 0xf2, 0x79, 0xa8, 0x51, 0xbb, 0xdd, 0x73, 0x4c, 0xdb, 0xf7, 0xe4, 0x3d, 0x2f, 0x7c, - 0x2f, 0x72, 0x4d, 0x01, 0x31, 0xc4, 0x93, 0xfb, 0x30, 0xa1, 0xfa, 0x2c, 0xdf, 0x05, 0x65, 0xb5, - 0x8e, 0x06, 0x8d, 0x2e, 0x33, 0x97, 0x44, 0x78, 0x63, 0x4c, 0x12, 0xf7, 0x2f, 0x28, 0xe2, 0xec, - 0xfe, 0x85, 0x40, 0xac, 0xf0, 0x2f, 0xa8, 0x47, 0x0c, 0x65, 0x10, 0x07, 0xea, 0xaa, 0x02, 0x1b, - 0x2b, 0xad, 0xb1, 0x9c, 0x4e, 0x94, 0x97, 0xc0, 0x07, 0x4c, 0x31, 0x2a, 0x81, 0x6c, 0x43, 0x95, - 0x4b, 0x67, 0xd2, 0x2a, 0x63, 0x90, 0x26, 0xa3, 0x66, 0x05, 0x47, 0x0c, 0x78, 0x6b, 0xff, 0x20, - 0x07, 0x93, 0x48, 0x7d, 0xd6, 0xf7, 0xc3, 0xcb, 0xf2, 0xe4, 0x49, 0x38, 0xd9, 0xdf, 0x5f, 0xcf, - 0x10, 0x29, 0xc1, 0xf9, 0xc8, 0xb3, 0x5c, 0xba, 0xb1, 0xbb, 0xb6, 0xbd, 0x8d, 0x8a, 0x3b, 0xb9, - 0x06, 0x35, 0xc7, 0x96, 0x1b, 0x78, 0x39, 0xff, 0xfe, 0x84, 0x08, 0x57, 0x97, 0xc0, 0x07, 0x07, - 0xb3, 0xe7, 0x82, 0x87, 0x58, 0x25, 0x31, 0x2c, 0xa9, 0xfd, 0x1c, 0x9b, 0xfc, 0x1d, 0xcb, 0x32, - 0xed, 0x4e, 0x3c, 0xfe, 0x8d, 0x58, 0x30, 0x25, 0x36, 0x19, 0x7b, 0xba, 0x69, 0xe9, 0x5b, 0x16, - 0xfd, 0x48, 0xbf, 0x67, 0xdf, 0x37, 0xad, 0x39, 0xd6, 0xb7, 0x7d, 0x77, 0x6e, 0xd9, 0xf6, 0xd7, - 0xdc, 0x96, 0xef, 0x9a, 0x76, 0x47, 0xa8, 0x6f, 0xab, 0x31, 0x5e, 0x98, 0xe0, 0xad, 0xfd, 0x9b, - 0x22, 0xf0, 0x53, 0x56, 0xe4, 0x8b, 0x50, 0xeb, 0x52, 0x63, 0x47, 0xb7, 0x4d, 0x4f, 0x5d, 0x6f, - 0xc0, 0x66, 0xc4, 0xda, 0xaa, 0x02, 0x3e, 0x60, 0xd3, 0x7e, 0xa3, 0xb5, 0xc2, 0x33, 0x33, 0x84, - 0xb4, 0xc4, 0x80, 0x72, 0xc7, 0xf3, 0xf4, 0x9e, 0x99, 0x39, 0x82, 0x59, 0x64, 0xd2, 0x17, 0xd6, - 0x7e, 0xf1, 0x1f, 0x25, 0x6b, 0x62, 0x40, 0xa9, 0x67, 0xe9, 0xa6, 0x9d, 0x39, 0xbc, 0x9d, 0xbd, - 0xc1, 0x3a, 0xe3, 0x24, 0x73, 0x25, 0xb1, 0xbf, 0x28, 0x78, 0x93, 0x3e, 0xd4, 0x3d, 0xc3, 0xd5, - 0xbb, 0xde, 0x8e, 0x7e, 0xf5, 0xc5, 0x97, 0x32, 0x4f, 0x0c, 0xa1, 0x28, 0x31, 0x68, 0x16, 0xb0, - 0xb1, 0xda, 0xba, 0xd1, 0xb8, 0xfa, 0xe2, 0x4b, 0x18, 0x95, 0x13, 0x15, 0xfb, 0xe2, 0x95, 0xab, - 0xd9, 0xef, 0x64, 0x4e, 0x17, 0xfb, 0xe2, 0x95, 0xab, 0x18, 0x95, 0xc3, 0x9a, 0xd4, 0x89, 0xec, - 0x60, 0xb3, 0x09, 0x5c, 0x0b, 0x23, 0x8b, 0xf8, 0x5f, 0x14, 0xbc, 0xb5, 0xff, 0x91, 0x83, 0x5a, - 0x80, 0x67, 0x8b, 0x88, 0xc8, 0x11, 0xbc, 0xbc, 0x38, 0xc2, 0xaa, 0xb4, 0x20, 0x8b, 0x62, 0xc0, - 0x84, 0xbc, 0x0d, 0x13, 0xe2, 0xbf, 0xcc, 0xd9, 0x9f, 0x3f, 0xf6, 0xc5, 0x00, 0x0b, 0x91, 0xe2, - 0x18, 0x63, 0x46, 0x5e, 0x81, 0x49, 0x6e, 0x34, 0x53, 0xab, 0x88, 0x34, 0x48, 0x04, 0x41, 0x6c, - 0x1b, 0x51, 0x24, 0xc6, 0x69, 0x83, 0x17, 0xe7, 0x5f, 0x82, 0x6c, 0x02, 0xb0, 0x95, 0x54, 0xd6, - 0xf2, 0x58, 0xaf, 0xce, 0x23, 0x25, 0x36, 0x83, 0xc2, 0x18, 0x61, 0x94, 0x72, 0xf5, 0x42, 0x7e, - 0xdc, 0x57, 0x2f, 0xcc, 0x43, 0x6d, 0x47, 0xb7, 0xdb, 0xde, 0x8e, 0xbe, 0x4b, 0xe5, 0xd1, 0xdf, - 0xc0, 0x45, 0x76, 0x43, 0x21, 0x30, 0xa4, 0xd1, 0xbe, 0x53, 0x06, 0x11, 0x7b, 0x4d, 0x9e, 0x87, - 0x6a, 0xdb, 0xf4, 0xa2, 0xb1, 0x47, 0x81, 0x3d, 0x65, 0x51, 0xc2, 0x31, 0xa0, 0x88, 0xda, 0x30, - 0x4a, 0x09, 0x1b, 0x86, 0xb4, 0x7c, 0x14, 0x22, 0x28, 0x65, 0xf9, 0x78, 0x15, 0xa6, 0x2d, 0xc7, - 0xd9, 0x65, 0x93, 0x73, 0xf4, 0x08, 0xe3, 0xa4, 0x70, 0x2e, 0xad, 0xc4, 0x51, 0x98, 0xa4, 0x25, - 0x9b, 0xf0, 0xe4, 0x7b, 0xd4, 0x75, 0x64, 0x94, 0x5f, 0xcb, 0xa2, 0xb4, 0xa7, 0xd8, 0x08, 0x0b, - 0x10, 0x3f, 0x61, 0xf9, 0xf5, 0x74, 0x12, 0x1c, 0x56, 0x96, 0x9f, 0x09, 0xd7, 0xdd, 0x0e, 0xf5, - 0xd7, 0x5d, 0xc7, 0xa0, 0x9e, 0x67, 0xda, 0x1d, 0xc5, 0xb6, 0x1c, 0xb2, 0xdd, 0x48, 0x27, 0xc1, - 0x61, 0x65, 0xc9, 0x5b, 0x30, 0x23, 0x50, 0xc2, 0x35, 0xd6, 0x10, 0x93, 0xb8, 0x69, 0x99, 0xfe, - 0xbe, 0x74, 0x85, 0x70, 0x8d, 0x71, 0x63, 0x08, 0x0d, 0x0e, 0x2d, 0x4d, 0xde, 0x80, 0x53, 0x2a, - 0x28, 0x77, 0x9d, 0x69, 0xe3, 0xba, 0x45, 0xa5, 0xc3, 0x44, 0x1e, 0x85, 0x55, 0x47, 0x41, 0x31, - 0x41, 0x85, 0x03, 0xe5, 0x08, 0xc2, 0x39, 0x1e, 0x74, 0xbf, 0xd9, 0x5b, 0x70, 0x1c, 0xab, 0xed, - 0xdc, 0xb3, 0xd5, 0xbb, 0x0b, 0xaf, 0x0a, 0xbf, 0x42, 0xb1, 0x95, 0x4a, 0x81, 0x43, 0x4a, 0xb2, - 0x37, 0xe7, 0x98, 0x45, 0xe7, 0x9e, 0x9d, 0xe4, 0x0a, 0xe1, 0x9b, 0xb7, 0x86, 0xd0, 0xe0, 0xd0, - 0xd2, 0xdc, 0x7c, 0x91, 0x78, 0x83, 0xcd, 0x9e, 0x0c, 0x57, 0x15, 0xbb, 0xc4, 0x01, 0x2c, 0xa6, - 0x94, 0x20, 0x2b, 0x70, 0x36, 0x09, 0x65, 0xe2, 0x64, 0xe4, 0xaa, 0xd8, 0xfd, 0xa7, 0xe0, 0x31, - 0xb5, 0x94, 0x56, 0x87, 0x5a, 0x70, 0xb5, 0xbe, 0xf6, 0xaf, 0xf3, 0x30, 0x9d, 0x48, 0x1a, 0x7c, - 0x02, 0x61, 0x51, 0x76, 0x2c, 0x2c, 0x6a, 0xf4, 0x2d, 0x64, 0xa2, 0xe6, 0x43, 0xa3, 0xa3, 0xf6, - 0x12, 0xd1, 0x51, 0xb7, 0xc6, 0x26, 0xf1, 0xe1, 0x41, 0x52, 0x87, 0x39, 0x38, 0x93, 0x28, 0x71, - 0x02, 0x71, 0x35, 0xdd, 0x78, 0x5c, 0xcd, 0x8d, 0x71, 0xbd, 0xec, 0x90, 0xf0, 0x9a, 0xff, 0x33, - 0xf8, 0x92, 0x2d, 0x11, 0x92, 0x56, 0x91, 0xf9, 0x59, 0xe5, 0x3b, 0x2e, 0x66, 0xad, 0x08, 0xff, - 0xbe, 0xf1, 0x7c, 0x97, 0x76, 0x07, 0x95, 0x14, 0xe2, 0x41, 0x55, 0x25, 0x61, 0x1d, 0x6f, 0xc0, - 0x5d, 0xd0, 0xd8, 0x41, 0x5e, 0xed, 0x40, 0x90, 0xf6, 0x8b, 0x05, 0x78, 0x22, 0xb5, 0x53, 0x9c, - 0x9c, 0x83, 0xff, 0x95, 0xb8, 0x83, 0xff, 0x99, 0xa4, 0x83, 0xff, 0x6c, 0xa2, 0x7e, 0x8f, 0xb1, - 0x9f, 0x7f, 0x8c, 0xbe, 0x6b, 0x6d, 0x1a, 0x26, 0x63, 0x89, 0x83, 0xb5, 0x1f, 0x94, 0xa1, 0x1e, - 0xe9, 0x49, 0x7f, 0xf2, 0x12, 0xb6, 0x92, 0x2f, 0xc3, 0x54, 0xd7, 0xeb, 0x2c, 0x2f, 0xde, 0xa0, - 0x7a, 0x9b, 0xba, 0x37, 0xa9, 0x4a, 0x62, 0x24, 0x36, 0x73, 0x31, 0x0c, 0x26, 0x28, 0xc9, 0x0a, - 0x3c, 0xe1, 0xd2, 0xbb, 0x7d, 0xea, 0xf9, 0x71, 0xd7, 0xb8, 0x54, 0x66, 0xe4, 0x7a, 0x96, 0x20, - 0xf0, 0x30, 0xbd, 0x10, 0x9b, 0xa3, 0x84, 0x3b, 0xa7, 0x9c, 0x71, 0xa0, 0xaa, 0x0f, 0xca, 0x8d, - 0x5a, 0xd2, 0x48, 0x12, 0x42, 0x94, 0x1b, 0x27, 0xfd, 0x40, 0x65, 0xe5, 0x63, 0x3c, 0x50, 0x19, - 0x3d, 0xc5, 0x5b, 0x7d, 0xe8, 0x29, 0xde, 0x61, 0x47, 0x55, 0x6b, 0x8f, 0xc3, 0x51, 0x55, 0xed, - 0x03, 0x88, 0x35, 0x38, 0x71, 0xa0, 0x16, 0xbc, 0x6c, 0xe6, 0x73, 0x25, 0xe1, 0xa1, 0x46, 0x6e, - 0x87, 0x0a, 0x1e, 0x31, 0x94, 0xa1, 0x6d, 0xb3, 0x61, 0xce, 0xd3, 0xcb, 0xca, 0xbb, 0x03, 0x37, - 0xa1, 0x22, 0x83, 0x35, 0x46, 0xf4, 0x4c, 0x71, 0xdb, 0x8c, 0x0a, 0xe2, 0x55, 0xbc, 0xb4, 0x7f, - 0x99, 0x87, 0x5a, 0x10, 0xd0, 0x46, 0x2e, 0x43, 0xd1, 0x0e, 0x6d, 0x88, 0x81, 0xce, 0xc1, 0xad, - 0x87, 0x1c, 0x13, 0x6f, 0x88, 0xfc, 0xa3, 0x6f, 0x88, 0xe8, 0x11, 0xdd, 0x42, 0x86, 0x23, 0xba, - 0x3d, 0xa8, 0xf8, 0xae, 0xd9, 0xe9, 0x50, 0x37, 0xb3, 0xab, 0x35, 0x68, 0xae, 0x0d, 0xc1, 0x50, - 0xb6, 0xac, 0x78, 0x40, 0x25, 0x46, 0x7b, 0x17, 0x4e, 0x25, 0x29, 0xf9, 0xd1, 0x3b, 0x69, 0xb7, - 0x97, 0x6d, 0x1c, 0x1e, 0xbd, 0x93, 0x70, 0x0c, 0x28, 0xd8, 0x60, 0x62, 0x9f, 0xe9, 0x3d, 0xc7, - 0x56, 0x8b, 0x20, 0x1f, 0x4c, 0x1b, 0x12, 0x86, 0x01, 0x56, 0xfb, 0xcf, 0x05, 0x38, 0x1f, 0x86, - 0x25, 0xae, 0xea, 0xb6, 0xde, 0x89, 0x5f, 0x14, 0xfa, 0x69, 0x7e, 0xb2, 0xb1, 0x5c, 0xac, 0x5a, - 0x78, 0x0c, 0x2e, 0x56, 0xfd, 0xc3, 0x02, 0xf0, 0x5c, 0x02, 0xe4, 0x03, 0x98, 0x50, 0xed, 0xd9, - 0x0a, 0x33, 0xa7, 0x5c, 0xcb, 0xfc, 0x39, 0x79, 0xca, 0x82, 0x20, 0x86, 0x24, 0x0a, 0xc5, 0x98, - 0x40, 0xe2, 0x0c, 0x24, 0x52, 0x19, 0x93, 0xf0, 0x61, 0x39, 0x54, 0xdc, 0xc1, 0x1c, 0x2a, 0x63, - 0x92, 0x38, 0x34, 0x7d, 0x0a, 0xf9, 0xd9, 0x1c, 0x4c, 0xba, 0x51, 0x93, 0xb4, 0x9c, 0x3f, 0x96, - 0x32, 0xb8, 0x21, 0x22, 0xdc, 0xa2, 0x07, 0x3c, 0xa3, 0x76, 0xef, 0xb8, 0x4c, 0xed, 0x3f, 0xe5, - 0x60, 0xb2, 0x65, 0x99, 0x6d, 0xd3, 0xee, 0x3c, 0xc2, 0xbb, 0x64, 0xd7, 0xa0, 0xe4, 0x59, 0x66, - 0x9b, 0x8e, 0x98, 0x72, 0x85, 0x6b, 0x66, 0xac, 0x96, 0x4c, 0x41, 0x61, 0x3f, 0xf1, 0xcb, 0x69, - 0x0b, 0x47, 0xb8, 0x9c, 0xf6, 0x77, 0xaa, 0x20, 0x33, 0x71, 0x90, 0x3e, 0xd4, 0x3a, 0xea, 0xba, - 0x4f, 0xf9, 0x8e, 0x37, 0x32, 0x5c, 0x6e, 0x17, 0xbb, 0x38, 0x54, 0x7c, 0xef, 0x00, 0x88, 0xa1, - 0x24, 0x42, 0xa1, 0xc4, 0x53, 0xa1, 0x65, 0xce, 0x1f, 0x1f, 0x49, 0x7a, 0x27, 0x5a, 0x86, 0x03, - 0x50, 0x70, 0x27, 0xba, 0x0c, 0x0c, 0x2d, 0x64, 0x8c, 0x85, 0x0a, 0x6f, 0x6a, 0x48, 0x46, 0x97, - 0x32, 0x11, 0xb6, 0xee, 0x7b, 0x99, 0x6f, 0x8c, 0x08, 0x4f, 0x96, 0xca, 0x83, 0xa7, 0xba, 0xef, - 0x21, 0x67, 0x4d, 0x7e, 0x0a, 0xea, 0xbe, 0xab, 0xdb, 0xde, 0xb6, 0xe3, 0x76, 0xa9, 0x2b, 0xed, - 0xf0, 0x4b, 0x19, 0x12, 0x9a, 0x6c, 0x84, 0xdc, 0x44, 0x58, 0x50, 0x0c, 0x84, 0x51, 0x69, 0x64, - 0x17, 0xaa, 0xfd, 0xb6, 0xa8, 0x98, 0xd4, 0xb7, 0x1b, 0x19, 0x24, 0x47, 0x8f, 0x39, 0xaa, 0x27, - 0x0c, 0x04, 0xb0, 0xde, 0x18, 0xa6, 0x57, 0xaf, 0x64, 0xec, 0x8d, 0x89, 0xd4, 0xaf, 0xc3, 0xf3, - 0xaa, 0x93, 0x6e, 0x68, 0x6d, 0xa8, 0x66, 0x6c, 0xdc, 0xd8, 0xae, 0x51, 0xde, 0xfd, 0x91, 0xb4, - 0x35, 0x98, 0x50, 0xee, 0xf1, 0xe0, 0x3a, 0xa9, 0x86, 0x5f, 0xcb, 0x18, 0xa3, 0x17, 0x4d, 0xb0, - 0x23, 0x20, 0x28, 0x05, 0x90, 0x6f, 0x40, 0xc1, 0xbb, 0xeb, 0xc9, 0x03, 0x0a, 0x19, 0x3c, 0x29, - 0x77, 0x55, 0xdf, 0xe4, 0x56, 0xee, 0xd6, 0x5d, 0x0f, 0x19, 0x5f, 0xed, 0xb7, 0xf3, 0x50, 0x61, - 0x38, 0xb6, 0x4e, 0xcd, 0x43, 0x4d, 0xbf, 0xe7, 0x21, 0xed, 0x84, 0x89, 0xca, 0x83, 0x59, 0xa8, - 0x71, 0xa7, 0x25, 0x10, 0x18, 0xd2, 0xb0, 0x02, 0xfc, 0x68, 0x33, 0xf7, 0xa7, 0xe7, 0xe3, 0x05, - 0xde, 0x54, 0x08, 0x0c, 0x69, 0xc8, 0x6d, 0x38, 0xc7, 0x1f, 0xd6, 0xee, 0xd9, 0xd4, 0x6d, 0xdc, - 0x69, 0x35, 0x0c, 0xc3, 0xe9, 0x73, 0x9f, 0x4d, 0x21, 0x76, 0x3a, 0xe1, 0xdc, 0x9b, 0xa9, 0x54, - 0x38, 0xa4, 0x34, 0xd9, 0x03, 0xd0, 0x3d, 0xaf, 0xdf, 0xa5, 0xe8, 0x04, 0x87, 0x92, 0x32, 0xec, - 0xe8, 0xef, 0xb4, 0x1a, 0x01, 0x37, 0xe1, 0x25, 0x09, 0x9f, 0x31, 0x22, 0x49, 0xfb, 0x5e, 0x09, - 0x6a, 0x41, 0xcb, 0x7e, 0x82, 0xdb, 0x6f, 0x01, 0x4e, 0xef, 0x99, 0x9e, 0x29, 0x4c, 0xf6, 0xd1, - 0x73, 0x90, 0x25, 0xa1, 0x0e, 0xde, 0x4e, 0x22, 0x71, 0x90, 0x9e, 0x2c, 0xc3, 0x99, 0xae, 0x7e, - 0xff, 0x56, 0xbf, 0xbb, 0x45, 0xdd, 0xb5, 0x6d, 0x69, 0x3f, 0xf2, 0x64, 0x70, 0x3a, 0x8f, 0x5f, - 0x5a, 0x1d, 0x44, 0x63, 0x5a, 0x19, 0xf2, 0x2a, 0x4c, 0xdf, 0xd3, 0x4d, 0x6e, 0x35, 0x88, 0x7a, - 0x37, 0x4a, 0xc2, 0xf7, 0x72, 0x27, 0x8e, 0xc2, 0x24, 0x2d, 0xb9, 0x02, 0x75, 0x15, 0x94, 0xb1, - 0xe9, 0x5a, 0x2a, 0xcf, 0xc6, 0xe1, 0xc1, 0x6c, 0x5d, 0x39, 0xd1, 0x36, 0x71, 0x05, 0xa3, 0x34, - 0xe4, 0xcb, 0x30, 0xa5, 0xfb, 0xbe, 0x6b, 0x6e, 0xf5, 0x7d, 0xde, 0xd4, 0xe2, 0x44, 0x94, 0xb4, - 0x8d, 0x34, 0x62, 0x18, 0x4c, 0x50, 0x92, 0x35, 0x78, 0x42, 0x1a, 0xc9, 0xe2, 0x84, 0x32, 0xd3, - 0x38, 0x57, 0x5d, 0x57, 0xd3, 0x08, 0x30, 0xbd, 0x5c, 0xa2, 0x3b, 0xc3, 0x89, 0x75, 0xe7, 0x2e, - 0x48, 0xe3, 0x22, 0x31, 0x20, 0x72, 0xc1, 0xbf, 0x4c, 0xa7, 0x39, 0x7f, 0x34, 0x35, 0x27, 0xcc, - 0x3d, 0x13, 0xde, 0xe4, 0x1a, 0xb0, 0xc2, 0x08, 0x5b, 0xed, 0x5f, 0xe5, 0xa1, 0xb0, 0xb1, 0xd2, - 0x22, 0x6f, 0x00, 0x31, 0x6d, 0x8f, 0x1a, 0x7d, 0x97, 0xb6, 0x76, 0xcd, 0xde, 0x6d, 0xea, 0x9a, - 0xdb, 0xfb, 0xd2, 0xaf, 0x17, 0x98, 0xfd, 0x96, 0x07, 0x28, 0x30, 0xa5, 0x14, 0x77, 0xdb, 0xea, - 0x0b, 0xd4, 0xcd, 0xe0, 0xb6, 0x6d, 0x84, 0xc5, 0x31, 0xc6, 0x8c, 0x6c, 0x02, 0x18, 0x21, 0xeb, - 0xc2, 0xb1, 0x7d, 0xad, 0x11, 0xc6, 0x11, 0x46, 0x04, 0xa1, 0xb6, 0xcb, 0x48, 0x39, 0xd7, 0xe2, - 0x71, 0xb8, 0xf2, 0x05, 0xf1, 0xa6, 0x2a, 0x8b, 0x21, 0x1b, 0xcd, 0x86, 0xc9, 0x0d, 0xbd, 0x13, - 0x36, 0x3c, 0xf9, 0x12, 0x54, 0x9d, 0x5e, 0x44, 0x4b, 0xac, 0xf1, 0xeb, 0x13, 0xaa, 0x6b, 0x12, - 0xf6, 0xe0, 0x60, 0x76, 0x72, 0xc5, 0xe9, 0x98, 0x86, 0x02, 0x60, 0x40, 0x4e, 0x34, 0x28, 0xf3, - 0x64, 0x9f, 0x2a, 0x00, 0x8a, 0x2f, 0x53, 0xfc, 0xfe, 0x73, 0x0f, 0x25, 0x46, 0xfb, 0x56, 0x11, - 0xc2, 0x63, 0x86, 0xc4, 0x83, 0xb2, 0x48, 0xfa, 0x24, 0x15, 0xd2, 0x47, 0x9a, 0x5f, 0x4a, 0x8a, - 0x22, 0x1d, 0x28, 0xbc, 0xeb, 0x6c, 0x65, 0xd6, 0x47, 0x23, 0x19, 0xcb, 0xc5, 0x9c, 0x11, 0x01, - 0x20, 0x93, 0x40, 0x7e, 0x39, 0x07, 0xa7, 0xbd, 0xa4, 0x15, 0x41, 0x76, 0x07, 0xcc, 0x6e, 0x2e, - 0x49, 0xda, 0x25, 0xc4, 0x3d, 0x17, 0x43, 0xd1, 0x38, 0x58, 0x17, 0xd6, 0xfe, 0xe2, 0x30, 0x9c, - 0xec, 0x4e, 0xa3, 0xb7, 0xbf, 0x38, 0x60, 0x17, 0x6f, 0xff, 0x38, 0x0c, 0xa5, 0x28, 0xed, 0xdf, - 0xe5, 0xa0, 0xb0, 0xb9, 0xb8, 0x74, 0xe2, 0x36, 0x40, 0xd2, 0x81, 0x4a, 0x47, 0xdc, 0x7e, 0x97, - 0x39, 0xb3, 0x86, 0xbc, 0x45, 0x4f, 0xa8, 0x7d, 0xf2, 0x01, 0x15, 0x77, 0x6d, 0x1f, 0xca, 0x9b, - 0x8b, 0x72, 0x4b, 0x7f, 0xc2, 0x76, 0xce, 0x9f, 0x82, 0x40, 0xdb, 0x3e, 0x79, 0xe1, 0xdf, 0xca, - 0x41, 0x7c, 0x83, 0x71, 0xf2, 0x55, 0xf8, 0x41, 0x0e, 0x12, 0xd9, 0xdc, 0xc8, 0x4b, 0xf2, 0xb2, - 0x9f, 0xf8, 0x89, 0x7d, 0x75, 0xd9, 0x0f, 0x89, 0x53, 0x47, 0x2e, 0xfd, 0xf9, 0x30, 0x07, 0x93, - 0x6e, 0x34, 0x3e, 0x4e, 0x4e, 0x19, 0x19, 0xa2, 0x7e, 0xd3, 0xa2, 0xed, 0xe4, 0x71, 0x8d, 0x28, - 0x0a, 0xe3, 0x72, 0xb5, 0x7f, 0x98, 0x87, 0xf2, 0x89, 0x25, 0x4d, 0xa6, 0x31, 0xaf, 0xfb, 0x42, - 0xc6, 0x19, 0x61, 0xa8, 0xb3, 0xbd, 0x9b, 0x70, 0xb6, 0x5f, 0xcb, 0x2a, 0xe8, 0xe1, 0x3e, 0xf6, - 0x7f, 0x9a, 0x03, 0x39, 0x1f, 0x2d, 0xdb, 0x9e, 0xaf, 0xdb, 0x06, 0x25, 0x46, 0x30, 0xf9, 0x65, - 0xf5, 0xbc, 0xca, 0x8c, 0x0b, 0x62, 0xbd, 0xe3, 0xff, 0xd5, 0x64, 0x47, 0x9e, 0x87, 0xea, 0x8e, - 0xe3, 0xf9, 0x76, 0xa8, 0xb9, 0x07, 0x16, 0xea, 0x1b, 0x12, 0x8e, 0x01, 0x05, 0xf9, 0x1c, 0x54, - 0xa4, 0x43, 0x47, 0x86, 0x1a, 0x05, 0x06, 0x78, 0xe9, 0xf1, 0x41, 0x85, 0xd7, 0xbe, 0x0e, 0xd3, - 0xc9, 0x14, 0xc4, 0xd7, 0x53, 0x53, 0x10, 0x3f, 0x3d, 0x24, 0x05, 0x71, 0x7d, 0x78, 0xfa, 0xe1, - 0xdf, 0x2f, 0xc0, 0xc4, 0x27, 0x26, 0xf5, 0x70, 0x4a, 0x5a, 0x98, 0x42, 0xc6, 0xb4, 0x30, 0xc5, - 0x63, 0xa5, 0x85, 0xf9, 0x24, 0xe4, 0x6c, 0xf9, 0x7e, 0x0e, 0xe0, 0xc4, 0xf2, 0x1e, 0xb7, 0xe3, - 0x91, 0x25, 0x99, 0xc7, 0x55, 0x7a, 0x40, 0xc9, 0x77, 0x2a, 0xea, 0x95, 0xb8, 0x9b, 0xfe, 0xc3, - 0x1c, 0x4c, 0xe9, 0xb1, 0x0c, 0x28, 0x99, 0x75, 0xca, 0x44, 0x42, 0x95, 0xe0, 0x34, 0x7b, 0x1c, - 0x8e, 0x09, 0xb1, 0xfc, 0x2c, 0xad, 0x8c, 0xa1, 0x88, 0x6c, 0xd8, 0x07, 0xee, 0x03, 0x96, 0x67, - 0x69, 0x23, 0x4f, 0x1f, 0x91, 0x71, 0xa6, 0x30, 0x96, 0x8c, 0x33, 0x51, 0x8f, 0x72, 0xf1, 0xa1, - 0x1e, 0xe5, 0x3d, 0xa8, 0x6d, 0xbb, 0x4e, 0x97, 0x27, 0x75, 0xe1, 0xf7, 0x10, 0x65, 0x99, 0xa4, - 0x17, 0x9c, 0xee, 0x96, 0x69, 0xd3, 0x36, 0x4f, 0x18, 0x13, 0x18, 0x2f, 0x96, 0x14, 0x7f, 0x0c, - 0x45, 0x71, 0xd7, 0xa2, 0x23, 0xa4, 0x96, 0xc7, 0x29, 0x35, 0x98, 0x4b, 0x37, 0x04, 0x77, 0x54, - 0x62, 0xe2, 0x89, 0x5c, 0x2a, 0x27, 0x94, 0xc8, 0x65, 0x3f, 0x9a, 0x1f, 0xa7, 0x9a, 0xd1, 0x02, - 0x7a, 0xbc, 0x84, 0xb2, 0x8f, 0x4d, 0x6a, 0x15, 0xed, 0x17, 0x2a, 0x6a, 0xa5, 0x79, 0xec, 0xee, - 0xb5, 0xfc, 0x34, 0xb5, 0x6c, 0x87, 0x0e, 0xe4, 0x7d, 0xad, 0x9e, 0x60, 0xde, 0xd7, 0xda, 0x78, - 0xf2, 0xbe, 0x42, 0xb6, 0xbc, 0xaf, 0xf5, 0x31, 0xe5, 0x7d, 0x9d, 0x18, 0x57, 0xde, 0xd7, 0xc9, - 0x91, 0xf2, 0xbe, 0x4e, 0x1d, 0x29, 0xef, 0xeb, 0x41, 0x01, 0x12, 0xbb, 0xf6, 0x4f, 0x83, 0x1d, - 0xfe, 0x58, 0x05, 0x3b, 0x7c, 0x3b, 0x0f, 0xe1, 0x6a, 0x74, 0xcc, 0xe3, 0x11, 0x6f, 0xf1, 0xe4, - 0x14, 0xe2, 0x2e, 0xf2, 0xd1, 0x14, 0xf9, 0x09, 0x99, 0xc8, 0x42, 0x5c, 0x42, 0x1e, 0x70, 0x23, - 0x1e, 0x80, 0x19, 0x5c, 0x10, 0x9f, 0xd9, 0x85, 0x1b, 0xde, 0x35, 0x2f, 0xac, 0xa9, 0xe1, 0x33, - 0x46, 0xc4, 0x68, 0xdf, 0x2b, 0x40, 0x59, 0xfa, 0xfe, 0x29, 0x94, 0xb6, 0xcd, 0xf0, 0xc8, 0xfb, - 0xe8, 0x36, 0xc1, 0x25, 0xc6, 0x45, 0x30, 0x15, 0x3e, 0x6a, 0x0e, 0x40, 0xc1, 0x9d, 0x3b, 0x1f, - 0x45, 0xcc, 0x81, 0x6c, 0xbf, 0x0c, 0xce, 0xc7, 0x68, 0xec, 0x82, 0x74, 0x3e, 0x0a, 0x10, 0x2a, - 0x19, 0xc2, 0xd7, 0x29, 0xee, 0x6e, 0x2f, 0x64, 0xf6, 0x75, 0x46, 0x42, 0xe7, 0x94, 0xaf, 0x53, - 0xdc, 0xdc, 0xae, 0x64, 0x90, 0xf7, 0xa1, 0xae, 0x1b, 0x46, 0xbf, 0xdb, 0xb7, 0xb8, 0xed, 0x38, - 0xeb, 0x35, 0xbe, 0x8d, 0x90, 0x97, 0x14, 0xcb, 0x77, 0x38, 0x11, 0x30, 0x46, 0xe5, 0x35, 0xbf, - 0xf1, 0xdd, 0x1f, 0x5d, 0xfa, 0xcc, 0xf7, 0x7f, 0x74, 0xe9, 0x33, 0x3f, 0xfc, 0xd1, 0xa5, 0xcf, - 0x7c, 0xeb, 0xf0, 0x52, 0xee, 0xbb, 0x87, 0x97, 0x72, 0xdf, 0x3f, 0xbc, 0x94, 0xfb, 0xe1, 0xe1, - 0xa5, 0xdc, 0xbf, 0x3f, 0xbc, 0x94, 0xfb, 0xcb, 0xff, 0xe1, 0xd2, 0x67, 0xbe, 0xfe, 0xc5, 0xb0, - 0x3a, 0xf3, 0xaa, 0x3a, 0xf3, 0x4a, 0xf8, 0x7c, 0x6f, 0xb7, 0x33, 0xcf, 0xaa, 0x13, 0x42, 0x54, - 0x75, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x87, 0xd4, 0x8c, 0xfa, 0xab, 0xba, 0x00, 0x00, + // 9612 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x8c, 0x1c, 0x57, + 0x76, 0x18, 0xbc, 0xfd, 0xee, 0x3e, 0x3d, 0x0f, 0xf2, 0x92, 0xa2, 0x86, 0x5c, 0x8a, 0x43, 0x97, + 0x2c, 0xad, 0xf6, 0x5b, 0x79, 0xe6, 0x23, 0x57, 0xd2, 0x6a, 0x57, 0xab, 0x95, 0xba, 0x67, 0x38, + 0xe4, 0x88, 0x33, 0x9c, 0xd1, 0xe9, 0x19, 0x52, 0xbb, 0xca, 0xae, 0x52, 0x53, 0x7d, 0xa7, 0xa7, + 0x34, 0xd5, 0x55, 0xcd, 0xaa, 0xea, 0x21, 0x47, 0x8e, 0xa0, 0xb5, 0x0d, 0x47, 0xeb, 0xc4, 0x40, + 0x82, 0x04, 0x81, 0x8d, 0x04, 0x81, 0x61, 0xc0, 0x80, 0x7f, 0x04, 0x06, 0x82, 0x24, 0xf6, 0x0f, + 0x1b, 0xc8, 0x63, 0x7f, 0x38, 0x8b, 0x78, 0x1d, 0x6f, 0x16, 0x01, 0xb2, 0x41, 0x92, 0x49, 0x76, + 0x92, 0xfc, 0x48, 0x7e, 0x39, 0x46, 0x9e, 0x4c, 0x10, 0x07, 0xf7, 0x55, 0xaf, 0xae, 0xa6, 0x66, + 0xba, 0x9a, 0x23, 0xca, 0xd6, 0xaf, 0xee, 0x3a, 0xe7, 0xdc, 0x73, 0x6e, 0xdd, 0xba, 0x8f, 0x73, + 0xcf, 0x39, 0xf7, 0x5c, 0xb8, 0xde, 0x31, 0xfd, 0x9d, 0xfe, 0xd6, 0x9c, 0xe1, 0x74, 0xe7, 0xed, + 0x7e, 0x57, 0xef, 0xb9, 0xce, 0xbb, 0xfc, 0xcf, 0xb6, 0xe5, 0xdc, 0x9b, 0xef, 0xed, 0x76, 0xe6, + 0xf5, 0x9e, 0xe9, 0x85, 0x90, 0xbd, 0x2b, 0xba, 0xd5, 0xdb, 0xd1, 0xaf, 0xcc, 0x77, 0xa8, 0x4d, + 0x5d, 0xdd, 0xa7, 0xed, 0xb9, 0x9e, 0xeb, 0xf8, 0x0e, 0xf9, 0x52, 0xc8, 0x68, 0x4e, 0x31, 0x9a, + 0x53, 0xc5, 0xe6, 0x7a, 0xbb, 0x9d, 0x39, 0xc6, 0x28, 0x84, 0x28, 0x46, 0x17, 0x7e, 0x2a, 0x52, + 0x83, 0x8e, 0xd3, 0x71, 0xe6, 0x39, 0xbf, 0xad, 0xfe, 0x36, 0x7f, 0xe2, 0x0f, 0xfc, 0x9f, 0x90, + 0x73, 0x41, 0xdb, 0x7d, 0xd9, 0x9b, 0x33, 0x1d, 0x56, 0xad, 0x79, 0xc3, 0x71, 0xe9, 0xfc, 0xde, + 0x40, 0x5d, 0x2e, 0xbc, 0x10, 0xd2, 0x74, 0x75, 0x63, 0xc7, 0xb4, 0xa9, 0xbb, 0xaf, 0xde, 0x65, + 0xde, 0xa5, 0x9e, 0xd3, 0x77, 0x0d, 0x7a, 0xac, 0x52, 0xde, 0x7c, 0x97, 0xfa, 0x7a, 0x9a, 0xac, + 0xf9, 0x61, 0xa5, 0xdc, 0xbe, 0xed, 0x9b, 0xdd, 0x41, 0x31, 0x2f, 0x7d, 0x54, 0x01, 0xcf, 0xd8, + 0xa1, 0x5d, 0x7d, 0xa0, 0xdc, 0x17, 0x87, 0x95, 0xeb, 0xfb, 0xa6, 0x35, 0x6f, 0xda, 0xbe, 0xe7, + 0xbb, 0xc9, 0x42, 0xda, 0xdf, 0xce, 0xc3, 0x64, 0xe3, 0x4e, 0xab, 0xe1, 0x79, 0xfd, 0x2e, 0x45, + 0xc7, 0xa2, 0xe4, 0xf3, 0x50, 0x71, 0x1d, 0x8b, 0x36, 0x5c, 0x7b, 0x26, 0x77, 0x39, 0xf7, 0x5c, + 0xad, 0x39, 0xfd, 0xbd, 0x83, 0xd9, 0xcf, 0x1c, 0x1e, 0xcc, 0x56, 0x18, 0xba, 0x81, 0xb7, 0x50, + 0xe1, 0xc9, 0x15, 0xa8, 0x7b, 0xd4, 0xf3, 0x4c, 0xc7, 0xbe, 0xa5, 0x77, 0xe9, 0x4c, 0x5e, 0x90, + 0x1f, 0x1e, 0xcc, 0xd6, 0x5b, 0x21, 0x18, 0xa3, 0x34, 0xe4, 0x55, 0x98, 0x6e, 0xf7, 0x5d, 0xdd, + 0x37, 0x1d, 0xbb, 0x45, 0x0d, 0xc7, 0x6e, 0x7b, 0x33, 0x85, 0xcb, 0xb9, 0xe7, 0x4a, 0xcd, 0x33, + 0x87, 0x07, 0xb3, 0xd3, 0x8b, 0x71, 0x14, 0x26, 0x69, 0xc9, 0x1c, 0x00, 0xbd, 0xef, 0x53, 0xd7, + 0xd6, 0xad, 0xe5, 0xc5, 0x99, 0x22, 0x17, 0x38, 0x75, 0x78, 0x30, 0x0b, 0xd7, 0x02, 0x28, 0x46, + 0x28, 0x88, 0x06, 0xe5, 0x9e, 0x63, 0x99, 0xc6, 0xfe, 0x4c, 0x89, 0xd3, 0xc2, 0xe1, 0xc1, 0x6c, + 0x79, 0x9d, 0x43, 0x50, 0x62, 0x18, 0x4f, 0xf1, 0xaf, 0xe1, 0xda, 0xde, 0x4c, 0xf9, 0x72, 0x41, + 0xf1, 0x14, 0x74, 0x0d, 0xbc, 0xe5, 0x61, 0x84, 0x42, 0xfb, 0x47, 0x00, 0x67, 0x1a, 0x5b, 0x9e, + 0xef, 0xea, 0x86, 0xbf, 0xee, 0xb4, 0x37, 0x68, 0xb7, 0x67, 0xe9, 0x3e, 0x25, 0xbb, 0x50, 0x65, + 0x7d, 0xa0, 0xad, 0xfb, 0x3a, 0x6f, 0xb9, 0xfa, 0xd5, 0xc6, 0xdc, 0x88, 0x7d, 0x7e, 0x6e, 0x55, + 0x32, 0x6a, 0x4e, 0x1c, 0x1e, 0xcc, 0x56, 0xd5, 0x13, 0x06, 0x02, 0xc8, 0x2f, 0xe7, 0x60, 0xc2, + 0x76, 0xda, 0xb4, 0x45, 0x2d, 0x6a, 0xf8, 0x8e, 0x3b, 0x93, 0xbf, 0x5c, 0x78, 0xae, 0x7e, 0xf5, + 0x5b, 0x23, 0x4b, 0x4c, 0x79, 0xa3, 0xb9, 0x5b, 0x11, 0x01, 0xd7, 0x6c, 0xdf, 0xdd, 0x6f, 0x9e, + 0x95, 0x7d, 0x61, 0x22, 0x8a, 0xc2, 0x58, 0x4d, 0xc8, 0x26, 0xd4, 0x7d, 0xc7, 0xa2, 0xe2, 0xc3, + 0xb1, 0xcf, 0xcb, 0x2a, 0x76, 0x69, 0x4e, 0xf4, 0x4e, 0x26, 0x7e, 0x8e, 0x0d, 0xcb, 0xb9, 0xbd, + 0x2b, 0x73, 0x1b, 0x01, 0x59, 0xf3, 0x8c, 0x64, 0x5c, 0x0f, 0x61, 0x1e, 0x46, 0xf9, 0x10, 0x0a, + 0xd3, 0x1e, 0x35, 0xfa, 0xae, 0xe9, 0xef, 0x2f, 0x38, 0xb6, 0x4f, 0xef, 0xfb, 0xfc, 0xfb, 0xd7, + 0xaf, 0x3e, 0x9b, 0xc6, 0x7a, 0xdd, 0x69, 0xb7, 0xe2, 0xd4, 0xa2, 0x87, 0x25, 0x80, 0x98, 0xe4, + 0x49, 0x6c, 0x38, 0x65, 0x76, 0xf5, 0x0e, 0x5d, 0xef, 0x5b, 0x56, 0x8b, 0x1a, 0x2e, 0xf5, 0xbd, + 0x99, 0x12, 0x7f, 0x85, 0xe7, 0xd2, 0xe4, 0xac, 0x38, 0x86, 0x6e, 0xad, 0x6d, 0xbd, 0x4b, 0x0d, + 0x1f, 0xe9, 0x36, 0x75, 0xa9, 0x6d, 0xd0, 0xe6, 0x8c, 0x7c, 0x99, 0x53, 0xcb, 0x09, 0x4e, 0x38, + 0xc0, 0x9b, 0x5c, 0x87, 0xd3, 0x3d, 0xd7, 0x74, 0x78, 0x15, 0x2c, 0xdd, 0xf3, 0xf8, 0x48, 0x2a, + 0xf3, 0xce, 0x7a, 0x5e, 0xb2, 0x39, 0xbd, 0x9e, 0x24, 0xc0, 0xc1, 0x32, 0xe4, 0x39, 0xa8, 0x2a, + 0xe0, 0x4c, 0x85, 0x0f, 0x29, 0xde, 0x77, 0x54, 0x59, 0x0c, 0xb0, 0x64, 0x09, 0xaa, 0xfa, 0xf6, + 0xb6, 0x69, 0x33, 0xca, 0x2a, 0x6f, 0xc2, 0x8b, 0x69, 0xaf, 0xd6, 0x90, 0x34, 0x82, 0x8f, 0x7a, + 0xc2, 0xa0, 0x2c, 0x79, 0x03, 0x88, 0x47, 0xdd, 0x3d, 0xd3, 0xa0, 0x0d, 0xc3, 0x70, 0xfa, 0xb6, + 0xcf, 0xeb, 0x5e, 0xe3, 0x75, 0xbf, 0x20, 0xeb, 0x4e, 0x5a, 0x03, 0x14, 0x98, 0x52, 0x8a, 0xbc, + 0x0e, 0xa7, 0xe4, 0xf4, 0x16, 0xb6, 0x02, 0x70, 0x4e, 0x67, 0x59, 0x43, 0x62, 0x02, 0x87, 0x03, + 0xd4, 0xa4, 0x0d, 0x17, 0xf5, 0xbe, 0xef, 0x74, 0x19, 0xcb, 0xb8, 0xd0, 0x0d, 0x67, 0x97, 0xda, + 0x33, 0xf5, 0xcb, 0xb9, 0xe7, 0xaa, 0xcd, 0xcb, 0x87, 0x07, 0xb3, 0x17, 0x1b, 0x0f, 0xa1, 0xc3, + 0x87, 0x72, 0x21, 0x6b, 0x50, 0x6b, 0xdb, 0x9e, 0x98, 0x19, 0x66, 0x26, 0x78, 0x05, 0xaf, 0xc8, + 0x57, 0xad, 0x2d, 0xde, 0x6a, 0x09, 0xc4, 0x83, 0x83, 0xd9, 0x8b, 0x83, 0xab, 0xd0, 0x5c, 0x80, + 0xc7, 0x90, 0x07, 0x59, 0xe5, 0x0c, 0x17, 0x1c, 0x7b, 0xdb, 0xec, 0xcc, 0x4c, 0xf2, 0xaf, 0x71, + 0x79, 0x48, 0x87, 0x5e, 0xbc, 0xd5, 0x12, 0x74, 0xcd, 0x49, 0x29, 0x4e, 0x3c, 0x62, 0xc8, 0x81, + 0xb4, 0x61, 0x4a, 0xad, 0x5f, 0x0b, 0x96, 0x6e, 0x76, 0xbd, 0x99, 0x29, 0xde, 0x79, 0x7f, 0x72, + 0x08, 0x4f, 0x8c, 0x12, 0x37, 0xcf, 0xc9, 0x57, 0x99, 0x8a, 0x81, 0x3d, 0x4c, 0xf0, 0xbc, 0xf0, + 0x1a, 0x9c, 0x1e, 0x98, 0x1b, 0xc8, 0x29, 0x28, 0xec, 0xd2, 0x7d, 0xb1, 0x68, 0x20, 0xfb, 0x4b, + 0xce, 0x42, 0x69, 0x4f, 0xb7, 0xfa, 0x72, 0x65, 0x40, 0xf1, 0xf0, 0x95, 0xfc, 0xcb, 0x39, 0xed, + 0xf7, 0x4b, 0x30, 0xa1, 0x66, 0x9c, 0x96, 0x69, 0xef, 0x92, 0x3b, 0x50, 0xb0, 0x9c, 0x8e, 0x9c, + 0x37, 0xbf, 0x3a, 0xf2, 0x2c, 0xb6, 0xe2, 0x74, 0x9a, 0x95, 0xc3, 0x83, 0xd9, 0xc2, 0x8a, 0xd3, + 0x41, 0xc6, 0x91, 0x18, 0x50, 0xda, 0xd5, 0xb7, 0x77, 0x75, 0x5e, 0x87, 0xfa, 0xd5, 0xe6, 0xc8, + 0xac, 0x6f, 0x32, 0x2e, 0xac, 0xae, 0xcd, 0xda, 0xe1, 0xc1, 0x6c, 0x89, 0x3f, 0xa2, 0xe0, 0x4d, + 0x1c, 0xa8, 0x6d, 0x59, 0xba, 0xb1, 0xbb, 0xe3, 0x58, 0x94, 0xaf, 0x67, 0x59, 0x04, 0x35, 0x15, + 0x27, 0xf1, 0x99, 0x83, 0x47, 0x0c, 0x65, 0x10, 0x03, 0xca, 0xfd, 0xb6, 0x67, 0xda, 0xbb, 0x72, + 0x0e, 0x7c, 0x6d, 0x64, 0x69, 0x9b, 0x8b, 0xfc, 0x9d, 0xf8, 0xc2, 0x28, 0xfe, 0xa3, 0x64, 0xcd, + 0x9a, 0x8e, 0x8d, 0x54, 0xca, 0xd7, 0xce, 0x2c, 0x6f, 0xc4, 0x06, 0x12, 0x0d, 0x9b, 0x8e, 0x3f, + 0xa2, 0xe0, 0x4d, 0xde, 0x86, 0x82, 0x77, 0xd7, 0xe3, 0x33, 0x5e, 0xfd, 0xea, 0xeb, 0xa3, 0x8b, + 0xb8, 0xeb, 0x71, 0x01, 0xfc, 0xe3, 0xb7, 0xee, 0x7a, 0xc8, 0xb8, 0x92, 0x0e, 0x94, 0x7b, 0x7d, + 0xcb, 0xd3, 0x5d, 0x3e, 0x23, 0xd6, 0xaf, 0x2e, 0x8c, 0xcc, 0x7f, 0x9d, 0xb3, 0x09, 0x9b, 0x4a, + 0x3c, 0xa3, 0x64, 0xaf, 0xfd, 0x78, 0x12, 0xa6, 0x54, 0x7f, 0xbe, 0x4d, 0x5d, 0x9f, 0xde, 0x27, + 0x97, 0xa1, 0x68, 0xb3, 0x59, 0x4c, 0x28, 0x51, 0x13, 0x72, 0x64, 0x15, 0xf9, 0xec, 0xc5, 0x31, + 0xec, 0x23, 0x8a, 0x51, 0x25, 0xfb, 0xe6, 0xe8, 0x1f, 0xb1, 0xc5, 0xd9, 0x88, 0x9a, 0x89, 0xff, + 0x28, 0x59, 0x93, 0xb7, 0xa1, 0xc8, 0xfb, 0x89, 0xe8, 0x95, 0xaf, 0x8e, 0x2e, 0x82, 0xbd, 0x7a, + 0x95, 0xbd, 0x01, 0xef, 0x23, 0x9c, 0x29, 0x1b, 0xb5, 0xfd, 0xf6, 0xb6, 0xec, 0x83, 0x5f, 0xcd, + 0xd0, 0x07, 0x97, 0xc4, 0x87, 0xdb, 0x5c, 0x5c, 0x42, 0xc6, 0x91, 0xfc, 0xa5, 0x1c, 0x9c, 0x36, + 0x1c, 0xdb, 0xd7, 0x99, 0x16, 0xab, 0xf4, 0x11, 0xd9, 0x0f, 0xdf, 0x18, 0x59, 0xce, 0x42, 0x92, + 0x63, 0xf3, 0x09, 0xb6, 0xbc, 0x0e, 0x80, 0x71, 0x50, 0x36, 0xf9, 0x1b, 0x39, 0x78, 0x82, 0x2d, + 0x7b, 0x03, 0xc4, 0xb2, 0xeb, 0x8e, 0xb3, 0x56, 0xe7, 0x0f, 0x0f, 0x66, 0x9f, 0x58, 0x4e, 0x13, + 0x86, 0xe9, 0x75, 0x60, 0xb5, 0x3b, 0xa3, 0x0f, 0x6a, 0x70, 0xb2, 0xdb, 0xaf, 0x8c, 0x53, 0x2b, + 0x6c, 0x7e, 0x56, 0x76, 0xe5, 0x34, 0x25, 0x18, 0xd3, 0x6a, 0x41, 0xae, 0x41, 0x65, 0xcf, 0xb1, + 0xfa, 0x5d, 0xea, 0xcd, 0x54, 0xf9, 0x6a, 0x74, 0x21, 0x6d, 0x35, 0xba, 0xcd, 0x49, 0xc2, 0xed, + 0x86, 0x78, 0xf6, 0x50, 0x95, 0x25, 0x26, 0x94, 0x2d, 0xb3, 0x6b, 0xfa, 0x1e, 0xd7, 0x31, 0xea, + 0x57, 0xaf, 0x8d, 0xfc, 0x5a, 0x62, 0x88, 0xae, 0x70, 0x66, 0x62, 0xd4, 0x88, 0xff, 0x28, 0x05, + 0xf0, 0xa9, 0xcf, 0xd0, 0x2d, 0xa1, 0x83, 0xd4, 0xaf, 0x7e, 0x6d, 0xf4, 0x61, 0xc3, 0xb8, 0x34, + 0x27, 0xe5, 0x3b, 0x95, 0xf8, 0x23, 0x0a, 0xde, 0xe4, 0x9b, 0x30, 0x15, 0xfb, 0x9a, 0xde, 0x4c, + 0x9d, 0xb7, 0xce, 0x53, 0x69, 0xad, 0x13, 0x50, 0x85, 0x8b, 0x74, 0xac, 0x87, 0x78, 0x98, 0x60, + 0x46, 0x6e, 0x42, 0xd5, 0x33, 0xdb, 0xd4, 0xd0, 0x5d, 0x6f, 0x66, 0xe2, 0x28, 0x8c, 0x4f, 0x49, + 0xc6, 0xd5, 0x96, 0x2c, 0x86, 0x01, 0x03, 0xbe, 0x49, 0xd2, 0x5d, 0xdf, 0x14, 0x3a, 0xfd, 0x24, + 0xd7, 0x2f, 0xc5, 0x26, 0x29, 0x80, 0x62, 0x84, 0x82, 0xd1, 0xb3, 0xb2, 0xcb, 0x76, 0xaf, 0xef, + 0x0b, 0x1d, 0x44, 0x6e, 0xaa, 0x5a, 0x01, 0x14, 0x23, 0x14, 0xe4, 0x37, 0x72, 0xf0, 0xd9, 0xf0, + 0x71, 0x70, 0x90, 0x4d, 0x8f, 0x7d, 0x90, 0xcd, 0x1e, 0x1e, 0xcc, 0x7e, 0xb6, 0x35, 0x5c, 0x24, + 0x3e, 0xac, 0x3e, 0xe4, 0xc3, 0x1c, 0x4c, 0xf5, 0x7b, 0x6d, 0xdd, 0xa7, 0x2d, 0x9f, 0xed, 0xa7, + 0x3b, 0xfb, 0x33, 0xa7, 0x78, 0x15, 0xaf, 0x8f, 0x3e, 0x0b, 0xc6, 0xd8, 0x85, 0x9f, 0x39, 0x0e, + 0xc7, 0x84, 0x58, 0xd2, 0x81, 0x8a, 0xe3, 0xb6, 0xa9, 0x4b, 0xdb, 0x33, 0xa7, 0x33, 0x2e, 0xa2, + 0x6b, 0x82, 0x4f, 0xb3, 0xce, 0x86, 0x9f, 0x7c, 0x40, 0xc5, 0x5d, 0x7b, 0x17, 0x4e, 0x37, 0x0c, + 0xa3, 0xdf, 0xed, 0x5b, 0xba, 0xef, 0xb8, 0x77, 0x4c, 0xbb, 0xed, 0xdc, 0x23, 0x9b, 0x50, 0x61, + 0x6a, 0xb8, 0xd3, 0xf7, 0xa5, 0xee, 0x36, 0x17, 0xe9, 0x63, 0x81, 0x19, 0x22, 0x14, 0xca, 0x36, + 0xb0, 0xac, 0xd7, 0xa9, 0x9d, 0xbe, 0x90, 0xb5, 0x21, 0x58, 0xa0, 0xe2, 0xa5, 0xdd, 0x81, 0xc9, + 0x46, 0xdf, 0xdf, 0x71, 0x5c, 0xf3, 0x3d, 0x4e, 0x46, 0x96, 0xa0, 0xe4, 0x73, 0x35, 0x5e, 0x48, + 0x79, 0x26, 0xad, 0x27, 0x8b, 0x2d, 0xd5, 0x4d, 0xba, 0xaf, 0xf4, 0x52, 0xa1, 0x6e, 0x08, 0xb5, + 0x5e, 0x14, 0xd7, 0x7e, 0x29, 0x0f, 0x95, 0xa6, 0x6e, 0xec, 0x3a, 0xdb, 0xdb, 0xe4, 0x2d, 0xa8, + 0x9a, 0xb6, 0x4f, 0xdd, 0x3d, 0xdd, 0x1a, 0xb1, 0xf2, 0x7c, 0x67, 0xb4, 0x2c, 0x79, 0x60, 0xc0, + 0x8d, 0xcc, 0x42, 0xc9, 0xf3, 0x69, 0xcf, 0xe3, 0x0b, 0xfb, 0xa4, 0xd4, 0x7a, 0x18, 0x00, 0x05, + 0x9c, 0x68, 0x50, 0xde, 0xd6, 0xf9, 0xbe, 0x9d, 0xad, 0xcb, 0x39, 0x31, 0x07, 0x2d, 0x71, 0x08, + 0x4a, 0x0c, 0x59, 0x86, 0x82, 0xa1, 0xf7, 0xe4, 0xe2, 0x7a, 0xdc, 0x9a, 0xf1, 0xe5, 0x74, 0x41, + 0xef, 0x21, 0xe3, 0xc1, 0xc4, 0xbd, 0x6b, 0xfa, 0x3e, 0x75, 0xf9, 0x12, 0x2a, 0xc5, 0xbd, 0xc1, + 0x21, 0x28, 0x31, 0xda, 0xaf, 0xe6, 0xa0, 0xd6, 0xd4, 0x3d, 0xd3, 0x60, 0x0d, 0x4f, 0x16, 0xa0, + 0xd8, 0xf7, 0xa8, 0x7b, 0xbc, 0xe6, 0xe6, 0xea, 0xc1, 0xa6, 0x47, 0x5d, 0xe4, 0x85, 0xc9, 0x1a, + 0x54, 0x7b, 0xba, 0xe7, 0xdd, 0x73, 0xdc, 0xb6, 0x54, 0x71, 0x8e, 0xc8, 0x48, 0xec, 0x5c, 0x65, + 0x51, 0x0c, 0x98, 0x68, 0x75, 0x08, 0xd5, 0x61, 0xed, 0x17, 0x73, 0x70, 0xa6, 0xd9, 0xdf, 0xde, + 0xa6, 0xae, 0xdc, 0xa8, 0xc9, 0x2d, 0x50, 0x1f, 0x6a, 0xef, 0x52, 0xdf, 0xf3, 0x5d, 0xaa, 0x77, + 0xa5, 0xd8, 0x1b, 0x23, 0x0f, 0x89, 0x37, 0xa8, 0xdf, 0xe2, 0x9c, 0xa2, 0x3b, 0xaf, 0x00, 0x88, + 0xa1, 0x24, 0xed, 0xbb, 0x65, 0x98, 0x58, 0x70, 0xba, 0x5b, 0xa6, 0x4d, 0xdb, 0xd7, 0xda, 0x1d, + 0x4a, 0xde, 0x81, 0x22, 0x6d, 0x77, 0xa8, 0x6c, 0xc2, 0xd1, 0x35, 0x2f, 0xc6, 0x2c, 0xd4, 0x1f, + 0xd9, 0x13, 0x72, 0xc6, 0x64, 0x05, 0xa6, 0xb6, 0x5d, 0xa7, 0x2b, 0x16, 0xb3, 0x8d, 0xfd, 0x9e, + 0xb2, 0xc0, 0xfd, 0xa4, 0x9a, 0x39, 0x96, 0x62, 0xd8, 0x07, 0x07, 0xb3, 0x10, 0x3e, 0x61, 0xa2, + 0x2c, 0x79, 0x0b, 0x66, 0x42, 0x48, 0x30, 0xab, 0x2f, 0xb0, 0xad, 0xaf, 0x34, 0xd1, 0x5d, 0x3c, + 0x3c, 0x98, 0x9d, 0x59, 0x1a, 0x42, 0x83, 0x43, 0x4b, 0xb3, 0xb9, 0xf2, 0x54, 0x88, 0x14, 0x2b, + 0xad, 0xec, 0xd6, 0x63, 0x5a, 0xc2, 0xb9, 0x8d, 0x60, 0x29, 0x21, 0x02, 0x07, 0x84, 0x92, 0x25, + 0x98, 0xf0, 0x9d, 0x48, 0x7b, 0x09, 0xa3, 0xa0, 0xa6, 0x8c, 0x5a, 0x1b, 0xce, 0xd0, 0xd6, 0x8a, + 0x95, 0x23, 0x08, 0xe7, 0xd4, 0x73, 0xa2, 0xa5, 0xca, 0xbc, 0xa5, 0x2e, 0x1c, 0x1e, 0xcc, 0x9e, + 0xdb, 0x48, 0xa5, 0xc0, 0x21, 0x25, 0xc9, 0xcf, 0xe4, 0x60, 0x4a, 0xa1, 0x64, 0x1b, 0x55, 0xc6, + 0xd9, 0x46, 0x84, 0xf5, 0x88, 0x8d, 0x98, 0x00, 0x4c, 0x08, 0x24, 0x1f, 0xc0, 0xb4, 0x82, 0xc8, + 0xe9, 0x5f, 0x1a, 0x88, 0xb2, 0xaf, 0x29, 0xdc, 0xfa, 0xb6, 0x11, 0x67, 0x8e, 0x49, 0x69, 0x5a, + 0x13, 0xea, 0x0b, 0x4e, 0xb7, 0xe7, 0x0a, 0x8b, 0x31, 0xf9, 0x22, 0x14, 0x7d, 0xf6, 0x9d, 0xc4, + 0x1e, 0x6a, 0x56, 0x8d, 0x01, 0xf9, 0x7d, 0xa6, 0x23, 0xa4, 0xfc, 0x23, 0x71, 0x62, 0xed, 0x37, + 0x2b, 0x50, 0x0b, 0x16, 0x6c, 0xf2, 0x34, 0x94, 0xb8, 0xcd, 0x4d, 0xf2, 0x08, 0x34, 0x31, 0x6e, + 0x9a, 0x43, 0x81, 0x23, 0xcf, 0x40, 0xc5, 0x70, 0xba, 0x5d, 0xdd, 0x6e, 0x73, 0x3b, 0x6a, 0x4d, + 0xac, 0x4a, 0x0b, 0x02, 0x84, 0x0a, 0x47, 0x2e, 0x42, 0x51, 0x77, 0x3b, 0xc2, 0xa4, 0x59, 0x13, + 0xb3, 0x5d, 0xc3, 0xed, 0x78, 0xc8, 0xa1, 0xe4, 0xcb, 0x50, 0xa0, 0xf6, 0xde, 0x4c, 0x71, 0xb8, + 0x86, 0x7b, 0xcd, 0xde, 0xbb, 0xad, 0xbb, 0xcd, 0xba, 0xac, 0x43, 0xe1, 0x9a, 0xbd, 0x87, 0xac, + 0x0c, 0x59, 0x81, 0x0a, 0xb5, 0xf7, 0x58, 0x07, 0x96, 0xb6, 0xc6, 0x9f, 0x18, 0x52, 0x9c, 0x91, + 0xc8, 0xcd, 0x5e, 0xa0, 0x27, 0x4b, 0x30, 0x2a, 0x16, 0xe4, 0xeb, 0x30, 0x21, 0x54, 0xe6, 0x55, + 0xd6, 0xb1, 0x84, 0x49, 0xbb, 0x7e, 0x75, 0x76, 0xb8, 0xce, 0xcd, 0xe9, 0x42, 0xdb, 0x6e, 0x04, + 0xe8, 0x61, 0x8c, 0x15, 0xf9, 0x3a, 0xd4, 0x94, 0x29, 0x48, 0x75, 0xcf, 0x54, 0xb3, 0xa8, 0xb2, + 0x1f, 0x21, 0xbd, 0xdb, 0x37, 0x5d, 0xda, 0xa5, 0xb6, 0xef, 0x35, 0x4f, 0x2b, 0x43, 0x99, 0xc2, + 0x7a, 0x18, 0x72, 0x23, 0x5b, 0x83, 0xf6, 0x5d, 0xd1, 0xf7, 0x9e, 0x1e, 0xb2, 0x66, 0x8c, 0x60, + 0xdc, 0xfd, 0x16, 0x4c, 0x07, 0x06, 0x58, 0x69, 0xc3, 0x13, 0xe6, 0xca, 0x17, 0x58, 0xf1, 0xe5, + 0x38, 0xea, 0xc1, 0xc1, 0xec, 0x53, 0x29, 0x56, 0xbc, 0x90, 0x00, 0x93, 0xcc, 0xc8, 0x7b, 0x30, + 0xe5, 0x52, 0xbd, 0x6d, 0xda, 0xd4, 0xf3, 0xd6, 0x5d, 0x67, 0x2b, 0xfb, 0xfe, 0x81, 0x73, 0x11, + 0x63, 0x17, 0x63, 0x9c, 0x31, 0x21, 0x89, 0xdc, 0x83, 0x49, 0xcb, 0xdc, 0xa3, 0xa1, 0xe8, 0xfa, + 0x58, 0x44, 0x9f, 0x3e, 0x3c, 0x98, 0x9d, 0x5c, 0x89, 0x32, 0xc6, 0xb8, 0x1c, 0xa6, 0x9a, 0xf5, + 0x1c, 0xd7, 0x57, 0x9b, 0x8c, 0x9f, 0x78, 0xe8, 0x26, 0x63, 0xdd, 0x71, 0xfd, 0x70, 0x10, 0xb2, + 0x27, 0x0f, 0x45, 0x71, 0xed, 0xef, 0x95, 0x60, 0x70, 0x2b, 0x1e, 0xef, 0x71, 0xb9, 0x71, 0xf7, + 0xb8, 0x64, 0x6f, 0x10, 0x0b, 0xe8, 0xcb, 0xb2, 0xd8, 0x18, 0x7a, 0x44, 0x4a, 0xaf, 0x2e, 0x8c, + 0xbb, 0x57, 0x3f, 0x36, 0x13, 0xcf, 0x60, 0xf7, 0x2f, 0x7f, 0x7c, 0xdd, 0xbf, 0x72, 0x32, 0xdd, + 0x5f, 0xfb, 0x4e, 0x11, 0xa6, 0x16, 0x75, 0xda, 0x75, 0xec, 0x8f, 0xb4, 0xc6, 0xe4, 0x1e, 0x0b, + 0x6b, 0xcc, 0x73, 0x50, 0x75, 0x69, 0xcf, 0x32, 0x0d, 0x5d, 0xec, 0x4f, 0xa4, 0xa3, 0x08, 0x25, + 0x0c, 0x03, 0xec, 0x10, 0x2b, 0x5c, 0xe1, 0xb1, 0xb4, 0xc2, 0x15, 0x3f, 0x7e, 0x2b, 0x9c, 0xf6, + 0x33, 0x79, 0xe0, 0xfa, 0x39, 0xb9, 0x0c, 0x45, 0xa6, 0x7b, 0x26, 0x6d, 0xbf, 0x7c, 0xb4, 0x70, + 0x0c, 0xb9, 0x00, 0x79, 0xdf, 0x91, 0xd3, 0x0d, 0x48, 0x7c, 0x7e, 0xc3, 0xc1, 0xbc, 0xef, 0x90, + 0xf7, 0x00, 0x0c, 0xc7, 0x6e, 0x9b, 0xca, 0x7f, 0x9a, 0xed, 0xc5, 0x96, 0x1c, 0xf7, 0x9e, 0xee, + 0xb6, 0x17, 0x02, 0x8e, 0xc2, 0x0e, 0x13, 0x3e, 0x63, 0x44, 0x1a, 0x79, 0x0d, 0xca, 0x8e, 0xbd, + 0xd4, 0xb7, 0x2c, 0xe9, 0x5c, 0xff, 0x1c, 0xdb, 0x29, 0xae, 0x71, 0xc8, 0x83, 0x83, 0xd9, 0xf3, + 0x62, 0xbf, 0xc5, 0x9e, 0xee, 0xb8, 0xa6, 0x6f, 0xda, 0x9d, 0xc0, 0x2c, 0x21, 0x8b, 0x69, 0x7f, + 0x25, 0x07, 0xf5, 0x25, 0xf3, 0x3e, 0x6d, 0x4b, 0x03, 0x01, 0x42, 0xd9, 0xa2, 0x76, 0xc7, 0xdf, + 0x19, 0x71, 0x8b, 0x2d, 0xac, 0x73, 0x9c, 0x03, 0x4a, 0x4e, 0x64, 0x1e, 0x6a, 0x62, 0xd3, 0x65, + 0xda, 0x1d, 0xde, 0x86, 0xd5, 0x70, 0xa6, 0x6f, 0x29, 0x04, 0x86, 0x34, 0xda, 0xfb, 0x70, 0x7a, + 0xa0, 0x19, 0xc8, 0x0e, 0x14, 0x7d, 0xbd, 0xa3, 0x16, 0x95, 0xa5, 0x91, 0x1b, 0x78, 0x43, 0xef, + 0x44, 0x1a, 0x37, 0xf8, 0xd8, 0x1b, 0x3a, 0xd3, 0x0c, 0x99, 0x04, 0xed, 0xb7, 0x8a, 0x50, 0xbe, + 0xde, 0x6a, 0x35, 0xd6, 0x97, 0xc9, 0x8b, 0x50, 0x97, 0xde, 0xcf, 0x5b, 0xa1, 0x73, 0x20, 0x70, + 0x7e, 0xb7, 0x42, 0x14, 0x46, 0xe9, 0x98, 0x16, 0xeb, 0x52, 0xdd, 0xea, 0xca, 0x1e, 0x13, 0x2c, + 0xa0, 0xc8, 0x80, 0x28, 0x70, 0x44, 0x87, 0x29, 0xb6, 0xed, 0xb6, 0xf5, 0x2e, 0x15, 0x5b, 0x6a, + 0xd9, 0x77, 0x8e, 0xb8, 0xe9, 0xe6, 0xb3, 0xec, 0x66, 0x8c, 0x01, 0x26, 0x18, 0x92, 0x97, 0xa1, + 0xaa, 0xf7, 0xfd, 0x1d, 0xbe, 0x79, 0x12, 0x1d, 0xe4, 0x22, 0x77, 0x0e, 0x4b, 0xd8, 0x83, 0x83, + 0xd9, 0x89, 0x9b, 0xd8, 0x7c, 0x51, 0x3d, 0x63, 0x40, 0xcd, 0x2a, 0xa7, 0xb6, 0xf1, 0xb2, 0x72, + 0xa5, 0x63, 0x57, 0x6e, 0x3d, 0xc6, 0x00, 0x13, 0x0c, 0xc9, 0xdb, 0x30, 0xb1, 0x4b, 0xf7, 0x7d, + 0x7d, 0x4b, 0x0a, 0x28, 0x1f, 0x47, 0xc0, 0x29, 0xa6, 0xf9, 0xde, 0x8c, 0x14, 0xc7, 0x18, 0x33, + 0xe2, 0xc1, 0xd9, 0x5d, 0xea, 0x6e, 0x51, 0xd7, 0x91, 0xae, 0x56, 0x29, 0xa4, 0x72, 0x1c, 0x21, + 0x33, 0x87, 0x07, 0xb3, 0x67, 0x6f, 0xa6, 0xb0, 0xc1, 0x54, 0xe6, 0xda, 0xff, 0xca, 0xc3, 0xf4, + 0x75, 0x11, 0xb1, 0xe3, 0xb8, 0x62, 0xf9, 0x25, 0xe7, 0xa1, 0xe0, 0xf6, 0xfa, 0xbc, 0xe7, 0x14, + 0x84, 0x99, 0x07, 0xd7, 0x37, 0x91, 0xc1, 0xc8, 0x5b, 0x50, 0x55, 0x01, 0x33, 0xd2, 0xf0, 0x31, + 0x92, 0x41, 0x4b, 0x3d, 0x61, 0xc0, 0x8d, 0x6d, 0x90, 0xba, 0x5e, 0xa7, 0x65, 0xbe, 0x47, 0xa5, + 0x2d, 0x80, 0x6f, 0x90, 0x56, 0x05, 0x08, 0x15, 0x8e, 0x2d, 0x2d, 0xbb, 0x74, 0x5f, 0xec, 0x84, + 0x8b, 0xe1, 0xd2, 0x72, 0x53, 0xc2, 0x30, 0xc0, 0x92, 0x59, 0xe5, 0x1a, 0x66, 0xbd, 0xa0, 0x28, + 0x2c, 0x64, 0xb7, 0x19, 0x40, 0x7a, 0x89, 0xd9, 0xbc, 0x21, 0x4d, 0x56, 0xe5, 0xd1, 0xe7, 0x8d, + 0xb8, 0x89, 0x8b, 0x7c, 0x01, 0x6a, 0x9c, 0x79, 0xd3, 0x72, 0xb6, 0xf8, 0x87, 0xab, 0x09, 0x7b, + 0xce, 0x6d, 0x05, 0xc4, 0x10, 0xaf, 0xfd, 0x71, 0x1e, 0xce, 0x5d, 0xa7, 0xbe, 0x58, 0xda, 0x17, + 0x69, 0xcf, 0x72, 0xf6, 0x99, 0x52, 0x89, 0xf4, 0x2e, 0x79, 0x1d, 0xc0, 0xf4, 0xb6, 0x5a, 0x7b, + 0xc6, 0x46, 0xb8, 0x39, 0xbd, 0x2c, 0x87, 0x24, 0x2c, 0xb7, 0x9a, 0x12, 0xf3, 0x20, 0xf6, 0x84, + 0x91, 0x32, 0xe1, 0xae, 0x34, 0xff, 0x90, 0x5d, 0x69, 0x0b, 0xa0, 0x17, 0xaa, 0xa6, 0x05, 0x4e, + 0xf9, 0x45, 0x25, 0xe6, 0x38, 0x5a, 0x69, 0x84, 0x4d, 0x16, 0x65, 0xd1, 0x86, 0x53, 0x6d, 0xba, + 0xad, 0xf7, 0x2d, 0x3f, 0x50, 0xa7, 0xe5, 0x20, 0x3e, 0xba, 0x46, 0x1e, 0x84, 0xc6, 0x2c, 0x26, + 0x38, 0xe1, 0x00, 0x6f, 0xed, 0xb7, 0x0b, 0x70, 0xe1, 0x3a, 0xf5, 0x03, 0x6b, 0x9b, 0x9c, 0x1d, + 0x5b, 0x3d, 0x6a, 0xb0, 0xaf, 0xf0, 0x61, 0x0e, 0xca, 0x96, 0xbe, 0x45, 0x2d, 0x36, 0x85, 0xb3, + 0xb7, 0x79, 0x67, 0xe4, 0x29, 0x7c, 0xb8, 0x94, 0xb9, 0x15, 0x2e, 0x41, 0x44, 0x3f, 0x4d, 0xc9, + 0xca, 0x97, 0x05, 0x10, 0xa5, 0x78, 0x36, 0xa9, 0x1b, 0x56, 0xdf, 0xf3, 0xc5, 0xf6, 0x46, 0x2a, + 0x55, 0xc1, 0xa4, 0xbe, 0x10, 0xa2, 0x30, 0x4a, 0x47, 0xae, 0x02, 0x18, 0x96, 0x49, 0x6d, 0x9f, + 0x97, 0x12, 0xe3, 0x8a, 0xa8, 0xef, 0xbb, 0x10, 0x60, 0x30, 0x42, 0xc5, 0x44, 0x75, 0x1d, 0xdb, + 0xf4, 0x1d, 0x21, 0xaa, 0x18, 0x17, 0xb5, 0x1a, 0xa2, 0x30, 0x4a, 0xc7, 0x8b, 0x51, 0xdf, 0x35, + 0x0d, 0x8f, 0x17, 0x2b, 0x25, 0x8a, 0x85, 0x28, 0x8c, 0xd2, 0x5d, 0xf8, 0x32, 0xd4, 0x23, 0xef, + 0x7f, 0xac, 0x08, 0x8f, 0xbf, 0x55, 0x83, 0x4b, 0xb1, 0x66, 0xf5, 0x75, 0x9f, 0x6e, 0xf7, 0xad, + 0x16, 0xf5, 0xd5, 0x07, 0x1c, 0x71, 0x2d, 0xfc, 0x8b, 0xe1, 0x77, 0x17, 0x41, 0x6f, 0xc6, 0x78, + 0xbe, 0xfb, 0x40, 0x05, 0x8f, 0xf4, 0xed, 0xe7, 0xa1, 0x66, 0xeb, 0xbe, 0xc7, 0x07, 0xae, 0x1c, + 0xa3, 0x81, 0x2e, 0x72, 0x4b, 0x21, 0x30, 0xa4, 0x21, 0xeb, 0x70, 0x56, 0x36, 0xf1, 0xb5, 0xfb, + 0x6c, 0xe3, 0x4b, 0x5d, 0x51, 0x56, 0x2e, 0xa7, 0xb2, 0xec, 0xd9, 0xd5, 0x14, 0x1a, 0x4c, 0x2d, + 0x49, 0x56, 0xe1, 0x8c, 0x21, 0x02, 0x81, 0xa8, 0xe5, 0xe8, 0x6d, 0xc5, 0x50, 0x18, 0x37, 0x83, + 0xfd, 0xc1, 0xc2, 0x20, 0x09, 0xa6, 0x95, 0x4b, 0xf6, 0xe6, 0xf2, 0x48, 0xbd, 0xb9, 0x32, 0x4a, + 0x6f, 0xae, 0x8e, 0xd6, 0x9b, 0x6b, 0x47, 0xeb, 0xcd, 0xac, 0xe5, 0x79, 0xcc, 0x89, 0xcb, 0xd4, + 0x13, 0xb1, 0xc2, 0x46, 0xe2, 0xcc, 0x82, 0x96, 0x6f, 0xa5, 0xd0, 0x60, 0x6a, 0x49, 0xb2, 0x05, + 0x17, 0x04, 0xfc, 0x9a, 0x6d, 0xb8, 0xfb, 0x3d, 0x19, 0xa9, 0xaa, 0xf8, 0xd6, 0x63, 0xd6, 0xe5, + 0x0b, 0xad, 0xa1, 0x94, 0xf8, 0x10, 0x2e, 0xe4, 0x15, 0x98, 0x14, 0x5f, 0x69, 0x55, 0xef, 0x71, + 0xb6, 0x22, 0xea, 0xec, 0x09, 0xc9, 0x76, 0x72, 0x21, 0x8a, 0xc4, 0x38, 0x2d, 0x69, 0xc0, 0x74, + 0x6f, 0xcf, 0x60, 0x7f, 0x97, 0xb7, 0x6f, 0x51, 0xda, 0xa6, 0x6d, 0xee, 0xbb, 0xad, 0x35, 0x9f, + 0x54, 0x26, 0x8e, 0xf5, 0x38, 0x1a, 0x93, 0xf4, 0xe4, 0x65, 0x98, 0xf0, 0x7c, 0xdd, 0xf5, 0xa5, + 0x35, 0x74, 0x66, 0x4a, 0x44, 0xe5, 0x29, 0x63, 0x61, 0x2b, 0x82, 0xc3, 0x18, 0x65, 0xea, 0x7a, + 0x31, 0xfd, 0xe8, 0xd6, 0x8b, 0x2c, 0xb3, 0xd5, 0x3f, 0xce, 0xc3, 0xe5, 0xeb, 0xd4, 0x5f, 0x75, + 0x6c, 0x69, 0x90, 0x4e, 0x5b, 0xf6, 0x8f, 0x64, 0x4a, 0x8e, 0x2f, 0xda, 0xf9, 0xb1, 0x2e, 0xda, + 0x85, 0x31, 0x2d, 0xda, 0xc5, 0x47, 0xb8, 0x68, 0xff, 0xfd, 0x3c, 0x3c, 0x19, 0x6b, 0xc9, 0x75, + 0xa7, 0xad, 0x26, 0xfc, 0x4f, 0x1b, 0xf0, 0x08, 0x0d, 0xf8, 0xfb, 0x05, 0x78, 0xea, 0x3a, 0x15, + 0xc1, 0xa7, 0x76, 0x67, 0xdd, 0xec, 0x51, 0xcb, 0xb4, 0x69, 0x84, 0x2d, 0xf9, 0xf3, 0x39, 0x98, + 0x10, 0xba, 0xa4, 0x0c, 0x1b, 0xcd, 0x6a, 0x57, 0x4a, 0xf1, 0xa2, 0x86, 0x03, 0x5c, 0x68, 0xb0, + 0x72, 0xf5, 0x88, 0xc9, 0xfd, 0x54, 0x8b, 0x3d, 0xca, 0xf7, 0xfc, 0xd9, 0x02, 0x9c, 0x67, 0xdf, + 0x53, 0x05, 0x93, 0x7c, 0xba, 0x95, 0xf8, 0x18, 0x3e, 0xc2, 0xaf, 0x97, 0xe0, 0xcc, 0x75, 0xea, + 0x0f, 0xcc, 0x48, 0x7f, 0x4a, 0x9b, 0x7f, 0x15, 0xce, 0x84, 0xc1, 0x4d, 0x2d, 0xdf, 0x71, 0x85, + 0x06, 0x9e, 0xd0, 0x18, 0x5b, 0x83, 0x24, 0x98, 0x56, 0x8e, 0x7c, 0x1d, 0x9e, 0xf4, 0xc4, 0x74, + 0x25, 0x6c, 0x14, 0x42, 0xa1, 0x8e, 0x9c, 0x64, 0x50, 0x9e, 0xdb, 0x27, 0x5b, 0xe9, 0x64, 0x38, + 0xac, 0x3c, 0xf9, 0x00, 0x26, 0x7a, 0x72, 0x0a, 0x64, 0xdf, 0x2c, 0xb3, 0x4b, 0x7c, 0x3d, 0xc2, + 0x2c, 0x9c, 0xe3, 0xa2, 0x50, 0x8c, 0x09, 0x4c, 0xed, 0xa9, 0xd5, 0x47, 0xd8, 0x53, 0xff, 0x28, + 0x0f, 0x95, 0xeb, 0xae, 0xd3, 0xef, 0x35, 0xf7, 0x49, 0x07, 0xca, 0xf7, 0xb8, 0x15, 0x55, 0xce, + 0xf0, 0xa3, 0x07, 0x08, 0x0b, 0x63, 0x6c, 0xb8, 0x89, 0x11, 0xcf, 0x28, 0xd9, 0xb3, 0x4e, 0xbc, + 0x4b, 0xf7, 0x69, 0x5b, 0x1a, 0x53, 0x83, 0x4e, 0x7c, 0x93, 0x01, 0x51, 0xe0, 0x48, 0x17, 0xa6, + 0x75, 0xcb, 0x72, 0xee, 0xd1, 0xf6, 0x8a, 0xee, 0x73, 0x07, 0x88, 0xb4, 0x2f, 0x1e, 0xd7, 0x34, + 0xc3, 0xbd, 0x5a, 0x8d, 0x38, 0x2b, 0x4c, 0xf2, 0x26, 0xef, 0x42, 0xc5, 0xf3, 0x1d, 0x57, 0x6d, + 0x8d, 0x32, 0x05, 0x6f, 0x37, 0xdf, 0x6c, 0x09, 0x56, 0xc2, 0x6e, 0x25, 0x1f, 0x50, 0x09, 0xd0, + 0xfe, 0x6f, 0x0e, 0xe0, 0xc6, 0xc6, 0xc6, 0xba, 0x34, 0xb1, 0xb5, 0xa1, 0xa8, 0xf7, 0x03, 0x8b, + 0xf5, 0xe8, 0x96, 0xe1, 0x58, 0x08, 0x9b, 0x8c, 0x17, 0xe8, 0xfb, 0x3b, 0xc8, 0xb9, 0x93, 0xcf, + 0x43, 0x45, 0x6e, 0x6b, 0x65, 0xb3, 0x07, 0x8e, 0x35, 0xb9, 0x12, 0xa3, 0xc2, 0x93, 0x77, 0x94, + 0x8b, 0xb5, 0x90, 0xd5, 0xa9, 0xc5, 0xb8, 0x08, 0x6b, 0x5b, 0xcc, 0xf7, 0xfa, 0xab, 0x05, 0x80, + 0xe5, 0xb6, 0x45, 0x5b, 0x2a, 0x68, 0xbc, 0xe6, 0xef, 0xb8, 0xd4, 0xdb, 0x71, 0xac, 0xf6, 0x88, + 0x76, 0x7b, 0x6e, 0x58, 0xdb, 0x50, 0x4c, 0x30, 0xe4, 0x47, 0xda, 0x6c, 0x43, 0x41, 0x7b, 0x2a, + 0x6c, 0x6e, 0x44, 0x4b, 0xe5, 0x29, 0xb1, 0xf9, 0x08, 0xf9, 0x60, 0x8c, 0x2b, 0xd1, 0xa1, 0x6e, + 0xda, 0x86, 0x18, 0x81, 0xcd, 0xfd, 0x11, 0x7b, 0x2a, 0x3f, 0xcb, 0xb8, 0x1c, 0xb2, 0xc1, 0x28, + 0x4f, 0x36, 0x20, 0x4c, 0xdb, 0xf4, 0x45, 0x9b, 0x2d, 0x52, 0x4b, 0xdf, 0x1f, 0x31, 0x58, 0x8f, + 0x0f, 0x88, 0xe5, 0x38, 0x2b, 0x4c, 0xf2, 0xd6, 0xfe, 0x42, 0x0e, 0xa6, 0xf9, 0xeb, 0xb1, 0xb7, + 0x16, 0x2a, 0x1b, 0xb9, 0x07, 0x75, 0x23, 0x0c, 0x82, 0x91, 0x4d, 0xb9, 0x98, 0xc1, 0x09, 0x16, + 0xf0, 0x12, 0xef, 0x1e, 0x01, 0x60, 0x54, 0x92, 0xf6, 0x87, 0x79, 0x38, 0x97, 0xa8, 0x8c, 0xec, + 0xb5, 0xe4, 0xcf, 0x0e, 0x9c, 0x83, 0xfc, 0xff, 0x8f, 0xd6, 0x1e, 0xe2, 0x18, 0xdd, 0x2a, 0xf5, + 0xf5, 0xd0, 0x70, 0x10, 0xc2, 0x22, 0x87, 0x1f, 0xfb, 0x50, 0xf4, 0xd8, 0x62, 0x20, 0x5e, 0xb7, + 0x35, 0xf2, 0xeb, 0xa6, 0xbf, 0x00, 0x5f, 0x1a, 0x02, 0x37, 0x0e, 0x5f, 0x12, 0xb8, 0x38, 0xf2, + 0x3e, 0x94, 0x3d, 0x5f, 0xf7, 0xfb, 0x6a, 0x18, 0x6e, 0x8e, 0x5b, 0x30, 0x67, 0x1e, 0x4e, 0xd2, + 0xe2, 0x19, 0xa5, 0x50, 0xed, 0x0f, 0x73, 0x70, 0x21, 0xbd, 0xe0, 0x8a, 0xe9, 0xf9, 0xe4, 0xcf, + 0x0c, 0x34, 0xfb, 0x11, 0xbb, 0x21, 0x2b, 0xcd, 0x1b, 0x3d, 0x88, 0xff, 0x56, 0x90, 0x48, 0x93, + 0xfb, 0x50, 0x32, 0x7d, 0xda, 0x55, 0x26, 0xb7, 0xb5, 0x31, 0xbf, 0x7a, 0x44, 0x6f, 0x62, 0x52, + 0x50, 0x08, 0xd3, 0xfe, 0xfa, 0xd0, 0x57, 0xe6, 0x6b, 0xf3, 0x9f, 0x1b, 0x8c, 0xf4, 0x5c, 0xcb, + 0x1e, 0xe9, 0x99, 0xa8, 0xd8, 0xd0, 0x80, 0xcf, 0x1f, 0x15, 0xe0, 0xe2, 0xc3, 0x3e, 0x24, 0x5b, + 0xbe, 0x65, 0x7f, 0xc9, 0xba, 0x7c, 0x3f, 0xbc, 0x67, 0x90, 0xab, 0x50, 0xea, 0xed, 0xe8, 0x9e, + 0xd2, 0x41, 0x2f, 0x06, 0xe1, 0x35, 0x0c, 0xf8, 0x80, 0x4d, 0x61, 0x5c, 0x77, 0xe5, 0x8f, 0x28, + 0x48, 0xd9, 0xea, 0xd3, 0xa5, 0x9e, 0x17, 0x5a, 0x2d, 0x83, 0xd5, 0x67, 0x55, 0x80, 0x51, 0xe1, + 0x89, 0x0f, 0x65, 0x61, 0x55, 0x92, 0xd3, 0xdb, 0x78, 0x37, 0x9a, 0xc1, 0x4b, 0xc9, 0x2d, 0xa6, + 0x94, 0x45, 0xe6, 0x64, 0xec, 0x5f, 0x29, 0x76, 0x9e, 0xb4, 0x98, 0xa2, 0x8e, 0x73, 0x3a, 0xf2, + 0x06, 0x10, 0x67, 0x8b, 0xdb, 0xd1, 0xda, 0xd2, 0x65, 0xc6, 0x66, 0xc4, 0x32, 0x77, 0x93, 0x05, + 0xa7, 0x51, 0xd7, 0x06, 0x28, 0x30, 0xa5, 0x94, 0xf6, 0x07, 0x55, 0x38, 0x97, 0xde, 0x1f, 0x58, + 0xbb, 0xed, 0x51, 0x97, 0xcf, 0xb6, 0x89, 0xe3, 0xf1, 0xb7, 0x05, 0x18, 0x15, 0xfe, 0x13, 0x1d, + 0x68, 0xf1, 0xeb, 0x39, 0x38, 0xef, 0x4a, 0xb3, 0xf0, 0x49, 0x04, 0x5b, 0x3c, 0x75, 0x78, 0x30, + 0x7b, 0x1e, 0x87, 0x09, 0xc4, 0xe1, 0x75, 0x21, 0xbf, 0x96, 0x83, 0x19, 0x69, 0xe5, 0x5d, 0x38, + 0x81, 0x13, 0x63, 0x3c, 0x08, 0x7a, 0x75, 0x88, 0x3c, 0x1c, 0x5a, 0x13, 0xf2, 0x01, 0xd4, 0x7b, + 0xac, 0x5f, 0x78, 0x3e, 0xb5, 0x0d, 0x15, 0x18, 0x35, 0xfa, 0x48, 0x5a, 0x0f, 0x79, 0x05, 0x27, + 0x46, 0xf8, 0x8a, 0x1d, 0x41, 0x60, 0x54, 0xe2, 0x63, 0x7e, 0x44, 0xec, 0x39, 0xa8, 0x7a, 0xd4, + 0xf7, 0x4d, 0xbb, 0x23, 0xb6, 0x57, 0x35, 0x31, 0x56, 0x5a, 0x12, 0x86, 0x01, 0x96, 0x7c, 0x01, + 0x6a, 0xdc, 0xca, 0xdc, 0x70, 0x3b, 0xde, 0x4c, 0x8d, 0x47, 0xe2, 0x4e, 0x8a, 0xc0, 0x0f, 0x09, + 0xc4, 0x10, 0x4f, 0x5e, 0x80, 0x89, 0x2d, 0x3e, 0x7c, 0xa5, 0xa5, 0x4c, 0x98, 0xfa, 0xb9, 0xee, + 0xd8, 0x8c, 0xc0, 0x31, 0x46, 0x45, 0xae, 0x02, 0xd0, 0xc0, 0x14, 0x2f, 0x0f, 0x8e, 0x07, 0x1a, + 0x49, 0x68, 0xa4, 0xc7, 0x08, 0x15, 0x79, 0x0a, 0x0a, 0xbe, 0xe5, 0x71, 0xe3, 0x7c, 0x35, 0xdc, + 0x71, 0x6f, 0xac, 0xb4, 0x90, 0xc1, 0xb5, 0x3f, 0xce, 0xc1, 0x74, 0xe2, 0x2c, 0x01, 0x2b, 0xd2, + 0x77, 0x2d, 0x39, 0x8d, 0x04, 0x45, 0x36, 0x71, 0x05, 0x19, 0x9c, 0xbc, 0x23, 0x77, 0x21, 0xf9, + 0x8c, 0xb9, 0x24, 0x6e, 0xe9, 0xbe, 0xc7, 0xb6, 0x1d, 0x03, 0x1b, 0x10, 0x6e, 0xd9, 0x0f, 0xeb, + 0x23, 0xd7, 0x81, 0x88, 0x65, 0x3f, 0xc4, 0x61, 0x8c, 0x92, 0x35, 0x90, 0x6f, 0x79, 0xd7, 0x6c, + 0x7d, 0xcb, 0xa2, 0x6d, 0x3e, 0x1b, 0x44, 0x1a, 0x68, 0x63, 0xa5, 0x25, 0x31, 0x18, 0xa1, 0xd2, + 0x7e, 0xa7, 0x10, 0x69, 0x01, 0xb9, 0xcf, 0xf8, 0x88, 0x16, 0x78, 0x96, 0x2d, 0xa0, 0xc1, 0xe2, + 0x5e, 0x8b, 0xae, 0x7f, 0x7c, 0x31, 0x96, 0x58, 0xf2, 0x3c, 0x54, 0x0d, 0xc7, 0xf6, 0xfa, 0x5d, + 0xea, 0xca, 0x97, 0x08, 0x54, 0x99, 0x05, 0x09, 0xc7, 0x80, 0x82, 0x7c, 0x15, 0xa6, 0xda, 0xd4, + 0x32, 0xf7, 0xa8, 0xfb, 0x8e, 0xcc, 0x0d, 0x52, 0x8c, 0x7b, 0x54, 0x16, 0x05, 0x56, 0x9a, 0x5c, + 0x26, 0xdb, 0xd1, 0x47, 0xf2, 0x0a, 0x4c, 0x6f, 0x9b, 0x96, 0x4f, 0xdd, 0x77, 0xbc, 0x3e, 0xd7, + 0x4d, 0x45, 0x7a, 0x88, 0x9a, 0x88, 0x50, 0x59, 0xe2, 0xa8, 0x96, 0xc4, 0xe0, 0xd4, 0x76, 0xec, + 0x99, 0xdc, 0x11, 0x9d, 0xa4, 0x9c, 0xf1, 0xbc, 0xec, 0xc6, 0x4a, 0x4b, 0x44, 0x7e, 0xa8, 0xee, + 0x15, 0xf4, 0x95, 0xca, 0x23, 0xea, 0x2b, 0xda, 0x3f, 0x29, 0x40, 0xfd, 0x0d, 0x67, 0xeb, 0x13, + 0x12, 0xe2, 0x98, 0xbe, 0x9e, 0xe6, 0x3f, 0xc6, 0xf5, 0x74, 0x13, 0x9e, 0xf4, 0x7d, 0x4b, 0xa6, + 0xb1, 0x69, 0x6c, 0xfb, 0xd4, 0x5d, 0x32, 0x6d, 0xd3, 0xdb, 0xa1, 0x6d, 0xe9, 0xf8, 0xff, 0xec, + 0xe1, 0xc1, 0xec, 0x93, 0x1b, 0x1b, 0x2b, 0x69, 0x24, 0x38, 0xac, 0x2c, 0x9f, 0xdf, 0xc4, 0x69, + 0x36, 0x7e, 0x82, 0x43, 0xc6, 0x03, 0x88, 0xf9, 0x2d, 0x02, 0xc7, 0x18, 0x95, 0xf6, 0x6f, 0xf2, + 0x50, 0x0b, 0xd2, 0x19, 0x90, 0x67, 0xa0, 0xb2, 0xe5, 0x3a, 0xbb, 0xd4, 0x15, 0x71, 0x14, 0xf2, + 0xf0, 0x43, 0x53, 0x80, 0x50, 0xe1, 0xc8, 0xd3, 0x50, 0xf2, 0x9d, 0x9e, 0x69, 0x24, 0x0d, 0x9d, + 0x1b, 0x0c, 0x88, 0x02, 0xc7, 0x47, 0x2c, 0x0f, 0x79, 0xe2, 0x6f, 0x55, 0x8d, 0x8c, 0x58, 0x0e, + 0x45, 0x89, 0x55, 0x03, 0xa1, 0x38, 0xf6, 0x81, 0xf0, 0x6c, 0xa0, 0xab, 0x96, 0xe2, 0x53, 0x46, + 0x42, 0xbb, 0x7c, 0x1b, 0x8a, 0x9e, 0xee, 0x59, 0x72, 0x28, 0x66, 0x38, 0x16, 0xdf, 0x68, 0xad, + 0xc8, 0x63, 0xf1, 0x8d, 0xd6, 0x0a, 0x72, 0xa6, 0xda, 0xdf, 0x29, 0x40, 0x5d, 0xb4, 0xaf, 0x98, + 0xe6, 0xc6, 0xd9, 0xc2, 0xaf, 0x71, 0x77, 0x30, 0x9f, 0xc9, 0xb8, 0x99, 0x50, 0x4e, 0x78, 0x41, + 0xae, 0x98, 0x85, 0x28, 0x32, 0x70, 0x09, 0x87, 0xa0, 0x3f, 0xd9, 0x4d, 0xcf, 0xd6, 0x34, 0x9e, + 0x92, 0x43, 0x2a, 0xe3, 0x32, 0xca, 0x2b, 0x58, 0xd3, 0x6e, 0x46, 0x70, 0x18, 0xa3, 0xd4, 0xfe, + 0x4b, 0x1e, 0x6a, 0x2b, 0xe6, 0x36, 0x35, 0xf6, 0x0d, 0x8b, 0x92, 0x6f, 0xc1, 0x85, 0x36, 0xb5, + 0x28, 0x5b, 0xda, 0xaf, 0xbb, 0xba, 0x41, 0xd7, 0xa9, 0x6b, 0xf2, 0x94, 0x42, 0x3c, 0x65, 0x95, + 0x08, 0xbe, 0xbb, 0x74, 0x78, 0x30, 0x7b, 0x61, 0x71, 0x28, 0x15, 0x3e, 0x84, 0x03, 0x59, 0x86, + 0x89, 0x36, 0xf5, 0x4c, 0x97, 0xb6, 0xd7, 0x23, 0x3b, 0xb7, 0x67, 0x54, 0x3d, 0x17, 0x23, 0xb8, + 0x07, 0x07, 0xb3, 0x93, 0xca, 0x40, 0x2d, 0xb6, 0x70, 0xb1, 0xa2, 0x6c, 0x6a, 0xe9, 0xe9, 0x7d, + 0x8f, 0xa6, 0xd4, 0xb3, 0xc0, 0xeb, 0xc9, 0xa7, 0x96, 0xf5, 0x74, 0x12, 0x1c, 0x56, 0x96, 0x6c, + 0xc1, 0x0c, 0xaf, 0x7f, 0x1a, 0xdf, 0x22, 0xe7, 0xfb, 0xec, 0xe1, 0xc1, 0xac, 0xb6, 0x48, 0x7b, + 0x2e, 0x35, 0x74, 0x9f, 0xb6, 0x17, 0x87, 0x50, 0xe3, 0x50, 0x3e, 0x5a, 0x09, 0x0a, 0x2b, 0x4e, + 0x47, 0xfb, 0x4e, 0x01, 0x82, 0x1c, 0x57, 0xe4, 0x17, 0x72, 0x50, 0xd7, 0x6d, 0xdb, 0xf1, 0x65, + 0xfe, 0x28, 0x11, 0xdb, 0x85, 0x99, 0x53, 0x69, 0xcd, 0x35, 0x42, 0xa6, 0x22, 0xa4, 0x27, 0x88, + 0x18, 0x89, 0x60, 0x30, 0x2a, 0x9b, 0xf4, 0x13, 0x91, 0x46, 0xab, 0xd9, 0x6b, 0x71, 0x84, 0x98, + 0xa2, 0x0b, 0x5f, 0x83, 0x53, 0xc9, 0xca, 0x1e, 0x27, 0x9a, 0x21, 0x4b, 0x20, 0xc4, 0xf7, 0xf3, + 0x00, 0xa1, 0xef, 0xfe, 0x04, 0x6c, 0x79, 0x66, 0xcc, 0x96, 0x37, 0xfa, 0xe9, 0xf9, 0xb0, 0xd2, + 0x43, 0xed, 0x77, 0x77, 0x13, 0xf6, 0xbb, 0xe5, 0x71, 0x08, 0x7b, 0xb8, 0xcd, 0xee, 0xbf, 0xe6, + 0xe1, 0x7c, 0x48, 0xdc, 0xdc, 0xef, 0xe9, 0x9e, 0x17, 0x04, 0x8b, 0x93, 0x1d, 0x99, 0x9b, 0x25, + 0x37, 0xf6, 0x10, 0xff, 0x64, 0xa2, 0x16, 0x1f, 0xaa, 0xdb, 0xba, 0x65, 0x31, 0x2d, 0x20, 0xb3, + 0x1a, 0x34, 0x28, 0x8d, 0x6f, 0xd5, 0x96, 0x24, 0x7f, 0x0c, 0x24, 0x91, 0x7b, 0x50, 0x73, 0xec, + 0x56, 0xdf, 0x30, 0x42, 0x5f, 0xd1, 0x38, 0xc5, 0xf2, 0x6d, 0xdf, 0x9a, 0x12, 0x80, 0xa1, 0x2c, + 0x6d, 0x0b, 0xce, 0x84, 0xad, 0x1e, 0x4e, 0xea, 0x37, 0x13, 0x93, 0xae, 0xd8, 0x77, 0x7c, 0x6e, + 0xc8, 0xa4, 0x3b, 0x1d, 0x89, 0x61, 0x19, 0x9c, 0x76, 0xb5, 0x1f, 0xe6, 0xe1, 0x54, 0x54, 0x08, + 0x3f, 0x40, 0xfb, 0x25, 0x98, 0x74, 0xa9, 0xde, 0x6e, 0xea, 0xbe, 0xb1, 0xc3, 0xa3, 0xa5, 0x73, + 0x3c, 0xbc, 0x99, 0x9f, 0x22, 0xc2, 0x28, 0x02, 0xe3, 0x74, 0x44, 0x87, 0x3a, 0x03, 0xc8, 0x44, + 0x08, 0x23, 0xfa, 0x44, 0xb8, 0x01, 0x00, 0x43, 0x36, 0x18, 0xe5, 0x49, 0x1c, 0xa8, 0xb9, 0xba, + 0x4f, 0x85, 0xa2, 0x98, 0x35, 0x49, 0x15, 0x2a, 0x4e, 0xe2, 0x2b, 0x04, 0x8f, 0x18, 0xca, 0x20, + 0x57, 0xa0, 0x6e, 0x38, 0xb6, 0xd1, 0x77, 0x5d, 0x6a, 0xcb, 0x5d, 0x56, 0x51, 0xb9, 0x15, 0x02, + 0x30, 0x46, 0x69, 0xb4, 0x1f, 0xe5, 0x60, 0x2a, 0xda, 0xa8, 0x8f, 0xdc, 0xae, 0xbd, 0x13, 0xb7, + 0x6b, 0x2f, 0x8c, 0x61, 0x4a, 0x18, 0x62, 0xcb, 0xfe, 0xf6, 0x64, 0xf4, 0xd5, 0xb8, 0xfd, 0x3a, + 0x6a, 0x20, 0xcc, 0x3d, 0xd4, 0x40, 0xf8, 0x69, 0xaa, 0xa8, 0xa1, 0xa9, 0xa2, 0x86, 0xed, 0x44, + 0x4b, 0x8f, 0xf1, 0x4e, 0xb4, 0xfc, 0x31, 0xee, 0x44, 0x23, 0xc9, 0x98, 0x2a, 0x19, 0x92, 0x31, + 0x75, 0x83, 0x64, 0x4c, 0xd5, 0xb1, 0x2d, 0xa6, 0x47, 0x49, 0xc8, 0x54, 0x3b, 0xd1, 0x84, 0x4c, + 0xf0, 0xa8, 0x12, 0x32, 0xd5, 0xb3, 0x26, 0x64, 0xfa, 0xb9, 0x1c, 0x4c, 0xb5, 0x63, 0xc7, 0x4e, + 0xb9, 0xed, 0x31, 0x8b, 0x0a, 0x15, 0x3f, 0xc5, 0x2a, 0x0c, 0x5a, 0x71, 0x18, 0x26, 0x44, 0xa6, + 0xa5, 0x41, 0x9a, 0xfc, 0x78, 0xd2, 0x20, 0xbd, 0x0f, 0x35, 0x4b, 0x2d, 0xf4, 0x3c, 0x46, 0x39, + 0xcb, 0xd8, 0x4f, 0x51, 0x1e, 0xc2, 0xa8, 0xfe, 0x00, 0x84, 0xa1, 0x44, 0xb2, 0x07, 0xe5, 0x2d, + 0xae, 0xdd, 0xc9, 0x08, 0x67, 0x1c, 0xc7, 0x42, 0x12, 0x57, 0x17, 0xc5, 0xb8, 0x10, 0x40, 0x94, + 0xd2, 0x84, 0x35, 0x5c, 0x1d, 0x85, 0x3c, 0x25, 0xa2, 0x77, 0x86, 0x1e, 0x83, 0xfc, 0x1f, 0x95, + 0xa8, 0xca, 0x72, 0xd2, 0x5e, 0xca, 0x97, 0xe2, 0x5e, 0xca, 0xcb, 0x49, 0x2f, 0xe5, 0x80, 0xbe, + 0x25, 0x3d, 0x95, 0xcf, 0x47, 0x56, 0xc9, 0x02, 0xcf, 0xa7, 0x14, 0x8c, 0x8b, 0x94, 0x95, 0xb2, + 0x01, 0xd3, 0x52, 0x4d, 0x53, 0x48, 0xbe, 0xe6, 0x4c, 0x86, 0x11, 0xef, 0x8b, 0x71, 0x34, 0x26, + 0xe9, 0x99, 0x40, 0x4f, 0xa5, 0x55, 0x2e, 0xc5, 0xcd, 0xc9, 0x41, 0xca, 0xe3, 0x80, 0x82, 0x3c, + 0x0b, 0x65, 0x97, 0xea, 0x9e, 0xf4, 0x35, 0x46, 0xcc, 0x1e, 0xc8, 0xa1, 0x28, 0xb1, 0x51, 0x87, + 0x6b, 0xe5, 0x23, 0x1c, 0xae, 0x3a, 0xd4, 0x2d, 0xdd, 0xf3, 0x45, 0x8f, 0x57, 0x29, 0x58, 0xfe, + 0xbf, 0xa3, 0x69, 0x3d, 0x4c, 0xdb, 0x0b, 0x77, 0xb6, 0x2b, 0x21, 0x1b, 0x8c, 0xf2, 0x24, 0x6d, + 0x98, 0x60, 0x8f, 0x7c, 0xfa, 0x6b, 0x37, 0x7c, 0x39, 0xad, 0x1e, 0x47, 0x46, 0x60, 0x53, 0x59, + 0x89, 0xf0, 0xc1, 0x18, 0xd7, 0x21, 0x3e, 0x59, 0x18, 0xc5, 0x27, 0x4b, 0x5e, 0x11, 0xaa, 0xf5, + 0x7e, 0xf0, 0x59, 0xeb, 0xfc, 0xb3, 0x06, 0x56, 0x7b, 0x8c, 0x22, 0x31, 0x4e, 0xcb, 0x7a, 0x45, + 0x5f, 0x36, 0x83, 0x2a, 0x3e, 0x11, 0xef, 0x15, 0x9b, 0x71, 0x34, 0x26, 0xe9, 0xc9, 0x3a, 0x9c, + 0x0d, 0x40, 0xd1, 0x6a, 0x4c, 0x72, 0x3e, 0xc1, 0xe9, 0x91, 0xcd, 0x14, 0x1a, 0x4c, 0x2d, 0xc9, + 0x0f, 0xda, 0x70, 0xc5, 0xd7, 0xbf, 0xa1, 0x7b, 0x3b, 0xf2, 0x60, 0x45, 0x78, 0xd0, 0x26, 0x44, + 0x61, 0x94, 0x8e, 0x5c, 0x05, 0x10, 0xec, 0x78, 0xa9, 0x69, 0x5e, 0x2a, 0xd8, 0x63, 0x6f, 0x06, + 0x18, 0x8c, 0x50, 0x69, 0xff, 0x27, 0x07, 0x55, 0x65, 0xdb, 0x67, 0x6b, 0xe9, 0x96, 0xee, 0x99, + 0x86, 0x1c, 0xf0, 0x19, 0x32, 0xd5, 0xaa, 0x74, 0x61, 0x22, 0xa2, 0x8c, 0x3f, 0xa2, 0xe0, 0x1d, + 0x26, 0x6c, 0xcb, 0x67, 0x4a, 0xd8, 0x46, 0x16, 0xa0, 0x68, 0xef, 0xd2, 0xfd, 0xe3, 0x1d, 0x65, + 0xe6, 0xca, 0xe7, 0xad, 0x9b, 0x74, 0x1f, 0x79, 0x61, 0xed, 0x37, 0xf3, 0x00, 0xec, 0xf5, 0x8f, + 0xe6, 0x76, 0xfa, 0x3c, 0x54, 0xa4, 0x6f, 0x47, 0xa5, 0xb4, 0x0f, 0x02, 0xf3, 0x04, 0x18, 0x15, + 0x9e, 0x3c, 0x0d, 0xa5, 0xbb, 0x7d, 0xda, 0x57, 0x31, 0x14, 0x81, 0x5a, 0xf1, 0x26, 0x03, 0xa2, + 0xc0, 0x3d, 0x3a, 0x8b, 0xab, 0xf2, 0xfa, 0x94, 0x1e, 0x95, 0xd7, 0xa7, 0x06, 0x95, 0x5b, 0x0e, + 0x8f, 0xf3, 0xd5, 0x5e, 0x00, 0x95, 0x11, 0x90, 0xb5, 0x0f, 0x95, 0xae, 0xbf, 0x5c, 0x3c, 0x70, + 0x51, 0xf9, 0xfd, 0x14, 0x5e, 0xfb, 0xcf, 0x79, 0x80, 0x30, 0xfa, 0x92, 0xfc, 0xcd, 0x1c, 0x3c, + 0x11, 0xf8, 0xa4, 0x7d, 0xa1, 0x53, 0xf2, 0x94, 0xd2, 0x99, 0xfd, 0x46, 0x69, 0xfe, 0x70, 0x9e, + 0xc0, 0x61, 0x3d, 0x4d, 0x1c, 0xa6, 0xd7, 0x82, 0x20, 0x54, 0x69, 0xb7, 0xe7, 0xef, 0x2f, 0x9a, + 0xae, 0xec, 0xb7, 0xa9, 0x41, 0xbe, 0xd7, 0x24, 0x8d, 0x28, 0x2a, 0x77, 0x54, 0x7c, 0xeb, 0xa6, + 0x30, 0x18, 0xf0, 0x21, 0x3b, 0x50, 0xb5, 0x9d, 0x77, 0x3c, 0xd6, 0x88, 0xb2, 0x13, 0x8f, 0x9e, + 0x4c, 0x4b, 0x7e, 0x0c, 0xe1, 0x3f, 0x90, 0x0f, 0x58, 0xb1, 0xe5, 0x27, 0xfa, 0xe5, 0x3c, 0x9c, + 0x49, 0x69, 0x07, 0xf2, 0x3a, 0x9c, 0x92, 0x81, 0xae, 0x61, 0x6e, 0xf5, 0x5c, 0x98, 0x5b, 0xbd, + 0x95, 0xc0, 0xe1, 0x00, 0x35, 0x79, 0x07, 0x40, 0xe7, 0x96, 0x95, 0x55, 0xa7, 0xad, 0xd6, 0xef, + 0xd7, 0xd8, 0x74, 0xd3, 0x08, 0xa0, 0x0f, 0x0e, 0x66, 0x7f, 0x2a, 0x2d, 0x76, 0x3d, 0xd1, 0xce, + 0x61, 0x01, 0x8c, 0xb0, 0x24, 0xdf, 0x02, 0x10, 0x1b, 0x8b, 0xe0, 0x88, 0xf9, 0x47, 0x6c, 0xf3, + 0xe7, 0x54, 0x1a, 0x9f, 0xb9, 0x37, 0xfb, 0xba, 0xed, 0x9b, 0xfe, 0xbe, 0x48, 0x6b, 0x71, 0x3b, + 0xe0, 0x82, 0x11, 0x8e, 0xda, 0xef, 0xe6, 0xa1, 0xaa, 0x6c, 0xe8, 0x27, 0x60, 0xd4, 0xec, 0xc4, + 0x8c, 0x9a, 0x63, 0x8a, 0x56, 0x4f, 0x33, 0x69, 0x3a, 0x09, 0x93, 0xe6, 0xf5, 0xec, 0xa2, 0x1e, + 0x6e, 0xd0, 0xfc, 0x67, 0x05, 0x98, 0x52, 0xa4, 0x59, 0x6d, 0x5e, 0xaf, 0xc2, 0xb4, 0x08, 0xbb, + 0x58, 0xd5, 0xef, 0x8b, 0x0c, 0x1f, 0xbc, 0xc1, 0x8a, 0x22, 0x1e, 0xb6, 0x19, 0x47, 0x61, 0x92, + 0x96, 0x75, 0x6b, 0x01, 0xda, 0x64, 0x4a, 0x53, 0x68, 0xd6, 0x9a, 0x14, 0xdd, 0xba, 0x99, 0xc0, + 0xe1, 0x00, 0x75, 0xd2, 0xe8, 0x56, 0x7c, 0xd4, 0x46, 0xb7, 0xd2, 0xc9, 0x1b, 0xdd, 0xca, 0x47, + 0x30, 0xba, 0xfd, 0xf3, 0x1c, 0x4c, 0x84, 0xdf, 0xf4, 0x91, 0x9b, 0xdc, 0xb6, 0xe3, 0x26, 0xb7, + 0x46, 0xe6, 0x2e, 0x3b, 0xcc, 0xe0, 0x56, 0x83, 0xd8, 0xc1, 0x0e, 0xb2, 0x05, 0x17, 0xcc, 0xd4, + 0x78, 0xcd, 0xc8, 0x8c, 0x18, 0x9c, 0xd6, 0x5d, 0x1e, 0x4a, 0x89, 0x0f, 0xe1, 0x42, 0xfa, 0x50, + 0xdd, 0xa3, 0xae, 0x6f, 0x1a, 0x54, 0xbd, 0xdf, 0xf5, 0xcc, 0x16, 0x28, 0xb9, 0x1b, 0x0c, 0xda, + 0xf4, 0xb6, 0x14, 0x80, 0x81, 0x28, 0xb2, 0x05, 0x25, 0xda, 0xee, 0x50, 0x75, 0xdb, 0x4a, 0xc6, + 0x64, 0xa3, 0x41, 0x7b, 0xb2, 0x27, 0x0f, 0x05, 0x6b, 0xe2, 0x45, 0x77, 0xd8, 0xc5, 0x8c, 0x5d, + 0xf9, 0xa8, 0xfb, 0xea, 0xdd, 0xc0, 0xcc, 0x54, 0x1a, 0xd3, 0x04, 0xf7, 0x10, 0x23, 0x93, 0x07, + 0xb5, 0x7b, 0xba, 0x4f, 0xdd, 0xae, 0xee, 0xee, 0x4a, 0x1b, 0xdd, 0xe8, 0x6f, 0x78, 0x47, 0x71, + 0x0a, 0xdf, 0x30, 0x00, 0x61, 0x28, 0x87, 0xcd, 0x10, 0xbe, 0x34, 0xa7, 0xa8, 0x94, 0x8a, 0xa3, + 0x0b, 0x55, 0x86, 0x19, 0xe9, 0x1c, 0x09, 0x1e, 0x31, 0x94, 0x41, 0xf6, 0x62, 0xa9, 0xb9, 0x45, + 0x42, 0xf6, 0x0c, 0x77, 0x3b, 0x28, 0x56, 0xe1, 0x92, 0x38, 0x24, 0xc5, 0xf7, 0x87, 0x39, 0x98, + 0x4e, 0x8c, 0x1c, 0xb9, 0xed, 0xbc, 0x31, 0xae, 0x68, 0x72, 0x75, 0x92, 0x22, 0x06, 0xc4, 0xa4, + 0xd4, 0x68, 0xca, 0x6c, 0x78, 0xa4, 0x29, 0xb3, 0xff, 0x5b, 0x29, 0x5c, 0x2d, 0x4f, 0xda, 0xdc, + 0xf2, 0x42, 0xdc, 0xdc, 0x72, 0x29, 0x69, 0x6e, 0x49, 0xc4, 0x14, 0x1c, 0x3f, 0x2c, 0x3c, 0x61, + 0xa5, 0x28, 0x3e, 0x02, 0x2b, 0xc5, 0x15, 0xa8, 0xef, 0xf1, 0xc9, 0x4f, 0xa4, 0x14, 0x2a, 0xf1, + 0xd5, 0x9d, 0x2f, 0x66, 0xb7, 0x43, 0x30, 0x46, 0x69, 0xf8, 0x9d, 0x64, 0xe2, 0xaa, 0x9a, 0x20, + 0x1f, 0xaf, 0x2c, 0xd2, 0x0a, 0xc1, 0x18, 0xa5, 0xe1, 0x36, 0x34, 0xd3, 0xde, 0x15, 0x05, 0x2a, + 0xbc, 0x80, 0xb0, 0xa1, 0x29, 0x20, 0x86, 0x78, 0xf2, 0x1c, 0x54, 0xfb, 0xed, 0x6d, 0x41, 0x5b, + 0xe5, 0xb4, 0x5c, 0xf1, 0xdf, 0x5c, 0x5c, 0x92, 0x29, 0x8e, 0x14, 0x96, 0xd5, 0xa4, 0xab, 0xf7, + 0x14, 0x82, 0x77, 0x75, 0x59, 0x93, 0xd5, 0x10, 0x8c, 0x51, 0x1a, 0xf2, 0x15, 0x98, 0x72, 0x69, + 0xbb, 0x6f, 0xd0, 0xa0, 0x14, 0xf0, 0x52, 0x32, 0x01, 0x62, 0x14, 0x83, 0x09, 0xca, 0x21, 0xb6, + 0x96, 0xfa, 0x48, 0xb6, 0x96, 0xaf, 0xc1, 0x54, 0xdb, 0xd5, 0x4d, 0x9b, 0xb6, 0xd7, 0x6c, 0x1e, + 0x38, 0x22, 0xe3, 0x5a, 0x03, 0x63, 0xec, 0x62, 0x0c, 0x8b, 0x09, 0x6a, 0x6d, 0x09, 0xc4, 0xf1, + 0x32, 0x32, 0x0b, 0xa5, 0x1d, 0xdf, 0xef, 0x29, 0xf7, 0x16, 0xdf, 0xde, 0xf3, 0x83, 0x76, 0x28, + 0xe0, 0xe4, 0x22, 0x14, 0xd9, 0x1f, 0x19, 0x1f, 0xcf, 0xf7, 0x9f, 0x0c, 0x8f, 0x1c, 0xaa, 0xfd, + 0x5e, 0x1e, 0x4a, 0x22, 0xbd, 0xe3, 0x32, 0x9c, 0x31, 0x6d, 0xd3, 0x37, 0x75, 0x8b, 0x1f, 0x86, + 0x8a, 0x06, 0xe2, 0x94, 0x9a, 0x4f, 0x1e, 0x1e, 0xcc, 0x9e, 0x59, 0x1e, 0x44, 0x63, 0x5a, 0x19, + 0xd6, 0xc8, 0x32, 0xcd, 0xbc, 0xe2, 0x22, 0x84, 0x8b, 0x04, 0xc9, 0x31, 0x0c, 0x26, 0x28, 0x99, + 0xae, 0xdb, 0x1b, 0x88, 0xb0, 0x29, 0x09, 0x5d, 0x37, 0x1e, 0xf4, 0x12, 0xa7, 0xe3, 0x7b, 0x30, + 0xe1, 0x9c, 0x0e, 0xce, 0xc4, 0xc9, 0x60, 0x3d, 0xb1, 0x07, 0x4b, 0xe0, 0x70, 0x80, 0x9a, 0x71, + 0xd8, 0xd6, 0x4d, 0xab, 0xef, 0xd2, 0x90, 0x43, 0x29, 0xe4, 0xb0, 0x94, 0xc0, 0xe1, 0x00, 0xb5, + 0xf6, 0x7b, 0x39, 0x00, 0x71, 0x6f, 0x0d, 0x37, 0x03, 0x8d, 0x29, 0xa5, 0x3e, 0xe9, 0x43, 0x6d, + 0x4b, 0x19, 0x82, 0x32, 0xe7, 0x5b, 0x17, 0xf5, 0x0b, 0x0d, 0x4b, 0xe2, 0x0a, 0x24, 0xf5, 0x88, + 0xa1, 0x24, 0xed, 0xef, 0xe6, 0x60, 0x3a, 0x41, 0x4d, 0xd6, 0xa0, 0xaa, 0x12, 0xd6, 0x1d, 0xef, + 0xad, 0xc4, 0x18, 0x96, 0x45, 0x31, 0x60, 0x32, 0xfe, 0x0c, 0xf6, 0x3f, 0x9b, 0x57, 0xdf, 0x80, + 0xc7, 0x5e, 0x5e, 0x05, 0x90, 0x89, 0x65, 0xda, 0x6d, 0x57, 0xaa, 0xa0, 0xe1, 0x3a, 0x1a, 0x60, + 0x30, 0x42, 0x75, 0xb4, 0x30, 0xc1, 0x97, 0x61, 0xa2, 0xe7, 0x3a, 0x6c, 0x82, 0x70, 0xb9, 0x76, + 0x9b, 0x88, 0xed, 0x5e, 0x8f, 0xe0, 0x30, 0x46, 0x49, 0x74, 0x69, 0x54, 0x2a, 0x8f, 0xe5, 0xc6, + 0xa4, 0x54, 0xb3, 0xd2, 0xff, 0xcc, 0xc3, 0x84, 0x6c, 0x04, 0x61, 0x90, 0x7b, 0x94, 0xcd, 0xa0, + 0xa2, 0x1f, 0xd3, 0x9a, 0x61, 0x21, 0x82, 0xc3, 0x18, 0x25, 0x59, 0x64, 0x03, 0x76, 0xcb, 0x33, + 0x5c, 0x93, 0xc7, 0xf7, 0xf3, 0xd2, 0x22, 0x4e, 0x3c, 0x38, 0xcd, 0xdd, 0x4a, 0xe0, 0x71, 0xa0, + 0x04, 0x79, 0x1e, 0xaa, 0x5d, 0xfd, 0xfe, 0xa6, 0xad, 0x1b, 0xbb, 0x72, 0xf5, 0x0a, 0xb4, 0xf8, + 0x55, 0x09, 0xc7, 0x80, 0xe2, 0x24, 0x9a, 0xfe, 0x57, 0x8a, 0x10, 0xee, 0x1b, 0xc9, 0x79, 0x28, + 0x74, 0xf5, 0xfb, 0x72, 0xc3, 0xce, 0x6d, 0x8b, 0xab, 0xfa, 0x7d, 0x64, 0x30, 0x8e, 0x32, 0x6d, + 0xb9, 0x21, 0x17, 0x28, 0xd3, 0x46, 0x06, 0x23, 0xef, 0xc2, 0x94, 0xab, 0x77, 0x7b, 0x9b, 0x3d, + 0xb5, 0x07, 0x1e, 0xf1, 0x74, 0xad, 0x58, 0xd5, 0x62, 0x9c, 0x30, 0xc1, 0x99, 0xf4, 0xa1, 0x24, + 0x4c, 0x67, 0xc5, 0x8c, 0x5e, 0xe6, 0xe0, 0xa5, 0x99, 0x26, 0xe8, 0xb8, 0x54, 0xde, 0x2b, 0x98, + 0x80, 0xa2, 0x90, 0xc6, 0xc4, 0x76, 0x9d, 0x76, 0x90, 0x94, 0x62, 0x2c, 0x62, 0x57, 0x19, 0xc3, + 0x01, 0xb1, 0x1c, 0x8a, 0x42, 0x9a, 0x30, 0xa5, 0xb0, 0x3e, 0xd8, 0x16, 0xcd, 0xc2, 0x7b, 0x42, + 0x55, 0x99, 0x52, 0x22, 0x08, 0x8c, 0xd3, 0x91, 0x65, 0x28, 0xf8, 0xbe, 0x25, 0xb7, 0x0f, 0x23, + 0xdd, 0x15, 0xb2, 0xb1, 0xb1, 0x82, 0x8c, 0x87, 0xf6, 0x57, 0xf3, 0x40, 0x22, 0xf5, 0xbb, 0xee, + 0x34, 0x75, 0x63, 0xf7, 0x16, 0xfb, 0xe8, 0x86, 0xe3, 0x58, 0x8b, 0xce, 0x3d, 0x5b, 0x2c, 0x74, + 0x23, 0x9e, 0x0b, 0xe7, 0x1f, 0x7d, 0x21, 0xc6, 0x09, 0x13, 0x9c, 0xc9, 0x12, 0x10, 0xd6, 0x0d, + 0x24, 0xc4, 0xa0, 0xb6, 0xaf, 0x12, 0x6c, 0x4c, 0x36, 0xcf, 0x31, 0x35, 0x06, 0x07, 0xb0, 0x98, + 0x52, 0x82, 0x29, 0x0d, 0xc1, 0xb1, 0xf3, 0x08, 0x23, 0x61, 0x24, 0xe2, 0x4a, 0xc3, 0xc6, 0x20, + 0x1a, 0xd3, 0xca, 0x68, 0x17, 0x60, 0x26, 0xd2, 0x28, 0xcb, 0xf6, 0x2a, 0xed, 0x3a, 0xee, 0xbe, + 0xb0, 0xbb, 0xfe, 0x5a, 0x11, 0x06, 0xbe, 0x28, 0xf9, 0xf9, 0x1c, 0xd4, 0x3c, 0x63, 0x87, 0xb6, + 0xfb, 0x16, 0x55, 0x6b, 0xc7, 0xea, 0x58, 0x7a, 0xaf, 0x62, 0x2a, 0xb2, 0x89, 0xa6, 0x61, 0x30, + 0x94, 0x4c, 0xde, 0x87, 0x8a, 0x4b, 0x2d, 0xfd, 0x3e, 0x55, 0x1f, 0xec, 0xe6, 0x38, 0x2a, 0x81, + 0x82, 0xa5, 0xfa, 0x1a, 0x49, 0x38, 0x2a, 0x99, 0xe4, 0x17, 0x72, 0x00, 0x8e, 0x6d, 0xed, 0x2f, + 0x6f, 0x6f, 0x7a, 0xf2, 0xac, 0x43, 0xfd, 0xea, 0xad, 0x71, 0x54, 0x61, 0x2d, 0xe0, 0x2a, 0x0c, + 0xfd, 0xa9, 0x28, 0x8c, 0x08, 0x67, 0x4d, 0xd1, 0x11, 0xbd, 0x59, 0xce, 0x26, 0x63, 0x69, 0x0a, + 0x39, 0x40, 0x06, 0x9a, 0x42, 0xc2, 0x51, 0xc9, 0xd4, 0xb6, 0x20, 0xbd, 0x8e, 0xc3, 0xba, 0x69, + 0x6e, 0x84, 0x6e, 0xfa, 0x1f, 0x72, 0x31, 0x21, 0x48, 0xdb, 0xa6, 0xc8, 0xd3, 0x42, 0x2e, 0x43, + 0x91, 0xcd, 0x31, 0xc9, 0x94, 0xd4, 0xdc, 0x12, 0xcf, 0x31, 0x6c, 0xc6, 0xef, 0xbb, 0x96, 0x5c, + 0x4e, 0x2b, 0x31, 0x8f, 0xd8, 0x1e, 0x54, 0x3d, 0x6a, 0xfb, 0xa6, 0x4d, 0x2d, 0xf9, 0x09, 0x47, + 0xf7, 0xd4, 0x88, 0x3a, 0x49, 0x6e, 0xf2, 0x0c, 0xb0, 0x3c, 0xeb, 0x27, 0x60, 0x18, 0xc8, 0x22, + 0xe7, 0x20, 0xdf, 0xde, 0x92, 0x7a, 0x72, 0xf9, 0xf0, 0x60, 0x36, 0xbf, 0xd8, 0xc4, 0x7c, 0x7b, + 0x4b, 0x3b, 0x0b, 0x29, 0x9d, 0x4e, 0x3b, 0x07, 0xa9, 0xa3, 0x41, 0xfb, 0xad, 0x3c, 0x0c, 0x4c, + 0xf4, 0xbc, 0x63, 0xba, 0x41, 0xf3, 0xc8, 0xb1, 0x71, 0x6b, 0x3c, 0x63, 0x43, 0x71, 0x1d, 0xe8, + 0x98, 0x21, 0x0a, 0x23, 0xc2, 0xc9, 0x5f, 0xcb, 0xc1, 0xa4, 0x19, 0x9d, 0x52, 0xe4, 0x7c, 0xf1, + 0xe6, 0x38, 0xaa, 0x13, 0x9b, 0xab, 0xc4, 0xf1, 0xd5, 0x61, 0x58, 0x8c, 0xd7, 0x42, 0xfb, 0x8d, + 0x1c, 0xd4, 0x78, 0x95, 0x3f, 0x21, 0xca, 0xf5, 0x6f, 0x17, 0xe1, 0x4c, 0x4a, 0xf7, 0x62, 0xea, + 0x65, 0x57, 0xf7, 0x7c, 0xa9, 0x03, 0x26, 0xd4, 0xcb, 0xd5, 0x00, 0x83, 0x11, 0x2a, 0xf2, 0x05, + 0xa8, 0x51, 0xbb, 0xdd, 0x73, 0x4c, 0xdb, 0xf7, 0xe4, 0xa5, 0x30, 0x7c, 0x2f, 0x72, 0x4d, 0x01, + 0x31, 0xc4, 0x93, 0xfb, 0x30, 0xa1, 0xfa, 0x2c, 0xdf, 0x05, 0x65, 0xb5, 0x8e, 0x06, 0x8d, 0x2e, + 0xd3, 0x9c, 0x44, 0x78, 0x63, 0x4c, 0x12, 0xf7, 0x2f, 0x28, 0xe2, 0xec, 0xfe, 0x85, 0x40, 0xac, + 0xf0, 0x2f, 0xa8, 0x47, 0x0c, 0x65, 0x10, 0x07, 0xea, 0xaa, 0x02, 0x1b, 0x2b, 0xad, 0xb1, 0x1c, + 0x65, 0x94, 0x37, 0xc6, 0x07, 0x4c, 0x31, 0x2a, 0x81, 0x6c, 0x43, 0x95, 0x4b, 0x67, 0xd2, 0x2a, + 0x63, 0x90, 0x26, 0x43, 0x6c, 0x05, 0x47, 0x0c, 0x78, 0x6b, 0xff, 0x20, 0x07, 0x93, 0x48, 0x7d, + 0xd6, 0xf7, 0xc3, 0x9b, 0xf5, 0xe4, 0xb1, 0x39, 0xd9, 0xdf, 0x5f, 0xcf, 0x10, 0x29, 0xc1, 0xf9, + 0xc8, 0x83, 0x5f, 0xba, 0xb1, 0xbb, 0xb6, 0xbd, 0x8d, 0x8a, 0x3b, 0xb9, 0x06, 0x35, 0xc7, 0x96, + 0x1b, 0x78, 0x39, 0xff, 0x7e, 0x4e, 0xc4, 0xb6, 0x4b, 0xe0, 0x83, 0x83, 0xd9, 0x73, 0xc1, 0x43, + 0xac, 0x92, 0x18, 0x96, 0xd4, 0x7e, 0x9e, 0x4d, 0xfe, 0x8e, 0x65, 0x99, 0x76, 0x27, 0x1e, 0x2c, + 0x47, 0x2c, 0x98, 0x12, 0x9b, 0x8c, 0x3d, 0xdd, 0xb4, 0xf4, 0x2d, 0x8b, 0x7e, 0xa4, 0xdf, 0xb3, + 0xef, 0x9b, 0xd6, 0x1c, 0xeb, 0xdb, 0xbe, 0x3b, 0xb7, 0x6c, 0xfb, 0x6b, 0x6e, 0xcb, 0x77, 0x4d, + 0xbb, 0x23, 0xd4, 0xb7, 0xd5, 0x18, 0x2f, 0x4c, 0xf0, 0xd6, 0xfe, 0x75, 0x11, 0xf8, 0x91, 0x2c, + 0xf2, 0x25, 0xa8, 0x75, 0xa9, 0xb1, 0xa3, 0xdb, 0xa6, 0xa7, 0xee, 0x42, 0x60, 0x33, 0x62, 0x6d, + 0x55, 0x01, 0x1f, 0xb0, 0x69, 0xbf, 0xd1, 0x5a, 0xe1, 0x69, 0x1c, 0x42, 0x5a, 0x62, 0x40, 0xb9, + 0xe3, 0x79, 0x7a, 0xcf, 0xcc, 0x1c, 0xee, 0x2c, 0xd2, 0xee, 0x0b, 0x6b, 0xbf, 0xf8, 0x8f, 0x92, + 0x35, 0x31, 0xa0, 0xd4, 0xb3, 0x74, 0xd3, 0xce, 0x1c, 0x0b, 0xcf, 0xde, 0x60, 0x9d, 0x71, 0x92, + 0x89, 0x95, 0xd8, 0x5f, 0x14, 0xbc, 0x49, 0x1f, 0xea, 0x9e, 0xe1, 0xea, 0x5d, 0x6f, 0x47, 0xbf, + 0xfa, 0xe2, 0x4b, 0x99, 0x27, 0x86, 0x50, 0x94, 0x18, 0x34, 0x0b, 0xd8, 0x58, 0x6d, 0xdd, 0x68, + 0x5c, 0x7d, 0xf1, 0x25, 0x8c, 0xca, 0x89, 0x8a, 0x7d, 0xf1, 0xca, 0xd5, 0xec, 0x17, 0x38, 0xa7, + 0x8b, 0x7d, 0xf1, 0xca, 0x55, 0x8c, 0xca, 0x61, 0x4d, 0xea, 0x44, 0x76, 0xb0, 0xd9, 0x04, 0xae, + 0x85, 0x91, 0x45, 0xfc, 0x2f, 0x0a, 0xde, 0xda, 0x7f, 0xcf, 0x41, 0x2d, 0xc0, 0xb3, 0x45, 0x44, + 0x24, 0x14, 0x5e, 0x5e, 0x1c, 0x61, 0x55, 0x5a, 0x90, 0x45, 0x31, 0x60, 0x42, 0xde, 0x86, 0x09, + 0xf1, 0x5f, 0x26, 0xf8, 0xcf, 0x1f, 0xfb, 0x16, 0x81, 0x85, 0x48, 0x71, 0x8c, 0x31, 0x23, 0xaf, + 0xc0, 0x24, 0x37, 0x9a, 0xa9, 0x55, 0x44, 0x1a, 0x24, 0x82, 0x20, 0xb6, 0x8d, 0x28, 0x12, 0xe3, + 0xb4, 0xc1, 0x8b, 0xf3, 0x2f, 0x41, 0x36, 0x01, 0xd8, 0x4a, 0x2a, 0x6b, 0x79, 0xac, 0x57, 0xe7, + 0x91, 0x12, 0x9b, 0x41, 0x61, 0x8c, 0x30, 0x4a, 0xb9, 0xa7, 0x21, 0x3f, 0xee, 0x7b, 0x1a, 0xe6, + 0xa1, 0xb6, 0xa3, 0xdb, 0x6d, 0x6f, 0x47, 0xdf, 0xa5, 0xf2, 0x9c, 0x70, 0xe0, 0x22, 0xbb, 0xa1, + 0x10, 0x18, 0xd2, 0x68, 0xdf, 0x2d, 0x83, 0x08, 0xd4, 0x26, 0xcf, 0x43, 0xb5, 0x6d, 0x7a, 0xd1, + 0xd8, 0xa3, 0xc0, 0x9e, 0xb2, 0x28, 0xe1, 0x18, 0x50, 0x44, 0x6d, 0x18, 0xa5, 0x84, 0x0d, 0x43, + 0x5a, 0x3e, 0x0a, 0x11, 0x94, 0xb2, 0x7c, 0xbc, 0x0a, 0xd3, 0x96, 0xe3, 0xec, 0xb2, 0xc9, 0x39, + 0x7a, 0xde, 0x71, 0x52, 0x38, 0x97, 0x56, 0xe2, 0x28, 0x4c, 0xd2, 0x92, 0x4d, 0x78, 0xf2, 0x3d, + 0xea, 0x3a, 0x32, 0xca, 0xaf, 0x65, 0x51, 0xda, 0x53, 0x6c, 0x84, 0x05, 0x88, 0x1f, 0xc7, 0xfc, + 0x46, 0x3a, 0x09, 0x0e, 0x2b, 0xcb, 0x0f, 0x90, 0xeb, 0x6e, 0x87, 0xfa, 0xeb, 0xae, 0x63, 0x50, + 0xcf, 0x33, 0xed, 0x8e, 0x62, 0x5b, 0x0e, 0xd9, 0x6e, 0xa4, 0x93, 0xe0, 0xb0, 0xb2, 0xe4, 0x2d, + 0x98, 0x11, 0x28, 0xe1, 0x1a, 0x6b, 0x88, 0x49, 0xdc, 0xb4, 0x4c, 0x7f, 0x5f, 0xba, 0x42, 0xb8, + 0xc6, 0xb8, 0x31, 0x84, 0x06, 0x87, 0x96, 0x26, 0x6f, 0xc0, 0x29, 0x15, 0x94, 0xbb, 0xce, 0xb4, + 0x71, 0xdd, 0xa2, 0xd2, 0x61, 0x22, 0xcf, 0xcd, 0xaa, 0x73, 0xa3, 0x98, 0xa0, 0xc2, 0x81, 0x72, + 0x04, 0xe1, 0x1c, 0x8f, 0xd0, 0xdf, 0xec, 0x2d, 0x38, 0x8e, 0xd5, 0x76, 0xee, 0xd9, 0xea, 0xdd, + 0x85, 0x57, 0x85, 0xdf, 0xb7, 0xd8, 0x4a, 0xa5, 0xc0, 0x21, 0x25, 0xd9, 0x9b, 0x73, 0xcc, 0xa2, + 0x73, 0xcf, 0x4e, 0x72, 0x85, 0xf0, 0xcd, 0x5b, 0x43, 0x68, 0x70, 0x68, 0x69, 0x6e, 0xbe, 0x48, + 0xbc, 0xc1, 0x66, 0x4f, 0x86, 0xab, 0x8a, 0x5d, 0xe2, 0x00, 0x16, 0x53, 0x4a, 0x90, 0x15, 0x38, + 0x9b, 0x84, 0x32, 0x71, 0x32, 0x72, 0x55, 0xec, 0xfe, 0x53, 0xf0, 0x98, 0x5a, 0x4a, 0xab, 0x43, + 0x2d, 0xb8, 0x87, 0x5f, 0xfb, 0x57, 0x79, 0x98, 0x4e, 0x64, 0x18, 0x3e, 0x81, 0xb0, 0x28, 0x3b, + 0x16, 0x16, 0x35, 0xfa, 0x16, 0x32, 0x51, 0xf3, 0xa1, 0xd1, 0x51, 0x7b, 0x89, 0xe8, 0xa8, 0x5b, + 0x63, 0x93, 0xf8, 0xf0, 0x20, 0xa9, 0xc3, 0x1c, 0x9c, 0x49, 0x94, 0x38, 0x81, 0xb8, 0x9a, 0x6e, + 0x3c, 0xae, 0xe6, 0xc6, 0xb8, 0x5e, 0x76, 0x48, 0x78, 0xcd, 0xff, 0x1e, 0x7c, 0xc9, 0x96, 0x08, + 0x49, 0xab, 0xc8, 0x64, 0xae, 0xf2, 0x1d, 0x17, 0xb3, 0x56, 0x84, 0x7f, 0xdf, 0x78, 0x72, 0x4c, + 0xbb, 0x83, 0x4a, 0x0a, 0xf1, 0xa0, 0xaa, 0x32, 0xb6, 0x8e, 0x37, 0xe0, 0x2e, 0x68, 0xec, 0x20, + 0x09, 0x77, 0x20, 0x48, 0xfb, 0xa5, 0x02, 0x3c, 0x91, 0xda, 0x29, 0x4e, 0xce, 0xc1, 0xff, 0x4a, + 0xdc, 0xc1, 0xff, 0x4c, 0xd2, 0xc1, 0x7f, 0x36, 0x51, 0xbf, 0xc7, 0xd8, 0xcf, 0x3f, 0x46, 0xdf, + 0xb5, 0x36, 0x0d, 0x93, 0xb1, 0x2c, 0xc3, 0xda, 0x0f, 0xcb, 0x50, 0x8f, 0xf4, 0xa4, 0x3f, 0x7d, + 0xd9, 0x5d, 0xc9, 0x57, 0x60, 0xaa, 0xeb, 0x75, 0x96, 0x17, 0x6f, 0x50, 0xbd, 0x4d, 0xdd, 0x9b, + 0x54, 0x65, 0x3c, 0x12, 0x9b, 0xb9, 0x18, 0x06, 0x13, 0x94, 0x64, 0x05, 0x9e, 0x70, 0xe9, 0xdd, + 0x3e, 0xf5, 0xfc, 0xb8, 0x6b, 0x5c, 0x2a, 0x33, 0x72, 0x3d, 0x4b, 0x10, 0x78, 0x98, 0x5e, 0x88, + 0xcd, 0x51, 0xc2, 0x9d, 0x53, 0xce, 0x38, 0x50, 0xd5, 0x07, 0xe5, 0x46, 0x2d, 0x69, 0x24, 0x09, + 0x21, 0xca, 0x8d, 0x93, 0x7e, 0xfa, 0xb2, 0xf2, 0x31, 0x9e, 0xbe, 0x8c, 0x1e, 0xf9, 0xad, 0x3e, + 0xf4, 0xc8, 0xef, 0xb0, 0x73, 0xad, 0xb5, 0xc7, 0xe1, 0x5c, 0xab, 0xf6, 0x01, 0xc4, 0x1a, 0x9c, + 0x38, 0x50, 0x0b, 0x5e, 0x36, 0xf3, 0xb9, 0x92, 0xf0, 0x04, 0x24, 0xb7, 0x43, 0x05, 0x8f, 0x18, + 0xca, 0xd0, 0xb6, 0xd9, 0x30, 0xe7, 0xb9, 0x68, 0xe5, 0x45, 0x83, 0x9b, 0x50, 0x91, 0xc1, 0x1a, + 0x23, 0x7a, 0xa6, 0xb8, 0x6d, 0x46, 0x05, 0xf1, 0x2a, 0x5e, 0xda, 0xbf, 0xc8, 0x43, 0x2d, 0x08, + 0x68, 0x23, 0x97, 0xa1, 0x68, 0x87, 0x36, 0xc4, 0x40, 0xe7, 0xe0, 0xd6, 0x43, 0x8e, 0x89, 0x37, + 0x44, 0xfe, 0xd1, 0x37, 0x44, 0xf4, 0x3c, 0x6f, 0x21, 0xc3, 0x79, 0xde, 0x1e, 0x54, 0x7c, 0xd7, + 0xec, 0x74, 0xa8, 0x9b, 0xd9, 0xd5, 0x1a, 0x34, 0xd7, 0x86, 0x60, 0x28, 0x5b, 0x56, 0x3c, 0xa0, + 0x12, 0xa3, 0xbd, 0x0b, 0xa7, 0x92, 0x94, 0xfc, 0xe8, 0x9d, 0xb4, 0xdb, 0xcb, 0x36, 0x0e, 0x8f, + 0xde, 0x49, 0x38, 0x06, 0x14, 0x6c, 0x30, 0xb1, 0xcf, 0xf4, 0x9e, 0x63, 0xab, 0x45, 0x90, 0x0f, + 0xa6, 0x0d, 0x09, 0xc3, 0x00, 0xab, 0xfd, 0xa7, 0x02, 0x9c, 0x0f, 0xc3, 0x12, 0x57, 0x75, 0x5b, + 0xef, 0xc4, 0x6f, 0x15, 0xfd, 0x34, 0x99, 0xd9, 0x58, 0x6e, 0x61, 0x2d, 0x3c, 0x06, 0xb7, 0xb0, + 0xfe, 0x51, 0x01, 0x78, 0xe2, 0x01, 0xf2, 0x01, 0x4c, 0xa8, 0xf6, 0x6c, 0x85, 0x69, 0x56, 0xae, + 0x65, 0xfe, 0x9c, 0x3c, 0xbf, 0x41, 0x10, 0x43, 0x12, 0x85, 0x62, 0x4c, 0x20, 0x71, 0x06, 0xb2, + 0xae, 0x8c, 0x49, 0xf8, 0xb0, 0x84, 0x2b, 0xee, 0x60, 0xc2, 0x95, 0x31, 0x49, 0x1c, 0x9a, 0x6b, + 0x85, 0xfc, 0x5c, 0x0e, 0x26, 0xdd, 0xa8, 0x49, 0x5a, 0xce, 0x1f, 0x4b, 0x19, 0xdc, 0x10, 0x11, + 0x6e, 0xd1, 0x03, 0x9e, 0x51, 0xbb, 0x77, 0x5c, 0xa6, 0xf6, 0x1f, 0x73, 0x30, 0xd9, 0xb2, 0xcc, + 0xb6, 0x69, 0x77, 0x1e, 0xe1, 0xc5, 0xb3, 0x6b, 0x50, 0xf2, 0x2c, 0xb3, 0x4d, 0x47, 0xcc, 0xcf, + 0xc2, 0x35, 0x33, 0x56, 0x4b, 0xa6, 0xa0, 0xb0, 0x9f, 0xf8, 0x4d, 0xb6, 0x85, 0x23, 0xdc, 0x64, + 0xfb, 0xbb, 0x55, 0x90, 0x69, 0x3b, 0x48, 0x1f, 0x6a, 0x1d, 0x75, 0x37, 0xa8, 0x7c, 0xc7, 0x1b, + 0x19, 0x6e, 0xc2, 0x8b, 0xdd, 0x32, 0x2a, 0xbe, 0x77, 0x00, 0xc4, 0x50, 0x12, 0xa1, 0x50, 0xe2, + 0x79, 0xd3, 0x32, 0x27, 0x9b, 0x8f, 0x64, 0xc8, 0x13, 0x2d, 0xc3, 0x01, 0x28, 0xb8, 0x13, 0x5d, + 0x06, 0x86, 0x16, 0x32, 0xc6, 0x42, 0x85, 0xd7, 0x3a, 0x24, 0xa3, 0x4b, 0x99, 0x08, 0x5b, 0xf7, + 0xbd, 0xcc, 0xd7, 0x4b, 0x84, 0x27, 0x4b, 0xe5, 0xc1, 0x53, 0xdd, 0xf7, 0x90, 0xb3, 0x26, 0x3f, + 0x0d, 0x75, 0xdf, 0xd5, 0x6d, 0x6f, 0xdb, 0x71, 0xbb, 0xd4, 0x95, 0x76, 0xf8, 0xa5, 0x0c, 0xd9, + 0x4f, 0x36, 0x42, 0x6e, 0x22, 0x2c, 0x28, 0x06, 0xc2, 0xa8, 0x34, 0xb2, 0x0b, 0xd5, 0x7e, 0x5b, + 0x54, 0x4c, 0xea, 0xdb, 0x8d, 0x0c, 0x92, 0xa3, 0xc7, 0x1c, 0xd5, 0x13, 0x06, 0x02, 0x58, 0x6f, + 0x0c, 0x73, 0xb1, 0x57, 0x32, 0xf6, 0xc6, 0x44, 0x9e, 0xd8, 0xe1, 0x49, 0xd8, 0x49, 0x37, 0xb4, + 0x36, 0x54, 0x33, 0x36, 0x6e, 0x6c, 0xd7, 0x28, 0x2f, 0x0a, 0x49, 0xda, 0x1a, 0x4c, 0x28, 0xf7, + 0x78, 0x70, 0x9d, 0x54, 0xc3, 0xaf, 0x65, 0x8c, 0xd1, 0x8b, 0x66, 0xe3, 0x11, 0x10, 0x94, 0x02, + 0xc8, 0x37, 0xa1, 0xe0, 0xdd, 0xf5, 0xe4, 0x01, 0x85, 0x0c, 0x9e, 0x94, 0xbb, 0xaa, 0x6f, 0x72, + 0x2b, 0x77, 0xeb, 0xae, 0x87, 0x8c, 0xaf, 0xf6, 0x3b, 0x79, 0xa8, 0x30, 0x1c, 0x5b, 0xa7, 0xe6, + 0xa1, 0xa6, 0xdf, 0xf3, 0x90, 0x76, 0xc2, 0xac, 0xe6, 0xc1, 0x2c, 0xd4, 0xb8, 0xd3, 0x12, 0x08, + 0x0c, 0x69, 0x58, 0x01, 0x7e, 0xb4, 0x99, 0xfb, 0xd3, 0xf3, 0xf1, 0x02, 0x6f, 0x2a, 0x04, 0x86, + 0x34, 0xe4, 0x36, 0x9c, 0xe3, 0x0f, 0x6b, 0xf7, 0x6c, 0xea, 0x36, 0xee, 0xb4, 0x1a, 0x86, 0xe1, + 0xf4, 0xb9, 0xcf, 0xa6, 0x10, 0x3b, 0x9d, 0x70, 0xee, 0xcd, 0x54, 0x2a, 0x1c, 0x52, 0x9a, 0xec, + 0x01, 0xe8, 0x9e, 0xd7, 0xef, 0x52, 0x74, 0x82, 0x43, 0x49, 0x19, 0x76, 0xf4, 0x77, 0x5a, 0x8d, + 0x80, 0x9b, 0xf0, 0x92, 0x84, 0xcf, 0x18, 0x91, 0xa4, 0x7d, 0xbf, 0x04, 0xb5, 0xa0, 0x65, 0x3f, + 0xc1, 0xed, 0xb7, 0x00, 0xa7, 0xf7, 0x4c, 0xcf, 0x14, 0x26, 0xfb, 0xe8, 0x39, 0xc8, 0x92, 0x50, + 0x07, 0x6f, 0x27, 0x91, 0x38, 0x48, 0x4f, 0x96, 0xe1, 0x4c, 0x57, 0xbf, 0x7f, 0xab, 0xdf, 0xdd, + 0xa2, 0xee, 0xda, 0xb6, 0xb4, 0x1f, 0x79, 0x32, 0x38, 0x9d, 0xc7, 0x2f, 0xad, 0x0e, 0xa2, 0x31, + 0xad, 0x0c, 0x79, 0x15, 0xa6, 0xef, 0xe9, 0x26, 0xb7, 0x1a, 0x44, 0xbd, 0x1b, 0x25, 0xe1, 0x7b, + 0xb9, 0x13, 0x47, 0x61, 0x92, 0x96, 0x5c, 0x81, 0xba, 0x0a, 0xca, 0xd8, 0x74, 0x2d, 0x95, 0x67, + 0xe3, 0xf0, 0x60, 0xb6, 0xae, 0x9c, 0x68, 0x9b, 0xb8, 0x82, 0x51, 0x1a, 0xf2, 0x15, 0x98, 0xd2, + 0x7d, 0xdf, 0x35, 0xb7, 0xfa, 0x3e, 0x6f, 0x6a, 0x71, 0x22, 0x4a, 0xda, 0x46, 0x1a, 0x31, 0x0c, + 0x26, 0x28, 0xc9, 0x1a, 0x3c, 0x21, 0x8d, 0x64, 0x71, 0x42, 0x99, 0x96, 0x9c, 0xab, 0xae, 0xab, + 0x69, 0x04, 0x98, 0x5e, 0x2e, 0xd1, 0x9d, 0xe1, 0xc4, 0xba, 0x73, 0x17, 0xa4, 0x71, 0x91, 0x18, + 0x00, 0x46, 0x90, 0x61, 0x4f, 0xe6, 0xde, 0x9c, 0x3f, 0x9a, 0x9a, 0x13, 0x26, 0xaa, 0x09, 0xaf, + 0x7d, 0x0d, 0x58, 0x61, 0x84, 0xad, 0xf6, 0x2f, 0xf3, 0x50, 0xd8, 0x58, 0x69, 0x91, 0x37, 0x80, + 0x98, 0xb6, 0x47, 0x8d, 0xbe, 0x4b, 0x5b, 0xbb, 0x66, 0xef, 0x36, 0x75, 0xcd, 0xed, 0x7d, 0xe9, + 0xd7, 0x0b, 0xcc, 0x7e, 0xcb, 0x03, 0x14, 0x98, 0x52, 0x8a, 0xbb, 0x6d, 0xf5, 0x05, 0xea, 0x66, + 0x70, 0xdb, 0x36, 0xc2, 0xe2, 0x18, 0x63, 0x46, 0x36, 0x01, 0x8c, 0x90, 0x75, 0xe1, 0xd8, 0xbe, + 0xd6, 0x08, 0xe3, 0x08, 0x23, 0x82, 0x50, 0xdb, 0x65, 0xa4, 0x9c, 0x6b, 0xf1, 0x38, 0x5c, 0xf9, + 0x82, 0x78, 0x53, 0x95, 0xc5, 0x90, 0x8d, 0x66, 0xc3, 0xe4, 0x86, 0xde, 0x09, 0x1b, 0x9e, 0x7c, + 0x19, 0xaa, 0x4e, 0x2f, 0xa2, 0x25, 0xd6, 0xf8, 0x5d, 0x0b, 0xd5, 0x35, 0x09, 0x7b, 0x70, 0x30, + 0x3b, 0xb9, 0xe2, 0x74, 0x4c, 0x43, 0x01, 0x30, 0x20, 0x27, 0x1a, 0x94, 0x79, 0x66, 0x50, 0x15, + 0x00, 0xc5, 0x97, 0x29, 0x7e, 0x59, 0xba, 0x87, 0x12, 0xa3, 0x7d, 0xbb, 0x08, 0xe1, 0x31, 0x43, + 0xe2, 0x41, 0x59, 0x64, 0x88, 0x92, 0x0a, 0xe9, 0x23, 0x4d, 0x46, 0x25, 0x45, 0x91, 0x0e, 0x14, + 0xde, 0x75, 0xb6, 0x32, 0xeb, 0xa3, 0x91, 0xf4, 0xe6, 0x62, 0xce, 0x88, 0x00, 0x90, 0x49, 0x20, + 0xbf, 0x92, 0x83, 0xd3, 0x5e, 0xd2, 0x8a, 0x20, 0xbb, 0x03, 0x66, 0x37, 0x97, 0x24, 0xed, 0x12, + 0xe2, 0x52, 0x8c, 0xa1, 0x68, 0x1c, 0xac, 0x0b, 0x6b, 0x7f, 0x71, 0x18, 0x4e, 0x76, 0xa7, 0xd1, + 0xdb, 0x5f, 0x1c, 0xb0, 0x8b, 0xb7, 0x7f, 0x1c, 0x86, 0x52, 0x94, 0xf6, 0x6f, 0x73, 0x50, 0xd8, + 0x5c, 0x5c, 0x3a, 0x71, 0x1b, 0x20, 0xe9, 0x40, 0xa5, 0x23, 0xae, 0xca, 0xcb, 0x9c, 0x59, 0x43, + 0x5e, 0xb9, 0x27, 0xd4, 0x3e, 0xf9, 0x80, 0x8a, 0xbb, 0xb6, 0x0f, 0xe5, 0xcd, 0x45, 0xb9, 0xa5, + 0x3f, 0x61, 0x3b, 0xe7, 0x4f, 0x43, 0xa0, 0x6d, 0x9f, 0xbc, 0xf0, 0x6f, 0xe7, 0x20, 0xbe, 0xc1, + 0x38, 0xf9, 0x2a, 0xfc, 0x30, 0x07, 0x89, 0xd4, 0x6f, 0xe4, 0x25, 0x79, 0x33, 0x50, 0xfc, 0xc4, + 0xbe, 0xba, 0x19, 0x88, 0xc4, 0xa9, 0x23, 0x37, 0x04, 0x7d, 0x98, 0x83, 0x49, 0x37, 0x1a, 0x1f, + 0x27, 0xa7, 0x8c, 0x0c, 0x51, 0xbf, 0x69, 0xd1, 0x76, 0xf2, 0xb8, 0x46, 0x14, 0x85, 0x71, 0xb9, + 0xda, 0x3f, 0xcc, 0x43, 0xf9, 0xc4, 0x32, 0x2c, 0xd3, 0x98, 0xd7, 0x7d, 0x21, 0xe3, 0x8c, 0x30, + 0xd4, 0xd9, 0xde, 0x4d, 0x38, 0xdb, 0xaf, 0x65, 0x15, 0xf4, 0x70, 0x1f, 0xfb, 0x3f, 0xcd, 0x81, + 0x9c, 0x8f, 0x96, 0x6d, 0xcf, 0xd7, 0x6d, 0x83, 0x12, 0x23, 0x98, 0xfc, 0xb2, 0x7a, 0x5e, 0x65, + 0xc6, 0x05, 0xb1, 0xde, 0xf1, 0xff, 0x6a, 0xb2, 0x23, 0xcf, 0x43, 0x75, 0xc7, 0xf1, 0x7c, 0x3b, + 0xd4, 0xdc, 0x03, 0x0b, 0xf5, 0x0d, 0x09, 0xc7, 0x80, 0x82, 0x7c, 0x1e, 0x2a, 0xd2, 0xa1, 0x23, + 0x43, 0x8d, 0x02, 0x03, 0xbc, 0xf4, 0xf8, 0xa0, 0xc2, 0x6b, 0xdf, 0x80, 0xe9, 0x64, 0xbe, 0xe2, + 0xeb, 0xa9, 0xf9, 0x8a, 0x9f, 0x1e, 0x92, 0xaf, 0xb8, 0x3e, 0x3c, 0x57, 0xf1, 0x1f, 0x14, 0x60, + 0xe2, 0x13, 0x93, 0xa7, 0x38, 0x25, 0x2d, 0x4c, 0x21, 0x63, 0x5a, 0x98, 0xe2, 0xb1, 0xd2, 0xc2, + 0x7c, 0x12, 0x72, 0xb6, 0xfc, 0x20, 0x07, 0x70, 0x62, 0x49, 0x92, 0xdb, 0xf1, 0xc8, 0x92, 0xcc, + 0xe3, 0x2a, 0x3d, 0xa0, 0xe4, 0xbb, 0x15, 0xf5, 0x4a, 0xdc, 0x4d, 0xff, 0x61, 0x0e, 0xa6, 0xf4, + 0x58, 0x06, 0x94, 0xcc, 0x3a, 0x65, 0x22, 0xa1, 0x4a, 0x70, 0x9a, 0x3d, 0x0e, 0xc7, 0x84, 0x58, + 0x7e, 0x96, 0x56, 0xc6, 0x50, 0x44, 0x36, 0xec, 0x03, 0x97, 0x07, 0xcb, 0xb3, 0xb4, 0x91, 0xa7, + 0x8f, 0xc8, 0x38, 0x53, 0x18, 0x4b, 0xc6, 0x99, 0xa8, 0x47, 0xb9, 0xf8, 0x50, 0x8f, 0xf2, 0x1e, + 0xd4, 0xb6, 0x5d, 0xa7, 0xcb, 0x93, 0xba, 0xf0, 0x4b, 0x8b, 0xb2, 0x4c, 0xd2, 0x0b, 0x4e, 0x77, + 0xcb, 0xb4, 0x69, 0x9b, 0x27, 0x8c, 0x09, 0x8c, 0x17, 0x4b, 0x8a, 0x3f, 0x86, 0xa2, 0xb8, 0x6b, + 0xd1, 0x11, 0x52, 0xcb, 0xe3, 0x94, 0x1a, 0xcc, 0xa5, 0x1b, 0x82, 0x3b, 0x2a, 0x31, 0xf1, 0x44, + 0x2e, 0x95, 0x13, 0x4a, 0xe4, 0xb2, 0x1f, 0xcd, 0x8f, 0x53, 0xcd, 0x68, 0x01, 0x3d, 0x5e, 0xf6, + 0xd9, 0xc7, 0x26, 0xb5, 0x8a, 0xf6, 0x8b, 0x15, 0xb5, 0xd2, 0x3c, 0x76, 0x97, 0x60, 0x7e, 0x9a, + 0x5a, 0xb6, 0x43, 0x07, 0xf2, 0xbe, 0x56, 0x4f, 0x30, 0xef, 0x6b, 0x6d, 0x3c, 0x79, 0x5f, 0x21, + 0x5b, 0xde, 0xd7, 0xfa, 0x98, 0xf2, 0xbe, 0x4e, 0x8c, 0x2b, 0xef, 0xeb, 0xe4, 0x48, 0x79, 0x5f, + 0xa7, 0x8e, 0x94, 0xf7, 0xf5, 0xa0, 0x00, 0x89, 0x5d, 0xfb, 0xa7, 0xc1, 0x0e, 0x7f, 0xa2, 0x82, + 0x1d, 0xbe, 0x93, 0x87, 0x70, 0x35, 0x3a, 0xe6, 0xf1, 0x88, 0xb7, 0x78, 0x72, 0x0a, 0x71, 0x71, + 0xf9, 0x68, 0x8a, 0xfc, 0x84, 0x4c, 0x64, 0x21, 0x6e, 0x2c, 0x0f, 0xb8, 0x11, 0x0f, 0xc0, 0x0c, + 0x6e, 0x93, 0xcf, 0xec, 0xc2, 0x0d, 0x2f, 0xa6, 0x17, 0xd6, 0xd4, 0xf0, 0x19, 0x23, 0x62, 0xb4, + 0xef, 0x17, 0xa0, 0x2c, 0x7d, 0xff, 0x14, 0x4a, 0xdb, 0x66, 0x78, 0xe4, 0x7d, 0x74, 0x9b, 0xe0, + 0x12, 0xe3, 0x22, 0x98, 0x0a, 0x1f, 0x35, 0x07, 0xa0, 0xe0, 0xce, 0x9d, 0x8f, 0x22, 0xe6, 0x40, + 0xb6, 0x5f, 0x06, 0xe7, 0x63, 0x34, 0x76, 0x41, 0x3a, 0x1f, 0x05, 0x08, 0x95, 0x0c, 0xe1, 0xeb, + 0x14, 0x17, 0xbd, 0x17, 0x32, 0xfb, 0x3a, 0x23, 0xa1, 0x73, 0xca, 0xd7, 0x29, 0xae, 0x79, 0x57, + 0x32, 0xc8, 0xfb, 0x50, 0xd7, 0x0d, 0xa3, 0xdf, 0xed, 0x5b, 0xdc, 0x76, 0x9c, 0xf5, 0xce, 0xdf, + 0x46, 0xc8, 0x4b, 0x8a, 0xe5, 0x3b, 0x9c, 0x08, 0x18, 0xa3, 0xf2, 0x9a, 0xdf, 0xfc, 0xde, 0x8f, + 0x2f, 0x7d, 0xe6, 0x07, 0x3f, 0xbe, 0xf4, 0x99, 0x1f, 0xfd, 0xf8, 0xd2, 0x67, 0xbe, 0x7d, 0x78, + 0x29, 0xf7, 0xbd, 0xc3, 0x4b, 0xb9, 0x1f, 0x1c, 0x5e, 0xca, 0xfd, 0xe8, 0xf0, 0x52, 0xee, 0xdf, + 0x1d, 0x5e, 0xca, 0xfd, 0xe5, 0x7f, 0x7f, 0xe9, 0x33, 0xdf, 0xf8, 0x52, 0x58, 0x9d, 0x79, 0x55, + 0x9d, 0x79, 0x25, 0x7c, 0xbe, 0xb7, 0xdb, 0x99, 0x67, 0xd5, 0x09, 0x21, 0xaa, 0x3a, 0xff, 0x2f, + 0x00, 0x00, 0xff, 0xff, 0xc0, 0x26, 0x38, 0xac, 0xd8, 0xba, 0x00, 0x00, } func (m *AWSAssumeRole) Marshal() (dAtA []byte, err error) { @@ -7575,6 +7576,18 @@ func (m *MonoVertexSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Streaming != nil { + i-- + if *m.Streaming { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } if m.Bypass != nil { { size, err := m.Bypass.MarshalToSizedBuffer(dAtA[:i]) @@ -13038,6 +13051,9 @@ func (m *MonoVertexSpec) Size() (n int) { l = m.Bypass.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Streaming != nil { + n += 3 + } return n } @@ -15397,6 +15413,7 @@ func (this *MonoVertexSpec) String() string { `UpdateStrategy:` + strings.Replace(strings.Replace(this.UpdateStrategy.String(), "UpdateStrategy", "UpdateStrategy", 1), `&`, ``, 1) + `,`, `Lifecycle:` + strings.Replace(strings.Replace(this.Lifecycle.String(), "MonoVertexLifecycle", "MonoVertexLifecycle", 1), `&`, ``, 1) + `,`, `Bypass:` + strings.Replace(this.Bypass.String(), "MonoVertexBypassCondition", "MonoVertexBypassCondition", 1) + `,`, + `Streaming:` + valueToStringGenerated(this.Streaming) + `,`, `}`, }, "") return s @@ -27477,6 +27494,27 @@ func (m *MonoVertexSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Streaming", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Streaming = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/numaflow/v1alpha1/generated.proto b/pkg/apis/numaflow/v1alpha1/generated.proto index 4921b6d2b3..00287475f8 100644 --- a/pkg/apis/numaflow/v1alpha1/generated.proto +++ b/pkg/apis/numaflow/v1alpha1/generated.proto @@ -1141,6 +1141,12 @@ message MonoVertexSpec { // and the next level specifies the conditions to trigger the said bypass. // +optional optional MonoVertexBypassCondition bypass = 15; + + // Streaming enables per-message, out-of-order source acknowledgement instead of the default + // whole-batch barrier. When true, the source reads continuously bounded by `spec.limits.concurrency` + // (in-flight messages) rather than one batch at a time. This is off by default. + // +optional + optional bool streaming = 16; } message MonoVertexStatus { diff --git a/pkg/apis/numaflow/v1alpha1/mono_vertex_types.go b/pkg/apis/numaflow/v1alpha1/mono_vertex_types.go index 9941bdd643..b66c5f73a6 100644 --- a/pkg/apis/numaflow/v1alpha1/mono_vertex_types.go +++ b/pkg/apis/numaflow/v1alpha1/mono_vertex_types.go @@ -198,6 +198,12 @@ func (mv MonoVertex) Scalable() bool { return !mv.Spec.Scale.Disabled } +// GetStreaming returns true if the streaming mode is explicitly enabled on this MonoVertex. +// Returns false when the field is nil (off by default). +func (mv MonoVertex) GetStreaming() bool { + return mv.Spec.Streaming != nil && *mv.Spec.Streaming +} + func (mv MonoVertex) GetDaemonServiceObj() *corev1.Service { labels := map[string]string{ KeyPartOf: Project, @@ -533,6 +539,11 @@ type MonoVertexSpec struct { // and the next level specifies the conditions to trigger the said bypass. // +optional Bypass *MonoVertexBypassCondition `json:"bypass,omitempty" protobuf:"bytes,15,opt,name=bypass"` + // Streaming enables per-message, out-of-order source acknowledgement instead of the default + // whole-batch barrier. When true, the source reads continuously bounded by `spec.limits.concurrency` + // (in-flight messages) rather than one batch at a time. This is off by default. + // +optional + Streaming *bool `json:"streaming,omitempty" protobuf:"varint,16,opt,name=streaming"` } func (mvspec MonoVertexSpec) DeepCopyWithoutReplicas() MonoVertexSpec { diff --git a/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go index d4f7fe19e4..8fa4828bce 100644 --- a/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go @@ -1693,6 +1693,11 @@ func (in *MonoVertexSpec) DeepCopyInto(out *MonoVertexSpec) { *out = new(MonoVertexBypassCondition) (*in).DeepCopyInto(*out) } + if in.Streaming != nil { + in, out := &in.Streaming, &out.Streaming + *out = new(bool) + **out = **in + } return } diff --git a/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go b/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go index 93db5d25cb..9039ec01f8 100644 --- a/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go +++ b/pkg/apis/numaflow/v1alpha1/zz_generated.openapi.go @@ -3560,6 +3560,13 @@ func schema_pkg_apis_numaflow_v1alpha1_MonoVertexSpec(ref common.ReferenceCallba Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.MonoVertexBypassCondition"), }, }, + "streaming": { + SchemaProps: spec.SchemaProps{ + Description: "Streaming enables per-message, out-of-order source acknowledgement instead of the default whole-batch barrier. When true, the source reads continuously bounded by `spec.limits.concurrency` (in-flight messages) rather than one batch at a time. This is off by default.", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, diff --git a/pkg/reconciler/validator/mvtx_validate.go b/pkg/reconciler/validator/mvtx_validate.go index 049eae651a..47094729c2 100644 --- a/pkg/reconciler/validator/mvtx_validate.go +++ b/pkg/reconciler/validator/mvtx_validate.go @@ -38,6 +38,12 @@ func ValidateMonoVertex(mvtx *dfv1.MonoVertex) error { if mvtx.Spec.Source.Serving != nil { return fmt.Errorf("serving source is not supported with Monovertex yet") } + if mvtx.GetStreaming() && mvtx.Spec.Source.Kafka != nil { + return fmt.Errorf("built-in Kafka source is not supported with streaming=true: " + + "the Kafka source commits offsets cumulatively (highest offset per partition), " + + "which is incompatible with streaming's per-message out-of-order acknowledgement and may cause data loss; " + + "disable streaming or use a different source") + } if err := validateSource(*mvtx.Spec.Source); err != nil { return fmt.Errorf("invalid source: %w", err) } diff --git a/pkg/reconciler/validator/mvtx_validate_test.go b/pkg/reconciler/validator/mvtx_validate_test.go index 4f7514e03f..0045a1e5eb 100644 --- a/pkg/reconciler/validator/mvtx_validate_test.go +++ b/pkg/reconciler/validator/mvtx_validate_test.go @@ -167,6 +167,53 @@ func TestValidateMonoVertex(t *testing.T) { assert.Contains(t, err.Error(), "invalid maxUnavailable") }) + t.Run("streaming with built-in Kafka source is rejected", func(t *testing.T) { + testObj := testMvtx.DeepCopy() + // Replace UDSource with Kafka-only source (no UDSource/UDTransformer to avoid other validation errors) + streaming := true + testObj.Spec.Streaming = &streaming + testObj.Spec.Source = &dfv1.Source{ + Kafka: &dfv1.KafkaSource{Brokers: []string{"broker:9092"}, Topic: "test-topic"}, + } + err := ValidateMonoVertex(testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), "built-in Kafka source is not supported with streaming=true") + }) + + t.Run("streaming with non-Kafka source is accepted", func(t *testing.T) { + testObj := testMvtx.DeepCopy() + streaming := true + testObj.Spec.Streaming = &streaming + // testMvtx already uses UDSource (non-Kafka), so no source change needed + err := ValidateMonoVertex(testObj) + assert.NoError(t, err) + }) + + t.Run("non-streaming with Kafka source is accepted", func(t *testing.T) { + testObj := testMvtx.DeepCopy() + // No streaming set; Kafka source alone must not be rejected by the streaming gate + testObj.Spec.Source = &dfv1.Source{ + Kafka: &dfv1.KafkaSource{Brokers: []string{"broker:9092"}, Topic: "test-topic"}, + } + err := ValidateMonoVertex(testObj) + // Should not fail on the streaming gate; any other error is unrelated to this gate + if err != nil { + assert.NotContains(t, err.Error(), "built-in Kafka source is not supported with streaming=true") + } + }) + + t.Run("nil streaming with Kafka source is accepted", func(t *testing.T) { + testObj := testMvtx.DeepCopy() + testObj.Spec.Streaming = nil + testObj.Spec.Source = &dfv1.Source{ + Kafka: &dfv1.KafkaSource{Brokers: []string{"broker:9092"}, Topic: "test-topic"}, + } + err := ValidateMonoVertex(testObj) + if err != nil { + assert.NotContains(t, err.Error(), "built-in Kafka source is not supported with streaming=true") + } + }) + t.Run("test udf spec validation", func(t *testing.T) { testObj := testMvtx.DeepCopy() err := ValidateMonoVertex(testObj) diff --git a/rust/numaflow-core/src/config/monovertex.rs b/rust/numaflow-core/src/config/monovertex.rs index 1db1f0c3c1..4c007b5e10 100644 --- a/rust/numaflow-core/src/config/monovertex.rs +++ b/rust/numaflow-core/src/config/monovertex.rs @@ -49,6 +49,10 @@ pub(crate) struct MonovertexConfig { pub(crate) metrics_config: MetricsConfig, pub(crate) callback_config: Option, pub(crate) rate_limit: Option, + /// When true, the source reads continuously bounded by `concurrency` in-flight messages + /// (per-message, out-of-order ack) instead of the default one-batch-in-flight barrier. + /// Off by default. + pub(crate) streaming: bool, } impl Default for MonovertexConfig { @@ -76,6 +80,7 @@ impl Default for MonovertexConfig { metrics_config: MetricsConfig::default(), callback_config: None, rate_limit: None, + streaming: false, } } } @@ -247,6 +252,8 @@ impl MonovertexConfig { }); } + let streaming = mono_vertex_obj.spec.streaming.unwrap_or(false); + Ok(MonovertexConfig { name: mono_vertex_name, replica: *get_vertex_replica(), @@ -264,6 +271,7 @@ impl MonovertexConfig { on_success_sink_config, callback_config, rate_limit, + streaming, }) } } @@ -661,4 +669,79 @@ mod tests { assert_eq!(config.source_config, expected_source_config); } + + #[test] + fn test_load_streaming_true_parses() { + let valid_config = r#" + { + "metadata": { + "name": "streaming-test-vertex" + }, + "spec": { + "streaming": true, + "limits": { + "readBatchSize": 100, + "readTimeout": "1s" + }, + "source": { + "udsource": { + "container": { + "image": "test-source", + "resources": {} + } + } + }, + "sink": { + "log": {} + } + } + } + "#; + let encoded = BASE64_STANDARD.encode(valid_config); + let mut env_vars = HashMap::new(); + env_vars.insert(ENV_MONO_VERTEX_OBJ.to_string(), encoded); + + let config = MonovertexConfig::load(env_vars).unwrap(); + assert!( + config.streaming, + "streaming should be true when spec.streaming=true" + ); + } + + #[test] + fn test_load_streaming_defaults_to_false() { + let valid_config = r#" + { + "metadata": { + "name": "non-streaming-vertex" + }, + "spec": { + "limits": { + "readBatchSize": 100, + "readTimeout": "1s" + }, + "source": { + "udsource": { + "container": { + "image": "test-source", + "resources": {} + } + } + }, + "sink": { + "log": {} + } + } + } + "#; + let encoded = BASE64_STANDARD.encode(valid_config); + let mut env_vars = HashMap::new(); + env_vars.insert(ENV_MONO_VERTEX_OBJ.to_string(), encoded); + + let config = MonovertexConfig::load(env_vars).unwrap(); + assert!( + !config.streaming, + "streaming should default to false when not set in spec" + ); + } } diff --git a/rust/numaflow-core/src/metrics/mod.rs b/rust/numaflow-core/src/metrics/mod.rs index ff070cc558..c594367b49 100644 --- a/rust/numaflow-core/src/metrics/mod.rs +++ b/rust/numaflow-core/src/metrics/mod.rs @@ -1795,6 +1795,7 @@ mod tests { None, cln_token.clone(), None, + false, ) .await; diff --git a/rust/numaflow-core/src/monovertex.rs b/rust/numaflow-core/src/monovertex.rs index 6413497c71..d7c316c4c8 100644 --- a/rust/numaflow-core/src/monovertex.rs +++ b/rust/numaflow-core/src/monovertex.rs @@ -103,6 +103,7 @@ async fn run_monovertex_forwarder( None, cln_token.clone(), rate_limiter, + config.streaming, ) .await?; diff --git a/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs b/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs index 1a37e81710..2b14b3fc9d 100644 --- a/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs +++ b/rust/numaflow-core/src/pipeline/forwarder/source_forwarder.rs @@ -226,6 +226,7 @@ where C: crate::typ::NumaflowTypeConfig, F: crate::pipeline::isb::ISBFactory, { + // Pipeline source vertices do not support streaming mode (MonoVertex-only feature). let source = create_components::create_source::( context.config.batch_size, context.config.concurrency, @@ -236,6 +237,7 @@ where source_watermark_handle.clone(), context.cln_token.clone(), rate_limiter, + false, // streaming is a MonoVertex-only feature ) .await?; @@ -921,6 +923,7 @@ mod tests { None, cln_token.clone(), None, + false, ) .await; diff --git a/rust/numaflow-core/src/shared/create_components.rs b/rust/numaflow-core/src/shared/create_components.rs index e7530ce19e..5b05212855 100644 --- a/rust/numaflow-core/src/shared/create_components.rs +++ b/rust/numaflow-core/src/shared/create_components.rs @@ -409,6 +409,7 @@ pub(crate) async fn create_mapper( /// Creates a source type with rate limiter based on the configuration. /// `concurrency` is the cap on in-flight (read-but-not-acked) messages, sourced from the vertex's /// `Limits.Concurrency`. +/// `streaming` enables per-message, out-of-order source ack instead of the default batch barrier. #[allow(clippy::too_many_arguments)] pub async fn create_source( batch_size: usize, @@ -420,6 +421,7 @@ pub async fn create_source( watermark_handle: Option, cln_token: CancellationToken, rate_limiter: Option, + streaming: bool, ) -> error::Result> { match &source_config.source_type { SourceType::Generator(generator_config) => { @@ -435,6 +437,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -457,6 +460,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -479,6 +483,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -500,6 +505,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -521,6 +527,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -538,6 +545,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -555,6 +563,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } @@ -582,6 +591,7 @@ pub async fn create_source( watermark_handle, cln_token, rate_limiter, + streaming, ) .await) } diff --git a/rust/numaflow-core/src/sinker/sink/sqs.rs b/rust/numaflow-core/src/sinker/sink/sqs.rs index a0a9272edb..02b88c7355 100644 --- a/rust/numaflow-core/src/sinker/sink/sqs.rs +++ b/rust/numaflow-core/src/sinker/sink/sqs.rs @@ -492,6 +492,7 @@ pub mod tests { None, cln_token, None, + false, ) .await, source_handle, diff --git a/rust/numaflow-core/src/source.rs b/rust/numaflow-core/src/source.rs index e17e8b3bf6..7f8b1a19b4 100644 --- a/rust/numaflow-core/src/source.rs +++ b/rust/numaflow-core/src/source.rs @@ -34,6 +34,7 @@ use std::collections::HashMap; use std::sync::Arc; use tokio::sync::OwnedSemaphorePermit; use tokio::sync::Semaphore; +use tokio::sync::mpsc::Sender; use tokio::sync::{mpsc, oneshot}; use tokio::task::JoinHandle; use tokio::time::{Duration, Instant}; @@ -251,6 +252,11 @@ pub(crate) struct Source { sender: mpsc::Sender, tracker: Tracker, read_ahead: bool, + /// When true, the source uses per-message in-flight permits (one per read-but-unacked message) + /// bounded by `concurrency`, and acks each message individually as its downstream disposition + /// resolves — out of order. When false (default), the existing one-batch-in-flight + batched-ack + /// behavior is used unchanged. + streaming: bool, /// Transformer handler for transforming messages from Source. transformer: Option, watermark_handle: Option, @@ -291,6 +297,7 @@ impl Source { watermark_handle: Option, cln_token: CancellationToken, rate_limiter: Option, + streaming: bool, ) -> Self { let (sender, receiver) = mpsc::channel(batch_size); let mut health_checker = None; @@ -395,6 +402,7 @@ impl Source { sender, tracker, read_ahead, + streaming, transformer, watermark_handle, health_checker, @@ -491,218 +499,512 @@ impl Source { ?self.read_batch_size, ?self.concurrency, ?self.read_ahead, + streaming = self.streaming, "Started streaming source" ); + let handle = tokio::spawn(async move { - // The semaphore caps the number of in-flight ack tasks. With read-ahead disabled, we - // allow exactly one batch in flight (sequential processing). With read-ahead enabled, - // we allow up to `concurrency` in-flight messages, divided by `read_batch_size` because - // we do batch acking. We always allow at least one task so a `concurrency` smaller than - // `read_batch_size` still makes progress. - let max_ack_tasks = match &self.read_ahead { - true => std::cmp::max(1, self.concurrency / self.read_batch_size.max(1)), - false => 1, - }; + if self.streaming { + if self.read_ahead { + warn!( + "streaming=true supersedes read_ahead=true; read_ahead is ignored in streaming mode" + ); + } + self.streaming_source( + pipeline_labels, + mvtx_labels, + bypass_router, + messages_tx, + cln_token, + ) + .await + } else { + // The semaphore caps the number of in-flight ack tasks. With read-ahead disabled, we + // allow exactly one batch in flight (sequential processing). With read-ahead enabled, + // we allow up to `concurrency` in-flight messages, divided by `read_batch_size` because + // we do batch acking. We always allow at least one task so a `concurrency` smaller than + // `read_batch_size` still makes progress. + let max_ack_tasks = match &self.read_ahead { + true => std::cmp::max(1, self.concurrency / self.read_batch_size.max(1)), + false => 1, + }; - let semaphore = Arc::new(Semaphore::new(max_ack_tasks)); - let mut result = Ok(()); - loop { - // Acquire the semaphore permit before reading the next batch to make - // sure we are not reading ahead and all the inflight messages are acked. + let semaphore = Arc::new(Semaphore::new(max_ack_tasks)); + let mut result = Ok(()); + loop { + // Acquire the semaphore permit before reading the next batch to make + // sure we are not reading ahead and all the inflight messages are acked. + let _permit = Arc::clone(&semaphore) + .acquire_owned() + .await + .expect("acquiring permit should not fail"); + + // Apply rate limiting before reading if configured. + // In source, we rate limit the `read` method invocations, + // and not the number of messages read. It just removes a single token per read. + // To throttle the number of messages read, make sure that `read_batch_size` is set to + // appropriate value. + if let Some(ref rate_limiter) = self.rate_limiter + && rate_limiter + .acquire_n(Some(1), Some(Duration::from_secs(1))) + .await + == 0 + { + continue; + } + + let read_start_time = Instant::now(); + let mut messages = match Self::read(self.sender.clone()).await { + Some(Ok(messages)) => messages, + None => { + info!("Source returned None (end of stream). Stopping the source."); + break; + } + Some(Err(e)) => { + error!("Error while reading messages: {:?}", e); + result = Err(e); + break; + } + }; + + let msgs_len = messages.len(); + let read_time = read_start_time.elapsed().as_micros() as f64; + Self::record_batch_read_metrics( + &pipeline_labels, + mvtx_labels, + read_time, + msgs_len, + false, + ); + + let mut msg_handles = vec![]; + let mut ack_batch = Vec::with_capacity(msgs_len); + + // Tracing: hold per-message `source.dispatch` span contexts keyed + // by source offset. Spans are created before tracker insert and closed only + // after the last downstream message for that source offset is bypassed/sent. + // This keeps the span honest even when the transformer fans one input message + // out into multiple outputs. + // + // Any messages whose dispatch spans are still in the map at end-of-iteration + // (e.g., transformer error that breaks the outer loop) have their spans + // closed by the RAII guard when the map is dropped. + // + let mut source_trace = + otel::SourceTraceState::new(msgs_len, self.transformer.is_some()); + + for mut message in messages.drain(..) { + Self::record_partition_read_metrics( + &pipeline_labels, + mvtx_labels, + message.offset.partition_idx(), + message.value.len(), + ); + + // Insert into the tracker first. A duplicate in-flight delivery (same + // offset already being processed in this pod) is ignored and not forwarded + // to downstream. The original copy already in the tracker drives the + // source-side ack/nack for that offset. + match self.tracker.insert(&message).await { + Ok(()) => {} + Err(Error::DuplicateInflight(_)) => { + warn!( + offset = ?message.offset, + "duplicate delivery from source, dropping" + ); + Self::record_duplicate_drop(mvtx_labels, message.value.len()); + continue; + } + Err(e) => return Err(e), + } + + // - Create `numaflow.vertex.process` root span for this message's full lifecycle. + // Parent: upstream trace context from message headers (W3C or B3), if present. + // The span is stored in MessageHandle's AckHandle and dropped on ack, giving + // accurate duration. + // - Create a topology-specific `source.dispatch` child span covering per-message + // source-stage work (tracker insert + optional `source.transform` child span + + // watermark + downstream bypass/send). It is closed after the last message for + // this source offset leaves the source stage, or by the RAII guard on error. + // Note: this span measures the per-message source-stage dispatch work, NOT + // source read latency. + // - Inject `vertex.process` context into sys_metadata["tracing"] so that map + // and sink become siblings of `source.dispatch` under `vertex.process`. + let platform_span = source_trace.start_message(&mut message); + + let (ack_tx, ack_rx) = oneshot::channel(); + // store the ack receiver in the batch to invoke ack later. + ack_batch.push((message.offset.clone(), ack_rx)); + let msg_handle = MessageHandle::new(message, ack_tx); + msg_handle.set_pipeline_span(platform_span); + msg_handles.push(msg_handle); + } + + // start a background task to invoke ack on the source for the offsets that are acked. + // if read ahead is disabled, acquire the semaphore permit before invoking ack so that + // we wait for all the inflight messages to be acked before reading the next batch. + tokio::spawn({ + let sender = self.sender.clone(); + let tracker = self.tracker.clone(); + let cln_token = cln_token.clone(); + async move { + let result = Self::invoke_ack( + read_start_time, + sender, + ack_batch, + _permit, + tracker, + cln_token.clone(), + ) + .await; + + if let Err(e) = result { + error!( + ?e, + "Non retryable error while invoking ack, stopping the source forwarder" + ); + // This cancels the source forwarder, which will stop the source. + cln_token.cancel(); + } + } + }); + + // transform the batch if the transformer is present, this need not + // be streaming because transformation should be fast operation. + // transform_batch accepts MessageHandles and returns MessageHandles with ack + // tracking preserved — flatmap outputs share the parent's ack handle. + // Move the read-only transform parents out of SourceTraceState; the dispatch span + // contexts remain owned by SourceTraceState for lifecycle cleanup. + let dispatch_parent_contexts = source_trace.take_transform_parents(); + let mut msg_handles = match self.transformer.as_mut() { + None => msg_handles, + Some(transformer) => match transformer + .transform_batch( + msg_handles, + cln_token.clone(), + dispatch_parent_contexts.as_ref(), + ) + .await + { + Ok(handles) => handles, + Err(e) => { + error!( + ?e, + "Error while transforming messages, sending nack to the batch" + ); + // handles dropped without mark_success, causing NAK + result = Err(e); + break; + } + }, + }; + + // Per-input-offset countdown driving `source.dispatch` end once the last + // downstream message for that input is bypassed or sent. Only built when + // tracing is on; otherwise SourceTraceState skips bookkeeping that would + // do no useful work. + let mut remaining_dispatches = source_trace + .remaining_dispatches(msg_handles.iter().map(|m| &m.message().offset)); + + // If a source input produced no downstream messages (for example, the transformer + // filtered it out), close its dispatch span now so it does not stay open for the + // rest of the batch's watermark/send work. + if let Some(ref rem) = remaining_dispatches { + source_trace.end_without_outputs(rem); + } + + if let Some(watermark_handle) = self.watermark_handle.as_mut() { + let entries: Vec = + msg_handles.iter().map(SourceWatermarkEntry::from).collect(); + watermark_handle + .generate_and_publish_source_watermark(&entries) + .await; + + let watermark = watermark_handle.fetch_source_watermark().await; + // set is_late on messages that arrived after the watermark + for msg_handle in msg_handles.iter_mut() { + if msg_handle.message().event_time < watermark { + msg_handle.message_mut().is_late = true; + } + } + } + + // write the messages to downstream as MessageHandles. + for read_message in msg_handles.into_iter() { + let offset = read_message.message().offset.clone(); + // Try to bypass the message. If bypassed, try_bypass takes ownership and returns None. + // If not bypassed, it returns Some(read_message) for us to send downstream. + let maybe_read_message = if let Some(ref bypass_router) = bypass_router { + match bypass_router + .try_bypass(read_message) + .await + .expect("failed to send message to bypass channel") + { + Some(msg) => msg, + None => { + decrement_remaining_dispatch( + remaining_dispatches.as_mut(), + &mut source_trace, + &offset, + ); + continue; + } + } + } else { + read_message + }; + + messages_tx + .send(maybe_read_message) + .await + .expect("send should not fail"); + + decrement_remaining_dispatch( + remaining_dispatches.as_mut(), + &mut source_trace, + &offset, + ); + } + // source_trace drops here — any remaining dispatch spans (shouldn't happen on success path) + // get closed by the RAII Drop impl. + } + + info!(status=?result, "Source stopped, waiting for inflight messages to be acked/nacked"); + // wait for all the ack tasks to be completed before stopping the source, since we give + // a permit for each ack task all the permits should be released when the ack tasks are + // done, we can verify this by trying to acquire the permit for max_ack_tasks. let _permit = Arc::clone(&semaphore) - .acquire_owned() + .acquire_many_owned(max_ack_tasks as u32) .await .expect("acquiring permit should not fail"); + info!("All inflight messages are acked/nacked. Source stopped."); - // Apply rate limiting before reading if configured. - // In source, we rate limit the `read` method invocations, - // and not the number of messages read. It just removes a single token per read. - // To throttle the number of messages read, make sure that `read_batch_size` is set to - // appropriate value. - if let Some(ref rate_limiter) = self.rate_limiter - && rate_limiter - .acquire_n(Some(1), Some(Duration::from_secs(1))) - .await - == 0 - { - continue; + // Shutdown rate limiter if configured + if let Some(ref rate_limiter) = self.rate_limiter { + rate_limiter.shutdown().await.map_err(|e| { + Error::Source(format!("Failed to shutdown rate limiter: {e}")) + })?; } - let read_start_time = Instant::now(); - let mut messages = match Self::read(self.sender.clone()).await { - Some(Ok(messages)) => messages, - None => { - info!("Source returned None (end of stream). Stopping the source."); - break; - } - Some(Err(e)) => { - error!("Error while reading messages: {:?}", e); - result = Err(e); - break; - } - }; + result + } // end non-streaming branch + }); + Ok((ReceiverStream::new(messages_rx), handle)) + } - let msgs_len = messages.len(); - let read_time = read_start_time.elapsed().as_micros() as f64; - Self::record_batch_read_metrics(&pipeline_labels, mvtx_labels, read_time, msgs_len); + async fn streaming_source( + mut self, + pipeline_labels: Vec<(String, String)>, + mvtx_labels: &Vec<(String, String)>, + bypass_router: Option, + messages_tx: Sender, + cln_token: CancellationToken, + ) -> Result<()> { + // Acquire-after-read model: + // 1. Call read() to get a full batch (up to read_batch_size messages). + // 2. For EACH returned message, block-acquire ONE permit before inserting + // it into the tracker and dispatching it downstream. + // 3. Each message is dispatched inline (one at a time) so that backpressure + // from permit acquisition does not prevent already-tracked messages from + // reaching downstream consumers + // 4. The permit travels with that message to its per-message ack task and + // is released only when the message is acked or nak'd. + // + // Transient read buffer: at most one read_batch_size worth of messages can + // be waiting on permit acquisition at any time. + let semaphore = Arc::new(Semaphore::new(self.concurrency)); + let mut result = Ok(()); + + 'outer: loop { + // Apply rate limiting before reading if configured. + if let Some(ref rate_limiter) = self.rate_limiter + && rate_limiter + .acquire_n(Some(1), Some(Duration::from_secs(1))) + .await + == 0 + { + continue; + } - let mut msg_handles = vec![]; - let mut ack_batch = Vec::with_capacity(msgs_len); + let read_start_time = Instant::now(); + let mut messages = match Self::read(self.sender.clone()).await { + Some(Ok(messages)) => messages, + None => { + info!("Source returned None (end of stream). Stopping the source."); + break 'outer; + } + Some(Err(e)) => { + error!("Error while reading messages: {:?}", e); + result = Err(e); + break 'outer; + } + }; - // Tracing: hold per-message `source.dispatch` span contexts keyed - // by source offset. Spans are created before tracker insert and closed only - // after the last downstream message for that source offset is bypassed/sent. - // This keeps the span honest even when the transformer fans one input message - // out into multiple outputs. - // - // Any messages whose dispatch spans are still in the map at end-of-iteration - // (e.g., transformer error that breaks the outer loop) have their spans - // closed by the RAII guard when the map is dropped. + let msgs_len = messages.len(); + + let read_time = read_start_time.elapsed().as_micros() as f64; + // streaming=true: read_time and read_batch_size are skipped on the mvtx + // path (batch semantics are meaningless per-message). Pipeline path unchanged. + // TODO: track per message metrics + Self::record_batch_read_metrics( + &pipeline_labels, + mvtx_labels, + read_time, + msgs_len, + true, + ); + + for mut message in messages.drain(..) { + // Pre-compute per-source-offset trace context (same as non-streaming). + let mut source_trace = otel::SourceTraceState::new(1, self.transformer.is_some()); + + Self::record_partition_read_metrics( + &pipeline_labels, + mvtx_labels, + message.offset.partition_idx(), + message.value.len(), + ); + + // Block-acquire one permit per message BEFORE inserting into the + // tracker. This is the sole backpressure point. + // When `concurrency` messages are already in flight, this await + // blocks until an ack/nak task releases a permit. // - let mut source_trace = - otel::SourceTraceState::new(msgs_len, self.transformer.is_some()); - - for mut message in messages.drain(..) { - Self::record_partition_read_metrics( - &pipeline_labels, - mvtx_labels, - message.offset.partition_idx(), - message.value.len(), - ); - - // Insert into the tracker first. A duplicate in-flight delivery (same - // offset already being processed in this pod) is ignored and not forwarded - // to downstream. The original copy already in the tracker drives the - // source-side ack/nack for that offset. - match self.tracker.insert(&message).await { - Ok(()) => {} - Err(Error::DuplicateInflight(_)) => { - warn!( - offset = ?message.offset, - "duplicate delivery from source, dropping" - ); - Self::record_duplicate_drop(mvtx_labels, message.value.len()); - continue; - } - Err(e) => return Err(e), + // Cancellation: select against cln_token so a cancel while + // waiting on a stalled permit acquisition does not hang forever. + // Messages already read but not yet permitted are dropped here + // (never tracker-inserted) and will be redelivered by the source. + let permit = tokio::select! { + biased; + _ = cln_token.cancelled() => { + // Loop is stopping; remaining messages in this batch are + // dropped without tracker insertion → redelivered by source. + break; + } + p = Arc::clone(&semaphore).acquire_owned() => { + p.expect("semaphore acquire should not fail") } + }; - // - Create `numaflow.vertex.process` root span for this message's full lifecycle. - // Parent: upstream trace context from message headers (W3C or B3), if present. - // The span is stored in MessageHandle's AckHandle and dropped on ack, giving - // accurate duration. - // - Create a topology-specific `source.dispatch` child span covering per-message - // source-stage work (tracker insert + optional `source.transform` child span + - // watermark + downstream bypass/send). It is closed after the last message for - // this source offset leaves the source stage, or by the RAII guard on error. - // Note: this span measures the per-message source-stage dispatch work, NOT - // source read latency. - // - Inject `vertex.process` context into sys_metadata["tracing"] so that map - // and sink become siblings of `source.dispatch` under `vertex.process`. - let platform_span = source_trace.start_message(&mut message); - - let (ack_tx, ack_rx) = oneshot::channel(); - // store the ack receiver in the batch to invoke ack later. - ack_batch.push((message.offset.clone(), ack_rx)); - let msg_handle = MessageHandle::new(message, ack_tx); - msg_handle.set_pipeline_span(platform_span); - msg_handles.push(msg_handle); + // Insert into the tracker. A duplicate in-flight delivery (same + // offset already being processed) is dropped; its permit is + // released immediately so it doesn't leak or skew the drain. + match self.tracker.insert(&message).await { + Ok(()) => {} + Err(Error::DuplicateInflight(_)) => { + warn!( + offset = ?message.offset, + "duplicate delivery from source, dropping" + ); + Self::record_duplicate_drop(mvtx_labels, message.value.len()); + // Drop the just-acquired permit to keep accounting exact. + drop(permit); + continue; + } + Err(e) => { + // Non-duplicate tracker error; drop permit and abort. + drop(permit); + result = Err(e); + break 'outer; + } } - // start a background task to invoke ack on the source for the offsets that are acked. - // if read ahead is disabled, acquire the semaphore permit before invoking ack so that - // we wait for all the inflight messages to be acked before reading the next batch. + let platform_span = source_trace.start_message(&mut message); + + let (ack_tx, ack_rx) = oneshot::channel(); + let msg_handle = MessageHandle::new(message, ack_tx); + msg_handle.set_pipeline_span(platform_span); + + // Spawn one ack task per message. The task owns one in-flight + // permit; dropping the permit on completion frees one slot. tokio::spawn({ let sender = self.sender.clone(); let tracker = self.tracker.clone(); let cln_token = cln_token.clone(); + let offset = msg_handle.message().offset.clone(); async move { - let result = Self::invoke_ack( + if let Err(e) = Self::invoke_ack_single( read_start_time, sender, - ack_batch, - _permit, + offset, + ack_rx, + permit, tracker, cln_token.clone(), ) - .await; - - if let Err(e) = result { + .await + { error!( ?e, - "Non retryable error while invoking ack, stopping the source forwarder" + "Non retryable error in per-message ack, stopping forwarder" ); - // This cancels the source forwarder, which will stop the source. cln_token.cancel(); } } }); - // transform the batch if the transformer is present, this need not - // be streaming because transformation should be fast operation. - // transform_batch accepts MessageHandles and returns MessageHandles with ack - // tracking preserved — flatmap outputs share the parent's ack handle. - // Move the read-only transform parents out of SourceTraceState; the dispatch span - // contexts remain owned by SourceTraceState for lifecycle cleanup. + // Each message is dispatched to downstream immediately after its + // permit is acquired and ack task is spawned. + // + // transform_batch is called with a single-element Vec (per-message transform). + // This trades batch transformer throughput for per-message forward latency, + // which is acceptable in streaming mode. + // + // Capture the input offset before msg_handle is consumed by transform_batch. + // This is needed to close the dispatch span if the transformer filters the + // message to zero outputs (see guard below). + let input_offset = msg_handle.message().offset.clone(); let dispatch_parent_contexts = source_trace.take_transform_parents(); - let mut msg_handles = match self.transformer.as_mut() { - None => msg_handles, - Some(transformer) => match transformer - .transform_batch( - msg_handles, - cln_token.clone(), - dispatch_parent_contexts.as_ref(), - ) - .await - { - Ok(handles) => handles, - Err(e) => { - error!( - ?e, - "Error while transforming messages, sending nack to the batch" - ); - // handles dropped without mark_success, causing NAK - result = Err(e); - break; + let mut transformed_handles = match self.transformer.as_mut() { + None => vec![msg_handle], + Some(transformer) => { + match transformer + .transform_batch( + vec![msg_handle], + cln_token.clone(), + dispatch_parent_contexts.as_ref(), + ) + .await + { + Ok(handles) => handles, + Err(e) => { + error!(?e, "Error transforming message, sending nack"); + result = Err(e); + break 'outer; + } } - }, + } }; - // Per-input-offset countdown driving `source.dispatch` end once the last - // downstream message for that input is bypassed or sent. Only built when - // tracing is on; otherwise SourceTraceState skips bookkeeping that would - // do no useful work. - let mut remaining_dispatches = source_trace - .remaining_dispatches(msg_handles.iter().map(|m| &m.message().offset)); - - // If a source input produced no downstream messages (for example, the transformer - // filtered it out), close its dispatch span now so it does not stay open for the - // rest of the batch's watermark/send work. - if let Some(ref rem) = remaining_dispatches { - source_trace.end_without_outputs(rem); + // If the transformer filtered this message to zero outputs, close its + // dispatch span now. Without this, the span stays open until source_trace + // drops at the end of this loop iteration, inflating its duration by all + // subsequent per-message work in the same batch. + if transformed_handles.is_empty() { + source_trace.end(&input_offset); } if let Some(watermark_handle) = self.watermark_handle.as_mut() { - let entries: Vec = - msg_handles.iter().map(SourceWatermarkEntry::from).collect(); + let entries: Vec = transformed_handles + .iter() + .map(SourceWatermarkEntry::from) + .collect(); watermark_handle .generate_and_publish_source_watermark(&entries) .await; let watermark = watermark_handle.fetch_source_watermark().await; // set is_late on messages that arrived after the watermark - for msg_handle in msg_handles.iter_mut() { + for msg_handle in transformed_handles.iter_mut() { if msg_handle.message().event_time < watermark { msg_handle.message_mut().is_late = true; } } } - // write the messages to downstream as MessageHandles. - for read_message in msg_handles.into_iter() { + // Bypass and downstream send inline for each output handle. + for read_message in transformed_handles.into_iter() { let offset = read_message.message().offset.clone(); - // Try to bypass the message. If bypassed, try_bypass takes ownership and returns None. - // If not bypassed, it returns Some(read_message) for us to send downstream. let maybe_read_message = if let Some(ref bypass_router) = bypass_router { match bypass_router .try_bypass(read_message) @@ -711,11 +1013,7 @@ impl Source { { Some(msg) => msg, None => { - decrement_remaining_dispatch( - remaining_dispatches.as_mut(), - &mut source_trace, - &offset, - ); + source_trace.end(&offset); continue; } } @@ -728,37 +1026,99 @@ impl Source { .await .expect("send should not fail"); - decrement_remaining_dispatch( - remaining_dispatches.as_mut(), - &mut source_trace, - &offset, - ); + source_trace.end(&offset); } - // source_trace drops here — any remaining dispatch spans (shouldn't happen on success path) - // get closed by the RAII Drop impl. } + // source_trace drops here; RAII closes any remaining dispatch spans + // (e.g., messages dropped mid-loop on cancellation). + + // If cln_token was cancelled mid-batch, stop the outer loop now. + if cln_token.is_cancelled() { + break 'outer; + } + } - info!(status=?result, "Source stopped, waiting for inflight messages to be acked/nacked"); - // wait for all the ack tasks to be completed before stopping the source, since we give - // a permit for each ack task all the permits should be released when the ack tasks are - // done, we can verify this by trying to acquire the permit for max_ack_tasks. - let _permit = Arc::clone(&semaphore) - .acquire_many_owned(max_ack_tasks as u32) + // Wait for every in-flight per-message ack task to complete. Each task + // releases its permit on ack/nak + info!( + status = ?result, + "Source stopped (streaming), waiting for all in-flight messages to ack/nack" + ); + let _drain_permit = Arc::clone(&semaphore) + .acquire_many_owned(self.concurrency as u32) + .await + .expect("acquiring drain permits should not fail"); + info!("All in-flight messages acked/nacked. Streaming source stopped."); + + // Shutdown rate limiter if configured. + if let Some(ref rate_limiter) = self.rate_limiter { + rate_limiter + .shutdown() .await - .expect("acquiring permit should not fail"); - info!("All inflight messages are acked/nacked. Source stopped."); + .map_err(|e| Error::Source(format!("Failed to shutdown rate limiter: {e}")))?; + } + + result + } - // Shutdown rate limiter if configured - if let Some(ref rate_limiter) = self.rate_limiter { - rate_limiter - .shutdown() + /// Per-message ack for the streaming path. Awaits a single message's oneshot, issues + /// ack or nack for that one offset, then releases the in-flight permit. This runs as an + /// independent background task per message, enabling out-of-order acknowledgement. + /// + /// Mirrors `invoke_ack` for a single `(offset, oneshot::Receiver)` pair. + async fn invoke_ack_single( + e2e_start_time: Instant, + source_handle: mpsc::Sender, + offset: Offset, + ack_rx: oneshot::Receiver, + permit: OwnedSemaphorePermit, // one permit per in-flight message; released on completion. + tracker: Tracker, + cancel_token: CancellationToken, + ) -> Result<()> { + let disposition = match ack_rx.await { + Ok(ReadAck::Ack) => true, + Ok(ReadAck::Nak) => { + warn!(?offset, "Nak received for offset (streaming)"); + false + } + Err(e) => { + error!(?offset, err=?e, "Error receiving ack for offset (streaming)"); + // Treat recv-error the same as Nak: delete from tracker so it does not + // accumulate, then release the permit. No retryable error is returned here + // (matches current behavior at the recv-error branch in invoke_ack). + tracker + .delete(&offset) .await - .map_err(|e| Error::Source(format!("Failed to shutdown rate limiter: {e}")))?; + .expect("Failed to delete offset from tracker"); + // Drop permit explicitly before returning so drain barrier sees it. + drop(permit); + return Ok(()); } + }; - result - }); - Ok((ReceiverStream::new(messages_rx), handle)) + // Delete from tracker exactly once for this offset. + tracker + .delete(&offset) + .await + .expect("Failed to delete offset from tracker"); + + let start = Instant::now(); + let ack_result = if disposition { + Self::ack_with_retry(source_handle, vec![offset], &cancel_token).await + } else { + Self::nack_with_retry(source_handle, vec![offset], &cancel_token).await + }; + + // streaming=true: ack_time and e2e_time are skipped on the mvtx path; + // ack_total still increments (n=1 per message — valid per-message counter). + Self::send_ack_metrics(e2e_start_time, 1, start, true); + + // Drop the permit here so the drain barrier sees one fewer in-flight message. + // The drop happens after ack_with_retry so we never signal "done" before the + // source SDK has actually received the ack. + drop(permit); + + ack_result } /// Listens to the oneshot receivers and invokes ack/nack on the source for the offsets. @@ -800,7 +1160,8 @@ impl Source { if !offsets_to_nack.is_empty() { Self::nack_with_retry(source_handle, offsets_to_nack, &cancel_token).await?; } - Self::send_ack_metrics(e2e_start_time, n, start); + // Non-streaming path: record all batch-granular metrics (streaming=false). + Self::send_ack_metrics(e2e_start_time, n, start, false); Ok(()) } @@ -870,21 +1231,32 @@ impl Source { /// Record per-batch read metrics (read_time, read_batch_size). /// These metrics are recorded once per batch read operation. + /// + /// `streaming`: when `true` and `is_mono_vertex()`, the batch-granular `read_time` and + /// `read_batch_size` metrics are skipped — their batch semantics are meaningless for + /// per-message streaming. The pipeline label path is always recorded unchanged. fn record_batch_read_metrics( pipeline_labels: &Vec<(String, String)>, mvtx_labels: &Vec<(String, String)>, read_time: f64, batch_size: usize, + streaming: bool, ) { if is_mono_vertex() { - monovertex_metrics() - .read_time - .get_or_create(mvtx_labels) - .observe(read_time); - monovertex_metrics() - .read_batch_size - .get_or_create(mvtx_labels) - .set(batch_size as i64); + // Gate batch-granular metrics off under streaming. read_time would measure + // the duration of a read that returns a full batch regardless of how many + // messages are actually in flight, and read_batch_size would pin to ~1 + // (meaningless for per-message throughput monitoring). + if !streaming { + monovertex_metrics() + .read_time + .get_or_create(mvtx_labels) + .observe(read_time); + monovertex_metrics() + .read_batch_size + .get_or_create(mvtx_labels) + .set(batch_size as i64); + } } else { pipeline_metrics() .forwarder @@ -968,23 +1340,32 @@ impl Source { } } - fn send_ack_metrics(e2e_start_time: Instant, n: usize, start: Instant) { + /// `streaming`: when `true` and `is_mono_vertex()`, `ack_time` and `e2e_time` observes + /// are skipped — these batch-granular histograms are meaningless per-message (one sample + /// per ack call would misrepresent the aggregate). `ack_total` always increments (n=1 + /// per message in the streaming path) since it is a valid per-message counter. The + /// pipeline label path is always recorded unchanged. + fn send_ack_metrics(e2e_start_time: Instant, n: usize, start: Instant, streaming: bool) { if is_mono_vertex() { let mvtx_labels = mvtx_forward_metric_labels(); - monovertex_metrics() - .ack_time - .get_or_create(mvtx_labels) - .observe(start.elapsed().as_micros() as f64); + // Gate batch-granular timing histograms off under streaming. + if !streaming { + monovertex_metrics() + .ack_time + .get_or_create(mvtx_labels) + .observe(start.elapsed().as_micros() as f64); + monovertex_metrics() + .e2e_time + .get_or_create(mvtx_labels) + .observe(e2e_start_time.elapsed().as_micros() as f64); + } + + // ack_total is a per-message counter — always valid, never gated. monovertex_metrics() .ack_total .get_or_create(mvtx_labels) .inc_by(n as u64); - - monovertex_metrics() - .e2e_time - .get_or_create(mvtx_labels) - .observe(e2e_start_time.elapsed().as_micros() as f64); } else { let mut pipeline_labels = pipeline_metric_labels(VERTEX_TYPE_SOURCE).clone(); pipeline_labels.push(( @@ -1249,6 +1630,7 @@ mod tests { None, cln_token.clone(), None, + false, // non-streaming path (existing test) ) .await; @@ -1449,6 +1831,7 @@ mod tests { None, cln_token.clone(), None, + false, // non-streaming path (existing test) ) .await; @@ -1505,4 +1888,497 @@ mod tests { let _ = shutdown_tx.send(()); server_handle.await.unwrap(); } + + // ─── Streaming-path tests ──────────────────────────────────────────────── + // + // These tests cover the acquire-after-read model (009) using a simple + // in-process generator source (no gRPC server needed). + + /// Build a generator-backed Source with `streaming = true`. + async fn make_streaming_source( + batch_size: usize, + concurrency: usize, + num_messages: usize, + tracker: Tracker, + cln_token: CancellationToken, + ) -> Source { + use crate::config::components::source::GeneratorConfig; + let cfg = GeneratorConfig { + rpu: num_messages, + content: bytes::Bytes::from_static(b"payload"), + duration: std::time::Duration::from_millis(10), + value: None, + key_count: 0, + msg_size_bytes: 8, + jitter: std::time::Duration::ZERO, + }; + let (reader, acker, lag) = + crate::source::generator::new_generator(cfg, batch_size, cln_token.clone()).unwrap(); + Source::new( + batch_size, + concurrency, + SourceType::Generator(reader, acker, lag), + tracker, + false, + None, + None, + cln_token, + None, + true, // streaming = true + ) + .await + } + + /// Streaming: in-flight count is capped at `concurrency`. + /// + /// We set `concurrency = 3` and `batch_size = 10`. After reading 3 messages + /// without acking them, the 4th permit acquisition must block (concurrency cap). + /// Once we ack one message, one more message can be admitted. No message is + /// dropped or skipped. + #[tokio::test] + async fn streaming_inflight_bounded_by_concurrency() { + let cln_token = CancellationToken::new(); + let tracker = Tracker::new(None, cln_token.clone()); + // concurrency=3, batch_size=10, 20 total messages + let source = make_streaming_source(10, 3, 20, tracker.clone(), cln_token.clone()).await; + + let (mut stream, handle) = source.streaming_read(cln_token.clone(), None).unwrap(); + + // Receive exactly 3 messages without acking — the 4th should not arrive + // while these are held (all permits consumed). + let msg1 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg1 timeout") + .expect("stream open"); + let msg2 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg2 timeout") + .expect("stream open"); + let msg3 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg3 timeout") + .expect("stream open"); + + // With concurrency=3 and all 3 permits held, the 4th message should not + // be forwarded downstream within 200ms (acquire_owned will block). + let no_fourth = tokio::time::timeout(Duration::from_millis(200), stream.next()).await; + assert!( + no_fourth.is_err(), + "4th message must not arrive while concurrency=3 slots are all held" + ); + + // Ack one — now one permit is released; the 4th message should arrive. + mark_success!(msg1); + let msg4 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg4 timeout after acking msg1") + .expect("stream open"); + + // Ack the rest. + mark_success!(msg2); + mark_success!(msg3); + mark_success!(msg4); + + cln_token.cancel(); + let _ = handle.await.unwrap(); + } + + /// Streaming: per-message out-of-order ack releases permits individually. + /// + /// We read exactly 2 messages with concurrency=2 (no more can be in flight). + /// Ack msg2 BEFORE msg1 (out of order). Both should succeed individually, and + /// after cancellation + drain, the tracker should be empty — no deadlock on + /// out-of-order resolution. + #[tokio::test] + async fn streaming_per_message_out_of_order_ack() { + let cln_token = CancellationToken::new(); + let tracker = Tracker::new(None, cln_token.clone()); + // concurrency=2, batch_size=2: exactly 2 messages in flight at a time. + let source = make_streaming_source(2, 2, 10, tracker.clone(), cln_token.clone()).await; + + let (mut stream, handle) = source.streaming_read(cln_token.clone(), None).unwrap(); + + let msg1 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg1") + .expect("stream open"); + let msg2 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg2") + .expect("stream open"); + + // Cancel before acking so no new messages are admitted after we ack. + // (The already-in-flight msg1 and msg2 will still be acked.) + cln_token.cancel(); + + // Ack msg2 BEFORE msg1 (out of order) — per-message ack means each oneshot + // fires independently; msg1's ack task does not wait for msg2's. + mark_success!(msg2); + mark_success!(msg1); + + // Handle must return Ok (drain completes once both permits are released). + let result = tokio::time::timeout(Duration::from_secs(5), handle) + .await + .expect("handle should complete") + .expect("handle join"); + assert!(result.is_ok(), "handle returned error: {:?}", result); + + // Tracker must be empty (both messages acked, no new ones admitted after cancel). + assert!( + tracker.is_empty().await.unwrap(), + "tracker should be empty after out-of-order ack" + ); + } + + /// Streaming duplicate-inflight: the duplicate drops its permit immediately + /// and does not stall/panic the drain. + /// + /// Uses `DuplicateSource` (already defined above). With streaming=true, the + /// duplicate's permit must be released so the drain can complete without + /// hanging. The one unique message and the first copy of "dup" are acked; + /// the duplicate copy is silently dropped. + #[tokio::test] + async fn streaming_duplicate_inflight_releases_permit_and_drains() { + let cln_token = CancellationToken::new(); + let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel(); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let sock_file = tmp_dir.path().join("streaming-dup-source.sock"); + let server_info_file = tmp_dir.path().join("streaming-dup-source-server-info"); + + let server_socket = sock_file.clone(); + let server_info = server_info_file.clone(); + let server_handle = tokio::spawn(async move { + source::Server::new(DuplicateSource::new()) + .with_socket_file(server_socket) + .with_server_info_file(server_info) + .start_with_shutdown(shutdown_rx) + .await + .unwrap() + }); + tokio::time::sleep(Duration::from_millis(100)).await; + + let client = SourceClient::new(create_rpc_channel(sock_file).await.unwrap()); + let (src_read, src_ack, lag_reader) = new_source( + client, + 5, + Duration::from_millis(1000), + cln_token.clone(), + true, + ) + .await + .expect("new_source"); + + let tracker = Tracker::new(None, cln_token.clone()); + // concurrency=5 so permits are plentiful; the test is about drain correctness + // not about backpressure. + let source: Source = Source::new( + 5, + 5, + SourceType::UserDefinedSource(Box::new(src_read), Box::new(src_ack), lag_reader), + tracker.clone(), + true, + None, + None, + cln_token.clone(), + None, + true, // streaming = true + ) + .await; + + let (mut stream, handle) = source.streaming_read(cln_token.clone(), None).unwrap(); + + // DuplicateSource emits ["dup", "dup", "unique"] — only 2 distinct offsets + // forwarded downstream ("dup" once + "unique"). + let first = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("first") + .expect("stream open"); + let second = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("second") + .expect("stream open"); + + // The two forwarded offsets must be distinct. + assert_ne!( + first.message.offset, second.message.offset, + "duplicate must not be forwarded twice" + ); + + // No third message (the duplicate was dropped). + let third = tokio::time::timeout(Duration::from_millis(200), stream.next()).await; + assert!(third.is_err(), "no third message expected"); + + mark_success!(first); + mark_success!(second); + + // Tracker must drain (no leaked permit, no hang). + tokio::time::timeout(Duration::from_secs(2), async { + loop { + if tracker.is_empty().await.unwrap() { + break; + } + tokio::time::sleep(Duration::from_millis(10)).await; + } + }) + .await + .expect("tracker should drain — no permit leak from duplicate"); + + cln_token.cancel(); + let _ = handle.await.unwrap(); + let _ = shutdown_tx.send(()); + server_handle.await.unwrap(); + } + + /// Streaming cancellation: already-read-but-not-yet-permitted messages are + /// dropped (never tracker-inserted) and eligible for redelivery; the drain + /// barrier completes without hanging; handle returns Ok. + /// + /// We set concurrency=1 so the first message fills the only permit. Then we + /// cancel while the second message (already read into the batch) is waiting on + /// permit acquisition. It must be dropped (tracker stays at 1 entry for the + /// in-flight first message). After we ack the first message the drain completes. + #[tokio::test] + async fn streaming_cancellation_drops_unpermitted_messages() { + let cln_token = CancellationToken::new(); + let tracker = Tracker::new(None, cln_token.clone()); + // concurrency=1, batch_size=5: 1 message in-flight, rest blocked on permit. + let source = make_streaming_source(5, 1, 10, tracker.clone(), cln_token.clone()).await; + + let (mut stream, handle) = source.streaming_read(cln_token.clone(), None).unwrap(); + + // Read one message; this fills the sole permit. + let msg1 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg1") + .expect("stream open"); + + // The source should have tracker size = 1 (msg1 in flight). + tokio::time::timeout(Duration::from_secs(1), async { + loop { + if !tracker.is_empty().await.unwrap() { + break; + } + tokio::time::sleep(Duration::from_millis(5)).await; + } + }) + .await + .expect("tracker should have 1 entry"); + + // Cancel while msg1 permit is held. The read loop should unblock, break + // out of permit acquisition, and stop. + cln_token.cancel(); + + // Ack msg1 — its permit is released; the drain barrier can complete. + mark_success!(msg1); + + // Handle must return Ok within a generous timeout (no hang). + let result = tokio::time::timeout(Duration::from_secs(5), handle) + .await + .expect("handle should complete after cancel + ack") + .expect("handle join"); + assert!(result.is_ok(), "handle returned error: {:?}", result); + + // Tracker must be empty (msg1 was acked, no other messages were inserted). + assert!( + tracker.is_empty().await.unwrap(), + "tracker should be empty after drain" + ); + } + + /// Streaming: dropping a MessageHandle without ack/nak triggers the recv-error + /// branch in invoke_ack_single (oneshot sender dropped) — the tracker entry is + /// deleted and the permit released so the drain completes (no hang/leak). + #[tokio::test] + async fn streaming_dropped_handle_releases_permit_via_recv_error() { + let cln_token = CancellationToken::new(); + let tracker = Tracker::new(None, cln_token.clone()); + let source = make_streaming_source(1, 1, 10, tracker.clone(), cln_token.clone()).await; + let (mut stream, handle) = source.streaming_read(cln_token.clone(), None).unwrap(); + + let msg1 = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("msg1") + .expect("stream open"); + + cln_token.cancel(); + drop(msg1); // no ack/nak → ack_rx.await returns Err → recv-error branch + + let result = tokio::time::timeout(Duration::from_secs(5), handle) + .await + .expect("handle completes") + .expect("join"); + assert!(result.is_ok()); + assert!( + tracker.is_empty().await.unwrap(), + "tracker empty after dropped handle" + ); + } + + /// 1->1 passthrough source transformer used to exercise the streaming + /// transformer branch (Some(transformer) => Ok) in `streaming_source`. + struct PassthroughTransformer; + + #[tonic::async_trait] + impl numaflow::sourcetransform::SourceTransformer for PassthroughTransformer { + async fn transform( + &self, + input: numaflow::sourcetransform::SourceTransformRequest, + ) -> Vec { + vec![ + numaflow::sourcetransform::Message::new(input.value, Utc::now()) + .with_keys(input.keys), + ] + } + } + + /// Streaming with a transformer present: exercises the + /// `Some(transformer) => transform_batch(...)` Ok branch of `streaming_source`. + /// A 1->1 passthrough transformer forwards each message downstream; we confirm + /// a transformed message arrives and the source drains cleanly on shutdown. + #[tokio::test] + async fn streaming_with_transformer_forwards_messages() { + use crate::config::components::source::GeneratorConfig; + use crate::transformer::Transformer; + use numaflow::sourcetransform; + use numaflow_pb::clients::sourcetransformer::source_transform_client::SourceTransformClient; + + let cln_token = CancellationToken::new(); + let tracker = Tracker::new(None, cln_token.clone()); + + // Start a UD source-transformer server (1->1 passthrough). + let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel(); + let tmp_dir = tempfile::TempDir::new().unwrap(); + let sock_file = tmp_dir.path().join("streaming-transformer.sock"); + let server_info_file = tmp_dir.path().join("streaming-transformer-server-info"); + let server_socket = sock_file.clone(); + let server_info = server_info_file.clone(); + let server_handle = tokio::spawn(async move { + sourcetransform::Server::new(PassthroughTransformer) + .with_socket_file(server_socket) + .with_server_info_file(server_info) + .start_with_shutdown(shutdown_rx) + .await + .unwrap(); + }); + tokio::time::sleep(Duration::from_millis(100)).await; + + let client = SourceTransformClient::new(create_rpc_channel(sock_file).await.unwrap()); + let transformer = + Transformer::new(10, 10, Duration::from_secs(10), client, tracker.clone()) + .await + .unwrap(); + + // Generator source (10 msgs), streaming=true, WITH the transformer. + let cfg = GeneratorConfig { + rpu: 10, + content: bytes::Bytes::from_static(b"payload"), + duration: Duration::from_millis(10), + value: None, + key_count: 0, + msg_size_bytes: 8, + jitter: Duration::ZERO, + }; + let (reader, acker, lag) = + crate::source::generator::new_generator(cfg, 5, cln_token.clone()).unwrap(); + // concurrency=1, batch_size=5: only one message is in flight at a time; the next + // is blocked on permit acquisition, so a cancel cleanly stops admission and the + // source never sends into a closed channel (mirrors the streaming_cancellation test). + let source: Source = Source::new( + 5, + 1, + SourceType::Generator(reader, acker, lag), + tracker.clone(), + false, + Some(transformer), + None, + cln_token.clone(), + None, + true, // streaming = true + ) + .await; + + let (mut stream, handle) = source.streaming_read(cln_token.clone(), None).unwrap(); + + // A transformed message must arrive (the transformer Ok branch produced + // output and it was forwarded downstream). + let msg = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("transformed message timeout") + .expect("stream open"); + + // Cancel BEFORE acking so no further message is admitted (the next one is blocked + // on permit acquisition and the cancel breaks it); then ack the one in hand so the + // drain barrier completes. The stream is kept alive — never dropped mid-send. + cln_token.cancel(); + mark_success!(msg); + let result = tokio::time::timeout(Duration::from_secs(5), handle) + .await + .expect("handle should complete") + .expect("handle join"); + assert!(result.is_ok(), "handle returned error: {:?}", result); + + let _ = shutdown_tx.send(()); + let _ = server_handle.await; + } + + /// Streaming with a bypass router present: exercises the + /// `if let Some(ref bypass_router) => try_bypass(...)` branch of `streaming_source`. + /// The bypass condition requires a tag the generator never sets, so no message is + /// bypassed — every message goes through `try_bypass` and is forwarded downstream + /// (the `Ok(Some(msg))` arm), then sent on the channel. + #[tokio::test] + async fn streaming_with_bypass_router_forwards_unmatched_messages() { + use crate::config::monovertex::BypassConditions; + use crate::monovertex::bypass_router::{BypassRouterConfig, MvtxBypassRouter}; + use crate::sinker::sink::{SinkClientType, SinkWriterBuilder}; + use numaflow_models::models::{ForwardConditions, TagConditions}; + + let cln_token = CancellationToken::new(); + let tracker = Tracker::new(None, cln_token.clone()); + + // Log sink writer backs the bypass receiver. It is never exercised here + // because no message matches the bypass condition. + let sink_writer = + SinkWriterBuilder::new(10, Duration::from_millis(100), SinkClientType::Log) + .build() + .await + .unwrap(); + + // Sink bypass condition requiring a tag the generator never sets → nothing + // is bypassed; messages flow through try_bypass and are forwarded. + let conditions = BypassConditions { + sink: Some(Box::new(ForwardConditions::new(TagConditions { + values: vec!["never-matches".to_string()], + operator: Some("or".to_string()), + }))), + fallback: None, + on_success: None, + }; + let config = BypassRouterConfig::new(conditions, 10, Duration::from_millis(1000)); + let (router, _router_handle) = + MvtxBypassRouter::initialize(config, sink_writer, cln_token.clone()).await; + + // concurrency=1, batch_size=5: one message in flight; cancel cleanly stops + // admission and the source never sends into a closed channel. + let source = make_streaming_source(5, 1, 10, tracker.clone(), cln_token.clone()).await; + let (mut stream, handle) = source + .streaming_read(cln_token.clone(), Some(router)) + .unwrap(); + + // Generator messages carry no tags → not bypassed → forwarded downstream. + let msg = tokio::time::timeout(Duration::from_secs(2), stream.next()) + .await + .expect("forwarded message timeout") + .expect("stream open"); + + // Cancel before acking (next message is blocked on permit; cancel breaks it), + // then ack the one in hand so the drain completes. Stream kept alive. + cln_token.cancel(); + mark_success!(msg); + let result = tokio::time::timeout(Duration::from_secs(5), handle) + .await + .expect("handle should complete") + .expect("handle join"); + assert!(result.is_ok(), "handle returned error: {:?}", result); + } } diff --git a/rust/numaflow-core/src/source/sqs.rs b/rust/numaflow-core/src/source/sqs.rs index 337202ac26..555dd98e77 100644 --- a/rust/numaflow-core/src/source/sqs.rs +++ b/rust/numaflow-core/src/source/sqs.rs @@ -293,6 +293,7 @@ pub mod tests { None, cln_token.clone(), None, + false, ) .await; diff --git a/rust/numaflow-core/src/source/test_utils.rs b/rust/numaflow-core/src/source/test_utils.rs index 2d69322451..d3bdd126f2 100644 --- a/rust/numaflow-core/src/source/test_utils.rs +++ b/rust/numaflow-core/src/source/test_utils.rs @@ -116,6 +116,7 @@ impl SourceTestHandle { None, cln_token.clone(), None, + false, ) .await } @@ -134,6 +135,7 @@ impl SourceTestHandle { None, cln_token.clone(), None, + false, ) .await } @@ -189,6 +191,7 @@ impl SourceTestHandle { None, cln_token, None, + false, ) .await; diff --git a/rust/numaflow-models/src/models/mono_vertex_spec.rs b/rust/numaflow-models/src/models/mono_vertex_spec.rs index 34ca565548..31e8997f7a 100644 --- a/rust/numaflow-models/src/models/mono_vertex_spec.rs +++ b/rust/numaflow-models/src/models/mono_vertex_spec.rs @@ -80,6 +80,9 @@ pub struct MonoVertexSpec { pub sink: Option>, #[serde(rename = "source", skip_serializing_if = "Option::is_none")] pub source: Option>, + /// Streaming enables per-message, out-of-order source acknowledgement instead of the default whole-batch barrier. When true, the source reads continuously bounded by `spec.limits.concurrency` (in-flight messages) rather than one batch at a time. This is off by default. + #[serde(rename = "streaming", skip_serializing_if = "Option::is_none")] + pub streaming: Option, /// If specified, the pod's tolerations. #[serde(rename = "tolerations", skip_serializing_if = "Option::is_none")] pub tolerations: Option>, @@ -118,6 +121,7 @@ impl MonoVertexSpec { sidecars: None, sink: None, source: None, + streaming: None, tolerations: None, udf: None, update_strategy: None, diff --git a/test/monovertex-e2e/monovertex_test.go b/test/monovertex-e2e/monovertex_test.go index 252afd0778..30e513c9c7 100644 --- a/test/monovertex-e2e/monovertex_test.go +++ b/test/monovertex-e2e/monovertex_test.go @@ -171,6 +171,38 @@ func (s *MonoVertexSuite) TestSourceTransformerBypass() { w.Expect().RedisSinkContains("bypass-sink-output", "primary-message") } +func (s *MonoVertexSuite) TestStreamingMonoVertex() { + w := s.Given().MonoVertex("@testdata/streaming-mono-vertex.yaml"). + When().CreateMonoVertexAndWait() + defer w.DeleteMonoVertexAndWait() + + monoVertexName := "streaming-mono-vertex" + + // wait for all the pods to come up + w.Expect().MonoVertexPodsRunning() + + // Send N=5 distinct messages through the HTTP source. + // Each message has a unique payload so we can assert individually that + // all N reached the sink (at-least-once: count >= 1 per message). + messages := []string{ + "stream-msg-0", + "stream-msg-1", + "stream-msg-2", + "stream-msg-3", + "stream-msg-4", + } + for _, msg := range messages { + w.SendMessageToMvTx(monoVertexName, NewHttpPostRequest().WithBody([]byte(msg))) + } + + // Assert all N messages reached the sink. The Rust redis-sink stores each + // message payload as a hash field (HINCRBY), so count >= 1 confirms + // at-least-once delivery even if a message was redelivered. + for _, msg := range messages { + w.Expect().RedisSinkContains("streaming-mvtx-output", msg) + } +} + func TestMonoVertexSuite(t *testing.T) { suite.Run(t, new(MonoVertexSuite)) } diff --git a/test/monovertex-e2e/testdata/streaming-mono-vertex.yaml b/test/monovertex-e2e/testdata/streaming-mono-vertex.yaml new file mode 100644 index 0000000000..21edbfad9c --- /dev/null +++ b/test/monovertex-e2e/testdata/streaming-mono-vertex.yaml @@ -0,0 +1,20 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + name: streaming-mono-vertex +spec: + streaming: true + scale: + min: 1 + source: + http: + service: true + sink: + udsink: + container: + # A redis sink for e2e testing, see https://github.com/numaproj/numaflow-rs/tree/main/examples/redis-sink + image: quay.io/numaio/numaflow-rs/redis-sink:stable + imagePullPolicy: IfNotPresent + env: + - name: SINK_HASH_KEY + value: "streaming-mvtx-output"