From 017537b2193937df97991ee810af8f44a1a3419c Mon Sep 17 00:00:00 2001 From: Liming Liu Date: Wed, 6 Mar 2024 10:21:48 +0800 Subject: [PATCH] feat: add the max traffic weight support for the traffic routing (nginx/plugins). (#3215) * add support for the traffic weight > 100. Signed-off-by: Liming Liu * unit test for the max weight ingress. Signed-off-by: Liming Liu * unit test for the max weight in canary rollout. Signed-off-by: Liming Liu * add docs Signed-off-by: Zach Aller * add docs Signed-off-by: Zach Aller --------- Signed-off-by: Liming Liu Signed-off-by: Zach Aller Co-authored-by: Zach Aller --- docs/features/specification.md | 3 + manifests/crds/rollout-crd.yaml | 3 + manifests/install.yaml | 3 + pkg/apiclient/rollout/rollout.swagger.json | 5 + pkg/apis/rollouts/v1alpha1/generated.pb.go | 926 +++++++++--------- pkg/apis/rollouts/v1alpha1/generated.proto | 3 + .../rollouts/v1alpha1/openapi_generated.go | 7 + pkg/apis/rollouts/v1alpha1/types.go | 4 + .../v1alpha1/zz_generated.deepcopy.go | 5 + pkg/apis/rollouts/validation/validation.go | 20 +- .../rollouts/validation/validation_test.go | 54 +- .../info/rollout_info.go | 5 +- rollout/canary_test.go | 87 ++ rollout/trafficrouting.go | 10 +- rollout/trafficrouting/nginx/nginx.go | 8 + rollout/trafficrouting/nginx/nginx_test.go | 46 + ui/src/models/rollout/generated/api.ts | 6 + utils/replicaset/canary.go | 48 +- utils/replicaset/canary_test.go | 149 +-- utils/weightutil/weight.go | 13 + 20 files changed, 850 insertions(+), 555 deletions(-) create mode 100644 utils/weightutil/weight.go diff --git a/docs/features/specification.md b/docs/features/specification.md index 85b18f28f6..607367c0c8 100644 --- a/docs/features/specification.md +++ b/docs/features/specification.md @@ -386,6 +386,9 @@ spec: # will achieve traffic split via a weighted replica counts between # the canary and stable ReplicaSet. trafficRouting: + # Supports nginx and plugins only: This lets you control the denominator or total weight of traffic. + # The total weight of traffic. If unspecified, it defaults to 100 + maxTrafficWeight: 1000 # This is a list of routes that Argo Rollouts has the rights to manage it is currently only required for # setMirrorRoute and setHeaderRoute. The order of managedRoutes array also sets the precedence of the route # in the traffic router. Argo Rollouts will place these routes in the order specified above any routes already diff --git a/manifests/crds/rollout-crd.yaml b/manifests/crds/rollout-crd.yaml index 65cc341158..9f17209eeb 100755 --- a/manifests/crds/rollout-crd.yaml +++ b/manifests/crds/rollout-crd.yaml @@ -923,6 +923,9 @@ spec: - name type: object type: array + maxTrafficWeight: + format: int32 + type: integer nginx: properties: additionalIngressAnnotations: diff --git a/manifests/install.yaml b/manifests/install.yaml index 99f2e34a3b..76d66f32d5 100755 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -12843,6 +12843,9 @@ spec: - name type: object type: array + maxTrafficWeight: + format: int32 + type: integer nginx: properties: additionalIngressAnnotations: diff --git a/pkg/apiclient/rollout/rollout.swagger.json b/pkg/apiclient/rollout/rollout.swagger.json index db6e03206f..014b6345b8 100755 --- a/pkg/apiclient/rollout/rollout.swagger.json +++ b/pkg/apiclient/rollout/rollout.swagger.json @@ -2303,6 +2303,11 @@ "format": "byte" }, "title": "+kubebuilder:validation:Schemaless\n+kubebuilder:pruning:PreserveUnknownFields\n+kubebuilder:validation:Type=object\nPlugins holds specific configuration that traffic router plugins can use for routing traffic" + }, + "maxTrafficWeight": { + "type": "integer", + "format": "int32", + "title": "MaxTrafficWeight The total weight of traffic. If unspecified, it defaults to 100" } }, "title": "RolloutTrafficRouting hosts all the different configuration for supported service meshes to enable more fine-grained traffic routing" diff --git a/pkg/apis/rollouts/v1alpha1/generated.pb.go b/pkg/apis/rollouts/v1alpha1/generated.pb.go index 773cebb542..f1b6428971 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.pb.go +++ b/pkg/apis/rollouts/v1alpha1/generated.pb.go @@ -3349,14 +3349,14 @@ func init() { } var fileDescriptor_e0e705f843545fab = []byte{ - // 8550 bytes of a gzipped FileDescriptorProto + // 8566 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x24, 0xd9, 0x71, 0x98, 0x9a, 0xc3, 0x21, 0x39, 0x35, 0x5c, 0x92, 0xfb, 0x76, 0xf7, 0x8e, 0xc7, 0xbb, 0xdd, 0x59, 0xf5, 0x39, 0x97, 0x3d, 0xeb, 0x44, 0x4a, 0x7b, 0x77, 0xc9, 0x49, 0xa7, 0x5c, 0x32, 0x43, 0xee, 0xde, 0x72, 0x8f, 0xdc, 0xe5, 0xd5, 0x70, 0x6f, 0x6d, 0x49, 0x67, 0xab, 0x39, 0xf3, 0x38, - 0xec, 0xe5, 0x4c, 0xf7, 0xa8, 0xbb, 0x87, 0xbb, 0x3c, 0x1d, 0xac, 0x93, 0x85, 0x53, 0x14, 0x41, + 0xec, 0xe5, 0x4c, 0xf7, 0xa8, 0xbb, 0x87, 0xbb, 0x3c, 0x1d, 0xac, 0x93, 0x84, 0x53, 0x14, 0x41, 0x82, 0x95, 0xd8, 0x42, 0x10, 0x24, 0x08, 0x14, 0xc3, 0x80, 0x93, 0xd8, 0x3f, 0x02, 0xc3, 0x41, - 0xf2, 0xc3, 0x40, 0x84, 0x38, 0x76, 0x14, 0x20, 0x0e, 0xe4, 0x1f, 0x89, 0x9c, 0x00, 0xa6, 0x23, + 0xf2, 0xc3, 0x40, 0x8c, 0x38, 0x76, 0x14, 0x20, 0x0e, 0xe4, 0x1f, 0x89, 0x9c, 0x00, 0xa6, 0x23, 0x3a, 0x7f, 0x62, 0x24, 0x10, 0x12, 0x28, 0x30, 0xb2, 0x3f, 0x82, 0xe0, 0x7d, 0xf6, 0xeb, 0x9e, 0x1e, 0xee, 0x90, 0xd3, 0x5c, 0x9d, 0x13, 0xff, 0x9b, 0x79, 0x55, 0xaf, 0xaa, 0xfa, 0x7d, 0xd6, 0xab, 0x57, 0x55, 0x0f, 0xd6, 0x5a, 0x6e, 0xb4, 0xd3, 0xdb, 0x5a, 0x6c, 0xf8, 0x9d, 0x25, 0x27, @@ -3371,21 +3371,21 @@ var fileDescriptor_e0e705f843545fab = []byte{ 0xab, 0x3b, 0x34, 0x72, 0xb2, 0x6a, 0x2d, 0x0d, 0xaa, 0x15, 0xf4, 0xbc, 0xc8, 0xed, 0xd0, 0xbe, 0x0a, 0x7f, 0xe9, 0x51, 0x15, 0xc2, 0xc6, 0x0e, 0xed, 0x38, 0x7d, 0xf5, 0x5e, 0x1c, 0x54, 0xaf, 0x17, 0xb9, 0xed, 0x25, 0xd7, 0x8b, 0xc2, 0x28, 0x48, 0x57, 0xb2, 0x7f, 0x58, 0x80, 0x52, 0x75, - 0xad, 0x56, 0x8f, 0x9c, 0xa8, 0x17, 0x92, 0xaf, 0x58, 0x30, 0xdd, 0xf6, 0x9d, 0x66, 0xcd, 0x69, + 0xad, 0x56, 0x8f, 0x9c, 0xa8, 0x17, 0x92, 0xaf, 0x5a, 0x30, 0xdd, 0xf6, 0x9d, 0x66, 0xcd, 0x69, 0x3b, 0x5e, 0x83, 0x06, 0xf3, 0xd6, 0x65, 0xeb, 0x4a, 0xf9, 0xea, 0xda, 0xe2, 0x28, 0xfd, 0xb5, 0x58, 0xbd, 0x1f, 0x22, 0x0d, 0xfd, 0x5e, 0xd0, 0xa0, 0x48, 0xb7, 0x6b, 0xe7, 0xbf, 0x7b, 0x50, - 0xf9, 0xd0, 0xe1, 0x41, 0x65, 0x7a, 0xcd, 0xe0, 0x84, 0x09, 0xbe, 0xe4, 0x5b, 0x16, 0x9c, 0x6d, + 0xf9, 0xd0, 0xe1, 0x41, 0x65, 0x7a, 0xcd, 0xe0, 0x84, 0x09, 0xbe, 0xe4, 0xdb, 0x16, 0x9c, 0x6d, 0x38, 0x9e, 0x13, 0xec, 0x6f, 0x3a, 0x41, 0x8b, 0x46, 0xaf, 0x07, 0x7e, 0xaf, 0x3b, 0x3f, 0x76, 0x0a, 0xd2, 0x3c, 0x25, 0xa5, 0x39, 0xbb, 0x9c, 0x66, 0x87, 0xfd, 0x12, 0x70, 0xb9, 0xc2, 0xc8, 0xd9, 0x6a, 0x53, 0x53, 0xae, 0xc2, 0x69, 0xca, 0x55, 0x4f, 0xb3, 0xc3, 0x7e, 0x09, 0xc8, 0xf3, 0x30, 0xe9, 0x7a, 0xad, 0x80, 0x86, 0xe1, 0xfc, 0xf8, 0x65, 0xeb, 0x4a, 0xa9, 0x36, 0x2b, 0xab, - 0x4f, 0xae, 0x8a, 0x62, 0x54, 0x70, 0xfb, 0x37, 0x0a, 0x70, 0xb6, 0xba, 0x56, 0xdb, 0x0c, 0x9c, + 0x4f, 0xae, 0x8a, 0x62, 0x54, 0x70, 0xfb, 0xd7, 0x0b, 0x70, 0xb6, 0xba, 0x56, 0xdb, 0x0c, 0x9c, 0xed, 0x6d, 0xb7, 0x81, 0x7e, 0x2f, 0x72, 0xbd, 0x96, 0x49, 0xc0, 0x3a, 0x9a, 0x00, 0x79, 0x19, 0xca, 0x21, 0x0d, 0xf6, 0xdc, 0x06, 0xdd, 0xf0, 0x83, 0x88, 0x77, 0x4a, 0xb1, 0x76, 0x4e, 0xa2, 0x97, 0xeb, 0x31, 0x08, 0x4d, 0x3c, 0x56, 0x2d, 0xf0, 0xfd, 0x48, 0xc2, 0x79, 0x9b, 0x95, 0xe2, 0x6a, 0x18, 0x83, 0xd0, 0xc4, 0x23, 0x2b, 0x30, 0xe7, 0x78, 0x9e, 0x1f, 0x39, 0x91, 0xeb, 0x7b, 0x1b, 0x01, 0xdd, 0x76, 0x1f, 0xc8, 0x4f, 0x9c, 0x97, 0x75, 0xe7, 0xaa, 0x29, 0x38, 0xf6, 0xd5, - 0x20, 0xdf, 0xb4, 0x60, 0x2e, 0x8c, 0xdc, 0xc6, 0xae, 0xeb, 0xd1, 0x30, 0x5c, 0xf6, 0xbd, 0x6d, + 0x20, 0xdf, 0xb2, 0x60, 0x2e, 0x8c, 0xdc, 0xc6, 0xae, 0xeb, 0xd1, 0x30, 0x5c, 0xf6, 0xbd, 0x6d, 0xb7, 0x35, 0x5f, 0xe4, 0xdd, 0x76, 0x6b, 0xb4, 0x6e, 0xab, 0xa7, 0xa8, 0xd6, 0xce, 0x33, 0x91, 0xd2, 0xa5, 0xd8, 0xc7, 0x9d, 0x7c, 0x04, 0x4a, 0xb2, 0x45, 0x69, 0x38, 0x3f, 0x71, 0xb9, 0x70, 0xa5, 0x54, 0x3b, 0x73, 0x78, 0x50, 0x29, 0xad, 0xaa, 0x42, 0x8c, 0xe1, 0xf6, 0x0a, 0xcc, 0x57, @@ -3405,7 +3405,7 @@ var fileDescriptor_e0e705f843545fab = []byte{ 0xa1, 0xfd, 0x47, 0x16, 0xcc, 0x1a, 0x1f, 0xb7, 0xe6, 0x86, 0x11, 0xf9, 0x6c, 0xdf, 0xe0, 0x59, 0x1c, 0x6e, 0xf0, 0xb0, 0xda, 0x7c, 0xe8, 0xcc, 0xc9, 0x2f, 0x9d, 0x52, 0x25, 0xc6, 0xc0, 0xf1, 0xa0, 0xe8, 0x46, 0xb4, 0x13, 0xce, 0x8f, 0x5d, 0x2e, 0x5c, 0x29, 0x5f, 0x5d, 0xcd, 0xad, 0x1b, - 0xe3, 0xf6, 0x5d, 0x65, 0xf4, 0x51, 0xb0, 0xb1, 0x7f, 0xb3, 0x90, 0xe8, 0xbe, 0x75, 0x25, 0xc7, + 0xe3, 0xf6, 0x5d, 0x65, 0xf4, 0x51, 0xb0, 0xb1, 0x7f, 0xa3, 0x90, 0xe8, 0xbe, 0x75, 0x25, 0xc7, 0xfb, 0x16, 0x4c, 0xb4, 0x9d, 0x2d, 0xda, 0x16, 0x73, 0xab, 0x7c, 0xf5, 0xed, 0xdc, 0x24, 0x51, 0x3c, 0x16, 0xd7, 0x38, 0xfd, 0x6b, 0x5e, 0x14, 0xec, 0xc7, 0xc3, 0x4b, 0x14, 0xa2, 0x64, 0x4e, 0xfe, 0x8e, 0x05, 0xe5, 0x78, 0x55, 0x53, 0xcd, 0xb2, 0x95, 0xbf, 0x30, 0xf1, 0x62, 0x2a, 0x25, @@ -3417,7 +3417,7 @@ var fileDescriptor_e0e705f843545fab = []byte{ 0x9f, 0x5c, 0xcf, 0x67, 0x5a, 0xc6, 0x4b, 0x45, 0x35, 0x68, 0x85, 0xc8, 0x39, 0x90, 0x25, 0x28, 0x45, 0x34, 0xe8, 0xb8, 0x9e, 0x13, 0x89, 0x1d, 0x74, 0xaa, 0x76, 0x56, 0xa2, 0x95, 0x36, 0x15, 0x00, 0x63, 0x1c, 0xd2, 0x86, 0x89, 0x66, 0xb0, 0x8f, 0x3d, 0x6f, 0x7e, 0x3c, 0x8f, 0xa6, 0x58, - 0xe1, 0xb4, 0xe2, 0x41, 0x2a, 0xfe, 0xa3, 0xe4, 0x41, 0x7e, 0xc5, 0x82, 0xf3, 0x1d, 0xea, 0x84, + 0xe1, 0xb4, 0xe2, 0x41, 0x2a, 0xfe, 0xa3, 0xe4, 0x41, 0x7e, 0xd9, 0x82, 0xf3, 0x1d, 0xea, 0x84, 0xbd, 0x80, 0xb2, 0x4f, 0x40, 0x1a, 0x51, 0x8f, 0x75, 0xec, 0x7c, 0x91, 0x33, 0xc7, 0x51, 0xfb, 0xa1, 0x9f, 0x72, 0xed, 0x19, 0x29, 0xca, 0xf9, 0x2c, 0x28, 0x66, 0x4a, 0x43, 0xde, 0x85, 0x72, 0x14, 0xb5, 0xeb, 0x11, 0xd3, 0x83, 0x5b, 0xfb, 0xf3, 0x13, 0x7c, 0xf1, 0x1a, 0x71, 0x85, 0xd9, @@ -3440,451 +3440,452 @@ var fileDescriptor_e0e705f843545fab = []byte{ 0xc3, 0xfe, 0x13, 0x8b, 0x6d, 0x43, 0xe2, 0xbb, 0x36, 0x69, 0xa7, 0xdb, 0x66, 0x4b, 0xe7, 0xe9, 0x2b, 0xc7, 0x51, 0x42, 0x39, 0xc6, 0x7c, 0xf6, 0x72, 0x25, 0xff, 0x20, 0x0d, 0xd9, 0xfe, 0xaf, 0x16, 0x9c, 0x4f, 0x23, 0x3f, 0x06, 0x85, 0x2e, 0x4c, 0x2a, 0x74, 0xb7, 0xf2, 0xfd, 0xda, 0x01, - 0x5a, 0xdd, 0x57, 0xc6, 0xfb, 0xbf, 0xf5, 0xff, 0x75, 0x1d, 0x21, 0xde, 0xf2, 0x0b, 0x3f, 0xce, + 0x5a, 0xdd, 0x57, 0xc7, 0xfb, 0xbf, 0xf5, 0xff, 0x75, 0x1d, 0x21, 0xde, 0xf2, 0x0b, 0x3f, 0xce, 0x2d, 0x7f, 0xfc, 0x83, 0xb4, 0xe5, 0xdb, 0xff, 0x70, 0x1c, 0xa6, 0xab, 0x5e, 0xe4, 0x56, 0xb7, - 0xb7, 0x5d, 0xcf, 0x8d, 0xf6, 0xc9, 0xd7, 0xc7, 0x60, 0xa9, 0x1b, 0xd0, 0x6d, 0x1a, 0x04, 0xb4, + 0xb7, 0x5d, 0xcf, 0x8d, 0xf6, 0xc9, 0x37, 0xc6, 0x60, 0xa9, 0x1b, 0xd0, 0x6d, 0x1a, 0x04, 0xb4, 0xb9, 0xd2, 0x0b, 0x5c, 0xaf, 0x55, 0x6f, 0xec, 0xd0, 0x66, 0xaf, 0xed, 0x7a, 0xad, 0xd5, 0x96, 0xe7, 0xeb, 0xe2, 0x6b, 0x0f, 0x68, 0xa3, 0xc7, 0x3f, 0x49, 0x4c, 0x8a, 0xce, 0x68, 0x9f, 0xb4, 0x71, 0x3c, 0xa6, 0xb5, 0x17, 0x0f, 0x0f, 0x2a, 0x4b, 0xc7, 0xac, 0x84, 0xc7, 0xfd, 0x34, 0xf2, - 0xd5, 0x31, 0x58, 0x0c, 0xe8, 0xe7, 0x7b, 0xee, 0xf0, 0xad, 0x21, 0x56, 0xad, 0xf6, 0x88, 0xbb, + 0xb5, 0x31, 0x58, 0x0c, 0xe8, 0xe7, 0x7b, 0xee, 0xf0, 0xad, 0x21, 0x56, 0xad, 0xf6, 0x88, 0xbb, 0xdb, 0xb1, 0x78, 0xd6, 0xae, 0x1e, 0x1e, 0x54, 0x8e, 0x59, 0x07, 0x8f, 0xf9, 0x5d, 0xf6, 0x06, 0x94, 0xab, 0x5d, 0x37, 0x74, 0x1f, 0xa0, 0xdf, 0x8b, 0xe8, 0x10, 0xe7, 0xf7, 0x0a, 0x14, 0x83, - 0x5e, 0x9b, 0x8a, 0xb9, 0x5d, 0xaa, 0x95, 0xd8, 0x2a, 0x84, 0xac, 0x00, 0x45, 0xb9, 0xfd, 0xf3, - 0x6c, 0xc5, 0xe5, 0x24, 0x53, 0x96, 0x9b, 0x7b, 0x50, 0x0c, 0x18, 0x13, 0x39, 0xb2, 0x46, 0x3d, - 0xe4, 0xc6, 0x52, 0x4b, 0x21, 0xd8, 0x4f, 0x14, 0x2c, 0xec, 0xdf, 0x1e, 0x83, 0x0b, 0xd5, 0x6e, - 0x77, 0x9d, 0x86, 0x3b, 0x29, 0x29, 0x7e, 0xc1, 0x82, 0x99, 0x3d, 0x37, 0x88, 0x7a, 0x4e, 0x5b, - 0x19, 0xe7, 0x84, 0x3c, 0xf5, 0x51, 0xe5, 0xe1, 0xdc, 0xde, 0x4a, 0x90, 0xae, 0x91, 0xc3, 0x83, - 0xca, 0x4c, 0xb2, 0x0c, 0x53, 0xec, 0xc9, 0xdf, 0xb6, 0x60, 0x4e, 0x16, 0xdd, 0xf2, 0x9b, 0xd4, - 0x34, 0xfe, 0xde, 0xc9, 0x53, 0x26, 0x4d, 0x5c, 0x18, 0xed, 0xd2, 0xa5, 0xd8, 0x27, 0x84, 0xfd, - 0xdf, 0xc7, 0xe0, 0xc9, 0x01, 0x34, 0xc8, 0xaf, 0x5a, 0x70, 0x5e, 0x58, 0x8c, 0x0d, 0x10, 0xd2, - 0x6d, 0xd9, 0x9a, 0x3f, 0x9d, 0xb7, 0xe4, 0xc8, 0xa6, 0x38, 0xf5, 0x1a, 0xb4, 0x36, 0xcf, 0x56, - 0xc3, 0xe5, 0x0c, 0xd6, 0x98, 0x29, 0x10, 0x97, 0x54, 0xd8, 0x90, 0x53, 0x92, 0x8e, 0x3d, 0x16, - 0x49, 0xeb, 0x19, 0xac, 0x31, 0x53, 0x20, 0xfb, 0xaf, 0xc2, 0xd3, 0x47, 0x90, 0x7b, 0xf4, 0xe4, - 0xb4, 0xdf, 0xd6, 0xa3, 0x3e, 0x39, 0xe6, 0x86, 0x98, 0xd7, 0x36, 0x4c, 0xf0, 0xa9, 0xa3, 0x26, - 0x36, 0xb0, 0xed, 0x8f, 0xcf, 0xa9, 0x10, 0x25, 0xc4, 0xfe, 0x6d, 0x0b, 0xa6, 0x8e, 0x61, 0xea, - 0xab, 0x24, 0x4d, 0x7d, 0xa5, 0x3e, 0x33, 0x5f, 0xd4, 0x6f, 0xe6, 0x7b, 0x7d, 0xb4, 0xde, 0x18, - 0xc6, 0xbc, 0xf7, 0x43, 0x0b, 0xce, 0xf6, 0x99, 0x03, 0xc9, 0x0e, 0x9c, 0xef, 0xfa, 0x4d, 0xa5, - 0x36, 0xdd, 0x70, 0xc2, 0x1d, 0x0e, 0x93, 0x9f, 0xf7, 0x12, 0xeb, 0xc9, 0x8d, 0x0c, 0xf8, 0xc3, - 0x83, 0xca, 0xbc, 0x26, 0x92, 0x42, 0xc0, 0x4c, 0x8a, 0xa4, 0x0b, 0x53, 0xdb, 0x2e, 0x6d, 0x37, - 0xe3, 0x21, 0x38, 0xa2, 0x82, 0x74, 0x5d, 0x52, 0x13, 0x96, 0x70, 0xf5, 0x0f, 0x35, 0x17, 0xfb, - 0x47, 0x16, 0xcc, 0x54, 0x7b, 0xd1, 0x0e, 0x53, 0x0f, 0x1a, 0xdc, 0xf8, 0x44, 0x3c, 0x28, 0x86, - 0x6e, 0x6b, 0xef, 0xa5, 0x7c, 0x16, 0xe3, 0x3a, 0x23, 0x25, 0x6f, 0x04, 0xb4, 0x6e, 0xca, 0x0b, - 0x51, 0xb0, 0x21, 0x01, 0x4c, 0xf8, 0x4e, 0x2f, 0xda, 0xb9, 0x2a, 0x3f, 0x79, 0xc4, 0x83, 0xf8, - 0x6d, 0xf6, 0x39, 0x57, 0x25, 0x47, 0xad, 0xad, 0x89, 0x52, 0x94, 0x9c, 0xec, 0x2f, 0xc2, 0x4c, - 0xf2, 0x9a, 0x69, 0x88, 0x31, 0x7b, 0x11, 0x0a, 0x4e, 0xe0, 0xc9, 0x11, 0x5b, 0x96, 0x08, 0x85, - 0x2a, 0xde, 0x42, 0x56, 0x4e, 0x5e, 0x80, 0xa9, 0xed, 0x5e, 0xbb, 0xcd, 0x2a, 0xc8, 0x3b, 0x1d, - 0x7d, 0x0a, 0xb8, 0x2e, 0xcb, 0x51, 0x63, 0xd8, 0xff, 0x7b, 0x1c, 0x66, 0x6b, 0xed, 0x1e, 0x7d, - 0x3d, 0xa0, 0x54, 0x99, 0x3e, 0xaa, 0x30, 0xdb, 0x0d, 0xe8, 0x9e, 0x4b, 0xef, 0xd7, 0x69, 0x9b, - 0x36, 0x22, 0x3f, 0x90, 0xd2, 0x3c, 0x29, 0x09, 0xcd, 0x6e, 0x24, 0xc1, 0x98, 0xc6, 0x27, 0xaf, - 0xc1, 0x8c, 0xd3, 0x88, 0xdc, 0x3d, 0xaa, 0x29, 0x08, 0x71, 0x9f, 0x90, 0x14, 0x66, 0xaa, 0x09, - 0x28, 0xa6, 0xb0, 0xc9, 0x67, 0x61, 0x3e, 0x6c, 0x38, 0x6d, 0x7a, 0xa7, 0x2b, 0x59, 0x2d, 0xef, - 0xd0, 0xc6, 0xee, 0x86, 0xef, 0x7a, 0x91, 0x34, 0xb3, 0x5d, 0x96, 0x94, 0xe6, 0xeb, 0x03, 0xf0, - 0x70, 0x20, 0x05, 0xf2, 0x2f, 0x2c, 0xb8, 0xd8, 0x0d, 0xe8, 0x46, 0xe0, 0x77, 0x7c, 0x36, 0xd4, - 0xfa, 0xac, 0x3f, 0xd2, 0x0a, 0xf2, 0xd6, 0x88, 0xba, 0x94, 0x28, 0xe9, 0xbf, 0xb2, 0xf8, 0xf0, - 0xe1, 0x41, 0xe5, 0xe2, 0xc6, 0x51, 0x02, 0xe0, 0xd1, 0xf2, 0x91, 0x7f, 0x69, 0xc1, 0xa5, 0xae, - 0x1f, 0x46, 0x47, 0x7c, 0x42, 0xf1, 0x54, 0x3f, 0xc1, 0x3e, 0x3c, 0xa8, 0x5c, 0xda, 0x38, 0x52, - 0x02, 0x7c, 0x84, 0x84, 0xf6, 0x61, 0x19, 0xce, 0x1a, 0x63, 0x4f, 0xda, 0x2e, 0x5e, 0x85, 0x33, - 0x6a, 0x30, 0xc4, 0xba, 0x4f, 0x29, 0x36, 0x65, 0x55, 0x4d, 0x20, 0x26, 0x71, 0xd9, 0xb8, 0xd3, - 0x43, 0x51, 0xd4, 0x4e, 0x8d, 0xbb, 0x8d, 0x04, 0x14, 0x53, 0xd8, 0x64, 0x15, 0xce, 0xc9, 0x12, - 0xa4, 0xdd, 0xb6, 0xdb, 0x70, 0x96, 0xfd, 0x9e, 0x1c, 0x72, 0xc5, 0xda, 0x93, 0x87, 0x07, 0x95, - 0x73, 0x1b, 0xfd, 0x60, 0xcc, 0xaa, 0x43, 0xd6, 0xe0, 0xbc, 0xd3, 0x8b, 0x7c, 0xfd, 0xfd, 0xd7, - 0x3c, 0xb6, 0x9d, 0x36, 0xf9, 0xd0, 0x9a, 0x12, 0xfb, 0x6e, 0x35, 0x03, 0x8e, 0x99, 0xb5, 0xc8, - 0x46, 0x8a, 0x5a, 0x9d, 0x36, 0x7c, 0xaf, 0x29, 0x7a, 0xb9, 0x18, 0x9f, 0xc0, 0xaa, 0x19, 0x38, - 0x98, 0x59, 0x93, 0xb4, 0x61, 0xa6, 0xe3, 0x3c, 0xb8, 0xe3, 0x39, 0x7b, 0x8e, 0xdb, 0x66, 0x4c, - 0xa4, 0x79, 0x6c, 0xb0, 0x51, 0xa5, 0x17, 0xb9, 0xed, 0x45, 0xe1, 0xb6, 0xb0, 0xb8, 0xea, 0x45, - 0xb7, 0x83, 0x7a, 0xc4, 0x34, 0x75, 0xa1, 0x41, 0xae, 0x27, 0x68, 0x61, 0x8a, 0x36, 0xb9, 0x0d, - 0x17, 0xf8, 0x74, 0x5c, 0xf1, 0xef, 0x7b, 0x2b, 0xb4, 0xed, 0xec, 0xab, 0x0f, 0x98, 0xe4, 0x1f, - 0xf0, 0xd4, 0xe1, 0x41, 0xe5, 0x42, 0x3d, 0x0b, 0x01, 0xb3, 0xeb, 0x11, 0x07, 0x9e, 0x4e, 0x02, - 0x90, 0xee, 0xb9, 0xa1, 0xeb, 0x7b, 0xc2, 0x0a, 0x35, 0x15, 0x5b, 0xa1, 0xea, 0x83, 0xd1, 0xf0, - 0x28, 0x1a, 0xe4, 0xef, 0x5a, 0x70, 0x3e, 0x6b, 0x1a, 0xce, 0x97, 0xf2, 0xb8, 0x3c, 0x4d, 0x4d, - 0x2d, 0x31, 0x22, 0x32, 0x17, 0x85, 0x4c, 0x21, 0xc8, 0x7b, 0x16, 0x4c, 0x3b, 0xc6, 0x09, 0x7a, - 0x1e, 0xf2, 0xd8, 0xb5, 0xcc, 0x33, 0x79, 0x6d, 0xee, 0xf0, 0xa0, 0x92, 0x38, 0xa5, 0x63, 0x82, - 0x23, 0xf9, 0xfb, 0x16, 0x5c, 0xc8, 0x9c, 0xe3, 0xf3, 0xe5, 0xd3, 0x68, 0x21, 0x3e, 0x48, 0xb2, - 0xd7, 0x9c, 0x6c, 0x31, 0xc8, 0x37, 0x2d, 0xbd, 0x95, 0xa9, 0xfb, 0xb4, 0xf9, 0x69, 0x2e, 0xda, - 0x9b, 0x23, 0x1a, 0x0d, 0x62, 0xad, 0x49, 0x11, 0xae, 0x9d, 0x33, 0x76, 0x46, 0x55, 0x88, 0x69, - 0xf6, 0xe4, 0x1b, 0x96, 0xda, 0x1a, 0xb5, 0x44, 0x67, 0x4e, 0x4b, 0x22, 0x12, 0xef, 0xb4, 0x5a, - 0xa0, 0x14, 0x73, 0xf2, 0x33, 0xb0, 0xe0, 0x6c, 0xf9, 0x41, 0x94, 0x39, 0xf9, 0xe6, 0x67, 0xf8, - 0x34, 0xba, 0x74, 0x78, 0x50, 0x59, 0xa8, 0x0e, 0xc4, 0xc2, 0x23, 0x28, 0xd8, 0xbf, 0x5e, 0x84, - 0x69, 0x71, 0x12, 0x92, 0x5b, 0xd7, 0x6f, 0x59, 0xf0, 0x4c, 0xa3, 0x17, 0x04, 0xd4, 0x8b, 0xea, - 0x11, 0xed, 0xf6, 0x6f, 0x5c, 0xd6, 0xa9, 0x6e, 0x5c, 0x97, 0x0f, 0x0f, 0x2a, 0xcf, 0x2c, 0x1f, - 0xc1, 0x1f, 0x8f, 0x94, 0x8e, 0xfc, 0x3b, 0x0b, 0x6c, 0x89, 0x50, 0x73, 0x1a, 0xbb, 0xad, 0xc0, - 0xef, 0x79, 0xcd, 0xfe, 0x8f, 0x18, 0x3b, 0xd5, 0x8f, 0x78, 0xee, 0xf0, 0xa0, 0x62, 0x2f, 0x3f, - 0x52, 0x0a, 0x1c, 0x42, 0x52, 0xf2, 0x3a, 0x9c, 0x95, 0x58, 0xd7, 0x1e, 0x74, 0x69, 0xe0, 0xb2, - 0x33, 0x87, 0x54, 0x1c, 0x63, 0x57, 0xac, 0x34, 0x02, 0xf6, 0xd7, 0x21, 0x21, 0x4c, 0xde, 0xa7, - 0x6e, 0x6b, 0x27, 0x52, 0xea, 0xd3, 0x88, 0xfe, 0x57, 0xd2, 0x2a, 0x72, 0x57, 0xd0, 0xac, 0x95, - 0x0f, 0x0f, 0x2a, 0x93, 0xf2, 0x0f, 0x2a, 0x4e, 0xe4, 0x16, 0xcc, 0x88, 0x73, 0xea, 0x86, 0xeb, - 0xb5, 0x36, 0x7c, 0x4f, 0x38, 0x11, 0x95, 0x6a, 0xcf, 0xa9, 0x0d, 0xbf, 0x9e, 0x80, 0x3e, 0x3c, - 0xa8, 0x4c, 0xab, 0xdf, 0x9b, 0xfb, 0x5d, 0x8a, 0xa9, 0xda, 0xf6, 0xef, 0x4e, 0x00, 0xa8, 0xe1, - 0x4a, 0xbb, 0xe4, 0x23, 0x50, 0x0a, 0x69, 0x24, 0xb8, 0xca, 0x8b, 0x13, 0x71, 0xdd, 0xa5, 0x0a, - 0x31, 0x86, 0x93, 0x5d, 0x28, 0x76, 0x9d, 0x5e, 0x48, 0xf3, 0x39, 0x3f, 0xc8, 0xce, 0xdf, 0x60, - 0x14, 0xc5, 0xc1, 0x94, 0xff, 0x44, 0xc1, 0x83, 0x7c, 0xd9, 0x02, 0xa0, 0xc9, 0x0e, 0x1b, 0xd9, - 0x40, 0x24, 0x59, 0xc6, 0x7d, 0xca, 0xda, 0xa0, 0x36, 0x73, 0x78, 0x50, 0x01, 0xa3, 0xeb, 0x0d, - 0xb6, 0xe4, 0x3e, 0x4c, 0x39, 0x6a, 0xcd, 0x1f, 0x3f, 0x8d, 0x35, 0x9f, 0x9f, 0x17, 0xf5, 0xa0, - 0xd5, 0xcc, 0xc8, 0x57, 0x2d, 0x98, 0x09, 0x69, 0x24, 0xbb, 0x8a, 0xad, 0x3c, 0x52, 0xe1, 0x1d, - 0x71, 0xd0, 0xd5, 0x13, 0x34, 0xc5, 0x0a, 0x9a, 0x2c, 0xc3, 0x14, 0x5f, 0x25, 0xca, 0x0d, 0xea, - 0x34, 0x69, 0xc0, 0xcd, 0x11, 0x52, 0x93, 0x1a, 0x5d, 0x14, 0x83, 0xa6, 0x16, 0xc5, 0x28, 0xc3, - 0x14, 0x5f, 0x25, 0xca, 0xba, 0x1b, 0x04, 0xbe, 0x14, 0x65, 0x2a, 0x27, 0x51, 0x0c, 0x9a, 0x5a, - 0x14, 0xa3, 0x0c, 0x53, 0x7c, 0xed, 0x6f, 0x9f, 0x81, 0x19, 0x35, 0x91, 0x62, 0xcd, 0x5e, 0x58, - 0xbf, 0x06, 0x68, 0xf6, 0xcb, 0x26, 0x10, 0x93, 0xb8, 0xac, 0xb2, 0x98, 0xaa, 0x49, 0xc5, 0x5e, - 0x57, 0xae, 0x9b, 0x40, 0x4c, 0xe2, 0x92, 0x0e, 0x14, 0xc3, 0x88, 0x76, 0xd5, 0x15, 0xfb, 0x88, - 0x37, 0xc0, 0xf1, 0xfa, 0x60, 0x58, 0x12, 0x18, 0x79, 0x14, 0x5c, 0xb8, 0x01, 0x37, 0x4a, 0xd8, - 0x74, 0xe5, 0xe4, 0xc8, 0x67, 0x7e, 0x26, 0xcd, 0xc5, 0xa2, 0x37, 0x92, 0x65, 0x98, 0x62, 0x9f, - 0xa1, 0xec, 0x17, 0x4f, 0x51, 0xd9, 0xff, 0x34, 0x4c, 0x75, 0x9c, 0x07, 0xf5, 0x5e, 0xd0, 0x3a, - 0xf9, 0xa1, 0x42, 0xba, 0x4c, 0x0a, 0x2a, 0xa8, 0xe9, 0x91, 0x2f, 0x59, 0xc6, 0x92, 0x23, 0xee, - 0xd3, 0xef, 0xe6, 0xbb, 0xe4, 0xe8, 0xbd, 0x72, 0xe0, 0xe2, 0xd3, 0xa7, 0x7a, 0x4f, 0x3d, 0x76, - 0xd5, 0x9b, 0xa9, 0x91, 0x62, 0x82, 0x68, 0x35, 0xb2, 0x74, 0xaa, 0x6a, 0xe4, 0x72, 0x82, 0x19, - 0xa6, 0x98, 0x73, 0x79, 0xc4, 0x9c, 0xd3, 0xf2, 0xc0, 0xa9, 0xca, 0x53, 0x4f, 0x30, 0xc3, 0x14, - 0xf3, 0xc1, 0xe7, 0xcd, 0xf2, 0xe9, 0x9c, 0x37, 0xa7, 0x73, 0x38, 0x6f, 0x1e, 0xad, 0x8a, 0x9f, - 0x19, 0x55, 0x15, 0x27, 0x37, 0x81, 0x34, 0xf7, 0x3d, 0xa7, 0xe3, 0x36, 0xe4, 0x62, 0xc9, 0xb7, - 0xcd, 0x19, 0x6e, 0x8f, 0x58, 0x90, 0x0b, 0x19, 0x59, 0xe9, 0xc3, 0xc0, 0x8c, 0x5a, 0x24, 0x82, - 0xa9, 0xae, 0xd2, 0xb8, 0x66, 0xf3, 0x18, 0xfd, 0x4a, 0x03, 0x13, 0x6e, 0x12, 0x6c, 0xe2, 0xa9, - 0x12, 0xd4, 0x9c, 0xc8, 0x1a, 0x9c, 0xef, 0xb8, 0xde, 0x86, 0xdf, 0x0c, 0x37, 0x68, 0x20, 0xad, - 0x2d, 0x75, 0x1a, 0xcd, 0xcf, 0xf1, 0xb6, 0xe1, 0x27, 0xe8, 0xf5, 0x0c, 0x38, 0x66, 0xd6, 0xb2, - 0xff, 0x97, 0x05, 0x73, 0xcb, 0x6d, 0xbf, 0xd7, 0xbc, 0xeb, 0x44, 0x8d, 0x1d, 0xe1, 0x21, 0x40, - 0x5e, 0x83, 0x29, 0xd7, 0x8b, 0x68, 0xb0, 0xe7, 0xb4, 0xe5, 0xfe, 0x64, 0x2b, 0xf3, 0xe9, 0xaa, - 0x2c, 0x7f, 0x78, 0x50, 0x99, 0x59, 0xe9, 0x05, 0xdc, 0x4a, 0x2d, 0x56, 0x2b, 0xd4, 0x75, 0xc8, - 0xb7, 0x2d, 0x38, 0x2b, 0x7c, 0x0c, 0x56, 0x9c, 0xc8, 0x79, 0xb3, 0x47, 0x03, 0x97, 0x2a, 0x2f, - 0x83, 0x11, 0x17, 0xaa, 0xb4, 0xac, 0x8a, 0xc1, 0x7e, 0xac, 0xa8, 0xaf, 0xa7, 0x39, 0x63, 0xbf, - 0x30, 0xf6, 0x2f, 0x16, 0xe0, 0xa9, 0x81, 0xb4, 0xc8, 0x02, 0x8c, 0xb9, 0x4d, 0xf9, 0xe9, 0x20, - 0xe9, 0x8e, 0xad, 0x36, 0x71, 0xcc, 0x6d, 0x92, 0x45, 0xae, 0x73, 0x06, 0x34, 0x0c, 0xd5, 0x85, - 0x73, 0x49, 0xab, 0x87, 0xb2, 0x14, 0x0d, 0x0c, 0x52, 0x81, 0x22, 0x77, 0x97, 0x95, 0xe7, 0x09, - 0xae, 0xc5, 0x72, 0xcf, 0x54, 0x14, 0xe5, 0xe4, 0xe7, 0x2d, 0x00, 0x21, 0x20, 0x3b, 0x8d, 0xc8, - 0x5d, 0x12, 0xf3, 0x6d, 0x26, 0x46, 0x59, 0x48, 0x19, 0xff, 0x47, 0x83, 0x2b, 0xd9, 0x84, 0x09, - 0xa6, 0xd0, 0xfa, 0xcd, 0x13, 0x6f, 0x8a, 0xfc, 0x26, 0x6a, 0x83, 0xd3, 0x40, 0x49, 0x8b, 0xb5, - 0x55, 0x40, 0xa3, 0x5e, 0xe0, 0xb1, 0xa6, 0xe5, 0xdb, 0xe0, 0x94, 0x90, 0x02, 0x75, 0x29, 0x1a, - 0x18, 0xf6, 0x3f, 0x1b, 0x83, 0xf3, 0x59, 0xa2, 0xb3, 0xdd, 0x66, 0x42, 0x48, 0x2b, 0x8f, 0xc6, - 0x3f, 0x95, 0x7f, 0xfb, 0x48, 0x77, 0x19, 0x7d, 0x4d, 0x21, 0xfd, 0x05, 0x25, 0x5f, 0xf2, 0x53, - 0xba, 0x85, 0xc6, 0x4e, 0xd8, 0x42, 0x9a, 0x72, 0xaa, 0x95, 0x2e, 0xc3, 0x78, 0xc8, 0x7a, 0xbe, - 0x90, 0xbc, 0xee, 0xe0, 0x7d, 0xc4, 0x21, 0x0c, 0xa3, 0xe7, 0xb9, 0x91, 0x8c, 0x31, 0xd1, 0x18, - 0x77, 0x3c, 0x37, 0x42, 0x0e, 0xb1, 0xbf, 0x35, 0x06, 0x0b, 0x83, 0x3f, 0x8a, 0x7c, 0xcb, 0x02, - 0x68, 0xb2, 0xe3, 0x4a, 0xc8, 0x1d, 0xb5, 0x85, 0x7b, 0x91, 0x73, 0x5a, 0x6d, 0xb8, 0xa2, 0x38, - 0xc5, 0xbe, 0x66, 0xba, 0x28, 0x44, 0x43, 0x10, 0x72, 0x55, 0x0d, 0x7d, 0x7e, 0x55, 0x23, 0x26, - 0x93, 0xae, 0xb3, 0xae, 0x21, 0x68, 0x60, 0xb1, 0xf3, 0xa8, 0xe7, 0x74, 0x68, 0xd8, 0x75, 0x74, - 0xc4, 0x0e, 0x3f, 0x8f, 0xde, 0x52, 0x85, 0x18, 0xc3, 0xed, 0x36, 0x3c, 0x3b, 0x84, 0x9c, 0x39, - 0x05, 0x44, 0xd8, 0xff, 0xc3, 0x82, 0x27, 0x97, 0xdb, 0xbd, 0x30, 0xa2, 0xc1, 0xff, 0x37, 0xae, - 0x7b, 0x7f, 0x6a, 0xc1, 0xd3, 0x03, 0xbe, 0xf9, 0x31, 0x78, 0xf0, 0xbd, 0x93, 0xf4, 0xe0, 0xbb, - 0x33, 0xea, 0x90, 0xce, 0xfc, 0x8e, 0x01, 0x8e, 0x7c, 0xff, 0xa6, 0x00, 0x67, 0xd8, 0xb2, 0xd5, - 0xf4, 0x5b, 0x39, 0x6d, 0x9c, 0xcf, 0x42, 0xf1, 0xf3, 0x6c, 0x03, 0x4a, 0x0f, 0x32, 0xbe, 0x2b, - 0xa1, 0x80, 0x91, 0x2f, 0x5b, 0x30, 0xf9, 0x79, 0xb9, 0xa7, 0x8a, 0xb3, 0xdc, 0x88, 0x8b, 0x61, - 0xe2, 0x1b, 0x16, 0xe5, 0x0e, 0x29, 0xe2, 0x2c, 0xb4, 0xef, 0xa0, 0xda, 0x4a, 0x15, 0x67, 0xf2, - 0x3c, 0x4c, 0x6e, 0xfb, 0x41, 0xa7, 0xd7, 0x76, 0xd2, 0xc1, 0x7d, 0xd7, 0x45, 0x31, 0x2a, 0x38, - 0x9b, 0xe4, 0x4e, 0xd7, 0x7d, 0x8b, 0x06, 0xa1, 0x70, 0xbb, 0x4f, 0x4c, 0xf2, 0xaa, 0x86, 0xa0, - 0x81, 0xc5, 0xeb, 0xb4, 0x5a, 0x01, 0x6d, 0x39, 0x91, 0x1f, 0xf0, 0x9d, 0xc3, 0xac, 0xa3, 0x21, - 0x68, 0x60, 0x2d, 0x7c, 0x12, 0xa6, 0x4d, 0xe1, 0x8f, 0x15, 0xb3, 0xf1, 0x29, 0x90, 0x4e, 0x84, - 0xa9, 0x25, 0xc9, 0x1a, 0x66, 0x49, 0xb2, 0xff, 0xc3, 0x18, 0x18, 0xd6, 0xa1, 0xc7, 0x30, 0xd5, - 0xbd, 0xc4, 0x54, 0x1f, 0xd1, 0xb2, 0x61, 0xd8, 0xba, 0x06, 0x45, 0xb0, 0xed, 0xa5, 0x22, 0xd8, - 0x6e, 0xe5, 0xc6, 0xf1, 0xe8, 0x00, 0xb6, 0xef, 0x5b, 0xf0, 0x74, 0x8c, 0xdc, 0x6f, 0xb8, 0x7d, - 0xf4, 0xba, 0xfd, 0x32, 0x94, 0x9d, 0xb8, 0x9a, 0x9c, 0x58, 0x46, 0xf8, 0x90, 0x06, 0xa1, 0x89, - 0x17, 0x87, 0x3e, 0x14, 0x4e, 0x18, 0xfa, 0x30, 0x7e, 0x74, 0xe8, 0x83, 0xfd, 0xa3, 0x31, 0xb8, - 0xd8, 0xff, 0x65, 0x6a, 0xc5, 0x19, 0xce, 0x0b, 0xe2, 0x15, 0x98, 0x8e, 0x64, 0x05, 0x63, 0xff, - 0xd4, 0xa1, 0xcc, 0x9b, 0x06, 0x0c, 0x13, 0x98, 0xac, 0x66, 0x43, 0xac, 0x75, 0xf5, 0x86, 0xdf, - 0x55, 0x61, 0x3b, 0xba, 0xe6, 0xb2, 0x01, 0xc3, 0x04, 0xa6, 0xf6, 0x19, 0x1e, 0x3f, 0x75, 0x9f, - 0xe1, 0x3a, 0x5c, 0x50, 0x5e, 0x92, 0xd7, 0xfd, 0x40, 0xfa, 0xff, 0xab, 0x15, 0x64, 0xaa, 0x76, - 0x51, 0x56, 0xb9, 0x80, 0x59, 0x48, 0x98, 0x5d, 0xd7, 0xfe, 0x7e, 0x01, 0xce, 0xc5, 0xcd, 0xbe, - 0xec, 0x7b, 0x4d, 0x97, 0x3b, 0xda, 0xbc, 0x0a, 0xe3, 0xd1, 0x7e, 0x57, 0x35, 0xf6, 0x5f, 0x54, - 0xe2, 0x6c, 0xee, 0x77, 0x59, 0x6f, 0x3f, 0x99, 0x51, 0x85, 0x9b, 0xce, 0x79, 0x25, 0xb2, 0xa6, - 0x67, 0x87, 0xe8, 0x81, 0x97, 0x92, 0xa3, 0xf9, 0xe1, 0x41, 0x25, 0x23, 0x92, 0x7f, 0x51, 0x53, - 0x4a, 0x8e, 0x79, 0x72, 0x0f, 0x66, 0xda, 0x4e, 0x18, 0xdd, 0xe9, 0x36, 0x9d, 0x88, 0x6e, 0xba, - 0xd2, 0x85, 0xe5, 0x78, 0x21, 0x13, 0xfa, 0xae, 0x7f, 0x2d, 0x41, 0x09, 0x53, 0x94, 0xc9, 0x1e, - 0x10, 0x56, 0xb2, 0x19, 0x38, 0x5e, 0x28, 0xbe, 0x8a, 0xf1, 0x3b, 0x7e, 0xfc, 0x8b, 0x3e, 0x3a, - 0xaf, 0xf5, 0x51, 0xc3, 0x0c, 0x0e, 0xe4, 0x39, 0x98, 0x08, 0xa8, 0x13, 0xea, 0xed, 0x40, 0xcf, - 0x7f, 0xe4, 0xa5, 0x28, 0xa1, 0xe6, 0x84, 0x9a, 0x78, 0xc4, 0x84, 0xfa, 0x43, 0x0b, 0x66, 0xe2, - 0x6e, 0x7a, 0x0c, 0xaa, 0x47, 0x27, 0xa9, 0x7a, 0xdc, 0xc8, 0x6b, 0x49, 0x1c, 0xa0, 0x6d, 0xfc, - 0xc9, 0xa4, 0xf9, 0x7d, 0x3c, 0x60, 0xe0, 0x0b, 0x50, 0x52, 0xb3, 0x5a, 0xe9, 0xf4, 0x23, 0x5a, - 0x20, 0x12, 0xda, 0x9e, 0x11, 0xc5, 0x27, 0x99, 0x60, 0xcc, 0x8f, 0xe9, 0x3a, 0x4d, 0xa9, 0xc7, - 0xc8, 0x61, 0xaf, 0x75, 0x1d, 0xa5, 0xdf, 0x64, 0xe9, 0x3a, 0xaa, 0x0e, 0xb9, 0x03, 0x4f, 0x76, - 0x03, 0x9f, 0xc7, 0x92, 0xaf, 0x50, 0xa7, 0xd9, 0x76, 0x3d, 0xaa, 0xcc, 0x3c, 0xc2, 0xd5, 0xe4, - 0xe9, 0xc3, 0x83, 0xca, 0x93, 0x1b, 0xd9, 0x28, 0x38, 0xa8, 0x6e, 0x32, 0x1a, 0x71, 0x7c, 0x88, - 0x68, 0xc4, 0xbf, 0xa1, 0x8d, 0xa9, 0x34, 0x94, 0x31, 0x81, 0x9f, 0xc9, 0xab, 0x2b, 0x33, 0x96, - 0xf5, 0x78, 0x48, 0x55, 0x25, 0x53, 0xd4, 0xec, 0x07, 0x5b, 0xec, 0x26, 0x4e, 0x68, 0xb1, 0x8b, - 0xe3, 0x2e, 0x26, 0x7f, 0x9c, 0x71, 0x17, 0x53, 0x1f, 0xa8, 0x50, 0xcb, 0x6f, 0x5b, 0x70, 0xce, - 0xe9, 0x8f, 0x32, 0xce, 0xc7, 0x78, 0x9c, 0x11, 0xbe, 0x5c, 0x7b, 0x5a, 0x0a, 0x99, 0x15, 0xcc, - 0x8d, 0x59, 0xa2, 0xd8, 0xef, 0x17, 0x61, 0x2e, 0xad, 0x24, 0x9d, 0x7e, 0x38, 0xe6, 0xdf, 0xb2, - 0x60, 0x4e, 0x4d, 0x70, 0xc1, 0x53, 0x1f, 0x31, 0xd6, 0x72, 0x5a, 0x57, 0x84, 0xba, 0xa7, 0xb3, - 0x64, 0x6c, 0xa6, 0xb8, 0x61, 0x1f, 0x7f, 0xf2, 0x36, 0x94, 0xf5, 0xad, 0xca, 0x89, 0x62, 0x33, - 0x79, 0xf8, 0x60, 0x35, 0x26, 0x81, 0x26, 0x3d, 0xf2, 0xbe, 0x05, 0xd0, 0x50, 0x3b, 0xb1, 0x5a, - 0x00, 0xde, 0xcc, 0x6b, 0x01, 0xd0, 0x7b, 0x7c, 0xac, 0xcf, 0xeb, 0xa2, 0x10, 0x0d, 0xc6, 0xe4, - 0x17, 0xf9, 0x7d, 0x8a, 0x1e, 0x09, 0x22, 0xfb, 0xc6, 0xc8, 0x6e, 0xef, 0x47, 0xe8, 0xce, 0xb1, - 0xb6, 0x67, 0x80, 0x42, 0x4c, 0x08, 0x61, 0xbf, 0x0a, 0xda, 0x51, 0x99, 0xad, 0xac, 0xdc, 0x55, - 0x79, 0xc3, 0x89, 0x76, 0xe4, 0x10, 0xd4, 0x2b, 0xeb, 0x75, 0x05, 0xc0, 0x18, 0xc7, 0xfe, 0x1c, - 0xcc, 0xbc, 0x1e, 0x38, 0xdd, 0x1d, 0x97, 0xdf, 0x5b, 0xb0, 0xf3, 0xf1, 0xf3, 0x30, 0xe9, 0x34, - 0x9b, 0x59, 0x09, 0x5d, 0xaa, 0xa2, 0x18, 0x15, 0x7c, 0xa8, 0xa3, 0xb0, 0xfd, 0xbb, 0x16, 0x90, - 0xf8, 0xee, 0xd7, 0xf5, 0x5a, 0xeb, 0x4e, 0xd4, 0xd8, 0x61, 0x47, 0xb8, 0x1d, 0x5e, 0x9a, 0x75, - 0x84, 0xbb, 0xa1, 0x21, 0x68, 0x60, 0x91, 0x77, 0xa1, 0x2c, 0xfe, 0xbd, 0xa5, 0x0f, 0x88, 0xa3, - 0xfb, 0x5b, 0xf3, 0x3d, 0x8f, 0xcb, 0x24, 0x46, 0xe1, 0x8d, 0x98, 0x03, 0x9a, 0xec, 0x58, 0x53, - 0xad, 0x7a, 0xdb, 0xed, 0xde, 0x83, 0xe6, 0x56, 0xdc, 0x54, 0xdd, 0xc0, 0xdf, 0x76, 0xdb, 0x34, - 0xdd, 0x54, 0x1b, 0xa2, 0x18, 0x15, 0x7c, 0xb8, 0xa6, 0xfa, 0x57, 0x16, 0x9c, 0x5f, 0x0d, 0x23, - 0xd7, 0x5f, 0xa1, 0x61, 0xc4, 0x76, 0x3e, 0xb6, 0x3e, 0xf6, 0xda, 0xc3, 0xc4, 0x1c, 0xac, 0xc0, - 0x9c, 0xbc, 0x87, 0xee, 0x6d, 0x85, 0x34, 0x32, 0x8e, 0x1a, 0x7a, 0x1e, 0x2f, 0xa7, 0xe0, 0xd8, - 0x57, 0x83, 0x51, 0x91, 0x17, 0xd2, 0x31, 0x95, 0x42, 0x92, 0x4a, 0x3d, 0x05, 0xc7, 0xbe, 0x1a, - 0xf6, 0xf7, 0x0a, 0x70, 0x8e, 0x7f, 0x46, 0x2a, 0x5e, 0xe8, 0x1b, 0x83, 0xe2, 0x85, 0x46, 0x9c, - 0xca, 0x9c, 0xd7, 0x09, 0xa2, 0x85, 0xfe, 0xa6, 0x05, 0xb3, 0xcd, 0x64, 0x4b, 0xe7, 0x63, 0x97, - 0xcb, 0xea, 0x43, 0xe1, 0x76, 0x97, 0x2a, 0xc4, 0x34, 0x7f, 0xf2, 0x4b, 0x16, 0xcc, 0x26, 0xc5, - 0x54, 0xab, 0xfb, 0x29, 0x34, 0x92, 0xf6, 0x93, 0x4f, 0x96, 0x87, 0x98, 0x16, 0xc1, 0xfe, 0xbd, - 0x31, 0xd9, 0xa5, 0xa7, 0x11, 0x0c, 0x43, 0xee, 0x43, 0x29, 0x6a, 0x87, 0xa2, 0x50, 0x7e, 0xed, - 0x88, 0x87, 0xd6, 0xcd, 0xb5, 0xba, 0x70, 0x01, 0x89, 0xf5, 0x4a, 0x59, 0xc2, 0xf4, 0x63, 0xc5, - 0x8b, 0x33, 0x6e, 0x74, 0x25, 0xe3, 0x5c, 0x4e, 0xcb, 0x9b, 0xcb, 0x1b, 0x69, 0xc6, 0xb2, 0x84, - 0x31, 0x56, 0xbc, 0xec, 0x5f, 0xb3, 0xa0, 0x74, 0xd3, 0x57, 0xeb, 0xc8, 0xcf, 0xe4, 0x60, 0x8b, - 0xd2, 0x2a, 0xab, 0x56, 0x5a, 0xe2, 0x53, 0xd0, 0x6b, 0x09, 0x4b, 0xd4, 0x33, 0x06, 0xed, 0x45, - 0x9e, 0xd7, 0x8e, 0x91, 0xba, 0xe9, 0x6f, 0x0d, 0x34, 0x1f, 0xff, 0x72, 0x11, 0xce, 0xbc, 0xe1, - 0xec, 0x53, 0x2f, 0x72, 0x8e, 0xbf, 0x49, 0xbc, 0x0c, 0x65, 0xa7, 0xcb, 0xef, 0x32, 0x8d, 0x63, - 0x48, 0x6c, 0xdc, 0x89, 0x41, 0x68, 0xe2, 0xc5, 0x0b, 0x9a, 0x88, 0x4c, 0xc9, 0x5a, 0x8a, 0x96, - 0x53, 0x70, 0xec, 0xab, 0x41, 0x6e, 0x02, 0x91, 0x81, 0xd4, 0xd5, 0x46, 0xc3, 0xef, 0x79, 0x62, - 0x49, 0x13, 0x76, 0x1f, 0x7d, 0x1e, 0x5e, 0xef, 0xc3, 0xc0, 0x8c, 0x5a, 0xe4, 0xb3, 0x30, 0xdf, - 0xe0, 0x94, 0xe5, 0xe9, 0xc8, 0xa4, 0x28, 0x4e, 0xc8, 0x3a, 0xd6, 0x63, 0x79, 0x00, 0x1e, 0x0e, - 0xa4, 0xc0, 0x24, 0x0d, 0x23, 0x3f, 0x70, 0x5a, 0xd4, 0xa4, 0x3b, 0x91, 0x94, 0xb4, 0xde, 0x87, - 0x81, 0x19, 0xb5, 0xc8, 0x17, 0xa1, 0x14, 0xed, 0x04, 0x34, 0xdc, 0xf1, 0xdb, 0x4d, 0xe9, 0x7b, - 0x32, 0xa2, 0x31, 0x50, 0xf6, 0xfe, 0xa6, 0xa2, 0x6a, 0x0c, 0x6f, 0x55, 0x84, 0x31, 0x4f, 0x12, - 0xc0, 0x44, 0xd8, 0xf0, 0xbb, 0x34, 0x94, 0xa7, 0x8a, 0x9b, 0xb9, 0x70, 0xe7, 0xc6, 0x2d, 0xc3, - 0x0c, 0xc9, 0x39, 0xa0, 0xe4, 0x64, 0xff, 0xce, 0x18, 0x4c, 0x9b, 0x88, 0x43, 0xac, 0x4d, 0x5f, - 0xb6, 0x60, 0xba, 0xe1, 0x7b, 0x51, 0xe0, 0xb7, 0x85, 0x89, 0x2d, 0x1f, 0x8d, 0x82, 0x91, 0x5a, - 0xa1, 0x91, 0xe3, 0xb6, 0x0d, 0x6b, 0x9d, 0xc1, 0x06, 0x13, 0x4c, 0xc9, 0xd7, 0x2d, 0x98, 0x8d, - 0x5d, 0x15, 0x63, 0x5b, 0x5f, 0xae, 0x82, 0xe8, 0xa5, 0xfe, 0x5a, 0x92, 0x13, 0xa6, 0x59, 0xdb, - 0x5b, 0x30, 0x97, 0xee, 0x6d, 0xd6, 0x94, 0x5d, 0x47, 0xce, 0xf5, 0x42, 0xdc, 0x94, 0x1b, 0x4e, - 0x18, 0x22, 0x87, 0x90, 0x17, 0x60, 0xaa, 0xe3, 0x04, 0x2d, 0xd7, 0x73, 0xda, 0xbc, 0x15, 0x0b, - 0xc6, 0x82, 0x24, 0xcb, 0x51, 0x63, 0xd8, 0x1f, 0x83, 0xe9, 0x75, 0xc7, 0x6b, 0xd1, 0xa6, 0x5c, - 0x87, 0x1f, 0x1d, 0x8e, 0xf9, 0xc7, 0xe3, 0x50, 0x36, 0x8e, 0x8f, 0xa7, 0x7f, 0xce, 0x4a, 0x24, - 0x9b, 0x29, 0xe4, 0x98, 0x6c, 0xe6, 0xd3, 0x00, 0xdb, 0xae, 0xe7, 0x86, 0x3b, 0x27, 0x4c, 0x63, - 0xc3, 0xef, 0xe6, 0xaf, 0x6b, 0x0a, 0x68, 0x50, 0x8b, 0x2f, 0x40, 0x8b, 0x47, 0x64, 0x84, 0x7b, - 0xdf, 0x32, 0xb6, 0x9b, 0x89, 0x3c, 0x1c, 0x3e, 0x8c, 0x8e, 0x59, 0x54, 0xdb, 0x8f, 0xb8, 0x9b, - 0x3a, 0x6a, 0x57, 0xda, 0x84, 0xa9, 0x80, 0x86, 0xbd, 0x0e, 0x3d, 0x51, 0xc2, 0x19, 0xee, 0x7a, - 0x83, 0xb2, 0x3e, 0x6a, 0x4a, 0x0b, 0xaf, 0xc2, 0x99, 0x84, 0x08, 0xc7, 0xba, 0x61, 0xf2, 0x21, - 0xd3, 0x46, 0x71, 0x92, 0xfb, 0x26, 0xd6, 0x17, 0x6d, 0x23, 0xd1, 0x8c, 0xee, 0x0b, 0xe1, 0x60, - 0x25, 0x60, 0xf6, 0x8f, 0x26, 0x40, 0xfa, 0x30, 0x0c, 0xb1, 0x5c, 0x99, 0x37, 0x97, 0x63, 0x27, - 0xb8, 0xb9, 0xbc, 0x09, 0xd3, 0xae, 0xe7, 0x46, 0xae, 0xd3, 0xe6, 0xf6, 0x27, 0xb9, 0x9d, 0x2a, - 0x0f, 0xf4, 0xe9, 0x55, 0x03, 0x96, 0x41, 0x27, 0x51, 0x97, 0xbc, 0x09, 0x45, 0xbe, 0xdf, 0xc8, - 0x01, 0x7c, 0x7c, 0x47, 0x0b, 0xee, 0x63, 0x23, 0xc2, 0xd2, 0x04, 0x25, 0x7e, 0xf8, 0x10, 0x99, - 0x76, 0xf4, 0xf1, 0x5b, 0x8e, 0xe3, 0xf8, 0xf0, 0x91, 0x82, 0x63, 0x5f, 0x0d, 0x46, 0x65, 0xdb, - 0x71, 0xdb, 0xbd, 0x80, 0xc6, 0x54, 0x26, 0x92, 0x54, 0xae, 0xa7, 0xe0, 0xd8, 0x57, 0x83, 0x6c, - 0xc3, 0xb4, 0x2c, 0x13, 0x6e, 0x73, 0x93, 0x27, 0xfc, 0x4a, 0xee, 0x1e, 0x79, 0xdd, 0xa0, 0x84, - 0x09, 0xba, 0xa4, 0x07, 0x67, 0x5d, 0xaf, 0xe1, 0x7b, 0x8d, 0x76, 0x2f, 0x74, 0xf7, 0x68, 0x1c, - 0x13, 0x76, 0x12, 0x66, 0x17, 0x0e, 0x0f, 0x2a, 0x67, 0x57, 0xd3, 0xe4, 0xb0, 0x9f, 0x03, 0xf9, - 0x92, 0x05, 0x17, 0x1a, 0xbe, 0x17, 0xf2, 0xd4, 0x15, 0x7b, 0xf4, 0x5a, 0x10, 0xf8, 0x81, 0xe0, - 0x5d, 0x3a, 0x21, 0x6f, 0x6e, 0xf6, 0x5c, 0xce, 0x22, 0x89, 0xd9, 0x9c, 0xc8, 0x3b, 0x30, 0xd5, - 0x0d, 0xfc, 0x3d, 0xb7, 0x49, 0x03, 0xe9, 0x82, 0xb9, 0x96, 0x47, 0x2a, 0x9d, 0x0d, 0x49, 0x33, - 0x5e, 0x7a, 0x54, 0x09, 0x6a, 0x7e, 0xf6, 0xff, 0x29, 0xc3, 0x4c, 0x12, 0x9d, 0xfc, 0x1c, 0x40, - 0x37, 0xf0, 0x3b, 0x34, 0xda, 0xa1, 0x3a, 0xb6, 0xe7, 0xd6, 0xa8, 0x19, 0x5b, 0x14, 0x3d, 0xe5, - 0xb6, 0xc4, 0x96, 0x8b, 0xb8, 0x14, 0x0d, 0x8e, 0x24, 0x80, 0xc9, 0x5d, 0xb1, 0xed, 0x4a, 0x2d, - 0xe4, 0x8d, 0x5c, 0x74, 0x26, 0xc9, 0x99, 0x07, 0xa5, 0xc8, 0x22, 0x54, 0x8c, 0xc8, 0x16, 0x14, - 0xee, 0xd3, 0xad, 0x7c, 0xd2, 0x05, 0xdc, 0xa5, 0xf2, 0x34, 0x53, 0x9b, 0x3c, 0x3c, 0xa8, 0x14, - 0xee, 0xd2, 0x2d, 0x64, 0xc4, 0xd9, 0x77, 0x35, 0x85, 0xef, 0x82, 0x5c, 0x2a, 0xde, 0xc8, 0xd1, - 0x11, 0x42, 0x7c, 0x97, 0x2c, 0x42, 0xc5, 0x88, 0xbc, 0x03, 0xa5, 0xfb, 0xce, 0x1e, 0xdd, 0x0e, - 0x7c, 0x2f, 0x92, 0xbe, 0x72, 0x23, 0x86, 0x7b, 0xdc, 0x55, 0xe4, 0x24, 0x5f, 0xbe, 0xbd, 0xeb, - 0x42, 0x8c, 0xd9, 0x91, 0x3d, 0x98, 0xf2, 0xe8, 0x7d, 0xa4, 0x6d, 0xb7, 0x91, 0x4f, 0x78, 0xc5, - 0x2d, 0x49, 0x4d, 0x72, 0xe6, 0xfb, 0x9e, 0x2a, 0x43, 0xcd, 0x8b, 0xf5, 0xe5, 0x3d, 0x7f, 0x4b, - 0x2e, 0x54, 0x23, 0xf6, 0xa5, 0x3e, 0x99, 0x8a, 0xbe, 0xbc, 0xe9, 0x6f, 0x21, 0x23, 0xce, 0xe6, - 0x48, 0x43, 0x3b, 0x6a, 0xc9, 0x65, 0xea, 0x56, 0xbe, 0x0e, 0x6a, 0x62, 0x8e, 0xc4, 0xa5, 0x68, - 0x70, 0x64, 0x6d, 0xdb, 0x92, 0xc6, 0x4a, 0xb9, 0x50, 0x8d, 0xd8, 0xb6, 0x49, 0xd3, 0xa7, 0x68, - 0x5b, 0x55, 0x86, 0x9a, 0x17, 0xe3, 0xeb, 0x4a, 0xcb, 0x5f, 0x3e, 0x4b, 0x55, 0xd2, 0x8e, 0x28, - 0xf8, 0xaa, 0x32, 0xd4, 0xbc, 0x58, 0x7b, 0x87, 0xbb, 0xfb, 0xf7, 0x9d, 0xf6, 0xae, 0xeb, 0xb5, - 0x64, 0xac, 0xea, 0xa8, 0x59, 0xa7, 0x77, 0xf7, 0xef, 0x0a, 0x7a, 0x66, 0x7b, 0xc7, 0xa5, 0x68, - 0x70, 0x24, 0x7f, 0xcf, 0x82, 0x89, 0x6e, 0xbb, 0xd7, 0x72, 0xbd, 0xf9, 0xe9, 0x3c, 0x9c, 0x98, - 0x92, 0x4b, 0xee, 0xe2, 0x06, 0x27, 0x2d, 0x14, 0xc5, 0x9f, 0xd4, 0x7e, 0x97, 0xbc, 0xf0, 0x6b, - 0x7f, 0x54, 0x99, 0xa7, 0x5e, 0xc3, 0x6f, 0xba, 0x5e, 0x6b, 0xe9, 0x5e, 0xe8, 0x7b, 0x8b, 0xe8, - 0xdc, 0x57, 0x3a, 0xba, 0x94, 0x69, 0xe1, 0x13, 0x50, 0x36, 0x48, 0x3c, 0x4a, 0xd1, 0x9b, 0x36, - 0x15, 0xbd, 0x5f, 0x9b, 0x80, 0x69, 0x33, 0xd7, 0xe4, 0x10, 0xda, 0x97, 0x3e, 0x71, 0x8c, 0x1d, - 0xe7, 0xc4, 0xc1, 0x8e, 0x98, 0xc6, 0x05, 0x97, 0x32, 0x6f, 0xad, 0xe6, 0xa6, 0x70, 0xc7, 0x47, - 0x4c, 0xa3, 0x30, 0xc4, 0x04, 0xd3, 0x63, 0xf8, 0xbc, 0x30, 0xb5, 0x55, 0x28, 0x76, 0xc5, 0xa4, - 0xda, 0x9a, 0x50, 0xd5, 0xae, 0x02, 0xc4, 0x49, 0x11, 0xe5, 0xc5, 0xa7, 0xd6, 0x87, 0x8d, 0x64, - 0x8d, 0x06, 0x16, 0x79, 0x0e, 0x26, 0x98, 0xea, 0x43, 0x9b, 0x32, 0x94, 0x5e, 0x9f, 0xe3, 0xaf, - 0xf3, 0x52, 0x94, 0x50, 0xf2, 0x0a, 0xd3, 0x52, 0x63, 0x85, 0x45, 0x46, 0xc8, 0x9f, 0x8f, 0xb5, - 0xd4, 0x18, 0x86, 0x09, 0x4c, 0x26, 0x3a, 0x65, 0xfa, 0x05, 0x5f, 0x1b, 0x0c, 0xd1, 0xb9, 0xd2, - 0x81, 0x02, 0xc6, 0xed, 0x4a, 0x29, 0x7d, 0x84, 0xcf, 0xe9, 0xa2, 0x61, 0x57, 0x4a, 0xc1, 0xb1, - 0xaf, 0x06, 0xfb, 0x18, 0x79, 0x67, 0x5b, 0x16, 0x0e, 0xd3, 0x03, 0x6e, 0x5b, 0xbf, 0x62, 0x9e, - 0xb5, 0x72, 0x9c, 0x43, 0x62, 0xd4, 0x0e, 0x7f, 0xd8, 0x1a, 0xed, 0x58, 0xf4, 0x39, 0x98, 0x49, - 0xee, 0x42, 0xb9, 0xdf, 0x7c, 0x7c, 0x75, 0x1c, 0xce, 0xdd, 0x6a, 0xb9, 0x5e, 0x3a, 0xd1, 0x59, - 0x56, 0x12, 0x7f, 0xeb, 0xd8, 0x49, 0xfc, 0x75, 0x4c, 0x9e, 0x4c, 0x91, 0x9f, 0x1d, 0x93, 0xa7, - 0xde, 0x2b, 0x48, 0xe2, 0x92, 0x3f, 0xb4, 0xe0, 0x19, 0xa7, 0x29, 0xce, 0x05, 0x4e, 0x5b, 0x96, - 0x1a, 0xb9, 0xa7, 0xe5, 0x8c, 0x0e, 0x47, 0xdc, 0xe5, 0xfb, 0x3f, 0x7e, 0xb1, 0x7a, 0x04, 0x57, - 0xd1, 0xe3, 0x3f, 0x21, 0xbf, 0xe0, 0x99, 0xa3, 0x50, 0xf1, 0x48, 0xf1, 0xc9, 0x5f, 0x81, 0xd9, - 0xc4, 0x07, 0x4b, 0x4b, 0x78, 0x49, 0x5c, 0x58, 0xd4, 0x93, 0x20, 0x4c, 0xe3, 0x2e, 0xdc, 0x86, - 0x0f, 0x3f, 0x52, 0xce, 0x63, 0x0d, 0xb6, 0xef, 0x5a, 0x30, 0x6d, 0xe6, 0x24, 0x22, 0x2f, 0xc0, - 0x54, 0xe4, 0xef, 0x52, 0xef, 0x4e, 0xa0, 0x1c, 0x76, 0xf5, 0x40, 0xdf, 0xe4, 0xe5, 0xb8, 0x86, - 0x1a, 0x83, 0x61, 0x37, 0xda, 0x2e, 0xf5, 0xa2, 0xd5, 0xa6, 0xec, 0x66, 0x8d, 0xbd, 0x2c, 0xca, - 0x57, 0x50, 0x63, 0x08, 0x1f, 0x3b, 0xf6, 0xbb, 0x4e, 0x1b, 0x01, 0x55, 0xee, 0xfd, 0x86, 0x8f, - 0x5d, 0x0c, 0xc3, 0x04, 0x26, 0xb1, 0xb5, 0x89, 0x73, 0x3c, 0xbe, 0xd7, 0x48, 0x99, 0x24, 0x7f, - 0xd3, 0x82, 0x92, 0x30, 0xd1, 0x23, 0xdd, 0x4e, 0xb9, 0xd8, 0xa6, 0x8c, 0x08, 0xd5, 0x8d, 0xd5, - 0x2c, 0x17, 0xdb, 0xcb, 0x30, 0xbe, 0xeb, 0x7a, 0xea, 0x4b, 0xf4, 0xb6, 0xf4, 0x86, 0xeb, 0x35, - 0x91, 0x43, 0xf4, 0xc6, 0x55, 0x18, 0xb8, 0x71, 0x2d, 0x41, 0x49, 0x3b, 0x9e, 0xc8, 0xe5, 0x5f, - 0x5b, 0x6f, 0xb5, 0xa3, 0x0a, 0xc6, 0x38, 0xf6, 0xaf, 0x58, 0x30, 0xc3, 0x63, 0xb8, 0xe3, 0xf3, - 0xf0, 0xcb, 0xda, 0x17, 0x4c, 0xc8, 0x7d, 0x31, 0xe9, 0x0b, 0xf6, 0xf0, 0xa0, 0x52, 0x16, 0x51, - 0xdf, 0x49, 0xd7, 0xb0, 0xcf, 0x48, 0x23, 0x1a, 0xf7, 0x58, 0x1b, 0x3b, 0xb6, 0x8d, 0x27, 0x16, - 0x53, 0x11, 0xc1, 0x98, 0x9e, 0xfd, 0x2e, 0x4c, 0x9b, 0xc1, 0x58, 0xe4, 0x65, 0x28, 0x77, 0x5d, - 0xaf, 0x95, 0x0c, 0xda, 0xd5, 0x17, 0x0d, 0x1b, 0x31, 0x08, 0x4d, 0x3c, 0x5e, 0xcd, 0x8f, 0xab, - 0xa5, 0xee, 0x27, 0x36, 0x7c, 0xb3, 0x5a, 0xfc, 0x87, 0xe7, 0xfd, 0xcf, 0x08, 0xfa, 0xcb, 0x3d, - 0xef, 0x7f, 0x06, 0x8f, 0x1f, 0x5f, 0xde, 0xff, 0x2c, 0x61, 0xfe, 0x6c, 0xe5, 0xfd, 0xff, 0x69, - 0x38, 0x6e, 0x4e, 0x54, 0xb6, 0xd7, 0xdf, 0x37, 0x13, 0x2b, 0xe8, 0x16, 0x97, 0x99, 0x15, 0x24, - 0xd4, 0xfe, 0x4e, 0x01, 0xe6, 0xd2, 0x47, 0xfe, 0xbc, 0xbd, 0x29, 0xc8, 0xd7, 0x2d, 0x98, 0x71, - 0x12, 0xf9, 0xe7, 0x72, 0x7a, 0x44, 0x28, 0x41, 0xd3, 0xc8, 0x7f, 0x96, 0x28, 0xc7, 0x14, 0x6f, - 0xf2, 0x17, 0x60, 0x32, 0x72, 0x3b, 0xd4, 0xef, 0x09, 0x43, 0x60, 0x41, 0x1c, 0xc8, 0x37, 0x45, - 0x11, 0x2a, 0x18, 0x5b, 0x94, 0x5d, 0xae, 0x41, 0x05, 0x54, 0x7a, 0x06, 0xcf, 0xc5, 0x96, 0x4b, - 0x51, 0x8e, 0x1a, 0x83, 0x3c, 0x80, 0x49, 0xe1, 0x77, 0xa1, 0x1c, 0x6c, 0xd6, 0x73, 0x32, 0x4d, - 0x08, 0xd7, 0x8e, 0xb8, 0x0b, 0xc4, 0xff, 0x10, 0x15, 0x3b, 0xfb, 0x63, 0x70, 0xcc, 0x24, 0xb1, - 0xf6, 0x35, 0x20, 0xe8, 0xb7, 0xdb, 0x5b, 0x4e, 0x63, 0xf7, 0xae, 0xeb, 0x35, 0xfd, 0xfb, 0x7c, - 0x29, 0x5a, 0x82, 0x52, 0x20, 0x43, 0x66, 0x43, 0x39, 0x6a, 0xf4, 0x5a, 0xa6, 0x62, 0x69, 0x43, - 0x8c, 0x71, 0xec, 0xdf, 0x1b, 0x83, 0x49, 0x19, 0xdf, 0xfd, 0x18, 0x22, 0x13, 0x76, 0x13, 0xf7, - 0xc1, 0xab, 0xb9, 0x84, 0xa5, 0x0f, 0x0c, 0x4b, 0x08, 0x53, 0x61, 0x09, 0x6f, 0xe4, 0xc3, 0xee, - 0xe8, 0x98, 0x84, 0x7f, 0x5d, 0x84, 0xd9, 0x54, 0xbc, 0x3c, 0xd3, 0xc5, 0xfb, 0x5c, 0x71, 0xef, - 0xe4, 0x1a, 0x92, 0xaf, 0x63, 0x91, 0x8e, 0xf6, 0xca, 0x0d, 0x13, 0x29, 0xbd, 0xf3, 0xf3, 0x65, - 0xfc, 0xf3, 0xec, 0xde, 0x79, 0x79, 0x99, 0x16, 0x3f, 0x38, 0x5e, 0xa6, 0xff, 0xc5, 0x82, 0xa7, - 0x06, 0x66, 0x7e, 0xe0, 0x89, 0xc3, 0x82, 0x24, 0x54, 0xae, 0x19, 0x39, 0xe7, 0xb7, 0xd1, 0xf7, - 0xc7, 0xe9, 0x5c, 0x4f, 0x69, 0xf6, 0xe4, 0x25, 0x98, 0xe6, 0x3a, 0x1a, 0x5b, 0x3d, 0x23, 0xda, - 0x95, 0xd7, 0x5f, 0xfc, 0x22, 0xa4, 0x6e, 0x94, 0x63, 0x02, 0xcb, 0xfe, 0xb6, 0x05, 0xf3, 0x83, - 0xd2, 0x48, 0x0d, 0x61, 0x9c, 0xf9, 0xcb, 0xa9, 0xe8, 0x8e, 0x4a, 0x5f, 0x74, 0x47, 0xca, 0x3c, - 0xa3, 0x02, 0x39, 0x0c, 0xcb, 0x48, 0xe1, 0x11, 0xc1, 0x0b, 0xdf, 0xb0, 0xe0, 0xc9, 0x01, 0x13, - 0xbe, 0x2f, 0xca, 0xc7, 0x3a, 0x71, 0x94, 0xcf, 0xd8, 0xb0, 0x51, 0x3e, 0xf6, 0xef, 0x17, 0x60, - 0x4e, 0xca, 0x13, 0x2b, 0xea, 0xaf, 0x24, 0x62, 0x64, 0x7e, 0x22, 0x15, 0x23, 0x73, 0x3e, 0x8d, - 0xff, 0xe7, 0x01, 0x32, 0x1f, 0xac, 0x00, 0x99, 0xaf, 0x15, 0xe1, 0x42, 0x66, 0x76, 0x2b, 0xf2, - 0xd5, 0x8c, 0xdd, 0xeb, 0x6e, 0xce, 0x69, 0xb4, 0x86, 0xdc, 0xbf, 0x46, 0x8d, 0x2a, 0xf9, 0x25, - 0x33, 0x9a, 0x43, 0xec, 0x46, 0xdb, 0xa7, 0x90, 0x10, 0xec, 0xb8, 0x81, 0x1d, 0x8f, 0xf7, 0xc9, - 0xab, 0x3f, 0x03, 0x5b, 0xcf, 0xd7, 0x0a, 0x70, 0x65, 0xd8, 0x96, 0xfd, 0x80, 0x46, 0x42, 0x86, - 0x89, 0x48, 0xc8, 0xc7, 0xa4, 0x6a, 0x9d, 0x4a, 0x50, 0xe4, 0x3f, 0x18, 0xd7, 0x7a, 0x40, 0xff, - 0x84, 0x1d, 0xca, 0x79, 0x64, 0x92, 0xa9, 0xe3, 0x2a, 0x53, 0x7a, 0xbc, 0x37, 0x4c, 0xd6, 0x45, - 0xf1, 0xc3, 0x83, 0xca, 0xd9, 0x38, 0xe9, 0x8c, 0x2c, 0x44, 0x55, 0x89, 0x5c, 0x81, 0xa9, 0x40, - 0x40, 0x55, 0xec, 0x97, 0xf4, 0xc0, 0x11, 0x65, 0xa8, 0xa1, 0xe4, 0x8b, 0xc6, 0xf9, 0x65, 0xfc, - 0xb4, 0x72, 0x2b, 0x1d, 0xe5, 0x58, 0xf4, 0x36, 0x4c, 0x85, 0x2a, 0x9d, 0xb7, 0x98, 0x4e, 0x2f, - 0x0e, 0x19, 0x52, 0xe8, 0x6c, 0xd1, 0xb6, 0xca, 0xed, 0x2d, 0xbe, 0x4f, 0x67, 0xfe, 0xd6, 0x24, - 0x89, 0xad, 0xed, 0x01, 0xe2, 0xe2, 0x03, 0xfa, 0x6d, 0x01, 0x24, 0x82, 0x49, 0xf9, 0x84, 0xad, - 0xbc, 0x91, 0x5d, 0xcf, 0x29, 0x36, 0x47, 0x7a, 0x6e, 0xf3, 0x63, 0xb6, 0xb2, 0x4b, 0x29, 0x56, - 0xf6, 0xf7, 0x2d, 0x28, 0xcb, 0x31, 0xf2, 0x18, 0x62, 0x2b, 0xef, 0x25, 0x63, 0x2b, 0xaf, 0xe5, - 0xb2, 0x84, 0x0f, 0x08, 0xac, 0xbc, 0x07, 0xd3, 0x66, 0x9e, 0x49, 0xf2, 0x69, 0x63, 0x0b, 0xb2, - 0x46, 0xc9, 0xdc, 0xa6, 0x36, 0xa9, 0x78, 0x7b, 0xb2, 0x7f, 0xbd, 0xa4, 0x5b, 0x91, 0x1f, 0xe6, - 0xcd, 0x91, 0x6f, 0x1d, 0x39, 0xf2, 0xcd, 0x81, 0x37, 0x96, 0xff, 0xc0, 0x7b, 0x13, 0xa6, 0xd4, - 0xb2, 0x28, 0xb5, 0xa9, 0x67, 0x4d, 0x57, 0x6e, 0xa6, 0x92, 0x31, 0x62, 0xc6, 0x74, 0xe1, 0x87, - 0xf2, 0xd8, 0x5a, 0xae, 0x96, 0x6b, 0x4d, 0x86, 0xbc, 0x03, 0xe5, 0xfb, 0x7e, 0xb0, 0xdb, 0xf6, - 0x1d, 0xfe, 0x86, 0x02, 0xe4, 0xe1, 0x3d, 0xa0, 0x2d, 0xde, 0x22, 0x9e, 0xe6, 0x6e, 0x4c, 0x1f, - 0x4d, 0x66, 0xa4, 0x0a, 0xb3, 0x1d, 0xd7, 0x43, 0xea, 0x34, 0x75, 0x08, 0xe5, 0xb8, 0xc8, 0x5f, - 0xae, 0xce, 0x1a, 0xeb, 0x49, 0x30, 0xa6, 0xf1, 0xb9, 0x35, 0x2c, 0x48, 0x98, 0x5f, 0x64, 0x92, - 0xe2, 0x8d, 0xd1, 0x07, 0x63, 0xd2, 0xa4, 0x23, 0x02, 0x4a, 0x92, 0xe5, 0x98, 0xe2, 0x4d, 0xbe, - 0x00, 0x53, 0xa1, 0x7a, 0x1c, 0xb2, 0x98, 0xe3, 0x29, 0x4c, 0x3f, 0x10, 0xa9, 0xbb, 0x52, 0xbf, - 0x10, 0xa9, 0x19, 0x92, 0x35, 0x38, 0xaf, 0xec, 0x49, 0x89, 0x77, 0xee, 0x26, 0xe2, 0x9c, 0x63, - 0x98, 0x01, 0xc7, 0xcc, 0x5a, 0x4c, 0xb7, 0xe5, 0xf9, 0x5b, 0xc5, 0x6d, 0xad, 0x71, 0xc1, 0xc9, - 0xe7, 0x5f, 0x13, 0x25, 0xf4, 0xa8, 0x08, 0xe1, 0xa9, 0x11, 0x22, 0x84, 0xeb, 0x70, 0x21, 0x0d, - 0xe2, 0xc9, 0xe4, 0x78, 0xfe, 0x3a, 0x63, 0x0b, 0xdd, 0xc8, 0x42, 0xc2, 0xec, 0xba, 0xe4, 0x2e, - 0x94, 0x02, 0xca, 0x4f, 0x9d, 0x55, 0xe5, 0xe8, 0x76, 0x6c, 0x97, 0x5e, 0x54, 0x04, 0x30, 0xa6, - 0xc5, 0xfa, 0xdd, 0x49, 0x66, 0x14, 0x7f, 0x33, 0xc7, 0xd7, 0xa3, 0x65, 0xdf, 0x0f, 0x48, 0xf2, - 0x68, 0xff, 0xdb, 0x59, 0x38, 0x93, 0x30, 0x8a, 0x91, 0x67, 0xa1, 0xc8, 0xb3, 0xeb, 0xf1, 0xd5, - 0x6a, 0x2a, 0x5e, 0x51, 0x45, 0xe3, 0x08, 0x18, 0xf9, 0x05, 0x0b, 0x66, 0xbb, 0x89, 0x4b, 0x1e, - 0xb5, 0x90, 0x8f, 0x68, 0x49, 0x4e, 0xde, 0x1c, 0x19, 0x6f, 0x71, 0x24, 0x99, 0x61, 0x9a, 0x3b, - 0x5b, 0x0f, 0xa4, 0x5f, 0x7c, 0x9b, 0x06, 0x1c, 0x5b, 0x2a, 0x7a, 0x9a, 0xc4, 0x72, 0x12, 0x8c, - 0x69, 0x7c, 0xd6, 0xc3, 0xfc, 0xeb, 0x46, 0x79, 0x21, 0xb4, 0xaa, 0x08, 0x60, 0x4c, 0x8b, 0xbc, - 0x06, 0x33, 0x32, 0x91, 0xf4, 0x86, 0xdf, 0xbc, 0xe1, 0x84, 0x3b, 0xf2, 0xc8, 0xa7, 0x8f, 0xa8, - 0xcb, 0x09, 0x28, 0xa6, 0xb0, 0xf9, 0xb7, 0xc5, 0xd9, 0xba, 0x39, 0x81, 0x89, 0xe4, 0x53, 0x25, - 0xcb, 0x49, 0x30, 0xa6, 0xf1, 0xc9, 0x0b, 0xc6, 0x36, 0x24, 0x3c, 0x28, 0xf4, 0x6a, 0x90, 0xb1, - 0x15, 0x55, 0x61, 0xb6, 0xc7, 0x4f, 0xc8, 0x4d, 0x05, 0x94, 0xf3, 0x51, 0x33, 0xbc, 0x93, 0x04, - 0x63, 0x1a, 0x9f, 0xbc, 0x0a, 0x67, 0x02, 0xb6, 0xd8, 0x6a, 0x02, 0xc2, 0xad, 0x42, 0xdf, 0x9a, - 0xa3, 0x09, 0xc4, 0x24, 0x2e, 0x79, 0x1d, 0xce, 0xc6, 0x79, 0x57, 0x15, 0x01, 0xe1, 0x67, 0xa1, - 0x93, 0x00, 0x56, 0xd3, 0x08, 0xd8, 0x5f, 0x87, 0xfc, 0x35, 0x98, 0x33, 0x5a, 0x62, 0xd5, 0x6b, - 0xd2, 0x07, 0x32, 0x37, 0x26, 0x7f, 0x7a, 0x6b, 0x39, 0x05, 0xc3, 0x3e, 0x6c, 0xf2, 0x49, 0x98, - 0x69, 0xf8, 0xed, 0x36, 0x5f, 0xe3, 0xc4, 0x33, 0x19, 0x22, 0x09, 0xa6, 0x48, 0x17, 0x9a, 0x80, - 0x60, 0x0a, 0x93, 0xdc, 0x04, 0xe2, 0x6f, 0x31, 0xf5, 0x8a, 0x36, 0x5f, 0xa7, 0x1e, 0x95, 0x1a, - 0xc7, 0x99, 0x64, 0x54, 0xce, 0xed, 0x3e, 0x0c, 0xcc, 0xa8, 0xc5, 0x73, 0x08, 0x1a, 0x51, 0xcc, - 0x33, 0x79, 0x3c, 0x67, 0x99, 0xb6, 0xe7, 0x3c, 0x32, 0x84, 0x39, 0x80, 0x09, 0x11, 0x24, 0x95, - 0x4f, 0x36, 0x4c, 0x33, 0x63, 0x7e, 0xbc, 0x47, 0x88, 0x52, 0x94, 0x9c, 0xc8, 0xcf, 0x41, 0x69, - 0x4b, 0x3d, 0x9f, 0xc2, 0x53, 0x60, 0x8e, 0xbc, 0x2f, 0xa6, 0x5e, 0x02, 0x8a, 0xed, 0x15, 0x1a, - 0x80, 0x31, 0x4b, 0xf2, 0x1c, 0x94, 0x6f, 0x6c, 0x54, 0xf5, 0x28, 0x3c, 0xcb, 0x7b, 0x7f, 0x9c, - 0x55, 0x41, 0x13, 0xc0, 0x66, 0x98, 0x56, 0xdf, 0x48, 0xd2, 0x75, 0x20, 0x43, 0x1b, 0x63, 0xd8, - 0xdc, 0x17, 0x02, 0xeb, 0xf3, 0xe7, 0x52, 0xd8, 0xb2, 0x1c, 0x35, 0x06, 0x79, 0x1b, 0xca, 0x72, - 0xbf, 0xe0, 0x6b, 0xd3, 0xf9, 0x93, 0x45, 0xc8, 0x63, 0x4c, 0x02, 0x4d, 0x7a, 0xfc, 0x12, 0x9b, - 0xbf, 0x2a, 0x41, 0xaf, 0xf7, 0xda, 0xed, 0xf9, 0x0b, 0x7c, 0xdd, 0x8c, 0x2f, 0xb1, 0x63, 0x10, - 0x9a, 0x78, 0xe4, 0x45, 0xe5, 0xd3, 0xf6, 0x44, 0xe2, 0x56, 0x5f, 0xfb, 0xb4, 0x69, 0xa5, 0x7b, - 0x40, 0x10, 0xcd, 0x93, 0x8f, 0x70, 0x26, 0xdb, 0x82, 0x05, 0xa5, 0xf1, 0xf5, 0x4f, 0x92, 0xf9, - 0xf9, 0x84, 0xed, 0x68, 0xe1, 0xee, 0x40, 0x4c, 0x3c, 0x82, 0x0a, 0xd9, 0x82, 0x82, 0xd3, 0xde, - 0x9a, 0x7f, 0x2a, 0x0f, 0xd5, 0xb5, 0xba, 0x56, 0x93, 0x23, 0x8a, 0x3b, 0xbe, 0x56, 0xd7, 0x6a, - 0xc8, 0x88, 0x13, 0x17, 0xc6, 0x9d, 0xf6, 0x56, 0x38, 0xbf, 0xc0, 0xe7, 0x6c, 0x6e, 0x4c, 0x62, - 0xe3, 0xc1, 0x5a, 0x2d, 0x44, 0xce, 0xc2, 0xfe, 0xd2, 0x98, 0xbe, 0xb9, 0xd2, 0x09, 0xc9, 0xdf, - 0x35, 0x27, 0x90, 0x38, 0xee, 0xdc, 0xce, 0x6d, 0x02, 0x49, 0xf5, 0xe2, 0xcc, 0xc0, 0xe9, 0xd3, - 0xd5, 0x4b, 0x46, 0x2e, 0x99, 0xcc, 0x92, 0xc9, 0xd6, 0xc5, 0xe9, 0x39, 0xb9, 0x60, 0xd8, 0xdf, - 0x01, 0x6d, 0x05, 0x4d, 0xf9, 0x83, 0x05, 0x50, 0x74, 0xc3, 0xc8, 0xf5, 0x73, 0x0c, 0x1c, 0x4f, - 0x65, 0x29, 0xe7, 0x71, 0x29, 0x1c, 0x80, 0x82, 0x15, 0xe3, 0xe9, 0xb5, 0x5c, 0xef, 0x81, 0xfc, - 0xfc, 0x37, 0x73, 0x77, 0xf4, 0x12, 0x3c, 0x39, 0x00, 0x05, 0x2b, 0x72, 0x4f, 0x0c, 0xea, 0x42, - 0x1e, 0x7d, 0x5d, 0x5d, 0xab, 0xa5, 0xf8, 0x25, 0x07, 0xf7, 0x3d, 0x28, 0x84, 0x1d, 0x57, 0xaa, - 0x4b, 0x23, 0xf2, 0xaa, 0xaf, 0xaf, 0x66, 0xf1, 0xaa, 0xaf, 0xaf, 0x22, 0x63, 0x42, 0xbe, 0x62, - 0x01, 0x38, 0x9d, 0x2d, 0x27, 0x0c, 0x9d, 0xa6, 0xb6, 0xce, 0x8c, 0xf8, 0xfa, 0x48, 0x55, 0xd3, - 0x4b, 0xb1, 0xe6, 0xae, 0xcd, 0x31, 0x14, 0x0d, 0xce, 0xe4, 0x1d, 0x98, 0x74, 0xc4, 0xf3, 0x8e, - 0xd2, 0x4b, 0x3f, 0x9f, 0x37, 0x4b, 0x53, 0x12, 0x70, 0x33, 0x8d, 0x04, 0xa1, 0x62, 0xc8, 0x78, - 0x47, 0x81, 0x43, 0xb7, 0xdd, 0x5d, 0x69, 0x1c, 0xaa, 0x8f, 0xfc, 0x00, 0x09, 0x23, 0x96, 0xc5, - 0x5b, 0x82, 0x50, 0x31, 0x14, 0xaf, 0xf9, 0x3b, 0x9e, 0xa3, 0x63, 0x2f, 0xf3, 0x89, 0xd0, 0x35, - 0xa3, 0x39, 0x8d, 0xd7, 0xfc, 0x4d, 0x46, 0x98, 0xe4, 0x4b, 0xf6, 0x60, 0xc2, 0xe1, 0x0f, 0xcf, - 0xca, 0xa3, 0x18, 0xe6, 0xf1, 0x88, 0x6d, 0xaa, 0x0d, 0xf8, 0xe2, 0x22, 0x9f, 0xb7, 0x95, 0xdc, - 0xc8, 0xaf, 0x5a, 0x30, 0x29, 0x1c, 0xc8, 0x99, 0x42, 0xca, 0xbe, 0xfd, 0x73, 0xa7, 0xf0, 0xda, - 0x81, 0x74, 0x6e, 0x97, 0x2e, 0x51, 0x1f, 0xd1, 0xde, 0xb1, 0xa2, 0xf4, 0x48, 0xf7, 0x76, 0x25, - 0xdd, 0xc2, 0x27, 0x61, 0xda, 0xa4, 0x72, 0x2c, 0x07, 0xf7, 0x1f, 0x16, 0x00, 0x78, 0x43, 0x8b, - 0x6c, 0x2b, 0x1d, 0x9e, 0x9a, 0x79, 0xc7, 0x6f, 0xe6, 0xf4, 0x48, 0xa5, 0x91, 0x34, 0x05, 0x64, - 0x1e, 0xe6, 0x1d, 0xbf, 0x89, 0x92, 0x09, 0x69, 0xc1, 0x78, 0xd7, 0x89, 0x76, 0xf2, 0xcf, 0xd0, - 0x32, 0x25, 0xc2, 0x8e, 0xa3, 0x1d, 0xe4, 0x0c, 0xc8, 0x7b, 0x56, 0xec, 0x2b, 0x54, 0xc8, 0xc7, - 0xa3, 0x43, 0xb5, 0xd9, 0xa2, 0xf4, 0x0e, 0x4a, 0x25, 0x59, 0x4d, 0xfb, 0x0c, 0x2d, 0xbc, 0x6f, - 0xc1, 0xb4, 0x89, 0x9a, 0xd1, 0x4d, 0x3f, 0x6b, 0x76, 0x53, 0x9e, 0xed, 0x61, 0xf6, 0xf8, 0x7f, - 0xb3, 0x00, 0xb0, 0xe7, 0xd5, 0x7b, 0x9d, 0x0e, 0x53, 0xba, 0xb5, 0x1f, 0xbf, 0x35, 0xb4, 0x1f, - 0xff, 0xd8, 0x31, 0xfd, 0xf8, 0x0b, 0xc7, 0xf2, 0xe3, 0x1f, 0x3f, 0xbe, 0x1f, 0x7f, 0x71, 0xb0, - 0x1f, 0xbf, 0xfd, 0x4d, 0x0b, 0xce, 0xf6, 0xed, 0x36, 0x4c, 0x0f, 0x0e, 0x7c, 0x3f, 0x1a, 0xe0, - 0x03, 0x8a, 0x31, 0x08, 0x4d, 0x3c, 0xb2, 0x02, 0x73, 0xf2, 0x21, 0x92, 0x7a, 0xb7, 0xed, 0x66, - 0x66, 0xcf, 0xd9, 0x4c, 0xc1, 0xb1, 0xaf, 0x86, 0xfd, 0x1d, 0x0b, 0xca, 0x46, 0xcc, 0x3d, 0xfb, - 0x0e, 0xee, 0x08, 0x2c, 0xc5, 0x88, 0xdf, 0x60, 0xe1, 0x17, 0x55, 0x02, 0x26, 0x2e, 0x91, 0x5b, - 0x46, 0x9a, 0xfa, 0xf8, 0x12, 0x99, 0x95, 0xa2, 0x84, 0x8a, 0x04, 0xe4, 0xb4, 0xcb, 0x1b, 0xbd, - 0x60, 0x26, 0x20, 0xa7, 0x5d, 0xe4, 0x10, 0xce, 0x8e, 0x1d, 0x08, 0xa4, 0x8f, 0xaf, 0xf1, 0xe4, - 0x8b, 0x13, 0x44, 0x28, 0x60, 0xe4, 0x22, 0x14, 0xa8, 0xd7, 0x94, 0xd6, 0x0b, 0xfd, 0x28, 0xeb, - 0x35, 0xaf, 0x89, 0xac, 0xdc, 0xbe, 0x0d, 0xd3, 0xc2, 0xbf, 0xf9, 0x0d, 0xba, 0x3f, 0xf4, 0x2b, - 0xaf, 0x6c, 0xb4, 0xa7, 0x5e, 0x79, 0x65, 0xd5, 0x59, 0xb9, 0xfd, 0x8f, 0x2d, 0x48, 0xbd, 0x4b, - 0x64, 0xdc, 0x9f, 0x58, 0x03, 0xef, 0x4f, 0x4c, 0x9b, 0xfb, 0xd8, 0x91, 0x36, 0xf7, 0x9b, 0x40, - 0x3a, 0x6c, 0x2a, 0x24, 0x5e, 0xe1, 0x92, 0x86, 0xa3, 0x38, 0xc3, 0x47, 0x1f, 0x06, 0x66, 0xd4, - 0xb2, 0xff, 0x91, 0x10, 0xd6, 0x7c, 0xa9, 0xe8, 0xd1, 0x0d, 0xd0, 0x83, 0x22, 0x27, 0x25, 0xad, - 0x67, 0x23, 0x5a, 0x9e, 0xfb, 0x33, 0x65, 0xc5, 0x1d, 0x29, 0xa7, 0x3c, 0xe7, 0x66, 0xff, 0xbe, - 0x90, 0xd5, 0x78, 0xca, 0x68, 0x08, 0x59, 0x3b, 0x49, 0x59, 0x6f, 0xe4, 0xb5, 0x56, 0x66, 0xcb, - 0x48, 0x16, 0x01, 0xba, 0x34, 0x68, 0x50, 0x2f, 0x52, 0x91, 0x47, 0x45, 0x19, 0x03, 0xab, 0x4b, - 0xd1, 0xc0, 0xb0, 0xbf, 0xc1, 0x26, 0x50, 0xfc, 0xfe, 0x31, 0xb9, 0x92, 0x76, 0x9e, 0x4d, 0x4f, - 0x0e, 0xed, 0x3b, 0x6b, 0xc4, 0xa3, 0x8c, 0x3d, 0x22, 0x1e, 0xe5, 0x79, 0x98, 0x0c, 0xfc, 0x36, - 0xad, 0x06, 0x5e, 0xda, 0xe3, 0x07, 0x59, 0x31, 0xde, 0x42, 0x05, 0xb7, 0x7f, 0xd9, 0x82, 0xb9, - 0x74, 0xc0, 0x5c, 0xee, 0x1e, 0xbd, 0x66, 0x54, 0x7f, 0xe1, 0xf8, 0x51, 0xfd, 0xf6, 0x7b, 0x4c, - 0xc8, 0xc8, 0x6d, 0xec, 0xba, 0x9e, 0x08, 0x84, 0x67, 0x2d, 0xf7, 0x3c, 0x4c, 0x52, 0xf9, 0x8e, - 0xab, 0x30, 0x02, 0x6b, 0x21, 0xd5, 0xf3, 0xad, 0x0a, 0x4e, 0xaa, 0x30, 0xab, 0xae, 0xbe, 0x94, - 0xe5, 0x5e, 0x24, 0xf0, 0xd0, 0x96, 0xc2, 0x95, 0x24, 0x18, 0xd3, 0xf8, 0xf6, 0x17, 0xa1, 0x6c, - 0x6c, 0x4a, 0x7c, 0xfd, 0x7e, 0xe0, 0x34, 0xa2, 0xf4, 0xba, 0x77, 0x8d, 0x15, 0xa2, 0x80, 0xf1, - 0x0b, 0x06, 0x11, 0xcf, 0x93, 0x5a, 0xf7, 0x64, 0x14, 0x8f, 0x84, 0x32, 0x62, 0x01, 0x6d, 0xd1, - 0x07, 0xea, 0x15, 0x01, 0x45, 0x0c, 0x59, 0x21, 0x0a, 0x98, 0xfd, 0x02, 0x4c, 0xa9, 0x34, 0x4b, - 0x3c, 0x57, 0x89, 0x32, 0x7e, 0x9b, 0xb9, 0x4a, 0xfc, 0x20, 0x42, 0x0e, 0xb1, 0xdf, 0x82, 0x29, - 0x95, 0x0d, 0xea, 0xd1, 0xd8, 0x6c, 0x29, 0x0a, 0x3d, 0xf7, 0x86, 0x1f, 0x46, 0x2a, 0x85, 0x95, - 0xb8, 0x9f, 0xbb, 0xb5, 0xca, 0xcb, 0x50, 0x43, 0xed, 0x3f, 0xb5, 0xa0, 0xbc, 0xb9, 0xb9, 0xa6, - 0x8f, 0xed, 0x08, 0x4f, 0x84, 0xa2, 0x85, 0xaa, 0xdb, 0x11, 0x35, 0x1d, 0x01, 0xc4, 0xc2, 0xb7, - 0x70, 0x78, 0x50, 0x79, 0xa2, 0x9e, 0x89, 0x81, 0x03, 0x6a, 0x92, 0x55, 0x38, 0x67, 0x42, 0x64, - 0x6a, 0x01, 0xb9, 0x46, 0xf2, 0x87, 0x7f, 0xeb, 0xfd, 0x60, 0xcc, 0xaa, 0x93, 0x26, 0x25, 0xb7, - 0x7b, 0xf3, 0x0d, 0xe1, 0x7a, 0x3f, 0x18, 0xb3, 0xea, 0xd8, 0x2f, 0xc2, 0x6c, 0xea, 0x86, 0x7a, - 0x88, 0x94, 0x2e, 0xbf, 0x53, 0x80, 0x69, 0xf3, 0xa2, 0x72, 0x88, 0xf5, 0x6b, 0xf8, 0x6d, 0x21, - 0xe3, 0x72, 0xb1, 0x70, 0xcc, 0xcb, 0x45, 0xf3, 0x36, 0x77, 0xfc, 0x74, 0x6f, 0x73, 0x8b, 0xf9, - 0xdc, 0xe6, 0x1a, 0x5e, 0x07, 0x13, 0x8f, 0xcf, 0xeb, 0xe0, 0xb7, 0x8a, 0x30, 0x93, 0xcc, 0x11, - 0x3a, 0x44, 0x4f, 0xbe, 0xd0, 0xd7, 0x93, 0xc7, 0xbc, 0xcd, 0x28, 0x8c, 0x7a, 0x9b, 0x31, 0x3e, - 0xea, 0x6d, 0x46, 0xf1, 0x04, 0xb7, 0x19, 0xfd, 0x77, 0x11, 0x13, 0x43, 0xdf, 0x45, 0x7c, 0x4a, - 0x3b, 0x68, 0x4e, 0x26, 0x1c, 0x78, 0x62, 0x07, 0x4d, 0x92, 0xec, 0x86, 0x65, 0xbf, 0x99, 0xe9, - 0xe8, 0x3a, 0xf5, 0x08, 0xab, 0x6d, 0x90, 0xe9, 0x4f, 0x79, 0xfc, 0x0b, 0xd3, 0x27, 0x8e, 0xe1, - 0x4b, 0xf9, 0x32, 0x94, 0xe5, 0x78, 0xe2, 0xca, 0x37, 0x24, 0x15, 0xf7, 0x7a, 0x0c, 0x42, 0x13, - 0x8f, 0x0d, 0x8c, 0x6e, 0x3c, 0x41, 0xf8, 0xbd, 0x5a, 0x39, 0x79, 0xaf, 0xb6, 0x91, 0x04, 0x63, - 0x1a, 0xdf, 0xfe, 0x02, 0x5c, 0xc8, 0x34, 0xa0, 0x70, 0xe3, 0x35, 0xd7, 0x0b, 0x69, 0x53, 0x22, - 0x18, 0x62, 0xa4, 0x9e, 0x0e, 0x59, 0xb8, 0x3b, 0x10, 0x13, 0x8f, 0xa0, 0x62, 0xff, 0x46, 0x01, - 0x66, 0x92, 0xef, 0xc7, 0x92, 0xfb, 0xda, 0xdc, 0x9a, 0x8b, 0xa5, 0x57, 0x90, 0x35, 0xf2, 0x4e, - 0x0e, 0xbc, 0xa6, 0xb9, 0xcf, 0xc7, 0xd7, 0x96, 0x4e, 0x82, 0x79, 0x7a, 0x8c, 0xe5, 0xfd, 0x88, - 0x64, 0xc7, 0x9f, 0x88, 0x8d, 0x43, 0x54, 0xe5, 0x39, 0x3e, 0x77, 0xee, 0x71, 0xa8, 0xa5, 0x66, - 0x85, 0x06, 0x5b, 0xb6, 0xb7, 0xec, 0xd1, 0xc0, 0xdd, 0x76, 0xf5, 0xdb, 0xf7, 0x7c, 0xe5, 0x7e, - 0x4b, 0x96, 0xa1, 0x86, 0xda, 0xef, 0x8d, 0x41, 0x89, 0x67, 0xd4, 0xba, 0x1e, 0xf8, 0x1d, 0xfe, - 0xc8, 0x62, 0x68, 0x9c, 0x99, 0x64, 0xb7, 0xdd, 0x1c, 0xf5, 0x25, 0xd3, 0x98, 0xa2, 0x74, 0x9e, - 0x37, 0x4a, 0x30, 0xc1, 0x91, 0x74, 0x61, 0x6a, 0x5b, 0x66, 0x00, 0x96, 0x7d, 0x37, 0x62, 0x16, - 0x4b, 0x95, 0x4f, 0x58, 0x34, 0x81, 0xfa, 0x87, 0x9a, 0x8b, 0xed, 0xc0, 0x6c, 0x2a, 0x25, 0x4a, - 0xee, 0x79, 0x83, 0xff, 0xe7, 0x38, 0x94, 0x74, 0xe4, 0x16, 0xf9, 0x44, 0xc2, 0x80, 0x55, 0xaa, - 0x7d, 0xd8, 0x78, 0x01, 0x6c, 0xc7, 0x6f, 0x3e, 0x3c, 0xa8, 0xcc, 0x6a, 0xe4, 0x94, 0x31, 0xea, - 0x22, 0x14, 0x7a, 0x41, 0x3b, 0x7d, 0x42, 0xbd, 0x83, 0x6b, 0xc8, 0xca, 0xcd, 0x68, 0xb3, 0xc2, - 0x63, 0x8d, 0x36, 0x63, 0xbb, 0xe4, 0x96, 0xdf, 0xdc, 0x4f, 0xbf, 0x18, 0x56, 0xf3, 0x9b, 0xfb, - 0xc8, 0x21, 0xe4, 0x35, 0x98, 0x91, 0x21, 0x74, 0x4a, 0x89, 0x29, 0x72, 0x3d, 0x55, 0xbb, 0x1d, - 0x6c, 0x26, 0xa0, 0x98, 0xc2, 0x66, 0xbb, 0xec, 0xbd, 0xd0, 0xf7, 0x78, 0x36, 0xe8, 0x89, 0xe4, - 0x1d, 0xe5, 0xcd, 0xfa, 0xed, 0x5b, 0xdc, 0x90, 0xa6, 0x31, 0x12, 0x51, 0x7a, 0x93, 0x8f, 0x8c, - 0xd2, 0x5b, 0x11, 0xb4, 0x99, 0xb4, 0x7c, 0x47, 0x99, 0xae, 0x5d, 0x51, 0x74, 0x59, 0xd9, 0xc3, - 0x83, 0x23, 0x4c, 0x9c, 0xba, 0x66, 0x56, 0x3c, 0x63, 0xe9, 0xc7, 0x17, 0xcf, 0x68, 0xdf, 0x81, - 0xd9, 0x54, 0xff, 0x29, 0x03, 0x87, 0x95, 0x6d, 0xe0, 0x18, 0xee, 0xcd, 0xb1, 0x7f, 0x6a, 0xc1, - 0xd9, 0xbe, 0x15, 0x69, 0xd8, 0xc0, 0xd2, 0xf4, 0xde, 0x38, 0x76, 0xf2, 0xbd, 0xb1, 0x70, 0xbc, - 0xbd, 0xb1, 0xb6, 0xf5, 0xdd, 0x1f, 0x5c, 0xfa, 0xd0, 0xf7, 0x7e, 0x70, 0xe9, 0x43, 0x7f, 0xf0, - 0x83, 0x4b, 0x1f, 0x7a, 0xef, 0xf0, 0x92, 0xf5, 0xdd, 0xc3, 0x4b, 0xd6, 0xf7, 0x0e, 0x2f, 0x59, - 0x7f, 0x70, 0x78, 0xc9, 0xfa, 0xcf, 0x87, 0x97, 0xac, 0x6f, 0xfe, 0xf1, 0xa5, 0x0f, 0x7d, 0xfa, - 0x53, 0x71, 0x4f, 0x2d, 0xa9, 0x9e, 0xe2, 0x3f, 0x3e, 0xaa, 0xfa, 0x65, 0xa9, 0xbb, 0xdb, 0x5a, - 0x62, 0x3d, 0xb5, 0xa4, 0x4b, 0x54, 0x4f, 0xfd, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x59, - 0x84, 0xec, 0x21, 0xa6, 0x00, 0x00, + 0x5e, 0x9b, 0x8a, 0xb9, 0x5d, 0xaa, 0x95, 0xd8, 0x2a, 0x84, 0xac, 0x00, 0x45, 0xb9, 0xfd, 0x65, + 0xb6, 0xe2, 0x72, 0x92, 0x29, 0xcb, 0xcd, 0x3d, 0x28, 0x06, 0x8c, 0x89, 0x1c, 0x59, 0xa3, 0x1e, + 0x72, 0x63, 0xa9, 0xa5, 0x10, 0xec, 0x27, 0x0a, 0x16, 0xf6, 0x6f, 0x8f, 0xc1, 0x85, 0x6a, 0xb7, + 0xbb, 0x4e, 0xc3, 0x9d, 0x94, 0x14, 0x3f, 0x6f, 0xc1, 0xcc, 0x9e, 0x1b, 0x44, 0x3d, 0xa7, 0xad, + 0x8c, 0x73, 0x42, 0x9e, 0xfa, 0xa8, 0xf2, 0x70, 0x6e, 0x6f, 0x25, 0x48, 0xd7, 0xc8, 0xe1, 0x41, + 0x65, 0x26, 0x59, 0x86, 0x29, 0xf6, 0xe4, 0x6f, 0x5b, 0x30, 0x27, 0x8b, 0x6e, 0xf9, 0x4d, 0x6a, + 0x1a, 0x7f, 0xef, 0xe4, 0x29, 0x93, 0x26, 0x2e, 0x8c, 0x76, 0xe9, 0x52, 0xec, 0x13, 0xc2, 0xfe, + 0xef, 0x63, 0xf0, 0xe4, 0x00, 0x1a, 0xe4, 0x57, 0x2c, 0x38, 0x2f, 0x2c, 0xc6, 0x06, 0x08, 0xe9, + 0xb6, 0x6c, 0xcd, 0x9f, 0xce, 0x5b, 0x72, 0x64, 0x53, 0x9c, 0x7a, 0x0d, 0x5a, 0x9b, 0x67, 0xab, + 0xe1, 0x72, 0x06, 0x6b, 0xcc, 0x14, 0x88, 0x4b, 0x2a, 0x6c, 0xc8, 0x29, 0x49, 0xc7, 0x1e, 0x8b, + 0xa4, 0xf5, 0x0c, 0xd6, 0x98, 0x29, 0x90, 0xfd, 0x57, 0xe1, 0xe9, 0x23, 0xc8, 0x3d, 0x7a, 0x72, + 0xda, 0x6f, 0xeb, 0x51, 0x9f, 0x1c, 0x73, 0x43, 0xcc, 0x6b, 0x1b, 0x26, 0xf8, 0xd4, 0x51, 0x13, + 0x1b, 0xd8, 0xf6, 0xc7, 0xe7, 0x54, 0x88, 0x12, 0x62, 0xff, 0xb6, 0x05, 0x53, 0xc7, 0x30, 0xf5, + 0x55, 0x92, 0xa6, 0xbe, 0x52, 0x9f, 0x99, 0x2f, 0xea, 0x37, 0xf3, 0xbd, 0x3e, 0x5a, 0x6f, 0x0c, + 0x63, 0xde, 0xfb, 0xa1, 0x05, 0x67, 0xfb, 0xcc, 0x81, 0x64, 0x07, 0xce, 0x77, 0xfd, 0xa6, 0x52, + 0x9b, 0x6e, 0x38, 0xe1, 0x0e, 0x87, 0xc9, 0xcf, 0x7b, 0x89, 0xf5, 0xe4, 0x46, 0x06, 0xfc, 0xe1, + 0x41, 0x65, 0x5e, 0x13, 0x49, 0x21, 0x60, 0x26, 0x45, 0xd2, 0x85, 0xa9, 0x6d, 0x97, 0xb6, 0x9b, + 0xf1, 0x10, 0x1c, 0x51, 0x41, 0xba, 0x2e, 0xa9, 0x09, 0x4b, 0xb8, 0xfa, 0x87, 0x9a, 0x8b, 0xfd, + 0x23, 0x0b, 0x66, 0xaa, 0xbd, 0x68, 0x87, 0xa9, 0x07, 0x0d, 0x6e, 0x7c, 0x22, 0x1e, 0x14, 0x43, + 0xb7, 0xb5, 0xf7, 0x52, 0x3e, 0x8b, 0x71, 0x9d, 0x91, 0x92, 0x37, 0x02, 0x5a, 0x37, 0xe5, 0x85, + 0x28, 0xd8, 0x90, 0x00, 0x26, 0x7c, 0xa7, 0x17, 0xed, 0x5c, 0x95, 0x9f, 0x3c, 0xe2, 0x41, 0xfc, + 0x36, 0xfb, 0x9c, 0xab, 0x92, 0xa3, 0xd6, 0xd6, 0x44, 0x29, 0x4a, 0x4e, 0xf6, 0x17, 0x61, 0x26, + 0x79, 0xcd, 0x34, 0xc4, 0x98, 0xbd, 0x08, 0x05, 0x27, 0xf0, 0xe4, 0x88, 0x2d, 0x4b, 0x84, 0x42, + 0x15, 0x6f, 0x21, 0x2b, 0x27, 0x2f, 0xc0, 0xd4, 0x76, 0xaf, 0xdd, 0x66, 0x15, 0xe4, 0x9d, 0x8e, + 0x3e, 0x05, 0x5c, 0x97, 0xe5, 0xa8, 0x31, 0xec, 0xff, 0x3d, 0x0e, 0xb3, 0xb5, 0x76, 0x8f, 0xbe, + 0x1e, 0x50, 0xaa, 0x4c, 0x1f, 0x55, 0x98, 0xed, 0x06, 0x74, 0xcf, 0xa5, 0xf7, 0xeb, 0xb4, 0x4d, + 0x1b, 0x91, 0x1f, 0x48, 0x69, 0x9e, 0x94, 0x84, 0x66, 0x37, 0x92, 0x60, 0x4c, 0xe3, 0x93, 0xd7, + 0x60, 0xc6, 0x69, 0x44, 0xee, 0x1e, 0xd5, 0x14, 0x84, 0xb8, 0x4f, 0x48, 0x0a, 0x33, 0xd5, 0x04, + 0x14, 0x53, 0xd8, 0xe4, 0xb3, 0x30, 0x1f, 0x36, 0x9c, 0x36, 0xbd, 0xd3, 0x95, 0xac, 0x96, 0x77, + 0x68, 0x63, 0x77, 0xc3, 0x77, 0xbd, 0x48, 0x9a, 0xd9, 0x2e, 0x4b, 0x4a, 0xf3, 0xf5, 0x01, 0x78, + 0x38, 0x90, 0x02, 0xf9, 0x17, 0x16, 0x5c, 0xec, 0x06, 0x74, 0x23, 0xf0, 0x3b, 0x3e, 0x1b, 0x6a, + 0x7d, 0xd6, 0x1f, 0x69, 0x05, 0x79, 0x6b, 0x44, 0x5d, 0x4a, 0x94, 0xf4, 0x5f, 0x59, 0x7c, 0xf8, + 0xf0, 0xa0, 0x72, 0x71, 0xe3, 0x28, 0x01, 0xf0, 0x68, 0xf9, 0xc8, 0xbf, 0xb4, 0xe0, 0x52, 0xd7, + 0x0f, 0xa3, 0x23, 0x3e, 0xa1, 0x78, 0xaa, 0x9f, 0x60, 0x1f, 0x1e, 0x54, 0x2e, 0x6d, 0x1c, 0x29, + 0x01, 0x3e, 0x42, 0x42, 0xfb, 0xb0, 0x0c, 0x67, 0x8d, 0xb1, 0x27, 0x6d, 0x17, 0xaf, 0xc2, 0x19, + 0x35, 0x18, 0x62, 0xdd, 0xa7, 0x14, 0x9b, 0xb2, 0xaa, 0x26, 0x10, 0x93, 0xb8, 0x6c, 0xdc, 0xe9, + 0xa1, 0x28, 0x6a, 0xa7, 0xc6, 0xdd, 0x46, 0x02, 0x8a, 0x29, 0x6c, 0xb2, 0x0a, 0xe7, 0x64, 0x09, + 0xd2, 0x6e, 0xdb, 0x6d, 0x38, 0xcb, 0x7e, 0x4f, 0x0e, 0xb9, 0x62, 0xed, 0xc9, 0xc3, 0x83, 0xca, + 0xb9, 0x8d, 0x7e, 0x30, 0x66, 0xd5, 0x21, 0x6b, 0x70, 0xde, 0xe9, 0x45, 0xbe, 0xfe, 0xfe, 0x6b, + 0x1e, 0xdb, 0x4e, 0x9b, 0x7c, 0x68, 0x4d, 0x89, 0x7d, 0xb7, 0x9a, 0x01, 0xc7, 0xcc, 0x5a, 0x64, + 0x23, 0x45, 0xad, 0x4e, 0x1b, 0xbe, 0xd7, 0x14, 0xbd, 0x5c, 0x8c, 0x4f, 0x60, 0xd5, 0x0c, 0x1c, + 0xcc, 0xac, 0x49, 0xda, 0x30, 0xd3, 0x71, 0x1e, 0xdc, 0xf1, 0x9c, 0x3d, 0xc7, 0x6d, 0x33, 0x26, + 0xd2, 0x3c, 0x36, 0xd8, 0xa8, 0xd2, 0x8b, 0xdc, 0xf6, 0xa2, 0x70, 0x5b, 0x58, 0x5c, 0xf5, 0xa2, + 0xdb, 0x41, 0x3d, 0x62, 0x9a, 0xba, 0xd0, 0x20, 0xd7, 0x13, 0xb4, 0x30, 0x45, 0x9b, 0xdc, 0x86, + 0x0b, 0x7c, 0x3a, 0xae, 0xf8, 0xf7, 0xbd, 0x15, 0xda, 0x76, 0xf6, 0xd5, 0x07, 0x4c, 0xf2, 0x0f, + 0x78, 0xea, 0xf0, 0xa0, 0x72, 0xa1, 0x9e, 0x85, 0x80, 0xd9, 0xf5, 0x88, 0x03, 0x4f, 0x27, 0x01, + 0x48, 0xf7, 0xdc, 0xd0, 0xf5, 0x3d, 0x61, 0x85, 0x9a, 0x8a, 0xad, 0x50, 0xf5, 0xc1, 0x68, 0x78, + 0x14, 0x0d, 0xf2, 0x77, 0x2d, 0x38, 0x9f, 0x35, 0x0d, 0xe7, 0x4b, 0x79, 0x5c, 0x9e, 0xa6, 0xa6, + 0x96, 0x18, 0x11, 0x99, 0x8b, 0x42, 0xa6, 0x10, 0xe4, 0x3d, 0x0b, 0xa6, 0x1d, 0xe3, 0x04, 0x3d, + 0x0f, 0x79, 0xec, 0x5a, 0xe6, 0x99, 0xbc, 0x36, 0x77, 0x78, 0x50, 0x49, 0x9c, 0xd2, 0x31, 0xc1, + 0x91, 0xfc, 0x7d, 0x0b, 0x2e, 0x64, 0xce, 0xf1, 0xf9, 0xf2, 0x69, 0xb4, 0x10, 0x1f, 0x24, 0xd9, + 0x6b, 0x4e, 0xb6, 0x18, 0xe4, 0x5b, 0x96, 0xde, 0xca, 0xd4, 0x7d, 0xda, 0xfc, 0x34, 0x17, 0xed, + 0xcd, 0x11, 0x8d, 0x06, 0xb1, 0xd6, 0xa4, 0x08, 0xd7, 0xce, 0x19, 0x3b, 0xa3, 0x2a, 0xc4, 0x34, + 0x7b, 0xf2, 0x4d, 0x4b, 0x6d, 0x8d, 0x5a, 0xa2, 0x33, 0xa7, 0x25, 0x11, 0x89, 0x77, 0x5a, 0x2d, + 0x50, 0x8a, 0x39, 0xf9, 0x19, 0x58, 0x70, 0xb6, 0xfc, 0x20, 0xca, 0x9c, 0x7c, 0xf3, 0x33, 0x7c, + 0x1a, 0x5d, 0x3a, 0x3c, 0xa8, 0x2c, 0x54, 0x07, 0x62, 0xe1, 0x11, 0x14, 0xec, 0x5f, 0x2b, 0xc2, + 0xb4, 0x38, 0x09, 0xc9, 0xad, 0xeb, 0x37, 0x2d, 0x78, 0xa6, 0xd1, 0x0b, 0x02, 0xea, 0x45, 0xf5, + 0x88, 0x76, 0xfb, 0x37, 0x2e, 0xeb, 0x54, 0x37, 0xae, 0xcb, 0x87, 0x07, 0x95, 0x67, 0x96, 0x8f, + 0xe0, 0x8f, 0x47, 0x4a, 0x47, 0xfe, 0x9d, 0x05, 0xb6, 0x44, 0xa8, 0x39, 0x8d, 0xdd, 0x56, 0xe0, + 0xf7, 0xbc, 0x66, 0xff, 0x47, 0x8c, 0x9d, 0xea, 0x47, 0x3c, 0x77, 0x78, 0x50, 0xb1, 0x97, 0x1f, + 0x29, 0x05, 0x0e, 0x21, 0x29, 0x79, 0x1d, 0xce, 0x4a, 0xac, 0x6b, 0x0f, 0xba, 0x34, 0x70, 0xd9, + 0x99, 0x43, 0x2a, 0x8e, 0xb1, 0x2b, 0x56, 0x1a, 0x01, 0xfb, 0xeb, 0x90, 0x10, 0x26, 0xef, 0x53, + 0xb7, 0xb5, 0x13, 0x29, 0xf5, 0x69, 0x44, 0xff, 0x2b, 0x69, 0x15, 0xb9, 0x2b, 0x68, 0xd6, 0xca, + 0x87, 0x07, 0x95, 0x49, 0xf9, 0x07, 0x15, 0x27, 0x72, 0x0b, 0x66, 0xc4, 0x39, 0x75, 0xc3, 0xf5, + 0x5a, 0x1b, 0xbe, 0x27, 0x9c, 0x88, 0x4a, 0xb5, 0xe7, 0xd4, 0x86, 0x5f, 0x4f, 0x40, 0x1f, 0x1e, + 0x54, 0xa6, 0xd5, 0xef, 0xcd, 0xfd, 0x2e, 0xc5, 0x54, 0x6d, 0xfb, 0x77, 0x27, 0x00, 0xd4, 0x70, + 0xa5, 0x5d, 0xf2, 0x11, 0x28, 0x85, 0x34, 0x12, 0x5c, 0xe5, 0xc5, 0x89, 0xb8, 0xee, 0x52, 0x85, + 0x18, 0xc3, 0xc9, 0x2e, 0x14, 0xbb, 0x4e, 0x2f, 0xa4, 0xf9, 0x9c, 0x1f, 0x64, 0xe7, 0x6f, 0x30, + 0x8a, 0xe2, 0x60, 0xca, 0x7f, 0xa2, 0xe0, 0x41, 0xbe, 0x62, 0x01, 0xd0, 0x64, 0x87, 0x8d, 0x6c, + 0x20, 0x92, 0x2c, 0xe3, 0x3e, 0x65, 0x6d, 0x50, 0x9b, 0x39, 0x3c, 0xa8, 0x80, 0xd1, 0xf5, 0x06, + 0x5b, 0x72, 0x1f, 0xa6, 0x1c, 0xb5, 0xe6, 0x8f, 0x9f, 0xc6, 0x9a, 0xcf, 0xcf, 0x8b, 0x7a, 0xd0, + 0x6a, 0x66, 0xe4, 0x6b, 0x16, 0xcc, 0x84, 0x34, 0x92, 0x5d, 0xc5, 0x56, 0x1e, 0xa9, 0xf0, 0x8e, + 0x38, 0xe8, 0xea, 0x09, 0x9a, 0x62, 0x05, 0x4d, 0x96, 0x61, 0x8a, 0xaf, 0x12, 0xe5, 0x06, 0x75, + 0x9a, 0x34, 0xe0, 0xe6, 0x08, 0xa9, 0x49, 0x8d, 0x2e, 0x8a, 0x41, 0x53, 0x8b, 0x62, 0x94, 0x61, + 0x8a, 0xaf, 0x12, 0x65, 0xdd, 0x0d, 0x02, 0x5f, 0x8a, 0x32, 0x95, 0x93, 0x28, 0x06, 0x4d, 0x2d, + 0x8a, 0x51, 0x86, 0x29, 0xbe, 0xf6, 0x77, 0xce, 0xc0, 0x8c, 0x9a, 0x48, 0xb1, 0x66, 0x2f, 0xac, + 0x5f, 0x03, 0x34, 0xfb, 0x65, 0x13, 0x88, 0x49, 0x5c, 0x56, 0x59, 0x4c, 0xd5, 0xa4, 0x62, 0xaf, + 0x2b, 0xd7, 0x4d, 0x20, 0x26, 0x71, 0x49, 0x07, 0x8a, 0x61, 0x44, 0xbb, 0xea, 0x8a, 0x7d, 0xc4, + 0x1b, 0xe0, 0x78, 0x7d, 0x30, 0x2c, 0x09, 0x8c, 0x3c, 0x0a, 0x2e, 0xdc, 0x80, 0x1b, 0x25, 0x6c, + 0xba, 0x72, 0x72, 0xe4, 0x33, 0x3f, 0x93, 0xe6, 0x62, 0xd1, 0x1b, 0xc9, 0x32, 0x4c, 0xb1, 0xcf, + 0x50, 0xf6, 0x8b, 0xa7, 0xa8, 0xec, 0x7f, 0x1a, 0xa6, 0x3a, 0xce, 0x83, 0x7a, 0x2f, 0x68, 0x9d, + 0xfc, 0x50, 0x21, 0x5d, 0x26, 0x05, 0x15, 0xd4, 0xf4, 0xc8, 0x97, 0x2c, 0x63, 0xc9, 0x11, 0xf7, + 0xe9, 0x77, 0xf3, 0x5d, 0x72, 0xf4, 0x5e, 0x39, 0x70, 0xf1, 0xe9, 0x53, 0xbd, 0xa7, 0x1e, 0xbb, + 0xea, 0xcd, 0xd4, 0x48, 0x31, 0x41, 0xb4, 0x1a, 0x59, 0x3a, 0x55, 0x35, 0x72, 0x39, 0xc1, 0x0c, + 0x53, 0xcc, 0xb9, 0x3c, 0x62, 0xce, 0x69, 0x79, 0xe0, 0x54, 0xe5, 0xa9, 0x27, 0x98, 0x61, 0x8a, + 0xf9, 0xe0, 0xf3, 0x66, 0xf9, 0x74, 0xce, 0x9b, 0xd3, 0x39, 0x9c, 0x37, 0x8f, 0x56, 0xc5, 0xcf, + 0x8c, 0xaa, 0x8a, 0x93, 0x9b, 0x40, 0x9a, 0xfb, 0x9e, 0xd3, 0x71, 0x1b, 0x72, 0xb1, 0xe4, 0xdb, + 0xe6, 0x0c, 0xb7, 0x47, 0x2c, 0xc8, 0x85, 0x8c, 0xac, 0xf4, 0x61, 0x60, 0x46, 0x2d, 0x12, 0xc1, + 0x54, 0x57, 0x69, 0x5c, 0xb3, 0x79, 0x8c, 0x7e, 0xa5, 0x81, 0x09, 0x37, 0x09, 0x36, 0xf1, 0x54, + 0x09, 0x6a, 0x4e, 0x64, 0x0d, 0xce, 0x77, 0x5c, 0x6f, 0xc3, 0x6f, 0x86, 0x1b, 0x34, 0x90, 0xd6, + 0x96, 0x3a, 0x8d, 0xe6, 0xe7, 0x78, 0xdb, 0xf0, 0x13, 0xf4, 0x7a, 0x06, 0x1c, 0x33, 0x6b, 0xd9, + 0xff, 0xcb, 0x82, 0xb9, 0xe5, 0xb6, 0xdf, 0x6b, 0xde, 0x75, 0xa2, 0xc6, 0x8e, 0xf0, 0x10, 0x20, + 0xaf, 0xc1, 0x94, 0xeb, 0x45, 0x34, 0xd8, 0x73, 0xda, 0x72, 0x7f, 0xb2, 0x95, 0xf9, 0x74, 0x55, + 0x96, 0x3f, 0x3c, 0xa8, 0xcc, 0xac, 0xf4, 0x02, 0x6e, 0xa5, 0x16, 0xab, 0x15, 0xea, 0x3a, 0xe4, + 0x3b, 0x16, 0x9c, 0x15, 0x3e, 0x06, 0x2b, 0x4e, 0xe4, 0xbc, 0xd9, 0xa3, 0x81, 0x4b, 0x95, 0x97, + 0xc1, 0x88, 0x0b, 0x55, 0x5a, 0x56, 0xc5, 0x60, 0x3f, 0x56, 0xd4, 0xd7, 0xd3, 0x9c, 0xb1, 0x5f, + 0x18, 0xfb, 0x17, 0x0a, 0xf0, 0xd4, 0x40, 0x5a, 0x64, 0x01, 0xc6, 0xdc, 0xa6, 0xfc, 0x74, 0x90, + 0x74, 0xc7, 0x56, 0x9b, 0x38, 0xe6, 0x36, 0xc9, 0x22, 0xd7, 0x39, 0x03, 0x1a, 0x86, 0xea, 0xc2, + 0xb9, 0xa4, 0xd5, 0x43, 0x59, 0x8a, 0x06, 0x06, 0xa9, 0x40, 0x91, 0xbb, 0xcb, 0xca, 0xf3, 0x04, + 0xd7, 0x62, 0xb9, 0x67, 0x2a, 0x8a, 0x72, 0xf2, 0x65, 0x0b, 0x40, 0x08, 0xc8, 0x4e, 0x23, 0x72, + 0x97, 0xc4, 0x7c, 0x9b, 0x89, 0x51, 0x16, 0x52, 0xc6, 0xff, 0xd1, 0xe0, 0x4a, 0x36, 0x61, 0x82, + 0x29, 0xb4, 0x7e, 0xf3, 0xc4, 0x9b, 0x22, 0xbf, 0x89, 0xda, 0xe0, 0x34, 0x50, 0xd2, 0x62, 0x6d, + 0x15, 0xd0, 0xa8, 0x17, 0x78, 0xac, 0x69, 0xf9, 0x36, 0x38, 0x25, 0xa4, 0x40, 0x5d, 0x8a, 0x06, + 0x86, 0xfd, 0xcf, 0xc6, 0xe0, 0x7c, 0x96, 0xe8, 0x6c, 0xb7, 0x99, 0x10, 0xd2, 0xca, 0xa3, 0xf1, + 0x4f, 0xe5, 0xdf, 0x3e, 0xd2, 0x5d, 0x46, 0x5f, 0x53, 0x48, 0x7f, 0x41, 0xc9, 0x97, 0xfc, 0x94, + 0x6e, 0xa1, 0xb1, 0x13, 0xb6, 0x90, 0xa6, 0x9c, 0x6a, 0xa5, 0xcb, 0x30, 0x1e, 0xb2, 0x9e, 0x2f, + 0x24, 0xaf, 0x3b, 0x78, 0x1f, 0x71, 0x08, 0xc3, 0xe8, 0x79, 0x6e, 0x24, 0x63, 0x4c, 0x34, 0xc6, + 0x1d, 0xcf, 0x8d, 0x90, 0x43, 0xec, 0x6f, 0x8f, 0xc1, 0xc2, 0xe0, 0x8f, 0x22, 0xdf, 0xb6, 0x00, + 0x9a, 0xec, 0xb8, 0x12, 0x72, 0x47, 0x6d, 0xe1, 0x5e, 0xe4, 0x9c, 0x56, 0x1b, 0xae, 0x28, 0x4e, + 0xb1, 0xaf, 0x99, 0x2e, 0x0a, 0xd1, 0x10, 0x84, 0x5c, 0x55, 0x43, 0x9f, 0x5f, 0xd5, 0x88, 0xc9, + 0xa4, 0xeb, 0xac, 0x6b, 0x08, 0x1a, 0x58, 0xec, 0x3c, 0xea, 0x39, 0x1d, 0x1a, 0x76, 0x1d, 0x1d, + 0xb1, 0xc3, 0xcf, 0xa3, 0xb7, 0x54, 0x21, 0xc6, 0x70, 0xbb, 0x0d, 0xcf, 0x0e, 0x21, 0x67, 0x4e, + 0x01, 0x11, 0xf6, 0xff, 0xb0, 0xe0, 0xc9, 0xe5, 0x76, 0x2f, 0x8c, 0x68, 0xf0, 0xff, 0x8d, 0xeb, + 0xde, 0x9f, 0x5a, 0xf0, 0xf4, 0x80, 0x6f, 0x7e, 0x0c, 0x1e, 0x7c, 0xef, 0x24, 0x3d, 0xf8, 0xee, + 0x8c, 0x3a, 0xa4, 0x33, 0xbf, 0x63, 0x80, 0x23, 0xdf, 0xbf, 0x29, 0xc0, 0x19, 0xb6, 0x6c, 0x35, + 0xfd, 0x56, 0x4e, 0x1b, 0xe7, 0xb3, 0x50, 0xfc, 0x3c, 0xdb, 0x80, 0xd2, 0x83, 0x8c, 0xef, 0x4a, + 0x28, 0x60, 0xe4, 0x2b, 0x16, 0x4c, 0x7e, 0x5e, 0xee, 0xa9, 0xe2, 0x2c, 0x37, 0xe2, 0x62, 0x98, + 0xf8, 0x86, 0x45, 0xb9, 0x43, 0x8a, 0x38, 0x0b, 0xed, 0x3b, 0xa8, 0xb6, 0x52, 0xc5, 0x99, 0x3c, + 0x0f, 0x93, 0xdb, 0x7e, 0xd0, 0xe9, 0xb5, 0x9d, 0x74, 0x70, 0xdf, 0x75, 0x51, 0x8c, 0x0a, 0xce, + 0x26, 0xb9, 0xd3, 0x75, 0xdf, 0xa2, 0x41, 0x28, 0xdc, 0xee, 0x13, 0x93, 0xbc, 0xaa, 0x21, 0x68, + 0x60, 0xf1, 0x3a, 0xad, 0x56, 0x40, 0x5b, 0x4e, 0xe4, 0x07, 0x7c, 0xe7, 0x30, 0xeb, 0x68, 0x08, + 0x1a, 0x58, 0x0b, 0x9f, 0x84, 0x69, 0x53, 0xf8, 0x63, 0xc5, 0x6c, 0x7c, 0x0a, 0xa4, 0x13, 0x61, + 0x6a, 0x49, 0xb2, 0x86, 0x59, 0x92, 0xec, 0xff, 0x30, 0x06, 0x86, 0x75, 0xe8, 0x31, 0x4c, 0x75, + 0x2f, 0x31, 0xd5, 0x47, 0xb4, 0x6c, 0x18, 0xb6, 0xae, 0x41, 0x11, 0x6c, 0x7b, 0xa9, 0x08, 0xb6, + 0x5b, 0xb9, 0x71, 0x3c, 0x3a, 0x80, 0xed, 0xfb, 0x16, 0x3c, 0x1d, 0x23, 0xf7, 0x1b, 0x6e, 0x1f, + 0xbd, 0x6e, 0xbf, 0x0c, 0x65, 0x27, 0xae, 0x26, 0x27, 0x96, 0x11, 0x3e, 0xa4, 0x41, 0x68, 0xe2, + 0xc5, 0xa1, 0x0f, 0x85, 0x13, 0x86, 0x3e, 0x8c, 0x1f, 0x1d, 0xfa, 0x60, 0xff, 0x68, 0x0c, 0x2e, + 0xf6, 0x7f, 0x99, 0x5a, 0x71, 0x86, 0xf3, 0x82, 0x78, 0x05, 0xa6, 0x23, 0x59, 0xc1, 0xd8, 0x3f, + 0x75, 0x28, 0xf3, 0xa6, 0x01, 0xc3, 0x04, 0x26, 0xab, 0xd9, 0x10, 0x6b, 0x5d, 0xbd, 0xe1, 0x77, + 0x55, 0xd8, 0x8e, 0xae, 0xb9, 0x6c, 0xc0, 0x30, 0x81, 0xa9, 0x7d, 0x86, 0xc7, 0x4f, 0xdd, 0x67, + 0xb8, 0x0e, 0x17, 0x94, 0x97, 0xe4, 0x75, 0x3f, 0x90, 0xfe, 0xff, 0x6a, 0x05, 0x99, 0xaa, 0x5d, + 0x94, 0x55, 0x2e, 0x60, 0x16, 0x12, 0x66, 0xd7, 0xb5, 0xbf, 0x5f, 0x80, 0x73, 0x71, 0xb3, 0x2f, + 0xfb, 0x5e, 0xd3, 0xe5, 0x8e, 0x36, 0xaf, 0xc2, 0x78, 0xb4, 0xdf, 0x55, 0x8d, 0xfd, 0x17, 0x95, + 0x38, 0x9b, 0xfb, 0x5d, 0xd6, 0xdb, 0x4f, 0x66, 0x54, 0xe1, 0xa6, 0x73, 0x5e, 0x89, 0xac, 0xe9, + 0xd9, 0x21, 0x7a, 0xe0, 0xa5, 0xe4, 0x68, 0x7e, 0x78, 0x50, 0xc9, 0x88, 0xe4, 0x5f, 0xd4, 0x94, + 0x92, 0x63, 0x9e, 0xdc, 0x83, 0x99, 0xb6, 0x13, 0x46, 0x77, 0xba, 0x4d, 0x27, 0xa2, 0x9b, 0xae, + 0x74, 0x61, 0x39, 0x5e, 0xc8, 0x84, 0xbe, 0xeb, 0x5f, 0x4b, 0x50, 0xc2, 0x14, 0x65, 0xb2, 0x07, + 0x84, 0x95, 0x6c, 0x06, 0x8e, 0x17, 0x8a, 0xaf, 0x62, 0xfc, 0x8e, 0x1f, 0xff, 0xa2, 0x8f, 0xce, + 0x6b, 0x7d, 0xd4, 0x30, 0x83, 0x03, 0x79, 0x0e, 0x26, 0x02, 0xea, 0x84, 0x7a, 0x3b, 0xd0, 0xf3, + 0x1f, 0x79, 0x29, 0x4a, 0xa8, 0x39, 0xa1, 0x26, 0x1e, 0x31, 0xa1, 0xfe, 0xd0, 0x82, 0x99, 0xb8, + 0x9b, 0x1e, 0x83, 0xea, 0xd1, 0x49, 0xaa, 0x1e, 0x37, 0xf2, 0x5a, 0x12, 0x07, 0x68, 0x1b, 0x7f, + 0x32, 0x69, 0x7e, 0x1f, 0x0f, 0x18, 0xf8, 0x02, 0x94, 0xd4, 0xac, 0x56, 0x3a, 0xfd, 0x88, 0x16, + 0x88, 0x84, 0xb6, 0x67, 0x44, 0xf1, 0x49, 0x26, 0x18, 0xf3, 0x63, 0xba, 0x4e, 0x53, 0xea, 0x31, + 0x72, 0xd8, 0x6b, 0x5d, 0x47, 0xe9, 0x37, 0x59, 0xba, 0x8e, 0xaa, 0x43, 0xee, 0xc0, 0x93, 0xdd, + 0xc0, 0xe7, 0xb1, 0xe4, 0x2b, 0xd4, 0x69, 0xb6, 0x5d, 0x8f, 0x2a, 0x33, 0x8f, 0x70, 0x35, 0x79, + 0xfa, 0xf0, 0xa0, 0xf2, 0xe4, 0x46, 0x36, 0x0a, 0x0e, 0xaa, 0x9b, 0x8c, 0x46, 0x1c, 0x1f, 0x22, + 0x1a, 0xf1, 0x6f, 0x68, 0x63, 0x2a, 0x0d, 0x65, 0x4c, 0xe0, 0x67, 0xf2, 0xea, 0xca, 0x8c, 0x65, + 0x3d, 0x1e, 0x52, 0x55, 0xc9, 0x14, 0x35, 0xfb, 0xc1, 0x16, 0xbb, 0x89, 0x13, 0x5a, 0xec, 0xe2, + 0xb8, 0x8b, 0xc9, 0x1f, 0x67, 0xdc, 0xc5, 0xd4, 0x07, 0x2a, 0xd4, 0xf2, 0x3b, 0x16, 0x9c, 0x73, + 0xfa, 0xa3, 0x8c, 0xf3, 0x31, 0x1e, 0x67, 0x84, 0x2f, 0xd7, 0x9e, 0x96, 0x42, 0x66, 0x05, 0x73, + 0x63, 0x96, 0x28, 0xf6, 0xfb, 0x45, 0x98, 0x4b, 0x2b, 0x49, 0xa7, 0x1f, 0x8e, 0xf9, 0xb7, 0x2c, + 0x98, 0x53, 0x13, 0x5c, 0xf0, 0xd4, 0x47, 0x8c, 0xb5, 0x9c, 0xd6, 0x15, 0xa1, 0xee, 0xe9, 0x2c, + 0x19, 0x9b, 0x29, 0x6e, 0xd8, 0xc7, 0x9f, 0xbc, 0x0d, 0x65, 0x7d, 0xab, 0x72, 0xa2, 0xd8, 0x4c, + 0x1e, 0x3e, 0x58, 0x8d, 0x49, 0xa0, 0x49, 0x8f, 0xbc, 0x6f, 0x01, 0x34, 0xd4, 0x4e, 0xac, 0x16, + 0x80, 0x37, 0xf3, 0x5a, 0x00, 0xf4, 0x1e, 0x1f, 0xeb, 0xf3, 0xba, 0x28, 0x44, 0x83, 0x31, 0xf9, + 0x05, 0x7e, 0x9f, 0xa2, 0x47, 0x82, 0xc8, 0xbe, 0x31, 0xb2, 0xdb, 0xfb, 0x11, 0xba, 0x73, 0xac, + 0xed, 0x19, 0xa0, 0x10, 0x13, 0x42, 0xd8, 0xaf, 0x82, 0x76, 0x54, 0x66, 0x2b, 0x2b, 0x77, 0x55, + 0xde, 0x70, 0xa2, 0x1d, 0x39, 0x04, 0xf5, 0xca, 0x7a, 0x5d, 0x01, 0x30, 0xc6, 0xb1, 0x3f, 0x07, + 0x33, 0xaf, 0x07, 0x4e, 0x77, 0xc7, 0xe5, 0xf7, 0x16, 0xec, 0x7c, 0xfc, 0x3c, 0x4c, 0x3a, 0xcd, + 0x66, 0x56, 0x42, 0x97, 0xaa, 0x28, 0x46, 0x05, 0x1f, 0xea, 0x28, 0x6c, 0xff, 0xae, 0x05, 0x24, + 0xbe, 0xfb, 0x75, 0xbd, 0xd6, 0xba, 0x13, 0x35, 0x76, 0xd8, 0x11, 0x6e, 0x87, 0x97, 0x66, 0x1d, + 0xe1, 0x6e, 0x68, 0x08, 0x1a, 0x58, 0xe4, 0x5d, 0x28, 0x8b, 0x7f, 0x6f, 0xe9, 0x03, 0xe2, 0xe8, + 0xfe, 0xd6, 0x7c, 0xcf, 0xe3, 0x32, 0x89, 0x51, 0x78, 0x23, 0xe6, 0x80, 0x26, 0x3b, 0xd6, 0x54, + 0xab, 0xde, 0x76, 0xbb, 0xf7, 0xa0, 0xb9, 0x15, 0x37, 0x55, 0x37, 0xf0, 0xb7, 0xdd, 0x36, 0x4d, + 0x37, 0xd5, 0x86, 0x28, 0x46, 0x05, 0x1f, 0xae, 0xa9, 0xfe, 0x95, 0x05, 0xe7, 0x57, 0xc3, 0xc8, + 0xf5, 0x57, 0x68, 0x18, 0xb1, 0x9d, 0x8f, 0xad, 0x8f, 0xbd, 0xf6, 0x30, 0x31, 0x07, 0x2b, 0x30, + 0x27, 0xef, 0xa1, 0x7b, 0x5b, 0x21, 0x8d, 0x8c, 0xa3, 0x86, 0x9e, 0xc7, 0xcb, 0x29, 0x38, 0xf6, + 0xd5, 0x60, 0x54, 0xe4, 0x85, 0x74, 0x4c, 0xa5, 0x90, 0xa4, 0x52, 0x4f, 0xc1, 0xb1, 0xaf, 0x86, + 0xfd, 0xbd, 0x02, 0x9c, 0xe3, 0x9f, 0x91, 0x8a, 0x17, 0xfa, 0xe6, 0xa0, 0x78, 0xa1, 0x11, 0xa7, + 0x32, 0xe7, 0x75, 0x82, 0x68, 0xa1, 0xbf, 0x69, 0xc1, 0x6c, 0x33, 0xd9, 0xd2, 0xf9, 0xd8, 0xe5, + 0xb2, 0xfa, 0x50, 0xb8, 0xdd, 0xa5, 0x0a, 0x31, 0xcd, 0x9f, 0xfc, 0xa2, 0x05, 0xb3, 0x49, 0x31, + 0xd5, 0xea, 0x7e, 0x0a, 0x8d, 0xa4, 0xfd, 0xe4, 0x93, 0xe5, 0x21, 0xa6, 0x45, 0xb0, 0x7f, 0x6f, + 0x4c, 0x76, 0xe9, 0x69, 0x04, 0xc3, 0x90, 0xfb, 0x50, 0x8a, 0xda, 0xa1, 0x28, 0x94, 0x5f, 0x3b, + 0xe2, 0xa1, 0x75, 0x73, 0xad, 0x2e, 0x5c, 0x40, 0x62, 0xbd, 0x52, 0x96, 0x30, 0xfd, 0x58, 0xf1, + 0xe2, 0x8c, 0x1b, 0x5d, 0xc9, 0x38, 0x97, 0xd3, 0xf2, 0xe6, 0xf2, 0x46, 0x9a, 0xb1, 0x2c, 0x61, + 0x8c, 0x15, 0x2f, 0xfb, 0x57, 0x2d, 0x28, 0xdd, 0xf4, 0xd5, 0x3a, 0xf2, 0x33, 0x39, 0xd8, 0xa2, + 0xb4, 0xca, 0xaa, 0x95, 0x96, 0xf8, 0x14, 0xf4, 0x5a, 0xc2, 0x12, 0xf5, 0x8c, 0x41, 0x7b, 0x91, + 0xe7, 0xb5, 0x63, 0xa4, 0x6e, 0xfa, 0x5b, 0x03, 0xcd, 0xc7, 0xbf, 0x54, 0x84, 0x33, 0x6f, 0x38, + 0xfb, 0xd4, 0x8b, 0x9c, 0xe3, 0x6f, 0x12, 0x2f, 0x43, 0xd9, 0xe9, 0xf2, 0xbb, 0x4c, 0xe3, 0x18, + 0x12, 0x1b, 0x77, 0x62, 0x10, 0x9a, 0x78, 0xf1, 0x82, 0x26, 0x22, 0x53, 0xb2, 0x96, 0xa2, 0xe5, + 0x14, 0x1c, 0xfb, 0x6a, 0x90, 0x9b, 0x40, 0x64, 0x20, 0x75, 0xb5, 0xd1, 0xf0, 0x7b, 0x9e, 0x58, + 0xd2, 0x84, 0xdd, 0x47, 0x9f, 0x87, 0xd7, 0xfb, 0x30, 0x30, 0xa3, 0x16, 0xf9, 0x2c, 0xcc, 0x37, + 0x38, 0x65, 0x79, 0x3a, 0x32, 0x29, 0x8a, 0x13, 0xb2, 0x8e, 0xf5, 0x58, 0x1e, 0x80, 0x87, 0x03, + 0x29, 0x30, 0x49, 0xc3, 0xc8, 0x0f, 0x9c, 0x16, 0x35, 0xe9, 0x4e, 0x24, 0x25, 0xad, 0xf7, 0x61, + 0x60, 0x46, 0x2d, 0xf2, 0x45, 0x28, 0x45, 0x3b, 0x01, 0x0d, 0x77, 0xfc, 0x76, 0x53, 0xfa, 0x9e, + 0x8c, 0x68, 0x0c, 0x94, 0xbd, 0xbf, 0xa9, 0xa8, 0x1a, 0xc3, 0x5b, 0x15, 0x61, 0xcc, 0x93, 0x04, + 0x30, 0x11, 0x36, 0xfc, 0x2e, 0x0d, 0xe5, 0xa9, 0xe2, 0x66, 0x2e, 0xdc, 0xb9, 0x71, 0xcb, 0x30, + 0x43, 0x72, 0x0e, 0x28, 0x39, 0xd9, 0xbf, 0x33, 0x06, 0xd3, 0x26, 0xe2, 0x10, 0x6b, 0xd3, 0x57, + 0x2c, 0x98, 0x6e, 0xf8, 0x5e, 0x14, 0xf8, 0x6d, 0x61, 0x62, 0xcb, 0x47, 0xa3, 0x60, 0xa4, 0x56, + 0x68, 0xe4, 0xb8, 0x6d, 0xc3, 0x5a, 0x67, 0xb0, 0xc1, 0x04, 0x53, 0xf2, 0x0d, 0x0b, 0x66, 0x63, + 0x57, 0xc5, 0xd8, 0xd6, 0x97, 0xab, 0x20, 0x7a, 0xa9, 0xbf, 0x96, 0xe4, 0x84, 0x69, 0xd6, 0xf6, + 0x16, 0xcc, 0xa5, 0x7b, 0x9b, 0x35, 0x65, 0xd7, 0x91, 0x73, 0xbd, 0x10, 0x37, 0xe5, 0x86, 0x13, + 0x86, 0xc8, 0x21, 0xe4, 0x05, 0x98, 0xea, 0x38, 0x41, 0xcb, 0xf5, 0x9c, 0x36, 0x6f, 0xc5, 0x82, + 0xb1, 0x20, 0xc9, 0x72, 0xd4, 0x18, 0xf6, 0xc7, 0x60, 0x7a, 0xdd, 0xf1, 0x5a, 0xb4, 0x29, 0xd7, + 0xe1, 0x47, 0x87, 0x63, 0xfe, 0xf1, 0x38, 0x94, 0x8d, 0xe3, 0xe3, 0xe9, 0x9f, 0xb3, 0x12, 0xc9, + 0x66, 0x0a, 0x39, 0x26, 0x9b, 0xf9, 0x34, 0xc0, 0xb6, 0xeb, 0xb9, 0xe1, 0xce, 0x09, 0xd3, 0xd8, + 0xf0, 0xbb, 0xf9, 0xeb, 0x9a, 0x02, 0x1a, 0xd4, 0xe2, 0x0b, 0xd0, 0xe2, 0x11, 0x19, 0xe1, 0xde, + 0xb7, 0x8c, 0xed, 0x66, 0x22, 0x0f, 0x87, 0x0f, 0xa3, 0x63, 0x16, 0xd5, 0xf6, 0x23, 0xee, 0xa6, + 0x8e, 0xda, 0x95, 0x36, 0x61, 0x2a, 0xa0, 0x61, 0xaf, 0x43, 0x4f, 0x94, 0x70, 0x86, 0xbb, 0xde, + 0xa0, 0xac, 0x8f, 0x9a, 0xd2, 0xc2, 0xab, 0x70, 0x26, 0x21, 0xc2, 0xb1, 0x6e, 0x98, 0x7c, 0xc8, + 0xb4, 0x51, 0x9c, 0xe4, 0xbe, 0x89, 0xf5, 0x45, 0xdb, 0x48, 0x34, 0xa3, 0xfb, 0x42, 0x38, 0x58, + 0x09, 0x98, 0xfd, 0xa3, 0x09, 0x90, 0x3e, 0x0c, 0x43, 0x2c, 0x57, 0xe6, 0xcd, 0xe5, 0xd8, 0x09, + 0x6e, 0x2e, 0x6f, 0xc2, 0xb4, 0xeb, 0xb9, 0x91, 0xeb, 0xb4, 0xb9, 0xfd, 0x49, 0x6e, 0xa7, 0xca, + 0x03, 0x7d, 0x7a, 0xd5, 0x80, 0x65, 0xd0, 0x49, 0xd4, 0x25, 0x6f, 0x42, 0x91, 0xef, 0x37, 0x72, + 0x00, 0x1f, 0xdf, 0xd1, 0x82, 0xfb, 0xd8, 0x88, 0xb0, 0x34, 0x41, 0x89, 0x1f, 0x3e, 0x44, 0xa6, + 0x1d, 0x7d, 0xfc, 0x96, 0xe3, 0x38, 0x3e, 0x7c, 0xa4, 0xe0, 0xd8, 0x57, 0x83, 0x51, 0xd9, 0x76, + 0xdc, 0x76, 0x2f, 0xa0, 0x31, 0x95, 0x89, 0x24, 0x95, 0xeb, 0x29, 0x38, 0xf6, 0xd5, 0x20, 0xdb, + 0x30, 0x2d, 0xcb, 0x84, 0xdb, 0xdc, 0xe4, 0x09, 0xbf, 0x92, 0xbb, 0x47, 0x5e, 0x37, 0x28, 0x61, + 0x82, 0x2e, 0xe9, 0xc1, 0x59, 0xd7, 0x6b, 0xf8, 0x5e, 0xa3, 0xdd, 0x0b, 0xdd, 0x3d, 0x1a, 0xc7, + 0x84, 0x9d, 0x84, 0xd9, 0x85, 0xc3, 0x83, 0xca, 0xd9, 0xd5, 0x34, 0x39, 0xec, 0xe7, 0x40, 0xbe, + 0x64, 0xc1, 0x85, 0x86, 0xef, 0x85, 0x3c, 0x75, 0xc5, 0x1e, 0xbd, 0x16, 0x04, 0x7e, 0x20, 0x78, + 0x97, 0x4e, 0xc8, 0x9b, 0x9b, 0x3d, 0x97, 0xb3, 0x48, 0x62, 0x36, 0x27, 0xf2, 0x0e, 0x4c, 0x75, + 0x03, 0x7f, 0xcf, 0x6d, 0xd2, 0x40, 0xba, 0x60, 0xae, 0xe5, 0x91, 0x4a, 0x67, 0x43, 0xd2, 0x8c, + 0x97, 0x1e, 0x55, 0x82, 0x9a, 0x9f, 0xfd, 0x7f, 0xca, 0x30, 0x93, 0x44, 0x27, 0x3f, 0x07, 0xd0, + 0x0d, 0xfc, 0x0e, 0x8d, 0x76, 0xa8, 0x8e, 0xed, 0xb9, 0x35, 0x6a, 0xc6, 0x16, 0x45, 0x4f, 0xb9, + 0x2d, 0xb1, 0xe5, 0x22, 0x2e, 0x45, 0x83, 0x23, 0x09, 0x60, 0x72, 0x57, 0x6c, 0xbb, 0x52, 0x0b, + 0x79, 0x23, 0x17, 0x9d, 0x49, 0x72, 0xe6, 0x41, 0x29, 0xb2, 0x08, 0x15, 0x23, 0xb2, 0x05, 0x85, + 0xfb, 0x74, 0x2b, 0x9f, 0x74, 0x01, 0x77, 0xa9, 0x3c, 0xcd, 0xd4, 0x26, 0x0f, 0x0f, 0x2a, 0x85, + 0xbb, 0x74, 0x0b, 0x19, 0x71, 0xf6, 0x5d, 0x4d, 0xe1, 0xbb, 0x20, 0x97, 0x8a, 0x37, 0x72, 0x74, + 0x84, 0x10, 0xdf, 0x25, 0x8b, 0x50, 0x31, 0x22, 0xef, 0x40, 0xe9, 0xbe, 0xb3, 0x47, 0xb7, 0x03, + 0xdf, 0x8b, 0xa4, 0xaf, 0xdc, 0x88, 0xe1, 0x1e, 0x77, 0x15, 0x39, 0xc9, 0x97, 0x6f, 0xef, 0xba, + 0x10, 0x63, 0x76, 0x64, 0x0f, 0xa6, 0x3c, 0x7a, 0x1f, 0x69, 0xdb, 0x6d, 0xe4, 0x13, 0x5e, 0x71, + 0x4b, 0x52, 0x93, 0x9c, 0xf9, 0xbe, 0xa7, 0xca, 0x50, 0xf3, 0x62, 0x7d, 0x79, 0xcf, 0xdf, 0x92, + 0x0b, 0xd5, 0x88, 0x7d, 0xa9, 0x4f, 0xa6, 0xa2, 0x2f, 0x6f, 0xfa, 0x5b, 0xc8, 0x88, 0xb3, 0x39, + 0xd2, 0xd0, 0x8e, 0x5a, 0x72, 0x99, 0xba, 0x95, 0xaf, 0x83, 0x9a, 0x98, 0x23, 0x71, 0x29, 0x1a, + 0x1c, 0x59, 0xdb, 0xb6, 0xa4, 0xb1, 0x52, 0x2e, 0x54, 0x23, 0xb6, 0x6d, 0xd2, 0xf4, 0x29, 0xda, + 0x56, 0x95, 0xa1, 0xe6, 0xc5, 0xf8, 0xba, 0xd2, 0xf2, 0x97, 0xcf, 0x52, 0x95, 0xb4, 0x23, 0x0a, + 0xbe, 0xaa, 0x0c, 0x35, 0x2f, 0xd6, 0xde, 0xe1, 0xee, 0xfe, 0x7d, 0xa7, 0xbd, 0xeb, 0x7a, 0x2d, + 0x19, 0xab, 0x3a, 0x6a, 0xd6, 0xe9, 0xdd, 0xfd, 0xbb, 0x82, 0x9e, 0xd9, 0xde, 0x71, 0x29, 0x1a, + 0x1c, 0xc9, 0xdf, 0xb3, 0x60, 0xa2, 0xdb, 0xee, 0xb5, 0x5c, 0x6f, 0x7e, 0x3a, 0x0f, 0x27, 0xa6, + 0xe4, 0x92, 0xbb, 0xb8, 0xc1, 0x49, 0x0b, 0x45, 0xf1, 0x27, 0xb5, 0xdf, 0x25, 0x2f, 0xfc, 0xfa, + 0x1f, 0x55, 0xe6, 0xa9, 0xd7, 0xf0, 0x9b, 0xae, 0xd7, 0x5a, 0xba, 0x17, 0xfa, 0xde, 0x22, 0x3a, + 0xf7, 0x95, 0x8e, 0x2e, 0x65, 0x5a, 0xf8, 0x04, 0x94, 0x0d, 0x12, 0x8f, 0x52, 0xf4, 0xa6, 0x4d, + 0x45, 0xef, 0x57, 0x27, 0x60, 0xda, 0xcc, 0x35, 0x39, 0x84, 0xf6, 0xa5, 0x4f, 0x1c, 0x63, 0xc7, + 0x39, 0x71, 0xb0, 0x23, 0xa6, 0x71, 0xc1, 0xa5, 0xcc, 0x5b, 0xab, 0xb9, 0x29, 0xdc, 0xf1, 0x11, + 0xd3, 0x28, 0x0c, 0x31, 0xc1, 0xf4, 0x18, 0x3e, 0x2f, 0x4c, 0x6d, 0x15, 0x8a, 0x5d, 0x31, 0xa9, + 0xb6, 0x26, 0x54, 0xb5, 0xab, 0x00, 0x71, 0x52, 0x44, 0x79, 0xf1, 0xa9, 0xf5, 0x61, 0x23, 0x59, + 0xa3, 0x81, 0x45, 0x9e, 0x83, 0x09, 0xa6, 0xfa, 0xd0, 0xa6, 0x0c, 0xa5, 0xd7, 0xe7, 0xf8, 0xeb, + 0xbc, 0x14, 0x25, 0x94, 0xbc, 0xc2, 0xb4, 0xd4, 0x58, 0x61, 0x91, 0x11, 0xf2, 0xe7, 0x63, 0x2d, + 0x35, 0x86, 0x61, 0x02, 0x93, 0x89, 0x4e, 0x99, 0x7e, 0xc1, 0xd7, 0x06, 0x43, 0x74, 0xae, 0x74, + 0xa0, 0x80, 0x71, 0xbb, 0x52, 0x4a, 0x1f, 0xe1, 0x73, 0xba, 0x68, 0xd8, 0x95, 0x52, 0x70, 0xec, + 0xab, 0xc1, 0x3e, 0x46, 0xde, 0xd9, 0x96, 0x85, 0xc3, 0xf4, 0x80, 0xdb, 0xd6, 0xaf, 0x9a, 0x67, + 0xad, 0x1c, 0xe7, 0x90, 0x18, 0xb5, 0xc3, 0x1f, 0xb6, 0x46, 0x3b, 0x16, 0x7d, 0x0e, 0x66, 0x92, + 0xbb, 0x50, 0xee, 0x37, 0x1f, 0x5f, 0x1b, 0x87, 0x73, 0xb7, 0x5a, 0xae, 0x97, 0x4e, 0x74, 0x96, + 0x95, 0xc4, 0xdf, 0x3a, 0x76, 0x12, 0x7f, 0x1d, 0x93, 0x27, 0x53, 0xe4, 0x67, 0xc7, 0xe4, 0xa9, + 0xf7, 0x0a, 0x92, 0xb8, 0xe4, 0x0f, 0x2d, 0x78, 0xc6, 0x69, 0x8a, 0x73, 0x81, 0xd3, 0x96, 0xa5, + 0x46, 0xee, 0x69, 0x39, 0xa3, 0xc3, 0x11, 0x77, 0xf9, 0xfe, 0x8f, 0x5f, 0xac, 0x1e, 0xc1, 0x55, + 0xf4, 0xf8, 0x4f, 0xc8, 0x2f, 0x78, 0xe6, 0x28, 0x54, 0x3c, 0x52, 0x7c, 0xf2, 0x57, 0x60, 0x36, + 0xf1, 0xc1, 0xd2, 0x12, 0x5e, 0x12, 0x17, 0x16, 0xf5, 0x24, 0x08, 0xd3, 0xb8, 0x0b, 0xb7, 0xe1, + 0xc3, 0x8f, 0x94, 0xf3, 0x58, 0x83, 0xed, 0xbb, 0x16, 0x4c, 0x9b, 0x39, 0x89, 0xc8, 0x0b, 0x30, + 0x15, 0xf9, 0xbb, 0xd4, 0xbb, 0x13, 0x28, 0x87, 0x5d, 0x3d, 0xd0, 0x37, 0x79, 0x39, 0xae, 0xa1, + 0xc6, 0x60, 0xd8, 0x8d, 0xb6, 0x4b, 0xbd, 0x68, 0xb5, 0x29, 0xbb, 0x59, 0x63, 0x2f, 0x8b, 0xf2, + 0x15, 0xd4, 0x18, 0xc2, 0xc7, 0x8e, 0xfd, 0xae, 0xd3, 0x46, 0x40, 0x95, 0x7b, 0xbf, 0xe1, 0x63, + 0x17, 0xc3, 0x30, 0x81, 0x49, 0x6c, 0x6d, 0xe2, 0x1c, 0x8f, 0xef, 0x35, 0x52, 0x26, 0xc9, 0xdf, + 0xb0, 0xa0, 0x24, 0x4c, 0xf4, 0x48, 0xb7, 0x53, 0x2e, 0xb6, 0x29, 0x23, 0x42, 0x75, 0x63, 0x35, + 0xcb, 0xc5, 0xf6, 0x32, 0x8c, 0xef, 0xba, 0x9e, 0xfa, 0x12, 0xbd, 0x2d, 0xbd, 0xe1, 0x7a, 0x4d, + 0xe4, 0x10, 0xbd, 0x71, 0x15, 0x06, 0x6e, 0x5c, 0x4b, 0x50, 0xd2, 0x8e, 0x27, 0x72, 0xf9, 0xd7, + 0xd6, 0x5b, 0xed, 0xa8, 0x82, 0x31, 0x8e, 0xfd, 0xcb, 0x16, 0xcc, 0xf0, 0x18, 0xee, 0xf8, 0x3c, + 0xfc, 0xb2, 0xf6, 0x05, 0x13, 0x72, 0x5f, 0x4c, 0xfa, 0x82, 0x3d, 0x3c, 0xa8, 0x94, 0x45, 0xd4, + 0x77, 0xd2, 0x35, 0xec, 0x33, 0xd2, 0x88, 0xc6, 0x3d, 0xd6, 0xc6, 0x8e, 0x6d, 0xe3, 0x89, 0xc5, + 0x54, 0x44, 0x30, 0xa6, 0x67, 0xbf, 0x0b, 0xd3, 0x66, 0x30, 0x16, 0x79, 0x19, 0xca, 0x5d, 0xd7, + 0x6b, 0x25, 0x83, 0x76, 0xf5, 0x45, 0xc3, 0x46, 0x0c, 0x42, 0x13, 0x8f, 0x57, 0xf3, 0xe3, 0x6a, + 0xa9, 0xfb, 0x89, 0x0d, 0xdf, 0xac, 0x16, 0xff, 0xe1, 0x79, 0xff, 0x33, 0x82, 0xfe, 0x72, 0xcf, + 0xfb, 0x9f, 0xc1, 0xe3, 0xc7, 0x97, 0xf7, 0x3f, 0x4b, 0x98, 0x3f, 0x5b, 0x79, 0xff, 0x7f, 0x1a, + 0x8e, 0x9b, 0x13, 0x95, 0xed, 0xf5, 0xf7, 0xcd, 0xc4, 0x0a, 0xba, 0xc5, 0x65, 0x66, 0x05, 0x09, + 0xb5, 0x7f, 0xab, 0x00, 0x73, 0xe9, 0x23, 0x7f, 0xde, 0xde, 0x14, 0xe4, 0x1b, 0x16, 0xcc, 0x38, + 0x89, 0xfc, 0x73, 0x39, 0x3d, 0x22, 0x94, 0xa0, 0x69, 0xe4, 0x3f, 0x4b, 0x94, 0x63, 0x8a, 0x37, + 0xf9, 0x0b, 0x30, 0x19, 0xb9, 0x1d, 0xea, 0xf7, 0x84, 0x21, 0xb0, 0x20, 0x0e, 0xe4, 0x9b, 0xa2, + 0x08, 0x15, 0x8c, 0x2d, 0xca, 0x2e, 0xd7, 0xa0, 0x02, 0x2a, 0x3d, 0x83, 0xe7, 0x62, 0xcb, 0xa5, + 0x28, 0x47, 0x8d, 0x41, 0x1e, 0xc0, 0xa4, 0xf0, 0xbb, 0x50, 0x0e, 0x36, 0xeb, 0x39, 0x99, 0x26, + 0x84, 0x6b, 0x47, 0xdc, 0x05, 0xe2, 0x7f, 0x88, 0x8a, 0x9d, 0xfd, 0x31, 0x38, 0x66, 0x92, 0x58, + 0xfb, 0x1a, 0x10, 0xf4, 0xdb, 0xed, 0x2d, 0xa7, 0xb1, 0x7b, 0xd7, 0xf5, 0x9a, 0xfe, 0x7d, 0xbe, + 0x14, 0x2d, 0x41, 0x29, 0x90, 0x21, 0xb3, 0xa1, 0x1c, 0x35, 0x7a, 0x2d, 0x53, 0xb1, 0xb4, 0x21, + 0xc6, 0x38, 0xf6, 0xef, 0x8d, 0xc1, 0xa4, 0x8c, 0xef, 0x7e, 0x0c, 0x91, 0x09, 0xbb, 0x89, 0xfb, + 0xe0, 0xd5, 0x5c, 0xc2, 0xd2, 0x07, 0x86, 0x25, 0x84, 0xa9, 0xb0, 0x84, 0x37, 0xf2, 0x61, 0x77, + 0x74, 0x4c, 0xc2, 0xbf, 0x2e, 0xc2, 0x6c, 0x2a, 0x5e, 0x9e, 0xe9, 0xe2, 0x7d, 0xae, 0xb8, 0x77, + 0x72, 0x0d, 0xc9, 0xd7, 0xb1, 0x48, 0x47, 0x7b, 0xe5, 0x86, 0x89, 0x94, 0xde, 0xf9, 0xf9, 0x32, + 0xfe, 0x79, 0x76, 0xef, 0xbc, 0xbc, 0x4c, 0x8b, 0x1f, 0x1c, 0x2f, 0xd3, 0xff, 0x62, 0xc1, 0x53, + 0x03, 0x33, 0x3f, 0xf0, 0xc4, 0x61, 0x41, 0x12, 0x2a, 0xd7, 0x8c, 0x9c, 0xf3, 0xdb, 0xe8, 0xfb, + 0xe3, 0x74, 0xae, 0xa7, 0x34, 0x7b, 0xf2, 0x12, 0x4c, 0x73, 0x1d, 0x8d, 0xad, 0x9e, 0x11, 0xed, + 0xca, 0xeb, 0x2f, 0x7e, 0x11, 0x52, 0x37, 0xca, 0x31, 0x81, 0x65, 0x7f, 0xc7, 0x82, 0xf9, 0x41, + 0x69, 0xa4, 0x86, 0x30, 0xce, 0xfc, 0xe5, 0x54, 0x74, 0x47, 0xa5, 0x2f, 0xba, 0x23, 0x65, 0x9e, + 0x51, 0x81, 0x1c, 0x86, 0x65, 0xa4, 0xf0, 0x88, 0xe0, 0x85, 0x6f, 0x5a, 0xf0, 0xe4, 0x80, 0x09, + 0xdf, 0x17, 0xe5, 0x63, 0x9d, 0x38, 0xca, 0x67, 0x6c, 0xd8, 0x28, 0x1f, 0xfb, 0xf7, 0x0b, 0x30, + 0x27, 0xe5, 0x89, 0x15, 0xf5, 0x57, 0x12, 0x31, 0x32, 0x3f, 0x91, 0x8a, 0x91, 0x39, 0x9f, 0xc6, + 0xff, 0xf3, 0x00, 0x99, 0x0f, 0x56, 0x80, 0xcc, 0xd7, 0x8b, 0x70, 0x21, 0x33, 0xbb, 0x15, 0xf9, + 0x5a, 0xc6, 0xee, 0x75, 0x37, 0xe7, 0x34, 0x5a, 0x43, 0xee, 0x5f, 0xa3, 0x46, 0x95, 0xfc, 0xa2, + 0x19, 0xcd, 0x21, 0x76, 0xa3, 0xed, 0x53, 0x48, 0x08, 0x76, 0xdc, 0xc0, 0x8e, 0xc7, 0xfb, 0xe4, + 0xd5, 0x9f, 0x81, 0xad, 0xe7, 0xeb, 0x05, 0xb8, 0x32, 0x6c, 0xcb, 0x7e, 0x40, 0x23, 0x21, 0xc3, + 0x44, 0x24, 0xe4, 0x63, 0x52, 0xb5, 0x4e, 0x25, 0x28, 0xf2, 0x1f, 0x8c, 0x6b, 0x3d, 0xa0, 0x7f, + 0xc2, 0x0e, 0xe5, 0x3c, 0x32, 0xc9, 0xd4, 0x71, 0x95, 0x29, 0x3d, 0xde, 0x1b, 0x26, 0xeb, 0xa2, + 0xf8, 0xe1, 0x41, 0xe5, 0x6c, 0x9c, 0x74, 0x46, 0x16, 0xa2, 0xaa, 0x44, 0xae, 0xc0, 0x54, 0x20, + 0xa0, 0x2a, 0xf6, 0x4b, 0x7a, 0xe0, 0x88, 0x32, 0xd4, 0x50, 0xf2, 0x45, 0xe3, 0xfc, 0x32, 0x7e, + 0x5a, 0xb9, 0x95, 0x8e, 0x72, 0x2c, 0x7a, 0x1b, 0xa6, 0x42, 0x95, 0xce, 0x5b, 0x4c, 0xa7, 0x17, + 0x87, 0x0c, 0x29, 0x74, 0xb6, 0x68, 0x5b, 0xe5, 0xf6, 0x16, 0xdf, 0xa7, 0x33, 0x7f, 0x6b, 0x92, + 0xc4, 0xd6, 0xf6, 0x00, 0x71, 0xf1, 0x01, 0xfd, 0xb6, 0x00, 0x12, 0xc1, 0xa4, 0x7c, 0xc2, 0x56, + 0xde, 0xc8, 0xae, 0xe7, 0x14, 0x9b, 0x23, 0x3d, 0xb7, 0xf9, 0x31, 0x5b, 0xd9, 0xa5, 0x14, 0x2b, + 0xfb, 0xfb, 0x16, 0x94, 0xe5, 0x18, 0x79, 0x0c, 0xb1, 0x95, 0xf7, 0x92, 0xb1, 0x95, 0xd7, 0x72, + 0x59, 0xc2, 0x07, 0x04, 0x56, 0xde, 0x83, 0x69, 0x33, 0xcf, 0x24, 0xf9, 0xb4, 0xb1, 0x05, 0x59, + 0xa3, 0x64, 0x6e, 0x53, 0x9b, 0x54, 0xbc, 0x3d, 0xd9, 0xbf, 0x56, 0xd2, 0xad, 0xc8, 0x0f, 0xf3, + 0xe6, 0xc8, 0xb7, 0x8e, 0x1c, 0xf9, 0xe6, 0xc0, 0x1b, 0xcb, 0x7f, 0xe0, 0xbd, 0x09, 0x53, 0x6a, + 0x59, 0x94, 0xda, 0xd4, 0xb3, 0xa6, 0x2b, 0x37, 0x53, 0xc9, 0x18, 0x31, 0x63, 0xba, 0xf0, 0x43, + 0x79, 0x6c, 0x2d, 0x57, 0xcb, 0xb5, 0x26, 0x43, 0xde, 0x81, 0xf2, 0x7d, 0x3f, 0xd8, 0x6d, 0xfb, + 0x0e, 0x7f, 0x43, 0x01, 0xf2, 0xf0, 0x1e, 0xd0, 0x16, 0x6f, 0x11, 0x4f, 0x73, 0x37, 0xa6, 0x8f, + 0x26, 0x33, 0x52, 0x85, 0xd9, 0x8e, 0xeb, 0x21, 0x75, 0x9a, 0x3a, 0x84, 0x72, 0x5c, 0xe4, 0x2f, + 0x57, 0x67, 0x8d, 0xf5, 0x24, 0x18, 0xd3, 0xf8, 0xdc, 0x1a, 0x16, 0x24, 0xcc, 0x2f, 0x32, 0x49, + 0xf1, 0xc6, 0xe8, 0x83, 0x31, 0x69, 0xd2, 0x11, 0x01, 0x25, 0xc9, 0x72, 0x4c, 0xf1, 0x26, 0x5f, + 0x80, 0xa9, 0x50, 0x3d, 0x0e, 0x59, 0xcc, 0xf1, 0x14, 0xa6, 0x1f, 0x88, 0xd4, 0x5d, 0xa9, 0x5f, + 0x88, 0xd4, 0x0c, 0xc9, 0x1a, 0x9c, 0x57, 0xf6, 0xa4, 0xc4, 0x3b, 0x77, 0x13, 0x71, 0xce, 0x31, + 0xcc, 0x80, 0x63, 0x66, 0x2d, 0xa6, 0xdb, 0xf2, 0xfc, 0xad, 0xe2, 0xb6, 0xd6, 0xb8, 0xe0, 0xe4, + 0xf3, 0xaf, 0x89, 0x12, 0x7a, 0x54, 0x84, 0xf0, 0xd4, 0x08, 0x11, 0xc2, 0x75, 0xb8, 0x90, 0x06, + 0xf1, 0x64, 0x72, 0x3c, 0x7f, 0x9d, 0xb1, 0x85, 0x6e, 0x64, 0x21, 0x61, 0x76, 0x5d, 0x72, 0x17, + 0x4a, 0x01, 0xe5, 0xa7, 0xce, 0xaa, 0x72, 0x74, 0x3b, 0xb6, 0x4b, 0x2f, 0x2a, 0x02, 0x18, 0xd3, + 0x62, 0xfd, 0xee, 0x24, 0x33, 0x8a, 0xbf, 0x99, 0xe3, 0xeb, 0xd1, 0xb2, 0xef, 0x07, 0x24, 0x79, + 0xb4, 0xff, 0xed, 0x2c, 0x9c, 0x49, 0x18, 0xc5, 0xc8, 0xb3, 0x50, 0xe4, 0xd9, 0xf5, 0xf8, 0x6a, + 0x35, 0x15, 0xaf, 0xa8, 0xa2, 0x71, 0x04, 0x8c, 0xfc, 0xbc, 0x05, 0xb3, 0xdd, 0xc4, 0x25, 0x8f, + 0x5a, 0xc8, 0x47, 0xb4, 0x24, 0x27, 0x6f, 0x8e, 0x8c, 0xb7, 0x38, 0x92, 0xcc, 0x30, 0xcd, 0x9d, + 0xad, 0x07, 0xd2, 0x2f, 0xbe, 0x4d, 0x03, 0x8e, 0x2d, 0x15, 0x3d, 0x4d, 0x62, 0x39, 0x09, 0xc6, + 0x34, 0x3e, 0xeb, 0x61, 0xfe, 0x75, 0xa3, 0xbc, 0x10, 0x5a, 0x55, 0x04, 0x30, 0xa6, 0x45, 0x5e, + 0x83, 0x19, 0x99, 0x48, 0x7a, 0xc3, 0x6f, 0xde, 0x70, 0xc2, 0x1d, 0x79, 0xe4, 0xd3, 0x47, 0xd4, + 0xe5, 0x04, 0x14, 0x53, 0xd8, 0xfc, 0xdb, 0xe2, 0x6c, 0xdd, 0x9c, 0xc0, 0x44, 0xf2, 0xa9, 0x92, + 0xe5, 0x24, 0x18, 0xd3, 0xf8, 0xe4, 0x05, 0x63, 0x1b, 0x12, 0x1e, 0x14, 0x7a, 0x35, 0xc8, 0xd8, + 0x8a, 0xaa, 0x30, 0xdb, 0xe3, 0x27, 0xe4, 0xa6, 0x02, 0xca, 0xf9, 0xa8, 0x19, 0xde, 0x49, 0x82, + 0x31, 0x8d, 0x4f, 0x5e, 0x85, 0x33, 0x01, 0x5b, 0x6c, 0x35, 0x01, 0xe1, 0x56, 0xa1, 0x6f, 0xcd, + 0xd1, 0x04, 0x62, 0x12, 0x97, 0xbc, 0x0e, 0x67, 0xe3, 0xbc, 0xab, 0x8a, 0x80, 0xf0, 0xb3, 0xd0, + 0x49, 0x00, 0xab, 0x69, 0x04, 0xec, 0xaf, 0x43, 0xfe, 0x1a, 0xcc, 0x19, 0x2d, 0xb1, 0xea, 0x35, + 0xe9, 0x03, 0x99, 0x1b, 0x93, 0x3f, 0xbd, 0xb5, 0x9c, 0x82, 0x61, 0x1f, 0x36, 0xf9, 0x24, 0xcc, + 0x34, 0xfc, 0x76, 0x9b, 0xaf, 0x71, 0xe2, 0x99, 0x0c, 0x91, 0x04, 0x53, 0xa4, 0x0b, 0x4d, 0x40, + 0x30, 0x85, 0x49, 0x6e, 0x02, 0xf1, 0xb7, 0x98, 0x7a, 0x45, 0x9b, 0xaf, 0x53, 0x8f, 0x4a, 0x8d, + 0xe3, 0x4c, 0x32, 0x2a, 0xe7, 0x76, 0x1f, 0x06, 0x66, 0xd4, 0xe2, 0x39, 0x04, 0x8d, 0x28, 0xe6, + 0x99, 0x3c, 0x9e, 0xb3, 0x4c, 0xdb, 0x73, 0x1e, 0x19, 0xc2, 0x1c, 0xc0, 0x84, 0x08, 0x92, 0xca, + 0x27, 0x1b, 0xa6, 0x99, 0x31, 0x3f, 0xde, 0x23, 0x44, 0x29, 0x4a, 0x4e, 0xe4, 0xe7, 0xa0, 0xb4, + 0xa5, 0x9e, 0x4f, 0xe1, 0x29, 0x30, 0x47, 0xde, 0x17, 0x53, 0x2f, 0x01, 0xc5, 0xf6, 0x0a, 0x0d, + 0xc0, 0x98, 0x25, 0x79, 0x0e, 0xca, 0x37, 0x36, 0xaa, 0x7a, 0x14, 0x9e, 0xe5, 0xbd, 0x3f, 0xce, + 0xaa, 0xa0, 0x09, 0x60, 0x33, 0x4c, 0xab, 0x6f, 0x24, 0xe9, 0x3a, 0x90, 0xa1, 0x8d, 0x31, 0x6c, + 0xee, 0x0b, 0x81, 0xf5, 0xf9, 0x73, 0x29, 0x6c, 0x59, 0x8e, 0x1a, 0x83, 0xbc, 0x0d, 0x65, 0xb9, + 0x5f, 0xf0, 0xb5, 0xe9, 0xfc, 0xc9, 0x22, 0xe4, 0x31, 0x26, 0x81, 0x26, 0x3d, 0x7e, 0x89, 0xcd, + 0x5f, 0x95, 0xa0, 0xd7, 0x7b, 0xed, 0xf6, 0xfc, 0x05, 0xbe, 0x6e, 0xc6, 0x97, 0xd8, 0x31, 0x08, + 0x4d, 0x3c, 0xf2, 0xa2, 0xf2, 0x69, 0x7b, 0x22, 0x71, 0xab, 0xaf, 0x7d, 0xda, 0xb4, 0xd2, 0x3d, + 0x20, 0x88, 0xe6, 0xc9, 0x47, 0x38, 0x93, 0x6d, 0xc1, 0x82, 0xd2, 0xf8, 0xfa, 0x27, 0xc9, 0xfc, + 0x7c, 0xc2, 0x76, 0xb4, 0x70, 0x77, 0x20, 0x26, 0x1e, 0x41, 0x85, 0x6c, 0x41, 0xc1, 0x69, 0x6f, + 0xcd, 0x3f, 0x95, 0x87, 0xea, 0x5a, 0x5d, 0xab, 0xc9, 0x11, 0xc5, 0x1d, 0x5f, 0xab, 0x6b, 0x35, + 0x64, 0xc4, 0x89, 0x0b, 0xe3, 0x4e, 0x7b, 0x2b, 0x9c, 0x5f, 0xe0, 0x73, 0x36, 0x37, 0x26, 0xb1, + 0xf1, 0x60, 0xad, 0x16, 0x22, 0x67, 0x61, 0x7f, 0x69, 0x4c, 0xdf, 0x5c, 0xe9, 0x84, 0xe4, 0xef, + 0x9a, 0x13, 0x48, 0x1c, 0x77, 0x6e, 0xe7, 0x36, 0x81, 0xa4, 0x7a, 0x71, 0x66, 0xe0, 0xf4, 0xe9, + 0xea, 0x25, 0x23, 0x97, 0x4c, 0x66, 0xc9, 0x64, 0xeb, 0xe2, 0xf4, 0x9c, 0x5c, 0x30, 0xec, 0x2f, + 0x97, 0xb5, 0x15, 0x34, 0xe5, 0x0f, 0x16, 0x40, 0xd1, 0x0d, 0x23, 0xd7, 0xcf, 0x31, 0x70, 0x3c, + 0x95, 0xa5, 0x9c, 0xc7, 0xa5, 0x70, 0x00, 0x0a, 0x56, 0x8c, 0xa7, 0xd7, 0x72, 0xbd, 0x07, 0xf2, + 0xf3, 0xdf, 0xcc, 0xdd, 0xd1, 0x4b, 0xf0, 0xe4, 0x00, 0x14, 0xac, 0xc8, 0x3d, 0x31, 0xa8, 0x0b, + 0x79, 0xf4, 0x75, 0x75, 0xad, 0x96, 0xe2, 0x97, 0x1c, 0xdc, 0xf7, 0xa0, 0x10, 0x76, 0x5c, 0xa9, + 0x2e, 0x8d, 0xc8, 0xab, 0xbe, 0xbe, 0x9a, 0xc5, 0xab, 0xbe, 0xbe, 0x8a, 0x8c, 0x09, 0xf9, 0xaa, + 0x05, 0xe0, 0x74, 0xb6, 0x9c, 0x30, 0x74, 0x9a, 0xda, 0x3a, 0x33, 0xe2, 0xeb, 0x23, 0x55, 0x4d, + 0x2f, 0xc5, 0x9a, 0xbb, 0x36, 0xc7, 0x50, 0x34, 0x38, 0x93, 0x77, 0x60, 0xd2, 0x11, 0xcf, 0x3b, + 0x4a, 0x2f, 0xfd, 0x7c, 0xde, 0x2c, 0x4d, 0x49, 0xc0, 0xcd, 0x34, 0x12, 0x84, 0x8a, 0x21, 0xe3, + 0x1d, 0x05, 0x0e, 0xdd, 0x76, 0x77, 0xa5, 0x71, 0xa8, 0x3e, 0xf2, 0x03, 0x24, 0x8c, 0x58, 0x16, + 0x6f, 0x09, 0x42, 0xc5, 0x50, 0xbc, 0xe6, 0xef, 0x78, 0x8e, 0x8e, 0xbd, 0xcc, 0x27, 0x42, 0xd7, + 0x8c, 0xe6, 0x34, 0x5e, 0xf3, 0x37, 0x19, 0x61, 0x92, 0x2f, 0xd9, 0x83, 0x09, 0x87, 0x3f, 0x3c, + 0x2b, 0x8f, 0x62, 0x98, 0xc7, 0x23, 0xb6, 0xa9, 0x36, 0xe0, 0x8b, 0x8b, 0x7c, 0xde, 0x56, 0x72, + 0x23, 0xbf, 0x62, 0xc1, 0xa4, 0x70, 0x20, 0x67, 0x0a, 0x29, 0xfb, 0xf6, 0xcf, 0x9d, 0xc2, 0x6b, + 0x07, 0xd2, 0xb9, 0x5d, 0xba, 0x44, 0x7d, 0x44, 0x7b, 0xc7, 0x8a, 0xd2, 0x23, 0xdd, 0xdb, 0x95, + 0x74, 0x4c, 0xf5, 0xed, 0x38, 0x0f, 0x12, 0xcf, 0xcb, 0x98, 0xaa, 0xef, 0x7a, 0x0a, 0x86, 0x7d, + 0xd8, 0x0b, 0x9f, 0x84, 0x69, 0x53, 0x8e, 0x63, 0xb9, 0xc8, 0xff, 0xb0, 0x00, 0xc0, 0xbb, 0x4a, + 0xe4, 0x6b, 0xe9, 0xf0, 0xe4, 0xce, 0x3b, 0x7e, 0x33, 0xa7, 0x67, 0x2e, 0x8d, 0xb4, 0x2b, 0x20, + 0x33, 0x39, 0xef, 0xf8, 0x4d, 0x94, 0x4c, 0x48, 0x0b, 0xc6, 0xbb, 0x4e, 0xb4, 0x93, 0x7f, 0x8e, + 0x97, 0x29, 0x11, 0xb8, 0x1c, 0xed, 0x20, 0x67, 0x40, 0xde, 0xb3, 0x62, 0x6f, 0xa3, 0x42, 0x3e, + 0x3e, 0x21, 0xaa, 0xcd, 0x16, 0xa5, 0x7f, 0x51, 0x2a, 0x4d, 0x6b, 0xda, 0xeb, 0x68, 0xe1, 0x7d, + 0x0b, 0xa6, 0x4d, 0xd4, 0x8c, 0x6e, 0xfa, 0x59, 0xb3, 0x9b, 0xf2, 0x6c, 0x0f, 0xb3, 0xc7, 0xff, + 0x9b, 0x05, 0x80, 0x3d, 0xaf, 0xde, 0xeb, 0x74, 0x98, 0xda, 0xae, 0x23, 0x01, 0xac, 0xa1, 0x23, + 0x01, 0xc6, 0x8e, 0x19, 0x09, 0x50, 0x38, 0x56, 0x24, 0xc0, 0xf8, 0xf1, 0x23, 0x01, 0x8a, 0x83, + 0x23, 0x01, 0xec, 0x6f, 0x59, 0x70, 0xb6, 0x6f, 0xbf, 0x62, 0x9a, 0x74, 0xe0, 0xfb, 0xd1, 0x00, + 0x2f, 0x52, 0x8c, 0x41, 0x68, 0xe2, 0x91, 0x15, 0x98, 0x93, 0x4f, 0x99, 0xd4, 0xbb, 0x6d, 0x37, + 0x33, 0xff, 0xce, 0x66, 0x0a, 0x8e, 0x7d, 0x35, 0xec, 0xdf, 0xb2, 0xa0, 0x6c, 0x44, 0xed, 0xb3, + 0xef, 0xe0, 0xae, 0xc4, 0x52, 0x8c, 0xf8, 0x15, 0x17, 0x7e, 0xd5, 0x25, 0x60, 0xe2, 0x1a, 0xba, + 0x65, 0x24, 0xba, 0x8f, 0xaf, 0xa1, 0x59, 0x29, 0x4a, 0xa8, 0x48, 0x61, 0x4e, 0xbb, 0xbc, 0xd1, + 0x0b, 0x66, 0x0a, 0x73, 0xda, 0x45, 0x0e, 0xe1, 0xec, 0xd8, 0x91, 0x42, 0x7a, 0x09, 0x1b, 0x8f, + 0xc6, 0x38, 0x41, 0x84, 0x02, 0x46, 0x2e, 0x42, 0x81, 0x7a, 0x4d, 0x69, 0xff, 0xd0, 0xcf, 0xba, + 0x5e, 0xf3, 0x9a, 0xc8, 0xca, 0xed, 0xdb, 0x30, 0x2d, 0x3c, 0xa4, 0xdf, 0xa0, 0xfb, 0x43, 0xbf, + 0x13, 0xcb, 0x46, 0x7b, 0xea, 0x9d, 0x58, 0x56, 0x9d, 0x95, 0xdb, 0xff, 0xd8, 0x82, 0xd4, 0xcb, + 0x46, 0xc6, 0x0d, 0x8c, 0x35, 0xf0, 0x06, 0xc6, 0xb4, 0xda, 0x8f, 0x1d, 0x69, 0xb5, 0xbf, 0x09, + 0xa4, 0xc3, 0xa6, 0x42, 0x72, 0xa1, 0x2d, 0x24, 0x9f, 0x9b, 0x58, 0xef, 0xc3, 0xc0, 0x8c, 0x5a, + 0xf6, 0x3f, 0x12, 0xc2, 0x9a, 0x6f, 0x1d, 0x3d, 0xba, 0x01, 0x7a, 0x50, 0xe4, 0xa4, 0xa4, 0xfd, + 0x6d, 0x44, 0xdb, 0x75, 0x7f, 0xae, 0xad, 0xb8, 0x23, 0xe5, 0x94, 0xe7, 0xdc, 0xec, 0xdf, 0x17, + 0xb2, 0x1a, 0x8f, 0x21, 0x0d, 0x21, 0x6b, 0x27, 0x29, 0xeb, 0x8d, 0xbc, 0xd6, 0xca, 0x6c, 0x19, + 0xc9, 0x22, 0x40, 0x97, 0x06, 0x0d, 0xea, 0x45, 0x2a, 0x76, 0xa9, 0x28, 0xa3, 0x68, 0x75, 0x29, + 0x1a, 0x18, 0xf6, 0x37, 0xd9, 0x04, 0x8a, 0x5f, 0x50, 0x26, 0x57, 0xd2, 0xee, 0xb7, 0xe9, 0xc9, + 0xa1, 0xbd, 0x6f, 0x8d, 0x88, 0x96, 0xb1, 0x47, 0x44, 0xb4, 0x3c, 0x0f, 0x93, 0x81, 0xdf, 0xa6, + 0xd5, 0xc0, 0x4b, 0xfb, 0x0c, 0x21, 0x2b, 0xc6, 0x5b, 0xa8, 0xe0, 0xf6, 0x2f, 0x59, 0x30, 0x97, + 0x0e, 0xb9, 0xcb, 0xdd, 0x27, 0xd8, 0xcc, 0x0b, 0x50, 0x38, 0x7e, 0x5e, 0x00, 0xfb, 0x3d, 0x26, + 0x64, 0xe4, 0x36, 0x76, 0x5d, 0x4f, 0x84, 0xd2, 0xb3, 0x96, 0x7b, 0x1e, 0x26, 0xa9, 0x7c, 0x09, + 0x56, 0x98, 0x91, 0xb5, 0x90, 0xea, 0x01, 0x58, 0x05, 0x27, 0x55, 0x98, 0x55, 0x97, 0x67, 0xca, + 0xf6, 0x2f, 0x52, 0x80, 0x68, 0x5b, 0xe3, 0x4a, 0x12, 0x8c, 0x69, 0x7c, 0xfb, 0x8b, 0x50, 0x36, + 0x36, 0x25, 0xbe, 0x7e, 0x3f, 0x70, 0x1a, 0x51, 0x7a, 0xdd, 0xbb, 0xc6, 0x0a, 0x51, 0xc0, 0xf8, + 0x15, 0x85, 0x88, 0x08, 0x4a, 0xad, 0x7b, 0x32, 0x0e, 0x48, 0x42, 0x19, 0xb1, 0x80, 0xb6, 0xe8, + 0x03, 0xf5, 0x0e, 0x81, 0x22, 0x86, 0xac, 0x10, 0x05, 0xcc, 0x7e, 0x01, 0xa6, 0x54, 0xa2, 0x26, + 0x9e, 0xed, 0x44, 0x99, 0xcf, 0xcd, 0x6c, 0x27, 0x7e, 0x10, 0x21, 0x87, 0xd8, 0x6f, 0xc1, 0x94, + 0xca, 0x27, 0xf5, 0x68, 0x6c, 0xb6, 0x14, 0x85, 0x9e, 0x7b, 0xc3, 0x0f, 0x23, 0x95, 0x04, 0x4b, + 0xdc, 0xf0, 0xdd, 0x5a, 0xe5, 0x65, 0xa8, 0xa1, 0xf6, 0x9f, 0x5a, 0x50, 0xde, 0xdc, 0x5c, 0xd3, + 0x07, 0x7f, 0x84, 0x27, 0x42, 0xd1, 0x42, 0xd5, 0xed, 0x88, 0x9a, 0xae, 0x04, 0x62, 0xe1, 0x5b, + 0x38, 0x3c, 0xa8, 0x3c, 0x51, 0xcf, 0xc4, 0xc0, 0x01, 0x35, 0xc9, 0x2a, 0x9c, 0x33, 0x21, 0x32, + 0x39, 0x81, 0x5c, 0x23, 0xf9, 0xd3, 0xc1, 0xf5, 0x7e, 0x30, 0x66, 0xd5, 0x49, 0x93, 0x92, 0xdb, + 0xbd, 0xf9, 0x0a, 0x71, 0xbd, 0x1f, 0x8c, 0x59, 0x75, 0xec, 0x17, 0x61, 0x36, 0x75, 0xc7, 0x3d, + 0x44, 0x52, 0x98, 0xdf, 0x29, 0xc0, 0xb4, 0x79, 0xd5, 0x39, 0xc4, 0xfa, 0x35, 0xfc, 0xb6, 0x90, + 0x71, 0x3d, 0x59, 0x38, 0xe6, 0xf5, 0xa4, 0x79, 0x1f, 0x3c, 0x7e, 0xba, 0xf7, 0xc1, 0xc5, 0x7c, + 0xee, 0x83, 0x0d, 0xbf, 0x85, 0x89, 0xc7, 0xe7, 0xb7, 0xf0, 0x9b, 0x45, 0x98, 0x49, 0x66, 0x19, + 0x1d, 0xa2, 0x27, 0x5f, 0xe8, 0xeb, 0xc9, 0x63, 0xde, 0x87, 0x14, 0x46, 0xbd, 0x0f, 0x19, 0x1f, + 0xf5, 0x3e, 0xa4, 0x78, 0x82, 0xfb, 0x90, 0xfe, 0xdb, 0x8c, 0x89, 0xa1, 0x6f, 0x33, 0x3e, 0xa5, + 0x5d, 0x3c, 0x27, 0x13, 0x2e, 0x40, 0xb1, 0x8b, 0x27, 0x49, 0x76, 0xc3, 0xb2, 0xdf, 0xcc, 0x74, + 0x95, 0x9d, 0x7a, 0x84, 0xdd, 0x37, 0xc8, 0xf4, 0xc8, 0x3c, 0xfe, 0x95, 0xeb, 0x13, 0xc7, 0xf0, + 0xc6, 0x7c, 0x19, 0xca, 0x72, 0x3c, 0x71, 0xe5, 0x1b, 0x92, 0x8a, 0x7b, 0x3d, 0x06, 0xa1, 0x89, + 0xc7, 0x06, 0x46, 0x37, 0x9e, 0x20, 0xfc, 0x66, 0xae, 0x9c, 0xbc, 0x99, 0xdb, 0x48, 0x82, 0x31, + 0x8d, 0x6f, 0x7f, 0x01, 0x2e, 0x64, 0x9a, 0x60, 0xb8, 0xf9, 0x9b, 0xeb, 0x85, 0xb4, 0x29, 0x11, + 0x0c, 0x31, 0x52, 0x8f, 0x8f, 0x2c, 0xdc, 0x1d, 0x88, 0x89, 0x47, 0x50, 0xb1, 0x7f, 0xbd, 0x00, + 0x33, 0xc9, 0x17, 0x68, 0xc9, 0x7d, 0x6d, 0xb0, 0xcd, 0xc5, 0x56, 0x2c, 0xc8, 0x1a, 0x99, 0x2b, + 0x07, 0x5e, 0xf4, 0xdc, 0xe7, 0xe3, 0x6b, 0x4b, 0xa7, 0xd1, 0x3c, 0x3d, 0xc6, 0xf2, 0x86, 0x45, + 0xb2, 0xe3, 0x8f, 0xcc, 0xc6, 0x41, 0xae, 0xf2, 0x1c, 0x9f, 0x3b, 0xf7, 0x38, 0x58, 0x53, 0xb3, + 0x42, 0x83, 0x2d, 0xdb, 0x5b, 0xf6, 0x68, 0xe0, 0x6e, 0xbb, 0xfa, 0xf5, 0x7c, 0xbe, 0x72, 0xbf, + 0x25, 0xcb, 0x50, 0x43, 0xed, 0xf7, 0xc6, 0xa0, 0xc4, 0x73, 0x72, 0x5d, 0x0f, 0xfc, 0x0e, 0x7f, + 0xa6, 0x31, 0x34, 0xce, 0x4c, 0xb2, 0xdb, 0x6e, 0x8e, 0xfa, 0x16, 0x6a, 0x4c, 0x51, 0xba, 0xdf, + 0x1b, 0x25, 0x98, 0xe0, 0x48, 0xba, 0x30, 0xb5, 0x2d, 0x73, 0x08, 0xcb, 0xbe, 0x1b, 0x31, 0x0f, + 0xa6, 0xca, 0x48, 0x2c, 0x9a, 0x40, 0xfd, 0x43, 0xcd, 0xc5, 0x76, 0x60, 0x36, 0x95, 0x54, 0x25, + 0xf7, 0xcc, 0xc3, 0xff, 0x73, 0x1c, 0x4a, 0x3a, 0xf6, 0x8b, 0x7c, 0x22, 0x61, 0xc0, 0x2a, 0xd5, + 0x3e, 0x6c, 0xbc, 0x21, 0xb6, 0xe3, 0x37, 0x1f, 0x1e, 0x54, 0x66, 0x35, 0x72, 0xca, 0x18, 0x75, + 0x11, 0x0a, 0xbd, 0xa0, 0x9d, 0x3e, 0xa1, 0xde, 0xc1, 0x35, 0x64, 0xe5, 0x66, 0xbc, 0x5a, 0xe1, + 0xb1, 0xc6, 0xab, 0xb1, 0x5d, 0x72, 0xcb, 0x6f, 0xee, 0xa7, 0xdf, 0x1c, 0xab, 0xf9, 0xcd, 0x7d, + 0xe4, 0x10, 0xf2, 0x1a, 0xcc, 0xc8, 0x20, 0x3c, 0xa5, 0xc4, 0x14, 0xb9, 0x9e, 0xaa, 0x1d, 0x17, + 0x36, 0x13, 0x50, 0x4c, 0x61, 0xb3, 0x5d, 0xf6, 0x5e, 0xe8, 0x7b, 0x3c, 0x9f, 0xf4, 0x44, 0xf2, + 0x96, 0xf3, 0x66, 0xfd, 0xf6, 0x2d, 0x6e, 0x48, 0xd3, 0x18, 0x89, 0x38, 0xbf, 0xc9, 0x47, 0xc6, + 0xf9, 0xad, 0x08, 0xda, 0x4c, 0x5a, 0xbe, 0xa3, 0x4c, 0xd7, 0xae, 0x28, 0xba, 0xac, 0xec, 0xe1, + 0xc1, 0x11, 0x46, 0x52, 0x5d, 0x33, 0x2b, 0x22, 0xb2, 0xf4, 0xe3, 0x8b, 0x88, 0xb4, 0xef, 0xc0, + 0x6c, 0xaa, 0xff, 0x94, 0x81, 0xc3, 0xca, 0x36, 0x70, 0x0c, 0xf7, 0x6a, 0xd9, 0x3f, 0xb5, 0xe0, + 0x6c, 0xdf, 0x8a, 0x34, 0x6c, 0x68, 0x6a, 0x7a, 0x6f, 0x1c, 0x3b, 0xf9, 0xde, 0x58, 0x38, 0xde, + 0xde, 0x58, 0xdb, 0xfa, 0xee, 0x0f, 0x2e, 0x7d, 0xe8, 0x7b, 0x3f, 0xb8, 0xf4, 0xa1, 0x3f, 0xf8, + 0xc1, 0xa5, 0x0f, 0xbd, 0x77, 0x78, 0xc9, 0xfa, 0xee, 0xe1, 0x25, 0xeb, 0x7b, 0x87, 0x97, 0xac, + 0x3f, 0x38, 0xbc, 0x64, 0xfd, 0xe7, 0xc3, 0x4b, 0xd6, 0xb7, 0xfe, 0xf8, 0xd2, 0x87, 0x3e, 0xfd, + 0xa9, 0xb8, 0xa7, 0x96, 0x54, 0x4f, 0xf1, 0x1f, 0x1f, 0x55, 0xfd, 0xb2, 0xd4, 0xdd, 0x6d, 0x2d, + 0xb1, 0x9e, 0x5a, 0xd2, 0x25, 0xaa, 0xa7, 0xfe, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0xcd, + 0x1f, 0xc0, 0x63, 0xa6, 0x00, 0x00, } func (m *ALBStatus) Marshal() (dAtA []byte, err error) { @@ -9125,6 +9126,11 @@ func (m *RolloutTrafficRouting) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxTrafficWeight != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.MaxTrafficWeight)) + i-- + dAtA[i] = 0x58 + } if len(m.Plugins) > 0 { keysForPlugins := make([]string, 0, len(m.Plugins)) for k := range m.Plugins { @@ -12352,6 +12358,9 @@ func (m *RolloutTrafficRouting) Size() (n int) { n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } + if m.MaxTrafficWeight != nil { + n += 1 + sovGenerated(uint64(*m.MaxTrafficWeight)) + } return n } @@ -14260,6 +14269,7 @@ func (this *RolloutTrafficRouting) String() string { `ManagedRoutes:` + repeatedStringForManagedRoutes + `,`, `Apisix:` + strings.Replace(this.Apisix.String(), "ApisixTrafficRouting", "ApisixTrafficRouting", 1) + `,`, `Plugins:` + mapStringForPlugins + `,`, + `MaxTrafficWeight:` + valueToStringGenerated(this.MaxTrafficWeight) + `,`, `}`, }, "") return s @@ -31598,6 +31608,26 @@ func (m *RolloutTrafficRouting) Unmarshal(dAtA []byte) error { } m.Plugins[mapkey] = ((encoding_json.RawMessage)(mapvalue)) iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxTrafficWeight", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.MaxTrafficWeight = &v 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 36eaf5f892..6e225848b9 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.proto +++ b/pkg/apis/rollouts/v1alpha1/generated.proto @@ -1606,6 +1606,9 @@ message RolloutTrafficRouting { // +kubebuilder:validation:Type=object // Plugins holds specific configuration that traffic router plugins can use for routing traffic map plugins = 10; + + // MaxTrafficWeight The total weight of traffic. If unspecified, it defaults to 100 + optional int32 maxTrafficWeight = 11; } message RouteMatch { diff --git a/pkg/apis/rollouts/v1alpha1/openapi_generated.go b/pkg/apis/rollouts/v1alpha1/openapi_generated.go index 4c70c15f08..1ccc09140f 100644 --- a/pkg/apis/rollouts/v1alpha1/openapi_generated.go +++ b/pkg/apis/rollouts/v1alpha1/openapi_generated.go @@ -4729,6 +4729,13 @@ func schema_pkg_apis_rollouts_v1alpha1_RolloutTrafficRouting(ref common.Referenc }, }, }, + "maxTrafficWeight": { + SchemaProps: spec.SchemaProps{ + Description: "MaxTrafficWeight The total weight of traffic. If unspecified, it defaults to 100", + Type: []string{"integer"}, + Format: "int32", + }, + }, }, }, }, diff --git a/pkg/apis/rollouts/v1alpha1/types.go b/pkg/apis/rollouts/v1alpha1/types.go index aedf8febca..32b8441689 100755 --- a/pkg/apis/rollouts/v1alpha1/types.go +++ b/pkg/apis/rollouts/v1alpha1/types.go @@ -379,11 +379,15 @@ type RolloutTrafficRouting struct { ManagedRoutes []MangedRoutes `json:"managedRoutes,omitempty" protobuf:"bytes,8,rep,name=managedRoutes"` // Apisix holds specific configuration to use Apisix to route traffic Apisix *ApisixTrafficRouting `json:"apisix,omitempty" protobuf:"bytes,9,opt,name=apisix"` + // +kubebuilder:validation:Schemaless // +kubebuilder:pruning:PreserveUnknownFields // +kubebuilder:validation:Type=object // Plugins holds specific configuration that traffic router plugins can use for routing traffic Plugins map[string]json.RawMessage `json:"plugins,omitempty" protobuf:"bytes,10,opt,name=plugins"` + + // MaxTrafficWeight The total weight of traffic. If unspecified, it defaults to 100 + MaxTrafficWeight *int32 `json:"maxTrafficWeight,omitempty" protobuf:"varint,11,opt,name=maxTrafficWeight"` } type MangedRoutes struct { diff --git a/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go index d8c859e20d..58d85887f3 100644 --- a/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/rollouts/v1alpha1/zz_generated.deepcopy.go @@ -2510,6 +2510,11 @@ func (in *RolloutTrafficRouting) DeepCopyInto(out *RolloutTrafficRouting) { (*out)[key] = outVal } } + if in.MaxTrafficWeight != nil { + in, out := &in.MaxTrafficWeight, &out.MaxTrafficWeight + *out = new(int32) + **out = **in + } return } diff --git a/pkg/apis/rollouts/validation/validation.go b/pkg/apis/rollouts/validation/validation.go index 54a7336566..76ab8d6c66 100644 --- a/pkg/apis/rollouts/validation/validation.go +++ b/pkg/apis/rollouts/validation/validation.go @@ -20,6 +20,7 @@ import ( "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" "github.com/argoproj/argo-rollouts/utils/defaults" + "github.com/argoproj/argo-rollouts/utils/weightutil" ) const ( @@ -27,8 +28,8 @@ const ( // MissingFieldMessage the message to indicate rollout is missing a field MissingFieldMessage = "Rollout has missing field '%s'" - // InvalidSetWeightMessage indicates the setweight value needs to be between 0 and 100 - InvalidSetWeightMessage = "SetWeight needs to be between 0 and 100" + // InvalidSetWeightMessage indicates the setweight value needs to be between 0 and max weight + InvalidSetWeightMessage = "SetWeight needs to be between 0 and %d" // InvalidCanaryExperimentTemplateWeightWithoutTrafficRouting indicates experiment weight cannot be set without trafficRouting InvalidCanaryExperimentTemplateWeightWithoutTrafficRouting = "Experiment template weight cannot be set unless TrafficRouting is enabled" // InvalidSetCanaryScaleTrafficPolicy indicates that TrafficRouting, required for SetCanaryScale, is missing @@ -72,6 +73,8 @@ const ( InvalidCanaryDynamicStableScale = "Canary dynamicStableScale can only be used with traffic routing" // InvalidCanaryDynamicStableScaleWithScaleDownDelay indicates that canary.dynamicStableScale cannot be used with scaleDownDelaySeconds InvalidCanaryDynamicStableScaleWithScaleDownDelay = "Canary dynamicStableScale cannot be used with scaleDownDelaySeconds" + // InvalidCanaryMaxWeightOnlySupportInNginxAndPlugins indicates that canary.maxTrafficWeight cannot be used + InvalidCanaryMaxWeightOnlySupportInNginxAndPlugins = "Canary maxTrafficWeight in traffic routing only supported in Nginx and Plugins" // InvalidPingPongProvidedMessage indicates that both ping and pong service must be set to use Ping-Pong feature InvalidPingPongProvidedMessage = "Ping service and Pong service must to be set to use Ping-Pong feature" // DuplicatedPingPongServicesMessage indicates that the rollout uses the same service for the ping and pong services @@ -295,6 +298,12 @@ func ValidateRolloutStrategyCanary(rollout *v1alpha1.Rollout, fldPath *field.Pat if canary.ScaleDownDelaySeconds != nil && canary.DynamicStableScale { allErrs = append(allErrs, field.Invalid(fldPath.Child("dynamicStableScale"), canary.DynamicStableScale, InvalidCanaryDynamicStableScaleWithScaleDownDelay)) } + // only the nginx and plugin have this support for now + if canary.TrafficRouting.MaxTrafficWeight != nil { + if canary.TrafficRouting.Nginx == nil && len(canary.TrafficRouting.Plugins) == 0 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("trafficRouting").Child("maxTrafficWeight"), canary.TrafficRouting.MaxTrafficWeight, InvalidCanaryMaxWeightOnlySupportInNginxAndPlugins)) + } + } } for i, step := range canary.Steps { @@ -306,8 +315,11 @@ func ValidateRolloutStrategyCanary(rollout *v1alpha1.Rollout, fldPath *field.Pat step.Experiment == nil, step.Pause == nil, step.SetWeight == nil, step.Analysis == nil, step.SetCanaryScale == nil, step.SetHeaderRoute == nil, step.SetMirrorRoute == nil) allErrs = append(allErrs, field.Invalid(stepFldPath, errVal, InvalidStepMessage)) } - if step.SetWeight != nil && (*step.SetWeight < 0 || *step.SetWeight > 100) { - allErrs = append(allErrs, field.Invalid(stepFldPath.Child("setWeight"), *canary.Steps[i].SetWeight, InvalidSetWeightMessage)) + + maxTrafficWeight := weightutil.MaxTrafficWeight(rollout) + + if step.SetWeight != nil && (*step.SetWeight < 0 || *step.SetWeight > maxTrafficWeight) { + allErrs = append(allErrs, field.Invalid(stepFldPath.Child("setWeight"), *canary.Steps[i].SetWeight, fmt.Sprintf(InvalidSetWeightMessage, maxTrafficWeight))) } if step.Pause != nil && step.Pause.DurationSeconds() < 0 { allErrs = append(allErrs, field.Invalid(stepFldPath.Child("pause").Child("duration"), step.Pause.DurationSeconds(), InvalidDurationMessage)) diff --git a/pkg/apis/rollouts/validation/validation_test.go b/pkg/apis/rollouts/validation/validation_test.go index 28f17c6858..5d5c19be5e 100644 --- a/pkg/apis/rollouts/validation/validation_test.go +++ b/pkg/apis/rollouts/validation/validation_test.go @@ -397,7 +397,59 @@ func TestValidateRolloutStrategyCanary(t *testing.T) { invalidRo := ro.DeepCopy() invalidRo.Spec.Strategy.Canary.Steps[0].SetWeight = &setWeight allErrs := ValidateRolloutStrategyCanary(invalidRo, field.NewPath("")) - assert.Equal(t, InvalidSetWeightMessage, allErrs[0].Detail) + assert.Equal(t, fmt.Sprintf(InvalidSetWeightMessage, 100), allErrs[0].Detail) + }) + + t.Run("only nginx/plugins support max weight value", func(t *testing.T) { + anyWeight := int32(1) + + type testCases struct { + trafficRouting *v1alpha1.RolloutTrafficRouting + expectError bool + expectedError string + } + + testCasesList := []testCases{ + { + trafficRouting: &v1alpha1.RolloutTrafficRouting{ + ALB: &v1alpha1.ALBTrafficRouting{RootService: "root-service"}, + MaxTrafficWeight: &anyWeight, + }, + expectError: true, + expectedError: InvalidCanaryMaxWeightOnlySupportInNginxAndPlugins, + }, + { + trafficRouting: &v1alpha1.RolloutTrafficRouting{ + Nginx: &v1alpha1.NginxTrafficRouting{ + StableIngress: "stable-ingress", + }, + MaxTrafficWeight: &anyWeight, + }, + expectError: false, + }, + { + trafficRouting: &v1alpha1.RolloutTrafficRouting{ + Plugins: map[string]json.RawMessage{ + "anyplugin": []byte(`{"key": "value"}`), + }, + MaxTrafficWeight: &anyWeight, + }, + expectError: false, + }, + } + + for _, testCase := range testCasesList { + invalidRo := ro.DeepCopy() + invalidRo.Spec.Strategy.Canary.Steps[0].SetWeight = &anyWeight + invalidRo.Spec.Strategy.Canary.TrafficRouting = testCase.trafficRouting + allErrs := ValidateRolloutStrategyCanary(invalidRo, field.NewPath("")) + if !testCase.expectError { + assert.Empty(t, allErrs) + continue + } + + assert.Equal(t, testCase.expectedError, allErrs[0].Detail) + } }) t.Run("invalid duration set in paused step", func(t *testing.T) { diff --git a/pkg/kubectl-argo-rollouts/info/rollout_info.go b/pkg/kubectl-argo-rollouts/info/rollout_info.go index 8afc8cf02f..5732972852 100644 --- a/pkg/kubectl-argo-rollouts/info/rollout_info.go +++ b/pkg/kubectl-argo-rollouts/info/rollout_info.go @@ -14,6 +14,7 @@ import ( "github.com/argoproj/argo-rollouts/utils/defaults" replicasetutil "github.com/argoproj/argo-rollouts/utils/replicaset" rolloututil "github.com/argoproj/argo-rollouts/utils/rollout" + "github.com/argoproj/argo-rollouts/utils/weightutil" ) func NewRolloutInfo( @@ -58,12 +59,12 @@ func NewRolloutInfo( currentStep, _ := replicasetutil.GetCurrentCanaryStep(ro) if currentStep == nil { - roInfo.ActualWeight = "100" + roInfo.ActualWeight = fmt.Sprintf("%d", weightutil.MaxTrafficWeight(ro)) } else if ro.Status.AvailableReplicas > 0 { if ro.Spec.Strategy.Canary.TrafficRouting == nil { for _, rs := range roInfo.ReplicaSets { if rs.Canary { - roInfo.ActualWeight = fmt.Sprintf("%d", (rs.Available*100)/ro.Status.AvailableReplicas) + roInfo.ActualWeight = fmt.Sprintf("%d", (rs.Available*weightutil.MaxTrafficWeight(ro))/ro.Status.AvailableReplicas) } } } else { diff --git a/rollout/canary_test.go b/rollout/canary_test.go index d92cfd2c17..f89f47494f 100644 --- a/rollout/canary_test.go +++ b/rollout/canary_test.go @@ -24,6 +24,7 @@ import ( "github.com/argoproj/argo-rollouts/utils/annotations" "github.com/argoproj/argo-rollouts/utils/conditions" "github.com/argoproj/argo-rollouts/utils/hash" + ingressutil "github.com/argoproj/argo-rollouts/utils/ingress" logutil "github.com/argoproj/argo-rollouts/utils/log" "github.com/argoproj/argo-rollouts/utils/record" replicasetutil "github.com/argoproj/argo-rollouts/utils/replicaset" @@ -550,6 +551,92 @@ func TestCanaryRolloutCreateFirstReplicasetWithSteps(t *testing.T) { assert.JSONEq(t, calculatePatch(r, expectedPatch), patch) } +func TestCanaryRolloutWithMaxWeightInTrafficRouting(t *testing.T) { + testCases := []struct { + name string + maxWeight *int32 + setWeight int32 + expectedCreatedReplicas int32 + expectedUpdatedReplicas int32 + }{ + { + name: "max weight 100", + maxWeight: int32Ptr(100), + setWeight: 10, + expectedCreatedReplicas: 0, + expectedUpdatedReplicas: 1, + }, + { + name: "max weight 1000", + maxWeight: int32Ptr(1000), + setWeight: 200, + expectedCreatedReplicas: 0, + expectedUpdatedReplicas: 2, + }, + } + + for _, tc := range testCases { + f := newFixture(t) + defer f.Close() + steps := []v1alpha1.CanaryStep{{ + SetWeight: int32Ptr(tc.setWeight), + }} + r1 := newCanaryRollout("foo", 10, nil, steps, int32Ptr(0), intstr.FromInt(1), intstr.FromInt(0)) + + canarySVCName := "canary" + stableSVCName := "stable" + + ingressName := "ingress" + r1.Spec.Strategy.Canary.TrafficRouting = &v1alpha1.RolloutTrafficRouting{ + MaxTrafficWeight: tc.maxWeight, + Nginx: &v1alpha1.NginxTrafficRouting{ + StableIngress: ingressName, + }, + } + r1.Spec.Strategy.Canary.StableService = stableSVCName + r1.Spec.Strategy.Canary.CanaryService = canarySVCName + r1.Status.StableRS = "895c6c4f9" + r2 := bumpVersion(r1) + + f.rolloutLister = append(f.rolloutLister, r2) + f.objects = append(f.objects, r2) + + rs1 := newReplicaSetWithStatus(r1, 10, 10) + rs2 := newReplicaSetWithStatus(r2, 1, 0) + + stableSvc := newService(stableSVCName, 80, + map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]}, r1) + + canarySvc := newService(canarySVCName, 80, + map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]}, r1) + f.replicaSetLister = append(f.replicaSetLister, rs1) + + ing := newIngress(ingressName, canarySvc, stableSvc) + ing.Spec.Rules[0].HTTP.Paths[0].Backend.ServiceName = stableSVCName + f.kubeobjects = append(f.kubeobjects, rs1, canarySvc, stableSvc, ing) + f.serviceLister = append(f.serviceLister, canarySvc, stableSvc) + f.ingressLister = append(f.ingressLister, ingressutil.NewLegacyIngress(ing)) + + createdRSIndex := f.expectCreateReplicaSetAction(rs2) + updatedRSIndex := f.expectUpdateReplicaSetAction(rs2) + updatedRolloutIndex := f.expectUpdateRolloutStatusAction(r2) + f.expectPatchRolloutAction(r2) + f.run(getKey(r2, t)) + + createdRS := f.getCreatedReplicaSet(createdRSIndex) + assert.Equal(t, tc.expectedCreatedReplicas, *createdRS.Spec.Replicas) + updatedRS := f.getUpdatedReplicaSet(updatedRSIndex) + assert.Equal(t, tc.expectedUpdatedReplicas, *updatedRS.Spec.Replicas) + + updatedRollout := f.getUpdatedRollout(updatedRolloutIndex) + progressingCondition := conditions.GetRolloutCondition(updatedRollout.Status, v1alpha1.RolloutProgressing) + assert.NotNil(t, progressingCondition) + assert.Equal(t, conditions.NewReplicaSetReason, progressingCondition.Reason) + assert.Equal(t, corev1.ConditionTrue, progressingCondition.Status) + assert.Equal(t, fmt.Sprintf(conditions.NewReplicaSetMessage, createdRS.Name), progressingCondition.Message) + } + +} func TestCanaryRolloutCreateNewReplicaWithCorrectWeight(t *testing.T) { f := newFixture(t) defer f.Close() diff --git a/rollout/trafficrouting.go b/rollout/trafficrouting.go index fe4f145ddd..55121ecc7f 100644 --- a/rollout/trafficrouting.go +++ b/rollout/trafficrouting.go @@ -26,6 +26,7 @@ import ( "github.com/argoproj/argo-rollouts/utils/record" replicasetutil "github.com/argoproj/argo-rollouts/utils/replicaset" rolloututil "github.com/argoproj/argo-rollouts/utils/rollout" + "github.com/argoproj/argo-rollouts/utils/weightutil" ) // NewTrafficRoutingReconciler identifies return the TrafficRouting Plugin that the rollout wants to modify @@ -132,6 +133,7 @@ func (c *Controller) NewTrafficRoutingReconciler(roCtx *rolloutContext) ([]traff return nil, nil } +// this currently only be used in the canary strategy func (c *rolloutContext) reconcileTrafficRouting() error { reconcilers, err := c.newTrafficRoutingReconciler(c) // a return here does ensure that all trafficReconcilers are healthy @@ -201,7 +203,7 @@ func (c *rolloutContext) reconcileTrafficRouting() error { // But we can only increase canary weight according to available replica counts of the canary. // we will need to set the desiredWeight to 0 when the newRS is not available. if c.rollout.Spec.Strategy.Canary.DynamicStableScale { - desiredWeight = (100 * c.newRS.Status.AvailableReplicas) / *c.rollout.Spec.Replicas + desiredWeight = (weightutil.MaxTrafficWeight(c.rollout) * c.newRS.Status.AvailableReplicas) / *c.rollout.Spec.Replicas } else if c.rollout.Status.Canary.Weights != nil { desiredWeight = c.rollout.Status.Canary.Weights.Canary.Weight } @@ -229,7 +231,7 @@ func (c *rolloutContext) reconcileTrafficRouting() error { desiredWeight = replicasetutil.GetCurrentSetWeight(c.rollout) weightDestinations = append(weightDestinations, c.calculateWeightDestinationsFromExperiment()...) } else { - desiredWeight = 100 + desiredWeight = weightutil.MaxTrafficWeight(c.rollout) } } // We need to check for revision > 1 because when we first install the rollout we run step 0 this prevents that. @@ -303,7 +305,7 @@ func (c *rolloutContext) calculateDesiredWeightOnAbortOrStableRollback() int32 { } // When using dynamic stable scaling, we must dynamically decreasing the weight to the canary // according to the availability of the stable (whatever it can support). - desiredWeight := 100 - ((100 * c.stableRS.Status.AvailableReplicas) / *c.rollout.Spec.Replicas) + desiredWeight := weightutil.MaxTrafficWeight(c.rollout) - ((weightutil.MaxTrafficWeight(c.rollout) * c.stableRS.Status.AvailableReplicas) / *c.rollout.Spec.Replicas) if c.rollout.Status.Canary.Weights != nil { // This ensures that if we are already at a lower weight, then we will not // increase the weight because stable availability is flapping (e.g. pod restarts) @@ -336,7 +338,7 @@ func calculateWeightStatus(ro *v1alpha1.Rollout, canaryHash, stableHash string, ServiceName: ro.Spec.Strategy.Canary.CanaryService, }, } - stableWeight := 100 - desiredWeight + stableWeight := weightutil.MaxTrafficWeight(ro) - desiredWeight for _, weightDest := range weightDestinations { weights.Additional = append(weights.Additional, weightDest) stableWeight -= weightDest.Weight diff --git a/rollout/trafficrouting/nginx/nginx.go b/rollout/trafficrouting/nginx/nginx.go index 3d56c55f6a..649931c258 100644 --- a/rollout/trafficrouting/nginx/nginx.go +++ b/rollout/trafficrouting/nginx/nginx.go @@ -133,6 +133,10 @@ func (r *Reconciler) buildCanaryIngress(stableIngress *networkingv1.Ingress, nam desiredCanaryIngress.Annotations[fmt.Sprintf("%s/canary", annotationPrefix)] = "true" desiredCanaryIngress.Annotations[fmt.Sprintf("%s/canary-weight", annotationPrefix)] = fmt.Sprintf("%d", desiredWeight) + if r.cfg.Rollout.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight != nil { + weightTotal := *r.cfg.Rollout.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight + desiredCanaryIngress.Annotations[fmt.Sprintf("%s/canary-weight-total", annotationPrefix)] = fmt.Sprintf("%d", weightTotal) + } return ingressutil.NewIngress(desiredCanaryIngress), nil } @@ -209,6 +213,10 @@ func (r *Reconciler) buildLegacyCanaryIngress(stableIngress *extensionsv1beta1.I desiredCanaryIngress.Annotations[fmt.Sprintf("%s/canary", annotationPrefix)] = "true" desiredCanaryIngress.Annotations[fmt.Sprintf("%s/canary-weight", annotationPrefix)] = fmt.Sprintf("%d", desiredWeight) + if r.cfg.Rollout.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight != nil { + weightTotal := *r.cfg.Rollout.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight + desiredCanaryIngress.Annotations[fmt.Sprintf("%s/canary-weight-total", annotationPrefix)] = fmt.Sprintf("%d", weightTotal) + } return ingressutil.NewLegacyIngress(desiredCanaryIngress), nil } diff --git a/rollout/trafficrouting/nginx/nginx_test.go b/rollout/trafficrouting/nginx/nginx_test.go index 2be80fa23a..c3b4ce357a 100644 --- a/rollout/trafficrouting/nginx/nginx_test.go +++ b/rollout/trafficrouting/nginx/nginx_test.go @@ -574,6 +574,52 @@ func TestCanaryIngressAdditionalAnnotations(t *testing.T) { } } +func TestCanaryIngressMaxWeightInTrafficRouting(t *testing.T) { + maxWeights := []*int32{nil, pointer.Int32(1000)} + for _, maxWeight := range maxWeights { + tests := generateMultiIngressTestData() + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := Reconciler{ + cfg: ReconcilerConfig{ + Rollout: fakeRollout(stableService, canaryService, test.singleIngress, test.multiIngress), + }, + } + r.cfg.Rollout.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight = maxWeight + for _, ing := range test.ingresses { + stable := extensionsIngress(ing, 80, stableService) + canary := extensionsIngress("canary-ingress", 80, canaryService) + canary.SetAnnotations(map[string]string{ + "nginx.ingress.kubernetes.io/canary": "true", + "nginx.ingress.kubernetes.io/canary-weight": "10", + }) + stableIngress := ingressutil.NewLegacyIngress(stable) + canaryIngress := ingressutil.NewLegacyIngress(canary) + + desiredCanaryIngress, err := r.canaryIngress(stableIngress, ingressutil.GetCanaryIngressName(r.cfg.Rollout.GetName(), ing), 15) + assert.Nil(t, err, "No error returned when calling canaryIngress") + + checkBackendService(t, desiredCanaryIngress, canaryService) + + patch, modified, err := ingressutil.BuildIngressPatch(canaryIngress.Mode(), canaryIngress, desiredCanaryIngress, + ingressutil.WithAnnotations(), ingressutil.WithLabels(), ingressutil.WithSpec()) + assert.Nil(t, err, "compareCanaryIngresses returns no error") + assert.True(t, modified, "compareCanaryIngresses returns modified=true") + if maxWeight == nil { + assert.Equal(t, + "{\"metadata\":{\"annotations\":{\"nginx.ingress.kubernetes.io/canary-weight\":\"15\"}}}", string(patch), "compareCanaryIngresses returns expected patch") + } else { + assert.Equal(t, + fmt.Sprintf("{\"metadata\":{\"annotations\":{\"nginx.ingress.kubernetes.io/canary-weight\":\"15\",\"nginx.ingress.kubernetes.io/canary-weight-total\":\"%d\"}}}", *maxWeight), + string(patch), "compareCanaryIngresses returns expected patch") + } + } + }) + } + } + +} + func TestReconciler_canaryIngress(t *testing.T) { tests := generateMultiIngressTestData() for _, test := range tests { diff --git a/ui/src/models/rollout/generated/api.ts b/ui/src/models/rollout/generated/api.ts index cf9a9cdfc5..2e657d455e 100755 --- a/ui/src/models/rollout/generated/api.ts +++ b/ui/src/models/rollout/generated/api.ts @@ -2495,6 +2495,12 @@ export interface GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutTraf * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutTrafficRouting */ plugins?: { [key: string]: string; }; + /** + * + * @type {number} + * @memberof GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1RolloutTrafficRouting + */ + maxTrafficWeight?: number; } /** * diff --git a/utils/replicaset/canary.go b/utils/replicaset/canary.go index d38a5d23a7..89ba648cf2 100755 --- a/utils/replicaset/canary.go +++ b/utils/replicaset/canary.go @@ -10,6 +10,7 @@ import ( "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" "github.com/argoproj/argo-rollouts/utils/defaults" + "github.com/argoproj/argo-rollouts/utils/weightutil" ) const ( @@ -56,7 +57,7 @@ func AtDesiredReplicaCountsForCanary(ro *v1alpha1.Rollout, newRS, stableRS *apps // when using the basic canary strategy. The function calculates the desired number of replicas for // the new and stable RS using the following equations: // -// desired newRS Replica count = spec.Replica * (setweight / 100) +// desired newRS Replica count = spec.Replica * (setweight / maxweight) // desired stableRS Replica count = spec.Replica - newRS // // The function for newRS finds the closest whole number of replicas based on the weight percentage @@ -92,8 +93,9 @@ func CalculateReplicaCountsForBasicCanary(rollout *v1alpha1.Rollout, newRS *apps rolloutSpecReplica := defaults.GetReplicasOrDefault(rollout.Spec.Replicas) _, desiredWeight := GetCanaryReplicasOrWeight(rollout) maxSurge := MaxSurge(rollout) + maxWeight := weightutil.MaxTrafficWeight(rollout) - desiredNewRSReplicaCount, desiredStableRSReplicaCount := approximateWeightedCanaryStableReplicaCounts(rolloutSpecReplica, desiredWeight, maxSurge) + desiredNewRSReplicaCount, desiredStableRSReplicaCount := approximateWeightedCanaryStableReplicaCounts(rolloutSpecReplica, desiredWeight, maxWeight, maxSurge) stableRSReplicaCount := int32(0) newRSReplicaCount := int32(0) @@ -181,7 +183,7 @@ func CalculateReplicaCountsForBasicCanary(rollout *v1alpha1.Rollout, newRS *apps // canary/stable replica counts might sum to either spec.replicas or spec.replicas + 1 but will not // exceed spec.replicas if maxSurge is 0. If the canary weight is between 1-99, and spec.replicas is > 1, // we will always return a minimum of 1 for stable and canary as to not return 0. -func approximateWeightedCanaryStableReplicaCounts(specReplicas, desiredWeight, maxSurge int32) (int32, int32) { +func approximateWeightedCanaryStableReplicaCounts(specReplicas, desiredWeight, maxWeight, maxSurge int32) (int32, int32) { if specReplicas == 0 { return 0, 0 } @@ -193,14 +195,14 @@ func approximateWeightedCanaryStableReplicaCounts(specReplicas, desiredWeight, m } var options []canaryOption - ceilWeightedCanaryCount := int32(math.Ceil(float64(specReplicas*desiredWeight) / 100.0)) - floorWeightedCanaryCount := int32(math.Floor(float64(specReplicas*desiredWeight) / 100.0)) + ceilWeightedCanaryCount := int32(math.Ceil(float64(specReplicas*desiredWeight) / float64(maxWeight))) + floorWeightedCanaryCount := int32(math.Floor(float64(specReplicas*desiredWeight) / float64(maxWeight))) - tied := floorCeilingTied(desiredWeight, specReplicas) + tied := floorCeilingTied(desiredWeight, maxWeight, specReplicas) // zeroAllowed indicates if are allowed to return the floored value if it is zero. We don't allow // the value to be zero if when user has a weight from 1-99, and they run 2+ replicas (surge included) - zeroAllowed := desiredWeight == 100 || desiredWeight == 0 || (specReplicas == 1 && maxSurge == 0) + zeroAllowed := desiredWeight == (maxWeight) || desiredWeight == 0 || (specReplicas == 1 && maxSurge == 0) if ceilWeightedCanaryCount < specReplicas || zeroAllowed { options = append(options, canaryOption{ceilWeightedCanaryCount, specReplicas}) @@ -214,7 +216,7 @@ func approximateWeightedCanaryStableReplicaCounts(specReplicas, desiredWeight, m // in order to achieve a closer canary weight if maxSurge > 0 { options = append(options, canaryOption{ceilWeightedCanaryCount, specReplicas + 1}) - surgeIsTied := floorCeilingTied(desiredWeight, specReplicas+1) + surgeIsTied := floorCeilingTied(desiredWeight, maxWeight, specReplicas+1) if !surgeIsTied && (floorWeightedCanaryCount != 0 || zeroAllowed) { options = append(options, canaryOption{floorWeightedCanaryCount, specReplicas + 1}) } @@ -226,10 +228,10 @@ func approximateWeightedCanaryStableReplicaCounts(specReplicas, desiredWeight, m } bestOption := options[0] - bestDelta := weightDelta(desiredWeight, bestOption.canary, bestOption.total) + bestDelta := weightDelta(desiredWeight, maxWeight, bestOption.canary, bestOption.total) for i := 1; i < len(options); i++ { currOption := options[i] - currDelta := weightDelta(desiredWeight, currOption.canary, currOption.total) + currDelta := weightDelta(desiredWeight, maxWeight, currOption.canary, currOption.total) if currDelta < bestDelta { bestOption = currOption bestDelta = currDelta @@ -242,15 +244,15 @@ func approximateWeightedCanaryStableReplicaCounts(specReplicas, desiredWeight, m // For example: replicas: 3, desiredWeight: 50% // A canary count of 1 (33.33%) or 2 (66.66%) are both equidistant from desired weight of 50%. // When this happens, we will pick the larger canary count -func floorCeilingTied(desiredWeight, totalReplicas int32) bool { - _, frac := math.Modf(float64(totalReplicas) * (float64(desiredWeight) / 100)) +func floorCeilingTied(desiredWeight, maxWeight, totalReplicas int32) bool { + _, frac := math.Modf(float64(totalReplicas) * (float64(desiredWeight) / float64(maxWeight))) return frac == 0.5 } // weightDelta calculates the difference that the canary replicas will be from the desired weight // This is used to pick the closest approximation of canary counts. -func weightDelta(desiredWeight, canaryReplicas, totalReplicas int32) float64 { - actualWeight := float64(canaryReplicas*100) / float64(totalReplicas) +func weightDelta(desiredWeight, maxWeight, canaryReplicas, totalReplicas int32) float64 { + actualWeight := float64(canaryReplicas*maxWeight) / float64(totalReplicas) return math.Abs(actualWeight - float64(desiredWeight)) } @@ -338,11 +340,12 @@ func CalculateReplicaCountsForTrafficRoutedCanary(rollout *v1alpha1.Rollout, wei var canaryCount, stableCount int32 rolloutSpecReplica := defaults.GetReplicasOrDefault(rollout.Spec.Replicas) setCanaryScaleReplicas, desiredWeight := GetCanaryReplicasOrWeight(rollout) + maxWeight := weightutil.MaxTrafficWeight(rollout) if setCanaryScaleReplicas != nil { // a canary count was explicitly set canaryCount = *setCanaryScaleReplicas } else { - canaryCount = CheckMinPodsPerReplicaSet(rollout, trafficWeightToReplicas(rolloutSpecReplica, desiredWeight)) + canaryCount = CheckMinPodsPerReplicaSet(rollout, trafficWeightToReplicas(rolloutSpecReplica, desiredWeight, maxWeight)) } if !rollout.Spec.Strategy.Canary.DynamicStableScale { @@ -358,9 +361,10 @@ func CalculateReplicaCountsForTrafficRoutedCanary(rollout *v1alpha1.Rollout, wei // high, until we reduce traffic to it. // Case 2 occurs when we are going from high to low canary weight. In this scenario, // we need to increase the stable scale in preparation for increase of traffic to stable. - stableCount = trafficWeightToReplicas(rolloutSpecReplica, 100-desiredWeight) + // TODO calculate the replica set count from the max traffic weight. + stableCount = trafficWeightToReplicas(rolloutSpecReplica, maxWeight-desiredWeight, maxWeight) if weights != nil { - actualStableWeightReplicaCount := trafficWeightToReplicas(rolloutSpecReplica, weights.Stable.Weight) + actualStableWeightReplicaCount := trafficWeightToReplicas(rolloutSpecReplica, weights.Stable.Weight, maxWeight) stableCount = max(stableCount, actualStableWeightReplicaCount) if rollout.Status.Abort { @@ -369,7 +373,7 @@ func CalculateReplicaCountsForTrafficRoutedCanary(rollout *v1alpha1.Rollout, wei // 1. actual canary traffic weight // 2. desired canary traffic weight // This if block makes sure we don't scale down the canary prematurely - trafficWeightReplicaCount := trafficWeightToReplicas(rolloutSpecReplica, weights.Canary.Weight) + trafficWeightReplicaCount := trafficWeightToReplicas(rolloutSpecReplica, weights.Canary.Weight, maxWeight) canaryCount = max(trafficWeightReplicaCount, canaryCount) } } @@ -378,8 +382,8 @@ func CalculateReplicaCountsForTrafficRoutedCanary(rollout *v1alpha1.Rollout, wei // trafficWeightToReplicas returns the appropriate replicas given the full spec.replicas and a weight // Rounds up if not evenly divisible. -func trafficWeightToReplicas(replicas, weight int32) int32 { - return int32(math.Ceil(float64(weight*replicas) / 100)) +func trafficWeightToReplicas(replicas, weight, maxWeight int32) int32 { + return int32(math.Ceil(float64(weight*replicas) / float64(maxWeight))) } func max(left, right int32) int32 { @@ -460,7 +464,7 @@ func GetCurrentCanaryStep(rollout *v1alpha1.Rollout) (*v1alpha1.CanaryStep, *int // GetCanaryReplicasOrWeight either returns a static set of replicas or a weight percentage func GetCanaryReplicasOrWeight(rollout *v1alpha1.Rollout) (*int32, int32) { if rollout.Status.PromoteFull || rollout.Status.StableRS == "" || rollout.Status.CurrentPodHash == rollout.Status.StableRS { - return nil, 100 + return nil, weightutil.MaxTrafficWeight(rollout) } if scs := UseSetCanaryScale(rollout); scs != nil { if scs.Replicas != nil { @@ -481,7 +485,7 @@ func GetCurrentSetWeight(rollout *v1alpha1.Rollout) int32 { } currentStep, currentStepIndex := GetCurrentCanaryStep(rollout) if currentStep == nil { - return 100 + return weightutil.MaxTrafficWeight(rollout) } for i := *currentStepIndex; i >= 0; i-- { diff --git a/utils/replicaset/canary_test.go b/utils/replicaset/canary_test.go index ed4f78697a..d1d49072e8 100755 --- a/utils/replicaset/canary_test.go +++ b/utils/replicaset/canary_test.go @@ -769,82 +769,83 @@ func TestApproximateWeightedNewStableReplicaCounts(t *testing.T) { tests := []struct { replicas int32 weight int32 + maxWeight int32 maxSurge int32 expCanary int32 expStable int32 }{ - {replicas: 0, weight: 0, maxSurge: 0, expCanary: 0, expStable: 0}, // 0% - {replicas: 0, weight: 50, maxSurge: 0, expCanary: 0, expStable: 0}, // 0% - {replicas: 0, weight: 100, maxSurge: 0, expCanary: 0, expStable: 0}, // 0% - - {replicas: 0, weight: 0, maxSurge: 1, expCanary: 0, expStable: 0}, // 0% - {replicas: 0, weight: 50, maxSurge: 1, expCanary: 0, expStable: 0}, // 0% - {replicas: 0, weight: 100, maxSurge: 1, expCanary: 0, expStable: 0}, // 0% - - {replicas: 1, weight: 0, maxSurge: 0, expCanary: 0, expStable: 1}, // 0% - {replicas: 1, weight: 1, maxSurge: 0, expCanary: 0, expStable: 1}, // 0% - {replicas: 1, weight: 49, maxSurge: 0, expCanary: 0, expStable: 1}, // 0% - {replicas: 1, weight: 50, maxSurge: 0, expCanary: 1, expStable: 0}, // 100% - {replicas: 1, weight: 99, maxSurge: 0, expCanary: 1, expStable: 0}, // 100% - {replicas: 1, weight: 100, maxSurge: 0, expCanary: 1, expStable: 0}, // 100% - - {replicas: 1, weight: 0, maxSurge: 1, expCanary: 0, expStable: 1}, // 0% - {replicas: 1, weight: 1, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% - {replicas: 1, weight: 49, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% - {replicas: 1, weight: 50, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% - {replicas: 1, weight: 99, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% - {replicas: 1, weight: 100, maxSurge: 1, expCanary: 1, expStable: 0}, // 100% - - {replicas: 2, weight: 0, maxSurge: 0, expCanary: 0, expStable: 2}, // 0% - {replicas: 2, weight: 1, maxSurge: 0, expCanary: 1, expStable: 1}, // 50% - {replicas: 2, weight: 50, maxSurge: 0, expCanary: 1, expStable: 1}, // 50% - {replicas: 2, weight: 99, maxSurge: 0, expCanary: 1, expStable: 1}, // 50% - {replicas: 2, weight: 100, maxSurge: 0, expCanary: 2, expStable: 0}, // 100% - - {replicas: 2, weight: 0, maxSurge: 1, expCanary: 0, expStable: 2}, // 0% - {replicas: 2, weight: 1, maxSurge: 1, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 2, weight: 50, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% - {replicas: 2, weight: 99, maxSurge: 1, expCanary: 2, expStable: 1}, // 66.6% - {replicas: 2, weight: 100, maxSurge: 1, expCanary: 2, expStable: 0}, // 100% - - {replicas: 3, weight: 10, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 25, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 33, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 34, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 49, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 50, maxSurge: 0, expCanary: 2, expStable: 1}, // 66.6% - - {replicas: 3, weight: 10, maxSurge: 1, expCanary: 1, expStable: 3}, // 25% - {replicas: 3, weight: 25, maxSurge: 1, expCanary: 1, expStable: 3}, // 25% - {replicas: 3, weight: 33, maxSurge: 1, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 34, maxSurge: 1, expCanary: 1, expStable: 2}, // 33.3% - {replicas: 3, weight: 49, maxSurge: 1, expCanary: 2, expStable: 2}, // 50% - {replicas: 3, weight: 50, maxSurge: 1, expCanary: 2, expStable: 2}, // 50% - - {replicas: 10, weight: 0, maxSurge: 1, expCanary: 0, expStable: 10}, // 0% - {replicas: 10, weight: 1, maxSurge: 0, expCanary: 1, expStable: 9}, // 10% - {replicas: 10, weight: 14, maxSurge: 0, expCanary: 1, expStable: 9}, // 10% - {replicas: 10, weight: 15, maxSurge: 0, expCanary: 2, expStable: 8}, // 20% - {replicas: 10, weight: 16, maxSurge: 0, expCanary: 2, expStable: 8}, // 20% - {replicas: 10, weight: 99, maxSurge: 0, expCanary: 9, expStable: 1}, // 90% - {replicas: 10, weight: 100, maxSurge: 1, expCanary: 10, expStable: 0}, // 100% - - {replicas: 10, weight: 0, maxSurge: 1, expCanary: 0, expStable: 10}, // 0% - {replicas: 10, weight: 1, maxSurge: 1, expCanary: 1, expStable: 10}, // 9.1% - {replicas: 10, weight: 18, maxSurge: 1, expCanary: 2, expStable: 9}, // 18.1% - {replicas: 10, weight: 19, maxSurge: 1, expCanary: 2, expStable: 9}, // 18.1% - {replicas: 10, weight: 20, maxSurge: 1, expCanary: 2, expStable: 8}, // 20% - {replicas: 10, weight: 23, maxSurge: 1, expCanary: 2, expStable: 8}, // 20% - {replicas: 10, weight: 24, maxSurge: 1, expCanary: 3, expStable: 8}, // 27.2% - {replicas: 10, weight: 25, maxSurge: 1, expCanary: 3, expStable: 8}, // 27.2% - {replicas: 10, weight: 99, maxSurge: 1, expCanary: 10, expStable: 1}, // 90.9% - {replicas: 10, weight: 100, maxSurge: 1, expCanary: 10, expStable: 0}, // 100% + {replicas: 0, weight: 0, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 0}, // 0% + {replicas: 0, weight: 50, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 0}, // 0% + {replicas: 0, weight: 100, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 0}, // 0% + + {replicas: 0, weight: 0, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 0}, // 0% + {replicas: 0, weight: 50, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 0}, // 0% + {replicas: 0, weight: 100, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 0}, // 0% + + {replicas: 1, weight: 0, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 1}, // 0% + {replicas: 1, weight: 1, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 1}, // 0% + {replicas: 1, weight: 49, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 1}, // 0% + {replicas: 1, weight: 50, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 0}, // 100% + {replicas: 1, weight: 99, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 0}, // 100% + {replicas: 1, weight: 100, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 0}, // 100% + + {replicas: 1, weight: 0, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 1}, // 0% + {replicas: 1, weight: 1, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% + {replicas: 1, weight: 49, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% + {replicas: 1, weight: 50, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% + {replicas: 1, weight: 99, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% + {replicas: 1, weight: 100, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 0}, // 100% + + {replicas: 2, weight: 0, maxWeight: 100, maxSurge: 0, expCanary: 0, expStable: 2}, // 0% + {replicas: 2, weight: 1, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 1}, // 50% + {replicas: 2, weight: 50, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 1}, // 50% + {replicas: 2, weight: 99, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 1}, // 50% + {replicas: 2, weight: 100, maxWeight: 100, maxSurge: 0, expCanary: 2, expStable: 0}, // 100% + + {replicas: 2, weight: 0, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 2}, // 0% + {replicas: 2, weight: 1, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 2, weight: 50, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 1}, // 50% + {replicas: 2, weight: 99, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 1}, // 66.6% + {replicas: 2, weight: 100, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 0}, // 100% + + {replicas: 3, weight: 10, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 25, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 33, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 34, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 49, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 50, maxWeight: 100, maxSurge: 0, expCanary: 2, expStable: 1}, // 66.6% + + {replicas: 3, weight: 10, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 3}, // 25% + {replicas: 3, weight: 25, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 3}, // 25% + {replicas: 3, weight: 33, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 34, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 2}, // 33.3% + {replicas: 3, weight: 49, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 2}, // 50% + {replicas: 3, weight: 50, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 2}, // 50% + + {replicas: 10, weight: 0, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 10}, // 0% + {replicas: 10, weight: 1, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 9}, // 10% + {replicas: 10, weight: 14, maxWeight: 100, maxSurge: 0, expCanary: 1, expStable: 9}, // 10% + {replicas: 10, weight: 15, maxWeight: 100, maxSurge: 0, expCanary: 2, expStable: 8}, // 20% + {replicas: 10, weight: 16, maxWeight: 100, maxSurge: 0, expCanary: 2, expStable: 8}, // 20% + {replicas: 10, weight: 99, maxWeight: 100, maxSurge: 0, expCanary: 9, expStable: 1}, // 90% + {replicas: 10, weight: 100, maxWeight: 100, maxSurge: 1, expCanary: 10, expStable: 0}, // 100% + + {replicas: 10, weight: 0, maxWeight: 100, maxSurge: 1, expCanary: 0, expStable: 10}, // 0% + {replicas: 10, weight: 1, maxWeight: 100, maxSurge: 1, expCanary: 1, expStable: 10}, // 9.1% + {replicas: 10, weight: 18, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 9}, // 18.1% + {replicas: 10, weight: 19, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 9}, // 18.1% + {replicas: 10, weight: 20, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 8}, // 20% + {replicas: 10, weight: 23, maxWeight: 100, maxSurge: 1, expCanary: 2, expStable: 8}, // 20% + {replicas: 10, weight: 24, maxWeight: 100, maxSurge: 1, expCanary: 3, expStable: 8}, // 27.2% + {replicas: 10, weight: 25, maxWeight: 100, maxSurge: 1, expCanary: 3, expStable: 8}, // 27.2% + {replicas: 10, weight: 99, maxWeight: 100, maxSurge: 1, expCanary: 10, expStable: 1}, // 90.9% + {replicas: 10, weight: 100, maxWeight: 100, maxSurge: 1, expCanary: 10, expStable: 0}, // 100% } for i := range tests { test := tests[i] - t.Run(fmt.Sprintf("%s_replicas:%d_weight:%d_surge:%d", t.Name(), test.replicas, test.weight, test.maxSurge), func(t *testing.T) { - newRSReplicaCount, stableRSReplicaCount := approximateWeightedCanaryStableReplicaCounts(test.replicas, test.weight, test.maxSurge) + t.Run(fmt.Sprintf("%s_replicas:%d_weight:%d_maxweight:%d_surge:%d", t.Name(), test.replicas, test.weight, test.maxWeight, test.maxSurge), func(t *testing.T) { + newRSReplicaCount, stableRSReplicaCount := approximateWeightedCanaryStableReplicaCounts(test.replicas, test.weight, test.maxWeight, test.maxSurge) assert.Equal(t, test.expCanary, newRSReplicaCount, "check canary replica count") assert.Equal(t, test.expStable, stableRSReplicaCount, "check stable replica count") }) @@ -953,12 +954,12 @@ func TestCalculateReplicaCountsForCanaryStableRSdEdgeCases(t *testing.T) { } func TestTrafficWeightToReplicas(t *testing.T) { - assert.Equal(t, int32(0), trafficWeightToReplicas(10, 0)) - assert.Equal(t, int32(2), trafficWeightToReplicas(10, 20)) - assert.Equal(t, int32(3), trafficWeightToReplicas(10, 25)) - assert.Equal(t, int32(4), trafficWeightToReplicas(10, 33)) - assert.Equal(t, int32(10), trafficWeightToReplicas(10, 99)) - assert.Equal(t, int32(10), trafficWeightToReplicas(10, 100)) + assert.Equal(t, int32(0), trafficWeightToReplicas(10, 0, 100)) + assert.Equal(t, int32(2), trafficWeightToReplicas(10, 20, 100)) + assert.Equal(t, int32(3), trafficWeightToReplicas(10, 25, 100)) + assert.Equal(t, int32(4), trafficWeightToReplicas(10, 33, 100)) + assert.Equal(t, int32(10), trafficWeightToReplicas(10, 99, 100)) + assert.Equal(t, int32(10), trafficWeightToReplicas(10, 100, 100)) } func TestGetOtherRSs(t *testing.T) { diff --git a/utils/weightutil/weight.go b/utils/weightutil/weight.go new file mode 100644 index 0000000000..357a5fdcd3 --- /dev/null +++ b/utils/weightutil/weight.go @@ -0,0 +1,13 @@ +package weightutil + +import ( + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" +) + +func MaxTrafficWeight(ro *v1alpha1.Rollout) int32 { + maxWeight := int32(100) + if ro.Spec.Strategy.Canary != nil && ro.Spec.Strategy.Canary.TrafficRouting != nil && ro.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight != nil { + maxWeight = *ro.Spec.Strategy.Canary.TrafficRouting.MaxTrafficWeight + } + return maxWeight +}