diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index db394d985a34..9bc3955815d5 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -284,6 +284,14 @@ const ( // Allows running an ephemeral container in pod namespaces to troubleshoot a running pod. EphemeralContainers featuregate.Feature = "EphemeralContainers" + // owner: @harche + // kep: http://kep.k8s.io/3386 + // alpha: v1.25 + // + // Allows using event-driven PLEG (pod lifecycle event generator) through kubelet + // which avoids frequent relisting of containers which helps optimize performance. + EventedPLEG featuregate.Feature = "EventedPLEG" + // owner: @andrewsykim @SergeyKanzhelev // GA: v1.20 // @@ -914,6 +922,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS EphemeralContainers: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 + EventedPLEG: {Default: false, PreRelease: featuregate.Alpha}, + ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update ExpandCSIVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.26 diff --git a/pkg/kubelet/container/cache.go b/pkg/kubelet/container/cache.go index ef760826b209..a43f07b31ab5 100644 --- a/pkg/kubelet/container/cache.go +++ b/pkg/kubelet/container/cache.go @@ -21,6 +21,8 @@ import ( "time" "k8s.io/apimachinery/pkg/types" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" ) // Cache stores the PodStatus for the pods. It represents *all* the visible @@ -36,7 +38,10 @@ import ( // cache entries. type Cache interface { Get(types.UID) (*PodStatus, error) - Set(types.UID, *PodStatus, error, time.Time) + // Set updates the cache by setting the PodStatus for the pod only + // if the data is newer than the cache based on the provided + // time stamp. Returns if the cache was updated. + Set(types.UID, *PodStatus, error, time.Time) (updated bool) // GetNewerThan is a blocking call that only returns the status // when it is newer than the given time. GetNewerThan(types.UID, time.Time) (*PodStatus, error) @@ -93,12 +98,22 @@ func (c *cache) GetNewerThan(id types.UID, minTime time.Time) (*PodStatus, error return d.status, d.err } -// Set sets the PodStatus for the pod. -func (c *cache) Set(id types.UID, status *PodStatus, err error, timestamp time.Time) { +// Set sets the PodStatus for the pod only if the data is newer than the cache +func (c *cache) Set(id types.UID, status *PodStatus, err error, timestamp time.Time) (updated bool) { c.lock.Lock() defer c.lock.Unlock() - defer c.notify(id, timestamp) + + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + // Set the value in the cache only if it's not present already + // or the timestamp in the cache is older than the current update timestamp + if cachedVal, ok := c.pods[id]; ok && cachedVal.modified.After(timestamp) { + return false + } + } + c.pods[id] = &data{status: status, err: err, modified: timestamp} + c.notify(id, timestamp) + return true } // Delete removes the entry of the pod. @@ -142,6 +157,29 @@ func (c *cache) get(id types.UID) *data { // Otherwise, it returns nil. The caller should acquire the lock. func (c *cache) getIfNewerThan(id types.UID, minTime time.Time) *data { d, ok := c.pods[id] + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + // Evented PLEG has CREATED, STARTED, STOPPED and DELETED events + // However if the container creation fails for some reason there is no + // CRI event received by the kubelet and that pod will get stuck a + // GetNewerThan call in the pod workers. This is reproducible with + // the node e2e test, + // https://github.com/kubernetes/kubernetes/blob/83415e5c9e6e59a3d60a148160490560af2178a1/test/e2e_node/pod_hostnamefqdn_test.go#L161 + // which forces failure during pod creation. This issue also exists in + // Generic PLEG but since it updates global timestamp periodically + // the GetNewerThan call gets unstuck. + + // During node e2e tests, it was observed this change does not have any + // adverse impact on the behaviour of the Generic PLEG as well. + switch { + case !ok: + return makeDefaultData(id) + case ok && (d.modified.After(minTime) || (c.timestamp != nil && c.timestamp.After(minTime))): + return d + default: + return nil + } + } + globalTimestampIsNewer := (c.timestamp != nil && c.timestamp.After(minTime)) if !ok && globalTimestampIsNewer { // Status is not cached, but the global timestamp is newer than diff --git a/pkg/kubelet/container/runtime.go b/pkg/kubelet/container/runtime.go index 4fee4ba6eafd..d4398ae04d88 100644 --- a/pkg/kubelet/container/runtime.go +++ b/pkg/kubelet/container/runtime.go @@ -122,6 +122,8 @@ type Runtime interface { // CheckpointContainer tells the runtime to checkpoint a container // and store the resulting archive to the checkpoint directory. CheckpointContainer(ctx context.Context, options *runtimeapi.CheckpointContainerRequest) error + // Generate pod status from the CRI event + GeneratePodStatus(event *runtimeapi.ContainerEventResponse) (*PodStatus, error) } // StreamingRuntime is the interface implemented by runtimes that handle the serving of the @@ -305,6 +307,8 @@ type PodStatus struct { // Status of the pod sandbox. // Only for kuberuntime now, other runtime may keep it nil. SandboxStatuses []*runtimeapi.PodSandboxStatus + // Timestamp at which container and pod statuses were recorded + TimeStamp time.Time } // Status represents the status of a container. diff --git a/pkg/kubelet/container/testing/fake_cache.go b/pkg/kubelet/container/testing/fake_cache.go index c940e4ba9781..457a94111535 100644 --- a/pkg/kubelet/container/testing/fake_cache.go +++ b/pkg/kubelet/container/testing/fake_cache.go @@ -40,7 +40,8 @@ func (c *fakeCache) GetNewerThan(id types.UID, minTime time.Time) (*container.Po return c.Get(id) } -func (c *fakeCache) Set(id types.UID, status *container.PodStatus, err error, timestamp time.Time) { +func (c *fakeCache) Set(id types.UID, status *container.PodStatus, err error, timestamp time.Time) (updated bool) { + return true } func (c *fakeCache) Delete(id types.UID) { diff --git a/pkg/kubelet/container/testing/fake_runtime.go b/pkg/kubelet/container/testing/fake_runtime.go index bafb63107307..2525bb9e52d8 100644 --- a/pkg/kubelet/container/testing/fake_runtime.go +++ b/pkg/kubelet/container/testing/fake_runtime.go @@ -276,6 +276,15 @@ func (f *FakeRuntime) KillContainerInPod(container v1.Container, pod *v1.Pod) er return f.Err } +func (f *FakeRuntime) GeneratePodStatus(event *runtimeapi.ContainerEventResponse) (*kubecontainer.PodStatus, error) { + f.Lock() + defer f.Unlock() + + f.CalledFunctions = append(f.CalledFunctions, "GeneratePodStatus") + status := f.PodStatus + return &status, f.Err +} + func (f *FakeRuntime) GetPodStatus(_ context.Context, uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error) { f.Lock() defer f.Unlock() diff --git a/pkg/kubelet/container/testing/runtime_mock.go b/pkg/kubelet/container/testing/runtime_mock.go index bf2701b85541..60ed691757e1 100644 --- a/pkg/kubelet/container/testing/runtime_mock.go +++ b/pkg/kubelet/container/testing/runtime_mock.go @@ -168,6 +168,21 @@ func (mr *MockRuntimeMockRecorder) GarbageCollect(ctx, gcPolicy, allSourcesReady return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GarbageCollect", reflect.TypeOf((*MockRuntime)(nil).GarbageCollect), ctx, gcPolicy, allSourcesReady, evictNonDeletedPods) } +// GeneratePodStatus mocks base method. +func (m *MockRuntime) GeneratePodStatus(event *v10.ContainerEventResponse) (*container.PodStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GeneratePodStatus", event) + ret0, _ := ret[0].(*container.PodStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GeneratePodStatus indicates an expected call of GeneratePodStatus. +func (mr *MockRuntimeMockRecorder) GeneratePodStatus(event interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GeneratePodStatus", reflect.TypeOf((*MockRuntime)(nil).GeneratePodStatus), event) +} + // GetContainerLogs mocks base method. func (m *MockRuntime) GetContainerLogs(ctx context.Context, pod *v1.Pod, containerID container.ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error { m.ctrl.T.Helper() diff --git a/pkg/kubelet/cri/remote/remote_runtime.go b/pkg/kubelet/cri/remote/remote_runtime.go index 5379c77b1b62..561d5e4e73ca 100644 --- a/pkg/kubelet/cri/remote/remote_runtime.go +++ b/pkg/kubelet/cri/remote/remote_runtime.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "io" "strings" "time" @@ -792,5 +793,25 @@ func (r *remoteRuntimeService) CheckpointContainer(ctx context.Context, options } func (r *remoteRuntimeService) GetContainerEvents(containerEventsCh chan *runtimeapi.ContainerEventResponse) error { - return nil + containerEventsStreamingClient, err := r.runtimeClient.GetContainerEvents(context.Background(), &runtimeapi.GetEventsRequest{}) + if err != nil { + klog.ErrorS(err, "GetContainerEvents failed to get streaming client") + return err + } + + for { + resp, err := containerEventsStreamingClient.Recv() + if err == io.EOF { + klog.ErrorS(err, "container events stream is closed") + return err + } + if err != nil { + klog.ErrorS(err, "failed to receive streaming container event") + return err + } + if resp != nil { + containerEventsCh <- resp + klog.V(4).InfoS("container event received", "resp", resp) + } + } } diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 870223a575d2..e71eeb6efcc2 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -162,7 +162,13 @@ const ( // Note that even though we set the period to 1s, the relisting itself can // take more than 1s to finish if the container runtime responds slowly // and/or when there are many container changes in one cycle. - plegRelistPeriod = time.Second * 1 + genericPlegRelistPeriod = time.Second * 1 + genericPlegRelistThreshold = time.Minute * 3 + + // Generic PLEG relist period and threshold when used with Evented PLEG. + eventedPlegRelistPeriod = time.Second * 300 + eventedPlegRelistThreshold = time.Minute * 10 + eventedPlegMaxStreamRetries = 5 // backOffPeriod is the period to back off when pod syncing results in an // error. It is also used as the base period for the exponential backoff @@ -699,9 +705,37 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, utilfeature.DefaultFeatureGate.Enabled(features.PodAndContainerStatsFromCRI)) } - klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{}) + eventChannel := make(chan *pleg.PodLifecycleEvent, plegChannelCapacity) + + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + // adjust Generic PLEG relisting period and threshold to higher value when Evented PLEG is turned on + genericRelistDuration := &pleg.RelistDuration{ + RelistPeriod: eventedPlegRelistPeriod, + RelistThreshold: eventedPlegRelistThreshold, + } + klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, eventChannel, genericRelistDuration, klet.podCache, clock.RealClock{}) + // In case Evented PLEG has to fall back on Generic PLEG due to an error, + // Evented PLEG should be able to reset the Generic PLEG relisting duration + // to the default value. + eventedRelistDuration := &pleg.RelistDuration{ + RelistPeriod: genericPlegRelistPeriod, + RelistThreshold: genericPlegRelistThreshold, + } + klet.eventedPleg = pleg.NewEventedPLEG(klet.containerRuntime, klet.runtimeService, eventChannel, + klet.podCache, klet.pleg, eventedPlegMaxStreamRetries, eventedRelistDuration, clock.RealClock{}) + } else { + genericRelistDuration := &pleg.RelistDuration{ + RelistPeriod: genericPlegRelistPeriod, + RelistThreshold: genericPlegRelistThreshold, + } + klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, eventChannel, genericRelistDuration, klet.podCache, clock.RealClock{}) + } + klet.runtimeState = newRuntimeState(maxWaitForContainerRuntime) klet.runtimeState.addHealthCheck("PLEG", klet.pleg.Healthy) + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + klet.runtimeState.addHealthCheck("EventedPLEG", klet.eventedPleg.Healthy) + } if _, err := klet.updatePodCIDR(ctx, kubeCfg.PodCIDR); err != nil { klog.ErrorS(err, "Pod CIDR update failed") } @@ -1062,6 +1096,9 @@ type Kubelet struct { // Generates pod events. pleg pleg.PodLifecycleEventGenerator + // Evented PLEG + eventedPleg pleg.PodLifecycleEventGenerator + // Store kubecontainer.PodStatus for all pods. podCache kubecontainer.Cache @@ -1485,6 +1522,12 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { // Start the pod lifecycle event generator. kl.pleg.Start() + + // Start eventedPLEG only if EventedPLEG feature gate is enabled. + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + kl.eventedPleg.Start() + } + kl.syncLoop(ctx, updates, kl) } diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index d6d8692f9f0b..119fc00450a5 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -313,7 +313,7 @@ func newTestKubeletWithImageList( kubelet.resyncInterval = 10 * time.Second kubelet.workQueue = queue.NewBasicWorkQueue(fakeClock) // Relist period does not affect the tests. - kubelet.pleg = pleg.NewGenericPLEG(fakeRuntime, 100, time.Hour, kubelet.podCache, clock.RealClock{}) + kubelet.pleg = pleg.NewGenericPLEG(fakeRuntime, make(chan *pleg.PodLifecycleEvent, 100), &pleg.RelistDuration{RelistPeriod: time.Hour, RelistThreshold: genericPlegRelistThreshold}, kubelet.podCache, clock.RealClock{}) kubelet.clock = fakeClock nodeRef := &v1.ObjectReference{ diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 9c042bc02848..8ab8b557eb1f 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -490,6 +490,29 @@ func (m *kubeGenericRuntimeManager) readLastStringFromContainerLogs(path string) return buf.String() } +func (m *kubeGenericRuntimeManager) convertToKubeContainerStatus(status *runtimeapi.ContainerStatus) (cStatus *kubecontainer.Status) { + cStatus = toKubeContainerStatus(status, m.runtimeName) + if status.State == runtimeapi.ContainerState_CONTAINER_EXITED { + // Populate the termination message if needed. + annotatedInfo := getContainerInfoFromAnnotations(status.Annotations) + // If a container cannot even be started, it certainly does not have logs, so no need to fallbackToLogs. + fallbackToLogs := annotatedInfo.TerminationMessagePolicy == v1.TerminationMessageFallbackToLogsOnError && + cStatus.ExitCode != 0 && cStatus.Reason != "ContainerCannotRun" + tMessage, checkLogs := getTerminationMessage(status, annotatedInfo.TerminationMessagePath, fallbackToLogs) + if checkLogs { + tMessage = m.readLastStringFromContainerLogs(status.GetLogPath()) + } + // Enrich the termination message written by the application is not empty + if len(tMessage) != 0 { + if len(cStatus.Message) != 0 { + cStatus.Message += ": " + } + cStatus.Message += tMessage + } + } + return cStatus +} + // getPodContainerStatuses gets all containers' statuses for the pod. func (m *kubeGenericRuntimeManager) getPodContainerStatuses(ctx context.Context, uid kubetypes.UID, name, namespace string) ([]*kubecontainer.Status, error) { // Select all containers of the given pod. @@ -521,25 +544,7 @@ func (m *kubeGenericRuntimeManager) getPodContainerStatuses(ctx context.Context, if status == nil { return nil, remote.ErrContainerStatusNil } - cStatus := toKubeContainerStatus(status, m.runtimeName) - if status.State == runtimeapi.ContainerState_CONTAINER_EXITED { - // Populate the termination message if needed. - annotatedInfo := getContainerInfoFromAnnotations(status.Annotations) - // If a container cannot even be started, it certainly does not have logs, so no need to fallbackToLogs. - fallbackToLogs := annotatedInfo.TerminationMessagePolicy == v1.TerminationMessageFallbackToLogsOnError && - cStatus.ExitCode != 0 && cStatus.Reason != "ContainerCannotRun" - tMessage, checkLogs := getTerminationMessage(status, annotatedInfo.TerminationMessagePath, fallbackToLogs) - if checkLogs { - tMessage = m.readLastStringFromContainerLogs(status.GetLogPath()) - } - // Enrich the termination message written by the application is not empty - if len(tMessage) != 0 { - if len(cStatus.Message) != 0 { - cStatus.Message += ": " - } - cStatus.Message += tMessage - } - } + cStatus := m.convertToKubeContainerStatus(status) statuses = append(statuses, cStatus) } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index c901271318cd..90f66b519204 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -34,6 +34,7 @@ import ( kubetypes "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilversion "k8s.io/apimachinery/pkg/util/version" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/record" ref "k8s.io/client-go/tools/reference" "k8s.io/client-go/util/flowcontrol" @@ -43,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/credentialprovider" "k8s.io/kubernetes/pkg/credentialprovider/plugin" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/events" @@ -967,6 +969,26 @@ func (m *kubeGenericRuntimeManager) killPodWithSyncResult(ctx context.Context, p return } +func (m *kubeGenericRuntimeManager) GeneratePodStatus(event *runtimeapi.ContainerEventResponse) (*kubecontainer.PodStatus, error) { + podIPs := m.determinePodSandboxIPs(event.PodSandboxStatus.Metadata.Namespace, event.PodSandboxStatus.Metadata.Name, event.PodSandboxStatus) + + kubeContainerStatuses := []*kubecontainer.Status{} + for _, status := range event.ContainersStatuses { + kubeContainerStatuses = append(kubeContainerStatuses, m.convertToKubeContainerStatus(status)) + } + + sort.Sort(containerStatusByCreated(kubeContainerStatuses)) + + return &kubecontainer.PodStatus{ + ID: kubetypes.UID(event.PodSandboxStatus.Metadata.Uid), + Name: event.PodSandboxStatus.Metadata.Name, + Namespace: event.PodSandboxStatus.Metadata.Namespace, + IPs: podIPs, + SandboxStatuses: []*runtimeapi.PodSandboxStatus{event.PodSandboxStatus}, + ContainerStatuses: kubeContainerStatuses, + }, nil +} + // GetPodStatus retrieves the status of the pod, including the // information of all containers in the pod that are visible in Runtime. func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubetypes.UID, name, namespace string) (*kubecontainer.PodStatus, error) { @@ -1001,6 +1023,9 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety klog.V(4).InfoS("getSandboxIDByPodUID got sandbox IDs for pod", "podSandboxID", podSandboxIDs, "pod", klog.KObj(pod)) sandboxStatuses := []*runtimeapi.PodSandboxStatus{} + containerStatuses := []*kubecontainer.Status{} + var timestamp time.Time + podIPs := []string{} for idx, podSandboxID := range podSandboxIDs { resp, err := m.runtimeService.PodSandboxStatus(ctx, podSandboxID, false) @@ -1024,16 +1049,45 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety if idx == 0 && resp.Status.State == runtimeapi.PodSandboxState_SANDBOX_READY { podIPs = m.determinePodSandboxIPs(namespace, name, resp.Status) } + + if idx == 0 && utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + if resp.Timestamp == 0 { + // If the Evented PLEG is enabled in the kubelet, but not in the runtime + // then the pod status we get will not have the timestamp set. + // e.g. CI job 'pull-kubernetes-e2e-gce-alpha-features' will runs with + // features gate enabled, which includes Evented PLEG, but uses the + // runtime without Evented PLEG support. + klog.V(4).InfoS("Runtime does not set pod status timestamp", "pod", klog.KObj(pod)) + containerStatuses, err = m.getPodContainerStatuses(ctx, uid, name, namespace) + if err != nil { + if m.logReduction.ShouldMessageBePrinted(err.Error(), podFullName) { + klog.ErrorS(err, "getPodContainerStatuses for pod failed", "pod", klog.KObj(pod)) + } + return nil, err + } + } else { + // Get the statuses of all containers visible to the pod and + // timestamp from sandboxStatus. + timestamp = time.Unix(resp.Timestamp, 0) + for _, cs := range resp.ContainersStatuses { + cStatus := m.convertToKubeContainerStatus(cs) + containerStatuses = append(containerStatuses, cStatus) + } + } + } } - // Get statuses of all containers visible in the pod. - containerStatuses, err := m.getPodContainerStatuses(ctx, uid, name, namespace) - if err != nil { - if m.logReduction.ShouldMessageBePrinted(err.Error(), podFullName) { - klog.ErrorS(err, "getPodContainerStatuses for pod failed", "pod", klog.KObj(pod)) + if !utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + // Get statuses of all containers visible in the pod. + containerStatuses, err = m.getPodContainerStatuses(ctx, uid, name, namespace) + if err != nil { + if m.logReduction.ShouldMessageBePrinted(err.Error(), podFullName) { + klog.ErrorS(err, "getPodContainerStatuses for pod failed", "pod", klog.KObj(pod)) + } + return nil, err } - return nil, err } + m.logReduction.ClearID(podFullName) return &kubecontainer.PodStatus{ @@ -1043,6 +1097,7 @@ func (m *kubeGenericRuntimeManager) GetPodStatus(ctx context.Context, uid kubety IPs: podIPs, SandboxStatuses: sandboxStatuses, ContainerStatuses: containerStatuses, + TimeStamp: timestamp, }, nil } diff --git a/pkg/kubelet/pleg/evented.go b/pkg/kubelet/pleg/evented.go new file mode 100644 index 000000000000..e100765559ce --- /dev/null +++ b/pkg/kubelet/pleg/evented.go @@ -0,0 +1,398 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pleg + +import ( + "fmt" + "sync" + "time" + + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + internalapi "k8s.io/cri-api/pkg/apis" + runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" + "k8s.io/klog/v2" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/metrics" + "k8s.io/utils/clock" +) + +// The frequency with which global timestamp of the cache is to +// is to be updated periodically. If pod workers get stuck at cache.GetNewerThan +// call, after this period it will be unblocked. +const globalCacheUpdatePeriod = 5 * time.Second + +var ( + eventedPLEGUsage = false + eventedPLEGUsageMu = sync.RWMutex{} +) + +// isEventedPLEGInUse indicates whether Evented PLEG is in use. Even after enabling +// the Evented PLEG feature gate, there could be several reasons it may not be in use. +// e.g. Streaming data issues from the runtime or the runtime does not implement the +// container events stream. +func isEventedPLEGInUse() bool { + eventedPLEGUsageMu.Lock() + defer eventedPLEGUsageMu.Unlock() + return eventedPLEGUsage +} + +// setEventedPLEGUsage should only be accessed from +// Start/Stop of Evented PLEG. +func setEventedPLEGUsage(enable bool) { + eventedPLEGUsageMu.RLock() + defer eventedPLEGUsageMu.RUnlock() + eventedPLEGUsage = enable +} + +type EventedPLEG struct { + // The container runtime. + runtime kubecontainer.Runtime + // The runtime service. + runtimeService internalapi.RuntimeService + // The channel from which the subscriber listens events. + eventChannel chan *PodLifecycleEvent + // Cache for storing the runtime states required for syncing pods. + cache kubecontainer.Cache + // For testability. + clock clock.Clock + // GenericPLEG is used to force relist when required. + genericPleg PodLifecycleEventGenerator + // The maximum number of retries when getting container events from the runtime. + eventedPlegMaxStreamRetries int + // Indicates relisting related parameters + relistDuration *RelistDuration + // Stop the Evented PLEG by closing the channel. + stopCh chan struct{} + // Stops the periodic update of the cache global timestamp. + stopCacheUpdateCh chan struct{} + // Locks the start/stop operation of the Evented PLEG. + runningMu sync.Mutex +} + +// NewEventedPLEG instantiates a new EventedPLEG object and return it. +func NewEventedPLEG(runtime kubecontainer.Runtime, runtimeService internalapi.RuntimeService, eventChannel chan *PodLifecycleEvent, + cache kubecontainer.Cache, genericPleg PodLifecycleEventGenerator, eventedPlegMaxStreamRetries int, + relistDuration *RelistDuration, clock clock.Clock) PodLifecycleEventGenerator { + return &EventedPLEG{ + runtime: runtime, + runtimeService: runtimeService, + eventChannel: eventChannel, + cache: cache, + genericPleg: genericPleg, + eventedPlegMaxStreamRetries: eventedPlegMaxStreamRetries, + relistDuration: relistDuration, + clock: clock, + } +} + +// Watch returns a channel from which the subscriber can receive PodLifecycleEvent events. +func (e *EventedPLEG) Watch() chan *PodLifecycleEvent { + return e.eventChannel +} + +// Relist relists all containers using GenericPLEG +func (e *EventedPLEG) Relist() { + e.genericPleg.Relist() +} + +// Start starts the Evented PLEG +func (e *EventedPLEG) Start() { + e.runningMu.Lock() + defer e.runningMu.Unlock() + if isEventedPLEGInUse() { + return + } + setEventedPLEGUsage(true) + e.stopCh = make(chan struct{}) + e.stopCacheUpdateCh = make(chan struct{}) + go wait.Until(e.watchEventsChannel, 0, e.stopCh) + go wait.Until(e.updateGlobalCache, globalCacheUpdatePeriod, e.stopCacheUpdateCh) +} + +// Stop stops the Evented PLEG +func (e *EventedPLEG) Stop() { + e.runningMu.Lock() + defer e.runningMu.Unlock() + if !isEventedPLEGInUse() { + return + } + setEventedPLEGUsage(false) + close(e.stopCh) + close(e.stopCacheUpdateCh) +} + +// In case the Evented PLEG experiences undetectable issues in the underlying +// GRPC connection there is a remote chance the pod might get stuck in a +// given state while it has progressed in its life cycle. This function will be +// called periodically to update the global timestamp of the cache so that those +// pods stuck at GetNewerThan in pod workers will get unstuck. +func (e *EventedPLEG) updateGlobalCache() { + e.cache.UpdateTime(time.Now()) +} + +// Update the relisting period and threshold +func (e *EventedPLEG) Update(relistDuration *RelistDuration) { + e.genericPleg.Update(relistDuration) +} + +// Healthy check if PLEG work properly. +func (e *EventedPLEG) Healthy() (bool, error) { + // GenericPLEG is declared unhealthy when relisting time is more + // than the relistThreshold. In case EventedPLEG is turned on, + // relistingPeriod and relistingThreshold are adjusted to higher + // values. So the health check of Generic PLEG should check + // the adjusted values of relistingPeriod and relistingThreshold. + + // EventedPLEG is declared unhealthy only if eventChannel is out of capacity. + if len(e.eventChannel) == cap(e.eventChannel) { + return false, fmt.Errorf("EventedPLEG: pleg event channel capacity is full with %v events", len(e.eventChannel)) + } + + timestamp := e.clock.Now() + metrics.PLEGLastSeen.Set(float64(timestamp.Unix())) + return true, nil +} + +func (e *EventedPLEG) watchEventsChannel() { + containerEventsResponseCh := make(chan *runtimeapi.ContainerEventResponse, cap(e.eventChannel)) + defer close(containerEventsResponseCh) + + // Get the container events from the runtime. + go func() { + numAttempts := 0 + for { + if numAttempts >= e.eventedPlegMaxStreamRetries { + if isEventedPLEGInUse() { + // Fall back to Generic PLEG relisting since Evented PLEG is not working. + klog.V(4).InfoS("Fall back to Generic PLEG relisting since Evented PLEG is not working") + e.Stop() + e.genericPleg.Stop() // Stop the existing Generic PLEG which runs with longer relisting period when Evented PLEG is in use. + e.Update(e.relistDuration) // Update the relisting period to the default value for the Generic PLEG. + e.genericPleg.Start() + break + } + } + + err := e.runtimeService.GetContainerEvents(containerEventsResponseCh) + if err != nil { + numAttempts++ + e.Relist() // Force a relist to get the latest container and pods running metric. + klog.V(4).InfoS("Evented PLEG: Failed to get container events, retrying: ", "err", err) + } + } + }() + + if isEventedPLEGInUse() { + e.processCRIEvents(containerEventsResponseCh) + } +} + +func (e *EventedPLEG) processCRIEvents(containerEventsResponseCh chan *runtimeapi.ContainerEventResponse) { + for event := range containerEventsResponseCh { + podID := types.UID(event.PodSandboxStatus.Metadata.Uid) + shouldSendPLEGEvent := false + + status, err := e.runtime.GeneratePodStatus(event) + if err != nil { + // nolint:logcheck // Not using the result of klog.V inside the + // if branch is okay, we just use it to determine whether the + // additional "podStatus" key and its value should be added. + if klog.V(6).Enabled() { + klog.ErrorS(err, "Evented PLEG: error generating pod status from the received event", "podUID", podID, "podStatus", status) + } else { + klog.ErrorS(err, "Evented PLEG: error generating pod status from the received event", "podUID", podID, "podStatus", status) + } + } else { + if klogV := klog.V(6); klogV.Enabled() { + klogV.InfoS("Evented PLEG: Generated pod status from the received event", "podUID", podID, "podStatus", status) + } else { + klog.V(4).InfoS("Evented PLEG: Generated pod status from the received event", "podUID", podID) + } + // Preserve the pod IP across cache updates if the new IP is empty. + // When a pod is torn down, kubelet may race with PLEG and retrieve + // a pod status after network teardown, but the kubernetes API expects + // the completed pod's IP to be available after the pod is dead. + status.IPs = e.getPodIPs(podID, status) + } + + e.updateRunningPodMetric(status) + e.updateRunningContainerMetric(status) + + if event.ContainerEventType == runtimeapi.ContainerEventType_CONTAINER_DELETED_EVENT { + for _, sandbox := range status.SandboxStatuses { + if sandbox.Id == event.ContainerId { + // When the CONTAINER_DELETED_EVENT is received by the kubelet, + // the runtime has indicated that the container has been removed + // by the runtime and hence, it must be removed from the cache + // of kubelet too. + e.cache.Delete(podID) + } + } + shouldSendPLEGEvent = true + } else { + if e.cache.Set(podID, status, err, time.Unix(event.GetCreatedAt(), 0)) { + shouldSendPLEGEvent = true + } + } + + if shouldSendPLEGEvent { + e.processCRIEvent(event) + } + } +} + +func (e *EventedPLEG) processCRIEvent(event *runtimeapi.ContainerEventResponse) { + switch event.ContainerEventType { + case runtimeapi.ContainerEventType_CONTAINER_STOPPED_EVENT: + e.sendPodLifecycleEvent(&PodLifecycleEvent{ID: types.UID(event.PodSandboxStatus.Metadata.Uid), Type: ContainerDied, Data: event.ContainerId}) + klog.V(4).InfoS("Received Container Stopped Event", "event", event.String()) + case runtimeapi.ContainerEventType_CONTAINER_CREATED_EVENT: + // We only need to update the pod status on container create. + // But we don't have to generate any PodLifeCycleEvent. Container creation related + // PodLifeCycleEvent is ignored by the existing Generic PLEG as well. + // https://github.com/kubernetes/kubernetes/blob/24753aa8a4df8d10bfd6330e0f29186000c018be/pkg/kubelet/pleg/generic.go#L88 and + // https://github.com/kubernetes/kubernetes/blob/24753aa8a4df8d10bfd6330e0f29186000c018be/pkg/kubelet/pleg/generic.go#L273 + klog.V(4).InfoS("Received Container Created Event", "event", event.String()) + case runtimeapi.ContainerEventType_CONTAINER_STARTED_EVENT: + e.sendPodLifecycleEvent(&PodLifecycleEvent{ID: types.UID(event.PodSandboxStatus.Metadata.Uid), Type: ContainerStarted, Data: event.ContainerId}) + klog.V(4).InfoS("Received Container Started Event", "event", event.String()) + case runtimeapi.ContainerEventType_CONTAINER_DELETED_EVENT: + // In case the pod is deleted it is safe to generate both ContainerDied and ContainerRemoved events, just like in the case of + // Generic PLEG. https://github.com/kubernetes/kubernetes/blob/24753aa8a4df8d10bfd6330e0f29186000c018be/pkg/kubelet/pleg/generic.go#L169 + e.sendPodLifecycleEvent(&PodLifecycleEvent{ID: types.UID(event.PodSandboxStatus.Metadata.Uid), Type: ContainerDied, Data: event.ContainerId}) + e.sendPodLifecycleEvent(&PodLifecycleEvent{ID: types.UID(event.PodSandboxStatus.Metadata.Uid), Type: ContainerRemoved, Data: event.ContainerId}) + klog.V(4).InfoS("Received Container Deleted Event", "event", event) + } +} + +func (e *EventedPLEG) getPodIPs(pid types.UID, status *kubecontainer.PodStatus) []string { + if len(status.IPs) != 0 { + return status.IPs + } + + oldStatus, err := e.cache.Get(pid) + if err != nil || len(oldStatus.IPs) == 0 { + return nil + } + + for _, sandboxStatus := range status.SandboxStatuses { + // If at least one sandbox is ready, then use this status update's pod IP + if sandboxStatus.State == runtimeapi.PodSandboxState_SANDBOX_READY { + return status.IPs + } + } + + // For pods with no ready containers or sandboxes (like exited pods) + // use the old status' pod IP + return oldStatus.IPs +} + +func (e *EventedPLEG) sendPodLifecycleEvent(event *PodLifecycleEvent) { + select { + case e.eventChannel <- event: + default: + // record how many events were discarded due to channel out of capacity + metrics.PLEGDiscardEvents.Inc() + klog.ErrorS(nil, "Evented PLEG: Event channel is full, discarded pod lifecycle event") + } +} + +func getPodSandboxState(podStatus *kubecontainer.PodStatus) kubecontainer.State { + // increase running pod count when cache doesn't contain podID + var sandboxId string + for _, sandbox := range podStatus.SandboxStatuses { + sandboxId = sandbox.Id + // pod must contain only one sandbox + break + } + + for _, containerStatus := range podStatus.ContainerStatuses { + if containerStatus.ID.ID == sandboxId { + if containerStatus.State == kubecontainer.ContainerStateRunning { + return containerStatus.State + } + } + } + return kubecontainer.ContainerStateExited +} + +func (e *EventedPLEG) updateRunningPodMetric(podStatus *kubecontainer.PodStatus) { + cachedPodStatus, err := e.cache.Get(podStatus.ID) + if err != nil { + klog.ErrorS(err, "Evented PLEG: Get cache", "podID", podStatus.ID) + } + // cache miss condition: The pod status object will have empty state if missed in cache + if len(cachedPodStatus.SandboxStatuses) < 1 { + sandboxState := getPodSandboxState(podStatus) + if sandboxState == kubecontainer.ContainerStateRunning { + metrics.RunningPodCount.Inc() + } + } else { + oldSandboxState := getPodSandboxState(cachedPodStatus) + currentSandboxState := getPodSandboxState(podStatus) + + if oldSandboxState == kubecontainer.ContainerStateRunning && currentSandboxState != kubecontainer.ContainerStateRunning { + metrics.RunningPodCount.Dec() + } else if oldSandboxState != kubecontainer.ContainerStateRunning && currentSandboxState == kubecontainer.ContainerStateRunning { + metrics.RunningPodCount.Inc() + } + } +} + +func getContainerStateCount(podStatus *kubecontainer.PodStatus) map[kubecontainer.State]int { + containerStateCount := make(map[kubecontainer.State]int) + for _, container := range podStatus.ContainerStatuses { + containerStateCount[container.State]++ + } + return containerStateCount +} + +func (e *EventedPLEG) updateRunningContainerMetric(podStatus *kubecontainer.PodStatus) { + cachedPodStatus, err := e.cache.Get(podStatus.ID) + if err != nil { + klog.ErrorS(err, "Evented PLEG: Get cache", "podID", podStatus.ID) + } + + // cache miss condition: The pod status object will have empty state if missed in cache + if len(cachedPodStatus.SandboxStatuses) < 1 { + containerStateCount := getContainerStateCount(podStatus) + for state, count := range containerStateCount { + // add currently obtained count + metrics.RunningContainerCount.WithLabelValues(string(state)).Add(float64(count)) + } + } else { + oldContainerStateCount := getContainerStateCount(cachedPodStatus) + currentContainerStateCount := getContainerStateCount(podStatus) + + // old and new set of container states may vary; + // get a unique set of container states combining both + containerStates := make(map[kubecontainer.State]bool) + for state := range oldContainerStateCount { + containerStates[state] = true + } + for state := range currentContainerStateCount { + containerStates[state] = true + } + + // update the metric via difference of old and current counts + for state := range containerStates { + diff := currentContainerStateCount[state] - oldContainerStateCount[state] + metrics.RunningContainerCount.WithLabelValues(string(state)).Add(float64(diff)) + } + } +} diff --git a/pkg/kubelet/pleg/evented_test.go b/pkg/kubelet/pleg/evented_test.go new file mode 100644 index 000000000000..89d7b823b5b3 --- /dev/null +++ b/pkg/kubelet/pleg/evented_test.go @@ -0,0 +1,133 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pleg + +import ( + "fmt" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/types" + "k8s.io/component-base/metrics/testutil" + v1 "k8s.io/cri-api/pkg/apis/runtime/v1" + critest "k8s.io/cri-api/pkg/apis/testing" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" + "k8s.io/kubernetes/pkg/kubelet/metrics" + testingclock "k8s.io/utils/clock/testing" +) + +func newTestEventedPLEG() *EventedPLEG { + return &EventedPLEG{ + runtime: &containertest.FakeRuntime{}, + clock: testingclock.NewFakeClock(time.Time{}), + cache: kubecontainer.NewCache(), + runtimeService: critest.NewFakeRuntimeService(), + eventChannel: make(chan *PodLifecycleEvent, 100), + } +} + +func TestHealthyEventedPLEG(t *testing.T) { + metrics.Register() + pleg := newTestEventedPLEG() + + _, _, events := createTestPodsStatusesAndEvents(100) + for _, event := range events[:5] { + pleg.eventChannel <- event + } + + // test if healthy when event channel has 5 events + isHealthy, err := pleg.Healthy() + require.NoError(t, err) + assert.Equal(t, true, isHealthy) + + // send remaining 95 events and make channel out of capacity + for _, event := range events[5:] { + pleg.eventChannel <- event + } + // pleg is unhealthy when channel is out of capacity + isHealthy, err = pleg.Healthy() + require.Error(t, err) + assert.Equal(t, false, isHealthy) +} + +func TestUpdateRunningPodMetric(t *testing.T) { + metrics.Register() + pleg := newTestEventedPLEG() + + podStatuses := make([]*kubecontainer.PodStatus, 5) + for i := range podStatuses { + id := fmt.Sprintf("test-pod-%d", i) + podStatuses[i] = &kubecontainer.PodStatus{ + ID: types.UID(id), + SandboxStatuses: []*v1.PodSandboxStatus{ + {Id: id}, + }, + ContainerStatuses: []*kubecontainer.Status{ + {ID: kubecontainer.ContainerID{ID: id}, State: kubecontainer.ContainerStateRunning}, + }, + } + + pleg.updateRunningPodMetric(podStatuses[i]) + pleg.cache.Set(podStatuses[i].ID, podStatuses[i], nil, time.Now()) + + } + pleg.cache.UpdateTime(time.Now()) + + expectedMetric := ` +# HELP kubelet_running_pods [ALPHA] Number of pods that have a running pod sandbox +# TYPE kubelet_running_pods gauge +kubelet_running_pods 5 +` + testMetric(t, expectedMetric, metrics.RunningPodCount.FQName()) + + // stop sandbox containers for first 2 pods + for _, podStatus := range podStatuses[:2] { + podId := string(podStatus.ID) + newPodStatus := kubecontainer.PodStatus{ + ID: podStatus.ID, + SandboxStatuses: []*v1.PodSandboxStatus{ + {Id: podId}, + }, + ContainerStatuses: []*kubecontainer.Status{ + // update state to container exited + {ID: kubecontainer.ContainerID{ID: podId}, State: kubecontainer.ContainerStateExited}, + }, + } + + pleg.updateRunningPodMetric(&newPodStatus) + pleg.cache.Set(newPodStatus.ID, &newPodStatus, nil, time.Now()) + } + pleg.cache.UpdateTime(time.Now()) + + expectedMetric = ` +# HELP kubelet_running_pods [ALPHA] Number of pods that have a running pod sandbox +# TYPE kubelet_running_pods gauge +kubelet_running_pods 3 +` + testMetric(t, expectedMetric, metrics.RunningPodCount.FQName()) +} + +func testMetric(t *testing.T, expectedMetric string, metricName string) { + err := testutil.GatherAndCompare(metrics.GetGather(), strings.NewReader(expectedMetric), metricName) + if err != nil { + t.Fatal(err) + } +} diff --git a/pkg/kubelet/pleg/generic.go b/pkg/kubelet/pleg/generic.go index 749d4b144930..656eafbca39a 100644 --- a/pkg/kubelet/pleg/generic.go +++ b/pkg/kubelet/pleg/generic.go @@ -19,14 +19,17 @@ package pleg import ( "context" "fmt" + "sync" "sync/atomic" "time" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" + utilfeature "k8s.io/apiserver/pkg/util/feature" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/utils/clock" @@ -48,8 +51,6 @@ import ( // recommended to set the relist period short and have an auxiliary, longer // periodic sync in kubelet as the safety net. type GenericPLEG struct { - // The period for relisting. - relistPeriod time.Duration // The container runtime. runtime kubecontainer.Runtime // The channel from which the subscriber listens events. @@ -65,6 +66,16 @@ type GenericPLEG struct { // Pods that failed to have their status retrieved during a relist. These pods will be // retried during the next relisting. podsToReinspect map[types.UID]*kubecontainer.Pod + // Stop the Generic PLEG by closing the channel. + stopCh chan struct{} + // Locks the relisting of the Generic PLEG + relistLock sync.Mutex + // Indicates if the Generic PLEG is running or not + isRunning bool + // Locks the start/stop operation of Generic PLEG + runningMu sync.Mutex + // Indicates relisting related parameters + relistDuration *RelistDuration } // plegContainerState has a one-to-one mapping to the @@ -77,11 +88,6 @@ const ( plegContainerExited plegContainerState = "exited" plegContainerUnknown plegContainerState = "unknown" plegContainerNonExistent plegContainerState = "non-existent" - - // The threshold needs to be greater than the relisting period + the - // relisting time, which can vary significantly. Set a conservative - // threshold to avoid flipping between healthy and unhealthy. - relistThreshold = 3 * time.Minute ) func convertState(state kubecontainer.State) plegContainerState { @@ -108,15 +114,16 @@ type podRecord struct { type podRecords map[types.UID]*podRecord // NewGenericPLEG instantiates a new GenericPLEG object and return it. -func NewGenericPLEG(runtime kubecontainer.Runtime, channelCapacity int, - relistPeriod time.Duration, cache kubecontainer.Cache, clock clock.Clock) PodLifecycleEventGenerator { +func NewGenericPLEG(runtime kubecontainer.Runtime, eventChannel chan *PodLifecycleEvent, + relistDuration *RelistDuration, cache kubecontainer.Cache, + clock clock.Clock) PodLifecycleEventGenerator { return &GenericPLEG{ - relistPeriod: relistPeriod, - runtime: runtime, - eventChannel: make(chan *PodLifecycleEvent, channelCapacity), - podRecords: make(podRecords), - cache: cache, - clock: clock, + relistDuration: relistDuration, + runtime: runtime, + eventChannel: eventChannel, + podRecords: make(podRecords), + cache: cache, + clock: clock, } } @@ -129,7 +136,26 @@ func (g *GenericPLEG) Watch() chan *PodLifecycleEvent { // Start spawns a goroutine to relist periodically. func (g *GenericPLEG) Start() { - go wait.Until(g.relist, g.relistPeriod, wait.NeverStop) + g.runningMu.Lock() + defer g.runningMu.Unlock() + if !g.isRunning { + g.isRunning = true + g.stopCh = make(chan struct{}) + go wait.Until(g.Relist, g.relistDuration.RelistPeriod, g.stopCh) + } +} + +func (g *GenericPLEG) Stop() { + g.runningMu.Lock() + defer g.runningMu.Unlock() + if g.isRunning { + close(g.stopCh) + g.isRunning = false + } +} + +func (g *GenericPLEG) Update(relistDuration *RelistDuration) { + g.relistDuration = relistDuration } // Healthy check if PLEG work properly. @@ -142,8 +168,8 @@ func (g *GenericPLEG) Healthy() (bool, error) { // Expose as metric so you can alert on `time()-pleg_last_seen_seconds > nn` metrics.PLEGLastSeen.Set(float64(relistTime.Unix())) elapsed := g.clock.Since(relistTime) - if elapsed > relistThreshold { - return false, fmt.Errorf("pleg was last seen active %v ago; threshold is %v", elapsed, relistThreshold) + if elapsed > g.relistDuration.RelistThreshold { + return false, fmt.Errorf("pleg was last seen active %v ago; threshold is %v", elapsed, g.relistDuration.RelistThreshold) } return true, nil } @@ -186,9 +212,12 @@ func (g *GenericPLEG) updateRelistTime(timestamp time.Time) { g.relistTime.Store(timestamp) } -// relist queries the container runtime for list of pods/containers, compare +// Relist queries the container runtime for list of pods/containers, compare // with the internal pods/containers, and generates events accordingly. -func (g *GenericPLEG) relist() { +func (g *GenericPLEG) Relist() { + g.relistLock.Lock() + defer g.relistLock.Unlock() + ctx := context.Background() klog.V(5).InfoS("GenericPLEG: Relisting") @@ -249,7 +278,7 @@ func (g *GenericPLEG) relist() { // inspecting the pod and getting the PodStatus to update the cache // serially may take a while. We should be aware of this and // parallelize if needed. - if err := g.updateCache(ctx, pod, pid); err != nil { + if err, updated := g.updateCache(ctx, pod, pid); err != nil { // Rely on updateCache calling GetPodStatus to log the actual error. klog.V(4).ErrorS(err, "PLEG: Ignoring events for pod", "pod", klog.KRef(pod.Namespace, pod.Name)) @@ -262,6 +291,11 @@ func (g *GenericPLEG) relist() { // from the list (we don't want the reinspection code below to inspect it a second time in // this relist execution) delete(g.podsToReinspect, pid) + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { + if !updated { + continue + } + } } } // Update the internal storage and send out the events. @@ -307,7 +341,7 @@ func (g *GenericPLEG) relist() { if len(g.podsToReinspect) > 0 { klog.V(5).InfoS("GenericPLEG: Reinspecting pods that previously failed inspection") for pid, pod := range g.podsToReinspect { - if err := g.updateCache(ctx, pod, pid); err != nil { + if err, _ := g.updateCache(ctx, pod, pid); err != nil { // Rely on updateCache calling GetPodStatus to log the actual error. klog.V(5).ErrorS(err, "PLEG: pod failed reinspection", "pod", klog.KRef(pod.Namespace, pod.Name)) needsReinspection[pid] = pod @@ -390,18 +424,20 @@ func (g *GenericPLEG) getPodIPs(pid types.UID, status *kubecontainer.PodStatus) return oldStatus.IPs } -func (g *GenericPLEG) updateCache(ctx context.Context, pod *kubecontainer.Pod, pid types.UID) error { +// updateCache tries to update the pod status in the kubelet cache and returns true if the +// pod status was actually updated in the cache. It will return false if the pod status +// was ignored by the cache. +func (g *GenericPLEG) updateCache(ctx context.Context, pod *kubecontainer.Pod, pid types.UID) (error, bool) { if pod == nil { // The pod is missing in the current relist. This means that // the pod has no visible (active or inactive) containers. klog.V(4).InfoS("PLEG: Delete status for pod", "podUID", string(pid)) g.cache.Delete(pid) - return nil + return nil, true } + timestamp := g.clock.Now() - // TODO: Consider adding a new runtime method - // GetPodStatus(pod *kubecontainer.Pod) so that Docker can avoid listing - // all containers again. + status, err := g.runtime.GetPodStatus(ctx, pod.ID, pod.Name, pod.Namespace) if err != nil { // nolint:logcheck // Not using the result of klog.V inside the @@ -425,8 +461,21 @@ func (g *GenericPLEG) updateCache(ctx context.Context, pod *kubecontainer.Pod, p status.IPs = g.getPodIPs(pid, status) } - g.cache.Set(pod.ID, status, err, timestamp) - return err + // When we use Generic PLEG only, the PodStatus is saved in the cache without + // any validation of the existing status against the current timestamp. + // This works well when there is only Generic PLEG setting the PodStatus in the cache however, + // if we have multiple entities, such as Evented PLEG, while trying to set the PodStatus in the + // cache we may run into the racy timestamps given each of them were to calculate the timestamps + // in their respective execution flow. While Generic PLEG calculates this timestamp and gets + // the PodStatus, we can only calculate the corresponding timestamp in + // Evented PLEG after the event has been received by the Kubelet. + // For more details refer to: + // https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3386-kubelet-evented-pleg#timestamp-of-the-pod-status + if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) && isEventedPLEGInUse() { + timestamp = status.TimeStamp + } + + return err, g.cache.Set(pod.ID, status, err, timestamp) } func updateEvents(eventsByPodID map[types.UID][]*PodLifecycleEvent, e *PodLifecycleEvent) { diff --git a/pkg/kubelet/pleg/generic_test.go b/pkg/kubelet/pleg/generic_test.go index baffabd59067..001e0e426c8d 100644 --- a/pkg/kubelet/pleg/generic_test.go +++ b/pkg/kubelet/pleg/generic_test.go @@ -61,11 +61,11 @@ func newTestGenericPLEGWithChannelSize(eventChannelCap int) *TestGenericPLEG { // The channel capacity should be large enough to hold all events in a // single test. pleg := &GenericPLEG{ - relistPeriod: time.Hour, - runtime: fakeRuntime, - eventChannel: make(chan *PodLifecycleEvent, eventChannelCap), - podRecords: make(podRecords), - clock: clock, + relistDuration: &RelistDuration{RelistPeriod: time.Hour, RelistThreshold: 3 * time.Minute}, + runtime: fakeRuntime, + eventChannel: make(chan *PodLifecycleEvent, eventChannelCap), + podRecords: make(podRecords), + clock: clock, } return &TestGenericPLEG{pleg: pleg, runtime: fakeRuntime, clock: clock} } @@ -126,7 +126,7 @@ func TestRelisting(t *testing.T) { }, }}, } - pleg.relist() + pleg.Relist() // Report every running/exited container if we see them for the first time. expected := []*PodLifecycleEvent{ {ID: "1234", Type: ContainerStarted, Data: "c2"}, @@ -138,7 +138,7 @@ func TestRelisting(t *testing.T) { // The second relist should not send out any event because no container has // changed. - pleg.relist() + pleg.Relist() actual = getEventsFromChannel(ch) assert.True(t, len(actual) == 0, "no container has changed, event length should be 0") @@ -157,7 +157,7 @@ func TestRelisting(t *testing.T) { }, }}, } - pleg.relist() + pleg.Relist() // Only report containers that transitioned to running or exited status. expected = []*PodLifecycleEvent{ {ID: "1234", Type: ContainerRemoved, Data: "c1"}, @@ -193,7 +193,7 @@ func TestEventChannelFull(t *testing.T) { }, }}, } - pleg.relist() + pleg.Relist() // Report every running/exited container if we see them for the first time. expected := []*PodLifecycleEvent{ {ID: "1234", Type: ContainerStarted, Data: "c2"}, @@ -218,7 +218,7 @@ func TestEventChannelFull(t *testing.T) { }, }}, } - pleg.relist() + pleg.Relist() allEvents := []*PodLifecycleEvent{ {ID: "1234", Type: ContainerRemoved, Data: "c1"}, {ID: "1234", Type: ContainerDied, Data: "c2"}, @@ -258,7 +258,7 @@ func testReportMissingContainers(t *testing.T, numRelists int) { } // Relist and drain the events from the channel. for i := 0; i < numRelists; i++ { - pleg.relist() + pleg.Relist() getEventsFromChannel(ch) } @@ -273,7 +273,7 @@ func testReportMissingContainers(t *testing.T, numRelists int) { }, }}, } - pleg.relist() + pleg.Relist() expected := []*PodLifecycleEvent{ {ID: "1234", Type: ContainerDied, Data: "c2"}, {ID: "1234", Type: ContainerRemoved, Data: "c2"}, @@ -297,14 +297,14 @@ func testReportMissingPods(t *testing.T, numRelists int) { } // Relist and drain the events from the channel. for i := 0; i < numRelists; i++ { - pleg.relist() + pleg.Relist() getEventsFromChannel(ch) } // Container c2 was stopped and removed between relists. We should report // the event. runtime.AllPodList = []*containertest.FakePod{} - pleg.relist() + pleg.Relist() expected := []*PodLifecycleEvent{ {ID: "1234", Type: ContainerDied, Data: "c2"}, {ID: "1234", Type: ContainerRemoved, Data: "c2"}, @@ -315,12 +315,12 @@ func testReportMissingPods(t *testing.T, numRelists int) { func newTestGenericPLEGWithRuntimeMock(runtimeMock kubecontainer.Runtime) *GenericPLEG { pleg := &GenericPLEG{ - relistPeriod: time.Hour, - runtime: runtimeMock, - eventChannel: make(chan *PodLifecycleEvent, 100), - podRecords: make(podRecords), - cache: kubecontainer.NewCache(), - clock: clock.RealClock{}, + relistDuration: &RelistDuration{RelistPeriod: time.Hour, RelistThreshold: 2 * time.Hour}, + runtime: runtimeMock, + eventChannel: make(chan *PodLifecycleEvent, 1000), + podRecords: make(podRecords), + cache: kubecontainer.NewCache(), + clock: clock.RealClock{}, } return pleg } @@ -366,7 +366,7 @@ func TestRelistWithCache(t *testing.T) { statusErr := fmt.Errorf("unable to get status") runtimeMock.EXPECT().GetPodStatus(ctx, pods[1].ID, "", "").Return(&kubecontainer.PodStatus{}, statusErr).Times(1) - pleg.relist() + pleg.Relist() actualEvents := getEventsFromChannel(ch) cases := []struct { pod *kubecontainer.Pod @@ -387,7 +387,7 @@ func TestRelistWithCache(t *testing.T) { // Return normal status for pods[1]. runtimeMock.EXPECT().GetPodStatus(ctx, pods[1].ID, "", "").Return(statuses[1], nil).Times(1) - pleg.relist() + pleg.Relist() actualEvents = getEventsFromChannel(ch) cases = []struct { pod *kubecontainer.Pod @@ -418,11 +418,11 @@ func TestRemoveCacheEntry(t *testing.T) { runtimeMock.EXPECT().GetPods(ctx, true).Return(pods, nil).Times(1) runtimeMock.EXPECT().GetPodStatus(ctx, pods[0].ID, "", "").Return(statuses[0], nil).Times(1) // Does a relist to populate the cache. - pleg.relist() + pleg.Relist() // Delete the pod from runtime. Verify that the cache entry has been // removed after relisting. runtimeMock.EXPECT().GetPods(ctx, true).Return([]*kubecontainer.Pod{}, nil).Times(1) - pleg.relist() + pleg.Relist() actualStatus, actualErr := pleg.cache.Get(pods[0].ID) assert.Equal(t, &kubecontainer.PodStatus{ID: pods[0].ID}, actualStatus) assert.Equal(t, nil, actualErr) @@ -443,14 +443,14 @@ func TestHealthy(t *testing.T) { // Relist and than advance the time by 1 minute. pleg should be healthy // because this is within the allowed limit. - pleg.relist() + pleg.Relist() clock.Step(time.Minute * 1) ok, _ = pleg.Healthy() assert.True(t, ok, "pleg should be healthy") // Advance by relistThreshold without any relisting. pleg should be unhealthy // because it has been longer than relistThreshold since a relist occurred. - clock.Step(relistThreshold) + clock.Step(pleg.relistDuration.RelistThreshold) ok, _ = pleg.Healthy() assert.False(t, ok, "pleg should be unhealthy") } @@ -482,7 +482,7 @@ func TestRelistWithReinspection(t *testing.T) { goodEvent := &PodLifecycleEvent{ID: podID, Type: ContainerStarted, Data: infraContainer.ID.ID} // listing 1 - everything ok, infra container set up for pod - pleg.relist() + pleg.Relist() actualEvents := getEventsFromChannel(ch) actualStatus, actualErr := pleg.cache.Get(podID) assert.Equal(t, goodStatus, actualStatus) @@ -504,7 +504,7 @@ func TestRelistWithReinspection(t *testing.T) { } runtimeMock.EXPECT().GetPodStatus(ctx, podID, "", "").Return(badStatus, errors.New("inspection error")).Times(1) - pleg.relist() + pleg.Relist() actualEvents = getEventsFromChannel(ch) actualStatus, actualErr = pleg.cache.Get(podID) assert.Equal(t, badStatus, actualStatus) @@ -516,7 +516,7 @@ func TestRelistWithReinspection(t *testing.T) { runtimeMock.EXPECT().GetPods(ctx, true).Return(pods, nil).Times(1) runtimeMock.EXPECT().GetPodStatus(ctx, podID, "", "").Return(goodStatus, nil).Times(1) - pleg.relist() + pleg.Relist() actualEvents = getEventsFromChannel(ch) actualStatus, actualErr = pleg.cache.Get(podID) assert.Equal(t, goodStatus, actualStatus) @@ -550,7 +550,7 @@ func TestRelistingWithSandboxes(t *testing.T) { }, }}, } - pleg.relist() + pleg.Relist() // Report every running/exited container if we see them for the first time. expected := []*PodLifecycleEvent{ {ID: "1234", Type: ContainerStarted, Data: "c2"}, @@ -562,7 +562,7 @@ func TestRelistingWithSandboxes(t *testing.T) { // The second relist should not send out any event because no container has // changed. - pleg.relist() + pleg.Relist() verifyEvents(t, expected, actual) runtime.AllPodList = []*containertest.FakePod{ @@ -580,7 +580,7 @@ func TestRelistingWithSandboxes(t *testing.T) { }, }}, } - pleg.relist() + pleg.Relist() // Only report containers that transitioned to running or exited status. expected = []*PodLifecycleEvent{ {ID: "1234", Type: ContainerRemoved, Data: "c1"}, @@ -639,7 +639,7 @@ func TestRelistIPChange(t *testing.T) { runtimeMock.EXPECT().GetPods(ctx, true).Return([]*kubecontainer.Pod{pod}, nil).Times(1) runtimeMock.EXPECT().GetPodStatus(ctx, pod.ID, "", "").Return(status, nil).Times(1) - pleg.relist() + pleg.Relist() actualEvents := getEventsFromChannel(ch) actualStatus, actualErr := pleg.cache.Get(pod.ID) assert.Equal(t, status, actualStatus, tc.name) @@ -660,7 +660,7 @@ func TestRelistIPChange(t *testing.T) { runtimeMock.EXPECT().GetPods(ctx, true).Return([]*kubecontainer.Pod{pod}, nil).Times(1) runtimeMock.EXPECT().GetPodStatus(ctx, pod.ID, "", "").Return(status, nil).Times(1) - pleg.relist() + pleg.Relist() actualEvents = getEventsFromChannel(ch) actualStatus, actualErr = pleg.cache.Get(pod.ID) // Must copy status to compare since its pointer gets passed through all @@ -704,7 +704,7 @@ func TestRunningPodAndContainerCount(t *testing.T) { }}, } - pleg.relist() + pleg.Relist() tests := []struct { name string diff --git a/pkg/kubelet/pleg/pleg.go b/pkg/kubelet/pleg/pleg.go index 86b48c7ef135..e7e678e6453b 100644 --- a/pkg/kubelet/pleg/pleg.go +++ b/pkg/kubelet/pleg/pleg.go @@ -17,12 +17,23 @@ limitations under the License. package pleg import ( + "time" + "k8s.io/apimachinery/pkg/types" ) // PodLifeCycleEventType define the event type of pod life cycle events. type PodLifeCycleEventType string +type RelistDuration struct { + // The period for relisting. + RelistPeriod time.Duration + // The relisting threshold needs to be greater than the relisting period + + // the relisting time, which can vary significantly. Set a conservative + // threshold to avoid flipping between healthy and unhealthy. + RelistThreshold time.Duration +} + const ( // ContainerStarted - event type when the new state of container is running. ContainerStarted PodLifeCycleEventType = "ContainerStarted" @@ -52,6 +63,9 @@ type PodLifecycleEvent struct { // PodLifecycleEventGenerator contains functions for generating pod life cycle events. type PodLifecycleEventGenerator interface { Start() + Stop() + Update(relistDuration *RelistDuration) Watch() chan *PodLifecycleEvent Healthy() (bool, error) + Relist() } diff --git a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go index ab24bd63cb92..0ca050ed7b72 100644 --- a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go +++ b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go @@ -2068,9 +2068,13 @@ type PodSandboxStatusResponse struct { // value should be in json format. The information could include anything useful for // debug, e.g. network namespace for linux container based container runtime. // It should only be returned non-empty when Verbose is true. - Info map[string]string `protobuf:"bytes,2,rep,name=info,proto3" json:"info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + Info map[string]string `protobuf:"bytes,2,rep,name=info,proto3" json:"info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Container statuses + ContainersStatuses []*ContainerStatus `protobuf:"bytes,3,rep,name=containers_statuses,json=containersStatuses,proto3" json:"containers_statuses,omitempty"` + // Timestamp at which container and pod statuses were recorded + Timestamp int64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *PodSandboxStatusResponse) Reset() { *m = PodSandboxStatusResponse{} } @@ -2119,6 +2123,20 @@ func (m *PodSandboxStatusResponse) GetInfo() map[string]string { return nil } +func (m *PodSandboxStatusResponse) GetContainersStatuses() []*ContainerStatus { + if m != nil { + return m.ContainersStatuses + } + return nil +} + +func (m *PodSandboxStatusResponse) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + // PodSandboxStateValue is the wrapper of PodSandboxState. type PodSandboxStateValue struct { // State of the sandbox. @@ -8914,10 +8932,12 @@ type ContainerEventResponse struct { ContainerEventType ContainerEventType `protobuf:"varint,2,opt,name=container_event_type,json=containerEventType,proto3,enum=runtime.v1.ContainerEventType" json:"container_event_type,omitempty"` // Creation timestamp of this event CreatedAt int64 `protobuf:"varint,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // ID of the sandbox container - PodSandboxMetadata *PodSandboxMetadata `protobuf:"bytes,4,opt,name=pod_sandbox_metadata,json=podSandboxMetadata,proto3" json:"pod_sandbox_metadata,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + // Sandbox status + PodSandboxStatus *PodSandboxStatus `protobuf:"bytes,4,opt,name=pod_sandbox_status,json=podSandboxStatus,proto3" json:"pod_sandbox_status,omitempty"` + // Container statuses + ContainersStatuses []*ContainerStatus `protobuf:"bytes,5,rep,name=containers_statuses,json=containersStatuses,proto3" json:"containers_statuses,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ContainerEventResponse) Reset() { *m = ContainerEventResponse{} } @@ -8973,9 +8993,16 @@ func (m *ContainerEventResponse) GetCreatedAt() int64 { return 0 } -func (m *ContainerEventResponse) GetPodSandboxMetadata() *PodSandboxMetadata { +func (m *ContainerEventResponse) GetPodSandboxStatus() *PodSandboxStatus { if m != nil { - return m.PodSandboxMetadata + return m.PodSandboxStatus + } + return nil +} + +func (m *ContainerEventResponse) GetContainersStatuses() []*ContainerStatus { + if m != nil { + return m.ContainersStatuses } return nil } @@ -9155,396 +9182,398 @@ func init() { func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 6216 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x7d, 0x4d, 0x6c, 0x1c, 0xc9, - 0x75, 0x30, 0x7b, 0x66, 0x48, 0xce, 0x3c, 0x72, 0x86, 0xc3, 0x12, 0x45, 0x8e, 0x86, 0xfa, 0x6d, - 0x79, 0x77, 0xf5, 0xb3, 0xa2, 0xb4, 0x5a, 0xed, 0x5a, 0x92, 0xb5, 0xbb, 0x1a, 0x91, 0x5c, 0x89, - 0x6b, 0x89, 0x1c, 0x37, 0x49, 0xf9, 0xef, 0x83, 0xfb, 0x6b, 0x4d, 0x17, 0x87, 0xbd, 0x9a, 0xe9, - 0x6e, 0x77, 0xf7, 0x48, 0xa2, 0x4f, 0x39, 0x26, 0x3e, 0x19, 0x48, 0x1c, 0x03, 0x46, 0x90, 0x20, - 0x87, 0x20, 0x01, 0x72, 0x70, 0x2e, 0x09, 0x0c, 0x04, 0x49, 0x80, 0x20, 0x30, 0x9c, 0x00, 0x06, - 0x7c, 0x48, 0x00, 0x1f, 0x02, 0xc4, 0xde, 0xe4, 0x94, 0x43, 0x2e, 0xf1, 0x21, 0xa7, 0x38, 0xa8, - 0xbf, 0xee, 0xae, 0xee, 0x9e, 0x9e, 0x21, 0x57, 0xde, 0x5d, 0x9f, 0x38, 0xf5, 0xea, 0xbd, 0x57, - 0xaf, 0x5e, 0xbd, 0x7a, 0xfd, 0xaa, 0xde, 0xeb, 0x26, 0x54, 0x0c, 0xd7, 0x5a, 0x71, 0x3d, 0x27, - 0x70, 0x10, 0x78, 0x03, 0x3b, 0xb0, 0xfa, 0x78, 0xe5, 0xd9, 0x1b, 0xcd, 0x2b, 0x5d, 0x2b, 0xd8, - 0x1f, 0x3c, 0x59, 0xe9, 0x38, 0xfd, 0xab, 0x5d, 0xa7, 0xeb, 0x5c, 0xa5, 0x28, 0x4f, 0x06, 0x7b, - 0xb4, 0x45, 0x1b, 0xf4, 0x17, 0x23, 0x55, 0x2f, 0x41, 0xed, 0x31, 0xf6, 0x7c, 0xcb, 0xb1, 0x35, - 0xfc, 0xcd, 0x01, 0xf6, 0x03, 0xd4, 0x80, 0xe9, 0x67, 0x0c, 0xd2, 0x50, 0xce, 0x2a, 0x17, 0x2a, - 0x9a, 0x68, 0xaa, 0x7f, 0xaa, 0xc0, 0x5c, 0x88, 0xec, 0xbb, 0x8e, 0xed, 0xe3, 0xe1, 0xd8, 0xe8, - 0x1c, 0xcc, 0x72, 0xb1, 0x74, 0xdb, 0xe8, 0xe3, 0x46, 0x81, 0x76, 0xcf, 0x70, 0xd8, 0xa6, 0xd1, - 0xc7, 0xe8, 0x35, 0x98, 0x13, 0x28, 0x82, 0x49, 0x91, 0x62, 0xd5, 0x38, 0x98, 0x8f, 0x86, 0x56, - 0xe0, 0x98, 0x40, 0x34, 0x5c, 0x2b, 0x44, 0x2e, 0x51, 0xe4, 0x79, 0xde, 0xd5, 0x72, 0x2d, 0x8e, - 0xaf, 0x7e, 0x1d, 0x2a, 0x6b, 0x9b, 0xdb, 0xab, 0x8e, 0xbd, 0x67, 0x75, 0x89, 0x88, 0x3e, 0xf6, - 0x08, 0x4d, 0x43, 0x39, 0x5b, 0x24, 0x22, 0xf2, 0x26, 0x6a, 0x42, 0xd9, 0xc7, 0x86, 0xd7, 0xd9, - 0xc7, 0x7e, 0xa3, 0x40, 0xbb, 0xc2, 0x36, 0xa1, 0x72, 0xdc, 0xc0, 0x72, 0x6c, 0xbf, 0x51, 0x64, - 0x54, 0xbc, 0xa9, 0xfe, 0x81, 0x02, 0x33, 0x6d, 0xc7, 0x0b, 0x1e, 0x19, 0xae, 0x6b, 0xd9, 0x5d, - 0x74, 0x0d, 0xca, 0x54, 0x97, 0x1d, 0xa7, 0x47, 0x75, 0x50, 0xbb, 0xbe, 0xb0, 0x12, 0x2d, 0xc8, - 0x4a, 0x9b, 0xf7, 0x69, 0x21, 0x16, 0x7a, 0x05, 0x6a, 0x1d, 0xc7, 0x0e, 0x0c, 0xcb, 0xc6, 0x9e, - 0xee, 0x3a, 0x5e, 0x40, 0x95, 0x33, 0xa9, 0x55, 0x43, 0x28, 0xe1, 0x8f, 0x96, 0xa1, 0xb2, 0xef, - 0xf8, 0x01, 0xc3, 0x28, 0x52, 0x8c, 0x32, 0x01, 0xd0, 0xce, 0x25, 0x98, 0xa6, 0x9d, 0x96, 0xcb, - 0xd5, 0x30, 0x45, 0x9a, 0x1b, 0xae, 0xfa, 0x53, 0x05, 0x26, 0x1f, 0x39, 0x03, 0x3b, 0x48, 0x0c, - 0x63, 0x04, 0xfb, 0x7c, 0x89, 0x62, 0xc3, 0x18, 0xc1, 0x7e, 0x34, 0x0c, 0xc1, 0x60, 0xab, 0xc4, - 0x86, 0x21, 0x9d, 0x4d, 0x28, 0x7b, 0xd8, 0x30, 0x1d, 0xbb, 0x77, 0x40, 0x45, 0x28, 0x6b, 0x61, - 0x9b, 0x2c, 0x9f, 0x8f, 0x7b, 0x96, 0x3d, 0x78, 0xa1, 0x7b, 0xb8, 0x67, 0x3c, 0xc1, 0x3d, 0x2a, - 0x4a, 0x59, 0xab, 0x71, 0xb0, 0xc6, 0xa0, 0xe8, 0x5d, 0x98, 0x71, 0x3d, 0xc7, 0x35, 0xba, 0x06, - 0xd1, 0x60, 0x63, 0x92, 0x2a, 0xe9, 0x64, 0x5c, 0x49, 0x54, 0xe0, 0x76, 0x84, 0xa3, 0xc5, 0x09, - 0x54, 0x1d, 0x2a, 0x1b, 0x6b, 0x42, 0xdd, 0xe1, 0xc4, 0x4d, 0x3a, 0x9d, 0x2a, 0x9f, 0xb8, 0x49, - 0x0c, 0x2e, 0x9a, 0xae, 0x65, 0xd2, 0xa9, 0x54, 0xb5, 0x99, 0x10, 0xb6, 0x61, 0xa2, 0x45, 0x98, - 0xea, 0x61, 0xbb, 0x1b, 0xec, 0xd3, 0xb9, 0x54, 0x35, 0xde, 0x52, 0x7f, 0x4f, 0x81, 0xea, 0xae, - 0x8f, 0x3d, 0x62, 0x95, 0xbe, 0x6b, 0x74, 0x30, 0xba, 0x02, 0xa5, 0xbe, 0x63, 0x62, 0xbe, 0xa0, - 0x27, 0xe2, 0xb2, 0x86, 0x48, 0x8f, 0x1c, 0x13, 0x6b, 0x14, 0x0d, 0x5d, 0x84, 0xd2, 0xc0, 0x32, - 0x99, 0x15, 0xcd, 0x5c, 0x3f, 0x1e, 0x47, 0x0f, 0x25, 0xd7, 0x28, 0x0a, 0x41, 0xed, 0x12, 0xd4, - 0x62, 0x2e, 0x2a, 0x41, 0x51, 0x7f, 0xa5, 0xc0, 0x5c, 0x38, 0xda, 0x16, 0x35, 0x3f, 0xf4, 0x26, - 0x4c, 0xdb, 0x38, 0x78, 0xee, 0x78, 0x4f, 0x47, 0xcb, 0x26, 0x30, 0xd1, 0x65, 0x28, 0xba, 0x5c, - 0x23, 0xb9, 0x04, 0x04, 0x8b, 0x20, 0x5b, 0x6e, 0x87, 0x6a, 0x28, 0x1f, 0xd9, 0x72, 0x3b, 0xc4, - 0x78, 0x02, 0xc3, 0xeb, 0x62, 0xba, 0x1e, 0xcc, 0x10, 0xcb, 0x0c, 0xb0, 0x61, 0xa2, 0xbb, 0x50, - 0x1b, 0xf8, 0xd8, 0xb3, 0x7d, 0x5d, 0x6c, 0x25, 0xb2, 0xf4, 0x33, 0x32, 0x53, 0x49, 0xef, 0x5a, - 0x95, 0x11, 0x6c, 0xf1, 0xbd, 0xa6, 0x02, 0x6c, 0xd8, 0xc1, 0xdb, 0x37, 0x1e, 0x1b, 0xbd, 0x01, - 0x46, 0x0b, 0x30, 0xf9, 0x8c, 0xfc, 0xa0, 0x33, 0x2f, 0x6a, 0xac, 0xa1, 0xfe, 0x4d, 0x09, 0x96, - 0x1f, 0x12, 0x73, 0xdb, 0x36, 0x6c, 0xf3, 0x89, 0xf3, 0x62, 0x1b, 0x77, 0x06, 0x9e, 0x15, 0x1c, - 0xac, 0x3a, 0x76, 0x80, 0x5f, 0x04, 0xe8, 0x01, 0xcc, 0xdb, 0x82, 0x7f, 0x28, 0x88, 0x42, 0x05, - 0x59, 0xce, 0x9c, 0x1d, 0x1b, 0x5c, 0xab, 0xdb, 0x32, 0xc0, 0x47, 0xf7, 0x22, 0x83, 0x17, 0x7c, - 0x0a, 0xe9, 0x09, 0x6d, 0xaf, 0x53, 0x69, 0x38, 0x17, 0xb1, 0x17, 0x04, 0x8f, 0xb7, 0x81, 0xb8, - 0x40, 0xdd, 0xf0, 0x75, 0x32, 0x53, 0xaa, 0xe5, 0x99, 0xeb, 0x8b, 0x92, 0x15, 0x84, 0x13, 0xd6, - 0x2a, 0xde, 0xc0, 0x6e, 0xf9, 0x44, 0x43, 0xe8, 0x26, 0x75, 0xa7, 0x84, 0xae, 0xeb, 0x39, 0x03, - 0xb7, 0x51, 0xce, 0x25, 0x04, 0x4a, 0x78, 0x9f, 0x60, 0x52, 0x2f, 0xcb, 0xb7, 0xac, 0xee, 0x39, - 0x4e, 0xb0, 0xe7, 0x8b, 0x6d, 0x2a, 0xc0, 0x1a, 0x85, 0xa2, 0xab, 0x70, 0xcc, 0x1f, 0xb8, 0x6e, - 0x0f, 0xf7, 0xb1, 0x1d, 0x18, 0x3d, 0x36, 0x10, 0x59, 0xb3, 0xe2, 0x85, 0xa2, 0x86, 0xe2, 0x5d, - 0x94, 0xb1, 0x8f, 0x4e, 0x03, 0xb8, 0x9e, 0xf5, 0xcc, 0xea, 0xe1, 0x2e, 0x36, 0x1b, 0x53, 0x94, - 0x69, 0x0c, 0x82, 0xde, 0x22, 0x9e, 0xb7, 0xd3, 0x71, 0xfa, 0x6e, 0xa3, 0x92, 0xd6, 0xb7, 0x58, - 0xa7, 0xb6, 0xe7, 0xec, 0x59, 0x3d, 0xac, 0x09, 0x5c, 0xf4, 0x79, 0x28, 0x1b, 0xae, 0x6b, 0x78, - 0x7d, 0xc7, 0x6b, 0xc0, 0x68, 0xba, 0x10, 0x19, 0xdd, 0x80, 0x05, 0xce, 0x43, 0x77, 0x59, 0x27, - 0x73, 0x6a, 0xd3, 0xc4, 0x2e, 0xef, 0x15, 0x1a, 0x8a, 0x86, 0x78, 0x3f, 0xa7, 0x25, 0x2e, 0x4e, - 0xfd, 0x07, 0x05, 0xe6, 0x12, 0x3c, 0xd1, 0x07, 0x30, 0x2b, 0x38, 0x04, 0x07, 0xae, 0x70, 0x03, - 0xaf, 0xe5, 0x88, 0xb1, 0xc2, 0xff, 0xee, 0x1c, 0xb8, 0x98, 0x7a, 0x2f, 0xd1, 0x40, 0xe7, 0xa1, - 0xda, 0x73, 0x3a, 0x46, 0x8f, 0x7a, 0x2d, 0x0f, 0xef, 0x71, 0x1f, 0x3b, 0x1b, 0x02, 0x35, 0xbc, - 0xa7, 0xde, 0x85, 0x99, 0x18, 0x03, 0x84, 0xa0, 0xa6, 0xb1, 0xa1, 0xd6, 0xf0, 0x9e, 0x31, 0xe8, - 0x05, 0xf5, 0x09, 0x54, 0x03, 0xd8, 0xb5, 0x3b, 0xe4, 0x99, 0x66, 0x63, 0xb3, 0xae, 0xa0, 0x2a, - 0x54, 0x1e, 0x0a, 0x16, 0xf5, 0x82, 0xfa, 0xfd, 0x22, 0x1c, 0xa7, 0x86, 0xd7, 0x76, 0x4c, 0xbe, - 0x13, 0xf8, 0x03, 0xf0, 0x3c, 0x54, 0x3b, 0x74, 0x2d, 0x75, 0xd7, 0xf0, 0xb0, 0x1d, 0xf0, 0xc7, - 0xc0, 0x2c, 0x03, 0xb6, 0x29, 0x0c, 0x69, 0x50, 0xf7, 0xf9, 0x8c, 0xf4, 0x0e, 0xdb, 0x39, 0xdc, - 0xb8, 0xa5, 0x59, 0xe7, 0x6c, 0x34, 0x6d, 0xce, 0x4f, 0xed, 0xbc, 0x69, 0xff, 0xc0, 0xef, 0x04, - 0x3d, 0xe1, 0xed, 0x56, 0x52, 0xac, 0x92, 0xc2, 0xae, 0x6c, 0x33, 0x82, 0x75, 0x3b, 0xf0, 0x0e, - 0x34, 0x41, 0x8e, 0xde, 0x83, 0xb2, 0xf3, 0x0c, 0x7b, 0xfb, 0xd8, 0x60, 0x5e, 0x66, 0xe6, 0xfa, - 0xf9, 0x14, 0xab, 0x55, 0xe1, 0xe8, 0x35, 0xec, 0x3b, 0x03, 0xaf, 0x83, 0x7d, 0x2d, 0x24, 0x42, - 0x2d, 0xa8, 0x78, 0x02, 0xcc, 0xbd, 0xd0, 0x58, 0x1c, 0x22, 0xaa, 0xe6, 0x6d, 0x98, 0x8d, 0x0b, - 0x87, 0xea, 0x50, 0x7c, 0x8a, 0x0f, 0xb8, 0x32, 0xc9, 0xcf, 0xc8, 0x3f, 0xb1, 0x15, 0x66, 0x8d, - 0xdb, 0x85, 0x9b, 0x8a, 0xea, 0x01, 0x8a, 0x66, 0xfa, 0x08, 0x07, 0x86, 0x69, 0x04, 0x06, 0x42, - 0x50, 0xa2, 0xa1, 0x11, 0x63, 0x41, 0x7f, 0x13, 0xae, 0x03, 0xee, 0xaa, 0x2b, 0x1a, 0xf9, 0x89, - 0x4e, 0x42, 0x25, 0xf4, 0x44, 0x3c, 0x3e, 0x8a, 0x00, 0x24, 0x4e, 0x31, 0x82, 0x00, 0xf7, 0xdd, - 0x80, 0x2a, 0xa6, 0xaa, 0x89, 0xa6, 0xfa, 0x3b, 0x93, 0x50, 0x4f, 0xd9, 0xc2, 0x6d, 0x28, 0xf7, - 0xf9, 0xf0, 0xdc, 0x07, 0x9e, 0x96, 0x82, 0x95, 0x94, 0x90, 0x5a, 0x88, 0x4f, 0x62, 0x01, 0x62, - 0x6b, 0xb1, 0x68, 0x2e, 0x6c, 0x33, 0x23, 0xef, 0xea, 0xa6, 0xe5, 0xe1, 0x4e, 0xe0, 0x78, 0x07, - 0x5c, 0xd0, 0xd9, 0x9e, 0xd3, 0x5d, 0x13, 0x30, 0x74, 0x03, 0xc0, 0xb4, 0x7d, 0x9d, 0xda, 0x70, - 0x97, 0xaf, 0xa3, 0xf4, 0x00, 0x0c, 0x83, 0x36, 0xad, 0x62, 0xda, 0x3e, 0x17, 0xf9, 0x0e, 0x54, - 0x49, 0x04, 0xa4, 0xf7, 0xd9, 0xb3, 0x91, 0x39, 0xa4, 0x99, 0xeb, 0x4b, 0xb2, 0xdc, 0x61, 0x3c, - 0xa6, 0xcd, 0xba, 0x51, 0xc3, 0x47, 0x77, 0x61, 0x8a, 0x06, 0x21, 0x7e, 0x63, 0x8a, 0x92, 0x5d, - 0xc8, 0x9e, 0x2e, 0xb7, 0xbe, 0x87, 0x14, 0x95, 0x19, 0x1f, 0xa7, 0x43, 0x5b, 0x30, 0x63, 0xd8, - 0xb6, 0x13, 0x18, 0xcc, 0xe3, 0x4f, 0x53, 0x36, 0x57, 0x72, 0xd9, 0xb4, 0x22, 0x7c, 0xc6, 0x2b, - 0xce, 0x01, 0x7d, 0x1e, 0x26, 0xe9, 0x23, 0x81, 0xfb, 0xf0, 0x73, 0x23, 0x37, 0x85, 0xc6, 0xf0, - 0xd1, 0x3b, 0x30, 0xfd, 0xdc, 0xb2, 0x4d, 0xe7, 0xb9, 0xcf, 0xfd, 0xa9, 0x64, 0xc2, 0x5f, 0x66, - 0x5d, 0x29, 0x62, 0x41, 0xd3, 0xbc, 0x05, 0x33, 0xb1, 0xf9, 0x1d, 0xc6, 0x7e, 0x9b, 0xef, 0x42, - 0x3d, 0x39, 0xa7, 0x43, 0xd9, 0xff, 0x00, 0x16, 0xb4, 0x81, 0x1d, 0x89, 0x26, 0x0e, 0x1b, 0x37, - 0x60, 0x8a, 0x5b, 0x03, 0x33, 0xc6, 0x93, 0x79, 0x6a, 0xd5, 0x38, 0x6e, 0xfc, 0xdc, 0xb0, 0x6f, - 0xd8, 0x66, 0x0f, 0x7b, 0x7c, 0x44, 0x71, 0x6e, 0x78, 0xc0, 0xa0, 0xea, 0x3b, 0x70, 0x3c, 0x31, - 0x2c, 0x3f, 0xb6, 0x7c, 0x0e, 0x6a, 0xae, 0x63, 0xea, 0x3e, 0x03, 0x8b, 0x58, 0xb2, 0x42, 0x6c, - 0x47, 0xe0, 0x6e, 0x98, 0x84, 0x7c, 0x3b, 0x70, 0xdc, 0xb4, 0xd8, 0xe3, 0x91, 0x37, 0x60, 0x31, - 0x49, 0xce, 0x86, 0x57, 0xdf, 0x83, 0x25, 0x0d, 0xf7, 0x9d, 0x67, 0xf8, 0xa8, 0xac, 0x9b, 0xd0, - 0x48, 0x33, 0xe0, 0xcc, 0xbf, 0x0a, 0x4b, 0x11, 0x74, 0x3b, 0x30, 0x82, 0x81, 0x7f, 0x28, 0xe6, - 0xfc, 0x4c, 0xf7, 0xc4, 0xf1, 0xd9, 0x42, 0x96, 0x35, 0xd1, 0x54, 0x97, 0x60, 0xb2, 0xed, 0x98, - 0x1b, 0x6d, 0x54, 0x83, 0x82, 0xe5, 0x72, 0xe2, 0x82, 0xe5, 0xaa, 0x9d, 0xf8, 0x98, 0x9b, 0x2c, - 0xea, 0x64, 0x43, 0x27, 0x51, 0xd1, 0x4d, 0xa8, 0x19, 0xa6, 0x69, 0x11, 0x43, 0x32, 0x7a, 0xba, - 0xe5, 0x8a, 0xa0, 0x79, 0x3e, 0xb1, 0xf4, 0x1b, 0x6d, 0xad, 0x1a, 0x21, 0x6e, 0xb8, 0xbe, 0x7a, - 0x0f, 0x2a, 0x51, 0x80, 0xfe, 0x56, 0x74, 0x3e, 0x2b, 0x8c, 0x8e, 0xe5, 0xc2, 0xc3, 0xdb, 0x66, - 0xea, 0x21, 0xc9, 0xc5, 0x7c, 0x0b, 0x20, 0x74, 0xaa, 0x22, 0x3c, 0x3c, 0x9e, 0xc9, 0x52, 0x8b, - 0x21, 0xaa, 0xff, 0x56, 0x8a, 0x3b, 0xd9, 0xd8, 0x94, 0xcd, 0x70, 0xca, 0xa6, 0xe4, 0x74, 0x0b, - 0x87, 0x74, 0xba, 0x6f, 0xc0, 0xa4, 0x1f, 0x18, 0x01, 0xe6, 0xf1, 0xf8, 0x72, 0x36, 0x21, 0x19, - 0x18, 0x6b, 0x0c, 0x13, 0x9d, 0x02, 0xe8, 0x78, 0xd8, 0x08, 0xb0, 0xa9, 0x1b, 0xec, 0xa9, 0x50, - 0xd4, 0x2a, 0x1c, 0xd2, 0x0a, 0x88, 0x17, 0x11, 0x27, 0x88, 0x8c, 0x07, 0xe1, 0x90, 0x65, 0x8c, - 0xce, 0x12, 0xa1, 0xf7, 0x9a, 0x1a, 0xe9, 0xbd, 0x38, 0x29, 0xf7, 0x5e, 0x91, 0x27, 0x9e, 0xce, - 0xf3, 0xc4, 0x8c, 0x68, 0x1c, 0x4f, 0x5c, 0xce, 0xf3, 0xc4, 0x9c, 0x4d, 0xbe, 0x27, 0xce, 0x70, - 0x24, 0x95, 0x2c, 0x47, 0xf2, 0x69, 0xba, 0xce, 0x9f, 0x28, 0xd0, 0x48, 0xef, 0x67, 0xee, 0xc7, - 0x6e, 0xc0, 0x94, 0x4f, 0x21, 0xf9, 0xfe, 0x93, 0x53, 0x71, 0x5c, 0x74, 0x0f, 0x4a, 0x96, 0xbd, - 0xe7, 0xf0, 0x8d, 0xb7, 0x92, 0x4b, 0xc3, 0x47, 0x5a, 0xd9, 0xb0, 0xf7, 0x1c, 0xa6, 0x41, 0x4a, - 0xdb, 0xfc, 0x3c, 0x54, 0x42, 0xd0, 0xa1, 0xe6, 0xb3, 0x01, 0x0b, 0x09, 0xbb, 0x65, 0x87, 0xbb, - 0xd0, 0xd0, 0x95, 0x71, 0x0d, 0x5d, 0xfd, 0xa5, 0x12, 0xdf, 0x7c, 0xef, 0x5b, 0xbd, 0x00, 0x7b, - 0xa9, 0xcd, 0xf7, 0xb6, 0xe0, 0xcb, 0x76, 0xde, 0xd9, 0x1c, 0xbe, 0xec, 0xec, 0xc4, 0x77, 0xd1, - 0x63, 0xa8, 0x51, 0xb3, 0xd3, 0x7d, 0xdc, 0xa3, 0xf1, 0x0b, 0x8f, 0x61, 0xaf, 0x66, 0x33, 0x60, - 0xa3, 0x33, 0xb3, 0xdd, 0xe6, 0x14, 0x4c, 0x5f, 0xd5, 0x5e, 0x1c, 0xd6, 0xbc, 0x0b, 0x28, 0x8d, - 0x74, 0x28, 0x0d, 0x3e, 0x22, 0x3e, 0xcc, 0x0f, 0x32, 0x9f, 0xa6, 0x7b, 0x54, 0x8c, 0x7c, 0x6b, - 0x60, 0xa2, 0x6a, 0x1c, 0x57, 0xfd, 0x97, 0x22, 0x40, 0xd4, 0xf9, 0x19, 0x77, 0x5e, 0xb7, 0x43, - 0x27, 0xc2, 0xa2, 0x40, 0x35, 0x9b, 0x65, 0xa6, 0xfb, 0xd8, 0x90, 0xdd, 0x07, 0x8b, 0x07, 0x5f, - 0x1b, 0xc2, 0xe0, 0xd0, 0x8e, 0x63, 0xfa, 0xb3, 0xe6, 0x38, 0xde, 0x87, 0xc5, 0xa4, 0x99, 0x70, - 0xaf, 0xf1, 0x3a, 0x4c, 0x5a, 0x01, 0xee, 0xb3, 0xfb, 0xd0, 0xc4, 0x25, 0x42, 0x0c, 0x9d, 0x21, - 0xa9, 0xef, 0xc2, 0xa2, 0xbc, 0x56, 0x87, 0x0b, 0x27, 0xd4, 0x87, 0xc9, 0x78, 0x24, 0x72, 0x5f, - 0xdc, 0x3e, 0x32, 0xaf, 0x63, 0x92, 0x34, 0x0c, 0x53, 0xfd, 0x91, 0x02, 0xc7, 0x13, 0x5d, 0x43, - 0x36, 0xfe, 0xd7, 0x53, 0x1b, 0x98, 0xf9, 0xbb, 0x1b, 0x39, 0xa3, 0x7c, 0x82, 0xbb, 0xf8, 0xcb, - 0xd0, 0x94, 0x97, 0x47, 0x52, 0xed, 0xad, 0xc4, 0x56, 0x3e, 0x37, 0x52, 0xe8, 0x70, 0x3f, 0xb7, - 0x61, 0x39, 0x93, 0x71, 0x5a, 0xe7, 0xc5, 0x31, 0x75, 0xfe, 0x3f, 0x85, 0xb8, 0xcf, 0x6e, 0x05, - 0x81, 0x67, 0x3d, 0x19, 0x04, 0xf8, 0xe5, 0x06, 0x3a, 0x6b, 0xe1, 0xce, 0x66, 0x7e, 0xf6, 0xf5, - 0x6c, 0xca, 0x68, 0xf4, 0xcc, 0x3d, 0xbe, 0x2d, 0xef, 0xf1, 0x12, 0x65, 0xf5, 0xc6, 0x48, 0x56, - 0xb9, 0xbb, 0xfd, 0xd3, 0xdc, 0xc4, 0xff, 0xa8, 0xc0, 0x5c, 0x62, 0x55, 0xd0, 0x5d, 0x00, 0x23, - 0x14, 0x9d, 0xdb, 0xc7, 0xd9, 0x51, 0x53, 0xd4, 0x62, 0x34, 0xe4, 0x99, 0xc8, 0x62, 0xb8, 0x8c, - 0x67, 0x62, 0x46, 0x0c, 0x17, 0x86, 0x70, 0x77, 0xa2, 0x03, 0x28, 0xbb, 0xb8, 0x54, 0x73, 0x0f, - 0xa0, 0x8c, 0x56, 0x90, 0xa8, 0xbf, 0x5b, 0x80, 0x85, 0x2c, 0xee, 0xe8, 0x55, 0x28, 0x76, 0xdc, - 0x01, 0x9f, 0x89, 0x94, 0x3c, 0x59, 0x75, 0x07, 0xbb, 0xbe, 0xd1, 0xc5, 0x1a, 0x41, 0x40, 0x57, - 0x61, 0xaa, 0x8f, 0xfb, 0x8e, 0x77, 0xc0, 0xe5, 0x96, 0xae, 0x00, 0x1e, 0xd1, 0x1e, 0x86, 0xcd, - 0xd1, 0xd0, 0xf5, 0x28, 0xd4, 0x65, 0xf2, 0x36, 0xa4, 0x88, 0x9e, 0x75, 0x31, 0x92, 0x30, 0xbe, - 0xbd, 0x0e, 0xd3, 0xae, 0xe7, 0x74, 0xb0, 0xef, 0xf3, 0x1b, 0x8a, 0x46, 0x22, 0x9b, 0x43, 0xba, - 0x38, 0x0d, 0x47, 0x44, 0xb7, 0x01, 0xc2, 0x34, 0x83, 0x78, 0x32, 0x35, 0xa5, 0x79, 0x88, 0x5e, - 0xa6, 0x92, 0x18, 0xb6, 0xfa, 0xc3, 0x02, 0x2c, 0x66, 0x6b, 0x0e, 0x5d, 0x89, 0xeb, 0x65, 0x39, - 0x43, 0xd5, 0xb2, 0x7a, 0xde, 0x4e, 0xa8, 0xe7, 0x74, 0x06, 0x45, 0x96, 0x96, 0x6e, 0x25, 0xb5, - 0x74, 0x26, 0x83, 0x30, 0x5b, 0x59, 0xb7, 0x92, 0xca, 0xca, 0x22, 0xcd, 0xd6, 0x59, 0x2b, 0x43, - 0x67, 0xe7, 0xb2, 0xe6, 0x38, 0x5c, 0x75, 0x7f, 0xa7, 0xc0, 0x6c, 0x5c, 0x2e, 0x74, 0x12, 0x2a, - 0x84, 0xda, 0x0f, 0x8c, 0xbe, 0xcb, 0x93, 0x04, 0x11, 0x00, 0x6d, 0xc2, 0xbc, 0xc9, 0x6e, 0x53, - 0x75, 0xcb, 0x0e, 0xb0, 0xb7, 0x67, 0x74, 0x44, 0x54, 0x78, 0x2e, 0xc3, 0x2e, 0x36, 0x04, 0x0e, - 0x13, 0xbc, 0xce, 0x69, 0x43, 0x30, 0x99, 0x41, 0xc8, 0x47, 0x78, 0xad, 0x31, 0x18, 0xc5, 0x88, - 0xd4, 0x7f, 0x56, 0xe0, 0x58, 0x86, 0x82, 0x47, 0x4c, 0x64, 0x77, 0xf8, 0x44, 0x2e, 0x0c, 0x5f, - 0xba, 0x91, 0xf3, 0x79, 0x90, 0x31, 0x9f, 0xf1, 0xf9, 0xc5, 0xa7, 0xf5, 0x2b, 0x05, 0x8e, 0x67, - 0x62, 0x65, 0x5e, 0x79, 0x5e, 0x87, 0xb2, 0xf7, 0x42, 0x7f, 0x72, 0x10, 0x60, 0x3f, 0x6b, 0x63, - 0xef, 0xc6, 0xf2, 0x1a, 0xd3, 0xde, 0x8b, 0x7b, 0x04, 0x0f, 0xdd, 0x80, 0x8a, 0xf7, 0x42, 0xc7, - 0x9e, 0xe7, 0x78, 0xc2, 0x17, 0x0d, 0x25, 0x2a, 0x7b, 0x2f, 0xd6, 0x29, 0x22, 0x19, 0x29, 0x10, - 0x23, 0x95, 0x46, 0x8c, 0x14, 0x44, 0x23, 0x05, 0xe1, 0x48, 0x93, 0x23, 0x46, 0x0a, 0xf8, 0x48, - 0xea, 0x9f, 0x15, 0xe0, 0x64, 0x9e, 0xba, 0x5e, 0x9a, 0x22, 0xd6, 0x01, 0x79, 0x2f, 0x74, 0xd7, - 0xe8, 0x3c, 0xc5, 0x81, 0xaf, 0x9b, 0x9e, 0xe3, 0xba, 0xd8, 0x1c, 0xa5, 0x91, 0xba, 0xf7, 0xa2, - 0xcd, 0x28, 0xd6, 0x18, 0xc1, 0x91, 0x34, 0xb3, 0x0e, 0x28, 0x48, 0x0f, 0x3d, 0x42, 0x45, 0xf5, - 0x20, 0x31, 0xb4, 0xfa, 0x21, 0xcc, 0xc6, 0x3d, 0xc4, 0x08, 0xdb, 0xbf, 0x03, 0x55, 0xee, 0x41, - 0xf4, 0x8e, 0x33, 0xb0, 0x83, 0x51, 0x8a, 0x9a, 0xe5, 0xd8, 0xab, 0x04, 0x59, 0xfd, 0x66, 0xb8, - 0xdd, 0x3e, 0xb1, 0x21, 0xff, 0x5c, 0x81, 0xca, 0x46, 0xdf, 0xe8, 0xe2, 0x6d, 0x17, 0x77, 0xc8, - 0x93, 0xde, 0x22, 0x0d, 0xbe, 0xee, 0xac, 0x81, 0x1e, 0xc8, 0x51, 0x0b, 0x8b, 0x53, 0x5f, 0x95, - 0x72, 0x7b, 0x82, 0xc3, 0x88, 0x50, 0xe5, 0xe3, 0xc6, 0x1b, 0xd7, 0xa1, 0xfc, 0x45, 0x7c, 0xc0, - 0x4e, 0xe4, 0x63, 0xd2, 0xa9, 0xdf, 0x2d, 0xc1, 0xd2, 0x90, 0xfc, 0x09, 0x3d, 0xce, 0xb9, 0x03, - 0xdd, 0xc5, 0x9e, 0xe5, 0x98, 0x42, 0xb5, 0x1d, 0x77, 0xd0, 0xa6, 0x00, 0xb4, 0x0c, 0xa4, 0xa1, - 0x7f, 0x73, 0xe0, 0xf0, 0x88, 0xb1, 0xa8, 0x95, 0x3b, 0xee, 0xe0, 0x4b, 0xa4, 0x2d, 0x68, 0xfd, - 0x7d, 0xc3, 0xc3, 0x6c, 0x93, 0x33, 0xda, 0x6d, 0x0a, 0x40, 0x6f, 0xc0, 0x71, 0xf6, 0x00, 0xd3, - 0x7b, 0x56, 0xdf, 0x22, 0xae, 0x30, 0x66, 0xbf, 0x45, 0x0d, 0xb1, 0xce, 0x87, 0xa4, 0x6f, 0xc3, - 0x66, 0x16, 0xab, 0x42, 0xd5, 0x71, 0xfa, 0xba, 0xdf, 0x71, 0x3c, 0xac, 0x1b, 0xe6, 0x87, 0xd4, - 0x58, 0x8b, 0xda, 0x8c, 0xe3, 0xf4, 0xb7, 0x09, 0xac, 0x65, 0x7e, 0x88, 0xce, 0xc0, 0x4c, 0xc7, - 0x1d, 0xf8, 0x38, 0xd0, 0xc9, 0x1f, 0x7a, 0xcb, 0x55, 0xd1, 0x80, 0x81, 0x56, 0xdd, 0x81, 0x1f, - 0x43, 0xe8, 0x93, 0x33, 0xd4, 0x74, 0x1c, 0xe1, 0x11, 0xee, 0xd3, 0x34, 0xf1, 0xfe, 0xa0, 0x8b, - 0x5d, 0xa3, 0x8b, 0x99, 0x68, 0xe2, 0xaa, 0x4a, 0x4a, 0x13, 0x3f, 0xe0, 0x28, 0x54, 0x40, 0xad, - 0xb6, 0x1f, 0x6f, 0xfa, 0xe8, 0x03, 0x98, 0x1e, 0xd8, 0xd6, 0x9e, 0x85, 0xcd, 0x46, 0x85, 0xd2, - 0x5e, 0x1b, 0x23, 0x5b, 0xb5, 0xb2, 0xcb, 0x48, 0x78, 0xf2, 0x8c, 0x33, 0x40, 0xb7, 0xa1, 0xc9, - 0x15, 0xe5, 0x3f, 0x37, 0xdc, 0xa4, 0xb6, 0x80, 0xaa, 0x60, 0x91, 0x61, 0x6c, 0x3f, 0x37, 0xdc, - 0xb8, 0xc6, 0x9a, 0xb7, 0x61, 0x36, 0xce, 0xf4, 0x50, 0xb6, 0x74, 0x0f, 0xaa, 0xd2, 0x24, 0xc9, - 0x6a, 0x53, 0xa5, 0xf8, 0xd6, 0xb7, 0xc4, 0x06, 0x28, 0x13, 0xc0, 0xb6, 0xf5, 0x2d, 0x9a, 0xdc, - 0xa7, 0x92, 0x51, 0x3e, 0x25, 0x8d, 0x35, 0x54, 0x03, 0xaa, 0x52, 0x3e, 0x9d, 0xf8, 0x4d, 0x9a, - 0x38, 0xe7, 0x7e, 0x93, 0xfc, 0x26, 0x30, 0xcf, 0xe9, 0x09, 0x09, 0xe8, 0x6f, 0x02, 0xa3, 0x99, - 0x5b, 0x96, 0x87, 0xa2, 0xbf, 0xe9, 0x10, 0xf8, 0x19, 0x2f, 0x53, 0xa9, 0x68, 0xac, 0xa1, 0xfe, - 0xa1, 0x02, 0xb0, 0x6a, 0xb8, 0xc6, 0x13, 0xab, 0x67, 0x05, 0x07, 0xe8, 0x22, 0xd4, 0x0d, 0xd3, - 0xd4, 0x3b, 0x02, 0x62, 0x61, 0x51, 0x37, 0x34, 0x67, 0x98, 0xe6, 0x6a, 0x0c, 0x8c, 0x2e, 0xc3, - 0x3c, 0xf1, 0x7a, 0x32, 0x2e, 0x2b, 0x24, 0xaa, 0x93, 0x0e, 0x09, 0xf9, 0x26, 0x34, 0x08, 0x5f, - 0xa3, 0xff, 0xc4, 0xc2, 0x76, 0x20, 0xd3, 0xb0, 0x0a, 0xa3, 0x45, 0xc3, 0x34, 0x5b, 0xac, 0x3b, - 0x4e, 0xa9, 0xfe, 0xed, 0x14, 0x9c, 0x92, 0x57, 0x3c, 0x59, 0xe2, 0x70, 0x1b, 0x66, 0x13, 0xf2, - 0xa6, 0x8a, 0x03, 0xa2, 0x19, 0x6a, 0x12, 0x6e, 0x22, 0x89, 0x5f, 0x48, 0x25, 0xf1, 0x33, 0xcb, - 0x27, 0x8a, 0x2f, 0xa9, 0x7c, 0xa2, 0xf4, 0x31, 0xcb, 0x27, 0x26, 0x8f, 0x5a, 0x3e, 0x31, 0x3b, - 0x76, 0xf9, 0xc4, 0xab, 0xf4, 0xaa, 0x47, 0x8c, 0x48, 0x9f, 0xd9, 0xcc, 0x27, 0x54, 0x43, 0xee, - 0xb6, 0x28, 0x66, 0x4b, 0x94, 0x59, 0x4c, 0x1f, 0xa6, 0xcc, 0xa2, 0x3c, 0xb4, 0xcc, 0xe2, 0x2c, - 0xcc, 0xda, 0x8e, 0x6e, 0xe3, 0xe7, 0x3a, 0x59, 0x16, 0xbf, 0x31, 0xc3, 0xd6, 0xc8, 0x76, 0x36, - 0xf1, 0xf3, 0x36, 0x81, 0xa0, 0x73, 0x30, 0xdb, 0x37, 0xfc, 0xa7, 0xd8, 0xa4, 0xf5, 0x0e, 0x7e, - 0xa3, 0x4a, 0xed, 0x69, 0x86, 0xc1, 0xda, 0x04, 0x84, 0x5e, 0x81, 0x50, 0x0e, 0x8e, 0x54, 0xa3, - 0x48, 0x55, 0x01, 0x65, 0x68, 0xb1, 0x92, 0x8d, 0xb9, 0x23, 0x96, 0x6c, 0xd4, 0x0f, 0x53, 0xb2, - 0x71, 0x05, 0xea, 0xe2, 0xb7, 0xa8, 0xd9, 0x60, 0x57, 0xf0, 0xb4, 0x5c, 0x63, 0x4e, 0xf4, 0x89, - 0xba, 0x8c, 0x61, 0x15, 0x1e, 0x90, 0x5b, 0xe1, 0xf1, 0x03, 0x85, 0x1f, 0x3c, 0xc3, 0x0d, 0xc4, - 0x53, 0xcb, 0x52, 0x55, 0x80, 0x72, 0x94, 0xaa, 0x00, 0xb4, 0x33, 0xb4, 0x6e, 0xe2, 0xe2, 0x70, - 0x4e, 0xa3, 0x2a, 0x27, 0xd4, 0x47, 0xe1, 0x99, 0xf0, 0x65, 0xd4, 0x7f, 0xa9, 0xff, 0xa1, 0xc0, - 0x29, 0xce, 0x6f, 0x48, 0x91, 0x54, 0x86, 0x95, 0x2b, 0x43, 0xac, 0xbc, 0xe3, 0x61, 0x13, 0xdb, - 0x81, 0x65, 0xf4, 0x74, 0xdf, 0xc5, 0x1d, 0x91, 0x7a, 0x8d, 0xc0, 0x34, 0xd0, 0x39, 0x07, 0xb3, - 0xac, 0xaa, 0x90, 0x1f, 0x0f, 0x59, 0xf1, 0xe0, 0x0c, 0x2d, 0x2c, 0xe4, 0x27, 0xc0, 0xad, 0x2c, - 0xcf, 0x52, 0x1a, 0x7a, 0xaf, 0x30, 0xd2, 0xc1, 0xa8, 0x0e, 0x2c, 0x0d, 0x49, 0x82, 0x67, 0x2e, - 0x93, 0x92, 0x5e, 0xa6, 0x5c, 0x25, 0xa5, 0x97, 0xe9, 0xbb, 0x0a, 0x9c, 0x49, 0x1d, 0x53, 0x3f, - 0x7d, 0xcd, 0xaa, 0x7f, 0xa9, 0x84, 0xf6, 0x93, 0x34, 0xf9, 0xd5, 0xb4, 0xc9, 0xbf, 0x92, 0x77, - 0xea, 0xce, 0x34, 0xfa, 0xc7, 0x43, 0x8d, 0xfe, 0x72, 0xee, 0x09, 0x7e, 0x94, 0x3e, 0xff, 0x55, - 0x81, 0x13, 0x43, 0x05, 0x48, 0xc4, 0x83, 0x4a, 0x32, 0x1e, 0xe4, 0xb1, 0x64, 0x14, 0xa2, 0xb3, - 0x58, 0x92, 0x46, 0xe1, 0x3c, 0x68, 0xd3, 0xfb, 0xc6, 0x0b, 0xab, 0x3f, 0xe8, 0xf3, 0x60, 0x92, - 0xb0, 0x7b, 0xc4, 0x20, 0x47, 0x89, 0x26, 0xaf, 0xc2, 0x02, 0x73, 0xf4, 0x34, 0xa0, 0x89, 0x28, - 0x58, 0x50, 0x39, 0xcf, 0xfa, 0x48, 0x6c, 0xc3, 0x09, 0xd4, 0x16, 0xcc, 0x87, 0xd3, 0xca, 0x2d, - 0x02, 0x8a, 0x15, 0xf5, 0x14, 0xe4, 0xa2, 0x1e, 0x1b, 0xa6, 0xd6, 0xf0, 0x33, 0xab, 0x83, 0x5f, - 0x4a, 0x75, 0xef, 0x59, 0x98, 0x71, 0xb1, 0xd7, 0xb7, 0x7c, 0x3f, 0x7c, 0xaa, 0x57, 0xb4, 0x38, - 0x48, 0xfd, 0xc1, 0x14, 0xcc, 0x25, 0x4d, 0xe8, 0x56, 0xaa, 0x86, 0xe8, 0x54, 0xe6, 0x5d, 0x57, - 0xc6, 0x25, 0xef, 0x65, 0x71, 0xfc, 0x29, 0xa4, 0x13, 0xec, 0xe1, 0x11, 0x47, 0x9c, 0x8a, 0x1a, - 0x30, 0xdd, 0x71, 0xfa, 0x7d, 0xc3, 0x36, 0x45, 0x09, 0x36, 0x6f, 0x12, 0x9d, 0x19, 0x5e, 0x97, - 0x5d, 0xef, 0x56, 0x34, 0xfa, 0x9b, 0xac, 0x30, 0xf1, 0x75, 0x96, 0x4d, 0xab, 0x90, 0xe8, 0x22, - 0x54, 0x34, 0xe0, 0xa0, 0x35, 0xcb, 0x43, 0x17, 0xa0, 0x84, 0xed, 0x67, 0x22, 0xef, 0x23, 0x5d, - 0x33, 0x8a, 0x23, 0x8f, 0x46, 0x31, 0xd0, 0x45, 0x98, 0xea, 0x13, 0xab, 0x11, 0x99, 0xea, 0xf9, - 0x54, 0xa9, 0xb2, 0xc6, 0x11, 0xd0, 0xeb, 0x30, 0x6d, 0xd2, 0xf5, 0x10, 0x31, 0x3e, 0x92, 0xea, - 0x99, 0x68, 0x97, 0x26, 0x50, 0xd0, 0x7b, 0xe1, 0x1d, 0x77, 0x25, 0x9d, 0x7c, 0x4a, 0xa8, 0x39, - 0xf3, 0x7a, 0x7b, 0x53, 0x3e, 0x28, 0x42, 0xfa, 0xa6, 0x3c, 0xc9, 0x25, 0x3f, 0x8f, 0x75, 0x02, - 0xca, 0x3d, 0xa7, 0xcb, 0x8c, 0x63, 0x86, 0xd5, 0xef, 0xf7, 0x9c, 0x2e, 0xb5, 0x8d, 0x05, 0x98, - 0xf4, 0x03, 0xd3, 0xb2, 0x69, 0xa8, 0x54, 0xd6, 0x58, 0x83, 0xec, 0x41, 0xfa, 0x43, 0x77, 0xec, - 0x0e, 0x6e, 0x54, 0x69, 0x57, 0x85, 0x42, 0xb6, 0xec, 0x0e, 0x3d, 0x32, 0x06, 0xc1, 0x41, 0xa3, - 0x46, 0xe1, 0xe4, 0x67, 0x74, 0xd5, 0x3c, 0x37, 0xe4, 0xaa, 0x39, 0x21, 0x70, 0xc6, 0x55, 0x73, - 0x7d, 0xe8, 0x23, 0x21, 0x49, 0xfb, 0x59, 0x28, 0x75, 0xfa, 0xa1, 0x02, 0x8b, 0xab, 0x34, 0x5f, - 0x19, 0x73, 0x61, 0x87, 0x29, 0xbf, 0x79, 0x33, 0xac, 0x89, 0xca, 0x28, 0x6c, 0x49, 0xce, 0x58, - 0x94, 0x44, 0xad, 0x42, 0x4d, 0xb0, 0xe5, 0xc4, 0xc5, 0x31, 0x0a, 0xaa, 0xaa, 0x7e, 0xbc, 0xa9, - 0xde, 0x81, 0xa5, 0x94, 0xe4, 0x3c, 0x6b, 0x94, 0x2c, 0xae, 0x67, 0x82, 0xc7, 0x8b, 0xeb, 0xd5, - 0xdb, 0x70, 0x7c, 0x3b, 0x30, 0xbc, 0x20, 0x35, 0xed, 0x31, 0x68, 0x69, 0xa9, 0x94, 0x4c, 0xcb, - 0xab, 0x99, 0xb6, 0x61, 0x61, 0x3b, 0x70, 0xdc, 0x23, 0x30, 0x25, 0xfe, 0x83, 0xcc, 0xdc, 0x19, - 0x88, 0xc7, 0x81, 0x68, 0xaa, 0x4b, 0xac, 0xb0, 0x2b, 0x3d, 0xda, 0x17, 0x60, 0x91, 0xd5, 0x55, - 0x1d, 0x65, 0x12, 0x27, 0x44, 0x55, 0x57, 0x9a, 0xef, 0x7d, 0x38, 0x26, 0xdd, 0x63, 0xf3, 0x9a, - 0x87, 0x6b, 0x72, 0xcd, 0xc3, 0xf0, 0x94, 0x41, 0x58, 0xf2, 0xf0, 0xbd, 0x42, 0xcc, 0x1f, 0x0f, - 0x49, 0x7c, 0xbe, 0x25, 0x57, 0x3c, 0x9c, 0x19, 0xce, 0x55, 0x2a, 0x78, 0x48, 0x5b, 0x67, 0x31, - 0xc3, 0x3a, 0x77, 0x53, 0x59, 0xd5, 0x52, 0xba, 0x8a, 0x24, 0x21, 0xe1, 0x27, 0x92, 0x4f, 0x7d, - 0xc8, 0xaa, 0x22, 0xc2, 0xa1, 0xc3, 0x54, 0xea, 0x9b, 0x89, 0x54, 0xea, 0x72, 0x8e, 0xa4, 0x61, - 0x12, 0xf5, 0x7b, 0x25, 0xa8, 0x84, 0x7d, 0x29, 0x0d, 0xa7, 0x55, 0x55, 0xc8, 0x50, 0x55, 0xfc, - 0x39, 0x59, 0x3c, 0xe2, 0x73, 0xb2, 0x34, 0xc6, 0x73, 0x72, 0x19, 0x2a, 0xf4, 0x07, 0x2d, 0x2e, - 0x67, 0xcf, 0xbd, 0x32, 0x05, 0x68, 0x78, 0x2f, 0x32, 0xb1, 0xa9, 0x31, 0x4d, 0x2c, 0x51, 0x81, - 0x31, 0x9d, 0xac, 0xc0, 0xb8, 0x15, 0x3e, 0xc3, 0xca, 0xe9, 0x8c, 0x47, 0xc8, 0x31, 0xf3, 0xe9, - 0x95, 0xb8, 0xe6, 0xac, 0xa4, 0xaf, 0x39, 0x23, 0xfa, 0xcf, 0x6c, 0x46, 0x76, 0x8b, 0x95, 0x55, - 0xc4, 0xed, 0x8c, 0xfb, 0xc8, 0xb7, 0xa4, 0x8c, 0x96, 0x92, 0x7e, 0xbf, 0x27, 0xf2, 0x0b, 0xf1, - 0x2c, 0xd6, 0x2e, 0x2c, 0x4a, 0x0b, 0x11, 0x95, 0x6b, 0x8e, 0xe7, 0xe3, 0x86, 0xd4, 0x6a, 0xfe, - 0x7e, 0x3c, 0x72, 0x1b, 0x52, 0x98, 0x78, 0x2b, 0x95, 0xaf, 0x1f, 0xdb, 0x42, 0xaf, 0xc9, 0xa5, - 0x3d, 0x87, 0xb6, 0xab, 0x54, 0x65, 0x0f, 0x8d, 0x2c, 0x0c, 0x8f, 0x77, 0xb3, 0x18, 0xba, 0xc2, - 0x21, 0x2d, 0x1a, 0xc0, 0xef, 0x59, 0xb6, 0xe5, 0xef, 0xb3, 0xfe, 0x29, 0x16, 0xc0, 0x0b, 0x50, - 0x8b, 0x5e, 0x2e, 0xe2, 0x17, 0x56, 0xa0, 0x77, 0x1c, 0x13, 0x53, 0xab, 0x9d, 0xd4, 0xca, 0x04, - 0xb0, 0xea, 0x98, 0x38, 0xda, 0x4f, 0xe5, 0xc3, 0xee, 0xa7, 0x4a, 0x62, 0x3f, 0x2d, 0xc2, 0x94, - 0x87, 0x0d, 0xdf, 0xb1, 0xd9, 0x9d, 0x83, 0xc6, 0x5b, 0x64, 0x21, 0xfa, 0xd8, 0xf7, 0xc9, 0x18, - 0x3c, 0x90, 0xe2, 0xcd, 0x58, 0xd0, 0x37, 0x9b, 0x13, 0xf4, 0xe5, 0x94, 0x3d, 0x26, 0x82, 0xbe, - 0x6a, 0x4e, 0xd0, 0x37, 0x56, 0xd5, 0x63, 0x14, 0xde, 0xd6, 0x46, 0x85, 0xb7, 0xf1, 0xf8, 0x70, - 0x4e, 0x8e, 0x0f, 0xef, 0xc4, 0x0f, 0x92, 0xf5, 0x74, 0xc2, 0x39, 0xff, 0x65, 0x8a, 0x4f, 0x71, - 0x03, 0xff, 0x93, 0x02, 0x4b, 0xa9, 0x0d, 0xc7, 0xb7, 0xf0, 0x9b, 0x89, 0x7a, 0xca, 0xe5, 0x1c, - 0x2d, 0x87, 0xe5, 0x94, 0x2d, 0xa9, 0x9c, 0xf2, 0x4a, 0x1e, 0xc9, 0x4b, 0xaf, 0xa6, 0xfc, 0x8e, - 0x02, 0x28, 0xe3, 0xa8, 0x7c, 0x4b, 0x44, 0xdd, 0x87, 0xb8, 0xd4, 0xe2, 0x81, 0xf7, 0x7b, 0x51, - 0xe0, 0x5d, 0x38, 0xcc, 0xf5, 0x40, 0x58, 0xe6, 0xf1, 0xf3, 0x02, 0x9c, 0xd9, 0x75, 0xcd, 0x44, - 0x18, 0xc9, 0xb1, 0xc6, 0xf7, 0x6c, 0xb7, 0xe4, 0x1a, 0x95, 0x23, 0x4e, 0xa1, 0x78, 0x94, 0x29, - 0xa0, 0x6f, 0x64, 0x55, 0x11, 0xdd, 0x91, 0xf2, 0x7d, 0xf9, 0x13, 0xfc, 0x35, 0x67, 0xe9, 0x54, - 0x38, 0x3b, 0x5c, 0x00, 0x1e, 0x72, 0xfe, 0x7f, 0x98, 0x5b, 0x7f, 0x81, 0x3b, 0xdb, 0x07, 0x76, - 0xe7, 0x10, 0x5a, 0xaf, 0x43, 0xb1, 0xd3, 0x37, 0x79, 0x12, 0x83, 0xfc, 0x8c, 0x47, 0xd1, 0x45, - 0x39, 0x8a, 0xd6, 0xa1, 0x1e, 0x8d, 0xc0, 0x37, 0xd0, 0x22, 0xd9, 0x40, 0x26, 0x41, 0x26, 0xcc, - 0x67, 0x35, 0xde, 0xe2, 0x70, 0xec, 0xb1, 0x37, 0x35, 0x18, 0x1c, 0x7b, 0x9e, 0xec, 0xb5, 0x8b, - 0xb2, 0xd7, 0x56, 0xbf, 0xaf, 0xc0, 0x0c, 0x19, 0xe1, 0x63, 0xc9, 0xcf, 0x8f, 0xa4, 0xc5, 0xe8, - 0x48, 0x1a, 0x9e, 0x6c, 0x4b, 0xf1, 0x93, 0x6d, 0x24, 0xf9, 0x24, 0x05, 0xa7, 0x25, 0x9f, 0x0a, - 0xe1, 0xd8, 0xf3, 0xd4, 0xb3, 0x30, 0xcb, 0x64, 0xe3, 0x33, 0xaf, 0x43, 0x71, 0xe0, 0xf5, 0xc4, - 0xfa, 0x0d, 0xbc, 0x9e, 0xfa, 0x6d, 0x05, 0xaa, 0xad, 0x20, 0x30, 0x3a, 0xfb, 0x87, 0x98, 0x40, - 0x28, 0x5c, 0x21, 0x2e, 0x5c, 0x7a, 0x12, 0x91, 0xb8, 0xa5, 0x21, 0xe2, 0x4e, 0x4a, 0xe2, 0xaa, - 0x50, 0x13, 0xb2, 0x0c, 0x15, 0x78, 0x13, 0x50, 0xdb, 0xf1, 0x82, 0xf7, 0x1d, 0xef, 0xb9, 0xe1, - 0x99, 0x87, 0x3b, 0xb5, 0x22, 0x28, 0xf1, 0x37, 0xd9, 0x8b, 0x17, 0x26, 0x35, 0xfa, 0x5b, 0x7d, - 0x0d, 0x8e, 0x49, 0xfc, 0x86, 0x0e, 0x7c, 0x1b, 0x66, 0xe8, 0x53, 0x98, 0x1f, 0x68, 0x2e, 0xc7, - 0x93, 0xe4, 0x23, 0x9e, 0xd6, 0xea, 0x1a, 0xcc, 0x93, 0x78, 0x8c, 0xc2, 0x43, 0xff, 0x72, 0x35, - 0x11, 0xf3, 0x2f, 0xa5, 0x58, 0x24, 0xe2, 0xfd, 0x5f, 0x2a, 0x30, 0x49, 0xe1, 0xa9, 0x18, 0x69, - 0x99, 0x3c, 0xe7, 0x5c, 0x47, 0x0f, 0x8c, 0x6e, 0xf8, 0x95, 0x00, 0x02, 0xd8, 0x31, 0xba, 0x34, - 0xf1, 0x42, 0x3b, 0x4d, 0xab, 0x8b, 0xfd, 0x40, 0x24, 0xf2, 0x66, 0x08, 0x6c, 0x8d, 0x81, 0x88, - 0x62, 0x68, 0xbe, 0xb3, 0x44, 0xd3, 0x9a, 0xf4, 0x37, 0xba, 0xc0, 0x5e, 0xf2, 0xcb, 0xcf, 0x5e, - 0xd1, 0x97, 0xff, 0x9a, 0x50, 0x4e, 0xa4, 0x9d, 0xc2, 0x36, 0xba, 0x08, 0x25, 0x7a, 0x4d, 0x3c, - 0x9d, 0xa7, 0x25, 0x8a, 0x42, 0xac, 0xc2, 0xb5, 0x6c, 0x1b, 0x9b, 0x34, 0x00, 0x2a, 0x6b, 0xbc, - 0xa5, 0xbe, 0x07, 0x28, 0xae, 0x3c, 0xbe, 0x40, 0x17, 0x61, 0x8a, 0xea, 0x56, 0x04, 0xb1, 0xf3, - 0x29, 0xd6, 0x1a, 0x47, 0x50, 0xbf, 0x0e, 0x88, 0x8d, 0x25, 0x05, 0xae, 0x87, 0x59, 0xc0, 0x9c, - 0x10, 0xf6, 0xaf, 0x14, 0x38, 0x26, 0x71, 0xe7, 0xf2, 0xbd, 0x26, 0xb3, 0xcf, 0x10, 0x8f, 0xb3, - 0x7e, 0x47, 0x7a, 0x32, 0x5f, 0x4c, 0x8b, 0xf1, 0x6b, 0x7a, 0x2a, 0xff, 0x44, 0x01, 0x68, 0x0d, - 0x82, 0x7d, 0x7e, 0x61, 0x1a, 0x5f, 0x44, 0x25, 0xb1, 0x88, 0x4d, 0x28, 0xbb, 0x86, 0xef, 0x3f, - 0x77, 0x3c, 0x71, 0x88, 0x0c, 0xdb, 0xf4, 0x9a, 0x73, 0xc0, 0x3f, 0x56, 0x50, 0xd1, 0xe8, 0x6f, - 0xf4, 0x0a, 0xd4, 0xd8, 0xe7, 0x2b, 0x74, 0xc3, 0x34, 0x3d, 0x51, 0x78, 0x57, 0xd1, 0xaa, 0x0c, - 0xda, 0x62, 0x40, 0x82, 0x66, 0xd1, 0xa4, 0x41, 0x70, 0xa0, 0x07, 0xce, 0x53, 0x6c, 0xf3, 0x83, - 0x61, 0x55, 0x40, 0x77, 0x08, 0x90, 0x65, 0x05, 0xbb, 0x96, 0x1f, 0x78, 0x02, 0x4d, 0xe4, 0x36, - 0x39, 0x94, 0xa2, 0xa9, 0x7f, 0xa1, 0x40, 0xbd, 0x3d, 0xe8, 0xf5, 0x98, 0x72, 0x8f, 0xb2, 0xc8, - 0x97, 0xf8, 0x54, 0x0a, 0x69, 0x93, 0x8f, 0x14, 0xc5, 0xa7, 0xf8, 0x52, 0xee, 0xb2, 0xae, 0xc1, - 0x7c, 0x4c, 0x62, 0x6e, 0x38, 0x52, 0x64, 0xaf, 0xc8, 0x91, 0xbd, 0xda, 0x02, 0xc4, 0xae, 0x6f, - 0x8e, 0x3c, 0x4b, 0xf5, 0x38, 0x1c, 0x93, 0x58, 0xf0, 0x47, 0xf1, 0x25, 0xa8, 0xf2, 0x22, 0x30, - 0x6e, 0x10, 0x27, 0xa0, 0x4c, 0x5c, 0x6a, 0xc7, 0x32, 0x45, 0x21, 0xc3, 0xb4, 0xeb, 0x98, 0xab, - 0x96, 0xe9, 0xa9, 0x5f, 0x82, 0x2a, 0x7f, 0xf3, 0x9b, 0xe3, 0xde, 0x85, 0x1a, 0x4f, 0xe3, 0xe9, - 0xd2, 0xab, 0x92, 0x27, 0x32, 0x2a, 0x0d, 0x85, 0x2a, 0xec, 0x78, 0x53, 0xfd, 0x06, 0x34, 0x59, - 0xb4, 0x20, 0x31, 0x16, 0x13, 0xbc, 0x0b, 0xe2, 0x9d, 0x85, 0x1c, 0xfe, 0x32, 0x65, 0xd5, 0x8b, - 0x37, 0xd5, 0x53, 0xb0, 0x9c, 0xc9, 0x9f, 0xcf, 0xde, 0x85, 0x7a, 0xd4, 0xc1, 0xde, 0xe7, 0x0b, - 0xab, 0x33, 0x94, 0x58, 0x75, 0xc6, 0x62, 0x18, 0x7b, 0x17, 0xc4, 0x93, 0x8b, 0x86, 0xd7, 0xd1, - 0x89, 0xab, 0x38, 0xec, 0xc4, 0x55, 0x92, 0x4e, 0x5c, 0xea, 0xa3, 0x50, 0x87, 0xfc, 0xdc, 0x7b, - 0x87, 0x9e, 0xcc, 0xd9, 0xd8, 0xc2, 0xa9, 0x9d, 0xcc, 0x9e, 0x1f, 0x43, 0xd2, 0x62, 0xf8, 0xea, - 0x45, 0xa8, 0xca, 0xee, 0x2d, 0xe6, 0xb1, 0x94, 0x94, 0xc7, 0xaa, 0x25, 0x9c, 0xd5, 0x1b, 0x89, - 0x23, 0x45, 0x96, 0x5e, 0x13, 0x07, 0x8a, 0x9b, 0x92, 0xdb, 0xfa, 0x9c, 0x94, 0x49, 0xff, 0x35, - 0x79, 0xac, 0x05, 0xee, 0xc7, 0xdf, 0xf7, 0x09, 0x3d, 0x9f, 0xa8, 0x7a, 0x1e, 0x66, 0x76, 0x87, - 0x7d, 0x7f, 0xa3, 0x24, 0xca, 0xbf, 0xde, 0x86, 0x85, 0xf7, 0xad, 0x1e, 0xf6, 0x0f, 0xfc, 0x00, - 0xf7, 0x37, 0xa8, 0x7b, 0xd9, 0xb3, 0xb0, 0x87, 0x4e, 0x03, 0xd0, 0x53, 0xa4, 0xeb, 0x58, 0xe1, - 0x37, 0x07, 0x62, 0x10, 0xf5, 0x67, 0x0a, 0xcc, 0x45, 0x84, 0xe3, 0x14, 0xe2, 0xbd, 0x05, 0x93, - 0x7b, 0xbe, 0xb8, 0x6d, 0x4b, 0xe4, 0x12, 0xb2, 0x44, 0xd0, 0x4a, 0x7b, 0xfe, 0x86, 0x89, 0xde, - 0x06, 0x18, 0xf8, 0xd8, 0xe4, 0xd9, 0xb9, 0x11, 0xa5, 0x91, 0x15, 0x82, 0xca, 0xf2, 0x7b, 0x37, - 0x61, 0xc6, 0xb2, 0x1d, 0x13, 0xd3, 0xcc, 0xad, 0x39, 0xaa, 0x2c, 0x12, 0x18, 0xee, 0xae, 0x8f, - 0x4d, 0xf5, 0x4f, 0xa2, 0xfc, 0xeb, 0x67, 0x79, 0x86, 0xaa, 0xce, 0x9f, 0xaf, 0x62, 0xd5, 0xb9, - 0xc9, 0x3e, 0x80, 0x79, 0xe6, 0x26, 0xf7, 0xc2, 0x21, 0x33, 0x5f, 0x17, 0x49, 0xcc, 0x4d, 0xab, - 0x5b, 0x3c, 0xb2, 0x12, 0x44, 0xea, 0x6d, 0x38, 0x9e, 0xa8, 0xdf, 0x1e, 0xff, 0x3a, 0xfd, 0x83, - 0xc4, 0xbd, 0x58, 0xb4, 0xa5, 0xae, 0xc9, 0xaf, 0x0d, 0xe5, 0x55, 0xda, 0xf3, 0x37, 0x58, 0x76, - 0xe1, 0x84, 0x74, 0x69, 0x27, 0xc9, 0x72, 0x33, 0x11, 0x2c, 0x9e, 0x1d, 0xce, 0x2f, 0x11, 0x35, - 0xfe, 0xa7, 0x02, 0x0b, 0x59, 0x08, 0x47, 0xbc, 0x30, 0xfe, 0xda, 0x90, 0x57, 0x0e, 0xdf, 0x1c, - 0x25, 0xd0, 0x27, 0x72, 0xc1, 0xbe, 0xc9, 0x5e, 0x58, 0x1a, 0xbd, 0x26, 0xc5, 0xf1, 0xd6, 0xe4, - 0x97, 0x85, 0x58, 0x52, 0x24, 0xe7, 0xa5, 0xa2, 0x8f, 0x71, 0x49, 0xb9, 0x9a, 0x78, 0xa7, 0xe8, - 0x72, 0x26, 0xe1, 0x88, 0x57, 0x8a, 0xb4, 0xac, 0xcb, 0x80, 0x6b, 0xa3, 0x38, 0x7d, 0x66, 0xef, - 0xaf, 0xff, 0x4b, 0x81, 0x9a, 0xbc, 0x20, 0xe8, 0xbd, 0x8c, 0x17, 0x8a, 0xce, 0x8c, 0x98, 0xa0, - 0xf4, 0x3e, 0x11, 0x7f, 0x81, 0xa7, 0x30, 0xfe, 0x0b, 0x3c, 0xc5, 0xf1, 0x5e, 0xe0, 0xb9, 0x07, - 0xb5, 0xe7, 0x9e, 0x15, 0x18, 0x4f, 0x7a, 0x58, 0xef, 0x19, 0x07, 0xd8, 0xe3, 0x5e, 0x38, 0xd7, - 0x0d, 0x55, 0x05, 0xc9, 0x43, 0x42, 0xa1, 0x7e, 0xbb, 0x00, 0xc7, 0x33, 0xdf, 0x25, 0xf9, 0xf8, - 0xf3, 0xbe, 0x12, 0x9f, 0xf7, 0x61, 0x5e, 0xd0, 0x29, 0x1e, 0xea, 0x05, 0x9d, 0x8d, 0x21, 0x5a, - 0xc8, 0x4a, 0x89, 0x8f, 0x50, 0xc6, 0x5f, 0x2b, 0x50, 0x16, 0x42, 0x8d, 0x7c, 0x5d, 0x66, 0x69, - 0x40, 0xd0, 0x74, 0x5a, 0x2d, 0x6d, 0x1b, 0xb6, 0xa3, 0xfb, 0x98, 0x84, 0x45, 0x23, 0x5f, 0x4e, - 0x58, 0xa0, 0x74, 0xab, 0x8e, 0x87, 0x37, 0x0d, 0xdb, 0xd9, 0x66, 0x44, 0xa8, 0x05, 0x75, 0xc6, - 0x8f, 0xb2, 0x22, 0x4c, 0x47, 0x3e, 0xaa, 0x6a, 0x94, 0x80, 0x30, 0x21, 0xcc, 0x7c, 0xf5, 0xef, - 0x15, 0x98, 0x4b, 0x68, 0xf6, 0x37, 0x6f, 0x12, 0x7f, 0x5c, 0x84, 0x99, 0xd8, 0x2a, 0x8f, 0x98, - 0xc0, 0x2a, 0xcc, 0x8b, 0xb2, 0x16, 0x1f, 0x07, 0xe3, 0xbd, 0x1c, 0x32, 0xc7, 0x29, 0xb6, 0x71, - 0xc0, 0x22, 0x99, 0xbb, 0x30, 0x67, 0x3c, 0x33, 0xac, 0x1e, 0xb5, 0xa0, 0xb1, 0x82, 0x84, 0x5a, - 0x88, 0x1f, 0xc6, 0x42, 0x6c, 0xde, 0x63, 0xbd, 0x22, 0x02, 0x14, 0x37, 0x7a, 0x53, 0xc7, 0xf7, - 0x63, 0xa5, 0x51, 0xb9, 0x6f, 0xea, 0xf8, 0x7e, 0x38, 0x1e, 0x2d, 0x15, 0xa7, 0xaf, 0x28, 0xf9, - 0xfc, 0x5b, 0x13, 0xc3, 0xc7, 0x23, 0xb8, 0xef, 0x53, 0x54, 0xa2, 0xb0, 0xbe, 0xf1, 0xa1, 0xe3, - 0xe9, 0x71, 0xfa, 0xe9, 0x11, 0x0a, 0xa3, 0x14, 0xed, 0x90, 0x89, 0xfa, 0xdf, 0x0a, 0xa0, 0xf4, - 0x86, 0xfc, 0x8d, 0x59, 0xaa, 0xf8, 0xd4, 0x4b, 0x63, 0xab, 0x4e, 0x7d, 0x17, 0x4e, 0x68, 0xd8, - 0x71, 0xb1, 0x1d, 0xfa, 0xbd, 0x87, 0x4e, 0xf7, 0x10, 0x11, 0xdb, 0x49, 0x68, 0x66, 0xd1, 0xf3, - 0x73, 0xe0, 0x00, 0x9a, 0xab, 0xfb, 0xb8, 0xf3, 0x94, 0x46, 0xff, 0x47, 0xa9, 0xe7, 0x68, 0x42, - 0xb9, 0xe7, 0x74, 0xd8, 0x37, 0x24, 0xf9, 0x55, 0x89, 0x68, 0xe7, 0xdc, 0x52, 0x9f, 0x82, 0xe5, - 0xcc, 0x61, 0xb9, 0x54, 0x08, 0xea, 0xf7, 0x71, 0xb0, 0xfe, 0x0c, 0xdb, 0x61, 0x40, 0xa8, 0xfe, - 0xaf, 0x12, 0x0b, 0x3d, 0x69, 0xd7, 0x21, 0xea, 0x60, 0x50, 0x1b, 0x16, 0x22, 0x14, 0x4c, 0xa8, - 0xd9, 0x37, 0xe4, 0xd8, 0xd7, 0x17, 0xb3, 0x73, 0x64, 0x74, 0x10, 0xfa, 0xe9, 0x38, 0xd4, 0x49, - 0xc1, 0x12, 0x99, 0xd3, 0x62, 0x32, 0x73, 0xda, 0x86, 0x85, 0x78, 0x70, 0x19, 0x06, 0x4b, 0xa5, - 0xb1, 0xde, 0xc0, 0x46, 0x6e, 0x0a, 0x76, 0xe9, 0x55, 0x28, 0x8b, 0xcf, 0x96, 0xa2, 0x69, 0x28, - 0xee, 0xac, 0xb6, 0xeb, 0x13, 0xe4, 0xc7, 0xee, 0x5a, 0xbb, 0xae, 0xa0, 0x32, 0x94, 0xb6, 0x57, - 0x77, 0xda, 0xf5, 0xc2, 0xa5, 0x3e, 0xd4, 0x93, 0x5f, 0xee, 0x44, 0x4b, 0x70, 0xac, 0xad, 0x6d, - 0xb5, 0x5b, 0xf7, 0x5b, 0x3b, 0x1b, 0x5b, 0x9b, 0x7a, 0x5b, 0xdb, 0x78, 0xdc, 0xda, 0x59, 0xaf, - 0x4f, 0xa0, 0x73, 0x70, 0x2a, 0xde, 0xf1, 0x60, 0x6b, 0x7b, 0x47, 0xdf, 0xd9, 0xd2, 0x57, 0xb7, - 0x36, 0x77, 0x5a, 0x1b, 0x9b, 0xeb, 0x5a, 0x5d, 0x41, 0xa7, 0xe0, 0x44, 0x1c, 0xe5, 0xde, 0xc6, - 0xda, 0x86, 0xb6, 0xbe, 0x4a, 0x7e, 0xb7, 0x1e, 0xd6, 0x0b, 0x97, 0xde, 0x81, 0xaa, 0x54, 0xe0, - 0x4c, 0x44, 0x6a, 0x6f, 0xad, 0xd5, 0x27, 0x50, 0x15, 0x2a, 0x71, 0x3e, 0x65, 0x28, 0x6d, 0x6e, - 0xad, 0xad, 0xd7, 0x0b, 0x08, 0x60, 0x6a, 0xa7, 0xa5, 0xdd, 0x5f, 0xdf, 0xa9, 0x17, 0x2f, 0xdd, - 0x4e, 0xbe, 0x4a, 0x8d, 0xd1, 0x3c, 0x54, 0xb7, 0x5b, 0x9b, 0x6b, 0xf7, 0xb6, 0xbe, 0xa2, 0x6b, - 0xeb, 0xad, 0xb5, 0xaf, 0xd6, 0x27, 0xd0, 0x02, 0xd4, 0x05, 0x68, 0x73, 0x6b, 0x87, 0x41, 0x95, - 0x4b, 0x4f, 0x13, 0x41, 0x13, 0x46, 0xc7, 0x61, 0x3e, 0x1c, 0x52, 0x5f, 0xd5, 0xd6, 0x5b, 0x3b, - 0xeb, 0x44, 0x12, 0x09, 0xac, 0xed, 0x6e, 0x6e, 0x6e, 0x6c, 0xde, 0xaf, 0x2b, 0x84, 0x6b, 0x04, - 0x5e, 0xff, 0xca, 0x06, 0x41, 0x2e, 0xc8, 0xc8, 0xbb, 0x9b, 0x5f, 0xdc, 0xdc, 0xfa, 0xf2, 0x66, - 0xbd, 0x78, 0xe9, 0xb7, 0xe3, 0x49, 0xbd, 0xc8, 0x0c, 0x96, 0x61, 0x29, 0x35, 0xa2, 0xbe, 0xfe, - 0x78, 0x7d, 0x73, 0xa7, 0x3e, 0x21, 0x77, 0x6e, 0xef, 0xb4, 0xb4, 0xa8, 0x53, 0x49, 0x76, 0x6e, - 0xb5, 0xdb, 0x61, 0x67, 0x41, 0xee, 0x5c, 0x5b, 0x7f, 0xb8, 0x1e, 0x51, 0x16, 0xaf, 0xff, 0x28, - 0xfa, 0x12, 0xe1, 0x36, 0xf6, 0x68, 0xe1, 0xe9, 0x1a, 0x4c, 0x8b, 0xef, 0xf2, 0x4a, 0x51, 0xbe, - 0xfc, 0x1d, 0xe1, 0xe6, 0x72, 0x66, 0x1f, 0xdf, 0x75, 0x13, 0xe8, 0x31, 0xbd, 0xa3, 0x89, 0x7d, - 0x77, 0xe4, 0x6c, 0xe2, 0x5e, 0x24, 0xf5, 0x79, 0x93, 0xe6, 0xb9, 0x1c, 0x8c, 0x90, 0xef, 0x57, - 0xa1, 0x26, 0x7f, 0x74, 0x0b, 0x9d, 0x93, 0xef, 0x4f, 0x32, 0xbe, 0xe7, 0xd5, 0x54, 0xf3, 0x50, - 0x42, 0xd6, 0x3a, 0xd4, 0x93, 0x1f, 0xdd, 0x42, 0x52, 0x5a, 0x72, 0xc8, 0x37, 0xbd, 0x9a, 0x9f, - 0xcb, 0x47, 0x8a, 0x0f, 0x90, 0xfa, 0x96, 0xd4, 0xf9, 0xfc, 0xaf, 0xf3, 0x64, 0x0c, 0x30, 0xec, - 0x13, 0x3e, 0x4c, 0x39, 0xf2, 0xa7, 0x21, 0x50, 0xe2, 0xf3, 0x4d, 0x19, 0x5f, 0x95, 0x91, 0x95, - 0x93, 0xfd, 0x45, 0x11, 0x75, 0x02, 0xfd, 0x3f, 0x98, 0x4b, 0xd4, 0x0e, 0x22, 0x89, 0x30, 0xbb, - 0x24, 0xb2, 0x79, 0x3e, 0x17, 0x47, 0x5e, 0xd5, 0x78, 0x7d, 0x60, 0x72, 0x55, 0x33, 0xea, 0x0e, - 0x93, 0xab, 0x9a, 0x59, 0x5e, 0x48, 0x0d, 0x51, 0xaa, 0x05, 0x94, 0x0d, 0x31, 0xab, 0xf6, 0xb0, - 0x79, 0x2e, 0x07, 0x23, 0xae, 0x90, 0x44, 0x35, 0xa0, 0xac, 0x90, 0xec, 0x3a, 0xc3, 0xe6, 0xf9, - 0x5c, 0x9c, 0xe4, 0x4a, 0x46, 0x55, 0x48, 0xe9, 0x95, 0x4c, 0x55, 0xc2, 0xa5, 0x57, 0x32, 0x5d, - 0xc4, 0xc4, 0x57, 0x32, 0x51, 0x37, 0xa4, 0xe6, 0xd6, 0x34, 0x64, 0xad, 0x64, 0x76, 0xdd, 0x83, - 0x3a, 0x81, 0x9e, 0x43, 0x63, 0x58, 0xea, 0x1a, 0x5d, 0x3e, 0x44, 0x86, 0xbd, 0xf9, 0xfa, 0x78, - 0xc8, 0xe1, 0xc0, 0x18, 0x50, 0x3a, 0x38, 0x41, 0xaf, 0xc8, 0xea, 0x1e, 0x12, 0xfc, 0x34, 0x5f, - 0x1d, 0x85, 0x16, 0x0e, 0x73, 0x1f, 0xca, 0x22, 0x29, 0x8e, 0x24, 0x17, 0x98, 0x48, 0xc6, 0x37, - 0x4f, 0x66, 0x77, 0x86, 0x8c, 0xbe, 0x00, 0x25, 0x02, 0x45, 0x4b, 0x49, 0x3c, 0xc1, 0xa0, 0x91, - 0xee, 0x08, 0x89, 0x5b, 0x30, 0xc5, 0xb2, 0xbd, 0x48, 0xba, 0x6e, 0x96, 0xb2, 0xd1, 0xcd, 0x66, - 0x56, 0x57, 0xc8, 0xa2, 0xcd, 0xbe, 0x72, 0xce, 0x93, 0xb7, 0xe8, 0x74, 0xf2, 0x73, 0x9b, 0x72, - 0x96, 0xb8, 0x79, 0x66, 0x68, 0x7f, 0xdc, 0x66, 0x13, 0x07, 0xf0, 0x73, 0x39, 0xb7, 0x44, 0x59, - 0x36, 0x9b, 0x7d, 0xf7, 0xc4, 0x16, 0x37, 0x7d, 0x37, 0x25, 0x2f, 0xee, 0xd0, 0xfb, 0x3f, 0x79, - 0x71, 0x87, 0x5f, 0x71, 0xb1, 0xad, 0x91, 0xfc, 0x46, 0x87, 0x9a, 0xf7, 0xfd, 0x9c, 0xac, 0xad, - 0x31, 0xe4, 0xbb, 0x3c, 0xea, 0x04, 0xda, 0x87, 0x63, 0x19, 0x1f, 0xee, 0x41, 0xaf, 0x0e, 0xf7, - 0xbf, 0xd2, 0x28, 0xaf, 0x8d, 0xc4, 0x8b, 0x8f, 0x94, 0x91, 0xb1, 0x91, 0x47, 0x1a, 0x9e, 0x32, - 0x92, 0x47, 0xca, 0x4b, 0xfd, 0x50, 0x43, 0xe4, 0x3e, 0xe4, 0x44, 0x56, 0x1a, 0x23, 0xc3, 0x10, - 0x53, 0x1e, 0x63, 0x1f, 0x8e, 0x65, 0x04, 0xf0, 0xb2, 0xb0, 0xc3, 0x0f, 0x16, 0xb2, 0xb0, 0x79, - 0x27, 0x81, 0x09, 0xf4, 0x35, 0x40, 0xf7, 0x71, 0x20, 0x47, 0x5e, 0x3e, 0x92, 0x36, 0x6a, 0xf2, - 0xac, 0x30, 0xc4, 0x3e, 0xa5, 0x43, 0x83, 0x3a, 0x71, 0x4d, 0xb9, 0xfe, 0x47, 0x45, 0x98, 0x65, - 0xf9, 0x42, 0x1e, 0x46, 0x3d, 0x02, 0x88, 0x52, 0xef, 0xe8, 0x54, 0x72, 0xf1, 0xa4, 0x7a, 0x86, - 0xe6, 0xe9, 0x61, 0xdd, 0xf1, 0xed, 0x1a, 0x4b, 0x69, 0xcb, 0xdb, 0x35, 0x9d, 0xa1, 0x97, 0xb7, - 0x6b, 0x46, 0x2e, 0x5c, 0x9d, 0x40, 0x1f, 0x40, 0x25, 0xcc, 0xa0, 0xca, 0x4a, 0x48, 0xa6, 0x82, - 0x9b, 0xa7, 0x86, 0xf4, 0xc6, 0xa5, 0x8b, 0x25, 0x46, 0x65, 0xe9, 0xd2, 0x49, 0x57, 0x59, 0xba, - 0xac, 0x8c, 0x6a, 0x34, 0x5f, 0x96, 0xba, 0xc8, 0x98, 0xaf, 0x94, 0xc9, 0xca, 0x98, 0xaf, 0x9c, - 0xf3, 0x50, 0x27, 0xee, 0xdd, 0xfd, 0xf1, 0x2f, 0x4e, 0x2b, 0x3f, 0xfb, 0xc5, 0xe9, 0x89, 0xdf, - 0xfa, 0xe8, 0xb4, 0xf2, 0xe3, 0x8f, 0x4e, 0x2b, 0x3f, 0xfd, 0xe8, 0xb4, 0xf2, 0xf3, 0x8f, 0x4e, - 0x2b, 0xdf, 0xf9, 0xf7, 0xd3, 0x13, 0x5f, 0x53, 0x9f, 0xde, 0xf4, 0x57, 0x2c, 0xe7, 0x6a, 0xc7, - 0xb3, 0xae, 0x18, 0xae, 0x75, 0xd5, 0x7d, 0xda, 0xbd, 0x6a, 0xb8, 0x96, 0x7f, 0x95, 0xf3, 0xbd, - 0xfa, 0xec, 0x8d, 0x27, 0x53, 0xf4, 0x3f, 0x3c, 0xbc, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0xc8, 0xcb, 0xbc, 0xe2, 0x9b, 0x63, 0x00, 0x00, + // 6254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3d, 0x4b, 0x6c, 0x1c, 0xc9, + 0x75, 0xec, 0x99, 0x21, 0x39, 0xf3, 0xc8, 0x19, 0x0e, 0x4b, 0x14, 0x39, 0x1a, 0xae, 0x28, 0xa9, + 0xe5, 0xdd, 0xd5, 0x67, 0x45, 0x69, 0xb5, 0xda, 0xb5, 0x24, 0x6b, 0x77, 0x35, 0x22, 0xb9, 0x12, + 0xd7, 0x12, 0x39, 0xee, 0x21, 0xe5, 0x5f, 0xe0, 0x4e, 0x6b, 0xba, 0x38, 0xec, 0xd5, 0x4c, 0x77, + 0xbb, 0xbb, 0x47, 0x12, 0x7d, 0xca, 0x31, 0xf1, 0xc9, 0x40, 0xe2, 0x18, 0x30, 0x82, 0x04, 0x39, + 0x04, 0x09, 0x90, 0x83, 0x73, 0x49, 0xe0, 0x20, 0x48, 0x02, 0x04, 0x81, 0xe1, 0x04, 0x08, 0xe0, + 0x43, 0x02, 0xf8, 0x10, 0x20, 0xf6, 0x26, 0xa7, 0x1c, 0x72, 0x89, 0x0f, 0xb9, 0x39, 0xa8, 0x4f, + 0x7f, 0xaa, 0x7f, 0x33, 0xc3, 0x5d, 0xef, 0xae, 0x4f, 0x9c, 0x7a, 0xf5, 0xde, 0xab, 0xaa, 0x57, + 0xaf, 0x5e, 0xbf, 0xaa, 0xf7, 0xaa, 0x08, 0x15, 0xcd, 0x36, 0xd6, 0x6d, 0xc7, 0xf2, 0x2c, 0x04, + 0xce, 0xd0, 0xf4, 0x8c, 0x01, 0x5e, 0x7f, 0xf6, 0x7a, 0xf3, 0x4a, 0xcf, 0xf0, 0x0e, 0x87, 0x4f, + 0xd6, 0xbb, 0xd6, 0xe0, 0x6a, 0xcf, 0xea, 0x59, 0x57, 0x29, 0xca, 0x93, 0xe1, 0x01, 0x2d, 0xd1, + 0x02, 0xfd, 0xc5, 0x48, 0xe5, 0x4b, 0x50, 0x7b, 0x8c, 0x1d, 0xd7, 0xb0, 0x4c, 0x05, 0x7f, 0x73, + 0x88, 0x5d, 0x0f, 0x35, 0x60, 0xf6, 0x19, 0x83, 0x34, 0xa4, 0xb3, 0xd2, 0x85, 0x8a, 0xe2, 0x17, + 0xe5, 0x3f, 0x95, 0x60, 0x21, 0x40, 0x76, 0x6d, 0xcb, 0x74, 0x71, 0x36, 0x36, 0x3a, 0x07, 0xf3, + 0xbc, 0x5b, 0xaa, 0xa9, 0x0d, 0x70, 0xa3, 0x40, 0xab, 0xe7, 0x38, 0x6c, 0x47, 0x1b, 0x60, 0xf4, + 0x2a, 0x2c, 0xf8, 0x28, 0x3e, 0x93, 0x22, 0xc5, 0xaa, 0x71, 0x30, 0x6f, 0x0d, 0xad, 0xc3, 0x09, + 0x1f, 0x51, 0xb3, 0x8d, 0x00, 0xb9, 0x44, 0x91, 0x17, 0x79, 0x55, 0xcb, 0x36, 0x38, 0xbe, 0xfc, + 0x75, 0xa8, 0x6c, 0xee, 0x74, 0x36, 0x2c, 0xf3, 0xc0, 0xe8, 0x91, 0x2e, 0xba, 0xd8, 0x21, 0x34, + 0x0d, 0xe9, 0x6c, 0x91, 0x74, 0x91, 0x17, 0x51, 0x13, 0xca, 0x2e, 0xd6, 0x9c, 0xee, 0x21, 0x76, + 0x1b, 0x05, 0x5a, 0x15, 0x94, 0x09, 0x95, 0x65, 0x7b, 0x86, 0x65, 0xba, 0x8d, 0x22, 0xa3, 0xe2, + 0x45, 0xf9, 0x0f, 0x24, 0x98, 0x6b, 0x5b, 0x8e, 0xf7, 0x48, 0xb3, 0x6d, 0xc3, 0xec, 0xa1, 0x6b, + 0x50, 0xa6, 0xb2, 0xec, 0x5a, 0x7d, 0x2a, 0x83, 0xda, 0xf5, 0xa5, 0xf5, 0x70, 0x42, 0xd6, 0xdb, + 0xbc, 0x4e, 0x09, 0xb0, 0xd0, 0xcb, 0x50, 0xeb, 0x5a, 0xa6, 0xa7, 0x19, 0x26, 0x76, 0x54, 0xdb, + 0x72, 0x3c, 0x2a, 0x9c, 0x69, 0xa5, 0x1a, 0x40, 0x09, 0x7f, 0xb4, 0x0a, 0x95, 0x43, 0xcb, 0xf5, + 0x18, 0x46, 0x91, 0x62, 0x94, 0x09, 0x80, 0x56, 0xae, 0xc0, 0x2c, 0xad, 0x34, 0x6c, 0x2e, 0x86, + 0x19, 0x52, 0xdc, 0xb6, 0xe5, 0x9f, 0x48, 0x30, 0xfd, 0xc8, 0x1a, 0x9a, 0x5e, 0xac, 0x19, 0xcd, + 0x3b, 0xe4, 0x53, 0x14, 0x69, 0x46, 0xf3, 0x0e, 0xc3, 0x66, 0x08, 0x06, 0x9b, 0x25, 0xd6, 0x0c, + 0xa9, 0x6c, 0x42, 0xd9, 0xc1, 0x9a, 0x6e, 0x99, 0xfd, 0x23, 0xda, 0x85, 0xb2, 0x12, 0x94, 0xc9, + 0xf4, 0xb9, 0xb8, 0x6f, 0x98, 0xc3, 0x17, 0xaa, 0x83, 0xfb, 0xda, 0x13, 0xdc, 0xa7, 0x5d, 0x29, + 0x2b, 0x35, 0x0e, 0x56, 0x18, 0x14, 0xbd, 0x03, 0x73, 0xb6, 0x63, 0xd9, 0x5a, 0x4f, 0x23, 0x12, + 0x6c, 0x4c, 0x53, 0x21, 0xbd, 0x14, 0x15, 0x12, 0xed, 0x70, 0x3b, 0xc4, 0x51, 0xa2, 0x04, 0xb2, + 0x0a, 0x95, 0xed, 0x4d, 0x5f, 0xdc, 0xc1, 0xc0, 0x75, 0x3a, 0x9c, 0x2a, 0x1f, 0xb8, 0x4e, 0x14, + 0x2e, 0x1c, 0xae, 0xa1, 0xd3, 0xa1, 0x54, 0x95, 0xb9, 0x00, 0xb6, 0xad, 0xa3, 0x65, 0x98, 0xe9, + 0x63, 0xb3, 0xe7, 0x1d, 0xd2, 0xb1, 0x54, 0x15, 0x5e, 0x92, 0x7f, 0x4f, 0x82, 0xea, 0xbe, 0x8b, + 0x1d, 0xa2, 0x95, 0xae, 0xad, 0x75, 0x31, 0xba, 0x02, 0xa5, 0x81, 0xa5, 0x63, 0x3e, 0xa1, 0xa7, + 0xa2, 0x7d, 0x0d, 0x90, 0x1e, 0x59, 0x3a, 0x56, 0x28, 0x1a, 0xba, 0x08, 0xa5, 0xa1, 0xa1, 0x33, + 0x2d, 0x9a, 0xbb, 0x7e, 0x32, 0x8a, 0x1e, 0xf4, 0x5c, 0xa1, 0x28, 0x04, 0xb5, 0x47, 0x50, 0x8b, + 0xb9, 0xa8, 0x04, 0x45, 0xfe, 0xa5, 0x04, 0x0b, 0x41, 0x6b, 0xbb, 0x54, 0xfd, 0xd0, 0x1b, 0x30, + 0x6b, 0x62, 0xef, 0xb9, 0xe5, 0x3c, 0x1d, 0xdd, 0x37, 0x1f, 0x13, 0x5d, 0x86, 0xa2, 0xcd, 0x25, + 0x92, 0x4b, 0x40, 0xb0, 0x08, 0xb2, 0x61, 0x77, 0xa9, 0x84, 0xf2, 0x91, 0x0d, 0xbb, 0x4b, 0x94, + 0xc7, 0xd3, 0x9c, 0x1e, 0xa6, 0xf3, 0xc1, 0x14, 0xb1, 0xcc, 0x00, 0xdb, 0x3a, 0xba, 0x0b, 0xb5, + 0xa1, 0x8b, 0x1d, 0xd3, 0x55, 0xfd, 0xa5, 0x44, 0xa6, 0x7e, 0x4e, 0x64, 0x2a, 0xc8, 0x5d, 0xa9, + 0x32, 0x82, 0x5d, 0xbe, 0xd6, 0x64, 0x80, 0x6d, 0xd3, 0x7b, 0xeb, 0xc6, 0x63, 0xad, 0x3f, 0xc4, + 0x68, 0x09, 0xa6, 0x9f, 0x91, 0x1f, 0x74, 0xe4, 0x45, 0x85, 0x15, 0xe4, 0xbf, 0x2d, 0xc1, 0xea, + 0x43, 0xa2, 0x6e, 0x1d, 0xcd, 0xd4, 0x9f, 0x58, 0x2f, 0x3a, 0xb8, 0x3b, 0x74, 0x0c, 0xef, 0x68, + 0xc3, 0x32, 0x3d, 0xfc, 0xc2, 0x43, 0x0f, 0x60, 0xd1, 0xf4, 0xf9, 0x07, 0x1d, 0x91, 0x68, 0x47, + 0x56, 0x53, 0x47, 0xc7, 0x1a, 0x57, 0xea, 0xa6, 0x08, 0x70, 0xd1, 0xbd, 0x50, 0xe1, 0x7d, 0x3e, + 0x85, 0xe4, 0x80, 0x3a, 0x5b, 0xb4, 0x37, 0x9c, 0x8b, 0xbf, 0x16, 0x7c, 0x1e, 0x6f, 0x01, 0x31, + 0x81, 0xaa, 0xe6, 0xaa, 0x64, 0xa4, 0x54, 0xca, 0x73, 0xd7, 0x97, 0x05, 0x2d, 0x08, 0x06, 0xac, + 0x54, 0x9c, 0xa1, 0xd9, 0x72, 0x89, 0x84, 0xd0, 0x4d, 0x6a, 0x4e, 0x09, 0x5d, 0xcf, 0xb1, 0x86, + 0x76, 0xa3, 0x9c, 0x4b, 0x08, 0x94, 0xf0, 0x3e, 0xc1, 0xa4, 0x56, 0x96, 0x2f, 0x59, 0xd5, 0xb1, + 0x2c, 0xef, 0xc0, 0xf5, 0x97, 0xa9, 0x0f, 0x56, 0x28, 0x14, 0x5d, 0x85, 0x13, 0xee, 0xd0, 0xb6, + 0xfb, 0x78, 0x80, 0x4d, 0x4f, 0xeb, 0xb3, 0x86, 0xc8, 0x9c, 0x15, 0x2f, 0x14, 0x15, 0x14, 0xad, + 0xa2, 0x8c, 0x5d, 0xb4, 0x06, 0x60, 0x3b, 0xc6, 0x33, 0xa3, 0x8f, 0x7b, 0x58, 0x6f, 0xcc, 0x50, + 0xa6, 0x11, 0x08, 0x7a, 0x93, 0x58, 0xde, 0x6e, 0xd7, 0x1a, 0xd8, 0x8d, 0x4a, 0x52, 0xde, 0xfe, + 0x3c, 0xb5, 0x1d, 0xeb, 0xc0, 0xe8, 0x63, 0xc5, 0xc7, 0x45, 0x9f, 0x87, 0xb2, 0x66, 0xdb, 0x9a, + 0x33, 0xb0, 0x9c, 0x06, 0x8c, 0xa6, 0x0b, 0x90, 0xd1, 0x0d, 0x58, 0xe2, 0x3c, 0x54, 0x9b, 0x55, + 0x32, 0xa3, 0x36, 0x4b, 0xf4, 0xf2, 0x5e, 0xa1, 0x21, 0x29, 0x88, 0xd7, 0x73, 0x5a, 0x62, 0xe2, + 0xe4, 0x7f, 0x94, 0x60, 0x21, 0xc6, 0x13, 0xbd, 0x0f, 0xf3, 0x3e, 0x07, 0xef, 0xc8, 0xf6, 0xcd, + 0xc0, 0xab, 0x39, 0xdd, 0x58, 0xe7, 0x7f, 0xf7, 0x8e, 0x6c, 0x4c, 0xad, 0x97, 0x5f, 0x40, 0xe7, + 0xa1, 0xda, 0xb7, 0xba, 0x5a, 0x9f, 0x5a, 0x2d, 0x07, 0x1f, 0x70, 0x1b, 0x3b, 0x1f, 0x00, 0x15, + 0x7c, 0x20, 0xdf, 0x85, 0xb9, 0x08, 0x03, 0x84, 0xa0, 0xa6, 0xb0, 0xa6, 0x36, 0xf1, 0x81, 0x36, + 0xec, 0x7b, 0xf5, 0x29, 0x54, 0x03, 0xd8, 0x37, 0xbb, 0xe4, 0x9b, 0x66, 0x62, 0xbd, 0x2e, 0xa1, + 0x2a, 0x54, 0x1e, 0xfa, 0x2c, 0xea, 0x05, 0xf9, 0xfb, 0x45, 0x38, 0x49, 0x15, 0xaf, 0x6d, 0xe9, + 0x7c, 0x25, 0xf0, 0x0f, 0xe0, 0x79, 0xa8, 0x76, 0xe9, 0x5c, 0xaa, 0xb6, 0xe6, 0x60, 0xd3, 0xe3, + 0x9f, 0x81, 0x79, 0x06, 0x6c, 0x53, 0x18, 0x52, 0xa0, 0xee, 0xf2, 0x11, 0xa9, 0x5d, 0xb6, 0x72, + 0xb8, 0x72, 0x0b, 0xa3, 0xce, 0x59, 0x68, 0xca, 0x82, 0x9b, 0x58, 0x79, 0xb3, 0xee, 0x91, 0xdb, + 0xf5, 0xfa, 0xbe, 0xb5, 0x5b, 0x4f, 0xb0, 0x8a, 0x77, 0x76, 0xbd, 0xc3, 0x08, 0xb6, 0x4c, 0xcf, + 0x39, 0x52, 0x7c, 0x72, 0xf4, 0x2e, 0x94, 0xad, 0x67, 0xd8, 0x39, 0xc4, 0x1a, 0xb3, 0x32, 0x73, + 0xd7, 0xcf, 0x27, 0x58, 0x6d, 0xf8, 0x86, 0x5e, 0xc1, 0xae, 0x35, 0x74, 0xba, 0xd8, 0x55, 0x02, + 0x22, 0xd4, 0x82, 0x8a, 0xe3, 0x83, 0xb9, 0x15, 0x1a, 0x8b, 0x43, 0x48, 0xd5, 0xbc, 0x0d, 0xf3, + 0xd1, 0xce, 0xa1, 0x3a, 0x14, 0x9f, 0xe2, 0x23, 0x2e, 0x4c, 0xf2, 0x33, 0xb4, 0x4f, 0x6c, 0x86, + 0x59, 0xe1, 0x76, 0xe1, 0xa6, 0x24, 0x3b, 0x80, 0xc2, 0x91, 0x3e, 0xc2, 0x9e, 0xa6, 0x6b, 0x9e, + 0x86, 0x10, 0x94, 0xa8, 0x6b, 0xc4, 0x58, 0xd0, 0xdf, 0x84, 0xeb, 0x90, 0x9b, 0xea, 0x8a, 0x42, + 0x7e, 0xa2, 0x97, 0xa0, 0x12, 0x58, 0x22, 0xee, 0x1f, 0x85, 0x00, 0xe2, 0xa7, 0x68, 0x9e, 0x87, + 0x07, 0xb6, 0x47, 0x05, 0x53, 0x55, 0xfc, 0xa2, 0xfc, 0x3b, 0xd3, 0x50, 0x4f, 0xe8, 0xc2, 0x6d, + 0x28, 0x0f, 0x78, 0xf3, 0xdc, 0x06, 0xae, 0x09, 0xce, 0x4a, 0xa2, 0x93, 0x4a, 0x80, 0x4f, 0x7c, + 0x01, 0xa2, 0x6b, 0x11, 0x6f, 0x2e, 0x28, 0x33, 0x25, 0xef, 0xa9, 0xba, 0xe1, 0xe0, 0xae, 0x67, + 0x39, 0x47, 0xbc, 0xa3, 0xf3, 0x7d, 0xab, 0xb7, 0xe9, 0xc3, 0xd0, 0x0d, 0x00, 0xdd, 0x74, 0x55, + 0xaa, 0xc3, 0x3d, 0x3e, 0x8f, 0xc2, 0x07, 0x30, 0x70, 0xda, 0x94, 0x8a, 0x6e, 0xba, 0xbc, 0xcb, + 0x77, 0xa0, 0x4a, 0x3c, 0x20, 0x75, 0xc0, 0xbe, 0x8d, 0xcc, 0x20, 0xcd, 0x5d, 0x5f, 0x11, 0xfb, + 0x1d, 0xf8, 0x63, 0xca, 0xbc, 0x1d, 0x16, 0x5c, 0x74, 0x17, 0x66, 0xa8, 0x13, 0xe2, 0x36, 0x66, + 0x28, 0xd9, 0x85, 0xf4, 0xe1, 0x72, 0xed, 0x7b, 0x48, 0x51, 0x99, 0xf2, 0x71, 0x3a, 0xb4, 0x0b, + 0x73, 0x9a, 0x69, 0x5a, 0x9e, 0xc6, 0x2c, 0xfe, 0x2c, 0x65, 0x73, 0x25, 0x97, 0x4d, 0x2b, 0xc4, + 0x67, 0xbc, 0xa2, 0x1c, 0xd0, 0xe7, 0x61, 0x9a, 0x7e, 0x12, 0xb8, 0x0d, 0x3f, 0x37, 0x72, 0x51, + 0x28, 0x0c, 0x1f, 0xbd, 0x0d, 0xb3, 0xcf, 0x0d, 0x53, 0xb7, 0x9e, 0xbb, 0xdc, 0x9e, 0x0a, 0x2a, + 0xfc, 0x65, 0x56, 0x95, 0x20, 0xf6, 0x69, 0x9a, 0xb7, 0x60, 0x2e, 0x32, 0xbe, 0x49, 0xf4, 0xb7, + 0xf9, 0x0e, 0xd4, 0xe3, 0x63, 0x9a, 0x48, 0xff, 0x87, 0xb0, 0xa4, 0x0c, 0xcd, 0xb0, 0x6b, 0xfe, + 0x66, 0xe3, 0x06, 0xcc, 0x70, 0x6d, 0x60, 0xca, 0xf8, 0x52, 0x9e, 0x58, 0x15, 0x8e, 0x1b, 0xdd, + 0x37, 0x1c, 0x6a, 0xa6, 0xde, 0xc7, 0x0e, 0x6f, 0xd1, 0xdf, 0x37, 0x3c, 0x60, 0x50, 0xf9, 0x6d, + 0x38, 0x19, 0x6b, 0x96, 0x6f, 0x5b, 0x3e, 0x07, 0x35, 0xdb, 0xd2, 0x55, 0x97, 0x81, 0x7d, 0x5f, + 0xb2, 0x42, 0x74, 0xc7, 0xc7, 0xdd, 0xd6, 0x09, 0x79, 0xc7, 0xb3, 0xec, 0x64, 0xb7, 0xc7, 0x23, + 0x6f, 0xc0, 0x72, 0x9c, 0x9c, 0x35, 0x2f, 0xbf, 0x0b, 0x2b, 0x0a, 0x1e, 0x58, 0xcf, 0xf0, 0x71, + 0x59, 0x37, 0xa1, 0x91, 0x64, 0xc0, 0x99, 0x7f, 0x15, 0x56, 0x42, 0x68, 0xc7, 0xd3, 0xbc, 0xa1, + 0x3b, 0x11, 0x73, 0xbe, 0xa7, 0x7b, 0x62, 0xb9, 0x6c, 0x22, 0xcb, 0x8a, 0x5f, 0x94, 0x57, 0x60, + 0xba, 0x6d, 0xe9, 0xdb, 0x6d, 0x54, 0x83, 0x82, 0x61, 0x73, 0xe2, 0x82, 0x61, 0xcb, 0xdd, 0x68, + 0x9b, 0x3b, 0xcc, 0xeb, 0x64, 0x4d, 0xc7, 0x51, 0xd1, 0x4d, 0xa8, 0x69, 0xba, 0x6e, 0x10, 0x45, + 0xd2, 0xfa, 0xaa, 0x61, 0xfb, 0x4e, 0xf3, 0x62, 0x6c, 0xea, 0xb7, 0xdb, 0x4a, 0x35, 0x44, 0xdc, + 0xb6, 0x5d, 0xf9, 0x1e, 0x54, 0x42, 0x07, 0xfd, 0xcd, 0x70, 0x7f, 0x56, 0x18, 0xed, 0xcb, 0x05, + 0x9b, 0xb7, 0x9d, 0xc4, 0x47, 0x92, 0x77, 0xf3, 0x4d, 0x80, 0xc0, 0xa8, 0xfa, 0xee, 0xe1, 0xc9, + 0x54, 0x96, 0x4a, 0x04, 0x51, 0xfe, 0x8f, 0x52, 0xd4, 0xc8, 0x46, 0x86, 0xac, 0x07, 0x43, 0xd6, + 0x05, 0xa3, 0x5b, 0x98, 0xd0, 0xe8, 0xbe, 0x0e, 0xd3, 0xae, 0xa7, 0x79, 0x98, 0xfb, 0xe3, 0xab, + 0xe9, 0x84, 0xa4, 0x61, 0xac, 0x30, 0x4c, 0x74, 0x1a, 0xa0, 0xeb, 0x60, 0xcd, 0xc3, 0xba, 0xaa, + 0xb1, 0xaf, 0x42, 0x51, 0xa9, 0x70, 0x48, 0xcb, 0x23, 0x56, 0xc4, 0xdf, 0x41, 0xa4, 0x7c, 0x08, + 0x33, 0xa6, 0x31, 0xdc, 0x4b, 0x04, 0xd6, 0x6b, 0x66, 0xa4, 0xf5, 0xe2, 0xa4, 0xdc, 0x7a, 0x85, + 0x96, 0x78, 0x36, 0xcf, 0x12, 0x33, 0xa2, 0x71, 0x2c, 0x71, 0x39, 0xcf, 0x12, 0x73, 0x36, 0xf9, + 0x96, 0x38, 0xc5, 0x90, 0x54, 0xd2, 0x0c, 0xc9, 0xa7, 0x69, 0x3a, 0xff, 0xba, 0x00, 0x8d, 0xe4, + 0x7a, 0xe6, 0x76, 0xec, 0x06, 0xcc, 0xb8, 0x14, 0x92, 0x6f, 0x3f, 0x39, 0x15, 0xc7, 0x45, 0xf7, + 0xa0, 0x64, 0x98, 0x07, 0x16, 0x5f, 0x78, 0xeb, 0xb9, 0x34, 0xbc, 0xa5, 0xf5, 0x6d, 0xf3, 0xc0, + 0x62, 0x12, 0xa4, 0xb4, 0xe8, 0x21, 0x9c, 0x08, 0x76, 0xd6, 0xae, 0xca, 0x18, 0x63, 0xdf, 0xcf, + 0x13, 0xb4, 0x34, 0xf0, 0xaa, 0x38, 0x47, 0x14, 0xd2, 0x75, 0x38, 0x19, 0xf1, 0x71, 0x08, 0xba, + 0xeb, 0x69, 0x03, 0xdb, 0xd7, 0xd8, 0x00, 0xd0, 0xfc, 0x3c, 0x54, 0x82, 0xe6, 0x27, 0x92, 0xdd, + 0x36, 0x2c, 0xc5, 0xd6, 0x08, 0xdb, 0x48, 0x06, 0x8b, 0x4a, 0x1a, 0x77, 0x51, 0xc9, 0xbf, 0x90, + 0xa2, 0x0b, 0xfd, 0x3d, 0xa3, 0xef, 0x61, 0x27, 0xb1, 0xd0, 0xdf, 0xf2, 0xf9, 0xb2, 0x55, 0x7e, + 0x36, 0x87, 0x2f, 0xdb, 0xa7, 0xf1, 0x15, 0xfb, 0x18, 0x6a, 0x54, 0xc5, 0x55, 0x17, 0xf7, 0xa9, + 0xaf, 0xc4, 0xe5, 0x78, 0x35, 0x9d, 0x01, 0x6b, 0x9d, 0x2d, 0x91, 0x0e, 0xa7, 0x60, 0x73, 0x53, + 0xed, 0x47, 0x61, 0xcd, 0xbb, 0x80, 0x92, 0x48, 0x13, 0x49, 0xf0, 0x11, 0xb1, 0x97, 0xae, 0x97, + 0xfa, 0xe5, 0x3e, 0xa0, 0xdd, 0xc8, 0xd7, 0x3c, 0xd6, 0x55, 0x85, 0xe3, 0xca, 0xff, 0x56, 0x04, + 0x08, 0x2b, 0x3f, 0xe3, 0x86, 0xf2, 0x76, 0x60, 0xb0, 0x98, 0xc7, 0x29, 0xa7, 0xb3, 0x4c, 0x35, + 0x55, 0xdb, 0xa2, 0xa9, 0x62, 0xbe, 0xe7, 0xab, 0x19, 0x0c, 0x26, 0x36, 0x52, 0xb3, 0x9f, 0x35, + 0x23, 0xf5, 0x1e, 0x2c, 0xc7, 0xd5, 0x84, 0x5b, 0xa8, 0xd7, 0x60, 0xda, 0xf0, 0xf0, 0x80, 0x9d, + 0xbd, 0xc6, 0x0e, 0x2c, 0x22, 0xe8, 0x0c, 0x49, 0x7e, 0x07, 0x96, 0xc5, 0xb9, 0x9a, 0xcc, 0x75, + 0x91, 0x1f, 0xc6, 0x7d, 0x9f, 0xd0, 0x54, 0x72, 0xfd, 0x48, 0x3d, 0xfa, 0x89, 0xd3, 0x30, 0x4c, + 0xf9, 0x47, 0x12, 0x9c, 0x8c, 0x55, 0x65, 0x2c, 0xfc, 0xaf, 0x27, 0x16, 0x30, 0xb3, 0xad, 0x37, + 0x72, 0x5a, 0xf9, 0x04, 0x57, 0xf1, 0x97, 0xa1, 0x29, 0x4e, 0x8f, 0x20, 0xda, 0x5b, 0xb1, 0xa5, + 0x7c, 0x6e, 0x64, 0xa7, 0x83, 0xf5, 0xdc, 0x86, 0xd5, 0x54, 0xc6, 0x49, 0x99, 0x17, 0xc7, 0x94, + 0xf9, 0xff, 0x15, 0xa2, 0x36, 0xbb, 0xe5, 0x79, 0x8e, 0xf1, 0x64, 0xe8, 0xe1, 0x8f, 0xd7, 0xa9, + 0xda, 0x0c, 0x56, 0x36, 0xb3, 0xb3, 0xaf, 0xa5, 0x53, 0x86, 0xad, 0xa7, 0xae, 0xf1, 0x8e, 0xb8, + 0xc6, 0x4b, 0x94, 0xd5, 0xeb, 0x23, 0x59, 0xe5, 0xae, 0xf6, 0x4f, 0x73, 0x11, 0xff, 0x93, 0x04, + 0x0b, 0xb1, 0x59, 0x41, 0x77, 0x01, 0xb4, 0xa0, 0xeb, 0x5c, 0x3f, 0xce, 0x8e, 0x1a, 0xa2, 0x12, + 0xa1, 0x21, 0xdf, 0x44, 0xe6, 0x2f, 0xa6, 0x7c, 0x13, 0x53, 0xfc, 0xc5, 0xc0, 0x5d, 0xbc, 0x13, + 0x6e, 0x76, 0xd9, 0x21, 0xa9, 0x9c, 0xbb, 0xd9, 0x65, 0xb4, 0x3e, 0x89, 0xfc, 0xbb, 0x05, 0x58, + 0x4a, 0xe3, 0x8e, 0x5e, 0x81, 0x62, 0xd7, 0x1e, 0xf2, 0x91, 0x08, 0x81, 0x9a, 0x0d, 0x7b, 0xb8, + 0xef, 0x6a, 0x3d, 0xac, 0x10, 0x04, 0x74, 0x15, 0x66, 0x06, 0x78, 0x60, 0x39, 0x47, 0xbc, 0xdf, + 0xc2, 0x71, 0xc3, 0x23, 0x5a, 0xc3, 0xb0, 0x39, 0x1a, 0xba, 0x1e, 0xba, 0xd5, 0xac, 0xbf, 0x0d, + 0x61, 0xf7, 0xc0, 0xaa, 0x18, 0x49, 0xe0, 0x4b, 0x5f, 0x87, 0x59, 0xdb, 0xb1, 0xba, 0xd8, 0x75, + 0xf9, 0x69, 0x48, 0x23, 0x16, 0x39, 0x22, 0x55, 0x9c, 0x86, 0x23, 0xa2, 0xdb, 0x00, 0xa1, 0x03, + 0xc5, 0xbf, 0x4c, 0xcd, 0x4c, 0x7f, 0xcb, 0x55, 0x22, 0xd8, 0xf2, 0x0f, 0x0b, 0xb0, 0x9c, 0x2e, + 0x39, 0x74, 0x25, 0x2a, 0x97, 0xd5, 0x14, 0x51, 0x8b, 0xe2, 0x79, 0x2b, 0x26, 0x9e, 0xb5, 0x14, + 0x8a, 0x34, 0x29, 0xdd, 0x8a, 0x4b, 0xe9, 0x4c, 0x0a, 0x61, 0xba, 0xb0, 0x6e, 0xc5, 0x85, 0x95, + 0x46, 0x9a, 0x2e, 0xb3, 0x56, 0x8a, 0xcc, 0xce, 0xa5, 0x8d, 0x31, 0x5b, 0x74, 0x7f, 0x2f, 0xc1, + 0x7c, 0xb4, 0x5f, 0xa2, 0xcb, 0x2a, 0xc5, 0x5c, 0x56, 0xb4, 0x03, 0x8b, 0x3a, 0x3b, 0xb9, 0x55, + 0x0d, 0xd3, 0xc3, 0xce, 0x81, 0xd6, 0xf5, 0xbd, 0xc2, 0x73, 0x29, 0x7a, 0xb1, 0xed, 0xe3, 0xb0, + 0x8e, 0xd7, 0x39, 0x6d, 0x00, 0x26, 0x23, 0x08, 0xf8, 0xf8, 0x56, 0x6b, 0x0c, 0x46, 0x11, 0x22, + 0xf9, 0x5f, 0x25, 0x38, 0x91, 0x22, 0xe0, 0x11, 0x03, 0xd9, 0xcf, 0x1e, 0xc8, 0x85, 0xec, 0xa9, + 0x1b, 0x39, 0x9e, 0x07, 0x29, 0xe3, 0x19, 0x9f, 0x5f, 0x74, 0x58, 0xbf, 0x94, 0xe0, 0x64, 0x2a, + 0x56, 0xea, 0xf1, 0xea, 0x75, 0x28, 0x3b, 0x2f, 0xd4, 0x27, 0x47, 0x1e, 0x76, 0xd3, 0x16, 0xf6, + 0x7e, 0x24, 0x86, 0x32, 0xeb, 0xbc, 0xb8, 0x47, 0xf0, 0xd0, 0x0d, 0xa8, 0x38, 0x2f, 0x54, 0xec, + 0x38, 0x96, 0xe3, 0xdb, 0xa2, 0x4c, 0xa2, 0xb2, 0xf3, 0x62, 0x8b, 0x22, 0x92, 0x96, 0x3c, 0xbf, + 0xa5, 0xd2, 0x88, 0x96, 0xbc, 0xb0, 0x25, 0x2f, 0x68, 0x69, 0x7a, 0x44, 0x4b, 0x1e, 0x6f, 0x49, + 0xfe, 0xb3, 0x02, 0xbc, 0x94, 0x27, 0xae, 0x8f, 0x4d, 0x10, 0x5b, 0x80, 0x9c, 0x17, 0xaa, 0xad, + 0x75, 0x9f, 0x62, 0xcf, 0x55, 0x75, 0xc7, 0xb2, 0x6d, 0xac, 0x8f, 0x92, 0x48, 0xdd, 0x79, 0xd1, + 0x66, 0x14, 0x9b, 0x8c, 0xe0, 0x58, 0x92, 0xd9, 0x02, 0xe4, 0x25, 0x9b, 0x1e, 0x21, 0xa2, 0xba, + 0x17, 0x6b, 0x5a, 0xfe, 0x00, 0xe6, 0xa3, 0x16, 0x62, 0x84, 0xee, 0xdf, 0x81, 0x2a, 0xb7, 0x20, + 0x6a, 0xd7, 0x1a, 0x9a, 0xde, 0x28, 0x41, 0xcd, 0x73, 0xec, 0x0d, 0x82, 0x2c, 0x7f, 0x33, 0x58, + 0x6e, 0x9f, 0x58, 0x93, 0x7f, 0x2e, 0x41, 0x65, 0x7b, 0xa0, 0xf5, 0x70, 0xc7, 0xc6, 0x5d, 0xf2, + 0xa5, 0x37, 0x48, 0x81, 0xcf, 0x3b, 0x2b, 0xa0, 0x07, 0xa2, 0xd7, 0xc2, 0xfc, 0xd4, 0x57, 0x84, + 0x38, 0xa2, 0xcf, 0x61, 0x84, 0xab, 0xf2, 0x51, 0xfd, 0x8d, 0xeb, 0x50, 0xfe, 0x22, 0x3e, 0x62, + 0x3b, 0xf2, 0x31, 0xe9, 0xe4, 0xef, 0x96, 0x60, 0x25, 0x23, 0x56, 0x43, 0xb7, 0x73, 0xf6, 0x50, + 0xb5, 0xb1, 0x63, 0x58, 0xba, 0x2f, 0xda, 0xae, 0x3d, 0x6c, 0x53, 0x00, 0x5a, 0x05, 0x52, 0x50, + 0xbf, 0x39, 0xb4, 0xb8, 0xc7, 0x58, 0x54, 0xca, 0x5d, 0x7b, 0xf8, 0x25, 0x52, 0xf6, 0x69, 0xdd, + 0x43, 0xcd, 0xc1, 0x6c, 0x91, 0x33, 0xda, 0x0e, 0x05, 0xa0, 0xd7, 0xe1, 0x24, 0xfb, 0x80, 0xa9, + 0x7d, 0x63, 0x60, 0x10, 0x53, 0x18, 0xd1, 0xdf, 0xa2, 0x82, 0x58, 0xe5, 0x43, 0x52, 0xb7, 0x6d, + 0x32, 0x8d, 0x95, 0xa1, 0x6a, 0x59, 0x03, 0xd5, 0xed, 0x5a, 0x0e, 0x56, 0x35, 0xfd, 0x03, 0xaa, + 0xac, 0x45, 0x65, 0xce, 0xb2, 0x06, 0x1d, 0x02, 0x6b, 0xe9, 0x1f, 0xa0, 0x33, 0x30, 0xd7, 0xb5, + 0x87, 0x2e, 0xf6, 0x54, 0xf2, 0x87, 0x9e, 0xa8, 0x55, 0x14, 0x60, 0xa0, 0x0d, 0x7b, 0xe8, 0x46, + 0x10, 0x06, 0x64, 0x0f, 0x35, 0x1b, 0x45, 0x78, 0x84, 0x07, 0x34, 0x24, 0x7d, 0x38, 0xec, 0x61, + 0x5b, 0xeb, 0x61, 0xd6, 0x35, 0xff, 0x58, 0x4c, 0x08, 0x49, 0x3f, 0xe0, 0x28, 0xb4, 0x83, 0x4a, + 0xed, 0x30, 0x5a, 0x74, 0xd1, 0xfb, 0x30, 0x3b, 0x34, 0x8d, 0x03, 0x03, 0xeb, 0x8d, 0x0a, 0xa5, + 0xbd, 0x36, 0x46, 0x64, 0x6c, 0x7d, 0x9f, 0x91, 0xf0, 0x40, 0x1d, 0x67, 0x80, 0x6e, 0x43, 0x93, + 0x0b, 0xca, 0x7d, 0xae, 0xd9, 0x71, 0x69, 0x01, 0x15, 0xc1, 0x32, 0xc3, 0xe8, 0x3c, 0xd7, 0xec, + 0xa8, 0xc4, 0x9a, 0xb7, 0x61, 0x3e, 0xca, 0x74, 0x22, 0x5d, 0xba, 0x07, 0x55, 0x61, 0x90, 0x64, + 0xb6, 0xa9, 0x50, 0x5c, 0xe3, 0x5b, 0xfe, 0x02, 0x28, 0x13, 0x40, 0xc7, 0xf8, 0x16, 0x4d, 0x24, + 0xa0, 0x3d, 0xa3, 0x7c, 0x4a, 0x0a, 0x2b, 0xc8, 0x1a, 0x54, 0x85, 0xd8, 0x3d, 0xb1, 0x9b, 0x34, + 0x48, 0xcf, 0xed, 0x26, 0xf9, 0x4d, 0x60, 0x8e, 0xd5, 0xf7, 0x7b, 0x40, 0x7f, 0x13, 0x18, 0x8d, + 0x12, 0xb3, 0x98, 0x17, 0xfd, 0x4d, 0x9b, 0xc0, 0xcf, 0x78, 0x4a, 0x4c, 0x45, 0x61, 0x05, 0xf9, + 0x0f, 0x25, 0x80, 0x0d, 0xcd, 0xd6, 0x9e, 0x18, 0x7d, 0xc3, 0x3b, 0x42, 0x17, 0xa1, 0xae, 0xe9, + 0xba, 0xda, 0xf5, 0x21, 0x06, 0xf6, 0x73, 0x94, 0x16, 0x34, 0x5d, 0xdf, 0x88, 0x80, 0xd1, 0x65, + 0x58, 0x24, 0x56, 0x4f, 0xc4, 0x65, 0x49, 0x4b, 0x75, 0x52, 0x21, 0x20, 0xdf, 0x84, 0x06, 0xe1, + 0xab, 0x0d, 0x9e, 0x18, 0xd8, 0xf4, 0x44, 0x1a, 0x96, 0xcd, 0xb4, 0xac, 0xe9, 0x7a, 0x8b, 0x55, + 0x47, 0x29, 0xe5, 0xbf, 0x9b, 0x81, 0xd3, 0xe2, 0x8c, 0xc7, 0xd3, 0x29, 0x6e, 0xc3, 0x7c, 0xac, + 0xbf, 0x89, 0x44, 0x84, 0x70, 0x84, 0x8a, 0x80, 0x1b, 0x4b, 0x18, 0x28, 0x24, 0x12, 0x06, 0x52, + 0x53, 0x35, 0x8a, 0x1f, 0x53, 0xaa, 0x46, 0xe9, 0x23, 0xa6, 0x6a, 0x4c, 0x1f, 0x37, 0x55, 0x63, + 0x7e, 0xec, 0x54, 0x8d, 0x57, 0xe8, 0x51, 0x8f, 0xdf, 0x22, 0xfd, 0x66, 0x33, 0x9b, 0x50, 0x0d, + 0xb8, 0x9b, 0x7e, 0xe2, 0x5c, 0x2c, 0xa5, 0x63, 0x76, 0x92, 0x94, 0x8e, 0x72, 0x66, 0x4a, 0xc7, + 0x59, 0x98, 0x37, 0x2d, 0xd5, 0xc4, 0xcf, 0x55, 0x32, 0x2d, 0x6e, 0x63, 0x8e, 0xcd, 0x91, 0x69, + 0xed, 0xe0, 0xe7, 0x6d, 0x02, 0x41, 0xe7, 0x60, 0x7e, 0xa0, 0xb9, 0x4f, 0xb1, 0x4e, 0x73, 0x2b, + 0xdc, 0x46, 0x95, 0xea, 0xd3, 0x1c, 0x83, 0xb5, 0x09, 0x08, 0xbd, 0x0c, 0x41, 0x3f, 0x38, 0x52, + 0x8d, 0x22, 0x55, 0x7d, 0x28, 0x43, 0x8b, 0xa4, 0x87, 0x2c, 0x1c, 0x33, 0x3d, 0xa4, 0x3e, 0x49, + 0x7a, 0xc8, 0x15, 0xa8, 0xfb, 0xbf, 0xfd, 0xfc, 0x10, 0x76, 0xdc, 0x4f, 0x53, 0x43, 0x16, 0xfc, + 0x3a, 0x3f, 0x07, 0x24, 0x2b, 0x9b, 0x04, 0x72, 0xb3, 0x49, 0x7e, 0x20, 0xf1, 0x8d, 0x67, 0xb0, + 0x80, 0x78, 0x18, 0x5b, 0xc8, 0x40, 0x90, 0x8e, 0x93, 0x81, 0x80, 0xf6, 0x32, 0x73, 0x34, 0x2e, + 0x66, 0x73, 0x1a, 0x95, 0xa5, 0x21, 0x3f, 0x0a, 0xf6, 0x84, 0x1f, 0x47, 0xae, 0x99, 0xfc, 0x5f, + 0x12, 0x9c, 0xe6, 0xfc, 0x32, 0x12, 0xb2, 0x52, 0xb4, 0x5c, 0xca, 0xd0, 0xf2, 0xae, 0x83, 0x75, + 0x6c, 0x7a, 0x86, 0xd6, 0x57, 0x5d, 0x1b, 0x77, 0xfd, 0x30, 0x6f, 0x08, 0xa6, 0x8e, 0xce, 0x39, + 0x98, 0x67, 0x19, 0x8c, 0x7c, 0x7b, 0xc8, 0x12, 0x15, 0xe7, 0x68, 0x12, 0x23, 0xdf, 0x01, 0xee, + 0xa6, 0x59, 0x96, 0x52, 0xe6, 0xb9, 0xc2, 0x48, 0x03, 0x23, 0x5b, 0xb0, 0x92, 0x11, 0x70, 0x4f, + 0x9d, 0x26, 0x29, 0x39, 0x4d, 0xb9, 0x42, 0x4a, 0x4e, 0xd3, 0x77, 0x25, 0x38, 0x93, 0xd8, 0xa6, + 0x7e, 0xfa, 0x92, 0x95, 0xff, 0x52, 0x0a, 0xf4, 0x27, 0xae, 0xf2, 0x1b, 0x49, 0x95, 0x7f, 0x39, + 0x6f, 0xd7, 0x9d, 0xaa, 0xf4, 0x8f, 0x33, 0x95, 0xfe, 0x72, 0xee, 0x0e, 0x7e, 0x94, 0x3c, 0xff, + 0x5d, 0x82, 0x53, 0x99, 0x1d, 0x88, 0xf9, 0x83, 0x52, 0xdc, 0x1f, 0xe4, 0xbe, 0x64, 0xe8, 0xa2, + 0x33, 0x5f, 0x92, 0x7a, 0xe1, 0xdc, 0x69, 0x53, 0x07, 0xda, 0x0b, 0x63, 0x30, 0x1c, 0x70, 0x67, + 0x92, 0xb0, 0x7b, 0xc4, 0x20, 0xc7, 0xf1, 0x26, 0xaf, 0xc2, 0x12, 0x33, 0xf4, 0xd4, 0xa1, 0x09, + 0x29, 0x98, 0x53, 0xb9, 0xc8, 0xea, 0x88, 0x6f, 0xc3, 0x09, 0xe4, 0x16, 0x2c, 0x06, 0xc3, 0xca, + 0x4d, 0x38, 0x8a, 0x24, 0x10, 0x15, 0xc4, 0x04, 0x22, 0x13, 0x66, 0x36, 0xf1, 0x33, 0xa3, 0x8b, + 0x3f, 0x96, 0x4c, 0xe2, 0xb3, 0x30, 0x67, 0x63, 0x67, 0x60, 0xb8, 0x6e, 0xf0, 0x55, 0xaf, 0x28, + 0x51, 0x90, 0xfc, 0x83, 0x19, 0x58, 0x88, 0xab, 0xd0, 0xad, 0x44, 0xbe, 0xd2, 0xe9, 0xd4, 0xb3, + 0xae, 0x94, 0x43, 0xde, 0xcb, 0xfe, 0xf6, 0xa7, 0x90, 0x0c, 0xe6, 0x07, 0x5b, 0x1c, 0x7f, 0x57, + 0xd4, 0x80, 0xd9, 0xae, 0x35, 0x18, 0x68, 0xa6, 0xee, 0xa7, 0x7b, 0xf3, 0x22, 0x91, 0x99, 0xe6, + 0xf4, 0xd8, 0xf1, 0x6e, 0x45, 0xa1, 0xbf, 0xc9, 0x0c, 0x13, 0x5b, 0x67, 0x98, 0x34, 0xe3, 0x89, + 0x4e, 0x42, 0x45, 0x01, 0x0e, 0xda, 0x34, 0x1c, 0x74, 0x01, 0x4a, 0xd8, 0x7c, 0xe6, 0xc7, 0x7d, + 0x84, 0x63, 0x46, 0x7f, 0xcb, 0xa3, 0x50, 0x0c, 0x74, 0x11, 0x66, 0x06, 0x44, 0x6b, 0xfc, 0xa8, + 0xf8, 0x62, 0x22, 0x2d, 0x5a, 0xe1, 0x08, 0xe8, 0x35, 0x98, 0xd5, 0xe9, 0x7c, 0xf8, 0x3e, 0x3e, + 0x12, 0x72, 0xa7, 0x68, 0x95, 0xe2, 0xa3, 0xa0, 0x77, 0x83, 0x33, 0xee, 0x4a, 0x32, 0xf8, 0x14, + 0x13, 0x73, 0xea, 0xf1, 0xf6, 0x8e, 0xb8, 0x51, 0x84, 0xe4, 0x49, 0x79, 0x9c, 0x4b, 0x7e, 0x1c, + 0xeb, 0x14, 0x94, 0xfb, 0x56, 0x8f, 0x29, 0xc7, 0x1c, 0xbb, 0x2b, 0xd0, 0xb7, 0x7a, 0x54, 0x37, + 0x96, 0x60, 0xda, 0xf5, 0x74, 0xc3, 0xa4, 0xae, 0x52, 0x59, 0x61, 0x05, 0xb2, 0x06, 0xe9, 0x0f, + 0xd5, 0x32, 0xbb, 0xb8, 0x51, 0xa5, 0x55, 0x15, 0x0a, 0xd9, 0x35, 0xbb, 0x74, 0xcb, 0xe8, 0x79, + 0x47, 0x8d, 0x1a, 0x85, 0x93, 0x9f, 0xe1, 0x51, 0xf3, 0x42, 0xc6, 0x51, 0x73, 0xac, 0xc3, 0x29, + 0x47, 0xcd, 0xf5, 0xcc, 0x4f, 0x42, 0x9c, 0xf6, 0xb3, 0x90, 0x56, 0xf5, 0x43, 0x09, 0x96, 0x37, + 0x68, 0xbc, 0x32, 0x62, 0xc2, 0x26, 0x49, 0xf5, 0x79, 0x23, 0xc8, 0xbf, 0x4a, 0x49, 0xa2, 0x89, + 0x8f, 0xd8, 0x4f, 0xbf, 0xda, 0x80, 0x9a, 0xcf, 0x96, 0x13, 0x17, 0xc7, 0x48, 0xde, 0xaa, 0xba, + 0xd1, 0xa2, 0x7c, 0x07, 0x56, 0x12, 0x3d, 0xe7, 0x51, 0xa3, 0x78, 0x22, 0x3f, 0xeb, 0x78, 0x34, + 0x91, 0x5f, 0xbe, 0x0d, 0x27, 0x3b, 0x9e, 0xe6, 0x78, 0x89, 0x61, 0x8f, 0x41, 0x4b, 0xd3, 0xb2, + 0x44, 0x5a, 0x9e, 0x39, 0xd5, 0x81, 0xa5, 0x8e, 0x67, 0xd9, 0xc7, 0x60, 0x4a, 0xec, 0x07, 0x19, + 0xb9, 0x35, 0xf4, 0x3f, 0x07, 0x7e, 0x51, 0x5e, 0x61, 0x49, 0x64, 0xc9, 0xd6, 0xbe, 0x00, 0xcb, + 0x2c, 0x87, 0xeb, 0x38, 0x83, 0x38, 0xe5, 0x67, 0x90, 0x25, 0xf9, 0xde, 0x87, 0x13, 0xc2, 0x39, + 0x36, 0xcf, 0x79, 0xb8, 0x26, 0xe6, 0x3c, 0x64, 0x87, 0x0c, 0x82, 0x94, 0x87, 0xef, 0x15, 0x22, + 0xf6, 0x38, 0x23, 0xf0, 0xf9, 0xa6, 0x98, 0xf1, 0x70, 0x26, 0x9b, 0xab, 0x90, 0xf0, 0x90, 0xd4, + 0xce, 0x62, 0x8a, 0x76, 0xee, 0x27, 0xa2, 0xaa, 0xa5, 0x64, 0xc6, 0x4a, 0xac, 0x87, 0x9f, 0x48, + 0x3c, 0xf5, 0x21, 0xcb, 0x8a, 0x08, 0x9a, 0x0e, 0x42, 0xa9, 0x6f, 0xc4, 0x42, 0xa9, 0xab, 0x39, + 0x3d, 0x0d, 0x82, 0xa8, 0xdf, 0x2b, 0x41, 0x25, 0xa8, 0x4b, 0x48, 0x38, 0x29, 0xaa, 0x42, 0x8a, + 0xa8, 0xa2, 0xdf, 0xc9, 0xe2, 0x31, 0xbf, 0x93, 0xa5, 0x31, 0xbe, 0x93, 0xab, 0x50, 0xa1, 0x3f, + 0x68, 0x22, 0x3b, 0xfb, 0xee, 0x95, 0x29, 0x40, 0xc1, 0x07, 0xa1, 0x8a, 0xcd, 0x8c, 0xa9, 0x62, + 0xb1, 0x0c, 0x8c, 0xd9, 0x78, 0x06, 0xc6, 0xad, 0xe0, 0x1b, 0x56, 0x4e, 0x46, 0x3c, 0x02, 0x8e, + 0xa9, 0x5f, 0xaf, 0xd8, 0x31, 0x67, 0x25, 0x79, 0xcc, 0x19, 0xd2, 0x7f, 0x66, 0x23, 0xb2, 0xbb, + 0x2c, 0xad, 0x22, 0xaa, 0x67, 0xdc, 0x46, 0xbe, 0x29, 0x44, 0xb4, 0xa4, 0xe4, 0x5d, 0xa2, 0xd0, + 0x2e, 0x44, 0xa3, 0x58, 0xfb, 0xb0, 0x1c, 0x4f, 0xc7, 0x9a, 0xc8, 0xc6, 0x65, 0xe4, 0x85, 0xfe, + 0x7e, 0xd4, 0x73, 0xcb, 0x48, 0x82, 0xbc, 0x95, 0x88, 0xd7, 0x8f, 0xad, 0xa1, 0xd7, 0xc4, 0xd4, + 0x9e, 0x89, 0xf5, 0x2a, 0x91, 0xd9, 0x43, 0x3d, 0x0b, 0xcd, 0xe1, 0xd5, 0xcc, 0x87, 0xae, 0x70, + 0x48, 0x8b, 0x3a, 0xf0, 0x07, 0x86, 0x69, 0xb8, 0x87, 0xac, 0x7e, 0x86, 0x39, 0xf0, 0x3e, 0xa8, + 0x45, 0x0f, 0x17, 0xf1, 0x0b, 0xc3, 0x53, 0xbb, 0x96, 0x8e, 0xa9, 0xd6, 0x4e, 0x2b, 0x65, 0x02, + 0xd8, 0xb0, 0x74, 0x1c, 0xae, 0xa7, 0xf2, 0xa4, 0xeb, 0xa9, 0x12, 0x5b, 0x4f, 0xcb, 0x30, 0xe3, + 0x60, 0xcd, 0xb5, 0x4c, 0x76, 0xe6, 0xa0, 0xf0, 0x12, 0x99, 0x88, 0x01, 0x76, 0x5d, 0xd2, 0x06, + 0x77, 0xa4, 0x78, 0x31, 0xe2, 0xf4, 0xcd, 0xe7, 0x38, 0x7d, 0x39, 0x29, 0x96, 0x31, 0xa7, 0xaf, + 0x9a, 0xe3, 0xf4, 0x8d, 0x95, 0x61, 0x19, 0xba, 0xb7, 0xb5, 0x51, 0xee, 0x6d, 0xd4, 0x3f, 0x5c, + 0x10, 0xfd, 0xc3, 0x3b, 0xd1, 0x8d, 0x64, 0x3d, 0x19, 0x70, 0xce, 0xbf, 0xb8, 0xf1, 0x29, 0x2e, + 0xe0, 0x7f, 0x96, 0x60, 0x25, 0xb1, 0xe0, 0xf8, 0x12, 0x7e, 0x23, 0x96, 0xbb, 0x99, 0x9b, 0x34, + 0xe9, 0xa7, 0x6e, 0xb6, 0x84, 0xd4, 0xcd, 0x2b, 0x79, 0x24, 0x19, 0x99, 0x9b, 0xc7, 0xcf, 0xa6, + 0xfc, 0x8e, 0x04, 0x28, 0x65, 0xab, 0x7c, 0xcb, 0xf7, 0xba, 0x27, 0x38, 0xd4, 0xe2, 0x8e, 0xf7, + 0xbb, 0xa1, 0xe3, 0x5d, 0x98, 0xe4, 0x78, 0x20, 0x48, 0xf3, 0xf8, 0x59, 0x01, 0xce, 0xec, 0xdb, + 0x7a, 0xcc, 0x8d, 0xe4, 0x58, 0xe3, 0x5b, 0xb6, 0x5b, 0x62, 0x8e, 0xca, 0x31, 0x87, 0x50, 0x3c, + 0xce, 0x10, 0xd0, 0x37, 0xd2, 0xb2, 0x88, 0xee, 0x08, 0xf1, 0xbe, 0xfc, 0x01, 0xfe, 0x8a, 0xa3, + 0x74, 0x32, 0x9c, 0xcd, 0xee, 0x00, 0x77, 0x39, 0x7f, 0x13, 0x16, 0xb6, 0x5e, 0xe0, 0x6e, 0xe7, + 0xc8, 0xec, 0x4e, 0x20, 0xf5, 0x3a, 0x14, 0xbb, 0x03, 0x9d, 0x07, 0x31, 0xc8, 0xcf, 0xa8, 0x17, + 0x5d, 0x14, 0xbd, 0x68, 0x15, 0xea, 0x61, 0x0b, 0x7c, 0x01, 0x2d, 0x93, 0x05, 0xa4, 0x13, 0x64, + 0xc2, 0x7c, 0x5e, 0xe1, 0x25, 0x0e, 0xc7, 0x0e, 0xbb, 0x15, 0xc2, 0xe0, 0xd8, 0x71, 0x44, 0xab, + 0x5d, 0x14, 0xad, 0xb6, 0xfc, 0x7d, 0x09, 0xe6, 0x48, 0x0b, 0x1f, 0xa9, 0xff, 0x7c, 0x4b, 0x5a, + 0x0c, 0xb7, 0xa4, 0xc1, 0xce, 0xb6, 0x14, 0xdd, 0xd9, 0x86, 0x3d, 0x9f, 0xa6, 0xe0, 0x64, 0xcf, + 0x67, 0x02, 0x38, 0x76, 0x1c, 0xf9, 0x2c, 0xcc, 0xb3, 0xbe, 0xf1, 0x91, 0xd7, 0xa1, 0x38, 0x74, + 0xfa, 0xfe, 0xfc, 0x0d, 0x9d, 0xbe, 0xfc, 0x6d, 0x09, 0xaa, 0x2d, 0xcf, 0xd3, 0xba, 0x87, 0x13, + 0x0c, 0x20, 0xe8, 0x5c, 0x21, 0xda, 0xb9, 0xe4, 0x20, 0xc2, 0xee, 0x96, 0x32, 0xba, 0x3b, 0x2d, + 0x74, 0x57, 0x86, 0x9a, 0xdf, 0x97, 0xcc, 0x0e, 0xef, 0x00, 0x6a, 0x5b, 0x8e, 0xf7, 0x9e, 0xe5, + 0x3c, 0xd7, 0x1c, 0x7d, 0xb2, 0x5d, 0x2b, 0x82, 0x12, 0xbf, 0x35, 0x5f, 0xbc, 0x30, 0xad, 0xd0, + 0xdf, 0xf2, 0xab, 0x70, 0x42, 0xe0, 0x97, 0xd9, 0xf0, 0x6d, 0x98, 0xa3, 0x5f, 0x61, 0xbe, 0xa1, + 0xb9, 0x1c, 0x0d, 0x92, 0x8f, 0xf8, 0x5a, 0xcb, 0x9b, 0xb0, 0x48, 0xfc, 0x31, 0x0a, 0x0f, 0xec, + 0xcb, 0xd5, 0x98, 0xcf, 0xbf, 0x92, 0x60, 0x11, 0xf3, 0xf7, 0x7f, 0x21, 0xc1, 0x34, 0x85, 0x27, + 0x7c, 0xa4, 0x55, 0xf2, 0x9d, 0xb3, 0x2d, 0xd5, 0xd3, 0x7a, 0xc1, 0x8b, 0x04, 0x04, 0xb0, 0xa7, + 0xf5, 0x68, 0xe0, 0x85, 0x56, 0xea, 0x46, 0x0f, 0xbb, 0x9e, 0x1f, 0xc8, 0x9b, 0x23, 0xb0, 0x4d, + 0x06, 0x22, 0x82, 0xa1, 0xf1, 0xce, 0x12, 0x0d, 0x6b, 0xd2, 0xdf, 0xe8, 0x02, 0xbb, 0x50, 0x98, + 0x1f, 0xbd, 0xa2, 0x17, 0x0d, 0x9b, 0x50, 0x8e, 0x85, 0x9d, 0x82, 0x32, 0xba, 0x08, 0x25, 0x7a, + 0x4c, 0x3c, 0x9b, 0x27, 0x25, 0x8a, 0x42, 0xb4, 0xc2, 0x36, 0x4c, 0x13, 0xeb, 0xd4, 0x01, 0x2a, + 0x2b, 0xbc, 0x24, 0xbf, 0x0b, 0x28, 0x2a, 0x3c, 0x3e, 0x41, 0x17, 0x61, 0x86, 0xca, 0xd6, 0x77, + 0x62, 0x17, 0x13, 0xac, 0x15, 0x8e, 0x20, 0x7f, 0x1d, 0x10, 0x6b, 0x4b, 0x70, 0x5c, 0x27, 0x99, + 0xc0, 0x1c, 0x17, 0xf6, 0xaf, 0x24, 0x38, 0x21, 0x70, 0xe7, 0xfd, 0x7b, 0x55, 0x64, 0x9f, 0xd2, + 0x3d, 0xce, 0xfa, 0x6d, 0xe1, 0xcb, 0x7c, 0x31, 0xd9, 0x8d, 0x5f, 0xd1, 0x57, 0xf9, 0x5f, 0x24, + 0x80, 0xd6, 0xd0, 0x3b, 0xe4, 0x07, 0xa6, 0xd1, 0x49, 0x94, 0x62, 0x93, 0xd8, 0x84, 0xb2, 0xad, + 0xb9, 0xee, 0x73, 0xcb, 0xf1, 0x37, 0x91, 0x41, 0x99, 0x1e, 0x73, 0x0e, 0xf9, 0xc3, 0x08, 0x15, + 0x85, 0xfe, 0x46, 0x2f, 0x43, 0x8d, 0x3d, 0x95, 0xa1, 0x6a, 0xba, 0xee, 0xf8, 0x89, 0x77, 0x15, + 0xa5, 0xca, 0xa0, 0x2d, 0x06, 0x24, 0x68, 0x06, 0x0d, 0x1a, 0x78, 0x47, 0xaa, 0x67, 0x3d, 0xc5, + 0x26, 0xdf, 0x18, 0x56, 0x7d, 0xe8, 0x1e, 0x01, 0xb2, 0xa8, 0x60, 0xcf, 0x70, 0x3d, 0xc7, 0x47, + 0xf3, 0x63, 0x9b, 0x1c, 0x4a, 0xd1, 0xe4, 0xbf, 0x90, 0xa0, 0xde, 0x1e, 0xf6, 0xfb, 0x4c, 0xb8, + 0xc7, 0x99, 0xe4, 0x4b, 0x7c, 0x28, 0x85, 0xa4, 0xca, 0x87, 0x82, 0xe2, 0x43, 0xfc, 0x58, 0xce, + 0xb2, 0xae, 0xc1, 0x62, 0xa4, 0xc7, 0x5c, 0x71, 0x04, 0xcf, 0x5e, 0x12, 0x3d, 0x7b, 0xb9, 0x05, + 0x88, 0x1d, 0xdf, 0x1c, 0x7b, 0x94, 0xf2, 0x49, 0x38, 0x21, 0xb0, 0xe0, 0x9f, 0xe2, 0x4b, 0x50, + 0xe5, 0x49, 0x60, 0x5c, 0x21, 0x4e, 0x41, 0x99, 0x98, 0xd4, 0xae, 0xa1, 0xfb, 0x89, 0x0c, 0xb3, + 0xb6, 0xa5, 0x6f, 0x18, 0xba, 0x23, 0x7f, 0x09, 0xaa, 0xfc, 0x96, 0x39, 0xc7, 0xbd, 0x0b, 0x35, + 0x1e, 0xc6, 0x53, 0x85, 0x6b, 0x99, 0xa7, 0x52, 0x32, 0x0d, 0x7d, 0x51, 0x98, 0xd1, 0xa2, 0xfc, + 0x0d, 0x68, 0x32, 0x6f, 0x41, 0x60, 0xec, 0x0f, 0xf0, 0x2e, 0xf8, 0x77, 0x16, 0x72, 0xf8, 0x8b, + 0x94, 0x55, 0x27, 0x5a, 0x94, 0x4f, 0xc3, 0x6a, 0x2a, 0x7f, 0x3e, 0x7a, 0x1b, 0xea, 0x61, 0x05, + 0xbb, 0x3b, 0x18, 0x64, 0x67, 0x48, 0x91, 0xec, 0x8c, 0xe5, 0xc0, 0xf7, 0x2e, 0xf8, 0x5f, 0x2e, + 0xea, 0x5e, 0x87, 0x3b, 0xae, 0x62, 0xd6, 0x8e, 0xab, 0x24, 0xec, 0xb8, 0xe4, 0x47, 0x81, 0x0c, + 0xf9, 0xbe, 0xf7, 0x0e, 0xdd, 0x99, 0xb3, 0xb6, 0x7d, 0xa3, 0xf6, 0x52, 0xfa, 0xf8, 0x18, 0x92, + 0x12, 0xc1, 0x97, 0x2f, 0x42, 0x55, 0x34, 0x6f, 0x11, 0x8b, 0x25, 0x25, 0x2c, 0x56, 0x2d, 0x66, + 0xac, 0x5e, 0x8f, 0x6d, 0x29, 0xd2, 0xe4, 0x1a, 0xdb, 0x50, 0xdc, 0x14, 0xcc, 0xd6, 0xe7, 0x84, + 0x48, 0xfa, 0xaf, 0xc8, 0x62, 0x2d, 0x71, 0x3b, 0xfe, 0x9e, 0x4b, 0xe8, 0xf9, 0x40, 0xe5, 0xf3, + 0x30, 0xb7, 0x9f, 0xf5, 0xd6, 0x47, 0xc9, 0x4f, 0xff, 0x7a, 0x0b, 0x96, 0xde, 0x33, 0xfa, 0xd8, + 0x3d, 0x72, 0x3d, 0x3c, 0xd8, 0xa6, 0xe6, 0xe5, 0xc0, 0xc0, 0x0e, 0x5a, 0x03, 0xa0, 0xbb, 0x48, + 0xdb, 0x32, 0x82, 0xf7, 0x0d, 0x22, 0x10, 0xf9, 0xa7, 0x12, 0x2c, 0x84, 0x84, 0xe3, 0x24, 0xe2, + 0xbd, 0x09, 0xd3, 0x07, 0xae, 0x7f, 0xda, 0x16, 0x8b, 0x25, 0xa4, 0x75, 0x41, 0x29, 0x1d, 0xb8, + 0xdb, 0x3a, 0x7a, 0x0b, 0x60, 0xe8, 0x62, 0x9d, 0x47, 0xe7, 0x46, 0xa4, 0x46, 0x56, 0x08, 0x2a, + 0x8b, 0xef, 0xdd, 0x84, 0x39, 0xc3, 0xb4, 0x74, 0x4c, 0x23, 0xb7, 0xfa, 0xa8, 0xb4, 0x48, 0x60, + 0xb8, 0xfb, 0x2e, 0xd6, 0xe5, 0x3f, 0x09, 0xe3, 0xaf, 0x9f, 0xe5, 0x11, 0xca, 0x2a, 0xff, 0xbe, + 0xfa, 0xb3, 0xce, 0x55, 0xf6, 0x01, 0x2c, 0x32, 0x33, 0x79, 0x10, 0x34, 0x99, 0x7a, 0x5d, 0x24, + 0x36, 0x36, 0xa5, 0x6e, 0x70, 0xcf, 0xca, 0x27, 0x92, 0x6f, 0xc3, 0xc9, 0x58, 0xfe, 0xf6, 0xf8, + 0xc7, 0xe9, 0xef, 0xc7, 0xce, 0xc5, 0xc2, 0x25, 0x75, 0x4d, 0xbc, 0x36, 0x94, 0x97, 0x69, 0xcf, + 0x6f, 0xb0, 0xec, 0xc3, 0x29, 0xe1, 0xd0, 0x4e, 0xe8, 0xcb, 0xcd, 0x98, 0xb3, 0x78, 0x36, 0x9b, + 0x5f, 0xcc, 0x6b, 0xfc, 0x6f, 0x09, 0x96, 0xd2, 0x10, 0x8e, 0x79, 0x60, 0xfc, 0xb5, 0x8c, 0x2b, + 0x87, 0x6f, 0x8c, 0xea, 0xd0, 0x27, 0x72, 0xc0, 0xbe, 0xc3, 0x2e, 0x2c, 0x8d, 0x9e, 0x93, 0xe2, + 0x78, 0x73, 0xf2, 0x8b, 0x42, 0x24, 0x28, 0x92, 0x73, 0xa9, 0xe8, 0x23, 0x1c, 0x52, 0x6e, 0xc4, + 0xee, 0x14, 0x5d, 0x4e, 0x25, 0x1c, 0x71, 0xa5, 0x48, 0x49, 0x3b, 0x0c, 0xb8, 0x36, 0x8a, 0xd3, + 0x67, 0xf6, 0xfc, 0xfa, 0x7f, 0x24, 0xa8, 0x89, 0x13, 0x82, 0xde, 0x4d, 0xb9, 0x50, 0x74, 0x66, + 0xc4, 0x00, 0x85, 0xfb, 0x44, 0xfc, 0x02, 0x4f, 0x61, 0xfc, 0x0b, 0x3c, 0xc5, 0xf1, 0x2e, 0xf0, + 0xdc, 0x83, 0xda, 0x73, 0xc7, 0xf0, 0xb4, 0x27, 0x7d, 0xac, 0xf6, 0xb5, 0x23, 0xec, 0x70, 0x2b, + 0x9c, 0x6b, 0x86, 0xaa, 0x3e, 0xc9, 0x43, 0x42, 0x21, 0x7f, 0xbb, 0x00, 0x27, 0x53, 0xef, 0x92, + 0x7c, 0xf4, 0x71, 0x5f, 0x89, 0x8e, 0x7b, 0x92, 0x0b, 0x3a, 0xc5, 0x89, 0x2e, 0xe8, 0x6c, 0x67, + 0x48, 0x21, 0x2d, 0x24, 0x3e, 0x42, 0x18, 0x7f, 0x23, 0x41, 0xd9, 0xef, 0xd4, 0xc8, 0xeb, 0x32, + 0x2b, 0x43, 0x82, 0xa6, 0xd2, 0x6c, 0x69, 0x53, 0x33, 0x2d, 0xd5, 0xc5, 0xc4, 0x2d, 0x1a, 0x79, + 0x39, 0x61, 0x89, 0xd2, 0x6d, 0x58, 0x0e, 0xde, 0xd1, 0x4c, 0xab, 0xc3, 0x88, 0x50, 0x0b, 0xea, + 0x8c, 0x1f, 0x65, 0x45, 0x98, 0x8e, 0xfc, 0x54, 0xd5, 0x28, 0x01, 0x61, 0x42, 0x98, 0xb9, 0xf2, + 0x3f, 0x48, 0xb0, 0x10, 0x93, 0xec, 0xaf, 0xdf, 0x20, 0xfe, 0xb8, 0x08, 0x73, 0x91, 0x59, 0x1e, + 0x31, 0x80, 0x0d, 0x58, 0xf4, 0xd3, 0x5a, 0x5c, 0xec, 0x8d, 0x77, 0x39, 0x64, 0x81, 0x53, 0x74, + 0xb0, 0xc7, 0x3c, 0x99, 0xbb, 0xb0, 0xa0, 0x3d, 0xd3, 0x8c, 0x3e, 0xd5, 0xa0, 0xb1, 0x9c, 0x84, + 0x5a, 0x80, 0x1f, 0xf8, 0x42, 0x6c, 0xdc, 0x63, 0x5d, 0x11, 0x01, 0x8a, 0x1b, 0xde, 0xd4, 0x71, + 0xdd, 0x48, 0x6a, 0x54, 0xee, 0x4d, 0x1d, 0xd7, 0x0d, 0xda, 0xa3, 0xa9, 0xe2, 0xf4, 0x8a, 0x92, + 0xcb, 0xdf, 0xb5, 0xc8, 0x6e, 0x8f, 0xe0, 0xbe, 0x47, 0x51, 0x89, 0xc0, 0x06, 0xda, 0x07, 0x96, + 0xa3, 0x46, 0xe9, 0x67, 0x47, 0x08, 0x8c, 0x52, 0xb4, 0x03, 0x26, 0xf2, 0xff, 0x4a, 0x80, 0x92, + 0x0b, 0xf2, 0xd7, 0x66, 0xaa, 0xa2, 0x43, 0x2f, 0x8d, 0x2d, 0x3a, 0xf9, 0x1d, 0x38, 0xa5, 0x60, + 0xcb, 0xc6, 0x66, 0x60, 0xf7, 0x1e, 0x5a, 0xbd, 0x09, 0x3c, 0xb6, 0x97, 0xa0, 0x99, 0x46, 0xcf, + 0xf7, 0x81, 0x43, 0x68, 0x6e, 0x1c, 0xe2, 0xee, 0x53, 0xea, 0xfd, 0x1f, 0x27, 0x9f, 0xa3, 0x09, + 0xe5, 0xbe, 0xd5, 0x65, 0xef, 0x55, 0xf2, 0xa3, 0x12, 0xbf, 0x9c, 0x73, 0x4a, 0x7d, 0x1a, 0x56, + 0x53, 0x9b, 0xe5, 0xbd, 0x42, 0x50, 0xbf, 0x8f, 0xbd, 0xad, 0x67, 0xd8, 0x0c, 0x1c, 0x42, 0xf9, + 0x47, 0x85, 0x88, 0xeb, 0x49, 0xab, 0x26, 0xc8, 0x83, 0x41, 0x6d, 0x58, 0x0a, 0x51, 0x30, 0xa1, + 0x66, 0xef, 0xd5, 0xb1, 0x97, 0x1e, 0xd3, 0x63, 0x64, 0xb4, 0x11, 0xfa, 0x4c, 0x5d, 0xf8, 0x12, + 0x47, 0x00, 0x8b, 0x45, 0x4e, 0x8b, 0xf1, 0xc8, 0xe9, 0xfb, 0x80, 0xa2, 0xce, 0x25, 0xdf, 0x6d, + 0x96, 0xc6, 0x78, 0x7c, 0xa4, 0x6e, 0xc7, 0x9f, 0xc9, 0xc9, 0x78, 0x42, 0x64, 0xfa, 0x58, 0x4f, + 0x88, 0x5c, 0x7a, 0x05, 0xca, 0xfe, 0x53, 0xab, 0x68, 0x16, 0x8a, 0x7b, 0x1b, 0xed, 0xfa, 0x14, + 0xf9, 0xb1, 0xbf, 0xd9, 0xae, 0x4b, 0xa8, 0x0c, 0xa5, 0xce, 0xc6, 0x5e, 0xbb, 0x5e, 0xb8, 0x34, + 0x80, 0x7a, 0xfc, 0xb5, 0x51, 0xb4, 0x02, 0x27, 0xda, 0xca, 0x6e, 0xbb, 0x75, 0xbf, 0xb5, 0xb7, + 0xbd, 0xbb, 0xa3, 0xb6, 0x95, 0xed, 0xc7, 0xad, 0xbd, 0xad, 0xfa, 0x14, 0x3a, 0x07, 0xa7, 0xa3, + 0x15, 0x0f, 0x76, 0x3b, 0x7b, 0xea, 0xde, 0xae, 0xba, 0xb1, 0xbb, 0xb3, 0xd7, 0xda, 0xde, 0xd9, + 0x52, 0xea, 0x12, 0x3a, 0x0d, 0xa7, 0xa2, 0x28, 0xf7, 0xb6, 0x37, 0xb7, 0x95, 0xad, 0x0d, 0xf2, + 0xbb, 0xf5, 0xb0, 0x5e, 0xb8, 0xf4, 0x36, 0x54, 0x85, 0x44, 0x69, 0xd2, 0xa5, 0xf6, 0xee, 0x66, + 0x7d, 0x0a, 0x55, 0xa1, 0x12, 0xe5, 0x53, 0x86, 0xd2, 0xce, 0xee, 0xe6, 0x56, 0xbd, 0x80, 0x00, + 0x66, 0xf6, 0x5a, 0xca, 0xfd, 0xad, 0xbd, 0x7a, 0xf1, 0xd2, 0xed, 0xf8, 0x95, 0x6c, 0x8c, 0x16, + 0xa1, 0xda, 0x69, 0xed, 0x6c, 0xde, 0xdb, 0xfd, 0x8a, 0xaa, 0x6c, 0xb5, 0x36, 0xbf, 0x5a, 0x9f, + 0x42, 0x4b, 0x50, 0xf7, 0x41, 0x3b, 0xbb, 0x7b, 0x0c, 0x2a, 0x5d, 0x7a, 0x1a, 0x73, 0xbe, 0x30, + 0x3a, 0x09, 0x8b, 0x41, 0x93, 0xea, 0x86, 0xb2, 0xd5, 0xda, 0xdb, 0x22, 0x3d, 0x11, 0xc0, 0xca, + 0xfe, 0xce, 0xce, 0xf6, 0xce, 0xfd, 0xba, 0x44, 0xb8, 0x86, 0xe0, 0xad, 0xaf, 0x6c, 0x13, 0xe4, + 0x82, 0x88, 0xbc, 0xbf, 0xf3, 0xc5, 0x9d, 0xdd, 0x2f, 0xef, 0xd4, 0x8b, 0x97, 0x7e, 0x3b, 0x1a, + 0x1c, 0x0c, 0xd5, 0x69, 0x15, 0x56, 0x12, 0x2d, 0xaa, 0x5b, 0x8f, 0xb7, 0x76, 0xf6, 0xea, 0x53, + 0x62, 0x65, 0x67, 0xaf, 0xa5, 0x84, 0x95, 0x52, 0xbc, 0x72, 0xb7, 0xdd, 0x0e, 0x2a, 0x0b, 0x62, + 0xe5, 0xe6, 0xd6, 0xc3, 0xad, 0x90, 0xb2, 0x78, 0xfd, 0x47, 0xe1, 0xeb, 0x89, 0x1d, 0xec, 0xd0, + 0x04, 0xd6, 0x4d, 0x98, 0xf5, 0xdf, 0x12, 0x16, 0x76, 0x0b, 0xe2, 0xdb, 0xc7, 0xcd, 0xd5, 0xd4, + 0x3a, 0xbe, 0x7a, 0xa7, 0xd0, 0x63, 0x7a, 0xd6, 0x13, 0x79, 0xbf, 0xe4, 0x6c, 0xec, 0x7c, 0x25, + 0xf1, 0x4c, 0x4a, 0xf3, 0x5c, 0x0e, 0x46, 0xc0, 0xf7, 0xab, 0x50, 0x13, 0x1f, 0x0a, 0x43, 0xe7, + 0xc4, 0x73, 0x98, 0x94, 0x37, 0xc8, 0x9a, 0x72, 0x1e, 0x4a, 0xc0, 0x5a, 0x85, 0x7a, 0xfc, 0xa1, + 0x30, 0x24, 0x84, 0x37, 0x33, 0xde, 0x21, 0x6b, 0x7e, 0x2e, 0x1f, 0x29, 0xda, 0x40, 0xe2, 0xfd, + 0xab, 0xf3, 0xf9, 0x2f, 0x0a, 0xa5, 0x34, 0x90, 0xf5, 0xec, 0x10, 0x13, 0x8e, 0xf8, 0xc4, 0x04, + 0x8a, 0x3d, 0x39, 0x95, 0xf2, 0x3a, 0x8d, 0x28, 0x9c, 0xf4, 0x97, 0x49, 0xe4, 0x29, 0xf4, 0x1b, + 0xb0, 0x10, 0xcb, 0x41, 0x44, 0x02, 0x61, 0x7a, 0x6a, 0x65, 0xf3, 0x7c, 0x2e, 0x8e, 0x38, 0xab, + 0xd1, 0x3c, 0xc3, 0xf8, 0xac, 0xa6, 0xe4, 0x2f, 0xc6, 0x67, 0x35, 0x35, 0x4d, 0x91, 0x2a, 0xa2, + 0x90, 0x53, 0x28, 0x2a, 0x62, 0x5a, 0x0e, 0x63, 0xf3, 0x5c, 0x0e, 0x46, 0x54, 0x20, 0xb1, 0xac, + 0x42, 0x51, 0x20, 0xe9, 0xf9, 0x8a, 0xcd, 0xf3, 0xb9, 0x38, 0xf1, 0x99, 0x0c, 0xb3, 0x99, 0x92, + 0x33, 0x99, 0xc8, 0xa8, 0x4b, 0xce, 0x64, 0x32, 0x19, 0x8a, 0xcf, 0x64, 0x2c, 0xff, 0x48, 0xce, + 0xcd, 0x8d, 0x48, 0x9b, 0xc9, 0xf4, 0xfc, 0x09, 0x79, 0x0a, 0x3d, 0x87, 0x46, 0x56, 0x08, 0x1c, + 0x5d, 0x9e, 0x20, 0x52, 0xdf, 0x7c, 0x6d, 0x3c, 0xe4, 0xa0, 0x61, 0x0c, 0x28, 0xe9, 0xe4, 0xa0, + 0x97, 0x45, 0x71, 0x67, 0x38, 0x51, 0xcd, 0x57, 0x46, 0xa1, 0x05, 0xcd, 0xdc, 0x87, 0xb2, 0x1f, + 0x5c, 0x47, 0x82, 0x09, 0x8c, 0x05, 0xf5, 0x9b, 0x2f, 0xa5, 0x57, 0x06, 0x8c, 0xbe, 0x00, 0x25, + 0x02, 0x45, 0x2b, 0x71, 0x3c, 0x9f, 0x41, 0x23, 0x59, 0x11, 0x10, 0xb7, 0x60, 0x86, 0x45, 0x8d, + 0x91, 0x70, 0x6c, 0x2d, 0x44, 0xb5, 0x9b, 0xcd, 0xb4, 0xaa, 0x80, 0x45, 0x9b, 0xbd, 0xcc, 0xce, + 0x83, 0xc0, 0x68, 0x2d, 0xfe, 0x44, 0xa8, 0x18, 0x6d, 0x6e, 0x9e, 0xc9, 0xac, 0x8f, 0xea, 0x6c, + 0x6c, 0x23, 0x7f, 0x2e, 0xe7, 0xb4, 0x29, 0x4d, 0x67, 0xd3, 0xcf, 0xb0, 0xd8, 0xe4, 0x26, 0xcf, + 0xb8, 0xc4, 0xc9, 0xcd, 0x3c, 0x47, 0x14, 0x27, 0x37, 0xfb, 0xa8, 0x8c, 0x2d, 0x8d, 0xf8, 0x5b, + 0x1f, 0x72, 0xde, 0x3b, 0x3c, 0x69, 0x4b, 0x23, 0xe3, 0x7d, 0x1f, 0x79, 0x0a, 0x1d, 0xc2, 0x89, + 0x94, 0x07, 0x80, 0xd0, 0x2b, 0xd9, 0xf6, 0x57, 0x68, 0xe5, 0xd5, 0x91, 0x78, 0xd1, 0x96, 0x52, + 0x22, 0x3f, 0x62, 0x4b, 0xd9, 0xa1, 0x27, 0xb1, 0xa5, 0xbc, 0x10, 0x12, 0x55, 0x44, 0x6e, 0x43, + 0x4e, 0xa5, 0x85, 0x43, 0x52, 0x14, 0x31, 0x61, 0x31, 0x0e, 0xe1, 0x44, 0xca, 0x46, 0x40, 0xec, + 0x6c, 0xf6, 0x06, 0x45, 0xec, 0x6c, 0xde, 0x8e, 0x62, 0x0a, 0x7d, 0x0d, 0xd0, 0x7d, 0xec, 0x89, + 0x9e, 0x97, 0x8b, 0x84, 0x85, 0x1a, 0xdf, 0x73, 0x64, 0xe8, 0xa7, 0xb0, 0xf9, 0x90, 0xa7, 0xae, + 0x49, 0xd7, 0xff, 0xa8, 0x08, 0xf3, 0x2c, 0xee, 0xc8, 0xdd, 0xa8, 0x47, 0x00, 0x61, 0x08, 0x1f, + 0x9d, 0x8e, 0x4f, 0x9e, 0x90, 0x17, 0xd1, 0x5c, 0xcb, 0xaa, 0x8e, 0x2e, 0xd7, 0x48, 0x68, 0x5c, + 0x5c, 0xae, 0xc9, 0x48, 0xbf, 0xb8, 0x5c, 0x53, 0x62, 0xea, 0xf2, 0x14, 0x7a, 0x1f, 0x2a, 0x41, + 0x24, 0x56, 0x14, 0x42, 0x3c, 0xa4, 0xdc, 0x3c, 0x9d, 0x51, 0x1b, 0xed, 0x5d, 0x24, 0xc0, 0x2a, + 0xf6, 0x2e, 0x19, 0xbc, 0x15, 0x7b, 0x97, 0x16, 0x99, 0x0d, 0xc7, 0xcb, 0x42, 0x20, 0x29, 0xe3, + 0x15, 0x22, 0x62, 0x29, 0xe3, 0x15, 0x63, 0x27, 0xf2, 0xd4, 0xbd, 0xbb, 0x3f, 0xfe, 0xf9, 0x9a, + 0xf4, 0xd3, 0x9f, 0xaf, 0x4d, 0xfd, 0xd6, 0x87, 0x6b, 0xd2, 0x8f, 0x3f, 0x5c, 0x93, 0x7e, 0xf2, + 0xe1, 0x9a, 0xf4, 0xb3, 0x0f, 0xd7, 0xa4, 0xef, 0xfc, 0xe7, 0xda, 0xd4, 0xd7, 0xe4, 0xa7, 0x37, + 0xdd, 0x75, 0xc3, 0xba, 0xda, 0x75, 0x8c, 0x2b, 0x9a, 0x6d, 0x5c, 0xb5, 0x9f, 0xf6, 0xae, 0x6a, + 0xb6, 0xe1, 0x5e, 0xe5, 0x7c, 0xaf, 0x3e, 0x7b, 0xfd, 0xc9, 0x0c, 0xfd, 0xaf, 0x14, 0x6f, 0xfc, + 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xd0, 0xd5, 0x73, 0x4f, 0x64, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -12264,6 +12293,25 @@ func (m *PodSandboxStatusResponse) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if m.Timestamp != 0 { + i = encodeVarintApi(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x20 + } + if len(m.ContainersStatuses) > 0 { + for iNdEx := len(m.ContainersStatuses) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ContainersStatuses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } if len(m.Info) > 0 { for k := range m.Info { v := m.Info[k] @@ -17726,9 +17774,23 @@ func (m *ContainerEventResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l - if m.PodSandboxMetadata != nil { + if len(m.ContainersStatuses) > 0 { + for iNdEx := len(m.ContainersStatuses) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ContainersStatuses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if m.PodSandboxStatus != nil { { - size, err := m.PodSandboxMetadata.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.PodSandboxStatus.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -18357,6 +18419,15 @@ func (m *PodSandboxStatusResponse) Size() (n int) { n += mapEntrySize + 1 + sovApi(uint64(mapEntrySize)) } } + if len(m.ContainersStatuses) > 0 { + for _, e := range m.ContainersStatuses { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } + if m.Timestamp != 0 { + n += 1 + sovApi(uint64(m.Timestamp)) + } return n } @@ -20588,10 +20659,16 @@ func (m *ContainerEventResponse) Size() (n int) { if m.CreatedAt != 0 { n += 1 + sovApi(uint64(m.CreatedAt)) } - if m.PodSandboxMetadata != nil { - l = m.PodSandboxMetadata.Size() + if m.PodSandboxStatus != nil { + l = m.PodSandboxStatus.Size() n += 1 + l + sovApi(uint64(l)) } + if len(m.ContainersStatuses) > 0 { + for _, e := range m.ContainersStatuses { + l = e.Size() + n += 1 + l + sovApi(uint64(l)) + } + } return n } @@ -20989,6 +21066,11 @@ func (this *PodSandboxStatusResponse) String() string { if this == nil { return "nil" } + repeatedStringForContainersStatuses := "[]*ContainerStatus{" + for _, f := range this.ContainersStatuses { + repeatedStringForContainersStatuses += strings.Replace(f.String(), "ContainerStatus", "ContainerStatus", 1) + "," + } + repeatedStringForContainersStatuses += "}" keysForInfo := make([]string, 0, len(this.Info)) for k := range this.Info { keysForInfo = append(keysForInfo, k) @@ -21002,6 +21084,8 @@ func (this *PodSandboxStatusResponse) String() string { s := strings.Join([]string{`&PodSandboxStatusResponse{`, `Status:` + strings.Replace(this.Status.String(), "PodSandboxStatus", "PodSandboxStatus", 1) + `,`, `Info:` + mapStringForInfo + `,`, + `ContainersStatuses:` + repeatedStringForContainersStatuses + `,`, + `Timestamp:` + fmt.Sprintf("%v", this.Timestamp) + `,`, `}`, }, "") return s @@ -22557,11 +22641,17 @@ func (this *ContainerEventResponse) String() string { if this == nil { return "nil" } + repeatedStringForContainersStatuses := "[]*ContainerStatus{" + for _, f := range this.ContainersStatuses { + repeatedStringForContainersStatuses += strings.Replace(f.String(), "ContainerStatus", "ContainerStatus", 1) + "," + } + repeatedStringForContainersStatuses += "}" s := strings.Join([]string{`&ContainerEventResponse{`, `ContainerId:` + fmt.Sprintf("%v", this.ContainerId) + `,`, `ContainerEventType:` + fmt.Sprintf("%v", this.ContainerEventType) + `,`, `CreatedAt:` + fmt.Sprintf("%v", this.CreatedAt) + `,`, - `PodSandboxMetadata:` + strings.Replace(this.PodSandboxMetadata.String(), "PodSandboxMetadata", "PodSandboxMetadata", 1) + `,`, + `PodSandboxStatus:` + strings.Replace(this.PodSandboxStatus.String(), "PodSandboxStatus", "PodSandboxStatus", 1) + `,`, + `ContainersStatuses:` + repeatedStringForContainersStatuses + `,`, `}`, }, "") return s @@ -26965,6 +27055,59 @@ func (m *PodSandboxStatusResponse) Unmarshal(dAtA []byte) error { } m.Info[mapkey] = mapvalue iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainersStatuses", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainersStatuses = append(m.ContainersStatuses, &ContainerStatus{}) + if err := m.ContainersStatuses[len(m.ContainersStatuses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -43600,7 +43743,7 @@ func (m *ContainerEventResponse) Unmarshal(dAtA []byte) error { } case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSandboxMetadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PodSandboxStatus", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -43627,10 +43770,44 @@ func (m *ContainerEventResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PodSandboxMetadata == nil { - m.PodSandboxMetadata = &PodSandboxMetadata{} + if m.PodSandboxStatus == nil { + m.PodSandboxStatus = &PodSandboxStatus{} + } + if err := m.PodSandboxStatus.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainersStatuses", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF } - if err := m.PodSandboxMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ContainersStatuses = append(m.ContainersStatuses, &ContainerStatus{}) + if err := m.ContainersStatuses[len(m.ContainersStatuses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto index 5ad75e1c569b..a85d09c2fc2c 100644 --- a/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto +++ b/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto @@ -121,7 +121,6 @@ service RuntimeService { // GetContainerEvents gets container events from the CRI runtime rpc GetContainerEvents(GetEventsRequest) returns (stream ContainerEventResponse) {} - } // ImageService defines the public APIs for managing images. @@ -540,6 +539,10 @@ message PodSandboxStatusResponse { // debug, e.g. network namespace for linux container based container runtime. // It should only be returned non-empty when Verbose is true. map info = 2; + // Container statuses + repeated ContainerStatus containers_statuses = 3; + // Timestamp at which container and pod statuses were recorded + int64 timestamp = 4; } // PodSandboxStateValue is the wrapper of PodSandboxState. @@ -1685,8 +1688,11 @@ message ContainerEventResponse { // Creation timestamp of this event int64 created_at = 3; - // ID of the sandbox container - PodSandboxMetadata pod_sandbox_metadata = 4; + // Sandbox status + PodSandboxStatus pod_sandbox_status = 4; + + // Container statuses + repeated ContainerStatus containers_statuses = 5; } enum ContainerEventType { @@ -1701,4 +1707,4 @@ enum ContainerEventType { // Container deleted CONTAINER_DELETED_EVENT = 3; -} +} \ No newline at end of file