Sfoglia il codice sorgente

Add swarm jobs

Adds support for ReplicatedJob and GlobalJob service modes. These modes
allow running service which execute tasks that exit upon success,
instead of daemon-type tasks.

Signed-off-by: Drew Erny <drew.erny@docker.com>
Drew Erny 5 anni fa
parent
commit
30d9fe30b1
32 ha cambiato i file con 3069 aggiunte e 888 eliminazioni
  1. 6 0
      api/server/router/swarm/helpers.go
  2. 53 0
      api/swagger.yaml
  3. 59 2
      api/types/swarm/service.go
  4. 6 0
      api/types/swarm/task.go
  5. 56 2
      daemon/cluster/convert/service.go
  6. 6 0
      daemon/cluster/convert/task.go
  7. 7 2
      daemon/cluster/services.go
  8. 19 2
      docs/api/version-history.md
  9. 8 1
      integration/internal/swarm/service.go
  10. 81 0
      integration/internal/swarm/states.go
  11. 143 0
      integration/service/jobs_test.go
  12. 1 1
      vendor.conf
  13. 209 174
      vendor/github.com/docker/swarmkit/api/control.pb.go
  14. 7 0
      vendor/github.com/docker/swarmkit/api/control.proto
  15. 280 159
      vendor/github.com/docker/swarmkit/api/objects.pb.go
  16. 8 0
      vendor/github.com/docker/swarmkit/api/objects.proto
  17. 453 190
      vendor/github.com/docker/swarmkit/api/specs.pb.go
  18. 22 0
      vendor/github.com/docker/swarmkit/api/specs.proto
  19. 588 332
      vendor/github.com/docker/swarmkit/api/types.pb.go
  20. 16 0
      vendor/github.com/docker/swarmkit/api/types.proto
  21. 99 7
      vendor/github.com/docker/swarmkit/manager/controlapi/service.go
  22. 11 0
      vendor/github.com/docker/swarmkit/manager/manager.go
  23. 2 2
      vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go
  24. 301 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/jobs/global/reconciler.go
  25. 250 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/jobs/orchestrator.go
  26. 296 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/jobs/replicated/reconciler.go
  27. 43 5
      vendor/github.com/docker/swarmkit/manager/orchestrator/restart/restart.go
  28. 20 0
      vendor/github.com/docker/swarmkit/manager/orchestrator/service.go
  29. 2 2
      vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go
  30. 4 4
      vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go
  31. 4 3
      vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go
  32. 9 0
      vendor/github.com/docker/swarmkit/vendor.conf

+ 6 - 0
api/server/router/swarm/helpers.go

@@ -101,5 +101,11 @@ func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
 			// API version 1.41
 			service.TaskTemplate.ContainerSpec.Capabilities = nil
 		}
+
+		// jobs were only introduced in API version 1.41. Nil out both Job
+		// modes; if the service is one of these modes and subsequently has no
+		// mode, then something down the pipe will thrown an error.
+		service.Mode.ReplicatedJob = nil
+		service.Mode.GlobalJob = nil
 	}
 }

+ 53 - 0
api/swagger.yaml

@@ -3183,6 +3183,12 @@ definitions:
                 type: "integer"
       DesiredState:
         $ref: "#/definitions/TaskState"
+      JobIteration:
+        description: |
+          If the Service this Task belongs to is a job-mode service, contains
+          the JobIteration of the Service this Task was created for. Absent if
+          the Task was created for a Replicated or Global Service.
+        $ref: "#/definitions/ObjectVersion"
     example:
       ID: "0kzzo1i0y4jz6027t0k7aezc7"
       Version:
@@ -3275,6 +3281,22 @@ definitions:
                 format: "int64"
           Global:
             type: "object"
+          ReplicatedJob:
+            description: "The mode used for services with a finite number of tasks that run to a completed state."
+            type: "object"
+            properties:
+              MaxConcurrent:
+                description: "The maximum number of replicas to run simultaneously."
+                type: "integer"
+                format: "int64"
+                default: 1
+              TotalCompletions:
+                description: "The total number of replicas desired to reach the Completed state. If unset, will default to the value of MaxConcurrent"
+                type: "integer"
+                format: "int64"
+          GlobalJob:
+            description: "The mode used for services which run a task to the completed state on each valid node."
+            type: "object"
       UpdateConfig:
         description: "Specification for the update strategy of the service."
         type: "object"
@@ -3475,6 +3497,37 @@ definitions:
             type: "integer"
             format: "uint64"
             example: 10
+          CompletedTasks:
+            description: |
+              The number of tasks for a job that are in the Completed state.
+              This field must be cross-referenced with the service type, as the
+              value of 0 may mean the service is not in a job mode, or it may
+              mean the job-mode service has no tasks yet Completed.
+            type: "integer"
+            format: "uint64"
+      JobStatus:
+        description: |
+          The status of the service when it is in one of ReplicatedJob or
+          GlobalJob modes. Absent on Replicated and Global mode services. The
+          JobIteration is an ObjectVersion, but unlike the Service's version,
+          does not need to be sent with an update request.
+        type: "object"
+        properties:
+          JobIteration:
+            description: |
+              JobIteration is a value increased each time a Job is executed,
+              successfully or otherwise. "Executed", in this case, means the
+              job as a whole has been started, not that an individual Task has
+              been launched. A job is "Executed" when its ServiceSpec is
+              updated. JobIteration can be used to disambiguate Tasks belonging
+              to different executions of a job.  Though JobIteration will
+              increase with each subsequent execution, it may not necessarily
+              increase by 1, and so JobIteration should not be used to
+            $ref: "#/definitions/ObjectVersion"
+          LastExecution:
+            description: "The last time, as observed by the server, that this job was started"
+            type: "string"
+            format: "dateTime"
     example:
       ID: "9mnpnzenvg8p8tdbtq4wvbkcz"
       Version:

+ 59 - 2
api/types/swarm/service.go

@@ -17,6 +17,10 @@ type Service struct {
 	// listing all tasks for a service, an operation that could be
 	// computation and network expensive.
 	ServiceStatus *ServiceStatus `json:",omitempty"`
+
+	// JobStatus is the status of a Service which is in one of ReplicatedJob or
+	// GlobalJob modes. It is absent on Replicated and Global services.
+	JobStatus *JobStatus `json:",omitempty"`
 }
 
 // ServiceSpec represents the spec of a service.
@@ -39,8 +43,10 @@ type ServiceSpec struct {
 
 // ServiceMode represents the mode of a service.
 type ServiceMode struct {
-	Replicated *ReplicatedService `json:",omitempty"`
-	Global     *GlobalService     `json:",omitempty"`
+	Replicated    *ReplicatedService `json:",omitempty"`
+	Global        *GlobalService     `json:",omitempty"`
+	ReplicatedJob *ReplicatedJob     `json:",omitempty"`
+	GlobalJob     *GlobalJob         `json:",omitempty"`
 }
 
 // UpdateState is the state of a service update.
@@ -77,6 +83,32 @@ type ReplicatedService struct {
 // GlobalService is a kind of ServiceMode.
 type GlobalService struct{}
 
+// ReplicatedJob is the a type of Service which executes a defined Tasks
+// in parallel until the specified number of Tasks have succeeded.
+type ReplicatedJob struct {
+	// MaxConcurrent indicates the maximum number of Tasks that should be
+	// executing simultaneously for this job at any given time. There may be
+	// fewer Tasks that MaxConcurrent executing simultaneously; for example, if
+	// there are fewer than MaxConcurrent tasks needed to reach
+	// TotalCompletions.
+	//
+	// If this field is empty, it will default to a max concurrency of 1.
+	MaxConcurrent *uint64 `json:",omitempty"`
+
+	// TotalCompletions is the total number of Tasks desired to run to
+	// completion.
+	//
+	// If this field is empty, the value of MaxConcurrent will be used.
+	TotalCompletions *uint64 `json:",omitempty"`
+}
+
+// GlobalJob is the type of a Service which executes a Task on every Node
+// matching the Service's placement constraints. These tasks run to completion
+// and then exit.
+//
+// This type is deliberately empty.
+type GlobalJob struct{}
+
 const (
 	// UpdateFailureActionPause PAUSE
 	UpdateFailureActionPause = "pause"
@@ -142,4 +174,29 @@ type ServiceStatus struct {
 	// services, this is computed by taking the number of tasks with desired
 	// state of not-Shutdown.
 	DesiredTasks uint64
+
+	// CompletedTasks is the number of tasks in the state Completed, if this
+	// service is in ReplicatedJob or GlobalJob mode. This field must be
+	// cross-referenced with the service type, because the default value of 0
+	// may mean that a service is not in a job mode, or it may mean that the
+	// job has yet to complete any tasks.
+	CompletedTasks uint64
+}
+
+// JobStatus is the status of a job-type service.
+type JobStatus struct {
+	// JobIteration is a value increased each time a Job is executed,
+	// successfully or otherwise. "Executed", in this case, means the job as a
+	// whole has been started, not that an individual Task has been launched. A
+	// job is "Executed" when its ServiceSpec is updated. JobIteration can be
+	// used to disambiguate Tasks belonging to different executions of a job.
+	//
+	// Though JobIteration will increase with each subsequent execution, it may
+	// not necessarily increase by 1, and so JobIteration should not be used to
+	// keep track of the number of times a job has been executed.
+	JobIteration Version
+
+	// LastExecution is the time that the job was last executed, as observed by
+	// Swarm manager.
+	LastExecution time.Time `json:",omitempty"`
 }

+ 6 - 0
api/types/swarm/task.go

@@ -56,6 +56,12 @@ type Task struct {
 	DesiredState        TaskState           `json:",omitempty"`
 	NetworksAttachments []NetworkAttachment `json:",omitempty"`
 	GenericResources    []GenericResource   `json:",omitempty"`
+
+	// JobIteration is the JobIteration of the Service that this Task was
+	// spawned from, if the Service is a ReplicatedJob or GlobalJob. This is
+	// used to determine which Tasks belong to which run of the job. This field
+	// is absent if the Service mode is Replicated or Global.
+	JobIteration *Version `json:",omitempty"`
 }
 
 // TaskSpec represents the spec of a task.

+ 56 - 2
daemon/cluster/convert/service.go

@@ -44,6 +44,15 @@ func ServiceFromGRPC(s swarmapi.Service) (types.Service, error) {
 	service.CreatedAt, _ = gogotypes.TimestampFromProto(s.Meta.CreatedAt)
 	service.UpdatedAt, _ = gogotypes.TimestampFromProto(s.Meta.UpdatedAt)
 
+	if s.JobStatus != nil {
+		service.JobStatus = &types.JobStatus{
+			JobIteration: types.Version{
+				Index: s.JobStatus.JobIteration.Index,
+			},
+		}
+		service.JobStatus.LastExecution, _ = gogotypes.TimestampFromProto(s.JobStatus.LastExecution)
+	}
+
 	// UpdateStatus
 	if s.UpdateStatus != nil {
 		service.UpdateStatus = &types.UpdateStatus{}
@@ -131,6 +140,13 @@ func serviceSpecFromGRPC(spec *swarmapi.ServiceSpec) (*types.ServiceSpec, error)
 		convertedSpec.Mode.Replicated = &types.ReplicatedService{
 			Replicas: &t.Replicated.Replicas,
 		}
+	case *swarmapi.ServiceSpec_ReplicatedJob:
+		convertedSpec.Mode.ReplicatedJob = &types.ReplicatedJob{
+			MaxConcurrent:    &t.ReplicatedJob.MaxConcurrent,
+			TotalCompletions: &t.ReplicatedJob.TotalCompletions,
+		}
+	case *swarmapi.ServiceSpec_GlobalJob:
+		convertedSpec.Mode.GlobalJob = &types.GlobalJob{}
 	}
 
 	return convertedSpec, nil
@@ -283,14 +299,52 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
 	}
 
 	// Mode
-	if s.Mode.Global != nil && s.Mode.Replicated != nil {
-		return swarmapi.ServiceSpec{}, fmt.Errorf("cannot specify both replicated mode and global mode")
+	numModes := 0
+	if s.Mode.Global != nil {
+		numModes++
+	}
+	if s.Mode.Replicated != nil {
+		numModes++
+	}
+	if s.Mode.ReplicatedJob != nil {
+		numModes++
+	}
+	if s.Mode.GlobalJob != nil {
+		numModes++
+	}
+
+	if numModes > 1 {
+		return swarmapi.ServiceSpec{}, fmt.Errorf("must specify only one service mode")
 	}
 
 	if s.Mode.Global != nil {
 		spec.Mode = &swarmapi.ServiceSpec_Global{
 			Global: &swarmapi.GlobalService{},
 		}
+	} else if s.Mode.GlobalJob != nil {
+		spec.Mode = &swarmapi.ServiceSpec_GlobalJob{
+			GlobalJob: &swarmapi.GlobalJob{},
+		}
+	} else if s.Mode.ReplicatedJob != nil {
+		// if the service is a replicated job, we have two different kinds of
+		// values that might need to be defaulted.
+
+		r := &swarmapi.ReplicatedJob{}
+		if s.Mode.ReplicatedJob.MaxConcurrent != nil {
+			r.MaxConcurrent = *s.Mode.ReplicatedJob.MaxConcurrent
+		} else {
+			r.MaxConcurrent = 1
+		}
+
+		if s.Mode.ReplicatedJob.TotalCompletions != nil {
+			r.TotalCompletions = *s.Mode.ReplicatedJob.TotalCompletions
+		} else {
+			r.TotalCompletions = r.MaxConcurrent
+		}
+
+		spec.Mode = &swarmapi.ServiceSpec_ReplicatedJob{
+			ReplicatedJob: r,
+		}
 	} else if s.Mode.Replicated != nil && s.Mode.Replicated.Replicas != nil {
 		spec.Mode = &swarmapi.ServiceSpec_Replicated{
 			Replicated: &swarmapi.ReplicatedService{Replicas: *s.Mode.Replicated.Replicas},

+ 6 - 0
daemon/cluster/convert/task.go

@@ -65,5 +65,11 @@ func TaskFromGRPC(t swarmapi.Task) (types.Task, error) {
 		})
 	}
 
+	if t.JobIteration != nil {
+		task.JobIteration = &types.Version{
+			Index: t.JobIteration.Index,
+		}
+	}
+
 	return task, nil
 }

+ 7 - 2
daemon/cluster/services.go

@@ -91,6 +91,10 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
 				mode = "global"
 			case *swarmapi.ServiceSpec_Replicated:
 				mode = "replicated"
+			case *swarmapi.ServiceSpec_ReplicatedJob:
+				mode = "replicatedjob"
+			case *swarmapi.ServiceSpec_GlobalJob:
+				mode = "globaljob"
 			}
 
 			if !options.Filters.ExactMatch("mode", mode) {
@@ -131,8 +135,9 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv
 		serviceMap := map[string]*types.ServiceStatus{}
 		for _, status := range resp.Statuses {
 			serviceMap[status.ServiceID] = &types.ServiceStatus{
-				RunningTasks: status.RunningTasks,
-				DesiredTasks: status.DesiredTasks,
+				RunningTasks:   status.RunningTasks,
+				DesiredTasks:   status.DesiredTasks,
+				CompletedTasks: status.CompletedTasks,
 			}
 		}
 

+ 19 - 2
docs/api/version-history.md

@@ -32,8 +32,25 @@ keywords: "API, Docker, rcli, REST, documentation"
   version. This change is not versioned, and affects all API versions if the daemon
   has this patch.
 * `GET /services` now accepts query parameter `status`. When set `true`,
-  services returned will include `ServiceStatus`, which provides Desired and
-  Running task counts for the service.
+  services returned will include `ServiceStatus`, which provides Desired,
+  Running, and Completed task counts for the service.
+* `GET /services` may now include `ReplicatedJob` or `GlobalJob` as the `Mode`
+  in a `ServiceSpec`.
+* `GET /services/{id}` may now include `ReplicatedJob` or `GlobalJob` as the
+  `Mode` in a `ServiceSpec`.
+* `POST /services/create` now accepts `ReplicatedJob or `GlobalJob` as the `Mode`
+  in the `ServiceSpec.
+* `POST /services/{id}/update` accepts updating the fields of the
+  `ReplicatedJob` object in the `ServiceSpec.Mode`. The service mode still
+  cannot be changed, however.
+* `GET /services` now includes `JobStatus` on Services with mode
+  `ReplicatedJob` or `GlobalJob`.
+* `GET /services/{id}` now includes `JobStatus` on Services with mode
+  `ReplicatedJob` or `GlobalJob`.
+* `GET /tasks` now includes `JobIteration` on Tasks spawned from a job-mode
+  service.
+* `GET /tasks/{id}` now includes `JobIteration` on the task if spawned from a
+  job-mode service.
 
 ## v1.40 API changes
 

+ 8 - 1
integration/internal/swarm/service.go

@@ -20,7 +20,7 @@ import (
 // ServicePoll tweaks the pollSettings for `service`
 func ServicePoll(config *poll.Settings) {
 	// Override the default pollSettings for `service` resource here ...
-	config.Timeout = 30 * time.Second
+	config.Timeout = 15 * time.Second
 	config.Delay = 100 * time.Millisecond
 	if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" {
 		config.Timeout = 90 * time.Second
@@ -91,6 +91,13 @@ func CreateServiceSpec(t *testing.T, opts ...ServiceSpecOpt) swarmtypes.ServiceS
 	return spec
 }
 
+// ServiceWithMode sets the mode of the service to the provided mode.
+func ServiceWithMode(mode swarmtypes.ServiceMode) func(*swarmtypes.ServiceSpec) {
+	return func(spec *swarmtypes.ServiceSpec) {
+		spec.Mode = mode
+	}
+}
+
 // ServiceWithInit sets whether the service should use init or not
 func ServiceWithInit(b *bool) func(*swarmtypes.ServiceSpec) {
 	return func(spec *swarmtypes.ServiceSpec) {

+ 81 - 0
integration/internal/swarm/states.go

@@ -2,6 +2,7 @@ package swarm
 
 import (
 	"context"
+	"fmt"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
@@ -82,3 +83,83 @@ func RunningTasksCount(client client.ServiceAPIClient, serviceID string, instanc
 		}
 	}
 }
+
+// JobComplete is a poll function for determining that a ReplicatedJob is
+// completed additionally, while polling, it verifies that the job never
+// exceeds MaxConcurrent running tasks
+func JobComplete(client client.CommonAPIClient, service swarmtypes.Service) func(log poll.LogT) poll.Result {
+	filter := filters.NewArgs()
+	filter.Add("service", service.ID)
+
+	var jobIteration swarmtypes.Version
+	if service.JobStatus != nil {
+		jobIteration = service.JobStatus.JobIteration
+	}
+
+	maxRaw := service.Spec.Mode.ReplicatedJob.MaxConcurrent
+	totalRaw := service.Spec.Mode.ReplicatedJob.TotalCompletions
+
+	max := int(*maxRaw)
+	total := int(*totalRaw)
+
+	previousResult := ""
+
+	return func(log poll.LogT) poll.Result {
+		tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
+			Filters: filter,
+		})
+
+		if err != nil {
+			poll.Error(err)
+		}
+
+		var running int
+		var completed int
+
+		var runningSlot []int
+		var runningID []string
+
+		for _, task := range tasks {
+			// make sure the task has the same job iteration
+			if task.JobIteration == nil || task.JobIteration.Index != jobIteration.Index {
+				continue
+			}
+			switch task.Status.State {
+			case swarmtypes.TaskStateRunning:
+				running++
+				runningSlot = append(runningSlot, task.Slot)
+				runningID = append(runningID, task.ID)
+			case swarmtypes.TaskStateComplete:
+				completed++
+			}
+		}
+
+		switch {
+		case running > max:
+			return poll.Error(fmt.Errorf(
+				"number of running tasks (%v) exceeds max (%v)", running, max,
+			))
+		case (completed + running) > total:
+			return poll.Error(fmt.Errorf(
+				"number of tasks exceeds total (%v), %v running and %v completed",
+				total, running, completed,
+			))
+		case completed == total && running == 0:
+			return poll.Success()
+		default:
+			newRes := fmt.Sprintf(
+				"Completed: %2d Running: %v\n\t%v",
+				completed, runningSlot, runningID,
+			)
+			if newRes == previousResult {
+			} else {
+				previousResult = newRes
+			}
+
+			return poll.Continue(
+				"Job not yet finished, %v completed and %v running out of %v total",
+				completed, running, total,
+			)
+		}
+	}
+}

+ 143 - 0
integration/service/jobs_test.go

@@ -0,0 +1,143 @@
+package service
+
+import (
+	"context"
+	"testing"
+
+	"github.com/docker/docker/api/types"
+	swarmtypes "github.com/docker/docker/api/types/swarm"
+	"github.com/docker/docker/integration/internal/swarm"
+	"gotest.tools/assert"
+	"gotest.tools/poll"
+	"gotest.tools/skip"
+)
+
+// The file jobs_test.go contains tests that verify that services which are in
+// the mode ReplicatedJob or GlobalJob.
+
+// TestCreateJob tests that a Service can be created and run with
+// mode ReplicatedJob
+func TestCreateJob(t *testing.T) {
+	skip.If(t, testEnv.IsRemoteDaemon)
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
+
+	defer setupTest(t)
+
+	d := swarm.NewSwarm(t, testEnv)
+	defer d.Stop(t)
+
+	client := d.NewClientT(t)
+	defer client.Close()
+
+	for _, mode := range []swarmtypes.ServiceMode{
+		{ReplicatedJob: &swarmtypes.ReplicatedJob{}},
+		{GlobalJob: &swarmtypes.GlobalJob{}},
+	} {
+		id := swarm.CreateService(t, d, swarm.ServiceWithMode(mode))
+
+		poll.WaitOn(t, swarm.RunningTasksCount(client, id, 1), swarm.ServicePoll)
+	}
+}
+
+// TestReplicatedJob tests that running a replicated job starts the requisite
+// number of tasks,
+func TestReplicatedJob(t *testing.T) {
+	skip.If(t, testEnv.IsRemoteDaemon)
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
+
+	// we need variables, because the replicas field takes a pointer
+	maxConcurrent := uint64(2)
+	// there is overhead, especially in the test environment, associated with
+	// starting tasks. if total is set too high, then the time needed to
+	// complete the test, even if everything is proceeding ideally, may exceed
+	// the time the test has to execute
+	//
+	// in CI,the test has been seen to time out with as few as 7 completions
+	// after 15 seconds. this means 7 completions ought not be too many.
+	total := uint64(7)
+
+	defer setupTest(t)
+
+	d := swarm.NewSwarm(t, testEnv)
+	defer d.Stop(t)
+
+	client := d.NewClientT(t)
+	defer client.Close()
+
+	id := swarm.CreateService(t, d,
+		swarm.ServiceWithMode(swarmtypes.ServiceMode{
+			ReplicatedJob: &swarmtypes.ReplicatedJob{
+				MaxConcurrent:    &maxConcurrent,
+				TotalCompletions: &total,
+			},
+		}),
+		// just run a command to execute and exit peacefully.
+		swarm.ServiceWithCommand([]string{"true"}),
+	)
+
+	service, _, err := client.ServiceInspectWithRaw(
+		context.Background(), id, types.ServiceInspectOptions{},
+	)
+	assert.NilError(t, err)
+
+	poll.WaitOn(t, swarm.JobComplete(client, service), swarm.ServicePoll)
+}
+
+// TestUpdateJob tests that a job can be updated, and that it runs with the
+// correct parameters.
+func TestUpdateReplicatedJob(t *testing.T) {
+	skip.If(t, testEnv.IsRemoteDaemon)
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
+
+	defer setupTest(t)()
+
+	d := swarm.NewSwarm(t, testEnv)
+	defer d.Stop(t)
+
+	client := d.NewClientT(t)
+	defer client.Close()
+
+	// avoid writing "context.Background()" over and over again
+	ctx := context.Background()
+
+	// Create the job service
+	id := swarm.CreateService(t, d,
+		swarm.ServiceWithMode(swarmtypes.ServiceMode{
+			ReplicatedJob: &swarmtypes.ReplicatedJob{
+				// use the default, empty values.
+			},
+		}),
+		// run "true" so the task exits with 0
+		swarm.ServiceWithCommand([]string{"true"}),
+	)
+
+	service, _, err := client.ServiceInspectWithRaw(
+		ctx, id, types.ServiceInspectOptions{},
+	)
+	assert.NilError(t, err)
+
+	// wait for the job to completed
+	poll.WaitOn(t, swarm.JobComplete(client, service), swarm.ServicePoll)
+
+	// update the job.
+	spec := service.Spec
+	spec.TaskTemplate.ForceUpdate++
+
+	_, err = client.ServiceUpdate(
+		ctx, id, service.Version, spec, types.ServiceUpdateOptions{},
+	)
+	assert.NilError(t, err)
+
+	service2, _, err := client.ServiceInspectWithRaw(
+		ctx, id, types.ServiceInspectOptions{},
+	)
+	assert.NilError(t, err)
+
+	// assert that the job iteration has increased
+	assert.Assert(t,
+		service.JobStatus.JobIteration.Index < service2.JobStatus.JobIteration.Index,
+	)
+
+	// now wait for the service to complete a second time.
+	poll.WaitOn(t, swarm.JobComplete(client, service2), swarm.ServicePoll)
+}

+ 1 - 1
vendor.conf

@@ -128,7 +128,7 @@ github.com/containerd/ttrpc                         92c8520ef9f86600c650dd540266
 github.com/gogo/googleapis                          d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
 
 # cluster
-github.com/docker/swarmkit                          24fb4cfe8af56803640180c5592bf32da732ced2
+github.com/docker/swarmkit                          ef128ab4f5d50ffe4851d937b2b296e55562d10f
 github.com/gogo/protobuf                            ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1
 github.com/golang/protobuf                          aa810b61a9c79d51363740d207bb46cf8e620ed5 # v1.2.0
 github.com/cloudflare/cfssl                         5d63dbd981b5c408effbb58c442d54761ff94fbd # 1.3.2

+ 209 - 174
vendor/github.com/docker/swarmkit/api/control.pb.go

@@ -1167,6 +1167,12 @@ type ListServiceStatusesResponse_ServiceStatus struct {
 	// request time. This may be larger than desired tasks if, for example, a
 	// service has been scaled down.
 	RunningTasks uint64 `protobuf:"varint,3,opt,name=running_tasks,json=runningTasks,proto3" json:"running_tasks,omitempty"`
+	// CompletedTasks is the number of tasks in state Completed, if this
+	// service is in mode ReplicatedJob or GlobalJob. This must be
+	// cross-referenced with the service type, because the default value of 0
+	// may mean that a service is not in a Job mode, or it may mean the Job has
+	// yet to complete any Tasks.
+	CompletedTasks uint64 `protobuf:"varint,4,opt,name=completed_tasks,json=completedTasks,proto3" json:"completed_tasks,omitempty"`
 }
 
 func (m *ListServiceStatusesResponse_ServiceStatus) Reset() {
@@ -3435,180 +3441,181 @@ func init() {
 }
 
 var fileDescriptor_b37401dd08bf8930 = []byte{
-	// 2760 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x49, 0x6f, 0x1b, 0xc9,
-	0x15, 0x16, 0x29, 0x4a, 0x22, 0x1f, 0xb5, 0xb9, 0x2c, 0x8f, 0x35, 0xb4, 0x23, 0x19, 0xed, 0x8d,
-	0x76, 0x1c, 0x72, 0x86, 0xce, 0x64, 0x1c, 0xcf, 0x38, 0x89, 0x65, 0x79, 0xa1, 0x17, 0xd9, 0x68,
-	0xc9, 0x46, 0x72, 0x08, 0x04, 0x8a, 0x2c, 0x69, 0xda, 0xa4, 0xba, 0x99, 0xee, 0xa6, 0xc7, 0x42,
-	0x90, 0x20, 0x8b, 0x83, 0x39, 0x05, 0xc8, 0x25, 0x40, 0x90, 0x43, 0x80, 0x9c, 0x02, 0xe4, 0x90,
-	0x43, 0x4e, 0x39, 0xe4, 0x07, 0x18, 0x39, 0xcd, 0x71, 0x4e, 0x4a, 0x46, 0x46, 0x80, 0x9c, 0xf2,
-	0x17, 0x12, 0xd4, 0xd6, 0x4b, 0xb1, 0x7a, 0xe1, 0x02, 0x78, 0x4e, 0x12, 0xab, 0xbf, 0xb7, 0x54,
-	0xbd, 0xd7, 0x5f, 0x55, 0xbf, 0x57, 0x70, 0x65, 0xcf, 0x70, 0x3f, 0xe9, 0xed, 0x54, 0x9a, 0xd6,
-	0x7e, 0xb5, 0x65, 0x35, 0xdb, 0xd8, 0xae, 0x3a, 0x9f, 0x36, 0xec, 0xfd, 0xb6, 0xe1, 0x56, 0x1b,
-	0x5d, 0xa3, 0xda, 0xb4, 0x4c, 0xd7, 0xb6, 0x3a, 0x95, 0xae, 0x6d, 0xb9, 0x16, 0x42, 0x0c, 0x52,
-	0x11, 0x90, 0xca, 0x8b, 0xf7, 0x4b, 0x97, 0x13, 0x34, 0x38, 0x5d, 0xdc, 0x74, 0x98, 0x7c, 0x29,
-	0xc9, 0x9a, 0xb5, 0xf3, 0x1c, 0x37, 0x5d, 0x81, 0x4e, 0xd2, 0xec, 0x1e, 0x74, 0xb1, 0xc0, 0x2e,
-	0xed, 0x59, 0x7b, 0x16, 0xfd, 0xb7, 0x4a, 0xfe, 0xe3, 0xa3, 0xef, 0xee, 0x59, 0xd6, 0x5e, 0x07,
-	0x57, 0xe9, 0xaf, 0x9d, 0xde, 0x6e, 0xb5, 0x61, 0x1e, 0xf0, 0x47, 0x1f, 0xc6, 0x28, 0xf7, 0xe0,
-	0xdd, 0x4e, 0x6f, 0xcf, 0x30, 0xf9, 0x1f, 0x26, 0xa8, 0x7d, 0x00, 0xf3, 0x77, 0xb1, 0xbb, 0x61,
-	0xb5, 0xb0, 0x8e, 0x7f, 0xd4, 0xc3, 0x8e, 0x8b, 0xce, 0xc2, 0x8c, 0x69, 0xb5, 0xf0, 0xb6, 0xd1,
-	0x5a, 0xce, 0x9c, 0xc9, 0x94, 0x0b, 0x6b, 0x70, 0x74, 0xb8, 0x3a, 0x4d, 0x10, 0xf5, 0x75, 0x7d,
-	0x9a, 0x3c, 0xaa, 0xb7, 0xb4, 0xef, 0xc2, 0x82, 0x27, 0xe6, 0x74, 0x2d, 0xd3, 0xc1, 0xe8, 0x0a,
-	0xe4, 0xc8, 0x43, 0x2a, 0x54, 0xac, 0x2d, 0x57, 0xfa, 0x17, 0xb7, 0x42, 0xf1, 0x14, 0xa5, 0xbd,
-	0x9a, 0x82, 0xc5, 0x87, 0x86, 0x43, 0x55, 0x38, 0xc2, 0xf4, 0x1d, 0x98, 0xd9, 0x35, 0x3a, 0x2e,
-	0xb6, 0x1d, 0xae, 0xe5, 0x8a, 0x4a, 0x8b, 0x2c, 0x56, 0xb9, 0xc3, 0x64, 0x74, 0x21, 0x5c, 0xfa,
-	0x53, 0x0e, 0x66, 0xf8, 0x20, 0x5a, 0x82, 0x29, 0xb3, 0xb1, 0x8f, 0x89, 0xc6, 0xc9, 0x72, 0x41,
-	0x67, 0x3f, 0x50, 0x15, 0x8a, 0x46, 0x6b, 0xbb, 0x6b, 0xe3, 0x5d, 0xe3, 0x25, 0x76, 0x96, 0xb3,
-	0xe4, 0xd9, 0xda, 0xfc, 0xd1, 0xe1, 0x2a, 0xd4, 0xd7, 0x9f, 0xf0, 0x51, 0x1d, 0x8c, 0x96, 0xf8,
-	0x1f, 0x3d, 0x81, 0xe9, 0x4e, 0x63, 0x07, 0x77, 0x9c, 0xe5, 0xc9, 0x33, 0x93, 0xe5, 0x62, 0xed,
-	0xda, 0x20, 0x9e, 0x55, 0x1e, 0x52, 0xd1, 0xdb, 0xa6, 0x6b, 0x1f, 0xe8, 0x5c, 0x0f, 0xfa, 0x21,
-	0x14, 0xe9, 0x3a, 0x73, 0xb5, 0x33, 0x54, 0xed, 0xc7, 0x03, 0xa9, 0x25, 0x83, 0x41, 0xd5, 0x60,
-	0x7a, 0x03, 0xe8, 0x11, 0x14, 0xf7, 0xf1, 0xfe, 0x0e, 0xb6, 0x9d, 0x4f, 0x8c, 0xae, 0xb3, 0x9c,
-	0x3b, 0x33, 0x59, 0x9e, 0xaf, 0x5d, 0x8c, 0x8a, 0xca, 0x66, 0x17, 0x37, 0x2b, 0x8f, 0x3c, 0xfc,
-	0x5a, 0x76, 0x71, 0x42, 0x0f, 0xca, 0xa3, 0x6f, 0xc1, 0x94, 0x6d, 0x75, 0xb0, 0xb3, 0x3c, 0x45,
-	0x15, 0x9d, 0x8e, 0x0c, 0xaf, 0xd5, 0xc1, 0x54, 0x9a, 0xc1, 0xd1, 0x59, 0x98, 0x23, 0x2b, 0xee,
-	0x2f, 0xf5, 0x34, 0x0d, 0xc3, 0x2c, 0x19, 0x14, 0x8b, 0x5b, 0xfa, 0x36, 0x14, 0x03, 0xd3, 0x40,
-	0x8b, 0x30, 0xd9, 0xc6, 0x07, 0x2c, 0xfb, 0x74, 0xf2, 0x2f, 0x09, 0xe2, 0x8b, 0x46, 0xa7, 0x87,
-	0x97, 0xb3, 0x74, 0x8c, 0xfd, 0xb8, 0x9e, 0xbd, 0x96, 0x29, 0xdd, 0x80, 0x05, 0x69, 0x15, 0x06,
-	0x11, 0xd7, 0x6e, 0xc1, 0xb1, 0xc0, 0xea, 0xf2, 0x4c, 0xae, 0xc0, 0x14, 0x59, 0x48, 0x96, 0x32,
-	0x71, 0xa9, 0xcc, 0x60, 0xda, 0x9f, 0x33, 0x70, 0xec, 0x69, 0xb7, 0xd5, 0x70, 0xf1, 0xa0, 0xef,
-	0x11, 0xfa, 0x0e, 0xcc, 0x52, 0xd0, 0x0b, 0x6c, 0x3b, 0x86, 0x65, 0x52, 0x07, 0x8b, 0xb5, 0x53,
-	0x2a, 0x8b, 0xcf, 0x18, 0x44, 0xa7, 0x59, 0xc3, 0x7f, 0xa0, 0xf7, 0x20, 0x47, 0x18, 0x69, 0x79,
-	0x92, 0xca, 0x9d, 0x8e, 0x0b, 0xaf, 0x4e, 0x91, 0xda, 0x1a, 0xa0, 0xa0, 0xaf, 0x43, 0xbd, 0xbc,
-	0x1b, 0x70, 0x4c, 0xc7, 0xfb, 0xd6, 0x8b, 0xc1, 0xe7, 0xbb, 0x04, 0x53, 0xbb, 0x96, 0xdd, 0x64,
-	0x91, 0xc8, 0xeb, 0xec, 0x87, 0xb6, 0x04, 0x28, 0xa8, 0x8f, 0xf9, 0xc4, 0xa9, 0x69, 0xab, 0xe1,
-	0xb4, 0x03, 0x26, 0xdc, 0x86, 0xd3, 0x96, 0x4c, 0x10, 0x04, 0x31, 0x41, 0x1e, 0x79, 0xd4, 0xc4,
-	0xc4, 0xfc, 0xd9, 0x91, 0x87, 0x71, 0xb3, 0xa3, 0x78, 0x8a, 0xd2, 0xae, 0x89, 0xd9, 0x0d, 0x6c,
-	0xda, 0x9b, 0x47, 0xd0, 0xba, 0xf6, 0xf7, 0x1c, 0xa3, 0x3a, 0x32, 0x38, 0x04, 0xd5, 0x05, 0xc5,
-	0xfa, 0xa9, 0xee, 0x9f, 0x93, 0x6f, 0x8f, 0xea, 0x54, 0x9e, 0x29, 0xa9, 0xae, 0x0a, 0x45, 0x07,
-	0xdb, 0x2f, 0x8c, 0x26, 0xc9, 0x0e, 0xc6, 0x45, 0xdc, 0x85, 0x4d, 0x36, 0x5c, 0x5f, 0x77, 0x74,
-	0xe0, 0x90, 0x7a, 0xcb, 0x41, 0x17, 0x20, 0xcf, 0x73, 0x89, 0x11, 0x4e, 0x61, 0xad, 0x78, 0x74,
-	0xb8, 0x3a, 0xc3, 0x92, 0xc9, 0xd1, 0x67, 0x58, 0x36, 0x39, 0xe8, 0x1e, 0xcc, 0xb7, 0xb0, 0x63,
-	0xd8, 0xb8, 0xb5, 0xed, 0xb8, 0x0d, 0x97, 0xd3, 0xcb, 0x7c, 0xed, 0x6b, 0x51, 0x21, 0xde, 0x24,
-	0x28, 0xca, 0x4f, 0x73, 0x5c, 0x90, 0x8e, 0x28, 0x78, 0x6a, 0xa6, 0x9f, 0xa7, 0x50, 0x09, 0xf2,
-	0x76, 0xcf, 0x74, 0x0d, 0xb2, 0xc6, 0x05, 0xfa, 0xdc, 0xfb, 0x8d, 0x4e, 0x03, 0xf4, 0xba, 0xdb,
-	0xae, 0xb5, 0x4d, 0xde, 0xad, 0xe5, 0x3c, 0x4d, 0xef, 0x7c, 0xaf, 0xbb, 0x65, 0xad, 0x37, 0x5c,
-	0x3c, 0x02, 0xc3, 0x09, 0x8a, 0xe2, 0x8b, 0xed, 0x53, 0x14, 0xc9, 0xb9, 0x58, 0x8a, 0xa2, 0x49,
-	0xc8, 0x60, 0xda, 0x03, 0x58, 0xba, 0x65, 0xe3, 0x86, 0x8b, 0xf9, 0x82, 0x8b, 0x34, 0xbc, 0xca,
-	0xf9, 0x83, 0xe5, 0xe0, 0xaa, 0x4a, 0x0d, 0x97, 0x08, 0x50, 0xc8, 0x06, 0x9c, 0x90, 0x94, 0x71,
-	0xaf, 0x3e, 0x80, 0x19, 0x1e, 0x44, 0xae, 0xf0, 0x54, 0x8c, 0x42, 0x5d, 0x60, 0xb5, 0xe7, 0x70,
-	0xec, 0x2e, 0x76, 0x25, 0xcf, 0xae, 0x00, 0xf8, 0x39, 0xc3, 0xdf, 0xb9, 0xb9, 0xa3, 0xc3, 0xd5,
-	0x82, 0x97, 0x32, 0x7a, 0xc1, 0xcb, 0x18, 0x74, 0x11, 0x16, 0x0c, 0xd3, 0xc1, 0xb6, 0xbb, 0xdd,
-	0xc2, 0xbb, 0x8d, 0x5e, 0xc7, 0x75, 0x38, 0xc3, 0xcc, 0xb3, 0xe1, 0x75, 0x3e, 0xaa, 0x3d, 0x00,
-	0x14, 0xb4, 0x35, 0x9a, 0xe3, 0x7f, 0xcd, 0xc2, 0x12, 0x23, 0xd3, 0x91, 0x9c, 0x5f, 0x87, 0x05,
-	0x81, 0x1e, 0x60, 0x1f, 0x98, 0xe7, 0x32, 0x62, 0x2b, 0xb8, 0x1a, 0xda, 0x0a, 0xd2, 0x85, 0x12,
-	0x3d, 0x82, 0xbc, 0x6d, 0x75, 0x3a, 0x3b, 0x8d, 0x66, 0x7b, 0x39, 0x77, 0x26, 0x53, 0x9e, 0xaf,
-	0xbd, 0xaf, 0x12, 0x54, 0x4d, 0xb2, 0xa2, 0x73, 0x41, 0xdd, 0x53, 0xa1, 0x69, 0x90, 0x17, 0xa3,
-	0x28, 0x0f, 0xb9, 0x8d, 0xc7, 0x1b, 0xb7, 0x17, 0x27, 0xd0, 0x2c, 0xe4, 0x9f, 0xe8, 0xb7, 0x9f,
-	0xd5, 0x1f, 0x3f, 0xdd, 0x5c, 0xcc, 0x90, 0xec, 0x91, 0xd4, 0x8d, 0x16, 0x84, 0x75, 0x58, 0x62,
-	0xa4, 0x3b, 0x4a, 0x0c, 0xb4, 0x93, 0x70, 0x42, 0xd2, 0xc2, 0xd9, 0xfb, 0xd5, 0x24, 0x1c, 0x27,
-	0xef, 0x1f, 0x1f, 0xf7, 0x08, 0xbc, 0x2e, 0x13, 0x78, 0x35, 0x8a, 0x26, 0x25, 0xc9, 0x7e, 0x0e,
-	0xff, 0x63, 0x76, 0xec, 0x1c, 0xbe, 0x29, 0x71, 0xf8, 0x47, 0x03, 0x3a, 0xa7, 0xa4, 0xf1, 0x3e,
-	0x8e, 0xcc, 0x25, 0x70, 0xe4, 0x54, 0x98, 0x23, 0x47, 0x61, 0xc1, 0xc7, 0xb0, 0x14, 0x76, 0x97,
-	0x27, 0xcd, 0x87, 0x90, 0xe7, 0x41, 0x14, 0x5c, 0x18, 0x9b, 0x35, 0x1e, 0x58, 0xbb, 0x06, 0xa5,
-	0x80, 0x42, 0xb2, 0x0b, 0xf4, 0x1c, 0x3f, 0xba, 0x25, 0x49, 0x6d, 0x21, 0x20, 0xf9, 0x8b, 0x2c,
-	0x9c, 0x52, 0x8a, 0x72, 0x97, 0x7e, 0x00, 0x79, 0x87, 0x8f, 0x71, 0x97, 0x6e, 0x24, 0xac, 0xbe,
-	0xac, 0xa2, 0x12, 0x1a, 0xd7, 0x3d, 0x75, 0xa5, 0xcf, 0x32, 0x30, 0x17, 0x7a, 0x36, 0x20, 0xd3,
-	0x9c, 0x05, 0xb1, 0xed, 0x6d, 0xb3, 0xed, 0x83, 0xac, 0x73, 0x4e, 0x9f, 0xe5, 0x83, 0x74, 0x8f,
-	0x21, 0x20, 0xbb, 0x67, 0x9a, 0x86, 0xb9, 0xc7, 0x41, 0x93, 0x0c, 0xc4, 0x07, 0xb7, 0xc2, 0x1b,
-	0xca, 0x06, 0x76, 0x3f, 0xb5, 0xec, 0xf6, 0x00, 0x1b, 0x0a, 0x97, 0x50, 0x6d, 0x28, 0x9e, 0x32,
-	0x9f, 0x12, 0x4c, 0x36, 0x14, 0x47, 0x09, 0x42, 0x4a, 0x60, 0xb5, 0xa7, 0x74, 0x43, 0x91, 0x3c,
-	0x43, 0x90, 0x23, 0x89, 0xca, 0xd3, 0x8d, 0xfe, 0x4f, 0x56, 0x8f, 0xcb, 0x90, 0xd5, 0xcb, 0xfa,
-	0xab, 0xc7, 0x65, 0xc9, 0xea, 0x71, 0x40, 0xbd, 0xc5, 0xf7, 0x8e, 0x31, 0xf9, 0xf8, 0x7d, 0x41,
-	0x5b, 0x63, 0x77, 0xd3, 0xa3, 0x32, 0xc9, 0x53, 0xed, 0x3f, 0x59, 0x46, 0x65, 0x7c, 0x7c, 0x08,
-	0x2a, 0x93, 0x24, 0xfb, 0xa9, 0xec, 0x57, 0x6f, 0x91, 0xca, 0x22, 0x9c, 0x1b, 0x9a, 0xca, 0xc6,
-	0x40, 0x57, 0xbe, 0x4b, 0x3e, 0x5d, 0xf1, 0x40, 0xc5, 0xd2, 0x95, 0x88, 0x9c, 0x07, 0xd6, 0x6e,
-	0xd2, 0x94, 0xbe, 0xd5, 0xe9, 0x39, 0x2e, 0xb6, 0x03, 0x5b, 0x5c, 0x93, 0x8d, 0x48, 0x2f, 0x3f,
-	0xc7, 0x91, 0xbc, 0xe0, 0x00, 0x2f, 0x7d, 0x3d, 0x15, 0x7e, 0xfa, 0x72, 0x48, 0x5c, 0xfa, 0x0a,
-	0x29, 0x81, 0xf5, 0x72, 0x89, 0x3f, 0x18, 0x22, 0x97, 0x24, 0xc9, 0xaf, 0x56, 0x2e, 0x45, 0x38,
-	0xf7, 0x36, 0x73, 0xc9, 0x77, 0xc9, 0xcf, 0x25, 0x1e, 0x8d, 0xd8, 0x5c, 0x12, 0xa1, 0xf3, 0xc0,
-	0xda, 0x6f, 0x33, 0x50, 0x7c, 0x80, 0x0f, 0x74, 0xcb, 0x6d, 0xb8, 0xe4, 0xe4, 0x78, 0x19, 0x8e,
-	0x91, 0x24, 0xc3, 0xf6, 0xf6, 0x73, 0xcb, 0x30, 0xb7, 0x5d, 0xab, 0x8d, 0x4d, 0xea, 0x5a, 0x5e,
-	0x5f, 0x60, 0x0f, 0xee, 0x5b, 0x86, 0xb9, 0x45, 0x86, 0xd1, 0x15, 0x40, 0xfb, 0x0d, 0xb3, 0xb1,
-	0x17, 0x06, 0xb3, 0xb3, 0xf6, 0x22, 0x7f, 0xa2, 0x44, 0xf7, 0xcc, 0x8e, 0xd5, 0x6c, 0x6f, 0x93,
-	0x59, 0x4f, 0x86, 0xd0, 0x4f, 0xe9, 0x83, 0x07, 0xf8, 0x80, 0x6c, 0xac, 0xfc, 0x38, 0x3d, 0x4a,
-	0x9e, 0x93, 0xe3, 0xb4, 0x40, 0x0f, 0x72, 0x9c, 0xe6, 0x32, 0x03, 0x1c, 0xa7, 0xb9, 0xf5, 0xc0,
-	0x71, 0xfa, 0x26, 0x39, 0x4e, 0xb3, 0x55, 0xa5, 0xc7, 0xe9, 0x08, 0xc1, 0xc0, 0xe2, 0xaf, 0xe5,
-	0x5e, 0x1f, 0xae, 0x4e, 0xe8, 0x9e, 0x98, 0x7f, 0x3c, 0x1e, 0xd3, 0x8b, 0x7a, 0x03, 0x16, 0xe9,
-	0x07, 0x4f, 0xd3, 0xc6, 0xae, 0x58, 0xcf, 0x4b, 0x50, 0x70, 0xe8, 0x80, 0xbf, 0x9c, 0xb3, 0x47,
-	0x87, 0xab, 0x79, 0x86, 0xaa, 0xaf, 0x93, 0xc3, 0x0e, 0xfd, 0xaf, 0xa5, 0xdd, 0xe5, 0xdf, 0x66,
-	0x4c, 0x9c, 0xbb, 0x52, 0x83, 0x69, 0x06, 0xe0, 0x9e, 0x94, 0xd4, 0x47, 0x2e, 0x2a, 0xc3, 0x91,
-	0xda, 0xdf, 0x32, 0x70, 0x5c, 0x9c, 0xfb, 0x87, 0xf3, 0x05, 0xad, 0xc1, 0x3c, 0x87, 0x0e, 0x10,
-	0xd7, 0x39, 0x26, 0x22, 0xc2, 0x5a, 0x0b, 0x85, 0x75, 0x25, 0xda, 0xf1, 0xc0, 0xf1, 0xe4, 0xbe,
-	0xff, 0x95, 0x37, 0xf2, 0x32, 0xfc, 0x3b, 0x0b, 0x88, 0x9d, 0xfc, 0xc8, 0x4f, 0x8f, 0x36, 0xef,
-	0xc9, 0xb4, 0x59, 0x89, 0x3e, 0x32, 0x06, 0x05, 0xfb, 0x59, 0xf3, 0xd5, 0xf8, 0x59, 0x53, 0x97,
-	0x58, 0xf3, 0xfa, 0x60, 0xbe, 0xbd, 0x15, 0xd2, 0x7c, 0x20, 0xbe, 0xda, 0xb8, 0x47, 0x3c, 0x64,
-	0xdf, 0x24, 0xdf, 0x98, 0x74, 0x88, 0x53, 0x66, 0x5c, 0xcc, 0x04, 0x54, 0xab, 0xc3, 0x71, 0x51,
-	0xf0, 0x08, 0xa6, 0x6e, 0x2d, 0x74, 0xd6, 0x4d, 0x9d, 0x4b, 0x61, 0x55, 0x23, 0xe4, 0xd2, 0xf7,
-	0xe0, 0xb8, 0xf8, 0x66, 0x1d, 0xf2, 0xed, 0x7e, 0xc7, 0xff, 0x76, 0x0e, 0x7a, 0xc3, 0x49, 0xe3,
-	0x96, 0x65, 0xee, 0x1a, 0x7b, 0x01, 0xb5, 0x4d, 0x3a, 0x20, 0xa9, 0x65, 0x28, 0xa2, 0x96, 0x3d,
-	0xf6, 0x48, 0x43, 0x88, 0xfb, 0x33, 0x64, 0x80, 0xb8, 0x19, 0x72, 0x19, 0x8e, 0x0c, 0x90, 0xc6,
-	0xb0, 0xbe, 0x10, 0xd2, 0xe0, 0xd0, 0x41, 0x48, 0x83, 0x89, 0x0c, 0x40, 0x1a, 0xcc, 0xb2, 0x8a,
-	0x34, 0xc6, 0xb0, 0x0c, 0x82, 0x34, 0xd8, 0xf0, 0x10, 0xa4, 0x11, 0x16, 0xfc, 0x6a, 0x91, 0x86,
-	0xda, 0xb7, 0xb7, 0x49, 0x1a, 0x9e, 0x47, 0x3e, 0x69, 0xb0, 0x40, 0xc4, 0x92, 0x06, 0x8f, 0x99,
-	0x80, 0xfa, 0xa4, 0x11, 0x4e, 0xdd, 0x14, 0xa4, 0xa1, 0xca, 0xa5, 0xb0, 0xaa, 0x11, 0x72, 0xc9,
-	0x23, 0x8d, 0xa1, 0xdf, 0x6e, 0x8f, 0x34, 0xc2, 0xde, 0x68, 0x3f, 0x81, 0x77, 0x98, 0x97, 0xb7,
-	0x5f, 0xba, 0xd8, 0xa4, 0xef, 0x11, 0x57, 0x7e, 0x13, 0x8a, 0x0d, 0xd3, 0xe4, 0x27, 0x1c, 0x27,
-	0xae, 0x36, 0x70, 0xd3, 0x87, 0xe9, 0x41, 0x19, 0x74, 0x06, 0x8a, 0x2d, 0xec, 0x34, 0x6d, 0xa3,
-	0xeb, 0x8a, 0x77, 0xb8, 0xa0, 0x07, 0x87, 0xb4, 0x67, 0x70, 0xb2, 0xcf, 0x3c, 0x5f, 0xa7, 0x8f,
-	0xa0, 0x80, 0xc5, 0x20, 0xb7, 0xae, 0xec, 0x10, 0xf8, 0x92, 0x3e, 0x5e, 0x7b, 0x08, 0xef, 0xb0,
-	0xe9, 0xf6, 0x4d, 0xab, 0x06, 0xb3, 0x1e, 0xcc, 0x5f, 0xb6, 0x85, 0xa3, 0xc3, 0xd5, 0xa2, 0x87,
-	0xad, 0xaf, 0xeb, 0x45, 0x0f, 0x54, 0x6f, 0x69, 0xef, 0xc2, 0xc9, 0x3e, 0x6d, 0x7c, 0xfd, 0xea,
-	0x70, 0xfc, 0x2e, 0x76, 0xc7, 0x62, 0x65, 0x13, 0x96, 0xc2, 0xaa, 0xc6, 0xb1, 0x10, 0x7f, 0xc8,
-	0x88, 0x32, 0x8d, 0x8e, 0x1d, 0xab, 0x67, 0xfb, 0xa5, 0xd6, 0x31, 0xc4, 0x17, 0x41, 0xae, 0x6d,
-	0x98, 0xbc, 0xb8, 0xa1, 0xd3, 0xff, 0x51, 0x05, 0x66, 0xba, 0x8d, 0x83, 0x8e, 0xd5, 0x68, 0x71,
-	0xe6, 0x5d, 0xaa, 0xb0, 0x1b, 0x10, 0x15, 0x71, 0xa5, 0xa1, 0x72, 0xd3, 0x3c, 0xd0, 0x05, 0x48,
-	0xd3, 0x45, 0x02, 0xfa, 0xfe, 0xf1, 0x79, 0x5f, 0x83, 0xbc, 0xcd, 0xc7, 0xb8, 0x77, 0xca, 0x56,
-	0xa9, 0x27, 0xe7, 0xa1, 0xb5, 0x7b, 0xa2, 0x98, 0x22, 0xcf, 0xb9, 0x0a, 0x45, 0x01, 0xf2, 0xa3,
-	0x42, 0x09, 0x51, 0x20, 0xeb, 0xeb, 0x3a, 0x08, 0x48, 0xbd, 0xa5, 0x2d, 0x8b, 0x3c, 0x92, 0xbd,
-	0xd3, 0x7e, 0x99, 0x15, 0x67, 0xfe, 0x51, 0x8d, 0xa0, 0x3b, 0xb0, 0xe8, 0x09, 0x0c, 0xb0, 0xdf,
-	0x2d, 0x08, 0x21, 0xb1, 0xe3, 0x49, 0x11, 0x9d, 0x1c, 0x22, 0xa2, 0x81, 0xe8, 0xe5, 0x52, 0x46,
-	0x4f, 0x5e, 0x84, 0x91, 0xa3, 0x77, 0x9b, 0x96, 0x3c, 0x46, 0x0e, 0xdd, 0x63, 0xfa, 0x66, 0x8e,
-	0xd1, 0xaf, 0xff, 0x65, 0xd9, 0x37, 0xbd, 0x78, 0xe4, 0x6d, 0xe9, 0xf7, 0xe5, 0x2d, 0xfd, 0xbd,
-	0xa8, 0x6d, 0x53, 0x16, 0xed, 0xdf, 0xd4, 0x7f, 0x3f, 0xfe, 0x4d, 0x7d, 0x4b, 0xda, 0xd4, 0x3f,
-	0x1e, 0xd4, 0xbb, 0xe1, 0xfb, 0x0a, 0x82, 0x20, 0xa6, 0x7c, 0x82, 0x18, 0x65, 0xab, 0xdf, 0x84,
-	0x13, 0x92, 0x9f, 0x3c, 0xa8, 0xd7, 0xa1, 0x20, 0xc2, 0x24, 0xb6, 0xfb, 0xf8, 0xa8, 0xfa, 0xf0,
-	0xda, 0x67, 0xe7, 0x60, 0xe6, 0x16, 0xbb, 0x62, 0x86, 0x0c, 0x98, 0xe1, 0x37, 0xa4, 0x90, 0xa6,
-	0x92, 0x0f, 0xdf, 0xba, 0x2a, 0x9d, 0x8d, 0xc5, 0x70, 0xa2, 0x38, 0xf1, 0x8f, 0xbf, 0xfc, 0xf7,
-	0x77, 0xd9, 0x05, 0x98, 0xa3, 0xa0, 0x6f, 0xf0, 0x02, 0x0a, 0xb2, 0xa0, 0xe0, 0x5d, 0x62, 0x41,
-	0xe7, 0xd2, 0xdc, 0x20, 0x2a, 0x9d, 0x4f, 0x40, 0xc5, 0x1b, 0xb4, 0x01, 0xfc, 0x3b, 0x24, 0xe8,
-	0x7c, 0x74, 0xc7, 0x30, 0x38, 0xc3, 0x0b, 0x49, 0xb0, 0x44, 0x9b, 0xfe, 0x1d, 0x11, 0xb5, 0xcd,
-	0xbe, 0x3b, 0x29, 0x6a, 0x9b, 0x8a, 0xab, 0x26, 0x11, 0x36, 0x59, 0x0c, 0xb7, 0x1a, 0x4e, 0x3b,
-	0x32, 0x86, 0x81, 0x3b, 0x22, 0x91, 0x31, 0x0c, 0xdd, 0x06, 0x89, 0x8f, 0x21, 0xeb, 0xc0, 0x9c,
-	0x4b, 0x73, 0xe3, 0x22, 0x3a, 0x86, 0xa1, 0xab, 0x02, 0x89, 0xeb, 0x49, 0xa7, 0x17, 0xb3, 0x9e,
-	0xc1, 0x19, 0x5e, 0x48, 0x82, 0x25, 0xda, 0xf4, 0x9b, 0xef, 0x6a, 0x9b, 0x7d, 0x17, 0x01, 0xd4,
-	0x36, 0xfb, 0x7b, 0xf8, 0x51, 0x36, 0x5f, 0xc2, 0x6c, 0xb0, 0x71, 0x88, 0x2e, 0xa6, 0xec, 0x84,
-	0x96, 0xca, 0xc9, 0xc0, 0x78, 0xcb, 0x3f, 0x86, 0xb9, 0xd0, 0x35, 0x09, 0xa4, 0xd4, 0xa8, 0xba,
-	0x96, 0x51, 0xba, 0x94, 0x02, 0x99, 0x68, 0x3c, 0xd4, 0x65, 0x57, 0x1b, 0x57, 0xf5, 0xf5, 0xd5,
-	0xc6, 0x95, 0x2d, 0xfb, 0x18, 0xe3, 0xa1, 0x66, 0xba, 0xda, 0xb8, 0xaa, 0x6b, 0xaf, 0x36, 0xae,
-	0xee, 0xcc, 0x47, 0x18, 0xff, 0x75, 0x26, 0xd4, 0xb0, 0x17, 0xbd, 0x55, 0x54, 0x49, 0xdd, 0x84,
-	0x65, 0x9e, 0x54, 0x07, 0x6c, 0xda, 0xc6, 0x27, 0x3d, 0xef, 0xe8, 0x44, 0x26, 0x7d, 0xb8, 0x0b,
-	0x18, 0x99, 0xf4, 0x72, 0x4b, 0x2f, 0x3e, 0xe9, 0x45, 0xfb, 0x29, 0x3a, 0xe9, 0xa5, 0x9e, 0x59,
-	0x74, 0xd2, 0xcb, 0x9d, 0xac, 0xc4, 0xa4, 0x17, 0x13, 0x8e, 0x49, 0x7a, 0x69, 0xce, 0x97, 0x52,
-	0x20, 0x53, 0xe6, 0x5d, 0xac, 0x71, 0x55, 0xdb, 0x35, 0x2e, 0xef, 0x52, 0x1a, 0x67, 0x71, 0xe6,
-	0xf5, 0xf7, 0xc8, 0x38, 0x87, 0x3b, 0x1b, 0x91, 0x71, 0x96, 0x8a, 0xff, 0x09, 0x71, 0x16, 0xad,
-	0xa1, 0xe8, 0x38, 0x4b, 0xfd, 0xac, 0xe8, 0x38, 0xcb, 0x5d, 0xa6, 0x44, 0x7e, 0x11, 0x13, 0x8e,
-	0xe1, 0x17, 0x69, 0xce, 0x97, 0x52, 0x20, 0x13, 0x37, 0x4b, 0xaf, 0x29, 0xa1, 0xde, 0x2c, 0xe5,
-	0x96, 0x47, 0xe9, 0x7c, 0x02, 0x2a, 0x71, 0x9d, 0x83, 0x1d, 0x00, 0xf5, 0x3a, 0x2b, 0xba, 0x1b,
-	0xa5, 0x72, 0x32, 0x30, 0xde, 0x72, 0x0f, 0x8a, 0x81, 0x3a, 0x36, 0xba, 0x90, 0xae, 0xf4, 0x5e,
-	0xba, 0x98, 0x88, 0x4b, 0x9c, 0x70, 0xb0, 0x4c, 0xad, 0x9e, 0xb0, 0xa2, 0x26, 0x5e, 0x2a, 0x27,
-	0x03, 0x13, 0x2d, 0x07, 0x4b, 0xd2, 0x6a, 0xcb, 0x8a, 0xb2, 0x77, 0xa9, 0x9c, 0x0c, 0x4c, 0x93,
-	0x55, 0xac, 0xa8, 0x15, 0x99, 0x55, 0xa1, 0xaa, 0x59, 0x64, 0x56, 0x49, 0x95, 0xb1, 0xa4, 0xac,
-	0xe2, 0x36, 0x63, 0xb2, 0x2a, 0x6c, 0xb6, 0x9c, 0x0c, 0x4c, 0x95, 0x55, 0xbc, 0xd0, 0x19, 0x9d,
-	0x55, 0xe1, 0xda, 0x6c, 0x74, 0x56, 0x49, 0x15, 0xd3, 0xc4, 0xac, 0x8a, 0x9b, 0xb0, 0xa2, 0x68,
-	0x1a, 0x97, 0x55, 0xa9, 0x97, 0x3a, 0x58, 0xb3, 0x8c, 0xcb, 0xaa, 0x14, 0x96, 0x95, 0xe5, 0xcf,
-	0x68, 0xcb, 0xc1, 0x52, 0x9c, 0xda, 0xb2, 0xa2, 0xee, 0xa7, 0xb6, 0xac, 0xaa, 0xea, 0x45, 0x59,
-	0xfe, 0x79, 0x06, 0x16, 0xa4, 0x8a, 0x28, 0xba, 0x1c, 0xbd, 0x90, 0x7d, 0x0e, 0x7c, 0x3d, 0x15,
-	0x36, 0xd9, 0x07, 0xa9, 0xde, 0xa9, 0xf6, 0x41, 0x5d, 0x62, 0x55, 0xfb, 0x10, 0x55, 0x40, 0x8d,
-	0x4e, 0xf6, 0x40, 0xf5, 0x06, 0x45, 0x6d, 0xb9, 0x52, 0x95, 0xa8, 0x74, 0x31, 0x11, 0x17, 0x6f,
-	0xf6, 0xa7, 0x30, 0x1f, 0xae, 0x67, 0xa1, 0x98, 0x8d, 0x4f, 0x36, 0x7e, 0x39, 0x0d, 0x34, 0x71,
-	0x87, 0x0e, 0x55, 0x38, 0x50, 0x39, 0x6d, 0xb1, 0x46, 0xbd, 0x43, 0x2b, 0xcb, 0x25, 0x31, 0x93,
-	0x0f, 0x97, 0x62, 0x51, 0xcc, 0xe9, 0x2e, 0xd5, 0xe4, 0xd5, 0x95, 0xdd, 0x18, 0xfb, 0xe1, 0x62,
-	0x2b, 0x8a, 0x39, 0xe0, 0xa5, 0xb2, 0x1f, 0x51, 0xbb, 0x55, 0xdb, 0x5f, 0x3b, 0xf7, 0xfa, 0xcb,
-	0x95, 0x89, 0x2f, 0xbe, 0x5c, 0x99, 0xf8, 0xd9, 0xd1, 0x4a, 0xe6, 0xf5, 0xd1, 0x4a, 0xe6, 0xf3,
-	0xa3, 0x95, 0xcc, 0xbf, 0x8e, 0x56, 0x32, 0xbf, 0x79, 0xb3, 0x32, 0xf1, 0xf9, 0x9b, 0x95, 0x89,
-	0x2f, 0xde, 0xac, 0x4c, 0xec, 0x4c, 0xd3, 0x4a, 0xe8, 0xd5, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff,
-	0x61, 0x29, 0x54, 0xa3, 0xb7, 0x38, 0x00, 0x00,
+	// 2778 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xdb, 0x6f, 0x1b, 0x59,
+	0x19, 0x8f, 0x1d, 0x27, 0xb6, 0x3f, 0x27, 0x4e, 0x7a, 0x9a, 0xb6, 0x5e, 0xb7, 0x24, 0xd5, 0xf4,
+	0x12, 0xb7, 0x14, 0x7b, 0xd7, 0x65, 0xd9, 0xd2, 0xdd, 0x02, 0x4d, 0xd3, 0x8b, 0x7b, 0x49, 0xab,
+	0x49, 0x5a, 0xc1, 0x03, 0x8a, 0x1c, 0xfb, 0x24, 0x3b, 0xb5, 0x33, 0x63, 0x66, 0xc6, 0xdd, 0x46,
+	0x08, 0xc4, 0xa5, 0x88, 0x27, 0x24, 0x5e, 0x90, 0x10, 0x0f, 0x48, 0x3c, 0x21, 0x81, 0x84, 0x10,
+	0x4f, 0x3c, 0xf0, 0x07, 0x54, 0x3c, 0xed, 0xe3, 0x3e, 0x05, 0x36, 0x15, 0x12, 0x4f, 0xfc, 0x0b,
+	0xac, 0xce, 0x6d, 0x6e, 0x3e, 0x73, 0xf1, 0x45, 0xea, 0x3e, 0x25, 0x3e, 0xf3, 0xfb, 0x2e, 0xe7,
+	0xfb, 0xbe, 0xf9, 0x9d, 0x33, 0xdf, 0x39, 0x70, 0x65, 0x4f, 0xb3, 0x3f, 0xee, 0xef, 0x54, 0x5b,
+	0xc6, 0x7e, 0xad, 0x6d, 0xb4, 0x3a, 0xd8, 0xac, 0x59, 0x9f, 0x34, 0xcd, 0xfd, 0x8e, 0x66, 0xd7,
+	0x9a, 0x3d, 0xad, 0xd6, 0x32, 0x74, 0xdb, 0x34, 0xba, 0xd5, 0x9e, 0x69, 0xd8, 0x06, 0x42, 0x0c,
+	0x52, 0x15, 0x90, 0xea, 0x8b, 0xf7, 0xca, 0x97, 0x63, 0x34, 0x58, 0x3d, 0xdc, 0xb2, 0x98, 0x7c,
+	0x39, 0xce, 0x9a, 0xb1, 0xf3, 0x1c, 0xb7, 0x6c, 0x81, 0x8e, 0xd3, 0x6c, 0x1f, 0xf4, 0xb0, 0xc0,
+	0x2e, 0xed, 0x19, 0x7b, 0x06, 0xfd, 0xb7, 0x46, 0xfe, 0xe3, 0xa3, 0xef, 0xec, 0x19, 0xc6, 0x5e,
+	0x17, 0xd7, 0xe8, 0xaf, 0x9d, 0xfe, 0x6e, 0xad, 0xa9, 0x1f, 0xf0, 0x47, 0x1f, 0x44, 0x28, 0x77,
+	0xe0, 0xbd, 0x6e, 0x7f, 0x4f, 0xd3, 0xf9, 0x1f, 0x26, 0xa8, 0xbc, 0x0f, 0xc5, 0xbb, 0xd8, 0xde,
+	0x30, 0xda, 0x58, 0xc5, 0x3f, 0xe8, 0x63, 0xcb, 0x46, 0xe7, 0x20, 0xab, 0x1b, 0x6d, 0xbc, 0xad,
+	0xb5, 0x4b, 0xa9, 0xb3, 0xa9, 0x4a, 0x7e, 0x0d, 0x8e, 0x0e, 0x57, 0x66, 0x09, 0xa2, 0xb1, 0xae,
+	0xce, 0x92, 0x47, 0x8d, 0xb6, 0xf2, 0x6d, 0x58, 0x70, 0xc4, 0xac, 0x9e, 0xa1, 0x5b, 0x18, 0x5d,
+	0x81, 0x0c, 0x79, 0x48, 0x85, 0x0a, 0xf5, 0x52, 0x75, 0x30, 0xb8, 0x55, 0x8a, 0xa7, 0x28, 0xe5,
+	0xd5, 0x0c, 0x2c, 0x3e, 0xd4, 0x2c, 0xaa, 0xc2, 0x12, 0xa6, 0xef, 0x40, 0x76, 0x57, 0xeb, 0xda,
+	0xd8, 0xb4, 0xb8, 0x96, 0x2b, 0x32, 0x2d, 0x41, 0xb1, 0xea, 0x1d, 0x26, 0xa3, 0x0a, 0xe1, 0xf2,
+	0x1f, 0x33, 0x90, 0xe5, 0x83, 0x68, 0x09, 0x66, 0xf4, 0xe6, 0x3e, 0x26, 0x1a, 0xa7, 0x2b, 0x79,
+	0x95, 0xfd, 0x40, 0x35, 0x28, 0x68, 0xed, 0xed, 0x9e, 0x89, 0x77, 0xb5, 0x97, 0xd8, 0x2a, 0xa5,
+	0xc9, 0xb3, 0xb5, 0xe2, 0xd1, 0xe1, 0x0a, 0x34, 0xd6, 0x9f, 0xf0, 0x51, 0x15, 0xb4, 0xb6, 0xf8,
+	0x1f, 0x3d, 0x81, 0xd9, 0x6e, 0x73, 0x07, 0x77, 0xad, 0xd2, 0xf4, 0xd9, 0xe9, 0x4a, 0xa1, 0x7e,
+	0x6d, 0x18, 0xcf, 0xaa, 0x0f, 0xa9, 0xe8, 0x6d, 0xdd, 0x36, 0x0f, 0x54, 0xae, 0x07, 0x7d, 0x1f,
+	0x0a, 0x34, 0xce, 0x5c, 0x6d, 0x96, 0xaa, 0xfd, 0x68, 0x28, 0xb5, 0x64, 0xd0, 0xab, 0x1a, 0x74,
+	0x67, 0x00, 0x3d, 0x82, 0xc2, 0x3e, 0xde, 0xdf, 0xc1, 0xa6, 0xf5, 0xb1, 0xd6, 0xb3, 0x4a, 0x99,
+	0xb3, 0xd3, 0x95, 0x62, 0x7d, 0x35, 0x2c, 0x2b, 0x9b, 0x3d, 0xdc, 0xaa, 0x3e, 0x72, 0xf0, 0x6b,
+	0xe9, 0xc5, 0x29, 0xd5, 0x2b, 0x8f, 0xbe, 0x01, 0x33, 0xa6, 0xd1, 0xc5, 0x56, 0x69, 0x86, 0x2a,
+	0x3a, 0x13, 0x9a, 0x5e, 0xa3, 0x8b, 0xa9, 0x34, 0x83, 0xa3, 0x73, 0x30, 0x4f, 0x22, 0xee, 0x86,
+	0x7a, 0x96, 0xa6, 0x61, 0x8e, 0x0c, 0x8a, 0xe0, 0x96, 0xbf, 0x09, 0x05, 0xcf, 0x34, 0xd0, 0x22,
+	0x4c, 0x77, 0xf0, 0x01, 0xab, 0x3e, 0x95, 0xfc, 0x4b, 0x92, 0xf8, 0xa2, 0xd9, 0xed, 0xe3, 0x52,
+	0x9a, 0x8e, 0xb1, 0x1f, 0xd7, 0xd3, 0xd7, 0x52, 0xe5, 0x1b, 0xb0, 0x10, 0x88, 0xc2, 0x30, 0xe2,
+	0xca, 0x2d, 0x38, 0xe6, 0x89, 0x2e, 0xaf, 0xe4, 0x2a, 0xcc, 0x90, 0x40, 0xb2, 0x92, 0x89, 0x2a,
+	0x65, 0x06, 0x53, 0xfe, 0x94, 0x82, 0x63, 0x4f, 0x7b, 0xed, 0xa6, 0x8d, 0x87, 0x7d, 0x8f, 0xd0,
+	0xb7, 0x60, 0x8e, 0x82, 0x5e, 0x60, 0xd3, 0xd2, 0x0c, 0x9d, 0x3a, 0x58, 0xa8, 0x9f, 0x96, 0x59,
+	0x7c, 0xc6, 0x20, 0x2a, 0xad, 0x1a, 0xfe, 0x03, 0xbd, 0x0b, 0x19, 0xc2, 0x48, 0xa5, 0x69, 0x2a,
+	0x77, 0x26, 0x2a, 0xbd, 0x2a, 0x45, 0x2a, 0x6b, 0x80, 0xbc, 0xbe, 0x8e, 0xf4, 0xf2, 0x6e, 0xc0,
+	0x31, 0x15, 0xef, 0x1b, 0x2f, 0x86, 0x9f, 0xef, 0x12, 0xcc, 0xec, 0x1a, 0x66, 0x8b, 0x65, 0x22,
+	0xa7, 0xb2, 0x1f, 0xca, 0x12, 0x20, 0xaf, 0x3e, 0xe6, 0x13, 0xa7, 0xa6, 0xad, 0xa6, 0xd5, 0xf1,
+	0x98, 0xb0, 0x9b, 0x56, 0x27, 0x60, 0x82, 0x20, 0x88, 0x09, 0xf2, 0xc8, 0xa1, 0x26, 0x26, 0xe6,
+	0xce, 0x8e, 0x3c, 0x8c, 0x9a, 0x1d, 0xc5, 0x53, 0x94, 0x72, 0x4d, 0xcc, 0x6e, 0x68, 0xd3, 0xce,
+	0x3c, 0xbc, 0xd6, 0x95, 0x7f, 0x64, 0x18, 0xd5, 0x91, 0xc1, 0x11, 0xa8, 0xce, 0x2b, 0x36, 0x48,
+	0x75, 0xff, 0x9a, 0x7e, 0x7b, 0x54, 0x27, 0xf3, 0x4c, 0x4a, 0x75, 0x35, 0x28, 0x58, 0xd8, 0x7c,
+	0xa1, 0xb5, 0x48, 0x75, 0x30, 0x2e, 0xe2, 0x2e, 0x6c, 0xb2, 0xe1, 0xc6, 0xba, 0xa5, 0x02, 0x87,
+	0x34, 0xda, 0x16, 0xba, 0x08, 0x39, 0x5e, 0x4b, 0x8c, 0x70, 0xf2, 0x6b, 0x85, 0xa3, 0xc3, 0x95,
+	0x2c, 0x2b, 0x26, 0x4b, 0xcd, 0xb2, 0x6a, 0xb2, 0xd0, 0x3d, 0x28, 0xb6, 0xb1, 0xa5, 0x99, 0xb8,
+	0xbd, 0x6d, 0xd9, 0x4d, 0x9b, 0xd3, 0x4b, 0xb1, 0xfe, 0x95, 0xb0, 0x14, 0x6f, 0x12, 0x14, 0xe5,
+	0xa7, 0x79, 0x2e, 0x48, 0x47, 0x24, 0x3c, 0x95, 0x1d, 0xe4, 0x29, 0x54, 0x86, 0x9c, 0xd9, 0xd7,
+	0x6d, 0x8d, 0xc4, 0x38, 0x4f, 0x9f, 0x3b, 0xbf, 0xd1, 0x19, 0x80, 0x7e, 0x6f, 0xdb, 0x36, 0xb6,
+	0xc9, 0xbb, 0x55, 0xca, 0xd1, 0xf2, 0xce, 0xf5, 0x7b, 0x5b, 0xc6, 0x7a, 0xd3, 0xc6, 0x63, 0x30,
+	0x9c, 0xa0, 0x28, 0x1e, 0x6c, 0x97, 0xa2, 0x48, 0xcd, 0x45, 0x52, 0x14, 0x2d, 0x42, 0x06, 0x53,
+	0x1e, 0xc0, 0xd2, 0x2d, 0x13, 0x37, 0x6d, 0xcc, 0x03, 0x2e, 0xca, 0xf0, 0x2a, 0xe7, 0x0f, 0x56,
+	0x83, 0x2b, 0x32, 0x35, 0x5c, 0xc2, 0x43, 0x21, 0x1b, 0x70, 0x22, 0xa0, 0x8c, 0x7b, 0xf5, 0x3e,
+	0x64, 0x79, 0x12, 0xb9, 0xc2, 0xd3, 0x11, 0x0a, 0x55, 0x81, 0x55, 0x9e, 0xc3, 0xb1, 0xbb, 0xd8,
+	0x0e, 0x78, 0x76, 0x05, 0xc0, 0xad, 0x19, 0xfe, 0xce, 0xcd, 0x1f, 0x1d, 0xae, 0xe4, 0x9d, 0x92,
+	0x51, 0xf3, 0x4e, 0xc5, 0xa0, 0x55, 0x58, 0xd0, 0x74, 0x0b, 0x9b, 0xf6, 0x76, 0x1b, 0xef, 0x36,
+	0xfb, 0x5d, 0xdb, 0xe2, 0x0c, 0x53, 0x64, 0xc3, 0xeb, 0x7c, 0x54, 0x79, 0x00, 0xc8, 0x6b, 0x6b,
+	0x3c, 0xc7, 0xff, 0x96, 0x86, 0x25, 0x46, 0xa6, 0x63, 0x39, 0xbf, 0x0e, 0x0b, 0x02, 0x3d, 0xc4,
+	0x3a, 0x50, 0xe4, 0x32, 0x62, 0x29, 0xb8, 0xea, 0x5b, 0x0a, 0x92, 0xa5, 0x12, 0x3d, 0x82, 0x9c,
+	0x69, 0x74, 0xbb, 0x3b, 0xcd, 0x56, 0xa7, 0x94, 0x39, 0x9b, 0xaa, 0x14, 0xeb, 0xef, 0xc9, 0x04,
+	0x65, 0x93, 0xac, 0xaa, 0x5c, 0x50, 0x75, 0x54, 0x28, 0x0a, 0xe4, 0xc4, 0x28, 0xca, 0x41, 0x66,
+	0xe3, 0xf1, 0xc6, 0xed, 0xc5, 0x29, 0x34, 0x07, 0xb9, 0x27, 0xea, 0xed, 0x67, 0x8d, 0xc7, 0x4f,
+	0x37, 0x17, 0x53, 0xa4, 0x7a, 0x02, 0xea, 0xc6, 0x4b, 0xc2, 0x3a, 0x2c, 0x31, 0xd2, 0x1d, 0x27,
+	0x07, 0xca, 0x29, 0x38, 0x11, 0xd0, 0xc2, 0xd9, 0xfb, 0xd5, 0x34, 0x1c, 0x27, 0xef, 0x1f, 0x1f,
+	0x77, 0x08, 0xbc, 0x11, 0x24, 0xf0, 0x5a, 0x18, 0x4d, 0x06, 0x24, 0x07, 0x39, 0xfc, 0x0f, 0xe9,
+	0x89, 0x73, 0xf8, 0x66, 0x80, 0xc3, 0x3f, 0x1c, 0xd2, 0x39, 0x29, 0x8d, 0x0f, 0x70, 0x64, 0x26,
+	0x86, 0x23, 0x67, 0xfc, 0x1c, 0x39, 0x0e, 0x0b, 0x3e, 0x86, 0x25, 0xbf, 0xbb, 0xbc, 0x68, 0x3e,
+	0x80, 0x1c, 0x4f, 0xa2, 0xe0, 0xc2, 0xc8, 0xaa, 0x71, 0xc0, 0xca, 0x35, 0x28, 0x7b, 0x14, 0x92,
+	0x55, 0xa0, 0x6f, 0xb9, 0xd9, 0x2d, 0x07, 0xd4, 0xe6, 0x3d, 0x92, 0x7f, 0x4e, 0xc3, 0x69, 0xa9,
+	0x28, 0x77, 0xe9, 0x7b, 0x90, 0xb3, 0xf8, 0x18, 0x77, 0xe9, 0x46, 0x4c, 0xf4, 0x83, 0x2a, 0xaa,
+	0xbe, 0x71, 0xd5, 0x51, 0x57, 0xfe, 0x6b, 0x0a, 0xe6, 0x7d, 0xcf, 0x86, 0x64, 0x9a, 0x73, 0x20,
+	0x96, 0xbd, 0x6d, 0xb6, 0x7c, 0x90, 0x38, 0x67, 0xd4, 0x39, 0x3e, 0x48, 0xd7, 0x18, 0x02, 0x32,
+	0xfb, 0xba, 0xae, 0xe9, 0x7b, 0x1c, 0x34, 0xcd, 0x40, 0x7c, 0x90, 0x81, 0x56, 0x61, 0xa1, 0x65,
+	0xec, 0xf7, 0xba, 0xd8, 0x76, 0x74, 0x65, 0x28, 0xac, 0xe8, 0x0c, 0x6f, 0xf9, 0x57, 0x9e, 0x0d,
+	0x6c, 0x7f, 0x62, 0x98, 0x9d, 0x21, 0x56, 0x1e, 0x2e, 0x21, 0x5b, 0x79, 0x1c, 0x65, 0x2e, 0x77,
+	0xe8, 0x6c, 0x28, 0x8a, 0x3b, 0x84, 0x94, 0xc0, 0x2a, 0x4f, 0xe9, 0xca, 0x13, 0xf0, 0x0c, 0x41,
+	0x86, 0x54, 0x34, 0xaf, 0x4b, 0xfa, 0x3f, 0x09, 0x33, 0x97, 0x21, 0x61, 0x4e, 0xbb, 0x61, 0xe6,
+	0xb2, 0x24, 0xcc, 0x1c, 0xd0, 0x68, 0xf3, 0x45, 0x66, 0x42, 0x3e, 0x7e, 0x57, 0xf0, 0xdb, 0xc4,
+	0xdd, 0x74, 0x38, 0x2f, 0xe0, 0xa9, 0xf2, 0xdf, 0x34, 0xe3, 0x3c, 0x3e, 0x3e, 0x02, 0xe7, 0x05,
+	0x24, 0x07, 0x39, 0xef, 0x17, 0x6f, 0x91, 0xf3, 0x42, 0x9c, 0x1b, 0x99, 0xf3, 0x26, 0xc0, 0x6b,
+	0xae, 0x4b, 0x2e, 0xaf, 0xf1, 0x44, 0x45, 0xf2, 0x9a, 0xc8, 0x9c, 0x03, 0x56, 0x6e, 0xd2, 0x92,
+	0xbe, 0xd5, 0xed, 0x5b, 0x36, 0x36, 0x3d, 0x6b, 0x61, 0x8b, 0x8d, 0x04, 0x58, 0x82, 0xe3, 0x48,
+	0x5d, 0x70, 0x80, 0x53, 0xbe, 0x8e, 0x0a, 0xb7, 0x7c, 0x39, 0x24, 0xaa, 0x7c, 0x85, 0x94, 0xc0,
+	0x3a, 0xb5, 0xc4, 0x1f, 0x8c, 0x50, 0x4b, 0x01, 0xc9, 0x2f, 0x57, 0x2d, 0x85, 0x38, 0xf7, 0x36,
+	0x6b, 0xc9, 0x75, 0xc9, 0xad, 0x25, 0x9e, 0x8d, 0xc8, 0x5a, 0x12, 0xa9, 0x73, 0xc0, 0xca, 0x6f,
+	0x52, 0x50, 0x78, 0x80, 0x0f, 0x54, 0xc3, 0x6e, 0xda, 0x64, 0x8b, 0x79, 0x19, 0x8e, 0x91, 0x22,
+	0xc3, 0xe6, 0xf6, 0x73, 0x43, 0xd3, 0xb7, 0x6d, 0xa3, 0x83, 0x75, 0xea, 0x5a, 0x4e, 0x5d, 0x60,
+	0x0f, 0xee, 0x1b, 0x9a, 0xbe, 0x45, 0x86, 0xd1, 0x15, 0x40, 0xfb, 0x4d, 0xbd, 0xb9, 0xe7, 0x07,
+	0xb3, 0x4d, 0xf9, 0x22, 0x7f, 0x22, 0x45, 0xf7, 0xf5, 0xae, 0xd1, 0xea, 0x6c, 0x93, 0x59, 0x4f,
+	0xfb, 0xd0, 0x4f, 0xe9, 0x83, 0x07, 0xf8, 0x40, 0xf9, 0x99, 0xb3, 0xef, 0x1e, 0xa7, 0xce, 0xc9,
+	0xbe, 0x5b, 0xa0, 0x87, 0xd9, 0x77, 0x73, 0x99, 0x21, 0xf6, 0xdd, 0xdc, 0xba, 0x67, 0xdf, 0x7d,
+	0x93, 0xec, 0xbb, 0x59, 0x54, 0xe9, 0xba, 0x19, 0x22, 0xe8, 0x09, 0xfe, 0x5a, 0xe6, 0xf5, 0xe1,
+	0xca, 0x94, 0xea, 0x88, 0xb9, 0xfb, 0xe8, 0x09, 0xbd, 0xa8, 0x37, 0x60, 0x91, 0x7e, 0x19, 0xb5,
+	0x4c, 0x6c, 0x8b, 0x78, 0x5e, 0x82, 0xbc, 0x45, 0x07, 0xdc, 0x70, 0xce, 0x1d, 0x1d, 0xae, 0xe4,
+	0x18, 0xaa, 0xb1, 0x4e, 0x76, 0x45, 0xf4, 0xbf, 0xb6, 0x72, 0x97, 0x7f, 0xc4, 0x31, 0x71, 0xee,
+	0x4a, 0x1d, 0x66, 0x19, 0x80, 0x7b, 0x52, 0x96, 0xef, 0xcd, 0xa8, 0x0c, 0x47, 0x2a, 0x7f, 0x4f,
+	0xc1, 0x71, 0xf1, 0x81, 0x30, 0x9a, 0x2f, 0x68, 0x0d, 0x8a, 0x1c, 0x3a, 0x44, 0x5e, 0xe7, 0x99,
+	0x88, 0x48, 0x6b, 0xdd, 0x97, 0xd6, 0xe5, 0x70, 0xc7, 0x3d, 0xdb, 0x93, 0xfb, 0xee, 0xe7, 0xe0,
+	0xd8, 0x61, 0xf8, 0x4f, 0x1a, 0x10, 0xdb, 0x22, 0x92, 0x9f, 0x0e, 0x6d, 0xde, 0x0b, 0xd2, 0x66,
+	0x35, 0x7c, 0x6f, 0xe9, 0x15, 0x1c, 0x64, 0xcd, 0x57, 0x93, 0x67, 0x4d, 0x35, 0xc0, 0x9a, 0xd7,
+	0x87, 0xf3, 0xed, 0xad, 0x90, 0xe6, 0x03, 0xf1, 0x79, 0xc7, 0x3d, 0xe2, 0x29, 0xfb, 0x3a, 0xf9,
+	0x18, 0xa5, 0x43, 0x9c, 0x32, 0xa3, 0x72, 0x26, 0xa0, 0x4a, 0x03, 0x8e, 0x8b, 0xce, 0x88, 0xb7,
+	0x74, 0xeb, 0xbe, 0xbd, 0x6e, 0xe2, 0x5a, 0xf2, 0xab, 0x1a, 0xa3, 0x96, 0xbe, 0x03, 0xc7, 0xc5,
+	0xc7, 0xed, 0x88, 0x6f, 0xf7, 0x49, 0xf7, 0x23, 0xdb, 0xeb, 0x0d, 0x27, 0x8d, 0x5b, 0x86, 0xbe,
+	0xab, 0xed, 0x79, 0xd4, 0xb6, 0xe8, 0x40, 0x40, 0x2d, 0x43, 0x11, 0xb5, 0xec, 0xb1, 0x43, 0x1a,
+	0x42, 0xdc, 0x9d, 0x21, 0x03, 0x44, 0xcd, 0x90, 0xcb, 0x70, 0xa4, 0x87, 0x34, 0x46, 0xf5, 0x85,
+	0x90, 0x06, 0x87, 0x0e, 0x43, 0x1a, 0x4c, 0x64, 0x08, 0xd2, 0x60, 0x96, 0x65, 0xa4, 0x31, 0x81,
+	0x30, 0x08, 0xd2, 0x60, 0xc3, 0x23, 0x90, 0x86, 0x5f, 0xf0, 0xcb, 0x45, 0x1a, 0x72, 0xdf, 0xde,
+	0x26, 0x69, 0x38, 0x1e, 0xb9, 0xa4, 0xc1, 0x12, 0x11, 0x49, 0x1a, 0x3c, 0x67, 0x02, 0xea, 0x92,
+	0x86, 0xbf, 0x74, 0x13, 0x90, 0x86, 0xac, 0x96, 0xfc, 0xaa, 0xc6, 0xa8, 0x25, 0x87, 0x34, 0x46,
+	0x7e, 0xbb, 0x1d, 0xd2, 0xf0, 0x7b, 0xa3, 0xfc, 0x08, 0x4e, 0x32, 0x2f, 0x6f, 0xbf, 0xb4, 0xb1,
+	0x4e, 0xdf, 0x23, 0xae, 0xfc, 0x26, 0x14, 0x9a, 0xba, 0xce, 0x77, 0x38, 0x56, 0x54, 0x6f, 0xe0,
+	0xa6, 0x0b, 0x53, 0xbd, 0x32, 0xe8, 0x2c, 0x14, 0xda, 0xd8, 0x6a, 0x99, 0x5a, 0xcf, 0x16, 0xef,
+	0x70, 0x5e, 0xf5, 0x0e, 0x29, 0xcf, 0xe0, 0xd4, 0x80, 0x79, 0x1e, 0xa7, 0x0f, 0x21, 0x8f, 0xc5,
+	0x20, 0xb7, 0x2e, 0x3d, 0x4a, 0x70, 0x25, 0x5d, 0xbc, 0xf2, 0x10, 0x4e, 0xb2, 0xe9, 0x0e, 0x4c,
+	0xab, 0x0e, 0x73, 0x0e, 0xcc, 0x0d, 0xdb, 0xc2, 0xd1, 0xe1, 0x4a, 0xc1, 0xc1, 0x36, 0xd6, 0xd5,
+	0x82, 0x03, 0x6a, 0xb4, 0x95, 0x77, 0xe0, 0xd4, 0x80, 0x36, 0x1e, 0xbf, 0x06, 0x1c, 0xbf, 0x8b,
+	0xed, 0x89, 0x58, 0xd9, 0x84, 0x25, 0xbf, 0xaa, 0x49, 0x04, 0xe2, 0xf7, 0x29, 0xd1, 0xa6, 0x51,
+	0xb1, 0x65, 0xf4, 0x4d, 0xb7, 0x27, 0x3b, 0x81, 0xfc, 0x22, 0xc8, 0x74, 0x34, 0x9d, 0x37, 0x37,
+	0x54, 0xfa, 0x3f, 0xaa, 0x42, 0xb6, 0xd7, 0x3c, 0xe8, 0x1a, 0xcd, 0x36, 0x67, 0xde, 0xa5, 0x2a,
+	0xbb, 0x2a, 0x51, 0x15, 0x77, 0x1f, 0xaa, 0x37, 0xf5, 0x03, 0x55, 0x80, 0x14, 0x55, 0x14, 0xa0,
+	0xeb, 0x1f, 0x9f, 0xf7, 0x35, 0xc8, 0x99, 0x7c, 0x8c, 0x7b, 0x27, 0x3d, 0x53, 0x75, 0xe4, 0x1c,
+	0xb4, 0x72, 0x4f, 0x34, 0x53, 0x82, 0x73, 0xae, 0x41, 0x41, 0x80, 0xdc, 0xac, 0x50, 0x42, 0x14,
+	0xc8, 0xc6, 0xba, 0x0a, 0x02, 0xd2, 0x68, 0x2b, 0x25, 0x51, 0x47, 0x41, 0xef, 0x94, 0x9f, 0xa7,
+	0xc5, 0x9e, 0x7f, 0x5c, 0x23, 0xe8, 0x0e, 0x2c, 0x3a, 0x02, 0x43, 0xac, 0x77, 0x0b, 0x42, 0x48,
+	0xac, 0x78, 0x81, 0x8c, 0x4e, 0x8f, 0x90, 0x51, 0x4f, 0xf6, 0x32, 0x09, 0xb3, 0x17, 0x0c, 0xc2,
+	0xd8, 0xd9, 0xbb, 0x4d, 0x5b, 0x1e, 0x63, 0xa7, 0xee, 0x31, 0x7d, 0x33, 0x27, 0xe8, 0xd7, 0xff,
+	0xd3, 0xec, 0x9b, 0x5e, 0x3c, 0x72, 0x96, 0xf4, 0xfb, 0xc1, 0x25, 0xfd, 0xdd, 0xb0, 0x65, 0x33,
+	0x28, 0x3a, 0xb8, 0xa8, 0xff, 0x6e, 0xf2, 0x8b, 0xfa, 0x56, 0x60, 0x51, 0xff, 0x68, 0x58, 0xef,
+	0x46, 0x3f, 0x80, 0x10, 0x04, 0x31, 0xe3, 0x12, 0xc4, 0x38, 0x4b, 0xfd, 0x26, 0x9c, 0x08, 0xf8,
+	0xc9, 0x93, 0x7a, 0x1d, 0xf2, 0x22, 0x4d, 0x62, 0xb9, 0x8f, 0xce, 0xaa, 0x0b, 0xaf, 0xff, 0xf2,
+	0x3c, 0x64, 0x6f, 0xb1, 0xbb, 0x68, 0x48, 0x83, 0x2c, 0xbf, 0x4a, 0x85, 0x14, 0x99, 0xbc, 0xff,
+	0x7a, 0x56, 0xf9, 0x5c, 0x24, 0x86, 0x13, 0xc5, 0x89, 0x7f, 0xfe, 0xe5, 0x7f, 0xbf, 0x4d, 0x2f,
+	0xc0, 0x3c, 0x05, 0x7d, 0x8d, 0x37, 0x50, 0x90, 0x01, 0x79, 0xe7, 0xb6, 0x0b, 0x3a, 0x9f, 0xe4,
+	0xaa, 0x51, 0xf9, 0x42, 0x0c, 0x2a, 0xda, 0xa0, 0x09, 0xe0, 0x5e, 0x36, 0x41, 0x17, 0xc2, 0x8f,
+	0x16, 0xbd, 0x33, 0xbc, 0x18, 0x07, 0x8b, 0xb5, 0xe9, 0x5e, 0x26, 0x91, 0xdb, 0x1c, 0xb8, 0xbc,
+	0x22, 0xb7, 0x29, 0xb9, 0x93, 0x12, 0x62, 0x93, 0xe5, 0x70, 0xab, 0x69, 0x75, 0x42, 0x73, 0xe8,
+	0xb9, 0x4c, 0x12, 0x9a, 0x43, 0xdf, 0xb5, 0x91, 0xe8, 0x1c, 0xb2, 0x53, 0x98, 0xf3, 0x49, 0xae,
+	0x66, 0x84, 0xe7, 0xd0, 0x77, 0xa7, 0x20, 0x36, 0x9e, 0x74, 0x7a, 0x11, 0xf1, 0xf4, 0xce, 0xf0,
+	0x62, 0x1c, 0x2c, 0xd6, 0xa6, 0x7b, 0x4a, 0x2f, 0xb7, 0x39, 0x70, 0x63, 0x40, 0x6e, 0x73, 0xf0,
+	0xb0, 0x3f, 0xcc, 0xe6, 0x4b, 0x98, 0xf3, 0x9e, 0x30, 0xa2, 0xd5, 0x84, 0x47, 0xa6, 0xe5, 0x4a,
+	0x3c, 0x30, 0xda, 0xf2, 0x0f, 0x61, 0xde, 0x77, 0x9f, 0x02, 0x49, 0x35, 0xca, 0xee, 0x6f, 0x94,
+	0x2f, 0x25, 0x40, 0xc6, 0x1a, 0xf7, 0x1d, 0xc7, 0xcb, 0x8d, 0xcb, 0x2e, 0x00, 0xc8, 0x8d, 0x4b,
+	0xcf, 0xf6, 0x23, 0x8c, 0xfb, 0x4e, 0xdd, 0xe5, 0xc6, 0x65, 0xc7, 0xfb, 0x72, 0xe3, 0xf2, 0x23,
+	0xfc, 0x10, 0xe3, 0xbf, 0x4a, 0xf9, 0x4e, 0xf6, 0xc5, 0x21, 0x2c, 0xaa, 0x26, 0x3e, 0xad, 0x65,
+	0x9e, 0xd4, 0x86, 0x3c, 0xdd, 0x8d, 0x2e, 0x7a, 0x7e, 0xa2, 0x13, 0x5a, 0xf4, 0xfe, 0x53, 0xc0,
+	0xd0, 0xa2, 0x0f, 0x1e, 0xe9, 0x45, 0x17, 0xbd, 0x38, 0x7e, 0x0a, 0x2f, 0xfa, 0xc0, 0x99, 0x59,
+	0x78, 0xd1, 0x07, 0x4f, 0xb2, 0x62, 0x8b, 0x5e, 0x4c, 0x38, 0xa2, 0xe8, 0x03, 0x73, 0xbe, 0x94,
+	0x00, 0x99, 0xb0, 0xee, 0x22, 0x8d, 0xcb, 0x8e, 0x5d, 0xa3, 0xea, 0x2e, 0xa1, 0x71, 0x96, 0x67,
+	0xde, 0x7f, 0x0f, 0xcd, 0xb3, 0xff, 0x64, 0x23, 0x34, 0xcf, 0x81, 0xe6, 0x7f, 0x4c, 0x9e, 0xc5,
+	0xd1, 0x50, 0x78, 0x9e, 0x03, 0xe7, 0x59, 0xe1, 0x79, 0x0e, 0x9e, 0x32, 0xc5, 0xf2, 0x8b, 0x98,
+	0x70, 0x04, 0xbf, 0x04, 0xe6, 0x7c, 0x29, 0x01, 0x32, 0x76, 0xb1, 0x74, 0x0e, 0x25, 0xe4, 0x8b,
+	0x65, 0xf0, 0xc8, 0xa3, 0x7c, 0x21, 0x06, 0x15, 0x1b, 0x67, 0xef, 0x09, 0x80, 0x3c, 0xce, 0x92,
+	0xd3, 0x8d, 0x72, 0x25, 0x1e, 0x18, 0x6d, 0xb9, 0x0f, 0x05, 0x4f, 0x1f, 0x1b, 0x5d, 0x4c, 0xd6,
+	0x7a, 0x2f, 0xaf, 0xc6, 0xe2, 0x62, 0x27, 0xec, 0x6d, 0x53, 0xcb, 0x27, 0x2c, 0xe9, 0x89, 0x97,
+	0x2b, 0xf1, 0xc0, 0x58, 0xcb, 0xde, 0x96, 0xb4, 0xdc, 0xb2, 0xa4, 0xed, 0x5d, 0xae, 0xc4, 0x03,
+	0x93, 0x54, 0x15, 0x6b, 0x6a, 0x85, 0x56, 0x95, 0xaf, 0x6b, 0x16, 0x5a, 0x55, 0x81, 0xce, 0x58,
+	0x5c, 0x55, 0x71, 0x9b, 0x11, 0x55, 0xe5, 0x37, 0x5b, 0x89, 0x07, 0x26, 0xaa, 0x2a, 0xde, 0xe8,
+	0x0c, 0xaf, 0x2a, 0x7f, 0x6f, 0x36, 0xbc, 0xaa, 0x02, 0x1d, 0xd3, 0xd8, 0xaa, 0x8a, 0x9a, 0xb0,
+	0xa4, 0x69, 0x1a, 0x55, 0x55, 0x89, 0x43, 0xed, 0xed, 0x59, 0x46, 0x55, 0x55, 0x02, 0xcb, 0xd2,
+	0xf6, 0x67, 0xb8, 0x65, 0x6f, 0x2b, 0x4e, 0x6e, 0x59, 0xd2, 0xf7, 0x93, 0x5b, 0x96, 0x75, 0xf5,
+	0xc2, 0x2c, 0xff, 0x34, 0x05, 0x0b, 0x81, 0x8e, 0x28, 0xba, 0x1c, 0x1e, 0xc8, 0x01, 0x07, 0xbe,
+	0x9a, 0x08, 0x1b, 0xef, 0x43, 0xa0, 0xdf, 0x29, 0xf7, 0x41, 0xde, 0x62, 0x95, 0xfb, 0x10, 0xd6,
+	0x40, 0x0d, 0x2f, 0x76, 0x4f, 0xf7, 0x06, 0x85, 0x2d, 0xb9, 0x81, 0x2e, 0x51, 0x79, 0x35, 0x16,
+	0x17, 0x6d, 0xf6, 0xc7, 0x50, 0xf4, 0xf7, 0xb3, 0x50, 0xc4, 0xc2, 0x17, 0x34, 0x7e, 0x39, 0x09,
+	0x34, 0x76, 0x85, 0xf6, 0x75, 0x38, 0x50, 0x25, 0x69, 0xb3, 0x46, 0xbe, 0x42, 0x4b, 0xdb, 0x25,
+	0x11, 0x93, 0xf7, 0xb7, 0x62, 0x51, 0xc4, 0xee, 0x2e, 0xd1, 0xe4, 0xe5, 0x9d, 0xdd, 0x08, 0xfb,
+	0xfe, 0x66, 0x2b, 0x8a, 0xd8, 0xe0, 0x25, 0xb2, 0x1f, 0xd2, 0xbb, 0x95, 0xdb, 0x5f, 0x3b, 0xff,
+	0xfa, 0xf3, 0xe5, 0xa9, 0xcf, 0x3e, 0x5f, 0x9e, 0xfa, 0xc9, 0xd1, 0x72, 0xea, 0xf5, 0xd1, 0x72,
+	0xea, 0xd3, 0xa3, 0xe5, 0xd4, 0xbf, 0x8f, 0x96, 0x53, 0xbf, 0x7e, 0xb3, 0x3c, 0xf5, 0xe9, 0x9b,
+	0xe5, 0xa9, 0xcf, 0xde, 0x2c, 0x4f, 0xed, 0xcc, 0xd2, 0x4e, 0xe8, 0xd5, 0x2f, 0x02, 0x00, 0x00,
+	0xff, 0xff, 0xf1, 0x75, 0x17, 0x2e, 0xe0, 0x38, 0x00, 0x00,
 }
 
 type authenticatedWrapperControlServer struct {
@@ -8269,6 +8276,11 @@ func (m *ListServiceStatusesResponse_ServiceStatus) MarshalTo(dAtA []byte) (int,
 		i++
 		i = encodeVarintControl(dAtA, i, uint64(m.RunningTasks))
 	}
+	if m.CompletedTasks != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintControl(dAtA, i, uint64(m.CompletedTasks))
+	}
 	return i, nil
 }
 
@@ -12102,6 +12114,9 @@ func (m *ListServiceStatusesResponse_ServiceStatus) Size() (n int) {
 	if m.RunningTasks != 0 {
 		n += 1 + sovControl(uint64(m.RunningTasks))
 	}
+	if m.CompletedTasks != 0 {
+		n += 1 + sovControl(uint64(m.CompletedTasks))
+	}
 	return n
 }
 
@@ -13373,6 +13388,7 @@ func (this *ListServiceStatusesResponse_ServiceStatus) String() string {
 		`ServiceID:` + fmt.Sprintf("%v", this.ServiceID) + `,`,
 		`DesiredTasks:` + fmt.Sprintf("%v", this.DesiredTasks) + `,`,
 		`RunningTasks:` + fmt.Sprintf("%v", this.RunningTasks) + `,`,
+		`CompletedTasks:` + fmt.Sprintf("%v", this.CompletedTasks) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -17797,6 +17813,25 @@ func (m *ListServiceStatusesResponse_ServiceStatus) Unmarshal(dAtA []byte) error
 					break
 				}
 			}
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CompletedTasks", wireType)
+			}
+			m.CompletedTasks = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowControl
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.CompletedTasks |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipControl(dAtA[iNdEx:])

+ 7 - 0
vendor/github.com/docker/swarmkit/api/control.proto

@@ -433,6 +433,13 @@ message ListServiceStatusesResponse {
 		// request time. This may be larger than desired tasks if, for example, a
 		// service has been scaled down.
 		uint64 running_tasks = 3;
+
+		// CompletedTasks is the number of tasks in state Completed, if this
+		// service is in mode ReplicatedJob or GlobalJob. This must be
+		// cross-referenced with the service type, because the default value of 0
+		// may mean that a service is not in a Job mode, or it may mean the Job has
+		// yet to complete any Tasks.
+		uint64 completed_tasks = 4;
 	}
 
 	repeated ServiceStatus statuses = 1;

+ 280 - 159
vendor/github.com/docker/swarmkit/api/objects.pb.go

@@ -164,6 +164,9 @@ type Service struct {
 	// UpdateStatus contains the status of an update, if one is in
 	// progress.
 	UpdateStatus *UpdateStatus `protobuf:"bytes,5,opt,name=update_status,json=updateStatus,proto3" json:"update_status,omitempty"`
+	// JobStatus contains the status of a Service that is in one of the Job
+	// modes. It is absent on Replicated and Global services.
+	JobStatus *JobStatus `protobuf:"bytes,12,opt,name=job_status,json=jobStatus,proto3" json:"job_status,omitempty"`
 	// PendingDelete indicates that this service's deletion has been requested.
 	// Services, as well as all service-level resources, can only be deleted
 	// after all of the service's containers have properly shut down.
@@ -359,6 +362,9 @@ type Task struct {
 	// If not present, the daemon's default will be used.
 	LogDriver                *Driver            `protobuf:"bytes,13,opt,name=log_driver,json=logDriver,proto3" json:"log_driver,omitempty"`
 	AssignedGenericResources []*GenericResource `protobuf:"bytes,15,rep,name=assigned_generic_resources,json=assignedGenericResources,proto3" json:"assigned_generic_resources,omitempty"`
+	// JobIteration is the iteration number of the Job-mode Service that this
+	// task belongs to.
+	JobIteration *Version `protobuf:"bytes,16,opt,name=job_iteration,json=jobIteration,proto3" json:"job_iteration,omitempty"`
 }
 
 func (m *Task) Reset()      { *m = Task{} }
@@ -767,111 +773,114 @@ func init() {
 }
 
 var fileDescriptor_6218a23329ef342d = []byte{
-	// 1654 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x73, 0x23, 0x47,
-	0x15, 0xf7, 0xc8, 0xb3, 0xfa, 0x78, 0xfa, 0x60, 0xe9, 0x18, 0x33, 0x2b, 0x8c, 0x64, 0x14, 0x42,
-	0x6d, 0xa5, 0xb6, 0xe4, 0xb0, 0x04, 0xf0, 0x1a, 0x42, 0x22, 0x59, 0x66, 0xa3, 0x4a, 0x36, 0xeb,
-	0x6a, 0x27, 0x9b, 0xdc, 0x86, 0xd6, 0x4c, 0x5b, 0x3b, 0x68, 0x34, 0x3d, 0x35, 0xdd, 0x52, 0x10,
-	0x27, 0xce, 0xcb, 0x85, 0xdb, 0xde, 0x38, 0x00, 0xff, 0x04, 0x17, 0x0e, 0x1c, 0xa8, 0xe5, 0x96,
-	0x13, 0x95, 0x93, 0x8b, 0xd5, 0xfe, 0x15, 0xdc, 0xa8, 0xee, 0xe9, 0x91, 0xc6, 0xd6, 0xf8, 0x8b,
-	0xda, 0x72, 0x71, 0x52, 0x7f, 0xfc, 0x7e, 0xaf, 0xdf, 0x7b, 0xdd, 0xef, 0x63, 0x04, 0xf7, 0x86,
-	0x9e, 0x78, 0x3a, 0x19, 0xb4, 0x1d, 0x36, 0xde, 0x71, 0x99, 0x33, 0xa2, 0xd1, 0x0e, 0xff, 0x92,
-	0x44, 0xe3, 0x91, 0x27, 0x76, 0x48, 0xe8, 0xed, 0xb0, 0xc1, 0xaf, 0xa9, 0x23, 0x78, 0x3b, 0x8c,
-	0x98, 0x60, 0x08, 0xc5, 0x90, 0x76, 0x02, 0x69, 0x4f, 0x7f, 0x58, 0x7f, 0xfb, 0x12, 0x09, 0x62,
-	0x16, 0x52, 0xcd, 0xbf, 0x14, 0xcb, 0x43, 0xea, 0x24, 0xd8, 0xe6, 0x90, 0xb1, 0xa1, 0x4f, 0x77,
-	0xd4, 0x6c, 0x30, 0x39, 0xde, 0x11, 0xde, 0x98, 0x72, 0x41, 0xc6, 0xa1, 0x06, 0x6c, 0x0c, 0xd9,
-	0x90, 0xa9, 0xe1, 0x8e, 0x1c, 0xe9, 0xd5, 0x3b, 0x67, 0x69, 0x24, 0x98, 0xe9, 0xad, 0x9f, 0x5e,
-	0x70, 0xfa, 0x02, 0x1e, 0xfa, 0x93, 0xa1, 0x17, 0xe8, 0x9f, 0x98, 0xd8, 0xfa, 0xab, 0x01, 0xe6,
-	0x23, 0x2a, 0x08, 0xfa, 0x19, 0x14, 0xa6, 0x34, 0xe2, 0x1e, 0x0b, 0x2c, 0x63, 0xdb, 0xb8, 0x5b,
-	0xbe, 0xff, 0x9d, 0xf6, 0xaa, 0x47, 0xda, 0x4f, 0x62, 0x48, 0xd7, 0x7c, 0x71, 0xd2, 0x5c, 0xc3,
-	0x09, 0x03, 0x3d, 0x00, 0x70, 0x22, 0x4a, 0x04, 0x75, 0x6d, 0x22, 0xac, 0x9c, 0xe2, 0xd7, 0xdb,
-	0xb1, 0xba, 0xed, 0xe4, 0xfc, 0xf6, 0xa7, 0x89, 0x95, 0xb8, 0xa4, 0xd1, 0x1d, 0x21, 0xa9, 0x93,
-	0xd0, 0x4d, 0xa8, 0xeb, 0x97, 0x53, 0x35, 0xba, 0x23, 0x5a, 0x7f, 0xb9, 0x05, 0xe6, 0x27, 0xcc,
-	0xa5, 0x68, 0x13, 0x72, 0x9e, 0xab, 0xd4, 0x2e, 0x75, 0xf3, 0xf3, 0x93, 0x66, 0xae, 0xdf, 0xc3,
-	0x39, 0xcf, 0x45, 0xf7, 0xc1, 0x1c, 0x53, 0x41, 0xb4, 0x42, 0x56, 0x96, 0x41, 0xd2, 0x76, 0x6d,
-	0x8d, 0xc2, 0xa2, 0x9f, 0x80, 0x29, 0xaf, 0x4a, 0x6b, 0xb2, 0x95, 0xc5, 0x91, 0x67, 0x1e, 0x85,
-	0xd4, 0x49, 0x78, 0x12, 0x8f, 0x0e, 0xa0, 0xec, 0x52, 0xee, 0x44, 0x5e, 0x28, 0xa4, 0x0f, 0x4d,
-	0x45, 0x7f, 0xf3, 0x3c, 0x7a, 0x6f, 0x09, 0xc5, 0x69, 0x1e, 0xfa, 0x39, 0xe4, 0xb9, 0x20, 0x62,
-	0xc2, 0xad, 0x5b, 0x4a, 0x42, 0xe3, 0x5c, 0x05, 0x14, 0x4a, 0xab, 0xa0, 0x39, 0xe8, 0x43, 0xa8,
-	0x8d, 0x49, 0x40, 0x86, 0x34, 0xb2, 0xb5, 0x94, 0xbc, 0x92, 0xf2, 0xbd, 0x4c, 0xd3, 0x63, 0x64,
-	0x2c, 0x08, 0x57, 0xc7, 0xe9, 0x29, 0xea, 0x03, 0x10, 0x21, 0x88, 0xf3, 0x74, 0x4c, 0x03, 0x61,
-	0x15, 0x94, 0x94, 0xb7, 0x32, 0x75, 0xa1, 0xe2, 0x4b, 0x16, 0x8d, 0x3a, 0x0b, 0x70, 0x37, 0x67,
-	0x19, 0x38, 0x45, 0x46, 0x0f, 0xa1, 0xec, 0xd0, 0x48, 0x78, 0xc7, 0x9e, 0x43, 0x04, 0xb5, 0x8a,
-	0x4a, 0x56, 0x33, 0x4b, 0xd6, 0xfe, 0x12, 0xa6, 0x0d, 0x4b, 0x33, 0xd1, 0x3b, 0x60, 0x46, 0xcc,
-	0xa7, 0x56, 0x69, 0xdb, 0xb8, 0x5b, 0x3b, 0xff, 0x6a, 0x30, 0xf3, 0x29, 0x56, 0x48, 0x79, 0xf4,
-	0x52, 0x11, 0x6e, 0xc1, 0xf6, 0xfa, 0x95, 0xcd, 0xc0, 0x69, 0x26, 0x6a, 0x41, 0xe5, 0xc9, 0x17,
-	0x1f, 0x77, 0x3e, 0xf9, 0xac, 0x77, 0x78, 0xc8, 0x22, 0x61, 0x95, 0xb7, 0x8d, 0xbb, 0x55, 0x7c,
-	0x6a, 0x6d, 0x6f, 0xf3, 0xd9, 0xf3, 0x16, 0x82, 0xdb, 0x45, 0xe3, 0xb6, 0xa1, 0xde, 0xa2, 0xf1,
-	0x8e, 0xf1, 0x85, 0xf1, 0x2b, 0xa3, 0xf5, 0x67, 0x13, 0x0a, 0x47, 0x34, 0x9a, 0x7a, 0xce, 0xeb,
-	0x7d, 0xa9, 0x0f, 0x4e, 0xbd, 0xd4, 0x4c, 0x87, 0xea, 0x63, 0x57, 0x1e, 0xeb, 0x2f, 0xa0, 0x22,
-	0x7f, 0xed, 0x24, 0xe2, 0xe1, 0xd2, 0x88, 0xc7, 0x65, 0x49, 0xd0, 0x13, 0xd4, 0x83, 0x6a, 0x18,
-	0xd1, 0xa9, 0xc7, 0x26, 0xdc, 0x56, 0x3a, 0xe4, 0xaf, 0xa4, 0x03, 0xae, 0x24, 0x2c, 0x39, 0x43,
-	0x8f, 0xe1, 0x5b, 0xa7, 0xa4, 0x2c, 0xd4, 0x29, 0x5f, 0xae, 0xce, 0x1b, 0x69, 0x49, 0x89, 0x5a,
-	0xbb, 0x50, 0xa4, 0x81, 0x1b, 0x32, 0x2f, 0x10, 0x3a, 0x00, 0x33, 0x1f, 0xc9, 0x81, 0xc6, 0xe0,
-	0x05, 0x1a, 0x1d, 0x40, 0x35, 0xce, 0x2b, 0xf6, 0xa9, 0xe8, 0xdb, 0xce, 0xa2, 0x7f, 0xa6, 0x80,
-	0x3a, 0x6c, 0x2a, 0x93, 0xd4, 0x0c, 0xbd, 0x05, 0xb5, 0x90, 0x06, 0xae, 0x17, 0x0c, 0x6d, 0x97,
-	0xfa, 0x54, 0x50, 0x15, 0x39, 0x45, 0x5c, 0xd5, 0xab, 0x3d, 0xb5, 0xb8, 0x87, 0x9e, 0x3d, 0x6f,
-	0xd5, 0xa0, 0x92, 0x7e, 0x29, 0xad, 0x3f, 0xe6, 0xa0, 0x98, 0x28, 0x86, 0xde, 0xd5, 0x57, 0x6b,
-	0x9c, 0xaf, 0x45, 0x82, 0x55, 0x7e, 0x8d, 0x6f, 0xf5, 0x5d, 0xb8, 0x15, 0xb2, 0x48, 0x70, 0x2b,
-	0xa7, 0xde, 0x79, 0x66, 0xea, 0x90, 0x2f, 0x75, 0x9f, 0x05, 0xc7, 0xde, 0x10, 0xc7, 0x60, 0xf4,
-	0x39, 0x94, 0xa7, 0x5e, 0x24, 0x26, 0xc4, 0xb7, 0xbd, 0x90, 0x5b, 0xeb, 0x8a, 0xfb, 0x83, 0x8b,
-	0x8e, 0x6c, 0x3f, 0x89, 0xf1, 0xfd, 0xc3, 0x6e, 0x6d, 0x7e, 0xd2, 0x84, 0xc5, 0x94, 0x63, 0xd0,
-	0xa2, 0xfa, 0x21, 0xaf, 0x3f, 0x82, 0xd2, 0x62, 0x07, 0xdd, 0x03, 0x08, 0xe2, 0x10, 0xb3, 0x17,
-	0x01, 0x50, 0x9d, 0x9f, 0x34, 0x4b, 0x3a, 0xf0, 0xfa, 0x3d, 0x5c, 0xd2, 0x80, 0xbe, 0x8b, 0x10,
-	0x98, 0xc4, 0x75, 0x23, 0x15, 0x0e, 0x25, 0xac, 0xc6, 0xad, 0xdf, 0x17, 0xc0, 0xfc, 0x94, 0xf0,
-	0xd1, 0x4d, 0x67, 0x7b, 0x79, 0xe6, 0xa5, 0x01, 0x54, 0xbb, 0x66, 0x00, 0xdd, 0x03, 0xe0, 0x71,
-	0x5c, 0x48, 0x77, 0x98, 0x4b, 0x77, 0xe8, 0x68, 0x91, 0xee, 0xd0, 0x80, 0xd8, 0x1d, 0xdc, 0x67,
-	0x42, 0x3d, 0x4a, 0x13, 0xab, 0x31, 0x7a, 0x13, 0x0a, 0x01, 0x73, 0x15, 0x3d, 0xaf, 0xe8, 0x30,
-	0x3f, 0x69, 0xe6, 0x65, 0xfe, 0xeb, 0xf7, 0x70, 0x5e, 0x6e, 0xf5, 0x5d, 0x95, 0xff, 0x82, 0x80,
-	0x09, 0x22, 0x6b, 0x0b, 0xd7, 0x69, 0x3c, 0x33, 0x4a, 0x3b, 0x4b, 0x58, 0x92, 0x7a, 0x53, 0x4c,
-	0xf4, 0x04, 0xde, 0x48, 0xf4, 0x4d, 0x0b, 0x2c, 0x5e, 0x47, 0x20, 0xd2, 0x12, 0x52, 0x3b, 0xa9,
-	0x72, 0x57, 0x3a, 0xbf, 0xdc, 0xa9, 0x1b, 0xc8, 0x2a, 0x77, 0x5d, 0xa8, 0xba, 0x94, 0x7b, 0x11,
-	0x75, 0x55, 0xd8, 0x52, 0x95, 0xc7, 0x6a, 0xf7, 0xbf, 0x7b, 0x91, 0x10, 0x8a, 0x2b, 0x9a, 0xa3,
-	0x66, 0xa8, 0x03, 0x45, 0xfd, 0xee, 0xb8, 0x55, 0xbe, 0x4e, 0x7d, 0x58, 0xd0, 0x4e, 0xa5, 0x9d,
-	0xca, 0xb5, 0xd2, 0xce, 0x03, 0x00, 0x9f, 0x0d, 0x6d, 0x37, 0xf2, 0xa6, 0x34, 0xb2, 0xaa, 0xba,
-	0xf9, 0xc9, 0xe0, 0xf6, 0x14, 0x02, 0x97, 0x7c, 0x36, 0x8c, 0x87, 0x88, 0x40, 0x9d, 0x70, 0xee,
-	0x0d, 0x03, 0xea, 0xda, 0x43, 0x1a, 0xd0, 0xc8, 0x73, 0xec, 0x88, 0x72, 0x36, 0x89, 0x1c, 0xca,
-	0xad, 0x6f, 0x28, 0x4b, 0x32, 0xdb, 0x8f, 0x87, 0x31, 0x18, 0x6b, 0x2c, 0xb6, 0x12, 0x31, 0x67,
-	0x36, 0xf8, 0x5e, 0xfd, 0xd9, 0xf3, 0xd6, 0x26, 0x6c, 0xa4, 0xd3, 0xd4, 0xae, 0xf1, 0x81, 0xf1,
-	0xa1, 0x71, 0x68, 0xb4, 0xfe, 0x9e, 0x83, 0x6f, 0xae, 0xf8, 0x04, 0xfd, 0x18, 0x0a, 0xda, 0x2b,
-	0x17, 0x35, 0x91, 0x9a, 0x87, 0x13, 0x2c, 0xda, 0x82, 0x92, 0x0c, 0x71, 0xca, 0x39, 0x8d, 0x93,
-	0x57, 0x09, 0x2f, 0x17, 0x90, 0x05, 0x05, 0xe2, 0x7b, 0x44, 0xee, 0xad, 0xab, 0xbd, 0x64, 0x8a,
-	0x26, 0xb0, 0x19, 0xbb, 0xce, 0x5e, 0xd6, 0x6a, 0x9b, 0x85, 0x82, 0x5b, 0xa6, 0xb2, 0xff, 0xfd,
-	0x2b, 0xdd, 0xa4, 0x76, 0xee, 0x72, 0xe1, 0x71, 0x28, 0xf8, 0x41, 0x20, 0xa2, 0x19, 0xde, 0x70,
-	0x33, 0xb6, 0xea, 0x0f, 0xe1, 0xce, 0xb9, 0x14, 0x74, 0x1b, 0xd6, 0x47, 0x74, 0x16, 0xa7, 0x27,
-	0x2c, 0x87, 0x68, 0x03, 0x6e, 0x4d, 0x89, 0x3f, 0xa1, 0x3a, 0x9b, 0xc5, 0x93, 0xbd, 0xdc, 0xae,
-	0xd1, 0xfa, 0x67, 0x0e, 0x0a, 0x5a, 0x9d, 0x9b, 0xee, 0x0c, 0xf4, 0xb1, 0x2b, 0x89, 0xed, 0x3d,
-	0xa8, 0x68, 0x97, 0xc6, 0x11, 0x65, 0x5e, 0xfa, 0x26, 0xcb, 0x31, 0x3e, 0x8e, 0xa6, 0xf7, 0xc0,
-	0xf4, 0x42, 0x32, 0xd6, 0xe5, 0x33, 0xf3, 0xe4, 0xfe, 0x61, 0xe7, 0xd1, 0xe3, 0x30, 0x4e, 0x0c,
-	0xc5, 0xf9, 0x49, 0xd3, 0x94, 0x0b, 0x58, 0xd1, 0x32, 0xea, 0x67, 0xfe, 0xaa, 0xf5, 0xf3, 0x1f,
-	0x79, 0x28, 0xec, 0xfb, 0x13, 0x2e, 0x68, 0x74, 0xd3, 0xbe, 0xd4, 0xc7, 0xae, 0xf8, 0x72, 0x1f,
-	0x0a, 0x11, 0x63, 0xc2, 0x76, 0xc8, 0x45, 0x6e, 0xc4, 0x8c, 0x89, 0xfd, 0x4e, 0xb7, 0x26, 0x89,
-	0x32, 0x85, 0xc7, 0x73, 0x9c, 0x97, 0xd4, 0x7d, 0x82, 0x3e, 0x87, 0xcd, 0xa4, 0x70, 0x0e, 0x18,
-	0x13, 0x5c, 0x44, 0x24, 0xb4, 0x47, 0x74, 0x26, 0x5b, 0x94, 0xf5, 0xf3, 0x5a, 0xfb, 0x83, 0xc0,
-	0x89, 0x66, 0xca, 0xc7, 0x1f, 0xd1, 0x19, 0xde, 0xd0, 0x02, 0xba, 0x09, 0xff, 0x23, 0x3a, 0xe3,
-	0xe8, 0x7d, 0xd8, 0xa2, 0x0b, 0x98, 0x94, 0x68, 0xfb, 0x64, 0x2c, 0x5b, 0x02, 0xdb, 0xf1, 0x99,
-	0x33, 0x52, 0x9e, 0x37, 0xf1, 0x1d, 0x9a, 0x16, 0xf5, 0x71, 0x8c, 0xd8, 0x97, 0x00, 0xc4, 0xc1,
-	0x1a, 0xf8, 0xc4, 0x19, 0xf9, 0x1e, 0x97, 0x5f, 0x6f, 0xa9, 0x4e, 0x5d, 0x16, 0x06, 0xa9, 0xdb,
-	0xee, 0x05, 0xde, 0x6a, 0x77, 0x97, 0xdc, 0x54, 0xdf, 0xaf, 0x03, 0xef, 0xdb, 0x83, 0xec, 0x5d,
-	0xd4, 0x85, 0xf2, 0x24, 0x90, 0xc7, 0xc7, 0x3e, 0x28, 0x5d, 0xd5, 0x07, 0x10, 0xb3, 0x94, 0xe5,
-	0x5b, 0x60, 0x1e, 0xcb, 0x56, 0x47, 0x56, 0x8b, 0x62, 0xfc, 0x06, 0x7f, 0xd9, 0x3f, 0x3c, 0xc2,
-	0x6a, 0x15, 0xb5, 0x01, 0xb9, 0xf4, 0x98, 0x4c, 0x7c, 0xd1, 0x89, 0x53, 0xd0, 0x21, 0x63, 0xbe,
-	0x2a, 0x0d, 0x25, 0x9c, 0xb1, 0x83, 0x1a, 0x00, 0x7c, 0x32, 0x08, 0xa8, 0x38, 0xf2, 0x7e, 0x4b,
-	0x55, 0xfe, 0xaf, 0xe2, 0xd4, 0xca, 0xca, 0xa7, 0x43, 0x75, 0xf5, 0xd3, 0xa1, 0x3e, 0x85, 0xad,
-	0x8b, 0xdc, 0x91, 0x91, 0x54, 0x3e, 0x48, 0x27, 0x95, 0xf2, 0xfd, 0xb7, 0xb3, 0x3c, 0x90, 0x2d,
-	0x32, 0x95, 0x80, 0x32, 0x03, 0xe9, 0x6f, 0x06, 0xe4, 0x8f, 0xa8, 0x13, 0x51, 0xf1, 0x5a, 0xe3,
-	0x68, 0xf7, 0x54, 0x1c, 0x35, 0xb2, 0xbf, 0x14, 0xe4, 0xa9, 0x2b, 0x61, 0x54, 0x87, 0xa2, 0x17,
-	0x08, 0x1a, 0x05, 0xc4, 0x57, 0x71, 0x54, 0xc4, 0x8b, 0x79, 0xa6, 0x01, 0x7f, 0x32, 0x20, 0x1f,
-	0xb7, 0xb8, 0x37, 0x6d, 0x40, 0x7c, 0xea, 0x59, 0x03, 0x32, 0x95, 0xfc, 0x8f, 0x01, 0xc5, 0xa4,
-	0xd2, 0xbe, 0x56, 0x35, 0xcf, 0xb4, 0x7c, 0xeb, 0xff, 0x73, 0xcb, 0x87, 0xc0, 0x1c, 0x79, 0x81,
-	0x6e, 0x4e, 0xb1, 0x1a, 0xa3, 0x36, 0x14, 0x42, 0x32, 0xf3, 0x19, 0x71, 0x75, 0x86, 0xdf, 0x58,
-	0xf9, 0xa7, 0xa6, 0x13, 0xcc, 0x70, 0x02, 0xda, 0xdb, 0x78, 0xf6, 0xbc, 0x75, 0x1b, 0x6a, 0x69,
-	0xcb, 0x9f, 0x1a, 0xad, 0x7f, 0x19, 0x50, 0x3a, 0xf8, 0x8d, 0xa0, 0x81, 0x6a, 0x85, 0xff, 0x2f,
-	0x8d, 0xdf, 0x5e, 0xfd, 0x37, 0xa7, 0x74, 0xea, 0x8f, 0x9a, 0xac, 0x4b, 0xed, 0x7e, 0xff, 0xc5,
-	0xcb, 0xc6, 0xda, 0xd7, 0x2f, 0x1b, 0x6b, 0xbf, 0x9b, 0x37, 0x8c, 0x17, 0xf3, 0x86, 0xf1, 0xd5,
-	0xbc, 0x61, 0xfc, 0x7b, 0xde, 0x30, 0xfe, 0xf0, 0xaa, 0xb1, 0xf6, 0xd5, 0xab, 0xc6, 0xda, 0xd7,
-	0xaf, 0x1a, 0x6b, 0x83, 0xbc, 0xf2, 0xd5, 0x8f, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x53, 0x14,
-	0x4d, 0x41, 0xa0, 0x14, 0x00, 0x00,
+	// 1700 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x73, 0x1b, 0x49,
+	0x15, 0xf7, 0xc8, 0x13, 0x49, 0xf3, 0xf4, 0x81, 0xe9, 0x35, 0x66, 0x62, 0x8c, 0x6c, 0xb4, 0x2c,
+	0x95, 0xda, 0x4a, 0xc9, 0x4b, 0x58, 0xc0, 0x31, 0xbb, 0x6c, 0x24, 0xdb, 0x64, 0xc5, 0x6e, 0x36,
+	0xae, 0xf6, 0x6e, 0x76, 0x6f, 0x43, 0x6b, 0xa6, 0xad, 0x4c, 0x34, 0x9a, 0x9e, 0x9a, 0x6e, 0x69,
+	0x11, 0x27, 0xce, 0x39, 0x71, 0xcb, 0x8d, 0x03, 0xc5, 0x3f, 0xc1, 0x85, 0x03, 0x07, 0x2a, 0x1c,
+	0xa8, 0xda, 0x13, 0x95, 0x93, 0x8b, 0x28, 0x7f, 0x05, 0x37, 0xaa, 0x7b, 0x7a, 0xa4, 0x71, 0x34,
+	0xb6, 0x1c, 0x2a, 0x95, 0xe2, 0xa4, 0xfe, 0xf8, 0xfd, 0x5e, 0xbf, 0xf7, 0xe6, 0x7d, 0x74, 0x0b,
+	0x6e, 0xf6, 0x7d, 0xf1, 0x70, 0xd4, 0x6b, 0xb9, 0x6c, 0xb8, 0xeb, 0x31, 0x77, 0x40, 0xe3, 0x5d,
+	0xfe, 0x35, 0x89, 0x87, 0x03, 0x5f, 0xec, 0x92, 0xc8, 0xdf, 0x65, 0xbd, 0x47, 0xd4, 0x15, 0xbc,
+	0x15, 0xc5, 0x4c, 0x30, 0x84, 0x12, 0x48, 0x2b, 0x85, 0xb4, 0xc6, 0x3f, 0xde, 0x7c, 0x77, 0x89,
+	0x04, 0x31, 0x89, 0xa8, 0xe6, 0x2f, 0xc5, 0xf2, 0x88, 0xba, 0x29, 0x76, 0xbb, 0xcf, 0x58, 0x3f,
+	0xa0, 0xbb, 0x6a, 0xd6, 0x1b, 0x9d, 0xee, 0x0a, 0x7f, 0x48, 0xb9, 0x20, 0xc3, 0x48, 0x03, 0xd6,
+	0xfb, 0xac, 0xcf, 0xd4, 0x70, 0x57, 0x8e, 0xf4, 0xea, 0xf5, 0x97, 0x69, 0x24, 0x9c, 0xe8, 0xad,
+	0x9f, 0x5f, 0x72, 0xfa, 0x0c, 0x1e, 0x05, 0xa3, 0xbe, 0x1f, 0xea, 0x9f, 0x84, 0xd8, 0xfc, 0x8b,
+	0x01, 0xe6, 0x3d, 0x2a, 0x08, 0xfa, 0x05, 0x94, 0xc6, 0x34, 0xe6, 0x3e, 0x0b, 0x6d, 0x63, 0xc7,
+	0xb8, 0x51, 0xb9, 0xf5, 0xbd, 0xd6, 0xa2, 0x47, 0x5a, 0x0f, 0x12, 0x48, 0xc7, 0x7c, 0x7a, 0xb6,
+	0xbd, 0x82, 0x53, 0x06, 0xba, 0x0d, 0xe0, 0xc6, 0x94, 0x08, 0xea, 0x39, 0x44, 0xd8, 0x05, 0xc5,
+	0xdf, 0x6c, 0x25, 0xea, 0xb6, 0xd2, 0xf3, 0x5b, 0x9f, 0xa7, 0x56, 0x62, 0x4b, 0xa3, 0xdb, 0x42,
+	0x52, 0x47, 0x91, 0x97, 0x52, 0x57, 0x97, 0x53, 0x35, 0xba, 0x2d, 0x9a, 0x7f, 0xbe, 0x06, 0xe6,
+	0x67, 0xcc, 0xa3, 0x68, 0x03, 0x0a, 0xbe, 0xa7, 0xd4, 0xb6, 0x3a, 0xc5, 0xe9, 0xd9, 0x76, 0xa1,
+	0x7b, 0x88, 0x0b, 0xbe, 0x87, 0x6e, 0x81, 0x39, 0xa4, 0x82, 0x68, 0x85, 0xec, 0x3c, 0x83, 0xa4,
+	0xed, 0xda, 0x1a, 0x85, 0x45, 0x3f, 0x03, 0x53, 0x7e, 0x2a, 0xad, 0xc9, 0x56, 0x1e, 0x47, 0x9e,
+	0x79, 0x12, 0x51, 0x37, 0xe5, 0x49, 0x3c, 0x3a, 0x82, 0x8a, 0x47, 0xb9, 0x1b, 0xfb, 0x91, 0x90,
+	0x3e, 0x34, 0x15, 0xfd, 0xed, 0x8b, 0xe8, 0x87, 0x73, 0x28, 0xce, 0xf2, 0xd0, 0x07, 0x50, 0xe4,
+	0x82, 0x88, 0x11, 0xb7, 0xaf, 0x29, 0x09, 0x8d, 0x0b, 0x15, 0x50, 0x28, 0xad, 0x82, 0xe6, 0xa0,
+	0x8f, 0xa1, 0x3e, 0x24, 0x21, 0xe9, 0xd3, 0xd8, 0xd1, 0x52, 0x8a, 0x4a, 0xca, 0x0f, 0x72, 0x4d,
+	0x4f, 0x90, 0x89, 0x20, 0x5c, 0x1b, 0x66, 0xa7, 0xa8, 0x0b, 0x40, 0x84, 0x20, 0xee, 0xc3, 0x21,
+	0x0d, 0x85, 0x5d, 0x52, 0x52, 0xde, 0xc9, 0xd5, 0x85, 0x8a, 0xaf, 0x59, 0x3c, 0x68, 0xcf, 0xc0,
+	0x9d, 0x82, 0x6d, 0xe0, 0x0c, 0x19, 0xdd, 0x85, 0x8a, 0x4b, 0x63, 0xe1, 0x9f, 0xfa, 0x2e, 0x11,
+	0xd4, 0x2e, 0x2b, 0x59, 0xdb, 0x79, 0xb2, 0x0e, 0xe6, 0x30, 0x6d, 0x58, 0x96, 0x89, 0xde, 0x03,
+	0x33, 0x66, 0x01, 0xb5, 0xad, 0x1d, 0xe3, 0x46, 0xfd, 0xe2, 0x4f, 0x83, 0x59, 0x40, 0xb1, 0x42,
+	0xca, 0xa3, 0xe7, 0x8a, 0x70, 0x1b, 0x76, 0x56, 0xaf, 0x6c, 0x06, 0xce, 0x32, 0x51, 0x13, 0xaa,
+	0x0f, 0xbe, 0xfa, 0xb4, 0xfd, 0xd9, 0x17, 0x87, 0xc7, 0xc7, 0x2c, 0x16, 0x76, 0x65, 0xc7, 0xb8,
+	0x51, 0xc3, 0xe7, 0xd6, 0xf6, 0x37, 0x1e, 0x3f, 0x69, 0x22, 0x58, 0x2b, 0x1b, 0x6b, 0x86, 0x8a,
+	0x45, 0xe3, 0x3d, 0xe3, 0x2b, 0xe3, 0x37, 0x46, 0xf3, 0xb9, 0x09, 0xa5, 0x13, 0x1a, 0x8f, 0x7d,
+	0xf7, 0xf5, 0x46, 0xea, 0xed, 0x73, 0x91, 0x9a, 0xeb, 0x50, 0x7d, 0xec, 0x42, 0xb0, 0xfe, 0x12,
+	0xaa, 0xf2, 0xd7, 0x49, 0x33, 0x1e, 0x96, 0x66, 0x3c, 0xae, 0x48, 0x82, 0x9e, 0xa0, 0x43, 0xa8,
+	0x45, 0x31, 0x1d, 0xfb, 0x6c, 0xc4, 0x1d, 0xa5, 0x43, 0xf1, 0x4a, 0x3a, 0xe0, 0x6a, 0xca, 0x92,
+	0x33, 0x74, 0x1f, 0xbe, 0x73, 0x4e, 0xca, 0x4c, 0x9d, 0xca, 0x72, 0x75, 0xde, 0xca, 0x4a, 0x4a,
+	0xd5, 0xda, 0x83, 0x32, 0x0d, 0xbd, 0x88, 0xf9, 0xa1, 0xd0, 0x09, 0x98, 0x1b, 0x24, 0x47, 0x1a,
+	0x83, 0x67, 0x68, 0x74, 0x04, 0xb5, 0xa4, 0xae, 0x38, 0xe7, 0xb2, 0x6f, 0x27, 0x8f, 0xfe, 0x85,
+	0x02, 0xea, 0xb4, 0xa9, 0x8e, 0x32, 0x33, 0xf4, 0x01, 0xc0, 0x23, 0xd6, 0x4b, 0x65, 0x54, 0x95,
+	0x8c, 0xef, 0xe7, 0xc9, 0xf8, 0x35, 0xeb, 0x69, 0x01, 0xd6, 0xa3, 0x74, 0x88, 0xde, 0x81, 0x7a,
+	0x44, 0x43, 0xcf, 0x0f, 0xfb, 0x8e, 0x47, 0x03, 0x2a, 0xa8, 0xca, 0xbb, 0x32, 0xae, 0xe9, 0xd5,
+	0x43, 0xb5, 0xb8, 0x8f, 0x1e, 0x3f, 0x69, 0xd6, 0xa1, 0x9a, 0x8d, 0xb3, 0xe6, 0x1f, 0x0b, 0x50,
+	0x4e, 0xcd, 0x42, 0xef, 0xeb, 0xc0, 0x30, 0x2e, 0xb6, 0x21, 0xc5, 0xaa, 0xaf, 0x92, 0xc4, 0xc4,
+	0xfb, 0x70, 0x2d, 0x62, 0xb1, 0xe0, 0x76, 0x41, 0x65, 0x49, 0x6e, 0xe1, 0x91, 0x71, 0x7e, 0xc0,
+	0xc2, 0x53, 0xbf, 0x8f, 0x13, 0x30, 0xfa, 0x12, 0x2a, 0x63, 0x3f, 0x16, 0x23, 0x12, 0x38, 0x7e,
+	0xc4, 0xed, 0x55, 0xc5, 0xfd, 0xd1, 0x65, 0x47, 0xb6, 0x1e, 0x24, 0xf8, 0xee, 0x71, 0xa7, 0x3e,
+	0x3d, 0xdb, 0x86, 0xd9, 0x94, 0x63, 0xd0, 0xa2, 0xba, 0x11, 0xdf, 0xbc, 0x07, 0xd6, 0x6c, 0x07,
+	0xdd, 0x04, 0x08, 0x93, 0x04, 0x75, 0x66, 0xe9, 0x53, 0x9b, 0x9e, 0x6d, 0x5b, 0x3a, 0x6d, 0xbb,
+	0x87, 0xd8, 0xd2, 0x80, 0xae, 0x87, 0x10, 0x98, 0xc4, 0xf3, 0x62, 0x95, 0x4c, 0x16, 0x56, 0xe3,
+	0xe6, 0x3f, 0x4b, 0x60, 0x7e, 0x4e, 0xf8, 0xe0, 0x4d, 0xf7, 0x0a, 0x79, 0xe6, 0xd2, 0xf4, 0xab,
+	0xbf, 0x62, 0xfa, 0xdd, 0x04, 0xe0, 0x49, 0x56, 0x49, 0x77, 0x98, 0x73, 0x77, 0xe8, 0x5c, 0x93,
+	0xee, 0xd0, 0x80, 0xc4, 0x1d, 0x3c, 0x60, 0x42, 0x85, 0xb4, 0x89, 0xd5, 0x18, 0xbd, 0x0d, 0xa5,
+	0x90, 0x79, 0x8a, 0x5e, 0x54, 0x74, 0x98, 0x9e, 0x6d, 0x17, 0x65, 0xf5, 0xec, 0x1e, 0xe2, 0xa2,
+	0xdc, 0xea, 0x7a, 0xaa, 0x7a, 0x86, 0x21, 0x13, 0x44, 0x76, 0x26, 0xae, 0x9b, 0x40, 0x6e, 0x8e,
+	0xb7, 0xe7, 0xb0, 0xb4, 0x70, 0x67, 0x98, 0xe8, 0x01, 0xbc, 0x95, 0xea, 0x9b, 0x15, 0x58, 0x7e,
+	0x15, 0x81, 0x48, 0x4b, 0xc8, 0xec, 0x64, 0x9a, 0xa5, 0x75, 0x71, 0xb3, 0x54, 0x5f, 0x20, 0xaf,
+	0x59, 0x76, 0xa0, 0xe6, 0x51, 0xee, 0xc7, 0xd4, 0x53, 0x09, 0x4b, 0x55, 0x15, 0xac, 0xe7, 0xe7,
+	0x6b, 0x2a, 0x84, 0xe2, 0xaa, 0xe6, 0xa8, 0x19, 0x6a, 0x43, 0x59, 0xc7, 0x1d, 0xb7, 0x2b, 0xaf,
+	0xd2, 0x5d, 0x66, 0xb4, 0x73, 0x45, 0xab, 0xfa, 0x4a, 0x45, 0xeb, 0x36, 0x40, 0xc0, 0xfa, 0x8e,
+	0x17, 0xfb, 0x63, 0x1a, 0xdb, 0x35, 0x7d, 0x75, 0xca, 0xe1, 0x1e, 0x2a, 0x04, 0xb6, 0x02, 0xd6,
+	0x4f, 0x86, 0x88, 0xc0, 0x26, 0xe1, 0xdc, 0xef, 0x87, 0xd4, 0x73, 0xfa, 0x34, 0xa4, 0xb1, 0xef,
+	0x3a, 0x31, 0xe5, 0x6c, 0x14, 0xbb, 0x94, 0xdb, 0xdf, 0x52, 0x96, 0xe4, 0x5e, 0x5e, 0xee, 0x26,
+	0x60, 0xac, 0xb1, 0xd8, 0x4e, 0xc5, 0xbc, 0xb4, 0xc1, 0xd1, 0x1d, 0xa8, 0xc9, 0x5a, 0xe8, 0x0b,
+	0x1a, 0xab, 0xcf, 0x65, 0xaf, 0x2d, 0x8f, 0xf2, 0xea, 0x23, 0xd6, 0xeb, 0xa6, 0x84, 0xfd, 0xcd,
+	0xc7, 0x4f, 0x9a, 0x1b, 0xb0, 0x9e, 0x2d, 0x74, 0x7b, 0xc6, 0x1d, 0xe3, 0x63, 0xe3, 0xd8, 0x68,
+	0xfe, 0xad, 0x00, 0xdf, 0x5e, 0xf0, 0x2a, 0xfa, 0x29, 0x94, 0xb4, 0x5f, 0x2f, 0xbb, 0xc4, 0x6a,
+	0x1e, 0x4e, 0xb1, 0x68, 0x0b, 0x2c, 0x59, 0x24, 0x28, 0xe7, 0x34, 0x29, 0x7f, 0x16, 0x9e, 0x2f,
+	0x20, 0x1b, 0x4a, 0x24, 0xf0, 0x89, 0xdc, 0x5b, 0x55, 0x7b, 0xe9, 0x14, 0x8d, 0x60, 0x23, 0x71,
+	0xbe, 0x33, 0xbf, 0x2b, 0x38, 0x2c, 0x12, 0xdc, 0x36, 0x95, 0x07, 0x3f, 0xba, 0x52, 0x2c, 0xe8,
+	0xcf, 0x33, 0x5f, 0xb8, 0x1f, 0x09, 0x7e, 0x14, 0x8a, 0x78, 0x82, 0xd7, 0xbd, 0x9c, 0xad, 0xcd,
+	0xbb, 0x70, 0xfd, 0x42, 0x0a, 0x5a, 0x83, 0xd5, 0x01, 0x9d, 0x24, 0x05, 0x0e, 0xcb, 0x21, 0x5a,
+	0x87, 0x6b, 0x63, 0x12, 0x8c, 0xa8, 0xae, 0x87, 0xc9, 0x64, 0xbf, 0xb0, 0x67, 0x34, 0xff, 0x51,
+	0x80, 0x92, 0x56, 0xe7, 0x4d, 0xdf, 0x4c, 0xf4, 0xb1, 0x0b, 0xa5, 0xf1, 0x43, 0xa8, 0x6a, 0x97,
+	0x26, 0x39, 0x69, 0x2e, 0x8d, 0xea, 0x4a, 0x82, 0x4f, 0xf2, 0xf1, 0x43, 0x30, 0xfd, 0x88, 0x0c,
+	0x75, 0xfb, 0xce, 0x3d, 0xb9, 0x7b, 0xdc, 0xbe, 0x77, 0x3f, 0x4a, 0x4a, 0x4b, 0x79, 0x7a, 0xb6,
+	0x6d, 0xca, 0x05, 0xac, 0x68, 0x39, 0x1d, 0xb8, 0x78, 0xd5, 0x0e, 0xfc, 0xf7, 0x22, 0x94, 0x0e,
+	0x82, 0x11, 0x17, 0x34, 0x7e, 0xd3, 0xbe, 0xd4, 0xc7, 0x2e, 0xf8, 0xf2, 0x00, 0x4a, 0x31, 0x63,
+	0xc2, 0x71, 0xc9, 0x65, 0x6e, 0xc4, 0x8c, 0x89, 0x83, 0x76, 0xa7, 0x2e, 0x89, 0xb2, 0x09, 0x24,
+	0x73, 0x5c, 0x94, 0xd4, 0x03, 0x82, 0xbe, 0x84, 0x8d, 0xb4, 0xf5, 0xf6, 0x18, 0x13, 0x5c, 0xc4,
+	0x24, 0x72, 0x06, 0x74, 0x22, 0xaf, 0x48, 0xab, 0x17, 0x3d, 0x2d, 0x8e, 0x42, 0x37, 0x9e, 0x28,
+	0x1f, 0x7f, 0x42, 0x27, 0x78, 0x5d, 0x0b, 0xe8, 0xa4, 0xfc, 0x4f, 0xe8, 0x84, 0xa3, 0x8f, 0x60,
+	0x8b, 0xce, 0x60, 0x52, 0xa2, 0x13, 0x90, 0xa1, 0xbc, 0x54, 0x38, 0x6e, 0xc0, 0xdc, 0x81, 0xf2,
+	0xbc, 0x89, 0xaf, 0xd3, 0xac, 0xa8, 0x4f, 0x13, 0xc4, 0x81, 0x04, 0x20, 0x0e, 0x76, 0x2f, 0x20,
+	0xee, 0x20, 0xf0, 0xb9, 0x7c, 0x3d, 0x66, 0x5e, 0x0a, 0xb2, 0xb5, 0x48, 0xdd, 0xf6, 0x2e, 0xf1,
+	0x56, 0xab, 0x33, 0xe7, 0x66, 0xde, 0x1d, 0x3a, 0xf1, 0xbe, 0xdb, 0xcb, 0xdf, 0x45, 0x1d, 0xa8,
+	0x8c, 0x42, 0x79, 0x7c, 0xe2, 0x03, 0xeb, 0xaa, 0x3e, 0x80, 0x84, 0xa5, 0x2c, 0xdf, 0x02, 0xf3,
+	0x54, 0x5e, 0x96, 0x64, 0xbf, 0x29, 0x27, 0x31, 0xf8, 0xab, 0xee, 0xf1, 0x09, 0x56, 0xab, 0xa8,
+	0x05, 0xc8, 0xa3, 0xa7, 0x64, 0x14, 0x88, 0x76, 0x52, 0x82, 0x8e, 0x19, 0x0b, 0x54, 0x73, 0xb1,
+	0x70, 0xce, 0x0e, 0x6a, 0x00, 0xf0, 0x51, 0x2f, 0xa4, 0xe2, 0xc4, 0xff, 0x1d, 0x55, 0x1d, 0xa4,
+	0x86, 0x33, 0x2b, 0x0b, 0x4f, 0x97, 0xda, 0xe2, 0xd3, 0x65, 0x73, 0x0c, 0x5b, 0x97, 0xb9, 0x23,
+	0xa7, 0xa8, 0xdc, 0xc9, 0x16, 0x95, 0xca, 0xad, 0x77, 0xf3, 0x3c, 0x90, 0x2f, 0x32, 0x53, 0x80,
+	0x72, 0x13, 0xe9, 0xaf, 0x06, 0x14, 0x4f, 0xa8, 0x1b, 0x53, 0xf1, 0x5a, 0xf3, 0x68, 0xef, 0x5c,
+	0x1e, 0x35, 0xf2, 0x5f, 0x2a, 0xf2, 0xd4, 0x85, 0x34, 0xda, 0x84, 0xb2, 0x1f, 0x0a, 0x1a, 0x87,
+	0x24, 0x50, 0x79, 0x54, 0xc6, 0xb3, 0x79, 0xae, 0x01, 0x7f, 0x32, 0xa0, 0x98, 0x5c, 0x92, 0xdf,
+	0xb4, 0x01, 0xc9, 0xa9, 0x2f, 0x1b, 0x90, 0xab, 0xe4, 0x7f, 0x0c, 0x28, 0xa7, 0xbd, 0xfa, 0xb5,
+	0xaa, 0xf9, 0xd2, 0xa5, 0x71, 0xf5, 0x7f, 0xbe, 0x34, 0x22, 0x30, 0x07, 0x7e, 0xa8, 0xaf, 0xb7,
+	0x58, 0x8d, 0x51, 0x0b, 0x4a, 0x11, 0x99, 0x04, 0x8c, 0x78, 0xba, 0xc2, 0xaf, 0x2f, 0xfc, 0x53,
+	0xd4, 0x0e, 0x27, 0x38, 0x05, 0xed, 0xaf, 0x3f, 0x7e, 0xd2, 0x5c, 0x83, 0x7a, 0xd6, 0xf2, 0x87,
+	0x46, 0xf3, 0x5f, 0x06, 0x58, 0x47, 0xbf, 0x15, 0x34, 0x54, 0x97, 0xe9, 0xff, 0x4b, 0xe3, 0x77,
+	0x16, 0xff, 0x4d, 0xb2, 0xce, 0xfd, 0x51, 0x94, 0xf7, 0x51, 0x3b, 0x3f, 0x7c, 0xfa, 0xbc, 0xb1,
+	0xf2, 0xec, 0x79, 0x63, 0xe5, 0xf7, 0xd3, 0x86, 0xf1, 0x74, 0xda, 0x30, 0xbe, 0x99, 0x36, 0x8c,
+	0x7f, 0x4f, 0x1b, 0xc6, 0x1f, 0x5e, 0x34, 0x56, 0xbe, 0x79, 0xd1, 0x58, 0x79, 0xf6, 0xa2, 0xb1,
+	0xd2, 0x2b, 0x2a, 0x5f, 0xfd, 0xe4, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9e, 0xda, 0xee, 0xd3,
+	0x20, 0x15, 0x00, 0x00,
 }
 
 func (m *Meta) Copy() *Meta {
@@ -972,6 +981,10 @@ func (m *Service) CopyFrom(src interface{}) {
 		m.UpdateStatus = &UpdateStatus{}
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.UpdateStatus, o.UpdateStatus)
 	}
+	if o.JobStatus != nil {
+		m.JobStatus = &JobStatus{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.JobStatus, o.JobStatus)
+	}
 }
 
 func (m *Endpoint) Copy() *Endpoint {
@@ -1070,6 +1083,10 @@ func (m *Task) CopyFrom(src interface{}) {
 		}
 	}
 
+	if o.JobIteration != nil {
+		m.JobIteration = &Version{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.JobIteration, o.JobIteration)
+	}
 }
 
 func (m *NetworkAttachment) Copy() *NetworkAttachment {
@@ -1503,6 +1520,16 @@ func (m *Service) MarshalTo(dAtA []byte) (int, error) {
 		}
 		i += n17
 	}
+	if m.JobStatus != nil {
+		dAtA[i] = 0x62
+		i++
+		i = encodeVarintObjects(dAtA, i, uint64(m.JobStatus.Size()))
+		n18, err := m.JobStatus.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n18
+	}
 	return i, nil
 }
 
@@ -1525,11 +1552,11 @@ func (m *Endpoint) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
-		n18, err := m.Spec.MarshalTo(dAtA[i:])
+		n19, err := m.Spec.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n18
+		i += n19
 	}
 	if len(m.Ports) > 0 {
 		for _, msg := range m.Ports {
@@ -1612,19 +1639,19 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n19, err := m.Meta.MarshalTo(dAtA[i:])
+	n20, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n19
+	i += n20
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
-	n20, err := m.Spec.MarshalTo(dAtA[i:])
+	n21, err := m.Spec.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n20
+	i += n21
 	if len(m.ServiceID) > 0 {
 		dAtA[i] = 0x22
 		i++
@@ -1645,27 +1672,27 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x3a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
-	n21, err := m.Annotations.MarshalTo(dAtA[i:])
+	n22, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n21
+	i += n22
 	dAtA[i] = 0x42
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.ServiceAnnotations.Size()))
-	n22, err := m.ServiceAnnotations.MarshalTo(dAtA[i:])
+	n23, err := m.ServiceAnnotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n22
+	i += n23
 	dAtA[i] = 0x4a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Status.Size()))
-	n23, err := m.Status.MarshalTo(dAtA[i:])
+	n24, err := m.Status.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n23
+	i += n24
 	if m.DesiredState != 0 {
 		dAtA[i] = 0x50
 		i++
@@ -1687,31 +1714,31 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x62
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.Endpoint.Size()))
-		n24, err := m.Endpoint.MarshalTo(dAtA[i:])
+		n25, err := m.Endpoint.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n24
+		i += n25
 	}
 	if m.LogDriver != nil {
 		dAtA[i] = 0x6a
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.LogDriver.Size()))
-		n25, err := m.LogDriver.MarshalTo(dAtA[i:])
+		n26, err := m.LogDriver.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n25
+		i += n26
 	}
 	if m.SpecVersion != nil {
 		dAtA[i] = 0x72
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.SpecVersion.Size()))
-		n26, err := m.SpecVersion.MarshalTo(dAtA[i:])
+		n27, err := m.SpecVersion.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n26
+		i += n27
 	}
 	if len(m.AssignedGenericResources) > 0 {
 		for _, msg := range m.AssignedGenericResources {
@@ -1725,6 +1752,18 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) {
 			i += n
 		}
 	}
+	if m.JobIteration != nil {
+		dAtA[i] = 0x82
+		i++
+		dAtA[i] = 0x1
+		i++
+		i = encodeVarintObjects(dAtA, i, uint64(m.JobIteration.Size()))
+		n28, err := m.JobIteration.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n28
+	}
 	return i, nil
 }
 
@@ -1747,11 +1786,11 @@ func (m *NetworkAttachment) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.Network.Size()))
-		n27, err := m.Network.MarshalTo(dAtA[i:])
+		n29, err := m.Network.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n27
+		i += n29
 	}
 	if len(m.Addresses) > 0 {
 		for _, s := range m.Addresses {
@@ -1827,38 +1866,38 @@ func (m *Network) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n28, err := m.Meta.MarshalTo(dAtA[i:])
+	n30, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n28
+	i += n30
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
-	n29, err := m.Spec.MarshalTo(dAtA[i:])
+	n31, err := m.Spec.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n29
+	i += n31
 	if m.DriverState != nil {
 		dAtA[i] = 0x22
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.DriverState.Size()))
-		n30, err := m.DriverState.MarshalTo(dAtA[i:])
+		n32, err := m.DriverState.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n30
+		i += n32
 	}
 	if m.IPAM != nil {
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.IPAM.Size()))
-		n31, err := m.IPAM.MarshalTo(dAtA[i:])
+		n33, err := m.IPAM.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n31
+		i += n33
 	}
 	if m.PendingDelete {
 		dAtA[i] = 0x30
@@ -1897,27 +1936,27 @@ func (m *Cluster) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n32, err := m.Meta.MarshalTo(dAtA[i:])
+	n34, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n32
+	i += n34
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
-	n33, err := m.Spec.MarshalTo(dAtA[i:])
+	n35, err := m.Spec.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n33
+	i += n35
 	dAtA[i] = 0x22
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.RootCA.Size()))
-	n34, err := m.RootCA.MarshalTo(dAtA[i:])
+	n36, err := m.RootCA.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n34
+	i += n36
 	if len(m.NetworkBootstrapKeys) > 0 {
 		for _, msg := range m.NetworkBootstrapKeys {
 			dAtA[i] = 0x2a
@@ -1955,11 +1994,11 @@ func (m *Cluster) MarshalTo(dAtA []byte) (int, error) {
 				dAtA[i] = 0x12
 				i++
 				i = encodeVarintObjects(dAtA, i, uint64(v.Size()))
-				n35, err := v.MarshalTo(dAtA[i:])
+				n37, err := v.MarshalTo(dAtA[i:])
 				if err != nil {
 					return 0, err
 				}
-				i += n35
+				i += n37
 			}
 		}
 	}
@@ -2037,19 +2076,19 @@ func (m *Secret) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n36, err := m.Meta.MarshalTo(dAtA[i:])
+	n38, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n36
+	i += n38
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
-	n37, err := m.Spec.MarshalTo(dAtA[i:])
+	n39, err := m.Spec.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n37
+	i += n39
 	if m.Internal {
 		dAtA[i] = 0x20
 		i++
@@ -2087,19 +2126,19 @@ func (m *Config) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n38, err := m.Meta.MarshalTo(dAtA[i:])
+	n40, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n38
+	i += n40
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
-	n39, err := m.Spec.MarshalTo(dAtA[i:])
+	n41, err := m.Spec.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n39
+	i += n41
 	return i, nil
 }
 
@@ -2127,19 +2166,19 @@ func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n40, err := m.Meta.MarshalTo(dAtA[i:])
+	n42, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n40
+	i += n42
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
-	n41, err := m.Annotations.MarshalTo(dAtA[i:])
+	n43, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n41
+	i += n43
 	if len(m.Kind) > 0 {
 		dAtA[i] = 0x22
 		i++
@@ -2150,11 +2189,11 @@ func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.Payload.Size()))
-		n42, err := m.Payload.MarshalTo(dAtA[i:])
+		n44, err := m.Payload.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n42
+		i += n44
 	}
 	return i, nil
 }
@@ -2183,19 +2222,19 @@ func (m *Extension) MarshalTo(dAtA []byte) (int, error) {
 	dAtA[i] = 0x12
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
-	n43, err := m.Meta.MarshalTo(dAtA[i:])
+	n45, err := m.Meta.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n43
+	i += n45
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
-	n44, err := m.Annotations.MarshalTo(dAtA[i:])
+	n46, err := m.Annotations.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n44
+	i += n46
 	if len(m.Description) > 0 {
 		dAtA[i] = 0x22
 		i++
@@ -2315,6 +2354,10 @@ func (m *Service) Size() (n int) {
 		l = m.PreviousSpecVersion.Size()
 		n += 1 + l + sovObjects(uint64(l))
 	}
+	if m.JobStatus != nil {
+		l = m.JobStatus.Size()
+		n += 1 + l + sovObjects(uint64(l))
+	}
 	return n
 }
 
@@ -2418,6 +2461,10 @@ func (m *Task) Size() (n int) {
 			n += 1 + l + sovObjects(uint64(l))
 		}
 	}
+	if m.JobIteration != nil {
+		l = m.JobIteration.Size()
+		n += 2 + l + sovObjects(uint64(l))
+	}
 	return n
 }
 
@@ -5323,6 +5370,7 @@ func (this *Service) String() string {
 		`PendingDelete:` + fmt.Sprintf("%v", this.PendingDelete) + `,`,
 		`SpecVersion:` + strings.Replace(fmt.Sprintf("%v", this.SpecVersion), "Version", "Version", 1) + `,`,
 		`PreviousSpecVersion:` + strings.Replace(fmt.Sprintf("%v", this.PreviousSpecVersion), "Version", "Version", 1) + `,`,
+		`JobStatus:` + strings.Replace(fmt.Sprintf("%v", this.JobStatus), "JobStatus", "JobStatus", 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -5370,6 +5418,7 @@ func (this *Task) String() string {
 		`LogDriver:` + strings.Replace(fmt.Sprintf("%v", this.LogDriver), "Driver", "Driver", 1) + `,`,
 		`SpecVersion:` + strings.Replace(fmt.Sprintf("%v", this.SpecVersion), "Version", "Version", 1) + `,`,
 		`AssignedGenericResources:` + strings.Replace(fmt.Sprintf("%v", this.AssignedGenericResources), "GenericResource", "GenericResource", 1) + `,`,
+		`JobIteration:` + strings.Replace(fmt.Sprintf("%v", this.JobIteration), "Version", "Version", 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -6385,6 +6434,42 @@ func (m *Service) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 12:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobStatus", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowObjects
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthObjects
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthObjects
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.JobStatus == nil {
+				m.JobStatus = &JobStatus{}
+			}
+			if err := m.JobStatus.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipObjects(dAtA[iNdEx:])
@@ -7187,6 +7272,42 @@ func (m *Task) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 16:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobIteration", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowObjects
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthObjects
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthObjects
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.JobIteration == nil {
+				m.JobIteration = &Version{}
+			}
+			if err := m.JobIteration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipObjects(dAtA[iNdEx:])

+ 8 - 0
vendor/github.com/docker/swarmkit/api/objects.proto

@@ -127,6 +127,10 @@ message Service {
 	// progress.
 	UpdateStatus update_status = 5;
 
+	// JobStatus contains the status of a Service that is in one of the Job
+	// modes. It is absent on Replicated and Global services.
+	JobStatus job_status = 12;
+
 	// PendingDelete indicates that this service's deletion has been requested.
 	// Services, as well as all service-level resources, can only be deleted
 	// after all of the service's containers have properly shut down.
@@ -261,6 +265,10 @@ message Task {
 	Driver log_driver = 13;
 
 	repeated GenericResource assigned_generic_resources = 15;
+
+	// JobIteration is the iteration number of the Job-mode Service that this
+	// task belongs to.
+	Version job_iteration = 16;
 }
 
 // NetworkAttachment specifies the network parameters of attachment to

File diff suppressed because it is too large
+ 453 - 190
vendor/github.com/docker/swarmkit/api/specs.pb.go


+ 22 - 0
vendor/github.com/docker/swarmkit/api/specs.proto

@@ -69,6 +69,8 @@ message ServiceSpec {
 	oneof mode {
 		ReplicatedService replicated = 3;
 		GlobalService global = 4;
+		ReplicatedJob replicated_job = 10;
+		GlobalJob global_job = 11;
 	}
 
 	// Update contains settings which affect updates.
@@ -99,6 +101,26 @@ message GlobalService {
 	// Empty message for now.
 }
 
+// ReplicatedJob is a certain type of one-off job which executes many Tasks in
+// parallel until the specified number of Tasks have succeeded.
+message ReplicatedJob {
+	// MaxConcurrent indicates the maximum number of Tasks that should be
+	// executing simultaneously at any given time.
+	uint64 max_concurrent = 1;
+
+	// TotalCompletions sets the total number of Tasks desired to run to
+	// completion. This is also the absolute maximum number of Tasks that will
+	// be executed in parallel. That is, if this number is smaller than
+	// MaxConcurrent, only this many replicas will run.
+	uint64 total_completions = 2;
+}
+
+// GlobalJob is a type of one-off job which executes one Task on every node
+// matching the service's placement constraints.
+message GlobalJob {
+	// Empty message for now.
+}
+
 message TaskSpec {
 	oneof runtime {
 		NetworkAttachmentSpec attachment = 8;

+ 588 - 332
vendor/github.com/docker/swarmkit/api/types.pb.go

@@ -4014,6 +4014,53 @@ func (m *Privileges_SELinuxContext) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_Privileges_SELinuxContext proto.InternalMessageInfo
 
+// JobStatus indicates the status of a Service that is in one of the Job modes.
+type JobStatus struct {
+	// JobIteration is the count of how many times the Job has been excecuted,
+	// successfully or otherwise. "Executed" refers to the job as a whole being
+	// started, not to the individual Tasks being launched. This is used to
+	// disambiguate which Tasks belong to which iteration of a Job.
+	JobIteration Version `protobuf:"bytes,1,opt,name=job_iteration,json=jobIteration,proto3" json:"job_iteration"`
+	// LastExecution is the time that the job was last executed. This is set by
+	// the orchestrator in the same transaction that JobIteration is incremented.
+	// While time is a fungible concept in distributed systems like Swarmkit,
+	// this value gives us a best-effort attempt to prevent weird behavior like
+	// newly added nodes executing long-forgotten jobs.
+	LastExecution *types.Timestamp `protobuf:"bytes,2,opt,name=last_execution,json=lastExecution,proto3" json:"last_execution,omitempty"`
+}
+
+func (m *JobStatus) Reset()      { *m = JobStatus{} }
+func (*JobStatus) ProtoMessage() {}
+func (*JobStatus) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0b5eafd0404ded3d, []int{56}
+}
+func (m *JobStatus) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *JobStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_JobStatus.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalTo(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *JobStatus) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_JobStatus.Merge(m, src)
+}
+func (m *JobStatus) XXX_Size() int {
+	return m.Size()
+}
+func (m *JobStatus) XXX_DiscardUnknown() {
+	xxx_messageInfo_JobStatus.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_JobStatus proto.InternalMessageInfo
+
 func init() {
 	proto.RegisterEnum("docker.swarmkit.v1.ResourceType", ResourceType_name, ResourceType_value)
 	proto.RegisterEnum("docker.swarmkit.v1.TaskState", TaskState_name, TaskState_value)
@@ -4104,6 +4151,7 @@ func init() {
 	proto.RegisterType((*Privileges)(nil), "docker.swarmkit.v1.Privileges")
 	proto.RegisterType((*Privileges_CredentialSpec)(nil), "docker.swarmkit.v1.Privileges.CredentialSpec")
 	proto.RegisterType((*Privileges_SELinuxContext)(nil), "docker.swarmkit.v1.Privileges.SELinuxContext")
+	proto.RegisterType((*JobStatus)(nil), "docker.swarmkit.v1.JobStatus")
 }
 
 func init() {
@@ -4111,338 +4159,342 @@ func init() {
 }
 
 var fileDescriptor_0b5eafd0404ded3d = []byte{
-	// 5289 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x3a, 0x4d, 0x6c, 0x23, 0x59,
-	0x5a, 0xb1, 0x63, 0x3b, 0xf6, 0x67, 0x27, 0xa9, 0x7e, 0x9d, 0xed, 0x49, 0x7b, 0x7a, 0x12, 0x4f,
-	0xcd, 0xf4, 0xce, 0x6c, 0xef, 0xe0, 0xfe, 0x9b, 0x1d, 0xf5, 0xcc, 0x30, 0x3b, 0xe3, 0xbf, 0x74,
-	0xbc, 0x9d, 0xd8, 0xd6, 0xb3, 0xd3, 0xbd, 0x8b, 0x04, 0x45, 0xa5, 0xea, 0xc5, 0xa9, 0x49, 0xb9,
-	0x5e, 0x51, 0x55, 0x4e, 0xda, 0x2c, 0x88, 0x39, 0x01, 0xca, 0x09, 0x2e, 0xcb, 0xae, 0x50, 0x24,
-	0x24, 0xb8, 0x71, 0xe0, 0xc0, 0x81, 0x85, 0xd3, 0x20, 0x21, 0xb4, 0xe2, 0xc2, 0x2e, 0x48, 0xb0,
-	0x02, 0x14, 0x98, 0xac, 0xc4, 0x0d, 0xc1, 0x05, 0x71, 0xe1, 0x80, 0xde, 0x4f, 0x95, 0x2b, 0xee,
-	0x4a, 0x32, 0xb3, 0xcb, 0x25, 0xf1, 0xfb, 0xfe, 0xde, 0xf7, 0xbe, 0xf7, 0xbd, 0xef, 0x7d, 0xdf,
-	0xf7, 0x0a, 0xee, 0x0c, 0xad, 0x60, 0x7f, 0xbc, 0x5b, 0x35, 0xe8, 0xe8, 0xae, 0x49, 0x8d, 0x03,
-	0xe2, 0xdd, 0xf5, 0x8f, 0x74, 0x6f, 0x74, 0x60, 0x05, 0x77, 0x75, 0xd7, 0xba, 0x1b, 0x4c, 0x5c,
-	0xe2, 0x57, 0x5d, 0x8f, 0x06, 0x14, 0x21, 0x41, 0x50, 0x0d, 0x09, 0xaa, 0x87, 0xf7, 0xcb, 0xeb,
-	0x43, 0x4a, 0x87, 0x36, 0xb9, 0xcb, 0x29, 0x76, 0xc7, 0x7b, 0x77, 0x03, 0x6b, 0x44, 0xfc, 0x40,
-	0x1f, 0xb9, 0x82, 0xa9, 0xbc, 0x36, 0x4b, 0x60, 0x8e, 0x3d, 0x3d, 0xb0, 0xa8, 0x73, 0x11, 0xfe,
-	0xc8, 0xd3, 0x5d, 0x97, 0x78, 0x72, 0xd2, 0xf2, 0xca, 0x90, 0x0e, 0x29, 0xff, 0x79, 0x97, 0xfd,
-	0x12, 0x50, 0x75, 0x1d, 0x16, 0x9e, 0x12, 0xcf, 0xb7, 0xa8, 0x83, 0x56, 0x20, 0x6b, 0x39, 0x26,
-	0x79, 0xbe, 0x9a, 0xaa, 0xa4, 0xde, 0xcc, 0x60, 0x31, 0x50, 0xef, 0x01, 0xb4, 0xd9, 0x8f, 0x96,
-	0x13, 0x78, 0x13, 0xa4, 0xc0, 0xfc, 0x01, 0x99, 0x70, 0x8a, 0x02, 0x66, 0x3f, 0x19, 0xe4, 0x50,
-	0xb7, 0x57, 0xd3, 0x02, 0x72, 0xa8, 0xdb, 0xea, 0x67, 0x29, 0x28, 0xd6, 0x1c, 0x87, 0x06, 0x5c,
-	0x3b, 0x1f, 0x21, 0xc8, 0x38, 0xfa, 0x88, 0x48, 0x26, 0xfe, 0x1b, 0x35, 0x20, 0x67, 0xeb, 0xbb,
-	0xc4, 0xf6, 0x57, 0xd3, 0x95, 0xf9, 0x37, 0x8b, 0x0f, 0xbe, 0x5a, 0x7d, 0xd1, 0x24, 0xd5, 0x98,
-	0x90, 0xea, 0x16, 0xa7, 0xe6, 0x4a, 0x60, 0xc9, 0x8a, 0xbe, 0x0e, 0x0b, 0x96, 0x63, 0x5a, 0x06,
-	0xf1, 0x57, 0x33, 0x5c, 0xca, 0x5a, 0x92, 0x94, 0xa9, 0xf6, 0xf5, 0xcc, 0x0f, 0x4e, 0xd7, 0xe7,
-	0x70, 0xc8, 0x54, 0x7e, 0x17, 0x8a, 0x31, 0xb1, 0x09, 0x6b, 0x5b, 0x81, 0xec, 0xa1, 0x6e, 0x8f,
-	0x89, 0x5c, 0x9d, 0x18, 0xbc, 0x97, 0x7e, 0x94, 0x52, 0x3f, 0x82, 0x95, 0x8e, 0x3e, 0x22, 0xe6,
-	0x63, 0xe2, 0x10, 0xcf, 0x32, 0x30, 0xf1, 0xe9, 0xd8, 0x33, 0x08, 0x5b, 0xeb, 0x81, 0xe5, 0x98,
-	0xe1, 0x5a, 0xd9, 0xef, 0x64, 0x29, 0x6a, 0x03, 0x5e, 0x6a, 0x5a, 0xbe, 0xe1, 0x91, 0x80, 0x7c,
-	0x61, 0x21, 0xf3, 0xa1, 0x90, 0xd3, 0x14, 0x2c, 0xcf, 0x72, 0xff, 0x02, 0x5c, 0x67, 0x26, 0x36,
-	0x35, 0x4f, 0x42, 0x34, 0xdf, 0x25, 0x06, 0x17, 0x56, 0x7c, 0xf0, 0x66, 0x92, 0x85, 0x92, 0x56,
-	0xb2, 0x39, 0x87, 0xaf, 0x71, 0x31, 0x21, 0xa0, 0xef, 0x12, 0x03, 0x19, 0x70, 0xc3, 0x94, 0x4a,
-	0xcf, 0x88, 0x4f, 0x73, 0xf1, 0x89, 0xdb, 0x78, 0xc1, 0x32, 0x37, 0xe7, 0xf0, 0x4a, 0x28, 0x2c,
-	0x3e, 0x49, 0x1d, 0x20, 0x1f, 0xca, 0x56, 0xbf, 0x9b, 0x82, 0x42, 0x88, 0xf4, 0xd1, 0x57, 0xa0,
-	0xe0, 0xe8, 0x0e, 0xd5, 0x0c, 0x77, 0xec, 0xf3, 0x05, 0xcd, 0xd7, 0x4b, 0x67, 0xa7, 0xeb, 0xf9,
-	0x8e, 0xee, 0xd0, 0x46, 0x6f, 0xc7, 0xc7, 0x79, 0x86, 0x6e, 0xb8, 0x63, 0x1f, 0xbd, 0x0a, 0xa5,
-	0x11, 0x19, 0x51, 0x6f, 0xa2, 0xed, 0x4e, 0x02, 0xe2, 0x4b, 0xb3, 0x15, 0x05, 0xac, 0xce, 0x40,
-	0xe8, 0x03, 0x58, 0x18, 0x0a, 0x95, 0x56, 0xe7, 0xb9, 0xfb, 0xbc, 0x96, 0xa4, 0xfd, 0x8c, 0xd6,
-	0x38, 0xe4, 0x51, 0xbf, 0x93, 0x86, 0x95, 0x08, 0x4a, 0x7e, 0x65, 0x6c, 0x79, 0x64, 0x44, 0x9c,
-	0xc0, 0x47, 0x5f, 0x83, 0x9c, 0x6d, 0x8d, 0xac, 0xc0, 0x97, 0x36, 0x7f, 0x25, 0x49, 0x6c, 0xb4,
-	0x28, 0x2c, 0x89, 0x51, 0x0d, 0x4a, 0x1e, 0xf1, 0x89, 0x77, 0x28, 0x3c, 0x5e, 0x5a, 0xf4, 0x0a,
-	0xe6, 0x73, 0x2c, 0xe8, 0x3d, 0x00, 0xff, 0x48, 0x77, 0xe5, 0x92, 0xe7, 0xb9, 0x80, 0x97, 0xab,
-	0x22, 0x2e, 0x54, 0xc3, 0xb8, 0x50, 0x6d, 0x3b, 0xc1, 0x3b, 0x6f, 0x3f, 0x65, 0xfe, 0x83, 0x0b,
-	0x8c, 0x5c, 0x58, 0x63, 0x13, 0xae, 0x49, 0x83, 0x31, 0x98, 0x6b, 0x39, 0xc4, 0x67, 0xc7, 0xea,
-	0x4a, 0x11, 0x8a, 0xe0, 0xea, 0x47, 0x4c, 0xea, 0x06, 0xe4, 0x7b, 0xb6, 0x1e, 0xec, 0x51, 0x6f,
-	0x84, 0x54, 0x28, 0xe9, 0x9e, 0xb1, 0x6f, 0x05, 0xc4, 0x08, 0xc6, 0x5e, 0x18, 0x03, 0xce, 0xc1,
-	0xd0, 0x0d, 0x48, 0x53, 0xb1, 0xdc, 0x42, 0x3d, 0x77, 0x76, 0xba, 0x9e, 0xee, 0xf6, 0x71, 0x9a,
-	0xfa, 0xea, 0xfb, 0x70, 0xad, 0x67, 0x8f, 0x87, 0x96, 0xd3, 0x24, 0xbe, 0xe1, 0x59, 0x2e, 0x5b,
-	0x23, 0x3b, 0x1b, 0x2c, 0x92, 0x86, 0x67, 0x83, 0xfd, 0x8e, 0x02, 0x4c, 0x7a, 0x1a, 0x60, 0xd4,
-	0xdf, 0x4a, 0xc3, 0xb5, 0x96, 0x33, 0xb4, 0x1c, 0x12, 0xe7, 0xbe, 0x0d, 0x4b, 0x84, 0x03, 0xb5,
-	0x43, 0x11, 0xf4, 0xa4, 0x9c, 0x45, 0x01, 0x0d, 0x23, 0x61, 0x7b, 0x26, 0x3a, 0xdd, 0x4f, 0xda,
-	0x84, 0x17, 0xa4, 0x27, 0xc6, 0xa8, 0x16, 0x2c, 0xb8, 0x7c, 0x11, 0xbe, 0x74, 0xb2, 0xdb, 0x49,
-	0xb2, 0x5e, 0x58, 0x67, 0x18, 0xaa, 0x24, 0xef, 0xcf, 0x12, 0xaa, 0xfe, 0x26, 0x0d, 0xcb, 0x1d,
-	0x6a, 0x9e, 0xb3, 0x43, 0x19, 0xf2, 0xfb, 0xd4, 0x0f, 0x62, 0x61, 0x39, 0x1a, 0xa3, 0x47, 0x90,
-	0x77, 0xe5, 0xf6, 0x49, 0x1f, 0xbc, 0x95, 0xac, 0xb2, 0xa0, 0xc1, 0x11, 0x35, 0x7a, 0x1f, 0x0a,
-	0xe1, 0xc1, 0x0d, 0xbd, 0xef, 0x0a, 0xf7, 0x9d, 0xd2, 0xa3, 0x0f, 0x20, 0x27, 0x36, 0x41, 0x3a,
-	0xdd, 0xed, 0xcf, 0x65, 0x73, 0x2c, 0x99, 0xd0, 0x63, 0xc8, 0x07, 0xb6, 0xaf, 0x59, 0xce, 0x1e,
-	0x5d, 0xcd, 0x72, 0x01, 0xeb, 0x89, 0xa1, 0x8e, 0x9a, 0x64, 0xb0, 0xd5, 0x6f, 0x3b, 0x7b, 0xb4,
-	0x5e, 0x3c, 0x3b, 0x5d, 0x5f, 0x90, 0x03, 0xbc, 0x10, 0xd8, 0x3e, 0xfb, 0x81, 0x6e, 0x41, 0x66,
-	0xcf, 0x72, 0xfd, 0xd5, 0x5c, 0x25, 0xf5, 0x66, 0xbe, 0x9e, 0x3f, 0x3b, 0x5d, 0xcf, 0x6c, 0xb4,
-	0x7b, 0x7d, 0xcc, 0xa1, 0xea, 0xef, 0xa6, 0xa0, 0x18, 0x93, 0x81, 0x5e, 0x01, 0x08, 0xbc, 0xb1,
-	0x1f, 0x68, 0x1e, 0xa5, 0x01, 0x37, 0x65, 0x09, 0x17, 0x38, 0x04, 0x53, 0x1a, 0xa0, 0x2a, 0x5c,
-	0x37, 0x88, 0x17, 0x68, 0x96, 0xef, 0x8f, 0x89, 0xa7, 0xf9, 0xe3, 0xdd, 0x8f, 0x89, 0x11, 0x70,
-	0xb3, 0x96, 0xf0, 0x35, 0x86, 0x6a, 0x73, 0x4c, 0x5f, 0x20, 0xd0, 0x43, 0xb8, 0x11, 0xa7, 0x77,
-	0xc7, 0xbb, 0xb6, 0x65, 0x68, 0x6c, 0xab, 0xe7, 0x39, 0xcb, 0xf5, 0x29, 0x4b, 0x8f, 0xe3, 0x9e,
-	0x90, 0x89, 0xfa, 0xe3, 0x14, 0x28, 0x58, 0xdf, 0x0b, 0xb6, 0xc9, 0x68, 0x97, 0x78, 0xfd, 0x40,
-	0x0f, 0xc6, 0x3e, 0xba, 0x01, 0x39, 0x9b, 0xe8, 0x26, 0xf1, 0xb8, 0x52, 0x79, 0x2c, 0x47, 0x68,
-	0x87, 0x45, 0x19, 0xdd, 0xd8, 0xd7, 0x77, 0x2d, 0xdb, 0x0a, 0x26, 0x5c, 0x95, 0xa5, 0x64, 0x07,
-	0x9f, 0x95, 0x59, 0xc5, 0x31, 0x46, 0x7c, 0x4e, 0x0c, 0x5a, 0x85, 0x85, 0x11, 0xf1, 0x7d, 0x7d,
-	0x48, 0xb8, 0xa6, 0x05, 0x1c, 0x0e, 0xd5, 0xf7, 0xa1, 0x14, 0xe7, 0x43, 0x45, 0x58, 0xd8, 0xe9,
-	0x3c, 0xe9, 0x74, 0x9f, 0x75, 0x94, 0x39, 0xb4, 0x0c, 0xc5, 0x9d, 0x0e, 0x6e, 0xd5, 0x1a, 0x9b,
-	0xb5, 0xfa, 0x56, 0x4b, 0x49, 0xa1, 0x45, 0x28, 0x4c, 0x87, 0x69, 0xf5, 0x4f, 0x53, 0x00, 0xcc,
-	0xdc, 0x72, 0x51, 0xef, 0x41, 0xd6, 0x0f, 0xf4, 0x40, 0xf8, 0xec, 0xd2, 0x83, 0xd7, 0x2f, 0xda,
-	0x61, 0xa9, 0x2f, 0xfb, 0x47, 0xb0, 0x60, 0x89, 0x6b, 0x98, 0x3e, 0xa7, 0x21, 0x0b, 0x1f, 0xba,
-	0x69, 0x7a, 0x52, 0x71, 0xfe, 0x5b, 0x7d, 0x1f, 0xb2, 0x9c, 0xfb, 0xbc, 0xba, 0x79, 0xc8, 0x34,
-	0xd9, 0xaf, 0x14, 0x2a, 0x40, 0x16, 0xb7, 0x6a, 0xcd, 0x6f, 0x29, 0x69, 0xa4, 0x40, 0xa9, 0xd9,
-	0xee, 0x37, 0xba, 0x9d, 0x4e, 0xab, 0x31, 0x68, 0x35, 0x95, 0x79, 0xf5, 0x36, 0x64, 0xdb, 0x23,
-	0x26, 0xf9, 0x16, 0x3b, 0x10, 0x7b, 0xc4, 0x23, 0x8e, 0x11, 0x9e, 0xb3, 0x29, 0x40, 0xfd, 0xac,
-	0x04, 0xd9, 0x6d, 0x3a, 0x76, 0x02, 0xf4, 0x20, 0x16, 0xd4, 0x96, 0x92, 0xb3, 0x18, 0x4e, 0x58,
-	0x1d, 0x4c, 0x5c, 0x22, 0x83, 0xde, 0x0d, 0xc8, 0x89, 0xa3, 0x23, 0x97, 0x23, 0x47, 0x0c, 0x1e,
-	0xe8, 0xde, 0x90, 0x04, 0x72, 0x3d, 0x72, 0x84, 0xde, 0x64, 0xb7, 0xaa, 0x6e, 0x52, 0xc7, 0x9e,
-	0xf0, 0x13, 0x96, 0x17, 0x57, 0x27, 0x26, 0xba, 0xd9, 0x75, 0xec, 0x09, 0x8e, 0xb0, 0xe8, 0x31,
-	0x14, 0x0d, 0xea, 0xf8, 0x96, 0x1f, 0x10, 0xc7, 0x98, 0xac, 0xe6, 0xb9, 0x52, 0xb7, 0x2f, 0x56,
-	0xaa, 0x31, 0x25, 0xc6, 0x71, 0x4e, 0xb4, 0x09, 0xa5, 0x5d, 0xcb, 0x31, 0x35, 0xea, 0x8a, 0x1b,
-	0x2d, 0x7b, 0xf1, 0xc1, 0x16, 0x92, 0xea, 0x96, 0x63, 0x76, 0x05, 0x31, 0x2e, 0xee, 0x4e, 0x07,
-	0xa8, 0x03, 0x4b, 0x87, 0xd4, 0x1e, 0x8f, 0x48, 0x24, 0x2b, 0xc7, 0x65, 0xbd, 0x71, 0xb1, 0xac,
-	0xa7, 0x9c, 0x3e, 0x94, 0xb6, 0x78, 0x18, 0x1f, 0xa2, 0x27, 0xb0, 0x18, 0x8c, 0xdc, 0x3d, 0x3f,
-	0x12, 0xb7, 0xc0, 0xc5, 0x7d, 0xf9, 0x12, 0xcb, 0x33, 0xf2, 0x50, 0x5a, 0x29, 0x88, 0x8d, 0xca,
-	0xdf, 0x9f, 0x87, 0x62, 0x4c, 0x73, 0xd4, 0x87, 0xa2, 0xeb, 0x51, 0x57, 0x1f, 0xf2, 0x5b, 0x59,
-	0x6e, 0xea, 0xfd, 0xcf, 0xb5, 0xea, 0x6a, 0x6f, 0xca, 0x88, 0xe3, 0x52, 0xd0, 0xdb, 0x50, 0x72,
-	0xa8, 0xe3, 0x11, 0x63, 0xec, 0xf9, 0xd6, 0xa1, 0xd8, 0xf4, 0x7c, 0x5d, 0x39, 0x3b, 0x5d, 0x2f,
-	0x75, 0xa8, 0x83, 0x43, 0x38, 0x3e, 0x47, 0xa5, 0x9e, 0xa4, 0xa1, 0x18, 0x13, 0x89, 0xee, 0x40,
-	0x1e, 0xf7, 0x70, 0xfb, 0x69, 0x6d, 0xd0, 0x52, 0xe6, 0xca, 0xb7, 0x8e, 0x4f, 0x2a, 0xab, 0x5c,
-	0x87, 0xf8, 0xb4, 0x3d, 0xcf, 0x3a, 0x64, 0x9e, 0xff, 0x26, 0x2c, 0x84, 0xa4, 0xa9, 0xf2, 0xcb,
-	0xc7, 0x27, 0x95, 0x97, 0x66, 0x49, 0x63, 0x94, 0xb8, 0xbf, 0x59, 0xc3, 0xad, 0xa6, 0x92, 0x4e,
-	0xa6, 0xc4, 0xfd, 0x7d, 0xdd, 0x23, 0x26, 0xfa, 0x32, 0xe4, 0x24, 0xe1, 0x7c, 0xb9, 0x7c, 0x7c,
-	0x52, 0xb9, 0x31, 0x4b, 0x38, 0xa5, 0xc3, 0xfd, 0xad, 0xda, 0xd3, 0x96, 0x92, 0x49, 0xa6, 0xc3,
-	0x7d, 0x5b, 0x3f, 0x24, 0xe8, 0x75, 0xc8, 0x0a, 0xb2, 0x6c, 0xf9, 0xe6, 0xf1, 0x49, 0xe5, 0x4b,
-	0x2f, 0x88, 0x63, 0x54, 0xe5, 0xd5, 0xdf, 0xfe, 0xc3, 0xb5, 0xb9, 0xbf, 0xf8, 0xa3, 0x35, 0x65,
-	0x16, 0x5d, 0xfe, 0xdf, 0x14, 0x2c, 0x9e, 0x73, 0x14, 0xa4, 0x42, 0xce, 0xa1, 0x06, 0x75, 0xc5,
-	0xe5, 0x9a, 0xaf, 0xc3, 0xd9, 0xe9, 0x7a, 0xae, 0x43, 0x1b, 0xd4, 0x9d, 0x60, 0x89, 0x41, 0x4f,
-	0x66, 0xd2, 0x83, 0x87, 0x9f, 0xd3, 0x0b, 0x13, 0x13, 0x84, 0x0f, 0x61, 0xd1, 0xf4, 0xac, 0x43,
-	0xe2, 0x69, 0x06, 0x75, 0xf6, 0xac, 0xa1, 0xbc, 0x38, 0xcb, 0x89, 0x99, 0x34, 0x27, 0xc4, 0x25,
-	0xc1, 0xd0, 0xe0, 0xf4, 0x3f, 0x43, 0x6a, 0x50, 0x76, 0xa1, 0x14, 0xf7, 0x6b, 0x76, 0x9b, 0xf9,
-	0xd6, 0xaf, 0x12, 0x99, 0x3f, 0xf2, 0x04, 0x1b, 0x17, 0x18, 0x44, 0xa4, 0x88, 0x6f, 0x40, 0x66,
-	0x44, 0x4d, 0x21, 0x67, 0xb1, 0x7e, 0x9d, 0x65, 0x28, 0xff, 0x74, 0xba, 0x5e, 0xa4, 0x7e, 0x75,
-	0xc3, 0xb2, 0xc9, 0x36, 0x35, 0x09, 0xe6, 0x04, 0x2c, 0xd6, 0x86, 0x07, 0x4b, 0xde, 0x06, 0x72,
-	0xa8, 0x7e, 0x2f, 0x05, 0x19, 0x16, 0xc4, 0xd0, 0xcb, 0x90, 0xa9, 0xb7, 0x3b, 0x4d, 0x65, 0xae,
-	0x7c, 0xed, 0xf8, 0xa4, 0xb2, 0xc8, 0xad, 0xc5, 0x10, 0xec, 0x30, 0xa0, 0x75, 0xc8, 0x3d, 0xed,
-	0x6e, 0xed, 0x6c, 0x33, 0xcf, 0xbb, 0x7e, 0x7c, 0x52, 0x59, 0x8e, 0xd0, 0xc2, 0x9e, 0xe8, 0x15,
-	0xc8, 0x0e, 0xb6, 0x7b, 0x1b, 0x7d, 0x25, 0x5d, 0x46, 0xc7, 0x27, 0x95, 0xa5, 0x08, 0xcf, 0x97,
-	0x83, 0x5e, 0x85, 0x6c, 0xa7, 0xd7, 0xee, 0xb5, 0x94, 0xf9, 0xf2, 0x8d, 0xe3, 0x93, 0x0a, 0x8a,
-	0xd0, 0xbc, 0xd2, 0xe9, 0x59, 0x2e, 0x29, 0x5f, 0x93, 0x3e, 0x51, 0x88, 0x70, 0xea, 0x8f, 0x52,
-	0x50, 0x8c, 0xc5, 0x32, 0xe6, 0xd6, 0xcd, 0xd6, 0x46, 0x6d, 0x67, 0x6b, 0xa0, 0xcc, 0xc5, 0xdc,
-	0x3a, 0x46, 0xd2, 0x24, 0x7b, 0xfa, 0xd8, 0x66, 0xb1, 0x15, 0x1a, 0xdd, 0x4e, 0xbf, 0xdd, 0x1f,
-	0xb4, 0x3a, 0x03, 0x25, 0x55, 0x5e, 0x3d, 0x3e, 0xa9, 0xac, 0xcc, 0x12, 0x6f, 0x8c, 0x6d, 0x9b,
-	0x39, 0x76, 0xa3, 0xd6, 0xd8, 0xe4, 0x27, 0x65, 0xea, 0xd8, 0x31, 0xaa, 0x86, 0x6e, 0xec, 0x13,
-	0x13, 0xbd, 0x05, 0x85, 0x66, 0x6b, 0xab, 0xf5, 0xb8, 0xc6, 0x6f, 0x94, 0xf2, 0x2b, 0xc7, 0x27,
-	0x95, 0x9b, 0x2f, 0xce, 0x6e, 0x93, 0xa1, 0x1e, 0x10, 0x73, 0xc6, 0xc1, 0x63, 0x24, 0xea, 0x7f,
-	0xa7, 0x61, 0x11, 0x13, 0x3f, 0xd0, 0xbd, 0xa0, 0x47, 0x6d, 0xcb, 0x98, 0xa0, 0x1e, 0x14, 0x0c,
-	0xea, 0x98, 0x56, 0x2c, 0x36, 0x3d, 0xb8, 0x20, 0x49, 0x9b, 0x72, 0x85, 0xa3, 0x46, 0xc8, 0x89,
-	0xa7, 0x42, 0xd0, 0x5d, 0xc8, 0x9a, 0xc4, 0xd6, 0x27, 0x32, 0x5b, 0xbc, 0xf9, 0x42, 0xb5, 0xd0,
-	0x94, 0x8d, 0x0a, 0x2c, 0xe8, 0x78, 0x6d, 0xa6, 0x3f, 0xd7, 0xf4, 0x20, 0x20, 0x23, 0x37, 0x10,
-	0x3e, 0x92, 0xc1, 0xc5, 0x91, 0xfe, 0xbc, 0x26, 0x41, 0xe8, 0x3e, 0xe4, 0x8e, 0x2c, 0xc7, 0xa4,
-	0x47, 0x32, 0x1b, 0xbc, 0x44, 0xa8, 0x24, 0x54, 0x8f, 0x59, 0x1a, 0x34, 0xa3, 0x26, 0x73, 0xb3,
-	0x4e, 0xb7, 0xd3, 0x0a, 0xdd, 0x4c, 0xe2, 0xbb, 0x4e, 0x87, 0x3a, 0x2c, 0x7a, 0x40, 0xb7, 0xa3,
-	0x6d, 0xd4, 0xda, 0x5b, 0x3b, 0x98, 0xb9, 0xda, 0xca, 0xf1, 0x49, 0x45, 0x89, 0x48, 0x36, 0x74,
-	0xcb, 0x66, 0xe5, 0xc9, 0x4d, 0x98, 0xaf, 0x75, 0xbe, 0xa5, 0xa4, 0xcb, 0xca, 0xf1, 0x49, 0xa5,
-	0x14, 0xa1, 0x6b, 0xce, 0x64, 0x6a, 0xf7, 0xd9, 0x79, 0xd5, 0xbf, 0x9d, 0x87, 0xd2, 0x8e, 0x6b,
-	0xea, 0x01, 0x11, 0xa7, 0x14, 0x55, 0xa0, 0xe8, 0xea, 0x9e, 0x6e, 0xdb, 0xc4, 0xb6, 0xfc, 0x91,
-	0x6c, 0xb1, 0xc4, 0x41, 0xe8, 0xdd, 0xcf, 0x6b, 0xc6, 0x7a, 0x9e, 0x9d, 0xbc, 0xef, 0xfe, 0xeb,
-	0x7a, 0x2a, 0x34, 0xe8, 0x0e, 0x2c, 0xed, 0x09, 0x6d, 0x35, 0xdd, 0xe0, 0x1b, 0x3b, 0xcf, 0x37,
-	0xb6, 0x9a, 0xb4, 0xb1, 0x71, 0xb5, 0xaa, 0x72, 0x91, 0x35, 0xce, 0x85, 0x17, 0xf7, 0xe2, 0x43,
-	0xf4, 0x10, 0x16, 0x46, 0xd4, 0xb1, 0x02, 0xea, 0x5d, 0xbd, 0x0b, 0x21, 0x25, 0xba, 0x03, 0xd7,
-	0xd8, 0xe6, 0x86, 0xfa, 0x70, 0x34, 0xbf, 0xf9, 0xd3, 0x78, 0x79, 0xa4, 0x3f, 0x97, 0x13, 0x62,
-	0x06, 0x46, 0x75, 0xc8, 0x52, 0x8f, 0xe5, 0xa8, 0x39, 0xae, 0xee, 0x5b, 0x57, 0xaa, 0x2b, 0x06,
-	0x5d, 0xc6, 0x83, 0x05, 0xab, 0xfa, 0x0e, 0x2c, 0x9e, 0x5b, 0x04, 0x4b, 0xcd, 0x7a, 0xb5, 0x9d,
-	0x7e, 0x4b, 0x99, 0x43, 0x25, 0xc8, 0x37, 0xba, 0x9d, 0x41, 0xbb, 0xb3, 0xc3, 0x72, 0xcb, 0x12,
-	0xe4, 0x71, 0x77, 0x6b, 0xab, 0x5e, 0x6b, 0x3c, 0x51, 0xd2, 0x6a, 0x15, 0x8a, 0x31, 0x69, 0x68,
-	0x09, 0xa0, 0x3f, 0xe8, 0xf6, 0xb4, 0x8d, 0x36, 0xee, 0x0f, 0x44, 0x66, 0xda, 0x1f, 0xd4, 0xf0,
-	0x40, 0x02, 0x52, 0xea, 0x7f, 0xa6, 0xc3, 0x1d, 0x95, 0xc9, 0x68, 0xfd, 0x7c, 0x32, 0x7a, 0x89,
-	0xf2, 0x32, 0x1d, 0x9d, 0x0e, 0xa2, 0xa4, 0xf4, 0x5d, 0x00, 0xee, 0x38, 0xc4, 0xd4, 0xf4, 0x40,
-	0x6e, 0x7c, 0xf9, 0x05, 0x23, 0x0f, 0xc2, 0x4e, 0x20, 0x2e, 0x48, 0xea, 0x5a, 0x80, 0x3e, 0x80,
-	0x92, 0x41, 0x47, 0xae, 0x4d, 0x24, 0xf3, 0xfc, 0x95, 0xcc, 0xc5, 0x88, 0xbe, 0x16, 0xc4, 0xd3,
-	0xe1, 0xcc, 0xf9, 0x84, 0xfd, 0x37, 0x53, 0xa1, 0x65, 0x12, 0x32, 0xe0, 0x12, 0xe4, 0x77, 0x7a,
-	0xcd, 0xda, 0xa0, 0xdd, 0x79, 0xac, 0xa4, 0x10, 0x40, 0x8e, 0x9b, 0xba, 0xa9, 0xa4, 0x59, 0xe6,
-	0xde, 0xe8, 0x6e, 0xf7, 0xb6, 0x5a, 0x3c, 0x62, 0xa1, 0x15, 0x50, 0x42, 0x63, 0x6b, 0xdc, 0x90,
-	0xad, 0xa6, 0x92, 0x41, 0xd7, 0x61, 0x39, 0x82, 0x4a, 0xce, 0x2c, 0xba, 0x01, 0x28, 0x02, 0x4e,
-	0x45, 0xe4, 0xd4, 0x5f, 0x87, 0xe5, 0x06, 0x75, 0x02, 0xdd, 0x72, 0xa2, 0xaa, 0xe6, 0x01, 0x5b,
-	0xb4, 0x04, 0x69, 0x96, 0xec, 0x90, 0xd5, 0x97, 0xcf, 0x4e, 0xd7, 0x8b, 0x11, 0x69, 0xbb, 0xc9,
-	0xb3, 0x50, 0x39, 0x30, 0xd9, 0xf9, 0x75, 0x2d, 0x93, 0x1b, 0x37, 0x5b, 0x5f, 0x38, 0x3b, 0x5d,
-	0x9f, 0xef, 0xb5, 0x9b, 0x98, 0xc1, 0xd0, 0xcb, 0x50, 0x20, 0xcf, 0xad, 0x40, 0x33, 0xd8, 0xad,
-	0xc6, 0x0c, 0x98, 0xc5, 0x79, 0x06, 0x68, 0x50, 0x93, 0xa8, 0x75, 0x80, 0x1e, 0xf5, 0x02, 0x39,
-	0xf3, 0xdb, 0x90, 0x75, 0xa9, 0xc7, 0x7b, 0x3a, 0x17, 0x76, 0x1a, 0x19, 0xb9, 0x70, 0x54, 0x2c,
-	0x88, 0xd5, 0xef, 0xcd, 0x03, 0x0c, 0x74, 0xff, 0x40, 0x0a, 0x79, 0x04, 0x85, 0xa8, 0xab, 0x2b,
-	0x9b, 0x43, 0x97, 0xee, 0x76, 0x44, 0x8c, 0x1e, 0x86, 0xce, 0x26, 0xea, 0xb5, 0xc4, 0xb2, 0x3a,
-	0x9c, 0x28, 0xa9, 0xe4, 0x39, 0x5f, 0x94, 0xb1, 0x24, 0x81, 0x78, 0x9e, 0xdc, 0x79, 0xf6, 0x13,
-	0x35, 0xf8, 0xb5, 0x20, 0x8c, 0x26, 0x13, 0xf5, 0xc4, 0x76, 0xd8, 0xcc, 0x8e, 0x6c, 0xce, 0xe1,
-	0x29, 0x1f, 0xfa, 0x10, 0x8a, 0x6c, 0xdd, 0x9a, 0xcf, 0x71, 0x32, 0x47, 0xbf, 0xd0, 0x54, 0x42,
-	0x02, 0x06, 0x77, 0x6a, 0xe5, 0x57, 0x00, 0x74, 0xd7, 0xb5, 0x2d, 0x62, 0x6a, 0xbb, 0x13, 0x9e,
-	0x94, 0x17, 0x70, 0x41, 0x42, 0xea, 0x13, 0x76, 0x5c, 0x42, 0xb4, 0x1e, 0xf0, 0xc2, 0xe4, 0x0a,
-	0x03, 0x4a, 0xea, 0x5a, 0x50, 0x57, 0x60, 0xc9, 0x1b, 0x3b, 0xcc, 0xa0, 0x52, 0x3b, 0xf5, 0x4f,
-	0xd2, 0xf0, 0x52, 0x87, 0x04, 0x47, 0xd4, 0x3b, 0xa8, 0x05, 0x81, 0x6e, 0xec, 0x8f, 0x88, 0x23,
-	0xb7, 0x2f, 0x56, 0x44, 0xa5, 0xce, 0x15, 0x51, 0xab, 0xb0, 0xa0, 0xdb, 0x96, 0xee, 0x13, 0x91,
-	0xfa, 0x15, 0x70, 0x38, 0x64, 0xa5, 0x1e, 0x2b, 0x1c, 0x89, 0xef, 0x13, 0xd1, 0xe9, 0x61, 0x8a,
-	0x87, 0x00, 0xf4, 0x6d, 0xb8, 0x21, 0x93, 0x3c, 0x3d, 0x9a, 0x8a, 0xd5, 0x1e, 0x61, 0xe3, 0xba,
-	0x95, 0x58, 0xc9, 0x26, 0x2b, 0x27, 0xb3, 0xc0, 0x29, 0xb8, 0xeb, 0x06, 0x32, 0xa7, 0x5c, 0x31,
-	0x13, 0x50, 0xe5, 0xc7, 0x70, 0xf3, 0x42, 0x96, 0x2f, 0xd4, 0x49, 0xfa, 0xfb, 0x34, 0x40, 0xbb,
-	0x57, 0xdb, 0x96, 0x46, 0x6a, 0x42, 0x6e, 0x4f, 0x1f, 0x59, 0xf6, 0xe4, 0xb2, 0x08, 0x38, 0xa5,
-	0xaf, 0xd6, 0x84, 0x39, 0x36, 0x38, 0x0f, 0x96, 0xbc, 0xbc, 0x8e, 0x1d, 0xef, 0x3a, 0x24, 0x88,
-	0xea, 0x58, 0x3e, 0x62, 0x6a, 0x78, 0xba, 0x13, 0xb9, 0xae, 0x18, 0xb0, 0x0d, 0x60, 0x29, 0xcf,
-	0x91, 0x3e, 0x09, 0xc3, 0x96, 0x1c, 0xa2, 0x4d, 0xde, 0x35, 0x26, 0xde, 0x21, 0x31, 0x57, 0xb3,
-	0xdc, 0xa8, 0x57, 0xe9, 0x83, 0x25, 0xb9, 0xb0, 0x5d, 0xc4, 0x5d, 0x7e, 0x9f, 0xa7, 0x4c, 0x53,
-	0xd4, 0x17, 0xb2, 0xd1, 0x3d, 0x58, 0x3c, 0xb7, 0xce, 0x17, 0x1a, 0x08, 0xed, 0xde, 0xd3, 0xb7,
-	0x95, 0x8c, 0xfc, 0xf5, 0x8e, 0x92, 0x53, 0xff, 0x7a, 0x5e, 0x04, 0x1a, 0x69, 0xd5, 0xe4, 0xd7,
-	0x92, 0x3c, 0xf7, 0x6e, 0x83, 0xda, 0x32, 0x00, 0xbc, 0x71, 0x79, 0xfc, 0x61, 0x75, 0x24, 0x27,
-	0xc7, 0x11, 0x23, 0x5a, 0x87, 0xa2, 0xf0, 0x62, 0x8d, 0x1d, 0x38, 0x6e, 0xd6, 0x45, 0x0c, 0x02,
-	0xc4, 0x38, 0xd1, 0x6d, 0x58, 0xe2, 0x0d, 0x27, 0x7f, 0x9f, 0x98, 0x82, 0x26, 0xc3, 0x69, 0x16,
-	0x23, 0x28, 0x27, 0xdb, 0x86, 0x92, 0x04, 0x68, 0xbc, 0x1a, 0xc8, 0x72, 0x85, 0xee, 0x5c, 0xa5,
-	0x90, 0x60, 0xe1, 0x45, 0x42, 0xd1, 0x9d, 0x0e, 0xd4, 0x5f, 0x86, 0x7c, 0xa8, 0x2c, 0x5a, 0x85,
-	0xf9, 0x41, 0xa3, 0xa7, 0xcc, 0x95, 0x97, 0x8f, 0x4f, 0x2a, 0xc5, 0x10, 0x3c, 0x68, 0xf4, 0x18,
-	0x66, 0xa7, 0xd9, 0x53, 0x52, 0xe7, 0x31, 0x3b, 0xcd, 0x1e, 0x2a, 0x43, 0xa6, 0xdf, 0x18, 0xf4,
-	0xc2, 0xfc, 0x2c, 0x44, 0x31, 0x58, 0x39, 0xc3, 0xf2, 0x33, 0x75, 0x0f, 0x8a, 0xb1, 0xd9, 0xd1,
-	0x6b, 0xb0, 0xd0, 0xee, 0x3c, 0xc6, 0xad, 0x7e, 0x5f, 0x99, 0x13, 0xe5, 0x41, 0x0c, 0xdb, 0x76,
-	0x86, 0x6c, 0xef, 0xd0, 0x2b, 0x90, 0xd9, 0xec, 0xb2, 0x7b, 0x5f, 0xd4, 0x1f, 0x31, 0x8a, 0x4d,
-	0xea, 0x07, 0xe5, 0xeb, 0x32, 0xf1, 0x8b, 0x0b, 0x56, 0x7f, 0x3f, 0x05, 0x39, 0x71, 0xd0, 0x12,
-	0x37, 0xb1, 0x36, 0x2d, 0x8a, 0x44, 0xd9, 0xf8, 0xc6, 0xc5, 0x25, 0x5e, 0x55, 0x56, 0x64, 0xc2,
-	0x35, 0x43, 0xbe, 0xf2, 0x7b, 0x50, 0x8a, 0x23, 0xbe, 0x90, 0x63, 0x7e, 0x1b, 0x8a, 0xcc, 0xf7,
-	0xc3, 0x52, 0xef, 0x01, 0xe4, 0x44, 0xb0, 0x88, 0xee, 0xa1, 0x8b, 0xeb, 0x4d, 0x49, 0x89, 0x1e,
-	0xc1, 0x82, 0xa8, 0x51, 0xc3, 0x5e, 0xf6, 0xda, 0xe5, 0x27, 0x0c, 0x87, 0xe4, 0xea, 0x87, 0x90,
-	0xe9, 0x11, 0xe2, 0x31, 0xdb, 0x3b, 0xd4, 0x24, 0xd3, 0xab, 0x5b, 0x96, 0xd7, 0x26, 0x69, 0x37,
-	0x59, 0x79, 0x6d, 0x92, 0xb6, 0x19, 0xf5, 0xe3, 0xd2, 0xb1, 0x7e, 0xdc, 0x00, 0x4a, 0xcf, 0x88,
-	0x35, 0xdc, 0x0f, 0x88, 0xc9, 0x05, 0xbd, 0x05, 0x19, 0x97, 0x44, 0xca, 0xaf, 0x26, 0x3a, 0x1f,
-	0x21, 0x1e, 0xe6, 0x54, 0x2c, 0xc6, 0x1c, 0x71, 0x6e, 0xf9, 0x0c, 0x24, 0x47, 0xea, 0xdf, 0xa5,
-	0x61, 0xa9, 0xed, 0xfb, 0x63, 0xdd, 0x31, 0xc2, 0xac, 0xee, 0xeb, 0xe7, 0xb3, 0xba, 0xc4, 0xf7,
-	0xb2, 0xf3, 0x2c, 0xe7, 0xdb, 0x8c, 0xf2, 0x66, 0x4d, 0x47, 0x37, 0xab, 0xfa, 0x1f, 0xa9, 0xb0,
-	0x97, 0x78, 0x3b, 0x16, 0x0a, 0x44, 0x8d, 0x18, 0x97, 0x44, 0x76, 0x9c, 0x03, 0x87, 0x1e, 0x39,
-	0xac, 0x7a, 0xc5, 0xad, 0x4e, 0xeb, 0x99, 0x92, 0x12, 0xee, 0x79, 0x8e, 0x08, 0x13, 0x87, 0x1c,
-	0x31, 0x49, 0xbd, 0x56, 0xa7, 0xc9, 0xb2, 0xb0, 0x74, 0x82, 0xa4, 0x1e, 0x71, 0x4c, 0xcb, 0x19,
-	0xa2, 0xd7, 0x20, 0xd7, 0xee, 0xf7, 0x77, 0x78, 0x09, 0xf9, 0xd2, 0xf1, 0x49, 0xe5, 0xfa, 0x39,
-	0x2a, 0xde, 0x47, 0x36, 0x19, 0x11, 0x2b, 0x81, 0x58, 0x7e, 0x96, 0x40, 0xc4, 0x72, 0x6b, 0x41,
-	0x84, 0xbb, 0x83, 0xda, 0xa0, 0xa5, 0x64, 0x13, 0x88, 0x30, 0x65, 0x7f, 0xe5, 0x71, 0xfb, 0xe7,
-	0x34, 0x28, 0x35, 0xc3, 0x20, 0x6e, 0xc0, 0xf0, 0xb2, 0xea, 0x1c, 0x40, 0xde, 0x65, 0xbf, 0x2c,
-	0x12, 0x66, 0x50, 0x8f, 0x12, 0x5f, 0x7c, 0x67, 0xf8, 0xaa, 0x98, 0xda, 0xa4, 0x66, 0x8e, 0x2c,
-	0xdf, 0xb7, 0xa8, 0x23, 0x60, 0x38, 0x92, 0x54, 0xfe, 0xaf, 0x14, 0x5c, 0x4f, 0xa0, 0x40, 0xf7,
-	0x20, 0xe3, 0x51, 0x3b, 0xdc, 0xc3, 0x5b, 0x17, 0xb5, 0x89, 0x19, 0x2b, 0xe6, 0x94, 0x68, 0x0d,
-	0x40, 0x1f, 0x07, 0x54, 0xe7, 0xf3, 0x8b, 0xe6, 0x1a, 0x8e, 0x41, 0xd0, 0x33, 0xc8, 0xf9, 0xc4,
-	0xf0, 0x48, 0x98, 0x67, 0x7f, 0xf8, 0xd3, 0x6a, 0x5f, 0xed, 0x73, 0x31, 0x58, 0x8a, 0x2b, 0x57,
-	0x21, 0x27, 0x20, 0xcc, 0xed, 0x4d, 0x3d, 0xd0, 0xe5, 0x23, 0x02, 0xff, 0xcd, 0xbc, 0x49, 0xb7,
-	0x87, 0xa1, 0x37, 0xe9, 0xf6, 0x50, 0xfd, 0xab, 0x34, 0x40, 0xeb, 0x79, 0x40, 0x3c, 0x47, 0xb7,
-	0x1b, 0x35, 0xd4, 0x8a, 0xdd, 0x0c, 0x62, 0xb5, 0x5f, 0x49, 0x7c, 0x37, 0x89, 0x38, 0xaa, 0x8d,
-	0x5a, 0xc2, 0xdd, 0x70, 0x13, 0xe6, 0xc7, 0x9e, 0x7c, 0xc4, 0x17, 0x39, 0xf2, 0x0e, 0xde, 0xc2,
-	0x0c, 0x86, 0x5a, 0xf1, 0x5e, 0xce, 0x85, 0x4f, 0xf5, 0xb1, 0x09, 0x12, 0x43, 0x17, 0x3b, 0xf9,
-	0x86, 0xae, 0x19, 0x44, 0xde, 0x2a, 0x25, 0x71, 0xf2, 0x1b, 0xb5, 0x06, 0xf1, 0x02, 0x9c, 0x33,
-	0x74, 0xf6, 0xff, 0x67, 0x8a, 0x6f, 0x6f, 0x01, 0x4c, 0x97, 0x86, 0xd6, 0x20, 0xdb, 0xd8, 0xe8,
-	0xf7, 0xb7, 0x94, 0x39, 0x11, 0xc0, 0xa7, 0x28, 0x0e, 0x56, 0xff, 0x3c, 0x0d, 0xf9, 0x46, 0x4d,
-	0x5e, 0xb9, 0x0d, 0x50, 0x78, 0x54, 0xe2, 0x4f, 0x2f, 0xe4, 0xb9, 0x6b, 0x79, 0x13, 0x19, 0x58,
-	0x2e, 0x29, 0x78, 0x97, 0x18, 0x0b, 0xd3, 0xba, 0xc5, 0x19, 0x10, 0x86, 0x12, 0x91, 0x46, 0xd0,
-	0x0c, 0x3d, 0x8c, 0xf1, 0x6b, 0x97, 0x1b, 0x4b, 0x94, 0x2e, 0xd3, 0xb1, 0x8f, 0x8b, 0xa1, 0x90,
-	0x86, 0xee, 0xa3, 0x77, 0x61, 0xd9, 0xb7, 0x86, 0x8e, 0xe5, 0x0c, 0xb5, 0xd0, 0x78, 0xfc, 0x1d,
-	0xa8, 0x7e, 0xed, 0xec, 0x74, 0x7d, 0xb1, 0x2f, 0x50, 0xd2, 0x86, 0x8b, 0x92, 0xb2, 0xc1, 0x4d,
-	0x89, 0xde, 0x81, 0xa5, 0x18, 0x2b, 0xb3, 0xa2, 0x30, 0x3b, 0xef, 0x18, 0x47, 0x9c, 0x4f, 0xc8,
-	0x04, 0x97, 0x22, 0xc6, 0x27, 0x84, 0xf7, 0x66, 0xf6, 0xa8, 0x67, 0x10, 0xcd, 0xe3, 0x67, 0x9a,
-	0xdf, 0xee, 0x19, 0x5c, 0xe4, 0x30, 0x71, 0xcc, 0xd5, 0xa7, 0x70, 0xbd, 0xeb, 0x19, 0xfb, 0xc4,
-	0x0f, 0x84, 0x29, 0xa4, 0x15, 0x3f, 0x84, 0x5b, 0x81, 0xee, 0x1f, 0x68, 0xfb, 0x96, 0x1f, 0x50,
-	0x6f, 0xa2, 0x79, 0x24, 0x20, 0x0e, 0xc3, 0x6b, 0xfc, 0x81, 0x5b, 0xb6, 0x13, 0x6f, 0x32, 0x9a,
-	0x4d, 0x41, 0x82, 0x43, 0x8a, 0x2d, 0x46, 0xa0, 0xb6, 0xa1, 0xc4, 0x4a, 0x18, 0xd9, 0x54, 0x63,
-	0xab, 0x07, 0x9b, 0x0e, 0xb5, 0xcf, 0x7d, 0x4d, 0x15, 0x6c, 0x3a, 0x14, 0x3f, 0xd5, 0x6f, 0x82,
-	0xd2, 0xb4, 0x7c, 0x57, 0x0f, 0x8c, 0xfd, 0xb0, 0x4f, 0x8a, 0x9a, 0xa0, 0xec, 0x13, 0xdd, 0x0b,
-	0x76, 0x89, 0x1e, 0x68, 0x2e, 0xf1, 0x2c, 0x6a, 0x5e, 0xbd, 0xcb, 0xcb, 0x11, 0x4b, 0x8f, 0x73,
-	0xa8, 0xff, 0x93, 0x02, 0xc0, 0xfa, 0x5e, 0x98, 0xad, 0x7d, 0x15, 0xae, 0xf9, 0x8e, 0xee, 0xfa,
-	0xfb, 0x34, 0xd0, 0x2c, 0x27, 0x20, 0xde, 0xa1, 0x6e, 0xcb, 0xe6, 0x8e, 0x12, 0x22, 0xda, 0x12,
-	0x8e, 0xde, 0x02, 0x74, 0x40, 0x88, 0xab, 0x51, 0xdb, 0xd4, 0x42, 0xa4, 0x78, 0xf8, 0xce, 0x60,
-	0x85, 0x61, 0xba, 0xb6, 0xd9, 0x0f, 0xe1, 0xa8, 0x0e, 0x6b, 0x6c, 0xf9, 0xc4, 0x09, 0x3c, 0x8b,
-	0xf8, 0xda, 0x1e, 0xf5, 0x34, 0xdf, 0xa6, 0x47, 0xda, 0x1e, 0xb5, 0x6d, 0x7a, 0x44, 0xbc, 0xb0,
-	0x6f, 0x56, 0xb6, 0xe9, 0xb0, 0x25, 0x88, 0x36, 0xa8, 0xd7, 0xb7, 0xe9, 0xd1, 0x46, 0x48, 0xc1,
-	0x52, 0xba, 0xe9, 0x9a, 0x03, 0xcb, 0x38, 0x08, 0x53, 0xba, 0x08, 0x3a, 0xb0, 0x8c, 0x03, 0xf4,
-	0x1a, 0x2c, 0x12, 0x9b, 0xf0, 0xf6, 0x89, 0xa0, 0xca, 0x72, 0xaa, 0x52, 0x08, 0x64, 0x44, 0xea,
-	0x47, 0xa0, 0xb4, 0x1c, 0xc3, 0x9b, 0xb8, 0xb1, 0x3d, 0x7f, 0x0b, 0x10, 0x0b, 0x92, 0x9a, 0x4d,
-	0x8d, 0x03, 0x6d, 0xa4, 0x3b, 0xfa, 0x90, 0xe9, 0x25, 0x5e, 0x1c, 0x15, 0x86, 0xd9, 0xa2, 0xc6,
-	0xc1, 0xb6, 0x84, 0xab, 0xef, 0x02, 0xf4, 0x5d, 0x8f, 0xe8, 0x66, 0x97, 0x65, 0x13, 0xcc, 0x74,
-	0x7c, 0xa4, 0x99, 0xf2, 0x3d, 0x97, 0x7a, 0xf2, 0xa8, 0x2b, 0x02, 0xd1, 0x8c, 0xe0, 0xea, 0x2f,
-	0xc2, 0xf5, 0x9e, 0xad, 0x1b, 0xfc, 0x0b, 0x8b, 0x5e, 0xf4, 0x84, 0x86, 0x1e, 0x41, 0x4e, 0x90,
-	0xca, 0x9d, 0x4c, 0x3c, 0x6e, 0xd3, 0x39, 0x37, 0xe7, 0xb0, 0xa4, 0xaf, 0x97, 0x00, 0xa6, 0x72,
-	0xd4, 0x7f, 0x4c, 0x41, 0x21, 0x92, 0x8f, 0x2a, 0xe2, 0x01, 0x2c, 0xf0, 0x74, 0xcb, 0x91, 0x15,
-	0x7f, 0x01, 0xc7, 0x41, 0xa8, 0x0d, 0x45, 0x37, 0xe2, 0xbe, 0x34, 0x9f, 0x4b, 0xd0, 0x1a, 0xc7,
-	0x79, 0xd1, 0x7b, 0x50, 0x08, 0x1f, 0xd0, 0xc3, 0x08, 0x7b, 0xf9, 0x7b, 0xfb, 0x94, 0x3c, 0x6c,
-	0xa4, 0x7a, 0xc4, 0xb5, 0x2d, 0x16, 0x73, 0x32, 0x51, 0x23, 0x15, 0x4b, 0x90, 0xfa, 0x75, 0x80,
-	0x6f, 0x50, 0xcb, 0x19, 0xd0, 0x03, 0xe2, 0xf0, 0x57, 0x61, 0x56, 0x52, 0x92, 0xd0, 0xd0, 0x72,
-	0xc4, 0x3b, 0x05, 0x62, 0x97, 0xa2, 0xc7, 0x51, 0x31, 0x54, 0xff, 0x32, 0x0d, 0x39, 0x4c, 0x69,
-	0xd0, 0xa8, 0xa1, 0x0a, 0xe4, 0x64, 0x28, 0xe1, 0x57, 0x54, 0xbd, 0x70, 0x76, 0xba, 0x9e, 0x15,
-	0x31, 0x24, 0x6b, 0xf0, 0xe0, 0x11, 0x0b, 0xf2, 0xe9, 0x8b, 0x82, 0x3c, 0xba, 0x07, 0x25, 0x49,
-	0xa4, 0xed, 0xeb, 0xfe, 0xbe, 0xa8, 0xef, 0xea, 0x4b, 0x67, 0xa7, 0xeb, 0x20, 0x28, 0x37, 0x75,
-	0x7f, 0x1f, 0x83, 0xa0, 0x66, 0xbf, 0x51, 0x0b, 0x8a, 0x1f, 0x53, 0xcb, 0xd1, 0x02, 0xbe, 0x08,
-	0xd9, 0x8b, 0x4c, 0xdc, 0xea, 0xe9, 0x52, 0xe5, 0x07, 0x14, 0xf0, 0xf1, 0x74, 0xf1, 0x2d, 0x58,
-	0xf4, 0x28, 0x0d, 0x44, 0x64, 0xb3, 0xa8, 0x23, 0xdb, 0x1c, 0x95, 0xc4, 0xee, 0x37, 0xa5, 0x01,
-	0x96, 0x74, 0xb8, 0xe4, 0xc5, 0x46, 0xe8, 0x1e, 0xac, 0xd8, 0xba, 0x1f, 0x68, 0x3c, 0x24, 0x9a,
-	0x53, 0x69, 0x39, 0x6e, 0x7c, 0xc4, 0x70, 0x1b, 0x1c, 0x15, 0x72, 0xa8, 0xff, 0x90, 0x82, 0x22,
-	0x5b, 0x8c, 0xb5, 0x67, 0x19, 0x2c, 0x0f, 0xfc, 0xe2, 0xe9, 0xc9, 0x4d, 0x98, 0x37, 0x7c, 0x4f,
-	0x1a, 0x95, 0xdf, 0xcf, 0x8d, 0x3e, 0xc6, 0x0c, 0x86, 0x3e, 0x82, 0x9c, 0x6c, 0xb7, 0x88, 0xcc,
-	0x44, 0xbd, 0x3a, 0x63, 0x95, 0xb6, 0x91, 0x7c, 0xdc, 0xdd, 0xa7, 0xda, 0x89, 0x7b, 0x02, 0xc7,
-	0x41, 0xe8, 0x06, 0xa4, 0x0d, 0x61, 0x2e, 0xf9, 0x85, 0x4e, 0xa3, 0x83, 0xd3, 0x86, 0xa3, 0xfe,
-	0x28, 0x05, 0x8b, 0xd3, 0x98, 0xc0, 0x3c, 0xe0, 0x16, 0x14, 0xfc, 0xf1, 0xae, 0x3f, 0xf1, 0x03,
-	0x32, 0x0a, 0x5f, 0xbc, 0x23, 0x00, 0x6a, 0x43, 0x41, 0xb7, 0x87, 0xd4, 0xb3, 0x82, 0xfd, 0x91,
-	0x2c, 0x64, 0x93, 0xb3, 0x89, 0xb8, 0xcc, 0x6a, 0x2d, 0x64, 0xc1, 0x53, 0xee, 0x30, 0x35, 0x10,
-	0x9f, 0x45, 0xf0, 0xd4, 0xe0, 0x55, 0x28, 0xd9, 0xfa, 0x88, 0xf7, 0x9f, 0x02, 0x6b, 0x44, 0xc2,
-	0xc3, 0x20, 0x61, 0x03, 0x6b, 0x44, 0x54, 0x15, 0x0a, 0x91, 0x30, 0xb4, 0x0c, 0xc5, 0x5a, 0xab,
-	0xaf, 0xdd, 0x7f, 0xf0, 0x48, 0x7b, 0xdc, 0xd8, 0x56, 0xe6, 0x64, 0xfa, 0xfa, 0x67, 0x29, 0x58,
-	0x94, 0x11, 0x4b, 0x96, 0x04, 0xaf, 0xc1, 0x82, 0xa7, 0xef, 0x05, 0x61, 0xd1, 0x92, 0x11, 0x5e,
-	0xcd, 0x2e, 0x01, 0x56, 0xb4, 0x30, 0x54, 0x72, 0xd1, 0x12, 0xfb, 0x06, 0x63, 0xfe, 0xd2, 0x6f,
-	0x30, 0x32, 0xff, 0x2f, 0xdf, 0x60, 0xa8, 0xbf, 0x01, 0xb0, 0x61, 0xd9, 0x64, 0x20, 0x5a, 0x55,
-	0x49, 0x25, 0x28, 0x4b, 0xf3, 0x64, 0x2b, 0x34, 0x4c, 0xf3, 0xda, 0x4d, 0xcc, 0x60, 0x0c, 0x35,
-	0xb4, 0x4c, 0x79, 0x18, 0x39, 0xea, 0x31, 0x43, 0x0d, 0x2d, 0x33, 0x7a, 0xf6, 0xcb, 0x5c, 0xf1,
-	0xec, 0xa7, 0x2e, 0xc3, 0x22, 0x16, 0x3d, 0x36, 0xa1, 0x83, 0x7a, 0x92, 0x82, 0x65, 0x99, 0xef,
-	0x46, 0x21, 0xfb, 0x2b, 0x50, 0x10, 0xa9, 0xef, 0xb4, 0x08, 0xe4, 0x1f, 0x22, 0x08, 0xba, 0x76,
-	0x13, 0xe7, 0x05, 0xba, 0x6d, 0xa2, 0x75, 0x28, 0x4a, 0xd2, 0xd8, 0xe7, 0x5d, 0x20, 0x40, 0x1d,
-	0xb6, 0x9e, 0xb7, 0x21, 0xb3, 0x67, 0xd9, 0x44, 0x7a, 0x7e, 0x62, 0x44, 0x98, 0x5a, 0x64, 0x73,
-	0x0e, 0x73, 0xea, 0x7a, 0x3e, 0x6c, 0xee, 0xa9, 0xff, 0x92, 0xe2, 0x2d, 0x66, 0x56, 0xaa, 0xc6,
-	0xf5, 0x13, 0x55, 0xeb, 0x8c, 0x7e, 0x82, 0x8e, 0xe9, 0x27, 0xd0, 0x42, 0x3f, 0x49, 0x1a, 0xd7,
-	0x4f, 0x80, 0x7e, 0x7a, 0xfd, 0xd0, 0x07, 0xb0, 0x20, 0x5b, 0x95, 0x32, 0xd4, 0xbd, 0x9a, 0xe8,
-	0x19, 0x71, 0x4b, 0x6f, 0xce, 0xe1, 0x90, 0x27, 0xb6, 0xbc, 0x2d, 0xb8, 0x51, 0xb7, 0x75, 0xe3,
-	0xc0, 0xb6, 0xfc, 0x80, 0x98, 0xf1, 0x08, 0xf4, 0x00, 0x72, 0xe7, 0xf2, 0xdc, 0xcb, 0x9a, 0xa8,
-	0x92, 0x52, 0xfd, 0xf7, 0x14, 0x94, 0x36, 0x89, 0x6e, 0x07, 0xfb, 0xd3, 0x4e, 0x55, 0x40, 0xfc,
-	0x40, 0xde, 0x8f, 0xfc, 0x37, 0xfa, 0x1a, 0xe4, 0xa3, 0x34, 0xe8, 0xca, 0xe7, 0xc0, 0x88, 0x14,
-	0x3d, 0x84, 0x05, 0xa6, 0x3b, 0x1d, 0x87, 0xf5, 0xd5, 0x65, 0x2f, 0x4d, 0x92, 0x92, 0x5d, 0x5a,
-	0x1e, 0xe1, 0x79, 0x0f, 0xb7, 0x53, 0x16, 0x87, 0x43, 0xf4, 0xf3, 0x50, 0xe2, 0x0f, 0x25, 0x61,
-	0x9a, 0x97, 0xbd, 0x4a, 0x66, 0x51, 0xbc, 0x75, 0x8a, 0x14, 0xef, 0x8f, 0xd3, 0xb0, 0xb2, 0xad,
-	0x4f, 0x76, 0x89, 0x0c, 0x43, 0xc4, 0xc4, 0xc4, 0xa0, 0x9e, 0x89, 0x7a, 0xf1, 0xf0, 0x75, 0xc9,
-	0xd3, 0x69, 0x12, 0x73, 0x72, 0x14, 0x0b, 0x6b, 0xbe, 0x74, 0xac, 0xe6, 0x5b, 0x81, 0xac, 0x43,
-	0x1d, 0x83, 0xc8, 0xd8, 0x26, 0x06, 0xea, 0x77, 0x52, 0xf1, 0xd8, 0x55, 0x8e, 0x9e, 0x35, 0x79,
-	0xd3, 0xab, 0x43, 0x83, 0x68, 0x3a, 0xf4, 0x11, 0x94, 0xfb, 0xad, 0x06, 0x6e, 0x0d, 0xea, 0xdd,
-	0x6f, 0x6a, 0xfd, 0xda, 0x56, 0xbf, 0xf6, 0xe0, 0x9e, 0xd6, 0xeb, 0x6e, 0x7d, 0xeb, 0xfe, 0xc3,
-	0x7b, 0x5f, 0x53, 0x52, 0xe5, 0xca, 0xf1, 0x49, 0xe5, 0x56, 0xa7, 0xd6, 0xd8, 0x12, 0x27, 0x6e,
-	0x97, 0x3e, 0xef, 0xeb, 0xb6, 0xaf, 0x3f, 0xb8, 0xd7, 0xa3, 0xf6, 0x84, 0xd1, 0xa0, 0xaf, 0x02,
-	0xda, 0x68, 0xe1, 0x4e, 0x6b, 0xa0, 0x85, 0x01, 0xb2, 0x51, 0x6f, 0x28, 0x69, 0x51, 0x49, 0x6d,
-	0x10, 0xcf, 0x21, 0x41, 0xad, 0xd5, 0xbf, 0xff, 0xe0, 0x51, 0xa3, 0xde, 0x60, 0x67, 0xbc, 0x14,
-	0xbf, 0x2d, 0xe3, 0x49, 0x40, 0xea, 0xc2, 0x24, 0x60, 0x9a, 0x4b, 0xa4, 0x2f, 0xc8, 0x25, 0x36,
-	0x60, 0xc5, 0xf0, 0xa8, 0xef, 0x6b, 0xac, 0x3c, 0x21, 0xe6, 0x4c, 0x01, 0xf4, 0xa5, 0xb3, 0xd3,
-	0xf5, 0x6b, 0x0d, 0x86, 0xef, 0x73, 0xb4, 0x14, 0x7f, 0xcd, 0x88, 0x81, 0xf8, 0x4c, 0xea, 0xf7,
-	0xe7, 0x59, 0xa6, 0x67, 0x1d, 0x5a, 0x36, 0x19, 0x12, 0x1f, 0x3d, 0x85, 0x65, 0xc3, 0x23, 0x26,
-	0xab, 0x3b, 0x74, 0x3b, 0xfe, 0x65, 0xf4, 0xcf, 0x25, 0x26, 0x5d, 0x11, 0x63, 0xb5, 0x11, 0x71,
-	0xf5, 0x5d, 0x62, 0xe0, 0x25, 0xe3, 0xdc, 0x18, 0x7d, 0x0c, 0xcb, 0x3e, 0xb1, 0x2d, 0x67, 0xfc,
-	0x5c, 0x33, 0xa8, 0x13, 0x90, 0xe7, 0xe1, 0x73, 0xde, 0x55, 0x72, 0xfb, 0xad, 0x2d, 0xc6, 0xd5,
-	0x10, 0x4c, 0x75, 0x74, 0x76, 0xba, 0xbe, 0x74, 0x1e, 0x86, 0x97, 0xa4, 0x64, 0x39, 0x2e, 0xef,
-	0xc3, 0xd2, 0x79, 0x6d, 0xd0, 0x8a, 0x0c, 0x34, 0x3c, 0x5e, 0x45, 0x81, 0xe4, 0x16, 0xe4, 0x3d,
-	0x32, 0xb4, 0xfc, 0xc0, 0x13, 0x66, 0x66, 0x98, 0x08, 0x82, 0x56, 0x21, 0x17, 0xfb, 0xe2, 0x84,
-	0xe1, 0xe4, 0x98, 0x45, 0x10, 0xf1, 0x31, 0x59, 0xf9, 0xd7, 0x60, 0x46, 0x17, 0x76, 0xe8, 0x4c,
-	0xcb, 0xd7, 0x77, 0xe5, 0x64, 0x79, 0x1c, 0x0e, 0x99, 0x2f, 0x8f, 0xfd, 0x28, 0x81, 0xe4, 0xbf,
-	0x19, 0x8c, 0x67, 0x3a, 0xf2, 0xd3, 0x3a, 0x9e, 0xcb, 0x84, 0x5f, 0xf0, 0x66, 0x62, 0x5f, 0xf0,
-	0xae, 0x40, 0xd6, 0x26, 0x87, 0xc4, 0x16, 0x39, 0x06, 0x16, 0x83, 0x3b, 0xf7, 0xa0, 0x14, 0x7e,
-	0x2a, 0xca, 0xbf, 0x19, 0xc9, 0x43, 0x66, 0x50, 0xeb, 0x3f, 0x51, 0xe6, 0x10, 0x40, 0x4e, 0xf8,
-	0xb8, 0x78, 0x84, 0x6c, 0x74, 0x3b, 0x1b, 0xed, 0xc7, 0x4a, 0xfa, 0xce, 0xef, 0x65, 0xa0, 0x10,
-	0x3d, 0x83, 0xb1, 0x3b, 0xad, 0xd3, 0x7a, 0x16, 0x1e, 0x92, 0x08, 0xde, 0x21, 0x47, 0xe8, 0xd5,
-	0x69, 0x03, 0xed, 0x23, 0xf1, 0xee, 0x1f, 0xa1, 0xc3, 0xe6, 0xd9, 0xeb, 0x90, 0xaf, 0xf5, 0xfb,
-	0xed, 0xc7, 0x9d, 0x56, 0x53, 0xf9, 0x34, 0x55, 0xfe, 0xd2, 0xf1, 0x49, 0xe5, 0x5a, 0x44, 0x54,
-	0xf3, 0x85, 0x5b, 0x72, 0xaa, 0x46, 0xa3, 0xd5, 0x1b, 0xb4, 0x9a, 0xca, 0x27, 0xe9, 0x59, 0x2a,
-	0xde, 0x10, 0xe2, 0xdf, 0x33, 0x15, 0x7a, 0xb8, 0xd5, 0xab, 0x61, 0x36, 0xe1, 0xa7, 0x69, 0xd1,
-	0xd7, 0x9b, 0xce, 0xe8, 0x11, 0x57, 0xf7, 0xd8, 0x9c, 0x6b, 0xe1, 0x67, 0x85, 0x9f, 0xcc, 0x8b,
-	0x0f, 0x5b, 0xa6, 0x6f, 0x7a, 0x44, 0x37, 0x27, 0x6c, 0x36, 0xfe, 0x98, 0xca, 0xc5, 0xcc, 0xcf,
-	0xcc, 0xd6, 0x67, 0x31, 0x8c, 0x49, 0x51, 0x61, 0x01, 0xef, 0x74, 0x3a, 0x8c, 0xe8, 0x93, 0xcc,
-	0xcc, 0xea, 0xf0, 0xd8, 0x61, 0xc5, 0x3e, 0xba, 0x0d, 0xf9, 0xf0, 0xad, 0x55, 0xf9, 0x34, 0x33,
-	0xa3, 0x50, 0x23, 0x7c, 0x28, 0xe6, 0x13, 0x6e, 0xee, 0x0c, 0xf8, 0x57, 0x8f, 0x9f, 0x64, 0x67,
-	0x27, 0xdc, 0x1f, 0x07, 0x26, 0x3d, 0x72, 0xd8, 0x69, 0x96, 0x2d, 0xc4, 0x4f, 0xb3, 0x22, 0x4a,
-	0x44, 0x34, 0xb2, 0x7f, 0xf8, 0x3a, 0xe4, 0x71, 0xeb, 0x1b, 0xe2, 0x03, 0xc9, 0x4f, 0x72, 0x33,
-	0x72, 0x30, 0xf9, 0x98, 0x18, 0x6c, 0xb6, 0x0a, 0xe4, 0x70, 0x6b, 0xbb, 0xfb, 0xb4, 0xa5, 0xfc,
-	0x41, 0x6e, 0x46, 0x0e, 0x26, 0x23, 0xca, 0x3f, 0xf8, 0xca, 0x77, 0x71, 0x6f, 0xb3, 0xc6, 0x37,
-	0x65, 0x56, 0x4e, 0xd7, 0x73, 0xf7, 0x75, 0x87, 0x98, 0xd3, 0x8f, 0x7b, 0x22, 0xd4, 0x9d, 0x5f,
-	0x82, 0x7c, 0x98, 0x53, 0xa3, 0x35, 0xc8, 0x3d, 0xeb, 0xe2, 0x27, 0x2d, 0xac, 0xcc, 0x09, 0x2b,
-	0x87, 0x98, 0x67, 0xa2, 0x1a, 0xaa, 0xc0, 0xc2, 0x76, 0xad, 0x53, 0x7b, 0xdc, 0xc2, 0x61, 0xff,
-	0x3f, 0x24, 0x90, 0x89, 0x61, 0x59, 0x91, 0x13, 0x44, 0x32, 0xeb, 0xaf, 0xff, 0xe0, 0xb3, 0xb5,
-	0xb9, 0x1f, 0x7f, 0xb6, 0x36, 0xf7, 0xc9, 0xd9, 0x5a, 0xea, 0x07, 0x67, 0x6b, 0xa9, 0x1f, 0x9e,
-	0xad, 0xa5, 0xfe, 0xed, 0x6c, 0x2d, 0xf5, 0x3b, 0x3f, 0x59, 0x9b, 0xfb, 0xe1, 0x4f, 0xd6, 0xe6,
-	0x7e, 0xfc, 0x93, 0xb5, 0xb9, 0xdd, 0x1c, 0xbf, 0x7a, 0x1e, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff,
-	0xff, 0x4e, 0x60, 0x1a, 0x9d, 0x2d, 0x34, 0x00, 0x00,
+	// 5345 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x3a, 0x4b, 0x6c, 0x24, 0x49,
+	0x56, 0xae, 0x72, 0x55, 0xb9, 0xea, 0x55, 0xd9, 0xce, 0x8e, 0xf6, 0xf6, 0xb8, 0x6b, 0x7a, 0x6c,
+	0x4f, 0xce, 0xf4, 0xce, 0xec, 0xec, 0xe0, 0xfe, 0xcd, 0x8e, 0x7a, 0x66, 0x98, 0x9d, 0xa9, 0x4f,
+	0xba, 0x5d, 0xdb, 0x76, 0x55, 0x29, 0xaa, 0xdc, 0xbd, 0x8b, 0x04, 0x49, 0x3a, 0x33, 0x5c, 0xce,
+	0x76, 0x56, 0x46, 0x92, 0x99, 0x65, 0x77, 0xb1, 0x20, 0xe6, 0x04, 0xc8, 0x27, 0xb8, 0x2c, 0xbb,
+	0x42, 0x96, 0x90, 0xe0, 0xc6, 0x81, 0x03, 0x07, 0x16, 0x4e, 0x83, 0x84, 0xd0, 0x8a, 0x0b, 0xbb,
+	0x20, 0xc1, 0x0a, 0x90, 0x61, 0xbc, 0x12, 0x37, 0x04, 0x17, 0xc4, 0x85, 0x03, 0x8a, 0x4f, 0x66,
+	0xa5, 0xab, 0xd3, 0xf6, 0xcc, 0x2e, 0x17, 0xbb, 0xe2, 0xfd, 0xf2, 0xc5, 0x8b, 0x17, 0x2f, 0xde,
+	0x7b, 0x11, 0xf0, 0xd6, 0xc0, 0x0e, 0xf7, 0x47, 0xbb, 0xeb, 0x26, 0x1d, 0xde, 0xb1, 0xa8, 0x79,
+	0x40, 0xfc, 0x3b, 0xc1, 0x91, 0xe1, 0x0f, 0x0f, 0xec, 0xf0, 0x8e, 0xe1, 0xd9, 0x77, 0xc2, 0xb1,
+	0x47, 0x82, 0x75, 0xcf, 0xa7, 0x21, 0x45, 0x48, 0x10, 0xac, 0x47, 0x04, 0xeb, 0x87, 0xf7, 0xaa,
+	0xab, 0x03, 0x4a, 0x07, 0x0e, 0xb9, 0xc3, 0x29, 0x76, 0x47, 0x7b, 0x77, 0x42, 0x7b, 0x48, 0x82,
+	0xd0, 0x18, 0x7a, 0x82, 0xa9, 0xba, 0x32, 0x4d, 0x60, 0x8d, 0x7c, 0x23, 0xb4, 0xa9, 0x7b, 0x11,
+	0xfe, 0xc8, 0x37, 0x3c, 0x8f, 0xf8, 0xf2, 0xa3, 0xd5, 0xa5, 0x01, 0x1d, 0x50, 0xfe, 0xf3, 0x0e,
+	0xfb, 0x25, 0xa0, 0xea, 0x2a, 0xcc, 0x3d, 0x21, 0x7e, 0x60, 0x53, 0x17, 0x2d, 0x41, 0xde, 0x76,
+	0x2d, 0xf2, 0x7c, 0x39, 0xb3, 0x96, 0x79, 0x33, 0x87, 0xc5, 0x40, 0xbd, 0x0b, 0xd0, 0x62, 0x3f,
+	0x34, 0x37, 0xf4, 0xc7, 0x48, 0x81, 0xd9, 0x03, 0x32, 0xe6, 0x14, 0x25, 0xcc, 0x7e, 0x32, 0xc8,
+	0xa1, 0xe1, 0x2c, 0x67, 0x05, 0xe4, 0xd0, 0x70, 0xd4, 0xcf, 0x32, 0x50, 0xae, 0xb9, 0x2e, 0x0d,
+	0xb9, 0x76, 0x01, 0x42, 0x90, 0x73, 0x8d, 0x21, 0x91, 0x4c, 0xfc, 0x37, 0x6a, 0x40, 0xc1, 0x31,
+	0x76, 0x89, 0x13, 0x2c, 0x67, 0xd7, 0x66, 0xdf, 0x2c, 0xdf, 0xff, 0xea, 0xfa, 0x8b, 0x26, 0x59,
+	0x4f, 0x08, 0x59, 0xdf, 0xe2, 0xd4, 0x5c, 0x09, 0x2c, 0x59, 0xd1, 0xd7, 0x61, 0xce, 0x76, 0x2d,
+	0xdb, 0x24, 0xc1, 0x72, 0x8e, 0x4b, 0x59, 0x49, 0x93, 0x32, 0xd1, 0xbe, 0x9e, 0xfb, 0xc1, 0xe9,
+	0xea, 0x0c, 0x8e, 0x98, 0xaa, 0xef, 0x41, 0x39, 0x21, 0x36, 0x65, 0x6e, 0x4b, 0x90, 0x3f, 0x34,
+	0x9c, 0x11, 0x91, 0xb3, 0x13, 0x83, 0xf7, 0xb3, 0x0f, 0x33, 0xea, 0xc7, 0xb0, 0xd4, 0x36, 0x86,
+	0xc4, 0x7a, 0x44, 0x5c, 0xe2, 0xdb, 0x26, 0x26, 0x01, 0x1d, 0xf9, 0x26, 0x61, 0x73, 0x3d, 0xb0,
+	0x5d, 0x2b, 0x9a, 0x2b, 0xfb, 0x9d, 0x2e, 0x45, 0x6d, 0xc0, 0x4b, 0x4d, 0x3b, 0x30, 0x7d, 0x12,
+	0x92, 0x2f, 0x2c, 0x64, 0x36, 0x12, 0x72, 0x9a, 0x81, 0xc5, 0x69, 0xee, 0x5f, 0x80, 0xeb, 0xcc,
+	0xc4, 0x96, 0xee, 0x4b, 0x88, 0x1e, 0x78, 0xc4, 0xe4, 0xc2, 0xca, 0xf7, 0xdf, 0x4c, 0xb3, 0x50,
+	0xda, 0x4c, 0x36, 0x67, 0xf0, 0x35, 0x2e, 0x26, 0x02, 0xf4, 0x3c, 0x62, 0x22, 0x13, 0x6e, 0x58,
+	0x52, 0xe9, 0x29, 0xf1, 0x59, 0x2e, 0x3e, 0x75, 0x19, 0x2f, 0x98, 0xe6, 0xe6, 0x0c, 0x5e, 0x8a,
+	0x84, 0x25, 0x3f, 0x52, 0x07, 0x28, 0x46, 0xb2, 0xd5, 0xef, 0x66, 0xa0, 0x14, 0x21, 0x03, 0xf4,
+	0x15, 0x28, 0xb9, 0x86, 0x4b, 0x75, 0xd3, 0x1b, 0x05, 0x7c, 0x42, 0xb3, 0xf5, 0xca, 0xd9, 0xe9,
+	0x6a, 0xb1, 0x6d, 0xb8, 0xb4, 0xd1, 0xdd, 0x09, 0x70, 0x91, 0xa1, 0x1b, 0xde, 0x28, 0x40, 0xaf,
+	0x42, 0x65, 0x48, 0x86, 0xd4, 0x1f, 0xeb, 0xbb, 0xe3, 0x90, 0x04, 0xd2, 0x6c, 0x65, 0x01, 0xab,
+	0x33, 0x10, 0xfa, 0x10, 0xe6, 0x06, 0x42, 0xa5, 0xe5, 0x59, 0xee, 0x3e, 0xaf, 0xa5, 0x69, 0x3f,
+	0xa5, 0x35, 0x8e, 0x78, 0xd4, 0xef, 0x64, 0x61, 0x29, 0x86, 0x92, 0x5f, 0x19, 0xd9, 0x3e, 0x19,
+	0x12, 0x37, 0x0c, 0xd0, 0xd7, 0xa0, 0xe0, 0xd8, 0x43, 0x3b, 0x0c, 0xa4, 0xcd, 0x5f, 0x49, 0x13,
+	0x1b, 0x4f, 0x0a, 0x4b, 0x62, 0x54, 0x83, 0x8a, 0x4f, 0x02, 0xe2, 0x1f, 0x0a, 0x8f, 0x97, 0x16,
+	0xbd, 0x82, 0xf9, 0x1c, 0x0b, 0x7a, 0x1f, 0x20, 0x38, 0x32, 0x3c, 0x39, 0xe5, 0x59, 0x2e, 0xe0,
+	0xe5, 0x75, 0x11, 0x17, 0xd6, 0xa3, 0xb8, 0xb0, 0xde, 0x72, 0xc3, 0x77, 0xdf, 0x79, 0xc2, 0xfc,
+	0x07, 0x97, 0x18, 0xb9, 0xb0, 0xc6, 0x26, 0x5c, 0x93, 0x06, 0x63, 0x30, 0xcf, 0x76, 0x49, 0xc0,
+	0xb6, 0xd5, 0x95, 0x22, 0x14, 0xc1, 0xd5, 0x8b, 0x99, 0xd4, 0x0d, 0x28, 0x76, 0x1d, 0x23, 0xdc,
+	0xa3, 0xfe, 0x10, 0xa9, 0x50, 0x31, 0x7c, 0x73, 0xdf, 0x0e, 0x89, 0x19, 0x8e, 0xfc, 0x28, 0x06,
+	0x9c, 0x83, 0xa1, 0x1b, 0x90, 0xa5, 0x62, 0xba, 0xa5, 0x7a, 0xe1, 0xec, 0x74, 0x35, 0xdb, 0xe9,
+	0xe1, 0x2c, 0x0d, 0xd4, 0x0f, 0xe0, 0x5a, 0xd7, 0x19, 0x0d, 0x6c, 0xb7, 0x49, 0x02, 0xd3, 0xb7,
+	0x3d, 0x36, 0x47, 0xb6, 0x37, 0x58, 0x24, 0x8d, 0xf6, 0x06, 0xfb, 0x1d, 0x07, 0x98, 0xec, 0x24,
+	0xc0, 0xa8, 0xbf, 0x95, 0x85, 0x6b, 0x9a, 0x3b, 0xb0, 0x5d, 0x92, 0xe4, 0xbe, 0x0d, 0x0b, 0x84,
+	0x03, 0xf5, 0x43, 0x11, 0xf4, 0xa4, 0x9c, 0x79, 0x01, 0x8d, 0x22, 0x61, 0x6b, 0x2a, 0x3a, 0xdd,
+	0x4b, 0x5b, 0x84, 0x17, 0xa4, 0xa7, 0xc6, 0x28, 0x0d, 0xe6, 0x3c, 0x3e, 0x89, 0x40, 0x3a, 0xd9,
+	0xed, 0x34, 0x59, 0x2f, 0xcc, 0x33, 0x0a, 0x55, 0x92, 0xf7, 0x67, 0x09, 0x55, 0x7f, 0x93, 0x85,
+	0xc5, 0x36, 0xb5, 0xce, 0xd9, 0xa1, 0x0a, 0xc5, 0x7d, 0x1a, 0x84, 0x89, 0xb0, 0x1c, 0x8f, 0xd1,
+	0x43, 0x28, 0x7a, 0x72, 0xf9, 0xa4, 0x0f, 0xde, 0x4a, 0x57, 0x59, 0xd0, 0xe0, 0x98, 0x1a, 0x7d,
+	0x00, 0xa5, 0x68, 0xe3, 0x46, 0xde, 0x77, 0x85, 0xfb, 0x4e, 0xe8, 0xd1, 0x87, 0x50, 0x10, 0x8b,
+	0x20, 0x9d, 0xee, 0xf6, 0xe7, 0xb2, 0x39, 0x96, 0x4c, 0xe8, 0x11, 0x14, 0x43, 0x27, 0xd0, 0x6d,
+	0x77, 0x8f, 0x2e, 0xe7, 0xb9, 0x80, 0xd5, 0xd4, 0x50, 0x47, 0x2d, 0xd2, 0xdf, 0xea, 0xb5, 0xdc,
+	0x3d, 0x5a, 0x2f, 0x9f, 0x9d, 0xae, 0xce, 0xc9, 0x01, 0x9e, 0x0b, 0x9d, 0x80, 0xfd, 0x40, 0xb7,
+	0x20, 0xb7, 0x67, 0x7b, 0xc1, 0x72, 0x61, 0x2d, 0xf3, 0x66, 0xb1, 0x5e, 0x3c, 0x3b, 0x5d, 0xcd,
+	0x6d, 0xb4, 0xba, 0x3d, 0xcc, 0xa1, 0xea, 0xef, 0x66, 0xa0, 0x9c, 0x90, 0x81, 0x5e, 0x01, 0x08,
+	0xfd, 0x51, 0x10, 0xea, 0x3e, 0xa5, 0x21, 0x37, 0x65, 0x05, 0x97, 0x38, 0x04, 0x53, 0x1a, 0xa2,
+	0x75, 0xb8, 0x6e, 0x12, 0x3f, 0xd4, 0xed, 0x20, 0x18, 0x11, 0x5f, 0x0f, 0x46, 0xbb, 0xcf, 0x88,
+	0x19, 0x72, 0xb3, 0x56, 0xf0, 0x35, 0x86, 0x6a, 0x71, 0x4c, 0x4f, 0x20, 0xd0, 0x03, 0xb8, 0x91,
+	0xa4, 0xf7, 0x46, 0xbb, 0x8e, 0x6d, 0xea, 0x6c, 0xa9, 0x67, 0x39, 0xcb, 0xf5, 0x09, 0x4b, 0x97,
+	0xe3, 0x1e, 0x93, 0xb1, 0xfa, 0xe3, 0x0c, 0x28, 0xd8, 0xd8, 0x0b, 0xb7, 0xc9, 0x70, 0x97, 0xf8,
+	0xbd, 0xd0, 0x08, 0x47, 0x01, 0xba, 0x01, 0x05, 0x87, 0x18, 0x16, 0xf1, 0xb9, 0x52, 0x45, 0x2c,
+	0x47, 0x68, 0x87, 0x45, 0x19, 0xc3, 0xdc, 0x37, 0x76, 0x6d, 0xc7, 0x0e, 0xc7, 0x5c, 0x95, 0x85,
+	0x74, 0x07, 0x9f, 0x96, 0xb9, 0x8e, 0x13, 0x8c, 0xf8, 0x9c, 0x18, 0xb4, 0x0c, 0x73, 0x43, 0x12,
+	0x04, 0xc6, 0x80, 0x70, 0x4d, 0x4b, 0x38, 0x1a, 0xaa, 0x1f, 0x40, 0x25, 0xc9, 0x87, 0xca, 0x30,
+	0xb7, 0xd3, 0x7e, 0xdc, 0xee, 0x3c, 0x6d, 0x2b, 0x33, 0x68, 0x11, 0xca, 0x3b, 0x6d, 0xac, 0xd5,
+	0x1a, 0x9b, 0xb5, 0xfa, 0x96, 0xa6, 0x64, 0xd0, 0x3c, 0x94, 0x26, 0xc3, 0xac, 0xfa, 0xa7, 0x19,
+	0x00, 0x66, 0x6e, 0x39, 0xa9, 0xf7, 0x21, 0x1f, 0x84, 0x46, 0x28, 0x7c, 0x76, 0xe1, 0xfe, 0xeb,
+	0x17, 0xad, 0xb0, 0xd4, 0x97, 0xfd, 0x23, 0x58, 0xb0, 0x24, 0x35, 0xcc, 0x9e, 0xd3, 0x90, 0x85,
+	0x0f, 0xc3, 0xb2, 0x7c, 0xa9, 0x38, 0xff, 0xad, 0x7e, 0x00, 0x79, 0xce, 0x7d, 0x5e, 0xdd, 0x22,
+	0xe4, 0x9a, 0xec, 0x57, 0x06, 0x95, 0x20, 0x8f, 0xb5, 0x5a, 0xf3, 0x5b, 0x4a, 0x16, 0x29, 0x50,
+	0x69, 0xb6, 0x7a, 0x8d, 0x4e, 0xbb, 0xad, 0x35, 0xfa, 0x5a, 0x53, 0x99, 0x55, 0x6f, 0x43, 0xbe,
+	0x35, 0x64, 0x92, 0x6f, 0xb1, 0x0d, 0xb1, 0x47, 0x7c, 0xe2, 0x9a, 0xd1, 0x3e, 0x9b, 0x00, 0xd4,
+	0xcf, 0x2a, 0x90, 0xdf, 0xa6, 0x23, 0x37, 0x44, 0xf7, 0x13, 0x41, 0x6d, 0x21, 0x3d, 0x8b, 0xe1,
+	0x84, 0xeb, 0xfd, 0xb1, 0x47, 0x64, 0xd0, 0xbb, 0x01, 0x05, 0xb1, 0x75, 0xe4, 0x74, 0xe4, 0x88,
+	0xc1, 0x43, 0xc3, 0x1f, 0x90, 0x50, 0xce, 0x47, 0x8e, 0xd0, 0x9b, 0xec, 0x54, 0x35, 0x2c, 0xea,
+	0x3a, 0x63, 0xbe, 0xc3, 0x8a, 0xe2, 0xe8, 0xc4, 0xc4, 0xb0, 0x3a, 0xae, 0x33, 0xc6, 0x31, 0x16,
+	0x3d, 0x82, 0xb2, 0x49, 0xdd, 0xc0, 0x0e, 0x42, 0xe2, 0x9a, 0xe3, 0xe5, 0x22, 0x57, 0xea, 0xf6,
+	0xc5, 0x4a, 0x35, 0x26, 0xc4, 0x38, 0xc9, 0x89, 0x36, 0xa1, 0xb2, 0x6b, 0xbb, 0x96, 0x4e, 0x3d,
+	0x71, 0xa2, 0xe5, 0x2f, 0xde, 0xd8, 0x42, 0x52, 0xdd, 0x76, 0xad, 0x8e, 0x20, 0xc6, 0xe5, 0xdd,
+	0xc9, 0x00, 0xb5, 0x61, 0xe1, 0x90, 0x3a, 0xa3, 0x21, 0x89, 0x65, 0x15, 0xb8, 0xac, 0x37, 0x2e,
+	0x96, 0xf5, 0x84, 0xd3, 0x47, 0xd2, 0xe6, 0x0f, 0x93, 0x43, 0xf4, 0x18, 0xe6, 0xc3, 0xa1, 0xb7,
+	0x17, 0xc4, 0xe2, 0xe6, 0xb8, 0xb8, 0x2f, 0x5f, 0x62, 0x79, 0x46, 0x1e, 0x49, 0xab, 0x84, 0x89,
+	0x51, 0xf5, 0xfb, 0xb3, 0x50, 0x4e, 0x68, 0x8e, 0x7a, 0x50, 0xf6, 0x7c, 0xea, 0x19, 0x03, 0x7e,
+	0x2a, 0xcb, 0x45, 0xbd, 0xf7, 0xb9, 0x66, 0xbd, 0xde, 0x9d, 0x30, 0xe2, 0xa4, 0x14, 0xf4, 0x0e,
+	0x54, 0x5c, 0xea, 0xfa, 0xc4, 0x1c, 0xf9, 0x81, 0x7d, 0x28, 0x16, 0xbd, 0x58, 0x57, 0xce, 0x4e,
+	0x57, 0x2b, 0x6d, 0xea, 0xe2, 0x08, 0x8e, 0xcf, 0x51, 0xa9, 0x27, 0x59, 0x28, 0x27, 0x44, 0xa2,
+	0xb7, 0xa0, 0x88, 0xbb, 0xb8, 0xf5, 0xa4, 0xd6, 0xd7, 0x94, 0x99, 0xea, 0xad, 0xe3, 0x93, 0xb5,
+	0x65, 0xae, 0x43, 0xf2, 0xb3, 0x5d, 0xdf, 0x3e, 0x64, 0x9e, 0xff, 0x26, 0xcc, 0x45, 0xa4, 0x99,
+	0xea, 0xcb, 0xc7, 0x27, 0x6b, 0x2f, 0x4d, 0x93, 0x26, 0x28, 0x71, 0x6f, 0xb3, 0x86, 0xb5, 0xa6,
+	0x92, 0x4d, 0xa7, 0xc4, 0xbd, 0x7d, 0xc3, 0x27, 0x16, 0xfa, 0x32, 0x14, 0x24, 0xe1, 0x6c, 0xb5,
+	0x7a, 0x7c, 0xb2, 0x76, 0x63, 0x9a, 0x70, 0x42, 0x87, 0x7b, 0x5b, 0xb5, 0x27, 0x9a, 0x92, 0x4b,
+	0xa7, 0xc3, 0x3d, 0xc7, 0x38, 0x24, 0xe8, 0x75, 0xc8, 0x0b, 0xb2, 0x7c, 0xf5, 0xe6, 0xf1, 0xc9,
+	0xda, 0x97, 0x5e, 0x10, 0xc7, 0xa8, 0xaa, 0xcb, 0xbf, 0xfd, 0x87, 0x2b, 0x33, 0x7f, 0xf1, 0x47,
+	0x2b, 0xca, 0x34, 0xba, 0xfa, 0xbf, 0x19, 0x98, 0x3f, 0xe7, 0x28, 0x48, 0x85, 0x82, 0x4b, 0x4d,
+	0xea, 0x89, 0xc3, 0xb5, 0x58, 0x87, 0xb3, 0xd3, 0xd5, 0x42, 0x9b, 0x36, 0xa8, 0x37, 0xc6, 0x12,
+	0x83, 0x1e, 0x4f, 0xa5, 0x07, 0x0f, 0x3e, 0xa7, 0x17, 0xa6, 0x26, 0x08, 0x1f, 0xc1, 0xbc, 0xe5,
+	0xdb, 0x87, 0xc4, 0xd7, 0x4d, 0xea, 0xee, 0xd9, 0x03, 0x79, 0x70, 0x56, 0x53, 0x33, 0x69, 0x4e,
+	0x88, 0x2b, 0x82, 0xa1, 0xc1, 0xe9, 0x7f, 0x86, 0xd4, 0xa0, 0xea, 0x41, 0x25, 0xe9, 0xd7, 0xec,
+	0x34, 0x0b, 0xec, 0x5f, 0x25, 0x32, 0x7f, 0xe4, 0x09, 0x36, 0x2e, 0x31, 0x88, 0x48, 0x11, 0xdf,
+	0x80, 0xdc, 0x90, 0x5a, 0x42, 0xce, 0x7c, 0xfd, 0x3a, 0xcb, 0x50, 0xfe, 0xe9, 0x74, 0xb5, 0x4c,
+	0x83, 0xf5, 0x0d, 0xdb, 0x21, 0xdb, 0xd4, 0x22, 0x98, 0x13, 0xb0, 0x58, 0x1b, 0x6d, 0x2c, 0x79,
+	0x1a, 0xc8, 0xa1, 0xfa, 0xbd, 0x0c, 0xe4, 0x58, 0x10, 0x43, 0x2f, 0x43, 0xae, 0xde, 0x6a, 0x37,
+	0x95, 0x99, 0xea, 0xb5, 0xe3, 0x93, 0xb5, 0x79, 0x6e, 0x2d, 0x86, 0x60, 0x9b, 0x01, 0xad, 0x42,
+	0xe1, 0x49, 0x67, 0x6b, 0x67, 0x9b, 0x79, 0xde, 0xf5, 0xe3, 0x93, 0xb5, 0xc5, 0x18, 0x2d, 0xec,
+	0x89, 0x5e, 0x81, 0x7c, 0x7f, 0xbb, 0xbb, 0xd1, 0x53, 0xb2, 0x55, 0x74, 0x7c, 0xb2, 0xb6, 0x10,
+	0xe3, 0xf9, 0x74, 0xd0, 0xab, 0x90, 0x6f, 0x77, 0x5b, 0x5d, 0x4d, 0x99, 0xad, 0xde, 0x38, 0x3e,
+	0x59, 0x43, 0x31, 0x9a, 0x57, 0x3a, 0x5d, 0xdb, 0x23, 0xd5, 0x6b, 0xd2, 0x27, 0x4a, 0x31, 0x4e,
+	0xfd, 0x51, 0x06, 0xca, 0x89, 0x58, 0xc6, 0xdc, 0xba, 0xa9, 0x6d, 0xd4, 0x76, 0xb6, 0xfa, 0xca,
+	0x4c, 0xc2, 0xad, 0x13, 0x24, 0x4d, 0xb2, 0x67, 0x8c, 0x1c, 0x16, 0x5b, 0xa1, 0xd1, 0x69, 0xf7,
+	0x5a, 0xbd, 0xbe, 0xd6, 0xee, 0x2b, 0x99, 0xea, 0xf2, 0xf1, 0xc9, 0xda, 0xd2, 0x34, 0xf1, 0xc6,
+	0xc8, 0x71, 0x98, 0x63, 0x37, 0x6a, 0x8d, 0x4d, 0xbe, 0x53, 0x26, 0x8e, 0x9d, 0xa0, 0x6a, 0x18,
+	0xe6, 0x3e, 0xb1, 0xd0, 0xdb, 0x50, 0x6a, 0x6a, 0x5b, 0xda, 0xa3, 0x1a, 0x3f, 0x51, 0xaa, 0xaf,
+	0x1c, 0x9f, 0xac, 0xdd, 0x7c, 0xf1, 0xeb, 0x0e, 0x19, 0x18, 0x21, 0xb1, 0xa6, 0x1c, 0x3c, 0x41,
+	0xa2, 0xfe, 0x77, 0x16, 0xe6, 0x31, 0x09, 0x42, 0xc3, 0x0f, 0xbb, 0xd4, 0xb1, 0xcd, 0x31, 0xea,
+	0x42, 0xc9, 0xa4, 0xae, 0x65, 0x27, 0x62, 0xd3, 0xfd, 0x0b, 0x92, 0xb4, 0x09, 0x57, 0x34, 0x6a,
+	0x44, 0x9c, 0x78, 0x22, 0x04, 0xdd, 0x81, 0xbc, 0x45, 0x1c, 0x63, 0x2c, 0xb3, 0xc5, 0x9b, 0x2f,
+	0x54, 0x0b, 0x4d, 0xd9, 0xa8, 0xc0, 0x82, 0x8e, 0xd7, 0x66, 0xc6, 0x73, 0xdd, 0x08, 0x43, 0x32,
+	0xf4, 0x42, 0xe1, 0x23, 0x39, 0x5c, 0x1e, 0x1a, 0xcf, 0x6b, 0x12, 0x84, 0xee, 0x41, 0xe1, 0xc8,
+	0x76, 0x2d, 0x7a, 0x24, 0xb3, 0xc1, 0x4b, 0x84, 0x4a, 0x42, 0xf5, 0x98, 0xa5, 0x41, 0x53, 0x6a,
+	0x32, 0x37, 0x6b, 0x77, 0xda, 0x5a, 0xe4, 0x66, 0x12, 0xdf, 0x71, 0xdb, 0xd4, 0x65, 0xd1, 0x03,
+	0x3a, 0x6d, 0x7d, 0xa3, 0xd6, 0xda, 0xda, 0xc1, 0xcc, 0xd5, 0x96, 0x8e, 0x4f, 0xd6, 0x94, 0x98,
+	0x64, 0xc3, 0xb0, 0x1d, 0x56, 0x9e, 0xdc, 0x84, 0xd9, 0x5a, 0xfb, 0x5b, 0x4a, 0xb6, 0xaa, 0x1c,
+	0x9f, 0xac, 0x55, 0x62, 0x74, 0xcd, 0x1d, 0x4f, 0xec, 0x3e, 0xfd, 0x5d, 0xf5, 0x6f, 0x67, 0xa1,
+	0xb2, 0xe3, 0x59, 0x46, 0x48, 0xc4, 0x2e, 0x45, 0x6b, 0x50, 0xf6, 0x0c, 0xdf, 0x70, 0x1c, 0xe2,
+	0xd8, 0xc1, 0x50, 0xb6, 0x58, 0x92, 0x20, 0xf4, 0xde, 0xe7, 0x35, 0x63, 0xbd, 0xc8, 0x76, 0xde,
+	0x77, 0xff, 0x75, 0x35, 0x13, 0x19, 0x74, 0x07, 0x16, 0xf6, 0x84, 0xb6, 0xba, 0x61, 0xf2, 0x85,
+	0x9d, 0xe5, 0x0b, 0xbb, 0x9e, 0xb6, 0xb0, 0x49, 0xb5, 0xd6, 0xe5, 0x24, 0x6b, 0x9c, 0x0b, 0xcf,
+	0xef, 0x25, 0x87, 0xe8, 0x01, 0xcc, 0x0d, 0xa9, 0x6b, 0x87, 0xd4, 0xbf, 0x7a, 0x15, 0x22, 0x4a,
+	0xf4, 0x16, 0x5c, 0x63, 0x8b, 0x1b, 0xe9, 0xc3, 0xd1, 0xfc, 0xe4, 0xcf, 0xe2, 0xc5, 0xa1, 0xf1,
+	0x5c, 0x7e, 0x10, 0x33, 0x30, 0xaa, 0x43, 0x9e, 0xfa, 0x2c, 0x47, 0x2d, 0x70, 0x75, 0xdf, 0xbe,
+	0x52, 0x5d, 0x31, 0xe8, 0x30, 0x1e, 0x2c, 0x58, 0xd5, 0x77, 0x61, 0xfe, 0xdc, 0x24, 0x58, 0x6a,
+	0xd6, 0xad, 0xed, 0xf4, 0x34, 0x65, 0x06, 0x55, 0xa0, 0xd8, 0xe8, 0xb4, 0xfb, 0xad, 0xf6, 0x0e,
+	0xcb, 0x2d, 0x2b, 0x50, 0xc4, 0x9d, 0xad, 0xad, 0x7a, 0xad, 0xf1, 0x58, 0xc9, 0xaa, 0xeb, 0x50,
+	0x4e, 0x48, 0x43, 0x0b, 0x00, 0xbd, 0x7e, 0xa7, 0xab, 0x6f, 0xb4, 0x70, 0xaf, 0x2f, 0x32, 0xd3,
+	0x5e, 0xbf, 0x86, 0xfb, 0x12, 0x90, 0x51, 0xff, 0x33, 0x1b, 0xad, 0xa8, 0x4c, 0x46, 0xeb, 0xe7,
+	0x93, 0xd1, 0x4b, 0x94, 0x97, 0xe9, 0xe8, 0x64, 0x10, 0x27, 0xa5, 0xef, 0x01, 0x70, 0xc7, 0x21,
+	0x96, 0x6e, 0x84, 0x72, 0xe1, 0xab, 0x2f, 0x18, 0xb9, 0x1f, 0x75, 0x02, 0x71, 0x49, 0x52, 0xd7,
+	0x42, 0xf4, 0x21, 0x54, 0x4c, 0x3a, 0xf4, 0x1c, 0x22, 0x99, 0x67, 0xaf, 0x64, 0x2e, 0xc7, 0xf4,
+	0xb5, 0x30, 0x99, 0x0e, 0xe7, 0xce, 0x27, 0xec, 0xbf, 0x99, 0x89, 0x2c, 0x93, 0x92, 0x01, 0x57,
+	0xa0, 0xb8, 0xd3, 0x6d, 0xd6, 0xfa, 0xad, 0xf6, 0x23, 0x25, 0x83, 0x00, 0x0a, 0xdc, 0xd4, 0x4d,
+	0x25, 0xcb, 0x32, 0xf7, 0x46, 0x67, 0xbb, 0xbb, 0xa5, 0xf1, 0x88, 0x85, 0x96, 0x40, 0x89, 0x8c,
+	0xad, 0x73, 0x43, 0x6a, 0x4d, 0x25, 0x87, 0xae, 0xc3, 0x62, 0x0c, 0x95, 0x9c, 0x79, 0x74, 0x03,
+	0x50, 0x0c, 0x9c, 0x88, 0x28, 0xa8, 0xbf, 0x0e, 0x8b, 0x0d, 0xea, 0x86, 0x86, 0xed, 0xc6, 0x55,
+	0xcd, 0x7d, 0x36, 0x69, 0x09, 0xd2, 0x6d, 0xd9, 0x21, 0xab, 0x2f, 0x9e, 0x9d, 0xae, 0x96, 0x63,
+	0xd2, 0x56, 0x93, 0x67, 0xa1, 0x72, 0x60, 0xb1, 0xfd, 0xeb, 0xd9, 0x16, 0x37, 0x6e, 0xbe, 0x3e,
+	0x77, 0x76, 0xba, 0x3a, 0xdb, 0x6d, 0x35, 0x31, 0x83, 0xa1, 0x97, 0xa1, 0x44, 0x9e, 0xdb, 0xa1,
+	0x6e, 0xb2, 0x53, 0x8d, 0x19, 0x30, 0x8f, 0x8b, 0x0c, 0xd0, 0xa0, 0x16, 0x51, 0xeb, 0x00, 0x5d,
+	0xea, 0x87, 0xf2, 0xcb, 0xef, 0x40, 0xde, 0xa3, 0x3e, 0xef, 0xe9, 0x5c, 0xd8, 0x69, 0x64, 0xe4,
+	0xc2, 0x51, 0xb1, 0x20, 0x56, 0xbf, 0x37, 0x0b, 0xd0, 0x37, 0x82, 0x03, 0x29, 0xe4, 0x21, 0x94,
+	0xe2, 0xae, 0xae, 0x6c, 0x0e, 0x5d, 0xba, 0xda, 0x31, 0x31, 0x7a, 0x10, 0x39, 0x9b, 0xa8, 0xd7,
+	0x52, 0xcb, 0xea, 0xe8, 0x43, 0x69, 0x25, 0xcf, 0xf9, 0xa2, 0x8c, 0x25, 0x09, 0xc4, 0xf7, 0xe5,
+	0xca, 0xb3, 0x9f, 0xa8, 0xc1, 0x8f, 0x05, 0x61, 0x34, 0x99, 0xa8, 0xa7, 0xb6, 0xc3, 0xa6, 0x56,
+	0x64, 0x73, 0x06, 0x4f, 0xf8, 0xd0, 0x47, 0x50, 0x66, 0xf3, 0xd6, 0x03, 0x8e, 0x93, 0x39, 0xfa,
+	0x85, 0xa6, 0x12, 0x12, 0x30, 0x78, 0x13, 0x2b, 0xbf, 0x02, 0x60, 0x78, 0x9e, 0x63, 0x13, 0x4b,
+	0xdf, 0x1d, 0xf3, 0xa4, 0xbc, 0x84, 0x4b, 0x12, 0x52, 0x1f, 0xb3, 0xed, 0x12, 0xa1, 0x8d, 0x90,
+	0x17, 0x26, 0x57, 0x18, 0x50, 0x52, 0xd7, 0xc2, 0xba, 0x02, 0x0b, 0xfe, 0xc8, 0x65, 0x06, 0x95,
+	0xda, 0xa9, 0x7f, 0x92, 0x85, 0x97, 0xda, 0x24, 0x3c, 0xa2, 0xfe, 0x41, 0x2d, 0x0c, 0x0d, 0x73,
+	0x7f, 0x48, 0x5c, 0xb9, 0x7c, 0x89, 0x22, 0x2a, 0x73, 0xae, 0x88, 0x5a, 0x86, 0x39, 0xc3, 0xb1,
+	0x8d, 0x80, 0x88, 0xd4, 0xaf, 0x84, 0xa3, 0x21, 0x2b, 0xf5, 0x58, 0xe1, 0x48, 0x82, 0x80, 0x88,
+	0x4e, 0x0f, 0x53, 0x3c, 0x02, 0xa0, 0x6f, 0xc3, 0x0d, 0x99, 0xe4, 0x19, 0xf1, 0xa7, 0x58, 0xed,
+	0x11, 0x35, 0xae, 0xb5, 0xd4, 0x4a, 0x36, 0x5d, 0x39, 0x99, 0x05, 0x4e, 0xc0, 0x1d, 0x2f, 0x94,
+	0x39, 0xe5, 0x92, 0x95, 0x82, 0xaa, 0x3e, 0x82, 0x9b, 0x17, 0xb2, 0x7c, 0xa1, 0x4e, 0xd2, 0xdf,
+	0x67, 0x01, 0x5a, 0xdd, 0xda, 0xb6, 0x34, 0x52, 0x13, 0x0a, 0x7b, 0xc6, 0xd0, 0x76, 0xc6, 0x97,
+	0x45, 0xc0, 0x09, 0xfd, 0x7a, 0x4d, 0x98, 0x63, 0x83, 0xf3, 0x60, 0xc9, 0xcb, 0xeb, 0xd8, 0xd1,
+	0xae, 0x4b, 0xc2, 0xb8, 0x8e, 0xe5, 0x23, 0xa6, 0x86, 0x6f, 0xb8, 0xb1, 0xeb, 0x8a, 0x01, 0x5b,
+	0x00, 0x96, 0xf2, 0x1c, 0x19, 0xe3, 0x28, 0x6c, 0xc9, 0x21, 0xda, 0xe4, 0x5d, 0x63, 0xe2, 0x1f,
+	0x12, 0x6b, 0x39, 0xcf, 0x8d, 0x7a, 0x95, 0x3e, 0x58, 0x92, 0x0b, 0xdb, 0xc5, 0xdc, 0xd5, 0x0f,
+	0x78, 0xca, 0x34, 0x41, 0x7d, 0x21, 0x1b, 0xdd, 0x85, 0xf9, 0x73, 0xf3, 0x7c, 0xa1, 0x81, 0xd0,
+	0xea, 0x3e, 0x79, 0x47, 0xc9, 0xc9, 0x5f, 0xef, 0x2a, 0x05, 0xf5, 0xaf, 0x67, 0x45, 0xa0, 0x91,
+	0x56, 0x4d, 0xbf, 0x2d, 0x29, 0x72, 0xef, 0x36, 0xa9, 0x23, 0x03, 0xc0, 0x1b, 0x97, 0xc7, 0x1f,
+	0x56, 0x47, 0x72, 0x72, 0x1c, 0x33, 0xa2, 0x55, 0x28, 0x0b, 0x2f, 0xd6, 0xd9, 0x86, 0xe3, 0x66,
+	0x9d, 0xc7, 0x20, 0x40, 0x8c, 0x13, 0xdd, 0x86, 0x05, 0xde, 0x70, 0x0a, 0xf6, 0x89, 0x25, 0x68,
+	0x72, 0x9c, 0x66, 0x3e, 0x86, 0x72, 0xb2, 0x6d, 0xa8, 0x48, 0x80, 0xce, 0xab, 0x81, 0x3c, 0x57,
+	0xe8, 0xad, 0xab, 0x14, 0x12, 0x2c, 0xbc, 0x48, 0x28, 0x7b, 0x93, 0x81, 0xfa, 0xcb, 0x50, 0x8c,
+	0x94, 0x45, 0xcb, 0x30, 0xdb, 0x6f, 0x74, 0x95, 0x99, 0xea, 0xe2, 0xf1, 0xc9, 0x5a, 0x39, 0x02,
+	0xf7, 0x1b, 0x5d, 0x86, 0xd9, 0x69, 0x76, 0x95, 0xcc, 0x79, 0xcc, 0x4e, 0xb3, 0x8b, 0xaa, 0x90,
+	0xeb, 0x35, 0xfa, 0xdd, 0x28, 0x3f, 0x8b, 0x50, 0x0c, 0x56, 0xcd, 0xb1, 0xfc, 0x4c, 0xdd, 0x83,
+	0x72, 0xe2, 0xeb, 0xe8, 0x35, 0x98, 0x6b, 0xb5, 0x1f, 0x61, 0xad, 0xd7, 0x53, 0x66, 0x44, 0x79,
+	0x90, 0xc0, 0xb6, 0xdc, 0x01, 0x5b, 0x3b, 0xf4, 0x0a, 0xe4, 0x36, 0x3b, 0xec, 0xdc, 0x17, 0xf5,
+	0x47, 0x82, 0x62, 0x93, 0x06, 0x61, 0xf5, 0xba, 0x4c, 0xfc, 0x92, 0x82, 0xd5, 0xdf, 0xcf, 0x40,
+	0x41, 0x6c, 0xb4, 0xd4, 0x45, 0xac, 0x4d, 0x8a, 0x22, 0x51, 0x36, 0xbe, 0x71, 0x71, 0x89, 0xb7,
+	0x2e, 0x2b, 0x32, 0xe1, 0x9a, 0x11, 0x5f, 0xf5, 0x7d, 0xa8, 0x24, 0x11, 0x5f, 0xc8, 0x31, 0xbf,
+	0x0d, 0x65, 0xe6, 0xfb, 0x51, 0xa9, 0x77, 0x1f, 0x0a, 0x22, 0x58, 0xc4, 0xe7, 0xd0, 0xc5, 0xf5,
+	0xa6, 0xa4, 0x44, 0x0f, 0x61, 0x4e, 0xd4, 0xa8, 0x51, 0x2f, 0x7b, 0xe5, 0xf2, 0x1d, 0x86, 0x23,
+	0x72, 0xf5, 0x23, 0xc8, 0x75, 0x09, 0xf1, 0x99, 0xed, 0x5d, 0x6a, 0x91, 0xc9, 0xd1, 0x2d, 0xcb,
+	0x6b, 0x8b, 0xb4, 0x9a, 0xac, 0xbc, 0xb6, 0x48, 0xcb, 0x8a, 0xfb, 0x71, 0xd9, 0x44, 0x3f, 0xae,
+	0x0f, 0x95, 0xa7, 0xc4, 0x1e, 0xec, 0x87, 0xc4, 0xe2, 0x82, 0xde, 0x86, 0x9c, 0x47, 0x62, 0xe5,
+	0x97, 0x53, 0x9d, 0x8f, 0x10, 0x1f, 0x73, 0x2a, 0x16, 0x63, 0x8e, 0x38, 0xb7, 0xbc, 0x06, 0x92,
+	0x23, 0xf5, 0xef, 0xb2, 0xb0, 0xd0, 0x0a, 0x82, 0x91, 0xe1, 0x9a, 0x51, 0x56, 0xf7, 0xf5, 0xf3,
+	0x59, 0x5d, 0xea, 0x7d, 0xd9, 0x79, 0x96, 0xf3, 0x6d, 0x46, 0x79, 0xb2, 0x66, 0xe3, 0x93, 0x55,
+	0xfd, 0x8f, 0x4c, 0xd4, 0x4b, 0xbc, 0x9d, 0x08, 0x05, 0xa2, 0x46, 0x4c, 0x4a, 0x22, 0x3b, 0xee,
+	0x81, 0x4b, 0x8f, 0x5c, 0x56, 0xbd, 0x62, 0xad, 0xad, 0x3d, 0x55, 0x32, 0xc2, 0x3d, 0xcf, 0x11,
+	0x61, 0xe2, 0x92, 0x23, 0x26, 0xa9, 0xab, 0xb5, 0x9b, 0x2c, 0x0b, 0xcb, 0xa6, 0x48, 0xea, 0x12,
+	0xd7, 0xb2, 0xdd, 0x01, 0x7a, 0x0d, 0x0a, 0xad, 0x5e, 0x6f, 0x87, 0x97, 0x90, 0x2f, 0x1d, 0x9f,
+	0xac, 0x5d, 0x3f, 0x47, 0xc5, 0xfb, 0xc8, 0x16, 0x23, 0x62, 0x25, 0x10, 0xcb, 0xcf, 0x52, 0x88,
+	0x58, 0x6e, 0x2d, 0x88, 0x70, 0xa7, 0x5f, 0xeb, 0x6b, 0x4a, 0x3e, 0x85, 0x08, 0x53, 0xf6, 0x57,
+	0x6e, 0xb7, 0x7f, 0xce, 0x82, 0x52, 0x33, 0x4d, 0xe2, 0x85, 0x0c, 0x2f, 0xab, 0xce, 0x3e, 0x14,
+	0x3d, 0xf6, 0xcb, 0x26, 0x51, 0x06, 0xf5, 0x30, 0xf5, 0xc6, 0x77, 0x8a, 0x6f, 0x1d, 0x53, 0x87,
+	0xd4, 0xac, 0xa1, 0x1d, 0x04, 0x36, 0x75, 0x05, 0x0c, 0xc7, 0x92, 0xaa, 0xff, 0x95, 0x81, 0xeb,
+	0x29, 0x14, 0xe8, 0x2e, 0xe4, 0x7c, 0xea, 0x44, 0x6b, 0x78, 0xeb, 0xa2, 0x36, 0x31, 0x63, 0xc5,
+	0x9c, 0x12, 0xad, 0x00, 0x18, 0xa3, 0x90, 0x1a, 0xfc, 0xfb, 0xa2, 0xb9, 0x86, 0x13, 0x10, 0xf4,
+	0x14, 0x0a, 0x01, 0x31, 0x7d, 0x12, 0xe5, 0xd9, 0x1f, 0xfd, 0xb4, 0xda, 0xaf, 0xf7, 0xb8, 0x18,
+	0x2c, 0xc5, 0x55, 0xd7, 0xa1, 0x20, 0x20, 0xcc, 0xed, 0x2d, 0x23, 0x34, 0xe4, 0x25, 0x02, 0xff,
+	0xcd, 0xbc, 0xc9, 0x70, 0x06, 0x91, 0x37, 0x19, 0xce, 0x40, 0xfd, 0xab, 0x2c, 0x80, 0xf6, 0x3c,
+	0x24, 0xbe, 0x6b, 0x38, 0x8d, 0x1a, 0xd2, 0x12, 0x27, 0x83, 0x98, 0xed, 0x57, 0x52, 0xef, 0x4d,
+	0x62, 0x8e, 0xf5, 0x46, 0x2d, 0xe5, 0x6c, 0xb8, 0x09, 0xb3, 0x23, 0x5f, 0x5e, 0xe2, 0x8b, 0x1c,
+	0x79, 0x07, 0x6f, 0x61, 0x06, 0x43, 0x5a, 0xb2, 0x97, 0x73, 0xe1, 0x55, 0x7d, 0xe2, 0x03, 0xa9,
+	0xa1, 0x8b, 0xed, 0x7c, 0xd3, 0xd0, 0x4d, 0x22, 0x4f, 0x95, 0x8a, 0xd8, 0xf9, 0x8d, 0x5a, 0x83,
+	0xf8, 0x21, 0x2e, 0x98, 0x06, 0xfb, 0xff, 0x33, 0xc5, 0xb7, 0xb7, 0x01, 0x26, 0x53, 0x43, 0x2b,
+	0x90, 0x6f, 0x6c, 0xf4, 0x7a, 0x5b, 0xca, 0x8c, 0x08, 0xe0, 0x13, 0x14, 0x07, 0xab, 0x7f, 0x9e,
+	0x85, 0x62, 0xa3, 0x26, 0x8f, 0xdc, 0x06, 0x28, 0x3c, 0x2a, 0xf1, 0xab, 0x17, 0xf2, 0xdc, 0xb3,
+	0xfd, 0xb1, 0x0c, 0x2c, 0x97, 0x14, 0xbc, 0x0b, 0x8c, 0x85, 0x69, 0xad, 0x71, 0x06, 0x84, 0xa1,
+	0x42, 0xa4, 0x11, 0x74, 0xd3, 0x88, 0x62, 0xfc, 0xca, 0xe5, 0xc6, 0x12, 0xa5, 0xcb, 0x64, 0x1c,
+	0xe0, 0x72, 0x24, 0xa4, 0x61, 0x04, 0xe8, 0x3d, 0x58, 0x0c, 0xec, 0x81, 0x6b, 0xbb, 0x03, 0x3d,
+	0x32, 0x1e, 0xbf, 0x07, 0xaa, 0x5f, 0x3b, 0x3b, 0x5d, 0x9d, 0xef, 0x09, 0x94, 0xb4, 0xe1, 0xbc,
+	0xa4, 0x6c, 0x70, 0x53, 0xa2, 0x77, 0x61, 0x21, 0xc1, 0xca, 0xac, 0x28, 0xcc, 0xce, 0x3b, 0xc6,
+	0x31, 0xe7, 0x63, 0x32, 0xc6, 0x95, 0x98, 0xf1, 0x31, 0xe1, 0xbd, 0x99, 0x3d, 0xea, 0x9b, 0x44,
+	0xf7, 0xf9, 0x9e, 0xe6, 0xa7, 0x7b, 0x0e, 0x97, 0x39, 0x4c, 0x6c, 0x73, 0xf5, 0x09, 0x5c, 0xef,
+	0xf8, 0xe6, 0x3e, 0x09, 0x42, 0x61, 0x0a, 0x69, 0xc5, 0x8f, 0xe0, 0x56, 0x68, 0x04, 0x07, 0xfa,
+	0xbe, 0x1d, 0x84, 0xd4, 0x1f, 0xeb, 0x3e, 0x09, 0x89, 0xcb, 0xf0, 0x3a, 0xbf, 0xe0, 0x96, 0xed,
+	0xc4, 0x9b, 0x8c, 0x66, 0x53, 0x90, 0xe0, 0x88, 0x62, 0x8b, 0x11, 0xa8, 0x2d, 0xa8, 0xb0, 0x12,
+	0x46, 0x36, 0xd5, 0xd8, 0xec, 0xc1, 0xa1, 0x03, 0xfd, 0x73, 0x1f, 0x53, 0x25, 0x87, 0x0e, 0xc4,
+	0x4f, 0xf5, 0x9b, 0xa0, 0x34, 0xed, 0xc0, 0x33, 0x42, 0x73, 0x3f, 0xea, 0x93, 0xa2, 0x26, 0x28,
+	0xfb, 0xc4, 0xf0, 0xc3, 0x5d, 0x62, 0x84, 0xba, 0x47, 0x7c, 0x9b, 0x5a, 0x57, 0xaf, 0xf2, 0x62,
+	0xcc, 0xd2, 0xe5, 0x1c, 0xea, 0xff, 0x64, 0x00, 0xb0, 0xb1, 0x17, 0x65, 0x6b, 0x5f, 0x85, 0x6b,
+	0x81, 0x6b, 0x78, 0xc1, 0x3e, 0x0d, 0x75, 0xdb, 0x0d, 0x89, 0x7f, 0x68, 0x38, 0xb2, 0xb9, 0xa3,
+	0x44, 0x88, 0x96, 0x84, 0xa3, 0xb7, 0x01, 0x1d, 0x10, 0xe2, 0xe9, 0xd4, 0xb1, 0xf4, 0x08, 0x29,
+	0x2e, 0xbe, 0x73, 0x58, 0x61, 0x98, 0x8e, 0x63, 0xf5, 0x22, 0x38, 0xaa, 0xc3, 0x0a, 0x9b, 0x3e,
+	0x71, 0x43, 0xdf, 0x26, 0x81, 0xbe, 0x47, 0x7d, 0x3d, 0x70, 0xe8, 0x91, 0xbe, 0x47, 0x1d, 0x87,
+	0x1e, 0x11, 0x3f, 0xea, 0x9b, 0x55, 0x1d, 0x3a, 0xd0, 0x04, 0xd1, 0x06, 0xf5, 0x7b, 0x0e, 0x3d,
+	0xda, 0x88, 0x28, 0x58, 0x4a, 0x37, 0x99, 0x73, 0x68, 0x9b, 0x07, 0x51, 0x4a, 0x17, 0x43, 0xfb,
+	0xb6, 0x79, 0x80, 0x5e, 0x83, 0x79, 0xe2, 0x10, 0xde, 0x3e, 0x11, 0x54, 0x79, 0x4e, 0x55, 0x89,
+	0x80, 0x8c, 0x48, 0xfd, 0x18, 0x14, 0xcd, 0x35, 0xfd, 0xb1, 0x97, 0x58, 0xf3, 0xb7, 0x01, 0xb1,
+	0x20, 0xa9, 0x3b, 0xd4, 0x3c, 0xd0, 0x87, 0x86, 0x6b, 0x0c, 0x98, 0x5e, 0xe2, 0xc6, 0x51, 0x61,
+	0x98, 0x2d, 0x6a, 0x1e, 0x6c, 0x4b, 0xb8, 0xfa, 0x1e, 0x40, 0xcf, 0xf3, 0x89, 0x61, 0x75, 0x58,
+	0x36, 0xc1, 0x4c, 0xc7, 0x47, 0xba, 0x25, 0xef, 0x73, 0xa9, 0x2f, 0xb7, 0xba, 0x22, 0x10, 0xcd,
+	0x18, 0xae, 0xfe, 0x22, 0x5c, 0xef, 0x3a, 0x86, 0xc9, 0x5f, 0x58, 0x74, 0xe3, 0x2b, 0x34, 0xf4,
+	0x10, 0x0a, 0x82, 0x54, 0xae, 0x64, 0xea, 0x76, 0x9b, 0x7c, 0x73, 0x73, 0x06, 0x4b, 0xfa, 0x7a,
+	0x05, 0x60, 0x22, 0x47, 0xfd, 0xc7, 0x0c, 0x94, 0x62, 0xf9, 0x68, 0x4d, 0x5c, 0x80, 0x85, 0xbe,
+	0x61, 0xbb, 0xb2, 0xe2, 0x2f, 0xe1, 0x24, 0x08, 0xb5, 0xa0, 0xec, 0xc5, 0xdc, 0x97, 0xe6, 0x73,
+	0x29, 0x5a, 0xe3, 0x24, 0x2f, 0x7a, 0x1f, 0x4a, 0xd1, 0x05, 0x7a, 0x14, 0x61, 0x2f, 0xbf, 0x6f,
+	0x9f, 0x90, 0x47, 0x8d, 0x54, 0x9f, 0x78, 0x8e, 0xcd, 0x62, 0x4e, 0x2e, 0x6e, 0xa4, 0x62, 0x09,
+	0x52, 0xbf, 0x0e, 0xf0, 0x0d, 0x6a, 0xbb, 0x7d, 0x7a, 0x40, 0x5c, 0x7e, 0x2b, 0xcc, 0x4a, 0x4a,
+	0x12, 0x19, 0x5a, 0x8e, 0x78, 0xa7, 0x40, 0xac, 0x52, 0x7c, 0x39, 0x2a, 0x86, 0xea, 0x5f, 0x66,
+	0xa1, 0x80, 0x29, 0x0d, 0x1b, 0x35, 0xb4, 0x06, 0x05, 0x19, 0x4a, 0xf8, 0x11, 0x55, 0x2f, 0x9d,
+	0x9d, 0xae, 0xe6, 0x45, 0x0c, 0xc9, 0x9b, 0x3c, 0x78, 0x24, 0x82, 0x7c, 0xf6, 0xa2, 0x20, 0x8f,
+	0xee, 0x42, 0x45, 0x12, 0xe9, 0xfb, 0x46, 0xb0, 0x2f, 0xea, 0xbb, 0xfa, 0xc2, 0xd9, 0xe9, 0x2a,
+	0x08, 0xca, 0x4d, 0x23, 0xd8, 0xc7, 0x20, 0xa8, 0xd9, 0x6f, 0xa4, 0x41, 0xf9, 0x19, 0xb5, 0x5d,
+	0x3d, 0xe4, 0x93, 0x90, 0xbd, 0xc8, 0xd4, 0xa5, 0x9e, 0x4c, 0x55, 0x3e, 0xa0, 0x80, 0x67, 0x93,
+	0xc9, 0x6b, 0x30, 0xef, 0x53, 0x1a, 0x8a, 0xc8, 0x66, 0x53, 0x57, 0xb6, 0x39, 0xd6, 0x52, 0xbb,
+	0xdf, 0x94, 0x86, 0x58, 0xd2, 0xe1, 0x8a, 0x9f, 0x18, 0xa1, 0xbb, 0xb0, 0xe4, 0x18, 0x41, 0xa8,
+	0xf3, 0x90, 0x68, 0x4d, 0xa4, 0x15, 0xb8, 0xf1, 0x11, 0xc3, 0x6d, 0x70, 0x54, 0xc4, 0xa1, 0xfe,
+	0x43, 0x06, 0xca, 0x6c, 0x32, 0xf6, 0x9e, 0x6d, 0xb2, 0x3c, 0xf0, 0x8b, 0xa7, 0x27, 0x37, 0x61,
+	0xd6, 0x0c, 0x7c, 0x69, 0x54, 0x7e, 0x3e, 0x37, 0x7a, 0x18, 0x33, 0x18, 0xfa, 0x18, 0x0a, 0xb2,
+	0xdd, 0x22, 0x32, 0x13, 0xf5, 0xea, 0x8c, 0x55, 0xda, 0x46, 0xf2, 0x71, 0x77, 0x9f, 0x68, 0x27,
+	0xce, 0x09, 0x9c, 0x04, 0xa1, 0x1b, 0x90, 0x35, 0x85, 0xb9, 0xe4, 0x0b, 0x9d, 0x46, 0x1b, 0x67,
+	0x4d, 0x57, 0xfd, 0x51, 0x06, 0xe6, 0x27, 0x31, 0x81, 0x79, 0xc0, 0x2d, 0x28, 0x05, 0xa3, 0xdd,
+	0x60, 0x1c, 0x84, 0x64, 0x18, 0xdd, 0x78, 0xc7, 0x00, 0xd4, 0x82, 0x92, 0xe1, 0x0c, 0xa8, 0x6f,
+	0x87, 0xfb, 0x43, 0x59, 0xc8, 0xa6, 0x67, 0x13, 0x49, 0x99, 0xeb, 0xb5, 0x88, 0x05, 0x4f, 0xb8,
+	0xa3, 0xd4, 0x40, 0x3c, 0x8b, 0xe0, 0xa9, 0xc1, 0xab, 0x50, 0x71, 0x8c, 0x21, 0xef, 0x3f, 0x85,
+	0xf6, 0x90, 0x44, 0x9b, 0x41, 0xc2, 0xfa, 0xf6, 0x90, 0xa8, 0x2a, 0x94, 0x62, 0x61, 0x68, 0x11,
+	0xca, 0x35, 0xad, 0xa7, 0xdf, 0xbb, 0xff, 0x50, 0x7f, 0xd4, 0xd8, 0x56, 0x66, 0x64, 0xfa, 0xfa,
+	0x67, 0x19, 0x98, 0x97, 0x11, 0x4b, 0x96, 0x04, 0xaf, 0xc1, 0x9c, 0x6f, 0xec, 0x85, 0x51, 0xd1,
+	0x92, 0x13, 0x5e, 0xcd, 0x0e, 0x01, 0x56, 0xb4, 0x30, 0x54, 0x7a, 0xd1, 0x92, 0x78, 0x83, 0x31,
+	0x7b, 0xe9, 0x1b, 0x8c, 0xdc, 0xff, 0xcb, 0x1b, 0x0c, 0xf5, 0x37, 0x00, 0x36, 0x6c, 0x87, 0xf4,
+	0x45, 0xab, 0x2a, 0xad, 0x04, 0x65, 0x69, 0x9e, 0x6c, 0x85, 0x46, 0x69, 0x5e, 0xab, 0x89, 0x19,
+	0x8c, 0xa1, 0x06, 0xb6, 0x25, 0x37, 0x23, 0x47, 0x3d, 0x62, 0xa8, 0x81, 0x6d, 0xc5, 0xd7, 0x7e,
+	0xb9, 0x2b, 0xae, 0xfd, 0xd4, 0x45, 0x98, 0xc7, 0xa2, 0xc7, 0x26, 0x74, 0x50, 0x4f, 0x32, 0xb0,
+	0x28, 0xf3, 0xdd, 0x38, 0x64, 0x7f, 0x05, 0x4a, 0x22, 0xf5, 0x9d, 0x14, 0x81, 0xfc, 0x21, 0x82,
+	0xa0, 0x6b, 0x35, 0x71, 0x51, 0xa0, 0x5b, 0x16, 0x5a, 0x85, 0xb2, 0x24, 0x4d, 0x3c, 0xef, 0x02,
+	0x01, 0x6a, 0xb3, 0xf9, 0xbc, 0x03, 0xb9, 0x3d, 0xdb, 0x21, 0xd2, 0xf3, 0x53, 0x23, 0xc2, 0xc4,
+	0x22, 0x9b, 0x33, 0x98, 0x53, 0xd7, 0x8b, 0x51, 0x73, 0x4f, 0xfd, 0x97, 0x0c, 0x6f, 0x31, 0xb3,
+	0x52, 0x35, 0xa9, 0x9f, 0xa8, 0x5a, 0xa7, 0xf4, 0x13, 0x74, 0x4c, 0x3f, 0x81, 0x16, 0xfa, 0x49,
+	0xd2, 0xa4, 0x7e, 0x02, 0xf4, 0xd3, 0xeb, 0x87, 0x3e, 0x84, 0x39, 0xd9, 0xaa, 0x94, 0xa1, 0xee,
+	0xd5, 0x54, 0xcf, 0x48, 0x5a, 0x7a, 0x73, 0x06, 0x47, 0x3c, 0x89, 0xe9, 0x6d, 0xc1, 0x8d, 0xba,
+	0x63, 0x98, 0x07, 0x8e, 0x1d, 0x84, 0xc4, 0x4a, 0x46, 0xa0, 0xfb, 0x50, 0x38, 0x97, 0xe7, 0x5e,
+	0xd6, 0x44, 0x95, 0x94, 0xea, 0xbf, 0x67, 0xa0, 0xb2, 0x49, 0x0c, 0x27, 0xdc, 0x9f, 0x74, 0xaa,
+	0x42, 0x12, 0x84, 0xf2, 0x7c, 0xe4, 0xbf, 0xd1, 0xd7, 0xa0, 0x18, 0xa7, 0x41, 0x57, 0x5e, 0x07,
+	0xc6, 0xa4, 0xe8, 0x01, 0xcc, 0x31, 0xdd, 0xe9, 0x28, 0xaa, 0xaf, 0x2e, 0xbb, 0x69, 0x92, 0x94,
+	0xec, 0xd0, 0xf2, 0x09, 0xcf, 0x7b, 0xb8, 0x9d, 0xf2, 0x38, 0x1a, 0xa2, 0x9f, 0x87, 0x0a, 0xbf,
+	0x28, 0x89, 0xd2, 0xbc, 0xfc, 0x55, 0x32, 0xcb, 0xe2, 0xae, 0x53, 0xa4, 0x78, 0x7f, 0x9c, 0x85,
+	0xa5, 0x6d, 0x63, 0xbc, 0x4b, 0x64, 0x18, 0x22, 0x16, 0x26, 0x26, 0xf5, 0x2d, 0xd4, 0x4d, 0x86,
+	0xaf, 0x4b, 0xae, 0x4e, 0xd3, 0x98, 0xd3, 0xa3, 0x58, 0x54, 0xf3, 0x65, 0x13, 0x35, 0xdf, 0x12,
+	0xe4, 0x5d, 0xea, 0x9a, 0x44, 0xc6, 0x36, 0x31, 0x50, 0xbf, 0x93, 0x49, 0xc6, 0xae, 0x6a, 0x7c,
+	0xad, 0xc9, 0x9b, 0x5e, 0x6d, 0x1a, 0xc6, 0x9f, 0x43, 0x1f, 0x43, 0xb5, 0xa7, 0x35, 0xb0, 0xd6,
+	0xaf, 0x77, 0xbe, 0xa9, 0xf7, 0x6a, 0x5b, 0xbd, 0xda, 0xfd, 0xbb, 0x7a, 0xb7, 0xb3, 0xf5, 0xad,
+	0x7b, 0x0f, 0xee, 0x7e, 0x4d, 0xc9, 0x54, 0xd7, 0x8e, 0x4f, 0xd6, 0x6e, 0xb5, 0x6b, 0x8d, 0x2d,
+	0xb1, 0xe3, 0x76, 0xe9, 0xf3, 0x9e, 0xe1, 0x04, 0xc6, 0xfd, 0xbb, 0x5d, 0xea, 0x8c, 0x19, 0x0d,
+	0xfa, 0x2a, 0xa0, 0x0d, 0x0d, 0xb7, 0xb5, 0xbe, 0x1e, 0x05, 0xc8, 0x46, 0xbd, 0xa1, 0x64, 0x45,
+	0x25, 0xb5, 0x41, 0x7c, 0x97, 0x84, 0x35, 0xad, 0x77, 0xef, 0xfe, 0xc3, 0x46, 0xbd, 0xc1, 0xf6,
+	0x78, 0x25, 0x79, 0x5a, 0x26, 0x93, 0x80, 0xcc, 0x85, 0x49, 0xc0, 0x24, 0x97, 0xc8, 0x5e, 0x90,
+	0x4b, 0x6c, 0xc0, 0x92, 0xe9, 0xd3, 0x20, 0xd0, 0x59, 0x79, 0x42, 0xac, 0xa9, 0x02, 0xe8, 0x4b,
+	0x67, 0xa7, 0xab, 0xd7, 0x1a, 0x0c, 0xdf, 0xe3, 0x68, 0x29, 0xfe, 0x9a, 0x99, 0x00, 0xf1, 0x2f,
+	0xa9, 0xdf, 0x9f, 0x65, 0x99, 0x9e, 0x7d, 0x68, 0x3b, 0x64, 0x40, 0x02, 0xf4, 0x04, 0x16, 0x4d,
+	0x9f, 0x58, 0xac, 0xee, 0x30, 0x9c, 0xe4, 0xcb, 0xe8, 0x9f, 0x4b, 0x4d, 0xba, 0x62, 0xc6, 0xf5,
+	0x46, 0xcc, 0xd5, 0xf3, 0x88, 0x89, 0x17, 0xcc, 0x73, 0x63, 0xf4, 0x0c, 0x16, 0x03, 0xe2, 0xd8,
+	0xee, 0xe8, 0xb9, 0x6e, 0x52, 0x37, 0x24, 0xcf, 0xa3, 0xeb, 0xbc, 0xab, 0xe4, 0xf6, 0xb4, 0x2d,
+	0xc6, 0xd5, 0x10, 0x4c, 0x75, 0x74, 0x76, 0xba, 0xba, 0x70, 0x1e, 0x86, 0x17, 0xa4, 0x64, 0x39,
+	0xae, 0xee, 0xc3, 0xc2, 0x79, 0x6d, 0xd0, 0x92, 0x0c, 0x34, 0x3c, 0x5e, 0xc5, 0x81, 0xe4, 0x16,
+	0x14, 0x7d, 0x32, 0xb0, 0x83, 0xd0, 0x17, 0x66, 0x66, 0x98, 0x18, 0x82, 0x96, 0xa1, 0x90, 0x78,
+	0x71, 0xc2, 0x70, 0x72, 0xcc, 0x22, 0x88, 0x78, 0x4c, 0x56, 0xfd, 0x35, 0x98, 0xd2, 0x85, 0x6d,
+	0x3a, 0xcb, 0x0e, 0x8c, 0x5d, 0xf9, 0xb1, 0x22, 0x8e, 0x86, 0xcc, 0x97, 0x47, 0x41, 0x9c, 0x40,
+	0xf2, 0xdf, 0x0c, 0xc6, 0x33, 0x1d, 0xf9, 0xb4, 0x8e, 0xe7, 0x32, 0xd1, 0x0b, 0xde, 0x5c, 0xe2,
+	0x05, 0xef, 0x12, 0xe4, 0x1d, 0x72, 0x48, 0x1c, 0x91, 0x63, 0x60, 0x31, 0xe0, 0x3e, 0xff, 0x0d,
+	0xba, 0x2b, 0x8f, 0xe1, 0x0d, 0x98, 0x7f, 0x46, 0x77, 0x75, 0x3b, 0x24, 0xfe, 0xe4, 0x61, 0x55,
+	0xf9, 0xfe, 0xcb, 0x69, 0xf6, 0x95, 0x0f, 0x79, 0x65, 0xa2, 0x53, 0x79, 0x46, 0x77, 0x5b, 0x11,
+	0x1b, 0xaa, 0xc1, 0x02, 0xcf, 0xdf, 0xc8, 0x73, 0x62, 0x8e, 0xb8, 0xa0, 0xab, 0xef, 0x5d, 0xe7,
+	0x19, 0x87, 0x16, 0x31, 0xbc, 0x75, 0x17, 0x2a, 0xd1, 0x1b, 0x56, 0xfe, 0x98, 0xa5, 0x08, 0xb9,
+	0x7e, 0xad, 0xf7, 0x58, 0x99, 0x41, 0x00, 0x05, 0xb1, 0xf9, 0xc4, 0xed, 0x68, 0xa3, 0xd3, 0xde,
+	0x68, 0x3d, 0x52, 0xb2, 0x6f, 0xfd, 0x5e, 0x0e, 0x4a, 0xf1, 0xfd, 0x1c, 0x3b, 0x6c, 0xdb, 0xda,
+	0xd3, 0x68, 0xf7, 0xc6, 0xf0, 0x36, 0x39, 0x42, 0xaf, 0x4e, 0x3a, 0x7b, 0x1f, 0x8b, 0x07, 0x09,
+	0x31, 0x3a, 0xea, 0xea, 0xbd, 0x0e, 0xc5, 0x5a, 0xaf, 0xd7, 0x7a, 0xd4, 0xd6, 0x9a, 0xca, 0xa7,
+	0x99, 0xea, 0x97, 0x8e, 0x4f, 0xd6, 0xae, 0xc5, 0x44, 0xb5, 0x40, 0xec, 0x17, 0x4e, 0xd5, 0x68,
+	0x68, 0xdd, 0xbe, 0xd6, 0x54, 0x3e, 0xc9, 0x4e, 0x53, 0xf1, 0x4e, 0x15, 0x7f, 0x68, 0x55, 0xea,
+	0x62, 0xad, 0x5b, 0xc3, 0xec, 0x83, 0x9f, 0x66, 0x45, 0xc3, 0x71, 0xf2, 0x45, 0x9f, 0x78, 0x86,
+	0xcf, 0xbe, 0xb9, 0x12, 0xbd, 0x77, 0xfc, 0x64, 0x56, 0xbc, 0xb8, 0x99, 0x5c, 0x36, 0x12, 0xc3,
+	0x1a, 0xb3, 0xaf, 0xf1, 0x5b, 0x5e, 0x2e, 0x66, 0x76, 0xea, 0x6b, 0x3d, 0x16, 0x5c, 0x99, 0x14,
+	0x15, 0xe6, 0xf0, 0x4e, 0xbb, 0xcd, 0x88, 0x3e, 0xc9, 0x4d, 0xcd, 0x0e, 0x8f, 0x5c, 0x97, 0xd1,
+	0xdc, 0x86, 0x62, 0x74, 0x09, 0xac, 0x7c, 0x9a, 0x9b, 0x52, 0xa8, 0x11, 0xdd, 0x60, 0xf3, 0x0f,
+	0x6e, 0xee, 0xf4, 0xf9, 0x73, 0xcc, 0x4f, 0xf2, 0xd3, 0x1f, 0xdc, 0x1f, 0x85, 0x16, 0x3d, 0x72,
+	0x59, 0x98, 0x91, 0xbd, 0xcd, 0x4f, 0xf3, 0x22, 0x7c, 0xc5, 0x34, 0xb2, 0xb1, 0xf9, 0x3a, 0x14,
+	0xb1, 0xf6, 0x0d, 0xf1, 0x72, 0xf3, 0x93, 0xc2, 0x94, 0x1c, 0x4c, 0x9e, 0x11, 0x93, 0x7d, 0x6d,
+	0x0d, 0x0a, 0x58, 0xdb, 0xee, 0x3c, 0xd1, 0x94, 0x3f, 0x28, 0x4c, 0xc9, 0xc1, 0x64, 0x48, 0xf9,
+	0x4b, 0xb4, 0x62, 0x07, 0x77, 0x37, 0x6b, 0x7c, 0x51, 0xa6, 0xe5, 0x74, 0x7c, 0x6f, 0xdf, 0x70,
+	0x89, 0x35, 0x79, 0x75, 0x14, 0xa3, 0xde, 0xfa, 0x25, 0x28, 0x46, 0xc9, 0x3e, 0x5a, 0x81, 0xc2,
+	0xd3, 0x0e, 0x7e, 0xac, 0x61, 0x65, 0x46, 0x58, 0x39, 0xc2, 0x3c, 0x15, 0x65, 0xda, 0x1a, 0xcc,
+	0x6d, 0xd7, 0xda, 0xb5, 0x47, 0x1a, 0x8e, 0x2e, 0x26, 0x22, 0x02, 0x99, 0xb1, 0x56, 0x15, 0xf9,
+	0x81, 0x58, 0x66, 0xfd, 0xf5, 0x1f, 0x7c, 0xb6, 0x32, 0xf3, 0xe3, 0xcf, 0x56, 0x66, 0x3e, 0x39,
+	0x5b, 0xc9, 0xfc, 0xe0, 0x6c, 0x25, 0xf3, 0xc3, 0xb3, 0x95, 0xcc, 0xbf, 0x9d, 0xad, 0x64, 0x7e,
+	0xe7, 0x27, 0x2b, 0x33, 0x3f, 0xfc, 0xc9, 0xca, 0xcc, 0x8f, 0x7f, 0xb2, 0x32, 0xb3, 0x5b, 0xe0,
+	0x4e, 0xff, 0xe0, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xde, 0x15, 0x00, 0xb1, 0xc6, 0x34, 0x00,
+	0x00,
 }
 
 func (m *Version) Copy() *Version {
@@ -5814,6 +5866,26 @@ func (m *Privileges_SELinuxContext) CopyFrom(src interface{}) {
 	*m = *o
 }
 
+func (m *JobStatus) Copy() *JobStatus {
+	if m == nil {
+		return nil
+	}
+	o := &JobStatus{}
+	o.CopyFrom(m)
+	return o
+}
+
+func (m *JobStatus) CopyFrom(src interface{}) {
+
+	o := src.(*JobStatus)
+	*m = *o
+	github_com_docker_swarmkit_api_deepcopy.Copy(&m.JobIteration, &o.JobIteration)
+	if o.LastExecution != nil {
+		m.LastExecution = &types.Timestamp{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.LastExecution, o.LastExecution)
+	}
+}
+
 func (m *Version) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -8499,6 +8571,42 @@ func (m *Privileges_SELinuxContext) MarshalTo(dAtA []byte) (int, error) {
 	return i, nil
 }
 
+func (m *JobStatus) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *JobStatus) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintTypes(dAtA, i, uint64(m.JobIteration.Size()))
+	n50, err := m.JobIteration.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n50
+	if m.LastExecution != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintTypes(dAtA, i, uint64(m.LastExecution.Size()))
+		n51, err := m.LastExecution.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n51
+	}
+	return i, nil
+}
+
 func encodeVarintTypes(dAtA []byte, offset int, v uint64) int {
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -9927,6 +10035,21 @@ func (m *Privileges_SELinuxContext) Size() (n int) {
 	return n
 }
 
+func (m *JobStatus) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = m.JobIteration.Size()
+	n += 1 + l + sovTypes(uint64(l))
+	if m.LastExecution != nil {
+		l = m.LastExecution.Size()
+		n += 1 + l + sovTypes(uint64(l))
+	}
+	return n
+}
+
 func sovTypes(x uint64) (n int) {
 	for {
 		n++
@@ -10865,6 +10988,17 @@ func (this *Privileges_SELinuxContext) String() string {
 	}, "")
 	return s
 }
+func (this *JobStatus) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&JobStatus{`,
+		`JobIteration:` + strings.Replace(strings.Replace(this.JobIteration.String(), "Version", "Version", 1), `&`, ``, 1) + `,`,
+		`LastExecution:` + strings.Replace(fmt.Sprintf("%v", this.LastExecution), "Timestamp", "types.Timestamp", 1) + `,`,
+		`}`,
+	}, "")
+	return s
+}
 func valueToStringTypes(v interface{}) string {
 	rv := reflect.ValueOf(v)
 	if rv.IsNil() {
@@ -20502,6 +20636,128 @@ func (m *Privileges_SELinuxContext) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *JobStatus) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTypes
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= uint64(b&0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: JobStatus: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: JobStatus: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JobIteration", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTypes
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthTypes
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthTypes
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.JobIteration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LastExecution", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTypes
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthTypes
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthTypes
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.LastExecution == nil {
+				m.LastExecution = &types.Timestamp{}
+			}
+			if err := m.LastExecution.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTypes(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthTypes
+			}
+			if (iNdEx + skippy) < 0 {
+				return ErrInvalidLengthTypes
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func skipTypes(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0

+ 16 - 0
vendor/github.com/docker/swarmkit/api/types.proto

@@ -1115,3 +1115,19 @@ message Privileges {
 	}
 	SELinuxContext selinux_context = 2 [(gogoproto.customname) = "SELinuxContext"];
 }
+
+// JobStatus indicates the status of a Service that is in one of the Job modes.
+message JobStatus {
+	// JobIteration is the count of how many times the Job has been excecuted,
+	// successfully or otherwise. "Executed" refers to the job as a whole being
+	// started, not to the individual Tasks being launched. This is used to
+	// disambiguate which Tasks belong to which iteration of a Job.
+	Version job_iteration = 1 [(gogoproto.nullable) = false];
+
+	// LastExecution is the time that the job was last executed. This is set by
+	// the orchestrator in the same transaction that JobIteration is incremented.
+	// While time is a fungible concept in distributed systems like Swarmkit,
+	// this value gives us a best-effort attempt to prevent weird behavior like
+	// newly added nodes executing long-forgotten jobs.
+	google.protobuf.Timestamp last_execution = 2;
+}

+ 99 - 7
vendor/github.com/docker/swarmkit/manager/controlapi/service.go

@@ -474,12 +474,32 @@ func (s *Server) validateNetworks(networks []*api.NetworkAttachmentConfig) error
 
 func validateMode(s *api.ServiceSpec) error {
 	m := s.GetMode()
-	switch m.(type) {
+	switch mode := m.(type) {
 	case *api.ServiceSpec_Replicated:
-		if int64(m.(*api.ServiceSpec_Replicated).Replicated.Replicas) < 0 {
+		if int64(mode.Replicated.Replicas) < 0 {
 			return status.Errorf(codes.InvalidArgument, "Number of replicas must be non-negative")
 		}
 	case *api.ServiceSpec_Global:
+	case *api.ServiceSpec_ReplicatedJob:
+		// this check shouldn't be required as the point of uint64 is to
+		// constrain the possible values to positive numbers, but it almost
+		// certainly is required because there are almost certainly blind casts
+		// from int64 to uint64, and uint64(-1) is almost certain to crash the
+		// cluster because of how large it is.
+		if int64(mode.ReplicatedJob.MaxConcurrent) < 0 {
+			return status.Errorf(
+				codes.InvalidArgument,
+				"Maximum concurrent jobs must not be negative",
+			)
+		}
+
+		if int64(mode.ReplicatedJob.TotalCompletions) < 0 {
+			return status.Errorf(
+				codes.InvalidArgument,
+				"Total completed jobs must not be negative",
+			)
+		}
+	case *api.ServiceSpec_GlobalJob:
 	default:
 		return status.Errorf(codes.InvalidArgument, "Unrecognized service mode")
 	}
@@ -487,6 +507,13 @@ func validateMode(s *api.ServiceSpec) error {
 	return nil
 }
 
+func validateJob(spec *api.ServiceSpec) error {
+	if spec.Update != nil {
+		return status.Errorf(codes.InvalidArgument, "Jobs may not have an update config")
+	}
+	return nil
+}
+
 func validateServiceSpec(spec *api.ServiceSpec) error {
 	if spec == nil {
 		return status.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
@@ -497,13 +524,32 @@ func validateServiceSpec(spec *api.ServiceSpec) error {
 	if err := validateTaskSpec(spec.Task); err != nil {
 		return err
 	}
-	if err := validateUpdate(spec.Update); err != nil {
+	err := validateMode(spec)
+	if err != nil {
 		return err
 	}
-	if err := validateEndpointSpec(spec.Endpoint); err != nil {
-		return err
+
+	// job-mode services are validated differently. most notably, they do not
+	// have UpdateConfigs, which is why this case statement skips update
+	// validation.
+	if isJobSpec(spec) {
+		if err := validateJob(spec); err != nil {
+			return err
+		}
+	} else {
+		if err := validateUpdate(spec.Update); err != nil {
+			return err
+		}
 	}
-	return validateMode(spec)
+
+	return validateEndpointSpec(spec.Endpoint)
+}
+
+func isJobSpec(spec *api.ServiceSpec) bool {
+	mode := spec.GetMode()
+	_, isGlobalJob := mode.(*api.ServiceSpec_GlobalJob)
+	_, isReplicatedJob := mode.(*api.ServiceSpec_ReplicatedJob)
+	return isGlobalJob || isReplicatedJob
 }
 
 // checkPortConflicts does a best effort to find if the passed in spec has port
@@ -689,6 +735,12 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe
 		SpecVersion: &api.Version{},
 	}
 
+	if isJobSpec(request.Spec) {
+		service.JobStatus = &api.JobStatus{
+			LastExecution: gogotypes.TimestampNow(),
+		}
+	}
+
 	if allocator.IsIngressNetworkNeeded(service) {
 		if _, err := allocator.GetIngressNetwork(s.store); err == allocator.ErrNoIngress {
 			return nil, status.Errorf(codes.FailedPrecondition, "service needs ingress network, but no ingress network is present")
@@ -819,6 +871,13 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
 
 		service.Meta.Version = *request.ServiceVersion
 
+		// if the service has a JobStatus, that means it must be a Job, and we
+		// should increment the JobIteration
+		if service.JobStatus != nil {
+			service.JobStatus.JobIteration.Index = service.JobStatus.JobIteration.Index + 1
+			service.JobStatus.LastExecution = gogotypes.TimestampNow()
+		}
+
 		if request.Rollback == api.UpdateServiceRequest_PREVIOUS {
 			if service.PreviousSpec == nil {
 				return status.Errorf(codes.FailedPrecondition, "service %s does not have a previous spec", request.ServiceID)
@@ -999,6 +1058,10 @@ func (s *Server) ListServiceStatuses(ctx context.Context, req *api.ListServiceSt
 			// use a boolean to see global vs replicated. this avoids us having to
 			// iterate the task list twice.
 			global := false
+			// jobIteration is the iteration that the Job is currently
+			// operating on, to distinguish Tasks in old executions from tasks
+			// in the current one. if nil, service is not a Job
+			var jobIteration *api.Version
 			service := store.GetService(tx, id)
 			// a service might be deleted, but it may still have tasks. in that
 			// case, we will be using 0 as the desired task count.
@@ -1009,23 +1072,52 @@ func (s *Server) ListServiceStatuses(ctx context.Context, req *api.ListServiceSt
 				// numbercrunchin
 				if replicated := service.Spec.GetReplicated(); replicated != nil {
 					status.DesiredTasks = replicated.Replicas
+				} else if replicatedJob := service.Spec.GetReplicatedJob(); replicatedJob != nil {
+					status.DesiredTasks = replicatedJob.MaxConcurrent
 				} else {
+					// global applies to both GlobalJob and regular Global
 					global = true
 				}
+
+				if service.JobStatus != nil {
+					jobIteration = &service.JobStatus.JobIteration
+				}
 			}
 
 			// now, figure out how many tasks are running. Pretty easy, and
 			// universal across both global and replicated services
 			for _, task := range tasks {
+				// if the service is a Job, jobIteration will be non-nil. This
+				// means we should check if the task belongs to the current job
+				// iteration. If not, skip accounting the task.
+				if jobIteration != nil {
+					if task.JobIteration == nil || task.JobIteration.Index != jobIteration.Index {
+						continue
+					}
+
+					// additionally, since we've verified that the service is a
+					// job and the task belongs to this iteration, we should
+					// increment CompletedTasks
+					if task.Status.State == api.TaskStateCompleted {
+						status.CompletedTasks++
+					}
+				}
 				if task.Status.State == api.TaskStateRunning {
 					status.RunningTasks++
 				}
-				// if the service is global,  a shortcut for figuring out the
+
+				// if the service is global, a shortcut for figuring out the
 				// number of tasks desired is to look at all tasks, and take a
 				// count of the ones whose desired state is not Shutdown.
 				if global && task.DesiredState == api.TaskStateRunning {
 					status.DesiredTasks++
 				}
+
+				// for jobs, this is any task with desired state Completed
+				// which is not actually in that state.
+				if global && task.Status.State != api.TaskStateCompleted && task.DesiredState == api.TaskStateCompleted {
+					status.DesiredTasks++
+				}
 			}
 		}
 	})

+ 11 - 0
vendor/github.com/docker/swarmkit/manager/manager.go

@@ -33,6 +33,7 @@ import (
 	"github.com/docker/swarmkit/manager/metrics"
 	"github.com/docker/swarmkit/manager/orchestrator/constraintenforcer"
 	"github.com/docker/swarmkit/manager/orchestrator/global"
+	"github.com/docker/swarmkit/manager/orchestrator/jobs"
 	"github.com/docker/swarmkit/manager/orchestrator/replicated"
 	"github.com/docker/swarmkit/manager/orchestrator/taskreaper"
 	"github.com/docker/swarmkit/manager/resourceapi"
@@ -146,6 +147,7 @@ type Manager struct {
 	watchServer            *watchapi.Server
 	replicatedOrchestrator *replicated.Orchestrator
 	globalOrchestrator     *global.Orchestrator
+	jobsOrchestrator       *jobs.Orchestrator
 	taskReaper             *taskreaper.TaskReaper
 	constraintEnforcer     *constraintenforcer.ConstraintEnforcer
 	scheduler              *scheduler.Scheduler
@@ -681,6 +683,9 @@ func (m *Manager) Stop(ctx context.Context, clearData bool) {
 	if m.globalOrchestrator != nil {
 		m.globalOrchestrator.Stop()
 	}
+	if m.jobsOrchestrator != nil {
+		m.jobsOrchestrator.Stop()
+	}
 	if m.taskReaper != nil {
 		m.taskReaper.Stop()
 	}
@@ -994,6 +999,7 @@ func (m *Manager) becomeLeader(ctx context.Context) {
 	m.replicatedOrchestrator = replicated.NewReplicatedOrchestrator(s)
 	m.constraintEnforcer = constraintenforcer.New(s)
 	m.globalOrchestrator = global.NewGlobalOrchestrator(s)
+	m.jobsOrchestrator = jobs.NewOrchestrator(s)
 	m.taskReaper = taskreaper.New(s)
 	m.scheduler = scheduler.New(s)
 	m.keyManager = keymanager.New(s, keymanager.DefaultConfig())
@@ -1090,6 +1096,11 @@ func (m *Manager) becomeLeader(ctx context.Context) {
 		}
 	}(m.replicatedOrchestrator)
 
+	go func(orchestrator *jobs.Orchestrator) {
+		// jobs orchestrator does not return errors.
+		orchestrator.Run(ctx)
+	}(m.jobsOrchestrator)
+
 	go func(globalOrchestrator *global.Orchestrator) {
 		if err := globalOrchestrator.Run(ctx); err != nil {
 			log.G(ctx).WithError(err).Error("global orchestrator exited with an error")

+ 2 - 2
vendor/github.com/docker/swarmkit/manager/orchestrator/constraintenforcer/constraint_enforcer.go

@@ -115,7 +115,7 @@ func (ce *ConstraintEnforcer) rejectNoncompliantTasks(node *api.Node) {
 	// to remove the most resource-intensive tasks.
 loop:
 	for _, t := range tasks {
-		if t.DesiredState < api.TaskStateAssigned || t.DesiredState > api.TaskStateRunning {
+		if t.DesiredState < api.TaskStateAssigned || t.DesiredState > api.TaskStateCompleted {
 			continue
 		}
 
@@ -195,7 +195,7 @@ loop:
 			for _, t := range removeTasks {
 				err := batch.Update(func(tx store.Tx) error {
 					t = store.GetTask(tx, t.ID)
-					if t == nil || t.DesiredState > api.TaskStateRunning {
+					if t == nil || t.DesiredState > api.TaskStateCompleted {
 						return nil
 					}
 

+ 301 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/jobs/global/reconciler.go

@@ -0,0 +1,301 @@
+package global
+
+import (
+	"context"
+
+	"github.com/docker/swarmkit/api"
+	"github.com/docker/swarmkit/manager/constraint"
+	"github.com/docker/swarmkit/manager/orchestrator"
+	"github.com/docker/swarmkit/manager/state/store"
+)
+
+// restartSupervisor is an interface representing the methods from the
+// restart.SupervisorInterface that are actually needed by the reconciler. This
+// more limited interface allows us to write a less ugly fake for unit testing.
+type restartSupervisor interface {
+	Restart(context.Context, store.Tx, *api.Cluster, *api.Service, api.Task) error
+}
+
+// Reconciler is an object that manages reconciliation of global jobs. It is
+// blocking and non-asynchronous, for ease of testing. It implements the
+// Reconciler interface from the orchestrator package above it, and the
+// taskinit.InitHandler interface.
+type Reconciler struct {
+	store *store.MemoryStore
+
+	restart restartSupervisor
+}
+
+// NewReconciler creates a new global job reconciler.
+func NewReconciler(store *store.MemoryStore, restart restartSupervisor) *Reconciler {
+	return &Reconciler{
+		store:   store,
+		restart: restart,
+	}
+}
+
+// ReconcileService reconciles one global job service.
+func (r *Reconciler) ReconcileService(id string) error {
+	var (
+		service *api.Service
+		cluster *api.Cluster
+		tasks   []*api.Task
+		nodes   []*api.Node
+		viewErr error
+	)
+
+	// we need to first get the latest iteration of the service, its tasks, and
+	// the nodes in the cluster.
+	r.store.View(func(tx store.ReadTx) {
+		service = store.GetService(tx, id)
+		if service == nil {
+			return
+		}
+
+		// getting tasks with FindTasks should only return an error if we've
+		// made a mistake coding; there's no user-input or even reasonable
+		// system state that can cause it. If it returns an error, we'll just
+		// panic and crash.
+		tasks, viewErr = store.FindTasks(tx, store.ByServiceID(id))
+		if viewErr != nil {
+			return
+		}
+
+		// same as with FindTasks
+		nodes, viewErr = store.FindNodes(tx, store.All)
+		if viewErr != nil {
+			return
+		}
+
+		clusters, _ := store.FindClusters(tx, store.All)
+		if len(clusters) == 1 {
+			cluster = clusters[0]
+		} else if len(clusters) > 1 {
+			panic("there should never be more than one cluster object")
+		}
+	})
+
+	if viewErr != nil {
+		return viewErr
+	}
+
+	// the service may be nil if the service has been deleted before we entered
+	// the View.
+	if service == nil {
+		return nil
+	}
+
+	if service.JobStatus == nil {
+		service.JobStatus = &api.JobStatus{}
+	}
+
+	// we need to compute the constraints on the service so we know which nodes
+	// to schedule it on
+	var constraints []constraint.Constraint
+	if service.Spec.Task.Placement != nil && len(service.Spec.Task.Placement.Constraints) != 0 {
+		// constraint.Parse does return an error, but we don't need to check
+		// it, because it was already checked when the service was created or
+		// updated.
+		constraints, _ = constraint.Parse(service.Spec.Task.Placement.Constraints)
+	}
+
+	var candidateNodes []string
+	var invalidNodes []string
+	for _, node := range nodes {
+		// instead of having a big ugly multi-line boolean expression in the
+		// if-statement, we'll have several if-statements, and bail out of
+		// this loop iteration with continue if the node is not acceptable
+		if !constraint.NodeMatches(constraints, node) {
+			continue
+		}
+
+		// if a node is invalid, we should remove any tasks that might be on it
+		if orchestrator.InvalidNode(node) {
+			invalidNodes = append(invalidNodes, node.ID)
+			continue
+		}
+
+		if node.Spec.Availability != api.NodeAvailabilityActive {
+			continue
+		}
+		if node.Status.State != api.NodeStatus_READY {
+			continue
+		}
+		// you can append to a nil slice and get a non-nil slice, which is
+		// pretty slick.
+		candidateNodes = append(candidateNodes, node.ID)
+	}
+
+	// now, we have a list of all nodes that match constraints. it's time to
+	// match running tasks to the nodes. we need to identify all nodes that
+	// need new tasks, which is any node that doesn't have a task of this job
+	// iteration. trade some space for some time by building a node ID to task
+	// ID mapping, so that we're just doing 2x linear operation, instead of a
+	// quadratic operation.
+	nodeToTask := map[string]string{}
+	// additionally, while we're iterating through tasks, if any of those tasks
+	// are failed, we'll hand them to the restart supervisor to handle
+	restartTasks := []string{}
+	// and if there are any tasks belonging to old job iterations, set them to
+	// be removed
+	removeTasks := []string{}
+	for _, task := range tasks {
+		// match all tasks belonging to this job iteration which are in desired
+		// state completed, including failed tasks. We only want to create
+		// tasks for nodes on which there are no existing tasks.
+		if task.JobIteration != nil {
+			if task.JobIteration.Index == service.JobStatus.JobIteration.Index &&
+				task.DesiredState <= api.TaskStateCompleted {
+				// we already know the task is desired to be executing (because its
+				// desired state is Completed). Check here to see if it's already
+				// failed, so we can restart it
+				if task.Status.State > api.TaskStateCompleted {
+					restartTasks = append(restartTasks, task.ID)
+				}
+				nodeToTask[task.NodeID] = task.ID
+			}
+
+			if task.JobIteration.Index != service.JobStatus.JobIteration.Index {
+				if task.DesiredState != api.TaskStateRemove {
+					removeTasks = append(removeTasks, task.ID)
+				}
+			}
+		}
+	}
+
+	return r.store.Batch(func(batch *store.Batch) error {
+		// first, create any new tasks required.
+		for _, node := range candidateNodes {
+			// check if there is a task for this node ID. If not, then we need
+			// to create one.
+			if _, ok := nodeToTask[node]; !ok {
+				if err := batch.Update(func(tx store.Tx) error {
+					// if the node does not already have a running or completed
+					// task, create a task for this node.
+					task := orchestrator.NewTask(cluster, service, 0, node)
+					task.JobIteration = &service.JobStatus.JobIteration
+					task.DesiredState = api.TaskStateCompleted
+					return store.CreateTask(tx, task)
+				}); err != nil {
+					return err
+				}
+			}
+		}
+
+		// then, restart any tasks that are failed
+		for _, taskID := range restartTasks {
+			if err := batch.Update(func(tx store.Tx) error {
+				// get the latest version of the task for the restart
+				t := store.GetTask(tx, taskID)
+				// if it's deleted, nothing to do
+				if t == nil {
+					return nil
+				}
+
+				// if it's not still desired to be running, then don't restart
+				// it.
+				if t.DesiredState > api.TaskStateCompleted {
+					return nil
+				}
+
+				// Finally, restart it
+				// TODO(dperny): pass in context to ReconcileService, so we can
+				// pass it in here.
+				return r.restart.Restart(context.Background(), tx, cluster, service, *t)
+			}); err != nil {
+				// TODO(dperny): probably should log like in the other
+				// orchestrators instead of returning here.
+				return err
+			}
+		}
+
+		// remove tasks that need to be removed
+		for _, taskID := range removeTasks {
+			if err := batch.Update(func(tx store.Tx) error {
+				t := store.GetTask(tx, taskID)
+				if t == nil {
+					return nil
+				}
+
+				if t.DesiredState == api.TaskStateRemove {
+					return nil
+				}
+
+				t.DesiredState = api.TaskStateRemove
+				return store.UpdateTask(tx, t)
+			}); err != nil {
+				return err
+			}
+		}
+
+		// finally, shut down any tasks on invalid nodes
+		for _, nodeID := range invalidNodes {
+			if taskID, ok := nodeToTask[nodeID]; ok {
+				if err := batch.Update(func(tx store.Tx) error {
+					t := store.GetTask(tx, taskID)
+					if t == nil {
+						return nil
+					}
+					// if the task is still desired to be running, and is still
+					// actually, running, then it still needs to be shut down.
+					if t.DesiredState > api.TaskStateCompleted || t.Status.State <= api.TaskStateRunning {
+						t.DesiredState = api.TaskStateShutdown
+						return store.UpdateTask(tx, t)
+					}
+					return nil
+				}); err != nil {
+					return err
+				}
+			}
+		}
+		return nil
+	})
+}
+
+// IsRelatedService returns true if the task is a global job. This method
+// fulfills the taskinit.InitHandler interface. Because it is just a wrapper
+// around a well-tested function call, it has no tests of its own.
+func (r *Reconciler) IsRelatedService(service *api.Service) bool {
+	return orchestrator.IsGlobalJob(service)
+}
+
+// FixTask validates that a task is compliant with the rest of the cluster
+// state, and fixes it if it's not. This covers some main scenarios:
+//
+// * The node that the task is running on is now paused or drained. we do not
+//   need to check if the node still meets constraints -- that is the purview
+//   of the constraint enforcer.
+// * The task has failed and needs to be restarted.
+//
+// This implements the FixTask method of the taskinit.InitHandler interface.
+func (r *Reconciler) FixTask(ctx context.Context, batch *store.Batch, t *api.Task) {
+	// tasks already desired to be shut down need no action.
+	if t.DesiredState > api.TaskStateCompleted {
+		return
+	}
+
+	batch.Update(func(tx store.Tx) error {
+		node := store.GetNode(tx, t.NodeID)
+		// if the node is no longer a valid node for this task, we need to shut
+		// it down
+		if orchestrator.InvalidNode(node) {
+			task := store.GetTask(tx, t.ID)
+			if task != nil && task.DesiredState < api.TaskStateShutdown {
+				task.DesiredState = api.TaskStateShutdown
+				return store.UpdateTask(tx, task)
+			}
+		}
+		// we will reconcile all services after fixing the tasks, so we don't
+		// need to restart tasks right now; we'll do so after this.
+		return nil
+	})
+}
+
+// SlotTuple returns a slot tuple representing this task. It implements the
+// taskinit.InitHandler interface.
+func (r *Reconciler) SlotTuple(t *api.Task) orchestrator.SlotTuple {
+	return orchestrator.SlotTuple{
+		ServiceID: t.ServiceID,
+		NodeID:    t.NodeID,
+	}
+}

+ 250 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/jobs/orchestrator.go

@@ -0,0 +1,250 @@
+package jobs
+
+import (
+	"context"
+	"sync"
+
+	"github.com/docker/go-events"
+
+	"github.com/docker/swarmkit/api"
+	"github.com/docker/swarmkit/log"
+	"github.com/docker/swarmkit/manager/orchestrator"
+	"github.com/docker/swarmkit/manager/orchestrator/jobs/global"
+	"github.com/docker/swarmkit/manager/orchestrator/jobs/replicated"
+	"github.com/docker/swarmkit/manager/orchestrator/restart"
+	"github.com/docker/swarmkit/manager/orchestrator/taskinit"
+	"github.com/docker/swarmkit/manager/state/store"
+)
+
+// Reconciler is the type that holds the reconciliation logic for the
+// orchestrator. It exists so that the logic of actually reconciling and
+// writing to the store is separated from the orchestrator, to make the event
+// handling logic in the orchestrator easier to test.
+type Reconciler interface {
+	taskinit.InitHandler
+
+	ReconcileService(id string) error
+}
+
+// Orchestrator is the combined orchestrator controlling both Global and
+// Replicated Jobs. Initially, these job types were two separate orchestrators,
+// like the Replicated and Global orchestrators. However, it became apparent
+// that because of the simplicity of Jobs as compared to Services, one combined
+// orchestrator suffices for both job types.
+type Orchestrator struct {
+	store *store.MemoryStore
+
+	// two reconcilers, one for each service type
+
+	replicatedReconciler Reconciler
+	globalReconciler     Reconciler
+
+	// startOnce is a function that stops the orchestrator from being started
+	// multiple times.
+	startOnce sync.Once
+
+	// restartSupervisor is the component that handles restarting tasks
+	restartSupervisor restart.SupervisorInterface
+
+	// stopChan is a channel that is closed to signal the orchestrator to stop
+	// running
+	stopChan chan struct{}
+	// stopOnce is used to ensure that stopChan can only be closed once, just
+	// in case some freak accident causes subsequent calls to Stop.
+	stopOnce sync.Once
+	// doneChan is closed when the orchestrator actually stops running
+	doneChan chan struct{}
+
+	// checkTasksFunc is a variable that hold taskinit.CheckTasks, but allows
+	// swapping it out in testing.
+	checkTasksFunc func(context.Context, *store.MemoryStore, store.ReadTx, taskinit.InitHandler, restart.SupervisorInterface) error
+
+	// the watchChan and watchCancel provide the event stream
+	watchChan   chan events.Event
+	watchCancel func()
+}
+
+func NewOrchestrator(store *store.MemoryStore) *Orchestrator {
+	return &Orchestrator{
+		store:    store,
+		stopChan: make(chan struct{}),
+		doneChan: make(chan struct{}),
+	}
+}
+
+// Run runs the Orchestrator reconciliation loop. It takes a context as an
+// argument, but canceling this context will not stop the routine; this context
+// is only for passing in logging information. Call Stop to stop the
+// Orchestrator
+func (o *Orchestrator) Run(ctx context.Context) {
+	o.startOnce.Do(func() { o.run(ctx) })
+}
+
+// init runs the once-off initialization logic for the orchestrator. This
+// includes initializing the sub-components, starting the channel watch, and
+// running the initial reconciliation pass. this runs as part of the run
+// method, but is broken out for the purpose of testing.
+func (o *Orchestrator) init(ctx context.Context) {
+	var (
+		services []*api.Service
+	)
+
+	// there are several components to the Orchestrator that are interfaces
+	// designed to be swapped out in testing. in production, these fields will
+	// all be unset, and be initialized here. in testing, we will set fakes,
+	// and this initialization will be skipped.
+
+	if o.restartSupervisor == nil {
+		o.restartSupervisor = restart.NewSupervisor(o.store)
+	}
+
+	if o.replicatedReconciler == nil {
+		// the cluster might be nil, but that doesn't matter.
+		o.replicatedReconciler = replicated.NewReconciler(o.store, o.restartSupervisor)
+	}
+
+	if o.globalReconciler == nil {
+		o.globalReconciler = global.NewReconciler(o.store, o.restartSupervisor)
+	}
+
+	if o.checkTasksFunc == nil {
+		o.checkTasksFunc = taskinit.CheckTasks
+	}
+
+	o.watchChan, o.watchCancel, _ = store.ViewAndWatch(o.store, func(tx store.ReadTx) error {
+		services, _ = store.FindServices(tx, store.All)
+		return nil
+	})
+
+	// checkTasksFunc is used to resume any in-progress restarts that were
+	// interrupted by a leadership change. In other orchestrators, this
+	// additionally queues up some tasks to be restarted. However, the jobs
+	// orchestrator will make a reconciliation pass across all services
+	// immediately after this, and so does not need to restart any tasks; they
+	// will be restarted during this pass.
+	//
+	// we cannot call o.checkTasksFunc inside of store.ViewAndWatch above.
+	// despite taking a callback with a ReadTx, it actually performs an Update,
+	// which acquires a lock and will result in a deadlock. instead, do
+	// o.checkTasksFunc here.
+	o.store.View(func(tx store.ReadTx) {
+		o.checkTasksFunc(ctx, o.store, tx, o.replicatedReconciler, o.restartSupervisor)
+		o.checkTasksFunc(ctx, o.store, tx, o.globalReconciler, o.restartSupervisor)
+	})
+
+	for _, service := range services {
+		if orchestrator.IsReplicatedJob(service) {
+			if err := o.replicatedReconciler.ReconcileService(service.ID); err != nil {
+				log.G(ctx).WithField(
+					"service.id", service.ID,
+				).WithError(err).Error("error reconciling replicated job")
+			}
+		}
+
+		if orchestrator.IsGlobalJob(service) {
+			if err := o.globalReconciler.ReconcileService(service.ID); err != nil {
+				log.G(ctx).WithField(
+					"service.id", service.ID,
+				).WithError(err).Error("error reconciling global job")
+			}
+		}
+	}
+}
+
+// run provides the actual meat of the the run operation. The call to run is
+// made inside of Run, and is enclosed in a sync.Once to stop this from being
+// called multiple times
+func (o *Orchestrator) run(ctx context.Context) {
+	ctx = log.WithModule(ctx, "orchestrator/jobs")
+
+	// closing doneChan should be the absolute last thing that happens in this
+	// method, and so should be the absolute first thing we defer.
+	defer close(o.doneChan)
+
+	o.init(ctx)
+	defer o.watchCancel()
+
+	for {
+		// first, before taking any action, see if we should stop the
+		// orchestrator. if both the stop channel and the watch channel are
+		// available to read, the channel that gets read is picked at random,
+		// but we always want to stop if it's possible.
+		select {
+		case <-o.stopChan:
+			return
+		default:
+		}
+
+		select {
+		case event := <-o.watchChan:
+			o.handleEvent(ctx, event)
+		case <-o.stopChan:
+			// we also need to check for stop in here, in case there are no
+			// updates to cause the loop to turn over.
+			return
+		}
+	}
+}
+
+// handle event does the logic of handling one event message and calling the
+// reconciler as needed. by handling the event logic in this function, we can
+// make an end-run around the run-loop and avoid being at the mercy of the go
+// scheduler when testing the orchestrator.
+func (o *Orchestrator) handleEvent(ctx context.Context, event events.Event) {
+	var (
+		service *api.Service
+		task    *api.Task
+	)
+
+	switch ev := event.(type) {
+	case api.EventCreateService:
+		service = ev.Service
+	case api.EventUpdateService:
+		service = ev.Service
+	case api.EventUpdateTask:
+		task = ev.Task
+	}
+
+	// if this is a task event, we should check if it means the service
+	// should be reconciled.
+	if task != nil {
+		// only bother with all this if the task has entered a terminal
+		// state and we don't want that to have happened.
+		if task.Status.State > api.TaskStateRunning && task.DesiredState <= api.TaskStateCompleted {
+			o.store.View(func(tx store.ReadTx) {
+				// if for any reason the service ID is invalid, then
+				// service will just be nil and nothing needs to be
+				// done
+				service = store.GetService(tx, task.ServiceID)
+			})
+		}
+	}
+
+	if orchestrator.IsReplicatedJob(service) {
+		if err := o.replicatedReconciler.ReconcileService(service.ID); err != nil {
+			log.G(ctx).WithField(
+				"service.id", service.ID,
+			).WithError(err).Error("error reconciling replicated job")
+		}
+	}
+
+	if orchestrator.IsGlobalJob(service) {
+		if err := o.globalReconciler.ReconcileService(service.ID); err != nil {
+			log.G(ctx).WithField(
+				"service.id", service.ID,
+			).WithError(err).Error("error reconciling global job")
+		}
+	}
+}
+
+// Stop stops the Orchestrator
+func (o *Orchestrator) Stop() {
+	// close stopChan inside of the Once so that there can be no races
+	// involving multiple attempts to close stopChan.
+	o.stopOnce.Do(func() {
+		close(o.stopChan)
+	})
+	// now, we wait for the Orchestrator to stop. this wait is unqualified; we
+	// will not return until Orchestrator has stopped successfully.
+	<-o.doneChan
+}

+ 296 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/jobs/replicated/reconciler.go

@@ -0,0 +1,296 @@
+package replicated
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/docker/swarmkit/api"
+	"github.com/docker/swarmkit/manager/orchestrator"
+	"github.com/docker/swarmkit/manager/state/store"
+)
+
+// restartSupervisor is an interface representing the methods from the
+// restart.SupervisorInterface that are actually needed by the reconciler. This
+// more limited interface allows us to write a less ugly fake for unit testing.
+type restartSupervisor interface {
+	Restart(context.Context, store.Tx, *api.Cluster, *api.Service, api.Task) error
+}
+
+// Reconciler is an object that manages reconciliation of replicated jobs. It
+// is blocking and non-asynchronous, for ease of testing. It implements two
+// interfaces. The first is the Reconciler interface of the Orchestrator
+// package above this one. The second is the taskinit.InitHandler interface.
+type Reconciler struct {
+	// we need the store, of course, to do updates
+	store *store.MemoryStore
+
+	restart restartSupervisor
+}
+
+// newReconciler creates a new reconciler object
+func NewReconciler(store *store.MemoryStore, restart restartSupervisor) *Reconciler {
+	return &Reconciler{
+		store:   store,
+		restart: restart,
+	}
+}
+
+// ReconcileService reconciles the replicated job service with the given ID by
+// checking to see if new replicas should be created. reconcileService returns
+// an error if there is some case prevent it from correctly reconciling the
+// service.
+func (r *Reconciler) ReconcileService(id string) error {
+	var (
+		service *api.Service
+		tasks   []*api.Task
+		cluster *api.Cluster
+		viewErr error
+	)
+	// first, get the service and all of its tasks
+	r.store.View(func(tx store.ReadTx) {
+		service = store.GetService(tx, id)
+
+		tasks, viewErr = store.FindTasks(tx, store.ByServiceID(id))
+
+		// there should only ever be 1 cluster object, but for reasons
+		// forgotten by me, it needs to be retrieved in a rather roundabout way
+		// from the store
+		var clusters []*api.Cluster
+		clusters, viewErr = store.FindClusters(tx, store.All)
+		if len(clusters) == 1 {
+			cluster = clusters[0]
+		} else if len(clusters) > 1 {
+			// this should never happen, and indicates that the system is
+			// broken.
+			panic("there should never be more than one cluster object")
+		}
+	})
+
+	// errors during view should only happen in a few rather catastrophic
+	// cases, but here it's not unreasonable to just return an error anyway.
+	if viewErr != nil {
+		return viewErr
+	}
+
+	// if the service has already been deleted, there's nothing to do here.
+	if service == nil {
+		return nil
+	}
+
+	// if this is the first iteration of the service, it may not yet have a
+	// JobStatus, so we should create one if so. this won't actually be
+	// committed, though.
+	if service.JobStatus == nil {
+		service.JobStatus = &api.JobStatus{}
+	}
+
+	// Jobs can be run in multiple iterations. The JobStatus of the service
+	// indicates which Version of iteration we're on. We should only be looking
+	// at tasks of the latest Version
+
+	jobVersion := service.JobStatus.JobIteration.Index
+
+	// now, check how many tasks we need and how many we have running. note
+	// that some of these Running tasks may complete before we even finish this
+	// code block, and so we might have to immediately re-enter reconciliation,
+	// so this number is 100% definitive, but it is accurate for this
+	// particular moment in time, and it won't result in us going OVER the
+	// needed task count
+	//
+	// importantly, we are computing only how many _new_ tasks are needed. Some
+	// tasks may need to be restarted as well, but we don't do this directly;
+	// restarting tasks is under the purview of the restartSupervisor.
+	//
+	// also also, for the math later, we need these values to be of type uint64.
+	runningTasks := uint64(0)
+	completeTasks := uint64(0)
+	restartTasks := []string{}
+	removeTasks := []string{}
+
+	// for replicated jobs, each task will get a different slot number, so that
+	// when the job has completed, there will be one Completed task in every
+	// slot number [0, TotalCompletions-1].
+	//
+	// By assigning each task to a unique slot, we simply handling of
+	// restarting failed tasks through the restart manager.
+	slots := map[uint64]bool{}
+	for _, task := range tasks {
+		// we only care about tasks from this job iteration. tasks from the
+		// previous job iteration are not important
+		if task.JobIteration != nil {
+			if task.JobIteration.Index == jobVersion {
+				if task.Status.State == api.TaskStateCompleted {
+					completeTasks++
+					slots[task.Slot] = true
+				}
+
+				// the Restart Manager may put a task in the desired state Ready,
+				// so we should match not only tasks in desired state Completed,
+				// but also those in any valid running state.
+				if task.Status.State != api.TaskStateCompleted && task.DesiredState <= api.TaskStateCompleted {
+					runningTasks++
+					slots[task.Slot] = true
+
+					// if the task is in a terminal state, we might need to restart
+					// it. throw it on the pile if so. this is still counted as a
+					// running task for the purpose of determining how many new
+					// tasks to create.
+					if task.Status.State > api.TaskStateCompleted {
+						restartTasks = append(restartTasks, task.ID)
+					}
+				}
+			} else {
+				// tasks belonging to a previous iteration of the job may
+				// exist. if any such tasks exist, they should have their task
+				// state set to Remove
+				if task.Status.State <= api.TaskStateRunning && task.DesiredState != api.TaskStateRemove {
+					removeTasks = append(removeTasks, task.ID)
+				}
+			}
+		}
+	}
+
+	// now that we have our counts, we need to see how many new tasks to
+	// create. this number can never exceed MaxConcurrent, but also should not
+	// result in us exceeding TotalCompletions. first, get these numbers out of
+	// the service spec.
+	rj := service.Spec.GetReplicatedJob()
+
+	// possibleNewTasks gives us the upper bound for how many tasks we'll
+	// create. also, ugh, subtracting uints. there's no way this can ever go
+	// wrong.
+	possibleNewTasks := rj.MaxConcurrent - runningTasks
+
+	// allowedNewTasks is how many tasks we could create, if there were no
+	// restriction on maximum concurrency. This is the total number of tasks
+	// we want completed, minus the tasks that are already completed, minus
+	// the tasks that are in progress.
+	//
+	// seriously, ugh, subtracting unsigned ints. totally a fine and not at all
+	// risky operation, with no possibility for catastrophe
+	allowedNewTasks := rj.TotalCompletions - completeTasks - runningTasks
+
+	// the lower number of allowedNewTasks and possibleNewTasks is how many we
+	// can create. we'll just use an if statement instead of some fancy floor
+	// function.
+	actualNewTasks := allowedNewTasks
+	if possibleNewTasks < allowedNewTasks {
+		actualNewTasks = possibleNewTasks
+	}
+
+	// this check might seem odd, but it protects us from an underflow of the
+	// above subtractions, which, again, is a totally impossible thing that can
+	// never happen, ever, obviously.
+	if actualNewTasks > rj.TotalCompletions {
+		return fmt.Errorf(
+			"uint64 underflow, we're not going to create %v tasks",
+			actualNewTasks,
+		)
+	}
+
+	// finally, we can create these tasks. do this in a batch operation, to
+	// avoid exceeding transaction size limits
+	err := r.store.Batch(func(batch *store.Batch) error {
+		for i := uint64(0); i < actualNewTasks; i++ {
+			if err := batch.Update(func(tx store.Tx) error {
+				var slot uint64
+				// each task will go into a unique slot, and at the end, there
+				// should be the same number of slots as there are desired
+				// total completions. We could simplify this logic by simply
+				// assuming that slots are filled in order, but it's a more
+				// robust solution to not assume that, and instead assure that
+				// the slot is unoccupied.
+				for s := uint64(0); s < rj.TotalCompletions; s++ {
+					// when we're iterating through, if the service has slots
+					// that haven't been used yet (for example, if this is the
+					// first time we're running this iteration), then doing
+					// a map lookup for the number will return the 0-value
+					// (false) even if the number doesn't exist in the map.
+					if !slots[s] {
+						slot = s
+						// once we've found a slot, mark it as occupied, so we
+						// don't double assign in subsequent iterations.
+						slots[slot] = true
+						break
+					}
+				}
+
+				task := orchestrator.NewTask(cluster, service, slot, "")
+				// when we create the task, we also need to set the
+				// JobIteration.
+				task.JobIteration = &api.Version{Index: jobVersion}
+				task.DesiredState = api.TaskStateCompleted
+
+				// finally, create the task in the store.
+				return store.CreateTask(tx, task)
+			}); err != nil {
+				return err
+			}
+		}
+
+		for _, taskID := range restartTasks {
+			if err := batch.Update(func(tx store.Tx) error {
+				t := store.GetTask(tx, taskID)
+				if t == nil {
+					return nil
+				}
+
+				if t.DesiredState > api.TaskStateCompleted {
+					return nil
+				}
+
+				// TODO(dperny): pass in context from above
+				return r.restart.Restart(context.Background(), tx, cluster, service, *t)
+			}); err != nil {
+				return err
+			}
+		}
+
+		for _, taskID := range removeTasks {
+			if err := batch.Update(func(tx store.Tx) error {
+				t := store.GetTask(tx, taskID)
+				if t == nil {
+					return nil
+				}
+
+				// don't do unnecessary updates
+				if t.DesiredState == api.TaskStateRemove {
+					return nil
+				}
+				t.DesiredState = api.TaskStateRemove
+				return store.UpdateTask(tx, t)
+			}); err != nil {
+				return err
+			}
+		}
+
+		return nil
+	})
+
+	return err
+}
+
+// IsRelatedService returns true if the task is a replicated job. This method
+// fulfills the taskinit.InitHandler interface. Because it is just a wrapper
+// around a well-tested function call, it has no tests of its own.
+func (r *Reconciler) IsRelatedService(service *api.Service) bool {
+	return orchestrator.IsReplicatedJob(service)
+}
+
+// FixTask ostensibly validates that a task is compliant with the rest of the
+// cluster state. However, in the replicated jobs case, the only action we
+// can take with a noncompliant task is to restart it. Because the replicated
+// jobs orchestrator reconciles the whole service at once, any tasks that
+// need to be restarted will be done when we make the reconiliation pass over
+// all services. Therefore, in this instance, FixTask does nothing except
+// implement the FixTask method of the taskinit.InitHandler interface.
+func (r *Reconciler) FixTask(_ context.Context, _ *store.Batch, _ *api.Task) {}
+
+// SlotTuple returns an orchestrator.SlotTuple object for this task. It
+// implements the taskinit.InitHandler interface
+func (r *Reconciler) SlotTuple(t *api.Task) orchestrator.SlotTuple {
+	return orchestrator.SlotTuple{
+		ServiceID: t.ServiceID,
+		Slot:      t.Slot,
+	}
+}

+ 43 - 5
vendor/github.com/docker/swarmkit/manager/orchestrator/restart/restart.go

@@ -49,6 +49,20 @@ type delayedStart struct {
 	waiter bool
 }
 
+// SupervisorInterface is an interface implemented by the Supervisor. It exists
+// to make testing easier, by allowing the restart supervisor to be mocked or
+// faked where desired.
+type SupervisorInterface interface {
+	Restart(context.Context, store.Tx, *api.Cluster, *api.Service, api.Task) error
+	UpdatableTasksInSlot(context.Context, orchestrator.Slot, *api.Service) orchestrator.Slot
+	RecordRestartHistory(orchestrator.SlotTuple, *api.Task)
+	DelayStart(context.Context, store.Tx, *api.Task, string, time.Duration, bool) <-chan struct{}
+	StartNow(store.Tx, string) error
+	Cancel(string)
+	CancelAll()
+	ClearServiceHistory(string)
+}
+
 // Supervisor initiates and manages restarts. It's responsible for
 // delaying restarts when applicable.
 type Supervisor struct {
@@ -121,7 +135,7 @@ func (r *Supervisor) Restart(ctx context.Context, tx store.Tx, cluster *api.Clus
 	// Sanity check: was the task shut down already by a separate call to
 	// Restart? If so, we must avoid restarting it, because this will create
 	// an extra task. This should never happen unless there is a bug.
-	if t.DesiredState > api.TaskStateRunning {
+	if t.DesiredState > api.TaskStateCompleted {
 		return errors.New("Restart called on task that was already shut down")
 	}
 
@@ -138,15 +152,21 @@ func (r *Supervisor) Restart(ctx context.Context, tx store.Tx, cluster *api.Clus
 
 	var restartTask *api.Task
 
-	if orchestrator.IsReplicatedService(service) {
+	if orchestrator.IsReplicatedService(service) || orchestrator.IsReplicatedJob(service) {
 		restartTask = orchestrator.NewTask(cluster, service, t.Slot, "")
-	} else if orchestrator.IsGlobalService(service) {
+	} else if orchestrator.IsGlobalService(service) || orchestrator.IsGlobalJob(service) {
 		restartTask = orchestrator.NewTask(cluster, service, 0, t.NodeID)
 	} else {
 		log.G(ctx).Error("service not supported by restart supervisor")
 		return nil
 	}
 
+	if orchestrator.IsReplicatedJob(service) || orchestrator.IsGlobalJob(service) {
+		restartTask.JobIteration = &api.Version{
+			Index: service.JobStatus.JobIteration.Index,
+		}
+	}
+
 	n := store.GetNode(tx, t.NodeID)
 
 	restartTask.DesiredState = api.TaskStateReady
@@ -197,7 +217,17 @@ func (r *Supervisor) shouldRestart(ctx context.Context, t *api.Task, service *ap
 	// There are 3 possible restart policies.
 	switch orchestrator.RestartCondition(t) {
 	case api.RestartOnAny:
-		// we will be restarting, we just need to do a few more checks
+		// we will be restarting, we just need to do a few more checks.
+		// however, if the task belongs to a job, then we will treat
+		// RestartOnAny the same as RestartOnFailure, as it would be
+		// nonsensical to restart completed jobs.
+		if orchestrator.IsReplicatedJob(service) || orchestrator.IsGlobalJob(service) {
+			// it'd be nice to put a fallthrough here, but we can't fallthrough
+			// from inside of an if statement.
+			if t.Status.State == api.TaskStateCompleted {
+				return false
+			}
+		}
 	case api.RestartOnFailure:
 		// we won't restart if the task is in TaskStateCompleted, as this is a
 		// not a failed state -- it indicates that the task exited with 0
@@ -498,7 +528,15 @@ func (r *Supervisor) StartNow(tx store.Tx, taskID string) error {
 	if t == nil || t.DesiredState >= api.TaskStateRunning {
 		return nil
 	}
-	t.DesiredState = api.TaskStateRunning
+
+	// only tasks belonging to jobs will have a JobIteration, so this can be
+	// used to distinguish whether this is a job task without looking at the
+	// service.
+	if t.JobIteration != nil {
+		t.DesiredState = api.TaskStateCompleted
+	} else {
+		t.DesiredState = api.TaskStateRunning
+	}
 	return store.UpdateTask(tx, t)
 }
 

+ 20 - 0
vendor/github.com/docker/swarmkit/manager/orchestrator/service.go

@@ -28,6 +28,26 @@ func IsGlobalService(service *api.Service) bool {
 	return ok
 }
 
+// IsReplicatedJob returns true if the service is a replicated job.
+func IsReplicatedJob(service *api.Service) bool {
+	if service == nil {
+		return false
+	}
+
+	_, ok := service.Spec.GetMode().(*api.ServiceSpec_ReplicatedJob)
+	return ok
+}
+
+// IsGlobalJob returns true if the service is a global job.
+func IsGlobalJob(service *api.Service) bool {
+	if service == nil {
+		return false
+	}
+
+	_, ok := service.Spec.GetMode().(*api.ServiceSpec_GlobalJob)
+	return ok
+}
+
 // SetServiceTasksRemove sets the desired state of tasks associated with a service
 // to REMOVE, so that they can be properly shut down by the agent and later removed
 // by the task reaper.

+ 2 - 2
vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go

@@ -23,7 +23,7 @@ type InitHandler interface {
 
 // CheckTasks fixes tasks in the store before orchestrator runs. The previous leader might
 // not have finished processing their updates and left them in an inconsistent state.
-func CheckTasks(ctx context.Context, s *store.MemoryStore, readTx store.ReadTx, initHandler InitHandler, startSupervisor *restart.Supervisor) error {
+func CheckTasks(ctx context.Context, s *store.MemoryStore, readTx store.ReadTx, initHandler InitHandler, startSupervisor restart.SupervisorInterface) error {
 	instances := make(map[orchestrator.SlotTuple][]*api.Task)
 	err := s.Batch(func(batch *store.Batch) error {
 		tasks, err := store.FindTasks(readTx, store.All)
@@ -59,7 +59,7 @@ func CheckTasks(ctx context.Context, s *store.MemoryStore, readTx store.ReadTx,
 
 			// desired state ready is a transient state that it should be started.
 			// however previous leader may not have started it, retry start here
-			if t.DesiredState != api.TaskStateReady || t.Status.State > api.TaskStateRunning {
+			if t.DesiredState != api.TaskStateReady || t.Status.State > api.TaskStateCompleted {
 				continue
 			}
 			restartDelay, _ := gogotypes.DurationFromProto(defaults.Service.Task.Restart.Delay)

+ 4 - 4
vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go

@@ -70,7 +70,7 @@ func (nodeInfo *NodeInfo) removeTask(t *api.Task) bool {
 	}
 
 	delete(nodeInfo.Tasks, t.ID)
-	if oldTask.DesiredState <= api.TaskStateRunning {
+	if oldTask.DesiredState <= api.TaskStateCompleted {
 		nodeInfo.ActiveTasksCount--
 		nodeInfo.ActiveTasksCountByService[t.ServiceID]--
 	}
@@ -108,12 +108,12 @@ func (nodeInfo *NodeInfo) removeTask(t *api.Task) bool {
 func (nodeInfo *NodeInfo) addTask(t *api.Task) bool {
 	oldTask, ok := nodeInfo.Tasks[t.ID]
 	if ok {
-		if t.DesiredState <= api.TaskStateRunning && oldTask.DesiredState > api.TaskStateRunning {
+		if t.DesiredState <= api.TaskStateCompleted && oldTask.DesiredState > api.TaskStateCompleted {
 			nodeInfo.Tasks[t.ID] = t
 			nodeInfo.ActiveTasksCount++
 			nodeInfo.ActiveTasksCountByService[t.ServiceID]++
 			return true
-		} else if t.DesiredState > api.TaskStateRunning && oldTask.DesiredState <= api.TaskStateRunning {
+		} else if t.DesiredState > api.TaskStateCompleted && oldTask.DesiredState <= api.TaskStateCompleted {
 			nodeInfo.Tasks[t.ID] = t
 			nodeInfo.ActiveTasksCount--
 			nodeInfo.ActiveTasksCountByService[t.ServiceID]--
@@ -145,7 +145,7 @@ func (nodeInfo *NodeInfo) addTask(t *api.Task) bool {
 		}
 	}
 
-	if t.DesiredState <= api.TaskStateRunning {
+	if t.DesiredState <= api.TaskStateCompleted {
 		nodeInfo.ActiveTasksCount++
 		nodeInfo.ActiveTasksCountByService[t.ServiceID]++
 	}

+ 4 - 3
vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go

@@ -74,9 +74,10 @@ func (s *Scheduler) setupTasksList(tx store.ReadTx) error {
 			continue
 		}
 
-		// Also ignore tasks that have not yet been assigned but desired state is beyond TaskStateRunning
-		// This can happen if you update, delete or scale down a service before its tasks were assigned.
-		if t.Status.State == api.TaskStatePending && t.DesiredState > api.TaskStateRunning {
+		// Also ignore tasks that have not yet been assigned but desired state
+		// is beyond TaskStateCompleted. This can happen if you update, delete
+		// or scale down a service before its tasks were assigned.
+		if t.Status.State == api.TaskStatePending && t.DesiredState > api.TaskStateCompleted {
 			continue
 		}
 

+ 9 - 0
vendor/github.com/docker/swarmkit/vendor.conf

@@ -65,3 +65,12 @@ golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
 golang.org/x/sys 9eafafc0a87e0fd0aeeba439a4573537970c44c7
 golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
 golang.org/x/time fbb02b2291d28baffd63558aa44b4b56f178d650
+
+# ginkgo is used for testing in some places in the code. this is it and its
+# sub-dependencies.
+github.com/onsi/ginkgo v1.8.0
+github.com/onsi/gomega v1.5.0
+gopkg.in/yaml.v2 v2.2.1
+github.com/hpcloud/tail v1.0.0
+gopkg.in/fsnotify.v1 v1.4.7
+gopkg.in/tomb.v1 v1

Some files were not shown because too many files changed in this diff