diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 2062ec5e029d..23555997a7e0 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -2612,19 +2612,6 @@ } } }, - "io.argoproj.workflow.v1alpha1.HolderNames": { - "type": "object", - "properties": { - "name": { - "description": "Name stores the name of the resource holding lock", - "type": "array", - "items": { - "type": "string" - }, - "x-kubernetes-list-type": "atomic" - } - } - }, "io.argoproj.workflow.v1alpha1.InfoResponse": { "type": "object", "properties": { @@ -2798,6 +2785,52 @@ } } }, + "io.argoproj.workflow.v1alpha1.Mutex": { + "description": "Mutex holds Mutex configuration", + "type": "object", + "properties": { + "name": { + "description": "name of the mutex", + "type": "string" + } + } + }, + "io.argoproj.workflow.v1alpha1.MutexHolding": { + "description": "MutexHolding describes the mutex and the object which is holding it.", + "type": "object", + "properties": { + "holder": { + "description": "Holder is a reference to the object which holds the Mutex. Holding Scenario:\n 1. Current workflow's NodeID which is holding the lock.\n e.g: ${NodeID}\nWaiting Scenario:\n 1. Current workflow or other workflow NodeID which is holding the lock.\n e.g: ${WorkflowName}/${NodeID}", + "type": "string" + }, + "mutex": { + "description": "Reference for the mutex e.g: ${namespace}/mutex/${mutexName}", + "type": "string" + } + } + }, + "io.argoproj.workflow.v1alpha1.MutexStatus": { + "description": "MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks.", + "type": "object", + "properties": { + "holding": { + "description": "Holding is a list of mutexes and their respective objects that are held by mutex lock for this io.argoproj.workflow.v1alpha1.", + "type": "array", + "items": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.MutexHolding" + }, + "x-kubernetes-list-type": "atomic" + }, + "waiting": { + "description": "Waiting is a list of mutexes and their respective objects this workflow is waiting for.", + "type": "array", + "items": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.MutexHolding" + }, + "x-kubernetes-list-type": "atomic" + } + } + }, "io.argoproj.workflow.v1alpha1.NodeStatus": { "description": "NodeStatus contains status information about an individual node in the workflow", "type": "object", @@ -3360,7 +3393,7 @@ } }, "waiting": { - "description": "Waiting indicates the list of current synchronization lock holders", + "description": "Waiting indicates the list of current synchronization lock holders.", "type": "array", "items": { "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreHolding" @@ -3473,6 +3506,10 @@ "description": "Synchronization holds synchronization lock configuration", "type": "object", "properties": { + "mutex": { + "description": "Mutex holds the Mutex lock details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.Mutex" + }, "semaphore": { "description": "Semaphore holds the Semaphore configuration", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreRef" @@ -3480,10 +3517,15 @@ } }, "io.argoproj.workflow.v1alpha1.SynchronizationStatus": { + "description": "SynchronizationStatus stores the status of semaphore and mutex.", "type": "object", "properties": { + "mutex": { + "description": "Mutex stores this workflow's mutex holder details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.MutexStatus" + }, "semaphore": { - "description": "SemaphoreHolders stores this workflow's Semaphore holder details", + "description": "Semaphore stores this workflow's Semaphore holder details", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.SemaphoreStatus" } } diff --git a/docs/fields.md b/docs/fields.md index 637ca1693d27..06c76e271edb 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -230,6 +230,10 @@ Workflow is the definition of a workflow resource - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -549,6 +553,10 @@ WorkflowSpec is the specification of a Workflow. - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -881,6 +889,10 @@ CronWorkflowSpec is the specification of a CronWorkflow - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -1176,6 +1188,10 @@ WorkflowTemplateSpec is a spec of WorkflowTemplate. - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -1381,6 +1397,8 @@ Arguments to a template - [`suspend-template-outputs.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template-outputs.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`work-avoidance.yaml`](https://github.com/argoproj/argo/blob/master/examples/work-avoidance.yaml) @@ -1470,6 +1488,10 @@ Synchronization holds synchronization lock configuration Examples with this field (click to open)
+- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -1478,6 +1500,7 @@ Synchronization holds synchronization lock configuration ### Fields | Field Name | Field Type | Description | |:----------:|:----------:|---------------| +|`mutex`|[`Mutex`](#mutex)|Mutex holds the Mutex lock details| |`semaphore`|[`SemaphoreRef`](#semaphoreref)|Semaphore holds the Semaphore configuration| ## Template @@ -1710,6 +1733,10 @@ Template is a reusable and composable unit of execution in a workflow - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -1938,12 +1965,16 @@ Outputs hold parameters, artifacts, and results from a step ## SynchronizationStatus -_No description available_ +SynchronizationStatus stores the status of semaphore and mutex.
Examples with this field (click to open)
+- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -1952,7 +1983,8 @@ _No description available_ ### Fields | Field Name | Field Type | Description | |:----------:|:----------:|---------------| -|`semaphore`|[`SemaphoreStatus`](#semaphorestatus)|SemaphoreHolders stores this workflow's Semaphore holder details| +|`mutex`|[`MutexStatus`](#mutexstatus)|Mutex stores this workflow's mutex holder details| +|`semaphore`|[`SemaphoreStatus`](#semaphorestatus)|Semaphore stores this workflow's Semaphore holder details| ## Artifact @@ -2151,6 +2183,8 @@ Parameter indicate a passed string parameter to a service template with an optio - [`suspend-template-outputs.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template-outputs.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`work-avoidance.yaml`](https://github.com/argoproj/argo/blob/master/examples/work-avoidance.yaml) @@ -2199,6 +2233,24 @@ Prometheus is a prometheus metric to be emitted |`name`|`string`|Name is the name of the metric| |`when`|`string`|When is a conditional statement that decides when to emit the metric| +## Mutex + +Mutex holds Mutex configuration + +
+Examples with this field (click to open) +
+ +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`name`|`string`|name of the mutex| + ## SemaphoreRef SemaphoreRef is a reference of Semaphore @@ -2725,6 +2777,10 @@ Pod metdata - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -3030,6 +3086,8 @@ WorkflowStep is a reference to a template to execute in a series of step - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`template-on-exit.yaml`](https://github.com/argoproj/argo/blob/master/examples/template-on-exit.yaml) @@ -3133,6 +3191,25 @@ _No description available_ |`hit`|`boolean`|_No description available_| |`key`|`string`|_No description available_| +## MutexStatus + +MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks. + +
+Examples with this field (click to open) +
+ +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`holding`|`Array<`[`MutexHolding`](#mutexholding)`>`|Holding is a list of mutexes and their respective objects that are held by mutex lock for this io.argoproj.workflow.v1alpha1.| +|`waiting`|`Array<`[`MutexHolding`](#mutexholding)`>`|Waiting is a list of mutexes and their respective objects this workflow is waiting for.| + ## SemaphoreStatus _No description available_ @@ -3150,7 +3227,7 @@ _No description available_ | Field Name | Field Type | Description | |:----------:|:----------:|---------------| |`holding`|`Array<`[`SemaphoreHolding`](#semaphoreholding)`>`|Holding stores the list of resource acquired synchronization lock for workflows.| -|`waiting`|`Array<`[`SemaphoreHolding`](#semaphoreholding)`>`|Waiting indicates the list of current synchronization lock holders| +|`waiting`|`Array<`[`SemaphoreHolding`](#semaphoreholding)`>`|Waiting indicates the list of current synchronization lock holders.| ## ArchiveStrategy @@ -3659,6 +3736,16 @@ Sequence expands a workflow step into numeric range |`format`|`string`|Format is a printf format string to format the value in the sequence| |`start`|[`IntOrString`](#intorstring)|Number at which to start the sequence (default: 0)| +## MutexHolding + +MutexHolding describes the mutex and the object which is holding it. + +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`holder`|`string`|Holder is a reference to the object which holds the Mutex. Holding Scenario: 1. Current workflow's NodeID which is holding the lock. e.g: ${NodeID}Waiting Scenario: 1. Current workflow or other workflow NodeID which is holding the lock. e.g: ${WorkflowName}/${NodeID}| +|`mutex`|`string`|Reference for the mutex e.g: ${namespace}/mutex/${mutexName}| + ## SemaphoreHolding _No description available_ @@ -3957,6 +4044,10 @@ ObjectMeta is metadata that all persisted resources must have, which includes al - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -4445,6 +4536,10 @@ A single application container that you want to run within a pod. - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -5091,6 +5186,10 @@ PersistentVolumeClaimSpec describes the common attributes of storage devices and - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) @@ -6092,6 +6191,10 @@ ListMeta describes metadata that synthetic resources must have, including lists - [`suspend-template.yaml`](https://github.com/argoproj/argo/blob/master/examples/suspend-template.yaml) +- [`synchronization-mutex-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-tmpl-level.yaml) + +- [`synchronization-mutex-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-mutex-wf-level.yaml) + - [`synchronization-tmpl-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-tmpl-level.yaml) - [`synchronization-wf-level.yaml`](https://github.com/argoproj/argo/blob/master/examples/synchronization-wf-level.yaml) diff --git a/docs/swagger.md b/docs/swagger.md index c11aeac0e008..7b627a6c3442 100644 --- a/docs/swagger.md +++ b/docs/swagger.md @@ -1082,12 +1082,6 @@ Histogram is a Histogram prometheus metric | buckets | [ [io.argoproj.workflow.v1alpha1.Amount](#io.argoproj.workflow.v1alpha1.amount) ] | Buckets is a list of bucket divisors for the histogram | Yes | | value | string | Value is the value of the metric | Yes | -#### io.argoproj.workflow.v1alpha1.HolderNames - -| Name | Type | Description | Required | -| ---- | ---- | ----------- | -------- | -| name | [ string ] | Name stores the name of the resource holding lock | No | - #### io.argoproj.workflow.v1alpha1.InfoResponse | Name | Type | Description | Required | @@ -1179,6 +1173,32 @@ Metrics are a list of metrics emitted from a Workflow/Template | ---- | ---- | ----------- | -------- | | prometheus | [ [io.argoproj.workflow.v1alpha1.Prometheus](#io.argoproj.workflow.v1alpha1.prometheus) ] | Prometheus is a list of prometheus metrics to be emitted | Yes | +#### io.argoproj.workflow.v1alpha1.Mutex + +Mutex holds Mutex configuration + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| name | string | name of the mutex | No | + +#### io.argoproj.workflow.v1alpha1.MutexHolding + +MutexHolding describes the mutex and the object which is holding it. + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| holder | string | Holder is a reference to the object which holds the Mutex. Holding Scenario: 1. Current workflow's NodeID which is holding the lock. e.g: ${NodeID} Waiting Scenario: 1. Current workflow or other workflow NodeID which is holding the lock. e.g: ${WorkflowName}/${NodeID} | No | +| mutex | string | Reference for the mutex e.g: ${namespace}/mutex/${mutexName} | No | + +#### io.argoproj.workflow.v1alpha1.MutexStatus + +MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks. + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| holding | [ [io.argoproj.workflow.v1alpha1.MutexHolding](#io.argoproj.workflow.v1alpha1.mutexholding) ] | Holding is a list of mutexes and their respective objects that are held by mutex lock for this io.argoproj.workflow.v1alpha1. | No | +| waiting | [ [io.argoproj.workflow.v1alpha1.MutexHolding](#io.argoproj.workflow.v1alpha1.mutexholding) ] | Waiting is a list of mutexes and their respective objects this workflow is waiting for. | No | + #### io.argoproj.workflow.v1alpha1.NodeStatus NodeStatus contains status information about an individual node in the workflow @@ -1378,7 +1398,7 @@ SemaphoreRef is a reference of Semaphore | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | | holding | [ [io.argoproj.workflow.v1alpha1.SemaphoreHolding](#io.argoproj.workflow.v1alpha1.semaphoreholding) ] | Holding stores the list of resource acquired synchronization lock for workflows. | No | -| waiting | [ [io.argoproj.workflow.v1alpha1.SemaphoreHolding](#io.argoproj.workflow.v1alpha1.semaphoreholding) ] | Waiting indicates the list of current synchronization lock holders | No | +| waiting | [ [io.argoproj.workflow.v1alpha1.SemaphoreHolding](#io.argoproj.workflow.v1alpha1.semaphoreholding) ] | Waiting indicates the list of current synchronization lock holders. | No | #### io.argoproj.workflow.v1alpha1.Sequence @@ -1437,13 +1457,17 @@ Synchronization holds synchronization lock configuration | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | +| mutex | [io.argoproj.workflow.v1alpha1.Mutex](#io.argoproj.workflow.v1alpha1.mutex) | Mutex holds the Mutex lock details | No | | semaphore | [io.argoproj.workflow.v1alpha1.SemaphoreRef](#io.argoproj.workflow.v1alpha1.semaphoreref) | Semaphore holds the Semaphore configuration | No | #### io.argoproj.workflow.v1alpha1.SynchronizationStatus +SynchronizationStatus stores the status of semaphore and mutex. + | Name | Type | Description | Required | | ---- | ---- | ----------- | -------- | -| semaphore | [io.argoproj.workflow.v1alpha1.SemaphoreStatus](#io.argoproj.workflow.v1alpha1.semaphorestatus) | SemaphoreHolders stores this workflow's Semaphore holder details | No | +| mutex | [io.argoproj.workflow.v1alpha1.MutexStatus](#io.argoproj.workflow.v1alpha1.mutexstatus) | Mutex stores this workflow's mutex holder details | No | +| semaphore | [io.argoproj.workflow.v1alpha1.SemaphoreStatus](#io.argoproj.workflow.v1alpha1.semaphorestatus) | Semaphore stores this workflow's Semaphore holder details | No | #### io.argoproj.workflow.v1alpha1.TTLStrategy diff --git a/examples/synchronization-mutex-tmpl-level.yaml b/examples/synchronization-mutex-tmpl-level.yaml new file mode 100644 index 000000000000..9652e48a7d0a --- /dev/null +++ b/examples/synchronization-mutex-tmpl-level.yaml @@ -0,0 +1,45 @@ +# This example demonstrates the use of a Synchronization Mutex lock on template execution. Mutex lock limits +# only one of the template execution across the workflows in the namespace which has same Mutex lock. + +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: synchronization-tmpl-level-mutex- +spec: + entrypoint: synchronization-tmpl-level-mutex-example + templates: + - name: synchronization-tmpl-level-mutex-example + steps: + - - name: synchronization-acquire-lock + template: acquire-lock + arguments: + parameters: + - name: seconds + value: "{{item}}" + withParam: '["1","2","3","4","5"]' + + - name: synchronization-acquire-lock1 + template: acquire-lock-1 + arguments: + parameters: + - name: seconds + value: "{{item}}" + withParam: '["1","2","3","4","5"]' + + - name: acquire-lock + synchronization: + mutex: + name: welcome + container: + image: alpine:latest + command: [sh, -c] + args: ["sleep 20; echo acquired lock"] + + - name: acquire-lock-1 + synchronization: + mutex: + name: test + container: + image: alpine:latest + command: [sh, -c] + args: ["sleep 50; echo acquired lock"] \ No newline at end of file diff --git a/examples/synchronization-mutex-wf-level.yaml b/examples/synchronization-mutex-wf-level.yaml new file mode 100644 index 000000000000..30bae7caace9 --- /dev/null +++ b/examples/synchronization-mutex-wf-level.yaml @@ -0,0 +1,17 @@ +# This example demonstrates the use of a Synchronization Mutex lock on workflow execution. Mutex lock limits +# only one of the workflow execution in the namespace which has same Mutex lock. +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: synchronization-wf-level- +spec: + entrypoint: whalesay + synchronization: + mutex: + name: test + templates: + - name: whalesay + container: + image: docker/whalesay:latest + command: [cowsay] + args: ["hello world"] diff --git a/examples/synchronization-wf-level.yaml b/examples/synchronization-wf-level.yaml index db3690fcb85b..f0d58a5d7666 100644 --- a/examples/synchronization-wf-level.yaml +++ b/examples/synchronization-wf-level.yaml @@ -21,8 +21,8 @@ spec: name: my-config key: workflow templates: - - name: whalesay - container: - image: docker/whalesay:latest - command: [cowsay] - args: ["hello world"] + - name: whalesay + container: + image: docker/whalesay:latest + command: [cowsay] + args: ["hello world"] diff --git a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml index fe21ed34f4a7..7ccdfe4cb1e0 100644 --- a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml @@ -864,6 +864,11 @@ spec: type: boolean synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -5595,6 +5600,11 @@ spec: type: object synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml index e3ac8effbfe8..b7b6e558ce3a 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -885,6 +885,11 @@ spec: type: boolean synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -5616,6 +5621,11 @@ spec: type: object synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: diff --git a/manifests/base/crds/full/argoproj.io_workflows.yaml b/manifests/base/crds/full/argoproj.io_workflows.yaml index d95bb8d9d798..ca1c1b3dfa60 100644 --- a/manifests/base/crds/full/argoproj.io_workflows.yaml +++ b/manifests/base/crds/full/argoproj.io_workflows.yaml @@ -874,6 +874,11 @@ spec: type: boolean synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -5605,6 +5610,11 @@ spec: type: object synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -13411,6 +13421,11 @@ spec: type: object synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -14893,6 +14908,11 @@ spec: type: boolean synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -19624,6 +19644,11 @@ spec: type: object synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -21016,6 +21041,29 @@ spec: type: object synchronization: properties: + mutex: + properties: + holding: + items: + properties: + holder: + type: string + mutex: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + waiting: + items: + properties: + holder: + type: string + mutex: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object semaphore: properties: holding: diff --git a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml index e7c8dc68b7c4..d3ffd85d7507 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml @@ -863,6 +863,11 @@ spec: type: boolean synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: @@ -5594,6 +5599,11 @@ spec: type: object synchronization: properties: + mutex: + properties: + name: + type: string + type: object semaphore: properties: configMapKeyRef: diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index 5c52541d0f19..eb1180e19b16 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -931,38 +931,10 @@ func (m *Histogram) XXX_DiscardUnknown() { var xxx_messageInfo_Histogram proto.InternalMessageInfo -func (m *HolderNames) Reset() { *m = HolderNames{} } -func (*HolderNames) ProtoMessage() {} -func (*HolderNames) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{32} -} -func (m *HolderNames) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HolderNames) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *HolderNames) XXX_Merge(src proto.Message) { - xxx_messageInfo_HolderNames.Merge(m, src) -} -func (m *HolderNames) XXX_Size() int { - return m.Size() -} -func (m *HolderNames) XXX_DiscardUnknown() { - xxx_messageInfo_HolderNames.DiscardUnknown(m) -} - -var xxx_messageInfo_HolderNames proto.InternalMessageInfo - func (m *Inputs) Reset() { *m = Inputs{} } func (*Inputs) ProtoMessage() {} func (*Inputs) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{33} + return fileDescriptor_c23edafa7e7ea072, []int{32} } func (m *Inputs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -990,7 +962,7 @@ var xxx_messageInfo_Inputs proto.InternalMessageInfo func (m *Item) Reset() { *m = Item{} } func (*Item) ProtoMessage() {} func (*Item) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{34} + return fileDescriptor_c23edafa7e7ea072, []int{33} } func (m *Item) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1018,7 +990,7 @@ var xxx_messageInfo_Item proto.InternalMessageInfo func (m *Link) Reset() { *m = Link{} } func (*Link) ProtoMessage() {} func (*Link) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{35} + return fileDescriptor_c23edafa7e7ea072, []int{34} } func (m *Link) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1046,7 +1018,7 @@ var xxx_messageInfo_Link proto.InternalMessageInfo func (m *MemoizationStatus) Reset() { *m = MemoizationStatus{} } func (*MemoizationStatus) ProtoMessage() {} func (*MemoizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{36} + return fileDescriptor_c23edafa7e7ea072, []int{35} } func (m *MemoizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1074,7 +1046,7 @@ var xxx_messageInfo_MemoizationStatus proto.InternalMessageInfo func (m *Memoize) Reset() { *m = Memoize{} } func (*Memoize) ProtoMessage() {} func (*Memoize) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{37} + return fileDescriptor_c23edafa7e7ea072, []int{36} } func (m *Memoize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1102,7 +1074,7 @@ var xxx_messageInfo_Memoize proto.InternalMessageInfo func (m *Metadata) Reset() { *m = Metadata{} } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{38} + return fileDescriptor_c23edafa7e7ea072, []int{37} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1130,7 +1102,7 @@ var xxx_messageInfo_Metadata proto.InternalMessageInfo func (m *MetricLabel) Reset() { *m = MetricLabel{} } func (*MetricLabel) ProtoMessage() {} func (*MetricLabel) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{39} + return fileDescriptor_c23edafa7e7ea072, []int{38} } func (m *MetricLabel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1158,7 +1130,7 @@ var xxx_messageInfo_MetricLabel proto.InternalMessageInfo func (m *Metrics) Reset() { *m = Metrics{} } func (*Metrics) ProtoMessage() {} func (*Metrics) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{40} + return fileDescriptor_c23edafa7e7ea072, []int{39} } func (m *Metrics) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1183,10 +1155,94 @@ func (m *Metrics) XXX_DiscardUnknown() { var xxx_messageInfo_Metrics proto.InternalMessageInfo +func (m *Mutex) Reset() { *m = Mutex{} } +func (*Mutex) ProtoMessage() {} +func (*Mutex) Descriptor() ([]byte, []int) { + return fileDescriptor_c23edafa7e7ea072, []int{40} +} +func (m *Mutex) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Mutex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Mutex) XXX_Merge(src proto.Message) { + xxx_messageInfo_Mutex.Merge(m, src) +} +func (m *Mutex) XXX_Size() int { + return m.Size() +} +func (m *Mutex) XXX_DiscardUnknown() { + xxx_messageInfo_Mutex.DiscardUnknown(m) +} + +var xxx_messageInfo_Mutex proto.InternalMessageInfo + +func (m *MutexHolding) Reset() { *m = MutexHolding{} } +func (*MutexHolding) ProtoMessage() {} +func (*MutexHolding) Descriptor() ([]byte, []int) { + return fileDescriptor_c23edafa7e7ea072, []int{41} +} +func (m *MutexHolding) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MutexHolding) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *MutexHolding) XXX_Merge(src proto.Message) { + xxx_messageInfo_MutexHolding.Merge(m, src) +} +func (m *MutexHolding) XXX_Size() int { + return m.Size() +} +func (m *MutexHolding) XXX_DiscardUnknown() { + xxx_messageInfo_MutexHolding.DiscardUnknown(m) +} + +var xxx_messageInfo_MutexHolding proto.InternalMessageInfo + +func (m *MutexStatus) Reset() { *m = MutexStatus{} } +func (*MutexStatus) ProtoMessage() {} +func (*MutexStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_c23edafa7e7ea072, []int{42} +} +func (m *MutexStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MutexStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *MutexStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_MutexStatus.Merge(m, src) +} +func (m *MutexStatus) XXX_Size() int { + return m.Size() +} +func (m *MutexStatus) XXX_DiscardUnknown() { + xxx_messageInfo_MutexStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_MutexStatus proto.InternalMessageInfo + func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} func (*NodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{41} + return fileDescriptor_c23edafa7e7ea072, []int{43} } func (m *NodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1214,7 +1270,7 @@ var xxx_messageInfo_NodeStatus proto.InternalMessageInfo func (m *NoneStrategy) Reset() { *m = NoneStrategy{} } func (*NoneStrategy) ProtoMessage() {} func (*NoneStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{42} + return fileDescriptor_c23edafa7e7ea072, []int{44} } func (m *NoneStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1242,7 +1298,7 @@ var xxx_messageInfo_NoneStrategy proto.InternalMessageInfo func (m *OSSArtifact) Reset() { *m = OSSArtifact{} } func (*OSSArtifact) ProtoMessage() {} func (*OSSArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{43} + return fileDescriptor_c23edafa7e7ea072, []int{45} } func (m *OSSArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1270,7 +1326,7 @@ var xxx_messageInfo_OSSArtifact proto.InternalMessageInfo func (m *OSSBucket) Reset() { *m = OSSBucket{} } func (*OSSBucket) ProtoMessage() {} func (*OSSBucket) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{44} + return fileDescriptor_c23edafa7e7ea072, []int{46} } func (m *OSSBucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1298,7 +1354,7 @@ var xxx_messageInfo_OSSBucket proto.InternalMessageInfo func (m *Outputs) Reset() { *m = Outputs{} } func (*Outputs) ProtoMessage() {} func (*Outputs) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{45} + return fileDescriptor_c23edafa7e7ea072, []int{47} } func (m *Outputs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1326,7 +1382,7 @@ var xxx_messageInfo_Outputs proto.InternalMessageInfo func (m *ParallelSteps) Reset() { *m = ParallelSteps{} } func (*ParallelSteps) ProtoMessage() {} func (*ParallelSteps) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{46} + return fileDescriptor_c23edafa7e7ea072, []int{48} } func (m *ParallelSteps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1354,7 +1410,7 @@ var xxx_messageInfo_ParallelSteps proto.InternalMessageInfo func (m *Parameter) Reset() { *m = Parameter{} } func (*Parameter) ProtoMessage() {} func (*Parameter) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{47} + return fileDescriptor_c23edafa7e7ea072, []int{49} } func (m *Parameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1382,7 +1438,7 @@ var xxx_messageInfo_Parameter proto.InternalMessageInfo func (m *PodGC) Reset() { *m = PodGC{} } func (*PodGC) ProtoMessage() {} func (*PodGC) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{48} + return fileDescriptor_c23edafa7e7ea072, []int{50} } func (m *PodGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1410,7 +1466,7 @@ var xxx_messageInfo_PodGC proto.InternalMessageInfo func (m *Prometheus) Reset() { *m = Prometheus{} } func (*Prometheus) ProtoMessage() {} func (*Prometheus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{49} + return fileDescriptor_c23edafa7e7ea072, []int{51} } func (m *Prometheus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1438,7 +1494,7 @@ var xxx_messageInfo_Prometheus proto.InternalMessageInfo func (m *RawArtifact) Reset() { *m = RawArtifact{} } func (*RawArtifact) ProtoMessage() {} func (*RawArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{50} + return fileDescriptor_c23edafa7e7ea072, []int{52} } func (m *RawArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1466,7 +1522,7 @@ var xxx_messageInfo_RawArtifact proto.InternalMessageInfo func (m *ResourceTemplate) Reset() { *m = ResourceTemplate{} } func (*ResourceTemplate) ProtoMessage() {} func (*ResourceTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{51} + return fileDescriptor_c23edafa7e7ea072, []int{53} } func (m *ResourceTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1494,7 +1550,7 @@ var xxx_messageInfo_ResourceTemplate proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{52} + return fileDescriptor_c23edafa7e7ea072, []int{54} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1522,7 +1578,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *S3Artifact) Reset() { *m = S3Artifact{} } func (*S3Artifact) ProtoMessage() {} func (*S3Artifact) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{53} + return fileDescriptor_c23edafa7e7ea072, []int{55} } func (m *S3Artifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1550,7 +1606,7 @@ var xxx_messageInfo_S3Artifact proto.InternalMessageInfo func (m *S3Bucket) Reset() { *m = S3Bucket{} } func (*S3Bucket) ProtoMessage() {} func (*S3Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{54} + return fileDescriptor_c23edafa7e7ea072, []int{56} } func (m *S3Bucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1578,7 +1634,7 @@ var xxx_messageInfo_S3Bucket proto.InternalMessageInfo func (m *ScriptTemplate) Reset() { *m = ScriptTemplate{} } func (*ScriptTemplate) ProtoMessage() {} func (*ScriptTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{55} + return fileDescriptor_c23edafa7e7ea072, []int{57} } func (m *ScriptTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1606,7 +1662,7 @@ var xxx_messageInfo_ScriptTemplate proto.InternalMessageInfo func (m *SemaphoreHolding) Reset() { *m = SemaphoreHolding{} } func (*SemaphoreHolding) ProtoMessage() {} func (*SemaphoreHolding) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{56} + return fileDescriptor_c23edafa7e7ea072, []int{58} } func (m *SemaphoreHolding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1634,7 +1690,7 @@ var xxx_messageInfo_SemaphoreHolding proto.InternalMessageInfo func (m *SemaphoreRef) Reset() { *m = SemaphoreRef{} } func (*SemaphoreRef) ProtoMessage() {} func (*SemaphoreRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{57} + return fileDescriptor_c23edafa7e7ea072, []int{59} } func (m *SemaphoreRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1662,7 +1718,7 @@ var xxx_messageInfo_SemaphoreRef proto.InternalMessageInfo func (m *SemaphoreStatus) Reset() { *m = SemaphoreStatus{} } func (*SemaphoreStatus) ProtoMessage() {} func (*SemaphoreStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{58} + return fileDescriptor_c23edafa7e7ea072, []int{60} } func (m *SemaphoreStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1690,7 +1746,7 @@ var xxx_messageInfo_SemaphoreStatus proto.InternalMessageInfo func (m *Sequence) Reset() { *m = Sequence{} } func (*Sequence) ProtoMessage() {} func (*Sequence) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{59} + return fileDescriptor_c23edafa7e7ea072, []int{61} } func (m *Sequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1718,7 +1774,7 @@ var xxx_messageInfo_Sequence proto.InternalMessageInfo func (m *Submit) Reset() { *m = Submit{} } func (*Submit) ProtoMessage() {} func (*Submit) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{60} + return fileDescriptor_c23edafa7e7ea072, []int{62} } func (m *Submit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1746,7 +1802,7 @@ var xxx_messageInfo_Submit proto.InternalMessageInfo func (m *SubmitOpts) Reset() { *m = SubmitOpts{} } func (*SubmitOpts) ProtoMessage() {} func (*SubmitOpts) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{61} + return fileDescriptor_c23edafa7e7ea072, []int{63} } func (m *SubmitOpts) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1774,7 +1830,7 @@ var xxx_messageInfo_SubmitOpts proto.InternalMessageInfo func (m *SuppliedValueFrom) Reset() { *m = SuppliedValueFrom{} } func (*SuppliedValueFrom) ProtoMessage() {} func (*SuppliedValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{62} + return fileDescriptor_c23edafa7e7ea072, []int{64} } func (m *SuppliedValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1802,7 +1858,7 @@ var xxx_messageInfo_SuppliedValueFrom proto.InternalMessageInfo func (m *SuspendTemplate) Reset() { *m = SuspendTemplate{} } func (*SuspendTemplate) ProtoMessage() {} func (*SuspendTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{63} + return fileDescriptor_c23edafa7e7ea072, []int{65} } func (m *SuspendTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1830,7 +1886,7 @@ var xxx_messageInfo_SuspendTemplate proto.InternalMessageInfo func (m *Synchronization) Reset() { *m = Synchronization{} } func (*Synchronization) ProtoMessage() {} func (*Synchronization) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{64} + return fileDescriptor_c23edafa7e7ea072, []int{66} } func (m *Synchronization) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1858,7 +1914,7 @@ var xxx_messageInfo_Synchronization proto.InternalMessageInfo func (m *SynchronizationStatus) Reset() { *m = SynchronizationStatus{} } func (*SynchronizationStatus) ProtoMessage() {} func (*SynchronizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{65} + return fileDescriptor_c23edafa7e7ea072, []int{67} } func (m *SynchronizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1886,7 +1942,7 @@ var xxx_messageInfo_SynchronizationStatus proto.InternalMessageInfo func (m *TTLStrategy) Reset() { *m = TTLStrategy{} } func (*TTLStrategy) ProtoMessage() {} func (*TTLStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{66} + return fileDescriptor_c23edafa7e7ea072, []int{68} } func (m *TTLStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1914,7 +1970,7 @@ var xxx_messageInfo_TTLStrategy proto.InternalMessageInfo func (m *TarStrategy) Reset() { *m = TarStrategy{} } func (*TarStrategy) ProtoMessage() {} func (*TarStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{67} + return fileDescriptor_c23edafa7e7ea072, []int{69} } func (m *TarStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1942,7 +1998,7 @@ var xxx_messageInfo_TarStrategy proto.InternalMessageInfo func (m *Template) Reset() { *m = Template{} } func (*Template) ProtoMessage() {} func (*Template) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{68} + return fileDescriptor_c23edafa7e7ea072, []int{70} } func (m *Template) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1970,7 +2026,7 @@ var xxx_messageInfo_Template proto.InternalMessageInfo func (m *TemplateRef) Reset() { *m = TemplateRef{} } func (*TemplateRef) ProtoMessage() {} func (*TemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{69} + return fileDescriptor_c23edafa7e7ea072, []int{71} } func (m *TemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1998,7 +2054,7 @@ var xxx_messageInfo_TemplateRef proto.InternalMessageInfo func (m *UserContainer) Reset() { *m = UserContainer{} } func (*UserContainer) ProtoMessage() {} func (*UserContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{70} + return fileDescriptor_c23edafa7e7ea072, []int{72} } func (m *UserContainer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2026,7 +2082,7 @@ var xxx_messageInfo_UserContainer proto.InternalMessageInfo func (m *ValueFrom) Reset() { *m = ValueFrom{} } func (*ValueFrom) ProtoMessage() {} func (*ValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{71} + return fileDescriptor_c23edafa7e7ea072, []int{73} } func (m *ValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2054,7 +2110,7 @@ var xxx_messageInfo_ValueFrom proto.InternalMessageInfo func (m *Version) Reset() { *m = Version{} } func (*Version) ProtoMessage() {} func (*Version) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{72} + return fileDescriptor_c23edafa7e7ea072, []int{74} } func (m *Version) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2079,38 +2135,10 @@ func (m *Version) XXX_DiscardUnknown() { var xxx_messageInfo_Version proto.InternalMessageInfo -func (m *WaitingStatus) Reset() { *m = WaitingStatus{} } -func (*WaitingStatus) ProtoMessage() {} -func (*WaitingStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{73} -} -func (m *WaitingStatus) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *WaitingStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil -} -func (m *WaitingStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_WaitingStatus.Merge(m, src) -} -func (m *WaitingStatus) XXX_Size() int { - return m.Size() -} -func (m *WaitingStatus) XXX_DiscardUnknown() { - xxx_messageInfo_WaitingStatus.DiscardUnknown(m) -} - -var xxx_messageInfo_WaitingStatus proto.InternalMessageInfo - func (m *Workflow) Reset() { *m = Workflow{} } func (*Workflow) ProtoMessage() {} func (*Workflow) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{74} + return fileDescriptor_c23edafa7e7ea072, []int{75} } func (m *Workflow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2138,7 +2166,7 @@ var xxx_messageInfo_Workflow proto.InternalMessageInfo func (m *WorkflowEventBinding) Reset() { *m = WorkflowEventBinding{} } func (*WorkflowEventBinding) ProtoMessage() {} func (*WorkflowEventBinding) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{75} + return fileDescriptor_c23edafa7e7ea072, []int{76} } func (m *WorkflowEventBinding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2166,7 +2194,7 @@ var xxx_messageInfo_WorkflowEventBinding proto.InternalMessageInfo func (m *WorkflowEventBindingList) Reset() { *m = WorkflowEventBindingList{} } func (*WorkflowEventBindingList) ProtoMessage() {} func (*WorkflowEventBindingList) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{76} + return fileDescriptor_c23edafa7e7ea072, []int{77} } func (m *WorkflowEventBindingList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2194,7 +2222,7 @@ var xxx_messageInfo_WorkflowEventBindingList proto.InternalMessageInfo func (m *WorkflowEventBindingSpec) Reset() { *m = WorkflowEventBindingSpec{} } func (*WorkflowEventBindingSpec) ProtoMessage() {} func (*WorkflowEventBindingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{77} + return fileDescriptor_c23edafa7e7ea072, []int{78} } func (m *WorkflowEventBindingSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2222,7 +2250,7 @@ var xxx_messageInfo_WorkflowEventBindingSpec proto.InternalMessageInfo func (m *WorkflowList) Reset() { *m = WorkflowList{} } func (*WorkflowList) ProtoMessage() {} func (*WorkflowList) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{78} + return fileDescriptor_c23edafa7e7ea072, []int{79} } func (m *WorkflowList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2250,7 +2278,7 @@ var xxx_messageInfo_WorkflowList proto.InternalMessageInfo func (m *WorkflowSpec) Reset() { *m = WorkflowSpec{} } func (*WorkflowSpec) ProtoMessage() {} func (*WorkflowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{79} + return fileDescriptor_c23edafa7e7ea072, []int{80} } func (m *WorkflowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2278,7 +2306,7 @@ var xxx_messageInfo_WorkflowSpec proto.InternalMessageInfo func (m *WorkflowStatus) Reset() { *m = WorkflowStatus{} } func (*WorkflowStatus) ProtoMessage() {} func (*WorkflowStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{80} + return fileDescriptor_c23edafa7e7ea072, []int{81} } func (m *WorkflowStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2306,7 +2334,7 @@ var xxx_messageInfo_WorkflowStatus proto.InternalMessageInfo func (m *WorkflowStep) Reset() { *m = WorkflowStep{} } func (*WorkflowStep) ProtoMessage() {} func (*WorkflowStep) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{81} + return fileDescriptor_c23edafa7e7ea072, []int{82} } func (m *WorkflowStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2334,7 +2362,7 @@ var xxx_messageInfo_WorkflowStep proto.InternalMessageInfo func (m *WorkflowTemplate) Reset() { *m = WorkflowTemplate{} } func (*WorkflowTemplate) ProtoMessage() {} func (*WorkflowTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{82} + return fileDescriptor_c23edafa7e7ea072, []int{83} } func (m *WorkflowTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2362,7 +2390,7 @@ var xxx_messageInfo_WorkflowTemplate proto.InternalMessageInfo func (m *WorkflowTemplateList) Reset() { *m = WorkflowTemplateList{} } func (*WorkflowTemplateList) ProtoMessage() {} func (*WorkflowTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{83} + return fileDescriptor_c23edafa7e7ea072, []int{84} } func (m *WorkflowTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2390,7 +2418,7 @@ var xxx_messageInfo_WorkflowTemplateList proto.InternalMessageInfo func (m *WorkflowTemplateRef) Reset() { *m = WorkflowTemplateRef{} } func (*WorkflowTemplateRef) ProtoMessage() {} func (*WorkflowTemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{84} + return fileDescriptor_c23edafa7e7ea072, []int{85} } func (m *WorkflowTemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2418,7 +2446,7 @@ var xxx_messageInfo_WorkflowTemplateRef proto.InternalMessageInfo func (m *WorkflowTemplateSpec) Reset() { *m = WorkflowTemplateSpec{} } func (*WorkflowTemplateSpec) ProtoMessage() {} func (*WorkflowTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c23edafa7e7ea072, []int{85} + return fileDescriptor_c23edafa7e7ea072, []int{86} } func (m *WorkflowTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2476,7 +2504,6 @@ func init() { proto.RegisterType((*HDFSKrbConfig)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.HDFSKrbConfig") proto.RegisterType((*HTTPArtifact)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.HTTPArtifact") proto.RegisterType((*Histogram)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Histogram") - proto.RegisterType((*HolderNames)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.HolderNames") proto.RegisterType((*Inputs)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Inputs") proto.RegisterType((*Item)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Item") proto.RegisterType((*Link)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Link") @@ -2487,6 +2514,9 @@ func init() { proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Metadata.LabelsEntry") proto.RegisterType((*MetricLabel)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.MetricLabel") proto.RegisterType((*Metrics)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Metrics") + proto.RegisterType((*Mutex)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Mutex") + proto.RegisterType((*MutexHolding)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.MutexHolding") + proto.RegisterType((*MutexStatus)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.MutexStatus") proto.RegisterType((*NodeStatus)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.NodeStatus") proto.RegisterMapType((ResourcesDuration)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.NodeStatus.ResourcesDurationEntry") proto.RegisterType((*NoneStrategy)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.NoneStrategy") @@ -2521,7 +2551,6 @@ func init() { proto.RegisterType((*UserContainer)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.UserContainer") proto.RegisterType((*ValueFrom)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.ValueFrom") proto.RegisterType((*Version)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Version") - proto.RegisterType((*WaitingStatus)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.WaitingStatus") proto.RegisterType((*Workflow)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.Workflow") proto.RegisterType((*WorkflowEventBinding)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.WorkflowEventBinding") proto.RegisterType((*WorkflowEventBindingList)(nil), "github.com.argoproj.argo.pkg.apis.workflow.v1alpha1.WorkflowEventBindingList") @@ -2545,445 +2574,448 @@ func init() { } var fileDescriptor_c23edafa7e7ea072 = []byte{ - // 7000 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5d, 0x6c, 0x23, 0xd7, - 0x75, 0xb0, 0x29, 0x89, 0x14, 0x79, 0x28, 0xad, 0xa4, 0xbb, 0x7f, 0xb4, 0xbc, 0x5e, 0x6e, 0xc6, - 0xb1, 0xb1, 0xfe, 0x92, 0x48, 0xf1, 0x6e, 0xfc, 0x7d, 0x4e, 0x1c, 0xff, 0x88, 0xd2, 0x4a, 0x2b, - 0xef, 0x8f, 0xe4, 0x43, 0xed, 0xee, 0x97, 0xd8, 0xb0, 0xbf, 0x11, 0xe7, 0x92, 0x9c, 0x15, 0x39, - 0x43, 0xcf, 0x0c, 0x57, 0x56, 0x9c, 0x0f, 0x75, 0x82, 0x06, 0x69, 0x12, 0x04, 0x6d, 0x11, 0xa0, - 0x75, 0x11, 0x14, 0xe8, 0x4b, 0x51, 0xa0, 0xe8, 0x6b, 0xfb, 0x52, 0x20, 0x0f, 0x45, 0x5b, 0xa4, - 0x79, 0x69, 0x8a, 0x3e, 0x34, 0x0f, 0x81, 0x12, 0xab, 0x2f, 0x2e, 0xd2, 0x36, 0x4f, 0x41, 0x81, - 0x45, 0x81, 0x16, 0xf7, 0x77, 0x7e, 0x38, 0xdc, 0xd5, 0x0e, 0xb5, 0x8b, 0xa0, 0xc9, 0x1b, 0xe7, - 0x9c, 0x73, 0xcf, 0xb9, 0xff, 0xf7, 0xfc, 0xdd, 0x4b, 0x58, 0x6e, 0xd9, 0x41, 0xbb, 0xbf, 0xbd, - 0xd0, 0x70, 0xbb, 0x8b, 0xa6, 0xd7, 0x72, 0x7b, 0x9e, 0x7b, 0x9b, 0xff, 0x58, 0xec, 0xed, 0xb4, - 0x16, 0xcd, 0x9e, 0xed, 0x2f, 0xee, 0xba, 0xde, 0x4e, 0xb3, 0xe3, 0xee, 0x2e, 0xde, 0x79, 0xce, - 0xec, 0xf4, 0xda, 0xe6, 0x73, 0x8b, 0x2d, 0xea, 0x50, 0xcf, 0x0c, 0xa8, 0xb5, 0xd0, 0xf3, 0xdc, - 0xc0, 0x25, 0x17, 0x43, 0x26, 0x0b, 0x8a, 0x09, 0xff, 0xb1, 0xd0, 0xdb, 0x69, 0x2d, 0x30, 0x26, - 0x0b, 0x8a, 0xc9, 0x82, 0x62, 0x32, 0xff, 0xa9, 0x88, 0xe4, 0x96, 0xcb, 0x04, 0x32, 0x5e, 0xdb, - 0xfd, 0x26, 0xff, 0xe2, 0x1f, 0xfc, 0x97, 0x90, 0x31, 0x6f, 0xec, 0xbc, 0xe0, 0x2f, 0xd8, 0x2e, - 0xab, 0xd2, 0x62, 0xc3, 0xf5, 0xe8, 0xe2, 0x9d, 0x81, 0x7a, 0xcc, 0x3f, 0x1b, 0xa1, 0xe9, 0xb9, - 0x1d, 0xbb, 0xb1, 0xb7, 0x78, 0xe7, 0xb9, 0x6d, 0x1a, 0x0c, 0x56, 0x79, 0xfe, 0x33, 0x21, 0x69, - 0xd7, 0x6c, 0xb4, 0x6d, 0x87, 0x7a, 0x7b, 0x61, 0x93, 0xbb, 0x34, 0x30, 0xd3, 0x04, 0x2c, 0x0e, - 0x2b, 0xe5, 0xf5, 0x9d, 0xc0, 0xee, 0xd2, 0x81, 0x02, 0xff, 0xfb, 0x7e, 0x05, 0xfc, 0x46, 0x9b, - 0x76, 0xcd, 0x81, 0x72, 0x17, 0x87, 0x95, 0xeb, 0x07, 0x76, 0x67, 0xd1, 0x76, 0x02, 0x3f, 0xf0, - 0x92, 0x85, 0x8c, 0x67, 0xa1, 0xb0, 0xd4, 0x75, 0xfb, 0x4e, 0x40, 0xaa, 0x90, 0xbf, 0x63, 0x76, - 0xfa, 0xb4, 0x92, 0x3b, 0x97, 0x3b, 0x3f, 0x55, 0x2b, 0x1d, 0xec, 0x57, 0xf3, 0x37, 0x19, 0x00, - 0x05, 0xdc, 0xf8, 0xfb, 0x1c, 0xcc, 0x2c, 0x79, 0x8d, 0xb6, 0x7d, 0x87, 0xd6, 0x03, 0xc6, 0xa3, - 0xb5, 0x47, 0xde, 0x80, 0xf1, 0xc0, 0xf4, 0x78, 0x91, 0xf2, 0x85, 0x57, 0x17, 0x32, 0x8c, 0xe9, - 0xc2, 0x96, 0xe9, 0x29, 0x76, 0xb5, 0xc9, 0x83, 0xfd, 0xea, 0xf8, 0x96, 0xe9, 0x21, 0xe3, 0x4a, - 0xde, 0x86, 0x09, 0xc7, 0x75, 0x68, 0x65, 0x8c, 0x73, 0x5f, 0xca, 0xc4, 0xfd, 0xba, 0xeb, 0xe8, - 0xda, 0xd6, 0x8a, 0x07, 0xfb, 0xd5, 0x09, 0x06, 0x41, 0xce, 0xd8, 0xf8, 0x79, 0x0e, 0x4a, 0x4b, - 0x5e, 0xab, 0xdf, 0xa5, 0x4e, 0xe0, 0x13, 0x0f, 0xa0, 0x67, 0x7a, 0x66, 0x97, 0x06, 0xd4, 0xf3, - 0x2b, 0xb9, 0x73, 0xe3, 0xe7, 0xcb, 0x17, 0x5e, 0xce, 0x24, 0x74, 0x53, 0xb1, 0xa9, 0x91, 0xef, - 0xef, 0x57, 0x1f, 0x3b, 0xd8, 0xaf, 0x82, 0x06, 0xf9, 0x18, 0x91, 0x42, 0x1c, 0x28, 0x99, 0x5e, - 0x60, 0x37, 0xcd, 0x46, 0xe0, 0x57, 0xc6, 0xb8, 0xc8, 0x97, 0x32, 0x89, 0x5c, 0x92, 0x5c, 0x6a, - 0x73, 0x52, 0x62, 0x49, 0x41, 0x7c, 0x0c, 0x45, 0x18, 0x3f, 0x1b, 0x87, 0xa2, 0x42, 0x90, 0x73, - 0x30, 0xe1, 0x98, 0x5d, 0x31, 0xe0, 0xa5, 0xda, 0x94, 0x2c, 0x38, 0x71, 0xdd, 0xec, 0xb2, 0x0e, - 0x32, 0xbb, 0x94, 0x51, 0xf4, 0xcc, 0xa0, 0xcd, 0x47, 0x20, 0x42, 0xb1, 0x69, 0x06, 0x6d, 0xe4, - 0x18, 0x72, 0x06, 0x26, 0xba, 0xae, 0x45, 0x2b, 0xe3, 0xe7, 0x72, 0xe7, 0xf3, 0xa2, 0x83, 0xaf, - 0xb9, 0x16, 0x45, 0x0e, 0x65, 0xe5, 0x9b, 0x9e, 0xdb, 0xad, 0x4c, 0xc4, 0xcb, 0xaf, 0x7a, 0x6e, - 0x17, 0x39, 0x86, 0x7c, 0x2b, 0x07, 0xb3, 0xaa, 0x7a, 0x57, 0xdd, 0x86, 0x19, 0xd8, 0xae, 0x53, - 0xc9, 0xf3, 0x01, 0xbf, 0x34, 0x52, 0x47, 0x28, 0x66, 0xb5, 0x8a, 0x94, 0x3a, 0x9b, 0xc4, 0xe0, - 0x80, 0x60, 0x72, 0x01, 0xa0, 0xd5, 0x71, 0xb7, 0xcd, 0x0e, 0xeb, 0x83, 0x4a, 0x81, 0xd7, 0x5a, - 0x0f, 0xe1, 0x9a, 0xc6, 0x60, 0x84, 0x8a, 0xec, 0xc0, 0xa4, 0x29, 0x56, 0x45, 0x65, 0x92, 0xd7, - 0x7b, 0x25, 0x63, 0xbd, 0x63, 0x2b, 0xab, 0x56, 0x3e, 0xd8, 0xaf, 0x4e, 0x4a, 0x20, 0x2a, 0x09, - 0xe4, 0x93, 0x50, 0x74, 0x7b, 0xac, 0xaa, 0x66, 0xa7, 0x52, 0x3c, 0x97, 0x3b, 0x5f, 0xac, 0xcd, - 0xca, 0xea, 0x15, 0x37, 0x24, 0x1c, 0x35, 0x85, 0xf1, 0x0f, 0x05, 0x18, 0x68, 0x35, 0x79, 0x0e, - 0xca, 0x92, 0xdb, 0x55, 0xb7, 0xe5, 0xf3, 0xc1, 0x2f, 0xd6, 0x66, 0x0e, 0xf6, 0xab, 0xe5, 0xa5, - 0x10, 0x8c, 0x51, 0x1a, 0x72, 0x0b, 0xc6, 0xfc, 0x8b, 0x72, 0x19, 0xbe, 0x92, 0xa9, 0x75, 0xf5, - 0x8b, 0x7a, 0x82, 0x16, 0x0e, 0xf6, 0xab, 0x63, 0xf5, 0x8b, 0x38, 0xe6, 0x5f, 0x64, 0xdb, 0x47, - 0xcb, 0x0e, 0xf8, 0xe4, 0xc9, 0xba, 0x7d, 0xac, 0xd9, 0x81, 0x66, 0xcd, 0xb7, 0x8f, 0x35, 0x3b, - 0x40, 0xc6, 0x95, 0x6d, 0x1f, 0xed, 0x20, 0xe8, 0xf1, 0xc9, 0x97, 0x75, 0xfb, 0xb8, 0xbc, 0xb5, - 0xb5, 0xa9, 0xd9, 0xf3, 0xd9, 0xcd, 0x20, 0xc8, 0x19, 0x93, 0xf7, 0x58, 0x4f, 0x0a, 0x9c, 0xeb, - 0xed, 0xc9, 0x59, 0x7b, 0x79, 0xa4, 0x59, 0xeb, 0x7a, 0x7b, 0x5a, 0x9c, 0x1c, 0x13, 0x8d, 0xc0, - 0xa8, 0x34, 0xde, 0x3a, 0xab, 0xe9, 0xf3, 0x49, 0x9a, 0xb9, 0x75, 0x2b, 0xab, 0xf5, 0x44, 0xeb, - 0x56, 0x56, 0xeb, 0xc8, 0x19, 0xb3, 0xb1, 0xf1, 0xcc, 0x5d, 0x39, 0xa7, 0xb3, 0x8d, 0x0d, 0x9a, - 0xbb, 0xf1, 0xb1, 0x41, 0x73, 0x17, 0x19, 0x57, 0xc6, 0xdc, 0xf5, 0x7d, 0x3e, 0x85, 0xb3, 0x32, - 0xdf, 0xa8, 0xd7, 0xe3, 0xcc, 0x37, 0xea, 0x75, 0x64, 0x5c, 0xf9, 0xac, 0x6a, 0xf8, 0x95, 0xd2, - 0x28, 0xb3, 0x6a, 0x39, 0xc1, 0x7c, 0x6d, 0xb9, 0x8e, 0x8c, 0xab, 0xd1, 0x82, 0x93, 0x0a, 0x83, - 0xb4, 0xe7, 0xfa, 0x36, 0x1f, 0x1a, 0xda, 0x24, 0x8b, 0x50, 0x6a, 0xb8, 0x4e, 0xd3, 0x6e, 0x5d, - 0x33, 0x7b, 0x72, 0x4b, 0xd5, 0x7b, 0xf1, 0xb2, 0x42, 0x60, 0x48, 0x43, 0x9e, 0x84, 0xf1, 0x1d, - 0xba, 0x27, 0xf7, 0xd6, 0xb2, 0x24, 0x1d, 0xbf, 0x42, 0xf7, 0x90, 0xc1, 0x8d, 0xef, 0xe5, 0xe0, - 0x78, 0xca, 0xb4, 0x60, 0xc5, 0xfa, 0x5e, 0x47, 0x4a, 0xd0, 0xc5, 0x6e, 0xe0, 0x55, 0x64, 0x70, - 0xf2, 0xf5, 0x1c, 0xcc, 0x44, 0xe6, 0xc9, 0x52, 0x5f, 0x6e, 0xdf, 0xd9, 0xf7, 0xa5, 0x18, 0xaf, - 0xda, 0x69, 0x29, 0x71, 0x26, 0x81, 0xc0, 0xa4, 0x54, 0xe3, 0x9f, 0xb8, 0xbe, 0x10, 0x83, 0x11, - 0x13, 0x8e, 0xf5, 0x7d, 0xea, 0xb1, 0xc3, 0xa5, 0x4e, 0x1b, 0x1e, 0x0d, 0xa4, 0xea, 0xf0, 0xf4, - 0x82, 0x50, 0x5e, 0x58, 0x2d, 0x16, 0x98, 0xaa, 0xb6, 0x70, 0xe7, 0xb9, 0x05, 0x41, 0x71, 0x85, - 0xee, 0xd5, 0x69, 0x87, 0x32, 0x1e, 0x35, 0x72, 0xb0, 0x5f, 0x3d, 0x76, 0x23, 0xc6, 0x00, 0x13, - 0x0c, 0x99, 0x88, 0x9e, 0xe9, 0xfb, 0xbb, 0xae, 0x67, 0x49, 0x11, 0x63, 0x0f, 0x2c, 0x62, 0x33, - 0xc6, 0x00, 0x13, 0x0c, 0x8d, 0xbf, 0xce, 0xc1, 0x64, 0xcd, 0x6c, 0xec, 0xb8, 0xcd, 0x26, 0xdb, - 0x91, 0xad, 0xbe, 0x27, 0xce, 0x2d, 0x31, 0x26, 0x7a, 0x47, 0x5e, 0x91, 0x70, 0xd4, 0x14, 0x64, - 0x0b, 0x0a, 0xa2, 0x3b, 0x64, 0xa5, 0x3e, 0x1d, 0xa9, 0x94, 0x56, 0xda, 0xf8, 0x70, 0x30, 0xa5, - 0x6d, 0x41, 0x28, 0x6d, 0x0b, 0xeb, 0x4e, 0xb0, 0xc1, 0x94, 0x24, 0xdb, 0x69, 0xd5, 0xe0, 0x60, - 0xbf, 0x5a, 0x58, 0xe5, 0x3c, 0x50, 0xf2, 0x22, 0xcf, 0x43, 0xb9, 0x6b, 0xbe, 0xab, 0xc4, 0xf1, - 0xed, 0xb4, 0x54, 0x3b, 0x2e, 0xab, 0x51, 0xbe, 0x16, 0xa2, 0x30, 0x4a, 0x67, 0xbc, 0x05, 0xf9, - 0x65, 0xb3, 0xd1, 0xa6, 0xe4, 0x46, 0x72, 0xea, 0x96, 0x2f, 0x9c, 0x4f, 0xeb, 0x2d, 0x3d, 0x8d, - 0xa3, 0x1d, 0x36, 0x3d, 0x6c, 0x82, 0x1b, 0x1f, 0xe5, 0xe0, 0xf4, 0x72, 0xa7, 0xef, 0x07, 0xd4, - 0xbb, 0x25, 0xe7, 0xd5, 0x16, 0xed, 0xf6, 0x3a, 0x66, 0x40, 0xc9, 0xff, 0x83, 0x22, 0x53, 0x98, - 0x2d, 0x33, 0x30, 0xa5, 0xc4, 0xe1, 0x5d, 0xc1, 0x67, 0x26, 0xa3, 0x66, 0x75, 0xd8, 0xd8, 0xbe, - 0x4d, 0x1b, 0xc1, 0x35, 0x1a, 0x98, 0xe1, 0xc9, 0x1c, 0xc2, 0x50, 0x73, 0x25, 0x3b, 0x30, 0xe1, - 0xf7, 0x68, 0x43, 0x76, 0xf4, 0x7a, 0xa6, 0xc9, 0x9f, 0xac, 0x76, 0xbd, 0x47, 0x1b, 0xa1, 0x1a, - 0xc3, 0xbe, 0x90, 0x0b, 0x31, 0xfe, 0x3d, 0x07, 0x4f, 0x0c, 0x69, 0xea, 0x55, 0xdb, 0x0f, 0xc8, - 0x9b, 0x03, 0xcd, 0x5d, 0x38, 0x5c, 0x73, 0x59, 0x69, 0xde, 0x58, 0x3d, 0xab, 0x14, 0x24, 0xd2, - 0xd4, 0x77, 0x20, 0x6f, 0x07, 0xb4, 0xab, 0x34, 0xc8, 0xab, 0x99, 0xda, 0x3a, 0xa4, 0xfa, 0xb5, - 0x69, 0x29, 0x38, 0xbf, 0xce, 0x44, 0xa0, 0x90, 0x64, 0xfc, 0x5d, 0x0e, 0xd8, 0xa0, 0x5b, 0xb6, - 0xd4, 0x29, 0x26, 0x82, 0xbd, 0x9e, 0xd2, 0x24, 0x9f, 0x54, 0x1d, 0xb4, 0xb5, 0xd7, 0xa3, 0x77, - 0xf7, 0xab, 0xd3, 0x9a, 0x90, 0x01, 0x90, 0x93, 0x92, 0xb7, 0xa0, 0xe0, 0x07, 0x66, 0xd0, 0xf7, - 0xe5, 0x06, 0xb8, 0x2a, 0x0b, 0x15, 0xea, 0x1c, 0x7a, 0x77, 0xbf, 0x7a, 0x28, 0x73, 0x6b, 0x41, - 0xf3, 0x16, 0xe5, 0x50, 0x72, 0x25, 0xcf, 0xc2, 0x64, 0x97, 0xfa, 0xbe, 0xd9, 0xa2, 0x72, 0x3d, - 0xcc, 0x48, 0x01, 0x93, 0xd7, 0x04, 0x18, 0x15, 0xde, 0xf8, 0x02, 0xc0, 0xb2, 0xeb, 0x04, 0xb6, - 0xd3, 0xa7, 0x1b, 0x0e, 0x79, 0x0a, 0xf2, 0xd4, 0xf3, 0x5c, 0x4f, 0x6a, 0x46, 0xba, 0xf9, 0x97, - 0x18, 0x10, 0x05, 0x8e, 0x3c, 0xc3, 0xd6, 0xb1, 0xdd, 0xa1, 0x16, 0xaf, 0x7d, 0xb1, 0x76, 0x4c, - 0xd5, 0x7e, 0x95, 0x43, 0x51, 0x62, 0x8d, 0x05, 0x98, 0x5c, 0x66, 0xd6, 0x15, 0xf5, 0x18, 0xdf, - 0xd0, 0xbe, 0x2a, 0x85, 0x7c, 0x63, 0x36, 0xd6, 0x0f, 0xc6, 0x60, 0x6a, 0xd9, 0x73, 0x1d, 0x35, - 0x0a, 0x8f, 0x60, 0x9d, 0xb4, 0x62, 0xeb, 0x24, 0x9b, 0xd2, 0x1d, 0xad, 0xf2, 0xb0, 0x35, 0x42, - 0x5c, 0x3d, 0xe2, 0x42, 0xdf, 0x5b, 0x1b, 0x5d, 0x14, 0x67, 0x17, 0x76, 0x7e, 0x7c, 0x0a, 0x18, - 0x3f, 0xca, 0xc1, 0x6c, 0x94, 0xfc, 0x11, 0xac, 0xc4, 0x66, 0x7c, 0x25, 0x2e, 0x8d, 0xdc, 0xc4, - 0x21, 0xcb, 0xef, 0x3f, 0xf3, 0xf1, 0xa6, 0xb1, 0x6e, 0x66, 0xb6, 0xd4, 0xd4, 0x6e, 0x04, 0x20, - 0xdb, 0xb7, 0x34, 0xd2, 0xd6, 0xc7, 0x87, 0xf3, 0xe3, 0xb2, 0x12, 0x53, 0x51, 0xe8, 0xdd, 0xc4, - 0x37, 0xc6, 0x84, 0xb3, 0x83, 0xd1, 0x6f, 0xb4, 0xa9, 0xd5, 0xef, 0x50, 0xb9, 0xc4, 0x75, 0xc7, - 0xd5, 0x25, 0x1c, 0x35, 0x05, 0x79, 0x13, 0xe6, 0x1a, 0xae, 0xd3, 0xe8, 0x7b, 0x1e, 0x75, 0x1a, - 0x7b, 0x9b, 0xdc, 0x11, 0x23, 0x17, 0xee, 0x82, 0x2c, 0x36, 0xb7, 0x9c, 0x24, 0xb8, 0x9b, 0x06, - 0xc4, 0x41, 0x46, 0x6c, 0x33, 0xf0, 0xfb, 0x7e, 0x8f, 0x3a, 0x16, 0xb7, 0x06, 0x8a, 0xe1, 0x66, - 0x50, 0x17, 0x60, 0x54, 0x78, 0x72, 0x03, 0x4e, 0xfb, 0x01, 0x53, 0x65, 0x9c, 0xd6, 0x0a, 0x35, - 0xad, 0x8e, 0xed, 0x30, 0xc5, 0xc2, 0x75, 0x2c, 0x9f, 0x2b, 0xf8, 0xe3, 0xb5, 0x27, 0x0e, 0xf6, - 0xab, 0xa7, 0xeb, 0xe9, 0x24, 0x38, 0xac, 0x2c, 0x79, 0x0b, 0xe6, 0xfd, 0x7e, 0xa3, 0x41, 0x7d, - 0xbf, 0xd9, 0xef, 0xbc, 0xe6, 0x6e, 0xfb, 0x97, 0x6d, 0x9f, 0x69, 0x45, 0x57, 0xed, 0xae, 0x1d, - 0x70, 0x25, 0x3e, 0x5f, 0x3b, 0x7b, 0xb0, 0x5f, 0x9d, 0xaf, 0x0f, 0xa5, 0xc2, 0x7b, 0x70, 0x20, - 0x08, 0xa7, 0xc4, 0x96, 0x33, 0xc0, 0x7b, 0x92, 0xf3, 0x9e, 0x3f, 0xd8, 0xaf, 0x9e, 0x5a, 0x4d, - 0xa5, 0xc0, 0x21, 0x25, 0xd9, 0x08, 0x06, 0x76, 0x97, 0x7e, 0xc9, 0x75, 0x28, 0xd7, 0xd4, 0x23, - 0x23, 0xb8, 0x25, 0xe1, 0xa8, 0x29, 0xc8, 0xed, 0x70, 0xf2, 0xb1, 0x45, 0x21, 0xd5, 0xef, 0x07, - 0xdf, 0xad, 0x4e, 0x30, 0x5b, 0xfd, 0x56, 0x84, 0x13, 0x5b, 0x58, 0x18, 0xe3, 0x6d, 0xfc, 0xed, - 0x18, 0x90, 0xc1, 0x8d, 0x80, 0x5c, 0x81, 0x82, 0xd9, 0x08, 0x98, 0x25, 0x2e, 0xbc, 0x37, 0x4f, - 0xa5, 0x29, 0x31, 0x42, 0x14, 0xd2, 0x26, 0x65, 0x33, 0x84, 0x86, 0xbb, 0xc7, 0x12, 0x2f, 0x8a, - 0x92, 0x05, 0x71, 0x61, 0xae, 0x63, 0xfa, 0x81, 0x9a, 0xab, 0x16, 0x6b, 0xb2, 0xdc, 0x24, 0xff, - 0xd7, 0xe1, 0x1a, 0xc5, 0x4a, 0xd4, 0x4e, 0xb2, 0x99, 0x7b, 0x35, 0xc9, 0x08, 0x07, 0x79, 0x13, - 0x0f, 0xa0, 0xa1, 0x0e, 0x33, 0xb6, 0x47, 0x66, 0xf7, 0x3f, 0xe9, 0x33, 0x31, 0xdc, 0xfa, 0x35, - 0xc8, 0xc7, 0x88, 0x14, 0xe3, 0xdf, 0x0a, 0x30, 0xb9, 0xb2, 0xb4, 0xb6, 0x65, 0xfa, 0x3b, 0x87, - 0x70, 0x07, 0xb1, 0x09, 0x21, 0xd5, 0x82, 0xe4, 0x92, 0x56, 0xea, 0x02, 0x6a, 0x0a, 0xe2, 0x42, - 0xc9, 0x54, 0xce, 0x35, 0xb9, 0xe5, 0xbf, 0x9c, 0xd1, 0x04, 0x91, 0x5c, 0xa2, 0xce, 0x2d, 0x09, - 0xc2, 0x50, 0x06, 0xf1, 0xa1, 0xac, 0x84, 0x23, 0x6d, 0x4a, 0xbb, 0x3f, 0xa3, 0x53, 0x32, 0xe4, - 0x23, 0xec, 0xf0, 0x08, 0x00, 0xa3, 0x52, 0xc8, 0x67, 0x60, 0xca, 0xa2, 0x6c, 0xe7, 0xa0, 0x4e, - 0xc3, 0xa6, 0x6c, 0x93, 0x18, 0x67, 0xfd, 0xc2, 0x36, 0xcb, 0x95, 0x08, 0x1c, 0x63, 0x54, 0xe4, - 0x36, 0x94, 0x76, 0xed, 0xa0, 0xcd, 0xf7, 0xf4, 0x4a, 0x81, 0x0f, 0xf5, 0x67, 0x33, 0x55, 0x94, - 0x71, 0x08, 0xbb, 0xe5, 0x96, 0xe2, 0x89, 0x21, 0x7b, 0x66, 0x98, 0xb2, 0x0f, 0xee, 0x81, 0xe4, - 0xbb, 0x41, 0x29, 0x5e, 0x80, 0x23, 0x30, 0xa4, 0x21, 0x3e, 0x4c, 0xb1, 0x8f, 0x3a, 0x7d, 0xa7, - 0xcf, 0x56, 0x88, 0xb4, 0xd2, 0xb3, 0xf9, 0x25, 0x15, 0x13, 0xd1, 0x23, 0xb7, 0x22, 0x6c, 0x31, - 0x26, 0x84, 0xcd, 0xbe, 0xdd, 0x36, 0x75, 0xf8, 0xb6, 0x11, 0x99, 0x7d, 0xb7, 0xda, 0xd4, 0x41, - 0x8e, 0x21, 0x2e, 0x5f, 0x1f, 0x52, 0x4d, 0xab, 0xc0, 0x08, 0xde, 0xa8, 0x50, 0xdb, 0xab, 0x1d, - 0x93, 0x8b, 0x43, 0x7e, 0x63, 0x44, 0x04, 0x53, 0xf2, 0x5c, 0xe7, 0xd2, 0xbb, 0x76, 0x50, 0x29, - 0xf3, 0x4a, 0xe9, 0x9d, 0x62, 0x83, 0x43, 0x51, 0x62, 0xd9, 0xe9, 0x22, 0x06, 0xd7, 0xaf, 0x4c, - 0xc5, 0x55, 0x4d, 0x31, 0x03, 0x7c, 0x54, 0x78, 0xe3, 0xaf, 0x72, 0x50, 0x66, 0xeb, 0x4d, 0xad, - 0x91, 0x67, 0xa0, 0x10, 0x98, 0x5e, 0x4b, 0xda, 0xc1, 0x11, 0x11, 0x5b, 0x1c, 0x8a, 0x12, 0x4b, - 0x4c, 0xc8, 0x07, 0xa6, 0xbf, 0xa3, 0xf4, 0x8a, 0xcf, 0x67, 0x6a, 0xb6, 0x5c, 0xe8, 0xa1, 0x4a, - 0xc1, 0xbe, 0x7c, 0x14, 0x9c, 0xc9, 0x79, 0x28, 0xb2, 0x73, 0x60, 0xd5, 0xf4, 0x85, 0x43, 0xae, - 0x58, 0x9b, 0x62, 0x0b, 0x7b, 0x55, 0xc2, 0x50, 0x63, 0x8d, 0xe7, 0x21, 0x7f, 0xe9, 0x0e, 0x75, - 0xf8, 0x01, 0xe1, 0x4b, 0x33, 0x30, 0x69, 0xfb, 0x2a, 0xf3, 0x10, 0x35, 0x85, 0xf1, 0x26, 0x1c, - 0xbb, 0xf4, 0x2e, 0x6d, 0xf4, 0x03, 0xd7, 0x13, 0xe6, 0x22, 0x79, 0x0d, 0x88, 0x4f, 0xbd, 0x3b, - 0x76, 0x83, 0x2e, 0x35, 0x1a, 0x4c, 0x4d, 0xbe, 0x1e, 0xee, 0x3f, 0xf3, 0x92, 0x13, 0xa9, 0x0f, - 0x50, 0x60, 0x4a, 0x29, 0xe3, 0x0f, 0x73, 0x50, 0x8e, 0x78, 0x6d, 0xd8, 0xee, 0xd3, 0x5a, 0xae, - 0xd7, 0xfa, 0x8d, 0x1d, 0xed, 0x64, 0x78, 0x39, 0xab, 0x2b, 0x48, 0x70, 0x09, 0x57, 0x8d, 0x06, - 0x61, 0x28, 0xe3, 0x7e, 0xee, 0x9c, 0xbf, 0xc8, 0x41, 0x58, 0x8e, 0x8d, 0xfb, 0x76, 0x58, 0xb5, - 0xc8, 0xb8, 0x4b, 0xbe, 0x12, 0x4b, 0xde, 0xcf, 0xc1, 0xe9, 0x78, 0x63, 0xb9, 0xe9, 0xfd, 0xe0, - 0x6e, 0x8d, 0xaa, 0x14, 0x70, 0xba, 0x9e, 0xce, 0x0d, 0x87, 0x89, 0x31, 0x6e, 0x42, 0x7e, 0xcd, - 0xec, 0xb7, 0xe8, 0xa1, 0x0c, 0x18, 0x36, 0x8b, 0x3c, 0x6a, 0x76, 0x02, 0x75, 0x58, 0xca, 0x59, - 0x84, 0x12, 0x86, 0x1a, 0x6b, 0xfc, 0xd9, 0x04, 0x94, 0x23, 0xce, 0x5b, 0xb6, 0x01, 0x78, 0xb4, - 0xe7, 0x26, 0x8f, 0x1f, 0xa4, 0x3d, 0x17, 0x39, 0x86, 0x4d, 0x37, 0x8f, 0xde, 0xb1, 0x7d, 0xdb, - 0x75, 0x92, 0xc7, 0x0f, 0x4a, 0x38, 0x6a, 0x0a, 0x52, 0x85, 0xbc, 0x45, 0x7b, 0x41, 0x9b, 0x4f, - 0xe6, 0x09, 0x11, 0xcf, 0x5a, 0x61, 0x00, 0x14, 0x70, 0x46, 0xd0, 0xa4, 0x41, 0xa3, 0x5d, 0x99, - 0xe0, 0x5b, 0x36, 0x27, 0x58, 0x65, 0x00, 0x14, 0xf0, 0x14, 0x67, 0x55, 0xfe, 0xe1, 0x3b, 0xab, - 0x0a, 0x47, 0xec, 0xac, 0x22, 0x3d, 0x38, 0xee, 0xfb, 0xed, 0x4d, 0xcf, 0xbe, 0x63, 0x06, 0x34, - 0x9c, 0x3d, 0x93, 0x0f, 0x22, 0xe7, 0xf4, 0xc1, 0x7e, 0xf5, 0x78, 0xbd, 0x7e, 0x39, 0xc9, 0x05, - 0xd3, 0x58, 0x93, 0x3a, 0x9c, 0xb4, 0x1d, 0x9f, 0x36, 0xfa, 0x1e, 0x5d, 0x6f, 0x39, 0xae, 0x47, - 0x2f, 0xbb, 0x3e, 0x63, 0x27, 0x23, 0x16, 0xca, 0x3d, 0x70, 0x72, 0x3d, 0x8d, 0x08, 0xd3, 0xcb, - 0x1a, 0x3f, 0xc8, 0xc1, 0x54, 0xd4, 0x5f, 0x4d, 0x7c, 0x80, 0xf6, 0xca, 0x6a, 0x5d, 0x6c, 0x25, - 0x72, 0x85, 0xbf, 0x92, 0xd9, 0x0d, 0x2e, 0xd8, 0x84, 0xfa, 0x52, 0x08, 0xc3, 0x88, 0x98, 0x43, - 0x04, 0xc4, 0x9e, 0x82, 0x7c, 0xd3, 0xf5, 0x1a, 0x54, 0xee, 0xa1, 0x7a, 0x95, 0xac, 0x32, 0x20, - 0x0a, 0x9c, 0xf1, 0x51, 0x0e, 0x22, 0x12, 0xc8, 0x6f, 0xc0, 0x34, 0x93, 0x71, 0xc5, 0xdb, 0x8e, - 0xb5, 0xa6, 0x96, 0xb9, 0x35, 0x9a, 0x53, 0xed, 0xa4, 0x94, 0x3f, 0x1d, 0x03, 0x63, 0x5c, 0x1e, - 0xf9, 0x04, 0x94, 0x4c, 0xcb, 0xf2, 0xa8, 0xef, 0x53, 0x71, 0xc4, 0x94, 0x84, 0x5b, 0x6f, 0x49, - 0x01, 0x31, 0xc4, 0xb3, 0x65, 0xd8, 0xb6, 0x9a, 0x3e, 0x9b, 0xd9, 0xd2, 0x42, 0xd3, 0xcb, 0x90, - 0x09, 0x61, 0x70, 0xd4, 0x14, 0xc6, 0xb7, 0x27, 0x20, 0x2e, 0x9b, 0x58, 0x30, 0xb3, 0xe3, 0x6d, - 0x2f, 0x73, 0xd7, 0x63, 0x16, 0x27, 0xf0, 0xf1, 0x83, 0xfd, 0xea, 0xcc, 0x95, 0x38, 0x07, 0x4c, - 0xb2, 0x94, 0x52, 0xae, 0xd0, 0xbd, 0xc0, 0xdc, 0xce, 0xb2, 0x61, 0x2a, 0x29, 0x51, 0x0e, 0x98, - 0x64, 0x49, 0x9e, 0x87, 0xf2, 0x8e, 0xb7, 0xad, 0x16, 0x79, 0xd2, 0xf3, 0x7a, 0x25, 0x44, 0x61, - 0x94, 0x8e, 0x75, 0xe1, 0x8e, 0xb7, 0xcd, 0x36, 0x45, 0x15, 0x1b, 0xd5, 0x5d, 0x78, 0x45, 0xc2, - 0x51, 0x53, 0x90, 0x1e, 0x90, 0x1d, 0xd5, 0x7b, 0xda, 0xd1, 0x2a, 0xf7, 0xa2, 0xc3, 0xfb, 0x69, - 0x4f, 0xb1, 0xc3, 0xf4, 0xca, 0x00, 0x1f, 0x4c, 0xe1, 0x4d, 0xbe, 0x00, 0xa7, 0x77, 0xbc, 0x6d, - 0x79, 0x54, 0x6c, 0x7a, 0xb6, 0xd3, 0xb0, 0x7b, 0xb1, 0xa0, 0xa8, 0x3e, 0x4e, 0xae, 0xa4, 0x93, - 0xe1, 0xb0, 0xf2, 0xc6, 0xa7, 0x60, 0x2a, 0x1a, 0x54, 0xbb, 0x4f, 0x38, 0xc3, 0xf8, 0x20, 0x07, - 0x25, 0x6e, 0x94, 0xb6, 0x98, 0x66, 0xaa, 0x8f, 0xa0, 0xf1, 0x7b, 0x1c, 0x41, 0x4d, 0x98, 0x14, - 0xa7, 0xa7, 0xcf, 0x77, 0xf6, 0xf2, 0x85, 0x17, 0xb3, 0x59, 0x1d, 0x3c, 0x2d, 0x22, 0xd4, 0xe5, - 0xc4, 0xc9, 0xec, 0xa3, 0x62, 0x6e, 0x7c, 0x02, 0xca, 0x97, 0xdd, 0x8e, 0x45, 0x3d, 0xd6, 0x2e, - 0x9f, 0x9c, 0xd1, 0xe6, 0x13, 0x5b, 0x3e, 0xc5, 0xb8, 0xe9, 0x64, 0xfc, 0x6b, 0x0e, 0x0a, 0xeb, - 0x4e, 0xaf, 0xff, 0x2b, 0x92, 0x67, 0x70, 0x0d, 0x26, 0x98, 0xf1, 0x41, 0x5e, 0x8c, 0x27, 0x95, - 0x3c, 0xad, 0x07, 0xeb, 0xee, 0x7e, 0xb5, 0x42, 0x9d, 0x86, 0x6b, 0xd9, 0x4e, 0x6b, 0xf1, 0xb6, - 0xef, 0x3a, 0x0b, 0x68, 0xee, 0x2a, 0xcf, 0xac, 0x28, 0xf3, 0xb9, 0xe2, 0x07, 0x7f, 0x54, 0x7d, - 0xec, 0xfd, 0x1f, 0x9f, 0x7b, 0xcc, 0xe8, 0xc0, 0xc4, 0x55, 0xdb, 0x39, 0x8c, 0x89, 0xfa, 0x14, - 0xe4, 0xfd, 0x86, 0xdb, 0x53, 0xf6, 0xa9, 0x9e, 0x21, 0x75, 0x06, 0x44, 0x81, 0x53, 0x73, 0x6e, - 0x7c, 0xc8, 0x9c, 0xfb, 0x6a, 0x0e, 0xe6, 0xae, 0xd1, 0xae, 0x6b, 0x7f, 0xc9, 0x0c, 0x1d, 0xcb, - 0xac, 0x50, 0xdb, 0x0e, 0xa4, 0x57, 0x58, 0x17, 0xba, 0x6c, 0x07, 0xc8, 0xe0, 0xf7, 0x51, 0xff, - 0x78, 0x74, 0x90, 0xed, 0x4e, 0xd7, 0xc3, 0x6d, 0x22, 0x8c, 0x0e, 0x2a, 0x04, 0x86, 0x34, 0xc6, - 0xd7, 0x72, 0x30, 0x29, 0x2a, 0x41, 0x15, 0xef, 0xdc, 0x10, 0xde, 0x6f, 0x40, 0x9e, 0x97, 0x93, - 0x1b, 0xdc, 0xe7, 0xb2, 0xd9, 0x44, 0x8c, 0x83, 0x50, 0x82, 0xf8, 0x4f, 0x14, 0x3c, 0x8d, 0xf7, - 0xc7, 0xa1, 0xa8, 0xbc, 0x30, 0xe4, 0x6b, 0x39, 0x28, 0x9b, 0x8e, 0xe3, 0x06, 0xa6, 0x70, 0x52, - 0x88, 0xc9, 0x7b, 0x3d, 0x93, 0x40, 0xc5, 0x74, 0x61, 0x29, 0x64, 0x78, 0xc9, 0x09, 0xbc, 0xbd, - 0x70, 0xff, 0x8c, 0x60, 0x30, 0x2a, 0x97, 0xbc, 0x03, 0x85, 0x8e, 0xb9, 0x4d, 0x3b, 0x6a, 0x2e, - 0xaf, 0x8f, 0x56, 0x83, 0xab, 0x9c, 0x97, 0x10, 0xae, 0x35, 0x71, 0x01, 0x44, 0x29, 0x68, 0xfe, - 0x65, 0x98, 0x4d, 0x56, 0x94, 0xcc, 0x46, 0xc6, 0x45, 0x0c, 0xc5, 0x09, 0x35, 0xdf, 0xf9, 0x3c, - 0x50, 0x13, 0x79, 0xec, 0x85, 0xdc, 0xfc, 0x67, 0xa1, 0x1c, 0x11, 0xf3, 0x20, 0x45, 0x8d, 0xd7, - 0xa1, 0x7c, 0x8d, 0x06, 0x9e, 0xdd, 0xe0, 0x0c, 0xee, 0x37, 0x1b, 0x9e, 0x8a, 0xf1, 0x19, 0x12, - 0x67, 0xf8, 0x12, 0x9b, 0x5c, 0x8c, 0xa5, 0xcf, 0xcc, 0xea, 0x9e, 0xe7, 0x76, 0x69, 0xd0, 0xa6, - 0x7d, 0x35, 0xa2, 0xd9, 0xf4, 0xa8, 0x4d, 0xcd, 0x46, 0x98, 0xd5, 0xe1, 0x37, 0x46, 0x44, 0x18, - 0xbf, 0x98, 0x06, 0xb8, 0xee, 0x5a, 0x54, 0xae, 0xab, 0x79, 0x18, 0xb3, 0x2d, 0xd9, 0x1a, 0x90, - 0x95, 0x1d, 0x5b, 0x5f, 0xc1, 0x31, 0xdb, 0xd2, 0xeb, 0x7d, 0x6c, 0xe8, 0x7a, 0x7f, 0x1e, 0xca, - 0x96, 0xed, 0xf7, 0x3a, 0xe6, 0xde, 0xf5, 0x94, 0x03, 0x78, 0x25, 0x44, 0x61, 0x94, 0x8e, 0x7c, - 0x52, 0x06, 0xac, 0xc4, 0xe1, 0x5b, 0x49, 0x04, 0xac, 0x8a, 0xac, 0x7a, 0x91, 0x58, 0xd5, 0x0b, - 0x30, 0xa5, 0x5c, 0x3e, 0x5c, 0x4a, 0x9e, 0x97, 0x3a, 0xa1, 0x9c, 0xe2, 0x5b, 0x11, 0x1c, 0xc6, - 0x28, 0x93, 0x2e, 0xa9, 0xc2, 0x23, 0x71, 0x49, 0xad, 0xc0, 0xac, 0x1f, 0xb8, 0x1e, 0xb5, 0x14, - 0xc5, 0xfa, 0x4a, 0x85, 0xc4, 0x1a, 0x3a, 0x5b, 0x4f, 0xe0, 0x71, 0xa0, 0x04, 0xd9, 0x84, 0x13, - 0xbb, 0x89, 0x58, 0x20, 0x6f, 0xfc, 0x71, 0xce, 0xe9, 0x8c, 0xe4, 0x74, 0xe2, 0x56, 0x0a, 0x0d, - 0xa6, 0x96, 0x24, 0x2f, 0xc2, 0xb4, 0xaa, 0x26, 0xdf, 0x8e, 0x2b, 0x27, 0x38, 0x2b, 0xad, 0xa2, - 0x6e, 0x45, 0x91, 0x18, 0xa7, 0x25, 0x9f, 0x86, 0x7c, 0xaf, 0x6d, 0xfa, 0x54, 0x7a, 0xb0, 0x94, - 0x7b, 0x20, 0xbf, 0xc9, 0x80, 0x77, 0xf7, 0xab, 0x25, 0x36, 0x66, 0xfc, 0x03, 0x05, 0x21, 0xb9, - 0x00, 0xb0, 0xed, 0xf6, 0x1d, 0xcb, 0xf4, 0xf6, 0xd6, 0x57, 0xa4, 0x03, 0x5b, 0x9f, 0x93, 0x35, - 0x8d, 0xc1, 0x08, 0x55, 0x34, 0x6a, 0x58, 0xba, 0x77, 0xd4, 0x90, 0xbc, 0x01, 0x25, 0xee, 0xec, - 0xa7, 0xd6, 0x52, 0x20, 0xbd, 0x51, 0x0f, 0xe2, 0x17, 0xd6, 0xbb, 0x7f, 0x5d, 0x31, 0xc1, 0x90, - 0x1f, 0x79, 0x0b, 0xa0, 0x69, 0x3b, 0xb6, 0xdf, 0xe6, 0xdc, 0xcb, 0x0f, 0xcc, 0x5d, 0xb7, 0x73, - 0x55, 0x73, 0xc1, 0x08, 0x47, 0xf2, 0xb3, 0x1c, 0xcc, 0x79, 0xd4, 0x77, 0xfb, 0x5e, 0x83, 0xfa, - 0x3a, 0x71, 0xe0, 0x24, 0x5f, 0xfc, 0x37, 0x33, 0x26, 0x5a, 0xaa, 0x15, 0xbd, 0x80, 0x49, 0xc6, - 0x62, 0x67, 0xa5, 0x2a, 0x8e, 0x33, 0x80, 0xbf, 0x9b, 0x06, 0xfc, 0xea, 0x4f, 0xaa, 0xd5, 0xc1, - 0xfc, 0x5d, 0xcd, 0x9c, 0xcd, 0xa8, 0x6f, 0xfe, 0xa4, 0x3a, 0xab, 0xbe, 0x75, 0x8a, 0xc3, 0x60, - 0xbb, 0xd8, 0x96, 0xd8, 0x73, 0xad, 0xf5, 0x4d, 0xe9, 0x9e, 0xd3, 0x5b, 0xe2, 0x26, 0x03, 0xa2, - 0xc0, 0x91, 0xf3, 0x50, 0xb4, 0x4c, 0xda, 0x75, 0x1d, 0x6a, 0x55, 0xa6, 0x43, 0xcf, 0xc5, 0x8a, - 0x84, 0xa1, 0xc6, 0x92, 0xb7, 0xa1, 0x60, 0x73, 0x55, 0xae, 0x72, 0x8c, 0x0f, 0x4c, 0x36, 0xfd, - 0x52, 0x68, 0x83, 0x22, 0x9f, 0x43, 0xfc, 0x46, 0xc9, 0x96, 0x34, 0x60, 0xd2, 0xed, 0x07, 0x5c, - 0xc2, 0x0c, 0x97, 0x90, 0xcd, 0xdf, 0xb7, 0x21, 0x78, 0x88, 0x54, 0x42, 0xf9, 0x81, 0x8a, 0x33, - 0x6b, 0x6f, 0xa3, 0x6d, 0x77, 0x2c, 0x8f, 0x3a, 0x95, 0x59, 0xae, 0xb3, 0xf2, 0xf6, 0x2e, 0x4b, - 0x18, 0x6a, 0x2c, 0xf9, 0x3f, 0x30, 0xed, 0xf6, 0x03, 0xbe, 0x4a, 0xd8, 0x28, 0xfb, 0x95, 0x39, - 0x4e, 0x3e, 0xc7, 0xd6, 0xec, 0x46, 0x14, 0x81, 0x71, 0x3a, 0xb6, 0x6f, 0xb6, 0x5d, 0x3f, 0x60, - 0x1f, 0x7c, 0xeb, 0x38, 0x15, 0xdf, 0x37, 0x2f, 0x47, 0x70, 0x18, 0xa3, 0x24, 0xdf, 0xca, 0xc1, - 0x5c, 0x37, 0xa9, 0x82, 0x55, 0x4e, 0xf3, 0xce, 0x58, 0xcd, 0x78, 0xd8, 0x27, 0xb8, 0x89, 0xc8, - 0xcc, 0x00, 0x18, 0x07, 0xe5, 0xce, 0xaf, 0xc0, 0xa9, 0xf4, 0x39, 0x7d, 0xbf, 0x63, 0x7c, 0x3c, - 0x7a, 0x8c, 0x1f, 0x83, 0xa9, 0x68, 0x36, 0x32, 0xf7, 0x58, 0x46, 0x92, 0xd8, 0x88, 0x0b, 0x25, - 0xb7, 0x7e, 0x14, 0x1e, 0xcb, 0x8d, 0xfa, 0x80, 0xc7, 0x52, 0x83, 0x30, 0x94, 0x71, 0x3f, 0x8f, - 0xe5, 0x9f, 0x8f, 0x41, 0x58, 0x8e, 0x99, 0xac, 0xd4, 0xb1, 0x7a, 0xae, 0xed, 0x04, 0x49, 0x5f, - 0xef, 0x25, 0x09, 0x47, 0x4d, 0x11, 0xf1, 0x6f, 0x8e, 0xdd, 0xd3, 0xbf, 0xd9, 0x86, 0x19, 0x93, - 0xc7, 0x34, 0x43, 0xc7, 0xd4, 0xf8, 0x03, 0x39, 0xa6, 0x74, 0x36, 0x5a, 0x9c, 0x0b, 0x26, 0xd9, - 0x32, 0x49, 0x7e, 0x58, 0x9c, 0x4b, 0x9a, 0xc8, 0x24, 0xa9, 0x1e, 0xe7, 0x82, 0x49, 0xb6, 0xc6, - 0x5f, 0x8e, 0x81, 0x5a, 0x6d, 0xbf, 0x0a, 0xb6, 0x1e, 0x31, 0xa0, 0xe0, 0x51, 0xbf, 0xdf, 0x09, - 0xa4, 0xf6, 0xc5, 0x77, 0x34, 0xe4, 0x10, 0x94, 0x18, 0xb6, 0xd9, 0xd0, 0x77, 0xed, 0x60, 0xd9, - 0xb5, 0x94, 0xce, 0xc5, 0x37, 0x9b, 0x4b, 0x12, 0x86, 0x1a, 0x6b, 0xec, 0xc2, 0x34, 0x6b, 0x57, - 0xa7, 0x43, 0x3b, 0xf5, 0x80, 0xf6, 0x7c, 0xd2, 0x84, 0xbc, 0xcf, 0x7e, 0xc8, 0xde, 0x1b, 0x31, - 0x9b, 0x21, 0xa0, 0xbd, 0x88, 0x51, 0xc8, 0xf8, 0xa2, 0x60, 0x6f, 0xdc, 0x1d, 0x83, 0x92, 0xee, - 0xd1, 0x43, 0x58, 0x9a, 0xb7, 0x60, 0xd2, 0xa2, 0x4d, 0x93, 0xb5, 0x3b, 0x6b, 0x2e, 0x5f, 0x59, - 0xc4, 0x88, 0x38, 0x13, 0x54, 0xdc, 0xc8, 0xeb, 0x51, 0x27, 0x47, 0x16, 0xb6, 0x03, 0x57, 0x37, - 0xc8, 0x0e, 0x94, 0xf8, 0x8f, 0x55, 0x95, 0x8c, 0x9f, 0x75, 0x16, 0xde, 0x54, 0x5c, 0x84, 0x7f, - 0x50, 0x7f, 0x62, 0xc8, 0x3f, 0x91, 0x44, 0x9f, 0x3f, 0x4c, 0x12, 0xbd, 0xb1, 0x0a, 0xec, 0x30, - 0x5e, 0x5b, 0x26, 0x2f, 0x41, 0xd1, 0x97, 0x1b, 0xa4, 0xec, 0xfb, 0x8f, 0xe9, 0x90, 0x92, 0x84, - 0xdf, 0xdd, 0xaf, 0x4e, 0x73, 0x62, 0x05, 0x40, 0x5d, 0xc4, 0xf8, 0xfa, 0x04, 0x44, 0xcc, 0x8e, - 0x43, 0x8c, 0xa2, 0x95, 0xb0, 0x24, 0x5f, 0xcd, 0x6a, 0x49, 0x2a, 0xf3, 0x4c, 0x4c, 0xff, 0xb8, - 0xf1, 0xc8, 0xea, 0xd1, 0xa6, 0x9d, 0x9e, 0x5c, 0x20, 0xba, 0x1e, 0x97, 0x69, 0xa7, 0x87, 0x1c, - 0xa3, 0xc3, 0x9f, 0x13, 0x43, 0xc3, 0x9f, 0x6f, 0x40, 0xbe, 0x65, 0xf6, 0x5b, 0x54, 0x3a, 0xfe, - 0xb2, 0x59, 0xf9, 0x3c, 0x92, 0x23, 0x26, 0x08, 0xff, 0x89, 0x82, 0x27, 0x9b, 0x20, 0x6d, 0xe5, - 0x65, 0x93, 0x56, 0x4a, 0xb6, 0x09, 0xa2, 0x7d, 0x75, 0x62, 0x82, 0xe8, 0x4f, 0x0c, 0xf9, 0x33, - 0xf5, 0xa6, 0x21, 0x92, 0xe2, 0x64, 0x14, 0xe2, 0xf3, 0x19, 0xa3, 0xb8, 0x9c, 0x87, 0x58, 0x45, - 0xf2, 0x03, 0x15, 0x67, 0x63, 0x11, 0xca, 0x91, 0xf4, 0x73, 0xd6, 0xbf, 0x3a, 0xe5, 0x2b, 0xd2, - 0xbf, 0x2b, 0x66, 0x60, 0x22, 0xc7, 0x18, 0xdf, 0x1d, 0x07, 0xad, 0x4c, 0x46, 0xe3, 0xb3, 0x66, - 0x23, 0x92, 0xdb, 0x1b, 0x4b, 0x16, 0x71, 0x1d, 0x94, 0x58, 0x66, 0xda, 0x74, 0xa9, 0xd7, 0xd2, - 0x87, 0xbb, 0x3c, 0xf6, 0xb4, 0x69, 0x73, 0x2d, 0x8a, 0xc4, 0x38, 0x2d, 0x3b, 0x5a, 0xbb, 0xa6, - 0x63, 0x37, 0xa9, 0x1f, 0x24, 0x1d, 0xea, 0xd7, 0x24, 0x1c, 0x35, 0x05, 0x59, 0x83, 0x39, 0x9f, - 0x06, 0x1b, 0xbb, 0x0e, 0xf5, 0x74, 0x12, 0x8b, 0xcc, 0x6a, 0x7a, 0x5c, 0x69, 0xd8, 0xf5, 0x24, - 0x01, 0x0e, 0x96, 0xe1, 0x66, 0xa2, 0x48, 0x28, 0xd2, 0xc9, 0x21, 0x72, 0xb5, 0x86, 0x66, 0x62, - 0x02, 0x8f, 0x03, 0x25, 0x18, 0x97, 0xa6, 0x69, 0x77, 0xfa, 0x1e, 0x0d, 0xb9, 0x14, 0xe2, 0x5c, - 0x56, 0x13, 0x78, 0x1c, 0x28, 0xc1, 0x63, 0x71, 0x1d, 0xb3, 0xe5, 0x57, 0x26, 0x23, 0xb1, 0x38, - 0x06, 0x40, 0x01, 0x37, 0x3e, 0x18, 0x83, 0x69, 0xa4, 0x81, 0xb7, 0xa7, 0x7b, 0xed, 0x75, 0xc8, - 0x77, 0x78, 0x82, 0x53, 0x6e, 0x94, 0x6d, 0x52, 0x64, 0x40, 0x09, 0x4e, 0x64, 0x05, 0xca, 0x1e, - 0x93, 0x21, 0xd3, 0xcf, 0xc4, 0x18, 0x1a, 0xca, 0x99, 0x80, 0x21, 0xea, 0x6e, 0xfc, 0x13, 0xa3, - 0xc5, 0x88, 0x03, 0x93, 0xdb, 0x22, 0x39, 0x5c, 0xee, 0xe0, 0xd9, 0xa6, 0xb7, 0x4c, 0x30, 0xe7, - 0x7e, 0x7b, 0x95, 0x6d, 0x7e, 0x37, 0xfc, 0x89, 0x4a, 0x88, 0xf1, 0x41, 0x0e, 0x20, 0xbc, 0x5f, - 0x43, 0x76, 0xa0, 0xe8, 0x5f, 0x8c, 0x69, 0x91, 0x19, 0x33, 0x37, 0x24, 0x93, 0x48, 0x4c, 0x5f, - 0x42, 0x50, 0x0b, 0xb8, 0x9f, 0x0a, 0xf9, 0xd1, 0x38, 0xe8, 0x52, 0x0f, 0x49, 0x83, 0x7c, 0x86, - 0x69, 0x1f, 0xad, 0x30, 0xed, 0x5d, 0xd3, 0x21, 0x87, 0xa2, 0xc4, 0x32, 0x0d, 0x44, 0x05, 0x16, - 0xe5, 0x6a, 0xe1, 0x1a, 0x88, 0x8a, 0x41, 0xa2, 0xc6, 0xa6, 0xe9, 0xa4, 0xf9, 0x47, 0xa6, 0x93, - 0x16, 0x1e, 0x8a, 0x4e, 0x4a, 0x9e, 0x85, 0x49, 0xcf, 0xed, 0xd0, 0x25, 0xbc, 0x2e, 0xfd, 0x27, - 0xda, 0xaf, 0x81, 0x02, 0x8c, 0x0a, 0x4f, 0x9e, 0x87, 0x72, 0xdf, 0xa7, 0xf5, 0x95, 0x2b, 0xcb, - 0x1e, 0xb5, 0x7c, 0x19, 0xb3, 0xd5, 0x1e, 0xb5, 0x1b, 0x21, 0x0a, 0xa3, 0x74, 0xc6, 0x6f, 0xe5, - 0xe0, 0x58, 0xbd, 0xe1, 0xd9, 0xbd, 0x40, 0x6f, 0x9e, 0xd7, 0xf9, 0xb5, 0x82, 0xc0, 0x64, 0x4b, - 0x51, 0x4e, 0xc5, 0x27, 0x87, 0x84, 0xab, 0x04, 0x51, 0xec, 0xc2, 0x8c, 0x00, 0x61, 0xc8, 0x82, - 0x0d, 0xb5, 0xd8, 0x9e, 0x93, 0x53, 0xa2, 0xce, 0xa1, 0x28, 0xb1, 0xc6, 0x6d, 0x98, 0xad, 0xd3, - 0xae, 0xd9, 0x6b, 0xf3, 0xf0, 0x71, 0xc7, 0xb2, 0x9d, 0x16, 0x59, 0x84, 0x92, 0xaf, 0x60, 0xc9, - 0xdb, 0x39, 0x9a, 0x18, 0x43, 0x1a, 0xf2, 0x34, 0x4c, 0xb6, 0x79, 0x74, 0x47, 0x05, 0x44, 0xf9, - 0x31, 0x23, 0x02, 0x3e, 0x3e, 0x2a, 0x9c, 0xb1, 0x0b, 0x53, 0x61, 0x71, 0xda, 0x24, 0x2d, 0x98, - 0x69, 0x44, 0xa2, 0x6f, 0x48, 0x9b, 0x0f, 0x7c, 0xa1, 0x82, 0x47, 0x1e, 0x97, 0xe3, 0x4c, 0x30, - 0xc9, 0xd5, 0xf8, 0x45, 0x0e, 0x66, 0xb4, 0x64, 0xe9, 0x4a, 0xed, 0x89, 0x3a, 0xdb, 0x4e, 0x4b, - 0x2a, 0xcb, 0x97, 0x32, 0xe6, 0x6c, 0xc5, 0x3b, 0x2f, 0x9c, 0x2c, 0x12, 0x80, 0x4a, 0x0c, 0x93, - 0xb8, 0x6b, 0xda, 0x01, 0x93, 0x38, 0xf6, 0x50, 0x24, 0xde, 0x12, 0xdc, 0x51, 0x89, 0x31, 0xfe, - 0x78, 0x0c, 0x8a, 0x3a, 0x69, 0xec, 0x75, 0xc8, 0xf3, 0xf3, 0x7e, 0xb4, 0x33, 0x80, 0xeb, 0x0e, - 0x28, 0x38, 0x31, 0x96, 0xdc, 0x0d, 0x97, 0x59, 0xa9, 0x2f, 0x09, 0xcb, 0xc2, 0xf4, 0x02, 0x14, - 0x9c, 0xc8, 0x15, 0x18, 0xa7, 0x8e, 0x95, 0x59, 0x9d, 0xe7, 0xf7, 0xcf, 0x2e, 0x39, 0x16, 0x32, - 0x2e, 0xfc, 0xe6, 0x81, 0xeb, 0x75, 0xcd, 0x40, 0xaa, 0x8a, 0xe1, 0xcd, 0x03, 0x0e, 0x45, 0x89, - 0x35, 0x7e, 0x7b, 0x0c, 0x0a, 0xf5, 0xfe, 0x36, 0x3b, 0xd6, 0x7e, 0x3f, 0x07, 0xc7, 0x93, 0x0e, - 0xd9, 0x70, 0x62, 0x5e, 0x3e, 0x92, 0x9b, 0x31, 0x48, 0x9b, 0xb5, 0x27, 0x64, 0x55, 0x8e, 0xa7, - 0x20, 0x31, 0xad, 0x06, 0x4c, 0xed, 0x0c, 0x53, 0x44, 0xc7, 0x8e, 0x24, 0x45, 0x74, 0x7a, 0x58, - 0x7a, 0xa8, 0xf1, 0x37, 0x13, 0x00, 0xa2, 0x47, 0x36, 0x7a, 0xc1, 0x61, 0x6c, 0x83, 0x17, 0x60, - 0x4a, 0x5d, 0x97, 0xbf, 0x1e, 0x46, 0x21, 0xb4, 0xfb, 0x6a, 0x2d, 0x82, 0xc3, 0x18, 0x25, 0x33, - 0x81, 0xa8, 0x13, 0x78, 0x7b, 0xe2, 0xb0, 0x9b, 0x88, 0x9b, 0x40, 0x97, 0x34, 0x06, 0x23, 0x54, - 0x64, 0x21, 0xe6, 0x2a, 0x10, 0x69, 0xa4, 0xc7, 0xee, 0x61, 0xe6, 0xbf, 0x08, 0xd3, 0xfa, 0x6b, - 0xd5, 0xee, 0xa8, 0xc8, 0xbc, 0x56, 0x39, 0x37, 0xa3, 0x48, 0x8c, 0xd3, 0x92, 0x97, 0xe1, 0x58, - 0x3c, 0xdf, 0x4b, 0x1e, 0x0b, 0xa7, 0x64, 0xe9, 0x63, 0xf1, 0x34, 0x31, 0x4c, 0x50, 0xb3, 0x59, - 0x68, 0x79, 0x7b, 0xd8, 0x77, 0xe4, 0xf9, 0xa0, 0x67, 0xe1, 0x0a, 0x87, 0xa2, 0xc4, 0xb2, 0x2e, - 0x64, 0x25, 0xa9, 0x27, 0xe0, 0xdc, 0xa9, 0x5e, 0x0c, 0xbb, 0xb0, 0x1e, 0xc1, 0x61, 0x8c, 0x92, - 0x49, 0x90, 0x86, 0x19, 0xc4, 0xe7, 0x79, 0xc2, 0xb4, 0xea, 0xc1, 0x31, 0x37, 0xae, 0x0b, 0x0b, - 0x6f, 0xf9, 0x67, 0x0e, 0x99, 0x78, 0x1e, 0x2b, 0x2b, 0x12, 0xaa, 0x12, 0xaa, 0x73, 0x82, 0xbf, - 0x71, 0x1c, 0xe6, 0xea, 0xfd, 0x5e, 0xaf, 0x63, 0x53, 0x4b, 0xdb, 0xbf, 0xc6, 0x2b, 0x30, 0x23, - 0xaf, 0x12, 0xe8, 0xe3, 0xef, 0x81, 0x6e, 0x06, 0x1a, 0x5f, 0x61, 0xfb, 0xf9, 0x9e, 0xd3, 0x68, - 0x7b, 0xae, 0x23, 0xbd, 0x8f, 0xc4, 0x49, 0x1e, 0x5a, 0x59, 0xdd, 0x1f, 0xd1, 0x23, 0x4a, 0xac, - 0x90, 0xb4, 0x33, 0xcf, 0xf8, 0x66, 0x0e, 0x4e, 0x26, 0xea, 0x20, 0x4f, 0x96, 0x77, 0x06, 0x6b, - 0xb2, 0x32, 0x5a, 0x4d, 0xa4, 0x13, 0x76, 0x78, 0x65, 0xfe, 0x23, 0x07, 0xe5, 0xad, 0xad, 0xab, - 0x5a, 0xdf, 0x47, 0x38, 0xe5, 0x8b, 0xcb, 0x14, 0x4b, 0xcd, 0x80, 0x7a, 0xcb, 0x6e, 0xb7, 0xd7, - 0xa1, 0xba, 0x73, 0xe5, 0x0d, 0x87, 0x7a, 0x2a, 0x05, 0x0e, 0x29, 0x49, 0xd6, 0xe1, 0x78, 0x14, - 0x23, 0xcd, 0x1d, 0xbe, 0xd0, 0xf3, 0x32, 0xe9, 0x6d, 0x10, 0x8d, 0x69, 0x65, 0x92, 0xac, 0xa4, - 0xcd, 0x23, 0xdf, 0x45, 0x18, 0x60, 0x25, 0xd1, 0x98, 0x56, 0xc6, 0xd8, 0x80, 0x72, 0xe4, 0x51, - 0x0c, 0xf2, 0x2a, 0xcc, 0x36, 0xdc, 0x6e, 0xcf, 0xa3, 0xbe, 0x6f, 0xbb, 0xce, 0x55, 0x7a, 0x87, - 0x76, 0x64, 0x93, 0xf9, 0x55, 0x89, 0xe5, 0x04, 0x0e, 0x07, 0xa8, 0x8d, 0x7f, 0x7c, 0x02, 0x74, - 0x82, 0xfe, 0xaf, 0xd3, 0xfc, 0x33, 0xc5, 0x54, 0x1b, 0x3a, 0xe6, 0x93, 0x1f, 0x3d, 0xe6, 0xa3, - 0xf7, 0xb2, 0x44, 0xdc, 0xa7, 0x15, 0xc6, 0x7d, 0x0a, 0x47, 0x10, 0xf7, 0xd1, 0x4a, 0xd4, 0x40, - 0xec, 0xe7, 0x1b, 0x39, 0x98, 0x72, 0x5c, 0x8b, 0x2a, 0x9d, 0x93, 0x9b, 0xdd, 0xe5, 0x0b, 0x1b, - 0x23, 0x75, 0xa2, 0x08, 0x01, 0x4a, 0x8e, 0x22, 0xe4, 0xa7, 0x37, 0xfa, 0x28, 0x0a, 0x63, 0xa2, - 0xc9, 0x2a, 0x14, 0xcd, 0x66, 0xd3, 0x76, 0xec, 0x60, 0x4f, 0xde, 0x34, 0x38, 0x93, 0xa6, 0x2a, - 0x2f, 0x49, 0x1a, 0x61, 0xb6, 0xa9, 0x2f, 0xd4, 0x65, 0x99, 0xdd, 0xab, 0x2f, 0xf6, 0x95, 0x46, - 0xb0, 0x7b, 0x55, 0x56, 0x48, 0xc4, 0x09, 0xa3, 0x2e, 0x21, 0x85, 0xf7, 0xfc, 0x0c, 0x28, 0x88, - 0x70, 0x20, 0x3f, 0x9d, 0x8a, 0xc2, 0xe9, 0x27, 0x42, 0x85, 0x28, 0x31, 0xa4, 0xa5, 0x1c, 0xd7, - 0x65, 0xde, 0xb9, 0xb5, 0xcc, 0x6e, 0x7f, 0xed, 0x0b, 0x4f, 0xf7, 0x5c, 0x93, 0xd7, 0xa2, 0x76, - 0xd6, 0xd4, 0x61, 0xec, 0xac, 0xe9, 0xa1, 0x36, 0x56, 0x0b, 0x0a, 0x3e, 0xb7, 0xe2, 0x78, 0x0c, - 0xb4, 0x7c, 0x61, 0x39, 0xdb, 0x2e, 0x1f, 0x33, 0x04, 0x45, 0xef, 0x08, 0x18, 0x4a, 0xf6, 0xc4, - 0x85, 0xa2, 0x0a, 0xd4, 0xca, 0x30, 0x6a, 0x36, 0xd3, 0x21, 0xe9, 0xb2, 0x53, 0xf9, 0xe6, 0x02, - 0x8a, 0x5a, 0x08, 0x79, 0x03, 0xc6, 0x2d, 0xb3, 0x25, 0x03, 0xaa, 0xaf, 0x66, 0xbe, 0x40, 0xa1, - 0xc4, 0x70, 0xad, 0x7c, 0x65, 0x69, 0x0d, 0x19, 0x57, 0xb2, 0x13, 0x5e, 0x30, 0x9c, 0x1d, 0xe5, - 0x74, 0x8c, 0xab, 0x10, 0xc2, 0xe6, 0x1c, 0xb8, 0xa2, 0x78, 0x09, 0x26, 0xef, 0xb8, 0x9d, 0x7e, - 0x57, 0x46, 0x62, 0xcb, 0x17, 0xe6, 0xd3, 0x46, 0xfb, 0x26, 0x27, 0x09, 0x37, 0x01, 0xf1, 0xed, - 0xa3, 0x2a, 0x4b, 0xbe, 0x9a, 0x83, 0x63, 0x6c, 0xe9, 0xe8, 0x79, 0xe0, 0x57, 0xc8, 0x08, 0x33, - 0xf5, 0x86, 0xcf, 0x8e, 0x56, 0x35, 0xc3, 0xb4, 0x22, 0xb9, 0x1e, 0x93, 0x80, 0x09, 0x89, 0xa4, - 0x07, 0x45, 0xdf, 0xb6, 0x68, 0xc3, 0xf4, 0xfc, 0xca, 0xf1, 0x23, 0x93, 0x1e, 0xba, 0xac, 0x24, - 0x6f, 0xd4, 0x52, 0xc8, 0x6f, 0xf2, 0x07, 0x32, 0xe4, 0xe3, 0x36, 0xf2, 0xc1, 0xa1, 0x13, 0x47, - 0xf9, 0xe0, 0xd0, 0x71, 0xf1, 0x3a, 0x46, 0x4c, 0x02, 0x26, 0x45, 0x92, 0xaf, 0xe4, 0xe0, 0xa4, - 0xb8, 0x69, 0x98, 0xbc, 0x66, 0x7a, 0x32, 0xa3, 0x9d, 0xf8, 0xf8, 0xc1, 0x7e, 0xf5, 0xe4, 0x52, - 0x1a, 0x4b, 0x4c, 0x97, 0x44, 0xde, 0x83, 0x69, 0x2f, 0xea, 0x53, 0xe5, 0x01, 0xfa, 0xac, 0x23, - 0x10, 0xf3, 0xce, 0x8a, 0xe4, 0x80, 0x18, 0x08, 0xe3, 0xb2, 0xc8, 0x73, 0x50, 0xee, 0xc9, 0xcd, - 0xcd, 0xf6, 0xbb, 0x3c, 0xb6, 0x3f, 0x2e, 0x0e, 0xe1, 0xcd, 0x10, 0x8c, 0x51, 0x1a, 0x72, 0x03, - 0xca, 0x81, 0xdb, 0xa1, 0x9e, 0xcc, 0x3e, 0xac, 0xf0, 0xf9, 0x72, 0x36, 0x6d, 0xf2, 0x6f, 0x69, - 0xb2, 0xd0, 0x75, 0x15, 0xc2, 0x7c, 0x8c, 0xf2, 0x61, 0x96, 0x94, 0xba, 0x87, 0xcc, 0x73, 0x79, - 0x2b, 0x8f, 0xc7, 0x2d, 0xa9, 0x7a, 0x14, 0x89, 0x71, 0x5a, 0xb2, 0x06, 0x73, 0x3d, 0xcf, 0x76, - 0x3d, 0x3b, 0xd8, 0x5b, 0xee, 0x98, 0xbe, 0xcf, 0x19, 0xcc, 0x73, 0x06, 0xda, 0x1d, 0xbf, 0x99, - 0x24, 0xc0, 0xc1, 0x32, 0xe4, 0x3c, 0x14, 0x15, 0xb0, 0xf2, 0x04, 0x57, 0xef, 0xf8, 0x4e, 0xa6, - 0xca, 0xa2, 0xc6, 0x0e, 0xb9, 0x36, 0x75, 0x26, 0xcb, 0xb5, 0x29, 0x62, 0xc1, 0x19, 0xb3, 0x1f, - 0xb8, 0x3c, 0xd7, 0x39, 0x5e, 0x64, 0xcb, 0xdd, 0xa1, 0x4e, 0xe5, 0x1c, 0x3f, 0xde, 0xce, 0x1d, - 0xec, 0x57, 0xcf, 0x2c, 0xdd, 0x83, 0x0e, 0xef, 0xc9, 0x85, 0x74, 0xa1, 0x48, 0xe5, 0xd5, 0xaf, - 0xca, 0xc7, 0x46, 0x38, 0x57, 0xe2, 0xf7, 0xc7, 0x54, 0x0c, 0x59, 0xc0, 0x50, 0x8b, 0x20, 0x5b, - 0x50, 0x6e, 0xbb, 0x7e, 0xb0, 0xd4, 0xb1, 0x4d, 0x9f, 0xfa, 0x95, 0x27, 0xf9, 0x3c, 0x49, 0x3d, - 0x12, 0x2f, 0x2b, 0xb2, 0x70, 0x9a, 0x5c, 0x0e, 0x4b, 0x62, 0x94, 0x0d, 0xa1, 0xdc, 0x5b, 0xdb, - 0xe7, 0xa3, 0xe6, 0x3a, 0x01, 0x7d, 0x37, 0xa8, 0x9c, 0xe5, 0x6d, 0x79, 0x26, 0x8d, 0xf3, 0xa6, - 0x6b, 0xd5, 0xe3, 0xd4, 0x62, 0x63, 0x48, 0x00, 0x31, 0xc9, 0x93, 0x99, 0xcc, 0x3d, 0xd7, 0xaa, - 0xf7, 0x68, 0x63, 0xd3, 0x0c, 0x1a, 0xed, 0x4a, 0x35, 0xee, 0x75, 0xd8, 0x8c, 0xe0, 0x30, 0x46, - 0xc9, 0x4c, 0x10, 0x8f, 0xfa, 0xdc, 0xc3, 0xb1, 0x49, 0x1d, 0xcb, 0x76, 0x5a, 0x9b, 0xae, 0xe5, - 0x57, 0x0c, 0x3e, 0x84, 0xdc, 0x04, 0xc1, 0x41, 0x34, 0xa6, 0x95, 0x21, 0x0d, 0x98, 0xec, 0x8a, - 0xfc, 0xd0, 0xca, 0x53, 0x23, 0x68, 0xa2, 0x32, 0xc7, 0x54, 0x9c, 0x63, 0xf2, 0x03, 0x15, 0x67, - 0xf2, 0x7b, 0x39, 0x98, 0xf1, 0xe3, 0xe6, 0x66, 0xe5, 0xe3, 0xa3, 0x9c, 0x9e, 0x71, 0x5e, 0xb5, - 0x67, 0x78, 0x7f, 0xc7, 0x81, 0x77, 0x07, 0x41, 0x98, 0xac, 0x84, 0x68, 0x3d, 0x4f, 0xbd, 0xae, - 0x3c, 0x3d, 0x52, 0xeb, 0x39, 0x0f, 0xd5, 0x7a, 0xfe, 0x81, 0x8a, 0xf3, 0xfc, 0x2b, 0x30, 0x37, - 0xa0, 0x30, 0x3f, 0x50, 0x5a, 0xf0, 0x4f, 0x99, 0x81, 0x1c, 0x31, 0x51, 0x8e, 0xda, 0xb0, 0x5b, - 0x83, 0x39, 0xf9, 0xe2, 0x24, 0xd3, 0xa6, 0x3a, 0x7d, 0xfd, 0xb6, 0x50, 0x24, 0xd0, 0x88, 0x49, - 0x02, 0x1c, 0x2c, 0xc3, 0x66, 0x74, 0x43, 0x3c, 0x2e, 0x23, 0xd2, 0x3e, 0x27, 0xe2, 0x4e, 0xa0, - 0xe5, 0x08, 0x0e, 0x63, 0x94, 0xc6, 0x9f, 0xe4, 0x60, 0x3a, 0x76, 0xb2, 0x1f, 0x79, 0x4c, 0x61, - 0x15, 0x48, 0xd7, 0xf6, 0x3c, 0xd7, 0x13, 0xea, 0xd1, 0x35, 0xb6, 0x67, 0xf9, 0xf2, 0xe6, 0x22, - 0xbf, 0x31, 0x73, 0x6d, 0x00, 0x8b, 0x29, 0x25, 0x8c, 0x3f, 0x1d, 0x87, 0x30, 0x1b, 0x42, 0x5f, - 0x13, 0xcb, 0x0d, 0xbd, 0x26, 0xf6, 0x49, 0x28, 0xde, 0xf6, 0x5d, 0x67, 0x33, 0xbc, 0x4c, 0xa6, - 0x87, 0xe2, 0xb5, 0xfa, 0xc6, 0x75, 0x4e, 0xa9, 0x29, 0x38, 0xf5, 0x3b, 0xab, 0x76, 0x27, 0x18, - 0xbc, 0x72, 0xf5, 0xda, 0xeb, 0x02, 0x8e, 0x9a, 0x82, 0xbf, 0x60, 0x73, 0x87, 0x6a, 0x9f, 0x5e, - 0xf8, 0x82, 0x0d, 0x03, 0xa2, 0xc0, 0x91, 0x45, 0x28, 0x69, 0x97, 0xa0, 0xf4, 0x50, 0xea, 0x9e, - 0xd2, 0xae, 0x43, 0x0c, 0x69, 0xb8, 0xa6, 0x26, 0xdd, 0x5e, 0xd2, 0x3a, 0x5d, 0xcd, 0xa8, 0xe3, - 0x26, 0x7c, 0x67, 0x62, 0x1b, 0x57, 0x60, 0xd4, 0x52, 0xa2, 0x19, 0x36, 0xf9, 0xa3, 0xcc, 0xb0, - 0x31, 0xbe, 0x36, 0x0e, 0x93, 0x37, 0xa9, 0xc7, 0xaf, 0x89, 0x3e, 0x0b, 0x93, 0x77, 0xc4, 0x4f, - 0x39, 0x5a, 0xa1, 0xc2, 0x2c, 0xc0, 0xa8, 0xf0, 0xac, 0xcb, 0xb6, 0xfb, 0x76, 0xc7, 0x5a, 0x09, - 0xd7, 0x8f, 0xee, 0xb2, 0x9a, 0x42, 0x60, 0x48, 0xc3, 0x0a, 0xb4, 0x98, 0xb6, 0xdb, 0xed, 0xda, - 0x41, 0xf2, 0xd2, 0xc7, 0x9a, 0x42, 0x60, 0x48, 0x43, 0x9e, 0x81, 0x42, 0xcb, 0x0e, 0xb6, 0xcc, - 0x56, 0xd2, 0xb9, 0xbf, 0xc6, 0xa1, 0x28, 0xb1, 0xdc, 0x33, 0x6d, 0x07, 0x5b, 0x1e, 0xe5, 0x6e, - 0xb4, 0x81, 0x84, 0xf4, 0xb5, 0x08, 0x0e, 0x63, 0x94, 0xbc, 0x4a, 0xae, 0x6c, 0x99, 0xf4, 0x18, - 0x87, 0x55, 0x52, 0x08, 0x0c, 0x69, 0xd8, 0xd4, 0x6b, 0xb8, 0xdd, 0x9e, 0xdd, 0x91, 0xd9, 0x1a, - 0x91, 0xa9, 0xb7, 0x2c, 0xe1, 0xa8, 0x29, 0x18, 0x35, 0xdb, 0x3c, 0x9a, 0xae, 0xd7, 0x4d, 0x3e, - 0x19, 0xb2, 0x29, 0xe1, 0xa8, 0x29, 0x8c, 0x2f, 0xc3, 0xb4, 0x8c, 0xef, 0x48, 0x37, 0xe3, 0x4e, - 0x18, 0x74, 0x1b, 0xe5, 0x49, 0xd9, 0xc8, 0xb5, 0xac, 0x78, 0xec, 0x2a, 0x16, 0xba, 0xfb, 0xde, - 0x18, 0x14, 0x1f, 0xe1, 0x3b, 0x4b, 0x8d, 0xd8, 0x3b, 0x4b, 0x47, 0xf0, 0x28, 0x4f, 0xda, 0x1b, - 0x4b, 0x3b, 0x89, 0x37, 0x96, 0x96, 0x47, 0xcc, 0x96, 0xbb, 0xe7, 0xfb, 0x4a, 0xff, 0x92, 0x03, - 0x9d, 0xfe, 0xcf, 0xf7, 0x96, 0x9a, 0xcd, 0x35, 0x88, 0x47, 0xd0, 0x99, 0x6e, 0xac, 0x33, 0xaf, - 0x8d, 0xd4, 0xca, 0x68, 0xd5, 0x87, 0x3e, 0xf0, 0xf6, 0x51, 0x0e, 0x2a, 0x69, 0x05, 0x1e, 0xc1, - 0x9b, 0x52, 0x4e, 0xfc, 0x4d, 0xa9, 0xf5, 0x23, 0x6b, 0xec, 0x90, 0xb7, 0xa5, 0x7e, 0x3c, 0xa4, - 0xa9, 0xfc, 0x55, 0xa7, 0xb7, 0xd5, 0xd9, 0x92, 0x1b, 0x21, 0x0b, 0x4d, 0x70, 0x4d, 0x3f, 0x97, - 0xde, 0x86, 0x82, 0x50, 0x47, 0xe5, 0xd8, 0xbe, 0x98, 0xf1, 0x90, 0x61, 0x2c, 0xa4, 0xe3, 0x89, - 0xff, 0x46, 0xc9, 0xd6, 0xf8, 0x61, 0x0e, 0xa6, 0x1e, 0xe1, 0x8b, 0x60, 0xdb, 0xf1, 0xd1, 0x7b, - 0x69, 0xa4, 0xd1, 0x1b, 0x32, 0x62, 0xdf, 0x78, 0x1c, 0x62, 0x2f, 0x71, 0x11, 0x07, 0x4a, 0x4a, - 0x8d, 0x53, 0x79, 0xb3, 0x2f, 0x8d, 0xe4, 0xdb, 0x0d, 0x0f, 0x09, 0x05, 0xf1, 0x31, 0x14, 0x91, - 0x88, 0x77, 0x8e, 0x1d, 0x2a, 0xde, 0xf9, 0xc8, 0xe3, 0x06, 0xe9, 0x66, 0xf3, 0xc4, 0x43, 0x31, - 0x9b, 0xcf, 0x1c, 0xb9, 0xd9, 0xfc, 0xe4, 0xc3, 0x37, 0x9b, 0x23, 0x7e, 0xc5, 0xfc, 0x08, 0x7e, - 0xc5, 0xf7, 0xe0, 0x84, 0xf8, 0xb9, 0xdc, 0x31, 0xed, 0xae, 0x9e, 0x2f, 0xf2, 0x99, 0xa3, 0x67, - 0x53, 0x8d, 0x65, 0xa6, 0x6c, 0xf8, 0x01, 0x75, 0x82, 0x9b, 0x61, 0xc9, 0xf0, 0x8e, 0xd9, 0xcd, - 0x14, 0x76, 0x98, 0x2a, 0x24, 0xe9, 0x55, 0x9a, 0x3c, 0x84, 0x57, 0xe9, 0xbb, 0x39, 0x38, 0x69, - 0xa6, 0x3d, 0xe9, 0x2b, 0xc3, 0x11, 0xaf, 0x8d, 0xe4, 0x16, 0x8c, 0x71, 0x94, 0x3e, 0xba, 0x34, - 0x14, 0xa6, 0xd7, 0x81, 0x3c, 0x1d, 0x7a, 0x96, 0x45, 0xf0, 0x3c, 0xdd, 0x27, 0xfc, 0xed, 0x64, - 0x44, 0x07, 0x78, 0x6f, 0xd7, 0x47, 0x56, 0x33, 0x8e, 0x20, 0xaa, 0x53, 0x1e, 0x21, 0xaa, 0x93, - 0x70, 0xf9, 0x4d, 0x1d, 0x91, 0xcb, 0xcf, 0x81, 0x59, 0xbb, 0x6b, 0xb6, 0xe8, 0x66, 0xbf, 0xd3, - 0x11, 0x29, 0x72, 0x7e, 0x65, 0x9a, 0xf3, 0x4e, 0xcd, 0xd3, 0xba, 0xea, 0x36, 0xcc, 0x4e, 0xf2, - 0xe1, 0x38, 0x9d, 0xdf, 0xba, 0x9e, 0xe0, 0x84, 0x03, 0xbc, 0xd9, 0xb4, 0xe4, 0xf7, 0x9b, 0x68, - 0xc0, 0x7a, 0x9b, 0x07, 0x3c, 0xe4, 0xa3, 0xeb, 0x97, 0x43, 0x30, 0x46, 0x69, 0xc8, 0x15, 0x28, - 0x59, 0x8e, 0x2f, 0x53, 0x51, 0x67, 0xf8, 0x2e, 0xf5, 0x29, 0xb6, 0xb7, 0xad, 0x5c, 0xaf, 0xeb, - 0x24, 0xd4, 0x33, 0x29, 0x17, 0xe4, 0x34, 0x1e, 0xc3, 0xf2, 0xe4, 0x1a, 0x67, 0x26, 0x5f, 0x17, - 0x11, 0x11, 0x8a, 0x73, 0x43, 0xbc, 0x56, 0x2b, 0xd7, 0xd5, 0x63, 0x28, 0xd3, 0x52, 0x9c, 0x7c, - 0x33, 0x24, 0xe4, 0x10, 0x79, 0x19, 0x6b, 0xee, 0x9e, 0x2f, 0x63, 0xdd, 0x80, 0xd3, 0x41, 0xd0, - 0x89, 0x05, 0xbe, 0xe5, 0x1d, 0x44, 0x7e, 0x21, 0x35, 0x2f, 0x1e, 0x53, 0xdc, 0xda, 0xba, 0x9a, - 0x46, 0x82, 0xc3, 0xca, 0xf2, 0x08, 0x70, 0xd0, 0xd1, 0x5e, 0xeb, 0xb3, 0xa3, 0x44, 0x80, 0xc3, - 0x0c, 0x03, 0x19, 0x01, 0x0e, 0x01, 0x18, 0x95, 0x42, 0x36, 0x86, 0xf9, 0xeb, 0x8f, 0xf3, 0x3d, - 0xe6, 0xc1, 0xbd, 0xef, 0x51, 0x87, 0xef, 0x89, 0x7b, 0x3a, 0x7c, 0x07, 0x1c, 0xd4, 0x27, 0x1f, - 0xc0, 0x41, 0xfd, 0x06, 0xbf, 0xfc, 0xb8, 0xb6, 0x2c, 0x9d, 0xfb, 0xd9, 0x34, 0x36, 0x7e, 0xdf, - 0x42, 0xa4, 0xb6, 0xf1, 0x9f, 0x28, 0x78, 0x92, 0x4d, 0x38, 0xd1, 0x73, 0xad, 0x01, 0xff, 0x36, - 0xf7, 0xe6, 0x47, 0x2e, 0x09, 0x6f, 0xa6, 0xd0, 0x60, 0x6a, 0x49, 0xbe, 0x81, 0x87, 0xf0, 0x4a, - 0x85, 0x77, 0x8c, 0xd8, 0xc0, 0x43, 0x30, 0x46, 0x69, 0x92, 0xee, 0xde, 0xc7, 0x1f, 0x9a, 0xbb, - 0x77, 0xfe, 0x11, 0xb8, 0x7b, 0x9f, 0x38, 0xb4, 0xbb, 0xf7, 0xff, 0xc3, 0xf1, 0x9e, 0x6b, 0xad, - 0xd8, 0xbe, 0xd7, 0xe7, 0x7f, 0xf8, 0x50, 0xeb, 0x5b, 0x2d, 0x1a, 0x70, 0x7f, 0x71, 0xf9, 0xc2, - 0x85, 0x68, 0x25, 0xc5, 0xff, 0xda, 0x2c, 0xc8, 0xff, 0xb5, 0xe1, 0x8b, 0x3c, 0x51, 0x8a, 0xdb, - 0x3d, 0xdc, 0x45, 0x9c, 0x82, 0xc4, 0x34, 0x39, 0x51, 0x17, 0xf1, 0xb9, 0x87, 0xe6, 0x22, 0x7e, - 0x15, 0x8a, 0x7e, 0xbb, 0x1f, 0x58, 0xee, 0xae, 0xc3, 0x03, 0x07, 0x25, 0xfd, 0x14, 0x6d, 0xb1, - 0x2e, 0xe1, 0x77, 0xf7, 0xab, 0xb3, 0xea, 0x77, 0xe4, 0x46, 0x90, 0x84, 0x90, 0xef, 0x0c, 0x49, - 0x7e, 0x34, 0x8e, 0x38, 0xf9, 0xf1, 0xf4, 0x03, 0x25, 0x3e, 0xa6, 0xb9, 0xbe, 0x9f, 0xfa, 0x25, - 0x70, 0x7d, 0x8f, 0xee, 0x95, 0xfe, 0xce, 0x0c, 0x1c, 0x4b, 0x3c, 0xcb, 0xaa, 0xaf, 0xee, 0xe7, - 0x0e, 0x7b, 0x75, 0x3f, 0x76, 0xb7, 0x7e, 0xec, 0xa1, 0xde, 0xad, 0x1f, 0x3f, 0xf2, 0xbb, 0xf5, - 0x91, 0x37, 0x04, 0x26, 0xee, 0xf3, 0x86, 0xc0, 0x12, 0xcc, 0xa8, 0x64, 0x2d, 0x2a, 0xef, 0x56, - 0x0b, 0x57, 0x9e, 0xce, 0xec, 0x5f, 0x8e, 0xa3, 0x31, 0x49, 0x4f, 0xbe, 0x0c, 0x79, 0x87, 0x17, - 0x2c, 0x8c, 0xf0, 0x16, 0x4b, 0x7c, 0xc0, 0xb8, 0xca, 0x27, 0x9f, 0x43, 0x51, 0x71, 0xfc, 0x3c, - 0x87, 0xdd, 0x55, 0x3f, 0x50, 0x08, 0x25, 0x6f, 0x42, 0xc5, 0x6d, 0x36, 0x3b, 0xae, 0x69, 0x85, - 0xf7, 0xff, 0x95, 0x77, 0x51, 0xe4, 0x6d, 0x9e, 0x93, 0x0c, 0x2a, 0x1b, 0x43, 0xe8, 0x70, 0x28, - 0x07, 0xa6, 0x99, 0xcf, 0xc4, 0xdf, 0xa5, 0xf0, 0x2b, 0x25, 0xde, 0xcc, 0xff, 0x7b, 0x14, 0xcd, - 0x8c, 0x3f, 0x82, 0x21, 0x1b, 0x1c, 0xde, 0xa9, 0x88, 0x63, 0x31, 0x59, 0x13, 0xe2, 0xc1, 0xa9, - 0x5e, 0x9a, 0xdd, 0xe2, 0xcb, 0x6c, 0xaa, 0x7b, 0x59, 0x4f, 0x67, 0xa5, 0x94, 0x53, 0xa9, 0x96, - 0x8f, 0x8f, 0x43, 0x38, 0x47, 0x5f, 0x06, 0x28, 0x3e, 0xb4, 0x97, 0x01, 0xe2, 0x0f, 0x11, 0x4f, - 0x3f, 0x8a, 0x87, 0x88, 0xc9, 0xcf, 0x53, 0x1f, 0xa4, 0x10, 0xea, 0xfe, 0x17, 0x8f, 0x62, 0xb0, - 0x7f, 0xe9, 0x1e, 0xa5, 0xf8, 0x83, 0x1c, 0xcc, 0x8b, 0x29, 0x95, 0xf6, 0x2f, 0x13, 0x32, 0x27, - 0xea, 0x08, 0xdc, 0xc4, 0x3c, 0x8a, 0x55, 0x8f, 0x09, 0xe2, 0x7e, 0xcd, 0x7b, 0x08, 0x27, 0xdf, - 0x48, 0x39, 0x9e, 0x66, 0x46, 0x30, 0x86, 0x53, 0x93, 0x8a, 0xa5, 0x82, 0x74, 0xbf, 0x13, 0x69, - 0x4f, 0xbc, 0x16, 0x34, 0xf4, 0xdd, 0xa4, 0x1b, 0xd1, 0xa3, 0x28, 0xeb, 0xd3, 0x45, 0xe1, 0xde, - 0x13, 0x7d, 0xb3, 0xe9, 0x2b, 0x39, 0x38, 0x91, 0xb6, 0x49, 0xa4, 0xd4, 0xa2, 0x1e, 0xaf, 0xc5, - 0x68, 0xde, 0xb6, 0x68, 0x1d, 0x8e, 0xe6, 0xed, 0x89, 0xdf, 0x2d, 0x44, 0x3c, 0x84, 0x01, 0xed, - 0xfd, 0x3a, 0x0b, 0x38, 0x53, 0x16, 0x70, 0xec, 0xd9, 0xee, 0xfc, 0x23, 0x7c, 0xb6, 0xbb, 0x90, - 0xe1, 0xd9, 0xee, 0xc9, 0x47, 0xf9, 0x6c, 0x77, 0xf1, 0x90, 0xcf, 0x76, 0x97, 0x7e, 0x69, 0x9e, - 0xed, 0x36, 0x3e, 0xcc, 0xc1, 0xec, 0xff, 0xf4, 0xff, 0x25, 0xfa, 0x69, 0x24, 0x44, 0xf7, 0x08, - 0xff, 0x90, 0xe8, 0x76, 0x3c, 0xe8, 0x71, 0xe9, 0x48, 0x1a, 0x39, 0x24, 0xf8, 0xf1, 0x0e, 0xa4, - 0x99, 0x5d, 0x87, 0xbb, 0xde, 0x15, 0x4b, 0x4b, 0x19, 0x3b, 0x74, 0x5a, 0xca, 0x7f, 0xa5, 0xf4, - 0x2a, 0x3f, 0x37, 0xdf, 0x7b, 0x58, 0x7f, 0xc0, 0x72, 0x22, 0xed, 0x0f, 0x58, 0x12, 0x7f, 0xb8, - 0x92, 0xfc, 0x03, 0x8e, 0xb1, 0x87, 0xf7, 0x07, 0x1c, 0xb5, 0x85, 0xef, 0x7f, 0x78, 0xf6, 0xb1, - 0x1f, 0x7e, 0x78, 0xf6, 0xb1, 0x1f, 0x7d, 0x78, 0xf6, 0xb1, 0xf7, 0x0f, 0xce, 0xe6, 0xbe, 0x7f, - 0x70, 0x36, 0xf7, 0xc3, 0x83, 0xb3, 0xb9, 0x1f, 0x1d, 0x9c, 0xcd, 0xfd, 0xf4, 0xe0, 0x6c, 0xee, - 0x77, 0xfe, 0xf9, 0xec, 0x63, 0x5f, 0x2c, 0xaa, 0xc6, 0xfc, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xbb, 0x19, 0xf9, 0x56, 0x33, 0x78, 0x00, 0x00, + // 7054 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5d, 0x6c, 0x1c, 0xd7, + 0x75, 0xb0, 0x87, 0xe4, 0x2e, 0x77, 0xcf, 0x92, 0x22, 0x75, 0xf5, 0xb7, 0xa6, 0x65, 0xad, 0x32, + 0x8e, 0x0d, 0xf9, 0xfb, 0x12, 0x32, 0x96, 0xe3, 0xef, 0x73, 0xe2, 0xf8, 0x87, 0x4b, 0x8a, 0x14, + 0x2d, 0x51, 0xa4, 0xcf, 0x52, 0x52, 0x13, 0x19, 0x76, 0x87, 0xbb, 0x77, 0x77, 0x47, 0xdc, 0x9d, + 0x59, 0xcf, 0xcc, 0x8a, 0x66, 0xdc, 0xa2, 0x4e, 0xd0, 0x20, 0x4d, 0x83, 0xa0, 0x2d, 0x02, 0xb4, + 0x2e, 0x82, 0x02, 0x7d, 0x29, 0x0a, 0x14, 0x7d, 0x6d, 0x5f, 0x0a, 0xe4, 0xa1, 0x68, 0x8b, 0x34, + 0x2f, 0x4d, 0xd1, 0x87, 0xe6, 0x21, 0x60, 0x62, 0xf6, 0xc5, 0x41, 0x9a, 0xe6, 0x29, 0x28, 0x20, + 0x14, 0x68, 0x71, 0x7f, 0xe7, 0x67, 0x67, 0x25, 0x6a, 0x96, 0x12, 0x82, 0x26, 0x6f, 0x3b, 0xe7, + 0x9c, 0x7b, 0xce, 0xfd, 0x3d, 0xf7, 0xfc, 0xdc, 0x7b, 0x17, 0x96, 0x5a, 0x76, 0xd0, 0xee, 0x6f, + 0xcf, 0xd7, 0xdd, 0xee, 0x82, 0xe5, 0xb5, 0xdc, 0x9e, 0xe7, 0xde, 0xe6, 0x3f, 0x16, 0x7a, 0x3b, + 0xad, 0x05, 0xab, 0x67, 0xfb, 0x0b, 0xbb, 0xae, 0xb7, 0xd3, 0xec, 0xb8, 0xbb, 0x0b, 0x77, 0x9e, + 0xb3, 0x3a, 0xbd, 0xb6, 0xf5, 0xdc, 0x42, 0x8b, 0x3a, 0xd4, 0xb3, 0x02, 0xda, 0x98, 0xef, 0x79, + 0x6e, 0xe0, 0x92, 0xe7, 0x43, 0x26, 0xf3, 0x8a, 0x09, 0xff, 0x31, 0xdf, 0xdb, 0x69, 0xcd, 0x33, + 0x26, 0xf3, 0x8a, 0xc9, 0xbc, 0x62, 0x32, 0xf7, 0xc9, 0x88, 0xe4, 0x96, 0xcb, 0x04, 0x32, 0x5e, + 0xdb, 0xfd, 0x26, 0xff, 0xe2, 0x1f, 0xfc, 0x97, 0x90, 0x31, 0x67, 0xee, 0xbc, 0xe8, 0xcf, 0xdb, + 0x2e, 0xab, 0xd2, 0x42, 0xdd, 0xf5, 0xe8, 0xc2, 0x9d, 0x81, 0x7a, 0xcc, 0x3d, 0x1b, 0xa1, 0xe9, + 0xb9, 0x1d, 0xbb, 0xbe, 0xb7, 0x70, 0xe7, 0xb9, 0x6d, 0x1a, 0x0c, 0x56, 0x79, 0xee, 0xd3, 0x21, + 0x69, 0xd7, 0xaa, 0xb7, 0x6d, 0x87, 0x7a, 0x7b, 0x61, 0x93, 0xbb, 0x34, 0xb0, 0xd2, 0x04, 0x2c, + 0x0c, 0x2b, 0xe5, 0xf5, 0x9d, 0xc0, 0xee, 0xd2, 0x81, 0x02, 0xff, 0xef, 0x7e, 0x05, 0xfc, 0x7a, + 0x9b, 0x76, 0xad, 0x81, 0x72, 0xcf, 0x0f, 0x2b, 0xd7, 0x0f, 0xec, 0xce, 0x82, 0xed, 0x04, 0x7e, + 0xe0, 0x25, 0x0b, 0x99, 0xcf, 0x42, 0x7e, 0xb1, 0xeb, 0xf6, 0x9d, 0x80, 0x54, 0x20, 0x77, 0xc7, + 0xea, 0xf4, 0x69, 0xd9, 0x38, 0x6f, 0x5c, 0x98, 0xaa, 0x16, 0x0f, 0xf6, 0x2b, 0xb9, 0x1b, 0x0c, + 0x80, 0x02, 0x6e, 0xfe, 0x93, 0x01, 0x33, 0x8b, 0x5e, 0xbd, 0x6d, 0xdf, 0xa1, 0xb5, 0x80, 0xf1, + 0x68, 0xed, 0x91, 0x5b, 0x30, 0x1e, 0x58, 0x1e, 0x2f, 0x52, 0xba, 0xf8, 0xda, 0x7c, 0x86, 0x31, + 0x9d, 0xdf, 0xb2, 0x3c, 0xc5, 0xae, 0x3a, 0x79, 0xb0, 0x5f, 0x19, 0xdf, 0xb2, 0x3c, 0x64, 0x5c, + 0xc9, 0xdb, 0x30, 0xe1, 0xb8, 0x0e, 0x2d, 0x8f, 0x71, 0xee, 0x8b, 0x99, 0xb8, 0x5f, 0x73, 0x1d, + 0x5d, 0xdb, 0x6a, 0xe1, 0x60, 0xbf, 0x32, 0xc1, 0x20, 0xc8, 0x19, 0x9b, 0x3f, 0x33, 0xa0, 0xb8, + 0xe8, 0xb5, 0xfa, 0x5d, 0xea, 0x04, 0x3e, 0xf1, 0x00, 0x7a, 0x96, 0x67, 0x75, 0x69, 0x40, 0x3d, + 0xbf, 0x6c, 0x9c, 0x1f, 0xbf, 0x50, 0xba, 0xf8, 0x4a, 0x26, 0xa1, 0x9b, 0x8a, 0x4d, 0x95, 0x7c, + 0x67, 0xbf, 0xf2, 0xd8, 0xc1, 0x7e, 0x05, 0x34, 0xc8, 0xc7, 0x88, 0x14, 0xe2, 0x40, 0xd1, 0xf2, + 0x02, 0xbb, 0x69, 0xd5, 0x03, 0xbf, 0x3c, 0xc6, 0x45, 0xbe, 0x9c, 0x49, 0xe4, 0xa2, 0xe4, 0x52, + 0x3d, 0x2e, 0x25, 0x16, 0x15, 0xc4, 0xc7, 0x50, 0x84, 0xf9, 0x93, 0x71, 0x28, 0x28, 0x04, 0x39, + 0x0f, 0x13, 0x8e, 0xd5, 0x15, 0x03, 0x5e, 0xac, 0x4e, 0xc9, 0x82, 0x13, 0xd7, 0xac, 0x2e, 0xeb, + 0x20, 0xab, 0x4b, 0x19, 0x45, 0xcf, 0x0a, 0xda, 0x7c, 0x04, 0x22, 0x14, 0x9b, 0x56, 0xd0, 0x46, + 0x8e, 0x21, 0x67, 0x61, 0xa2, 0xeb, 0x36, 0x68, 0x79, 0xfc, 0xbc, 0x71, 0x21, 0x27, 0x3a, 0x78, + 0xdd, 0x6d, 0x50, 0xe4, 0x50, 0x56, 0xbe, 0xe9, 0xb9, 0xdd, 0xf2, 0x44, 0xbc, 0xfc, 0x8a, 0xe7, + 0x76, 0x91, 0x63, 0xc8, 0xd7, 0x0d, 0x98, 0x55, 0xd5, 0xbb, 0xea, 0xd6, 0xad, 0xc0, 0x76, 0x9d, + 0x72, 0x8e, 0x0f, 0xf8, 0xa5, 0x91, 0x3a, 0x42, 0x31, 0xab, 0x96, 0xa5, 0xd4, 0xd9, 0x24, 0x06, + 0x07, 0x04, 0x93, 0x8b, 0x00, 0xad, 0x8e, 0xbb, 0x6d, 0x75, 0x58, 0x1f, 0x94, 0xf3, 0xbc, 0xd6, + 0x7a, 0x08, 0x57, 0x35, 0x06, 0x23, 0x54, 0x64, 0x07, 0x26, 0x2d, 0xb1, 0x2a, 0xca, 0x93, 0xbc, + 0xde, 0xcb, 0x19, 0xeb, 0x1d, 0x5b, 0x59, 0xd5, 0xd2, 0xc1, 0x7e, 0x65, 0x52, 0x02, 0x51, 0x49, + 0x20, 0x9f, 0x80, 0x82, 0xdb, 0x63, 0x55, 0xb5, 0x3a, 0xe5, 0xc2, 0x79, 0xe3, 0x42, 0xa1, 0x3a, + 0x2b, 0xab, 0x57, 0xd8, 0x90, 0x70, 0xd4, 0x14, 0xe6, 0x3f, 0xe7, 0x61, 0xa0, 0xd5, 0xe4, 0x39, + 0x28, 0x49, 0x6e, 0x57, 0xdd, 0x96, 0xcf, 0x07, 0xbf, 0x50, 0x9d, 0x39, 0xd8, 0xaf, 0x94, 0x16, + 0x43, 0x30, 0x46, 0x69, 0xc8, 0x4d, 0x18, 0xf3, 0x9f, 0x97, 0xcb, 0xf0, 0xd5, 0x4c, 0xad, 0xab, + 0x3d, 0xaf, 0x27, 0x68, 0xfe, 0x60, 0xbf, 0x32, 0x56, 0x7b, 0x1e, 0xc7, 0xfc, 0xe7, 0x99, 0xfa, + 0x68, 0xd9, 0x01, 0x9f, 0x3c, 0x59, 0xd5, 0xc7, 0xaa, 0x1d, 0x68, 0xd6, 0x5c, 0x7d, 0xac, 0xda, + 0x01, 0x32, 0xae, 0x4c, 0x7d, 0xb4, 0x83, 0xa0, 0xc7, 0x27, 0x5f, 0x56, 0xf5, 0x71, 0x79, 0x6b, + 0x6b, 0x53, 0xb3, 0xe7, 0xb3, 0x9b, 0x41, 0x90, 0x33, 0x26, 0xef, 0xb1, 0x9e, 0x14, 0x38, 0xd7, + 0xdb, 0x93, 0xb3, 0xf6, 0xf2, 0x48, 0xb3, 0xd6, 0xf5, 0xf6, 0xb4, 0x38, 0x39, 0x26, 0x1a, 0x81, + 0x51, 0x69, 0xbc, 0x75, 0x8d, 0xa6, 0xcf, 0x27, 0x69, 0xe6, 0xd6, 0x2d, 0xaf, 0xd4, 0x12, 0xad, + 0x5b, 0x5e, 0xa9, 0x21, 0x67, 0xcc, 0xc6, 0xc6, 0xb3, 0x76, 0xe5, 0x9c, 0xce, 0x36, 0x36, 0x68, + 0xed, 0xc6, 0xc7, 0x06, 0xad, 0x5d, 0x64, 0x5c, 0x19, 0x73, 0xd7, 0xf7, 0xf9, 0x14, 0xce, 0xca, + 0x7c, 0xa3, 0x56, 0x8b, 0x33, 0xdf, 0xa8, 0xd5, 0x90, 0x71, 0xe5, 0xb3, 0xaa, 0xee, 0x97, 0x8b, + 0xa3, 0xcc, 0xaa, 0xa5, 0x04, 0xf3, 0xd5, 0xa5, 0x1a, 0x32, 0xae, 0x66, 0x0b, 0x4e, 0x29, 0x0c, + 0xd2, 0x9e, 0xeb, 0xdb, 0x7c, 0x68, 0x68, 0x93, 0x2c, 0x40, 0xb1, 0xee, 0x3a, 0x4d, 0xbb, 0xb5, + 0x6e, 0xf5, 0xa4, 0x4a, 0xd5, 0xba, 0x78, 0x49, 0x21, 0x30, 0xa4, 0x21, 0x4f, 0xc2, 0xf8, 0x0e, + 0xdd, 0x93, 0xba, 0xb5, 0x24, 0x49, 0xc7, 0xaf, 0xd0, 0x3d, 0x64, 0x70, 0xf3, 0xdb, 0x06, 0x9c, + 0x48, 0x99, 0x16, 0xac, 0x58, 0xdf, 0xeb, 0x48, 0x09, 0xba, 0xd8, 0x75, 0xbc, 0x8a, 0x0c, 0x4e, + 0xbe, 0x6a, 0xc0, 0x4c, 0x64, 0x9e, 0x2c, 0xf6, 0xa5, 0xfa, 0xce, 0xae, 0x97, 0x62, 0xbc, 0xaa, + 0x67, 0xa4, 0xc4, 0x99, 0x04, 0x02, 0x93, 0x52, 0xcd, 0x7f, 0xe5, 0xf6, 0x42, 0x0c, 0x46, 0x2c, + 0x38, 0xd6, 0xf7, 0xa9, 0xc7, 0x36, 0x97, 0x1a, 0xad, 0x7b, 0x34, 0x90, 0xa6, 0xc3, 0xd3, 0xf3, + 0xc2, 0x78, 0x61, 0xb5, 0x98, 0x67, 0xa6, 0xda, 0xfc, 0x9d, 0xe7, 0xe6, 0x05, 0xc5, 0x15, 0xba, + 0x57, 0xa3, 0x1d, 0xca, 0x78, 0x54, 0xc9, 0xc1, 0x7e, 0xe5, 0xd8, 0xf5, 0x18, 0x03, 0x4c, 0x30, + 0x64, 0x22, 0x7a, 0x96, 0xef, 0xef, 0xba, 0x5e, 0x43, 0x8a, 0x18, 0x7b, 0x60, 0x11, 0x9b, 0x31, + 0x06, 0x98, 0x60, 0x68, 0xfe, 0x9d, 0x01, 0x93, 0x55, 0xab, 0xbe, 0xe3, 0x36, 0x9b, 0x4c, 0x23, + 0x37, 0xfa, 0x9e, 0xd8, 0xb7, 0xc4, 0x98, 0x68, 0x8d, 0xbc, 0x2c, 0xe1, 0xa8, 0x29, 0xc8, 0x16, + 0xe4, 0x45, 0x77, 0xc8, 0x4a, 0x7d, 0x2a, 0x52, 0x29, 0x6d, 0xb4, 0xf1, 0xe1, 0x60, 0x46, 0xdb, + 0xbc, 0x30, 0xda, 0xe6, 0xd7, 0x9c, 0x60, 0x83, 0x19, 0x49, 0xb6, 0xd3, 0xaa, 0xc2, 0xc1, 0x7e, + 0x25, 0xbf, 0xc2, 0x79, 0xa0, 0xe4, 0x45, 0x5e, 0x80, 0x52, 0xd7, 0x7a, 0x57, 0x89, 0xe3, 0xea, + 0xb4, 0x58, 0x3d, 0x21, 0xab, 0x51, 0x5a, 0x0f, 0x51, 0x18, 0xa5, 0x33, 0xdf, 0x82, 0xdc, 0x92, + 0x55, 0x6f, 0x53, 0x72, 0x3d, 0x39, 0x75, 0x4b, 0x17, 0x2f, 0xa4, 0xf5, 0x96, 0x9e, 0xc6, 0xd1, + 0x0e, 0x9b, 0x1e, 0x36, 0xc1, 0xcd, 0x8f, 0x0c, 0x38, 0xb3, 0xd4, 0xe9, 0xfb, 0x01, 0xf5, 0x6e, + 0xca, 0x79, 0xb5, 0x45, 0xbb, 0xbd, 0x8e, 0x15, 0x50, 0xf2, 0xeb, 0x50, 0x60, 0x06, 0x73, 0xc3, + 0x0a, 0x2c, 0x29, 0x71, 0x78, 0x57, 0xf0, 0x99, 0xc9, 0xa8, 0x59, 0x1d, 0x36, 0xb6, 0x6f, 0xd3, + 0x7a, 0xb0, 0x4e, 0x03, 0x2b, 0xdc, 0x99, 0x43, 0x18, 0x6a, 0xae, 0x64, 0x07, 0x26, 0xfc, 0x1e, + 0xad, 0xcb, 0x8e, 0x5e, 0xcb, 0x34, 0xf9, 0x93, 0xd5, 0xae, 0xf5, 0x68, 0x3d, 0x34, 0x63, 0xd8, + 0x17, 0x72, 0x21, 0xe6, 0x7f, 0x18, 0xf0, 0xc4, 0x90, 0xa6, 0x5e, 0xb5, 0xfd, 0x80, 0xbc, 0x39, + 0xd0, 0xdc, 0xf9, 0xc3, 0x35, 0x97, 0x95, 0xe6, 0x8d, 0xd5, 0xb3, 0x4a, 0x41, 0x22, 0x4d, 0x7d, + 0x07, 0x72, 0x76, 0x40, 0xbb, 0xca, 0x82, 0xbc, 0x9a, 0xa9, 0xad, 0x43, 0xaa, 0x5f, 0x9d, 0x96, + 0x82, 0x73, 0x6b, 0x4c, 0x04, 0x0a, 0x49, 0xe6, 0x3f, 0x1a, 0xc0, 0x06, 0xbd, 0x61, 0x4b, 0x9b, + 0x62, 0x22, 0xd8, 0xeb, 0x29, 0x4b, 0xf2, 0x49, 0xd5, 0x41, 0x5b, 0x7b, 0x3d, 0x7a, 0x77, 0xbf, + 0x32, 0xad, 0x09, 0x19, 0x00, 0x39, 0x29, 0x79, 0x0b, 0xf2, 0x7e, 0x60, 0x05, 0x7d, 0x5f, 0x2a, + 0xc0, 0x15, 0x59, 0x28, 0x5f, 0xe3, 0xd0, 0xbb, 0xfb, 0x95, 0x43, 0xb9, 0x5b, 0xf3, 0x9a, 0xb7, + 0x28, 0x87, 0x92, 0x2b, 0x79, 0x16, 0x26, 0xbb, 0xd4, 0xf7, 0xad, 0x16, 0x95, 0xeb, 0x61, 0x46, + 0x0a, 0x98, 0x5c, 0x17, 0x60, 0x54, 0x78, 0xf3, 0xf3, 0x00, 0x4b, 0xae, 0x13, 0xd8, 0x4e, 0x9f, + 0x6e, 0x38, 0xe4, 0x29, 0xc8, 0x51, 0xcf, 0x73, 0x3d, 0x69, 0x19, 0xe9, 0xe6, 0x5f, 0x62, 0x40, + 0x14, 0x38, 0xf2, 0x0c, 0x5b, 0xc7, 0x76, 0x87, 0x36, 0x78, 0xed, 0x0b, 0xd5, 0x63, 0xaa, 0xf6, + 0x2b, 0x1c, 0x8a, 0x12, 0x6b, 0xce, 0xc3, 0xe4, 0x12, 0xf3, 0xae, 0xa8, 0xc7, 0xf8, 0x86, 0xfe, + 0x55, 0x31, 0xe4, 0x1b, 0xf3, 0xb1, 0xbe, 0x3b, 0x06, 0x53, 0x4b, 0x9e, 0xeb, 0xa8, 0x51, 0x78, + 0x04, 0xeb, 0xa4, 0x15, 0x5b, 0x27, 0xd9, 0x8c, 0xee, 0x68, 0x95, 0x87, 0xad, 0x11, 0xe2, 0xea, + 0x11, 0x17, 0xf6, 0xde, 0xea, 0xe8, 0xa2, 0x38, 0xbb, 0xb0, 0xf3, 0xe3, 0x53, 0xc0, 0xfc, 0xbe, + 0x01, 0xb3, 0x51, 0xf2, 0x47, 0xb0, 0x12, 0x9b, 0xf1, 0x95, 0xb8, 0x38, 0x72, 0x13, 0x87, 0x2c, + 0xbf, 0xff, 0xca, 0xc5, 0x9b, 0xc6, 0xba, 0x99, 0xf9, 0x52, 0x53, 0xbb, 0x11, 0x80, 0x6c, 0xdf, + 0xe2, 0x48, 0xaa, 0x8f, 0x0f, 0xe7, 0xc7, 0x65, 0x25, 0xa6, 0xa2, 0xd0, 0xbb, 0x89, 0x6f, 0x8c, + 0x09, 0x67, 0x1b, 0xa3, 0x5f, 0x6f, 0xd3, 0x46, 0xbf, 0x43, 0xe5, 0x12, 0xd7, 0x1d, 0x57, 0x93, + 0x70, 0xd4, 0x14, 0xe4, 0x4d, 0x38, 0x5e, 0x77, 0x9d, 0x7a, 0xdf, 0xf3, 0xa8, 0x53, 0xdf, 0xdb, + 0xe4, 0x81, 0x18, 0xb9, 0x70, 0xe7, 0x65, 0xb1, 0xe3, 0x4b, 0x49, 0x82, 0xbb, 0x69, 0x40, 0x1c, + 0x64, 0xc4, 0x94, 0x81, 0xdf, 0xf7, 0x7b, 0xd4, 0x69, 0x70, 0x6f, 0xa0, 0x10, 0x2a, 0x83, 0x9a, + 0x00, 0xa3, 0xc2, 0x93, 0xeb, 0x70, 0xc6, 0x0f, 0x98, 0x29, 0xe3, 0xb4, 0x96, 0xa9, 0xd5, 0xe8, + 0xd8, 0x0e, 0x33, 0x2c, 0x5c, 0xa7, 0xe1, 0x73, 0x03, 0x7f, 0xbc, 0xfa, 0xc4, 0xc1, 0x7e, 0xe5, + 0x4c, 0x2d, 0x9d, 0x04, 0x87, 0x95, 0x25, 0x6f, 0xc1, 0x9c, 0xdf, 0xaf, 0xd7, 0xa9, 0xef, 0x37, + 0xfb, 0x9d, 0xd7, 0xdd, 0x6d, 0xff, 0xb2, 0xed, 0x33, 0xab, 0xe8, 0xaa, 0xdd, 0xb5, 0x03, 0x6e, + 0xc4, 0xe7, 0xaa, 0xe7, 0x0e, 0xf6, 0x2b, 0x73, 0xb5, 0xa1, 0x54, 0x78, 0x0f, 0x0e, 0x04, 0xe1, + 0xb4, 0x50, 0x39, 0x03, 0xbc, 0x27, 0x39, 0xef, 0xb9, 0x83, 0xfd, 0xca, 0xe9, 0x95, 0x54, 0x0a, + 0x1c, 0x52, 0x92, 0x8d, 0x60, 0x60, 0x77, 0xe9, 0x17, 0x5d, 0x87, 0x72, 0x4b, 0x3d, 0x32, 0x82, + 0x5b, 0x12, 0x8e, 0x9a, 0x82, 0xdc, 0x0e, 0x27, 0x1f, 0x5b, 0x14, 0xd2, 0xfc, 0x7e, 0x70, 0x6d, + 0x75, 0x92, 0xf9, 0xea, 0x37, 0x23, 0x9c, 0xd8, 0xc2, 0xc2, 0x18, 0x6f, 0xf3, 0x1f, 0xc6, 0x80, + 0x0c, 0x2a, 0x02, 0x72, 0x05, 0xf2, 0x56, 0x3d, 0x60, 0x9e, 0xb8, 0x88, 0xde, 0x3c, 0x95, 0x66, + 0xc4, 0x08, 0x51, 0x48, 0x9b, 0x94, 0xcd, 0x10, 0x1a, 0x6a, 0x8f, 0x45, 0x5e, 0x14, 0x25, 0x0b, + 0xe2, 0xc2, 0xf1, 0x8e, 0xe5, 0x07, 0x6a, 0xae, 0x36, 0x58, 0x93, 0xa5, 0x92, 0xfc, 0x3f, 0x87, + 0x6b, 0x14, 0x2b, 0x51, 0x3d, 0xc5, 0x66, 0xee, 0xd5, 0x24, 0x23, 0x1c, 0xe4, 0x4d, 0x3c, 0x80, + 0xba, 0xda, 0xcc, 0x98, 0x8e, 0xcc, 0x1e, 0x7f, 0xd2, 0x7b, 0x62, 0xa8, 0xfa, 0x35, 0xc8, 0xc7, + 0x88, 0x14, 0xf3, 0xa7, 0x79, 0x98, 0x5c, 0x5e, 0x5c, 0xdd, 0xb2, 0xfc, 0x9d, 0x43, 0x84, 0x83, + 0xd8, 0x84, 0x90, 0x66, 0x41, 0x72, 0x49, 0x2b, 0x73, 0x01, 0x35, 0x05, 0x71, 0xa1, 0x68, 0xa9, + 0xe0, 0x9a, 0x54, 0xf9, 0xaf, 0x64, 0x74, 0x41, 0x24, 0x97, 0x68, 0x70, 0x4b, 0x82, 0x30, 0x94, + 0x41, 0x7c, 0x28, 0x29, 0xe1, 0x48, 0x9b, 0xd2, 0xef, 0xcf, 0x18, 0x94, 0x0c, 0xf9, 0x08, 0x3f, + 0x3c, 0x02, 0xc0, 0xa8, 0x14, 0xf2, 0x69, 0x98, 0x6a, 0x50, 0xa6, 0x39, 0xa8, 0x53, 0xb7, 0x29, + 0x53, 0x12, 0xe3, 0xac, 0x5f, 0x98, 0xb2, 0x5c, 0x8e, 0xc0, 0x31, 0x46, 0x45, 0x6e, 0x43, 0x71, + 0xd7, 0x0e, 0xda, 0x5c, 0xa7, 0x97, 0xf3, 0x7c, 0xa8, 0x3f, 0x93, 0xa9, 0xa2, 0x8c, 0x43, 0xd8, + 0x2d, 0x37, 0x15, 0x4f, 0x0c, 0xd9, 0x33, 0xc7, 0x94, 0x7d, 0xf0, 0x08, 0x24, 0xd7, 0x06, 0xc5, + 0x78, 0x01, 0x8e, 0xc0, 0x90, 0x86, 0xf8, 0x30, 0xc5, 0x3e, 0x6a, 0xf4, 0x9d, 0x3e, 0x5b, 0x21, + 0xd2, 0x4b, 0xcf, 0x16, 0x97, 0x54, 0x4c, 0x44, 0x8f, 0xdc, 0x8c, 0xb0, 0xc5, 0x98, 0x10, 0x36, + 0xfb, 0x76, 0xdb, 0xd4, 0xe1, 0x6a, 0x23, 0x32, 0xfb, 0x6e, 0xb6, 0xa9, 0x83, 0x1c, 0x43, 0x5c, + 0xbe, 0x3e, 0xa4, 0x99, 0x56, 0x86, 0x11, 0xa2, 0x51, 0xa1, 0xb5, 0x57, 0x3d, 0x26, 0x17, 0x87, + 0xfc, 0xc6, 0x88, 0x08, 0x66, 0xe4, 0xb9, 0xce, 0xa5, 0x77, 0xed, 0xa0, 0x5c, 0xe2, 0x95, 0xd2, + 0x9a, 0x62, 0x83, 0x43, 0x51, 0x62, 0xd9, 0xee, 0x22, 0x06, 0xd7, 0x2f, 0x4f, 0xc5, 0x4d, 0x4d, + 0x31, 0x03, 0x7c, 0x54, 0x78, 0xf3, 0x6f, 0x0d, 0x28, 0xb1, 0xf5, 0xa6, 0xd6, 0xc8, 0x33, 0x90, + 0x0f, 0x2c, 0xaf, 0x25, 0xfd, 0xe0, 0x88, 0x88, 0x2d, 0x0e, 0x45, 0x89, 0x25, 0x16, 0xe4, 0x02, + 0xcb, 0xdf, 0x51, 0x76, 0xc5, 0xe7, 0x32, 0x35, 0x5b, 0x2e, 0xf4, 0xd0, 0xa4, 0x60, 0x5f, 0x3e, + 0x0a, 0xce, 0xe4, 0x02, 0x14, 0xd8, 0x3e, 0xb0, 0x62, 0xf9, 0x22, 0x20, 0x57, 0xa8, 0x4e, 0xb1, + 0x85, 0xbd, 0x22, 0x61, 0xa8, 0xb1, 0xe6, 0x0b, 0x90, 0xbb, 0x74, 0x87, 0x3a, 0x7c, 0x83, 0xf0, + 0xa5, 0x1b, 0x98, 0xf4, 0x7d, 0x95, 0x7b, 0x88, 0x9a, 0xc2, 0x7c, 0x13, 0x8e, 0x5d, 0x7a, 0x97, + 0xd6, 0xfb, 0x81, 0xeb, 0x09, 0x77, 0x91, 0xbc, 0x0e, 0xc4, 0xa7, 0xde, 0x1d, 0xbb, 0x4e, 0x17, + 0xeb, 0x75, 0x66, 0x26, 0x5f, 0x0b, 0xf5, 0xcf, 0x9c, 0xe4, 0x44, 0x6a, 0x03, 0x14, 0x98, 0x52, + 0xca, 0xfc, 0x13, 0x03, 0x4a, 0x91, 0xa8, 0x0d, 0xd3, 0x3e, 0xad, 0xa5, 0x5a, 0xb5, 0x5f, 0xdf, + 0xd1, 0x41, 0x86, 0x57, 0xb2, 0x86, 0x82, 0x04, 0x97, 0x70, 0xd5, 0x68, 0x10, 0x86, 0x32, 0xee, + 0x17, 0xce, 0xf9, 0x6b, 0x03, 0xc2, 0x72, 0x6c, 0xdc, 0xb7, 0xc3, 0xaa, 0x45, 0xc6, 0x5d, 0xf2, + 0x95, 0x58, 0xf2, 0xbe, 0x01, 0x67, 0xe2, 0x8d, 0xe5, 0xae, 0xf7, 0x83, 0x87, 0x35, 0x2a, 0x52, + 0xc0, 0x99, 0x5a, 0x3a, 0x37, 0x1c, 0x26, 0xc6, 0xbc, 0x01, 0xb9, 0x55, 0xab, 0xdf, 0xa2, 0x87, + 0x72, 0x60, 0xd8, 0x2c, 0xf2, 0xa8, 0xd5, 0x09, 0xd4, 0x66, 0x29, 0x67, 0x11, 0x4a, 0x18, 0x6a, + 0xac, 0xf9, 0x97, 0x13, 0x50, 0x8a, 0x04, 0x6f, 0x99, 0x02, 0xf0, 0x68, 0xcf, 0x4d, 0x6e, 0x3f, + 0x48, 0x7b, 0x2e, 0x72, 0x0c, 0x9b, 0x6e, 0x1e, 0xbd, 0x63, 0xfb, 0xb6, 0xeb, 0x24, 0xb7, 0x1f, + 0x94, 0x70, 0xd4, 0x14, 0xa4, 0x02, 0xb9, 0x06, 0xed, 0x05, 0x6d, 0x3e, 0x99, 0x27, 0x44, 0x3e, + 0x6b, 0x99, 0x01, 0x50, 0xc0, 0x19, 0x41, 0x93, 0x06, 0xf5, 0x76, 0x79, 0x82, 0xab, 0x6c, 0x4e, + 0xb0, 0xc2, 0x00, 0x28, 0xe0, 0x29, 0xc1, 0xaa, 0xdc, 0xc3, 0x0f, 0x56, 0xe5, 0x8f, 0x38, 0x58, + 0x45, 0x7a, 0x70, 0xc2, 0xf7, 0xdb, 0x9b, 0x9e, 0x7d, 0xc7, 0x0a, 0x68, 0x38, 0x7b, 0x26, 0x1f, + 0x44, 0xce, 0x99, 0x83, 0xfd, 0xca, 0x89, 0x5a, 0xed, 0x72, 0x92, 0x0b, 0xa6, 0xb1, 0x26, 0x35, + 0x38, 0x65, 0x3b, 0x3e, 0xad, 0xf7, 0x3d, 0xba, 0xd6, 0x72, 0x5c, 0x8f, 0x5e, 0x76, 0x7d, 0xc6, + 0x4e, 0x66, 0x2c, 0x54, 0x78, 0xe0, 0xd4, 0x5a, 0x1a, 0x11, 0xa6, 0x97, 0x35, 0xbf, 0x6b, 0xc0, + 0x54, 0x34, 0x5e, 0x4d, 0x7c, 0x80, 0xf6, 0xf2, 0x4a, 0x4d, 0xa8, 0x12, 0xb9, 0xc2, 0x5f, 0xcd, + 0x1c, 0x06, 0x17, 0x6c, 0x42, 0x7b, 0x29, 0x84, 0x61, 0x44, 0xcc, 0x21, 0x12, 0x62, 0x4f, 0x41, + 0xae, 0xe9, 0x7a, 0x75, 0x2a, 0x75, 0xa8, 0x5e, 0x25, 0x2b, 0x0c, 0x88, 0x02, 0x67, 0x7e, 0x64, + 0x40, 0x44, 0x02, 0xf9, 0x2d, 0x98, 0x66, 0x32, 0xae, 0x78, 0xdb, 0xb1, 0xd6, 0x54, 0x33, 0xb7, + 0x46, 0x73, 0xaa, 0x9e, 0x92, 0xf2, 0xa7, 0x63, 0x60, 0x8c, 0xcb, 0x23, 0xff, 0x17, 0x8a, 0x56, + 0xa3, 0xe1, 0x51, 0xdf, 0xa7, 0x62, 0x8b, 0x29, 0x8a, 0xb0, 0xde, 0xa2, 0x02, 0x62, 0x88, 0x67, + 0xcb, 0xb0, 0xdd, 0x68, 0xfa, 0x6c, 0x66, 0x4b, 0x0f, 0x4d, 0x2f, 0x43, 0x26, 0x84, 0xc1, 0x51, + 0x53, 0x98, 0xdf, 0x98, 0x80, 0xb8, 0x6c, 0xd2, 0x80, 0x99, 0x1d, 0x6f, 0x7b, 0x89, 0x87, 0x1e, + 0xb3, 0x04, 0x81, 0x4f, 0x1c, 0xec, 0x57, 0x66, 0xae, 0xc4, 0x39, 0x60, 0x92, 0xa5, 0x94, 0x72, + 0x85, 0xee, 0x05, 0xd6, 0x76, 0x16, 0x85, 0xa9, 0xa4, 0x44, 0x39, 0x60, 0x92, 0x25, 0x79, 0x01, + 0x4a, 0x3b, 0xde, 0xb6, 0x5a, 0xe4, 0xc9, 0xc8, 0xeb, 0x95, 0x10, 0x85, 0x51, 0x3a, 0xd6, 0x85, + 0x3b, 0xde, 0x36, 0x53, 0x8a, 0x2a, 0x37, 0xaa, 0xbb, 0xf0, 0x8a, 0x84, 0xa3, 0xa6, 0x20, 0x3d, + 0x20, 0x3b, 0xaa, 0xf7, 0x74, 0xa0, 0x55, 0xea, 0xa2, 0xc3, 0xc7, 0x69, 0x4f, 0xb3, 0xcd, 0xf4, + 0xca, 0x00, 0x1f, 0x4c, 0xe1, 0x4d, 0x3e, 0x0f, 0x67, 0x76, 0xbc, 0x6d, 0xb9, 0x55, 0x6c, 0x7a, + 0xb6, 0x53, 0xb7, 0x7b, 0xb1, 0xa4, 0xa8, 0xde, 0x4e, 0xae, 0xa4, 0x93, 0xe1, 0xb0, 0xf2, 0xe6, + 0x27, 0x61, 0x2a, 0x9a, 0x54, 0xbb, 0x4f, 0x3a, 0xc3, 0xfc, 0xc0, 0x80, 0x22, 0x77, 0x4a, 0x5b, + 0xcc, 0x32, 0xd5, 0x5b, 0xd0, 0xf8, 0x3d, 0xb6, 0xa0, 0x26, 0x4c, 0x8a, 0xdd, 0xd3, 0xe7, 0x9a, + 0xbd, 0x74, 0xf1, 0xa5, 0x6c, 0x5e, 0x07, 0x3f, 0x16, 0x11, 0xda, 0x72, 0x62, 0x67, 0xf6, 0x51, + 0x31, 0x37, 0xff, 0xdd, 0x80, 0xfc, 0x9a, 0xd3, 0xeb, 0xff, 0x92, 0x1c, 0x1d, 0x58, 0x87, 0x09, + 0xe6, 0x4f, 0x90, 0x97, 0xe2, 0xe7, 0x44, 0x9e, 0xd6, 0xfd, 0x7f, 0x77, 0xbf, 0x52, 0xa6, 0x4e, + 0xdd, 0x6d, 0xd8, 0x4e, 0x6b, 0xe1, 0xb6, 0xef, 0x3a, 0xf3, 0x68, 0xed, 0xaa, 0x60, 0xab, 0x28, + 0xf3, 0xd9, 0xc2, 0x07, 0x7f, 0x5a, 0x79, 0xec, 0xfd, 0x1f, 0x9c, 0x7f, 0xcc, 0xec, 0xc0, 0xc4, + 0x55, 0xdb, 0x39, 0x8c, 0xd7, 0xf9, 0x14, 0xe4, 0xfc, 0xba, 0xdb, 0x53, 0x2e, 0xa7, 0x1e, 0xf4, + 0x1a, 0x03, 0xa2, 0xc0, 0xa9, 0x69, 0x34, 0x3e, 0x64, 0x1a, 0x7d, 0xd9, 0x80, 0xe3, 0xeb, 0xb4, + 0xeb, 0xda, 0x5f, 0xb4, 0xc2, 0x58, 0x31, 0x2b, 0xd4, 0xb6, 0x03, 0x19, 0xe8, 0xd5, 0x85, 0x2e, + 0xdb, 0x01, 0x32, 0xf8, 0x7d, 0x2c, 0x3a, 0x9e, 0xf0, 0x63, 0x0a, 0xe7, 0x5a, 0xb8, 0xf2, 0xc3, + 0x84, 0x9f, 0x42, 0x60, 0x48, 0x63, 0x7e, 0xc5, 0x80, 0x49, 0x51, 0x09, 0xaa, 0x78, 0x1b, 0x43, + 0x78, 0xdf, 0x82, 0x1c, 0x2f, 0x27, 0x75, 0xd6, 0x67, 0xb3, 0xb9, 0x39, 0x8c, 0x83, 0xb0, 0x6b, + 0xf8, 0x4f, 0x14, 0x3c, 0xcd, 0xf7, 0xc7, 0xa1, 0xa0, 0x02, 0x2b, 0xe4, 0x2b, 0x06, 0x94, 0x2c, + 0xc7, 0x71, 0x03, 0x4b, 0xc4, 0x1d, 0xc4, 0xe4, 0xbd, 0x96, 0x49, 0xa0, 0x62, 0x3a, 0xbf, 0x18, + 0x32, 0xbc, 0xe4, 0x04, 0xde, 0x5e, 0xa8, 0x12, 0x23, 0x18, 0x8c, 0xca, 0x25, 0xef, 0x40, 0xbe, + 0x63, 0x6d, 0xd3, 0x8e, 0x9a, 0xcb, 0x6b, 0xa3, 0xd5, 0xe0, 0x2a, 0xe7, 0x25, 0x84, 0x6b, 0xe3, + 0x5a, 0x00, 0x51, 0x0a, 0x9a, 0x7b, 0x05, 0x66, 0x93, 0x15, 0x25, 0xb3, 0x91, 0x71, 0x11, 0x43, + 0x71, 0x52, 0xcd, 0x77, 0x3e, 0x0f, 0xd4, 0x44, 0x1e, 0x7b, 0xd1, 0x98, 0xfb, 0x0c, 0x94, 0x22, + 0x62, 0x1e, 0xa4, 0xa8, 0xf9, 0x06, 0x94, 0xd6, 0x69, 0xe0, 0xd9, 0x75, 0xce, 0xe0, 0x7e, 0xb3, + 0xe1, 0xa9, 0x18, 0x9f, 0x21, 0xa9, 0x83, 0x2f, 0xb2, 0xc9, 0xc5, 0x58, 0xfa, 0xcc, 0x53, 0xee, + 0x79, 0x6e, 0x97, 0x06, 0x6d, 0xda, 0x57, 0x23, 0x9a, 0xcd, 0x34, 0xda, 0xd4, 0x6c, 0x84, 0xa7, + 0x1c, 0x7e, 0x63, 0x44, 0x84, 0xf9, 0x2c, 0xe4, 0xd6, 0xfb, 0x01, 0x7d, 0xf7, 0xfe, 0xab, 0xd9, + 0xbc, 0x05, 0x53, 0x9c, 0xf4, 0xb2, 0xdb, 0x61, 0x8a, 0x82, 0xb5, 0xad, 0xcb, 0xbe, 0x93, 0x5e, + 0x05, 0x27, 0x42, 0x81, 0x63, 0xee, 0x52, 0xdb, 0xed, 0x34, 0xa8, 0x27, 0x7b, 0x40, 0x8f, 0xe8, + 0x65, 0x0e, 0x45, 0x89, 0x35, 0x7f, 0x6c, 0x40, 0x89, 0x17, 0x94, 0x0b, 0xbc, 0x03, 0x93, 0x6d, + 0x21, 0x47, 0xf6, 0x42, 0xb6, 0x58, 0x78, 0xb4, 0xc2, 0xe1, 0x86, 0x20, 0x01, 0xa8, 0x44, 0x30, + 0x69, 0xbb, 0x96, 0x1d, 0x30, 0x69, 0x63, 0x47, 0x2e, 0xed, 0xa6, 0xe0, 0x8c, 0x4a, 0x84, 0xf9, + 0xf3, 0x69, 0x80, 0x6b, 0x6e, 0x83, 0xca, 0xa6, 0xce, 0xc1, 0x98, 0xdd, 0x90, 0x9d, 0x08, 0xb2, + 0xd0, 0xd8, 0xda, 0x32, 0x8e, 0xd9, 0x0d, 0x3d, 0x2a, 0x63, 0x43, 0x75, 0xec, 0x0b, 0x50, 0x6a, + 0xd8, 0x7e, 0xaf, 0x63, 0xed, 0x5d, 0x4b, 0xb1, 0x63, 0x96, 0x43, 0x14, 0x46, 0xe9, 0xc8, 0x27, + 0x64, 0xde, 0x4f, 0xd8, 0x30, 0xe5, 0x44, 0xde, 0xaf, 0xc0, 0xaa, 0x17, 0x49, 0xf9, 0xbd, 0x08, + 0x53, 0x2a, 0x72, 0xc6, 0xa5, 0xe4, 0x78, 0xa9, 0x93, 0x2a, 0xb7, 0xb0, 0x15, 0xc1, 0x61, 0x8c, + 0x32, 0x19, 0xd9, 0xcb, 0x3f, 0x92, 0xc8, 0xde, 0x32, 0xcc, 0xfa, 0x81, 0xeb, 0xd1, 0x86, 0xa2, + 0x58, 0x5b, 0x2e, 0x93, 0x58, 0x43, 0x67, 0x6b, 0x09, 0x3c, 0x0e, 0x94, 0x20, 0x9b, 0x70, 0x72, + 0x37, 0x91, 0x52, 0xe5, 0x8d, 0x3f, 0xc1, 0x39, 0x9d, 0x95, 0x9c, 0x4e, 0xde, 0x4c, 0xa1, 0xc1, + 0xd4, 0x92, 0xe4, 0x25, 0x98, 0x56, 0xd5, 0xe4, 0x5b, 0x60, 0xf9, 0x24, 0x67, 0xa5, 0x2d, 0xfd, + 0xad, 0x28, 0x12, 0xe3, 0xb4, 0xe4, 0x53, 0x90, 0xeb, 0xb5, 0x2d, 0x9f, 0xca, 0x40, 0xa0, 0x8a, + 0xb2, 0xe4, 0x36, 0x19, 0xf0, 0xee, 0x7e, 0xa5, 0xc8, 0xc6, 0x8c, 0x7f, 0xa0, 0x20, 0x24, 0x17, + 0x01, 0xb6, 0xdd, 0xbe, 0xd3, 0xb0, 0xbc, 0xbd, 0xb5, 0x65, 0x99, 0x07, 0xd0, 0xb6, 0x49, 0x55, + 0x63, 0x30, 0x42, 0x15, 0x4d, 0xbe, 0x16, 0xef, 0x9d, 0x7c, 0x25, 0xb7, 0xa0, 0xc8, 0x73, 0x26, + 0xb4, 0xb1, 0x18, 0xc8, 0xa0, 0xde, 0x83, 0x84, 0xd7, 0xf5, 0x8e, 0x5b, 0x53, 0x4c, 0x30, 0xe4, + 0x47, 0xde, 0x02, 0x68, 0xda, 0x8e, 0xed, 0xb7, 0x39, 0xf7, 0xd2, 0x03, 0x73, 0xd7, 0xed, 0x5c, + 0xd1, 0x5c, 0x30, 0xc2, 0x91, 0xfc, 0xc4, 0x80, 0xe3, 0x1e, 0xf5, 0xdd, 0xbe, 0x57, 0xa7, 0xbe, + 0x3e, 0x7f, 0x71, 0x8a, 0x2f, 0xfe, 0x1b, 0x19, 0xcf, 0xab, 0xaa, 0x15, 0x3d, 0x8f, 0x49, 0xc6, + 0x62, 0x37, 0xa3, 0x2a, 0x1d, 0x36, 0x80, 0xbf, 0x9b, 0x06, 0xfc, 0xf2, 0x0f, 0x2b, 0x95, 0xc1, + 0x63, 0xd0, 0x9a, 0x39, 0x9b, 0x51, 0xbf, 0xfb, 0xc3, 0xca, 0xac, 0xfa, 0xd6, 0x27, 0x45, 0x06, + 0xdb, 0xc5, 0x54, 0x75, 0xcf, 0x6d, 0xac, 0x6d, 0xca, 0x28, 0xa7, 0x56, 0xd5, 0x9b, 0x0c, 0x88, + 0x02, 0x47, 0x2e, 0x40, 0xa1, 0x61, 0xd1, 0xae, 0xeb, 0xd0, 0x46, 0x79, 0x3a, 0x0c, 0x00, 0x2d, + 0x4b, 0x18, 0x6a, 0x2c, 0x79, 0x1b, 0xf2, 0x36, 0x37, 0x9f, 0xcb, 0xc7, 0xf8, 0xc0, 0x64, 0x33, + 0xd3, 0x85, 0x05, 0x2e, 0x8e, 0xc5, 0x88, 0xdf, 0x28, 0xd9, 0x92, 0x3a, 0x4c, 0xba, 0xfd, 0x80, + 0x4b, 0x98, 0xe1, 0x12, 0xb2, 0x85, 0x4d, 0x37, 0x04, 0x0f, 0x71, 0x22, 0x53, 0x7e, 0xa0, 0xe2, + 0xcc, 0xda, 0x5b, 0x6f, 0xdb, 0x9d, 0x86, 0x47, 0x9d, 0xf2, 0x2c, 0xf7, 0x9c, 0x79, 0x7b, 0x97, + 0x24, 0x0c, 0x35, 0x96, 0xfc, 0x7f, 0x98, 0x76, 0xfb, 0x01, 0x5f, 0x25, 0x6c, 0x94, 0xfd, 0xf2, + 0x71, 0x4e, 0x7e, 0x9c, 0xad, 0xd9, 0x8d, 0x28, 0x02, 0xe3, 0x74, 0x4c, 0x6f, 0xb6, 0x5d, 0x3f, + 0x60, 0x1f, 0x5c, 0x75, 0x9c, 0x8e, 0xeb, 0xcd, 0xcb, 0x11, 0x1c, 0xc6, 0x28, 0xc9, 0xd7, 0x0d, + 0x38, 0xde, 0x4d, 0x9a, 0xbd, 0xe5, 0x33, 0xbc, 0x33, 0x56, 0x32, 0x1a, 0x58, 0x09, 0x6e, 0x22, + 0xc1, 0x35, 0x00, 0xc6, 0x41, 0xb9, 0x73, 0xcb, 0x70, 0x3a, 0x7d, 0x4e, 0xdf, 0xcf, 0x74, 0x1a, + 0x8f, 0x9a, 0x4e, 0xc7, 0x60, 0x2a, 0x7a, 0xa8, 0x9b, 0x07, 0x7e, 0x23, 0x67, 0x01, 0x89, 0x0b, + 0x45, 0xb7, 0x76, 0x14, 0x81, 0xdf, 0x8d, 0xda, 0x40, 0xe0, 0x57, 0x83, 0x30, 0x94, 0x71, 0xbf, + 0xc0, 0xef, 0x5f, 0x8d, 0x41, 0x58, 0x8e, 0x79, 0xfe, 0xd4, 0x69, 0xf4, 0x5c, 0xdb, 0x09, 0x92, + 0x21, 0xf3, 0x4b, 0x12, 0x8e, 0x9a, 0x22, 0x12, 0x26, 0x1e, 0xbb, 0x67, 0x98, 0xb8, 0x0d, 0x33, + 0x16, 0x4f, 0x0d, 0x87, 0xf1, 0xbd, 0xf1, 0x07, 0x8a, 0xef, 0xe9, 0x43, 0x7d, 0x71, 0x2e, 0x98, + 0x64, 0xcb, 0x24, 0xf9, 0x61, 0x71, 0x2e, 0x69, 0x22, 0x93, 0xa4, 0x5a, 0x9c, 0x0b, 0x26, 0xd9, + 0x9a, 0x7f, 0x33, 0x06, 0x6a, 0xb5, 0xfd, 0x32, 0xf8, 0xd7, 0xc4, 0x84, 0xbc, 0x47, 0xfd, 0x7e, + 0x27, 0x90, 0xd6, 0x17, 0xd7, 0x68, 0xc8, 0x21, 0x28, 0x31, 0x4c, 0xd9, 0xd0, 0x77, 0xed, 0x60, + 0xc9, 0x6d, 0x28, 0x9b, 0x8b, 0x2b, 0x9b, 0x4b, 0x12, 0x86, 0x1a, 0x6b, 0xee, 0xc2, 0x34, 0x6b, + 0x57, 0xa7, 0x43, 0x3b, 0xb5, 0x80, 0xf6, 0x7c, 0xd2, 0x84, 0x9c, 0xcf, 0x7e, 0x8c, 0x64, 0x08, + 0x87, 0xf9, 0x76, 0xda, 0x8b, 0x38, 0xe2, 0x8c, 0x2f, 0x0a, 0xf6, 0xe6, 0xdd, 0x31, 0x28, 0xea, + 0x1e, 0x3d, 0x84, 0x77, 0x7f, 0x13, 0x26, 0x1b, 0xb4, 0x69, 0xb1, 0x76, 0x67, 0x3d, 0x12, 0x59, + 0x12, 0xa9, 0x36, 0xce, 0x04, 0x15, 0x37, 0xf2, 0x46, 0x34, 0x56, 0x94, 0x85, 0xed, 0xc0, 0x0d, + 0x18, 0xb2, 0x03, 0x45, 0xfe, 0x63, 0x45, 0xdd, 0x69, 0xc8, 0x3a, 0x0b, 0x6f, 0x28, 0x2e, 0x22, + 0xcc, 0xaa, 0x3f, 0x31, 0xe4, 0x9f, 0xb8, 0x8b, 0x90, 0x3b, 0xcc, 0x5d, 0x04, 0x73, 0x05, 0xd8, + 0x66, 0xbc, 0xba, 0x44, 0x5e, 0x86, 0x82, 0x2f, 0x15, 0xa4, 0xec, 0xfb, 0x8f, 0xe9, 0xcc, 0x9c, + 0x84, 0xdf, 0xdd, 0xaf, 0x4c, 0x73, 0x62, 0x05, 0x40, 0x5d, 0xc4, 0xfc, 0xea, 0x04, 0x44, 0x5c, + 0xbd, 0x43, 0x8c, 0x62, 0x23, 0xe1, 0xbd, 0xbf, 0x96, 0xd5, 0x7b, 0x57, 0x2e, 0xb1, 0x98, 0xfe, + 0x71, 0x87, 0x9d, 0xd5, 0xa3, 0x4d, 0x3b, 0x3d, 0xb9, 0x40, 0x74, 0x3d, 0x2e, 0xd3, 0x4e, 0x0f, + 0x39, 0x46, 0x67, 0x91, 0x27, 0x86, 0x66, 0x91, 0x6f, 0x41, 0xae, 0x65, 0xf5, 0x5b, 0x54, 0xc6, + 0x4f, 0xb3, 0x45, 0x56, 0x78, 0x42, 0x4c, 0x4c, 0x10, 0xfe, 0x13, 0x05, 0x4f, 0x36, 0x41, 0xda, + 0x2a, 0x58, 0x29, 0xbd, 0x94, 0x6c, 0x13, 0x44, 0x87, 0x3c, 0xc5, 0x04, 0xd1, 0x9f, 0x18, 0xf2, + 0x67, 0xe6, 0x4d, 0x5d, 0x9c, 0x2d, 0x94, 0xc9, 0x9c, 0xcf, 0x65, 0x4c, 0x86, 0x73, 0x1e, 0x62, + 0x15, 0xc9, 0x0f, 0x54, 0x9c, 0xcd, 0x05, 0x28, 0x45, 0x4e, 0xf1, 0xb3, 0xfe, 0xd5, 0x27, 0xe7, + 0x22, 0xfd, 0xbb, 0x6c, 0x05, 0x16, 0x72, 0x8c, 0xf9, 0xad, 0x71, 0xd0, 0xc6, 0x64, 0x34, 0xcd, + 0x6d, 0xd5, 0x23, 0x47, 0xa4, 0x63, 0x67, 0x6e, 0x5c, 0x07, 0x25, 0x96, 0xb9, 0x36, 0x5d, 0xea, + 0xb5, 0xf4, 0xe6, 0x2e, 0xb7, 0x3d, 0xed, 0xda, 0xac, 0x47, 0x91, 0x18, 0xa7, 0x65, 0x5b, 0x6b, + 0xd7, 0x72, 0xec, 0x26, 0xf5, 0x83, 0x64, 0x5e, 0x62, 0x5d, 0xc2, 0x51, 0x53, 0x90, 0x55, 0x38, + 0xee, 0xd3, 0x60, 0x63, 0xd7, 0xa1, 0x9e, 0x3e, 0x0b, 0x24, 0x0f, 0x87, 0x3d, 0xae, 0x2c, 0xec, + 0x5a, 0x92, 0x00, 0x07, 0xcb, 0x70, 0x37, 0x51, 0x9c, 0xcb, 0xd2, 0x67, 0x6c, 0xe4, 0x6a, 0x0d, + 0xdd, 0xc4, 0x04, 0x1e, 0x07, 0x4a, 0x30, 0x2e, 0x4d, 0xcb, 0xee, 0xf4, 0x3d, 0x1a, 0x72, 0xc9, + 0xc7, 0xb9, 0xac, 0x24, 0xf0, 0x38, 0x50, 0x82, 0xa7, 0x34, 0x3b, 0x56, 0xcb, 0x2f, 0x4f, 0x46, + 0x52, 0x9a, 0x0c, 0x80, 0x02, 0x6e, 0x7e, 0x30, 0x06, 0xd3, 0x48, 0x03, 0x6f, 0x4f, 0xf7, 0xda, + 0x1b, 0x90, 0xeb, 0xf0, 0x73, 0x62, 0xc6, 0x28, 0x6a, 0x52, 0x1c, 0x24, 0x13, 0x9c, 0xc8, 0x32, + 0x94, 0x3c, 0x26, 0x43, 0x9e, 0xe2, 0x13, 0x63, 0x68, 0xaa, 0x60, 0x02, 0x86, 0xa8, 0xbb, 0xf1, + 0x4f, 0x8c, 0x16, 0x23, 0x0e, 0x4c, 0x6e, 0x8b, 0x33, 0xf6, 0x52, 0x83, 0x67, 0x9b, 0xde, 0xf2, + 0x9c, 0x3e, 0x4f, 0x7f, 0xa8, 0x43, 0xfb, 0x77, 0xc3, 0x9f, 0xa8, 0x84, 0x98, 0x1f, 0x18, 0x00, + 0xe1, 0x35, 0x25, 0xb2, 0x03, 0x05, 0xff, 0xf9, 0x98, 0x15, 0x99, 0xf1, 0x00, 0x8c, 0x64, 0x12, + 0x39, 0x1a, 0x21, 0x21, 0xa8, 0x05, 0xdc, 0xcf, 0x84, 0xfc, 0x68, 0x1c, 0x74, 0xa9, 0x87, 0x64, + 0x41, 0x3e, 0xc3, 0xac, 0x8f, 0x56, 0x78, 0x7b, 0x40, 0xd3, 0x21, 0x87, 0xa2, 0xc4, 0x32, 0x0b, + 0x44, 0xe5, 0x67, 0xe5, 0x6a, 0xe1, 0x16, 0x88, 0x4a, 0xe5, 0xa2, 0xc6, 0xa6, 0xd9, 0xa4, 0xb9, + 0x47, 0x66, 0x93, 0xe6, 0x1f, 0x8a, 0x4d, 0x4a, 0x9e, 0x85, 0x49, 0xcf, 0xed, 0xd0, 0x45, 0xbc, + 0x26, 0xe3, 0x27, 0x3a, 0xae, 0x81, 0x02, 0x8c, 0x0a, 0x4f, 0x5e, 0x80, 0x52, 0xdf, 0xa7, 0xb5, + 0xe5, 0x2b, 0x4b, 0x1e, 0x6d, 0xf8, 0x32, 0xf5, 0xad, 0x23, 0x6a, 0xd7, 0x43, 0x14, 0x46, 0xe9, + 0xcc, 0xdf, 0x31, 0xe0, 0x58, 0xad, 0xee, 0xd9, 0xbd, 0x40, 0x2b, 0xcf, 0x6b, 0xfc, 0x76, 0x46, + 0x60, 0xb1, 0xa5, 0x28, 0xa7, 0xe2, 0x93, 0x43, 0xb2, 0x7e, 0x82, 0x28, 0x76, 0xef, 0x48, 0x80, + 0x30, 0x64, 0xc1, 0x86, 0x5a, 0xa8, 0xe7, 0xe4, 0x94, 0xa8, 0x71, 0x28, 0x4a, 0xac, 0x79, 0x1b, + 0x66, 0x6b, 0xb4, 0x6b, 0xf5, 0xda, 0x3c, 0x0b, 0x2f, 0x42, 0x9c, 0x0b, 0x50, 0xf4, 0x15, 0x2c, + 0x79, 0xc9, 0x49, 0x13, 0x63, 0x48, 0x43, 0x9e, 0x16, 0x11, 0x58, 0x66, 0xb6, 0x8b, 0xbc, 0x72, + 0x49, 0x85, 0x4e, 0x99, 0xbd, 0xad, 0x70, 0xe6, 0x2e, 0x4c, 0x85, 0xc5, 0x69, 0x93, 0xb4, 0x60, + 0xa6, 0x1e, 0x49, 0x62, 0x22, 0x6d, 0x3e, 0xf0, 0xbd, 0x14, 0x9e, 0xc0, 0x5d, 0x8a, 0x33, 0xc1, + 0x24, 0x57, 0xf3, 0xe7, 0x06, 0xcc, 0x68, 0xc9, 0x32, 0x94, 0xda, 0x4b, 0x46, 0x8d, 0x2f, 0x65, + 0x3c, 0xfa, 0x16, 0xef, 0xbc, 0x7b, 0x44, 0x8e, 0x7b, 0xc9, 0xc8, 0xf1, 0x51, 0x4b, 0x1c, 0x88, + 0x1e, 0xff, 0xd9, 0x18, 0x14, 0xf4, 0xd9, 0xbb, 0x37, 0x20, 0xc7, 0xf7, 0xfb, 0xd1, 0xf6, 0x00, + 0x6e, 0x3b, 0xa0, 0xe0, 0xc4, 0x58, 0xf2, 0x30, 0x5c, 0x66, 0xa3, 0xbe, 0x28, 0x3c, 0x0b, 0xcb, + 0x0b, 0x50, 0x70, 0x22, 0x57, 0x60, 0x9c, 0x3a, 0x8d, 0xcc, 0xe6, 0x3c, 0xbf, 0xc6, 0x77, 0xc9, + 0x69, 0x20, 0xe3, 0xc2, 0x2f, 0x70, 0xb8, 0x5e, 0xd7, 0x0a, 0xa4, 0xa9, 0x18, 0x5e, 0xe0, 0xe0, + 0x50, 0x94, 0x58, 0xf3, 0xf7, 0xc6, 0x20, 0x5f, 0xeb, 0x6f, 0xb3, 0x6d, 0xed, 0x8f, 0x0c, 0x38, + 0x91, 0x0c, 0xc8, 0x86, 0x13, 0xf3, 0xf2, 0x91, 0x5c, 0x30, 0x42, 0xda, 0xac, 0x3e, 0x21, 0xab, + 0x72, 0x22, 0x05, 0x89, 0x69, 0x35, 0x60, 0x66, 0x67, 0x78, 0xd2, 0x76, 0xec, 0x48, 0x4e, 0xda, + 0x4e, 0x0f, 0x3b, 0x65, 0x6b, 0xfe, 0xfd, 0x04, 0x80, 0xe8, 0x91, 0x8d, 0x5e, 0x70, 0x18, 0xdf, + 0xe0, 0x45, 0x98, 0x52, 0xaf, 0x0e, 0x5c, 0x0b, 0xb3, 0x10, 0x3a, 0x7c, 0xb5, 0x1a, 0xc1, 0x61, + 0x8c, 0x92, 0xb9, 0x40, 0xd4, 0x09, 0xbc, 0x3d, 0xb1, 0xd9, 0x4d, 0xc4, 0x5d, 0xa0, 0x4b, 0x1a, + 0x83, 0x11, 0x2a, 0x32, 0x1f, 0x0b, 0x15, 0x88, 0xd3, 0xb8, 0xc7, 0xee, 0xe1, 0xe6, 0xbf, 0x04, + 0xd3, 0xfa, 0x6b, 0xc5, 0xee, 0xa8, 0x03, 0x0e, 0xda, 0xe4, 0xdc, 0x8c, 0x22, 0x31, 0x4e, 0x4b, + 0x5e, 0x81, 0x63, 0xf1, 0x63, 0x73, 0x72, 0x5b, 0x38, 0x2d, 0x4b, 0x1f, 0x8b, 0x9f, 0xb6, 0xc3, + 0x04, 0x35, 0x9b, 0x85, 0x0d, 0x6f, 0x0f, 0xfb, 0x8e, 0xdc, 0x1f, 0xf4, 0x2c, 0x5c, 0xe6, 0x50, + 0x94, 0x58, 0xd6, 0x85, 0xac, 0x24, 0xf5, 0x04, 0x9c, 0x07, 0xd5, 0x0b, 0x61, 0x17, 0xd6, 0x22, + 0x38, 0x8c, 0x51, 0x32, 0x09, 0xd2, 0x31, 0x83, 0xf8, 0x3c, 0x4f, 0xb8, 0x56, 0x3d, 0x38, 0xe6, + 0xc6, 0x6d, 0x61, 0x11, 0x2d, 0xff, 0xf4, 0x21, 0xcf, 0xef, 0xc7, 0xca, 0x8a, 0x73, 0x69, 0x09, + 0xd3, 0x39, 0xc1, 0xdf, 0x3c, 0x01, 0xc7, 0x6b, 0xfd, 0x5e, 0xaf, 0x63, 0xd3, 0x86, 0xf6, 0x7f, + 0xcd, 0x57, 0x61, 0x46, 0xde, 0xc8, 0xd0, 0xdb, 0xdf, 0x03, 0x5d, 0xb0, 0x34, 0xf7, 0x99, 0x3e, + 0xdf, 0x73, 0xea, 0x6d, 0xcf, 0x75, 0x64, 0xf4, 0x91, 0x38, 0xc9, 0x4d, 0x2b, 0x6b, 0xf8, 0x23, + 0xba, 0x45, 0x89, 0x15, 0x92, 0xba, 0xe7, 0xdd, 0x52, 0x29, 0xcd, 0x51, 0x92, 0xf7, 0x3c, 0x0b, + 0x28, 0xb4, 0x60, 0x34, 0x15, 0x6a, 0xfe, 0xd4, 0x80, 0x53, 0x89, 0x06, 0xca, 0x6d, 0xeb, 0x9d, + 0xc1, 0x66, 0x2e, 0x8f, 0xd6, 0x4c, 0x19, 0xe1, 0x1d, 0xde, 0x52, 0x2b, 0xde, 0xd2, 0xd7, 0xb2, + 0xb7, 0x54, 0x8a, 0x1a, 0x6c, 0xef, 0x7f, 0x1a, 0x50, 0xda, 0xda, 0xba, 0xaa, 0xfd, 0x15, 0x84, + 0xd3, 0xbe, 0xb8, 0x53, 0xb3, 0xd8, 0x0c, 0xa8, 0xb7, 0xe4, 0x76, 0x7b, 0x1d, 0xaa, 0x27, 0x87, + 0xbc, 0xe8, 0x52, 0x4b, 0xa5, 0xc0, 0x21, 0x25, 0xc9, 0x1a, 0x9c, 0x88, 0x62, 0xa4, 0xbb, 0xc6, + 0x1b, 0x95, 0x93, 0x67, 0x1f, 0x07, 0xd1, 0x98, 0x56, 0x26, 0xc9, 0x4a, 0xfa, 0x6c, 0xf2, 0x79, + 0x8c, 0x01, 0x56, 0x12, 0x8d, 0x69, 0x65, 0xcc, 0x0d, 0x28, 0x45, 0xde, 0x46, 0x21, 0xaf, 0xc1, + 0x6c, 0xdd, 0xed, 0xf6, 0x3c, 0xea, 0xfb, 0xb6, 0xeb, 0x5c, 0xa5, 0x77, 0x68, 0x47, 0x36, 0x99, + 0xdf, 0x98, 0x59, 0x4a, 0xe0, 0x70, 0x80, 0xda, 0xfc, 0x97, 0x27, 0x40, 0xdf, 0xd3, 0xf8, 0xd5, + 0x6d, 0x8f, 0x4c, 0x39, 0xe1, 0xba, 0xce, 0x59, 0xe5, 0x46, 0xcf, 0x59, 0x69, 0x5d, 0x9c, 0xc8, + 0x5b, 0xb5, 0xc2, 0xbc, 0x55, 0xfe, 0x08, 0xf2, 0x56, 0xda, 0x08, 0x1c, 0xc8, 0x5d, 0x7d, 0xcd, + 0x80, 0x29, 0xc7, 0x6d, 0x50, 0x65, 0x33, 0xf3, 0xb0, 0x41, 0xe9, 0xe2, 0xc6, 0x48, 0x9d, 0x28, + 0x52, 0x98, 0x92, 0xa3, 0x48, 0x59, 0xea, 0x8d, 0x2a, 0x8a, 0xc2, 0x98, 0x68, 0xb2, 0x02, 0x05, + 0xab, 0xd9, 0xb4, 0x1d, 0x3b, 0xd8, 0x93, 0x17, 0x4e, 0xce, 0xa6, 0x99, 0xfa, 0x8b, 0x92, 0x46, + 0xb8, 0x9d, 0xea, 0x0b, 0x75, 0x59, 0xe6, 0xb7, 0xeb, 0xfb, 0x9d, 0xc5, 0x11, 0xfc, 0x76, 0x75, + 0x92, 0x28, 0x12, 0x44, 0x52, 0x77, 0xd1, 0xc2, 0xeb, 0x9e, 0x26, 0xe4, 0x45, 0x3a, 0x93, 0xef, + 0xae, 0x05, 0x11, 0xb4, 0x14, 0xa9, 0x4e, 0x94, 0x18, 0xd2, 0x52, 0x81, 0xf7, 0x12, 0xef, 0xdc, + 0x6a, 0xe6, 0xb4, 0x85, 0x8e, 0xe5, 0xa7, 0x47, 0xde, 0xc9, 0xeb, 0x51, 0x3f, 0x71, 0xea, 0x30, + 0x7e, 0xe2, 0xf4, 0x50, 0x1f, 0xb1, 0x05, 0x79, 0x9f, 0x7b, 0xa1, 0x3c, 0x87, 0x5b, 0xba, 0xb8, + 0x94, 0x6d, 0x23, 0x89, 0x39, 0xb2, 0xa2, 0x77, 0x04, 0x0c, 0x25, 0x7b, 0xe2, 0x42, 0x41, 0x25, + 0x9a, 0x65, 0x1a, 0x38, 0x9b, 0xeb, 0x93, 0x0c, 0x39, 0xaa, 0x6b, 0x07, 0x02, 0x8a, 0x5a, 0x08, + 0xb9, 0x05, 0xe3, 0x0d, 0xab, 0x25, 0x13, 0xc2, 0xaf, 0x65, 0xbe, 0x47, 0xa3, 0xc4, 0x70, 0xaf, + 0x62, 0x79, 0x71, 0x15, 0x19, 0x57, 0xb2, 0x13, 0xde, 0x33, 0x9d, 0x1d, 0x65, 0x03, 0x8e, 0x9b, + 0x40, 0xc2, 0x67, 0x1e, 0xb8, 0xa9, 0x7a, 0x09, 0x26, 0xef, 0xb8, 0x9d, 0x7e, 0x57, 0x66, 0x92, + 0x4b, 0x17, 0xe7, 0xd2, 0x46, 0xfb, 0x06, 0x27, 0x09, 0x95, 0x80, 0xf8, 0xf6, 0x51, 0x95, 0x25, + 0x5f, 0x36, 0xe0, 0x18, 0x5b, 0x3a, 0x7a, 0x1e, 0xf8, 0x65, 0x32, 0xc2, 0x4c, 0xbd, 0xee, 0xb3, + 0xad, 0x55, 0xcd, 0x30, 0x6d, 0x08, 0xaf, 0xc5, 0x24, 0x60, 0x42, 0x22, 0xe9, 0x41, 0xc1, 0xb7, + 0x1b, 0xb4, 0x6e, 0x79, 0x7e, 0xf9, 0xc4, 0x91, 0x49, 0x0f, 0x43, 0x6e, 0x92, 0x37, 0x6a, 0x29, + 0xe4, 0xb7, 0xf9, 0x3b, 0x29, 0xf2, 0x8d, 0x23, 0xf9, 0xee, 0xd4, 0xc9, 0xa3, 0x7c, 0x77, 0xea, + 0x84, 0x78, 0x24, 0x25, 0x26, 0x01, 0x93, 0x22, 0xc9, 0x97, 0x0c, 0x38, 0x25, 0x2e, 0x9c, 0x26, + 0x6f, 0x1b, 0x9f, 0xca, 0xe8, 0xe7, 0x3e, 0x7e, 0xb0, 0x5f, 0x39, 0xb5, 0x98, 0xc6, 0x12, 0xd3, + 0x25, 0x91, 0xf7, 0x60, 0xda, 0x8b, 0xc6, 0x84, 0xf9, 0x01, 0x83, 0xac, 0x23, 0x10, 0x8b, 0x2e, + 0x8b, 0xc3, 0x0d, 0x31, 0x10, 0xc6, 0x65, 0x91, 0xe7, 0xa0, 0xd4, 0x93, 0xca, 0xcd, 0xf6, 0xbb, + 0xfc, 0x6c, 0xc2, 0xb8, 0xd8, 0x84, 0x37, 0x43, 0x30, 0x46, 0x69, 0xc8, 0x75, 0x28, 0x05, 0x6e, + 0x87, 0x7a, 0xf2, 0xc4, 0x6a, 0x99, 0xcf, 0x97, 0x73, 0x69, 0x93, 0x7f, 0x4b, 0x93, 0x85, 0xa1, + 0xb7, 0x10, 0xe6, 0x63, 0x94, 0x0f, 0xf3, 0x04, 0xd5, 0x75, 0x74, 0x8f, 0x3b, 0xaa, 0x8f, 0xc7, + 0x3d, 0xc1, 0x5a, 0x14, 0x89, 0x71, 0x5a, 0xb2, 0x0a, 0xc7, 0x7b, 0x9e, 0xed, 0x7a, 0x76, 0xb0, + 0xb7, 0xd4, 0xb1, 0x7c, 0x9f, 0x33, 0x98, 0xe3, 0x0c, 0x74, 0x3a, 0x61, 0x33, 0x49, 0x80, 0x83, + 0x65, 0xc8, 0x05, 0x28, 0x28, 0x60, 0xf9, 0x09, 0x6e, 0xde, 0x71, 0x4d, 0xa6, 0xca, 0xa2, 0xc6, + 0x0e, 0xb9, 0x3d, 0x77, 0x36, 0xcb, 0xed, 0x39, 0xd2, 0x80, 0xb3, 0x56, 0x3f, 0x70, 0xf9, 0x91, + 0xf7, 0x78, 0x91, 0x2d, 0x77, 0x87, 0x3a, 0xe5, 0xf3, 0x7c, 0x7b, 0x3b, 0x7f, 0xb0, 0x5f, 0x39, + 0xbb, 0x78, 0x0f, 0x3a, 0xbc, 0x27, 0x17, 0xd2, 0x85, 0x02, 0x95, 0x37, 0x00, 0xcb, 0x1f, 0x1b, + 0x61, 0x5f, 0x89, 0x5f, 0x23, 0x54, 0x39, 0x70, 0x01, 0x43, 0x2d, 0x82, 0x6c, 0x41, 0xa9, 0xed, + 0xfa, 0xc1, 0x62, 0xc7, 0xb6, 0x7c, 0xea, 0x97, 0x9f, 0xe4, 0xf3, 0x24, 0x75, 0x4b, 0xbc, 0xac, + 0xc8, 0xc2, 0x69, 0x72, 0x39, 0x2c, 0x89, 0x51, 0x36, 0x84, 0xf2, 0x68, 0x73, 0x9f, 0x8f, 0x9a, + 0xeb, 0x04, 0xf4, 0xdd, 0xa0, 0x7c, 0x8e, 0xb7, 0xe5, 0x99, 0x34, 0xce, 0x9b, 0x6e, 0xa3, 0x16, + 0xa7, 0x16, 0x8a, 0x21, 0x01, 0xc4, 0x24, 0x4f, 0xe6, 0xf2, 0xf7, 0xdc, 0x46, 0xad, 0x47, 0xeb, + 0x9b, 0x56, 0x50, 0x6f, 0x97, 0x2b, 0xf1, 0xa8, 0xc9, 0x66, 0x04, 0x87, 0x31, 0x4a, 0xe6, 0x82, + 0x78, 0xd4, 0xe7, 0x11, 0x9a, 0x4d, 0xea, 0x34, 0x6c, 0xa7, 0xb5, 0xe9, 0x36, 0xfc, 0xb2, 0xc9, + 0x87, 0x90, 0xbb, 0x20, 0x38, 0x88, 0xc6, 0xb4, 0x32, 0xa4, 0x0e, 0x93, 0x5d, 0x71, 0xa6, 0xb8, + 0xfc, 0xd4, 0x08, 0x96, 0xa8, 0x3c, 0x97, 0x2c, 0xf6, 0x31, 0xf9, 0x81, 0x8a, 0x33, 0xf9, 0x43, + 0x03, 0x66, 0xfc, 0xb8, 0x47, 0x5b, 0xfe, 0xf8, 0x28, 0xbb, 0x67, 0x9c, 0x57, 0xf5, 0x19, 0xde, + 0xdf, 0x71, 0xe0, 0xdd, 0x41, 0x10, 0x26, 0x2b, 0x21, 0x5a, 0xcf, 0x8f, 0xeb, 0x97, 0x9f, 0x1e, + 0xa9, 0xf5, 0x9c, 0x87, 0x6a, 0x3d, 0xff, 0x40, 0xc5, 0x79, 0xee, 0x55, 0x38, 0x3e, 0x60, 0x30, + 0x3f, 0xd0, 0x51, 0xf2, 0x1f, 0x31, 0x07, 0x39, 0xe2, 0xa2, 0x1c, 0xb5, 0x63, 0xb7, 0x0a, 0xc7, + 0xe5, 0xc3, 0xa3, 0xcc, 0x9a, 0xea, 0xf4, 0xf5, 0x13, 0x53, 0x91, 0x44, 0x29, 0x26, 0x09, 0x70, + 0xb0, 0x0c, 0x9b, 0xd1, 0x75, 0xf1, 0xc6, 0x90, 0x38, 0xb6, 0x3a, 0x11, 0x0f, 0x62, 0x2d, 0x45, + 0x70, 0x18, 0xa3, 0x34, 0xff, 0xdc, 0x80, 0xe9, 0xd8, 0xce, 0x7e, 0xe4, 0x39, 0x91, 0x15, 0x20, + 0x5d, 0xdb, 0xf3, 0x5c, 0x4f, 0x98, 0x47, 0xeb, 0x4c, 0x67, 0xf9, 0xf2, 0x02, 0x2b, 0xbf, 0x38, + 0xb5, 0x3e, 0x80, 0xc5, 0x94, 0x12, 0xe6, 0x5f, 0x8c, 0x43, 0x78, 0x9a, 0x43, 0xdf, 0x16, 0x34, + 0x86, 0xde, 0x16, 0xfc, 0x04, 0x14, 0x6e, 0xfb, 0xae, 0xb3, 0x19, 0xde, 0x29, 0xd4, 0x43, 0xf1, + 0x7a, 0x6d, 0xe3, 0x1a, 0xa7, 0xd4, 0x14, 0x9c, 0xfa, 0x9d, 0x15, 0xbb, 0x13, 0x0c, 0xde, 0xbc, + 0x7b, 0xfd, 0x0d, 0x01, 0x47, 0x4d, 0xc1, 0x1f, 0x32, 0xba, 0x43, 0x75, 0x4c, 0x32, 0x7c, 0xc8, + 0x88, 0x01, 0x51, 0xe0, 0xc8, 0x02, 0x14, 0x75, 0x48, 0x53, 0x46, 0x58, 0x75, 0x4f, 0xe9, 0xd0, + 0x27, 0x86, 0x34, 0xdc, 0x52, 0x93, 0x61, 0x3b, 0xe9, 0x9d, 0xae, 0x64, 0xb4, 0x71, 0x13, 0xb1, + 0x3f, 0xa1, 0xc6, 0x15, 0x18, 0xb5, 0x94, 0xe8, 0x09, 0xa1, 0xdc, 0x51, 0x9e, 0x10, 0x32, 0xbf, + 0x32, 0x0e, 0x93, 0x37, 0xa8, 0xc7, 0x6f, 0x0b, 0x3f, 0x0b, 0x93, 0x77, 0xc4, 0x4f, 0x39, 0x5a, + 0xa1, 0xc1, 0x2c, 0xc0, 0xa8, 0xf0, 0xac, 0xcb, 0xb6, 0xfb, 0x76, 0xa7, 0xb1, 0x1c, 0xae, 0x1f, + 0xdd, 0x65, 0x55, 0x85, 0xc0, 0x90, 0x86, 0x15, 0x68, 0x31, 0x6b, 0xb7, 0xdb, 0xb5, 0x83, 0xe4, + 0x45, 0xa1, 0x55, 0x85, 0xc0, 0x90, 0x86, 0x3c, 0x03, 0xf9, 0x96, 0x1d, 0x6c, 0x59, 0xad, 0x64, + 0x72, 0x62, 0x95, 0x43, 0x51, 0x62, 0x79, 0x64, 0xdd, 0x0e, 0xb6, 0x3c, 0xca, 0x23, 0x75, 0x03, + 0x07, 0xea, 0x57, 0x23, 0x38, 0x8c, 0x51, 0xf2, 0x2a, 0xb9, 0xb2, 0x65, 0x32, 0xe2, 0x1d, 0x56, + 0x49, 0x21, 0x30, 0xa4, 0x61, 0x53, 0xaf, 0xee, 0x76, 0x7b, 0x76, 0x47, 0x9e, 0x36, 0x89, 0x4c, + 0xbd, 0x25, 0x09, 0x47, 0x4d, 0xc1, 0xa8, 0x99, 0xf2, 0x68, 0xba, 0x5e, 0x37, 0xf9, 0x72, 0xcc, + 0xa6, 0x84, 0xa3, 0xa6, 0x30, 0xbf, 0x3d, 0x06, 0x85, 0x47, 0xf8, 0xe0, 0x55, 0x3d, 0xf6, 0xe0, + 0xd5, 0x11, 0xbc, 0x8e, 0x94, 0xf6, 0xd8, 0xd5, 0x4e, 0xe2, 0xb1, 0xab, 0xa5, 0x11, 0xcf, 0xdb, + 0xdd, 0xf3, 0xa1, 0xab, 0x1f, 0x1b, 0xa0, 0x2f, 0x10, 0xf0, 0xd5, 0x5d, 0xb5, 0xf9, 0x1e, 0xfe, + 0x08, 0x3a, 0xd3, 0x8d, 0x75, 0xe6, 0xfa, 0x48, 0xad, 0x8c, 0x56, 0x7d, 0xe8, 0x4b, 0x7b, 0x1f, + 0x19, 0x50, 0x4e, 0x2b, 0xf0, 0x08, 0x1e, 0xf7, 0x72, 0xe2, 0x8f, 0x7b, 0xad, 0x1d, 0x59, 0x63, + 0x87, 0x3c, 0xf2, 0xf5, 0x83, 0x21, 0x4d, 0xe5, 0xcf, 0x6b, 0xbd, 0xad, 0xb4, 0xbb, 0x31, 0x42, + 0x92, 0x41, 0x70, 0x4d, 0xdf, 0x19, 0xde, 0x86, 0xbc, 0x30, 0x08, 0xe5, 0xd8, 0xbe, 0x94, 0x51, + 0xcd, 0x33, 0x16, 0x32, 0xf4, 0xc3, 0x7f, 0xa3, 0x64, 0x6b, 0x7e, 0xcf, 0x80, 0xa9, 0x47, 0xf8, + 0x34, 0xdb, 0x76, 0x7c, 0xf4, 0x5e, 0x1e, 0x69, 0xf4, 0x86, 0x8c, 0xd8, 0xd7, 0x1e, 0x87, 0xd8, + 0x93, 0x68, 0xc4, 0x81, 0xa2, 0x32, 0xa4, 0xd4, 0xc9, 0xdb, 0x97, 0x47, 0x8a, 0xae, 0x86, 0x6a, + 0x5a, 0x41, 0x7c, 0x0c, 0x45, 0x24, 0x32, 0xa6, 0x63, 0x87, 0xca, 0x98, 0x3e, 0xf2, 0xc8, 0x7d, + 0xba, 0xe3, 0x3a, 0xf1, 0x50, 0x1c, 0xd7, 0xb3, 0x47, 0xee, 0xb8, 0x3e, 0xf9, 0xf0, 0x1d, 0xd7, + 0x48, 0x64, 0x2f, 0x37, 0x42, 0x64, 0xef, 0x3d, 0x38, 0x29, 0x7e, 0x2e, 0x75, 0x2c, 0xbb, 0xab, + 0xe7, 0x8b, 0x7c, 0x6f, 0xea, 0xd9, 0x54, 0x77, 0x95, 0x6d, 0xf7, 0x7e, 0x40, 0x9d, 0xe0, 0x46, + 0x58, 0x32, 0xbc, 0xa5, 0x76, 0x23, 0x85, 0x1d, 0xa6, 0x0a, 0x49, 0xc6, 0x75, 0x26, 0x0f, 0x11, + 0xd7, 0xf9, 0x96, 0x01, 0xa7, 0xac, 0xb4, 0xb7, 0x95, 0x65, 0x42, 0xe0, 0xf5, 0x91, 0x02, 0x73, + 0x31, 0x8e, 0x32, 0x4a, 0x96, 0x86, 0xc2, 0xf4, 0x3a, 0x90, 0xa7, 0xc3, 0xd8, 0xae, 0x48, 0xbf, + 0xa7, 0x47, 0x65, 0xbf, 0x91, 0xcc, 0xa9, 0x00, 0xef, 0xed, 0xda, 0xc8, 0x66, 0xc6, 0x11, 0xe4, + 0x55, 0x4a, 0x23, 0xe4, 0x55, 0x12, 0x41, 0xb7, 0xa9, 0x23, 0x0a, 0xba, 0x39, 0x30, 0x6b, 0x77, + 0xad, 0x16, 0xdd, 0xec, 0x77, 0x3a, 0xe2, 0x90, 0x9d, 0x5f, 0x9e, 0xe6, 0xbc, 0x53, 0x4f, 0x7a, + 0x5d, 0x75, 0xeb, 0x56, 0x27, 0xf9, 0x82, 0x9f, 0x3e, 0x21, 0xbb, 0x96, 0xe0, 0x84, 0x03, 0xbc, + 0xd9, 0xb4, 0xe4, 0x37, 0xa4, 0x68, 0xc0, 0x7a, 0x9b, 0xa7, 0x1c, 0xe4, 0xeb, 0xf7, 0x97, 0x43, + 0x30, 0x46, 0x69, 0xc8, 0x15, 0x28, 0x36, 0x1c, 0x5f, 0x1e, 0x66, 0x9d, 0xe1, 0x5a, 0xea, 0x93, + 0x4c, 0xb7, 0x2d, 0x5f, 0xab, 0xe9, 0x63, 0xac, 0x67, 0x53, 0xae, 0xd8, 0x69, 0x3c, 0x86, 0xe5, + 0xc9, 0x3a, 0x67, 0x26, 0x9f, 0x79, 0x11, 0x39, 0x82, 0xf3, 0x43, 0xe2, 0x46, 0xcb, 0xd7, 0xd4, + 0xab, 0x34, 0xd3, 0x52, 0x9c, 0x7c, 0xbc, 0x25, 0xe4, 0x10, 0x79, 0xa2, 0xec, 0xf8, 0x3d, 0x9f, + 0x28, 0xbb, 0x0e, 0x67, 0x82, 0xa0, 0x13, 0x4b, 0x3d, 0xcb, 0x5b, 0x8c, 0xfc, 0x4a, 0x6b, 0x4e, + 0xbc, 0x6a, 0xb9, 0xb5, 0x75, 0x35, 0x8d, 0x04, 0x87, 0x95, 0xe5, 0x39, 0xd8, 0xa0, 0xa3, 0xe3, + 0xc6, 0xe7, 0x46, 0xc9, 0xc1, 0x86, 0x39, 0x7e, 0x99, 0x83, 0x0d, 0x01, 0x18, 0x95, 0x42, 0x36, + 0x86, 0x45, 0xcc, 0x4f, 0x70, 0x1d, 0xf3, 0xe0, 0xf1, 0xef, 0x68, 0xc8, 0xf5, 0xe4, 0x3d, 0x43, + 0xae, 0x03, 0x21, 0xe2, 0x53, 0x0f, 0x10, 0x22, 0xbe, 0xc5, 0xaf, 0x4f, 0xae, 0x2e, 0xc9, 0xf0, + 0x7a, 0x36, 0x8b, 0x8d, 0xdf, 0xd8, 0x10, 0xc7, 0x24, 0xf8, 0x4f, 0x14, 0x3c, 0xc9, 0x26, 0x9c, + 0xec, 0xb9, 0x8d, 0x81, 0x08, 0x33, 0x8f, 0xa7, 0x47, 0xae, 0x19, 0x6f, 0xa6, 0xd0, 0x60, 0x6a, + 0x49, 0xae, 0xc0, 0x43, 0x78, 0xb9, 0xcc, 0x3b, 0x46, 0x28, 0xf0, 0x10, 0x8c, 0x51, 0x9a, 0x64, + 0xc0, 0xf5, 0xf1, 0x87, 0x16, 0x70, 0x9d, 0x7b, 0x04, 0x01, 0xd7, 0x27, 0x0e, 0x1d, 0x70, 0xfd, + 0x4d, 0x38, 0xd1, 0x73, 0x1b, 0xcb, 0xb6, 0xef, 0xf5, 0xf9, 0x3f, 0x6f, 0x54, 0xfb, 0x8d, 0x16, + 0x0d, 0x78, 0xc4, 0xb6, 0x74, 0xf1, 0x62, 0xb4, 0x92, 0xe2, 0x0f, 0x86, 0xe6, 0xe5, 0x1f, 0x0c, + 0xf1, 0x45, 0x9e, 0x28, 0xc5, 0xfd, 0x1e, 0x1e, 0xa4, 0x4d, 0x41, 0x62, 0x9a, 0x9c, 0x68, 0x90, + 0xf6, 0xfc, 0x43, 0x0b, 0xd2, 0xbe, 0x06, 0x05, 0xbf, 0xdd, 0x0f, 0x1a, 0xee, 0xae, 0xc3, 0x43, + 0xf7, 0x45, 0xfd, 0x26, 0x70, 0xa1, 0x26, 0xe1, 0x77, 0xf7, 0x2b, 0xb3, 0xea, 0x77, 0xe4, 0x4e, + 0x91, 0x84, 0x90, 0x6f, 0x0e, 0x39, 0x3e, 0x69, 0x1e, 0xf1, 0xf1, 0xc9, 0x33, 0x0f, 0x74, 0x74, + 0x32, 0x2d, 0xf8, 0xfc, 0xd4, 0x2f, 0x40, 0xf0, 0x79, 0xf4, 0xb8, 0xf0, 0x37, 0x67, 0xe0, 0x58, + 0xe2, 0x7d, 0x5c, 0x7d, 0xf9, 0xdf, 0x38, 0xec, 0xe5, 0xff, 0xd8, 0xed, 0xfc, 0xb1, 0x87, 0x7a, + 0x3b, 0x7f, 0xfc, 0xc8, 0x6f, 0xe7, 0x47, 0x5e, 0x21, 0x98, 0xb8, 0xcf, 0x2b, 0x04, 0x8b, 0x30, + 0xa3, 0x8e, 0x4b, 0x51, 0x79, 0x3b, 0x5b, 0x04, 0xd3, 0xf4, 0xdd, 0x80, 0xa5, 0x38, 0x1a, 0x93, + 0xf4, 0xe4, 0x37, 0x20, 0xe7, 0xf0, 0x82, 0xf9, 0x11, 0x5e, 0xd0, 0x89, 0x0f, 0x18, 0x37, 0xf9, + 0xe4, 0x23, 0x36, 0x2a, 0x93, 0x9e, 0xe3, 0xb0, 0xbb, 0xea, 0x07, 0x0a, 0xa1, 0xe4, 0x4d, 0x28, + 0xbb, 0xcd, 0x66, 0xc7, 0xb5, 0x1a, 0xe1, 0x0b, 0x02, 0x2a, 0xbe, 0x27, 0x4e, 0x7e, 0x9e, 0x97, + 0x0c, 0xca, 0x1b, 0x43, 0xe8, 0x70, 0x28, 0x07, 0x66, 0x99, 0xcf, 0xc4, 0x5f, 0xb6, 0xf0, 0xcb, + 0x45, 0xde, 0xcc, 0x5f, 0x3b, 0x8a, 0x66, 0xc6, 0x9f, 0xd1, 0x90, 0x0d, 0x0e, 0x6f, 0x65, 0xc4, + 0xb1, 0x98, 0xac, 0x09, 0xf1, 0xe0, 0x74, 0x2f, 0xcd, 0x6f, 0xf1, 0xe5, 0x79, 0xa6, 0x7b, 0x79, + 0x4f, 0xe7, 0xa4, 0x94, 0xd3, 0xa9, 0x9e, 0x8f, 0x8f, 0x43, 0x38, 0x47, 0xdf, 0x16, 0x28, 0x3c, + 0xb4, 0xb7, 0x05, 0xe2, 0x2f, 0x42, 0x4f, 0x3f, 0x8a, 0x17, 0xa1, 0xc9, 0xcf, 0x52, 0x9f, 0xb4, + 0x10, 0xe6, 0xfe, 0x17, 0x8e, 0x62, 0xb0, 0x7f, 0xe1, 0x9e, 0xb5, 0xf8, 0x63, 0x03, 0xe6, 0xc4, + 0x94, 0x4a, 0xfb, 0xbb, 0x0f, 0x79, 0x2a, 0xe9, 0x08, 0xc2, 0xc4, 0x3c, 0x8f, 0x54, 0x8b, 0x09, + 0xe2, 0x71, 0xcd, 0x7b, 0x08, 0x27, 0x5f, 0x4b, 0xd9, 0x9e, 0x66, 0x46, 0x70, 0x86, 0x53, 0x4f, + 0x0e, 0x4b, 0x03, 0xe9, 0x7e, 0x3b, 0xd2, 0x9e, 0x78, 0x6f, 0x68, 0xe8, 0x6b, 0x57, 0xd7, 0xa3, + 0x5b, 0x51, 0xd6, 0x07, 0xa7, 0x42, 0xdd, 0x13, 0x7d, 0x69, 0xeb, 0x4b, 0x06, 0x9c, 0x4c, 0x53, + 0x12, 0x29, 0xb5, 0xa8, 0xc5, 0x6b, 0x31, 0x5a, 0xb4, 0x2d, 0x5a, 0x87, 0xa3, 0x79, 0xbd, 0xe2, + 0x0f, 0xf2, 0x91, 0x08, 0x61, 0x40, 0x7b, 0xbf, 0x3a, 0x87, 0x9b, 0xe9, 0x1c, 0x6e, 0xec, 0xfd, + 0xf4, 0xdc, 0x23, 0x7c, 0x3f, 0x3d, 0x9f, 0xe1, 0xfd, 0xf4, 0xc9, 0x47, 0xf9, 0x7e, 0x7a, 0xe1, + 0x90, 0xef, 0xa7, 0x17, 0x7f, 0x61, 0xde, 0x4f, 0x37, 0x3f, 0x34, 0x60, 0xf6, 0x7f, 0xfb, 0x1f, + 0x44, 0xfd, 0x28, 0x92, 0xa2, 0x7b, 0x84, 0xff, 0x0c, 0x75, 0x3b, 0x9e, 0xf4, 0xb8, 0x74, 0x24, + 0x8d, 0x1c, 0x92, 0xfc, 0x78, 0x07, 0xd2, 0xdc, 0xae, 0xc3, 0x5d, 0x10, 0x8b, 0x1d, 0x0c, 0x19, + 0x3b, 0xf4, 0xc1, 0x90, 0xff, 0x4e, 0xe9, 0x55, 0xbe, 0x6f, 0xbe, 0xf7, 0xb0, 0xfe, 0x09, 0xe7, + 0x64, 0xda, 0x3f, 0xe1, 0x24, 0xfe, 0xf9, 0x26, 0xf9, 0x4f, 0x28, 0x63, 0x0f, 0xef, 0x9f, 0x50, + 0xaa, 0xf3, 0xdf, 0xf9, 0xf0, 0xdc, 0x63, 0xdf, 0xfb, 0xf0, 0xdc, 0x63, 0xdf, 0xff, 0xf0, 0xdc, + 0x63, 0xef, 0x1f, 0x9c, 0x33, 0xbe, 0x73, 0x70, 0xce, 0xf8, 0xde, 0xc1, 0x39, 0xe3, 0xfb, 0x07, + 0xe7, 0x8c, 0x1f, 0x1d, 0x9c, 0x33, 0x7e, 0xff, 0xdf, 0xce, 0x3d, 0xf6, 0x85, 0x82, 0x6a, 0xcc, + 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x86, 0x06, 0xb1, 0xe5, 0xbc, 0x79, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -4632,38 +4664,6 @@ func (m *Histogram) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *HolderNames) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *HolderNames) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HolderNames) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Name) > 0 { - for iNdEx := len(m.Name) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Name[iNdEx]) - copy(dAtA[i:], m.Name[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func (m *Inputs) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5005,7 +5005,7 @@ func (m *Metrics) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *NodeStatus) Marshal() (dAtA []byte, err error) { +func (m *Mutex) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -5015,35 +5015,147 @@ func (m *NodeStatus) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *NodeStatus) MarshalTo(dAtA []byte) (int, error) { +func (m *Mutex) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *NodeStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Mutex) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.MemoizationStatus != nil { - { - size, err := m.MemoizationStatus.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xba + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MutexHolding) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - i -= len(m.HostNodeName) - copy(dAtA[i:], m.HostNodeName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.HostNodeName))) + return dAtA[:n], nil +} + +func (m *MutexHolding) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MutexHolding) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Holder) + copy(dAtA[i:], m.Holder) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Holder))) i-- - dAtA[i] = 0x1 + dAtA[i] = 0x12 + i -= len(m.Mutex) + copy(dAtA[i:], m.Mutex) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Mutex))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MutexStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MutexStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MutexStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Waiting) > 0 { + for iNdEx := len(m.Waiting) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Waiting[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Holding) > 0 { + for iNdEx := len(m.Holding) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Holding[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *NodeStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MemoizationStatus != nil { + { + size, err := m.MemoizationStatus.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + } + i -= len(m.HostNodeName) + copy(dAtA[i:], m.HostNodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.HostNodeName))) + i-- + dAtA[i] = 0x1 i-- dAtA[i] = 0xb2 if len(m.ResourcesDuration) > 0 { @@ -6323,6 +6435,18 @@ func (m *Synchronization) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Mutex != nil { + { + size, err := m.Mutex.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } if m.Semaphore != nil { { size, err := m.Semaphore.MarshalToSizedBuffer(dAtA[:i]) @@ -6358,6 +6482,18 @@ func (m *SynchronizationStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Mutex != nil { + { + size, err := m.Mutex.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } if m.Semaphore != nil { { size, err := m.Semaphore.MarshalToSizedBuffer(dAtA[:i]) @@ -7131,39 +7267,6 @@ func (m *Version) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *WaitingStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *WaitingStatus) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *WaitingStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Holders.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *Workflow) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -8908,21 +9011,6 @@ func (m *Histogram) Size() (n int) { return n } -func (m *HolderNames) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Name) > 0 { - for _, s := range m.Name { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - func (m *Inputs) Size() (n int) { if m == nil { return 0 @@ -9054,6 +9142,51 @@ func (m *Metrics) Size() (n int) { return n } +func (m *Mutex) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MutexHolding) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Mutex) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Holder) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MutexStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Holding) > 0 { + for _, e := range m.Holding { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Waiting) > 0 { + for _, e := range m.Waiting { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *NodeStatus) Size() (n int) { if m == nil { return 0 @@ -9543,6 +9676,10 @@ func (m *Synchronization) Size() (n int) { l = m.Semaphore.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Mutex != nil { + l = m.Mutex.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -9556,6 +9693,10 @@ func (m *SynchronizationStatus) Size() (n int) { l = m.Semaphore.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Mutex != nil { + l = m.Mutex.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -9818,17 +9959,6 @@ func (m *Version) Size() (n int) { return n } -func (m *WaitingStatus) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Holders.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - func (m *Workflow) Size() (n int) { if m == nil { return 0 @@ -10658,16 +10788,6 @@ func (this *Histogram) String() string { }, "") return s } -func (this *HolderNames) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HolderNames{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `}`, - }, "") - return s -} func (this *Inputs) String() string { if this == nil { return "nil" @@ -10781,6 +10901,48 @@ func (this *Metrics) String() string { }, "") return s } +func (this *Mutex) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Mutex{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} +func (this *MutexHolding) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MutexHolding{`, + `Mutex:` + fmt.Sprintf("%v", this.Mutex) + `,`, + `Holder:` + fmt.Sprintf("%v", this.Holder) + `,`, + `}`, + }, "") + return s +} +func (this *MutexStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForHolding := "[]MutexHolding{" + for _, f := range this.Holding { + repeatedStringForHolding += strings.Replace(strings.Replace(f.String(), "MutexHolding", "MutexHolding", 1), `&`, ``, 1) + "," + } + repeatedStringForHolding += "}" + repeatedStringForWaiting := "[]MutexHolding{" + for _, f := range this.Waiting { + repeatedStringForWaiting += strings.Replace(strings.Replace(f.String(), "MutexHolding", "MutexHolding", 1), `&`, ``, 1) + "," + } + repeatedStringForWaiting += "}" + s := strings.Join([]string{`&MutexStatus{`, + `Holding:` + repeatedStringForHolding + `,`, + `Waiting:` + repeatedStringForWaiting + `,`, + `}`, + }, "") + return s +} func (this *NodeStatus) String() string { if this == nil { return "nil" @@ -11126,6 +11288,7 @@ func (this *Synchronization) String() string { } s := strings.Join([]string{`&Synchronization{`, `Semaphore:` + strings.Replace(this.Semaphore.String(), "SemaphoreRef", "SemaphoreRef", 1) + `,`, + `Mutex:` + strings.Replace(this.Mutex.String(), "Mutex", "Mutex", 1) + `,`, `}`, }, "") return s @@ -11136,6 +11299,7 @@ func (this *SynchronizationStatus) String() string { } s := strings.Join([]string{`&SynchronizationStatus{`, `Semaphore:` + strings.Replace(this.Semaphore.String(), "SemaphoreStatus", "SemaphoreStatus", 1) + `,`, + `Mutex:` + strings.Replace(this.Mutex.String(), "MutexStatus", "MutexStatus", 1) + `,`, `}`, }, "") return s @@ -11305,16 +11469,6 @@ func (this *Version) String() string { }, "") return s } -func (this *WaitingStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&WaitingStatus{`, - `Holders:` + strings.Replace(strings.Replace(this.Holders.String(), "HolderNames", "HolderNames", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} func (this *Workflow) String() string { if this == nil { return "nil" @@ -16639,7 +16793,7 @@ func (m *Histogram) Unmarshal(dAtA []byte) error { } return nil } -func (m *HolderNames) Unmarshal(dAtA []byte) error { +func (m *Inputs) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -16662,95 +16816,10 @@ func (m *HolderNames) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HolderNames: wiretype end group for non-group") + return fmt.Errorf("proto: Inputs: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HolderNames: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = append(m.Name, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Inputs) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Inputs: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Inputs: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Inputs: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -17620,7 +17689,296 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.Labels[mapkey] = mapvalue + m.Labels[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MetricLabel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MetricLabel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MetricLabel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Metrics) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Metrics: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metrics: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prometheus", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prometheus = append(m.Prometheus, &Prometheus{}) + if err := m.Prometheus[len(m.Prometheus)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Mutex) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Mutex: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Mutex: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -17646,7 +18004,7 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { } return nil } -func (m *MetricLabel) Unmarshal(dAtA []byte) error { +func (m *MutexHolding) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -17669,15 +18027,15 @@ func (m *MetricLabel) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MetricLabel: wiretype end group for non-group") + return fmt.Errorf("proto: MutexHolding: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MetricLabel: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutexHolding: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Mutex", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -17705,11 +18063,11 @@ func (m *MetricLabel) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = string(dAtA[iNdEx:postIndex]) + m.Mutex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Holder", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -17737,7 +18095,7 @@ func (m *MetricLabel) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = string(dAtA[iNdEx:postIndex]) + m.Holder = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -17763,7 +18121,7 @@ func (m *MetricLabel) Unmarshal(dAtA []byte) error { } return nil } -func (m *Metrics) Unmarshal(dAtA []byte) error { +func (m *MutexStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -17786,15 +18144,15 @@ func (m *Metrics) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Metrics: wiretype end group for non-group") + return fmt.Errorf("proto: MutexStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Metrics: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MutexStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Prometheus", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Holding", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -17821,8 +18179,42 @@ func (m *Metrics) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Prometheus = append(m.Prometheus, &Prometheus{}) - if err := m.Prometheus[len(m.Prometheus)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Holding = append(m.Holding, MutexHolding{}) + if err := m.Holding[len(m.Holding)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Waiting", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Waiting = append(m.Waiting, MutexHolding{}) + if err := m.Waiting[len(m.Waiting)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -22185,6 +22577,42 @@ func (m *Synchronization) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mutex", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Mutex == nil { + m.Mutex = &Mutex{} + } + if err := m.Mutex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -22274,6 +22702,42 @@ func (m *SynchronizationStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mutex", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Mutex == nil { + m.Mutex = &MutexStatus{} + } + if err := m.Mutex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -24693,92 +25157,6 @@ func (m *Version) Unmarshal(dAtA []byte) error { } return nil } -func (m *WaitingStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: WaitingStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: WaitingStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Holders", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Holders.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *Workflow) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto index a0d6292b375d..40013913db48 100644 --- a/pkg/apis/workflow/v1alpha1/generated.proto +++ b/pkg/apis/workflow/v1alpha1/generated.proto @@ -444,12 +444,6 @@ message Histogram { repeated Amount buckets = 4; } -message HolderNames { - // Name stores the name of the resource holding lock - // +listType=atomic - repeated string name = 1; -} - // Inputs are the mechanism for passing parameters, artifacts, volumes from one template to another message Inputs { // Parameters are a list of parameters passed as inputs @@ -522,6 +516,39 @@ message Metrics { repeated Prometheus prometheus = 1; } +// Mutex holds Mutex configuration +message Mutex { + // name of the mutex + optional string name = 1; +} + +// MutexHolding describes the mutex and the object which is holding it. +message MutexHolding { + // Reference for the mutex + // e.g: ${namespace}/mutex/${mutexName} + optional string mutex = 1; + + // Holder is a reference to the object which holds the Mutex. + // Holding Scenario: + // 1. Current workflow's NodeID which is holding the lock. + // e.g: ${NodeID} + // Waiting Scenario: + // 1. Current workflow or other workflow NodeID which is holding the lock. + // e.g: ${WorkflowName}/${NodeID} + optional string holder = 2; +} + +// MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks. +message MutexStatus { + // Holding is a list of mutexes and their respective objects that are held by mutex lock for this workflow. + // +listType=atomic + repeated MutexHolding holding = 1; + + // Waiting is a list of mutexes and their respective objects this workflow is waiting for. + // +listType=atomic + repeated MutexHolding waiting = 2; +} + // NodeStatus contains status information about an individual node in the workflow message NodeStatus { // ID is a unique identifier of a node within the worklow @@ -825,7 +852,7 @@ message SemaphoreStatus { // Holding stores the list of resource acquired synchronization lock for workflows. repeated SemaphoreHolding holding = 1; - // Waiting indicates the list of current synchronization lock holders + // Waiting indicates the list of current synchronization lock holders. repeated SemaphoreHolding waiting = 2; } @@ -899,11 +926,18 @@ message SuspendTemplate { message Synchronization { // Semaphore holds the Semaphore configuration optional SemaphoreRef semaphore = 1; + + // Mutex holds the Mutex lock details + optional Mutex mutex = 2; } +// SynchronizationStatus stores the status of semaphore and mutex. message SynchronizationStatus { - // SemaphoreHolders stores this workflow's Semaphore holder details + // Semaphore stores this workflow's Semaphore holder details optional SemaphoreStatus semaphore = 1; + + // Mutex stores this workflow's mutex holder details + optional MutexStatus mutex = 2; } // TTLStrategy is the strategy for the time to live depending on if the workflow succeeded or failed @@ -1139,11 +1173,6 @@ message Version { optional string platform = 8; } -message WaitingStatus { - // Holders stores the list of current holder names - optional HolderNames holders = 1; -} - // Workflow is the definition of a workflow resource // +genclient // +genclient:noStatus diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index c4f6ab703a97..d11505ee86c1 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -45,7 +45,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.HDFSKrbConfig": schema_pkg_apis_workflow_v1alpha1_HDFSKrbConfig(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.HTTPArtifact": schema_pkg_apis_workflow_v1alpha1_HTTPArtifact(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Histogram": schema_pkg_apis_workflow_v1alpha1_Histogram(ref), - "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.HolderNames": schema_pkg_apis_workflow_v1alpha1_HolderNames(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Inputs": schema_pkg_apis_workflow_v1alpha1_Inputs(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Item": schema_pkg_apis_workflow_v1alpha1_Item(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Link": schema_pkg_apis_workflow_v1alpha1_Link(ref), @@ -54,6 +53,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Metadata": schema_pkg_apis_workflow_v1alpha1_Metadata(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MetricLabel": schema_pkg_apis_workflow_v1alpha1_MetricLabel(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Metrics": schema_pkg_apis_workflow_v1alpha1_Metrics(ref), + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Mutex": schema_pkg_apis_workflow_v1alpha1_Mutex(ref), + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexHolding": schema_pkg_apis_workflow_v1alpha1_MutexHolding(ref), + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexStatus": schema_pkg_apis_workflow_v1alpha1_MutexStatus(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.NodeStatus": schema_pkg_apis_workflow_v1alpha1_NodeStatus(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.NoneStrategy": schema_pkg_apis_workflow_v1alpha1_NoneStrategy(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.OSSArtifact": schema_pkg_apis_workflow_v1alpha1_OSSArtifact(ref), @@ -86,7 +88,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.UserContainer": schema_pkg_apis_workflow_v1alpha1_UserContainer(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.ValueFrom": schema_pkg_apis_workflow_v1alpha1_ValueFrom(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Version": schema_pkg_apis_workflow_v1alpha1_Version(ref), - "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.WaitingStatus": schema_pkg_apis_workflow_v1alpha1_WaitingStatus(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Workflow": schema_pkg_apis_workflow_v1alpha1_Workflow(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.WorkflowEventBinding": schema_pkg_apis_workflow_v1alpha1_WorkflowEventBinding(ref), "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.WorkflowEventBindingList": schema_pkg_apis_workflow_v1alpha1_WorkflowEventBindingList(ref), @@ -1548,37 +1549,6 @@ func schema_pkg_apis_workflow_v1alpha1_Histogram(ref common.ReferenceCallback) c } } -func schema_pkg_apis_workflow_v1alpha1_HolderNames(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "name": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Name stores the name of the resource holding lock", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_workflow_v1alpha1_Inputs(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1839,6 +1809,104 @@ func schema_pkg_apis_workflow_v1alpha1_Metrics(ref common.ReferenceCallback) com } } +func schema_pkg_apis_workflow_v1alpha1_Mutex(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Mutex holds Mutex configuration", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "name of the mutex", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_workflow_v1alpha1_MutexHolding(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "MutexHolding describes the mutex and the object which is holding it.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mutex": { + SchemaProps: spec.SchemaProps{ + Description: "Reference for the mutex e.g: ${namespace}/mutex/${mutexName}", + Type: []string{"string"}, + Format: "", + }, + }, + "holder": { + SchemaProps: spec.SchemaProps{ + Description: "Holder is a reference to the object which holds the Mutex. Holding Scenario:\n 1. Current workflow's NodeID which is holding the lock.\n e.g: ${NodeID}\nWaiting Scenario:\n 1. Current workflow or other workflow NodeID which is holding the lock.\n e.g: ${WorkflowName}/${NodeID}", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_workflow_v1alpha1_MutexStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "holding": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Holding is a list of mutexes and their respective objects that are held by mutex lock for this workflow.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexHolding"), + }, + }, + }, + }, + }, + "waiting": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Waiting is a list of mutexes and their respective objects this workflow is waiting for.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexHolding"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexHolding"}, + } +} + func schema_pkg_apis_workflow_v1alpha1_NodeStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2944,7 +3012,7 @@ func schema_pkg_apis_workflow_v1alpha1_SemaphoreStatus(ref common.ReferenceCallb }, "waiting": { SchemaProps: spec.SchemaProps{ - Description: "Waiting indicates the list of current synchronization lock holders", + Description: "Waiting indicates the list of current synchronization lock holders.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -3165,11 +3233,17 @@ func schema_pkg_apis_workflow_v1alpha1_Synchronization(ref common.ReferenceCallb Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.SemaphoreRef"), }, }, + "mutex": { + SchemaProps: spec.SchemaProps{ + Description: "Mutex holds the Mutex lock details", + Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Mutex"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.SemaphoreRef"}, + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.Mutex", "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.SemaphoreRef"}, } } @@ -3177,19 +3251,26 @@ func schema_pkg_apis_workflow_v1alpha1_SynchronizationStatus(ref common.Referenc return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, + Description: "SynchronizationStatus stores the status of semaphore and mutex.", + Type: []string{"object"}, Properties: map[string]spec.Schema{ "semaphore": { SchemaProps: spec.SchemaProps{ - Description: "SemaphoreHolders stores this workflow's Semaphore holder details", + Description: "Semaphore stores this workflow's Semaphore holder details", Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.SemaphoreStatus"), }, }, + "mutex": { + SchemaProps: spec.SchemaProps{ + Description: "Mutex stores this workflow's mutex holder details", + Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexStatus"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.SemaphoreStatus"}, + "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.MutexStatus", "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.SemaphoreStatus"}, } } @@ -3985,26 +4066,6 @@ func schema_pkg_apis_workflow_v1alpha1_Version(ref common.ReferenceCallback) com } } -func schema_pkg_apis_workflow_v1alpha1_WaitingStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "holders": { - SchemaProps: spec.SchemaProps{ - Description: "Holders stores the list of current holder names", - Ref: ref("github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.HolderNames"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1.HolderNames"}, - } -} - func schema_pkg_apis_workflow_v1alpha1_Workflow(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apis/workflow/v1alpha1/workflow_types.go b/pkg/apis/workflow/v1alpha1/workflow_types.go index 5a55b485810b..ce87186ff27a 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types.go @@ -860,6 +860,8 @@ type TemplateRef struct { type Synchronization struct { // Semaphore holds the Semaphore configuration Semaphore *SemaphoreRef `json:"semaphore,omitempty" protobuf:"bytes,1,opt,name=semaphore"` + // Mutex holds the Mutex lock details + Mutex *Mutex `json:"mutex,omitempty" protobuf:"bytes,2,opt,name=mutex"` } // SemaphoreRef is a reference of Semaphore @@ -868,6 +870,12 @@ type SemaphoreRef struct { ConfigMapKeyRef *apiv1.ConfigMapKeySelector `json:"configMapKeyRef,omitempty" protobuf:"bytes,1,opt,name=configMapKeyRef"` } +// Mutex holds Mutex configuration +type Mutex struct { + // name of the mutex + Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` +} + // WorkflowTemplateRef is a reference to a WorkflowTemplate resource. type WorkflowTemplateRef struct { // Name is the resource name of the workflow template. @@ -989,7 +997,7 @@ type WorkflowStatus struct { type SemaphoreStatus struct { // Holding stores the list of resource acquired synchronization lock for workflows. Holding []SemaphoreHolding `json:"holding,omitempty" protobuf:"bytes,1,opt,name=holding"` - // Waiting indicates the list of current synchronization lock holders + // Waiting indicates the list of current synchronization lock holders. Waiting []SemaphoreHolding `json:"waiting,omitempty" protobuf:"bytes,2,opt,name=waiting"` } @@ -1001,20 +1009,37 @@ type SemaphoreHolding struct { Holders []string `json:"holders,omitempty" protobuf:"bytes,2,opt,name=holders"` } -type WaitingStatus struct { - // Holders stores the list of current holder names - Holders HolderNames `json:"holders,omitempty" protobuf:"bytes,1,opt,name=holders"` -} - -type HolderNames struct { - // Name stores the name of the resource holding lock +// MutexHolding describes the mutex and the object which is holding it. +type MutexHolding struct { + // Reference for the mutex + // e.g: ${namespace}/mutex/${mutexName} + Mutex string `json:"mutex,omitempty" protobuf:"bytes,1,opt,name=mutex"` + // Holder is a reference to the object which holds the Mutex. + // Holding Scenario: + // 1. Current workflow's NodeID which is holding the lock. + // e.g: ${NodeID} + // Waiting Scenario: + // 1. Current workflow or other workflow NodeID which is holding the lock. + // e.g: ${WorkflowName}/${NodeID} + Holder string `json:"holder,omitempty" protobuf:"bytes,2,opt,name=holder"` +} + +// MutexStatus contains which objects hold mutex locks, and which objects this workflow is waiting on to release locks. +type MutexStatus struct { + // Holding is a list of mutexes and their respective objects that are held by mutex lock for this workflow. + // +listType=atomic + Holding []MutexHolding `json:"holding,omitempty" protobuf:"bytes,1,opt,name=holding"` + // Waiting is a list of mutexes and their respective objects this workflow is waiting for. // +listType=atomic - Name []string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` + Waiting []MutexHolding `json:"waiting,omitempty" protobuf:"bytes,2,opt,name=waiting"` } +// SynchronizationStatus stores the status of semaphore and mutex. type SynchronizationStatus struct { - // SemaphoreHolders stores this workflow's Semaphore holder details + // Semaphore stores this workflow's Semaphore holder details Semaphore *SemaphoreStatus `json:"semaphore,omitempty" protobuf:"bytes,1,opt,name=semaphore"` + // Mutex stores this workflow's mutex holder details + Mutex *MutexStatus `json:"mutex,omitempty" protobuf:"bytes,2,opt,name=mutex"` } func (ws *WorkflowStatus) IsOffloadNodeStatus() bool { diff --git a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go index 9ef0a3e7c2db..9ecd49cb26f4 100644 --- a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go @@ -887,27 +887,6 @@ func (in *Histogram) DeepCopy() *Histogram { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HolderNames) DeepCopyInto(out *HolderNames) { - *out = *in - if in.Name != nil { - in, out := &in.Name, &out.Name - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HolderNames. -func (in *HolderNames) DeepCopy() *HolderNames { - if in == nil { - return nil - } - out := new(HolderNames) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Inputs) DeepCopyInto(out *Inputs) { *out = *in @@ -1074,6 +1053,64 @@ func (in *Metrics) DeepCopy() *Metrics { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Mutex) DeepCopyInto(out *Mutex) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mutex. +func (in *Mutex) DeepCopy() *Mutex { + if in == nil { + return nil + } + out := new(Mutex) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutexHolding) DeepCopyInto(out *MutexHolding) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutexHolding. +func (in *MutexHolding) DeepCopy() *MutexHolding { + if in == nil { + return nil + } + out := new(MutexHolding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MutexStatus) DeepCopyInto(out *MutexStatus) { + *out = *in + if in.Holding != nil { + in, out := &in.Holding, &out.Holding + *out = make([]MutexHolding, len(*in)) + copy(*out, *in) + } + if in.Waiting != nil { + in, out := &in.Waiting, &out.Waiting + *out = make([]MutexHolding, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutexStatus. +func (in *MutexStatus) DeepCopy() *MutexStatus { + if in == nil { + return nil + } + out := new(MutexStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeStatus) DeepCopyInto(out *NodeStatus) { *out = *in @@ -1692,6 +1729,11 @@ func (in *Synchronization) DeepCopyInto(out *Synchronization) { *out = new(SemaphoreRef) (*in).DeepCopyInto(*out) } + if in.Mutex != nil { + in, out := &in.Mutex, &out.Mutex + *out = new(Mutex) + **out = **in + } return } @@ -1713,6 +1755,11 @@ func (in *SynchronizationStatus) DeepCopyInto(out *SynchronizationStatus) { *out = new(SemaphoreStatus) (*in).DeepCopyInto(*out) } + if in.Mutex != nil { + in, out := &in.Mutex, &out.Mutex + *out = new(MutexStatus) + (*in).DeepCopyInto(*out) + } return } @@ -2027,23 +2074,6 @@ func (in *Version) DeepCopy() *Version { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WaitingStatus) DeepCopyInto(out *WaitingStatus) { - *out = *in - in.Holders.DeepCopyInto(&out.Holders) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WaitingStatus. -func (in *WaitingStatus) DeepCopy() *WaitingStatus { - if in == nil { - return nil - } - out := new(WaitingStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Workflow) DeepCopyInto(out *Workflow) { *out = *in diff --git a/test/e2e/cli_test.go b/test/e2e/cli_test.go index 69fc4dbd6565..735de3182429 100644 --- a/test/e2e/cli_test.go +++ b/test/e2e/cli_test.go @@ -1023,6 +1023,45 @@ func (s *CLISuite) TestRetryOmit() { WaitForWorkflow(20 * time.Second) } +func (s *CLISuite) TestSynchronizationWfLevelMutex() { + s.testNeedsOffloading() + s.Given(). + Workflow("@functional/synchronization-mutex-wf-level.yaml"). + When(). + RunCli([]string{"submit", "functional/synchronization-mutex-wf-level-1.yaml"}, func(t *testing.T, output string, err error) { + if assert.NoError(t, err) { + assert.Contains(t, output, "synchronization-wf-level-mutex") + } + }). + SubmitWorkflow(). + Wait(1*time.Second). + RunCli([]string{"get", "synchronization-wf-level-mutex"}, func(t *testing.T, output string, err error) { + assert.Contains(t, output, "Pending") + }). + WaitForWorkflow(30 * time.Second). + Then(). + ExpectWorkflow(func(t *testing.T, _ *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.NodeSucceeded, status.Phase) + }) +} + +func (s *CLISuite) TestTemplateLevelMutex() { + s.testNeedsOffloading() + s.Given(). + Workflow("@functional/synchronization-mutex-tmpl-level.yaml"). + When(). + SubmitWorkflow(). + Wait(3*time.Second). + RunCli([]string{"get", "synchronization-tmpl-level-mutex"}, func(t *testing.T, output string, err error) { + assert.Contains(t, output, "Waiting for") + }). + WaitForWorkflow(30 * time.Second). + Then(). + ExpectWorkflow(func(t *testing.T, _ *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Equal(t, wfv1.NodeSucceeded, status.Phase) + }) +} + func (s *CLIWithServerSuite) TestResourceTemplateStopAndTerminate() { s.testNeedsOffloading() s.Run("ResourceTemplateStop", func() { diff --git a/test/e2e/functional/synchronization-mutex-tmpl-level.yaml b/test/e2e/functional/synchronization-mutex-tmpl-level.yaml new file mode 100644 index 000000000000..74a88f4b70bd --- /dev/null +++ b/test/e2e/functional/synchronization-mutex-tmpl-level.yaml @@ -0,0 +1,42 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: synchronization-tmpl-level-mutex + labels: + argo-e2e: true +spec: + entrypoint: synchronization-tmpl-level-example-mutex + templates: + - name: synchronization-tmpl-level-example-mutex + steps: + - - name: synchronization-acquire-lock + template: acquire-lock + arguments: + parameters: + - name: seconds + value: "{{item}}" + withParam: '["1","2"]' + + - name: synchronization-acquire-lock-1 + template: acquire-lock-1 + arguments: + parameters: + - name: seconds + value: "{{item}}" + withParam: '["1","2"]' + + - name: acquire-lock + synchronization: + mutex: + name: welcome + container: + image: argoproj/argosay:v2 + args: ["sleep", "5s"] + + - name: acquire-lock-1 + synchronization: + mutex: + name: test + container: + image: argoproj/argosay:v2 + args: ["sleep", "5s"] \ No newline at end of file diff --git a/test/e2e/functional/synchronization-mutex-wf-level-1.yaml b/test/e2e/functional/synchronization-mutex-wf-level-1.yaml new file mode 100644 index 000000000000..faf3d3456ee2 --- /dev/null +++ b/test/e2e/functional/synchronization-mutex-wf-level-1.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: synchronization-wf-level-mutex-1 + labels: + argo-e2e: true +spec: + entrypoint: whalesay + synchronization: + mutex: + name: test + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 + args: ["sleep", "5s"] diff --git a/test/e2e/functional/synchronization-mutex-wf-level.yaml b/test/e2e/functional/synchronization-mutex-wf-level.yaml new file mode 100644 index 000000000000..b996fc6622b5 --- /dev/null +++ b/test/e2e/functional/synchronization-mutex-wf-level.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: synchronization-wf-level-mutex + labels: + argo-e2e: true +spec: + entrypoint: whalesay + synchronization: + mutex: + name: test + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 + args: ["sleep", "5s"] diff --git a/workflow/sync/mutex.go b/workflow/sync/mutex.go new file mode 100644 index 000000000000..d6ef261a3fbd --- /dev/null +++ b/workflow/sync/mutex.go @@ -0,0 +1,63 @@ +package sync + +import ( + "sync" + "time" +) + +type Mutex struct { + name string + mutex *Semaphore + lock *sync.Mutex +} + +// NewMutex creates new mutex lock object +// name of the mutex +// callbackFunc is a release notification function. +func NewMutex(name string, callbackFunc func(string)) *Mutex { + return &Mutex{ + name: name, + lock: &sync.Mutex{}, + mutex: NewSemaphore(name, 1, callbackFunc, LockTypeMutex), + } +} + +func (m *Mutex) getName() string { + return m.name +} + +func (m *Mutex) getLimit() int { + return m.mutex.limit +} + +func (m *Mutex) getCurrentHolders() []string { + return m.mutex.getCurrentHolders() +} + +func (m *Mutex) resize(n int) bool { + return false +} + +func (m *Mutex) release(key string) bool { + m.lock.Lock() + defer m.lock.Unlock() + return m.mutex.release(key) +} + +func (m *Mutex) acquire(holderKey string) bool { + m.lock.Lock() + defer m.lock.Unlock() + return m.mutex.acquire(holderKey) +} + +func (m *Mutex) addToQueue(holderKey string, priority int32, creationTime time.Time) { + m.lock.Lock() + defer m.lock.Unlock() + m.mutex.addToQueue(holderKey, priority, creationTime) +} + +func (m *Mutex) tryAcquire(holderKey string) (bool, string) { + m.lock.Lock() + defer m.lock.Unlock() + return m.mutex.tryAcquire(holderKey) +} diff --git a/workflow/sync/mutex_test.go b/workflow/sync/mutex_test.go new file mode 100644 index 000000000000..3c1d34e233c5 --- /dev/null +++ b/workflow/sync/mutex_test.go @@ -0,0 +1,326 @@ +package sync + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + + fakewfclientset "github.com/argoproj/argo/pkg/client/clientset/versioned/fake" +) + +var mutexWf = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: synchronization-wf-level- +spec: + entrypoint: whalesay + synchronization: + mutex: + name: test + templates: + - name: whalesay + container: + image: docker/whalesay:latest + command: [cowsay] + args: ["hello world"] +` + +var mutexwfstatus = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + creationTimestamp: "2020-07-31T20:35:41Z" + generateName: synchronization-wf-level- + generation: 5 + labels: + workflows.argoproj.io/phase: Running + name: synchronization-wf-level-xxs94 + namespace: default + resourceVersion: "347429" + selfLink: /apis/argoproj.io/v1alpha1/namespaces/default/workflows/synchronization-wf-level-xxs94 + uid: fad73006-e1f3-4234-b04b-38c0bf79c5c1 +spec: + arguments: {} + entrypoint: whalesay + synchronization: + mutex: + name: test + templates: + - arguments: {} + container: + args: + - hello world + command: + - cowsay + image: docker/whalesay:latest + name: "" + resources: {} + inputs: {} + metadata: {} + name: whalesay + outputs: {} +status: + finishedAt: null + nodes: + synchronization-wf-level-xxs94: + displayName: synchronization-wf-level-xxs94 + finishedAt: null + hostNodeName: docker-desktop + id: synchronization-wf-level-xxs94 + message: ContainerCreating + name: synchronization-wf-level-xxs94 + phase: Pending + startedAt: "2020-07-31T20:35:49Z" + templateName: whalesay + templateScope: local/synchronization-wf-level-xxs94 + type: Pod + phase: Running + startedAt: "2020-07-31T20:35:49Z" + synchronization: + mutex: + holding: + - holder: synchronization-wf-level-xxs94 + mutex: default/mutex/test +` + +func TestMutexLock(t *testing.T) { + kube := fake.NewSimpleClientset() + syncLimitFunc := GetSyncLimitFunc(kube) + t.Run("InitializeSynchronization", func(t *testing.T) { + concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) { + }) + wf := unmarshalWF(mutexwfstatus) + wfclientset := fakewfclientset.NewSimpleClientset(wf) + + wfList, err := wfclientset.ArgoprojV1alpha1().Workflows("default").List(metav1.ListOptions{}) + assert.NoError(t, err) + concurrenyMgr.Initialize(wfList) + assert.Equal(t, 1, len(concurrenyMgr.syncLockMap)) + }) + t.Run("WfLevelMutexAcquireAndRelease", func(t *testing.T) { + var nextKey string + concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) { + nextKey = key + }) + wf := unmarshalWF(mutexWf) + wf1 := wf.DeepCopy() + wf2 := wf.DeepCopy() + wf3 := wf.DeepCopy() + status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "", 0, time.Now(), wf.Spec.Synchronization) + assert.NoError(t, err) + assert.Empty(t, msg) + assert.True(t, status) + assert.True(t, wfUpdate) + assert.NotNil(t, wf.Status.Synchronization) + assert.NotNil(t, wf.Status.Synchronization.Mutex) + assert.NotNil(t, wf.Status.Synchronization.Mutex.Holding) + assert.Equal(t, wf.Name, wf.Status.Synchronization.Mutex.Holding[0].Holder) + + // Try to acquire again + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "", 0, time.Now(), wf.Spec.Synchronization) + assert.NoError(t, err) + assert.True(t, status) + assert.Empty(t, msg) + assert.False(t, wfUpdate) + + wf1.Name = "two" + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", 0, time.Now(), wf1.Spec.Synchronization) + assert.NoError(t, err) + assert.NotEmpty(t, msg) + assert.False(t, status) + assert.True(t, wfUpdate) + + wf2.Name = "three" + holderKey2 := getHolderKey(wf2, "") + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", 5, time.Now(), wf2.Spec.Synchronization) + assert.NoError(t, err) + assert.NotEmpty(t, msg) + assert.False(t, status) + assert.True(t, wfUpdate) + + wf3.Name = "four" + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf3, "", 0, time.Now(), wf3.Spec.Synchronization) + assert.NoError(t, err) + assert.NotEmpty(t, msg) + assert.False(t, status) + assert.True(t, wfUpdate) + + concurrenyMgr.Release(wf, "", wf.Namespace, wf.Spec.Synchronization) + assert.Equal(t, holderKey2, nextKey) + assert.NotNil(t, wf.Status.Synchronization) + assert.Equal(t, 0, len(wf.Status.Synchronization.Mutex.Holding)) + + // Low priority workflow try to acquire the lock + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf1, "", 0, time.Now(), wf1.Spec.Synchronization) + assert.NoError(t, err) + assert.NotEmpty(t, msg) + assert.False(t, status) + assert.True(t, wfUpdate) + + // High Priority workflow acquires the lock + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf2, "", 5, time.Now(), wf2.Spec.Synchronization) + assert.NoError(t, err) + assert.Empty(t, msg) + assert.True(t, status) + assert.True(t, wfUpdate) + assert.NotNil(t, wf2.Status.Synchronization) + assert.NotNil(t, wf2.Status.Synchronization.Mutex) + assert.Equal(t, wf2.Name, wf2.Status.Synchronization.Mutex.Holding[0].Holder) + concurrenyMgr.ReleaseAll(wf2) + assert.Nil(t, wf2.Status.Synchronization) + }) + +} + +var mutexWfWithTmplLevel = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + name: synchronization-tmpl-level-mutex-vjcdk + namespace: default +spec: + entrypoint: synchronization-tmpl-level-mutex-example + templates: + - name: synchronization-tmpl-level-mutex-example + steps: + - - arguments: + parameters: + - name: seconds + value: '{{item}}' + name: synchronization-acquire-lock + template: acquire-lock + withParam: '["1","2","3"]' + - container: + args: + - sleep 20; echo acquired lock + command: + - sh + - -c + image: alpine:latest + name: "" + name: acquire-lock + synchronization: + mutex: + name: welcome +status: + finishedAt: null + nodes: + synchronization-tmpl-level-mutex-vjcdk: + children: + - synchronization-tmpl-level-mutex-vjcdk-1320763997 + displayName: synchronization-tmpl-level-mutex-vjcdk + finishedAt: null + id: synchronization-tmpl-level-mutex-vjcdk + name: synchronization-tmpl-level-mutex-vjcdk + phase: Pending + startedAt: "2020-08-03T04:13:26Z" + templateName: synchronization-tmpl-level-mutex-example + templateScope: local/synchronization-tmpl-level-mutex-vjcdk + type: Steps + synchronization-tmpl-level-mutex-vjcdk-1320763997: + boundaryID: synchronization-tmpl-level-mutex-vjcdk + children: + - synchronization-tmpl-level-mutex-vjcdk-3941195474 + - synchronization-tmpl-level-mutex-vjcdk-1432992664 + - synchronization-tmpl-level-mutex-vjcdk-2216915482 + displayName: '[0]' + finishedAt: null + id: synchronization-tmpl-level-mutex-vjcdk-1320763997 + name: synchronization-tmpl-level-mutex-vjcdk[0] + phase: Pending + startedAt: "2020-08-03T04:13:26Z" + templateName: synchronization-tmpl-level-mutex-example + templateScope: local/synchronization-tmpl-level-mutex-vjcdk + type: StepGroup + synchronization-tmpl-level-mutex-vjcdk-1432992664: + boundaryID: synchronization-tmpl-level-mutex-vjcdk + displayName: synchronization-acquire-lock(1:2) + finishedAt: null + id: synchronization-tmpl-level-mutex-vjcdk-1432992664 + message: 'Waiting for argo/mutex/welcome lock. Lock status: 0/1 ' + name: synchronization-tmpl-level-mutex-vjcdk[0].synchronization-acquire-lock(1:2) + phase: Pending + startedAt: "2020-08-03T04:13:26Z" + templateName: acquire-lock + templateScope: local/synchronization-tmpl-level-mutex-vjcdk + type: Pod + synchronization-tmpl-level-mutex-vjcdk-2216915482: + boundaryID: synchronization-tmpl-level-mutex-vjcdk + displayName: synchronization-acquire-lock(2:3) + finishedAt: null + id: synchronization-tmpl-level-mutex-vjcdk-2216915482 + message: 'Waiting for argo/mutex/welcome lock. Lock status: 0/1 ' + name: synchronization-tmpl-level-mutex-vjcdk[0].synchronization-acquire-lock(2:3) + phase: Pending + startedAt: "2020-08-03T04:13:26Z" + templateName: acquire-lock + templateScope: local/synchronization-tmpl-level-mutex-vjcdk + type: Pod + synchronization-tmpl-level-mutex-vjcdk-3941195474: + boundaryID: synchronization-tmpl-level-mutex-vjcdk + displayName: synchronization-acquire-lock(0:1) + finishedAt: null + id: synchronization-tmpl-level-mutex-vjcdk-3941195474 + name: synchronization-tmpl-level-mutex-vjcdk[0].synchronization-acquire-lock(0:1) + phase: Pending + startedAt: "2020-08-03T04:13:26Z" + templateName: acquire-lock + templateScope: local/synchronization-tmpl-level-mutex-vjcdk + type: Pod + phase: Running + startedAt: "2020-08-03T04:13:26Z" +` + +func TestMutexTmplLevel(t *testing.T) { + kube := fake.NewSimpleClientset() + + syncLimitFunc := GetSyncLimitFunc(kube) + t.Run("TemplateLevelAcquireAndRelease", func(t *testing.T) { + //var nextKey string + concurrenyMgr := NewLockManager(syncLimitFunc, func(key string) { + //nextKey = key + }) + wf := unmarshalWF(mutexWfWithTmplLevel) + tmpl := wf.Spec.Templates[1] + + status, wfUpdate, msg, err := concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", 0, time.Now(), tmpl.Synchronization) + assert.NoError(t, err) + assert.Empty(t, msg) + assert.True(t, status) + assert.True(t, wfUpdate) + assert.NotNil(t, wf.Status.Synchronization) + assert.NotNil(t, wf.Status.Synchronization.Mutex) + assert.Equal(t, "synchronization-tmpl-level-mutex-vjcdk-3941195474", wf.Status.Synchronization.Mutex.Holding[0].Holder) + + // Try to acquire again + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-2216915482", 0, time.Now(), tmpl.Synchronization) + assert.NoError(t, err) + assert.True(t, wfUpdate) + assert.False(t, status) + assert.NotEmpty(t, msg) + + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-1432992664", 0, time.Now(), tmpl.Synchronization) + assert.NoError(t, err) + assert.NotEmpty(t, msg) + assert.True(t, wfUpdate) + assert.False(t, status) + + concurrenyMgr.Release(wf, "synchronization-tmpl-level-mutex-vjcdk-3941195474", wf.Namespace, tmpl.Synchronization) + assert.NotNil(t, wf.Status.Synchronization) + assert.NotNil(t, wf.Status.Synchronization.Mutex) + assert.Empty(t, wf.Status.Synchronization.Mutex.Holding) + + status, wfUpdate, msg, err = concurrenyMgr.TryAcquire(wf, "synchronization-tmpl-level-mutex-vjcdk-2216915482", 0, time.Now(), tmpl.Synchronization) + assert.NoError(t, err) + assert.Empty(t, msg) + assert.True(t, status) + assert.True(t, wfUpdate) + assert.NotNil(t, wf.Status.Synchronization) + assert.NotNil(t, wf.Status.Synchronization.Mutex) + assert.Equal(t, "synchronization-tmpl-level-mutex-vjcdk-2216915482", wf.Status.Synchronization.Mutex.Holding[0].Holder) + }) +} diff --git a/workflow/sync/semaphore.go b/workflow/sync/semaphore.go index e5ae35ebd516..6f913eae153b 100644 --- a/workflow/sync/semaphore.go +++ b/workflow/sync/semaphore.go @@ -22,7 +22,7 @@ type Semaphore struct { log *log.Entry } -func NewSemaphore(name string, limit int, callbackFunc func(string)) *Semaphore { +func NewSemaphore(name string, limit int, callbackFunc func(string), lockType LockType) *Semaphore { return &Semaphore{ name: name, limit: limit, @@ -33,7 +33,7 @@ func NewSemaphore(name string, limit int, callbackFunc func(string)) *Semaphore lock: &sync.Mutex{}, releaseNotifyFunc: callbackFunc, log: log.WithFields(log.Fields{ - "semaphore": name, + string(lockType): name, }), } } diff --git a/workflow/sync/sync_manager.go b/workflow/sync/sync_manager.go index de274a6ff0b7..492b43144c97 100644 --- a/workflow/sync/sync_manager.go +++ b/workflow/sync/sync_manager.go @@ -28,6 +28,7 @@ type LockName struct { Kind string ResourceName string Key string + Type LockType } type Synchronization interface { @@ -53,6 +54,7 @@ type LockType string const ( LockTypeSemaphore LockType = "semaphore" + LockTypeMutex LockType = "mutex" ) func NewLockManager(getSyncLimitConfigFunc func(string) (int, error), callbackFunc func(string)) *SyncManager { @@ -67,24 +69,43 @@ func NewLockManager(getSyncLimitConfigFunc func(string) (int, error), callbackFu func (cm *SyncManager) Initialize(wfList *wfv1.WorkflowList) { for _, wf := range wfList.Items { - if wf.Status.Synchronization == nil || wf.Status.Synchronization.Semaphore == nil || wf.Status.Synchronization.Semaphore.Holding == nil { + if wf.Status.Synchronization == nil { continue } - for _, holding := range wf.Status.Synchronization.Semaphore.Holding { - semaphore := cm.syncLockMap[holding.Semaphore] - if semaphore == nil { - semaphore, err := cm.initializeSemaphore(holding.Semaphore) - if err != nil { - log.Warnf("Synchronization configmap %s is not found. %v", holding.Semaphore, err) - continue + if wf.Status.Synchronization.Semaphore != nil { + for _, holding := range wf.Status.Synchronization.Semaphore.Holding { + semaphore := cm.syncLockMap[holding.Semaphore] + if semaphore == nil { + semaphore, err := cm.initializeSemaphore(holding.Semaphore) + if err != nil { + log.Warnf("Synchronization configmap %s is not found. %v", holding.Semaphore, err) + continue + } + + cm.syncLockMap[holding.Semaphore] = semaphore + } + for _, ele := range holding.Holders { + resourceKey := getResourceKey(wf.Namespace, wf.Name, ele) + if semaphore != nil && semaphore.acquire(resourceKey) { + log.Infof("Lock acquired by %s from %s", resourceKey, holding.Semaphore) + } } - - cm.syncLockMap[holding.Semaphore] = semaphore } - for _, ele := range holding.Holders { - resourceKey := getResourceKey(wf.Namespace, wf.Name, ele) - if semaphore != nil && semaphore.acquire(resourceKey) { - log.Infof("Lock acquired by %s from %s", resourceKey, holding.Semaphore) + } + if wf.Status.Synchronization.Mutex != nil { + for _, holding := range wf.Status.Synchronization.Mutex.Holding { + mutex := cm.syncLockMap[holding.Mutex] + if mutex == nil { + mutex, err := cm.initializeMutex(holding.Mutex) + if err != nil { + log.Warnf("Synchronization Mutex %s initialization failed. %v", holding.Mutex, err) + continue + } + if holding.Holder != "" { + resourceKey := getResourceKey(wf.Namespace, wf.Name, holding.Holder) + mutex.acquire(resourceKey) + } + cm.syncLockMap[holding.Mutex] = mutex } } } @@ -104,7 +125,11 @@ func (cm *SyncManager) initializeSemaphore(semaphoreName string) (Synchronizatio if err != nil { return nil, err } - return NewSemaphore(semaphoreName, limit, cm.releaseNotifyFunc), nil + return NewSemaphore(semaphoreName, limit, cm.releaseNotifyFunc, LockTypeSemaphore), nil +} + +func (cm *SyncManager) initializeMutex(mutexName string) (Synchronization, error) { + return NewMutex(mutexName, cm.releaseNotifyFunc), nil } func (cm *SyncManager) isSemaphoreSizeChanged(semaphore Synchronization) (bool, int, error) { @@ -160,6 +185,18 @@ func (cm *SyncManager) TryAcquire(wf *wfv1.Workflow, nodeName string, priority i return false, false, "", err } lockType = LockTypeSemaphore + } else if syncLockRef.Mutex != nil { + syncLockName = getMutexLockName(wf.Namespace, syncLockRef.Mutex) + mutexLockKey := syncLockName.getLockKey() + _, found := cm.syncLockMap[mutexLockKey] + if !found { + mutexLock, err := cm.initializeMutex(mutexLockKey) + if err != nil { + return false, false, "", err + } + cm.syncLockMap[mutexLockKey] = mutexLock + } + lockType = LockTypeMutex } if syncLockName == nil { @@ -202,6 +239,14 @@ func (cm *SyncManager) Release(wf *wfv1.Workflow, nodeName, namespace string, sy cm.updateConcurrencyStatus(holderKey, lockName.getLockKey(), LockTypeSemaphore, LockActionReleased, wf) } } + if syncRef.Mutex != nil { + lockName := getMutexLockName(namespace, syncRef.Mutex) + if syncLockHolder, ok := cm.syncLockMap[lockName.getLockKey()]; ok { + syncLockHolder.release(holderKey) + log.Debugf("%s sync lock is released by %s", lockName.getLockKey(), holderKey) + cm.updateConcurrencyStatus(holderKey, lockName.getLockKey(), LockTypeMutex, LockActionReleased, wf) + } + } } func (cm *SyncManager) ReleaseAll(wf *wfv1.Workflow) bool { @@ -226,61 +271,138 @@ func (cm *SyncManager) ReleaseAll(wf *wfv1.Workflow) bool { } // Clear the Synchronization details wf.Status.Synchronization.Semaphore = nil - wf.Status.Synchronization = nil } + if wf.Status.Synchronization.Mutex != nil { + for _, ele := range wf.Status.Synchronization.Mutex.Holding { + syncLockHolder := cm.syncLockMap[ele.Mutex] + if syncLockHolder == nil { + continue + } + resourceKey := getResourceKey(wf.Namespace, wf.Name, ele.Holder) + syncLockHolder.release(resourceKey) + cm.updateConcurrencyStatus(ele.Holder, ele.Mutex, LockTypeMutex, LockActionReleased, wf) + log.Infof("%s released a lock from %s", resourceKey, ele.Mutex) + } + wf.Status.Synchronization.Mutex = nil + } + wf.Status.Synchronization = nil return true } -// updateConcurrencyStatus updates the synchronization status update -// It return the status of workflow updated or not. -func (cm *SyncManager) updateConcurrencyStatus(holderKey, lockKey string, lockType LockType, lockAction LockAction, wf *wfv1.Workflow) bool { - - if wf.Status.Synchronization == nil { +// updateSemaphoreStatus updates the semaphore holding and waiting details +func (cm *SyncManager) updateSemaphoreStatus(holderKey, lockKey string, lockAction LockAction, wf *wfv1.Workflow) bool { + if wf.Status.Synchronization == nil || wf.Status.Synchronization.Semaphore == nil { wf.Status.Synchronization = &wfv1.SynchronizationStatus{Semaphore: &wfv1.SemaphoreStatus{}} } - if lockType == LockTypeSemaphore { - if lockAction == LockActionWaiting { - index, semaphoreWaiting := getSemaphoreHolding(wf.Status.Synchronization.Semaphore.Waiting, lockKey) - currentHolder := cm.getCurrentLockHolders(lockKey) - if index == -1 { - wf.Status.Synchronization.Semaphore.Waiting = append(wf.Status.Synchronization.Semaphore.Waiting, wfv1.SemaphoreHolding{Semaphore: lockKey, Holders: currentHolder}) - } else { - semaphoreWaiting.Holders = currentHolder - wf.Status.Synchronization.Semaphore.Waiting[index] = semaphoreWaiting - } + // Update the semaphore which the workflow is waiting for + if lockAction == LockActionWaiting { + index, semaphoreWaiting := getSemaphoreHolding(wf.Status.Synchronization.Semaphore.Waiting, lockKey) + currentHolder := cm.getCurrentLockHolders(lockKey) + if index == -1 { + wf.Status.Synchronization.Semaphore.Waiting = append(wf.Status.Synchronization.Semaphore.Waiting, wfv1.SemaphoreHolding{Semaphore: lockKey, Holders: currentHolder}) + } else { + semaphoreWaiting.Holders = currentHolder + wf.Status.Synchronization.Semaphore.Waiting[index] = semaphoreWaiting + } + return true + } + // Update the semaphore which is acquired by the workflow + if lockAction == LockActionAcquired { + index, semaphoreHolding := getSemaphoreHolding(wf.Status.Synchronization.Semaphore.Holding, lockKey) + items := strings.Split(holderKey, "/") + holdingName := items[len(items)-1] + if index == -1 { + wf.Status.Synchronization.Semaphore.Holding = append(wf.Status.Synchronization.Semaphore.Holding, wfv1.SemaphoreHolding{Semaphore: lockKey, Holders: []string{holdingName}}) return true + } else { + if !slice.ContainsString(semaphoreHolding.Holders, holdingName) { + semaphoreHolding.Holders = append(semaphoreHolding.Holders, holdingName) + wf.Status.Synchronization.Semaphore.Holding[index] = semaphoreHolding + return true + } + } + return false + } + // Clear the semaphore which is released by the workflow + if lockAction == LockActionReleased { + items := strings.Split(holderKey, "/") + holdingName := items[len(items)-1] + index, semaphoreHolding := getSemaphoreHolding(wf.Status.Synchronization.Semaphore.Holding, lockKey) + if index != -1 { + semaphoreHolding.Holders = slice.RemoveString(semaphoreHolding.Holders, holdingName) + wf.Status.Synchronization.Semaphore.Holding[index] = semaphoreHolding } + return true + } + return false +} - if lockAction == LockActionAcquired { - index, semaphoreHolding := getSemaphoreHolding(wf.Status.Synchronization.Semaphore.Holding, lockKey) - items := strings.Split(holderKey, "/") - holdingName := items[len(items)-1] - if index == -1 { - wf.Status.Synchronization.Semaphore.Holding = append(wf.Status.Synchronization.Semaphore.Holding, wfv1.SemaphoreHolding{Semaphore: lockKey, Holders: []string{holdingName}}) - return true - } else { - if !slice.ContainsString(semaphoreHolding.Holders, holdingName) { - semaphoreHolding.Holders = append(semaphoreHolding.Holders, holdingName) - wf.Status.Synchronization.Semaphore.Holding[index] = semaphoreHolding - return true - } +// updateMutexStatus updates the mutex holding and waiting details +func (cm *SyncManager) updateMutexStatus(holderKey, lockKey string, lockAction LockAction, wf *wfv1.Workflow) bool { + if wf.Status.Synchronization == nil || wf.Status.Synchronization.Mutex == nil { + wf.Status.Synchronization = &wfv1.SynchronizationStatus{Mutex: &wfv1.MutexStatus{}} + } + // Update mutex which the workflow is waiting for + if lockAction == LockActionWaiting { + index, mutexWaiting := getMutexHolding(wf.Status.Synchronization.Mutex.Waiting, lockKey) + currentHolder := cm.getCurrentLockHolders(lockKey) + if len(currentHolder) == 0 { + return true + } + if index == -1 { + wf.Status.Synchronization.Mutex.Waiting = append(wf.Status.Synchronization.Mutex.Waiting, wfv1.MutexHolding{Mutex: lockKey, Holder: currentHolder[0]}) + } else { + if mutexWaiting.Holder != currentHolder[0] { + mutexWaiting.Holder = currentHolder[0] + wf.Status.Synchronization.Mutex.Waiting[index] = mutexWaiting } - return false } - if lockAction == LockActionReleased { - items := strings.Split(holderKey, "/") - holdingName := items[len(items)-1] - index, semaphoreHolding := getSemaphoreHolding(wf.Status.Synchronization.Semaphore.Holding, lockKey) - if index != -1 { - semaphoreHolding.Holders = slice.RemoveString(semaphoreHolding.Holders, holdingName) - wf.Status.Synchronization.Semaphore.Holding[index] = semaphoreHolding + return true + } + // Update mutex which is acquired by the workflow + if lockAction == LockActionAcquired { + index, mutexHolding := getMutexHolding(wf.Status.Synchronization.Mutex.Holding, lockKey) + items := strings.Split(holderKey, "/") + holdingName := items[len(items)-1] + if index == -1 { + wf.Status.Synchronization.Mutex.Holding = append(wf.Status.Synchronization.Mutex.Holding, wfv1.MutexHolding{Mutex: lockKey, Holder: holdingName}) + return true + } else { + if mutexHolding.Holder != holdingName { + mutexHolding.Holder = holdingName + wf.Status.Synchronization.Mutex.Holding[index] = mutexHolding + return true } } + return false + } + // Clear the mutex which is released by the workflow + if lockAction == LockActionReleased { + index, _ := getMutexHolding(wf.Status.Synchronization.Mutex.Holding, lockKey) + if index != -1 { + wf.Status.Synchronization.Mutex.Holding = append(wf.Status.Synchronization.Mutex.Holding[:index], wf.Status.Synchronization.Mutex.Holding[index+1:]...) + } + return true + } + return false +} + +// updateConcurrencyStatus updates the synchronization status update +// It return the status of workflow updated or not. +func (cm *SyncManager) updateConcurrencyStatus(holderKey, lockKey string, lockType LockType, lockAction LockAction, wf *wfv1.Workflow) bool { + + if lockType == LockTypeSemaphore { + return cm.updateSemaphoreStatus(holderKey, lockKey, lockAction, wf) + } else if lockType == LockTypeMutex { + return cm.updateMutexStatus(holderKey, lockKey, lockAction, wf) } return false } func (ln *LockName) getLockKey() string { + if ln.Kind == string(LockTypeMutex) { + return fmt.Sprintf("%s/%s/%s", ln.Namespace, ln.Kind, ln.ResourceName) + } return fmt.Sprintf("%s/%s/%s/%s", ln.Namespace, ln.Kind, ln.ResourceName, ln.Key) } func (ln *LockName) validate() error { @@ -293,7 +415,7 @@ func (ln *LockName) validate() error { if ln.ResourceName == "" { return errors.New(errors.CodeBadRequest, "Invalid Lock Key. ResourceName is missing") } - if ln.Key == "" { + if ln.Kind != string(LockTypeMutex) && ln.Key == "" { return errors.New(errors.CodeBadRequest, "Invalid Lock Key. Key is missing") } return nil @@ -301,15 +423,20 @@ func (ln *LockName) validate() error { func DecodeLockName(lockName string) (*LockName, error) { items := strings.Split(lockName, "/") - if len(items) < 4 { + var lock LockName + // For mutex lockname + if len(items) == 3 && items[1] == string(LockTypeMutex) { + lock = LockName{Namespace: items[0], Kind: items[1], ResourceName: items[2]} + } else if len(items) == 4 { // For Semaphore lockname + lock = LockName{Namespace: items[0], Kind: items[1], ResourceName: items[2], Key: items[3]} + } else { return nil, errors.New(errors.CodeBadRequest, "Invalid Lock Key") } - lock := &LockName{Namespace: items[0], Kind: items[1], ResourceName: items[2], Key: items[3]} err := lock.validate() if err != nil { return nil, err } - return lock, nil + return &lock, nil } func NewLockName(namespace, kind, resourceName, lockKey string) *LockName { @@ -339,6 +466,10 @@ func getSemaphoreLockName(namespace string, semaphoreRef *wfv1.SemaphoreRef) *Lo return nil } +func getMutexLockName(namespace string, mutex *wfv1.Mutex) *LockName { + return NewLockName(namespace, string(LockTypeMutex), mutex.Name, "") +} + func getResourceKey(namespace, wfName, resourceName string) string { resourceKey := fmt.Sprintf("%s/%s", namespace, wfName) // Template level semaphore @@ -356,3 +487,12 @@ func getSemaphoreHolding(semaphoreHolding []wfv1.SemaphoreHolding, semaphoreName } return -1, wfv1.SemaphoreHolding{} } + +func getMutexHolding(mutexHolding []wfv1.MutexHolding, mutexName string) (int, wfv1.MutexHolding) { + for idx, holder := range mutexHolding { + if holder.Mutex == mutexName { + return idx, holder + } + } + return -1, wfv1.MutexHolding{} +}