diff --git a/cmd/rollouts-controller/main.go b/cmd/rollouts-controller/main.go index d666c73fc8..57fbc08320 100644 --- a/cmd/rollouts-controller/main.go +++ b/cmd/rollouts-controller/main.go @@ -11,6 +11,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic/dynamicinformer" kubeinformers "k8s.io/client-go/informers" @@ -97,6 +98,8 @@ func newCommand() *cobra.Command { checkError(err) dynamicClient, err := dynamic.NewForConfig(config) checkError(err) + discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) + checkError(err) smiClient, err := smiclientset.NewForConfig(config) resyncDuration := time.Duration(rolloutResyncPeriod) * time.Second kubeInformerFactory := kubeinformers.NewSharedInformerFactoryWithOptions( @@ -130,6 +133,7 @@ func newCommand() *cobra.Command { rolloutClient, dynamicClient, smiClient, + discoveryClient, kubeInformerFactory.Apps().V1().ReplicaSets(), kubeInformerFactory.Core().V1().Services(), kubeInformerFactory.Extensions().V1beta1().Ingresses(), diff --git a/controller/controller.go b/controller/controller.go index 65e507cae6..3fff5c141a 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -12,6 +12,7 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" appsinformers "k8s.io/client-go/informers/apps/v1" batchinformers "k8s.io/client-go/informers/batch/v1" @@ -85,6 +86,8 @@ type Manager struct { experimentWorkqueue workqueue.RateLimitingInterface analysisRunWorkqueue workqueue.RateLimitingInterface + refResolver rollout.TemplateRefResolver + dynamicClientSet dynamic.Interface namespace string @@ -97,6 +100,7 @@ func NewManager( argoprojclientset clientset.Interface, dynamicclientset dynamic.Interface, smiclientset smiclientset.Interface, + discoveryClient discovery.DiscoveryInterface, replicaSetInformer appsinformers.ReplicaSetInformer, servicesInformer coreinformers.ServiceInformer, ingressesInformer extensionsinformers.IngressInformer, @@ -141,11 +145,14 @@ func NewManager( serviceWorkqueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Services") ingressWorkqueue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Ingresses") + refResolver := rollout.NewInformerBasedWorkloadRefResolver(namespace, dynamicclientset, discoveryClient, rolloutWorkqueue, rolloutsInformer.Informer()) + rolloutController := rollout.NewController(rollout.ControllerConfig{ Namespace: namespace, KubeClientSet: kubeclientset, ArgoProjClientset: argoprojclientset, DynamicClientSet: dynamicclientset, + RefResolver: refResolver, SmiClientSet: smiclientset, ExperimentInformer: experimentsInformer, AnalysisRunInformer: analysisRunInformer, @@ -238,6 +245,7 @@ func NewManager( experimentController: experimentController, analysisController: analysisController, dynamicClientSet: dynamicclientset, + refResolver: refResolver, namespace: namespace, } @@ -255,6 +263,7 @@ func (c *Manager) Run(rolloutThreadiness, serviceThreadiness, ingressThreadiness defer c.rolloutWorkqueue.ShutDown() defer c.experimentWorkqueue.ShutDown() defer c.analysisRunWorkqueue.ShutDown() + // Wait for the caches to be synced before starting workers log.Info("Waiting for controller's informer caches to sync") if ok := cache.WaitForCacheSync(stopCh, c.serviceSynced, c.ingressSynced, c.jobSynced, c.rolloutSynced, c.experimentSynced, c.analysisRunSynced, c.analysisTemplateSynced, c.replicasSetSynced); !ok { diff --git a/docs/migrating.md b/docs/migrating.md index c7e7f6151f..d9432f177a 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -1,6 +1,11 @@ # Migrating to Rollouts -Migrating to Argo Rollouts involves converting an existing Deployment resource, to a Rollout resource. +There are ways to migrate to Rollout: + +* Convert an existing Deployment resource to a Rollout resource. +* Reference an existing Deployment from a Rollout using `workloadRef` field. + +## Convert Deployment to Rollout When converting a Deployment to a Rollout, it involves changing three fields: @@ -36,8 +41,79 @@ spec: - pause: {} ``` -## Other Considerations +!!! warning + When migrating a Deployment which is already serving live production traffic, a Rollout should + run next to the Deployment before deleting the Deployment or scaling down the Deployment. + **Not following this approach might result in downtime**. It also allows for the Rollout to be + tested before deleting the original Deployment. + + +## Reference Deployment From Rollout + +Instead of removing Deployment you can scale-down in to zero and reference from the Rollout resource: + +1. Create a Rollout resource. +1. Reference an existing Deployment using `workloadRef` field. +1. Scale-down existing Deployment by changing `replicas` field of an existing Deployment to zero. + +Below is an example of a Rollout resource referencing a Deployment. + +```yaml +apiVersion: argoproj.io/v1alpha1 # Create a rollout resource +kind: Rollout +metadata: + name: rollout-ref-deployment +spec: + replicas: 5 + workloadRef: # Reference an existing Deployment using workloadRef field + apiVersion: apps/v1 + kind: Deployment + name: rollout-ref-deployment + strategy: + canary: + steps: + - setWeight: 20 + - pause: {duration: 10s} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: rollout-canary + name: rollout-ref-deployment +spec: + replicas: 0 # Scale down existing deployment + selector: + matchLabels: + app: rollout-ref-deployment + template: + metadata: + labels: + app: rollout-ref-deployment + spec: + containers: + - name: rollouts-demo + image: argoproj/rollouts-demo:blue + imagePullPolicy: Always + ports: + - containerPort: 8080 +``` + +Consider following if your Deployment runs in production: + +**Running Rollout and Deployment side-by-side** + +After creation Rollout will spinup required number of Pods side-by-side with the Deployment Pods. +Rollout won't try to manage existing Deployment Pods. That means you can safely update add Rollout +to the production environment without any interruption but you are going to run twice more Pods during migration. + +**Traffic Management During Migration** + +The Rollout offers traffic management functionality that manages routing rules and flows the traffic to different +versions of an application. For example [Blue-Green](../docs/features/bluegreen.md) deployment strategy manipulates +Kubernetes Service selector and direct production traffic to "green" instances only. -When migrating a Deployment which is already serving live production traffic, a Rollout should -run next to the Deployment before deleting the Deployment. **Not following this approach might result in -downtime**. It also allows for the Rollout to be tested before deleting the original Deployment. +If you are using this feature then Rollout switches production traffic to Pods that it manages. The switch happens +only when the required number of Pod is running and healthy so it is safe in production as well. However, if you +want to be extra careful then consider creating a temporal Service or Ingress object to validate Rollout behavior. +Once testing is done delete temporal Service/Ingress and switch rollout to production one. \ No newline at end of file diff --git a/examples/rollout-template-ref.yaml b/examples/rollout-template-ref.yaml new file mode 100644 index 0000000000..2422447180 --- /dev/null +++ b/examples/rollout-template-ref.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: rollout-canary + name: rollout-ref-deployment +spec: + replicas: 0 + selector: + matchLabels: + app: rollout-ref-deployment + template: + metadata: + labels: + app: rollout-ref-deployment + spec: + containers: + - name: rollouts-demo + image: argoproj/rollouts-demo:blue + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: rollout-ref-deployment +spec: + replicas: 5 + revisionHistoryLimit: 2 + workloadRef: + apiVersion: apps/v1 + kind: Deployment + name: rollout-ref-deployment + strategy: + canary: + steps: + - setWeight: 20 + - pause: {duration: 10s} diff --git a/manifests/crds/rollout-crd.yaml b/manifests/crds/rollout-crd.yaml index 0ec8f5b39f..d30d8ce682 100644 --- a/manifests/crds/rollout-crd.yaml +++ b/manifests/crds/rollout-crd.yaml @@ -2643,9 +2643,15 @@ spec: - containers type: object type: object - required: - - selector - - template + workloadRef: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + type: object type: object status: properties: diff --git a/manifests/install.yaml b/manifests/install.yaml index 13e5dffc93..3664f42b59 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -12330,9 +12330,15 @@ spec: - containers type: object type: object - required: - - selector - - template + workloadRef: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + type: object type: object status: properties: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 45ac042e1a..a9b19bfbcd 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -12330,9 +12330,15 @@ spec: - containers type: object type: object - required: - - selector - - template + workloadRef: + properties: + apiVersion: + type: string + kind: + type: string + name: + type: string + type: object type: object status: properties: diff --git a/pkg/apiclient/rollout/rollout.pb.gw.go b/pkg/apiclient/rollout/rollout.pb.gw.go index 2ab97fb555..02bfc7bb1b 100644 --- a/pkg/apiclient/rollout/rollout.pb.gw.go +++ b/pkg/apiclient/rollout/rollout.pb.gw.go @@ -21,6 +21,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -31,6 +32,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_RolloutService_GetRolloutInfo_0(ctx context.Context, marshaler runtime.Marshaler, client RolloutServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq RolloutInfoQuery @@ -922,11 +924,14 @@ func local_request_RolloutService_Version_0(ctx context.Context, marshaler runti // RegisterRolloutServiceHandlerServer registers the http handlers for service RolloutService to "mux". // UnaryRPC :call RolloutServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterRolloutServiceHandlerFromEndpoint instead. func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server RolloutServiceServer) error { mux.Handle("GET", pattern_RolloutService_GetRolloutInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -934,6 +939,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_GetRolloutInfo_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -954,6 +960,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("GET", pattern_RolloutService_ListRolloutInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -961,6 +969,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_ListRolloutInfos_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -981,6 +990,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("GET", pattern_RolloutService_GetNamespace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -988,6 +999,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_GetNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1001,6 +1013,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("PUT", pattern_RolloutService_RestartRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1008,6 +1022,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_RestartRollout_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1021,6 +1036,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("PUT", pattern_RolloutService_PromoteRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1028,6 +1045,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_PromoteRollout_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1041,6 +1059,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("PUT", pattern_RolloutService_AbortRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1048,6 +1068,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_AbortRollout_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1061,6 +1082,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("PUT", pattern_RolloutService_SetRolloutImage_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1068,6 +1091,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_SetRolloutImage_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1081,6 +1105,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("PUT", pattern_RolloutService_UndoRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1088,6 +1114,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_UndoRollout_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1101,6 +1128,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("PUT", pattern_RolloutService_RetryRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1108,6 +1137,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_RetryRollout_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) @@ -1121,6 +1151,8 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve mux.Handle("GET", pattern_RolloutService_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) if err != nil { @@ -1128,6 +1160,7 @@ func RegisterRolloutServiceHandlerServer(ctx context.Context, mux *runtime.Serve return } resp, md, err := local_request_RolloutService_Version_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) diff --git a/pkg/apiclient/rollout/rollout.swagger.json b/pkg/apiclient/rollout/rollout.swagger.json index 7a52d30224..bd511a52f6 100644 --- a/pkg/apiclient/rollout/rollout.swagger.json +++ b/pkg/apiclient/rollout/rollout.swagger.json @@ -826,6 +826,24 @@ }, "title": "NginxTrafficRouting configuration for Nginx ingress controller to control traffic routing" }, + "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.ObjectRef": { + "type": "object", + "properties": { + "apiVersion": { + "type": "string", + "title": "API Version of the referent" + }, + "kind": { + "type": "string", + "title": "Kind of the referent" + }, + "name": { + "type": "string", + "title": "Name of the referent" + } + }, + "title": "ObjectRef holds a references to the Kubernetes object" + }, "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.PauseCondition": { "type": "object", "properties": { @@ -1078,11 +1096,15 @@ }, "selector": { "$ref": "#/definitions/k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector", - "description": "Label selector for pods. Existing ReplicaSets whose pods are\nselected by this will be the ones affected by this rollout.\nIt must match the pod template's labels." + "title": "Label selector for pods. Existing ReplicaSets whose pods are\nselected by this will be the ones affected by this rollout.\nIt must match the pod template's labels.\n+optional" }, "template": { "$ref": "#/definitions/k8s.io.api.core.v1.PodTemplateSpec", - "description": "Template describes the pods that will be created." + "title": "Template describes the pods that will be created.\n+optional" + }, + "workloadRef": { + "$ref": "#/definitions/github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.ObjectRef", + "title": "WorkloadRef holds a references to a workload that provides Pod template\n+optional" }, "minReadySeconds": { "type": "integer", diff --git a/pkg/apis/rollouts/v1alpha1/generated.pb.go b/pkg/apis/rollouts/v1alpha1/generated.pb.go index dbffc5c501..d33b063619 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.pb.go +++ b/pkg/apis/rollouts/v1alpha1/generated.pb.go @@ -1196,10 +1196,38 @@ func (m *NginxTrafficRouting) XXX_DiscardUnknown() { var xxx_messageInfo_NginxTrafficRouting proto.InternalMessageInfo +func (m *ObjectRef) Reset() { *m = ObjectRef{} } +func (*ObjectRef) ProtoMessage() {} +func (*ObjectRef) Descriptor() ([]byte, []int) { + return fileDescriptor_e0e705f843545fab, []int{41} +} +func (m *ObjectRef) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ObjectRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ObjectRef) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObjectRef.Merge(m, src) +} +func (m *ObjectRef) XXX_Size() int { + return m.Size() +} +func (m *ObjectRef) XXX_DiscardUnknown() { + xxx_messageInfo_ObjectRef.DiscardUnknown(m) +} + +var xxx_messageInfo_ObjectRef proto.InternalMessageInfo + func (m *PauseCondition) Reset() { *m = PauseCondition{} } func (*PauseCondition) ProtoMessage() {} func (*PauseCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{41} + return fileDescriptor_e0e705f843545fab, []int{42} } func (m *PauseCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1227,7 +1255,7 @@ var xxx_messageInfo_PauseCondition proto.InternalMessageInfo func (m *PodTemplateMetadata) Reset() { *m = PodTemplateMetadata{} } func (*PodTemplateMetadata) ProtoMessage() {} func (*PodTemplateMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{42} + return fileDescriptor_e0e705f843545fab, []int{43} } func (m *PodTemplateMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1257,7 +1285,7 @@ func (m *PreferredDuringSchedulingIgnoredDuringExecution) Reset() { } func (*PreferredDuringSchedulingIgnoredDuringExecution) ProtoMessage() {} func (*PreferredDuringSchedulingIgnoredDuringExecution) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{43} + return fileDescriptor_e0e705f843545fab, []int{44} } func (m *PreferredDuringSchedulingIgnoredDuringExecution) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1285,7 +1313,7 @@ var xxx_messageInfo_PreferredDuringSchedulingIgnoredDuringExecution proto.Intern func (m *PrometheusMetric) Reset() { *m = PrometheusMetric{} } func (*PrometheusMetric) ProtoMessage() {} func (*PrometheusMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{44} + return fileDescriptor_e0e705f843545fab, []int{45} } func (m *PrometheusMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1315,7 +1343,7 @@ func (m *RequiredDuringSchedulingIgnoredDuringExecution) Reset() { } func (*RequiredDuringSchedulingIgnoredDuringExecution) ProtoMessage() {} func (*RequiredDuringSchedulingIgnoredDuringExecution) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{45} + return fileDescriptor_e0e705f843545fab, []int{46} } func (m *RequiredDuringSchedulingIgnoredDuringExecution) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1343,7 +1371,7 @@ var xxx_messageInfo_RequiredDuringSchedulingIgnoredDuringExecution proto.Interna func (m *Rollout) Reset() { *m = Rollout{} } func (*Rollout) ProtoMessage() {} func (*Rollout) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{46} + return fileDescriptor_e0e705f843545fab, []int{47} } func (m *Rollout) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1371,7 +1399,7 @@ var xxx_messageInfo_Rollout proto.InternalMessageInfo func (m *RolloutAnalysis) Reset() { *m = RolloutAnalysis{} } func (*RolloutAnalysis) ProtoMessage() {} func (*RolloutAnalysis) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{47} + return fileDescriptor_e0e705f843545fab, []int{48} } func (m *RolloutAnalysis) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1399,7 +1427,7 @@ var xxx_messageInfo_RolloutAnalysis proto.InternalMessageInfo func (m *RolloutAnalysisBackground) Reset() { *m = RolloutAnalysisBackground{} } func (*RolloutAnalysisBackground) ProtoMessage() {} func (*RolloutAnalysisBackground) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{48} + return fileDescriptor_e0e705f843545fab, []int{49} } func (m *RolloutAnalysisBackground) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1427,7 +1455,7 @@ var xxx_messageInfo_RolloutAnalysisBackground proto.InternalMessageInfo func (m *RolloutAnalysisRunStatus) Reset() { *m = RolloutAnalysisRunStatus{} } func (*RolloutAnalysisRunStatus) ProtoMessage() {} func (*RolloutAnalysisRunStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{49} + return fileDescriptor_e0e705f843545fab, []int{50} } func (m *RolloutAnalysisRunStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1455,7 +1483,7 @@ var xxx_messageInfo_RolloutAnalysisRunStatus proto.InternalMessageInfo func (m *RolloutAnalysisTemplate) Reset() { *m = RolloutAnalysisTemplate{} } func (*RolloutAnalysisTemplate) ProtoMessage() {} func (*RolloutAnalysisTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{50} + return fileDescriptor_e0e705f843545fab, []int{51} } func (m *RolloutAnalysisTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1483,7 +1511,7 @@ var xxx_messageInfo_RolloutAnalysisTemplate proto.InternalMessageInfo func (m *RolloutCondition) Reset() { *m = RolloutCondition{} } func (*RolloutCondition) ProtoMessage() {} func (*RolloutCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{51} + return fileDescriptor_e0e705f843545fab, []int{52} } func (m *RolloutCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1511,7 +1539,7 @@ var xxx_messageInfo_RolloutCondition proto.InternalMessageInfo func (m *RolloutExperimentStep) Reset() { *m = RolloutExperimentStep{} } func (*RolloutExperimentStep) ProtoMessage() {} func (*RolloutExperimentStep) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{52} + return fileDescriptor_e0e705f843545fab, []int{53} } func (m *RolloutExperimentStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1541,7 +1569,7 @@ func (m *RolloutExperimentStepAnalysisTemplateRef) Reset() { } func (*RolloutExperimentStepAnalysisTemplateRef) ProtoMessage() {} func (*RolloutExperimentStepAnalysisTemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{53} + return fileDescriptor_e0e705f843545fab, []int{54} } func (m *RolloutExperimentStepAnalysisTemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1569,7 +1597,7 @@ var xxx_messageInfo_RolloutExperimentStepAnalysisTemplateRef proto.InternalMessa func (m *RolloutExperimentTemplate) Reset() { *m = RolloutExperimentTemplate{} } func (*RolloutExperimentTemplate) ProtoMessage() {} func (*RolloutExperimentTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{54} + return fileDescriptor_e0e705f843545fab, []int{55} } func (m *RolloutExperimentTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1597,7 +1625,7 @@ var xxx_messageInfo_RolloutExperimentTemplate proto.InternalMessageInfo func (m *RolloutList) Reset() { *m = RolloutList{} } func (*RolloutList) ProtoMessage() {} func (*RolloutList) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{55} + return fileDescriptor_e0e705f843545fab, []int{56} } func (m *RolloutList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1625,7 +1653,7 @@ var xxx_messageInfo_RolloutList proto.InternalMessageInfo func (m *RolloutPause) Reset() { *m = RolloutPause{} } func (*RolloutPause) ProtoMessage() {} func (*RolloutPause) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{56} + return fileDescriptor_e0e705f843545fab, []int{57} } func (m *RolloutPause) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1653,7 +1681,7 @@ var xxx_messageInfo_RolloutPause proto.InternalMessageInfo func (m *RolloutSpec) Reset() { *m = RolloutSpec{} } func (*RolloutSpec) ProtoMessage() {} func (*RolloutSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{57} + return fileDescriptor_e0e705f843545fab, []int{58} } func (m *RolloutSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1681,7 +1709,7 @@ var xxx_messageInfo_RolloutSpec proto.InternalMessageInfo func (m *RolloutStatus) Reset() { *m = RolloutStatus{} } func (*RolloutStatus) ProtoMessage() {} func (*RolloutStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{58} + return fileDescriptor_e0e705f843545fab, []int{59} } func (m *RolloutStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1709,7 +1737,7 @@ var xxx_messageInfo_RolloutStatus proto.InternalMessageInfo func (m *RolloutStrategy) Reset() { *m = RolloutStrategy{} } func (*RolloutStrategy) ProtoMessage() {} func (*RolloutStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{59} + return fileDescriptor_e0e705f843545fab, []int{60} } func (m *RolloutStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1737,7 +1765,7 @@ var xxx_messageInfo_RolloutStrategy proto.InternalMessageInfo func (m *RolloutTrafficRouting) Reset() { *m = RolloutTrafficRouting{} } func (*RolloutTrafficRouting) ProtoMessage() {} func (*RolloutTrafficRouting) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{60} + return fileDescriptor_e0e705f843545fab, []int{61} } func (m *RolloutTrafficRouting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1765,7 +1793,7 @@ var xxx_messageInfo_RolloutTrafficRouting proto.InternalMessageInfo func (m *SMITrafficRouting) Reset() { *m = SMITrafficRouting{} } func (*SMITrafficRouting) ProtoMessage() {} func (*SMITrafficRouting) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{61} + return fileDescriptor_e0e705f843545fab, []int{62} } func (m *SMITrafficRouting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1793,7 +1821,7 @@ var xxx_messageInfo_SMITrafficRouting proto.InternalMessageInfo func (m *ScopeDetail) Reset() { *m = ScopeDetail{} } func (*ScopeDetail) ProtoMessage() {} func (*ScopeDetail) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{62} + return fileDescriptor_e0e705f843545fab, []int{63} } func (m *ScopeDetail) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1821,7 +1849,7 @@ var xxx_messageInfo_ScopeDetail proto.InternalMessageInfo func (m *SecretKeyRef) Reset() { *m = SecretKeyRef{} } func (*SecretKeyRef) ProtoMessage() {} func (*SecretKeyRef) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{63} + return fileDescriptor_e0e705f843545fab, []int{64} } func (m *SecretKeyRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1849,7 +1877,7 @@ var xxx_messageInfo_SecretKeyRef proto.InternalMessageInfo func (m *SetCanaryScale) Reset() { *m = SetCanaryScale{} } func (*SetCanaryScale) ProtoMessage() {} func (*SetCanaryScale) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{64} + return fileDescriptor_e0e705f843545fab, []int{65} } func (m *SetCanaryScale) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1877,7 +1905,7 @@ var xxx_messageInfo_SetCanaryScale proto.InternalMessageInfo func (m *TemplateSpec) Reset() { *m = TemplateSpec{} } func (*TemplateSpec) ProtoMessage() {} func (*TemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{65} + return fileDescriptor_e0e705f843545fab, []int{66} } func (m *TemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1905,7 +1933,7 @@ var xxx_messageInfo_TemplateSpec proto.InternalMessageInfo func (m *TemplateStatus) Reset() { *m = TemplateStatus{} } func (*TemplateStatus) ProtoMessage() {} func (*TemplateStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{66} + return fileDescriptor_e0e705f843545fab, []int{67} } func (m *TemplateStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1933,7 +1961,7 @@ var xxx_messageInfo_TemplateStatus proto.InternalMessageInfo func (m *ValueFrom) Reset() { *m = ValueFrom{} } func (*ValueFrom) ProtoMessage() {} func (*ValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{67} + return fileDescriptor_e0e705f843545fab, []int{68} } func (m *ValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1961,7 +1989,7 @@ var xxx_messageInfo_ValueFrom proto.InternalMessageInfo func (m *WavefrontMetric) Reset() { *m = WavefrontMetric{} } func (*WavefrontMetric) ProtoMessage() {} func (*WavefrontMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{68} + return fileDescriptor_e0e705f843545fab, []int{69} } func (m *WavefrontMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1989,7 +2017,7 @@ var xxx_messageInfo_WavefrontMetric proto.InternalMessageInfo func (m *WebMetric) Reset() { *m = WebMetric{} } func (*WebMetric) ProtoMessage() {} func (*WebMetric) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{69} + return fileDescriptor_e0e705f843545fab, []int{70} } func (m *WebMetric) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2017,7 +2045,7 @@ var xxx_messageInfo_WebMetric proto.InternalMessageInfo func (m *WebMetricHeader) Reset() { *m = WebMetricHeader{} } func (*WebMetricHeader) ProtoMessage() {} func (*WebMetricHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_e0e705f843545fab, []int{70} + return fileDescriptor_e0e705f843545fab, []int{71} } func (m *WebMetricHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2086,6 +2114,7 @@ func init() { proto.RegisterType((*NewRelicMetric)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.NewRelicMetric") proto.RegisterType((*NginxTrafficRouting)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.NginxTrafficRouting") proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.NginxTrafficRouting.AdditionalIngressAnnotationsEntry") + proto.RegisterType((*ObjectRef)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.ObjectRef") proto.RegisterType((*PauseCondition)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.PauseCondition") proto.RegisterType((*PodTemplateMetadata)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.PodTemplateMetadata") proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.PodTemplateMetadata.AnnotationsEntry") @@ -2125,349 +2154,354 @@ func init() { } var fileDescriptor_e0e705f843545fab = []byte{ - // 5462 bytes of a gzipped FileDescriptorProto + // 5543 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5d, 0x8c, 0x24, 0xd7, - 0x55, 0xb0, 0xab, 0x7b, 0x7a, 0xa6, 0xe7, 0xf4, 0xfc, 0xde, 0x9d, 0xcd, 0x76, 0xd6, 0xbb, 0xd3, - 0x9b, 0x72, 0xe4, 0xcf, 0xf9, 0x48, 0x7a, 0xe2, 0xb5, 0x0d, 0x26, 0x8e, 0x2c, 0xba, 0x67, 0x77, - 0xbd, 0x33, 0x9e, 0xd9, 0x9d, 0xbd, 0x3d, 0xeb, 0x55, 0xfc, 0x03, 0xa9, 0xe9, 0xbe, 0xd3, 0x53, - 0xbb, 0xd5, 0x55, 0x9d, 0xaa, 0xea, 0xd9, 0x1d, 0x27, 0x4a, 0xec, 0x44, 0x26, 0x06, 0x25, 0xb2, - 0xf9, 0x79, 0x41, 0x08, 0x84, 0x10, 0x0f, 0x08, 0x5e, 0x78, 0xc8, 0x0b, 0x12, 0x11, 0x51, 0x00, - 0xc9, 0x3c, 0x40, 0xc2, 0x0b, 0x0e, 0x48, 0x69, 0x70, 0x07, 0x09, 0xc1, 0x0b, 0x0a, 0x8a, 0x84, - 0xb2, 0xe2, 0x01, 0xdd, 0x9f, 0xba, 0x55, 0xb7, 0xaa, 0x66, 0xa6, 0x7b, 0xbb, 0x66, 0x89, 0x80, - 0xb7, 0xe9, 0x73, 0xce, 0x3d, 0xe7, 0xfe, 0x9c, 0x7b, 0xce, 0xb9, 0xf7, 0x9c, 0x5b, 0x03, 0x1b, - 0x6d, 0xd3, 0xdf, 0xeb, 0xed, 0x54, 0x9b, 0x4e, 0x67, 0xc5, 0x70, 0xdb, 0x4e, 0xd7, 0x75, 0x6e, - 0xb3, 0x3f, 0x3e, 0xe1, 0x3a, 0x96, 0xe5, 0xf4, 0x7c, 0x6f, 0xa5, 0x7b, 0xa7, 0xbd, 0x62, 0x74, - 0x4d, 0x6f, 0x45, 0x42, 0xf6, 0x9f, 0x34, 0xac, 0xee, 0x9e, 0xf1, 0xe4, 0x4a, 0x9b, 0xd8, 0xc4, - 0x35, 0x7c, 0xd2, 0xaa, 0x76, 0x5d, 0xc7, 0x77, 0xd0, 0xa7, 0x43, 0x6e, 0xd5, 0x80, 0x1b, 0xfb, - 0xe3, 0x17, 0x82, 0xb6, 0xd5, 0xee, 0x9d, 0x76, 0x95, 0x72, 0xab, 0x4a, 0x48, 0xc0, 0xed, 0xec, - 0x27, 0x22, 0x7d, 0x69, 0x3b, 0x6d, 0x67, 0x85, 0x31, 0xdd, 0xe9, 0xed, 0xb2, 0x5f, 0xec, 0x07, - 0xfb, 0x8b, 0x0b, 0x3b, 0xfb, 0xd8, 0x9d, 0x67, 0xbd, 0xaa, 0xe9, 0xd0, 0xbe, 0xad, 0xec, 0x18, - 0x7e, 0x73, 0x6f, 0x65, 0x3f, 0xd1, 0xa3, 0xb3, 0x7a, 0x84, 0xa8, 0xe9, 0xb8, 0x24, 0x8d, 0xe6, - 0xe9, 0x90, 0xa6, 0x63, 0x34, 0xf7, 0x4c, 0x9b, 0xb8, 0x07, 0xe1, 0xa8, 0x3b, 0xc4, 0x37, 0xd2, - 0x5a, 0xad, 0x1c, 0xd6, 0xca, 0xed, 0xd9, 0xbe, 0xd9, 0x21, 0x89, 0x06, 0x3f, 0x7d, 0x5c, 0x03, - 0xaf, 0xb9, 0x47, 0x3a, 0x46, 0xa2, 0xdd, 0x53, 0x87, 0xb5, 0xeb, 0xf9, 0xa6, 0xb5, 0x62, 0xda, - 0xbe, 0xe7, 0xbb, 0xf1, 0x46, 0xfa, 0xbf, 0x6b, 0xb0, 0x58, 0xdb, 0xa8, 0x6f, 0xbb, 0xc6, 0xee, - 0xae, 0xd9, 0xc4, 0x4e, 0xcf, 0x37, 0xed, 0x36, 0xfa, 0x18, 0x4c, 0x99, 0x76, 0xdb, 0x25, 0x9e, - 0x57, 0xd6, 0x2e, 0x68, 0x4f, 0x4c, 0xd7, 0xe7, 0xdf, 0xeb, 0x57, 0x1e, 0x19, 0xf4, 0x2b, 0x53, - 0x6b, 0x1c, 0x8c, 0x03, 0x3c, 0x7a, 0x06, 0x4a, 0x1e, 0x71, 0xf7, 0xcd, 0x26, 0xd9, 0x72, 0x5c, - 0xbf, 0x9c, 0xbb, 0xa0, 0x3d, 0x51, 0xa8, 0x9f, 0x12, 0xe4, 0xa5, 0x46, 0x88, 0xc2, 0x51, 0x3a, - 0xda, 0xcc, 0x75, 0x1c, 0x5f, 0xe0, 0xcb, 0x79, 0x26, 0x45, 0x36, 0xc3, 0x21, 0x0a, 0x47, 0xe9, - 0xd0, 0x25, 0x58, 0x30, 0x6c, 0xdb, 0xf1, 0x0d, 0xdf, 0x74, 0xec, 0x2d, 0x97, 0xec, 0x9a, 0xf7, - 0xca, 0x13, 0xac, 0x6d, 0x59, 0xb4, 0x5d, 0xa8, 0xc5, 0xf0, 0x38, 0xd1, 0x42, 0xff, 0xbb, 0x1c, - 0x94, 0x6a, 0xb6, 0x61, 0x1d, 0x78, 0xa6, 0x87, 0x7b, 0x36, 0xfa, 0x2c, 0x14, 0xe9, 0xea, 0xb5, - 0x0c, 0xdf, 0x60, 0xe3, 0x2d, 0x5d, 0xfc, 0x64, 0x95, 0x4f, 0x66, 0x35, 0x3a, 0x99, 0xa1, 0x4e, - 0x52, 0xea, 0xea, 0xfe, 0x93, 0xd5, 0xeb, 0x3b, 0xb7, 0x49, 0xd3, 0xdf, 0x24, 0xbe, 0x51, 0x47, - 0x42, 0x3e, 0x84, 0x30, 0x2c, 0xb9, 0x22, 0x07, 0x26, 0xbc, 0x2e, 0x69, 0xb2, 0xe9, 0x29, 0x5d, - 0xdc, 0xac, 0x8e, 0xa3, 0xff, 0xd5, 0x48, 0xd7, 0x1b, 0x5d, 0xd2, 0xac, 0xcf, 0x08, 0xd1, 0x13, - 0xf4, 0x17, 0x66, 0x82, 0xd0, 0x5d, 0x98, 0xf4, 0x7c, 0xc3, 0xef, 0x79, 0x6c, 0x6a, 0x4b, 0x17, - 0xaf, 0x67, 0x27, 0x92, 0xb1, 0xad, 0xcf, 0x09, 0xa1, 0x93, 0xfc, 0x37, 0x16, 0xe2, 0xf4, 0xbf, - 0xd7, 0xe0, 0x54, 0x84, 0xba, 0xe6, 0xb6, 0x7b, 0x1d, 0x62, 0xfb, 0xe8, 0x02, 0x4c, 0xd8, 0x46, - 0x87, 0x08, 0x7d, 0x92, 0x5d, 0xbe, 0x66, 0x74, 0x08, 0x66, 0x18, 0xf4, 0x18, 0x14, 0xf6, 0x0d, - 0xab, 0x47, 0xd8, 0x24, 0x4d, 0xd7, 0x67, 0x05, 0x49, 0xe1, 0x25, 0x0a, 0xc4, 0x1c, 0x87, 0xbe, - 0x00, 0xd3, 0xec, 0x8f, 0x2b, 0xae, 0xd3, 0xc9, 0x68, 0x68, 0xa2, 0x87, 0x2f, 0x05, 0x6c, 0xeb, - 0xb3, 0x83, 0x7e, 0x65, 0x5a, 0xfe, 0xc4, 0xa1, 0x40, 0xfd, 0x1f, 0x34, 0x98, 0x8f, 0x0c, 0x6e, - 0xc3, 0xf4, 0x7c, 0xf4, 0x6a, 0x42, 0x79, 0xaa, 0xc3, 0x29, 0x0f, 0x6d, 0xcd, 0x54, 0x67, 0x41, - 0x8c, 0xb4, 0x18, 0x40, 0x22, 0x8a, 0x63, 0x43, 0xc1, 0xf4, 0x49, 0xc7, 0x2b, 0xe7, 0x2e, 0xe4, - 0x9f, 0x28, 0x5d, 0x5c, 0xcb, 0x6c, 0x19, 0xc3, 0xf9, 0x5d, 0xa3, 0xfc, 0x31, 0x17, 0xa3, 0xff, - 0x56, 0x4e, 0x19, 0x21, 0xd5, 0x28, 0xe4, 0xc0, 0x54, 0x87, 0xf8, 0xae, 0xd9, 0xa4, 0xd6, 0x80, - 0xf6, 0xe2, 0xd2, 0x78, 0xbd, 0xd8, 0x64, 0xcc, 0x42, 0x9b, 0xc2, 0x7f, 0x7b, 0x38, 0x90, 0x82, - 0xf6, 0x60, 0xc2, 0x70, 0xdb, 0xc1, 0x98, 0xaf, 0x64, 0xb3, 0xbe, 0xa1, 0xce, 0xd5, 0xdc, 0xb6, - 0x87, 0x99, 0x04, 0xb4, 0x02, 0xd3, 0x3e, 0x71, 0x3b, 0xa6, 0x6d, 0xf8, 0xdc, 0x08, 0x15, 0xeb, - 0x8b, 0x82, 0x6c, 0x7a, 0x3b, 0x40, 0xe0, 0x90, 0x46, 0x7f, 0x3f, 0x07, 0x8b, 0x89, 0xcd, 0x80, - 0x9e, 0x86, 0x42, 0x77, 0xcf, 0xf0, 0x02, 0xed, 0x5e, 0x0e, 0xa6, 0x76, 0x8b, 0x02, 0xef, 0xf7, - 0x2b, 0xb3, 0x41, 0x13, 0x06, 0xc0, 0x9c, 0x98, 0x5a, 0xd9, 0x0e, 0xf1, 0x3c, 0xa3, 0x1d, 0xa8, - 0x7c, 0x64, 0x46, 0x18, 0x18, 0x07, 0x78, 0xf4, 0x55, 0x0d, 0x66, 0xf9, 0xec, 0x60, 0xe2, 0xf5, - 0x2c, 0x9f, 0x6e, 0x6b, 0x3a, 0x37, 0xeb, 0x59, 0xac, 0x04, 0x67, 0x59, 0x3f, 0x2d, 0xa4, 0xcf, - 0x46, 0xa1, 0x1e, 0x56, 0xe5, 0xa2, 0x5b, 0x30, 0xed, 0xf9, 0x86, 0xeb, 0x93, 0x56, 0xcd, 0x67, - 0xa6, 0xb7, 0x74, 0xf1, 0xff, 0x0f, 0xa7, 0xef, 0xdb, 0x66, 0x87, 0xf0, 0xbd, 0xd5, 0x08, 0x18, - 0xe0, 0x90, 0x97, 0xfe, 0xaf, 0x1a, 0x2c, 0x04, 0xd3, 0xb4, 0x4d, 0x3a, 0x5d, 0xcb, 0xf0, 0xc9, - 0x43, 0xb0, 0xcc, 0xbe, 0x62, 0x99, 0x71, 0x36, 0xfb, 0x2b, 0xe8, 0xff, 0x61, 0xe6, 0x59, 0xff, - 0x17, 0x0d, 0x96, 0xe2, 0xc4, 0x0f, 0xc1, 0x9a, 0x78, 0xaa, 0x35, 0xb9, 0x96, 0xed, 0x68, 0x0f, - 0x31, 0x29, 0x3f, 0x4c, 0x19, 0xeb, 0xff, 0x70, 0xbb, 0xa2, 0xff, 0xfe, 0x04, 0xcc, 0xd4, 0x6c, - 0xdf, 0xac, 0xed, 0xee, 0x9a, 0xb6, 0xe9, 0x1f, 0xa0, 0xaf, 0xe5, 0x60, 0xa5, 0xeb, 0x92, 0x5d, - 0xe2, 0xba, 0xa4, 0x75, 0xa9, 0xe7, 0x9a, 0x76, 0xbb, 0xd1, 0xdc, 0x23, 0xad, 0x9e, 0x65, 0xda, - 0xed, 0xb5, 0xb6, 0xed, 0x48, 0xf0, 0xe5, 0x7b, 0xa4, 0xd9, 0xa3, 0xc1, 0x8a, 0x58, 0xff, 0xce, - 0x78, 0xdd, 0xdc, 0x1a, 0x4d, 0x68, 0xfd, 0xa9, 0x41, 0xbf, 0xb2, 0x32, 0x62, 0x23, 0x3c, 0xea, - 0xd0, 0xd0, 0xdb, 0x39, 0xa8, 0xba, 0xe4, 0x73, 0x3d, 0x73, 0xf8, 0xd9, 0xe0, 0x1b, 0xd4, 0x1a, - 0x6f, 0x36, 0xf0, 0x48, 0x32, 0xeb, 0x17, 0x07, 0xfd, 0xca, 0x88, 0x6d, 0xf0, 0x88, 0xe3, 0xd2, - 0xff, 0x4c, 0x83, 0xe2, 0x08, 0x51, 0x52, 0x45, 0x8d, 0x92, 0xa6, 0x13, 0x11, 0x92, 0x9f, 0x8c, - 0x90, 0x5e, 0x18, 0x6f, 0xd2, 0x86, 0x89, 0x8c, 0xfe, 0x8d, 0x9e, 0x23, 0xe2, 0x91, 0x14, 0xda, - 0x83, 0xa5, 0xae, 0xd3, 0x0a, 0x36, 0xfd, 0x55, 0xc3, 0xdb, 0x63, 0x38, 0x31, 0xbc, 0xa7, 0x07, - 0xfd, 0xca, 0xd2, 0x56, 0x0a, 0xfe, 0x7e, 0xbf, 0x52, 0x96, 0x4c, 0x62, 0x04, 0x38, 0x95, 0x23, - 0xea, 0x42, 0x71, 0xd7, 0x24, 0x56, 0x0b, 0x93, 0x5d, 0xa1, 0x29, 0x63, 0x6e, 0xef, 0x2b, 0x82, - 0x5b, 0x7d, 0x86, 0xda, 0xd2, 0xe0, 0x17, 0x96, 0x52, 0xf4, 0x1f, 0x4f, 0xc0, 0x7c, 0xdd, 0xea, - 0x91, 0x17, 0x5c, 0x42, 0x82, 0x38, 0xa0, 0x06, 0xf3, 0x5d, 0x97, 0xec, 0x9b, 0xe4, 0x6e, 0x83, - 0x58, 0xa4, 0xe9, 0x3b, 0xae, 0x18, 0xea, 0x19, 0xb1, 0x92, 0xf3, 0x5b, 0x2a, 0x1a, 0xc7, 0xe9, - 0xd1, 0xf3, 0x30, 0x67, 0x34, 0x7d, 0x73, 0x9f, 0x48, 0x0e, 0x7c, 0xa1, 0x3f, 0x24, 0x38, 0xcc, - 0xd5, 0x14, 0x2c, 0x8e, 0x51, 0xa3, 0x57, 0xa1, 0xec, 0x35, 0x0d, 0x8b, 0xdc, 0xec, 0x0a, 0x51, - 0xab, 0x7b, 0xa4, 0x79, 0x67, 0xcb, 0x31, 0x6d, 0x5f, 0x04, 0x38, 0x17, 0x04, 0xa7, 0x72, 0xe3, - 0x10, 0x3a, 0x7c, 0x28, 0x07, 0xf4, 0xa7, 0x1a, 0x9c, 0xef, 0xba, 0x64, 0xcb, 0x75, 0x3a, 0x0e, - 0xd5, 0xde, 0x44, 0x28, 0x24, 0x42, 0x82, 0x97, 0xc6, 0xdc, 0xa6, 0x1c, 0x92, 0x3c, 0x75, 0x7c, - 0x64, 0xd0, 0xaf, 0x9c, 0xdf, 0x3a, 0xaa, 0x03, 0xf8, 0xe8, 0xfe, 0xa1, 0x6f, 0x6b, 0xb0, 0xdc, - 0x75, 0x3c, 0xff, 0x88, 0x21, 0x14, 0x4e, 0x74, 0x08, 0xfa, 0xa0, 0x5f, 0x59, 0xde, 0x3a, 0xb2, - 0x07, 0xf8, 0x98, 0x1e, 0xea, 0x5f, 0x2e, 0xc1, 0x62, 0x44, 0xf7, 0xe8, 0x81, 0xbe, 0x7d, 0x80, - 0x9e, 0x83, 0xd9, 0x40, 0x19, 0xf8, 0xa9, 0x9a, 0xeb, 0x9e, 0x8c, 0xeb, 0x6a, 0x51, 0x24, 0x56, - 0x69, 0xa9, 0xde, 0x49, 0x55, 0xe4, 0xad, 0x63, 0x7a, 0xb7, 0xa5, 0x60, 0x71, 0x8c, 0x1a, 0xad, - 0xc1, 0x29, 0x01, 0xc1, 0xa4, 0x6b, 0x99, 0x4d, 0x63, 0xd5, 0xe9, 0x09, 0x95, 0x2b, 0xd4, 0xcf, - 0x0c, 0xfa, 0x95, 0x53, 0x5b, 0x49, 0x34, 0x4e, 0x6b, 0x83, 0x36, 0x60, 0xc9, 0xe8, 0xf9, 0x8e, - 0x1c, 0xff, 0x65, 0xdb, 0xd8, 0xb1, 0x48, 0x8b, 0xa9, 0x56, 0xb1, 0x5e, 0xa6, 0x56, 0xa3, 0x96, - 0x82, 0xc7, 0xa9, 0xad, 0xd0, 0x56, 0x8c, 0x5b, 0x83, 0x34, 0x1d, 0xbb, 0xc5, 0x57, 0xb9, 0x50, - 0x3f, 0x27, 0x86, 0xa7, 0x72, 0x14, 0x34, 0x38, 0xb5, 0x25, 0xb2, 0x60, 0xae, 0x63, 0xdc, 0xbb, - 0x69, 0x1b, 0xfb, 0x86, 0x69, 0x51, 0x21, 0xe5, 0xc9, 0x63, 0x42, 0xd3, 0x9e, 0x6f, 0x5a, 0x55, - 0x7e, 0x03, 0x53, 0x5d, 0xb3, 0xfd, 0xeb, 0x6e, 0xc3, 0xa7, 0x4e, 0xa0, 0x8e, 0xe8, 0xc4, 0x6e, - 0x2a, 0xbc, 0x70, 0x8c, 0x37, 0xba, 0x0e, 0xa7, 0xd9, 0x76, 0xbc, 0xe4, 0xdc, 0xb5, 0x2f, 0x11, - 0xcb, 0x38, 0x08, 0x06, 0x30, 0xc5, 0x06, 0xf0, 0xe1, 0x41, 0xbf, 0x72, 0xba, 0x91, 0x46, 0x80, - 0xd3, 0xdb, 0x21, 0x03, 0x1e, 0x55, 0x11, 0x98, 0xec, 0x9b, 0x9e, 0xe9, 0xd8, 0x1b, 0x66, 0xc7, - 0xf4, 0xcb, 0x45, 0xc6, 0xb6, 0x32, 0xe8, 0x57, 0x1e, 0x6d, 0x1c, 0x4e, 0x86, 0x8f, 0xe2, 0x81, - 0x7e, 0x53, 0x83, 0xa5, 0xb4, 0x6d, 0x58, 0x9e, 0xce, 0xe2, 0xfe, 0x23, 0xb6, 0xb5, 0xb8, 0x46, - 0xa4, 0x1a, 0x85, 0xd4, 0x4e, 0xa0, 0x37, 0x34, 0x98, 0x31, 0x22, 0xc1, 0x59, 0x19, 0x58, 0xaf, - 0xd6, 0xc7, 0x8d, 0x86, 0x43, 0x8e, 0xf5, 0x85, 0x41, 0xbf, 0xa2, 0x04, 0x80, 0x58, 0x91, 0x88, - 0x7e, 0x5b, 0x83, 0xd3, 0xa9, 0x7b, 0xbc, 0x5c, 0x3a, 0x89, 0x19, 0x62, 0x4a, 0x92, 0x6e, 0x73, - 0xd2, 0xbb, 0x81, 0xde, 0xd5, 0xa4, 0x2b, 0xdb, 0x0c, 0xce, 0x23, 0x33, 0xac, 0x6b, 0x37, 0xc6, - 0x8c, 0x47, 0x43, 0xef, 0x1d, 0x30, 0xae, 0x9f, 0x8a, 0x78, 0xc6, 0x00, 0x88, 0xe3, 0xe2, 0xd1, - 0xd7, 0xb5, 0xc0, 0x35, 0xca, 0x1e, 0xcd, 0x9e, 0x54, 0x8f, 0x50, 0xe8, 0x69, 0x65, 0x87, 0x62, - 0xc2, 0xf5, 0x7f, 0xce, 0xc3, 0xcc, 0xaa, 0x61, 0x1b, 0xee, 0x81, 0x70, 0x2d, 0x7f, 0xa2, 0xc1, - 0xb9, 0x66, 0xcf, 0x75, 0x89, 0xed, 0x37, 0x7c, 0xd2, 0x4d, 0x3a, 0x16, 0xed, 0x44, 0x1d, 0xcb, - 0x85, 0x41, 0xbf, 0x72, 0x6e, 0xf5, 0x08, 0xf9, 0xf8, 0xc8, 0xde, 0xa1, 0xbf, 0xd6, 0x40, 0x17, - 0x04, 0x75, 0xa3, 0x79, 0xa7, 0xed, 0x3a, 0x3d, 0xbb, 0x95, 0x1c, 0x44, 0xee, 0x44, 0x07, 0xf1, - 0xf8, 0xa0, 0x5f, 0xd1, 0x57, 0x8f, 0xed, 0x05, 0x1e, 0xa2, 0xa7, 0xe8, 0x05, 0x58, 0x14, 0x54, - 0x97, 0xef, 0x75, 0x89, 0x6b, 0xd2, 0xd8, 0x54, 0xdc, 0x34, 0x7f, 0x58, 0x98, 0xfd, 0xc5, 0xd5, - 0x38, 0x01, 0x4e, 0xb6, 0xd1, 0xff, 0x68, 0x02, 0x20, 0x58, 0x69, 0xd2, 0x45, 0x3f, 0x05, 0xd3, - 0x1e, 0xf1, 0x6f, 0x11, 0xb3, 0xbd, 0xe7, 0xb3, 0x35, 0x2d, 0x88, 0x6b, 0x8d, 0x00, 0x88, 0x43, - 0x3c, 0xba, 0x03, 0x85, 0xae, 0xd1, 0xf3, 0x88, 0x98, 0xb7, 0xf5, 0x4c, 0xe6, 0x6d, 0x8b, 0x72, - 0xe4, 0xb1, 0x3f, 0xfb, 0x13, 0x73, 0x19, 0xe8, 0x2b, 0x1a, 0x00, 0x51, 0xc7, 0x5a, 0xba, 0xd8, - 0xc8, 0x44, 0x64, 0x38, 0x1d, 0x74, 0x0e, 0xea, 0x73, 0x83, 0x7e, 0x05, 0x22, 0xb3, 0x16, 0x11, - 0x8b, 0xee, 0x42, 0xd1, 0x08, 0xcc, 0xd9, 0xc4, 0x49, 0x98, 0x33, 0x16, 0x92, 0xcb, 0xf5, 0x96, - 0xc2, 0xd0, 0xdb, 0x1a, 0xcc, 0x79, 0xc4, 0x17, 0x4b, 0x45, 0xfd, 0x93, 0x88, 0xe5, 0x36, 0xc6, - 0x93, 0xdf, 0x50, 0x78, 0x72, 0xe3, 0xa0, 0xc2, 0x70, 0x4c, 0xae, 0xfe, 0x9f, 0x45, 0x98, 0x0b, - 0x54, 0x26, 0x0c, 0xcf, 0x9a, 0x1c, 0x92, 0x1e, 0x9e, 0xad, 0x46, 0x91, 0x58, 0xa5, 0xa5, 0x8d, - 0x3d, 0x9f, 0xc6, 0x03, 0x6a, 0x74, 0x26, 0x1b, 0x37, 0xa2, 0x48, 0xac, 0xd2, 0xa2, 0x0e, 0x14, - 0x3c, 0x9f, 0x74, 0x83, 0x4b, 0xc3, 0xab, 0xe3, 0xcd, 0x46, 0xb8, 0x13, 0xc2, 0x0b, 0x1f, 0xfa, - 0xcb, 0xc3, 0x5c, 0x0a, 0x7a, 0x47, 0x83, 0x39, 0x5f, 0x49, 0x28, 0x09, 0x35, 0xc8, 0x46, 0x13, - 0xd5, 0x5c, 0x15, 0x5f, 0x0d, 0x15, 0x86, 0x63, 0xe2, 0x53, 0x22, 0xb6, 0xc2, 0x09, 0x46, 0x6c, - 0x2f, 0x43, 0xb1, 0x63, 0xdc, 0x6b, 0xf4, 0xdc, 0xf6, 0x83, 0x47, 0x86, 0x4c, 0xc5, 0x37, 0x05, - 0x17, 0x2c, 0xf9, 0xa1, 0x37, 0xb5, 0xc8, 0xe6, 0x9a, 0x62, 0xcc, 0x6f, 0x65, 0xbb, 0xb9, 0xa4, - 0x41, 0x3d, 0x74, 0x9b, 0x25, 0xe2, 0xa7, 0xe2, 0x43, 0x8f, 0x9f, 0x68, 0x2c, 0xc0, 0x37, 0x88, - 0x8c, 0x05, 0xa6, 0x4f, 0x34, 0x16, 0x58, 0x55, 0x84, 0xe1, 0x98, 0x70, 0xd6, 0x1f, 0xbe, 0xe7, - 0x64, 0x7f, 0xe0, 0x44, 0xfb, 0xd3, 0x50, 0x84, 0xe1, 0x98, 0x70, 0xfd, 0x87, 0x1a, 0x9c, 0x59, - 0xb5, 0x7a, 0x9e, 0x4f, 0xdc, 0xff, 0x35, 0x77, 0xea, 0xff, 0xa1, 0xc1, 0xa3, 0x87, 0x8c, 0xf9, - 0x21, 0x5c, 0xad, 0xbf, 0xae, 0x5e, 0xad, 0xdf, 0x1c, 0xd3, 0xc6, 0xa6, 0x8f, 0xe3, 0x90, 0x1b, - 0x76, 0x1f, 0x66, 0x2f, 0x19, 0xbe, 0xd1, 0x72, 0xda, 0xfc, 0xca, 0x1b, 0x3d, 0x0f, 0x45, 0xd3, - 0xf6, 0x89, 0xbb, 0x6f, 0x58, 0xc2, 0xcb, 0xe8, 0x41, 0xd7, 0xd7, 0x04, 0xfc, 0x7e, 0xbf, 0x32, - 0x77, 0xa9, 0xe7, 0xb2, 0xb4, 0x38, 0xb7, 0x39, 0x58, 0xb6, 0x41, 0x8f, 0x41, 0xe1, 0x73, 0x3d, - 0xe2, 0x1e, 0xc4, 0x53, 0xb1, 0x37, 0x28, 0x10, 0x73, 0x9c, 0xfe, 0xb7, 0x39, 0x88, 0x44, 0x00, - 0x0f, 0x41, 0xad, 0x6c, 0x45, 0xad, 0xc6, 0xf4, 0xe9, 0x91, 0x78, 0xe6, 0xb0, 0x1c, 0xfa, 0x7e, - 0x2c, 0x87, 0x7e, 0x2d, 0x33, 0x89, 0x47, 0xa7, 0xd0, 0xdf, 0xd7, 0xe0, 0xd1, 0x90, 0x38, 0x19, - 0xd7, 0x1e, 0x7f, 0x49, 0xfc, 0x0c, 0x94, 0x8c, 0xb0, 0x99, 0x58, 0x45, 0x59, 0x5d, 0x11, 0xe1, - 0x88, 0xa3, 0x74, 0x61, 0x1a, 0x33, 0xff, 0x80, 0x69, 0xcc, 0x89, 0xa3, 0xd3, 0x98, 0xfa, 0x8f, - 0x72, 0x70, 0x3e, 0x39, 0xb2, 0x40, 0xbb, 0x31, 0xd9, 0x1d, 0x62, 0x6c, 0xcf, 0xc2, 0x8c, 0x2f, - 0x1a, 0x50, 0xa8, 0x18, 0xdc, 0x92, 0xa0, 0x9c, 0xd9, 0x8e, 0xe0, 0xb0, 0x42, 0x49, 0x5b, 0x36, - 0xf9, 0xbe, 0x6a, 0x34, 0x9d, 0x6e, 0x90, 0xef, 0x95, 0x2d, 0x57, 0x23, 0x38, 0xac, 0x50, 0xca, - 0xc4, 0xd1, 0xc4, 0x89, 0x27, 0xa4, 0x1b, 0x70, 0x3a, 0xc8, 0x1f, 0x5c, 0x71, 0xdc, 0x55, 0xa7, - 0xd3, 0xb5, 0x08, 0x4b, 0x7f, 0x14, 0x58, 0x67, 0xcf, 0x8b, 0x26, 0xa7, 0x71, 0x1a, 0x11, 0x4e, - 0x6f, 0xab, 0xbf, 0x9f, 0x87, 0x53, 0xe1, 0xb4, 0xaf, 0x3a, 0x76, 0xcb, 0x64, 0x59, 0x98, 0xe7, - 0x60, 0xc2, 0x3f, 0xe8, 0x06, 0x93, 0xfd, 0xff, 0x82, 0xee, 0x6c, 0x1f, 0x74, 0xe9, 0x6a, 0x9f, - 0x49, 0x69, 0x42, 0x51, 0x98, 0x35, 0x42, 0x1b, 0x72, 0x77, 0xf0, 0x15, 0x78, 0x5a, 0xd5, 0xe6, - 0xfb, 0xfd, 0x4a, 0x4a, 0x4d, 0x55, 0x55, 0x72, 0x52, 0x75, 0x1e, 0xdd, 0x86, 0x39, 0xcb, 0xf0, - 0xfc, 0x9b, 0xdd, 0x96, 0xe1, 0x93, 0x6d, 0xb3, 0x43, 0xc4, 0x9e, 0x1b, 0x25, 0xb7, 0x2c, 0xaf, - 0x2a, 0x37, 0x14, 0x4e, 0x38, 0xc6, 0x19, 0xed, 0x03, 0xa2, 0x90, 0x6d, 0xd7, 0xb0, 0x3d, 0x3e, - 0x2a, 0x2a, 0x6f, 0xf4, 0x5c, 0xf6, 0x59, 0x21, 0x0f, 0x6d, 0x24, 0xb8, 0xe1, 0x14, 0x09, 0xe8, - 0x71, 0x98, 0x74, 0x89, 0xe1, 0x89, 0xc5, 0x9c, 0x0e, 0xf7, 0x3f, 0x66, 0x50, 0x2c, 0xb0, 0xd1, - 0x0d, 0x35, 0x79, 0xcc, 0x86, 0xfa, 0xbe, 0x06, 0x73, 0xe1, 0x32, 0x3d, 0x04, 0x37, 0xd7, 0x51, - 0xdd, 0xdc, 0xd5, 0xac, 0x4c, 0xe2, 0x21, 0x9e, 0xed, 0x83, 0x7c, 0x74, 0x7c, 0x2c, 0x6b, 0xfc, - 0x79, 0x98, 0x0e, 0x76, 0x75, 0x90, 0x37, 0x1e, 0x33, 0xf2, 0x54, 0x22, 0x8b, 0x48, 0xf9, 0x87, - 0x10, 0x82, 0x43, 0x79, 0xd4, 0xb1, 0xb6, 0x84, 0xd3, 0x14, 0x6a, 0x2f, 0x1d, 0x6b, 0xe0, 0x4c, - 0xd3, 0x1c, 0x6b, 0xd0, 0x06, 0xdd, 0x84, 0x33, 0x5d, 0xd7, 0x61, 0x95, 0x73, 0x97, 0x88, 0xd1, - 0xb2, 0x4c, 0x9b, 0x04, 0xd7, 0xb9, 0xfc, 0xa6, 0xfc, 0xd1, 0x41, 0xbf, 0x72, 0x66, 0x2b, 0x9d, - 0x04, 0x1f, 0xd6, 0x56, 0x2d, 0x63, 0x99, 0x38, 0xbe, 0x8c, 0x05, 0xfd, 0x92, 0x3c, 0x46, 0x10, - 0xaf, 0x5c, 0x60, 0x93, 0xf8, 0x4a, 0x56, 0x4b, 0x99, 0x62, 0xd6, 0x43, 0x95, 0xaa, 0x09, 0xa1, - 0x58, 0x8a, 0xd7, 0xdf, 0x2a, 0xc0, 0x42, 0xdc, 0x37, 0x9e, 0x7c, 0x45, 0xcd, 0xaf, 0x6a, 0xb0, - 0x10, 0xac, 0x2b, 0x97, 0x49, 0x82, 0xf3, 0xf1, 0x46, 0x46, 0xea, 0xc4, 0xbd, 0xbc, 0x2c, 0x4c, - 0xdc, 0x8e, 0x49, 0xc3, 0x09, 0xf9, 0xe8, 0x35, 0x28, 0xc9, 0x63, 0xe4, 0x03, 0x95, 0xd7, 0xcc, - 0x33, 0xff, 0x1e, 0xb2, 0xc0, 0x51, 0x7e, 0xe8, 0x2d, 0x0d, 0xa0, 0x19, 0x18, 0xe0, 0x60, 0xdd, - 0x6f, 0x64, 0xb5, 0xee, 0xd2, 0xb4, 0x87, 0x61, 0x9c, 0x04, 0x79, 0x38, 0x22, 0x18, 0xfd, 0x1a, - 0x3b, 0x40, 0xca, 0xb8, 0xc3, 0x2b, 0x4f, 0xb2, 0x9e, 0x7c, 0x26, 0x6b, 0x0d, 0x0c, 0xaf, 0x15, - 0xa5, 0x93, 0x8f, 0xa0, 0x3c, 0xac, 0x74, 0x42, 0x7f, 0x0e, 0x64, 0x9a, 0x97, 0x6e, 0x28, 0x96, - 0xe8, 0xdd, 0x32, 0xfc, 0x3d, 0xa1, 0x82, 0x72, 0x43, 0x5d, 0x09, 0x10, 0x38, 0xa4, 0xd1, 0xff, - 0x5c, 0x83, 0xa5, 0x35, 0xcf, 0x37, 0x9d, 0x4b, 0xc4, 0xf3, 0xe9, 0x1e, 0xa3, 0xee, 0xb8, 0x67, - 0x91, 0x21, 0x02, 0x9a, 0x4b, 0xb0, 0x20, 0xee, 0x7a, 0x7a, 0x3b, 0x1e, 0xf1, 0x23, 0x41, 0x8d, - 0x54, 0x9d, 0xd5, 0x18, 0x1e, 0x27, 0x5a, 0x50, 0x2e, 0xe2, 0xd2, 0x27, 0xe4, 0x92, 0x57, 0xb9, - 0x34, 0x62, 0x78, 0x9c, 0x68, 0xa1, 0x7f, 0x33, 0x07, 0xa7, 0xd8, 0x30, 0x62, 0x05, 0xc1, 0xbf, - 0xa2, 0xc1, 0xdc, 0xbe, 0xe9, 0xfa, 0x3d, 0xc3, 0x8a, 0xde, 0x5e, 0x8d, 0xad, 0x3d, 0x4c, 0xd6, - 0x4b, 0x0a, 0xe3, 0xd0, 0x8d, 0xab, 0x70, 0x1c, 0xeb, 0x00, 0xed, 0xd3, 0x7c, 0x4b, 0x9d, 0xed, - 0x6c, 0x4e, 0x9c, 0x69, 0xeb, 0xc8, 0x73, 0x14, 0x31, 0x20, 0x8e, 0xcb, 0xd7, 0x5f, 0x11, 0xd3, - 0xa7, 0x76, 0x7d, 0x08, 0x25, 0xd0, 0x61, 0xd2, 0x75, 0x7a, 0xd4, 0xa5, 0x51, 0xc7, 0x3a, 0x5d, - 0x07, 0x16, 0x17, 0x30, 0x08, 0x16, 0x18, 0xfd, 0x0f, 0x35, 0x98, 0x5e, 0x77, 0x76, 0xc4, 0x19, - 0xef, 0xe7, 0x33, 0x38, 0x6f, 0x49, 0xb3, 0x2c, 0x2f, 0x12, 0x42, 0x4f, 0xff, 0xbc, 0x72, 0xda, - 0x3a, 0x17, 0xe1, 0x5d, 0x65, 0x55, 0xf4, 0x94, 0xd5, 0xba, 0xb3, 0x73, 0xe8, 0x71, 0xfc, 0x77, - 0x0b, 0x30, 0xfb, 0xa2, 0x71, 0x40, 0x6c, 0xdf, 0x10, 0x3d, 0xfe, 0x18, 0x4c, 0x19, 0xad, 0x56, - 0x5a, 0x55, 0x79, 0x8d, 0x83, 0x71, 0x80, 0x67, 0x07, 0x98, 0x2e, 0x4b, 0x09, 0x47, 0x5c, 0x6d, - 0x78, 0x80, 0x09, 0x51, 0x38, 0x4a, 0x17, 0x6e, 0xa5, 0x55, 0xc7, 0xde, 0x35, 0xdb, 0x69, 0x9b, - 0x60, 0x35, 0x86, 0xc7, 0x89, 0x16, 0x68, 0x1d, 0x90, 0xa8, 0x18, 0xab, 0x35, 0x9b, 0x4e, 0xcf, - 0xe6, 0x9b, 0x89, 0x9f, 0x6d, 0x64, 0xcc, 0xb7, 0x99, 0xa0, 0xc0, 0x29, 0xad, 0xd0, 0xab, 0x50, - 0x6e, 0x32, 0xce, 0x22, 0x02, 0x88, 0x72, 0xe4, 0x51, 0xa0, 0x2c, 0xc7, 0x58, 0x3d, 0x84, 0x0e, - 0x1f, 0xca, 0x81, 0xf6, 0xd4, 0xf3, 0x1d, 0xd7, 0x68, 0x93, 0x28, 0xdf, 0x49, 0xb5, 0xa7, 0x8d, - 0x04, 0x05, 0x4e, 0x69, 0x85, 0xbe, 0x04, 0xd3, 0xfe, 0x9e, 0x4b, 0xbc, 0x3d, 0xc7, 0x6a, 0x89, - 0x9b, 0xc5, 0x31, 0x0f, 0xbc, 0x62, 0xf5, 0xb7, 0x03, 0xae, 0x91, 0x98, 0x24, 0x00, 0xe1, 0x50, - 0x26, 0x72, 0x61, 0xd2, 0xa3, 0xa7, 0x2d, 0xaf, 0x5c, 0xcc, 0x22, 0xaa, 0x13, 0xd2, 0xd9, 0x01, - 0x2e, 0x72, 0xd4, 0x66, 0x12, 0xb0, 0x90, 0xa4, 0xff, 0x45, 0x0e, 0x66, 0xa2, 0x84, 0x43, 0xec, - 0xd4, 0xaf, 0x68, 0x30, 0xd3, 0x74, 0x6c, 0xdf, 0x75, 0x2c, 0x7e, 0x8c, 0xe4, 0x1b, 0x64, 0xcc, - 0xca, 0x6c, 0xc6, 0xea, 0x12, 0xf1, 0x0d, 0xd3, 0x8a, 0x9c, 0x48, 0x23, 0x62, 0xb0, 0x22, 0x14, - 0x7d, 0x4d, 0x83, 0xf9, 0x30, 0xe5, 0x12, 0x9e, 0x67, 0x33, 0xed, 0x88, 0xac, 0x5a, 0xba, 0xac, - 0x4a, 0xc2, 0x71, 0xd1, 0xfa, 0x0e, 0x2c, 0xc4, 0x57, 0x9b, 0x4e, 0x65, 0xd7, 0x10, 0x7b, 0x3d, - 0x1f, 0x4e, 0xe5, 0x96, 0xe1, 0x79, 0x98, 0x61, 0xd0, 0xc7, 0xa1, 0xd8, 0x31, 0xdc, 0xb6, 0x69, - 0x1b, 0x16, 0x9b, 0xc5, 0x7c, 0xc4, 0x20, 0x09, 0x38, 0x96, 0x14, 0xfa, 0x0f, 0x26, 0xa0, 0xb4, - 0x49, 0x0c, 0xaf, 0xe7, 0x12, 0x76, 0xe1, 0x74, 0xe2, 0x21, 0xa2, 0x52, 0xea, 0x9c, 0xcf, 0xae, - 0xd4, 0x19, 0xbd, 0x0c, 0xb0, 0x6b, 0xda, 0xa6, 0xb7, 0xf7, 0x80, 0x45, 0xd4, 0x2c, 0xf9, 0x76, - 0x45, 0x72, 0xc0, 0x11, 0x6e, 0xe1, 0x2b, 0x8a, 0xc2, 0x11, 0xaf, 0x28, 0xde, 0xd2, 0x22, 0xce, - 0x83, 0x07, 0x5f, 0xb7, 0xc6, 0xad, 0xbd, 0x95, 0x0b, 0x53, 0x0d, 0x9c, 0xc9, 0x65, 0xdb, 0x77, - 0x0f, 0x8e, 0xf4, 0x31, 0xdb, 0x50, 0x74, 0x89, 0xd7, 0xeb, 0xd0, 0x60, 0x77, 0x6a, 0xe4, 0x69, - 0x60, 0xf9, 0x09, 0x2c, 0xda, 0x63, 0xc9, 0xe9, 0xec, 0x73, 0x30, 0xab, 0x74, 0x01, 0x2d, 0x40, - 0xfe, 0x0e, 0x39, 0xe0, 0x7a, 0x82, 0xe9, 0x9f, 0x68, 0x49, 0xa9, 0xa2, 0x14, 0xd3, 0xf2, 0xa9, - 0xdc, 0xb3, 0x9a, 0xfe, 0xa3, 0x49, 0x98, 0x14, 0xfe, 0xea, 0x78, 0x5b, 0x10, 0xbd, 0x67, 0xcd, - 0x3d, 0xc0, 0x3d, 0xeb, 0x3a, 0xcc, 0x98, 0xb6, 0xe9, 0x9b, 0x86, 0xc5, 0x8a, 0x68, 0x84, 0xaf, - 0x7a, 0x3c, 0xd8, 0xff, 0x6b, 0x11, 0x5c, 0x0a, 0x1f, 0xa5, 0x2d, 0xba, 0x01, 0x05, 0x66, 0xcc, - 0x85, 0x3e, 0x8d, 0x9e, 0x72, 0x62, 0xe9, 0x64, 0x5e, 0x96, 0xc5, 0x39, 0xb1, 0x98, 0xb2, 0xd7, - 0x6c, 0x12, 0xcf, 0x93, 0x81, 0xbc, 0x50, 0xab, 0x30, 0xa6, 0x8c, 0xe1, 0x71, 0xa2, 0x05, 0xe5, - 0xb2, 0x6b, 0x98, 0x56, 0xcf, 0x25, 0x21, 0x97, 0x49, 0x95, 0xcb, 0x95, 0x18, 0x1e, 0x27, 0x5a, - 0xa0, 0x5d, 0x98, 0x11, 0x30, 0x5e, 0xa6, 0x34, 0xf5, 0x80, 0xa3, 0x64, 0x99, 0xa5, 0x2b, 0x11, - 0x4e, 0x58, 0xe1, 0x8b, 0x7a, 0xb0, 0x68, 0xda, 0x4d, 0xc7, 0x6e, 0x5a, 0x3d, 0xcf, 0xdc, 0x27, - 0x61, 0x4d, 0xd4, 0x83, 0x08, 0x3b, 0x3d, 0xe8, 0x57, 0x16, 0xd7, 0xe2, 0xec, 0x70, 0x52, 0x02, - 0x7a, 0x53, 0x83, 0xd3, 0x4d, 0xc7, 0xf6, 0x58, 0x55, 0xf0, 0x3e, 0xb9, 0xec, 0xba, 0x8e, 0xcb, - 0x65, 0x4f, 0x3f, 0xa0, 0x6c, 0x56, 0xf3, 0xb3, 0x9a, 0xc6, 0x12, 0xa7, 0x4b, 0x42, 0xaf, 0x43, - 0xb1, 0xeb, 0x3a, 0xfb, 0x66, 0x8b, 0xb8, 0x22, 0x7b, 0xb5, 0x91, 0x45, 0x41, 0xfe, 0x96, 0xe0, - 0x19, 0x5a, 0x82, 0x00, 0x82, 0xa5, 0x3c, 0xfd, 0x1b, 0x93, 0x30, 0xa7, 0x92, 0xa3, 0x2f, 0x02, - 0x74, 0x5d, 0xa7, 0x43, 0xfc, 0x3d, 0x22, 0x6b, 0x67, 0xae, 0x8d, 0x5b, 0x0c, 0x1f, 0xf0, 0x13, - 0x6f, 0x05, 0x98, 0x25, 0x0d, 0xa1, 0x38, 0x22, 0x11, 0xb9, 0x30, 0x75, 0x87, 0xfb, 0x34, 0xe1, - 0xe2, 0x5f, 0xcc, 0x24, 0x20, 0x11, 0x92, 0x4b, 0xd4, 0xe5, 0x08, 0x10, 0x0e, 0x04, 0xa1, 0x1d, - 0xc8, 0xdf, 0x25, 0x3b, 0xd9, 0x94, 0x6d, 0xdf, 0x22, 0xe2, 0xa8, 0x50, 0x9f, 0x1a, 0xf4, 0x2b, - 0xf9, 0x5b, 0x64, 0x07, 0x53, 0xe6, 0x74, 0x5c, 0x2d, 0x9e, 0x2d, 0x12, 0xa6, 0x62, 0xcc, 0x71, - 0x29, 0xa9, 0x27, 0x3e, 0x2e, 0x01, 0xc2, 0x81, 0x20, 0xf4, 0x3a, 0x4c, 0xdf, 0x35, 0xf6, 0xc9, - 0xae, 0xeb, 0xd8, 0xbe, 0xc8, 0xbd, 0x8f, 0x59, 0x13, 0x72, 0x2b, 0x60, 0x27, 0xe4, 0x32, 0x6f, - 0x2b, 0x81, 0x38, 0x14, 0x87, 0xf6, 0xa1, 0x68, 0x93, 0xbb, 0x98, 0x58, 0x66, 0x53, 0xa4, 0xe3, - 0xc7, 0x54, 0xeb, 0x6b, 0x82, 0x9b, 0x90, 0xcc, 0xdc, 0x50, 0x00, 0xc3, 0x52, 0x16, 0x5d, 0xcb, - 0xdb, 0xce, 0x8e, 0x30, 0x54, 0x63, 0xae, 0xa5, 0x3c, 0xf6, 0xf1, 0xb5, 0x5c, 0x77, 0x76, 0x30, - 0x65, 0xae, 0x7f, 0x73, 0x02, 0x66, 0xa2, 0xcf, 0xb5, 0x86, 0xf0, 0x59, 0x32, 0x6c, 0xca, 0x8d, - 0x12, 0x36, 0xd1, 0xa8, 0xb7, 0x13, 0xfa, 0xf8, 0xe0, 0xaa, 0x6c, 0x2d, 0xb3, 0xa8, 0x21, 0x8c, - 0x7a, 0x23, 0x40, 0x0f, 0x2b, 0x42, 0x47, 0x48, 0x35, 0xd1, 0x38, 0x88, 0xbb, 0x43, 0x5e, 0xe7, - 0x2b, 0xe3, 0x20, 0xc5, 0xc1, 0x5d, 0x04, 0x10, 0xee, 0x6a, 0xb7, 0x67, 0x31, 0xe5, 0x28, 0x84, - 0x97, 0x57, 0x0d, 0x89, 0xc1, 0x11, 0x2a, 0xf4, 0x38, 0x4c, 0x52, 0x87, 0x41, 0x5a, 0xa2, 0x00, - 0x57, 0x1e, 0x2d, 0xae, 0x30, 0x28, 0x16, 0x58, 0xf4, 0x2c, 0xf5, 0xed, 0xa1, 0x99, 0x17, 0x75, - 0xb5, 0x4b, 0xa1, 0x6f, 0x0f, 0x71, 0x58, 0xa1, 0xa4, 0x5d, 0x27, 0xd4, 0x2a, 0x33, 0xd3, 0x1f, - 0xe9, 0x3a, 0x33, 0xd5, 0x98, 0xe3, 0xd8, 0x51, 0x37, 0x66, 0xc5, 0x99, 0xd1, 0x2e, 0x44, 0x8e, - 0xba, 0x31, 0x3c, 0x4e, 0xb4, 0xd0, 0x3f, 0x0b, 0x73, 0xaa, 0x36, 0xd3, 0x29, 0xee, 0xba, 0xce, - 0xae, 0x69, 0x91, 0xf8, 0x21, 0x7d, 0x8b, 0x83, 0x71, 0x80, 0x1f, 0x2e, 0x4b, 0xfc, 0x97, 0x79, - 0x38, 0x75, 0xad, 0x6d, 0xda, 0xf7, 0x62, 0x37, 0x4a, 0x69, 0x2f, 0xb9, 0xb5, 0x51, 0x5f, 0x72, - 0x87, 0x65, 0x51, 0xe2, 0x5d, 0x7a, 0x7a, 0x59, 0x54, 0xf0, 0x68, 0x5d, 0xa5, 0x45, 0xdf, 0xd7, - 0xe0, 0x9c, 0xd1, 0xe2, 0xf1, 0x85, 0x61, 0x09, 0x68, 0x28, 0x34, 0xd0, 0x71, 0x6f, 0x4c, 0x6b, - 0x91, 0x1c, 0x7c, 0xb5, 0x76, 0x84, 0x54, 0x1e, 0x35, 0x7f, 0x54, 0x8c, 0xe0, 0xdc, 0x51, 0xa4, - 0xf8, 0xc8, 0xee, 0x9f, 0xbd, 0x0e, 0x1f, 0x39, 0x56, 0xd0, 0x48, 0xb1, 0xf1, 0xef, 0x69, 0x30, - 0xc7, 0xea, 0x0d, 0xc3, 0xb0, 0xec, 0x19, 0x99, 0xd3, 0xe2, 0x8b, 0x77, 0x5e, 0xcd, 0x69, 0xdd, - 0xef, 0x57, 0x4a, 0xbc, 0x42, 0x51, 0x4d, 0x71, 0xbd, 0x22, 0x8e, 0x56, 0x2c, 0xf3, 0x96, 0x1b, - 0x39, 0xf2, 0x97, 0x17, 0x09, 0x8d, 0x80, 0x09, 0x0e, 0xf9, 0xe9, 0xdf, 0xc8, 0xc3, 0xa9, 0x94, - 0xc2, 0x19, 0x7a, 0xea, 0x99, 0xb4, 0x8c, 0x1d, 0x62, 0x05, 0x79, 0xa3, 0xd7, 0x32, 0x2f, 0xce, - 0xa9, 0x6e, 0x30, 0xfe, 0x7c, 0x0d, 0xa5, 0x65, 0xe0, 0x40, 0x2c, 0x84, 0xa3, 0xdf, 0xd0, 0xa0, - 0x64, 0x44, 0xd4, 0x8c, 0xa7, 0xd2, 0x76, 0xb2, 0xef, 0x4c, 0x42, 0xab, 0x22, 0x25, 0x00, 0xa1, - 0x12, 0x45, 0xfb, 0x72, 0xf6, 0x67, 0xa1, 0x14, 0x19, 0xc2, 0x28, 0xda, 0x71, 0xf6, 0x79, 0x58, - 0x18, 0x4b, 0xbb, 0x3e, 0x03, 0xa3, 0xbe, 0x3b, 0xa4, 0xb6, 0xf8, 0x6e, 0xb4, 0x0c, 0x57, 0xce, - 0xb8, 0xa8, 0xc3, 0x15, 0x58, 0x7d, 0x07, 0x16, 0xe2, 0xa1, 0xdf, 0x28, 0xb7, 0x91, 0x43, 0x19, - 0xba, 0x4f, 0xc2, 0x88, 0x2f, 0x05, 0xf5, 0xbf, 0xca, 0xc1, 0x94, 0xa8, 0xbe, 0x7b, 0x08, 0xd5, - 0x33, 0x77, 0x94, 0xfb, 0xdc, 0xb5, 0x4c, 0x8a, 0x06, 0x0f, 0x2d, 0x9d, 0xf1, 0x62, 0xa5, 0x33, - 0x2f, 0x66, 0x23, 0xee, 0xe8, 0xba, 0x99, 0x77, 0x72, 0x30, 0x1f, 0xab, 0x66, 0x44, 0xbf, 0xa8, - 0x25, 0xd3, 0xc5, 0x37, 0x33, 0x2d, 0x98, 0x94, 0xb5, 0x59, 0x47, 0x67, 0x8e, 0x3d, 0xe5, 0xed, - 0xf1, 0x8d, 0xcc, 0xbe, 0xe3, 0x70, 0xe4, 0x33, 0xe4, 0x7f, 0xd2, 0xe0, 0xc3, 0x87, 0xd6, 0x77, - 0xb2, 0x37, 0x1e, 0xae, 0x8a, 0x15, 0xba, 0x97, 0x71, 0xbd, 0xb6, 0xbc, 0x47, 0x8c, 0x97, 0xfd, - 0xc7, 0xc5, 0xa3, 0xa7, 0x61, 0x86, 0xd9, 0x71, 0xba, 0x7d, 0x7c, 0xd2, 0x15, 0x9f, 0x93, 0x61, - 0x67, 0xf6, 0x46, 0x04, 0x8e, 0x15, 0x2a, 0xfd, 0x77, 0x34, 0x28, 0x1f, 0xf6, 0xa2, 0x60, 0x88, - 0x88, 0xf8, 0x67, 0x62, 0x95, 0x2c, 0x95, 0x44, 0x25, 0x4b, 0x2c, 0x26, 0x0e, 0x8a, 0x56, 0x22, - 0xe1, 0x68, 0xfe, 0x98, 0x42, 0x8d, 0xaf, 0x6b, 0x70, 0xe6, 0x10, 0xc5, 0x49, 0x54, 0x34, 0x69, - 0x0f, 0x5c, 0xd1, 0x94, 0x1b, 0xb6, 0xa2, 0x49, 0xff, 0x9b, 0x3c, 0x2c, 0x88, 0xfe, 0x84, 0xce, - 0xfc, 0x59, 0xa5, 0x1e, 0xe8, 0xa3, 0xb1, 0x7a, 0xa0, 0xa5, 0x38, 0xfd, 0xff, 0x15, 0x03, 0xfd, - 0x64, 0x15, 0x03, 0xfd, 0x38, 0x07, 0xa7, 0x53, 0x5f, 0x6b, 0xa0, 0xb7, 0x53, 0xac, 0xe0, 0xad, - 0x8c, 0x9f, 0x85, 0x0c, 0x69, 0x07, 0xc7, 0xad, 0xa0, 0xf9, 0xf5, 0x68, 0xe5, 0x0a, 0x0f, 0xd0, - 0x77, 0x4f, 0xe0, 0x81, 0xcb, 0xa8, 0x45, 0x2c, 0xbf, 0x9c, 0x87, 0x27, 0x86, 0x65, 0xf4, 0x13, - 0x5a, 0xe4, 0xe8, 0x29, 0x45, 0x8e, 0x0f, 0xc7, 0x43, 0x9d, 0x4c, 0xbd, 0xe3, 0x57, 0xf3, 0xd2, - 0xed, 0x25, 0xf5, 0x73, 0xa8, 0x6b, 0xfd, 0x29, 0x1a, 0xc5, 0x04, 0xdf, 0x12, 0x08, 0x4d, 0xe1, - 0x54, 0x83, 0x83, 0xef, 0xf7, 0x2b, 0x8b, 0xe2, 0xc9, 0x72, 0x83, 0xf8, 0x02, 0x88, 0x83, 0x46, - 0xe8, 0x09, 0x28, 0xba, 0x1c, 0x1b, 0x94, 0x75, 0x89, 0x54, 0x05, 0x87, 0x61, 0x89, 0x45, 0x5f, - 0x8a, 0x84, 0x7d, 0x13, 0x27, 0xf5, 0x60, 0xe0, 0xa8, 0x0c, 0xcc, 0x6b, 0x50, 0xf4, 0x82, 0x0f, - 0x0d, 0xf0, 0x7b, 0xb9, 0xa7, 0x86, 0xac, 0x16, 0xa4, 0xa7, 0x84, 0xe0, 0xab, 0x03, 0x7c, 0x7c, - 0xf2, 0x9b, 0x04, 0x92, 0xa5, 0xfe, 0xbe, 0x06, 0x25, 0xb1, 0x12, 0x0f, 0xa1, 0x38, 0xf1, 0xb6, - 0x5a, 0x9c, 0x78, 0x39, 0x13, 0xbb, 0x70, 0x48, 0x65, 0xe2, 0x6d, 0x98, 0x89, 0x3e, 0xc6, 0x43, - 0x2f, 0x47, 0xec, 0x9a, 0x36, 0xce, 0xa3, 0x9f, 0xc0, 0xf2, 0x85, 0x36, 0x4f, 0xff, 0x4e, 0x41, - 0xce, 0x22, 0x2b, 0x81, 0x8c, 0xea, 0x97, 0x76, 0xa4, 0x7e, 0x45, 0x97, 0x37, 0x97, 0xf9, 0xf2, - 0xa2, 0x1b, 0x50, 0x0c, 0x8c, 0x8f, 0x70, 0xd1, 0x8f, 0x45, 0xeb, 0x44, 0xa8, 0x9f, 0xa7, 0xcc, - 0x22, 0x4a, 0xc9, 0x4e, 0x0c, 0x72, 0x0d, 0xa5, 0x51, 0x94, 0x6c, 0x50, 0x0d, 0xe6, 0x3b, 0xa6, - 0x8d, 0x89, 0xd1, 0x92, 0x0f, 0xdd, 0x27, 0xf8, 0x37, 0x04, 0x82, 0x20, 0x72, 0x53, 0x45, 0xe3, - 0x38, 0x3d, 0xfa, 0x3c, 0x14, 0x3d, 0xf1, 0xe8, 0x2e, 0x9b, 0xbb, 0x66, 0x79, 0xfc, 0xe0, 0x4c, - 0xc3, 0xfe, 0x07, 0x10, 0x2c, 0x05, 0xa2, 0x0d, 0x58, 0x72, 0xc5, 0x5b, 0xf8, 0xab, 0xa6, 0xe7, - 0x3b, 0xee, 0x01, 0x4f, 0xe3, 0xf0, 0xcb, 0x45, 0xf6, 0x54, 0x1d, 0xa7, 0xe0, 0x71, 0x6a, 0x2b, - 0x1a, 0x25, 0xb0, 0x97, 0x9d, 0xfc, 0xb2, 0xb1, 0x18, 0x46, 0x09, 0x4c, 0xe9, 0x5a, 0x58, 0x60, - 0x8f, 0xaa, 0x2b, 0x2d, 0x8e, 0x51, 0x57, 0x7a, 0x0b, 0xa6, 0x5d, 0xc2, 0x42, 0xed, 0x5a, 0x90, - 0x88, 0x1a, 0x39, 0x03, 0x8e, 0x03, 0x06, 0x38, 0xe4, 0xa5, 0xff, 0xf1, 0x0c, 0xcc, 0x2a, 0x87, - 0x3a, 0x7a, 0xc6, 0x36, 0x76, 0x1c, 0x97, 0x9f, 0xe4, 0x8b, 0xe1, 0xa6, 0xab, 0x51, 0x20, 0xe6, - 0x38, 0xf4, 0x8e, 0x06, 0xf3, 0x5d, 0xe5, 0x02, 0x2a, 0xd8, 0xeb, 0x63, 0x5e, 0xe9, 0xab, 0xb7, - 0x5a, 0x91, 0xcf, 0xb5, 0xa8, 0xc2, 0x70, 0x5c, 0x3a, 0x55, 0x57, 0x51, 0x97, 0x61, 0x11, 0x97, - 0x51, 0x0b, 0x8f, 0x2b, 0x59, 0xac, 0xaa, 0x68, 0x1c, 0xa7, 0xa7, 0x93, 0xcc, 0x46, 0x37, 0xce, - 0x17, 0xd5, 0x6a, 0x01, 0x03, 0x1c, 0xf2, 0x42, 0xcf, 0xc3, 0x9c, 0x78, 0xcb, 0xbc, 0xe5, 0xb4, - 0xae, 0x1a, 0xde, 0x9e, 0x08, 0x35, 0x65, 0x68, 0xbc, 0xaa, 0x60, 0x71, 0x8c, 0x9a, 0x8d, 0x2d, - 0x7c, 0x30, 0xce, 0x18, 0x4c, 0xaa, 0x5f, 0xb3, 0x59, 0x55, 0xd1, 0x38, 0x4e, 0x8f, 0x3e, 0x1e, - 0xb1, 0x54, 0xfc, 0xba, 0x5c, 0xee, 0x9d, 0x14, 0x6b, 0x55, 0x83, 0xf9, 0x1e, 0x8b, 0xcc, 0x5b, - 0x01, 0x52, 0x68, 0xaf, 0x14, 0x78, 0x53, 0x45, 0xe3, 0x38, 0x3d, 0x7a, 0x0e, 0x66, 0x5d, 0x6a, - 0x0b, 0x24, 0x03, 0x7e, 0x87, 0x2e, 0x2f, 0x84, 0x71, 0x14, 0x89, 0x55, 0x5a, 0xf4, 0x02, 0x2c, - 0x86, 0xaf, 0x3a, 0x03, 0x06, 0xfc, 0x52, 0x5d, 0x3e, 0x18, 0xaf, 0xc5, 0x09, 0x70, 0xb2, 0x0d, - 0xfa, 0x39, 0x58, 0x88, 0xcc, 0xc4, 0x9a, 0xdd, 0x22, 0xf7, 0xd8, 0x87, 0x1d, 0x0a, 0xf5, 0x25, - 0x76, 0x31, 0x1f, 0xc3, 0xe1, 0x04, 0x35, 0xfa, 0x14, 0xcc, 0x35, 0x1d, 0xcb, 0x62, 0x16, 0x81, - 0x7f, 0x49, 0x65, 0x86, 0x67, 0x27, 0xd8, 0xba, 0x29, 0x18, 0x1c, 0xa3, 0x44, 0xeb, 0x80, 0x9c, - 0x1d, 0x8f, 0xb8, 0xfb, 0xa4, 0xf5, 0x02, 0xff, 0xdc, 0x2b, 0x75, 0x4a, 0xb3, 0x6a, 0x55, 0xd8, - 0xf5, 0x04, 0x05, 0x4e, 0x69, 0x85, 0xbe, 0xac, 0x96, 0x0c, 0xcf, 0x65, 0xf1, 0xdd, 0xb8, 0xf8, - 0x39, 0xf2, 0xd8, 0x7a, 0x61, 0x17, 0x26, 0x79, 0x91, 0x5e, 0x79, 0x3e, 0x8b, 0x97, 0xa6, 0xd1, - 0x8f, 0x36, 0x84, 0x16, 0x95, 0x43, 0xb1, 0x90, 0x84, 0xbe, 0x08, 0xd3, 0x3b, 0xc1, 0x17, 0x76, - 0xca, 0x0b, 0x59, 0x78, 0x91, 0xd8, 0xc7, 0xa2, 0xc2, 0x73, 0x92, 0x44, 0xe0, 0x50, 0x24, 0x7a, - 0x1c, 0x4a, 0x57, 0xb7, 0x6a, 0x52, 0x0b, 0x17, 0xd9, 0xea, 0x4f, 0xd0, 0x26, 0x38, 0x8a, 0xa0, - 0x3b, 0x4c, 0x7a, 0x78, 0xc4, 0x96, 0x38, 0xf4, 0x4e, 0x49, 0x87, 0x4d, 0xa9, 0x59, 0x0e, 0x04, - 0x37, 0xca, 0xa7, 0x62, 0xd4, 0x02, 0x8e, 0x25, 0x05, 0x7a, 0x0d, 0x4a, 0xc2, 0x64, 0x33, 0xdb, - 0xb4, 0xf4, 0x60, 0xe5, 0xe8, 0x38, 0x64, 0x81, 0xa3, 0xfc, 0xd0, 0x33, 0x50, 0xea, 0xb2, 0x0f, - 0x8f, 0x90, 0x2b, 0x3d, 0xcb, 0x2a, 0x9f, 0x66, 0x76, 0x53, 0x5e, 0x51, 0x6f, 0x85, 0x28, 0x1c, - 0xa5, 0xd3, 0xdf, 0x0c, 0xaf, 0xf9, 0xe4, 0xdb, 0xfa, 0x2f, 0x44, 0x57, 0x4b, 0xcb, 0xe2, 0xb3, - 0xb0, 0x89, 0xcf, 0x2b, 0x71, 0x43, 0x9b, 0xba, 0x56, 0x5d, 0xa9, 0x9f, 0x99, 0x3c, 0x4d, 0x54, - 0xbf, 0x1b, 0xc0, 0x4b, 0x81, 0x55, 0xed, 0xd4, 0xdf, 0xcf, 0xcb, 0xa3, 0x7e, 0x2c, 0xaf, 0xe6, - 0x42, 0xc1, 0xf4, 0x7c, 0xd3, 0xc9, 0xb0, 0x3e, 0x3b, 0xf6, 0xe0, 0x9e, 0xd5, 0x09, 0x31, 0x04, - 0xe6, 0xa2, 0xa8, 0x4c, 0xbb, 0x6d, 0xda, 0xf7, 0xc4, 0xf0, 0x6f, 0x64, 0x9e, 0x30, 0xe3, 0x32, - 0x19, 0x02, 0x73, 0x51, 0xe8, 0x36, 0xe4, 0x0d, 0x6b, 0x27, 0xa3, 0x4f, 0x00, 0xc7, 0x3f, 0x80, - 0xcd, 0xb3, 0xec, 0xb5, 0x8d, 0x3a, 0xa6, 0x42, 0xa8, 0x2c, 0xaf, 0x63, 0x0a, 0xdf, 0x3c, 0xa6, - 0xac, 0xc6, 0xe6, 0x5a, 0x9a, 0xac, 0xc6, 0xe6, 0x1a, 0xa6, 0x42, 0xf4, 0x77, 0x35, 0x58, 0x4c, - 0xd0, 0xc4, 0x3f, 0x97, 0xad, 0x0d, 0xff, 0xb9, 0x6c, 0xf1, 0x25, 0x84, 0x46, 0xd7, 0x32, 0x53, - 0x9f, 0x16, 0x6c, 0xc7, 0xf0, 0x38, 0xd1, 0x42, 0xff, 0x96, 0x06, 0xa5, 0x48, 0x59, 0x28, 0x0d, - 0xd5, 0x58, 0xf9, 0xac, 0xe8, 0x46, 0xf8, 0x11, 0x08, 0x76, 0xa9, 0xc0, 0x71, 0xfc, 0x7e, 0xab, - 0x1d, 0xde, 0xf2, 0x44, 0xee, 0xb7, 0x28, 0x14, 0x0b, 0x2c, 0x3d, 0x8d, 0x7b, 0x3e, 0xe9, 0xb2, - 0x85, 0x8c, 0x54, 0x89, 0xb2, 0x5b, 0x5e, 0x86, 0x61, 0xe2, 0xa8, 0xcd, 0x10, 0x29, 0xff, 0xc8, - 0x37, 0x27, 0x0c, 0x1a, 0x19, 0x32, 0x1c, 0x3a, 0x0f, 0x79, 0x62, 0xb7, 0x44, 0x80, 0x53, 0x12, - 0x24, 0xf9, 0xcb, 0x76, 0x0b, 0x53, 0xb8, 0x7e, 0x1d, 0x66, 0x1a, 0xa4, 0xe9, 0x12, 0xff, 0x45, - 0x72, 0x30, 0xdc, 0x0d, 0xcc, 0x79, 0x9e, 0xb9, 0xca, 0xa9, 0x0c, 0x69, 0x73, 0x0a, 0xd7, 0xff, - 0x40, 0x83, 0xd8, 0x27, 0x40, 0x90, 0x1e, 0x4b, 0x46, 0x41, 0x32, 0x11, 0xa5, 0x9c, 0xdc, 0x72, - 0x47, 0x9e, 0xdc, 0xd6, 0x01, 0x75, 0x0c, 0xbf, 0xb9, 0x27, 0xd6, 0x47, 0x7c, 0x6d, 0x86, 0xc7, - 0x96, 0x61, 0x11, 0x7a, 0x82, 0x02, 0xa7, 0xb4, 0xd2, 0xbf, 0x93, 0x83, 0x19, 0xe5, 0xcb, 0xab, - 0xc7, 0x0f, 0x7f, 0xf8, 0x8e, 0xa6, 0x1c, 0xd8, 0xf2, 0x23, 0x1e, 0xd8, 0xa2, 0xa7, 0xd4, 0x89, - 0x93, 0x3d, 0xa5, 0x16, 0x32, 0x39, 0xa5, 0xea, 0xdf, 0x9e, 0x80, 0x39, 0xf5, 0x3d, 0xd7, 0x10, - 0x73, 0xfa, 0xf1, 0xc4, 0x9c, 0x8e, 0x18, 0x0c, 0xe7, 0xc7, 0x0d, 0x86, 0x27, 0xc6, 0x0d, 0x86, - 0x0b, 0x0f, 0x10, 0x0c, 0x27, 0x43, 0xd9, 0xc9, 0xa1, 0x43, 0xd9, 0x4f, 0xcb, 0xbc, 0xc2, 0x94, - 0x72, 0x11, 0x17, 0xe6, 0x15, 0x90, 0xba, 0x0c, 0xab, 0x4e, 0x2b, 0x35, 0x3f, 0x53, 0x3c, 0xa6, - 0x5c, 0xc8, 0x4d, 0x4d, 0x03, 0x8c, 0x7e, 0xe4, 0xfd, 0xd0, 0xf0, 0x29, 0x00, 0xfd, 0x8d, 0x1c, - 0x84, 0x1f, 0x53, 0x65, 0x5f, 0x55, 0xf1, 0x22, 0x36, 0x4a, 0x38, 0xf0, 0xf5, 0x71, 0x3f, 0x5d, - 0x14, 0x72, 0x14, 0x79, 0xb4, 0x08, 0x04, 0x2b, 0x12, 0xff, 0x1b, 0x3e, 0xa2, 0x6a, 0xc0, 0x7c, - 0xac, 0x90, 0x2f, 0xf3, 0xbc, 0xfc, 0xb7, 0x72, 0x30, 0x2d, 0x4b, 0x21, 0xa9, 0x59, 0xef, 0xb9, - 0xc1, 0x47, 0x31, 0xa4, 0x59, 0xbf, 0x89, 0x37, 0x30, 0x85, 0xa3, 0x7b, 0x30, 0xb5, 0x47, 0x8c, - 0x16, 0x71, 0x83, 0x7b, 0x85, 0xcd, 0x8c, 0x6a, 0x30, 0xaf, 0x32, 0xae, 0xe1, 0x58, 0xf8, 0x6f, - 0x0f, 0x07, 0xe2, 0xe8, 0x61, 0xdd, 0x37, 0x3b, 0x84, 0x06, 0xb5, 0x11, 0x2b, 0x9a, 0x0f, 0x0f, - 0xeb, 0xdb, 0x0a, 0x16, 0xc7, 0xa8, 0xa9, 0x71, 0xb9, 0xed, 0x39, 0x36, 0x7b, 0xb0, 0x38, 0xa1, - 0x46, 0xf6, 0xeb, 0x8d, 0xeb, 0xd7, 0xd8, 0x7b, 0x45, 0x49, 0x41, 0xa9, 0x4d, 0x56, 0x0a, 0xe6, - 0x12, 0x71, 0xd3, 0xbe, 0x10, 0x16, 0xae, 0x73, 0x38, 0x96, 0x14, 0xfa, 0x4d, 0x98, 0x8f, 0x0d, - 0x24, 0x70, 0x8f, 0x5a, 0xba, 0x7b, 0x1c, 0xea, 0x7f, 0x39, 0xd4, 0xab, 0xef, 0x7d, 0xb0, 0xfc, - 0xc8, 0x77, 0x3f, 0x58, 0x7e, 0xe4, 0x7b, 0x1f, 0x2c, 0x3f, 0xf2, 0xc6, 0x60, 0x59, 0x7b, 0x6f, - 0xb0, 0xac, 0x7d, 0x77, 0xb0, 0xac, 0x7d, 0x6f, 0xb0, 0xac, 0xfd, 0xe3, 0x60, 0x59, 0x7b, 0xf7, - 0x07, 0xcb, 0x8f, 0xbc, 0x5c, 0x0c, 0x26, 0xf3, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x85, 0x55, - 0x6d, 0xa5, 0x84, 0x66, 0x00, 0x00, + 0x55, 0xb0, 0xab, 0x7f, 0x66, 0xba, 0x4f, 0xcf, 0xef, 0xdd, 0xd9, 0x6c, 0x67, 0xbd, 0x3b, 0xbd, + 0x29, 0x47, 0xfe, 0x9c, 0x8f, 0xa4, 0x27, 0x59, 0xdb, 0x60, 0xe2, 0xc8, 0xa2, 0x7b, 0x76, 0xd7, + 0x3b, 0xe3, 0x99, 0xdd, 0xde, 0xdb, 0xb3, 0x5e, 0xc5, 0x3f, 0x90, 0x9a, 0xee, 0x3b, 0x3d, 0xb5, + 0x5b, 0x5d, 0xd5, 0xa9, 0xaa, 0x9e, 0xdd, 0x71, 0xa2, 0xc4, 0x8e, 0x65, 0x62, 0x50, 0x22, 0x9b, + 0x9f, 0x17, 0x84, 0x40, 0x08, 0xf1, 0x80, 0xe0, 0x85, 0x87, 0xbc, 0x20, 0x11, 0x11, 0x05, 0x90, + 0x8c, 0x10, 0x10, 0x5e, 0x70, 0x40, 0x4a, 0x83, 0x27, 0x48, 0x08, 0x5e, 0x50, 0x50, 0x24, 0x94, + 0x15, 0x0f, 0xe8, 0xfe, 0xd4, 0xad, 0xba, 0xd5, 0x35, 0x33, 0xdd, 0xdb, 0x35, 0x4b, 0x04, 0xbc, + 0x4d, 0x9f, 0x73, 0xee, 0x39, 0xf7, 0xe7, 0xdc, 0x73, 0xce, 0xbd, 0xe7, 0xd4, 0x1d, 0xd8, 0xe8, + 0x98, 0xfe, 0x6e, 0x7f, 0xbb, 0xda, 0x72, 0xba, 0x2b, 0x86, 0xdb, 0x71, 0x7a, 0xae, 0x73, 0x9b, + 0xfd, 0xf1, 0x09, 0xd7, 0xb1, 0x2c, 0xa7, 0xef, 0x7b, 0x2b, 0xbd, 0x3b, 0x9d, 0x15, 0xa3, 0x67, + 0x7a, 0x2b, 0x12, 0xb2, 0xf7, 0x29, 0xc3, 0xea, 0xed, 0x1a, 0x9f, 0x5a, 0xe9, 0x10, 0x9b, 0xb8, + 0x86, 0x4f, 0xda, 0xd5, 0x9e, 0xeb, 0xf8, 0x0e, 0xfa, 0x4c, 0xc8, 0xad, 0x1a, 0x70, 0x63, 0x7f, + 0xfc, 0x5c, 0xd0, 0xb6, 0xda, 0xbb, 0xd3, 0xa9, 0x52, 0x6e, 0x55, 0x09, 0x09, 0xb8, 0x9d, 0xfd, + 0x44, 0xa4, 0x2f, 0x1d, 0xa7, 0xe3, 0xac, 0x30, 0xa6, 0xdb, 0xfd, 0x1d, 0xf6, 0x8b, 0xfd, 0x60, + 0x7f, 0x71, 0x61, 0x67, 0x1f, 0xbb, 0xf3, 0x8c, 0x57, 0x35, 0x1d, 0xda, 0xb7, 0x95, 0x6d, 0xc3, + 0x6f, 0xed, 0xae, 0xec, 0x0d, 0xf5, 0xe8, 0xac, 0x1e, 0x21, 0x6a, 0x39, 0x2e, 0x49, 0xa2, 0x79, + 0x2a, 0xa4, 0xe9, 0x1a, 0xad, 0x5d, 0xd3, 0x26, 0xee, 0x7e, 0x38, 0xea, 0x2e, 0xf1, 0x8d, 0xa4, + 0x56, 0x2b, 0x87, 0xb5, 0x72, 0xfb, 0xb6, 0x6f, 0x76, 0xc9, 0x50, 0x83, 0x9f, 0x3c, 0xae, 0x81, + 0xd7, 0xda, 0x25, 0x5d, 0x63, 0xa8, 0xdd, 0x93, 0x87, 0xb5, 0xeb, 0xfb, 0xa6, 0xb5, 0x62, 0xda, + 0xbe, 0xe7, 0xbb, 0xf1, 0x46, 0xfa, 0xbf, 0x6b, 0xb0, 0x58, 0xdb, 0xa8, 0x6f, 0xb9, 0xc6, 0xce, + 0x8e, 0xd9, 0xc2, 0x4e, 0xdf, 0x37, 0xed, 0x0e, 0xfa, 0x18, 0x4c, 0x9b, 0x76, 0xc7, 0x25, 0x9e, + 0x57, 0xd6, 0x2e, 0x68, 0x4f, 0x14, 0xeb, 0xf3, 0xef, 0x0d, 0x2a, 0x8f, 0x1c, 0x0c, 0x2a, 0xd3, + 0x6b, 0x1c, 0x8c, 0x03, 0x3c, 0x7a, 0x1a, 0x4a, 0x1e, 0x71, 0xf7, 0xcc, 0x16, 0x69, 0x38, 0xae, + 0x5f, 0xce, 0x5c, 0xd0, 0x9e, 0xc8, 0xd7, 0x4f, 0x09, 0xf2, 0x52, 0x33, 0x44, 0xe1, 0x28, 0x1d, + 0x6d, 0xe6, 0x3a, 0x8e, 0x2f, 0xf0, 0xe5, 0x2c, 0x93, 0x22, 0x9b, 0xe1, 0x10, 0x85, 0xa3, 0x74, + 0xe8, 0x12, 0x2c, 0x18, 0xb6, 0xed, 0xf8, 0x86, 0x6f, 0x3a, 0x76, 0xc3, 0x25, 0x3b, 0xe6, 0xbd, + 0x72, 0x8e, 0xb5, 0x2d, 0x8b, 0xb6, 0x0b, 0xb5, 0x18, 0x1e, 0x0f, 0xb5, 0xd0, 0xff, 0x2e, 0x03, + 0xa5, 0x9a, 0x6d, 0x58, 0xfb, 0x9e, 0xe9, 0xe1, 0xbe, 0x8d, 0x3e, 0x07, 0x05, 0xba, 0x7a, 0x6d, + 0xc3, 0x37, 0xd8, 0x78, 0x4b, 0x17, 0x3f, 0x59, 0xe5, 0x93, 0x59, 0x8d, 0x4e, 0x66, 0xa8, 0x93, + 0x94, 0xba, 0xba, 0xf7, 0xa9, 0xea, 0xf5, 0xed, 0xdb, 0xa4, 0xe5, 0x6f, 0x12, 0xdf, 0xa8, 0x23, + 0x21, 0x1f, 0x42, 0x18, 0x96, 0x5c, 0x91, 0x03, 0x39, 0xaf, 0x47, 0x5a, 0x6c, 0x7a, 0x4a, 0x17, + 0x37, 0xab, 0x93, 0xe8, 0x7f, 0x35, 0xd2, 0xf5, 0x66, 0x8f, 0xb4, 0xea, 0x33, 0x42, 0x74, 0x8e, + 0xfe, 0xc2, 0x4c, 0x10, 0xba, 0x0b, 0x53, 0x9e, 0x6f, 0xf8, 0x7d, 0x8f, 0x4d, 0x6d, 0xe9, 0xe2, + 0xf5, 0xf4, 0x44, 0x32, 0xb6, 0xf5, 0x39, 0x21, 0x74, 0x8a, 0xff, 0xc6, 0x42, 0x9c, 0xfe, 0xf7, + 0x1a, 0x9c, 0x8a, 0x50, 0xd7, 0xdc, 0x4e, 0xbf, 0x4b, 0x6c, 0x1f, 0x5d, 0x80, 0x9c, 0x6d, 0x74, + 0x89, 0xd0, 0x27, 0xd9, 0xe5, 0x6b, 0x46, 0x97, 0x60, 0x86, 0x41, 0x8f, 0x41, 0x7e, 0xcf, 0xb0, + 0xfa, 0x84, 0x4d, 0x52, 0xb1, 0x3e, 0x2b, 0x48, 0xf2, 0x2f, 0x52, 0x20, 0xe6, 0x38, 0xf4, 0x45, + 0x28, 0xb2, 0x3f, 0xae, 0xb8, 0x4e, 0x37, 0xa5, 0xa1, 0x89, 0x1e, 0xbe, 0x18, 0xb0, 0xad, 0xcf, + 0x1e, 0x0c, 0x2a, 0x45, 0xf9, 0x13, 0x87, 0x02, 0xf5, 0x7f, 0xd0, 0x60, 0x3e, 0x32, 0xb8, 0x0d, + 0xd3, 0xf3, 0xd1, 0x2b, 0x43, 0xca, 0x53, 0x1d, 0x4d, 0x79, 0x68, 0x6b, 0xa6, 0x3a, 0x0b, 0x62, + 0xa4, 0x85, 0x00, 0x12, 0x51, 0x1c, 0x1b, 0xf2, 0xa6, 0x4f, 0xba, 0x5e, 0x39, 0x73, 0x21, 0xfb, + 0x44, 0xe9, 0xe2, 0x5a, 0x6a, 0xcb, 0x18, 0xce, 0xef, 0x1a, 0xe5, 0x8f, 0xb9, 0x18, 0xfd, 0x37, + 0x32, 0xca, 0x08, 0xa9, 0x46, 0x21, 0x07, 0xa6, 0xbb, 0xc4, 0x77, 0xcd, 0x16, 0xb5, 0x06, 0xb4, + 0x17, 0x97, 0x26, 0xeb, 0xc5, 0x26, 0x63, 0x16, 0xda, 0x14, 0xfe, 0xdb, 0xc3, 0x81, 0x14, 0xb4, + 0x0b, 0x39, 0xc3, 0xed, 0x04, 0x63, 0xbe, 0x92, 0xce, 0xfa, 0x86, 0x3a, 0x57, 0x73, 0x3b, 0x1e, + 0x66, 0x12, 0xd0, 0x0a, 0x14, 0x7d, 0xe2, 0x76, 0x4d, 0xdb, 0xf0, 0xb9, 0x11, 0x2a, 0xd4, 0x17, + 0x05, 0x59, 0x71, 0x2b, 0x40, 0xe0, 0x90, 0x46, 0x7f, 0x3f, 0x03, 0x8b, 0x43, 0x9b, 0x01, 0x3d, + 0x05, 0xf9, 0xde, 0xae, 0xe1, 0x05, 0xda, 0xbd, 0x1c, 0x4c, 0x6d, 0x83, 0x02, 0xef, 0x0f, 0x2a, + 0xb3, 0x41, 0x13, 0x06, 0xc0, 0x9c, 0x98, 0x5a, 0xd9, 0x2e, 0xf1, 0x3c, 0xa3, 0x13, 0xa8, 0x7c, + 0x64, 0x46, 0x18, 0x18, 0x07, 0x78, 0xf4, 0x55, 0x0d, 0x66, 0xf9, 0xec, 0x60, 0xe2, 0xf5, 0x2d, + 0x9f, 0x6e, 0x6b, 0x3a, 0x37, 0xeb, 0x69, 0xac, 0x04, 0x67, 0x59, 0x3f, 0x2d, 0xa4, 0xcf, 0x46, + 0xa1, 0x1e, 0x56, 0xe5, 0xa2, 0x5b, 0x50, 0xf4, 0x7c, 0xc3, 0xf5, 0x49, 0xbb, 0xe6, 0x33, 0xd3, + 0x5b, 0xba, 0xf8, 0xff, 0x47, 0xd3, 0xf7, 0x2d, 0xb3, 0x4b, 0xf8, 0xde, 0x6a, 0x06, 0x0c, 0x70, + 0xc8, 0x4b, 0xff, 0x57, 0x0d, 0x16, 0x82, 0x69, 0xda, 0x22, 0xdd, 0x9e, 0x65, 0xf8, 0xe4, 0x21, + 0x58, 0x66, 0x5f, 0xb1, 0xcc, 0x38, 0x9d, 0xfd, 0x15, 0xf4, 0xff, 0x30, 0xf3, 0xac, 0xff, 0x8b, + 0x06, 0x4b, 0x71, 0xe2, 0x87, 0x60, 0x4d, 0x3c, 0xd5, 0x9a, 0x5c, 0x4b, 0x77, 0xb4, 0x87, 0x98, + 0x94, 0x1f, 0x24, 0x8c, 0xf5, 0x7f, 0xb8, 0x5d, 0xd1, 0x7f, 0x37, 0x07, 0x33, 0x35, 0xdb, 0x37, + 0x6b, 0x3b, 0x3b, 0xa6, 0x6d, 0xfa, 0xfb, 0xe8, 0x6b, 0x19, 0x58, 0xe9, 0xb9, 0x64, 0x87, 0xb8, + 0x2e, 0x69, 0x5f, 0xea, 0xbb, 0xa6, 0xdd, 0x69, 0xb6, 0x76, 0x49, 0xbb, 0x6f, 0x99, 0x76, 0x67, + 0xad, 0x63, 0x3b, 0x12, 0x7c, 0xf9, 0x1e, 0x69, 0xf5, 0x69, 0xb0, 0x22, 0xd6, 0xbf, 0x3b, 0x59, + 0x37, 0x1b, 0xe3, 0x09, 0xad, 0x3f, 0x79, 0x30, 0xa8, 0xac, 0x8c, 0xd9, 0x08, 0x8f, 0x3b, 0x34, + 0xf4, 0x76, 0x06, 0xaa, 0x2e, 0xf9, 0x7c, 0xdf, 0x1c, 0x7d, 0x36, 0xf8, 0x06, 0xb5, 0x26, 0x9b, + 0x0d, 0x3c, 0x96, 0xcc, 0xfa, 0xc5, 0x83, 0x41, 0x65, 0xcc, 0x36, 0x78, 0xcc, 0x71, 0xe9, 0x7f, + 0xa2, 0x41, 0x61, 0x8c, 0x28, 0xa9, 0xa2, 0x46, 0x49, 0xc5, 0xa1, 0x08, 0xc9, 0x1f, 0x8e, 0x90, + 0x9e, 0x9f, 0x6c, 0xd2, 0x46, 0x89, 0x8c, 0xfe, 0x8d, 0x9e, 0x23, 0xe2, 0x91, 0x14, 0xda, 0x85, + 0xa5, 0x9e, 0xd3, 0x0e, 0x36, 0xfd, 0x55, 0xc3, 0xdb, 0x65, 0x38, 0x31, 0xbc, 0xa7, 0x0e, 0x06, + 0x95, 0xa5, 0x46, 0x02, 0xfe, 0xfe, 0xa0, 0x52, 0x96, 0x4c, 0x62, 0x04, 0x38, 0x91, 0x23, 0xea, + 0x41, 0x61, 0xc7, 0x24, 0x56, 0x1b, 0x93, 0x1d, 0xa1, 0x29, 0x13, 0x6e, 0xef, 0x2b, 0x82, 0x5b, + 0x7d, 0x86, 0xda, 0xd2, 0xe0, 0x17, 0x96, 0x52, 0xf4, 0x1f, 0xe5, 0x60, 0xbe, 0x6e, 0xf5, 0xc9, + 0xf3, 0x2e, 0x21, 0x41, 0x1c, 0x50, 0x83, 0xf9, 0x9e, 0x4b, 0xf6, 0x4c, 0x72, 0xb7, 0x49, 0x2c, + 0xd2, 0xf2, 0x1d, 0x57, 0x0c, 0xf5, 0x8c, 0x58, 0xc9, 0xf9, 0x86, 0x8a, 0xc6, 0x71, 0x7a, 0xf4, + 0x1c, 0xcc, 0x19, 0x2d, 0xdf, 0xdc, 0x23, 0x92, 0x03, 0x5f, 0xe8, 0x0f, 0x09, 0x0e, 0x73, 0x35, + 0x05, 0x8b, 0x63, 0xd4, 0xe8, 0x15, 0x28, 0x7b, 0x2d, 0xc3, 0x22, 0x37, 0x7b, 0x42, 0xd4, 0xea, + 0x2e, 0x69, 0xdd, 0x69, 0x38, 0xa6, 0xed, 0x8b, 0x00, 0xe7, 0x82, 0xe0, 0x54, 0x6e, 0x1e, 0x42, + 0x87, 0x0f, 0xe5, 0x80, 0xfe, 0x58, 0x83, 0xf3, 0x3d, 0x97, 0x34, 0x5c, 0xa7, 0xeb, 0x50, 0xed, + 0x1d, 0x0a, 0x85, 0x44, 0x48, 0xf0, 0xe2, 0x84, 0xdb, 0x94, 0x43, 0x86, 0x4f, 0x1d, 0x1f, 0x39, + 0x18, 0x54, 0xce, 0x37, 0x8e, 0xea, 0x00, 0x3e, 0xba, 0x7f, 0xe8, 0xdb, 0x1a, 0x2c, 0xf7, 0x1c, + 0xcf, 0x3f, 0x62, 0x08, 0xf9, 0x13, 0x1d, 0x82, 0x7e, 0x30, 0xa8, 0x2c, 0x37, 0x8e, 0xec, 0x01, + 0x3e, 0xa6, 0x87, 0xfa, 0x57, 0x4a, 0xb0, 0x18, 0xd1, 0x3d, 0x7a, 0xa0, 0xef, 0xec, 0xa3, 0x67, + 0x61, 0x36, 0x50, 0x06, 0x7e, 0xaa, 0xe6, 0xba, 0x27, 0xe3, 0xba, 0x5a, 0x14, 0x89, 0x55, 0x5a, + 0xaa, 0x77, 0x52, 0x15, 0x79, 0xeb, 0x98, 0xde, 0x35, 0x14, 0x2c, 0x8e, 0x51, 0xa3, 0x35, 0x38, + 0x25, 0x20, 0x98, 0xf4, 0x2c, 0xb3, 0x65, 0xac, 0x3a, 0x7d, 0xa1, 0x72, 0xf9, 0xfa, 0x99, 0x83, + 0x41, 0xe5, 0x54, 0x63, 0x18, 0x8d, 0x93, 0xda, 0xa0, 0x0d, 0x58, 0x32, 0xfa, 0xbe, 0x23, 0xc7, + 0x7f, 0xd9, 0x36, 0xb6, 0x2d, 0xd2, 0x66, 0xaa, 0x55, 0xa8, 0x97, 0xa9, 0xd5, 0xa8, 0x25, 0xe0, + 0x71, 0x62, 0x2b, 0xd4, 0x88, 0x71, 0x6b, 0x92, 0x96, 0x63, 0xb7, 0xf9, 0x2a, 0xe7, 0xeb, 0xe7, + 0xc4, 0xf0, 0x54, 0x8e, 0x82, 0x06, 0x27, 0xb6, 0x44, 0x16, 0xcc, 0x75, 0x8d, 0x7b, 0x37, 0x6d, + 0x63, 0xcf, 0x30, 0x2d, 0x2a, 0xa4, 0x3c, 0x75, 0x4c, 0x68, 0xda, 0xf7, 0x4d, 0xab, 0xca, 0x6f, + 0x60, 0xaa, 0x6b, 0xb6, 0x7f, 0xdd, 0x6d, 0xfa, 0xd4, 0x09, 0xd4, 0x11, 0x9d, 0xd8, 0x4d, 0x85, + 0x17, 0x8e, 0xf1, 0x46, 0xd7, 0xe1, 0x34, 0xdb, 0x8e, 0x97, 0x9c, 0xbb, 0xf6, 0x25, 0x62, 0x19, + 0xfb, 0xc1, 0x00, 0xa6, 0xd9, 0x00, 0x3e, 0x7c, 0x30, 0xa8, 0x9c, 0x6e, 0x26, 0x11, 0xe0, 0xe4, + 0x76, 0xc8, 0x80, 0x47, 0x55, 0x04, 0x26, 0x7b, 0xa6, 0x67, 0x3a, 0xf6, 0x86, 0xd9, 0x35, 0xfd, + 0x72, 0x81, 0xb1, 0xad, 0x1c, 0x0c, 0x2a, 0x8f, 0x36, 0x0f, 0x27, 0xc3, 0x47, 0xf1, 0x40, 0xbf, + 0xae, 0xc1, 0x52, 0xd2, 0x36, 0x2c, 0x17, 0xd3, 0xb8, 0xff, 0x88, 0x6d, 0x2d, 0xae, 0x11, 0x89, + 0x46, 0x21, 0xb1, 0x13, 0xe8, 0x75, 0x0d, 0x66, 0x8c, 0x48, 0x70, 0x56, 0x06, 0xd6, 0xab, 0xf5, + 0x49, 0xa3, 0xe1, 0x90, 0x63, 0x7d, 0xe1, 0x60, 0x50, 0x51, 0x02, 0x40, 0xac, 0x48, 0x44, 0xbf, + 0xa9, 0xc1, 0xe9, 0xc4, 0x3d, 0x5e, 0x2e, 0x9d, 0xc4, 0x0c, 0x31, 0x25, 0x49, 0xb6, 0x39, 0xc9, + 0xdd, 0x40, 0xef, 0x6a, 0xd2, 0x95, 0x6d, 0x06, 0xe7, 0x91, 0x19, 0xd6, 0xb5, 0x1b, 0x13, 0xc6, + 0xa3, 0xa1, 0xf7, 0x0e, 0x18, 0xd7, 0x4f, 0x45, 0x3c, 0x63, 0x00, 0xc4, 0x71, 0xf1, 0xe8, 0xeb, + 0x5a, 0xe0, 0x1a, 0x65, 0x8f, 0x66, 0x4f, 0xaa, 0x47, 0x28, 0xf4, 0xb4, 0xb2, 0x43, 0x31, 0xe1, + 0xfa, 0x3f, 0x67, 0x61, 0x66, 0xd5, 0xb0, 0x0d, 0x77, 0x5f, 0xb8, 0x96, 0x3f, 0xd2, 0xe0, 0x5c, + 0xab, 0xef, 0xba, 0xc4, 0xf6, 0x9b, 0x3e, 0xe9, 0x0d, 0x3b, 0x16, 0xed, 0x44, 0x1d, 0xcb, 0x85, + 0x83, 0x41, 0xe5, 0xdc, 0xea, 0x11, 0xf2, 0xf1, 0x91, 0xbd, 0x43, 0x7f, 0xa5, 0x81, 0x2e, 0x08, + 0xea, 0x46, 0xeb, 0x4e, 0xc7, 0x75, 0xfa, 0x76, 0x7b, 0x78, 0x10, 0x99, 0x13, 0x1d, 0xc4, 0xe3, + 0x07, 0x83, 0x8a, 0xbe, 0x7a, 0x6c, 0x2f, 0xf0, 0x08, 0x3d, 0x45, 0xcf, 0xc3, 0xa2, 0xa0, 0xba, + 0x7c, 0xaf, 0x47, 0x5c, 0x93, 0xc6, 0xa6, 0xe2, 0xa6, 0xf9, 0xc3, 0xc2, 0xec, 0x2f, 0xae, 0xc6, + 0x09, 0xf0, 0x70, 0x1b, 0xfd, 0x0f, 0x72, 0x00, 0xc1, 0x4a, 0x93, 0x1e, 0xfa, 0x09, 0x28, 0x7a, + 0xc4, 0xbf, 0x45, 0xcc, 0xce, 0xae, 0xcf, 0xd6, 0x34, 0x2f, 0xae, 0x35, 0x02, 0x20, 0x0e, 0xf1, + 0xe8, 0x0e, 0xe4, 0x7b, 0x46, 0xdf, 0x23, 0x62, 0xde, 0xd6, 0x53, 0x99, 0xb7, 0x06, 0xe5, 0xc8, + 0x63, 0x7f, 0xf6, 0x27, 0xe6, 0x32, 0xd0, 0x9b, 0x1a, 0x00, 0x51, 0xc7, 0x5a, 0xba, 0xd8, 0x4c, + 0x45, 0x64, 0x38, 0x1d, 0x74, 0x0e, 0xea, 0x73, 0x07, 0x83, 0x0a, 0x44, 0x66, 0x2d, 0x22, 0x16, + 0xdd, 0x85, 0x82, 0x11, 0x98, 0xb3, 0xdc, 0x49, 0x98, 0x33, 0x16, 0x92, 0xcb, 0xf5, 0x96, 0xc2, + 0xd0, 0xdb, 0x1a, 0xcc, 0x79, 0xc4, 0x17, 0x4b, 0x45, 0xfd, 0x93, 0x88, 0xe5, 0x36, 0x26, 0x93, + 0xdf, 0x54, 0x78, 0x72, 0xe3, 0xa0, 0xc2, 0x70, 0x4c, 0xae, 0xfe, 0x9f, 0x05, 0x98, 0x0b, 0x54, + 0x26, 0x0c, 0xcf, 0x5a, 0x1c, 0x92, 0x1c, 0x9e, 0xad, 0x46, 0x91, 0x58, 0xa5, 0xa5, 0x8d, 0x3d, + 0x9f, 0xc6, 0x03, 0x6a, 0x74, 0x26, 0x1b, 0x37, 0xa3, 0x48, 0xac, 0xd2, 0xa2, 0x2e, 0xe4, 0x3d, + 0x9f, 0xf4, 0x82, 0x4b, 0xc3, 0xab, 0x93, 0xcd, 0x46, 0xb8, 0x13, 0xc2, 0x0b, 0x1f, 0xfa, 0xcb, + 0xc3, 0x5c, 0x0a, 0x7a, 0x47, 0x83, 0x39, 0x5f, 0x49, 0x28, 0x09, 0x35, 0x48, 0x47, 0x13, 0xd5, + 0x5c, 0x15, 0x5f, 0x0d, 0x15, 0x86, 0x63, 0xe2, 0x13, 0x22, 0xb6, 0xfc, 0x09, 0x46, 0x6c, 0x2f, + 0x41, 0xa1, 0x6b, 0xdc, 0x6b, 0xf6, 0xdd, 0xce, 0x83, 0x47, 0x86, 0x4c, 0xc5, 0x37, 0x05, 0x17, + 0x2c, 0xf9, 0xa1, 0x37, 0xb4, 0xc8, 0xe6, 0x9a, 0x66, 0xcc, 0x6f, 0xa5, 0xbb, 0xb9, 0xa4, 0x41, + 0x3d, 0x74, 0x9b, 0x0d, 0xc5, 0x4f, 0x85, 0x87, 0x1e, 0x3f, 0xd1, 0x58, 0x80, 0x6f, 0x10, 0x19, + 0x0b, 0x14, 0x4f, 0x34, 0x16, 0x58, 0x55, 0x84, 0xe1, 0x98, 0x70, 0xd6, 0x1f, 0xbe, 0xe7, 0x64, + 0x7f, 0xe0, 0x44, 0xfb, 0xd3, 0x54, 0x84, 0xe1, 0x98, 0x70, 0xfd, 0x07, 0x1a, 0x9c, 0x59, 0xb5, + 0xfa, 0x9e, 0x4f, 0xdc, 0xff, 0x35, 0x77, 0xea, 0xff, 0xa1, 0xc1, 0xa3, 0x87, 0x8c, 0xf9, 0x21, + 0x5c, 0xad, 0xbf, 0xa6, 0x5e, 0xad, 0xdf, 0x9c, 0xd0, 0xc6, 0x26, 0x8f, 0xe3, 0x90, 0x1b, 0x76, + 0x1f, 0x66, 0x2f, 0x19, 0xbe, 0xd1, 0x76, 0x3a, 0xfc, 0xca, 0x1b, 0x3d, 0x07, 0x05, 0xd3, 0xf6, + 0x89, 0xbb, 0x67, 0x58, 0xc2, 0xcb, 0xe8, 0x41, 0xd7, 0xd7, 0x04, 0xfc, 0xfe, 0xa0, 0x32, 0x77, + 0xa9, 0xef, 0xb2, 0xb4, 0x38, 0xb7, 0x39, 0x58, 0xb6, 0x41, 0x8f, 0x41, 0xfe, 0xf3, 0x7d, 0xe2, + 0xee, 0xc7, 0x53, 0xb1, 0x37, 0x28, 0x10, 0x73, 0x9c, 0xfe, 0xb7, 0x19, 0x88, 0x44, 0x00, 0x0f, + 0x41, 0xad, 0x6c, 0x45, 0xad, 0x26, 0xf4, 0xe9, 0x91, 0x78, 0xe6, 0xb0, 0x1c, 0xfa, 0x5e, 0x2c, + 0x87, 0x7e, 0x2d, 0x35, 0x89, 0x47, 0xa7, 0xd0, 0xdf, 0xd7, 0xe0, 0xd1, 0x90, 0x78, 0x38, 0xae, + 0x3d, 0xfe, 0x92, 0xf8, 0x69, 0x28, 0x19, 0x61, 0x33, 0xb1, 0x8a, 0xb2, 0xba, 0x22, 0xc2, 0x11, + 0x47, 0xe9, 0xc2, 0x34, 0x66, 0xf6, 0x01, 0xd3, 0x98, 0xb9, 0xa3, 0xd3, 0x98, 0xfa, 0x0f, 0x33, + 0x70, 0x7e, 0x78, 0x64, 0x81, 0x76, 0x63, 0xb2, 0x33, 0xc2, 0xd8, 0x9e, 0x81, 0x19, 0x5f, 0x34, + 0xa0, 0x50, 0x31, 0xb8, 0x25, 0x41, 0x39, 0xb3, 0x15, 0xc1, 0x61, 0x85, 0x92, 0xb6, 0x6c, 0xf1, + 0x7d, 0xd5, 0x6c, 0x39, 0xbd, 0x20, 0xdf, 0x2b, 0x5b, 0xae, 0x46, 0x70, 0x58, 0xa1, 0x94, 0x89, + 0xa3, 0xdc, 0x89, 0x27, 0xa4, 0x9b, 0x70, 0x3a, 0xc8, 0x1f, 0x5c, 0x71, 0xdc, 0x55, 0xa7, 0xdb, + 0xb3, 0x08, 0x4b, 0x7f, 0xe4, 0x59, 0x67, 0xcf, 0x8b, 0x26, 0xa7, 0x71, 0x12, 0x11, 0x4e, 0x6e, + 0xab, 0xbf, 0x9f, 0x85, 0x53, 0xe1, 0xb4, 0xaf, 0x3a, 0x76, 0xdb, 0x64, 0x59, 0x98, 0x67, 0x21, + 0xe7, 0xef, 0xf7, 0x82, 0xc9, 0xfe, 0x7f, 0x41, 0x77, 0xb6, 0xf6, 0x7b, 0x74, 0xb5, 0xcf, 0x24, + 0x34, 0xa1, 0x28, 0xcc, 0x1a, 0xa1, 0x0d, 0xb9, 0x3b, 0xf8, 0x0a, 0x3c, 0xa5, 0x6a, 0xf3, 0xfd, + 0x41, 0x25, 0xa1, 0xa6, 0xaa, 0x2a, 0x39, 0xa9, 0x3a, 0x8f, 0x6e, 0xc3, 0x9c, 0x65, 0x78, 0xfe, + 0xcd, 0x5e, 0xdb, 0xf0, 0xc9, 0x96, 0xd9, 0x25, 0x62, 0xcf, 0x8d, 0x93, 0x5b, 0x96, 0x57, 0x95, + 0x1b, 0x0a, 0x27, 0x1c, 0xe3, 0x8c, 0xf6, 0x00, 0x51, 0xc8, 0x96, 0x6b, 0xd8, 0x1e, 0x1f, 0x15, + 0x95, 0x37, 0x7e, 0x2e, 0xfb, 0xac, 0x90, 0x87, 0x36, 0x86, 0xb8, 0xe1, 0x04, 0x09, 0xe8, 0x71, + 0x98, 0x72, 0x89, 0xe1, 0x89, 0xc5, 0x2c, 0x86, 0xfb, 0x1f, 0x33, 0x28, 0x16, 0xd8, 0xe8, 0x86, + 0x9a, 0x3a, 0x66, 0x43, 0x7d, 0x4f, 0x83, 0xb9, 0x70, 0x99, 0x1e, 0x82, 0x9b, 0xeb, 0xaa, 0x6e, + 0xee, 0x6a, 0x5a, 0x26, 0xf1, 0x10, 0xcf, 0xf6, 0x41, 0x36, 0x3a, 0x3e, 0x96, 0x35, 0xfe, 0x02, + 0x14, 0x83, 0x5d, 0x1d, 0xe4, 0x8d, 0x27, 0x8c, 0x3c, 0x95, 0xc8, 0x22, 0x52, 0xfe, 0x21, 0x84, + 0xe0, 0x50, 0x1e, 0x75, 0xac, 0x6d, 0xe1, 0x34, 0x85, 0xda, 0x4b, 0xc7, 0x1a, 0x38, 0xd3, 0x24, + 0xc7, 0x1a, 0xb4, 0x41, 0x37, 0xe1, 0x4c, 0xcf, 0x75, 0x58, 0xe5, 0xdc, 0x25, 0x62, 0xb4, 0x2d, + 0xd3, 0x26, 0xc1, 0x75, 0x2e, 0xbf, 0x29, 0x7f, 0xf4, 0x60, 0x50, 0x39, 0xd3, 0x48, 0x26, 0xc1, + 0x87, 0xb5, 0x55, 0xcb, 0x58, 0x72, 0xc7, 0x97, 0xb1, 0xa0, 0x5f, 0x90, 0xc7, 0x08, 0xe2, 0x95, + 0xf3, 0x6c, 0x12, 0x5f, 0x4e, 0x6b, 0x29, 0x13, 0xcc, 0x7a, 0xa8, 0x52, 0x35, 0x21, 0x14, 0x4b, + 0xf1, 0xfa, 0x5b, 0x79, 0x58, 0x88, 0xfb, 0xc6, 0x93, 0xaf, 0xa8, 0xf9, 0x65, 0x0d, 0x16, 0x82, + 0x75, 0xe5, 0x32, 0x49, 0x70, 0x3e, 0xde, 0x48, 0x49, 0x9d, 0xb8, 0x97, 0x97, 0x85, 0x89, 0x5b, + 0x31, 0x69, 0x78, 0x48, 0x3e, 0x7a, 0x15, 0x4a, 0xf2, 0x18, 0xf9, 0x40, 0xe5, 0x35, 0xf3, 0xcc, + 0xbf, 0x87, 0x2c, 0x70, 0x94, 0x1f, 0x7a, 0x4b, 0x03, 0x68, 0x05, 0x06, 0x38, 0x58, 0xf7, 0x1b, + 0x69, 0xad, 0xbb, 0x34, 0xed, 0x61, 0x18, 0x27, 0x41, 0x1e, 0x8e, 0x08, 0x46, 0xbf, 0xc2, 0x0e, + 0x90, 0x32, 0xee, 0xf0, 0xca, 0x53, 0xac, 0x27, 0x9f, 0x4d, 0x5b, 0x03, 0xc3, 0x6b, 0x45, 0xe9, + 0xe4, 0x23, 0x28, 0x0f, 0x2b, 0x9d, 0xd0, 0x9f, 0x05, 0x99, 0xe6, 0xa5, 0x1b, 0x8a, 0x25, 0x7a, + 0x1b, 0x86, 0xbf, 0x2b, 0x54, 0x50, 0x6e, 0xa8, 0x2b, 0x01, 0x02, 0x87, 0x34, 0xfa, 0x9f, 0x6a, + 0xb0, 0xb4, 0xe6, 0xf9, 0xa6, 0x73, 0x89, 0x78, 0x3e, 0xdd, 0x63, 0xd4, 0x1d, 0xf7, 0x2d, 0x32, + 0x42, 0x40, 0x73, 0x09, 0x16, 0xc4, 0x5d, 0x4f, 0x7f, 0xdb, 0x23, 0x7e, 0x24, 0xa8, 0x91, 0xaa, + 0xb3, 0x1a, 0xc3, 0xe3, 0xa1, 0x16, 0x94, 0x8b, 0xb8, 0xf4, 0x09, 0xb9, 0x64, 0x55, 0x2e, 0xcd, + 0x18, 0x1e, 0x0f, 0xb5, 0xd0, 0xbf, 0x99, 0x81, 0x53, 0x6c, 0x18, 0xb1, 0x82, 0xe0, 0x5f, 0xd2, + 0x60, 0x6e, 0xcf, 0x74, 0xfd, 0xbe, 0x61, 0x45, 0x6f, 0xaf, 0x26, 0xd6, 0x1e, 0x26, 0xeb, 0x45, + 0x85, 0x71, 0xe8, 0xc6, 0x55, 0x38, 0x8e, 0x75, 0x80, 0xf6, 0x69, 0xbe, 0xad, 0xce, 0x76, 0x3a, + 0x27, 0xce, 0xa4, 0x75, 0xe4, 0x39, 0x8a, 0x18, 0x10, 0xc7, 0xe5, 0xeb, 0x2f, 0x8b, 0xe9, 0x53, + 0xbb, 0x3e, 0x82, 0x12, 0xe8, 0x30, 0xe5, 0x3a, 0x7d, 0xea, 0xd2, 0xa8, 0x63, 0x2d, 0xd6, 0x81, + 0xc5, 0x05, 0x0c, 0x82, 0x05, 0x46, 0xff, 0x7d, 0x0d, 0x8a, 0xeb, 0xce, 0xb6, 0x38, 0xe3, 0xfd, + 0x6c, 0x0a, 0xe7, 0x2d, 0x69, 0x96, 0xe5, 0x45, 0x42, 0xe8, 0xe9, 0x9f, 0x53, 0x4e, 0x5b, 0xe7, + 0x22, 0xbc, 0xab, 0xac, 0x8a, 0x9e, 0xb2, 0x5a, 0x77, 0xb6, 0x0f, 0x3d, 0x8e, 0xff, 0x76, 0x1e, + 0x66, 0x5f, 0x30, 0xf6, 0x89, 0xed, 0x1b, 0xa2, 0xc7, 0x1f, 0x83, 0x69, 0xa3, 0xdd, 0x4e, 0xaa, + 0x2a, 0xaf, 0x71, 0x30, 0x0e, 0xf0, 0xec, 0x00, 0xd3, 0x63, 0x29, 0xe1, 0x88, 0xab, 0x0d, 0x0f, + 0x30, 0x21, 0x0a, 0x47, 0xe9, 0xc2, 0xad, 0xb4, 0xea, 0xd8, 0x3b, 0x66, 0x27, 0x69, 0x13, 0xac, + 0xc6, 0xf0, 0x78, 0xa8, 0x05, 0x5a, 0x07, 0x24, 0x2a, 0xc6, 0x6a, 0xad, 0x96, 0xd3, 0xb7, 0xf9, + 0x66, 0xe2, 0x67, 0x1b, 0x19, 0xf3, 0x6d, 0x0e, 0x51, 0xe0, 0x84, 0x56, 0xe8, 0x15, 0x28, 0xb7, + 0x18, 0x67, 0x11, 0x01, 0x44, 0x39, 0xf2, 0x28, 0x50, 0x96, 0x63, 0xac, 0x1e, 0x42, 0x87, 0x0f, + 0xe5, 0x40, 0x7b, 0xea, 0xf9, 0x8e, 0x6b, 0x74, 0x48, 0x94, 0xef, 0x94, 0xda, 0xd3, 0xe6, 0x10, + 0x05, 0x4e, 0x68, 0x85, 0xbe, 0x0c, 0x45, 0x7f, 0xd7, 0x25, 0xde, 0xae, 0x63, 0xb5, 0xc5, 0xcd, + 0xe2, 0x84, 0x07, 0x5e, 0xb1, 0xfa, 0x5b, 0x01, 0xd7, 0x48, 0x4c, 0x12, 0x80, 0x70, 0x28, 0x13, + 0xb9, 0x30, 0xe5, 0xd1, 0xd3, 0x96, 0x57, 0x2e, 0xa4, 0x11, 0xd5, 0x09, 0xe9, 0xec, 0x00, 0x17, + 0x39, 0x6a, 0x33, 0x09, 0x58, 0x48, 0xd2, 0xff, 0x2c, 0x03, 0x33, 0x51, 0xc2, 0x11, 0x76, 0xea, + 0x9b, 0x1a, 0xcc, 0xb4, 0x1c, 0xdb, 0x77, 0x1d, 0x8b, 0x1f, 0x23, 0xf9, 0x06, 0x99, 0xb0, 0x32, + 0x9b, 0xb1, 0xba, 0x44, 0x7c, 0xc3, 0xb4, 0x22, 0x27, 0xd2, 0x88, 0x18, 0xac, 0x08, 0x45, 0x5f, + 0xd3, 0x60, 0x3e, 0x4c, 0xb9, 0x84, 0xe7, 0xd9, 0x54, 0x3b, 0x22, 0xab, 0x96, 0x2e, 0xab, 0x92, + 0x70, 0x5c, 0xb4, 0xbe, 0x0d, 0x0b, 0xf1, 0xd5, 0xa6, 0x53, 0xd9, 0x33, 0xc4, 0x5e, 0xcf, 0x86, + 0x53, 0xd9, 0x30, 0x3c, 0x0f, 0x33, 0x0c, 0xfa, 0x38, 0x14, 0xba, 0x86, 0xdb, 0x31, 0x6d, 0xc3, + 0x62, 0xb3, 0x98, 0x8d, 0x18, 0x24, 0x01, 0xc7, 0x92, 0x42, 0xff, 0x7e, 0x0e, 0x4a, 0x9b, 0xc4, + 0xf0, 0xfa, 0x2e, 0x61, 0x17, 0x4e, 0x27, 0x1e, 0x22, 0x2a, 0xa5, 0xce, 0xd9, 0xf4, 0x4a, 0x9d, + 0xd1, 0x4b, 0x00, 0x3b, 0xa6, 0x6d, 0x7a, 0xbb, 0x0f, 0x58, 0x44, 0xcd, 0x92, 0x6f, 0x57, 0x24, + 0x07, 0x1c, 0xe1, 0x16, 0x7e, 0x45, 0x91, 0x3f, 0xe2, 0x2b, 0x8a, 0xb7, 0xb4, 0x88, 0xf3, 0xe0, + 0xc1, 0xd7, 0xad, 0x49, 0x6b, 0x6f, 0xe5, 0xc2, 0x54, 0x03, 0x67, 0x72, 0xd9, 0xf6, 0xdd, 0xfd, + 0x23, 0x7d, 0xcc, 0x16, 0x14, 0x5c, 0xe2, 0xf5, 0xbb, 0x34, 0xd8, 0x9d, 0x1e, 0x7b, 0x1a, 0x58, + 0x7e, 0x02, 0x8b, 0xf6, 0x58, 0x72, 0x3a, 0xfb, 0x2c, 0xcc, 0x2a, 0x5d, 0x40, 0x0b, 0x90, 0xbd, + 0x43, 0xf6, 0xb9, 0x9e, 0x60, 0xfa, 0x27, 0x5a, 0x52, 0xaa, 0x28, 0xc5, 0xb4, 0x7c, 0x3a, 0xf3, + 0x8c, 0xa6, 0xff, 0x70, 0x0a, 0xa6, 0x84, 0xbf, 0x3a, 0xde, 0x16, 0x44, 0xef, 0x59, 0x33, 0x0f, + 0x70, 0xcf, 0xba, 0x0e, 0x33, 0xa6, 0x6d, 0xfa, 0xa6, 0x61, 0xb1, 0x22, 0x1a, 0xe1, 0xab, 0x1e, + 0x0f, 0xf6, 0xff, 0x5a, 0x04, 0x97, 0xc0, 0x47, 0x69, 0x8b, 0x6e, 0x40, 0x9e, 0x19, 0x73, 0xa1, + 0x4f, 0xe3, 0xa7, 0x9c, 0x58, 0x3a, 0x99, 0x97, 0x65, 0x71, 0x4e, 0x2c, 0xa6, 0xec, 0xb7, 0x5a, + 0xc4, 0xf3, 0x64, 0x20, 0x2f, 0xd4, 0x2a, 0x8c, 0x29, 0x63, 0x78, 0x3c, 0xd4, 0x82, 0x72, 0xd9, + 0x31, 0x4c, 0xab, 0xef, 0x92, 0x90, 0xcb, 0x94, 0xca, 0xe5, 0x4a, 0x0c, 0x8f, 0x87, 0x5a, 0xa0, + 0x1d, 0x98, 0x11, 0x30, 0x5e, 0xa6, 0x34, 0xfd, 0x80, 0xa3, 0x64, 0x99, 0xa5, 0x2b, 0x11, 0x4e, + 0x58, 0xe1, 0x8b, 0xfa, 0xb0, 0x68, 0xda, 0x2d, 0xc7, 0x6e, 0x59, 0x7d, 0xcf, 0xdc, 0x23, 0x61, + 0x4d, 0xd4, 0x83, 0x08, 0x3b, 0x7d, 0x30, 0xa8, 0x2c, 0xae, 0xc5, 0xd9, 0xe1, 0x61, 0x09, 0xe8, + 0x0d, 0x0d, 0x4e, 0xb7, 0x1c, 0xdb, 0x63, 0x55, 0xc1, 0x7b, 0xe4, 0xb2, 0xeb, 0x3a, 0x2e, 0x97, + 0x5d, 0x7c, 0x40, 0xd9, 0xac, 0xe6, 0x67, 0x35, 0x89, 0x25, 0x4e, 0x96, 0x84, 0x5e, 0x83, 0x42, + 0xcf, 0x75, 0xf6, 0xcc, 0x36, 0x71, 0x45, 0xf6, 0x6a, 0x23, 0x8d, 0x82, 0xfc, 0x86, 0xe0, 0x19, + 0x5a, 0x82, 0x00, 0x82, 0xa5, 0x3c, 0xfd, 0x1b, 0x53, 0x30, 0xa7, 0x92, 0xa3, 0x2f, 0x01, 0xf4, + 0x5c, 0xa7, 0x4b, 0xfc, 0x5d, 0x22, 0x6b, 0x67, 0xae, 0x4d, 0x5a, 0x0c, 0x1f, 0xf0, 0x13, 0xdf, + 0x0a, 0x30, 0x4b, 0x1a, 0x42, 0x71, 0x44, 0x22, 0x72, 0x61, 0xfa, 0x0e, 0xf7, 0x69, 0xc2, 0xc5, + 0xbf, 0x90, 0x4a, 0x40, 0x22, 0x24, 0x97, 0xa8, 0xcb, 0x11, 0x20, 0x1c, 0x08, 0x42, 0xdb, 0x90, + 0xbd, 0x4b, 0xb6, 0xd3, 0x29, 0xdb, 0xbe, 0x45, 0xc4, 0x51, 0xa1, 0x3e, 0x7d, 0x30, 0xa8, 0x64, + 0x6f, 0x91, 0x6d, 0x4c, 0x99, 0xd3, 0x71, 0xb5, 0x79, 0xb6, 0x48, 0x98, 0x8a, 0x09, 0xc7, 0xa5, + 0xa4, 0x9e, 0xf8, 0xb8, 0x04, 0x08, 0x07, 0x82, 0xd0, 0x6b, 0x50, 0xbc, 0x6b, 0xec, 0x91, 0x1d, + 0xd7, 0xb1, 0x7d, 0x91, 0x7b, 0x9f, 0xb0, 0x26, 0xe4, 0x56, 0xc0, 0x4e, 0xc8, 0x65, 0xde, 0x56, + 0x02, 0x71, 0x28, 0x0e, 0xed, 0x41, 0xc1, 0x26, 0x77, 0x31, 0xb1, 0xcc, 0x96, 0x48, 0xc7, 0x4f, + 0xa8, 0xd6, 0xd7, 0x04, 0x37, 0x21, 0x99, 0xb9, 0xa1, 0x00, 0x86, 0xa5, 0x2c, 0xba, 0x96, 0xb7, + 0x9d, 0x6d, 0x61, 0xa8, 0x26, 0x5c, 0x4b, 0x79, 0xec, 0xe3, 0x6b, 0xb9, 0xee, 0x6c, 0x63, 0xca, + 0x5c, 0xff, 0x66, 0x0e, 0x66, 0xa2, 0x9f, 0x6b, 0x8d, 0xe0, 0xb3, 0x64, 0xd8, 0x94, 0x19, 0x27, + 0x6c, 0xa2, 0x51, 0x6f, 0x37, 0xf4, 0xf1, 0xc1, 0x55, 0xd9, 0x5a, 0x6a, 0x51, 0x43, 0x18, 0xf5, + 0x46, 0x80, 0x1e, 0x56, 0x84, 0x8e, 0x91, 0x6a, 0xa2, 0x71, 0x10, 0x77, 0x87, 0xbc, 0xce, 0x57, + 0xc6, 0x41, 0x8a, 0x83, 0xbb, 0x08, 0x20, 0xdc, 0xd5, 0x4e, 0xdf, 0x62, 0xca, 0x91, 0x0f, 0x2f, + 0xaf, 0x9a, 0x12, 0x83, 0x23, 0x54, 0xe8, 0x71, 0x98, 0xa2, 0x0e, 0x83, 0xb4, 0x45, 0x01, 0xae, + 0x3c, 0x5a, 0x5c, 0x61, 0x50, 0x2c, 0xb0, 0xe8, 0x19, 0xea, 0xdb, 0x43, 0x33, 0x2f, 0xea, 0x6a, + 0x97, 0x42, 0xdf, 0x1e, 0xe2, 0xb0, 0x42, 0x49, 0xbb, 0x4e, 0xa8, 0x55, 0x66, 0xa6, 0x3f, 0xd2, + 0x75, 0x66, 0xaa, 0x31, 0xc7, 0xb1, 0xa3, 0x6e, 0xcc, 0x8a, 0x33, 0xa3, 0x9d, 0x8f, 0x1c, 0x75, + 0x63, 0x78, 0x3c, 0xd4, 0x42, 0xff, 0x1c, 0xcc, 0xa9, 0xda, 0x4c, 0xa7, 0xb8, 0xe7, 0x3a, 0x3b, + 0xa6, 0x45, 0xe2, 0x87, 0xf4, 0x06, 0x07, 0xe3, 0x00, 0x3f, 0x5a, 0x96, 0xf8, 0xcf, 0xb3, 0x70, + 0xea, 0x5a, 0xc7, 0xb4, 0xef, 0xc5, 0x6e, 0x94, 0x92, 0xbe, 0xe4, 0xd6, 0xc6, 0xfd, 0x92, 0x3b, + 0x2c, 0x8b, 0x12, 0xdf, 0xa5, 0x27, 0x97, 0x45, 0x05, 0x1f, 0xad, 0xab, 0xb4, 0xe8, 0x7b, 0x1a, + 0x9c, 0x33, 0xda, 0x3c, 0xbe, 0x30, 0x2c, 0x01, 0x0d, 0x85, 0x06, 0x3a, 0xee, 0x4d, 0x68, 0x2d, + 0x86, 0x07, 0x5f, 0xad, 0x1d, 0x21, 0x95, 0x47, 0xcd, 0x1f, 0x15, 0x23, 0x38, 0x77, 0x14, 0x29, + 0x3e, 0xb2, 0xfb, 0x67, 0xaf, 0xc3, 0x47, 0x8e, 0x15, 0x34, 0x56, 0x6c, 0xfc, 0xa6, 0x06, 0x45, + 0x7e, 0x7b, 0x84, 0xc9, 0x0e, 0xdd, 0x3c, 0x46, 0xcf, 0x7c, 0x91, 0xb8, 0x5e, 0xf0, 0xb1, 0x5a, + 0x31, 0xdc, 0x3c, 0xb5, 0xc6, 0x9a, 0xc0, 0xe0, 0x08, 0x15, 0x35, 0x4f, 0x77, 0x4c, 0xbb, 0x2d, + 0x96, 0x49, 0x9a, 0xa7, 0x17, 0x4c, 0xbb, 0x8d, 0x19, 0x46, 0x1a, 0xb0, 0xec, 0x61, 0x06, 0x4c, + 0xff, 0x1d, 0x0d, 0xe6, 0x58, 0xd5, 0x63, 0x18, 0x1c, 0x3e, 0x2d, 0x33, 0x6b, 0xbc, 0x1b, 0xe7, + 0xd5, 0xcc, 0xda, 0xfd, 0x41, 0xa5, 0xc4, 0xeb, 0x24, 0xd5, 0x44, 0xdb, 0xcb, 0xe2, 0x80, 0xc7, + 0xf2, 0x7f, 0x99, 0xb1, 0xcf, 0x1f, 0xf2, 0x3a, 0xa3, 0x19, 0x30, 0xc1, 0x21, 0x3f, 0xfd, 0x1b, + 0x59, 0x38, 0x95, 0x50, 0xbe, 0x43, 0xcf, 0x5e, 0x53, 0x96, 0xb1, 0x4d, 0xac, 0x20, 0x7b, 0xf5, + 0x6a, 0xea, 0x25, 0x42, 0xd5, 0x0d, 0xc6, 0x9f, 0x6b, 0x92, 0xb4, 0x4f, 0x1c, 0x88, 0x85, 0x70, + 0xf4, 0x6b, 0x1a, 0x94, 0x8c, 0x88, 0xb2, 0xf3, 0x84, 0xde, 0x76, 0xfa, 0x9d, 0x19, 0xd2, 0xed, + 0x48, 0x21, 0x42, 0xa8, 0xca, 0xd1, 0xbe, 0x9c, 0xfd, 0x69, 0x28, 0x45, 0x86, 0x30, 0x8e, 0x8e, + 0x9e, 0x7d, 0x0e, 0x16, 0x26, 0xd2, 0xf1, 0xcf, 0xc2, 0xb8, 0x5f, 0x3f, 0x52, 0x8f, 0x70, 0x37, + 0x5a, 0x0c, 0x2c, 0x67, 0x5c, 0x54, 0x03, 0x0b, 0xac, 0xbe, 0x0d, 0x0b, 0xf1, 0x00, 0x74, 0x9c, + 0x3b, 0xd1, 0x91, 0xcc, 0xed, 0x27, 0x61, 0xcc, 0xef, 0x15, 0xf5, 0xbf, 0xcc, 0xc0, 0xb4, 0xa8, + 0x01, 0x7c, 0x08, 0x35, 0x3c, 0x77, 0x94, 0x5b, 0xe5, 0xb5, 0x54, 0x4a, 0x17, 0x0f, 0x2d, 0xe0, + 0xf1, 0x62, 0x05, 0x3c, 0x2f, 0xa4, 0x23, 0xee, 0xe8, 0xea, 0x9d, 0x77, 0x32, 0x30, 0x1f, 0xab, + 0xa9, 0x44, 0x3f, 0xaf, 0x0d, 0x27, 0xad, 0x6f, 0xa6, 0x5a, 0xb6, 0x29, 0x2b, 0xc4, 0x8e, 0xce, + 0x5f, 0x7b, 0xca, 0x17, 0xd0, 0x37, 0x52, 0x7b, 0x4d, 0xe2, 0xc8, 0x8f, 0xa1, 0xff, 0x49, 0x83, + 0x0f, 0x1f, 0x5a, 0x65, 0xca, 0xbe, 0x34, 0x71, 0x55, 0xac, 0xd0, 0xbd, 0x94, 0xab, 0xc6, 0xe5, + 0x6d, 0x66, 0xfc, 0xe3, 0x83, 0xb8, 0x78, 0xf4, 0x14, 0xcc, 0x30, 0x3b, 0x4e, 0xb7, 0x8f, 0x4f, + 0x7a, 0xe2, 0x51, 0x1b, 0x76, 0x73, 0xd0, 0x8c, 0xc0, 0xb1, 0x42, 0xa5, 0xff, 0x96, 0x06, 0xe5, + 0xc3, 0xbe, 0x6b, 0x18, 0x21, 0x2e, 0xff, 0xa9, 0x58, 0x3d, 0x4d, 0x65, 0xa8, 0x9e, 0x26, 0x16, + 0x99, 0x07, 0xa5, 0x33, 0x91, 0xa0, 0x38, 0x7b, 0x4c, 0xb9, 0xc8, 0xd7, 0x35, 0x38, 0x73, 0x88, + 0xe2, 0x0c, 0xd5, 0x55, 0x69, 0x0f, 0x5c, 0x57, 0x95, 0x19, 0xb5, 0xae, 0x4a, 0xff, 0x9b, 0x2c, + 0x2c, 0x88, 0xfe, 0x84, 0xce, 0xfc, 0x19, 0xa5, 0x2a, 0xe9, 0xa3, 0xb1, 0xaa, 0xa4, 0xa5, 0x38, + 0xfd, 0xff, 0x95, 0x24, 0xfd, 0x78, 0x95, 0x24, 0xfd, 0x28, 0x03, 0xa7, 0x13, 0xbf, 0x19, 0x41, + 0x6f, 0x27, 0x58, 0xc1, 0x5b, 0x29, 0x7f, 0x9c, 0x32, 0xa2, 0x1d, 0x9c, 0xb4, 0x8e, 0xe7, 0x57, + 0xa3, 0xf5, 0x33, 0xfc, 0x98, 0xb0, 0x73, 0x02, 0x9f, 0xd9, 0x8c, 0x5b, 0x4a, 0xf3, 0x8b, 0x59, + 0x78, 0x62, 0x54, 0x46, 0x3f, 0xa6, 0xa5, 0x96, 0x9e, 0x52, 0x6a, 0xf9, 0x70, 0x3c, 0xd4, 0xc9, + 0x54, 0x5d, 0x7e, 0x35, 0x2b, 0xdd, 0xde, 0xb0, 0x7e, 0x8e, 0x94, 0x5c, 0x98, 0xa6, 0x51, 0x4c, + 0xf0, 0xa2, 0x41, 0x68, 0x0a, 0xa7, 0x9b, 0x1c, 0x7c, 0x7f, 0x50, 0x59, 0x14, 0x1f, 0x4e, 0x37, + 0x89, 0x2f, 0x80, 0x38, 0x68, 0x84, 0x9e, 0x80, 0x82, 0xcb, 0xb1, 0x41, 0x71, 0x99, 0x48, 0x98, + 0x70, 0x18, 0x96, 0x58, 0xf4, 0xe5, 0x48, 0xd8, 0x97, 0x3b, 0xa9, 0xcf, 0x16, 0x8e, 0xca, 0x03, + 0xbd, 0x0a, 0x05, 0x2f, 0x78, 0xee, 0x80, 0xdf, 0x0e, 0x3e, 0x39, 0x62, 0xcd, 0x22, 0x3d, 0x25, + 0x04, 0x6f, 0x1f, 0xf0, 0xf1, 0xc9, 0x97, 0x11, 0x24, 0x4b, 0xfd, 0x7d, 0x0d, 0x4a, 0x62, 0x25, + 0x1e, 0x42, 0x89, 0xe4, 0x6d, 0xb5, 0x44, 0xf2, 0x72, 0x2a, 0x76, 0xe1, 0x90, 0xfa, 0xc8, 0xdb, + 0x30, 0x13, 0xfd, 0x24, 0x10, 0xbd, 0x14, 0xb1, 0x6b, 0xda, 0x24, 0x9f, 0x1e, 0x05, 0x96, 0x2f, + 0xb4, 0x79, 0xfa, 0x5f, 0x4c, 0xc9, 0x59, 0x64, 0x85, 0x98, 0x51, 0xfd, 0xd2, 0x8e, 0xd4, 0xaf, + 0xe8, 0xf2, 0x66, 0x52, 0x5f, 0x5e, 0x74, 0x03, 0x0a, 0x81, 0xf1, 0x11, 0x2e, 0xfa, 0xb1, 0x68, + 0xb5, 0x0a, 0xf5, 0xf3, 0x94, 0x59, 0x44, 0x29, 0xd9, 0x89, 0x41, 0xae, 0xa1, 0x34, 0x8a, 0x92, + 0x0d, 0x7a, 0x0d, 0x4a, 0x77, 0x1d, 0xf7, 0x8e, 0xe5, 0x18, 0xec, 0x45, 0x11, 0x48, 0xe3, 0x0e, + 0x57, 0xde, 0x9c, 0xf0, 0x2a, 0xbd, 0x5b, 0x21, 0x7f, 0x1c, 0x15, 0x86, 0x6a, 0x30, 0xdf, 0x35, + 0x6d, 0x4c, 0x8c, 0xb6, 0xfc, 0xd4, 0x3f, 0xc7, 0x5f, 0x51, 0x08, 0x02, 0xd8, 0x4d, 0x15, 0x8d, + 0xe3, 0xf4, 0xe8, 0x0b, 0x50, 0xf0, 0xc4, 0x67, 0x87, 0xe9, 0xdc, 0xb6, 0xcb, 0xa3, 0x0f, 0x67, + 0x1a, 0xce, 0x5d, 0x00, 0xc1, 0x52, 0x20, 0xda, 0x80, 0x25, 0x57, 0xbc, 0x06, 0x70, 0xd5, 0xf4, + 0x7c, 0xc7, 0xdd, 0xe7, 0x89, 0x2c, 0x7e, 0xbd, 0xca, 0x3e, 0xd6, 0xc7, 0x09, 0x78, 0x9c, 0xd8, + 0x8a, 0x46, 0x28, 0xec, 0xdb, 0x56, 0x7e, 0xdd, 0x5a, 0x08, 0x23, 0x14, 0xa6, 0xf0, 0x6d, 0x2c, + 0xb0, 0x47, 0x55, 0xd6, 0x16, 0x26, 0xa8, 0xac, 0xbd, 0x05, 0x45, 0x97, 0xb0, 0x30, 0xbf, 0x16, + 0xa4, 0xe2, 0xc6, 0xae, 0x01, 0xc0, 0x01, 0x03, 0x1c, 0xf2, 0xd2, 0xff, 0x70, 0x06, 0x66, 0x95, + 0x03, 0x25, 0x3d, 0xdf, 0x1b, 0xdb, 0x8e, 0xcb, 0x6f, 0x11, 0x0a, 0xe1, 0x86, 0xaf, 0x51, 0x20, + 0xe6, 0x38, 0xf4, 0x8e, 0x06, 0xf3, 0x3d, 0xe5, 0xf2, 0x2b, 0xb0, 0x33, 0x13, 0x26, 0x35, 0xd4, + 0x1b, 0xb5, 0xc8, 0x83, 0x35, 0xaa, 0x30, 0x1c, 0x97, 0x4e, 0xd5, 0x55, 0x54, 0xa6, 0x58, 0xc4, + 0x65, 0xd4, 0xc2, 0xdb, 0x4b, 0x16, 0xab, 0x2a, 0x1a, 0xc7, 0xe9, 0xe9, 0x24, 0xb3, 0xd1, 0x4d, + 0xf2, 0xa6, 0x5c, 0x2d, 0x60, 0x80, 0x43, 0x5e, 0xe8, 0x39, 0x98, 0x13, 0x5f, 0x73, 0x37, 0x9c, + 0xf6, 0x55, 0xc3, 0xdb, 0x15, 0x61, 0xae, 0x0c, 0xcb, 0x57, 0x15, 0x2c, 0x8e, 0x51, 0xb3, 0xb1, + 0x85, 0x9f, 0xcc, 0x33, 0x06, 0x53, 0xea, 0x7b, 0x3e, 0xab, 0x2a, 0x1a, 0xc7, 0xe9, 0xd1, 0xc7, + 0x23, 0x56, 0x92, 0x27, 0x0c, 0xe4, 0xde, 0x49, 0xb0, 0x94, 0x35, 0x98, 0xef, 0xb3, 0x53, 0x41, + 0x3b, 0x40, 0x0a, 0xed, 0x95, 0x02, 0x6f, 0xaa, 0x68, 0x1c, 0xa7, 0x47, 0xcf, 0xc2, 0xac, 0x4b, + 0x6d, 0x81, 0x64, 0xc0, 0xb3, 0x08, 0xf2, 0x4a, 0x1c, 0x47, 0x91, 0x58, 0xa5, 0x45, 0xcf, 0xc3, + 0x62, 0xf8, 0x5d, 0x6b, 0xc0, 0x80, 0xa7, 0x15, 0xe4, 0x27, 0xf3, 0xb5, 0x38, 0x01, 0x1e, 0x6e, + 0x83, 0x7e, 0x06, 0x16, 0x22, 0x33, 0xb1, 0x66, 0xb7, 0xc9, 0x3d, 0xf6, 0xb4, 0x45, 0xbe, 0xbe, + 0xc4, 0x52, 0x13, 0x31, 0x1c, 0x1e, 0xa2, 0x46, 0x9f, 0x86, 0xb9, 0x96, 0x63, 0x59, 0xcc, 0x22, + 0xf0, 0xb7, 0x64, 0x66, 0x78, 0x7e, 0x86, 0xad, 0x9b, 0x82, 0xc1, 0x31, 0x4a, 0xb4, 0x0e, 0xc8, + 0xd9, 0xf6, 0x88, 0xbb, 0x47, 0xda, 0xcf, 0xf3, 0x07, 0x6f, 0xa9, 0x43, 0x9c, 0x55, 0xeb, 0xe2, + 0xae, 0x0f, 0x51, 0xe0, 0x84, 0x56, 0xe8, 0x2b, 0x6a, 0xd1, 0xf4, 0x5c, 0x1a, 0x2f, 0xe7, 0xc5, + 0xcf, 0xb0, 0xc7, 0x56, 0x4c, 0xbb, 0x30, 0xc5, 0xcb, 0x14, 0xcb, 0xf3, 0x69, 0x7c, 0x6b, 0x1b, + 0x7d, 0xb6, 0x22, 0xb4, 0xa8, 0x1c, 0x8a, 0x85, 0x24, 0xf4, 0x25, 0x28, 0x6e, 0x07, 0x6f, 0x0c, + 0x95, 0x17, 0xd2, 0xf0, 0x22, 0xb1, 0xe7, 0xb2, 0xc2, 0x33, 0x9a, 0x44, 0xe0, 0x50, 0x24, 0x7a, + 0x1c, 0x4a, 0x57, 0x1b, 0x35, 0xa9, 0x85, 0x8b, 0x6c, 0xf5, 0x73, 0xb4, 0x09, 0x8e, 0x22, 0xe8, + 0x0e, 0x93, 0xd1, 0x05, 0x62, 0x4b, 0x1c, 0x7a, 0xa7, 0xe1, 0x60, 0x81, 0x52, 0xb3, 0x2c, 0x10, + 0x6e, 0x96, 0x4f, 0xc5, 0xa8, 0x05, 0x1c, 0x4b, 0x0a, 0xf4, 0x2a, 0x94, 0x84, 0xc9, 0x66, 0xb6, + 0x69, 0xe9, 0xc1, 0x0a, 0xf2, 0x71, 0xc8, 0x02, 0x47, 0xf9, 0xa1, 0xa7, 0xa1, 0xd4, 0x63, 0x4f, + 0xaf, 0x90, 0x2b, 0x7d, 0xcb, 0x2a, 0x9f, 0x66, 0x76, 0x53, 0x5e, 0x8f, 0x37, 0x42, 0x14, 0x8e, + 0xd2, 0xe9, 0x6f, 0x84, 0x57, 0x8c, 0xf2, 0x75, 0x81, 0x2f, 0x46, 0x57, 0x4b, 0x4b, 0xe3, 0x61, + 0xdc, 0xa1, 0x07, 0xa6, 0xb8, 0xa1, 0x4d, 0x5c, 0xab, 0x9e, 0xd4, 0xcf, 0x54, 0x3e, 0xce, 0x54, + 0x5f, 0x4e, 0xe0, 0xc5, 0xd0, 0xaa, 0x76, 0xea, 0xef, 0x67, 0xe5, 0x35, 0x43, 0x2c, 0xb3, 0xe8, + 0x42, 0xde, 0xf4, 0x7c, 0xd3, 0x49, 0xb1, 0x42, 0x3d, 0xf6, 0xe4, 0x00, 0xab, 0x94, 0x62, 0x08, + 0xcc, 0x45, 0x51, 0x99, 0x76, 0xc7, 0xb4, 0xef, 0x89, 0xe1, 0xdf, 0x48, 0x3d, 0x65, 0xc8, 0x65, + 0x32, 0x04, 0xe6, 0xa2, 0xd0, 0x6d, 0xc8, 0x1a, 0xd6, 0x76, 0x4a, 0x8f, 0x20, 0xc7, 0x9f, 0x00, + 0xe7, 0x75, 0x06, 0xb5, 0x8d, 0x3a, 0xa6, 0x42, 0xa8, 0x2c, 0xaf, 0x6b, 0x0a, 0xdf, 0x3c, 0xa1, + 0xac, 0xe6, 0xe6, 0x5a, 0x92, 0xac, 0xe6, 0xe6, 0x1a, 0xa6, 0x42, 0xf4, 0x77, 0x35, 0x58, 0x1c, + 0xa2, 0x89, 0x3f, 0x18, 0xae, 0x8d, 0xfe, 0x60, 0xb8, 0x78, 0x0b, 0xa2, 0xd9, 0xb3, 0xcc, 0xc4, + 0x8f, 0x2b, 0xb6, 0x62, 0x78, 0x3c, 0xd4, 0x42, 0xff, 0x96, 0x06, 0xa5, 0x48, 0x61, 0x2c, 0x0d, + 0xd5, 0x58, 0x01, 0xb1, 0xe8, 0x46, 0xf8, 0x0c, 0x06, 0xbb, 0xd0, 0xe0, 0x38, 0x7e, 0xb7, 0xd6, + 0x09, 0x6f, 0x98, 0x22, 0x77, 0x6b, 0x14, 0x8a, 0x05, 0x16, 0x5d, 0x80, 0x9c, 0xe7, 0x93, 0x1e, + 0x5b, 0xc8, 0x48, 0x9d, 0x2c, 0xbb, 0x61, 0x66, 0x18, 0x26, 0x8e, 0xda, 0x0c, 0x51, 0xf4, 0x10, + 0x79, 0x75, 0xc3, 0xa0, 0x91, 0x21, 0xc3, 0xa1, 0xf3, 0x90, 0x25, 0x76, 0x5b, 0x04, 0x38, 0x25, + 0x41, 0x92, 0xbd, 0x6c, 0xb7, 0x31, 0x85, 0xeb, 0xd7, 0x61, 0xa6, 0x49, 0x5a, 0x2e, 0xf1, 0x5f, + 0x20, 0xfb, 0xa3, 0xdd, 0xfe, 0x9c, 0xe7, 0x59, 0xb3, 0x8c, 0xca, 0x90, 0x36, 0xa7, 0x70, 0xfd, + 0xf7, 0x34, 0x88, 0x3d, 0x82, 0x82, 0xf4, 0x58, 0x22, 0x0c, 0x86, 0x93, 0x60, 0xca, 0xa9, 0x31, + 0x73, 0xe4, 0xa9, 0x71, 0x1d, 0x50, 0xd7, 0xf0, 0x5b, 0xbb, 0x62, 0x7d, 0xc4, 0x7b, 0x3b, 0x3c, + 0xb6, 0x0c, 0xcb, 0xf0, 0x87, 0x28, 0x70, 0x42, 0x2b, 0xfd, 0xaf, 0x33, 0x30, 0xa3, 0xbc, 0x3d, + 0x7b, 0xfc, 0xf0, 0x47, 0xef, 0x68, 0xc2, 0x81, 0x2d, 0x3b, 0xe6, 0x81, 0x2d, 0x7a, 0x42, 0xce, + 0x9d, 0xec, 0x09, 0x39, 0x9f, 0xca, 0x09, 0x59, 0xff, 0x76, 0x0e, 0xe6, 0xd4, 0x2f, 0xda, 0x46, + 0x98, 0xd3, 0x8f, 0x0f, 0xcd, 0xe9, 0x98, 0xc1, 0x70, 0x76, 0xd2, 0x60, 0x38, 0x37, 0x69, 0x30, + 0x9c, 0x7f, 0x80, 0x60, 0x78, 0x38, 0x94, 0x9d, 0x1a, 0x39, 0x94, 0xfd, 0x8c, 0xcc, 0x69, 0x4c, + 0x2b, 0x97, 0x80, 0x61, 0x4e, 0x03, 0xa9, 0xcb, 0xb0, 0xea, 0xb4, 0x13, 0x73, 0x43, 0x85, 0x63, + 0x0a, 0xa6, 0xdc, 0xc4, 0x14, 0xc4, 0xf8, 0x47, 0xde, 0x0f, 0x8d, 0x9e, 0x7e, 0xd0, 0x5f, 0xcf, + 0x40, 0xf8, 0x9c, 0x2c, 0x7b, 0x57, 0xc6, 0x8b, 0xd8, 0x28, 0xe1, 0xc0, 0xd7, 0x27, 0x7d, 0xbc, + 0x29, 0xe4, 0x28, 0x72, 0x78, 0x11, 0x08, 0x56, 0x24, 0xfe, 0x37, 0x3c, 0x23, 0x6b, 0xc0, 0x7c, + 0xac, 0x94, 0x31, 0xf5, 0x9a, 0x80, 0x6f, 0x65, 0xa0, 0x28, 0x8b, 0x41, 0xa9, 0x59, 0xef, 0xbb, + 0xc1, 0xb3, 0x20, 0xd2, 0xac, 0xdf, 0xc4, 0x1b, 0x98, 0xc2, 0xd1, 0x3d, 0x98, 0xde, 0x25, 0x46, + 0x9b, 0xb8, 0xc1, 0xbd, 0xc2, 0x66, 0x4a, 0x55, 0xa8, 0x57, 0x19, 0xd7, 0x70, 0x2c, 0xfc, 0xb7, + 0x87, 0x03, 0x71, 0xf4, 0xb0, 0xee, 0x9b, 0x5d, 0x42, 0x83, 0xda, 0x88, 0x15, 0xcd, 0x86, 0x87, + 0xf5, 0x2d, 0x05, 0x8b, 0x63, 0xd4, 0xd4, 0xb8, 0xdc, 0xf6, 0x1c, 0x9b, 0x7d, 0xb2, 0x99, 0x53, + 0x23, 0xfb, 0xf5, 0xe6, 0xf5, 0x6b, 0xec, 0x8b, 0x4d, 0x49, 0x41, 0xa9, 0x4d, 0x56, 0x0c, 0xe7, + 0x12, 0x71, 0xcb, 0xbf, 0x10, 0x96, 0xee, 0x73, 0x38, 0x96, 0x14, 0xfa, 0x4d, 0x98, 0x8f, 0x0d, + 0x24, 0x70, 0x8f, 0x5a, 0xb2, 0x7b, 0x1c, 0xe9, 0xbf, 0x59, 0xd4, 0xab, 0xef, 0x7d, 0xb0, 0xfc, + 0xc8, 0x77, 0x3e, 0x58, 0x7e, 0xe4, 0xbb, 0x1f, 0x2c, 0x3f, 0xf2, 0xfa, 0xc1, 0xb2, 0xf6, 0xde, + 0xc1, 0xb2, 0xf6, 0x9d, 0x83, 0x65, 0xed, 0xbb, 0x07, 0xcb, 0xda, 0x3f, 0x1e, 0x2c, 0x6b, 0xef, + 0x7e, 0x7f, 0xf9, 0x91, 0x97, 0x0a, 0xc1, 0x64, 0xfe, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf1, + 0x8e, 0xe0, 0x92, 0x86, 0x67, 0x00, 0x00, } func (m *ALBTrafficRouting) Marshal() (dAtA []byte, err error) { @@ -4872,6 +4906,44 @@ func (m *NginxTrafficRouting) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ObjectRef) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ObjectRef) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ObjectRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x12 + i -= len(m.APIVersion) + copy(dAtA[i:], m.APIVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *PauseCondition) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5623,6 +5695,18 @@ func (m *RolloutSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.WorkloadRef != nil { + { + size, err := m.WorkloadRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + } if m.RestartAt != nil { { size, err := m.RestartAt.MarshalToSizedBuffer(dAtA[:i]) @@ -7327,6 +7411,21 @@ func (m *NginxTrafficRouting) Size() (n int) { return n } +func (m *ObjectRef) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIVersion) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Kind) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *PauseCondition) Size() (n int) { if m == nil { return 0 @@ -7620,6 +7719,10 @@ func (m *RolloutSpec) Size() (n int) { l = m.RestartAt.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.WorkloadRef != nil { + l = m.WorkloadRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -8545,6 +8648,18 @@ func (this *NginxTrafficRouting) String() string { }, "") return s } +func (this *ObjectRef) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ObjectRef{`, + `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} func (this *PauseCondition) String() string { if this == nil { return "nil" @@ -8794,6 +8909,7 @@ func (this *RolloutSpec) String() string { `Paused:` + fmt.Sprintf("%v", this.Paused) + `,`, `ProgressDeadlineSeconds:` + valueToStringGenerated(this.ProgressDeadlineSeconds) + `,`, `RestartAt:` + strings.Replace(fmt.Sprintf("%v", this.RestartAt), "Time", "v1.Time", 1) + `,`, + `WorkloadRef:` + strings.Replace(this.WorkloadRef.String(), "ObjectRef", "ObjectRef", 1) + `,`, `}`, }, "") return s @@ -16681,6 +16797,155 @@ func (m *NginxTrafficRouting) Unmarshal(dAtA []byte) error { } return nil } +func (m *ObjectRef) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ObjectRef: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ObjectRef: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.APIVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PauseCondition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -19253,6 +19518,42 @@ func (m *RolloutSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkloadRef", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.WorkloadRef == nil { + m.WorkloadRef = &ObjectRef{} + } + if err := m.WorkloadRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/rollouts/v1alpha1/generated.proto b/pkg/apis/rollouts/v1alpha1/generated.proto index 4c6221626a..e65b806d16 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.proto +++ b/pkg/apis/rollouts/v1alpha1/generated.proto @@ -736,6 +736,18 @@ message NginxTrafficRouting { map additionalIngressAnnotations = 3; } +// ObjectRef holds a references to the Kubernetes object +message ObjectRef { + // API Version of the referent + optional string apiVersion = 1; + + // Kind of the referent + optional string kind = 2; + + // Name of the referent + optional string name = 3; +} + // PauseCondition the reason for a pause and when it started message PauseCondition { optional string reason = 1; @@ -924,11 +936,17 @@ message RolloutSpec { // Label selector for pods. Existing ReplicaSets whose pods are // selected by this will be the ones affected by this rollout. // It must match the pod template's labels. + // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // +optional optional k8s.io.api.core.v1.PodTemplateSpec template = 3; + // WorkloadRef holds a references to a workload that provides Pod template + // +optional + optional ObjectRef workloadRef = 10; + // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) diff --git a/pkg/apis/rollouts/v1alpha1/openapi_generated.go b/pkg/apis/rollouts/v1alpha1/openapi_generated.go index 6fcd0e038c..89a6977c99 100644 --- a/pkg/apis/rollouts/v1alpha1/openapi_generated.go +++ b/pkg/apis/rollouts/v1alpha1/openapi_generated.go @@ -70,6 +70,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.MetricResult": schema_pkg_apis_rollouts_v1alpha1_MetricResult(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.NewRelicMetric": schema_pkg_apis_rollouts_v1alpha1_NewRelicMetric(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.NginxTrafficRouting": schema_pkg_apis_rollouts_v1alpha1_NginxTrafficRouting(ref), + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.ObjectRef": schema_pkg_apis_rollouts_v1alpha1_ObjectRef(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.PauseCondition": schema_pkg_apis_rollouts_v1alpha1_PauseCondition(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.PodTemplateMetadata": schema_pkg_apis_rollouts_v1alpha1_PodTemplateMetadata(ref), "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.PreferredDuringSchedulingIgnoredDuringExecution": schema_pkg_apis_rollouts_v1alpha1_PreferredDuringSchedulingIgnoredDuringExecution(ref), @@ -2156,6 +2157,40 @@ func schema_pkg_apis_rollouts_v1alpha1_NginxTrafficRouting(ref common.ReferenceC } } +func schema_pkg_apis_rollouts_v1alpha1_ObjectRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ObjectRef holds a references to the Kubernetes object", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "API Version of the referent", + Type: []string{"string"}, + Format: "", + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind of the referent", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the referent", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_rollouts_v1alpha1_PauseCondition(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2842,6 +2877,12 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutSpec(ref common.ReferenceCallback) Ref: ref("k8s.io/api/core/v1.PodTemplateSpec"), }, }, + "workloadRef": { + SchemaProps: spec.SchemaProps{ + Description: "WorkloadRef holds a references to a workload that provides Pod template", + Ref: ref("github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.ObjectRef"), + }, + }, "minReadySeconds": { SchemaProps: spec.SchemaProps{ Description: "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", @@ -2884,11 +2925,10 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutSpec(ref common.ReferenceCallback) }, }, }, - Required: []string{"selector", "template"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutStrategy", "k8s.io/api/core/v1.PodTemplateSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.ObjectRef", "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1.RolloutStrategy", "k8s.io/api/core/v1.PodTemplateSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } diff --git a/pkg/apis/rollouts/v1alpha1/types.go b/pkg/apis/rollouts/v1alpha1/types.go index 5159d2e591..05943f4bdb 100644 --- a/pkg/apis/rollouts/v1alpha1/types.go +++ b/pkg/apis/rollouts/v1alpha1/types.go @@ -1,11 +1,14 @@ package v1alpha1 import ( + "encoding/json" "strconv" "time" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -30,6 +33,8 @@ type Rollout struct { // RolloutSpec is the spec for a Rollout resource type RolloutSpec struct { + TemplateResolvedFromRef bool `json:"-"` + SelectorResolvedFromRef bool `json:"-"` // Number of desired pods. This is a pointer to distinguish between explicit // zero and not specified. Defaults to 1. // +optional @@ -37,9 +42,14 @@ type RolloutSpec struct { // Label selector for pods. Existing ReplicaSets whose pods are // selected by this will be the ones affected by this rollout. // It must match the pod template's labels. + // +optional Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // +optional Template corev1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` + // WorkloadRef holds a references to a workload that provides Pod template + // +optional + WorkloadRef *ObjectRef `json:"workloadRef,omitempty" protobuf:"bytes,10,opt,name=workloadRef"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) @@ -63,6 +73,52 @@ type RolloutSpec struct { RestartAt *metav1.Time `json:"restartAt,omitempty" protobuf:"bytes,9,opt,name=restartAt"` } +func (s *RolloutSpec) SetResolvedSelector(selector *metav1.LabelSelector) { + s.SelectorResolvedFromRef = true + s.Selector = selector +} + +func (s *RolloutSpec) SetResolvedTemplate(template corev1.PodTemplateSpec) { + s.TemplateResolvedFromRef = true + s.Template = template +} + +func (s *RolloutSpec) MarshalJSON() ([]byte, error) { + type Alias RolloutSpec + + if s.TemplateResolvedFromRef || s.SelectorResolvedFromRef { + obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&struct { + Alias `json:",inline"` + }{ + Alias: (Alias)(*s), + }) + if err != nil { + return nil, err + } + if s.TemplateResolvedFromRef { + unstructured.RemoveNestedField(obj, "template") + } + if s.SelectorResolvedFromRef { + unstructured.RemoveNestedField(obj, "selector") + } + + return json.Marshal(obj) + } + return json.Marshal(&struct{ *Alias }{ + Alias: (*Alias)(s), + }) +} + +// ObjectRef holds a references to the Kubernetes object +type ObjectRef struct { + // API Version of the referent + APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,opt,name=apiVersion"` + // Kind of the referent + Kind string `json:"kind,omitempty" protobuf:"bytes,2,opt,name=kind"` + // Name of the referent + Name string `json:"name,omitempty" protobuf:"bytes,3,opt,name=name"` +} + const ( // DefaultRolloutUniqueLabelKey is the default key of the selector that is added // to existing ReplicaSets (and label key that is added to its pods) to prevent the existing ReplicaSets diff --git a/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go index f701f002c4..c24844160a 100644 --- a/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go @@ -1168,6 +1168,22 @@ func (in *NginxTrafficRouting) DeepCopy() *NginxTrafficRouting { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectRef) DeepCopyInto(out *ObjectRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectRef. +func (in *ObjectRef) DeepCopy() *ObjectRef { + if in == nil { + return nil + } + out := new(ObjectRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PauseCondition) DeepCopyInto(out *PauseCondition) { *out = *in @@ -1539,6 +1555,11 @@ func (in *RolloutSpec) DeepCopyInto(out *RolloutSpec) { (*in).DeepCopyInto(*out) } in.Template.DeepCopyInto(&out.Template) + if in.WorkloadRef != nil { + in, out := &in.WorkloadRef, &out.WorkloadRef + *out = new(ObjectRef) + **out = **in + } in.Strategy.DeepCopyInto(&out.Strategy) if in.RevisionHistoryLimit != nil { in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit diff --git a/rollout/controller.go b/rollout/controller.go index 09a2290891..02ac200cf2 100644 --- a/rollout/controller.go +++ b/rollout/controller.go @@ -54,6 +54,10 @@ import ( unstructuredutil "github.com/argoproj/argo-rollouts/utils/unstructured" ) +type TemplateRefResolver interface { + Resolve(r *v1alpha1.Rollout) error +} + // Controller is the controller implementation for Rollout resources type Controller struct { reconcilerBase @@ -81,6 +85,7 @@ type ControllerConfig struct { KubeClientSet kubernetes.Interface ArgoProjClientset clientset.Interface DynamicClientSet dynamic.Interface + RefResolver TemplateRefResolver SmiClientSet smiclientset.Interface ExperimentInformer informers.ExperimentInformer AnalysisRunInformer informers.AnalysisRunInformer @@ -112,6 +117,8 @@ type reconcilerBase struct { dynamicclientset dynamic.Interface smiclientset smiclientset.Interface + refResolver TemplateRefResolver + replicaSetLister appslisters.ReplicaSetLister replicaSetSynced cache.InformerSynced rolloutsInformer cache.SharedIndexInformer @@ -174,6 +181,7 @@ func NewController(cfg ControllerConfig) *Controller { recorder: cfg.Recorder, resyncPeriod: cfg.ResyncPeriod, podRestarter: podRestarter, + refResolver: cfg.RefResolver, } controller := &Controller{ @@ -342,6 +350,11 @@ func (c *Controller) syncHandler(key string) error { // rollout spec and pod template spec, the hash will be consistent. See issue #70 // This also returns a copy of the rollout to prevent mutation of the informer cache. r := remarshalRollout(rollout) + + if err := c.refResolver.Resolve(r); err != nil { + return err + } + logCtx := logutil.WithRollout(r) logCtx = logutil.WithVersionFields(logCtx, r) logCtx.Info("Started syncing rollout") diff --git a/rollout/controller_test.go b/rollout/controller_test.go index c3c7157db0..bb3d0ca9ab 100644 --- a/rollout/controller_test.go +++ b/rollout/controller_test.go @@ -61,6 +61,17 @@ const ( }` ) +type FakeWorkloadRefResolver struct { +} + +func (f *FakeWorkloadRefResolver) Resolve(_ *v1alpha1.Rollout) error { + return nil +} + +func (f *FakeWorkloadRefResolver) Init() error { + return nil +} + type FakeEventRecorder struct { Events chan string } @@ -479,6 +490,7 @@ func (f *fixture) newController(resync resyncFunc) (*Controller, informers.Share IngressWorkQueue: ingressWorkqueue, MetricsServer: metricsServer, Recorder: &FakeEventRecorder{}, + RefResolver: &FakeWorkloadRefResolver{}, }) var enqueuedObjectsLock sync.Mutex diff --git a/rollout/sync.go b/rollout/sync.go index 7f2a8337aa..f55160031e 100644 --- a/rollout/sync.go +++ b/rollout/sync.go @@ -91,7 +91,10 @@ func (c *rolloutContext) syncReplicaSetRevision() (*appsv1.ReplicaSet, error) { c.log.WithError(err).Error("Error: updating rollout revision") return nil, err } - c.rollout = updatedRollout + c.rollout = updatedRollout.DeepCopy() + if err := c.refResolver.Resolve(c.rollout); err != nil { + return nil, err + } c.newRollout = updatedRollout c.log.Infof("Updated rollout revision annotation to %s", rsCopy.Annotations[annotations.RevisionAnnotation]) } @@ -244,6 +247,10 @@ func (c *rolloutContext) createDesiredReplicaSet() (*appsv1.ReplicaSet, error) { return nil, err } c.rollout = updatedRollout + if err := c.refResolver.Resolve(c.rollout); err != nil { + return nil, err + } + c.log.Infof("Updated rollout revision to %s", c.rollout.Annotations[annotations.RevisionAnnotation]) } if !alreadyExists { @@ -254,7 +261,10 @@ func (c *rolloutContext) createDesiredReplicaSet() (*appsv1.ReplicaSet, error) { if err != nil { return nil, err } - c.rollout = updatedRollout + c.rollout = updatedRollout.DeepCopy() + if err := c.refResolver.Resolve(c.rollout); err != nil { + return nil, err + } c.newRollout = updatedRollout c.log.Infof("Set rollout condition: %v", condition) } diff --git a/rollout/temlateref.go b/rollout/temlateref.go new file mode 100644 index 0000000000..4e16cfc7f0 --- /dev/null +++ b/rollout/temlateref.go @@ -0,0 +1,266 @@ +package rollout + +import ( + "context" + "encoding/json" + "fmt" + "sync" + "time" + + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + unstructuredutil "github.com/argoproj/argo-rollouts/utils/unstructured" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/dynamicinformer" + "k8s.io/client-go/informers" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" +) + +const ( + templateRefIndexName = "byTemplateRef" +) + +type knownKindInfo struct { + TemplatePath []string + SelectorPath []string +} + +var ( + infoByGroupKind = map[schema.GroupKind]knownKindInfo{ + {Kind: "PodTemplate"}: { + TemplatePath: []string{"template"}, + }, + {Group: "apps", Kind: "Deployment"}: { + TemplatePath: []string{"spec", "template"}, SelectorPath: []string{"spec", "selector"}, + }, + {Group: "apps", Kind: "ReplicaSet"}: { + TemplatePath: []string{"spec", "template"}, SelectorPath: []string{"spec", "selector"}, + }, + } +) + +type informerBasedTemplateResolver struct { + namespace string + informerResyncDuration time.Duration + informerSyncTimeout time.Duration + informersLock sync.Mutex + informers map[schema.GroupVersionKind]func() (informers.GenericInformer, error) + dynamicClient dynamic.Interface + discoClient discovery.DiscoveryInterface + ctx context.Context + cancelContext context.CancelFunc + rolloutWorkQueue workqueue.Interface + rolloutsInformer cache.SharedIndexInformer +} + +// NewInformerBasedWorkloadRefResolver create new instance of workload ref resolver. +func NewInformerBasedWorkloadRefResolver( + namespace string, + dynamicClient dynamic.Interface, + discoClient discovery.DiscoveryInterface, + rolloutWorkQueue workqueue.Interface, + rolloutsInformer cache.SharedIndexInformer, +) *informerBasedTemplateResolver { + ctx, cancelContext := context.WithCancel(context.TODO()) + err := rolloutsInformer.AddIndexers(cache.Indexers{ + templateRefIndexName: func(obj interface{}) ([]string, error) { + if ro := unstructuredutil.ObjectToRollout(obj); ro != nil && ro.Spec.WorkloadRef != nil { + return []string{refKey(*ro.Spec.WorkloadRef, ro.Namespace)}, nil + } + return nil, nil + }, + }) + if err != nil { + panic(err) + } + return &informerBasedTemplateResolver{ + informers: map[schema.GroupVersionKind]func() (informers.GenericInformer, error){}, + namespace: namespace, + ctx: ctx, + cancelContext: cancelContext, + informerResyncDuration: time.Minute * 5, + informerSyncTimeout: time.Minute, + dynamicClient: dynamicClient, + discoClient: discoClient, + rolloutWorkQueue: rolloutWorkQueue, + rolloutsInformer: rolloutsInformer, + } +} + +func refKey(ref v1alpha1.ObjectRef, namespace string) string { + return fmt.Sprintf("%s/%s/%s/%s", ref.APIVersion, ref.Kind, namespace, ref.Name) +} + +// Stop stops all started informers +func (r *informerBasedTemplateResolver) Stop() { + r.informersLock.Lock() + defer r.informersLock.Unlock() + if r.cancelContext != nil { + r.cancelContext() + } + ctx, cancelContext := context.WithCancel(context.TODO()) + r.ctx = ctx + r.cancelContext = cancelContext +} + +func remashalMap(objMap map[string]interface{}, res interface{}) error { + data, err := json.Marshal(objMap) + if err != nil { + return err + } + return json.Unmarshal(data, res) +} + +// Resolve verifies if given rollout has template reference and resolves pod template +func (r *informerBasedTemplateResolver) Resolve(rollout *v1alpha1.Rollout) error { + if rollout.Spec.WorkloadRef == nil { + return nil + } + + gvk := schema.FromAPIVersionAndKind(rollout.Spec.WorkloadRef.APIVersion, rollout.Spec.WorkloadRef.Kind) + + info, ok := infoByGroupKind[gvk.GroupKind()] + if !ok { + return fmt.Errorf("workload of type %s/%s is not supported", gvk.Group, gvk.Kind) + } + + informer, err := r.getInformer(gvk) + if err != nil { + return err + } + obj, err := informer.Lister().Get(fmt.Sprintf("%s/%s", rollout.Namespace, rollout.Spec.WorkloadRef.Name)) + if err != nil { + return err + } + un, ok := obj.(*unstructured.Unstructured) + if !ok { + return fmt.Errorf("informer for %v must have unstructured object but had %v", gvk, obj) + } + + if podTemplateSpecMap, ok, _ := unstructured.NestedMap(un.Object, info.TemplatePath...); ok { + var template corev1.PodTemplateSpec + if err := remashalMap(podTemplateSpecMap, &template); err != nil { + return err + } + + rollout.Spec.SetResolvedTemplate(template) + } + + if rollout.Spec.Selector == nil && info.SelectorPath != nil { + if selectorMap, ok, _ := unstructured.NestedMap(un.Object, info.SelectorPath...); ok { + var selector v1.LabelSelector + if err := remashalMap(selectorMap, &selector); err != nil { + return err + } + rollout.Spec.SetResolvedSelector(&selector) + } + } + + return nil +} + +// newInformerForGVK create an informer for a given group version kind +func (r *informerBasedTemplateResolver) newInformerForGVK(gvk schema.GroupVersionKind) (informers.GenericInformer, error) { + resources, err := r.discoClient.ServerResourcesForGroupVersion(gvk.GroupVersion().String()) + if err != nil { + return nil, err + } + var apiResource *v1.APIResource + for _, r := range resources.APIResources { + if r.Kind == gvk.Kind { + apiResource = &r + break + } + } + if apiResource == nil { + return nil, errors.NewNotFound(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, "") + } + informer := dynamicinformer.NewFilteredDynamicInformer( + r.dynamicClient, + schema.GroupVersionResource{Group: gvk.Group, Version: gvk.Version, Resource: apiResource.Name}, + r.namespace, + r.informerResyncDuration, + cache.Indexers{}, + nil) + informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + r.requeueReferencedRollouts(obj, gvk) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + r.requeueReferencedRollouts(newObj, gvk) + }, + DeleteFunc: func(obj interface{}) { + r.requeueReferencedRollouts(obj, gvk) + }, + }) + return informer, nil + +} + +// requeueReferencedRollouts re-queues all rollouts referenced by given object +func (r *informerBasedTemplateResolver) requeueReferencedRollouts(obj interface{}, gvk schema.GroupVersionKind) { + roMeta, err := meta.Accessor(obj) + if err != nil { + return + } + rollouts, err := r.rolloutsInformer.GetIndexer().ByIndex(templateRefIndexName, refKey(v1alpha1.ObjectRef{ + Kind: gvk.Kind, + APIVersion: gvk.GroupVersion().String(), + Name: roMeta.GetName(), + }, roMeta.GetNamespace())) + if err != nil { + return + } + for _, ro := range rollouts { + if key, err := cache.MetaNamespaceKeyFunc(ro); err == nil { + r.rolloutWorkQueue.Add(key) + } + } +} + +// getInformer on-demand creates and informer that watches all resources of a given group version kind +func (r *informerBasedTemplateResolver) getInformer(gvk schema.GroupVersionKind) (informers.GenericInformer, error) { + r.informersLock.Lock() + getInformer, ok := r.informers[gvk] + if !ok { + var initLock sync.Mutex + initialized := false + var informer informers.GenericInformer + getInformer = func() (informers.GenericInformer, error) { + initLock.Lock() + defer initLock.Unlock() + if !initialized { + if i, err := r.newInformerForGVK(gvk); err != nil { + return nil, err + } else { + informer = i + } + go informer.Informer().Run(r.ctx.Done()) + ctx, cancel := context.WithTimeout(r.ctx, r.informerSyncTimeout) + defer cancel() + if !cache.WaitForCacheSync(ctx.Done(), informer.Informer().HasSynced) { + return nil, fmt.Errorf("failed to sync informer for %v", gvk) + } + initialized = true + } + + return informer, nil + } + r.informers[gvk] = getInformer + } + r.informersLock.Unlock() + + informer, err := getInformer() + if err != nil { + return nil, err + } + return informer, nil +} diff --git a/rollout/temlateref_test.go b/rollout/temlateref_test.go new file mode 100644 index 0000000000..93c239e557 --- /dev/null +++ b/rollout/temlateref_test.go @@ -0,0 +1,408 @@ +package rollout + +import ( + "context" + "testing" + "time" + + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + "github.com/argoproj/argo-rollouts/pkg/client/clientset/versioned" + "github.com/argoproj/argo-rollouts/pkg/client/clientset/versioned/fake" + rolloutinformers "github.com/argoproj/argo-rollouts/pkg/client/informers/externalversions/rollouts/v1alpha1" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + disco "k8s.io/client-go/discovery" + discofake "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/dynamic" + dynamicfake "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/kubernetes/scheme" + k8stesting "k8s.io/client-go/testing" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" +) + +func newFakeDiscoClient() *discofake.FakeDiscovery { + return &discofake.FakeDiscovery{ + Fake: &k8stesting.Fake{ + Resources: []*metav1.APIResourceList{ + { + GroupVersion: corev1.SchemeGroupVersion.String(), + APIResources: []metav1.APIResource{ + {Name: "podtemplates", Namespaced: true, Kind: "PodTemplate"}, + }, + }, + { + GroupVersion: appsv1.SchemeGroupVersion.String(), + APIResources: []metav1.APIResource{ + {Name: "deployments", Namespaced: true, Kind: "Deployment"}, + {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"}, + }, + }, + }, + }, + } +} + +func newResolver(dynamicClient dynamic.Interface, discoveryClient disco.DiscoveryInterface, rolloutClient versioned.Interface) (*informerBasedTemplateResolver, context.CancelFunc) { + rolloutsInformer := rolloutinformers.NewRolloutInformer(rolloutClient, "", time.Minute, cache.Indexers{}) + resolver := NewInformerBasedWorkloadRefResolver("", dynamicClient, discoveryClient, workqueue.NewDelayingQueue(), rolloutsInformer) + stop := make(chan struct{}) + go rolloutsInformer.Run(stop) + cache.WaitForCacheSync(stop, rolloutsInformer.HasSynced) + return resolver, func() { + stop <- struct{}{} + resolver.Stop() + } +} + +func mustToUnstructured(obj runtime.Object) *unstructured.Unstructured { + res, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + panic(err) + } + return &unstructured.Unstructured{Object: res} +} + +func TestResolve_NotSupportedGroup(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-rs", + Kind: "argoproj", + APIVersion: "Workflow/v1", + }, + }, + } + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.Error(t, err) +} + +func TestResolve_NotSupportedKind(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-rs", + Kind: "Deployment", + APIVersion: "apps/v1", + }, + }, + } + + discoveryClient := &discofake.FakeDiscovery{Fake: &k8stesting.Fake{ + Resources: []*metav1.APIResourceList{ + { + GroupVersion: appsv1.SchemeGroupVersion.String(), + APIResources: []metav1.APIResource{ + {Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"}, + }, + }, + }, + }} + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.Error(t, err) + assert.True(t, errors.IsNotFound(err)) +} + +func TestResolve_UnknownAPIResource(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-deployment", + Kind: "Deployment", + APIVersion: "apps/v1", + }, + }, + } + + discoveryClient := &discofake.FakeDiscovery{Fake: &k8stesting.Fake{}} + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.Error(t, err) + assert.Equal(t, `GroupVersion "apps/v1" not found`, err.Error()) +} + +func TestResolve_RefDoesNotExists(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-deployment", + Kind: "Deployment", + APIVersion: "apps/v1", + }, + }, + } + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.Error(t, err) + assert.True(t, errors.IsNotFound(err)) +} + +func TestResolve_DeploymentRef(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-deployment", + Kind: "Deployment", + APIVersion: "apps/v1", + }, + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: appsv1.SchemeGroupVersion.String(), + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + Namespace: "default", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"app": "my-app"}}, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"test-label": "test-label-val"}}, + }, + }, + } + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme, deployment) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.NoError(t, err) + assert.Equal(t, deployment.Spec.Template, rollout.Spec.Template) + assert.Equal(t, deployment.Spec.Selector, rollout.Spec.Selector) +} + +func TestResolve_ReplicaSetRef(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-rs", + Kind: "ReplicaSet", + APIVersion: "apps/v1", + }, + }, + } + + rs := &appsv1.ReplicaSet{ + TypeMeta: metav1.TypeMeta{ + APIVersion: appsv1.SchemeGroupVersion.String(), + Kind: "ReplicaSet", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-rs", + Namespace: "default", + }, + Spec: appsv1.ReplicaSetSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"test-label": "test-label-val"}}, + }, + }, + } + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme, rs) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.NoError(t, err) + assert.Equal(t, rs.Spec.Template, rollout.Spec.Template) +} + +func TestResolveRefDeployment_PodTemplate(t *testing.T) { + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-pod-template", + Kind: "PodTemplate", + APIVersion: "v1", + }, + }, + } + + rs := &corev1.PodTemplate{ + TypeMeta: metav1.TypeMeta{ + APIVersion: corev1.SchemeGroupVersion.String(), + Kind: "PodTemplate", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-pod-template", + Namespace: "default", + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"test-label": "test-label-val"}}, + }, + } + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme, rs) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + + assert.NoError(t, err) + assert.Equal(t, rs.Template, rollout.Spec.Template) +} + +func TestRequeueReferencedRollouts(t *testing.T) { + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: appsv1.SchemeGroupVersion.String(), + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + Namespace: "default", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"test-label": "test-label-val"}}, + }, + }, + } + + rollout := v1alpha1.Rollout{ + ObjectMeta: v1.ObjectMeta{ + Name: "my-rollout", + Namespace: "default", + }, + Spec: v1alpha1.RolloutSpec{ + WorkloadRef: &v1alpha1.ObjectRef{ + Name: "my-deployment", + Kind: "Deployment", + APIVersion: "apps/v1", + }, + }, + } + rolloutsClient := fake.NewSimpleClientset(&rollout) + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme, deployment) + resolver, cancel := newResolver(dynamicClient, discoveryClient, rolloutsClient) + defer cancel() + + err := resolver.Resolve(&rollout) + require.NoError(t, err) + + deploymentsClient := dynamicClient.Resource(appsv1.SchemeGroupVersion.WithResource("deployments")).Namespace("default") + + _, err = deploymentsClient.Update(context.TODO(), mustToUnstructured(deployment), v1.UpdateOptions{}) + require.NoError(t, err) + + go func() { + // shutdown queue to make sure test fails if requeue functionality is broken + time.Sleep(5 * time.Second) + resolver.rolloutWorkQueue.ShutDown() + }() + + item, done := resolver.rolloutWorkQueue.Get() + require.False(t, done) + assert.Equal(t, "default/my-rollout", item) + resolver.rolloutWorkQueue.Done(item) + + err = deploymentsClient.Delete(context.TODO(), deployment.Name, v1.DeleteOptions{}) + require.NoError(t, err) + + item, done = resolver.rolloutWorkQueue.Get() + require.False(t, done) + assert.Equal(t, "default/my-rollout", item) + resolver.rolloutWorkQueue.Done(item) +} + +func TestRequeueReferencedRollouts_InvalidMeta(t *testing.T) { + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme) + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + resolver.requeueReferencedRollouts(nil, schema.GroupVersionKind{}) + + assert.Equal(t, 0, resolver.rolloutWorkQueue.Len()) +} + +func TestResolveNotRef(t *testing.T) { + rollout := v1alpha1.Rollout{} + + discoveryClient := newFakeDiscoClient() + dynamicClient := dynamicfake.NewSimpleDynamicClient(scheme.Scheme) + + resolver, cancel := newResolver(dynamicClient, discoveryClient, fake.NewSimpleClientset()) + defer cancel() + + err := resolver.Resolve(&rollout) + assert.NoError(t, err) + assert.Equal(t, corev1.PodTemplateSpec{}, rollout.Spec.Template) + assert.Nil(t, rollout.Spec.Selector) +} + +func TestRemashalMapFails(t *testing.T) { + err := remashalMap(nil, struct{}{}) + assert.Error(t, err) +} diff --git a/test/e2e/functional_test.go b/test/e2e/functional_test.go index 4bab71b3d6..e4b4bfe6ed 100644 --- a/test/e2e/functional_test.go +++ b/test/e2e/functional_test.go @@ -904,3 +904,55 @@ spec: }). ExpectActiveRevision("2") } + +func (s *FunctionalSuite) TestWorkloadRef() { + s.Given(). + RolloutObjects(` +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: rollout-canary + name: rollout-ref-deployment +spec: + replicas: 0 + selector: + matchLabels: + app: rollout-ref-deployment + template: + metadata: + labels: + app: rollout-ref-deployment + spec: + containers: + - name: rollouts-demo + image: argoproj/rollouts-demo:blue + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: rollout-ref-deployment +spec: + replicas: 1 + revisionHistoryLimit: 2 + workloadRef: + apiVersion: apps/v1 + kind: Deployment + name: rollout-ref-deployment + strategy: + canary: + steps: + - setWeight: 100 +`). + When(). + ApplyManifests(). + WaitForRolloutReplicas(1). + WaitForRolloutStatus("Healthy"). + Then(). + ExpectRollout("Resolved template not persisted", func(rollout *v1alpha1.Rollout) bool { + return rollout.Spec.Selector == nil && len(rollout.Spec.Template.Spec.Containers) == 0 + }) +} diff --git a/ui/src/models/rollout/generated/api.ts b/ui/src/models/rollout/generated/api.ts index 65dd22e713..48437f537b 100644 --- a/ui/src/models/rollout/generated/api.ts +++ b/ui/src/models/rollout/generated/api.ts @@ -523,6 +523,31 @@ export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1NginxTraffi */ additionalIngressAnnotations?: { [key: string]: string; }; } +/** + * + * @export + * @interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef + */ +export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef { + /** + * + * @type {string} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef + */ + apiVersion?: string; + /** + * + * @type {string} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef + */ + kind?: string; + /** + * + * @type {string} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef + */ + name?: string; +} /** * * @export @@ -867,6 +892,12 @@ export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutSpec * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutSpec */ template?: K8sIoApiCoreV1PodTemplateSpec; + /** + * + * @type {GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutSpec + */ + workloadRef?: GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1ObjectRef; /** * * @type {number}