From 6dbcfb085c603e3fe6d6c607bdf9bb90226eb142 Mon Sep 17 00:00:00 2001 From: Reza Miraskar <15625518+RezaMash@users.noreply.github.com> Date: Tue, 19 May 2026 20:22:51 +0000 Subject: [PATCH 01/10] chore(ingress): migrate PodDisruptionBudgets informer from policy/v1beta1 to policy/v1 --- pkg/sloop/ingress/kubewatcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/sloop/ingress/kubewatcher.go b/pkg/sloop/ingress/kubewatcher.go index 06663ba..f9335f1 100644 --- a/pkg/sloop/ingress/kubewatcher.go +++ b/pkg/sloop/ingress/kubewatcher.go @@ -122,7 +122,7 @@ func (i *kubeWatcherImpl) startWellKnownInformers(kubeclient kubernetes.Interfac i.informerFactory.Core().V1().PersistentVolumeClaims().Informer().AddEventHandler(i.getEventHandlerForResource("PersistentVolumeClaim", enableGranularMetrics)) i.informerFactory.Core().V1().PersistentVolumes().Informer().AddEventHandler(i.getEventHandlerForResource("PersistentVolume", enableGranularMetrics)) i.informerFactory.Core().V1().Pods().Informer().AddEventHandler(i.getEventHandlerForResource("Pod", enableGranularMetrics)) - i.informerFactory.Policy().V1beta1().PodDisruptionBudgets().Informer().AddEventHandler(i.getEventHandlerForResource("PodDisruptionBudget", enableGranularMetrics)) + i.informerFactory.Policy().V1().PodDisruptionBudgets().Informer().AddEventHandler(i.getEventHandlerForResource("PodDisruptionBudget", enableGranularMetrics)) i.informerFactory.Core().V1().Services().Informer().AddEventHandler(i.getEventHandlerForResource("Service", enableGranularMetrics)) i.informerFactory.Core().V1().ReplicationControllers().Informer().AddEventHandler(i.getEventHandlerForResource("ReplicationController", enableGranularMetrics)) i.informerFactory.Storage().V1().StorageClasses().Informer().AddEventHandler(i.getEventHandlerForResource("StorageClass", enableGranularMetrics)) From 00859a29526e75636b9acdabdd42437f317d11d3 Mon Sep 17 00:00:00 2001 From: Reza Miraskar <15625518+RezaMash@users.noreply.github.com> Date: Tue, 2 Jun 2026 20:51:33 +0000 Subject: [PATCH 02/10] fix(ingress): prevent startup deadlock when watching many CRDs On clusters with a large number of CRDs (e.g. ~477 on GDCH), sloop would hang during startup and never bind its webserver on :8080. Liveness and startup probes against /healthz then got "connection refused" forever, putting the pod into a permanent CrashLoopBackOff. Root cause was a lock-ordering deadlock during the initial informer sync: - writeToOutChan() sent to the bounded kubeWatchChan (buffer 1000) while holding i.protection. The author had already flagged this line as dangerous. - The single processing goroutine drains that channel doing several synchronous, fsync'd (SyncWrites=true) BadgerDB transactions per event, so it could not keep up with the initial-sync burst from the CRD informers plus the core resources. - Once the channel filled, informer handlers blocked on the send while holding i.protection. Meanwhile the main goroutine was still in startCustomInformers() iterating over every CRD, and each informer setup also needs i.protection. It blocked, so NewKubeWatcherSource() never returned and webserver.Run() was never reached. Two changes: 1. ingress/kubewatcher.go: do not hold i.protection across the channel send. Take the lock only to read `stopped`, release it, then send via a select on i.outchan / i.stopChan. The send no longer blocks the lock, and it unblocks promptly on shutdown instead of blocking forever on a full channel. This removes the deadlock. 2. server/server.go: construct the kube watcher in a background goroutine so the main goroutine reaches webserver.Run() and binds /healthz immediately, regardless of how long the initial CRD sync takes. This is defense in depth: even a merely slow (not deadlocked) watcher no longer causes probes to kill the pod during startup. Shutdown reads kubeWatcherSource under a mutex since it is now set from a goroutine. With these changes the pod becomes Ready in seconds with watchCrds=true, and CRD-backed resources (e.g. *.dbadmin.gdc.goog Instances) are recorded. Verified: go build ./pkg/..., go test ./pkg/sloop/ingress/... ./pkg/sloop/server/..., and go test -race ./pkg/sloop/ingress/... all pass. --- pkg/sloop/ingress/kubewatcher.go | 21 +++++++++++----- pkg/sloop/server/server.go | 43 +++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/pkg/sloop/ingress/kubewatcher.go b/pkg/sloop/ingress/kubewatcher.go index f9335f1..9b70737 100644 --- a/pkg/sloop/ingress/kubewatcher.go +++ b/pkg/sloop/ingress/kubewatcher.go @@ -345,15 +345,24 @@ func (i *kubeWatcherImpl) processUpdate(kind string, obj interface{}, watchResul } func (i *kubeWatcherImpl) writeToOutChan(watchResult *typed.KubeWatchResult) { - // We need to ensure that no messages are written to outChan after stop is called - // Kube watch library has a way to tell it to stop, but no way to know it is complete - // Use a lock around output channel for this purpose + // We need to ensure that no messages are written to outChan after stop is called. + // The lock only guards the stopped check; we must NOT hold it across the channel + // send, otherwise a full channel would block here while holding i.protection, which + // deadlocks any other path that needs the lock (e.g. starting CRD informers during + // the initial sync of a cluster with many CRDs). i.protection.Lock() - defer i.protection.Unlock() - if i.stopped { + stopped := i.stopped + i.protection.Unlock() + if stopped { return } - i.outchan <- *watchResult // WARNING - if this channel gets full, this push will block while holding i.protection in a locked state + + // Send without holding the lock. Select on stopChan so that the send unblocks if the + // watcher is stopped while the channel is full, instead of blocking forever. + select { + case i.outchan <- *watchResult: + case <-i.stopChan: + } } func (i *kubeWatcherImpl) getResourceAsJsonString(kind string, obj interface{}) (string, error) { diff --git a/pkg/sloop/server/server.go b/pkg/sloop/server/server.go index a33a094..33d054e 100644 --- a/pkg/sloop/server/server.go +++ b/pkg/sloop/server/server.go @@ -12,6 +12,7 @@ import ( "os" "path" "strings" + "sync" "time" "github.com/pkg/errors" @@ -96,18 +97,33 @@ func RealMain() error { processor := processing.NewProcessing(kubeWatchChan, tables, conf.KeepMinorNodeUpdates, conf.MaxLookback) processor.Start() - // Real kubernetes watcher + // Real kubernetes watcher. + // + // Setting up the watcher (especially CRD informers on clusters with many CRDs) can + // take a while during the initial sync. We start it in a background goroutine so that + // the webserver below can bind and start serving /healthz immediately, instead of the + // process appearing unhealthy (and being killed by liveness/startup probes) while the + // watcher is still coming up. Access to kubeWatcherSource is guarded by + // kubeWatcherMu because shutdown reads it from the main goroutine. var kubeWatcherSource ingress.KubeWatcher + var kubeWatcherMu sync.Mutex if !conf.DisableKubeWatcher { - kubeClient, err := ingress.MakeKubernetesClient(conf.ApiServerHost, kubeContext, conf.PrivilegedAccess) - if err != nil { - return errors.Wrap(err, "failed to create kubernetes client") - } - - kubeWatcherSource, err = ingress.NewKubeWatcherSource(kubeClient, kubeWatchChan, conf.KubeWatchResyncInterval, conf.WatchCrds, conf.CrdRefreshInterval, conf.ApiServerHost, kubeContext, conf.EnableGranularMetrics, conf.ExclusionRules) - if err != nil { - return errors.Wrap(err, "failed to initialize kubeWatcher") - } + go func() { + kubeClient, err := ingress.MakeKubernetesClient(conf.ApiServerHost, kubeContext, conf.PrivilegedAccess) + if err != nil { + glog.Errorf("failed to create kubernetes client: %v", err) + return + } + + kw, err := ingress.NewKubeWatcherSource(kubeClient, kubeWatchChan, conf.KubeWatchResyncInterval, conf.WatchCrds, conf.CrdRefreshInterval, conf.ApiServerHost, kubeContext, conf.EnableGranularMetrics, conf.ExclusionRules) + if err != nil { + glog.Errorf("failed to initialize kubeWatcher: %v", err) + return + } + kubeWatcherMu.Lock() + kubeWatcherSource = kw + kubeWatcherMu.Unlock() + }() } // File playback @@ -175,8 +191,11 @@ func RealMain() error { // 1. Shut down ingress so that it stops emitting events // 2. Close the input channel which signals processing to finish work // 3. Wait on processor to tell us all work is complete. Store will not change after that - if kubeWatcherSource != nil { - kubeWatcherSource.Stop() + kubeWatcherMu.Lock() + kw := kubeWatcherSource + kubeWatcherMu.Unlock() + if kw != nil { + kw.Stop() } close(kubeWatchChan) processor.Wait() From 3991795ab3cfebd9ecc83acaff197f6681faabba Mon Sep 17 00:00:00 2001 From: Reza Miraskar <15625518+RezaMash@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:23:35 +0000 Subject: [PATCH 03/10] feat(queries): add kubectl-style describe view for resource history Add a GetResDescribe query that renders stored payloads via k8s.io/kubectl describers backed by a fake clientset seeded with the payload and its Events, surfacing fields like Image ID that the raw JSON views bury. Kinds without constructible describers and CRDs fall back to a generic field-tree rendering. Adds a Describe pane to the resource detail page. --- go.mod | 17 + go.sum | 41 +++ pkg/sloop/queries/describequery.go | 378 +++++++++++++++++++++ pkg/sloop/queries/describequery_test.go | 183 ++++++++++ pkg/sloop/queries/eventquery.go | 12 +- pkg/sloop/queries/query.go | 1 + pkg/sloop/queries/respayloadquery.go | 16 +- pkg/sloop/webserver/bindata.go | 63 ++-- pkg/sloop/webserver/resourcehandler.go | 4 + pkg/sloop/webserver/webfiles/resource.css | 10 + pkg/sloop/webserver/webfiles/resource.html | 40 +++ 11 files changed, 734 insertions(+), 31 deletions(-) create mode 100644 pkg/sloop/queries/describequery.go create mode 100644 pkg/sloop/queries/describequery_test.go diff --git a/go.mod b/go.mod index d74b0f4..9d9fc57 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( k8s.io/apiextensions-apiserver v0.0.0-20230112083153-33db789573b1 k8s.io/apimachinery v0.28.6 k8s.io/client-go v0.28.6 + k8s.io/kubectl v0.28.6 ) require ( @@ -35,30 +36,43 @@ require ( github.com/dustin/go-humanize v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/fatih/camelcase v1.0.0 // indirect + github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/imdario/mergo v0.3.8 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect + github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/xlab/treeprint v1.2.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect @@ -68,10 +82,13 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/cli-runtime v0.28.6 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 6485b8e..ff9047e 100644 --- a/go.sum +++ b/go.sum @@ -67,6 +67,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -91,9 +92,13 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -154,6 +159,8 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -181,10 +188,14 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -192,6 +203,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -220,6 +233,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -235,6 +250,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -244,6 +261,8 @@ github.com/nsf/jsondiff v0.0.0-20190712045011-8443391ee9b6/go.mod h1:uFMI8w+ref4 github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -279,6 +298,8 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -290,6 +311,8 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -298,17 +321,21 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -319,6 +346,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -409,6 +438,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -450,10 +481,12 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -629,12 +662,16 @@ k8s.io/apiextensions-apiserver v0.0.0-20230112083153-33db789573b1 h1:2qhBPkS5H8V k8s.io/apiextensions-apiserver v0.0.0-20230112083153-33db789573b1/go.mod h1:Etq6CUKqU9FqOs0Us9CXqTr+kbX3Tw4IXL8iYvp2H/k= k8s.io/apimachinery v0.28.6 h1:RsTeR4z6S07srPg6XYrwXpTJVMXsjPXn0ODakMytSW0= k8s.io/apimachinery v0.28.6/go.mod h1:QFNX/kCl/EMT2WTSz8k4WLCv2XnkOLMaL8GAVRMdpsA= +k8s.io/cli-runtime v0.28.6 h1:bDH2+ZbHBK3NORGmIygj/zWOkVd/hGWg9RqAa5c/Ev0= +k8s.io/cli-runtime v0.28.6/go.mod h1:KFk67rlb7Pxh15uLbYGBUlW7ZUcpl7IM1GnHtskrcWA= k8s.io/client-go v0.28.6 h1:Gge6ziyIdafRchfoBKcpaARuz7jfrK1R1azuwORIsQI= k8s.io/client-go v0.28.6/go.mod h1:+nu0Yp21Oeo/cBCsprNVXB2BfJTV51lFfe5tXl2rUL8= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/kubectl v0.28.6 h1:46O3gGJYlpqy7wtwYlggieemyIcuZqmflnQVDci3MgY= +k8s.io/kubectl v0.28.6/go.mod h1:FS5ugZhi3kywpMQSCnp8MN+gctdFHJACzC6mH3fZ6lc= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -642,6 +679,10 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/pkg/sloop/queries/describequery.go b/pkg/sloop/queries/describequery.go new file mode 100644 index 0000000..5123437 --- /dev/null +++ b/pkg/sloop/queries/describequery.go @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2019, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +package queries + +import ( + "bytes" + "encoding/json" + "fmt" + "net/url" + "sort" + "strings" + "text/tabwriter" + "time" + "unicode" + + "github.com/golang/glog" + "github.com/pkg/errors" + "github.com/salesforce/sloop/pkg/sloop/store/typed" + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + policyv1 "k8s.io/api/policy/v1" + storagev1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/kubectl/pkg/describe" +) + +// GetResDescribe renders the stored payloads of a resource the same way `kubectl describe` +// would have at that point in time. It returns one entry per payload in the time range that +// produced a distinct describe output. +// +// kubectl's describers normally fetch live objects from an API server. Here each historical +// payload is deserialized back into its typed object and loaded into a fake clientset +// (together with the resource's Events from the watch table), and the matching describer runs +// against that. Kinds without an externally constructible describer (e.g. Deployment, +// StatefulSet, and all CRDs) fall back to a generic rendering modeled on kubectl's generic +// describer. + +type DescribeOutput struct { + PayloadKey string `json:"payloadKey"` + PayLoadTime int64 `json:"payloadTime"` + Describe string `json:"describe"` +} + +func GetResDescribe(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) ([]byte, error) { + watchRes, err := getResPayloadWatchResults(params, t, startTime, endTime, requestId) + if err != nil { + return []byte{}, err + } + payloadOutputList := removeDupePayloads(getPayloadOutputList(watchRes)) + + events, err := getResourceEventList(params, t, startTime, endTime, requestId) + if err != nil { + // Describe output is still useful without the events section + glog.Errorf("Failed to get events for describe query: %v", err) + events = nil + } + + selectedKind := params.Get(KindParam) + describeList := []DescribeOutput{} + lastDescribe := "" + for _, payloadOutput := range payloadOutputList { + describeText, describeErr := describePayload(selectedKind, payloadOutput.Payload, events) + if describeErr != nil { + glog.Errorf("Failed to describe payload for key %v: %v", payloadOutput.PayloadKey, describeErr) + describeText = fmt.Sprintf("Failed to generate describe output: %v", describeErr) + } + // Payloads that differ only in fields describe does not show (e.g. resourceVersion) + // produce identical output, so collapse them the same way removeDupePayloads does + if describeText == lastDescribe { + continue + } + lastDescribe = describeText + describeList = append(describeList, DescribeOutput{ + PayloadKey: payloadOutput.PayloadKey, + PayLoadTime: payloadOutput.PayLoadTime, + Describe: describeText, + }) + } + + bytes, err := json.MarshalIndent(describeList, "", " ") + if err != nil { + return nil, fmt.Errorf("failed to marshal json for DescribeList %v", err) + } + return bytes, nil +} + +// getResourceEventList returns the Events involving the selected resource within the time +// range, deserialized to corev1.Event with only the latest stored copy of each event kept. +func getResourceEventList(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) ([]corev1.Event, error) { + watchEvents, err := getEventWatchResults(params, t, startTime, endTime, requestId) + if err != nil { + return nil, err + } + + // The watch table holds every update of an Event (count keeps growing); keep the latest per name + latestKeys := map[string]typed.WatchTableKey{} + for key := range watchEvents { + if existing, ok := latestKeys[key.Name]; !ok || key.Timestamp.After(existing.Timestamp) { + latestKeys[key.Name] = key + } + } + + events := []corev1.Event{} + for _, key := range latestKeys { + event := corev1.Event{} + err = json.Unmarshal([]byte(watchEvents[key].Payload), &event) + if err != nil { + glog.Errorf("Failed to unmarshal event payload for key %v: %v", key.String(), err) + continue + } + events = append(events, event) + } + sort.Slice(events, func(i, j int) bool { + return events[i].LastTimestamp.Time.Before(events[j].LastTimestamp.Time) + }) + return events, nil +} + +type typedDescriberEntry struct { + // Payloads from the well-known informers carry no apiVersion/kind (TypeMeta is empty in + // informer objects), so each kind maps to its concrete type explicitly + newObject func() runtime.Object + newDescriber func(c kubernetes.Interface) describe.ResourceDescriber +} + +// Kinds from startWellKnownInformers whose kubectl describers can be constructed with a plain +// clientset. The remaining well-known kinds (Deployment, StatefulSet, HorizontalPodAutoscaler, +// MutatingWebhookConfiguration, Event) have describers with unexported fields or none at all, +// and use the generic fallback like CRDs do. +var typedDescribers = map[string]typedDescriberEntry{ + "Pod": { + func() runtime.Object { return &corev1.Pod{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { return &describe.PodDescriber{Interface: c} }, + }, + "ReplicaSet": { + func() runtime.Object { return &appsv1.ReplicaSet{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.ReplicaSetDescriber{Interface: c} + }, + }, + "DaemonSet": { + func() runtime.Object { return &appsv1.DaemonSet{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.DaemonSetDescriber{Interface: c} + }, + }, + "Job": { + func() runtime.Object { return &batchv1.Job{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { return &describe.JobDescriber{Interface: c} }, + }, + "Namespace": { + func() runtime.Object { return &corev1.Namespace{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.NamespaceDescriber{Interface: c} + }, + }, + "Node": { + func() runtime.Object { return &corev1.Node{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { return &describe.NodeDescriber{Interface: c} }, + }, + "PersistentVolume": { + func() runtime.Object { return &corev1.PersistentVolume{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.PersistentVolumeDescriber{Interface: c} + }, + }, + "PersistentVolumeClaim": { + func() runtime.Object { return &corev1.PersistentVolumeClaim{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.PersistentVolumeClaimDescriber{Interface: c} + }, + }, + "Service": { + func() runtime.Object { return &corev1.Service{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.ServiceDescriber{Interface: c} + }, + }, + // Sloop's kind label for v1.Endpoints + "Endpoint": { + func() runtime.Object { return &corev1.Endpoints{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.EndpointsDescriber{Interface: c} + }, + }, + "ConfigMap": { + func() runtime.Object { return &corev1.ConfigMap{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.ConfigMapDescriber{Interface: c} + }, + }, + "StorageClass": { + func() runtime.Object { return &storagev1.StorageClass{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.StorageClassDescriber{Interface: c} + }, + }, + "PodDisruptionBudget": { + func() runtime.Object { return &policyv1.PodDisruptionBudget{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.PodDisruptionBudgetDescriber{Interface: c} + }, + }, + "ReplicationController": { + func() runtime.Object { return &corev1.ReplicationController{} }, + func(c kubernetes.Interface) describe.ResourceDescriber { + return &describe.ReplicationControllerDescriber{Interface: c} + }, + }, +} + +func describePayload(kind string, payload string, events []corev1.Event) (string, error) { + entry, ok := typedDescribers[kind] + if !ok { + return genericDescribePayload(payload, events) + } + + obj := entry.newObject() + err := json.Unmarshal([]byte(payload), obj) + if err != nil { + return "", errors.Wrapf(err, "payload cannot be unmarshalled into kind %v", kind) + } + metaObj, ok := obj.(metav1.Object) + if !ok { + return "", fmt.Errorf("object for kind %v has no metadata", kind) + } + + clientObjects := []runtime.Object{obj} + for i := range events { + clientObjects = append(clientObjects, &events[i]) + } + client := fake.NewSimpleClientset(clientObjects...) + + describer := entry.newDescriber(client) + return describer.Describe(metaObj.GetNamespace(), metaObj.GetName(), describe.DescriberSettings{ShowEvents: true, ChunkSize: 500}) +} + +// genericDescribePayload mirrors the output of kubectl's generic describer (used by +// `kubectl describe` for CRDs), which renders the object's content as an indented field tree. +func genericDescribePayload(payload string, events []corev1.Event) (string, error) { + var content map[string]interface{} + err := json.Unmarshal([]byte(payload), &content) + if err != nil { + return "", errors.Wrap(err, "payload cannot be unmarshalled") + } + + metadata, _ := content["metadata"].(map[string]interface{}) + + buf := &bytes.Buffer{} + out := tabwriter.NewWriter(buf, 0, 8, 2, ' ', 0) + w := describe.NewPrefixWriter(out) + w.Write(describe.LEVEL_0, "Name:\t%v\n", metadata["name"]) + w.Write(describe.LEVEL_0, "Namespace:\t%v\n", metadata["namespace"]) + writeStringMapMultiline(w, "Labels", metadata["labels"]) + writeStringMapMultiline(w, "Annotations", metadata["annotations"]) + writeUnstructuredContent(w, describe.LEVEL_0, content, "", + ".metadata.managedFields", ".metadata.name", ".metadata.namespace", ".metadata.labels", ".metadata.annotations") + if len(events) > 0 { + describe.DescribeEvents(&corev1.EventList{Items: events}, w) + } + err = out.Flush() + if err != nil { + return "", err + } + return buf.String(), nil +} + +func writeStringMapMultiline(w describe.PrefixWriter, title string, value interface{}) { + m, _ := value.(map[string]interface{}) + if len(m) == 0 { + w.Write(describe.LEVEL_0, "%s:\t\n", title) + return + } + keys := []string{} + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + for i, k := range keys { + if i == 0 { + w.Write(describe.LEVEL_0, "%s:\t%s=%v\n", title, k, m[k]) + } else { + w.Write(describe.LEVEL_0, "\t%s=%v\n", k, m[k]) + } + } +} + +func writeUnstructuredContent(w describe.PrefixWriter, level int, content map[string]interface{}, skipPrefix string, skip ...string) { + fields := []string{} + for field := range content { + fields = append(fields, field) + } + sort.Strings(fields) + + for _, field := range fields { + skipExpr := fmt.Sprintf("%s.%s", skipPrefix, field) + if containsString(skip, skipExpr) { + continue + } + switch typedValue := content[field].(type) { + case map[string]interface{}: + w.Write(level, "%s:\n", smartLabelFor(field)) + writeUnstructuredContent(w, level+1, typedValue, skipExpr, skip...) + case []interface{}: + w.Write(level, "%s:\n", smartLabelFor(field)) + for _, child := range typedValue { + switch typedChild := child.(type) { + case map[string]interface{}: + writeUnstructuredContent(w, level+1, typedChild, skipExpr, skip...) + default: + w.Write(level+1, "%v\n", typedChild) + } + } + default: + w.Write(level, "%s:\t%v\n", smartLabelFor(field), typedValue) + } + } +} + +func containsString(list []string, s string) bool { + for _, item := range list { + if item == s { + return true + } + } + return false +} + +// smartLabelFor turns a camelCase field name into the spaced label kubectl shows, +// e.g. "containerStatuses" -> "Container Statuses", "apiVersion" -> "API Version". +func smartLabelFor(field string) string { + if strings.IndexFunc(field, func(r rune) bool { + return !unicode.IsLetter(r) && r != '-' + }) != -1 { + return field + } + + commonAcronyms := map[string]bool{"API": true, "URL": true, "UID": true, "OSB": true, "GUID": true} + result := []string{} + for _, part := range splitCamelCase(field) { + if commonAcronyms[strings.ToUpper(part)] { + part = strings.ToUpper(part) + } else { + runes := []rune(part) + runes[0] = unicode.ToUpper(runes[0]) + part = string(runes) + } + result = append(result, part) + } + return strings.Join(result, " ") +} + +// splitCamelCase splits at lower-to-upper transitions and before the last upper of an +// uppercase run ("APIVersion" -> "API", "Version"). +func splitCamelCase(s string) []string { + runes := []rune(s) + parts := []string{} + start := 0 + for i := 1; i < len(runes); i++ { + lowerToUpper := unicode.IsUpper(runes[i]) && !unicode.IsUpper(runes[i-1]) + endOfUpperRun := i+1 < len(runes) && unicode.IsUpper(runes[i]) && !unicode.IsUpper(runes[i+1]) && unicode.IsUpper(runes[i-1]) + if lowerToUpper || endOfUpperRun { + parts = append(parts, string(runes[start:i])) + start = i + } + } + parts = append(parts, string(runes[start:])) + return parts +} diff --git a/pkg/sloop/queries/describequery_test.go b/pkg/sloop/queries/describequery_test.go new file mode 100644 index 0000000..f76b9e7 --- /dev/null +++ b/pkg/sloop/queries/describequery_test.go @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2019, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +package queries + +import ( + "encoding/json" + "testing" + "time" + + "github.com/dgraph-io/badger/v2" + "github.com/stretchr/testify/assert" + + "github.com/salesforce/sloop/pkg/sloop/store/typed" + "github.com/salesforce/sloop/pkg/sloop/store/untyped" + "github.com/salesforce/sloop/pkg/sloop/store/untyped/badgerwrap" +) + +const somePodPayloadWithContainers = `{ + "metadata": { + "name": "somePod", + "namespace": "someNamespace", + "uid": "6c2a9795-a282-11e9-ba2f-14187761de09", + "creationTimestamp": "2019-01-02T03:04:05Z", + "labels": {"app": "someApp"} + }, + "spec": { + "nodeName": "someNode", + "containers": [ + { + "name": "database", + "image": "gcr.io/some-registry/someimage:15", + "ports": [{"containerPort": 5432, "protocol": "TCP"}] + } + ] + }, + "status": { + "phase": "Running", + "containerStatuses": [ + { + "name": "database", + "image": "gcr.io/some-registry/someimage:15", + "imageID": "gcr.io/some-registry/someimage@sha256:4f2e646a914a3c441ef2be6a1d55a14e2c006a5eb1c6a2569cf6649f57b02549", + "containerID": "containerd://c133b3454d0aa5ffe846f218b63f281cbc00c7125ea86b375cd1acb1eedb2e25", + "restartCount": 0, + "ready": true, + "state": {"running": {"startedAt": "2019-01-02T03:04:10Z"}} + } + ] + } +}` + +const someEventPayload = `{ + "metadata": { + "name": "somePod.157de23babbb985d", + "namespace": "someNamespace", + "uid": "0a4selfb-a282-11e9-ba2f-14187761de09" + }, + "involvedObject": {"kind": "Pod", "name": "somePod", "namespace": "someNamespace"}, + "reason": "Started", + "message": "Started container database", + "type": "Normal", + "count": 1, + "source": {"component": "kubelet", "host": "someNode"}, + "firstTimestamp": "2019-01-02T03:04:10Z", + "lastTimestamp": "2019-01-02T03:04:10Z" +}` + +const someCrdPayload = `{ + "apiVersion": "example.com/v1", + "kind": "SomeCrd", + "metadata": { + "name": "someCrd", + "namespace": "someNamespace", + "labels": {"team": "someTeam"} + }, + "spec": {"replicaCount": 3, "apiEndpoint": "https://example.com"} +}` + +func helper_get_describe_tables(t *testing.T, records map[string]string) typed.Tables { + db, err := (&badgerwrap.MockFactory{}).Open(badger.DefaultOptions("")) + assert.Nil(t, err) + wt := typed.OpenKubeWatchResultTable() + + err = db.Update(func(txn badgerwrap.Txn) error { + for key, payload := range records { + val := &typed.KubeWatchResult{Kind: "Pod", Timestamp: somePTime, Payload: payload} + txerr := wt.Set(txn, key, val) + if txerr != nil { + return txerr + } + } + return nil + }) + assert.Nil(t, err) + return typed.NewTableList(db) +} + +func helper_run_describe(t *testing.T, kind string, name string, records map[string]string) []DescribeOutput { + values := helper_get_params() + values[KindParam] = []string{kind} + values[NamespaceParam] = []string{"someNamespace"} + values[NameParam] = []string{name} + + tables := helper_get_describe_tables(t, records) + res, err := GetResDescribe(values, tables, someTs.Add(-1*time.Hour), someTs.Add(time.Hour), someRequestId) + assert.Nil(t, err) + + var describeList []DescribeOutput + assert.Nil(t, json.Unmarshal(res, &describeList)) + return describeList +} + +func Test_GetResDescribe_PodShowsImageIdAndEvents(t *testing.T) { + untyped.TestHookSetPartitionDuration(time.Hour) + partitionId := untyped.GetPartitionId(someTs) + + records := map[string]string{ + typed.NewWatchTableKey(partitionId, "Pod", "someNamespace", "somePod", someTs).String(): somePodPayloadWithContainers, + typed.NewWatchTableKey(partitionId, "Event", "someNamespace", "somePod.157de23babbb985d", someTs).String(): someEventPayload, + typed.NewWatchTableKey(partitionId, "Pod", "someNamespace", "someOtherPod", someTs).String(): somePodPayload, + } + + describeList := helper_run_describe(t, "Pod", "somePod", records) + assert.Equal(t, 1, len(describeList)) + + describeText := describeList[0].Describe + assert.Regexp(t, `Name:\s+somePod`, describeText) + assert.Contains(t, describeText, "Image ID:") + assert.Contains(t, describeText, "sha256:4f2e646a914a3c441ef2be6a1d55a14e2c006a5eb1c6a2569cf6649f57b02549") + assert.Contains(t, describeText, "Container ID:") + assert.Contains(t, describeText, "Events:") + assert.Contains(t, describeText, "Started container database") +} + +func Test_GetResDescribe_OnePerDistinctPayload(t *testing.T) { + untyped.TestHookSetPartitionDuration(time.Hour) + partitionId := untyped.GetPartitionId(someTs) + + changedPod := somePodPayloadWithContainers[:len(somePodPayloadWithContainers)-1] + `,"spec2": {"x": 1}}` + records := map[string]string{ + typed.NewWatchTableKey(partitionId, "Pod", "someNamespace", "somePod", someTs).String(): somePodPayloadWithContainers, + typed.NewWatchTableKey(partitionId, "Pod", "someNamespace", "somePod", someTs.Add(time.Minute)).String(): somePodPayloadWithContainers, + typed.NewWatchTableKey(partitionId, "Pod", "someNamespace", "somePod", someTs.Add(2*time.Minute)).String(): changedPod, + } + + // the unchanged payload collapses; the changed one does not parse differently for describe + // (unknown field), so it also collapses into the first describe output + describeList := helper_run_describe(t, "Pod", "somePod", records) + assert.Equal(t, 1, len(describeList)) +} + +func Test_GetResDescribe_UnknownKindUsesGenericDescribe(t *testing.T) { + untyped.TestHookSetPartitionDuration(time.Hour) + partitionId := untyped.GetPartitionId(someTs) + + records := map[string]string{ + typed.NewWatchTableKey(partitionId, "SomeCrd", "someNamespace", "someCrd", someTs).String(): someCrdPayload, + } + + describeList := helper_run_describe(t, "SomeCrd", "someCrd", records) + assert.Equal(t, 1, len(describeList)) + + describeText := describeList[0].Describe + assert.Regexp(t, `Name:\s+someCrd`, describeText) + assert.Regexp(t, `Namespace:\s+someNamespace`, describeText) + assert.Contains(t, describeText, "team=someTeam") + assert.Contains(t, describeText, "API Version:") + assert.Regexp(t, `Replica Count:\s+3`, describeText) + assert.Contains(t, describeText, "API Endpoint:") +} + +func Test_smartLabelFor(t *testing.T) { + assert.Equal(t, "Container Statuses", smartLabelFor("containerStatuses")) + assert.Equal(t, "API Version", smartLabelFor("apiVersion")) + assert.Equal(t, "UID", smartLabelFor("uid")) + assert.Equal(t, "Host IP", smartLabelFor("hostIP")) + assert.Equal(t, "some.field/name", smartLabelFor("some.field/name")) +} diff --git a/pkg/sloop/queries/eventquery.go b/pkg/sloop/queries/eventquery.go index 2c7f24e..18e9975 100644 --- a/pkg/sloop/queries/eventquery.go +++ b/pkg/sloop/queries/eventquery.go @@ -33,7 +33,9 @@ type EventOutput struct { EventKey string `json:"eventKey"` } -func GetEventData(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) ([]byte, error) { +// getEventWatchResults returns the watch records of the Events that involve the resource +// selected by params, within [startTime, endTime]. +func getEventWatchResults(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) (map[typed.WatchTableKey]*typed.KubeWatchResult, error) { var watchEvents map[typed.WatchTableKey]*typed.KubeWatchResult err := t.Db().View(func(txn badgerwrap.Txn) error { var err2 error @@ -68,6 +70,14 @@ func GetEventData(params url.Values, t typed.Tables, startTime time.Time, endTim stats.Log(requestId) return nil }) + if err != nil { + return nil, err + } + return watchEvents, nil +} + +func GetEventData(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) ([]byte, error) { + watchEvents, err := getEventWatchResults(params, t, startTime, endTime, requestId) if err != nil { return []byte{}, err } diff --git a/pkg/sloop/queries/query.go b/pkg/sloop/queries/query.go index 9589035..7574c81 100644 --- a/pkg/sloop/queries/query.go +++ b/pkg/sloop/queries/query.go @@ -23,6 +23,7 @@ var funcMap = map[string]ganttJsonQuery{ "EventHeatMap": EventHeatMap3Query, "GetEventData": GetEventData, "GetResPayload": GetResPayload, + "GetResDescribe": GetResDescribe, "Namespaces": NamespaceQuery, "Kinds": KindQuery, "Queries": QueryAvailableQueries, diff --git a/pkg/sloop/queries/respayloadquery.go b/pkg/sloop/queries/respayloadquery.go index b126d67..65369ba 100644 --- a/pkg/sloop/queries/respayloadquery.go +++ b/pkg/sloop/queries/respayloadquery.go @@ -33,9 +33,12 @@ type PayloadOuput struct { Payload string `json:"payload,omitempty"` } -func GetResPayload(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) ([]byte, error) { +// getResPayloadWatchResults returns the watch records for the resource selected by params within +// [startTime, endTime], plus the latest record just before startTime (so callers always have the +// state of the resource as of the start of the window). +func getResPayloadWatchResults(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) (map[typed.WatchTableKey]*typed.KubeWatchResult, error) { - glog.V(common.GlogVerbose).Infof("GetResPayload: startTime: %v, endTime: %v", startTime.Unix(), endTime.Unix()) + glog.V(common.GlogVerbose).Infof("getResPayloadWatchResults: startTime: %v, endTime: %v", startTime.Unix(), endTime.Unix()) var watchRes map[typed.WatchTableKey]*typed.KubeWatchResult var previousKey *typed.WatchTableKey var previousVal *typed.KubeWatchResult @@ -83,6 +86,15 @@ func GetResPayload(params url.Values, t typed.Tables, startTime time.Time, endTi stats.Log(requestId) return nil }) + if err != nil { + return nil, err + } + + return watchRes, nil +} + +func GetResPayload(params url.Values, t typed.Tables, startTime time.Time, endTime time.Time, requestId string) ([]byte, error) { + watchRes, err := getResPayloadWatchResults(params, t, startTime, endTime, requestId) if err != nil { return []byte{}, err } diff --git a/pkg/sloop/webserver/bindata.go b/pkg/sloop/webserver/bindata.go index 9950238..75eb4ba 100644 --- a/pkg/sloop/webserver/bindata.go +++ b/pkg/sloop/webserver/bindata.go @@ -1,4 +1,4 @@ -// Code generated by go-bindata. +// Code generated for package webserver by go-bindata DO NOT EDIT. (@generated) // sources: // webfiles/debug.html // webfiles/debug.js @@ -14,8 +14,6 @@ // webfiles/resource.html // webfiles/sloop.css // webfiles/sloop_ui.js -// DO NOT EDIT! - package webserver import ( @@ -62,26 +60,37 @@ type bindataFileInfo struct { modTime time.Time } +// Name return file name func (fi bindataFileInfo) Name() string { return fi.name } + +// Size return file size func (fi bindataFileInfo) Size() int64 { return fi.size } + +// Mode return file mode func (fi bindataFileInfo) Mode() os.FileMode { return fi.mode } + +// Mode return file modify time func (fi bindataFileInfo) ModTime() time.Time { return fi.modTime } + +// IsDir return file whether a directory func (fi bindataFileInfo) IsDir() bool { - return false + return fi.mode&os.ModeDir != 0 } + +// Sys return file is sys mode func (fi bindataFileInfo) Sys() interface{} { return nil } -var _webfilesDebugHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x54\xcd\x6e\xe3\x36\x10\xbe\xeb\x29\xa6\xbc\xd8\xc6\x46\x62\x37\x3d\x75\x57\x16\xb0\x6b\xa7\xd8\xa0\x4e\xd1\xc6\x45\x51\x20\xc8\x81\xa6\x46\x16\x13\x8a\xa3\x90\x23\x3b\x7e\xfb\x82\xa2\xf3\xdb\xd6\xeb\x83\x45\x0d\xbf\xbf\x21\x07\x2a\x7f\xc8\xf3\x6c\x41\xfd\xc1\x9b\x6d\xcb\x30\xd5\x33\x38\xff\xf1\xe3\xcf\x67\x10\x94\xc5\xd0\x90\xd7\x58\x68\xea\xce\xc0\x38\x5d\x64\x5f\xac\x85\x11\x18\xc0\x63\x40\xbf\xc3\xba\xc8\xd6\xbf\x2f\xff\xce\x57\x46\xa3\x0b\x98\x5f\xd6\xe8\xd8\x34\x06\xfd\x27\xf8\xba\x5e\xe6\x3f\xe5\x0b\xab\x86\x80\xd9\x2f\xe4\xa1\x19\xac\x05\x9b\x90\xc0\xf8\xc8\x67\x10\x10\x61\x75\xb9\xb8\xf8\x6d\x7d\x51\xf0\x23\x43\x63\x2c\x82\x71\xc0\x2d\x82\xc7\x9e\xc0\x13\x31\x90\x87\x96\xb9\x0f\x9f\xa4\xa4\x1e\x5d\xa0\x21\xe6\x22\xbf\x95\x47\xb5\x20\xdf\x98\xe5\x79\x95\x95\x2d\x77\x36\x3e\x50\xd5\x55\x06\x00\x50\x06\xed\x4d\xcf\xc0\x87\x1e\xe7\x22\xfa\xcb\x3b\xb5\x53\xa9\x2a\x12\x26\xfe\x6a\xd2\x43\x87\x8e\x8b\xbd\x37\x8c\x53\x51\x6e\x54\x40\x68\x3d\x36\xf3\x89\x14\xf0\x01\xf6\xc6\xd5\xb4\x2f\x2c\x69\xc5\x86\x5c\xd1\x2b\x6e\x9d\xea\xb0\x08\xbd\x35\x3c\x9d\xc8\xc9\xec\xe6\xe3\x2d\x7c\x00\x21\x27\x20\x2b\x31\xfb\x9c\xfc\x65\xb2\x7a\x9b\x26\x78\x3d\x17\x7b\xdc\xc4\xce\x83\xac\x71\x33\x6c\x8b\xbb\x20\xaa\x77\x68\x36\x6c\xb1\x5a\x5b\xa2\x1e\x96\x11\x04\x57\xe8\x86\x52\xa6\x7a\xc2\x58\xe3\xee\xc1\xa3\x9d\x4f\x42\x4b\x9e\xf5\xc0\x60\x34\xb9\x49\xea\x78\x62\x3a\xb5\x45\xf9\x98\xa7\x5a\xea\xe7\xd9\xb8\x51\xbb\x58\x2f\x8c\xa6\x98\x39\x2b\x65\x3a\xb8\x72\x43\xf5\x01\xc8\x59\x52\xf5\x5c\xc4\xff\x6f\xd4\xe1\x35\x36\xd3\xd9\x67\x51\x41\x76\x03\xa5\x02\x53\xcf\x45\x4b\x1d\xae\x8c\xbb\x17\x55\x04\x94\x52\x55\x70\x9b\x65\x65\x7b\xfe\x1f\xa1\xdb\xf3\x2a\xcb\xca\xc1\x3e\xe7\xae\x4a\x95\x02\x89\xf1\x00\xa4\x35\x81\xef\xf1\x10\xa4\xa8\xfe\x18\xd0\x1f\x60\xa9\x58\xc1\x9a\xc9\x27\xe5\x1c\xbe\x58\x4b\xfb\x00\x07\x1a\x80\x09\x1e\x46\x50\x64\x80\x72\x35\xec\x94\x1d\x30\x40\xe3\xa9\x1b\x27\x69\xa3\xea\x2d\x7a\x08\x89\x6f\xcd\xff\xfa\xb6\x26\x30\x6d\xbd\xea\xa4\x38\xc6\xfe\x35\x6a\x7e\x7b\x2a\x1f\xcd\xff\x32\xb8\x1f\x85\x47\xc7\xf6\x65\xf7\x84\xb4\x26\xd7\x98\xad\x14\xd5\x62\x5c\xbc\x57\xd2\x83\xf7\xe8\x18\x94\x66\xb3\x43\x48\x68\x68\xc8\xc3\x98\xe3\xa4\x34\xab\x4d\xbc\x42\x51\xfd\x39\x2e\x5e\x4b\x7f\x4d\x9d\xaf\xd6\x57\x30\x6e\xc2\xa5\x6b\xe8\xa4\x98\xc7\x87\x01\x03\x07\x51\x1d\xb9\xd7\xc7\x42\x94\x3d\xc9\xc4\x1d\xba\x57\xbc\x8b\xf1\xf5\xbb\xac\x9d\xf2\x2f\x9c\x2b\x64\x6f\xf4\x29\x52\x97\x10\x4f\xd7\xf3\x2f\x42\x29\xe3\x58\x65\xa5\x8c\x73\x3b\x8e\x71\xfc\x0c\xfc\x13\x00\x00\xff\xff\x18\xd3\x24\xd6\xe7\x04\x00\x00") +var _webfilesDebugHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x54\xcd\x6e\xe3\x36\x10\xbe\xeb\x29\xa6\xbc\xd8\xc6\x46\x62\x37\x3d\x75\x57\x16\xb0\x6b\xa7\xd8\xa0\x4e\xd1\xc6\x45\x51\x20\xc8\x81\xa6\x46\x16\x13\x8a\xa3\x90\x23\x3b\x7e\xfb\x82\xa2\xf3\xdb\xd6\xab\x83\x44\x0d\xbf\xbf\x11\x07\x2a\x7f\xc8\xf3\x6c\x41\xfd\xc1\x9b\x6d\xcb\x30\xd5\x33\x38\xff\xf1\xe3\xcf\x67\x10\x94\xc5\xd0\x90\xd7\x58\x68\xea\xce\xc0\x38\x5d\x64\x5f\xac\x85\x11\x18\xc0\x63\x40\xbf\xc3\xba\xc8\xd6\xbf\x2f\xff\xce\x57\x46\xa3\x0b\x98\x5f\xd6\xe8\xd8\x34\x06\xfd\x27\xf8\xba\x5e\xe6\x3f\xe5\x0b\xab\x86\x80\xd9\x2f\xe4\xa1\x19\xac\x05\x9b\x90\xc0\xf8\xc8\x67\x10\x10\x61\x75\xb9\xb8\xf8\x6d\x7d\x51\xf0\x23\x43\x63\x2c\x82\x71\xc0\x2d\x82\xc7\x9e\xc0\x13\x31\x90\x87\x96\xb9\x0f\x9f\xa4\xa4\x1e\x5d\xa0\x21\xe6\x22\xbf\x95\x47\xb5\x20\xdf\x98\xe5\x79\x95\x95\x2d\x77\x36\x3e\x50\xd5\x55\x06\x00\x50\x06\xed\x4d\xcf\xc0\x87\x1e\xe7\x22\xfa\xcb\x3b\xb5\x53\xa9\x2a\x12\x26\x5e\x35\xe9\xa1\x43\xc7\xc5\xde\x1b\xc6\xa9\x28\x37\x2a\x20\xb4\x1e\x9b\xf9\x44\x0a\xf8\x00\x7b\xe3\x6a\xda\x17\x96\xb4\x62\x43\xae\xe8\x15\xb7\x4e\x75\x58\x84\xde\x1a\x9e\x4e\xe4\x64\x76\xf3\xf1\x16\x3e\x80\x90\x13\x90\x95\x98\x7d\x4e\xfe\x32\x59\xbd\x4d\x13\xbc\x9e\x8b\x3d\x6e\x62\xe7\x41\xd6\xb8\x19\xb6\xc5\x5d\x10\xd5\x3b\x34\x1b\xb6\x58\xad\x2d\x51\x0f\xcb\x08\x82\x2b\x74\x43\x29\x53\x3d\x61\xac\x71\xf7\xe0\xd1\xce\x27\xa1\x25\xcf\x7a\x60\x30\x9a\xdc\x24\x75\x3c\x31\x9d\xda\xa2\x7c\xcc\x53\x2d\xf5\xf3\x6c\xdc\xa8\x5d\xac\x17\x46\x53\xcc\x9c\x95\x32\x7d\xb8\x72\x43\xf5\x01\xc8\x59\x52\xf5\x5c\xc4\xfb\x37\xea\xf0\x1a\x9b\xe9\xec\xb3\xa8\xb2\x1b\x28\x15\x98\x7a\x2e\x5a\xea\x70\x65\xdc\xbd\xa8\xe2\x7e\x29\x55\x05\xb7\x59\x56\xb6\xe7\xff\x91\xb9\x3d\xaf\xb2\xac\x1c\xec\x73\xec\xaa\x54\x29\x8f\x18\xfb\x97\xd6\x04\xbe\xc7\x43\x90\xa2\xfa\x63\x40\x7f\x80\xa5\x62\x05\x6b\x26\x9f\x94\x73\xf8\x62\x2d\xed\x03\x1c\x68\x00\x26\x78\x18\x41\x91\x01\xca\xd5\xb0\x53\x76\xc0\x00\x8d\xa7\x6e\x1c\xa4\x8d\xaa\xb7\xe8\x21\x24\xbe\x35\xff\xeb\xdb\x9a\xc0\xb4\xf5\xaa\x93\xe2\x18\xfb\xd7\xa8\xf9\xed\xa9\x7c\x34\xff\xcb\xe0\x7e\x14\x1e\x1d\xdb\x97\xdd\x13\xd2\x9a\x5c\x63\xb6\x52\x54\x8b\x71\xf1\x5e\x49\x0f\xde\xa3\x63\x50\x9a\xcd\x0e\x21\xa1\xa1\x21\x0f\x63\x8e\x93\xd2\xac\x36\xf1\x04\x45\xf5\xe7\xb8\x78\x2d\xfd\x35\x75\xbe\x5a\x5f\xc1\xb8\x09\x97\xae\xa1\x93\x62\x1e\x1f\x06\x0c\x1c\x44\x75\xe4\x5e\x1f\x0b\x51\xf6\x24\x13\x77\xe8\x5e\xf1\x2e\xc6\xd7\xef\xb2\x76\xca\xbf\x70\xae\x90\xbd\xd1\xa7\x48\xb2\x4b\x90\xa7\xf3\xf9\x17\xa3\x94\x71\xae\xb2\x52\xc6\xb9\x1d\xc7\x78\xfc\x0d\xfc\x13\x00\x00\xff\xff\xbe\x5a\xd1\x37\xe8\x04\x00\x00") func webfilesDebugHtmlBytes() ([]byte, error) { return bindataRead( @@ -96,7 +105,7 @@ func webfilesDebugHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debug.html", size: 1255, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debug.html", size: 1256, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -116,7 +125,7 @@ func webfilesDebugJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debug.js", size: 463, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debug.js", size: 463, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -136,7 +145,7 @@ func webfilesDebugconfigHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debugconfig.html", size: 754, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debugconfig.html", size: 754, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,7 +165,7 @@ func webfilesDebughistogramHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debughistogram.html", size: 2468, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debughistogram.html", size: 2468, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -176,7 +185,7 @@ func webfilesDebuglistkeysHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debuglistkeys.html", size: 3340, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debuglistkeys.html", size: 3340, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -196,7 +205,7 @@ func webfilesDebugtablesHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debugtables.html", size: 1091, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debugtables.html", size: 1091, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -216,7 +225,7 @@ func webfilesDebugviewkeyHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/debugviewkey.html", size: 946, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/debugviewkey.html", size: 946, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -236,7 +245,7 @@ func webfilesFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/favicon.ico", size: 15406, mode: os.FileMode(493), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/favicon.ico", size: 15406, mode: os.FileMode(488), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -256,7 +265,7 @@ func webfilesFilterJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/filter.js", size: 5321, mode: os.FileMode(420), modTime: time.Unix(1661208231, 0)} + info := bindataFileInfo{name: "webfiles/filter.js", size: 5321, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -276,12 +285,12 @@ func webfilesIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/index.html", size: 5777, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/index.html", size: 5777, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _webfilesResourceCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x92\x41\x4f\x1b\x31\x10\x85\xef\xfb\x2b\x46\x42\x95\x00\xc5\xd9\x40\xcb\x01\x73\x6a\x21\xa8\x48\xa8\xaa\xc4\xa5\x37\xe4\xb5\x67\x77\x2d\x26\x9e\xd5\x78\x36\x24\x42\xfd\xef\xd5\x6e\x36\xa5\x8d\xa0\xbd\x59\x9e\xe7\xf7\x3e\x3f\xbb\x3c\x2d\xe0\x14\xae\xb9\xdb\x4a\x6c\x5a\x85\x63\x7f\x02\xe7\x8b\xb3\xcb\x19\x64\x47\x98\x6b\x16\x8f\x73\xcf\xab\x19\xc4\xe4\xe7\x83\xf6\x33\x11\x8c\xda\x0c\x82\x19\x65\x8d\x61\xdc\x7f\xf8\x7e\xf3\xc3\xdc\x47\x8f\x29\xa3\xb9\x0b\x98\x34\xd6\x11\xc5\xc2\x97\x87\x1b\xf3\xd1\x5c\x93\xeb\x33\x0e\xc2\x5b\x16\xa8\x7b\x22\xa0\x9d\x18\x14\x37\x3a\x83\x8c\x08\xf7\x77\xd7\xcb\x6f\x0f\xcb\xb9\x6e\x14\xea\x48\x08\x31\x81\xb6\x08\x82\x1d\x83\x30\x2b\xb0\x40\xab\xda\x65\x5b\x96\xdc\x61\xca\xdc\x0f\x80\x2c\x4d\x39\xb9\xe5\xf2\x20\xaf\x2c\x8a\x56\x57\x34\x83\x8a\xc3\x16\x5e\x0a\x00\x00\x5e\xa3\xd4\xc4\xcf\x16\x5c\xaf\x7c\x55\xfc\x2c\x8a\x23\xc1\x9d\xd9\x23\xae\x31\xe9\xa3\xba\x8a\x70\x92\xd7\x9c\xd4\xd4\x6e\x15\x69\x6b\xe1\x2b\xd2\x1a\x35\x7a\x37\x54\x94\xb2\xc9\x28\xb1\xbe\x1a\x75\x15\x4b\x40\x31\x9e\x89\x5c\x97\xd1\xc2\x7e\xb5\x1b\x3f\xc7\xa0\xad\x85\xb3\xc5\xe2\xc3\x18\x39\xdf\x47\x9a\xca\x89\x21\x57\x21\xed\x03\x23\x91\x85\xa3\xe5\xc5\xf2\xf2\x76\x71\x80\xe7\x39\xa9\x8b\x09\x65\xd2\x1e\xb8\x1e\x79\xe2\xfc\x1b\x9c\xd8\xa9\x1d\x5f\x6b\x87\xd0\xb9\x10\x62\x6a\xec\x79\xb7\x81\x8b\x6e\x33\x61\x3b\xff\xd4\x08\xf7\x29\xd8\x55\x0c\x69\x50\x57\xd4\x4f\xd0\x9e\x89\xc5\xc2\x73\x1b\x15\x47\xff\x37\x7b\xd2\x30\x83\x77\x26\xed\xc4\xb2\x2b\xc7\xc2\x59\xb7\x81\xcc\x14\x03\xd0\x90\xd4\x08\x6e\xff\x66\x83\x4f\x03\xd8\xbb\x4f\xa2\x62\x93\xb6\xc6\xb7\x91\xc2\xf1\x30\x38\x79\x79\xbd\x80\xf9\x13\x37\xaf\xf8\x09\xaf\xfe\x65\xd4\x0e\x1f\x01\xde\x38\xff\x8a\xf6\xfe\xf1\xfd\xc5\x86\xef\x6b\x1c\xc5\x26\x59\x20\xac\xf5\xb0\xd4\xbd\xe7\xff\xba\x1d\x77\x7a\xc9\x2c\xb6\xe3\x98\x14\x65\x68\xe1\x57\x00\x00\x00\xff\xff\x99\x8a\x0e\x7b\xa1\x03\x00\x00") +var _webfilesResourceCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x93\x4f\x6f\xd4\x30\x10\xc5\xef\xf9\x14\x23\x55\x48\x6d\x15\xef\x9f\x42\x11\x75\x4f\xb0\xdd\x8a\x4a\x05\x21\xf5\xc2\xad\x72\xec\xc9\xc6\xea\xc4\x13\xd9\x93\xed\x2e\x15\xdf\x1d\xe5\xcf\x52\x58\xb6\x20\x6e\x91\xfd\xe6\xcd\xcf\x6f\x26\xd3\xd3\x0c\x4e\x61\xc1\xcd\x36\xfa\x55\x25\x70\x6c\x4f\xe0\x6c\x36\xbf\xc8\x21\x19\xc2\x54\x72\xb4\x38\xb1\x5c\xe7\xe0\x83\x9d\x74\xda\xf7\x44\xd0\x6b\x13\x44\x4c\x18\xd7\xe8\xfa\xf3\xbb\x2f\x57\x5f\xd5\xad\xb7\x18\x12\xaa\x1b\x87\x41\x7c\xe9\x31\x6a\xf8\x70\x77\xa5\x5e\xab\x05\x99\x36\x61\x27\xbc\xe6\x08\x65\x4b\x04\x34\x88\x41\x70\x23\x39\x24\x44\xb8\xbd\x59\x2c\x3f\xdf\x2d\x27\xb2\x11\x28\x3d\x21\xf8\x00\x52\x21\x44\x6c\x18\x22\xb3\x00\x47\xa8\x44\x9a\xa4\xa7\x53\x6e\x30\x24\x6e\x3b\x40\x8e\xab\xe9\xe8\x96\xa6\x7b\xfd\xa6\x59\x56\x49\x4d\x39\x14\xec\xb6\xf0\x94\x01\x00\xf0\x1a\x63\x49\xfc\xa8\xc1\xb4\xc2\x97\xd9\xf7\x2c\x3b\x8a\x38\x98\xdd\xe3\x1a\x83\xdc\x8b\x29\x08\x47\x79\xc9\x41\x54\x69\x6a\x4f\x5b\x0d\x1f\x91\xd6\x28\xde\x9a\x2e\xa2\x90\x54\xc2\xe8\xcb\xcb\x5e\x57\x70\x74\x18\x95\x65\x22\xd3\x24\xd4\xb0\xfb\x1a\xae\x1f\xbd\x93\x4a\xc3\x7c\x36\x7b\xd5\xb7\x9c\xec\x5a\xaa\xc2\x44\x45\xa6\x40\xda\x35\xf4\x44\x1a\x8e\x96\xe7\xcb\x8b\xeb\xd9\x1e\x9e\xe5\x20\xc6\x07\x8c\xa3\x76\xcf\xf5\xc8\x12\xa7\x9f\xe0\xc4\x46\x74\x3f\xad\x01\xa1\x31\xce\xf9\xb0\xd2\x67\xcd\x06\xce\x9b\xcd\x88\x6d\xec\xc3\x2a\x72\x1b\x9c\xae\xbd\x0b\x9d\xba\xa0\x76\x84\xb6\x4c\x1c\x35\x3c\x56\x5e\xb0\xf7\x3f\x98\x93\xb8\x1c\x5e\xb8\xa9\x46\x96\x21\x1c\x0d\xf3\x66\x03\x89\xc9\x3b\xa0\xae\xd3\x2a\xe2\xf6\x77\x36\x78\xd3\x81\xbd\x38\x12\x89\x3a\x48\xa5\x6c\xe5\xc9\x1d\x77\x17\x27\x4f\xcf\x0f\x50\xbf\xe2\xa6\x9a\x1f\xf0\xf2\x6f\x46\x55\xb7\x08\x70\xa0\xfe\x19\xed\xe5\xf2\xdd\xc3\xba\xf5\x55\x86\xfc\x2a\x68\x20\x2c\x65\x3f\xd4\x9d\xe7\xbf\xb2\xed\x4f\xda\x98\x38\xea\x86\x7d\x10\x8c\x43\x0a\x0e\x93\x8d\xbe\xc0\x7b\x6e\xa5\x69\xe5\xd0\x4e\x7e\xc2\x40\x9c\xc3\x82\x43\x62\x32\x29\x87\x9a\x03\xa7\xc6\xd8\xd1\xb6\x17\x27\xff\x0d\x35\xcc\xcf\xfe\x1c\xfb\x81\xd4\xfe\x73\x64\xef\x76\xa6\xfb\x7f\x56\x77\x56\x9b\x8d\xaa\xb0\xab\xd4\xf0\x76\x36\x1b\xa6\xfb\x23\x00\x00\xff\xff\x17\x64\xe2\x63\x79\x04\x00\x00") func webfilesResourceCssBytes() ([]byte, error) { return bindataRead( @@ -296,12 +305,12 @@ func webfilesResourceCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/resource.css", size: 929, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/resource.css", size: 1145, mode: os.FileMode(416), modTime: time.Unix(1781122707, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _webfilesResourceHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3a\x79\x6f\xdb\x46\xf6\xff\xfb\x53\xbc\xb0\x45\x49\xfd\x6a\x91\xb6\x8b\x1f\xb0\x4b\x8b\xea\x61\xa7\xd8\x34\x8e\x13\x54\x6e\xd0\x45\x51\x04\x23\xf2\x51\x9a\x98\x9a\xe1\xce\x0c\x15\x6b\x55\x7d\xf7\xc5\xcc\x50\xe2\xa5\xcb\x4e\x16\xc1\x02\xe1\x3f\x9e\xe3\x5d\xf3\xe6\xcd\xbb\xac\xc1\xb3\x7e\xff\xe4\x8a\xe7\x0b\x41\x27\x53\x05\x5e\xdc\x83\x8b\xb3\xf3\xbf\x9f\x82\x24\x19\xca\x94\x8b\x18\xfd\x98\xcf\x4e\x81\xb2\xd8\x3f\xf9\x31\xcb\xc0\x00\x4a\x10\x28\x51\xcc\x31\xf1\x4f\x46\x6f\xae\x7f\xef\xdf\xd0\x18\x99\xc4\xfe\x8b\x04\x99\xa2\x29\x45\x11\xc2\x4f\xa3\xeb\xfe\x77\xfd\xab\x8c\x14\x12\x4f\x7e\xe6\x02\xd2\x22\xcb\x20\xb3\x90\xa0\xf0\x41\x9d\x82\x44\x84\x9b\x17\x57\xcf\x6f\x47\xcf\x7d\xf5\xa0\x20\xa5\x19\x02\x65\xa0\xa6\x08\x02\x73\x0e\x82\x73\x05\x5c\xc0\x54\xa9\x5c\x86\x41\xc0\x73\x64\x92\x17\x5a\x2e\x2e\x26\x41\x49\x4d\x06\x0d\x66\xfd\xfe\xf0\x64\xf0\xec\xfa\xf5\xd5\xdd\x3f\xdf\x3c\x87\xa9\x9a\x65\xc3\x93\x81\xfe\x03\x19\x61\x93\xc8\x41\xe6\xe8\x05\x24\xc9\xf0\x04\x00\x60\x30\x43\x45\x20\x9e\x12\x21\x51\x45\xce\x6f\x77\x3f\xf7\xff\xe6\x94\x5b\x19\x65\xf7\x20\x30\x8b\x5c\x39\xe5\x42\xc5\x85\x02\x1a\x73\xe6\x82\x5a\xe4\x18\xb9\x74\x46\x26\x18\x3c\xf4\xed\xda\x54\x60\x1a\xb9\x1f\x70\xac\xcf\x21\x83\x94\xcc\xf5\xba\x4f\x63\xee\x06\x6d\x7a\x8e\x54\x8b\x0c\xe5\x14\x51\x39\x96\x98\xa3\x75\x12\xc4\x52\x3a\x96\x90\xb3\x21\x24\x33\xce\x73\x5f\xef\x7c\x0c\x15\x81\xa5\xe6\x0e\x12\xb2\x88\x6b\x9d\x17\x2c\xbf\x9f\x68\x33\x08\x58\x2e\xf8\x44\xa0\x94\x3f\x9c\xf9\x17\xfe\x59\x35\x37\x24\x01\x9e\x72\xc8\x35\x97\x18\x67\x28\x68\x7c\xef\x4f\xa8\x9a\x16\x63\x9f\xf2\xe0\xbd\x4c\x68\x9a\x66\x74\x1c\xe8\xbf\x73\x8a\x1f\x2a\x3e\x96\x91\xa2\x2a\xc3\xe1\xaf\xe5\xc1\x60\xb9\xf4\x5f\x52\x96\xac\x56\xc1\x72\xe9\xdf\x92\x19\xca\x9c\xc4\x58\x4d\x57\xab\x41\x60\x51\x4a\xfc\x67\xfd\x3e\xdc\x4d\xa9\x84\x8c\x4a\x05\x3c\x05\x19\x0b\x9a\x2b\x09\x0c\x31\x91\xa0\x38\x90\x4c\x72\xc8\xe8\xdc\x98\x25\x65\x09\x3e\xf8\xc6\x92\xb4\x8d\x19\x12\x16\x03\xa4\x88\xb7\x69\x8c\x3c\x50\x2e\x83\x84\x4a\x65\x87\xfe\x8c\x32\xff\xbd\x6c\x28\xe3\x3d\x99\x13\x4b\xc5\x19\x0e\x02\x3b\xda\x43\x3c\x4e\x34\x85\x04\x33\x3a\x17\x3e\x43\x15\xb0\x7c\x16\xcc\x0b\xb4\x5c\xe6\x05\x7e\x24\xfd\x63\xae\xfb\x23\x4f\x70\xd4\x55\xef\xe6\x01\x9f\x84\x49\x46\xc7\x47\xf2\x38\x19\x04\xd6\x59\x0c\xc6\x3c\x59\x0c\x4f\x06\x09\x9d\x03\x4d\x22\x67\xfd\xa2\xde\xe9\x75\x07\x8c\xb1\x47\x4e\x4e\x92\x84\xb2\x49\x78\x7e\x96\x3f\x38\xdb\xa0\x63\xce\x14\xa1\x0c\xc5\xfa\x15\x8e\x0b\xa5\x38\xd3\x40\x6e\x9c\x71\x89\x2e\x70\x16\x67\x34\xbe\x8f\x5c\x35\xa5\xd2\xcf\x89\x40\xa6\x6e\x79\x82\x3b\x86\x02\x67\x7c\x8e\x57\x53\x9a\x25\xde\x6e\x8c\xde\x25\x08\x54\x85\x60\x90\x92\x4c\xe2\xa5\x3b\xfc\x7d\x10\x58\xde\xa5\x20\xd3\x8b\xe1\x35\x2a\x42\x33\x39\x08\xa6\x17\x6b\xe9\x86\xfa\xed\x0c\x82\xf1\x30\x84\xea\x21\x8d\x45\x63\xdb\xbc\xb4\x06\x4c\xf9\xf6\xea\x80\xfa\x71\x6e\x60\xec\x4b\xd5\xdb\x06\xc4\xc2\x90\xd2\x2b\x2c\x97\xfe\x08\xb3\xf4\x37\x91\xad\x56\x0e\x28\x22\x26\xda\x33\xbf\x1b\x67\x84\xdd\x3b\xc3\xd7\x39\x32\x78\xc1\xe0\x16\x3f\xc0\x1d\x19\x0f\x02\x52\xa3\xb1\x5c\xd2\x14\x18\x82\x97\x21\x03\xff\x86\xb2\x7b\xd9\x83\x33\x58\xad\xcc\xee\xfa\x98\x66\xbd\x3a\xa4\x45\x14\x84\x4d\xb0\xc4\x59\xad\xea\xc2\xec\x10\x64\xb9\xf4\xef\xf0\x41\x69\xbf\x62\x45\x58\x2e\x51\x9f\xaa\x14\xc4\x8e\xed\xc9\x3a\x56\x90\x93\x45\xc6\x49\xe2\x0c\x1b\x72\xbd\xa5\xf8\x81\xb2\x09\x58\x51\x96\x4b\xff\x4a\xdb\xc1\x1d\xd5\x3a\x87\x6f\x83\xbe\x5e\x7a\x93\x15\xf2\x15\x65\x85\xb4\xcb\xcd\x53\x0c\x14\x19\xeb\x20\x5a\x67\x85\x73\x64\xea\x9d\xd9\xa8\xb1\xb3\xd0\x02\xe6\x7d\x9a\x46\x8e\xe4\x42\x61\xf2\x2b\xca\x37\x56\x2e\xe9\x67\xc8\x26\x6a\xda\x42\xb0\x48\x53\xf8\xc1\xda\xa7\x41\xf3\xdc\x0c\x53\x55\xe2\xb9\x3d\x67\x78\x83\xa9\x82\x72\x3e\x08\xd4\xf4\x18\x12\x26\xb1\xa8\xd1\xf8\xd5\x64\x24\x87\x88\x0c\x4b\x00\xd0\x77\x76\x2c\xab\x52\xf3\x5a\x7b\x9a\xd3\x9b\x6a\x0a\xdf\x7c\xf5\x70\x71\x7e\xf5\xff\x5d\x4a\x83\x40\x89\xd6\x4a\x5e\x6a\xee\xd9\x6e\xd5\x0d\xe8\xf0\x96\x43\xc9\x4f\x42\xca\x0b\x96\x40\xca\x05\xe8\x47\x0a\x39\x0a\xca\x93\x41\x40\x87\x83\x20\xdf\x76\x2f\x29\x17\xe6\x16\x75\xec\xe9\x30\xd9\x7a\x31\xc9\xf0\xeb\xa5\x40\x2d\xc0\xe6\x42\x56\x03\xca\xf2\x42\x95\x7e\x4e\x90\x84\x72\x07\xc2\x39\xc9\x0a\x34\xc4\xfd\xb5\x21\x42\x58\x1a\xcd\x7a\xe5\x25\x2e\x1c\x98\xf7\x67\x3c\xd1\xa1\xbc\x46\x52\xaf\x72\x16\xc6\x53\x6d\xa4\x91\x93\xf0\x6b\x9a\xa6\x5e\xef\xd2\x09\x86\x83\x40\x25\xfb\x04\xab\x5f\xf3\xa7\x92\xac\x4e\xf3\x49\xa2\x0d\x08\x84\xfa\xa9\x83\x65\xc2\x05\x9d\xbc\xd5\x52\xc0\x5f\x30\x41\xb5\x7e\xa9\xef\x0a\x91\x75\x5d\xc0\xc6\x5f\x92\xbd\x67\x87\x9a\xf4\xc6\xd2\x2c\xe9\x94\x8b\x19\x51\x0a\x93\x77\x4a\xbf\xe5\x2e\x85\xa6\xdd\x0d\x02\xf3\x88\x6b\x0b\x6b\xb7\xa2\x23\x1a\x2f\x54\x5e\x28\x67\x08\x83\x20\xa1\xf3\xd2\xeb\xd6\x86\xf5\x98\x99\x16\x2c\x56\x94\x33\xd0\x88\xbf\x49\xca\x26\xbf\x8c\x3c\x7d\xc5\x77\x26\x31\x37\x2a\xb5\x43\x1d\x8c\xef\x16\x39\xf6\x60\xb9\x61\xeb\x14\x12\x41\x2a\x41\x63\xe5\x5c\x6e\x56\xe7\x44\xc0\x78\xf1\x22\x81\xa8\x22\xef\xd1\xa4\x8e\xb8\xfe\xca\x38\x94\xf0\xb8\x98\x21\x53\xfe\x04\xd5\xf3\x0c\xf5\xf0\xa7\xc5\x8b\x44\x23\x5d\x36\x70\x56\xa7\x8d\xe9\x98\x48\x84\x08\xd6\x61\x5c\x4b\xc2\x26\x3f\xca\x1b\xca\x50\x6e\x4e\xd1\x6b\xe2\x30\xfc\xa0\x4b\x8c\x5d\x58\x9b\x13\xb7\xd0\xe4\x0c\x22\x8d\xbb\x41\x1b\xe1\xbf\x0a\x64\x31\xbe\x22\x2a\x9e\xa2\xf0\xb4\x2c\xa7\x25\xf5\x16\x2e\xcf\x63\x9e\xa0\x84\x08\xe4\x4c\x1f\xf1\x5d\xb9\xe0\xb5\xe0\xaa\xcb\xd3\xd7\x19\x19\x25\x7a\xf5\x2b\x6d\xc1\xeb\x04\x02\x1f\xd4\x88\xfe\x5b\x6b\xc1\xa9\x5d\x41\x83\x92\x4f\x19\x43\xf1\x8f\xbb\x57\x37\x2d\xa8\x26\x7e\x7d\xf6\xd7\x5f\xc0\x8a\x2c\xbb\x3c\xd9\x41\x91\xe4\x39\xb2\xc4\x26\x1a\x9b\x4c\x6d\x5c\xd0\x2c\xd1\x81\xcb\x5b\x76\x6e\x49\x6b\xd4\x28\x38\x34\xd3\xce\x95\xd4\xf6\xad\x0a\xb7\x6a\x30\x5c\x0f\xba\x66\xa0\x09\xe8\x74\x23\x04\xa7\x1e\x76\x9c\xad\x9c\x4a\xc0\x46\x6c\x71\x76\xea\x36\xac\x4f\x9a\x50\xeb\x47\x11\x6e\x46\x9b\xed\x55\xaf\xb4\xdd\x32\xf2\x6b\xdb\x79\x5b\x60\x4d\x37\x98\x85\xe0\x7e\xd5\x4e\x04\xdc\x8a\x83\x4e\xee\x67\x54\xa1\x90\x21\xfc\xe1\x7e\xbd\x74\x4f\xc1\x5d\xb9\x7f\xd6\x00\x88\x22\x61\xeb\x59\x89\x4d\x68\x08\xe1\x8f\x3f\x5b\x87\x2a\x84\x4e\x02\x47\x5c\xa8\x9f\x16\x21\x34\x22\xe0\x4e\xc8\x6b\x2a\xd0\x3c\xe2\x10\x5c\x22\xe3\x16\xa0\x54\x44\x28\x4d\x20\x04\xb7\xb5\x55\x8b\x14\x21\x14\x2c\xc1\x94\x32\x4c\x9a\x30\x75\x9f\xbd\x13\x28\xe6\x05\x53\x21\x9c\x55\xba\xad\xf6\x53\x9a\x59\x05\x35\xb5\xd0\x75\xaa\x5e\xc1\xe8\x03\x23\x8c\x9b\xd9\x1e\x67\xa4\x2f\xea\x9a\xa8\x16\x02\x04\x70\x7e\x66\xbe\x9e\xaf\xf8\x8b\xd1\xeb\x91\x71\x1b\x5e\xcf\x97\x79\x46\x95\xe7\xde\xb9\x3d\xff\x3d\xa7\xcc\x73\xc1\xdd\xef\xb5\x5a\xb1\xc4\x33\x91\x6e\x8f\x40\x4e\x82\xe3\x62\x12\x68\x0b\xfb\xfe\x3e\x72\xe0\x5b\x30\x18\xb5\x20\xd8\x62\xb7\x4d\x4f\x33\xad\x43\x4c\xbc\x36\x9f\xdb\x37\x9b\xda\x9d\xb3\x94\x4e\x0a\x81\x5e\x57\x12\x24\x3a\x34\x84\xe0\x22\x91\x6d\x53\x31\xd4\x29\xa3\xb3\x62\x16\xc2\x99\xff\x5d\x77\xd7\x96\x1e\x5b\x8d\xbd\x29\x78\xaf\xe6\x70\xf4\x67\x6b\x65\xca\x14\x8a\x18\x73\xc5\x85\xf4\x85\x76\xbb\x52\xf9\x85\x44\xcf\x4a\x0c\xd1\x70\x8b\xee\xaa\x73\x19\x0b\xf5\x5a\x57\x52\x53\xaf\xa5\x72\xf9\x04\x49\x64\xce\x99\x44\x23\xca\x7a\x72\x48\x98\x84\x33\xdc\x23\xcb\x9a\xcc\x31\xd2\x74\x68\xe8\xd0\xe2\xb9\xba\x30\xb0\xca\x35\xc5\x8a\xdb\xeb\xc2\xa9\x29\xb2\x03\x12\xeb\x8f\xa6\xb0\x81\xf2\xb5\xab\xd9\x66\xa3\xeb\xcf\x94\x9b\x95\xef\x81\x08\x1a\xa8\xfe\x8c\xe4\x5e\x95\x0d\xcc\x49\xb6\x8f\x58\x4d\x23\xfb\x81\xc0\x58\xd7\xc6\x89\x85\xfa\x65\xd4\xd3\xab\xae\x2d\xee\xc0\x7e\x89\x8b\x06\xf2\x4b\x5c\x1c\x8d\xdb\x40\x3c\x8c\x55\x77\x8b\x6d\x97\xb9\xed\x6b\xb8\xc8\x63\x10\x36\x79\xab\x11\x6c\x3f\xfc\xaa\x6b\x8a\x9b\xad\x2d\x66\x6a\xd6\x01\x33\x89\x7b\x2e\x26\xe6\x4c\xf2\x0c\xfd\x8c\x4f\x3c\x67\x7b\xdd\x63\x4b\x1e\xa7\x6b\x9b\xd0\xf0\x5f\x95\x28\x5b\x5d\x1a\xaa\x29\x4f\x3a\xae\x5f\x57\x48\x61\x2d\xf3\x94\x26\xda\x6d\x33\x37\x6d\xe0\x76\x17\xa2\x28\xb2\x26\xdc\x08\x91\xbb\x6c\xb4\x0d\xb9\x09\x91\x10\x81\xb7\x67\x33\x8a\x6c\x08\xed\xc1\xf7\xe0\x26\x28\x63\x17\xca\xa0\xda\x55\x75\x57\x0b\x5d\xf9\x74\x46\x69\x06\x7b\xe3\x4d\x2e\x50\xa9\x45\x5d\x25\x87\x22\xce\x2f\xa3\xd7\xb7\x65\x5e\x4c\xd3\x85\x67\xa6\x39\x11\x12\x4b\xcc\x53\x93\x1d\x9e\xc2\xc5\xfe\x40\x67\xab\xae\x3a\xe3\x5d\xb7\x60\x8e\x56\x7b\x18\xf0\x2c\xaa\x92\x01\xf8\xe6\x9b\xd2\xbd\xd4\x5e\x42\x03\x62\xd7\x3d\xd5\x8b\x1a\xdb\x0f\x33\xaa\xe8\xb0\xeb\x9d\x42\x67\xbb\xce\xac\x77\x0a\xe7\x5b\x5e\xc3\xea\x70\xd8\x8d\xf9\x2c\x2f\x14\x26\xdb\x8c\xb4\x51\xc6\x1f\xd2\x52\x79\x33\x2d\x37\xeb\x9b\x4e\x86\x47\x4e\x61\xdc\xdb\xed\xc8\x33\x54\x90\x3c\xc1\x44\xcf\x21\x84\xfe\xf9\x76\x2f\xa0\x6f\x8d\xfc\xd1\x35\xc9\x3f\x61\x00\xe3\x6d\xeb\xbd\xf5\x11\xfa\xe7\xf0\x7f\x95\x38\x8f\xa5\x3e\x3c\x40\xfd\x00\xe1\x12\xea\x6c\xcb\x65\xb6\x6d\xf9\xa4\x39\xd2\xfb\xf5\x5e\x70\xa7\x91\x67\xba\x6b\x9b\xff\xa8\x4c\x2f\x86\xcf\xcd\x42\xad\x83\x7a\x74\x4b\x6e\x4b\x3b\xce\x12\xdb\xde\x8c\x3b\xdc\x00\xeb\x36\xbf\x66\x28\x25\x99\x98\xc6\xd7\x2b\x3b\xdc\xd3\xf4\xea\x76\xe9\x90\x48\xce\x4c\x7f\xce\x8c\x1e\x83\x6b\x4f\xae\x71\x47\xf6\xdf\x35\x8f\xc0\x35\x95\x80\x46\xbd\xd2\x83\xc7\x60\xa6\x54\x48\x35\x42\x34\x42\xff\xac\x27\x20\x11\x1f\x25\x78\x46\x2a\x0a\x37\x64\x2f\x81\x56\xbb\xa6\xdb\x22\x6c\x5d\xa7\x6d\x10\x5a\x0b\x3a\xb2\x3d\xd8\x6c\x0d\x1a\x7a\x8d\xfe\xe0\xf3\xba\x39\x56\x48\x55\x97\xab\xc2\xfb\x84\x9d\xae\xaa\xcb\x65\x29\x97\x66\x06\xdb\x5a\x5a\x2d\x50\x6b\x53\xc7\x40\x96\xff\xe6\x3b\x02\xd2\xd8\xcb\x31\x80\x1b\xf3\xe8\x34\xe4\x12\xa2\x8e\x62\xb5\xb6\x8e\xa3\x08\x54\xf6\xb1\x69\xe5\x95\x1d\xba\x46\x77\xee\x60\xcf\xc0\x5a\xcc\x27\x68\x19\x58\x6b\x39\xdc\x31\xa8\x9e\xd1\xd1\xfd\x82\x27\x57\xed\x5a\x71\x07\x53\x15\x5b\x0a\x7f\xb6\x1a\xdc\x5c\xc0\xff\x64\x05\x5e\x9a\xce\x97\x02\xbc\x21\xcb\xa7\x29\xc0\xed\x6b\xfa\x2c\xf5\xb7\x65\xfd\xf1\xe5\xb7\xce\x19\x4d\xca\x9f\xbc\x25\x19\x44\xd0\xac\x01\xd6\xd5\xee\x8e\x12\x71\xfd\x1d\x5d\xc3\x97\x61\x22\xac\x58\xae\x23\xc7\xe1\x72\xd7\xda\x73\x1d\xb5\xfc\x7d\xcb\x94\x4b\x75\x44\x79\x6d\xc2\x4e\x1d\xdd\xae\x1c\xc6\x2c\xdb\x92\x15\xa2\x59\x38\x8c\xb7\xf1\xa1\x75\x5c\xb3\x78\x47\x67\x28\x15\x99\xe5\x47\x74\x11\x48\x97\x86\x5e\x7b\x04\x89\x66\x9f\xe0\xb3\xb7\x09\x3a\xd9\xcf\x97\x26\xc1\x7f\xb5\x49\xf0\xa4\x72\x75\x9d\x27\x3c\xaa\x58\x2d\x93\xdd\x2f\xb5\xea\xe7\xa9\x55\xd7\x99\x65\x50\xfe\x6c\x29\xb0\x3f\x85\xfc\x4f\x00\x00\x00\xff\xff\x38\xcb\xd6\x85\xf5\x29\x00\x00") +var _webfilesResourceHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x3a\xfb\x6f\xdb\xb6\xd6\xbf\xe7\xaf\x38\xd5\x8a\xc9\xfe\x16\x4b\x49\x87\x0f\xf8\x3e\x45\xf6\x1e\x49\x87\x9b\x35\x4d\x8b\x25\x2b\x76\x51\x14\x05\x2d\x1d\xd9\x6c\x64\x52\x97\xa4\x9c\xf8\x7a\xfe\xdf\x2f\x48\x4a\xd6\xcb\xaf\xa4\xbd\x1b\x06\xcc\xbf\x84\x22\xcf\x8b\x87\xe7\xc5\xc3\x84\xcf\x06\x83\xa3\x73\x9e\x2d\x04\x9d\x4c\x15\xf4\xa2\x3e\xbc\x38\x39\xfd\xff\x63\x90\x24\x45\x99\x70\x11\xa1\x17\xf1\xd9\x31\x50\x16\x79\x47\x3f\xa4\x29\x18\x40\x09\x02\x25\x8a\x39\xc6\xde\xd1\xcd\xdb\x8b\xdf\x06\x57\x34\x42\x26\x71\x70\x19\x23\x53\x34\xa1\x28\x02\xf8\xf1\xe6\x62\xf0\xed\xe0\x3c\x25\xb9\xc4\xa3\x9f\xb8\x80\x24\x4f\x53\x48\x2d\x24\x28\x7c\x50\xc7\x20\x11\xe1\xea\xf2\xfc\xe5\xf5\xcd\x4b\x4f\x3d\x28\x48\x68\x8a\x40\x19\xa8\x29\x82\xc0\x8c\x83\xe0\x5c\x01\x17\x30\x55\x2a\x93\x81\xef\xf3\x0c\x99\xe4\xb9\x96\x8b\x8b\x89\x5f\x50\x93\x7e\x83\xd9\x60\x30\x3a\x0a\x9f\x5d\xbc\x39\xbf\xfd\xe7\xdb\x97\x30\x55\xb3\x74\x74\x14\xea\x3f\x90\x12\x36\x19\x3a\xc8\x1c\x3d\x81\x24\x1e\x1d\x01\x00\x84\x33\x54\x04\xa2\x29\x11\x12\xd5\xd0\xf9\xf5\xf6\xa7\xc1\xff\x39\xc5\x52\x4a\xd9\x1d\x08\x4c\x87\xae\x9c\x72\xa1\xa2\x5c\x01\x8d\x38\x73\x41\x2d\x32\x1c\xba\x74\x46\x26\xe8\x3f\x0c\xec\xdc\x54\x60\x32\x74\xef\x71\xac\xf7\x21\xfd\x84\xcc\xf5\xbc\x47\x23\xee\xfa\x6d\x7a\x8e\x54\x8b\x14\xe5\x14\x51\x39\x96\x98\xa3\x75\xe2\x47\x52\x3a\x96\x90\xb3\x26\x24\x53\xce\x33\x4f\xaf\x7c\x0e\x15\x81\x85\xe6\xf6\x12\xb2\x88\xa5\xce\x73\x96\xdd\x4d\xb4\x19\xf8\x2c\x13\x7c\x22\x50\xca\xef\x4f\xbc\x17\xde\x49\xf5\x6d\x48\x02\x3c\x65\x93\x25\x97\x08\x67\x28\x68\x74\xe7\x4d\xa8\x9a\xe6\x63\x8f\x72\xff\x93\x8c\x69\x92\xa4\x74\xec\xeb\xbf\x73\x8a\xf7\x15\x1f\xcb\x48\x51\x95\xe2\xe8\x97\x62\x63\xb0\x5c\x7a\xaf\x28\x8b\x57\x2b\x7f\xb9\xf4\xae\xc9\x0c\x65\x46\x22\xac\x3e\x57\xab\xd0\xb7\x28\x05\xfe\xb3\xc1\x00\x6e\xa7\x54\x42\x4a\xa5\x02\x9e\x80\x8c\x04\xcd\x94\x04\x86\x18\x4b\x50\x1c\x48\x2a\x39\xa4\x74\x6e\xcc\x92\xb2\x18\x1f\x3c\x63\x49\xda\xc6\x0c\x09\x8b\x01\x52\x44\x9b\x34\x46\x1e\x28\x97\x7e\x4c\xa5\xb2\x43\x6f\x46\x99\xf7\x49\x36\x94\xf1\x89\xcc\x89\xa5\xe2\x8c\x42\xdf\x8e\x76\x10\x8f\x62\x4d\x21\xc6\x94\xce\x85\xc7\x50\xf9\x2c\x9b\xf9\xf3\x1c\x2d\x97\x79\x8e\x9f\x49\xff\x90\xe3\xfe\xcc\x1d\x1c\x74\xd4\xdb\x79\xc0\x17\x61\x92\xd2\xf1\x81\x3c\x8e\x42\xdf\x06\x8b\x70\xcc\xe3\xc5\xe8\x28\x8c\xe9\x1c\x68\x3c\x74\x4a\x8f\xfa\xa8\xe7\x1d\x30\xc6\x3e\x74\x32\x12\xc7\x94\x4d\x82\xd3\x93\xec\xc1\xd9\x04\x1d\x71\xa6\x08\x65\x28\x4a\x2f\x1c\xe7\x4a\x71\xa6\x81\xdc\x28\xe5\x12\x5d\xe0\x2c\x4a\x69\x74\x37\x74\xd5\x94\x4a\x2f\x23\x02\x99\xba\xe6\x31\x6e\x19\x0a\x9c\xf1\x39\x9e\x4f\x69\x1a\xf7\xb6\x63\xf4\xcf\x40\xa0\xca\x05\x83\x84\xa4\x12\xcf\xdc\xd1\x6f\xa1\x6f\x79\x17\x82\x4c\x5f\x8c\x2e\x50\x11\x9a\xca\xd0\x9f\xbe\x28\xa5\x1b\x69\xdf\x09\xfd\xf1\x28\x80\xca\x91\xc6\xa2\xb1\x6c\x3c\xad\x01\x53\xf8\x5e\x1d\x50\x3b\xe7\x1a\xc6\x7a\xaa\x5e\x36\x20\x16\x86\x14\x51\x61\xb9\xf4\x6e\x30\x4d\x7e\x15\xe9\x6a\xe5\x80\x22\x62\xa2\x23\xf3\xc7\x71\x4a\xd8\x9d\x33\x7a\x93\x21\x83\x4b\x06\xd7\x78\x0f\xb7\x64\x1c\xfa\xa4\x46\x63\xb9\xa4\x09\x30\x84\x5e\x8a\x0c\xbc\x2b\xca\xee\x64\x1f\x4e\x60\xb5\x32\xab\xe5\x36\xcd\x7c\xb5\x49\x8b\x28\x08\x9b\x60\x81\xb3\x5a\xd5\x85\xd9\x22\xc8\x72\xe9\xdd\xe2\x83\xd2\x71\xc5\x8a\xb0\x5c\xa2\xde\x55\x21\x88\x1d\xdb\x9d\x75\xac\x20\x23\x8b\x94\x93\xd8\x19\x35\xe4\x7a\x47\xf1\x9e\xb2\x09\x58\x51\x96\x4b\xef\x5c\xdb\xc1\x2d\xd5\x3a\x87\x6f\xfc\x81\x9e\x7a\x9b\xe6\xf2\x35\x65\xb9\xb4\xd3\xcd\x5d\x84\x8a\x8c\x75\x12\xad\xb3\xc2\x39\x32\xf5\xd1\x2c\xd4\xd8\x59\x68\x01\xf3\x01\x4d\x86\x8e\xe4\x42\x61\xfc\x0b\xca\xb7\x56\x2e\xe9\xa5\xc8\x26\x6a\xda\x42\xb0\x48\x53\xf8\xde\xda\xa7\x41\xeb\xb9\x29\x26\xaa\xc0\x73\xfb\xce\xe8\x0a\x13\x05\xc5\x77\xe8\xab\xe9\x21\x24\x4c\x61\x51\xa3\xf1\x8b\xa9\x48\xf6\x11\x19\x15\x00\xa0\xcf\xec\x50\x56\x85\xe6\xb5\xf6\x34\xa7\xb7\xd5\x27\x7c\xfd\xd5\xc3\x8b\xd3\xf3\xff\xed\x52\x0a\x7d\x25\x5a\x33\x59\xa1\xb9\x67\xdb\x55\x17\xd2\xd1\x35\x87\x82\x9f\x84\x84\xe7\x2c\x86\x84\x0b\xd0\x4e\x0a\x19\x0a\xca\xe3\xd0\xa7\xa3\xd0\xcf\x36\x9d\x4b\xc2\x85\x39\x45\x9d\x7b\x3a\x4c\x36\x1e\x4c\x3c\x7a\xbe\x14\xa8\x05\x58\x1f\xc8\x2a\xa4\x2c\xcb\x55\x11\xe7\x04\x89\x29\x77\x20\x98\x93\x34\x47\x43\xdc\x2b\x0d\x11\x82\xc2\x68\xca\x99\x57\xb8\x70\x60\x3e\x98\xf1\x58\xa7\xf2\x1a\x49\x3d\xcb\x59\x10\x4d\xb5\x91\x0e\x9d\x98\x5f\xd0\x24\xe9\xf5\xcf\x1c\x7f\x14\xfa\x2a\xde\x25\x58\xfd\x98\xbf\x94\x64\x75\x9a\x4f\x12\x2d\x24\x10\x68\x57\x07\xcb\x84\x0b\x3a\x79\xa7\xa5\x80\xdf\x61\x82\xaa\xf4\xd4\x8f\xb9\x48\xbb\x21\x60\x1d\x2f\xc9\xce\xbd\x43\x4d\x7a\x63\x69\x96\x74\xc2\xc5\x8c\x28\x85\xf1\x47\xa5\x7d\xb9\x4b\xa1\x69\x77\xa1\x6f\x9c\xb8\x36\x51\x86\x15\x9d\xd1\x78\xae\xb2\x5c\x39\x23\x08\xfd\x98\xce\x8b\xa8\x5b\x1b\xd6\x73\x66\x92\xb3\x48\x51\xce\x40\x23\xfe\x2a\x29\x9b\xfc\x7c\xd3\xd3\x47\x7c\x6b\x0a\x73\xa3\x52\x3b\xd4\xc9\xf8\x76\x91\x61\x1f\x96\x6b\xb6\x4e\x2e\x11\xa4\x12\x34\x52\xce\xd9\x7a\x76\x4e\x04\x8c\x17\x97\x31\x0c\x2b\xf2\x3d\x1a\xd7\x11\xcb\x5f\x91\x87\x62\x1e\xe5\x33\x64\xca\x9b\xa0\x7a\x99\xa2\x1e\xfe\xb8\xb8\x8c\x35\xd2\x59\x03\x67\x75\xdc\xf8\x1c\x13\x89\x30\x84\x32\x8d\x6b\x49\xd8\xe4\x07\x79\x45\x19\xca\xf5\x2e\xfa\x4d\x1c\x86\xf7\xfa\x8a\xb1\x0d\x6b\xbd\xe3\x16\x9a\x9c\xc1\x50\xe3\xae\xd1\x6e\xf0\x5f\x39\xb2\x08\x5f\x13\x15\x4d\x51\xf4\xb4\x2c\xc7\x05\xf5\x16\x2e\xcf\x22\x1e\xa3\x84\x21\xc8\x99\xde\xe2\xc7\x62\xa2\xd7\x82\xab\x0e\x4f\x1f\xe7\xd0\x28\xb1\x57\x3f\xd2\x16\xbc\x2e\x20\xf0\x41\xdd\xd0\x7f\x6b\x2d\x38\xb5\x23\x68\x50\xf2\x28\x63\x28\xfe\x71\xfb\xfa\xaa\x05\xd5\xc4\xaf\x7f\xfd\xfe\x3b\xb0\x3c\x4d\xcf\x8e\xb6\x50\x24\x59\x86\x2c\xb6\x85\xc6\xba\x52\x1b\xe7\x34\x8d\x75\xe2\xea\x2d\x3b\xa7\xa4\x35\x6a\x14\x1c\x98\xcf\xce\x91\xd4\xd6\xad\x0a\x37\x6a\x30\x28\x07\x5d\x33\xd0\x04\x74\xb9\x11\x80\x53\x4f\x3b\xce\x46\x4e\x05\x60\x23\xb7\x38\x5b\x75\x1b\xd4\x3f\x9a\x50\xa5\x53\x04\xeb\xd1\x7a\x79\xd5\x2f\x6c\xb7\xc8\xfc\xda\x76\xde\xe5\x58\xd3\x0d\xa6\x01\xb8\x5f\xb5\x0b\x01\xb7\xe2\xa0\x8b\xfb\x19\x55\x28\x64\x00\xef\xdd\xe7\x4b\xf7\x18\xdc\x95\xfb\xa1\x06\x40\x14\x09\x5a\x6e\x25\xd6\xa9\x21\x80\xf7\x1f\x5a\x9b\xca\x85\x2e\x02\x6f\xb8\x50\x3f\x2e\x02\x68\x64\xc0\xad\x90\x17\x54\xa0\x71\xe2\x00\x5c\x22\xa3\x16\xa0\x54\x44\x28\x4d\x20\x00\xb7\xb5\x54\xcb\x14\x01\xe4\x2c\xc6\x84\x32\x8c\x9b\x30\xf5\x98\xbd\x15\x28\xe2\x39\x53\x01\x9c\x54\xba\xad\xd6\x13\x9a\x5a\x05\x35\xb5\xd0\x0d\xaa\xbd\x9c\xd1\x07\x46\x18\x37\x5f\x3b\x82\x91\x3e\xa8\x0b\xa2\x5a\x08\xe0\xc3\xe9\x89\xf9\xf5\x3d\xc5\x2f\x6f\xde\xdc\x98\xb0\xd1\xeb\x7b\x32\x4b\xa9\xea\xb9\xb7\x6e\xdf\xfb\xc4\x29\xeb\xb9\xe0\xee\x8e\x5a\xad\x5c\xd2\x33\x99\x6e\x87\x40\x4e\x8c\xe3\x7c\xe2\x6b\x0b\xfb\xee\x6e\xe8\xc0\x37\x60\x30\x6a\x49\xb0\xc5\x6e\x93\x9e\x66\x5a\x87\x18\xf7\xda\x7c\xae\xdf\xae\xef\xee\x9c\x25\x74\x92\x0b\xec\x75\x25\x41\xa2\x53\x43\x00\x2e\x12\xd9\x36\x15\x43\x9d\x32\x3a\xcb\x67\x01\x9c\x78\xdf\x76\x57\xed\xd5\x63\xa3\xb1\x37\x05\xef\xd7\x02\x8e\xfe\xd9\xbb\x32\x65\x0a\x45\x84\x99\xe2\x42\x7a\x42\x87\x5d\xa9\xbc\x5c\x62\xcf\x4a\x0c\xc3\xd1\x06\xdd\x55\xfb\x32\x16\xda\x6b\x1d\x49\x4d\xbd\x96\xca\xd9\x13\x24\x91\x19\x67\x12\x8d\x28\xe5\xc7\x3e\x61\x62\xce\x70\x87\x2c\x25\x99\x43\xa4\xe9\xd0\xd0\xa9\xa5\xe7\xea\x8b\x81\x55\xae\xb9\xac\xb8\xfd\x2e\x9c\x9a\x22\xdb\x23\xb1\xfe\xd1\x04\xd6\x50\x9e\x0e\x35\x9b\x6c\xb4\xfc\x99\xeb\x66\x15\x7b\x60\x08\x0d\x54\x6f\x46\xb2\x5e\x55\x0d\xcc\x49\xba\x8b\x58\x4d\x23\xbb\x81\xc0\x58\xd7\x3a\x88\x05\xda\x33\xea\xe5\x55\xd7\x16\xb7\x60\xbf\xc2\x45\x03\xf9\x15\x2e\x0e\xc6\x6d\x20\xee\xc7\xaa\x87\xc5\x76\xc8\xdc\xf4\x6b\x84\xc8\x43\x10\xd6\x75\xab\x11\x6c\x37\xfc\xaa\x6b\x8a\xeb\xa5\x0d\x66\x6a\xe6\x01\x53\x89\x3b\x0e\x26\xe2\x4c\xf2\x14\xbd\x94\x4f\x7a\xce\xe6\x7b\x8f\xbd\xf2\x38\x5d\xdb\x84\x46\xfc\xaa\x44\xd9\x18\xd2\x50\x4d\x79\xdc\x09\xfd\xfa\x86\x14\xd4\x2a\x4f\x69\xb2\xdd\x26\x73\xd3\x06\x6e\x57\x61\x38\x1c\x5a\x13\x6e\xa4\xc8\x6d\x36\xda\x86\x5c\xa7\x48\x18\x42\x6f\xc7\xe2\x70\x68\x53\x68\x1f\xbe\x03\x37\x46\x19\xb9\x50\x24\xd5\xae\xaa\xbb\x5a\xe8\xca\xa7\x2b\x4a\x33\xd8\x99\x6f\x32\x81\x4a\x2d\xea\x2a\xd9\x97\x71\x7e\xbe\x79\x73\x5d\xd4\xc5\x34\x59\xf4\xcc\x67\x46\x84\xc4\x02\xf3\xd8\x54\x87\xc7\xf0\x62\x77\xa2\xb3\xb7\xae\x3a\xe3\x6d\xa7\x60\xb6\x56\x73\x0c\x78\x36\xac\x8a\x01\xf8\xfa\xeb\x22\xbc\xd4\x3c\xa1\x01\xb1\xed\x9c\xea\x97\x1a\xdb\x0f\x33\xaa\xe8\xb0\xeb\x1f\x43\x67\xb9\xce\xac\x7f\x0c\xa7\x1b\xbc\x61\xb5\x3f\xed\x46\x7c\x96\xe5\x0a\xe3\x4d\x46\xda\xb8\xc6\xef\xd3\x52\x71\x32\xad\x30\xeb\x99\x4e\x46\x8f\x1c\xc3\xb8\xbf\x3d\x90\xa7\xa8\x20\x7e\x82\x89\x9e\x42\x00\x83\xd3\xcd\x51\x40\x9f\x1a\x79\xdf\x35\xc9\x0f\x10\xc2\x78\xd3\x7c\xbf\xdc\xc2\xe0\x14\xfe\xa7\x12\xe7\xb1\xd4\x47\x7b\xa8\xef\x21\x5c\x40\x9d\x6c\x38\xcc\xb6\x2d\x1f\x35\x47\x7a\xbd\xde\x0b\xee\x34\xf2\xb4\x3f\x0b\x3a\x2e\x5b\x6b\xb6\x89\x6a\xa7\x6a\x5d\xd4\x75\xb7\xa8\x04\xff\x8c\x2e\x51\xa8\x70\x96\xa5\x44\x61\x41\xb3\x4b\xb2\x6a\x10\xa4\x64\x8c\x29\x98\x4e\x52\x09\x66\xea\x5a\xa7\x7a\x36\x91\x4a\x93\x22\x12\x78\x12\x84\xbe\x41\xa8\x11\x90\x98\x62\xa4\x6c\x93\xa1\x41\xa0\x6a\xc0\x58\x10\x8c\x2f\x59\x8c\x0f\xed\x0e\x23\xcf\x8c\x81\x15\xdd\xac\x1e\x55\x68\xde\x13\x63\x7c\xe8\x03\x65\xb0\x96\xbd\x6a\xfd\x50\x4b\xe6\xf9\x12\x34\xf0\xde\xae\x09\xac\x42\xdf\x32\xa9\x37\x4a\xac\x4c\xb5\x99\x4c\x60\x73\x13\x65\xbb\xe4\xf9\xb2\x12\xe2\x7d\x63\x2b\x1f\xbc\x72\x41\xf3\xc8\x04\x96\x3d\x95\x52\xff\xa3\xa3\xa2\xbf\xd2\xe8\xad\xec\xbd\xf1\x95\x54\x3f\xf7\xca\xb7\x16\xbb\x7b\xe3\x6b\xec\xe3\xaf\x7c\x85\x7a\xcc\x9d\x66\x4f\x79\x5c\x7a\xe5\x1f\x5f\x1f\xaf\x0f\xaa\x5d\x1e\x6f\xaf\xc2\x7c\x1f\x62\x4c\x48\x9e\x2a\x50\xdc\x3c\x88\xcf\xb8\x54\x20\x30\x42\xa6\x0a\x97\x2d\x5e\xca\xef\x29\x8b\xf9\xfd\x6e\x09\x1a\xf6\x00\xc3\x96\x58\x45\xdc\x80\x01\x6c\x89\xfa\x8f\xae\xfd\xd6\x8e\xa3\x77\xf9\x65\x0a\xc0\xc3\xa2\xb1\x79\xeb\x90\xb5\x58\xfc\xd2\x4c\xd4\x22\xf1\xc1\x0f\x24\x1b\x1e\x47\x2c\xb1\xcd\x4f\x23\xfb\x9f\x23\xba\x4f\x11\x33\x94\x92\x4c\xcc\x33\xc4\x6b\x3b\xdc\xf1\x04\xd1\x7d\x33\x41\x22\x39\x33\xaf\x25\x66\xf4\x18\x5c\xbb\x73\x8d\x7b\x63\xb3\xc0\x23\x70\x4d\x5f\x46\xa3\x9e\xeb\xc1\x63\x30\x13\x2a\xa4\xba\x41\x34\x42\xff\xa4\x3f\x40\x22\x3e\x4a\xf0\x94\x54\x14\xae\xc8\x4e\x02\xad\xe6\x79\xf7\xc1\xa6\x75\x9c\x36\x11\x5b\x0b\x3a\xf0\xb1\xa6\xf9\x50\x63\xe8\x35\x5e\x6b\x5e\xd6\xcd\xb1\x42\xaa\xde\x1c\x2a\xbc\x2f\xf8\xee\x50\xbd\x39\x58\xca\x85\x99\xc1\xa6\x07\x86\x16\xa8\xb5\xa9\x43\x20\x8b\xea\xe1\x00\x48\x63\x2f\x87\x00\xae\xcd\xa3\x93\xe8\x63\x1d\xef\x0e\xa0\x50\x5a\xc7\x41\x04\x2a\xfb\x58\x3f\xac\x3c\x29\x9f\x5b\x8b\xf9\x02\x0d\x5c\x6b\x2d\xfb\xfb\xb7\x95\x1b\x1d\xdc\xbd\x7d\x72\x01\xa0\x15\xb7\xf7\xe2\x68\x1b\x93\x7f\x5a\x47\xd4\x1c\xc0\x5f\xb2\x1f\x5a\x98\xce\x01\x6d\xbf\xbf\xdb\xa1\x8f\x6d\x87\x5a\x6f\xfa\x53\xba\xa1\x96\xf5\xe7\x37\x43\xf5\x0d\xde\x34\x60\xe2\x77\x24\x85\x21\x34\x3b\x32\xe5\xd5\x68\x4b\xc3\xae\xfc\x1d\xdc\x51\x2d\xd2\x44\x50\xb1\x2c\x33\xc7\xfe\xe6\xa3\xb5\xe7\x3a\x6a\xf1\xdf\x86\x53\x2e\xd5\x01\xcd\x4e\x93\x76\xea\xe8\x76\x66\x3f\x66\xf1\x48\x54\x21\x9a\x89\xfd\x78\xeb\x18\x5a\xc7\x35\x93\xfa\xa6\x29\x15\x99\x65\x07\xf4\x74\x49\x97\x86\x9e\x7b\x04\x89\x66\xd7\x76\x27\xf8\x1f\xd1\xb4\xed\x54\x3f\x7f\xb7\x6c\xff\xab\x2d\xdb\x27\x35\x0f\xcb\x3a\xe1\x51\xad\xc3\xa2\xd8\xfd\xbb\x73\xf8\xe7\x74\x0e\xcb\xca\xd2\x2f\xfe\x89\xd4\xb7\xff\x98\xfe\x9f\x00\x00\x00\xff\xff\x4e\x3b\xdf\x43\x83\x2f\x00\x00") func webfilesResourceHtmlBytes() ([]byte, error) { return bindataRead( @@ -316,7 +325,7 @@ func webfilesResourceHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/resource.html", size: 10741, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/resource.html", size: 12163, mode: os.FileMode(416), modTime: time.Unix(1781122689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -336,7 +345,7 @@ func webfilesSloopCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/sloop.css", size: 3310, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/sloop.css", size: 3310, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -356,7 +365,7 @@ func webfilesSloop_uiJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/sloop_ui.js", size: 21534, mode: os.FileMode(420), modTime: time.Unix(1659992879, 0)} + info := bindataFileInfo{name: "webfiles/sloop_ui.js", size: 21534, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -433,13 +442,11 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// +// data/ +// foo.txt +// img/ +// a.png +// b.png // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error diff --git a/pkg/sloop/webserver/resourcehandler.go b/pkg/sloop/webserver/resourcehandler.go index c576b3b..f25d91b 100644 --- a/pkg/sloop/webserver/resourcehandler.go +++ b/pkg/sloop/webserver/resourcehandler.go @@ -34,6 +34,7 @@ type resourceData struct { Links []ComputedLink EventsUrl string PayloadUrl string + DescribeUrl string PlusMinusTime time.Duration } @@ -90,6 +91,9 @@ func resourceHandler(resLinks []ResourceLinkTemplate, currentContext string) htt dataParams = fmt.Sprintf("?query=%v&namespace=%v&start_time=%v&end_time=%v&kind=%v&name=%v", "GetResPayload", d.Namespace, queryStart, queryEnd, d.Kind, d.Name) d.PayloadUrl = path.Join("/", currentContext, "data"+dataParams) + dataParams = fmt.Sprintf("?query=%v&namespace=%v&start_time=%v&end_time=%v&kind=%v&name=%v", "GetResDescribe", d.Namespace, queryStart, queryEnd, d.Kind, d.Name) + d.DescribeUrl = path.Join("/", currentContext, "data"+dataParams) + err = resourceTemplate.Execute(writer, d) if err != nil { logWebError(err, "Template.ExecuteTemplate failed", request, writer) diff --git a/pkg/sloop/webserver/webfiles/resource.css b/pkg/sloop/webserver/webfiles/resource.css index f08cd64..cb69e4c 100644 --- a/pkg/sloop/webserver/webfiles/resource.css +++ b/pkg/sloop/webserver/webfiles/resource.css @@ -43,3 +43,13 @@ html, body { color: white; cursor:pointer; } + +#describe_output { + font-family: Menlo, Consolas, monospace; + font-size: 12px; + background-color: whitesmoke; + border: 1px solid lightgrey; + padding: 8px; + overflow: auto; + max-height: 600px; +} diff --git a/pkg/sloop/webserver/webfiles/resource.html b/pkg/sloop/webserver/webfiles/resource.html index 772804d..ed342af 100644 --- a/pkg/sloop/webserver/webfiles/resource.html +++ b/pkg/sloop/webserver/webfiles/resource.html @@ -170,6 +170,46 @@

Viewing range {{.ClickTime}} +/- {{.PlusMinusTime}}

}); +
+

Describe

+

No payloads found for this period

+ +
+ +

Events

From 507dfc1fc520ef03adb52ec4457fed5bfa629c00 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:28:18 +0000 Subject: [PATCH 04/10] fix(ui): anchor time window to end of recorded data instead of now Return the effective query window in view_options and use it for the timeline axis and end-time display. Default to an empty end_time so the server anchors to the newest data (the backup time when browsing a restore); replace the Now button with Latest. --- pkg/sloop/queries/queryd3heatmap.go | 2 +- pkg/sloop/queries/queryd3heatmap_test.go | 8 +++- pkg/sloop/queries/types.go | 6 +++ pkg/sloop/webserver/bindata.go | 12 ++--- pkg/sloop/webserver/webfiles/filter.js | 10 ++-- pkg/sloop/webserver/webfiles/index.html | 2 +- pkg/sloop/webserver/webfiles/sloop_ui.js | 58 +++++++++++++++--------- 7 files changed, 62 insertions(+), 36 deletions(-) diff --git a/pkg/sloop/queries/queryd3heatmap.go b/pkg/sloop/queries/queryd3heatmap.go index 662599e..919088d 100644 --- a/pkg/sloop/queries/queryd3heatmap.go +++ b/pkg/sloop/queries/queryd3heatmap.go @@ -94,7 +94,7 @@ func EventHeatMap3Query(params url.Values, t typed.Tables, queryStartTime time.T sortParam := params.Get(SortParam) outputRoot := TimelineRoot{ Rows: outputRows, - ViewOpt: ViewOptions{Sort: sortParam}, + ViewOpt: ViewOptions{Sort: sortParam, QueryStart: queryStartTime.Unix(), QueryEnd: queryEndTime.Unix()}, } bytes, err := json.MarshalIndent(outputRoot, "", " ") diff --git a/pkg/sloop/queries/queryd3heatmap_test.go b/pkg/sloop/queries/queryd3heatmap_test.go index 9ae37b4..62c877b 100644 --- a/pkg/sloop/queries/queryd3heatmap_test.go +++ b/pkg/sloop/queries/queryd3heatmap_test.go @@ -122,7 +122,9 @@ func Test_EventHeatMap3_SimpleTestWithOneDeployment(t *testing.T) { assert.Nil(t, err) expectedJson := `{ "view_options": { - "sort": "" + "sort": "", + "query_start": 1551398400, + "query_end": 1551402000 }, "rows": [ { @@ -155,7 +157,9 @@ func Test_EventHeatMap3_OneDeploymentAnd3Events(t *testing.T) { assert.Nil(t, err) expectedJson := `{ "view_options": { - "sort": "" + "sort": "", + "query_start": 1551398400, + "query_end": 1551402000 }, "rows": [ { diff --git a/pkg/sloop/queries/types.go b/pkg/sloop/queries/types.go index a073a63..94d11e1 100644 --- a/pkg/sloop/queries/types.go +++ b/pkg/sloop/queries/types.go @@ -26,6 +26,12 @@ type TimelineRow struct { type ViewOptions struct { Sort string `json:"sort"` + // The effective query window in unix seconds, after computeTimeRange clamped the + // requested range to the data available in the store. The UI uses this for the + // timeline axis and to display the real end time (which differs from the requested + // one when viewing restored/old data). + QueryStart int64 `json:"query_start"` + QueryEnd int64 `json:"query_end"` } type Overlay struct { diff --git a/pkg/sloop/webserver/bindata.go b/pkg/sloop/webserver/bindata.go index 75eb4ba..0792f99 100644 --- a/pkg/sloop/webserver/bindata.go +++ b/pkg/sloop/webserver/bindata.go @@ -250,7 +250,7 @@ func webfilesFaviconIco() (*asset, error) { return a, nil } -var _webfilesFilterJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x58\x6d\x6f\xdc\xc6\x11\xfe\xae\x5f\x31\x61\x83\x13\x99\xa3\x48\xb9\x41\x3f\xd4\x2a\x1b\x38\x92\xdc\x1e\xa2\x44\xb1\xcf\x36\x0a\x08\x4a\xb1\x26\x87\xc7\x8d\xf6\x76\x99\xdd\xa5\xce\x87\xc0\xff\xbd\x98\x5d\xbe\x9f\xa4\xd8\x35\xda\x03\x24\x9e\x96\xb3\xcf\xcc\x3e\xf3\xba\x4a\xbf\x39\x82\x6f\xe0\x5c\xd5\x7b\xcd\x37\x95\x85\x30\x8f\xe0\xcf\xa7\xcf\xfe\x1a\x83\x61\x02\x4d\xa9\x74\x8e\x49\xae\xb6\x31\x70\x99\x27\x24\xfb\x42\x08\x70\xb2\x06\x34\x1a\xd4\xf7\x58\xb8\xf5\xf5\xcf\x17\xff\x3a\xb9\xe2\x39\x4a\x83\x27\xab\x02\xa5\xe5\x25\x47\xfd\x1c\xbe\x5f\x5f\x9c\x7c\x7b\x72\x2e\x58\x63\x90\x04\x5f\x2a\x0d\x65\x23\x04\x08\x2f\x0c\x16\x3f\xd8\x18\x0c\x22\x5c\xad\xce\x2f\x7f\x5a\x5f\x26\xf6\x83\x85\x92\x0b\x04\x2e\xc1\x56\x08\x1a\x6b\x05\x5a\x29\x0b\x4a\x43\x65\x6d\x6d\x9e\xa7\xa9\xaa\x51\x1a\xd5\x90\x81\x4a\x6f\xd2\x16\xcd\xa4\x33\x7d\xe9\xd1\x51\xd9\xc8\xdc\x72\x25\x61\x83\xf6\xad\x16\xef\x98\x36\x61\x04\xbf\x1f\x01\x00\xdc\x33\x4d\x3f\x06\x32\xf8\xfd\xe3\x59\xbf\x54\x33\x6d\x69\x6d\xc7\x65\xa1\x76\x89\x50\x39\x23\x84\xa4\xd2\x58\x26\x1a\x6b\xc1\x72\x0c\xd3\x9b\xef\x16\xb7\xcb\xf0\xe6\x97\x6c\x71\xbb\x8c\xb2\xf0\xe6\x97\xc5\xed\x37\x51\xba\xe1\x31\x74\x2a\xc3\x6d\x7c\x87\xfb\xf8\x9e\x89\x06\x3b\x95\xad\x0e\x73\x73\x87\xfb\x5b\xc8\xc0\xbd\xf4\xaa\x3f\x46\xfe\xa9\xd1\x36\x5a\x3a\xa9\xb3\xa3\x8f\x07\x27\xf8\x99\x69\xb6\x0d\x6b\xfa\x8d\x16\x75\x0c\x05\x96\xac\x11\xd6\xab\x19\x0e\xd6\x68\xd1\x0b\x41\x36\x91\xf2\x7a\x78\x19\x3e\x78\x42\x2e\x0b\xfc\x70\x5d\x0e\x2a\x22\xf8\x3b\x9c\x3c\x83\xc5\x02\x0a\xcc\x55\x81\x6f\x5f\xaf\xce\xd5\xb6\x56\x12\xa5\x0d\xc7\xb4\xde\xf4\x5b\x6e\x23\xf8\x2a\x83\x20\x80\x68\x38\xf6\x81\x41\x9f\x8c\xd5\xf2\x33\x66\x67\x0c\xe6\x58\x4a\x53\xb8\x52\xea\x0e\x9a\xda\x45\x4d\xa3\x05\x0c\xda\x02\xf7\x35\x80\xc6\x70\xb9\x81\xa0\xe5\xe2\x1d\x71\x11\x00\x2f\x41\x2a\x0b\xa5\x6a\x64\x41\x30\xb6\x42\x09\x06\xad\xc3\x29\x95\xde\x82\xaa\x1d\xff\x3b\x6e\x2b\xe0\x05\x04\x28\x70\x8b\xd2\xae\x8a\x00\xac\x02\x5b\x31\xeb\xfd\x38\xb8\xca\xa0\xbd\xd0\xaa\x2e\xd4\x4e\x7a\x1e\x63\xe8\x37\xf5\x1e\x73\xfa\x29\xb9\x0c\x6a\xff\xc7\xaa\xfc\x91\x1b\xb2\x71\x1a\xa1\xa2\x41\xc8\x0e\xdd\x3f\x05\x8a\x86\x00\x36\x28\x30\xb7\xc4\xb1\xca\x1b\x52\x9a\x6c\xd0\x5e\x7a\xfd\xdf\xef\x57\x45\xd8\xdb\x32\xda\xe4\xce\x0f\x19\x94\x4c\x50\xee\x00\xd0\xd9\x43\x7a\xc3\x21\x83\xd3\x33\x0e\x7f\x6b\x81\x13\xcf\x87\x49\x04\xca\x8d\xad\xce\x80\x2f\x97\x23\x3f\xf3\x32\x9c\xca\xdd\xf0\xdb\xa4\x3d\x44\x1b\xf0\x30\x4e\x07\xfa\x1c\x6e\xf0\x2b\x48\x16\x59\xdd\x85\x6c\xf7\xe9\x6c\xa5\x37\xfd\x8b\x8f\xa3\x28\xe1\x25\x84\x5f\x79\xa9\xc5\xe2\x49\x86\x47\xda\x59\x5d\xa3\x2c\x42\x90\xb8\x83\x6b\x67\x49\x78\xef\x5d\xd4\x3e\x1c\x35\xb1\xd3\x1a\x45\x87\x31\xe9\x63\xe0\x7f\x1c\x8b\x54\x30\x81\xcb\xba\xb1\x9f\x19\x8f\x6f\xf0\x83\xfd\x83\x58\xfc\xb2\xa8\xe3\xb2\xfe\x9c\x98\x23\xf1\x2e\x2c\x5a\x73\xff\x8f\x5c\x6a\x56\x70\x05\x79\x85\xf9\x1d\x16\xed\x61\x89\x3b\xdd\x20\x30\x59\x40\xce\x84\xf0\xa4\x77\x14\xee\x68\x7b\xbb\x61\x42\xec\x6b\x82\xfa\x44\x66\x05\xda\xcf\x64\xf6\x31\x3a\x7d\xb9\x4f\xba\x13\x8c\xb3\xe4\xb7\x06\xf5\xfe\xbc\x62\x72\x83\xe1\xd3\xdb\xe7\x1d\x67\xe0\xfc\x1f\x68\x81\x81\xe0\xc6\x82\x2a\xfd\x1b\x03\xa5\x56\x5b\x8f\xfe\x56\x0b\x08\xdb\x06\xed\x4b\x64\x09\x0c\x7e\x35\x4a\x02\xd3\x9a\xed\x23\xc2\x58\xb9\xb4\x03\x5b\x29\x43\xdd\xdc\x2a\x28\xb4\xaa\x81\x8a\x62\x1f\xbb\xf8\x5b\xc3\xc4\x38\x82\x69\xe3\x0b\x59\x78\xba\xf7\xaa\x81\x92\xcb\x02\x58\xcb\xda\x96\xd9\xbc\x22\x5f\xf7\x71\xd0\xc7\x00\x79\x96\x5b\x72\x62\x57\x3a\x06\x2f\xd5\xaa\x6e\x04\xb3\xd8\xd5\xe4\x97\x5a\x6d\x5f\xd1\x39\xfe\xb0\x38\x77\xa7\xfd\xb2\xd4\x68\xe1\x3f\x23\x3b\xd2\x14\xd6\x96\x69\x62\xbf\xf4\x64\xfd\xda\x18\x0b\x4c\x76\xcd\xa8\x54\xda\xb1\xef\x8d\x71\x9e\xa1\x3f\xdf\xbe\xbe\x72\xfb\x5b\xbc\xff\xa6\xa6\x49\xb6\x45\x53\xb3\x1c\x69\x06\x2a\xbe\x4d\xc8\xab\x61\xcf\xc3\xd9\x4c\x26\xa1\xb4\x0a\x7b\xa6\x43\x8d\xa6\x11\x76\x5c\x5d\x3b\x53\x34\x6e\xd5\x3d\x86\xa7\xd1\x78\x10\x7a\xa0\xed\xf8\x88\x24\x94\xa4\x54\xfa\x92\xe5\x55\x38\x2a\xfe\xfd\x70\xa5\xd5\x6e\xde\x45\x00\xb8\x59\x0f\x7d\x23\xec\x9b\x0e\xc9\xce\x24\x9f\x20\x48\xab\x5d\x0c\xee\x57\x4b\xce\x80\x1a\x41\x74\x36\x57\x59\x42\x38\x16\x98\x9b\xf4\x68\xbf\x1a\x77\x2d\x18\xcd\x7f\xd3\xfe\x35\x07\xfc\x02\xc7\x8e\x9a\x64\xf4\x60\xde\x7f\xdd\x97\x8b\x28\xd1\xc8\x8a\x7d\xef\xd7\xb0\xaf\x60\x5f\x87\xc7\x7f\xea\x12\xec\x52\x16\x6f\xf8\x16\x8f\xa3\x44\xc9\xf0\xf8\xbd\x68\xf4\xf1\x68\xfa\xc5\x7b\x3b\x9b\x7a\xa1\x60\x16\x69\xc7\xbb\x36\x83\x1e\xcb\x86\xe3\x43\x0d\xa3\xc1\x15\x26\x63\x4e\x2f\xd4\x83\x8e\x95\x24\x56\xad\xad\xe6\x72\x13\x8e\xd8\x35\x68\x0c\x57\x72\x6d\x95\x66\x1b\x4c\x0c\xda\x95\xc5\xed\xa1\xd6\xf8\x41\x15\x9f\x04\x64\xd7\x07\x58\xe4\xa9\x0b\x66\x31\x8c\x12\xab\x56\xeb\xeb\xce\xae\x68\x18\xff\xe9\x67\xd2\x5b\x5e\x72\x61\x51\x9b\x17\xb2\x78\xed\x7c\xf5\xaa\x4d\xc3\xb0\x2d\x34\xd4\x1a\xdf\xb3\xfc\xae\xaf\x3c\x3f\x70\x39\xd4\xb0\x9f\xba\x2c\xed\xfc\x90\xa6\xf0\x03\x22\x75\x52\x6e\xe8\x7e\x65\xf6\x32\xf7\xd5\xa5\xbe\xdb\xa4\x46\x28\x55\xa7\x94\xe9\x1c\x4d\xea\x2a\x9a\x49\x36\xea\xa8\x2f\x48\x6a\x8b\x54\xe8\x6d\x85\x06\x41\x22\x16\x54\x6d\x2b\xee\x3b\x2a\x99\x81\xae\x70\xf3\xbc\x02\xcb\xee\xd0\xb8\x0e\x62\xad\x40\xb0\x7c\x8b\x1d\xcc\x85\xf2\x6d\x83\x51\x6f\x91\xd4\x56\xb8\x36\xb6\x7b\xfb\xe6\xfa\xe2\xfa\x39\xb8\x73\xf6\xb0\x27\x84\xcb\xc8\xd8\xa9\xd4\x0b\x61\x54\x0c\x3b\x6a\x0b\x7b\xc8\x95\x34\xbc\x40\x9a\x43\xb8\xe5\x4c\x88\x7d\x57\xf6\xa9\x5f\x10\x14\x75\x9f\x93\xa1\xfb\xcc\xaa\x67\xdf\x51\x0c\x30\xb2\x9c\xae\x79\x95\x12\x05\xea\x4e\xa9\xff\x34\xd2\x72\x41\x4a\x37\xdd\x58\xe6\xef\xb3\xc6\x3a\x5b\x3d\x5b\xb3\xb8\x81\x6c\x1e\x2a\x9b\xc7\x62\x2e\xea\xb4\xad\x4a\x68\x0c\x6a\x30\x55\x63\x7d\xcf\x24\x65\x4a\x14\xed\xbd\xd4\x8d\x29\x74\x0f\x06\xe6\x42\xcb\xaf\xc6\xfd\x84\xd3\xc6\x00\x34\x1c\x0a\x6e\x6a\xc1\xf6\xe4\x2f\x32\xc6\x2a\x90\x6a\xd7\xcf\xc9\x07\xb6\x66\x19\xc8\x46\x88\x79\xf2\x4a\xb5\x83\x0c\x1e\x0d\xe3\xd9\x34\x3d\x3e\xbb\x54\xbb\xc4\x34\xef\x8d\x97\x3c\x8d\xdd\x82\xbf\x3c\x9c\xfc\x65\x3c\x48\xa3\x30\x38\xd3\x8a\x03\x4a\xa7\x78\xa6\x60\x92\x8f\x73\xd5\xed\xf6\xa9\xa9\x89\x11\x3c\xc7\xf0\x34\x3e\x79\xd6\x69\xf7\xd3\x59\x9b\x4d\x74\xcc\x0e\x70\xb8\xc7\x05\xdd\xeb\x20\x86\xa0\x74\x89\x39\x5a\x39\x48\x48\x57\x78\x7d\x30\x28\x6d\x07\xc8\x03\x58\x7a\x1d\xc4\x6e\xbd\x85\x1d\xaf\x18\x9a\x02\xfe\x4d\x7e\x0b\xda\x9a\x1e\x1d\xf5\x2d\xd8\x8d\x43\x2e\xb8\xfc\x78\x1f\xf4\x8b\x83\x8d\x93\xa5\xa0\xdd\xec\x83\xe5\xaa\xbd\xf7\x3f\xf0\xbf\x8e\x9a\xd9\x8a\x76\x8e\xea\xe7\x30\x5b\x4e\x0e\xf3\xf8\x6c\x15\x38\xe1\xe9\xd1\x26\x4b\x97\xf7\x28\xed\x3f\x91\xd9\x1f\x59\x4d\x6b\x53\xab\x96\x41\x5a\x30\xcb\xbe\x73\x5b\xb2\x57\xbe\x2c\x2d\x3a\xca\xb3\x60\xd9\x7d\xed\x66\x12\x33\x25\xf9\x49\xd3\xfa\x01\x66\x4a\x54\xb7\x34\x2f\xa0\xf1\x93\xb6\xf5\x62\x4f\x99\x77\xc7\xdd\x08\xf0\x69\xe6\x91\x70\xcb\x52\x67\xde\x78\x69\x52\xec\xe1\xd0\xa1\x53\xf3\x48\xec\x31\xcb\xfc\x1d\x83\x59\xf6\xaa\x75\xec\x53\x40\xc1\xd2\x3d\x97\xc1\xa2\xe7\x2a\x0b\x96\xd2\x2c\x83\x87\xd0\x97\xc1\x82\x6c\xce\x82\x25\x3d\x96\xc1\x82\xc2\x3a\x0b\x96\xf4\x68\x21\x5c\x5c\x12\x44\xf7\x7d\x19\x2c\x50\x16\x2e\xdc\x49\x72\x9a\xce\xe3\x99\xa5\x37\x99\xe6\x96\xff\x04\x00\x00\xff\xff\xcc\x6c\xfa\x0a\xc9\x14\x00\x00") +var _webfilesFilterJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x58\x6d\x73\xdc\xb6\x11\xfe\xae\x5f\xb1\x61\x33\x27\xd2\x77\xe2\xd9\xcd\xa7\x5a\x65\x33\x8e\x25\xb7\x9a\x28\x51\x6c\xd9\x6e\x67\x34\x4a\x07\x26\x97\x47\x44\x38\x80\x01\x96\x3a\xdd\x24\xfe\xef\x9d\x05\xf8\x7a\x27\x29\x76\x3d\xed\xcd\x48\x3c\x81\x8b\xdd\xc5\xb3\xbb\xcf\x2e\xb4\x7c\x72\x00\x4f\xe0\xa5\xa9\xb7\x56\xae\x2a\x82\x38\x4f\xe0\xcf\x4f\x9f\xfd\x65\x01\x4e\x28\x74\xa5\xb1\x39\xa6\xb9\x59\x2f\x40\xea\x3c\x65\xd9\x17\x4a\x81\x97\x75\x60\xd1\xa1\xbd\xc5\xc2\xaf\x5f\xfe\x74\xf2\xaf\xa3\x73\x99\xa3\x76\x78\x74\x56\xa0\x26\x59\x4a\xb4\xcf\xe1\xbb\xcb\x93\xa3\x6f\x8e\x5e\x2a\xd1\x38\x64\xc1\x57\xc6\x42\xd9\x28\x05\x2a\x08\x03\xe1\x1d\x2d\xc0\x21\xc2\xf9\xd9\xcb\xd3\x1f\x2f\x4f\x53\xba\x23\x28\xa5\x42\x90\x1a\xa8\x42\xb0\x58\x1b\xb0\xc6\x10\x18\x0b\x15\x51\xed\x9e\x2f\x97\xa6\x46\xed\x4c\xc3\x0e\x1a\xbb\x5a\xb6\xda\xdc\x72\xc7\xde\xf2\xe0\xa0\x6c\x74\x4e\xd2\x68\x58\x21\xbd\xb3\xea\xbd\xb0\x2e\x4e\xe0\xb7\x03\x00\x80\x5b\x61\xf9\xc7\x41\x06\xbf\x7d\x3c\xee\x97\x6a\x61\x89\xd7\x36\x52\x17\x66\x93\x2a\x93\x0b\xd6\x90\x56\x16\xcb\xd4\x62\xad\x44\x8e\xf1\xf2\xea\xdb\xd9\xf5\x3c\xbe\xfa\x39\x9b\x5d\xcf\x93\x2c\xbe\xfa\x79\x76\xfd\x24\x59\xae\xe4\x02\x3a\x93\xf1\x7a\x71\x83\xdb\xc5\xad\x50\x0d\x76\x26\x5b\x1b\xee\xea\x06\xb7\xd7\x90\x81\x7f\x19\x4c\x7f\x4c\xc2\xd3\x22\x35\x56\x7b\xa9\xe3\x83\x8f\x7b\x27\xf8\x49\x58\xb1\x8e\x6b\xfe\x8d\x84\x76\x01\x05\x96\xa2\x51\x14\xcc\x0c\x07\x6b\xac\xea\x85\x20\x9b\x48\x05\x3b\xb2\x8c\xef\x3d\xa1\xd4\x05\xde\x5d\x94\x83\x89\x04\xfe\x06\x47\xcf\x60\x36\x83\x02\x73\x53\xe0\xbb\x37\x67\x2f\xcd\xba\x36\x1a\x35\xc5\x63\x58\xaf\xfa\x2d\xd7\x09\x7c\x95\x41\x14\x41\x32\x1c\x7b\xcf\xa1\x4f\xd6\xd5\xe2\x33\x46\x67\xac\xcc\xa3\xb4\x5c\xc2\xb9\x31\x37\xd0\xd4\x3e\x6b\x1a\xab\x60\xb0\x16\xf9\xaf\x11\x34\x4e\xea\x15\x44\x2d\x16\xef\x19\x8b\x08\x64\x09\xda\x10\x94\xa6\xd1\x05\xab\xa1\x0a\x35\x38\x24\xaf\xa7\x34\x76\x0d\xa6\xf6\xf8\x6f\x24\x55\x20\x0b\x88\x50\xe1\x1a\x35\x9d\x15\x11\x90\x01\xaa\x04\x85\x38\x0e\xa1\x72\x48\x27\xd6\xd4\x85\xd9\xe8\x80\xe3\x02\xfa\x4d\x7d\xc4\xbc\x7d\x2e\x2e\x87\x36\xfc\x71\x56\xfe\x20\x1d\xfb\x38\xcd\x50\xd5\x20\x64\xfb\xe1\x9f\x2a\x4a\x86\x04\x76\xa8\x30\x27\xc6\xd8\xe4\x0d\x1b\x4d\x57\x48\xa7\xc1\xfe\x77\xdb\xb3\x22\xee\x7d\x19\x6d\xf2\xe7\x87\x0c\x4a\xa1\xb8\x76\x00\xf8\xec\x31\xbf\x91\x90\xc1\xd3\x63\x09\x7f\x6d\x15\xa7\x01\x0f\x97\x2a\xd4\x2b\xaa\x8e\x41\xce\xe7\xa3\x38\xcb\x32\x9e\xca\x5d\xc9\xeb\xb4\x3d\x44\x9b\xf0\x30\x2e\x07\xfe\xec\x6f\x08\x2b\xc8\x1e\x91\xed\x52\xb6\xfb\x74\xbe\xf2\x9b\xfe\xc5\xc7\x51\x96\xc8\x12\xe2\xaf\x82\xd4\x6c\xf6\x28\xc2\x23\xeb\xa2\xae\x51\x17\x31\x68\xdc\xc0\x85\xf7\x24\xbe\x0d\x21\x6a\x1f\x1e\x9a\x85\xb7\x9a\x24\xfb\x39\x19\x72\xe0\x7f\x9c\x8b\x4c\x98\x20\x75\xdd\xd0\x67\xe6\xe3\x5b\xbc\xa3\x3f\xc8\xc5\x2f\xcb\x3a\xa9\xeb\xcf\xc9\x39\x16\xef\xd2\xa2\x75\xf7\xff\x88\xa5\x15\x85\x34\x90\x57\x98\xdf\x60\xd1\x1e\x96\xb1\xb3\x0d\x82\xd0\x05\xe4\x42\xa9\x00\x7a\x07\xe1\x86\xb7\xb7\x1b\x26\xc0\xbe\x61\x55\x9f\x88\xac\x42\xfa\x4c\x64\x1f\x82\x33\xd0\x7d\xda\x9d\x60\x5c\x25\xbf\x36\x68\xb7\x2f\x2b\xa1\x57\x18\x3f\xbe\x7d\xb7\xe3\x0c\x98\xff\x1d\x09\x04\x28\xe9\x08\x4c\x19\xde\x38\x28\xad\x59\x07\xed\xef\xac\x82\xb8\x6d\xd0\x81\x22\x4b\x10\xf0\x8b\x33\x1a\x84\xb5\x62\x9b\xb0\x8e\x33\x5f\x76\x40\x95\x71\xdc\xcd\xc9\x40\x61\x4d\x0d\x4c\x8a\x7d\xee\xe2\xaf\x8d\x50\xe3\x0c\xe6\x8d\x2f\x74\x11\xe0\xde\x9a\x06\x4a\xa9\x0b\x10\x2d\x6a\x6b\x41\x79\xc5\xb1\xee\xf3\xa0\xcf\x01\x8e\xac\x24\x0e\x62\x47\x1d\x43\x94\x6a\x53\x37\x4a\x10\x76\x9c\xfc\xca\x9a\xf5\x6b\x3e\xc7\x1f\x92\x73\x77\xda\x2f\x2b\x8d\x56\xfd\x67\x54\xc7\x72\x09\x97\x24\x2c\xa3\x5f\x06\xb0\x7e\x69\x1c\x81\xd0\x5d\x33\x2a\x8d\xf5\xe8\x07\x67\x7c\x64\xf8\xcf\x77\x6f\xce\xfd\xfe\x56\xdf\x7f\xc3\x69\x5a\xac\xd1\xd5\x22\x47\x9e\x81\x8a\x6f\x52\x8e\x6a\xdc\xe3\x70\xbc\x23\x93\x72\x59\xc5\x3d\xd2\xb1\x45\xd7\x28\x1a\xb3\x6b\xe7\x8a\xc5\xb5\xb9\xc5\xf8\x69\x32\x1e\x84\xee\x69\x3b\x21\x23\x59\x4b\x5a\x1a\x7b\x2a\xf2\x2a\x1e\x91\x7f\x3f\x5c\x59\xb3\xd9\xed\x22\x00\xd2\x5d\x0e\x7d\x23\xee\x9b\x0e\xcb\xee\x48\x3e\x02\x90\x35\x9b\x05\xf8\x5f\x2d\x38\x83\xd6\x04\x92\xe3\x5d\x93\x25\xc4\x63\x81\x5d\x97\x1e\xec\x57\xe3\xae\x05\xa3\xf9\x6f\xda\xbf\x76\x15\x7e\x41\x60\x47\x4d\x32\xb9\xb7\xee\xbf\xee\xe9\x22\x49\x2d\x8a\x62\xdb\xc7\x35\xee\x19\xec\xeb\xf8\xf0\x4f\x5d\x81\x9d\xea\xe2\xad\x5c\xe3\x61\x92\x1a\x1d\x1f\x7e\x50\x8d\x3d\x1c\x4d\xbf\x78\x4b\x3b\x53\x2f\x14\x82\x90\x77\xbc\x6f\x2b\xe8\xa1\x6a\x38\xdc\xb7\x30\x1a\x5c\x61\x32\xe6\xf4\x42\xbd\xd2\xb1\x91\x94\xcc\x25\x59\xa9\x57\xf1\x08\x5d\x87\xce\x49\xa3\x2f\xc9\x58\xb1\xc2\xd4\x21\x9d\x11\xae\xf7\xad\x2e\xee\x35\x91\x0c\xe3\x3a\xff\x4c\x7a\xc1\x2b\xa9\x08\xad\x7b\xa1\x8b\x37\x1e\xdb\xd7\x6d\xd9\xc4\x2d\x31\x70\x2b\xfb\x20\xf2\x9b\x9e\x29\xbe\x97\x7a\xe0\x9c\x1f\xbb\xaa\xea\x70\x5b\x2e\xe1\x7b\x44\xee\x7c\xd2\xf1\x7d\xc8\x6d\x75\x1e\xd8\xa0\xbe\x59\x2d\x9d\x32\xa6\x5e\x72\x65\x4a\x74\x4b\xcf\x40\x2e\x5d\x99\x83\x9e\x40\xcc\x1a\x99\x98\xa9\x42\x87\xa0\x11\x0b\x66\xc7\x4a\x86\x0e\xc8\x6e\xa0\x27\x5a\x99\x57\x40\xe2\x06\x9d\x67\x7c\x22\x85\x40\x72\x8d\x9d\x9a\x13\x13\x68\x5e\x70\x2f\xd0\xdc\x06\xa4\x75\xd4\xbd\x7d\x7b\x71\x72\xf1\x1c\xfc\x39\x7b\xb5\x47\xac\x57\xb0\xb3\x53\xa9\x17\xca\x99\x05\x6c\x98\xc6\xb7\x90\x1b\xed\x64\x81\x3c\x37\x48\x92\x42\xa9\x6d\x47\xd3\xcc\xef\xac\x8a\xbb\xc5\xd1\xd0\x2d\x76\xd8\xae\xef\x00\x0e\x04\x7b\xce\xd7\xb2\xca\xa8\x02\x6d\x67\x34\x7c\x1a\x4d\x52\xb1\xd1\x55\x37\x46\x85\xfb\xa7\x23\xef\x6b\x40\x6b\x27\xce\x90\xed\xe6\xc8\xea\xa1\x1c\x49\x3a\x6b\xff\x64\x1f\xb5\x01\xbc\xab\x95\xcc\x25\x01\x83\xc0\x38\x72\x16\x31\x1e\x1a\x70\x5d\xd3\x96\xd7\xff\xcd\xeb\xe0\x02\xb0\xfe\x1e\x6d\x41\xe8\xbc\x32\xd6\xf9\xa5\x70\x2f\xeb\x34\x53\x90\x63\x25\xa6\x04\x8b\xb9\xb1\x05\x16\x9c\xe7\x02\x62\xbe\x3a\x73\xf5\xe8\xe2\xa2\xf4\xae\x4b\x0d\x5d\x4a\xb0\x15\xcb\x63\x40\xba\x32\x49\x0a\x17\xda\x07\xf8\xb6\x8f\x6c\xae\x1a\xc7\x63\x94\x9f\x18\xa5\x83\x48\x9b\x4d\x74\x1c\x5a\xef\x07\x6b\x36\x7e\xaa\x12\x4c\xc6\x64\x2c\x16\x1e\xaf\xa6\xe6\x2e\x2b\x5d\x1f\xec\xa6\x3e\x74\xcc\x42\xe8\xc8\xbb\x94\xf6\x03\xf8\x1e\xa8\x59\x06\x9a\xc1\xff\xfd\xf7\x7d\xc0\x33\xbe\x2e\xee\x0f\xe5\xe3\x90\x44\xd1\x68\xe6\x46\xe5\x70\x87\x5d\xb0\x97\x64\x52\x3c\x11\x84\xbb\x2e\x4c\x38\x60\x57\x7d\xbb\x3d\x25\x73\x76\x79\xd1\x91\x46\xea\x94\xcc\x31\x7e\xba\x38\x7a\xd6\x4d\xfc\x61\x90\x6b\x0b\x19\xb2\x41\xe1\x70\xe5\x8b\xba\xd7\xd1\x02\xa2\xd2\x73\xc2\x68\x65\x8f\x0b\x3c\x47\x87\x3c\x34\x96\x06\x95\x7b\x6a\xf9\x75\xb4\xf0\xeb\xad\xda\xf1\x8a\xe3\x81\xc1\xa7\x56\xd4\xd2\x7f\x72\xd0\x77\x6b\x3f\x39\xf9\xbc\x0e\x37\x81\xa8\x5f\x1c\x7c\x9c\x2c\x45\xed\xe6\x90\x8b\xe7\xed\xbf\x08\xee\xf9\xb7\x48\x2d\xa8\xe2\x9d\x23\xaa\x1d\xc6\xd0\xc9\x61\x1e\x1e\xc3\x22\x2f\x3c\x3d\xda\x64\xe9\xf4\x16\x35\xfd\x03\x05\xfd\x20\x6a\x5e\x9b\x7a\x35\x8f\x96\x9c\x7a\xdf\xfa\x2d\xd9\xeb\x90\xfe\xb3\x0e\xf2\x2c\x9a\x77\x5f\xbb\xf1\xc5\x4d\x41\x7e\xd4\xb5\x7e\xd6\x99\x02\xd5\x2d\xed\x72\xf7\xe2\x51\xdf\x7a\xb1\xc7\xdc\xbb\x91\x7e\x5a\xf8\x34\xf7\x58\xb8\x45\xa9\x73\x6f\xbc\x34\xe9\x33\xb0\x1f\xd0\xa9\x7b\x2c\xf6\x90\x67\xe1\x3a\x22\x48\xbc\x6e\x03\xfb\x98\xa2\x68\xee\x9f\xf3\x68\xd6\x63\x95\x45\x73\xed\xe6\xd1\x7d\xda\xe7\xd1\x8c\x7d\xce\xa2\x39\x3f\xe6\xd1\x8c\xd3\x3a\x8b\xe6\xfc\x68\x55\xf8\xbc\x64\x15\xdd\xf7\x79\x34\xeb\x98\x94\x25\xa7\xe5\x3c\x1e\x6f\x7a\x97\x79\xc4\xf9\x4f\x00\x00\x00\xff\xff\xe1\x47\x0e\xcc\xf4\x14\x00\x00") func webfilesFilterJsBytes() ([]byte, error) { return bindataRead( @@ -265,12 +265,12 @@ func webfilesFilterJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/filter.js", size: 5321, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} + info := bindataFileInfo{name: "webfiles/filter.js", size: 5364, mode: os.FileMode(416), modTime: time.Unix(1781201533, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _webfilesIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xed\x52\x1b\xb9\xd2\xfe\xcf\x55\xf4\xaa\xea\x2d\xa0\x96\x99\xc1\x36\x61\xb3\xc4\x9e\xda\x60\x48\x60\x43\xf2\xb2\x31\x24\x24\xa7\x4e\xa5\xe4\x51\xdb\x23\x2c\x4b\x13\x49\x63\xe3\xb8\xb8\xf7\x53\x92\x6c\x3c\x36\xe6\x23\xb5\xf1\x1f\x4b\x1a\xf5\xd3\x9f\x6a\x75\xab\xf9\x5b\x14\x6d\xb4\x55\x31\xd1\xbc\x9f\x5b\xd8\xca\xb6\xa1\xbe\x5b\xfb\x73\x07\x0c\x15\x68\x7a\x4a\x67\x18\x67\x6a\xb8\x03\x5c\x66\xf1\xc6\x6b\x21\xc0\x6f\x34\xa0\xd1\xa0\x1e\x21\x8b\x37\x3a\xe7\x47\x57\xd1\x19\xcf\x50\x1a\x8c\x4e\x19\x4a\xcb\x7b\x1c\xf5\x01\x1c\x76\x8e\xa2\x46\xd4\x16\xb4\x34\xb8\xf1\x46\x69\xe8\x95\x42\x80\x08\x3b\xc1\xe2\x8d\xdd\x01\x83\x08\x67\xa7\xed\xe3\x0f\x9d\xe3\xd8\xde\x58\xe8\x71\x81\xc0\x25\xd8\x1c\x41\x63\xa1\x40\x2b\x65\x41\x69\xc8\xad\x2d\xcc\x41\x92\xa8\x02\xa5\x51\xa5\x93\x4b\xe9\x7e\x32\x43\x33\xc9\x12\xb3\x28\x4a\x37\x9a\xbf\x1d\xfd\x7f\xfb\xe2\xcb\xf9\x31\xe4\x76\x28\xdc\x3c\x8a\x4c\x59\x14\x1a\x8d\x81\x13\x3b\x14\x97\x72\x20\xd5\x58\x5e\x50\xdd\x47\xbb\x03\x7f\x77\x2e\xa5\x46\xa3\xc4\x08\xd9\x27\xaa\x39\xed\x0a\x04\x0f\x64\xec\x44\x20\xd8\x49\x81\x2d\xe2\xa4\x4e\x32\x63\x48\xba\xd1\x4c\xfc\x87\x74\xa3\x99\x23\x65\xe9\x06\x00\x40\xd3\x64\x9a\x17\xb6\xba\xf9\x9a\x8e\x68\x58\x25\x61\x8f\xfb\x31\x95\x95\x43\x94\x36\x1e\x6b\x6e\x71\x8b\x34\xbb\xd4\x20\xe4\x1a\x7b\xad\xcd\x84\xc0\xef\x30\xe6\x92\xa9\x71\x2c\x54\x46\x2d\x57\x32\x2e\xa8\xcd\x25\x1d\x62\x6c\x0a\xc1\xed\xd6\x66\xb2\xb9\xfd\x9f\xda\x7f\xe1\x77\x20\xc9\x26\x24\x29\xd9\x7e\x15\xf8\x27\x81\xd5\x4c\x9a\x21\x5a\xea\x2d\x17\xe1\xf7\x92\x8f\x5a\xa4\xad\xa4\x45\x69\x23\x27\x1f\x81\x2c\xcc\x66\x82\x3a\x33\xbd\x82\x2c\xa7\xda\xa0\x6d\x95\xb6\x17\xbd\x9c\x49\xdc\xb4\xdc\x0a\x4c\x3b\x42\xa9\x62\x3a\xe5\x3d\xd8\x92\x08\x71\xbb\xd4\x1a\xa5\xf5\x90\x37\x16\x08\xd9\xbe\xbd\x85\x08\xa6\xd3\x95\x2f\xb7\xb7\xd3\x29\x4a\x76\x7b\xdb\x4c\x02\x4e\xc0\x14\x5c\x0e\x40\xa3\x68\x11\x6f\x46\x93\x23\x5a\xb2\x6a\xe5\x60\x12\x32\xc6\xae\x0b\x0c\x93\x18\x27\x42\x1c\xec\xbf\x8c\xb2\x69\x72\xa5\x6d\x56\x5a\xe0\x99\x92\x9b\x01\x68\x93\x0f\x69\x1f\x93\x9b\x28\xac\x05\xfb\xde\x81\xf5\xe8\xc8\xad\xc7\x3c\x53\x9b\xc9\xa3\x52\x05\x29\xe6\x21\x98\x31\x19\x5f\x1b\x86\x82\x8f\x74\x2c\xd1\x26\xb2\x18\x26\x5d\xa5\xac\xb1\x9a\x16\x7f\xed\xc5\x2f\xe2\x46\xc2\xb8\xf1\x2a\x2c\x3e\xc4\x43\x2e\xbd\xe8\x77\x51\x00\xc0\xa5\xc5\xbe\xe6\x76\xd2\x22\x26\xa7\x8d\x97\x7b\xd1\xc5\xd5\x4b\x5b\xff\xe3\x38\xfb\x78\xdc\xc0\x84\xe7\x97\x7f\xfc\x18\xfe\x73\xf3\x49\x66\x47\xaf\x27\x2f\xca\xd3\x77\x3f\xf6\xf4\xf1\xa0\x7f\x7a\x85\xef\x91\xed\xbd\xdf\xbd\x16\xbd\xd3\xa3\xf3\x51\x7f\xbf\xfc\xfe\xee\xb4\x7e\x73\xa5\xeb\x55\xf4\x4c\x2b\x63\x94\xe6\x7d\x2e\x5b\x84\x4a\x25\x27\x43\x55\x86\xd0\x0d\x21\xbb\xd1\xec\x2a\x36\x49\x37\x9a\x8c\x8f\xc0\x2b\xdc\x22\x8c\x9b\x42\xd0\xc9\x01\xf4\x04\xde\xbc\x82\x31\x67\x36\x3f\xa8\xed\xee\xfe\xdf\x2b\xc8\xd1\x9d\x7d\x3f\x99\xdb\xdf\x11\x72\xd6\x22\xde\x31\x02\x7b\x56\xd2\x11\x81\x4c\x50\x63\x56\x16\x17\xc1\xdf\x34\x05\x95\x73\x76\x3d\x25\x6d\x64\xf8\x0f\x3c\xa8\xef\x16\x37\x24\x04\x19\x8c\x76\xe3\x7a\x33\x71\xfb\xd2\x66\x57\x3f\x49\x5a\xab\x3b\xd2\x77\x65\x17\xb5\x44\x8b\x06\x4e\xb8\xb1\x4a\x4f\xe0\x13\x37\x25\x15\xfc\x87\x3f\x44\x15\x40\x0f\xfa\x78\x28\x2f\x78\x0a\xda\x45\x01\x3d\xa5\x5b\x24\x5b\xda\xb8\xc4\x72\xb6\x76\xd0\x4c\xfc\x7e\xc7\x22\xa9\x08\xce\x65\x51\x56\xf3\x02\xf1\x66\x5b\xc1\x83\x11\x15\x25\xb6\xc8\x9a\x33\x44\x80\x71\xe3\x72\x12\x6b\x11\xab\x4b\x24\x55\x3d\xfc\xf1\x5a\xf0\xea\x29\x3d\x04\x9a\x39\x9d\x5b\x84\xc0\x10\x6d\xae\x58\x8b\xf4\xb1\x9a\x82\xfc\xce\xdf\xa2\x08\x3e\x28\x0b\x26\x57\x63\x2e\xfb\x3e\xed\x7e\x2f\x51\x4f\x80\x69\x55\x00\x53\x63\x09\xd4\xc0\x18\x41\x49\x31\x81\x9c\x8e\xdc\x68\xbe\x87\x5a\x4f\x30\x54\x2e\x95\xf9\x5c\x79\x0f\xbc\x6a\xbc\x1e\x17\x16\xb5\x27\x25\xe9\x3f\xee\xaf\x6a\x2c\x48\xd2\xfb\x10\x06\x05\x66\x16\x5c\xe6\x6b\x91\x40\xe9\xed\x56\x85\x82\x9c\x33\x86\x72\x6e\x16\x97\x03\x3d\xd5\x3a\x69\x66\x26\xf3\x8c\x96\x3f\x57\xe4\x0c\xe4\xc8\x8e\x25\xbb\xe0\x43\x24\xe9\xb1\x64\xe0\x46\x0f\xf8\x76\x7e\x10\x96\x57\xee\x79\x9d\x51\x8b\x96\x0f\x31\x72\x49\x5d\x10\x30\x16\x8b\x16\xa9\x05\x85\x56\x79\xce\x54\xbe\xb7\x9c\x3c\xc1\xa4\x5b\x5a\xab\xe4\x5d\x20\x7d\x50\xe3\x39\x94\x74\x43\xc7\xca\x0d\x56\x84\x4f\x9c\xf4\x3e\x96\x1e\xb6\x4a\x30\xb9\x50\x6a\xd0\xa5\xd9\x80\xa4\x67\x4a\x0d\xe0\x90\x66\x03\xf8\x48\x65\xff\x51\xdb\x2c\x79\xf1\x0e\xa1\xe2\xc8\x05\xea\x7d\xed\x54\xe1\xe2\x78\xae\x50\x2d\x27\x69\x0d\x4e\x54\xa9\x9b\x49\xf8\xf2\x24\x49\x23\x27\x69\xc3\x93\x98\x67\xd3\xec\xe7\x24\xdd\xff\x49\x9a\x5a\xdd\xc9\x56\xff\x49\xaa\xfa\x9e\xd7\xe8\x88\x4e\x9e\xcf\x68\xff\xa5\xa7\xf9\x8c\x38\x78\xbe\x15\x1a\x4e\xa7\xba\x27\x7a\x40\xba\xbb\x83\x73\x97\x59\x9e\x08\x06\xe7\x50\x53\xd0\x0c\x49\xfa\xc6\x2f\xc0\x87\xf9\xca\xb3\xc3\x61\x81\x51\x89\x87\x0a\xf0\x7a\x09\x97\x57\x9f\x29\xee\x80\x4b\x76\x27\xe9\x3b\x2e\xd9\x01\x3c\x2d\xe5\x42\x28\x4f\x3e\x93\x3a\x40\xfd\x3b\xeb\x19\xa5\x2d\x49\x3b\x4a\x2f\xdd\x19\x8f\xd9\xca\x53\x54\x24\x0a\x08\x4f\x79\xde\x58\xaa\xad\xf5\x89\xac\xe3\x86\x3e\x95\x3d\x3b\x6e\x86\xca\x58\x1c\xa1\xb4\x86\xa4\xef\x95\xb1\x70\xec\x27\xcf\xa6\x77\x92\x93\xd4\xc5\xc5\x2f\x0c\xba\x21\xb5\x59\x1e\x50\x21\xf8\xf3\x11\x13\xde\xbf\x79\x17\x91\x17\x80\x56\x22\x6f\x86\xfe\x80\x40\x55\x38\x53\x76\x87\xbc\xea\x82\x66\xe2\xee\xde\xca\xdc\xdd\x3a\x17\xaa\xdf\x17\x08\x66\xcc\x6d\x96\x83\x55\xfe\xb6\x85\x82\x4e\x84\xa2\xcc\x15\xdc\xb2\x8f\x66\xe9\xee\xf3\x65\xd5\xbc\x88\xf2\x64\x91\xab\xd5\x29\x97\xa8\x57\xc3\xae\xf0\xd2\xcf\xd0\x2e\x7c\x55\xd2\x71\xf8\xe7\x33\xfc\x76\xc0\x6f\x26\x45\xba\xce\xb2\x4b\x5c\x48\x0a\x8f\x5f\x2f\x59\x8e\xd9\xa0\xab\x6e\x48\x95\x69\xdb\x2d\x12\x50\x32\xa8\xb2\xbc\x8e\x7a\x6b\x9b\x80\xa7\x43\xb6\x26\x5a\x7c\x41\x77\x57\x2f\x72\x86\x1a\xb4\x2a\xdd\xe9\x9a\x95\x6b\x2b\xd1\x12\xbc\x5c\x31\xf8\xfc\xe2\x5d\x2c\xdd\xf3\x5b\x33\xaf\xa7\x67\x5c\xba\xbc\x97\xd7\x2b\xb4\x74\x56\xd8\x33\xec\x96\xfd\x64\x5e\x7b\x1e\xb9\x19\xbc\x47\x59\x36\x13\xba\x5a\xc6\xcd\x49\x82\x01\x18\xb5\xd4\xf5\x12\xae\x6b\x20\xe9\x11\xb5\xd4\x85\x23\x82\x6b\x76\x2f\x72\x6e\xc0\x57\x39\x8f\xc0\xcc\x5b\x8a\x3e\xb7\x79\xd9\x75\x9d\x76\xb2\x68\xbc\x43\xb7\x43\xc0\xfa\x0e\xb5\x45\xbe\x75\x05\x75\x7c\x3a\xbe\xfd\x85\xb6\x62\xae\x18\x83\xb7\xdc\x9e\x94\xdd\x05\x93\xe9\x54\x3b\x37\x40\x7c\x86\x3d\x7b\x48\xb5\xd7\xbc\x5a\x1e\xce\x99\x4f\xa7\xf1\xa5\x16\xae\xb4\x5c\xe5\x30\x9d\xc6\x17\xbe\xea\xac\xa2\x86\x22\x73\x63\xd9\xea\x8b\x0e\x80\x35\xbe\xe5\xa8\x71\x51\xfc\x8f\xfa\x95\xa0\x9d\xd5\xec\x9b\xa1\x9d\x80\x7b\xfd\xc4\xab\xcd\xf4\x3e\xf4\xac\x99\x36\x3a\x5b\x58\x8a\x35\xae\x8d\xef\xfc\x59\x23\x1e\xbd\x88\xaf\x8d\x0f\x94\x6a\xd3\x1b\x26\x4b\x61\xb3\x84\x90\x29\x86\xf1\xb5\xaf\x1d\xbd\xc1\xc3\x30\x6a\xc4\x7b\x71\xcd\xf7\x68\xd7\x4b\x2d\xda\x6a\x93\x56\x7f\xb1\x1f\xb5\x3b\x57\x4a\x5f\x8d\xbe\x66\x17\x03\xca\x6f\xf6\xbf\x8c\xd4\xfe\x49\x51\x64\x5f\xdf\xa2\xed\x7e\x79\xff\xf6\x73\xe7\x8d\x38\x1c\xbf\x3c\xe9\xb5\xff\x56\xad\x65\xac\x87\x5a\xb2\x7f\xa9\x43\xc9\x93\x5a\x5c\xab\xc7\xb5\xb9\x36\x25\x7f\xa6\x2a\x9f\xe8\x8f\xf3\x3f\xff\xf8\xda\x1e\x5b\x1c\xbc\x36\xa3\xfe\xf9\x61\xe7\x72\x7c\xfe\xe6\x1d\xd3\xe3\xa3\x46\x29\x2f\x7b\x9d\xb7\x9f\xbe\x68\x9a\x5f\x7e\xbf\xfc\x69\x55\x82\x2e\x3e\x05\xba\xc3\xc0\x8d\x6f\x17\x04\x37\x16\x54\x0f\xc2\x2e\x03\x12\x91\x21\x83\xee\x04\x34\xce\x5e\x76\x72\x3b\x14\x3b\xd0\xc5\x8c\x96\x06\x81\x4b\x89\xda\xbf\xe2\x40\x46\x25\x48\x65\x21\x2c\x67\xa2\x64\x95\xcc\xb9\x36\x5e\x4a\x59\x0c\xfa\xde\x46\xf4\x86\x2b\x13\xfa\x72\x3f\x9c\x1b\x08\xa8\x99\xc8\xcc\x1d\xe9\x07\x5e\x6d\xd6\xfa\x66\xc5\x1f\xeb\x9e\x04\x46\x25\x06\x76\xa3\x12\x7f\x15\xa3\x85\x3a\xb2\xd0\xaa\xaf\xd1\x98\xbf\x76\xe3\x7a\xbc\xbb\x98\xff\x32\x9d\x70\x88\x9a\x67\x83\x78\x96\x9c\xb8\x4a\xae\x0d\xe3\xbd\x9e\xe0\xdd\xc4\xfd\x8f\x38\x8e\x3d\xb3\xf5\x3c\xe0\x97\x30\x11\xbc\xfb\x4c\x1e\xf7\x99\x2c\x5e\x7a\xfc\xdd\xfe\x70\xb2\x58\x64\xe6\x24\x81\xcf\x39\x4a\xd7\xf1\x6a\xf4\xf7\xa7\x0b\xd9\x82\xf6\x11\xac\x8b\xe1\x31\x17\x02\x0c\x86\xc6\x37\x53\x5a\xbb\xea\x2c\x54\x30\x5c\x49\xe3\x0a\x15\xff\xc9\xb5\xcf\x91\x6b\x9f\x0d\x74\xa9\x41\xe6\x12\x75\x41\x8d\x1b\x71\x37\xd2\x74\x88\xae\x82\x5b\xbc\x08\x52\x4b\xfd\x6d\x71\xa9\x05\xb4\x1c\x8b\x50\xd8\x98\xd7\x92\x7d\x44\x5b\x6a\x39\xff\xba\xe5\x12\xf7\x11\xf6\x68\x29\xec\xd9\xac\x71\xba\xbd\x25\x3b\x50\x59\x77\xd5\xed\xea\xda\x5d\x6d\x7e\x7b\x3b\x7f\x2e\x84\xea\x53\x64\x1f\xed\xb1\x40\x37\x3c\x9c\x9c\xb2\xad\xe5\xcb\x6d\x3b\x76\x77\x06\xb4\x96\xe4\x5c\xfb\xe6\xb8\xd6\x01\xfe\x26\xfb\x56\xf2\x75\x2e\x08\x09\xbf\x99\x84\xa7\xa8\xff\x05\x00\x00\xff\xff\xef\xab\xd7\xea\x91\x16\x00\x00") +var _webfilesIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xed\x52\x1b\xb9\xd2\xfe\xcf\x55\xf4\xaa\xea\x2d\xa0\x96\x99\xc1\x36\x61\xb3\xc4\x9e\xda\x60\x48\x60\x43\xf2\xb2\x31\x24\x24\xa7\x4e\xa5\xe4\x51\xdb\x23\x2c\x4b\x13\x49\x63\xe3\xb8\xb8\xf7\x53\x92\x6c\x3c\x36\xe6\x23\xb5\xf1\x1f\x4b\x1a\xf5\xd3\x9f\x6a\x75\xab\xf9\x5b\x14\x6d\xb4\x55\x31\xd1\xbc\x9f\x5b\xd8\xca\xb6\xa1\xbe\x5b\xfb\x73\x07\x0c\x15\x68\x7a\x4a\x67\x18\x67\x6a\xb8\x03\x5c\x66\xf1\xc6\x6b\x21\xc0\x6f\x34\xa0\xd1\xa0\x1e\x21\x8b\x37\x3a\xe7\x47\x57\xd1\x19\xcf\x50\x1a\x8c\x4e\x19\x4a\xcb\x7b\x1c\xf5\x01\x1c\x76\x8e\xa2\x46\xd4\x16\xb4\x34\xb8\xf1\x46\x69\xe8\x95\x42\x80\x08\x3b\xc1\xe2\x8d\xdd\x01\x83\x08\x67\xa7\xed\xe3\x0f\x9d\xe3\xd8\xde\x58\xe8\x71\x81\xc0\x25\xd8\x1c\x41\x63\xa1\x40\x2b\x65\x41\x69\xc8\xad\x2d\xcc\x41\x92\xa8\x02\xa5\x51\xa5\x93\x4b\xe9\x7e\x32\x43\x33\xc9\x12\xb3\x28\x4a\x37\x9a\xbf\x1d\xfd\x7f\xfb\xe2\xcb\xf9\x31\xe4\x76\x28\xdc\x3c\x8a\x4c\x59\x14\x1a\x8d\x81\x13\x3b\x14\x97\x72\x20\xd5\x58\x5e\x50\xdd\x47\xbb\x03\x7f\x77\x2e\xa5\x46\xa3\xc4\x08\xd9\x27\xaa\x39\xed\x0a\x04\x0f\x64\xec\x44\x20\xd8\x49\x81\x2d\xe2\xa4\x4e\x32\x63\x48\xba\xd1\x4c\xfc\x87\x74\xa3\x99\x23\x65\xe9\x06\x00\x40\xd3\x64\x9a\x17\xb6\xba\xf9\x9a\x8e\x68\x58\x25\x61\x8f\xfb\x31\x95\x95\x43\x94\x36\x1e\x6b\x6e\x71\x8b\x34\xbb\xd4\x20\xe4\x1a\x7b\xad\xcd\x84\xc0\xef\x30\xe6\x92\xa9\x71\x2c\x54\x46\x2d\x57\x32\x2e\xa8\xcd\x25\x1d\x62\x6c\x0a\xc1\xed\xd6\x66\xb2\xb9\xfd\x9f\xda\x7f\xe1\x77\x20\xc9\x26\x24\x29\xd9\x7e\x15\xf8\x27\x81\xd5\x4c\x9a\x21\x5a\xea\x2d\x17\xe1\xf7\x92\x8f\x5a\xa4\xad\xa4\x45\x69\x23\x27\x1f\x81\x2c\xcc\x66\x82\x3a\x33\xbd\x82\x2c\xa7\xda\xa0\x6d\x95\xb6\x17\xbd\x9c\x49\xdc\xb4\xdc\x0a\x4c\x3b\x42\xa9\x62\x3a\xe5\x3d\xd8\x92\x08\x71\xbb\xd4\x1a\xa5\xf5\x90\x37\x16\x08\xd9\xbe\xbd\x85\x08\xa6\xd3\x95\x2f\xb7\xb7\xd3\x29\x4a\x76\x7b\xdb\x4c\x02\x4e\xc0\x14\x5c\x0e\x40\xa3\x68\x11\x6f\x46\x93\x23\x5a\xb2\x6a\xe5\x60\x12\x32\xc6\xae\x0b\x0c\x93\x18\x27\x42\x1c\xec\xbf\x8c\xb2\x69\x72\xa5\x6d\x56\x5a\xe0\x99\x92\x9b\x01\x68\x93\x0f\x69\x1f\x93\x9b\x28\xac\x05\xfb\xde\x81\xf5\xe8\xc8\xad\xc7\x3c\x53\x9b\xc9\xa3\x52\x05\x29\xe6\x21\x98\x31\x19\x5f\x1b\x86\x82\x8f\x74\x2c\xd1\x26\xb2\x18\x26\x5d\xa5\xac\xb1\x9a\x16\x7f\xed\xc5\x2f\xe2\x46\xc2\xb8\xf1\x2a\x2c\x3e\xc4\x43\x2e\xbd\xe8\x77\x51\x00\xc0\xa5\xc5\xbe\xe6\x76\xd2\x22\x26\xa7\x8d\x97\x7b\xd1\xc5\xd5\x4b\x5b\xff\xe3\x38\xfb\x78\xdc\xc0\x84\xe7\x97\x7f\xfc\x18\xfe\x73\xf3\x49\x66\x47\xaf\x27\x2f\xca\xd3\x77\x3f\xf6\xf4\xf1\xa0\x7f\x7a\x85\xef\x91\xed\xbd\xdf\xbd\x16\xbd\xd3\xa3\xf3\x51\x7f\xbf\xfc\xfe\xee\xb4\x7e\x73\xa5\xeb\x55\xf4\x4c\x2b\x63\x94\xe6\x7d\x2e\x5b\x84\x4a\x25\x27\x43\x55\x86\xd0\x0d\x21\xbb\xd1\xec\x2a\x36\x49\x37\x9a\x8c\x8f\xc0\x2b\xdc\x22\x8c\x9b\x42\xd0\xc9\x01\xf4\x04\xde\xbc\x82\x31\x67\x36\x3f\xa8\xed\xee\xfe\xdf\x2b\xc8\xd1\x9d\x7d\x3f\x99\xdb\xdf\x11\x72\xd6\x22\xde\x31\x02\x7b\x56\xd2\x11\x81\x4c\x50\x63\x56\x16\x17\xc1\xdf\x34\x05\x95\x73\x76\x3d\x25\x6d\x64\xf8\x0f\x3c\xa8\xef\x16\x37\x24\x04\x19\x8c\x76\xe3\x7a\x33\x71\xfb\xd2\x66\x57\x3f\x49\x5a\xab\x3b\xd2\x77\x65\x17\xb5\x44\x8b\x06\x4e\xb8\xb1\x4a\x4f\xe0\x13\x37\x25\x15\xfc\x87\x3f\x44\x15\x40\x0f\xfa\x78\x28\x2f\x78\x0a\xda\x45\x01\x3d\xa5\x5b\x24\x5b\xda\xb8\xc4\x72\xb6\x76\xd0\x4c\xfc\x7e\xc7\x22\xa9\x08\xce\x65\x51\x56\xf3\x02\xf1\x66\x5b\xc1\x83\x11\x15\x25\xb6\xc8\x9a\x33\x44\x80\x71\xe3\x72\x12\x6b\x11\xab\x4b\x24\x55\x3d\xfc\xf1\x5a\xf0\xea\x29\x3d\x04\x9a\x39\x9d\x5b\x84\xc0\x10\x6d\xae\x58\x8b\xf4\xb1\x9a\x82\xfc\xce\xdf\xa2\x08\x3e\x28\x0b\x26\x57\x63\x2e\xfb\x3e\xed\x7e\x2f\x51\x4f\x80\x69\x55\x00\x53\x63\x09\xd4\xc0\x18\x41\x49\x31\x81\x9c\x8e\xdc\x68\xbe\x87\x5a\x4f\x30\x54\x2e\x95\xf9\x5c\x79\x0f\xbc\x6a\xbc\x1e\x17\x16\xb5\x27\x25\xe9\x3f\xee\xaf\x6a\x2c\x48\xd2\xfb\x10\x06\x05\x66\x16\x5c\xe6\x6b\x91\x40\xe9\xed\x56\x85\x82\x9c\x33\x86\x72\x6e\x16\x97\x03\x3d\xd5\x3a\x69\x66\x26\xf3\x8c\x96\x3f\x57\xe4\x0c\xe4\xc8\x8e\x25\xbb\xe0\x43\x24\xe9\xb1\x64\xe0\x46\x0f\xf8\x76\x7e\x10\x96\x57\xee\x79\x9d\x51\x8b\x96\x0f\x31\x72\x49\x5d\x10\x30\x16\x8b\x16\xa9\x05\x85\x56\x79\xce\x54\xbe\xb7\x9c\x3c\xc1\xa4\x5b\x5a\xab\xe4\x5d\x20\x9d\x51\x8b\xc6\xce\xd1\xc4\x6c\xe6\x18\xce\xc7\x3e\x25\xb7\xc8\xdf\xe5\xb0\x00\xab\xbc\x3f\x51\x32\x50\x3d\xd0\x98\x29\xcd\x90\x01\xa3\x96\xae\x06\x4e\xe2\xf4\xf5\xd1\xf7\xb0\x1d\x83\x93\x84\x52\x83\x2e\xcd\x06\x24\x3d\x53\x6a\x00\x87\x34\x1b\xc0\x47\x2a\xfb\x8f\x5a\x73\xc9\xef\x77\x08\x15\xd7\x2f\x50\xef\xdb\x43\x15\x2e\xf2\xe7\x26\xa8\xe5\x24\xad\xc1\x89\x2a\x75\x33\x09\x5f\x9e\x24\x69\xe4\x24\x6d\x78\x12\xf3\x6c\x9a\xfd\x9c\xa4\xfb\x3f\x49\x53\xab\x3b\xd9\xea\x3f\x49\x55\xdf\xf3\x1a\x1d\xd1\xc9\xf3\x19\xed\xbf\xf4\x34\x9f\x11\x07\xcf\xb7\x42\xc3\xe9\x54\xf7\x44\x0f\x48\x77\x77\xd4\xee\x72\xd1\x13\xc1\xe0\x1c\x6a\x0a\x9a\x21\x49\xdf\xf8\x05\xf8\x30\x5f\x79\x76\x38\x2c\x30\x2a\xf1\x50\x01\x5e\x2f\xe1\xf2\xea\x33\xc5\x1d\x70\xc9\xee\x24\x7d\xc7\x25\x3b\x80\xa7\xa5\x5c\x08\xe5\xc9\x67\x52\x07\xa8\x7f\x67\x3d\xa3\xb4\x25\x69\x47\xe9\xa5\x5b\xe6\x31\x5b\x79\x8a\x8a\x44\x01\xe1\x29\xcf\x1b\x4b\xb5\xb5\x3e\xf5\x75\xdc\xd0\x27\xbf\x67\xc7\xcd\x50\x19\x8b\x23\x94\xd6\x90\xf4\xbd\x32\x16\x8e\xfd\xe4\xd9\xf4\x4e\x72\x92\xba\xb8\xf8\x85\x41\x37\xa4\x36\xcb\x03\x2a\x04\x7f\x3e\x62\xc2\xfb\x77\xf5\x22\xf2\x02\xd0\x4a\xe4\xcd\xd0\x1f\x10\xa8\x0a\x67\xca\xee\x90\x57\x5d\xd0\x4c\xdc\x6d\x5d\x99\xbb\x7b\xea\x42\xf5\xfb\x02\xc1\x8c\xb9\xcd\x72\x97\x96\xdd\xfd\x0c\x05\x9d\x08\x45\x99\x2b\xd1\x65\x1f\xcd\xd2\x6d\xe9\x0b\xb1\x79\xd9\xe5\xc9\x22\x57\xdd\x53\x2e\x51\xaf\x86\x5d\xe1\xa5\x9f\xa1\x5d\xf8\x3a\xa6\xe3\xf0\xcf\x67\xf8\xed\x80\xdf\x4c\x8a\x74\x9d\x65\x97\xb8\x90\x14\x1e\xbf\x90\xb2\x1c\xb3\x41\x57\xdd\x90\x2a\xd3\xb6\x5b\x24\xa0\x64\x50\x65\x79\x1d\xf5\xd6\x36\x01\x4f\x87\x6c\x4d\xb4\xf8\x12\xf0\xae\xc2\xe4\x0c\x35\x68\x55\xba\xd3\x35\x2b\xf0\x56\xa2\x25\x78\xb9\x62\xf0\xf9\x55\xbd\x58\xba\xe7\xb7\x66\x5e\x4f\xcf\xb8\x74\x79\x2f\xaf\x57\x68\xe9\xac\x15\x60\xd8\x2d\xfb\xc9\xbc\x5a\x3d\x72\x33\x78\x8f\xb2\x6c\x26\x74\xb5\xf0\x9b\x93\x04\x03\xb8\xbb\xd4\x75\x1f\xae\xcf\x20\xe9\x11\xb5\xd4\x85\x23\x82\x6b\x8f\x2f\x72\x6e\xc0\xd7\x45\x8f\xc0\xcc\x9b\x90\x3e\xb7\x79\xd9\x75\xbd\x79\xb2\x68\xd5\x43\x7f\x44\xc0\xfa\x9e\xb6\x45\xbe\x75\x05\x75\x7c\x3a\xbe\x61\x86\xb6\x62\xae\x7c\x83\xb7\xdc\x9e\x94\xdd\x05\x93\xe9\x54\x3b\x37\x40\x7c\x86\x3d\x7b\x48\xb5\xd7\xbc\x5a\x50\xce\x99\x4f\xa7\xf1\xa5\x16\xae\x18\x5d\xe5\x30\x9d\xc6\x17\xbe\x4e\xad\xa2\x86\xb2\x74\x63\xd9\xea\x8b\x9e\x81\x35\xbe\xe5\xa8\x71\xd1\x2e\x8c\xfa\x95\xa0\x9d\x55\xf9\x9b\xa1\x01\x81\x7b\x1d\xc8\xab\xcd\xf4\x3e\xf4\xac\xfd\x36\x3a\x5b\x58\x8a\x35\xae\x8d\x7f\x2b\x60\x8d\x78\xf4\x22\xbe\x36\x3e\x50\xaa\x6d\x72\x98\x2c\x85\xcd\x12\x42\xa6\x18\xc6\xd7\xbe\xda\xf4\x06\x0f\xc3\xa8\x11\xef\xc5\x35\xdf\xd5\x5d\x2f\x35\x75\xab\x6d\x5d\xfd\xc5\x7e\xd4\xee\x5c\x29\x7d\x35\xfa\x9a\x5d\x0c\x28\xbf\xd9\xff\x32\x52\xfb\x27\x45\x91\x7d\x7d\x8b\xb6\xfb\xe5\xfd\xdb\xcf\x9d\x37\xe2\x70\xfc\xf2\xa4\xd7\xfe\x5b\xb5\x96\xb1\x1e\x6a\xe2\xfe\xa5\x0e\x25\x4f\x6a\x71\xad\x1e\xd7\xe6\xda\x94\xfc\x99\xaa\x7c\xa2\x3f\xce\xff\xfc\xe3\x6b\x7b\x6c\x71\xf0\xda\x8c\xfa\xe7\x87\x9d\xcb\xf1\xf9\x9b\x77\x4c\x8f\x8f\x1a\xa5\xbc\xec\x75\xde\x7e\xfa\xa2\x69\x7e\xf9\xfd\xf2\xa7\x55\x09\xba\xf8\x14\xe8\x0e\x03\x37\xbe\x20\x15\xdc\x58\x57\x91\x86\x5d\x06\x24\xa2\xab\x4b\xbb\x13\xd0\x38\x7b\x0b\xca\xed\x50\xec\x40\x17\x33\x5a\x1a\x04\x2e\x25\x6a\xff\xee\x03\x19\x95\x20\x95\x85\xb0\x9c\x89\x92\x55\x32\xe7\xda\x78\x29\x65\x31\xe8\x7b\x1b\xd1\x1b\xae\x4c\xe8\xe4\xfd\x70\x6e\x20\xa0\x66\x22\x33\x77\xa4\x1f\x78\xe7\x59\xeb\x9b\x15\x7f\xac\x7b\x44\x18\x95\x18\xd8\x8d\x4a\xfc\x55\x8c\x16\xea\xc8\x42\xab\xbe\x46\x63\xfe\xda\x8d\xeb\xf1\xee\x62\xfe\xcb\x74\xc2\x21\x6a\x9e\x0d\xe2\x59\x72\xe2\x2a\xb9\x36\x8c\xf7\x7a\x82\x77\x13\xf7\x3f\xe2\x38\xf6\xcc\xd6\xf3\x80\x5f\xc2\x44\xf0\xee\x33\x79\xdc\x67\xb2\x78\x1b\xf2\x77\xfb\xc3\xc9\x62\x91\x99\x93\x04\x3e\xe7\x28\x5d\x8f\xac\xd1\xdf\x9f\x2e\x64\x0b\xda\x47\xb0\x2e\x86\xc7\x5c\x08\x30\x18\x5a\xe5\x4c\x69\xed\xaa\xb3\x50\xc1\x70\x25\x8d\x2b\x54\xfc\x27\xd7\x70\x47\xae\xe1\x36\xd0\xa5\x06\x99\x4b\xd4\x05\x35\x6e\xc4\xdd\x48\xd3\x21\xba\x0a\x6e\xf1\x86\x48\x2d\xf5\xb7\xc5\xa5\x16\xd0\x72\x2c\x42\x61\x63\x5e\x4b\xf6\x11\x6d\xa9\xe5\xfc\xeb\x96\x4b\xdc\x47\xd8\xa3\xa5\xb0\x67\xb3\xc6\xe9\xf6\x96\xec\x40\x65\xdd\x55\xb7\xab\x6b\x77\xb5\xf9\xed\xed\xfc\x81\x11\xaa\x8f\x97\x7d\xb4\xc7\x02\xdd\xf0\x70\x72\xca\xb6\x96\x2f\xb7\xed\xd8\xdd\x19\xd0\x5a\x92\x73\xed\x2b\xe5\x5a\x07\xf8\x9b\xec\x5b\xc9\xd7\xb9\x20\x24\xfc\x66\x12\x1e\xaf\xfe\x17\x00\x00\xff\xff\x99\x67\xe3\xa1\xc3\x16\x00\x00") func webfilesIndexHtmlBytes() ([]byte, error) { return bindataRead( @@ -285,7 +285,7 @@ func webfilesIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/index.html", size: 5777, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} + info := bindataFileInfo{name: "webfiles/index.html", size: 5827, mode: os.FileMode(416), modTime: time.Unix(1781201512, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -350,7 +350,7 @@ func webfilesSloopCss() (*asset, error) { return a, nil } -var _webfilesSloop_uiJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x7c\x7d\x73\x1b\x37\xce\xf8\xff\xfe\x14\xe8\x26\xf3\x78\x15\xaf\x56\x92\x9d\xa4\x8e\x6d\xf9\x19\xcb\x2f\xd7\xfc\x2e\x49\xfb\xab\xd3\xbb\x66\x3c\x9e\x86\xda\x85\x24\x9e\x57\xa4\x8e\xa4\x2c\xa9\x39\x7f\xf7\x67\x48\xee\x0b\xf7\xcd\x2f\xb9\x36\x77\xee\x4c\xb3\x22\x01\x10\x00\x41\x10\x00\xb9\xdb\x7b\xb1\x05\x2f\xe0\x94\x2f\x36\x82\x4e\x67\x0a\xfc\xa8\x03\xbb\xfd\xc1\x9b\x00\x24\x49\x50\x4e\xb8\x88\x30\x8c\xf8\x3c\x00\xca\xa2\x50\xc3\x9e\x24\x09\x18\x58\x09\x02\x25\x8a\x5b\x8c\x4d\xfb\xe5\x4f\x67\xbf\x76\xdf\xd1\x08\x99\xc4\xee\xdb\x18\x99\xa2\x13\x8a\xe2\x00\x46\x97\x67\xdd\xbd\xee\x69\x42\x96\x12\x35\xe0\x05\x17\x30\x59\x26\x09\x24\x16\x18\x14\xae\x55\x00\x12\x11\xde\xbd\x3d\x3d\xff\x70\x79\x1e\xaa\xb5\x82\x09\x4d\x10\x28\x03\x35\x43\x10\xb8\xe0\x20\x38\x57\xc0\x05\xcc\x94\x5a\xc8\x83\x5e\x8f\x2f\x90\x49\xbe\xd4\x0c\x72\x31\xed\xa5\xd4\x64\xaf\x32\x5e\x6f\x6b\x2b\xe2\x4c\x2a\x58\x90\x04\x95\x42\x18\xc2\x97\x2d\x00\x80\x31\x91\x78\x46\xc4\xcd\x01\x5c\x79\xcf\x76\xcf\xf7\x5e\xbe\xec\x7b\x01\x78\xcf\xf6\x46\x2f\x77\x5f\xed\x9a\xc7\x97\x7b\x2f\x4f\x5f\x9d\xdb\xc7\xd3\x57\xaf\x5f\x9f\x78\xd7\x41\x8e\xfb\x4e\x2b\xc1\x20\x9f\xed\x9f\x9d\x9f\xbf\x31\x60\xe7\xaf\xce\xdf\x5c\x58\x3a\xe7\xa7\xe7\x17\x17\x2f\xcd\xe3\xc5\xde\xc5\xde\xc5\x79\x86\xbc\x10\x74\x4e\xc4\xc6\xa0\xee\x5f\x8c\x4e\x47\x23\x03\xb4\xbf\x7f\xda\x3f\xb3\xa8\xfb\x83\x93\xc1\xe9\xc0\x3c\xbe\x3a\xdf\x1f\x9c\x9c\x66\xa8\x33\x3a\x9d\x25\xf9\xb8\xa3\x8b\xd7\x83\xd7\x27\x06\xec\xac\xbf\xff\xfd\xf7\xe9\xb8\xa3\xd3\xd1\xbe\x25\x79\xb2\x37\x3a\xdf\x3f\xf5\x2c\xae\xfe\xf3\x9e\x8d\x5e\xee\x9f\x9f\x9c\x79\x81\xf7\xec\xe4\xec\x64\x7f\xf4\x5a\x3f\xc5\xe4\xfb\xd7\xaf\xfa\xfa\xe9\xec\xe5\x9b\xd7\x27\xdf\x9b\xde\xd1\xe9\xcb\x93\x51\x09\xf5\xe4\xe5\xc9\xeb\xb3\x5d\xdd\xf9\x66\x30\x3a\xbf\xb0\x4f\xdf\x8f\x06\x27\x86\xc8\xfe\xc9\x9b\xd1\xeb\xfd\x8c\x51\x89\xb7\x28\xa8\xd2\x42\x6e\x3f\x7b\x39\x3a\xdb\x7f\xf5\x6a\x3b\x80\xed\x67\xe7\xfd\xf3\x7e\xbf\x6f\x1e\xcf\xf6\x5f\x8e\x5e\x8e\xb6\xaf\x83\xad\xbb\xc3\xad\xad\xad\x5e\x0f\xfe\x92\xf0\x31\x49\x24\xbc\xa3\xb7\x08\x3f\xa0\xc0\xad\x04\x15\x28\xbe\x38\x59\x53\x19\xc0\x98\x2b\xc5\xe7\xfa\xf9\xd0\x80\x7f\x9c\xa1\x44\x98\x2c\x59\xa4\x28\x67\x12\xa6\xa8\x20\x22\x49\x82\x31\xac\x66\xc8\x34\x07\xc6\x7a\x16\x82\x2f\x50\x28\x8a\x12\xf8\x04\x90\xaa\x19\x0a\x20\x6b\x2a\x81\x08\x84\x68\x46\xd8\x14\x63\x77\xa8\x33\x41\x56\x17\x4b\x16\xb9\x43\x66\x6d\xee\xd0\x1a\x3d\xde\x03\xa9\xc4\x32\x52\xd2\x50\x58\x6b\xd8\xcb\x88\x24\x18\xc0\x46\x3f\x8f\x08\x8b\x2d\xce\x89\x10\x64\x03\x11\x67\x8a\x50\x46\xd9\x14\x62\xa2\x08\x08\x54\x82\xe2\x2d\xc6\x30\x11\x7c\x0e\x32\xe1\x7c\x01\x66\x59\x09\x43\x50\x03\xe5\x63\x82\xa2\x73\x84\x98\xca\x45\x42\x36\x18\x03\x67\x10\xa1\xd0\xf4\x60\xce\x97\x12\xb9\x16\x99\xb0\xd8\xfe\x9a\xf3\x5b\x04\xbc\x45\x96\xf2\xa6\x66\xf8\x91\xce\xd1\x95\x20\xc6\x09\x65\x68\xb4\x34\x27\x6b\x3a\x5f\xce\x21\x16\x64\xa5\xb9\x93\x0b\x12\xa1\x1e\x41\x77\xae\x28\x8b\xf9\x2a\x84\xb7\x10\x73\xb6\xad\x49\x51\x76\xa3\xc9\xa8\x19\x95\x40\xa5\x01\x8a\xb8\x10\x18\x29\x58\x91\x8d\x56\xf4\x52\x6a\x32\xca\x8c\x73\x4b\x84\x84\x2e\x50\x05\x31\x47\xa9\x29\x08\x24\x49\xb2\xd1\x2e\x64\x61\x70\xcc\x00\xfa\x27\xfd\x9d\xb2\xa9\x26\xad\xe5\x58\x21\x15\x31\xcc\x29\xd3\xac\x49\xd3\x94\x4a\x0f\x32\x22\x89\x1e\x20\xe2\xcb\x24\x86\x05\x57\xda\xe3\x18\x9a\x91\x5e\xf9\x7a\xd6\xc7\x09\xce\x65\x68\xd5\x68\xb1\xde\x93\xf5\xaf\x81\xf3\xe3\x93\x55\xc6\xdf\xb4\x79\x44\x24\x31\x42\x6b\xa2\x63\x54\x2b\x44\x06\x63\x22\x64\xea\x3e\x04\x5a\x67\x33\x22\x22\x03\xbf\x4c\xa1\x87\xd0\x0f\x77\x2d\x25\x79\x3b\x05\x81\x13\x14\xc8\x22\x84\x09\x17\x20\x90\xc5\x28\x8c\x46\x6f\xa7\xa9\x52\xe2\x3d\xc3\x94\xbc\x9d\x5a\xac\x4b\xaa\xa1\x57\xb8\xad\x0d\x2a\xd5\xbf\x1e\x5a\xab\xdf\xfc\xbb\xa2\x5a\xe3\x46\xcb\x92\xcc\xb1\x30\xad\x15\x8d\xd5\x0c\xba\x76\x46\xa9\x84\x39\x11\x53\xca\xd2\x79\xb5\xd3\x62\x27\x32\x93\xc8\xba\x53\x2b\x8a\xa6\x0d\x5d\xa3\x55\xaa\xb6\xa5\x63\x9b\x9a\xde\xd8\x4c\x80\x1d\x38\x1d\x3b\x1f\xd6\xb2\x3f\x27\x49\x32\x22\xe2\xbd\x19\xf3\x70\xcb\x34\xa6\x0c\x64\x4e\x56\xf1\xc5\x01\xec\xf6\xad\x53\x48\x70\xa2\x0e\x60\xd0\xef\x9b\x15\x9f\xda\x14\x67\x66\xd2\xb5\x5f\x4e\x38\x89\x2f\xff\xf6\x97\xc3\xad\xad\x6c\x51\x03\x65\x54\xcf\x2a\xfd\x1d\xcf\xe8\x1c\x99\xd4\x0b\xdd\xef\xa4\xc4\x9d\x49\x85\x21\xc4\x3c\x5a\xce\x91\xa9\x30\x7b\x38\x4f\xd0\xfc\x8e\x12\x8a\x4c\xfd\x5d\x6b\xea\xb0\x82\xf7\xe9\x61\xbc\x1f\x50\xfb\xdb\xc3\xad\xbb\xad\xad\x18\x15\xa1\x09\xc6\x1f\x39\x4f\x3e\xd2\xc5\x5b\xf9\x37\x2a\xe9\x38\xd1\xac\x4f\x48\x22\x31\x55\x01\xe3\x97\x5c\xa8\x0b\xad\x84\x5c\x8e\x9c\x67\x81\x6a\x29\x18\x58\x15\x58\xcb\x8a\xf8\x7c\x41\x04\x5e\x2a\x52\xc3\x22\x01\x8c\x33\x4c\x3a\x01\x9f\x84\x37\x94\xc5\xf0\xdd\x10\xc6\xe6\x29\xeb\x73\x28\xa7\xd4\xfe\x4a\x59\x6c\xd1\x0d\xc0\x9d\x3b\x38\x09\xa5\x1e\x0b\xba\x30\xb6\x4f\x87\x9a\x9b\x12\x33\xef\xb9\x54\xe7\xc6\x75\x7c\x13\x8e\xc6\xa1\x76\x5d\x09\xd9\xc8\x30\x41\x36\xd5\x26\x0d\xa4\xda\x56\xe7\xf2\x03\x99\xe3\x37\xe1\xcf\xdf\xde\x86\x1d\x20\xa1\x0e\x55\x3a\x61\xc2\xb5\x83\x3f\xb5\x68\xfe\xd8\xb6\x1a\xee\xf4\xf4\x47\xf3\x85\xe1\x29\x33\x03\xd7\x9c\x53\x0b\xcf\xad\x61\x41\x36\xba\x49\x5b\xe1\x5e\xf8\x0f\xc9\x99\xaf\xfd\xfd\xff\x5f\xa2\xd8\xfc\x22\x92\xce\xa1\x0b\x14\xaa\x19\x32\xbf\x90\x54\xa0\x5c\x26\xca\x95\xa7\x79\xb1\x1c\xe6\xfd\xda\x01\x0d\x53\x87\x94\xa1\x17\xbd\x63\xca\xe2\xf7\x7a\xdf\xb0\xf3\xee\xcb\xdb\xa9\xd3\x4b\x16\x0b\x64\xf1\xc9\x1a\xab\x1d\x96\x9c\x5e\x12\x8a\x2e\xb2\xd1\xee\xb4\x3a\xb6\x72\x69\xad\x97\xfb\x29\x15\x56\xf1\xe9\x34\x41\x90\x2b\xaa\xa2\x99\xd9\xc3\xcc\x16\x0c\x8a\xe7\xce\x3d\xd3\x4b\xd6\x43\xa3\x1b\x59\x68\x31\xed\x3d\x9d\x61\x74\x83\xc2\x2f\xa6\xdb\xcf\xd7\xf2\x14\xb3\x65\x3c\xda\xbc\x8d\x7d\xcf\x45\xf1\x3a\x61\x64\x50\x63\x18\x0e\x41\x89\x25\xba\x4a\x34\xdb\x74\xa8\x37\xe3\x26\x6a\x72\xb4\x39\x4d\x88\x94\xda\xf2\x1c\xaa\x9a\x4b\xaf\xd3\xc9\x89\xe8\xbf\x70\x4e\x16\x3e\xc2\xf0\x18\x30\x94\x6a\x93\x60\x98\x49\x37\x04\x6f\x9c\x70\xcd\x48\xaa\x2d\xc0\x44\xe2\x9f\xc1\xc3\xfd\x4c\x30\xce\x30\xe7\x41\x3b\xb8\x5e\x0f\xe0\x2c\xed\x8f\xe9\xc4\x6c\x63\x0a\xfe\xa9\xcd\x11\xe6\xa8\x66\x3c\x96\x26\xf4\x35\x91\x87\x20\x31\xe5\x70\x4b\x92\x25\x16\x53\x63\x60\x2d\x2f\xbe\x01\x70\xd7\xa2\x69\x08\x0d\x06\x0c\x87\x43\xf0\x04\x4e\x71\xed\x7d\xad\xf6\x53\xec\xaf\xd5\xfa\xd3\x15\x2d\x14\xd5\x42\x3e\x69\xc8\xb2\x8e\x5b\x35\xe1\x10\xff\x66\xda\x70\x59\xfb\x36\xca\x28\x5b\xbd\xb6\xb8\xdc\x70\xca\x5e\x29\xd5\x41\x16\x00\xc3\x50\x87\x73\x11\x4a\x79\xc2\x62\xed\x55\x7f\x4e\x23\x18\x59\x76\x63\x19\xfc\x68\xa3\x9d\x79\x00\xda\xe1\xcb\x40\xa7\x92\x0a\x05\xc6\x67\x36\x96\xce\x67\xe1\x3b\x0d\xeb\xea\xbb\x88\xde\xad\x47\xd6\x31\x26\xfe\xa2\x22\xbf\x13\x0a\x63\xd2\x57\x36\xbc\x09\x75\x24\x13\x94\xe2\x8f\x2e\x38\x5d\xd7\x8e\x56\xf3\x98\xc9\x21\xa9\x7f\xfa\x9d\x70\x41\xe2\x98\xb2\xa9\xdf\x1e\x5a\x6a\xcf\x99\x11\xaa\x24\x27\x96\x9c\x4e\x63\x3e\xf2\x85\x5f\x70\xee\x7a\xf4\x5a\xf6\x52\x20\x8d\x4c\x5f\x33\x9e\xab\x2f\x18\xc2\xd5\x75\xb3\x97\x2a\x34\x6d\xc9\x32\x94\xca\xef\x84\x37\xb8\xf1\x63\x6d\x00\xb1\xdd\x70\x43\x64\x3a\xc5\x91\x66\x6b\x73\x46\x31\x93\xa3\x31\x73\x32\xc6\x76\x32\x54\xdc\xb8\xc2\x8f\x89\x38\xe5\x09\x17\x7f\x41\x56\xc8\x61\x74\xf9\xa3\x88\x29\x23\x89\xdf\x09\x63\x3e\x27\x94\xf9\x86\x6e\x36\x61\x69\xd2\x1f\xe6\x89\xb3\xbb\x1d\xa6\x39\x6a\x0b\xe1\x77\x94\x21\x11\x05\xdd\xab\x7e\x00\x83\x00\x76\xaf\xab\xb4\x33\x3a\x2e\xbf\xed\x96\x54\x5e\x2d\x19\xed\x78\x2f\x9c\x53\xbb\xfb\x07\x90\xaa\xc0\x84\x66\x9d\x40\xa3\xcf\xc9\xba\xdc\x87\x2c\xee\x5c\x57\x68\x3d\xd9\x44\x1f\x61\xa3\x8d\xdc\xc6\x7b\xe9\x58\x9a\xa5\x34\x38\xab\xba\x81\x32\x33\x8a\x2f\x02\x70\xc1\xe1\x05\xf8\x7b\xfd\x4e\xa7\x60\x4a\xf1\x45\x55\xa0\xa7\xad\x8f\x72\x3a\x62\x92\xb2\x01\xbc\x28\x64\x0b\xc7\x59\xbe\x64\x02\x92\x76\x6b\x0f\x23\xce\x22\xa2\x42\xb2\x58\x24\x1b\xff\xea\x3a\x68\x31\x51\xe3\xbe\x65\xa7\x65\xe1\x84\x13\x2e\xce\x49\x34\xcb\xa0\x23\x6d\x65\x56\xbf\xe6\xd1\xaf\x98\xb4\x9f\x2e\x97\x4e\xee\x1e\xb7\x9e\xbe\xea\x9f\xba\xe2\x73\xaf\x29\x6f\xa7\x26\x41\x82\xa1\x63\xba\xe9\x24\x76\xae\x06\xd7\xb0\x03\xfe\x2e\xbc\x70\x2d\xc8\xf1\xb9\xf2\x76\x6a\xd3\x24\x18\x3a\xfa\x6e\xc5\x56\x7c\x91\x8d\xdd\xeb\x81\x48\x0b\x15\x6b\x2a\x55\x96\x26\xe7\x29\xb4\xcd\xf9\x05\x46\x02\x89\x42\xa0\x2a\x84\x2c\xd6\xd3\x61\xa8\xe3\x8d\x6c\x70\xab\xad\x17\x13\x8c\x94\xef\x3d\x8b\xf7\x7e\x9b\xa1\x28\x6d\x71\xf2\x76\x9a\xf6\x9f\x24\x89\xbf\xfd\x62\xbb\x13\xda\xe1\xfd\xd2\x16\x7d\x0f\xad\x9c\x54\x68\x23\x62\xdf\x93\xb7\xd3\x52\xb3\x52\xc2\xf7\x6e\x29\xae\x46\x7c\xed\x05\xf0\xb9\x0f\x7d\x78\xfe\x25\x53\xf0\x9d\x7d\xb6\xea\xba\xfb\xec\x20\x46\x7a\x77\x45\x4b\xb0\xab\x53\x71\x64\xca\x0b\x6c\x7c\xaa\xed\xd5\x40\x6a\xbe\xb4\x10\xd9\xe0\xd3\x4c\xba\x5e\x0f\x4e\xad\x8e\x74\xa2\x3e\x15\x64\x31\x33\x15\x0d\x81\x0b\x81\x12\x99\x22\x66\x9b\xe5\x13\x40\x12\xcd\xf2\x12\x80\x25\x2a\xf8\x72\xa1\x5d\xf1\xb4\xe0\xa6\xd0\x92\x57\x12\x4f\x2f\x05\xdf\xb5\x73\xa7\x0f\x99\xd2\xe1\x78\x5d\x45\x0d\x0a\x52\x82\x30\x39\xe1\x62\xee\x69\xc7\x10\x00\xed\xe8\x65\xf2\xd9\x34\x27\x44\xa1\xaf\x95\x96\xdb\x92\x4f\x3b\xb0\x53\x59\xe1\x77\x1d\x57\x7b\x5a\x2a\xdf\x5a\xc9\xcf\x85\xbb\xc8\xcc\x2c\x8f\x67\x4c\x7c\x7a\x69\x64\xe3\xc2\xf7\xc6\x3c\xde\x78\x9d\xb0\x50\x80\x79\x38\x74\x53\x3f\x79\x3b\xd5\x81\x4a\xe6\xe4\x75\x62\x87\x2b\x78\x4f\x16\xfe\xd5\x95\xf7\x81\x8b\x39\x49\xbc\xa0\x7f\x1d\x5c\x79\x7f\x27\x82\x51\x36\xf5\x82\x81\xfe\x75\x2e\x04\x17\x5e\xb0\x7b\x6d\x3c\x6d\x91\xbb\xdc\x1f\xc7\x38\x81\x8f\x36\xa1\x1f\x17\xb6\xb4\xa9\xb3\x36\xdd\x1f\xea\xc6\xdf\xb8\x6d\x3d\x74\x22\x99\xb4\x5b\xf0\x95\xec\x54\xb6\x68\x18\xc2\x97\xbb\xf6\x1d\xbc\xa0\xad\x91\x0b\xff\xf6\xa5\xe4\x8b\xb3\xa4\xb6\x5c\xab\x38\x2c\xc1\xa4\x09\x9d\xef\x30\x1e\x4a\x2e\x4a\x29\x6a\x4e\x8f\x48\x04\xcf\xec\x70\x8a\xce\xd1\x3b\xa8\x41\x3c\x76\xd4\xec\x6f\x2c\x90\xdc\xd4\xbb\xec\x40\x8c\x3c\x76\x0c\x5b\x52\xf8\x8a\x21\xe6\x5c\x2a\x5b\x6c\x7d\xdc\x40\x6e\x85\xe5\x49\xc3\xc5\x38\x21\xcb\x44\xb5\x0c\xc2\x99\xe4\x09\x86\x09\x9f\xfa\xde\x2f\xec\x86\xf1\x15\x03\x3d\x09\x07\xe0\xc1\x0e\xd4\xa6\xe6\xd1\x23\xdf\x6d\x95\x7e\x5a\x93\xc9\xcb\x7c\xee\x5f\x18\x86\x71\x50\x6b\x35\x53\x7d\x90\x45\x35\xbf\xc5\xda\x53\xbd\x80\x41\xbf\xdf\xaf\xc3\x22\x8b\x0f\xc0\x6f\x00\xd5\x4e\xc0\x8f\xc3\x78\x29\xac\x37\x4b\x5b\xeb\x14\xb2\xca\x91\x1e\x30\xaf\x22\xe5\x99\x49\x9d\x67\xb0\x1e\x14\xb3\x52\xf6\x8f\x16\x27\x2d\xed\xa7\xe5\xd4\x18\x28\x6b\xc3\x5c\xdc\x4c\x7b\xa6\x76\xdf\xd3\x1e\x86\xa2\xec\xa9\xcd\x02\x65\x38\xe5\x8d\x18\x66\xd3\x5c\x24\x54\x7d\xc4\xb5\xd6\x22\x9a\x1a\x52\x68\x9a\x7c\x0f\xbc\x4e\x2b\xd6\x8a\x0b\xa9\x2e\x0b\x67\x94\x06\x87\x39\xb1\xc0\x1c\xa7\xb5\x4b\x09\x8e\x67\x4b\xa9\xe8\x24\xcf\x77\xc7\x3f\xf0\xf4\xa6\xdd\xcc\xc3\x9d\x1b\x72\x55\x99\x4b\x55\xdd\x68\x16\xd9\x5f\x18\x86\x58\x9f\xb0\xec\x2f\x35\x13\x1f\x1b\x26\xbf\x1d\xcb\x1a\x4c\x13\x8e\x36\x18\x7c\x84\xc1\xe4\xe3\xe7\xe7\x56\x25\x45\xb7\x23\x08\x24\x92\xb3\x83\x74\x06\xdb\xe1\x22\xbe\x64\xea\xa0\x98\xf4\xab\xdd\xeb\x66\xe0\xbb\xe6\x25\x99\xce\x59\xaa\xe1\x1a\xc8\x5d\x79\xb6\x2a\x44\x52\x64\xbb\x68\xb7\x0a\x1c\xe3\x03\x7c\xe3\x98\x4a\x15\x3d\x03\xad\x37\x87\x86\x44\xbd\x56\x2d\x2d\x17\xb6\xb3\x4a\xa9\x4d\xfd\xaa\x95\x52\xd3\x5a\x22\x57\xa9\x2b\x66\xfb\x1f\x65\x58\x89\x74\x74\x53\x3d\x8c\xd8\x0c\xbc\xa0\x21\xe4\xec\x5f\xd7\x21\x77\x1b\x21\x07\x75\x48\xa9\x04\xbf\x41\x2f\x00\x4f\x4c\xc7\xc4\xef\x07\xe6\xbf\xf0\x55\xc7\x1d\xde\xd4\x36\x7c\x6f\xc1\xa9\x0e\x7a\xba\xa9\xe7\x0f\x8a\xaa\x8a\x1b\xbd\x5b\x51\x9e\x1e\x17\xdd\x1b\x13\x39\xc2\x96\x43\xa1\x88\x24\x89\x5f\xc9\x1b\xda\x85\xcc\xb2\xd8\xfc\x48\xbb\xac\x92\x3c\x2a\x4d\x09\x3a\x11\x29\x94\x12\x8e\x3f\x57\xc6\x41\x93\x8c\xf5\x6c\xe7\xdf\x17\xb3\xa0\xe9\x48\x5a\x2f\x54\xe5\xf5\xee\xfc\x9c\xcb\xfc\x2e\x67\x0d\x36\xba\xac\xab\x24\xa6\xb7\x5e\xb3\x8a\x0d\x91\x6c\xe0\xd2\xb0\x4d\xd5\xf9\x74\x6c\xbd\x4a\x38\xf3\xbd\xfc\xd0\xd7\x0b\x1a\x0e\x9e\x20\xf5\xd1\x57\xeb\x00\x36\xd7\xe9\xce\xa1\x31\x7c\x35\xa3\xd2\xf5\xea\x3a\xa0\x74\x92\x40\xca\x6e\x51\x28\x7f\xdd\x81\x23\x37\x37\x4c\x6b\x01\xda\xfc\xe0\x5f\xff\x6a\xc1\x38\x6e\xc4\x18\x5c\x77\xaa\x31\x61\x29\x6e\xc9\x8f\x63\xc7\x44\x00\x5f\x2a\x9d\xb5\x8c\xf9\x92\xc5\x12\xd6\x8e\xe2\xd2\x70\x56\xb3\xbb\x81\xa3\x46\x2f\x60\x38\xdb\xc0\x71\xf3\xc2\xff\x5a\x26\x14\x5f\xd4\xd9\x28\x93\xd2\xde\xaa\xc1\xda\x1d\x3b\x7f\xfe\x65\x7d\x07\xfd\xce\xe7\x4a\x08\x96\x1e\xd2\x97\xf3\xf0\x5c\xa1\x65\x58\x5b\xc3\x6c\x39\x94\x6c\x8a\xba\xed\x1d\x07\x63\x64\xbf\x5a\x0b\x30\x7e\x2b\x5c\x90\x29\xfe\x5a\xdf\x77\x1c\xf0\x4f\x55\xf0\x4f\x75\xf0\x05\x97\xa6\x24\x9c\xad\x8d\x6c\xa4\x20\x27\xd2\xa9\xc6\x94\xe5\xa7\xbb\xbc\x2e\xe3\x66\xe9\x5e\x98\x25\xab\x5e\xa7\xb0\x73\xbd\x11\x96\xec\xbc\x74\xb2\xf7\x24\xcd\x14\x2b\xd6\xac\x84\x74\xda\x26\x34\x49\xbc\x20\x2b\xdc\x84\x31\x11\xe6\xac\xa9\x3a\x5d\x56\xb2\x6c\x3b\xe0\x0b\x12\x51\xb5\xf1\x02\x18\x74\x6a\xc2\x15\xcc\x27\x48\x2a\xab\xf4\xcf\xe2\xfe\x91\xc5\xa6\x07\xc5\xe9\xdf\x27\x4e\xcd\xe7\x7c\xbd\x34\x19\x03\x33\x35\x4f\xfc\x29\x2a\x27\x97\x3f\xb5\x25\x11\xbf\x66\x77\xcd\xb1\xa6\xa2\x2a\x41\x1d\xff\xb7\xc7\x65\x5a\x05\x07\x69\x99\xba\x19\x42\xe7\x8d\xe6\xfe\x84\x06\xcb\x7f\x34\xc3\xea\x3c\xf6\x20\x5b\xbf\xf5\x00\xad\xd4\xd2\x69\x51\x67\x94\xd0\xe8\xa6\x5d\x95\x72\xc6\x57\x67\x8e\x26\xf5\x2a\x8b\x83\x7c\x61\x06\x90\xba\x72\x48\x17\x13\xd8\xe4\xe4\x2d\x53\x4b\xaa\xe8\x2d\x26\x1b\xd8\x8e\xb7\x35\x99\x65\x12\xc3\xd8\xd6\x8a\xb6\x67\x48\xd4\x9c\x2c\xb6\x01\xed\x49\x0f\x74\x61\xbc\x54\xe6\xf2\xca\x6a\x46\x94\xb9\x47\x65\xc3\xdc\x8c\xa0\x46\x33\x23\x9a\x6d\x49\x66\x37\x7f\x92\x8d\x41\xd4\x43\xa4\x79\x54\x7e\xd3\x24\x25\x1d\xc2\x07\xae\x40\x2e\x05\xc2\x6a\xb6\x81\x2e\xbc\x4d\xaf\x12\xa5\x84\xe3\xbd\x94\xa2\x8d\xa7\x74\xfe\xa5\xdd\x75\xb2\x81\x84\xde\x68\x76\x89\x0a\x1b\x1c\x44\x2a\xc1\x9f\xe4\x1f\xb4\x1b\xd4\xf1\x2b\x53\xa7\x59\x0d\xb7\xe2\x14\x0e\x6b\xf0\x69\x9c\xfe\x96\xc5\xb8\x86\xa1\x46\x97\xf8\x96\xd9\x35\xaa\xf3\xad\x13\xa5\x04\x1d\x2f\x15\xfa\x1e\xd5\x30\x5e\x75\x25\xda\x0b\x5b\x54\xfe\x98\xa7\x54\x45\x26\x7b\xe5\x52\xbf\xae\xe4\x63\x65\x7f\x10\x5a\xc6\xd3\x33\xbc\x4e\x1e\x9a\xb8\x3e\xb5\xe4\x31\x1c\x41\x2b\x1c\x7d\x9d\xa3\x71\x64\xb0\xf7\x24\x3a\xae\x2b\xad\x89\x9c\xd6\x3d\x1b\x33\x48\x8d\x7e\x00\x55\x82\xf5\xc5\x78\xff\xb2\x7e\xec\x92\x7e\xc0\x7f\xa4\x89\xaa\xcb\x8d\x69\x6a\xa9\x66\xb8\x70\x58\x65\xeb\xae\xa2\x88\xc7\xce\xfb\xd3\x67\xa7\xe9\xc8\xab\x34\x45\xf9\x59\x56\xa7\x6d\xc7\x6b\x63\x27\x34\x0a\x83\x21\x34\x98\xb8\xe9\xf2\x9a\xf7\x9a\x7a\xfd\xe8\xbe\xbd\x34\x07\xca\x36\x88\x1f\xec\xd2\xcf\x36\x87\xd4\x7e\x5c\xa6\xbf\xe5\xf6\xfb\xe4\xe5\x96\x7a\x92\xa6\xa5\xf0\x4d\x5d\xc8\xa3\x4d\xe9\x09\x16\xf4\x6f\x86\x16\x7f\xf0\x5e\xd8\xb0\x6d\x54\xae\xce\xfc\x69\x9b\xc7\xfa\x27\xae\xd3\xe3\x9d\x66\xc5\xae\xab\x0b\xc3\x94\xf9\xd2\xc3\xb8\x16\x1c\xd3\xdd\x84\x37\xcb\x8e\xe1\x5a\x10\x6d\x7f\x13\xa6\x86\xb2\x9a\x78\xa4\xb1\xa5\xc5\xb4\x32\xa5\x5b\x22\xd2\x4b\x5b\x23\xce\x93\x7a\xba\xd2\xcc\x15\x8d\xbd\x6a\xad\xc8\x63\x3c\x4a\xe7\x65\x38\x84\x7e\xe3\x19\x42\x3e\x4e\x71\x01\xd3\xed\x6f\x4c\xcc\x6a\x88\x3a\xd5\xbe\xb7\xd4\xfd\xe0\xb6\x74\xff\x46\x91\x85\x85\x99\x76\x03\x68\xe1\xe7\xc0\xe5\xeb\xde\xfd\xa1\xcd\x8e\x02\x6b\x69\x5d\x78\x55\xb6\x93\x20\x35\xa7\x1d\x18\xf4\x1f\xb5\xa9\xa7\x56\x12\x64\xe6\xd4\x80\xf8\xc7\x78\x6f\xab\x92\xff\x98\xf3\xfe\xaf\x5d\x9c\x4f\x99\xee\x9d\x96\xe9\xee\x0e\xfa\x2d\xf3\xd9\x6d\x9b\xcd\x47\x39\xe7\x4a\x3d\xac\xbe\x07\xc7\xee\x29\x26\x49\x92\x9f\x4d\xee\x60\xae\xfa\x54\x8f\x39\x42\x81\xf1\x32\x42\xdf\x17\x01\x24\x01\xd0\x00\x48\xa7\x7c\x76\x51\x3d\x29\x49\x9c\x43\x8a\xc3\x32\x54\xba\xf1\xa4\x80\x45\xa5\x7d\x70\xdd\x0c\x78\xca\x63\x53\x64\x76\x8f\x41\x5c\xac\x16\xfa\x59\x12\x50\xbd\xfe\x73\xe5\xd2\xbd\xae\x95\xd3\x3f\x1f\x29\x71\x5c\x4f\x1c\x8f\x54\x7c\x0c\x47\xe3\x63\x78\xfe\xa5\x18\xbb\x7f\x7d\x07\x47\xbd\xf1\x31\x1c\xf5\x54\xfc\x58\xa4\xdd\x12\x52\xdd\xcb\x64\x58\x60\x26\x79\xe8\x99\xc0\xe3\xe0\xf9\x97\x92\x5c\x77\xde\x71\xd1\xa2\xc9\xde\xdd\xcb\x47\x4f\x89\xe3\xcf\xb0\x03\xc2\xda\x46\x00\x9e\xe7\xde\x2a\x51\xc4\xde\x8e\xff\x7c\x64\x9e\x8e\x41\xeb\xc0\xf0\x61\x6d\xc2\x72\xaa\x7f\xeb\x9c\x59\xc2\x25\xa2\xd3\x96\x1d\xbe\xa4\x2d\x7a\x2c\x78\xfe\xa5\x30\x28\x2d\xae\xa5\xfb\xb9\x74\x62\xff\xf9\x03\xd1\x2e\xf7\x68\x7c\xfc\xfc\x4b\x6c\xc3\x52\x23\xc5\xd1\x58\xf4\x0a\x21\xfe\x6a\xb2\x84\x14\x48\xa7\x0a\x0d\x30\x1f\x8a\x5c\x21\x05\xcc\x13\x86\x0c\x1a\x1c\xf0\xe7\x5f\x0c\x3b\x77\x4e\xc3\x84\x8b\x39\x51\x67\x44\x99\xaa\x40\x76\xa6\xd9\xb9\x83\x6e\x53\x27\xb2\xb8\x73\xf7\xb9\xba\xbc\x1a\x6a\x20\x71\xe5\xd4\xe5\xf3\x51\x4c\x6f\x81\xc6\x43\x4f\x51\xb6\xe9\x66\x85\xe4\xe3\xfb\x34\xf1\x19\x76\x72\x46\x3f\xdf\xa3\x8d\x12\xdc\x23\x34\x52\xc1\x30\x2d\x0d\xb2\xea\x7d\xb1\x73\x77\xd4\x8b\xe9\xad\x9e\xbf\x8a\xcc\xe5\x8d\x21\x76\x6f\x11\xc7\xa1\xdd\x27\x1b\x6e\xf2\xff\xdb\x6a\xf8\xa9\x7c\xef\x9c\xa8\xa6\x59\xb2\x9c\x43\xca\xba\xb5\xfc\x6a\xa8\xf1\x47\x31\xf4\x81\x57\xef\xc2\x3f\x9e\xa7\x92\x4e\xab\x18\x15\x03\x62\xb8\x02\xdd\xe9\xc7\x9d\x50\xf1\x5f\x3e\x9e\x5e\x2a\x41\xd9\xd4\x2f\x1f\x42\xd4\xee\xd7\x14\x74\xec\x7b\x19\x98\x94\x4e\x40\x9c\x10\xdc\xf6\xcb\x75\xa9\xb0\x9d\xaf\x07\xc7\x67\xac\x60\x08\xef\x89\x9a\x99\x63\xed\x12\xa8\x5e\x1d\xd0\x6d\x42\x0f\x8a\xf8\xc4\x8e\x43\xe5\x3b\x32\xc6\xe4\xe7\x74\xbf\xf5\xe5\x1a\x8e\x4b\x77\x21\x7b\xb0\x0b\xff\xab\xd9\xd9\x81\x15\x1c\x95\xba\x0e\x74\x73\x17\x56\x70\x0c\xfd\x8c\x31\x4c\xf2\x29\xc9\x4f\x71\x04\x46\xaa\x7e\xb6\xa5\xb7\x65\xb9\xae\x35\xe7\x3b\x70\xe3\x75\x44\xe8\xda\xfb\x71\xe5\x0b\x4e\x9d\x1a\x95\x7c\x7f\xaf\xf5\xa4\xd9\x59\x5b\x99\xb7\x00\xcf\x0f\x9b\xf2\x8c\xb4\x7c\xa0\x67\x5e\x60\x82\x21\xf4\x8b\x0b\x7a\x3f\x09\xca\x8a\xb3\xfd\xb4\xd6\x66\xca\x83\xe6\x2a\x19\x1f\xff\x03\x23\x7b\xaa\xec\x5c\xb6\xc8\x6e\x3f\x16\x61\x5a\xda\xe5\x2e\x5b\x3b\x59\x69\xc7\xe5\xaf\x65\xdb\xe0\x6e\x59\xc5\xd9\x8b\x4b\x48\x7f\x6f\xc6\xa9\x9b\x4a\x95\x5a\x29\x60\xf4\x0b\x16\x8e\xf4\xec\x99\x63\x23\xa7\x71\x27\x1f\xae\x03\xc7\xc6\x9a\x76\x60\xd5\xa9\x9d\x1f\xb1\x9d\x9d\x72\x58\x55\x3a\x50\xca\xd2\xf0\xf2\x59\x92\x7d\x45\x30\x2b\x0e\x38\x81\x6f\xe3\xa9\x92\xde\x53\x6d\x78\xe3\x79\x0d\xc9\x95\xad\xb0\xb5\x94\xce\xf2\xf8\xeb\xbe\x64\xc7\x31\xf4\x87\x0c\xbe\x62\x81\xda\xf0\x73\x8d\xb5\x42\x6d\x5a\x97\xc0\x0b\xe8\x87\x83\x57\xad\x88\x42\xd3\x7f\xdd\xde\xbd\xb9\xb7\xfb\x81\xe5\xa7\xc7\x6e\x47\xce\x56\x5d\x6e\x72\x1a\xfc\xfb\x76\x56\x1f\x55\x74\xe3\xb5\x72\x49\x2b\xbd\xc6\x33\xec\x33\x22\x6e\xae\xf6\x1a\x2e\xe9\x94\x90\xba\x19\xef\xde\x60\xb1\x6e\x9f\x3b\x5b\x9f\xb3\x57\x87\xda\x81\x9a\xcf\x31\xfb\xf0\xfc\x4b\xf7\x9e\x9b\x99\x15\x2a\xb6\x7a\x10\xe8\xb5\xd2\x00\x93\x7b\xa7\xac\xa2\x9f\x1d\x85\x67\x10\x77\xe5\x7a\x8e\xb5\xfa\xac\x54\x40\x14\x7c\x37\x04\xb6\x4c\x92\xd2\x1d\x48\xa7\xbf\xc1\x2d\xe9\x9d\x53\x2a\x32\x5f\x54\xd7\x4d\xaf\x07\x24\x8e\x61\x9c\x90\xe8\xc6\xbc\x81\x06\x73\x22\x6e\xf4\xfe\x6b\xef\x08\x98\x45\x4c\x58\x0c\x5d\x18\xf4\x06\xfd\xec\xe7\x1f\xb8\x9c\x1c\xf7\x95\x73\xf9\xc2\x5c\x60\xba\x77\x7d\xbd\x81\x17\xe0\x37\x1b\x7a\x4f\x6f\x94\x5f\xbb\x4a\x7a\xd0\x6e\xf3\x99\x9d\xed\x3e\xb4\x2a\xbc\xd5\x8c\x2a\x6c\x97\x3b\xb3\x8f\x62\x5a\xee\xb1\x92\x72\x01\xaf\x6a\x2b\x55\xca\xb1\xbd\x9e\x93\x95\x95\x0a\x9b\x2a\xdf\xb8\x77\x63\xcc\xb8\xcd\xa4\xf2\xee\xaf\xb0\x28\x81\x71\xd9\x9e\x14\x5f\x94\x8c\xe9\xd5\x7f\x87\x2d\x7d\x13\x73\x10\x18\xff\xe7\x8c\x21\x33\x85\xac\xb3\xcd\x24\x30\xc9\x35\xad\x5d\xa4\x1b\xf5\xe9\xdf\xd9\xc6\xdb\x14\x0b\x96\x22\xd1\xff\xb5\xa1\xe5\x2b\x1b\x63\xea\xd0\x73\xc7\x55\x62\xf5\x24\xae\x7a\x63\xa9\xdf\x78\x63\x29\x8b\x1e\xba\x63\x22\xba\x89\x1e\xac\x26\x7c\x56\xd7\xd1\x5c\x76\x09\x8b\x66\x5c\xd4\x59\xf3\x90\xc5\x1e\x1c\xa4\xb7\xb2\xbd\x4e\x39\x27\xc3\x5b\x92\xfc\xbf\xcb\x0b\xc1\xe7\x3f\xa8\x79\xe2\xcf\xd4\x3c\x71\xcb\x3c\x0c\x57\xe9\xa1\x87\xfb\x46\xbd\xcd\x17\xd2\x0e\x7f\x3b\xa6\xb7\xdb\xa9\x62\x0b\xf8\x90\x32\x86\xe2\x87\x8f\xef\xdf\xc1\x10\x34\x59\xe7\xb5\x92\x48\xd0\x85\x92\xf6\xca\x7d\x06\x5e\x7a\x23\xf1\x23\x99\xda\xf7\x11\x2d\x68\x16\x40\xe9\xa0\xca\xd7\x14\xa8\x89\x64\x81\xea\xb0\xce\x12\xcb\xde\x25\x87\x9d\x1d\xea\xae\x4f\x2d\x9f\x9f\xc2\x5c\xd1\xeb\x82\xab\xc6\xb7\x15\xab\x57\x5d\xd6\x01\x6c\x5c\x75\x38\x97\x6c\xd6\x87\xd5\xd6\x4f\x30\x84\x8d\xb3\x81\x35\xe4\x26\x2e\x67\x95\xda\x9c\x48\x17\xa5\x5f\x7e\xb5\x2b\x1b\xb1\x03\x3b\xe0\x2d\x4a\x65\xcb\x0a\x81\x04\x27\x1a\xdf\xf8\xb4\xe6\xe4\xb5\x19\x21\x97\xe9\xa1\x01\x32\x0e\x9d\x11\x0a\x61\x37\x25\x61\x3f\x3d\x20\xac\xdd\x69\xcb\xd2\x7e\x2a\xa4\xfd\xf4\xb0\xb4\x8a\x2f\xee\x17\xb6\xd7\x83\xb7\x0a\x12\xce\x6f\x64\xf6\x51\x92\x29\xe7\x93\x8d\xe6\x76\xc3\x97\xf6\x83\x27\x21\xec\xf6\x17\x6b\xa0\x12\xc8\x58\xc7\xef\xe6\xbb\x1a\xf4\x77\xd4\x8e\xda\x7c\x3c\x85\x2f\xa5\xf9\x58\x0a\x81\x41\x7f\xbf\x6f\x3e\x4e\x82\xf9\xb7\x4a\xee\xe7\x2d\xb7\x8a\x1d\xd8\xed\x3f\x28\x4f\xae\x91\x46\xed\x3e\xa6\xf0\x9d\x11\xcc\x1d\x08\x9d\x32\x2e\xb0\x5b\xbb\xca\x6a\x8e\x54\x1e\x30\x91\x07\x89\x14\x8e\xa8\xbc\x82\x5a\x8e\xef\xd2\xb3\x3b\x7b\x8c\xda\xb2\xa2\x6a\x77\xd6\x2a\x6b\xab\x76\x49\xed\xb1\x9a\xd1\x74\x9c\x77\x0d\xb5\xa3\x83\x61\x4b\x05\xae\xb4\xb1\x3c\xf9\x50\xe8\x8f\xba\xa2\xd0\x76\xe3\xa8\x28\x41\x36\x58\x92\x39\x7c\xa9\xc8\xe9\x80\x3d\xe9\x1a\xdf\x43\x9f\x44\x69\xb6\x9e\xe6\x7b\xa8\xe9\xa4\x3b\xb9\xf9\x43\x13\xff\x98\xc9\x87\xbc\x64\x90\x89\xfc\x33\xfe\x73\x89\x52\xfd\x44\xcc\x21\x4e\x51\x08\x29\xe0\x9f\x87\xe4\x1f\x64\xed\x97\xa7\x75\x29\x92\x83\x26\x1a\xe5\x79\x89\x89\x22\x07\x4d\x67\x8e\x09\x8d\x6e\x7e\xb3\x33\xd6\x74\xb3\x53\xef\x6b\xa6\x32\xd7\xf0\x72\x02\x33\xd5\xc2\x36\x5b\x7a\xac\xb5\xb4\xdb\xdc\x5d\xf9\xa7\x5c\x46\x11\x4a\x79\x00\xf7\x7d\x6b\xe4\x11\x06\x50\x3f\x59\x85\x06\x2b\x2c\x7f\x84\x24\xfb\xab\x84\x1b\xad\x70\x8f\x30\xd6\x96\x85\x71\xe7\x6e\xec\xcf\xf3\x2f\x1e\x74\x42\x81\x24\xde\xe4\xe1\x7c\x7e\x7f\xba\xd7\xbb\x34\x9f\x37\x5a\x03\x49\x12\xbe\xc2\x18\x6c\x91\x53\xbb\x79\xa2\xb0\x67\x3e\xcd\xa5\x38\x30\xbe\x32\xf0\xd6\xe6\x18\x5f\xa5\x6f\x0c\x9a\xea\x6a\xa9\x48\xb9\x54\xd1\x87\x72\x37\xe3\x2b\x6d\x07\xbf\x7c\x3c\xbd\x58\x26\xc9\x27\xf3\xfa\x79\x00\x45\xeb\x7b\xce\x74\xe8\xed\x36\x59\xb2\x6e\xcb\x0f\x7c\x29\x64\x05\x8f\xb2\xa5\xc2\x4a\xe3\x25\x46\x9c\xc5\xb2\xb8\x87\xd5\xeb\x65\xdf\xfe\x58\x4a\x14\x85\x78\xc8\x62\xfb\xe1\x31\xce\x60\x49\x81\x4c\x14\x0a\x6b\xcf\x20\x97\xe3\x39\x55\x30\x5e\x2a\xc5\x19\x98\x52\xd6\x44\xa0\x9c\xd9\xef\xae\x91\x29\x3a\xaa\xd3\x3f\xb3\x97\xd7\xb4\xa2\x7e\xf9\x78\x9a\x93\x9d\x50\x21\x95\xf9\x3a\x0e\x65\xd3\xdc\xa7\x6b\x36\xb4\x7c\x30\x4c\x75\x95\xdf\x68\x34\xdf\x6f\xd1\x7e\xbd\xce\xe4\xcc\x44\xea\x98\x7f\xba\x6a\x0f\xa4\x15\x34\xdf\x0a\x24\x4a\x49\x39\xbb\x54\x5c\x90\x29\x6a\x6d\xbc\x55\x38\xf7\xb7\x25\xaa\xcb\x94\xdc\x39\x8b\xf5\x62\xdc\xee\xc0\x77\x43\x9b\xfe\xe5\x76\xf3\x3f\xff\x03\xdf\x99\xd9\x0a\xcd\x25\x89\x27\x51\xeb\xc0\x51\x31\xd9\x99\x74\xc5\xca\x87\x2e\xec\x99\x8c\xac\x58\x66\x8e\x0a\x72\xc4\xf6\x11\xab\xc3\xb9\xef\x34\xe7\xc3\x49\x54\x99\x3d\xb8\x2c\xe4\x36\x02\x5d\xa8\xb2\xf6\x3b\x67\xf8\xe3\x64\x22\x51\xe5\xd7\xc1\xca\xe4\x92\x84\xa6\x5a\xf6\x4d\x5c\x92\x7e\x67\xab\xe5\x6b\x3c\x75\x4e\xb3\x4f\xa1\x14\x64\x15\x7f\x7b\xf9\x63\x76\x08\x11\xca\x84\x46\xe8\xf7\x03\xe8\x0e\x32\x6b\x7d\xee\x6f\x3f\x63\x7c\xb5\xdd\x09\x8d\x29\x3a\x0b\xb6\x5a\x5f\x16\x28\x51\x7d\x68\x5c\x88\x60\x5f\x65\x34\xdd\xf7\x49\xf2\x95\xd2\xe4\xa4\xef\x93\x26\x77\xbb\xe5\x69\xb5\xef\xa5\xb7\xcc\x6c\x2b\x96\x6c\x33\x86\xe0\x31\xcc\xb8\xd7\xa5\xf4\xff\xfe\x2f\x00\x00\xff\xff\x79\x05\xf5\x67\x1e\x54\x00\x00") +var _webfilesSloop_uiJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x7c\xfb\x73\xdb\x36\xf2\xf8\xef\xfe\x2b\xf6\x98\xcc\x99\x8a\x25\x4a\xb6\x93\xd4\xf5\xeb\xc6\xb2\x9d\x6b\xbe\x97\xb4\xfd\xd6\xe9\xb5\x19\x8f\xa7\x81\xc8\x95\x84\x33\x45\xf0\x00\xc8\x96\x9a\xfa\x7f\xff\xcc\x02\x7c\x80\x2f\x3f\x72\x6d\xef\xdc\x99\x86\x22\x16\x8b\xc5\x62\x77\xb1\x0f\x10\xc3\x17\x1b\xf0\x02\x4e\x45\xba\x96\x7c\x36\xd7\xe0\x87\x3d\xd8\x19\x6d\x7f\xdd\x07\xc5\x62\x54\x53\x21\x43\x0c\x42\xb1\xe8\x03\x4f\xc2\x80\x60\x4f\xe2\x18\x0c\xac\x02\x89\x0a\xe5\x0d\x46\xe6\xfd\xc5\xf7\x67\x3f\x0f\xde\xf1\x10\x13\x85\x83\xb7\x11\x26\x9a\x4f\x39\xca\x7d\x18\x5f\x9c\x0d\x76\x07\xa7\x31\x5b\x2a\x24\xc0\x37\x42\xc2\x74\x19\xc7\x10\x5b\x60\xd0\xb8\xd2\x7d\x50\x88\xf0\xee\xed\xe9\xf9\xb7\x17\xe7\x81\x5e\x69\x98\xf2\x18\x81\x27\xa0\xe7\x08\x12\x53\x01\x52\x08\x0d\x42\xc2\x5c\xeb\x54\xed\x0f\x87\x22\xc5\x44\x89\x25\x11\x28\xe4\x6c\x98\x61\x53\xc3\xda\x78\xc3\x8d\x8d\x50\x24\x4a\x43\xca\x62\xd4\x1a\xe1\x08\x3e\x6f\x00\x00\x4c\x98\xc2\x33\x26\xaf\xf7\xe1\xd2\x7b\xb6\x73\xbe\xfb\xf2\xe5\xc8\xeb\x83\xf7\x6c\x77\xfc\x72\xe7\xd5\x8e\x79\x7c\xb9\xfb\xf2\xf4\xd5\xb9\x7d\x3c\x7d\xf5\xfa\xf5\x89\x77\xd5\x2f\xfa\xbe\x23\x26\x98\xce\x67\x7b\x67\xe7\xe7\x5f\x1b\xb0\xf3\x57\xe7\x5f\xbf\xb1\x78\xce\x4f\xcf\xdf\xbc\x79\x69\x1e\xdf\xec\xbe\xd9\x7d\x73\x9e\x77\x4e\x25\x5f\x30\xb9\x36\x5d\xf7\xde\x8c\x4f\xc7\x63\x03\xb4\xb7\x77\x3a\x3a\xb3\x5d\xf7\xb6\x4f\xb6\x4f\xb7\xcd\xe3\xab\xf3\xbd\xed\x93\xd3\xbc\xeb\x9c\xcf\xe6\x71\x31\xee\xf8\xcd\xeb\xed\xd7\x27\x06\xec\x6c\xb4\xf7\xd5\x57\xd9\xb8\xe3\xd3\xf1\x9e\x45\x79\xb2\x3b\x3e\xdf\x3b\xf5\x6c\x5f\xfa\xf3\x9e\x8d\x5f\xee\x9d\x9f\x9c\x79\x7d\xef\xd9\xc9\xd9\xc9\xde\xf8\x35\x3d\x45\xec\xab\xd7\xaf\x46\xf4\x74\xf6\xf2\xeb\xd7\x27\x5f\x99\xd6\xf1\xe9\xcb\x93\x71\xa5\xeb\xc9\xcb\x93\xd7\x67\x3b\xd4\xf8\xf5\xf6\xf8\xfc\x8d\x7d\xfa\x6a\xbc\x7d\x62\x90\xec\x9d\x7c\x3d\x7e\xbd\x97\x13\xaa\xf0\x06\x25\xd7\x34\xc9\xcd\x67\x2f\xc7\x67\x7b\xaf\x5e\x6d\xf6\x61\xf3\xd9\xf9\xe8\x7c\x34\x1a\x99\xc7\xb3\xbd\x97\xe3\x97\xe3\xcd\xab\xfe\xc6\xdd\xc1\xc6\xc6\xc6\x70\x08\x7f\x8f\xc5\x84\xc5\x0a\xde\xf1\x1b\x84\x6f\x50\xe2\x46\x8c\x1a\xb4\x48\x4f\x56\x5c\xf5\x61\x22\xb4\x16\x0b\x7a\x3e\x30\xe0\x1f\xe6\xa8\x10\xa6\xcb\x24\xd4\x5c\x24\x0a\x66\xa8\x21\x64\x71\x8c\x11\xdc\xce\x31\x21\x0a\x8c\xf4\xa4\x52\xa4\x28\x35\x47\x05\x62\x0a\xc8\xf5\x1c\x25\xb0\x15\x57\xc0\x24\x42\x38\x67\xc9\x0c\x23\x77\xa8\x33\xc9\x6e\xdf\x2c\x93\xd0\x1d\x32\x7f\xe7\x0e\x4d\xdd\xa3\x5d\x50\x5a\x2e\x43\xad\x0c\x86\x15\xc1\x5e\x84\x2c\xc6\x3e\xac\xe9\x79\xcc\x92\xc8\xf6\x39\x91\x92\xad\x21\x14\x89\x66\x3c\xe1\xc9\x0c\x22\xa6\x19\x48\xd4\x92\xe3\x0d\x46\x30\x95\x62\x01\x2a\x16\x22\x05\xa3\x56\xd2\x20\x24\xa0\x62\x4c\xd0\x7c\x81\x10\x71\x95\xc6\x6c\x8d\x11\x88\x04\x42\x94\x84\x0f\x16\x62\xa9\x50\xd0\x94\x59\x12\xd9\x5f\x0b\x71\x83\x80\x37\x98\x64\xb4\xe9\x39\x7e\xe0\x0b\x74\x67\x10\xe1\x94\x27\x68\xb8\xb4\x60\x2b\xbe\x58\x2e\x20\x92\xec\x96\xa8\x53\x29\x0b\x91\x46\xa0\xc6\x5b\x9e\x44\xe2\x36\x80\xb7\x10\x89\x64\x93\x50\xf1\xe4\x9a\xd0\xe8\x39\x57\xc0\x95\x01\x0a\x85\x94\x18\x6a\xb8\x65\x6b\x62\xf4\x52\x11\x1a\x6d\xc6\xb9\x61\x52\xc1\x00\xb8\x86\x48\xa0\x22\x0c\x12\x59\x1c\xaf\xc9\x84\xa4\xa6\x8f\x19\x80\x7e\xf2\x5f\x79\x32\x23\xd4\x34\x8f\x5b\xe4\x32\x82\x05\x4f\x88\x34\x65\x5e\x65\xb3\x07\x15\xb2\x98\x06\x08\xc5\x32\x8e\x20\x15\x9a\x2c\x8e\xc1\x19\x92\xe6\xd3\xaa\x4f\x62\x5c\xa8\xc0\xb2\xd1\xf6\x7a\xcf\x56\x3f\xf7\x9d\x1f\x1f\x2d\x33\xfe\x49\xe2\x11\xb2\xd8\x4c\x9a\x90\x4e\x50\xdf\x22\x26\x30\x61\x52\x65\xe6\x43\xa2\x35\x36\x63\x26\x73\xf0\x8b\x0c\xfa\x08\x46\xc1\x8e\xc5\xa4\x6e\x66\x20\x71\x8a\x12\x93\x10\x61\x2a\x24\x48\x4c\x22\x94\x86\xa3\x37\xb3\x8c\x29\xd1\xae\x21\x4a\xdd\xcc\x6c\xaf\x0b\x4e\xd0\xb7\xb8\x49\x02\x95\xf1\x9f\x86\x26\xf6\x9b\x7f\x6f\x39\x71\xdc\x70\x59\xb1\x05\x96\xa2\x75\xcb\x23\x3d\x87\x81\x5d\x51\xae\x60\xc1\xe4\x8c\x27\xd9\xba\xda\x65\xb1\x0b\x99\xcf\xc8\x9a\x53\x3b\x15\xc2\x0d\x03\xc3\x55\xae\x37\x95\x23\x9b\x84\x6f\x62\x16\xc0\x0e\x9c\x8d\x5d\x0c\x6b\xc9\x5f\xb0\x38\x1e\x33\xf9\xde\x8c\x79\xb0\x61\x5e\x66\x04\xe4\x46\x56\x8b\x74\x1f\x76\x46\xd6\x28\xc4\x38\xd5\xfb\xb0\x3d\x1a\x19\x8d\xcf\x64\x4a\x24\x66\xd1\xc9\x2e\xc7\x82\x45\x17\xff\xfc\xfb\xc1\xc6\x46\xae\xd4\xc0\x13\x4e\xab\xca\x7f\xc5\x33\xbe\xc0\x44\x91\xa2\xfb\xbd\x0c\xb9\xb3\xa8\x70\x04\x91\x08\x97\x0b\x4c\x74\x90\x3f\x9c\xc7\x68\x7e\x87\x31\xc7\x44\xff\x44\x9c\x3a\xa8\xf5\xfb\xf8\x70\xbf\x6f\x90\xec\xed\xc1\xc6\xdd\xc6\x46\x84\x9a\xf1\x18\xa3\x0f\x42\xc4\x1f\x78\xfa\x56\xfd\x93\x2b\x3e\x89\x89\xf4\x29\x8b\x15\x66\x2c\x48\xc4\x85\x90\xfa\x0d\x31\xa1\x98\x47\x41\xb3\x44\xbd\x94\x09\x58\x16\x58\xc9\x0a\xc5\x22\x65\x12\x2f\x34\x6b\xf4\x62\x7d\x98\xe4\x3d\xf9\x14\x7c\x16\x5c\xf3\x24\x82\xbf\x1c\xc1\xc4\x3c\xe5\x6d\x0e\xe6\x0c\xdb\x3f\x78\x12\xd9\xee\x06\xe0\xce\x1d\x9c\x05\x8a\xc6\x82\x01\x4c\xec\xd3\x01\x51\x53\x21\xe6\xbd\x50\xfa\xdc\x98\x8e\x3f\x85\xa2\x49\x40\xa6\x2b\x66\x6b\x15\xc4\x98\xcc\x48\xa4\x81\xd5\xdf\x35\xa9\xfc\x96\x2d\xf0\x4f\xa1\xcf\xdf\xdc\x84\x2d\x60\x01\xb9\x2a\xbd\x20\x16\x64\xe0\x4f\x6d\x37\x7f\x62\xdf\x1a\xea\x68\xf9\xc3\x45\x6a\x68\xca\xc5\xc0\x15\xe7\x4c\xc2\x0b\x69\x48\xd9\x9a\x5e\x91\x14\xee\x06\xff\x52\x22\xf1\xc9\xde\xff\xff\x25\xca\xf5\x8f\x32\xee\x1d\xb8\x40\x81\x9e\x63\xe2\x97\x33\x95\xa8\x96\xb1\x76\xe7\xd3\xae\x2c\x07\x45\x3b\x19\xa0\xa3\xcc\x20\xe5\xdd\xcb\xd6\x09\x4f\xa2\xf7\xb4\x6f\xd8\x75\xf7\xd5\xcd\xcc\x69\x65\x69\x8a\x49\x74\xb2\xc2\x7a\x83\x45\x47\x2a\xa1\x79\x9a\x8f\x76\x47\xec\xd8\x28\x66\x6b\xad\xdc\xf7\xd9\x64\xb5\x98\xcd\x62\x04\x75\xcb\x75\x38\x37\x7b\x98\xd9\x82\x41\x8b\xc2\xb8\xe7\x7c\xc9\x5b\x78\x78\xad\x4a\x2e\x66\xad\xa7\x73\x0c\xaf\x51\xfa\xe5\x72\xfb\x85\x2e\xcf\x30\x57\xe3\xf1\xfa\x6d\xe4\x7b\x6e\x17\xaf\x17\x84\xa6\x6b\x04\x47\x47\xa0\xe5\x12\x5d\x26\x9a\x6d\x3a\xa0\xcd\xb8\x0d\x9b\x1a\xaf\x4f\x63\xa6\x14\x49\x9e\x83\x95\xa8\xf4\x7a\xbd\x02\x09\xfd\x05\x0b\x96\xfa\x08\x47\xc7\x80\x81\xd2\xeb\x18\x83\x7c\x76\x47\xe0\x4d\x62\x41\x84\x64\xdc\x02\x8c\x15\xfe\x11\x34\xdc\x4f\x44\x22\x12\x2c\x68\x20\x03\x37\x1c\x02\x9c\x65\xed\x11\x9f\x9a\x6d\x4c\xc3\xbf\x49\x1c\x61\x81\x7a\x2e\x22\x65\x5c\x5f\xe3\x79\x48\x16\x71\x01\x37\x2c\x5e\x62\xb9\x34\x06\xd6\xd2\xe2\x1b\x00\x57\x17\xcd\x8b\xc0\xf4\x80\xa3\xa3\x23\xf0\x24\xce\x70\xe5\x7d\x29\xf7\xb3\xde\x5f\xca\xf5\xa7\x33\x5a\x6a\x4e\x93\x7c\xd2\x90\x55\x1e\x77\x72\xc2\x41\xfe\xa7\x71\xc3\x25\xed\xcf\x61\x46\x55\xea\x33\x89\xbb\x98\x8b\x5b\xe3\x5d\x60\x12\x91\xdf\x48\x8f\xa5\x8b\x9b\x39\x86\xbe\xf1\x8e\x8d\x3b\x63\x7c\xe3\x4d\x05\x38\x9d\x62\xa8\x29\x54\xb0\x02\x2a\x49\xe8\x7a\x99\xab\x42\x88\x31\x89\x06\xc6\x61\x9e\x88\x55\x9f\x9c\x9b\x1b\x94\x1a\xc9\xfe\x18\x44\x13\xb1\xda\x54\x60\x6c\xb9\x05\x33\x10\x09\x4d\x2a\x30\xce\xb6\xd2\x42\x62\x64\x25\x9c\x7c\x5c\x72\x5f\x8c\x63\x1a\x8b\x04\xf7\x81\x25\x80\x8b\x54\xaf\xab\x70\xd7\x88\xa9\x02\x2d\x59\x78\x9d\xb9\xbf\x90\xe0\x2d\x2a\xeb\xc9\x1b\xbd\x41\x63\xcd\x4b\x9d\x59\xa6\x11\xd3\x78\x9e\x44\xe4\x9d\x8f\xc5\xca\xc7\x24\xfa\x31\xe1\xab\x0b\x0c\x45\x12\xa9\x5c\x20\x68\x6f\xc1\x24\x3a\x63\x26\x86\x4d\xf0\x16\xe8\xb1\x06\x0c\x2f\xc8\xbf\x1a\x65\x2c\xce\xc0\x03\x85\xfa\x3d\x4f\x96\x1a\x95\x9f\xbf\x9a\x95\xaf\x7a\x30\x00\xe7\x35\x51\xf1\xab\x48\xf0\xbb\xe9\x54\xa1\xf6\x7b\x6d\xb8\xe2\x98\x2b\x3b\xa0\x9f\x2c\xe3\x7c\xa3\xea\xb2\xbe\x9b\x0a\x63\x0c\x35\x46\xd9\x1c\x37\x7b\xb9\xe8\x17\x58\xb5\x78\x7b\xf1\xdd\x85\x26\x3f\xd9\xef\x05\x8a\x82\x79\x7f\xd4\x87\xc1\xb6\xd9\x48\x4a\x5e\x55\x37\x2f\x87\x33\x86\xbb\x47\xe4\xf5\x87\xa8\xd4\x49\x12\xd1\xe6\xfb\x43\xe6\xe8\xaa\xea\x6e\x97\xc3\x8f\xd7\xb4\xe7\xf7\x81\xfc\x02\xd5\x87\x29\x8f\x35\x4a\x24\x82\x28\xe4\x22\x48\xda\xb5\x8c\x3b\xef\x88\xde\x80\xfc\x85\x25\x09\x52\x5d\x02\x33\x59\x25\xaf\x5f\xe7\xc1\x1a\xc5\x99\xfb\x14\xf8\x48\x9c\x12\x13\x28\x88\x59\xe7\xb8\xc3\x98\x2d\x52\x23\x26\x56\x24\xcd\x24\xd8\x0d\xe3\x31\x9b\x94\xd9\x0f\x23\x5f\x7d\x50\xc2\x84\xb5\x70\xc3\xd1\x04\x08\x14\x3b\x66\xa2\x37\x61\xe1\xf5\x32\x35\x72\x9f\x61\x36\xe1\x2d\x92\x40\x30\xed\x0a\xa1\xc4\x50\xc8\x08\x23\x3b\x14\x4f\x94\x46\x66\xb4\x4e\x69\x89\x3a\x9c\x3b\xc4\x48\xfc\xf7\x12\x95\x51\x18\xbe\xc0\x82\x71\x34\xfc\x77\xa9\x8d\xb8\xc9\x99\x20\xbe\x06\xf4\xf2\x17\x91\xbd\xfd\xed\x37\xf8\x7c\x57\x72\xda\xf0\xe6\x27\xcb\x9a\x23\x20\x71\x39\x28\xec\xa0\x83\x2c\x30\x70\xbf\x58\xcf\xf4\xaf\x7f\x85\x66\x13\x56\xbd\xb7\x2a\xde\xcb\x2e\x54\x56\x21\xfa\xed\xf8\xb2\xd6\xab\xd2\x08\x36\x94\xb1\x9d\x8e\xdc\x84\x15\x33\xf9\x0b\x31\xd4\x25\xaf\xcc\x04\x58\xef\x8e\xe2\x55\xfc\x51\x87\x7e\x2f\x30\x96\xca\xbf\xb4\xa1\x52\x40\x66\xa5\x5f\x89\x65\x06\xe0\x34\x5d\x39\x16\x9a\x06\x72\xa6\xed\x0e\x57\x1d\x32\x88\xc4\x82\xf1\xa4\x02\x5c\xa2\xb9\x2b\x9e\x8a\x80\xce\xa1\x91\x7e\xfa\xbd\x20\x65\x51\x44\xda\xd8\x1d\xf7\xf6\x32\x25\x01\x1b\xe7\xb9\x59\x12\x8b\x8e\x84\xf0\x83\x48\xfd\x92\x2e\xd7\xdd\x6c\xa4\x56\xca\x4e\x63\xd3\xd6\xde\xcf\xd5\x52\x5a\xf7\xab\x76\x17\xaa\xd4\x6f\x8b\x36\x41\xa5\xfd\x5e\x70\x8d\x6b\x3f\xa2\xdd\x29\xb2\xd1\x40\x80\x89\x96\x1c\x95\xf1\xbb\x9d\x51\x8c\x49\xa0\x9e\x05\x1a\xb3\xb1\xe5\x5d\x71\xed\x4e\x7e\xc2\xe4\xa9\x88\x85\xfc\x3b\x26\xe5\x3c\x0c\x2f\xbf\x93\x11\x4f\x58\xec\xf7\xf2\x05\x31\x78\x73\x09\xc8\x32\x92\x41\x91\xd5\x73\x7d\xf5\x2c\x81\xd6\x81\xf8\x1d\x4f\x90\xc9\x12\xef\xe5\xa8\x0f\xdb\x7d\xd8\xb9\xaa\xe3\xce\xf1\xb8\xf4\x76\x8b\x66\x75\x2b\x6f\x0a\x11\xe9\xf6\x65\xb4\x1b\x2c\xb8\x8d\x54\xfa\x90\x71\xc4\xe8\x5a\xaf\x4f\xd8\x16\x6c\x55\x6d\x23\x7d\xb9\xaa\xa1\x7e\xb2\x0a\x3c\x42\x64\x5b\x89\x8f\x76\xb3\xb1\x88\xa4\x2c\x90\xac\xbb\x2c\x55\x62\xb4\x48\xfb\xe0\x82\xc3\x0b\xf0\x77\x47\xbd\x5e\x49\x94\x16\x69\x7d\x42\x4f\x53\x97\x6a\xea\xc4\x24\x90\xb6\xe1\x45\x39\xb7\x60\x92\xe7\x76\x4c\xf0\xd4\x2d\xfc\x41\x28\x92\x90\xe9\x80\xa5\x69\xbc\xf6\x2f\xaf\xfa\x1d\x12\x6b\xf6\x5b\xd5\xeb\xd0\xa3\x60\x2a\xe4\x39\x0b\xe7\x39\x74\x48\x42\x67\xf9\x6b\x1e\xfd\x9a\x84\xfb\x99\xf6\xf4\xaa\x76\xf0\x69\x46\xe0\xa9\x06\xa0\xd8\x50\xd4\xcd\xcc\x24\x73\xe0\xc8\xb5\x78\x76\x11\x7b\x97\xdb\x57\xb0\x05\xfe\x0e\xbc\x70\x25\xc8\xd9\xf8\xd5\xcd\xcc\xa6\x74\xe0\xc8\xe1\x77\x67\x6f\x2d\xd2\x5e\xe9\x0c\xc8\x2c\xa9\xba\xe2\x4a\xe7\x29\xbd\x22\xdd\x67\xf3\x93\x12\x43\x89\xe4\xa3\x71\x1d\x40\x1e\x97\x52\xc8\xec\x18\x27\x1b\x88\x93\xf4\x1a\xc7\xc8\xf7\x9e\x45\xbb\xbf\xcc\x51\x56\xdc\x71\x75\x33\xcb\xda\x4f\xe2\xd8\xdf\x7c\xb1\xd9\x0b\xec\xf0\x7e\x25\x9c\xb8\x07\x57\x81\x2a\xb0\xd1\xbb\xef\xa9\x9b\x59\xe5\xb5\xd6\xd2\xf7\x68\x87\x1b\x8b\x95\xd7\x87\x4f\x23\x18\xc1\xf3\xcf\x39\x83\xef\xec\xb3\x65\xd7\xdd\x27\xa7\x63\x48\x91\x00\x5a\x84\x83\x50\x24\x1a\x13\xed\xf5\x6d\x2c\x4d\xf2\x6a\x20\x89\x2e\x9a\x44\x3e\xf8\x2c\x9f\xdd\x70\x08\xa7\x96\x47\xe4\x67\xcc\x24\x4b\xe7\x26\xfb\x2a\x31\x95\xa8\x30\xd1\xcc\xf8\x7a\x62\x0a\xc8\xc2\x79\x91\xae\xb4\x48\xa5\x58\xa6\x64\x99\x67\x25\x35\x25\x97\xbc\xca\xf4\x48\x15\x7c\x57\xce\x9d\x36\x4c\x34\x4a\xbf\x85\x45\x2d\x0c\xd2\x92\x25\x6a\x2a\xe4\xc2\x23\xc3\xd0\x07\xde\x23\x35\xf9\x64\x5e\xc7\xe4\x83\x13\xd3\x0a\x59\xf2\x79\x0f\xb6\x6a\x1a\x7e\xd7\x73\xb9\x47\xb3\xf2\xad\x94\xfc\x50\x9a\x8b\x5c\xcc\x0a\x2f\xda\xd8\xdd\x0b\x33\x37\x21\x7d\x6f\x22\xa2\xb5\xd7\x0b\x4a\x06\x98\x87\x03\x37\x4d\xa5\x6e\x66\xe4\x2d\xe7\x36\x3f\x0b\x13\xde\xb3\xd4\xbf\xbc\xf4\xbe\x15\x72\xc1\x62\xaf\x3f\xba\xea\x5f\x7a\x3f\x31\x99\xf0\x64\xe6\xf5\xb7\xe9\xd7\xb9\x94\x42\x7a\xfd\x9d\x2b\x63\x69\xcb\x3c\xcb\xfd\xce\xb4\xe3\x7d\x3f\xe8\x14\x1e\x38\x9e\x52\xd6\x2c\xc5\xad\xea\xd5\x76\x6c\x38\x82\xcf\x77\xdd\x1b\x7a\x89\x9b\x3a\x97\xf6\xad\xea\x06\xe5\x09\xb8\x6a\x5e\xf5\xa0\x02\x93\x25\x9f\x2a\xde\x9d\x12\x52\xd7\x5d\x2a\x83\x8f\x29\x04\xcf\xec\x70\xe4\x09\x7b\xfb\x0d\x88\xc7\x8e\x9a\xff\x4d\x24\xb2\xeb\x66\x93\x1d\x28\x61\x8f\x1d\xc3\xa6\x3f\xbf\x60\x88\x85\x50\xda\x16\x86\x1e\x37\x90\x9b\x0d\x7e\xd2\x70\x11\x4e\xd9\x32\xd6\x1d\x83\x88\x44\x89\x18\x83\x58\xcc\x7c\xef\xc7\xe4\x3a\x11\xb7\x09\xd0\x22\xec\x83\x07\x5b\xd0\x58\x9a\x47\x8f\x7c\xb7\x51\xf9\x69\x45\xa6\x28\x49\xb8\x7f\x41\x10\x44\xfd\xc6\x5b\xb3\xd4\xfb\xb9\x57\xf3\x0b\x05\x04\x79\x18\xd1\x80\xc5\x24\xda\x07\xbf\x05\x94\x8c\x80\x1f\x05\xd1\x52\x5a\x6b\x96\xbd\x6d\x62\xc8\xb3\xdc\x34\x60\x91\xf1\x2e\xb2\x28\x4d\x9a\xc1\x5a\x50\xcc\xcb\x6e\xdf\xd9\x3e\x59\x19\x32\x2b\xfd\x44\xc0\x93\xae\x9e\xe9\xf5\x6c\x68\xea\x8c\x43\xb2\x30\x1c\xd5\x50\xaf\x53\x54\xc1\x4c\xb4\xf6\x30\x9b\x66\x1a\x73\xfd\x01\x57\xc4\x45\x34\xf9\xee\xc0\xbc\xf2\x3d\xf0\x7a\x9d\xbd\x6e\x85\x54\xfa\xa2\x34\x46\x99\x73\x58\x20\xeb\x9b\xd2\x7f\xf7\x2c\xc1\xb1\x6c\x19\x96\x60\x86\xda\x77\xc7\xdf\xf7\x68\xd3\x6e\xa7\xe1\xce\x75\xb9\xea\xc4\x65\xac\x6e\x15\x8b\xfc\x2f\x08\x02\x6c\x2e\x58\xfe\x97\x89\x89\x8f\x2d\x8b\xdf\xdd\xcb\x0a\x4c\x5b\x1f\x12\x18\x7c\x84\xc0\x14\xe3\x17\x35\xf6\x0a\xa3\xbb\x3b\x48\x64\x4a\x24\xfb\xd9\x0a\x76\xc3\x85\x62\x99\xe8\xfd\x72\xd1\x2f\x77\xae\xda\x81\xef\xda\x55\x32\x5b\xb3\x8c\xc3\x0d\x90\xbb\xea\x6a\xd5\x90\x64\x9d\xad\xd2\x96\x21\x6b\xcf\xd8\x00\xdf\x18\xa6\x4a\xf5\xc1\x40\xd3\xe6\x50\x26\x15\x8b\x0d\xac\x51\xd9\xa9\x16\xe1\xf2\xaa\x8e\x8d\x04\xeb\x55\x1d\xf3\xb6\x82\xae\x56\x03\xc9\xf7\x3f\x9e\x60\xcd\xd3\xa1\x57\x4d\x37\x62\xbd\xed\xf5\x5b\x5c\xce\xd1\x55\x13\x72\xa7\x15\x72\xbb\x09\xa9\xb4\x14\xd7\xe8\xf5\xc1\x93\xb3\x09\xf3\x47\x7d\xf3\x5f\xf0\xaa\xe7\x0e\x6f\xf2\xb0\xbe\x97\x0a\x4e\x4e\xcf\x20\xb3\xfc\xfd\x32\x03\xec\x7a\xef\x76\x2a\x4f\xf7\x8b\xee\xf5\x89\x9c\xc9\x56\x5d\xa1\x90\xc5\xb1\x5f\x8b\x1b\xba\x27\x99\x07\xb5\xc5\xf1\x9b\x2a\x4b\x0a\xaf\x34\x43\xe8\x78\xa4\x50\x09\x38\xfe\xd8\x39\x6e\xb7\xcd\xb1\x19\xed\xfc\xe7\xd3\x2c\x71\x3a\x33\x6d\x66\x4b\x8b\xda\x5c\x51\x93\x37\xbf\xab\x51\x83\xf5\x2e\x9b\x2c\x89\xf8\x8d\xd7\xce\x62\x83\x24\x1f\xb8\x32\x6c\x5b\x25\x31\x1b\x9b\xb4\x44\x24\xbe\x57\x1c\x50\xf1\xfa\x2d\x45\x72\xc8\x6c\xf4\xe5\xaa\x0f\xeb\xab\x6c\xe7\xa0\x1e\xbe\x9e\x73\xe5\x5a\x75\x72\x28\x9d\x20\x90\x9b\x1c\xbf\xbf\xea\xc1\x61\x4b\x36\x8c\xc4\x0f\x7e\xfb\xad\xa3\xc7\x71\x6b\x8f\xed\xab\x5e\xdd\x27\xac\xf8\x2d\xc5\xd1\x91\x09\x93\x20\x96\x9a\xa2\x96\x89\x58\x26\x91\x82\x95\xc3\xb8\xcc\x9d\x25\x72\xd7\x70\xd8\x6a\x05\x0c\x65\x6b\x38\x6e\x57\xfc\x2f\x25\x42\x8b\xb4\x49\x46\x15\x15\x59\xab\x16\x69\x77\xe4\xfc\xf9\xe7\xd5\x1d\x8c\x7a\x9f\x6a\x2e\x58\x76\xa0\xa8\x1a\x87\x17\x0c\xad\xc2\xda\x1c\x69\xc7\x01\x8a\x36\xaf\xdb\x9e\xc7\x32\x42\xf6\xb3\x95\x00\x63\xb7\x82\x94\xcd\xf0\xe7\xe6\xbe\xe3\x80\x7f\xac\x83\x7f\x6c\x82\xa7\x42\x99\xf2\x55\xae\x1b\xf9\x48\xfd\x02\x49\xaf\xee\x53\x56\x9f\xee\x8a\xbc\x8c\x1b\xa5\x7b\x41\x1e\xac\x7a\xbd\x52\xce\x69\x23\xac\xc8\x79\x25\x8f\xfd\x24\xce\x94\x1a\x6b\x34\x21\x5b\xb6\x29\x8f\x63\xaf\x9f\x27\x6e\x82\x88\x49\x53\x17\xaf\x2f\x97\x9d\x59\xbe\x1d\x88\x94\x85\x5c\xaf\xbd\x3e\x6c\xf7\x1a\x93\x2b\x89\x8f\x91\xd5\xb4\xf4\x8f\xa2\xfe\x91\xc9\xa6\x07\xa7\x33\xba\x6f\x3a\x0d\x9b\xf3\xe5\xb3\xc9\x09\x98\xeb\x45\xec\xcf\x50\x3b\xb1\xfc\xa9\x4d\x89\xf8\x0d\xb9\x6b\xf7\x35\x35\xd7\x31\x92\xff\xdf\xed\x97\x11\x0b\xf6\xb3\xac\x75\x3b\x04\xc5\x8d\xe6\xac\x17\x81\x15\x3f\xda\x61\x29\x8e\xdd\xcf\xf5\xb7\xe9\xa0\x55\xde\xf4\x3a\xd8\x19\xc6\x3c\xbc\xee\x66\xa5\x9a\x8b\xdb\x33\x87\x93\xa4\x65\x51\xbf\x50\xcc\x3e\x64\xa6\x1c\x32\x65\x02\x1b\x9c\xbc\x4d\xf4\x92\x6b\x7e\x83\xf1\x1a\x36\xa3\x4d\x42\xb3\x8c\x23\x98\xd8\x5c\xd1\xe6\x1c\x99\x5e\xb0\x74\x13\xd0\xd6\x17\x61\x00\x93\xa5\x36\x25\xb7\xdb\x39\xd3\xe6\xcc\xa7\x75\x73\x73\x84\xa6\xb2\x4c\x23\x9a\x6d\x49\xe5\xa7\x14\xe3\xb5\xe9\x48\x43\x64\x71\x54\x71\x2a\x2e\x43\x1d\xc0\xb7\x42\x83\x5a\x4a\x84\xdb\xf9\x1a\x06\xf0\x36\x3b\xf6\x98\x21\x8e\x76\x33\x8c\xd6\x9f\xa2\xf8\x8b\xcc\x75\xbc\x86\x98\x5f\x13\xb9\x4c\x07\x2d\x06\x22\x9b\xc1\x1f\x64\x1f\xc8\x0c\x92\xff\x9a\xe8\xd3\x3c\x87\x5b\x33\x0a\x07\x0d\xf8\xcc\x4f\x7f\x9b\x44\xb8\x82\x23\xea\xae\xf0\x6d\x62\x75\x94\xe2\xad\x13\xad\x25\x9f\x2c\x35\xfa\x1e\x27\x18\xaf\xae\x89\xf6\x70\x29\x57\xdf\x15\x21\x55\x19\xc9\x5e\xba\xd8\xaf\x6a\xf1\x58\xd5\x1e\x04\x96\xf0\xac\x72\xdc\x2b\x5c\x13\xd7\xa6\x56\x2c\x86\x33\xd1\x1a\x45\x5f\x66\x68\x9c\x39\xd8\x33\x5d\x3d\xd7\x94\x36\xa6\x9c\xe5\x3d\x5b\x23\x48\xea\xbe\x0f\x75\x84\x4d\x65\xbc\x5f\xad\x1f\xab\xd2\x0f\xd8\x8f\x2c\x50\x75\xa9\x31\xaf\x3a\xb2\x19\x2e\x1c\xd6\xc9\xba\xab\x31\xe2\xb1\xeb\xfe\xf4\xd5\x69\xab\x80\x55\x96\xa8\x28\x6d\xf5\xba\x76\xbc\x2e\x72\x02\xc3\x30\x38\x82\x16\x11\x37\x4d\x5e\xfb\x5e\xd3\xcc\x1f\xdd\xb7\x97\x16\x40\xf9\x06\xf1\x8d\x55\xfd\x7c\x73\xc8\xe4\xa7\xd7\xa8\xcc\xfe\x39\xdb\xef\x93\xd5\x2d\xb3\x24\x6d\xaa\xf0\xa7\x9a\x90\x47\x8b\xd2\x13\x24\xe8\x3f\x74\x2d\x7e\xe7\xbd\xb0\x65\xdb\xa8\x1d\xf3\xfb\xc3\x36\x8f\xd5\xf7\x82\xc2\xe3\xad\x76\xc6\xae\xea\x8a\x61\xd2\x7c\x59\x31\xae\xa3\x8f\x69\x6e\xeb\x37\xcf\xcb\x70\x1d\x1d\x6d\x7b\x5b\x4f\x82\xb2\x9c\x78\xa4\xb0\x65\xc9\xb4\x2a\xa6\x1b\x26\xb3\x03\xa6\x63\x21\xe2\x66\xb8\xd2\x4e\x15\x8f\xbc\x7a\xae\xc8\x4b\x44\x98\xad\xcb\xd1\x11\x8c\x5a\x6b\x08\xc5\x38\xe5\x61\x71\xb7\xbd\x35\x30\x6b\x74\xa4\x50\xfb\xde\x54\xf7\x83\xdb\xd2\xfd\x1b\x45\xee\x16\xe6\xdc\xed\x43\x07\x3d\xfb\x2e\x5d\xf7\xee\x0f\x5d\x72\xd4\xb7\x92\x36\x80\x57\x55\x39\xe9\x67\xe2\xb4\x05\xdb\xa3\x47\x6d\xea\x99\x94\xf4\x73\x71\x6a\xe9\xf8\xfb\x58\x6f\xcb\x92\xff\x9a\xf1\xfe\x9f\x55\xce\xa7\x2c\xf7\x56\xc7\x72\x0f\xb6\x47\x1d\xeb\x39\xe8\x5a\xcd\x47\x19\xe7\x5a\x3e\xac\xb9\x07\x47\x6e\x15\x93\xc5\xf1\x0f\x26\x76\x30\x27\x7f\xea\x65\x8e\x40\x62\xb4\x0c\xd1\xf7\x65\x1f\xe2\x3e\xf0\x3e\xb0\x5e\xb5\x76\x51\xaf\x94\xc4\x4e\x91\xe2\xa0\x0a\x95\x6d\x3c\x19\x60\x99\x69\xdf\xbe\x6a\x07\x3c\x15\x91\x49\x32\xbb\x65\x10\xb7\x57\x07\xfe\x3c\x08\xa8\x9f\x06\xba\x74\xf1\x5e\x35\xd2\xe9\x9f\x0e\xb5\x3c\x6e\x06\x8e\x87\x3a\x3a\x86\xc3\xc9\x31\x3c\xff\x5c\x8e\x3d\xba\xba\x83\xc3\xe1\xe4\x18\x0e\x87\x3a\x7a\x6c\xa7\x9d\x4a\xa7\xa6\x95\xc9\x7b\x81\x59\xe4\x23\xcf\x38\x1e\xfb\xcf\x3f\x57\xe6\x75\xe7\x1d\x97\x6f\x08\xed\xdd\xbd\x74\x0c\xb5\x3c\xfe\x04\x5b\x20\xad\x6c\xf4\xc1\xf3\xdc\x53\x25\x9a\xd9\x2f\x79\x3e\x1d\x9a\xa7\x63\x20\x1e\x18\x3a\xac\x4c\x58\x4a\xe9\x37\xc5\xcc\x0a\x2e\x10\x9d\x77\x79\xf1\x25\x7b\x43\x63\xc1\xf3\xcf\xa5\x40\xd1\x74\x2d\xde\x4f\x95\x8a\xfd\xa7\x6f\x19\x99\xdc\xc3\xc9\xf1\xf3\xcf\x91\x75\x4b\xcd\x2c\x0e\x27\x72\x58\x4e\xe2\x1f\x26\x4a\xc8\x80\x28\x54\x68\x81\xf9\xb6\x8c\x15\x32\xc0\x22\x60\xc8\xa1\xc1\x01\x7f\xfe\xd9\x90\x73\xe7\xbc\x98\x0a\xb9\x60\xfa\x8c\x69\x93\x15\xc8\x6b\x9a\xbd\x3b\x18\xb4\x35\x62\x12\xf5\xee\x3e\xd5\xd5\xab\x25\x07\x12\xd5\xaa\x2e\x9f\x0e\x23\x7e\x03\x3c\x3a\xf2\x34\x4f\xd6\x83\x3c\x91\x7c\x7c\x1f\x27\x3e\xc1\x56\x41\xe8\xa7\x7b\xb8\x51\x81\x7b\x04\x47\x6a\x3d\xcc\x9b\x96\xb9\xd2\xbe\xd8\xbb\x3b\x1c\x46\xfc\x86\xd6\xaf\x36\xe7\xea\xc6\x10\xb9\x5f\x3c\x44\x81\xdd\x27\x5b\xbe\x3a\xfa\x8f\xd9\xf0\x7d\xf5\x1b\x19\xa6\xdb\x56\xc9\x52\x0e\x19\xe9\x56\xf2\xeb\xae\xc6\xef\x45\xd0\xb7\xa2\xfe\xdd\xce\xe3\x69\xaa\xf0\xb4\xde\xa3\x26\x40\xc5\xd1\xf7\xa8\x17\x68\xf1\xe3\x87\xd3\xfc\xdc\x78\xb5\xf6\x57\x3f\x5f\x53\xe2\xb1\xdf\x90\x61\x5c\xa9\x80\x38\x2e\xb8\x6d\x57\xab\x4a\x62\xbb\xd0\x07\xc7\x66\xdc\xc2\x11\xbc\x67\x7a\x6e\xca\xda\x15\x50\x73\x56\x79\xd0\xd6\xbd\x5f\xfa\x27\x76\x1c\xae\xde\xb1\x09\xc6\x3f\x64\xfb\xad\xaf\x56\x70\x5c\x39\x0b\x39\x84\x1d\xf8\x1b\x91\xb3\x05\xb7\x70\x58\x69\xda\xa7\xd7\x03\xb8\x85\x63\x18\xe5\x84\x61\x5c\x2c\x49\x51\xc5\x91\x18\xea\x66\x6d\x8b\xb6\x65\xb5\x6a\xbc\x2e\x76\xe0\xd6\xe3\x88\x30\xb0\xe7\xe3\xaa\x07\x9c\x7a\x0d\x2c\xc5\xfe\xde\x68\xc9\xa2\xb3\xae\x34\x6f\x09\x5e\x14\x9b\x8a\x88\xb4\x5a\xd0\x33\x1f\x5b\xc2\x11\x8c\xdc\xd3\xfa\x3c\x29\x6b\xfb\x59\xae\xcd\xa4\x07\xcd\x51\x32\x31\xf9\x17\x86\xb6\xaa\xec\x1c\xb6\xc8\x4f\x3f\x96\x6e\x5a\xd6\xe4\xaa\xad\x5d\xac\xac\xe1\xe2\xe7\xaa\x6c\x08\x37\xad\xe2\xec\xc5\x95\x4e\x3f\xb5\xf7\x69\x8a\x4a\x1d\x5b\xc5\x61\xf4\x4b\x12\x0e\x69\xf5\x4c\xd9\xc8\x79\xb9\x55\x0c\xd7\x83\x63\x23\x4d\x5b\x70\xdb\x6b\xd4\x8f\x92\xad\xad\xaa\x5b\x55\x29\x28\xe5\x61\x78\xb5\x96\x64\x3f\x67\xce\x93\x03\x8e\xe3\xdb\x5a\x55\xa2\x3d\xd5\xba\x37\x9e\xd7\x12\x5c\xd9\x0c\x5b\x47\xea\xac\xf0\xbf\xee\x0b\x76\x1c\x41\x7f\x48\xe0\x6b\x12\x48\x82\x5f\x70\xac\x13\x6a\xdd\xa9\x02\x2f\x60\x14\x6c\xbf\xea\xec\x28\x09\xff\xeb\xee\xe6\xf5\xbd\xcd\x0f\xa8\x1f\x8d\xdd\xdd\x39\xd7\xba\x42\xe4\x08\xfc\xab\x6e\x52\x1f\x95\x74\x13\x8d\x74\x49\x27\xbe\xd6\x1a\xf6\x19\x93\xd7\x97\xbb\x2d\x87\x74\x2a\x9d\x06\x39\xed\xde\x76\xba\xea\x5e\x3b\x9b\x9f\xb3\x47\x87\xba\x81\xda\xeb\x98\x23\x78\xfe\x79\x70\xcf\xc9\xcc\x1a\x16\x9b\x3d\xe8\x93\xae\xb4\xc0\x14\xd6\x29\xcf\xe8\xe7\xa5\xf0\x1c\xe2\xae\x9a\xcf\xb1\x52\x9f\xa7\x0a\x98\x86\xbf\xd8\xaf\x61\x2a\x67\x20\x9d\xf6\x16\xb3\x44\x3b\xa7\xd2\x6c\x91\xd6\xf5\x66\x38\x04\x16\x45\x30\x89\x59\x78\x6d\xbe\x96\x85\x05\x93\xd7\xb4\xff\xda\x33\x02\x46\x89\x59\x12\xc1\x00\xb6\x87\xdb\xa3\xfc\xe7\xef\xa8\x4e\x8e\xf9\x2a\xa8\x7c\x61\x0e\x30\xdd\xab\x5f\x5f\xc3\x0b\xf0\xdb\x05\x7d\x48\x1b\xe5\x97\x6a\xc9\x10\xba\x65\x3e\x97\xb3\x9d\x87\xb4\xc2\xbb\x9d\x73\x8d\xdd\xf3\xce\xe5\xa3\x5c\x96\x7b\xa4\xa4\x9a\xc0\xab\xcb\x4a\x1d\x73\x64\x8f\xe7\xe4\x69\xa5\x52\xa6\x9a\x5f\x1e\xe5\x3e\x66\xd4\x25\x52\x45\xf3\x17\x48\x94\x34\x9f\x7f\x39\xf2\xa4\x45\x5a\x11\xa6\x57\xff\x1b\xb2\xf4\xa7\x88\x83\xc4\xe8\xbf\x27\x0c\xb9\x28\xe4\x8d\x5d\x22\x81\x71\xc1\x69\x32\x91\xae\xd7\x47\xbf\xf3\x8d\xb7\xcd\x17\xac\x78\xa2\x7f\xb3\xae\xe5\x2b\xeb\x63\x92\xeb\xb9\xe5\x32\xb1\x5e\x89\xab\x9f\x58\x1a\xb5\x9e\x58\xca\xbd\x87\xc1\x84\xc9\x41\x4c\x83\x35\x26\x9f\xe7\x75\x88\xca\x01\x4b\xc2\xb9\x90\x4d\xd2\x3c\x4c\x22\x0f\xf6\xb3\x53\xd9\x5e\xed\x23\x51\xbc\x61\xf1\xff\xbb\x78\x23\xc5\xe2\x1b\xbd\x88\xfd\xb9\x5e\xc4\x6e\x9a\x27\xc1\xdb\xac\xe8\xe1\xde\xfe\x61\xe3\x85\xac\xc1\xdf\x8c\xf8\xcd\x66\xc6\xd8\x12\x3e\xe0\x49\x82\xf2\x9b\x0f\xef\xdf\xc1\x11\x10\x5a\xe7\xb3\x92\x50\xf2\x54\x2b\x7b\xe4\x3e\x07\xaf\x7c\x3d\xfd\x81\xcd\xec\xb7\xd3\x16\x34\x77\xa0\xc8\xa9\xf2\x09\x03\x37\x9e\x2c\x70\x72\xeb\x2c\xb2\xfc\xde\x0b\xd8\xda\xe2\xae\x7e\xd2\xfc\xfc\x0c\xe6\x92\x5f\x95\x54\xb9\x5f\x56\x97\xa7\xf8\x6b\x47\x5d\x56\x7d\x58\xbb\xec\x70\x0e\xd9\xac\x0e\xea\x6f\x3f\xc2\x11\xac\x9d\x0d\xac\x25\x36\x71\x29\xab\xe5\xe6\x64\xa6\x94\x7e\xf5\xd3\xae\x7c\xc4\x1e\x6c\x81\x97\x56\xd2\x96\x35\x04\x31\x4e\xa9\xbf\xb1\x69\xed\xc1\x6b\x7b\x87\x62\x4e\x0f\x0d\x90\x53\xe8\x8c\x50\x4e\x76\x5d\x99\xec\xc7\x07\x26\x6b\x77\xda\xea\x6c\x3f\x96\xb3\xfd\xf8\xf0\x6c\xb5\x48\xef\x9f\xec\x70\x08\x6f\x35\xc4\x42\x5c\xab\xfc\x02\xa5\x99\x10\xd3\x35\x51\xbb\x16\x4b\x7b\x39\x53\x00\x3b\xa3\x74\x05\x5c\x01\x9b\x90\xff\x6e\x3e\x21\xe6\xbf\x62\xfe\x6d\xbd\xc9\x4c\x83\x48\x80\xc1\xf6\x68\x6f\x64\x2e\x52\xc2\xe2\x5e\xa5\xfb\x69\x2b\xa4\x62\x0b\x76\x46\x0f\xce\xa7\xe0\x48\x2b\x77\x1f\x93\xf8\xce\x11\x16\x06\x84\xcf\x12\x21\x71\xd0\x38\xca\x6a\x4a\x2a\x0f\x88\xc8\x83\x48\x4a\x43\x54\xd5\xa0\x8e\xf2\x5d\x56\xbb\xb3\x65\xd4\x0e\x8d\x6a\x9c\x59\xab\xe9\x56\xe3\x90\xda\x63\x39\x43\x78\x9c\x6f\x0d\xc9\xd0\xc1\x51\x47\x06\xae\xb2\xb1\x3c\xb9\x28\xf4\x7b\x1d\x51\xe8\x3a\x71\x54\xa6\x20\x5b\x24\xc9\x14\x5f\x6a\xf3\x74\xc0\x9e\x74\x8c\xef\xa1\xeb\x9b\xda\xa5\xa7\xfd\x1c\x6a\xb6\xe8\x4e\x6c\xfe\xd0\xc2\x3f\x66\xf1\xa1\x48\x19\xe4\x53\xfe\xc1\x7e\x84\xff\x3d\x33\x45\x9c\x32\x11\x52\xc2\x3f\x0f\xd8\xbf\xd8\xca\xaf\x2e\xeb\x52\xc6\xfb\x6d\x38\xaa\xeb\x12\x31\xcd\xf6\xdb\x6a\x8e\x31\x0f\xaf\x7f\xb1\x2b\xd6\x76\xb2\x33\xbf\x25\xc2\x6f\xf9\x38\x21\x31\xd9\xc2\x2e\x59\x7a\xac\xb4\x74\xcb\xdc\x5d\xf5\xa7\x5a\x86\x21\x2a\xb5\x0f\xf7\xdd\x8b\xf4\x08\x01\x68\x56\x56\xa1\x45\x0a\xab\x17\x26\xe5\x7f\x35\x77\xa3\x13\xee\x11\xc2\xda\xa1\x18\x77\xee\xc6\xfe\xbc\xb8\x9d\xa5\x17\x48\x64\xd1\xba\x70\xe7\x8b\xf3\xd3\xc3\x61\x71\x8d\x0f\x59\xfc\xa5\x42\x39\xc8\xef\xe0\x30\xd7\xac\xd8\xab\x29\xa6\x1a\x25\xa8\xe5\x64\xc1\xf5\x50\xe2\x54\xa2\x9a\x07\xf0\xd3\x1c\x13\x48\x44\x62\xbe\x2f\xb2\xf7\x4b\xf4\xdd\x9b\x25\x26\x62\x05\x4a\xb3\xb5\xca\x6e\x3f\x59\x26\x9a\xc7\xe5\xed\x15\xe4\xd6\x2a\xd3\xc1\xda\x4d\xd5\x75\x69\x4b\x4e\x46\x8e\xd7\x77\xae\x80\xa9\xdc\x52\xd1\x83\x81\xb9\x1c\xb4\x71\x33\x43\xaf\x74\xbe\x0c\x99\x59\x93\x29\x93\x29\xc5\x45\x72\xa1\x85\x64\x33\x73\xa9\xc9\x5b\x8d\x8b\x96\x7b\x48\x4a\x9b\x5b\x41\x51\x37\xb4\xc4\xc0\xfa\xbd\x2b\xd5\x0e\xce\x05\x12\x19\xac\x7b\xe9\x4a\xf1\xae\x76\xeb\x8a\xfb\xbe\xe3\xda\x95\x26\xca\xf6\xbb\x57\xe0\xcb\xee\x5f\x29\x50\xdf\x77\x01\x0b\x94\x1b\xf7\x70\x08\xde\x3b\xa6\x51\x69\x0f\x24\x66\xfe\xb9\x5d\xe3\x1b\x8e\xb7\xf9\xdd\x21\x6d\xeb\xb8\x0f\x61\x8c\xcc\x5e\x8d\x82\xab\x34\xe6\x21\x37\x17\xda\xe4\x78\x8d\x4c\x2a\xe1\xc8\x0b\xa4\x3c\xbc\x56\x8d\x3b\x74\xdc\x6b\x51\x80\x29\xe7\x82\xca\x02\xdd\x73\x7f\xf3\x59\x6c\xc8\xdc\xec\x05\xc6\x9c\x39\x4a\xe2\x9c\xcb\xa9\xca\x89\xfd\xbc\xfa\x5e\x51\xf9\x42\x36\x6f\x6e\x3a\x87\x7b\xe8\x7f\xff\x17\x00\x00\xff\xff\x80\x7a\x97\x2e\x78\x57\x00\x00") func webfilesSloop_uiJsBytes() ([]byte, error) { return bindataRead( @@ -365,7 +365,7 @@ func webfilesSloop_uiJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/sloop_ui.js", size: 21534, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} + info := bindataFileInfo{name: "webfiles/sloop_ui.js", size: 22392, mode: os.FileMode(416), modTime: time.Unix(1781201511, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/pkg/sloop/webserver/webfiles/filter.js b/pkg/sloop/webserver/webfiles/filter.js index 88a53ce..dacc686 100644 --- a/pkg/sloop/webserver/webfiles/filter.js +++ b/pkg/sloop/webserver/webfiles/filter.js @@ -89,7 +89,6 @@ $(document).ready(function(e) { var dateTimeValue = document.getElementById('selectedEndTime').value; var selectedEndTimeValue = dateTimeValue.toString(); sessionStorage.setItem('selectedEndTime', selectedEndTimeValue); - sessionStorage.setItem('setSelectedEndTime', new Date().toISOString()); }); }); @@ -103,10 +102,11 @@ function setFiltersAndReturnQueryUrl(defaultLookback, defaultKind, defaultNamesp // until we get the full list back selectedEndTime = sessionStorage.getItem('selectedEndTime') - // If user shut down the old window and open a new window, set the default ui displayed time to now - if (selectedEndTime === null) { - var now = new Date().toISOString() - selectedEndTime = now.substring(0, now.length-5) + // With no explicit end time, send an empty end_time so the server anchors the window + // to the end of recorded data (see getEndOfTime in queries/timerange.go). On a live + // cluster that is "now"; when browsing a restored backup it is the backup's newest data. + if (selectedEndTime === null || selectedEndTime === "") { + selectedEndTime = "" } else { var endTime = new Date(selectedEndTime); diff --git a/pkg/sloop/webserver/webfiles/index.html b/pkg/sloop/webserver/webfiles/index.html index 14d2b9c..14b63e3 100644 --- a/pkg/sloop/webserver/webfiles/index.html +++ b/pkg/sloop/webserver/webfiles/index.html @@ -39,7 +39,7 @@
- +

diff --git a/pkg/sloop/webserver/webfiles/sloop_ui.js b/pkg/sloop/webserver/webfiles/sloop_ui.js index 3237ae9..1f2d7c0 100644 --- a/pkg/sloop/webserver/webfiles/sloop_ui.js +++ b/pkg/sloop/webserver/webfiles/sloop_ui.js @@ -124,13 +124,35 @@ function queryChange(radio) { } } +// Show the end of the displayed window (from the server's effective query range) in the +// end-time box, converted to the box's local-time convention. The stored value is left +// alone: an empty stored value keeps tracking the newest data on reload. +function updateEndTimeBox(endUnixSeconds) { + let endDate = new Date(endUnixSeconds * 1000); + endDate.setMinutes(endDate.getMinutes() - endDate.getTimezoneOffset()); + endDate.setMilliseconds(null); + document.getElementById('selectedEndTime').value = endDate.toISOString().slice(0, -1); +} + function render(result) { let data = processAndSortResources(result); let dataByKind, kinds, filteredData; + // Prefer the server-computed effective query window for the time axis: it reflects any + // clamping to the data available in the store, so when viewing a restored backup the + // axis ends at the newest recorded data instead of stretching to the requested time + let viewOptions = result.view_options || {}; + let queryWindow = null; + if (viewOptions.query_start && viewOptions.query_end) { + queryWindow = [viewOptions.query_start * 1000, viewOptions.query_end * 1000]; + updateEndTimeBox(viewOptions.query_end); + } if (!data) { xAxisScale = d3.scaleUtc().range([margin.left, displayMaxX - margin.left]); + if (queryWindow) { + xAxisScale.domain(queryWindow); + } yAxisBand = d3.scaleBand().padding(resourceBarVerticalSpacing); topAxisDrawFunc = d3.axisTop(xAxisScale); @@ -144,7 +166,7 @@ function render(result) { severityColorGenFunc = d3.scaleLinear().domain([0, 1, 2]).range(palette.severity); xAxisScale = d3.scaleUtc() - .domain([d3.min(data, d => d.start), d3.max(data, d => d.end)]) + .domain(queryWindow || [d3.min(data, d => d.start), d3.max(data, d => d.end)]) .range([margin.left, displayMaxX - margin.left]); yAxisBand = d3.scaleBand() @@ -608,28 +630,22 @@ function showDetailedTooltip(d, event, parent) { } $(document).ready(function() { - //Set max allowed selected date/time to now - const now = new Date(); - const utcNow = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds()); - - //Display user selected end time on ui after click submit button or refresh the page - //Set page default to UTC time on first loading - let userDate = utcNow; - // check if selected end time happened within 3 seconds - if (sessionStorage.getItem('setSelectedEndTime') !== null - && ! Date.parse(sessionStorage.getItem('setSelectedEndTime')) < new Date(userDate.getTime() - 3000)){ - userDate = new Date(sessionStorage.getItem('selectedEndTime')); + // Display the user-selected end time after submit/refresh. When none is stored, the + // box stays empty until the data loads, then shows the server's effective end time + // (the end of recorded data) - see updateEndTimeBox() + let storedEndTime = sessionStorage.getItem('selectedEndTime'); + if (storedEndTime) { + let userDate = new Date(storedEndTime); + userDate.setMinutes(userDate.getMinutes() - userDate.getTimezoneOffset()); + userDate.setMilliseconds(null); + document.getElementById('selectedEndTime').value = userDate.toISOString().slice(0, -1); } - userDate.setMinutes(userDate.getMinutes() - userDate.getTimezoneOffset()); - userDate.setMilliseconds(null); - document.getElementById('selectedEndTime').value = userDate.toISOString().slice(0, -1); - - $('#now').click(function(){ - const resetNow = new Date(); - resetNow.setMilliseconds(null); - document.getElementById('selectedEndTime').value = resetNow.toISOString().slice(0, -1); + + // "Latest" re-anchors the view to the end of recorded data: clear the explicit end + // time so the server picks the newest data in the store as the window end + $('#latest').click(function(){ sessionStorage.removeItem('selectedEndTime'); - sessionStorage.setItem('selectedEndTime', resetNow.toISOString().slice(0, -1)); + document.getElementById('selectedEndTime').value = ''; }); }); From 9179c35b2a2b827549fdf89e2f724bfddfc93bd9 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Thu, 11 Jun 2026 20:57:58 +0000 Subject: [PATCH 05/10] fix(ui): anchor historic views to the newest record, fix Latest button getEndOfTime now uses the newest resource-summary lastSeen instead of the hour-aligned partition end, removing the dead zone at the end of restored-backup views. The Latest button now fits its label and resubmits immediately instead of leaving the end-time box empty. --- pkg/sloop/queries/timerange.go | 47 +++++++++++++++++++++--- pkg/sloop/queries/timerange_test.go | 47 ++++++++++++++++++++++++ pkg/sloop/webserver/bindata.go | 8 ++-- pkg/sloop/webserver/webfiles/sloop.css | 10 +++++ pkg/sloop/webserver/webfiles/sloop_ui.js | 4 +- 5 files changed, 106 insertions(+), 10 deletions(-) diff --git a/pkg/sloop/queries/timerange.go b/pkg/sloop/queries/timerange.go index 38d1a9f..bd8a346 100644 --- a/pkg/sloop/queries/timerange.go +++ b/pkg/sloop/queries/timerange.go @@ -17,6 +17,7 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/salesforce/sloop/pkg/sloop/store/typed" "github.com/salesforce/sloop/pkg/sloop/store/untyped" + "github.com/salesforce/sloop/pkg/sloop/store/untyped/badgerwrap" ) const minLookback = 1 * time.Minute @@ -106,8 +107,11 @@ func computeTimeRangeInternal(params url.Values, endOfTime time.Time, maxLookBac } -// This looks at our store, and if it has data finds the newest partition, then finds the end time of that -// But if that is in the future we return now +// This looks at our store, and if it has data finds the end of recorded data. +// If the newest partition is still being written (its end is in the future) that is now. +// Otherwise (historic data, e.g. a restored backup) it is the newest record in that +// partition - the partition boundary itself can be up to an hour past the last record, +// which would leave a dead zone at the end of the view. // This bit of logic is needed for queries with a lookback to determine a good end time func getEndOfTime(tables typed.Tables) time.Time { now := time.Now() @@ -120,7 +124,7 @@ func getEndOfTime(tables typed.Tables) time.Time { return now } - _, endTimeOfNewestPartition, err := untyped.GetTimeRangeForPartition(maxPartition) + startTimeOfNewestPartition, endTimeOfNewestPartition, err := untyped.GetTimeRangeForPartition(maxPartition) if err != nil { glog.Errorf("Error getting MinAndMaxPartition: %v", err) return now @@ -129,9 +133,42 @@ func getEndOfTime(tables typed.Tables) time.Time { // The newest partition ends in the future, so use now instead if endTimeOfNewestPartition.After(now) { return now - } else { - return endTimeOfNewestPartition } + + newestRecordTime, found := getNewestRecordTime(tables, startTimeOfNewestPartition, endTimeOfNewestPartition) + if found { + return newestRecordTime + } + return endTimeOfNewestPartition +} + +// getNewestRecordTime returns the latest lastSeen across the resource summaries of the newest +// partition. Resource summaries track every non-Event watch, so this is the end of recorded +// data to within about a minute. The scan covers a single partition of the ressum table - +// the same order of work the heatmap query does for every partition it renders. +func getNewestRecordTime(tables typed.Tables, partitionStart time.Time, partitionEnd time.Time) (time.Time, bool) { + newest := time.Time{} + err := tables.Db().View(func(txn badgerwrap.Txn) error { + resSums, _, rangeErr := tables.ResourceSummaryTable().RangeRead(txn, nil, nil, nil, partitionStart, partitionEnd) + if rangeErr != nil { + return rangeErr + } + for _, resSum := range resSums { + lastSeen, tsErr := ptypes.Timestamp(resSum.LastSeen) + if tsErr == nil && lastSeen.After(newest) { + newest = lastSeen + } + } + return nil + }) + if err != nil { + glog.Errorf("Error finding newest record in partition: %v", err) + return time.Time{}, false + } + if newest.IsZero() { + return time.Time{}, false + } + return newest, true } func getDurationFromLookback(lookbackVal string) (time.Duration, error) { diff --git a/pkg/sloop/queries/timerange_test.go b/pkg/sloop/queries/timerange_test.go index f9f1f11..1f6c95f 100644 --- a/pkg/sloop/queries/timerange_test.go +++ b/pkg/sloop/queries/timerange_test.go @@ -12,8 +12,11 @@ import ( "testing" "time" + "github.com/dgraph-io/badger/v2" "github.com/golang/protobuf/ptypes" "github.com/salesforce/sloop/pkg/sloop/store/typed" + "github.com/salesforce/sloop/pkg/sloop/store/untyped" + "github.com/salesforce/sloop/pkg/sloop/store/untyped/badgerwrap" "github.com/stretchr/testify/assert" ) @@ -202,3 +205,47 @@ func Test_parseTimestampString(t *testing.T) { assert.NotNil(t, err) assert.Equal(t, result.Format(""), "") } + +func Test_getEndOfTime_HistoricDataAnchorsToNewestRecord(t *testing.T) { + untyped.TestHookSetPartitionDuration(time.Hour) + db, err := (&badgerwrap.MockFactory{}).Open(badger.DefaultOptions("")) + assert.Nil(t, err) + tables := typed.NewTableList(db) + + // A record well in the past (e.g. a restored backup), 27 minutes into its partition + newestRecordTs := time.Date(2019, 3, 1, 18, 27, 0, 0, time.UTC) + olderRecordTs := newestRecordTs.Add(-10 * time.Minute) + err = tables.Db().Update(func(txn badgerwrap.Txn) error { + for i, ts := range []time.Time{olderRecordTs, newestRecordTs} { + pts, _ := ptypes.TimestampProto(ts) + key := typed.NewResourceSummaryKey(ts, "Pod", "ns", fmt.Sprintf("name%v", i), "uid") + setErr := tables.ResourceSummaryTable().Set(txn, key.String(), &typed.ResourceSummary{CreateTime: pts, LastSeen: pts}) + if setErr != nil { + return setErr + } + } + return nil + }) + assert.Nil(t, err) + + // Anchored to the newest record, not the partition end (19:00) + assert.Equal(t, newestRecordTs, getEndOfTime(tables)) +} + +func Test_getEndOfTime_NoSummariesFallsBackToPartitionEnd(t *testing.T) { + untyped.TestHookSetPartitionDuration(time.Hour) + db, err := (&badgerwrap.MockFactory{}).Open(badger.DefaultOptions("")) + assert.Nil(t, err) + tables := typed.NewTableList(db) + + // Only a watch record exists, so there is no resource summary to anchor to + recordTs := time.Date(2019, 3, 1, 18, 27, 0, 0, time.UTC) + pts, _ := ptypes.TimestampProto(recordTs) + err = tables.Db().Update(func(txn badgerwrap.Txn) error { + key := typed.NewWatchTableKey(untyped.GetPartitionId(recordTs), "Pod", "ns", "name", recordTs) + return tables.WatchTable().Set(txn, key.String(), &typed.KubeWatchResult{Kind: "Pod", Timestamp: pts, Payload: "{}"}) + }) + assert.Nil(t, err) + + assert.Equal(t, time.Date(2019, 3, 1, 19, 0, 0, 0, time.UTC), getEndOfTime(tables)) +} diff --git a/pkg/sloop/webserver/bindata.go b/pkg/sloop/webserver/bindata.go index 0792f99..7ebe44c 100644 --- a/pkg/sloop/webserver/bindata.go +++ b/pkg/sloop/webserver/bindata.go @@ -330,7 +330,7 @@ func webfilesResourceHtml() (*asset, error) { return a, nil } -var _webfilesSloopCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x5b\x6f\xdb\x3a\x12\x7e\xb6\x7e\xc5\x20\xc1\x02\x69\x1a\xd9\xf2\x2d\x68\x64\xe4\xc1\x49\xdc\x6e\xda\x6e\xdb\xdc\x8a\xec\x16\x45\x41\x49\x63\x8a\x6b\x8a\xd4\x21\x29\x5b\x6e\x91\xff\x7e\x40\xc9\x52\x24\xc7\x69\x83\x03\xbf\xc8\xa3\x4f\x33\xdf\x7c\x73\x21\x7b\x87\x0e\x1c\xc2\xb9\x4c\xd7\x8a\xd1\xd8\xc0\x41\xf8\x0a\x06\x5e\xff\xe4\x08\x34\xe1\xa8\xe7\x52\x85\xd8\x0d\x65\x72\x04\x4c\x84\x5d\x8b\x9d\x72\x0e\x05\x56\x83\x42\x8d\x6a\x89\x51\x61\xbf\xf9\x72\x71\xef\x7e\x64\x21\x0a\x8d\xee\x65\x84\xc2\xb0\x39\x43\xe5\xc3\xd9\xcd\x85\x3b\x74\xcf\x39\xc9\x34\x5a\xe0\x5b\xa9\x60\x9e\x71\x0e\xbc\x04\x83\xc1\xdc\x1c\x81\x46\x84\x8f\x97\xe7\xb3\x4f\x37\xb3\xae\xc9\x0d\xcc\x19\x47\x60\x02\x4c\x8c\xa0\x30\x95\xa0\xa4\x34\x20\x15\xc4\xc6\xa4\xda\xef\xf5\x64\x8a\x42\xcb\xcc\x12\x94\x8a\xf6\x36\xde\x74\x6f\x2b\x5e\xcf\x71\x02\x19\xad\xe1\x97\xd3\x99\x4b\x61\xdc\x39\x49\x18\x5f\xfb\xa0\x89\xd0\xae\x46\xc5\xe6\x13\xe7\xc1\x71\xba\x7a\x49\xdd\x50\x0a\x43\x98\x40\x65\xd1\x31\xda\x2c\x7d\xe8\x7b\xde\xbf\x26\x4e\x67\xc5\x22\x13\xd7\xff\xe4\x12\xd5\x9c\xcb\x95\x0f\x3a\x54\x92\xf3\x89\xd3\x09\x48\xb8\xa0\x4a\x66\x22\x72\x43\xc9\xa5\xf2\x61\x15\x33\x83\x3a\x91\x0b\x2c\x42\xe8\x25\xb5\x7e\x7f\xba\x4c\x44\x98\xfb\xe0\xf6\xcb\xc8\x86\x85\x8b\x42\x84\x9a\xa3\x66\x3f\xd1\x87\xfe\x28\xcd\x0b\x44\x6c\x12\x7e\x04\x55\x16\x5b\xbc\x52\x12\x45\x4c\x50\x1f\xbc\x89\xd3\x49\x88\xa2\x4c\x94\xcf\x8f\x14\x63\x16\x45\x28\x26\x7f\x10\xa0\xa0\xf1\xcb\xe9\x6c\xc8\xef\xcf\xc6\xb3\x93\xb7\x5e\xf9\x8e\x51\x21\x15\xba\xa9\x64\xc2\xa0\x72\x71\x89\xc2\x68\x0b\x6e\x5b\x7c\x10\x52\x94\xc9\x76\x15\x96\xc5\x71\x03\xa2\x5c\x4e\x02\xe4\x16\x1f\xc9\x84\x09\x22\x8c\x1b\x10\x8d\x9c\x09\xf4\x21\x26\x82\x32\x41\x27\x0e\x00\xc0\xae\xf4\xbb\x31\x12\x93\x90\xb4\x20\x97\x29\x6d\xd9\x6d\xe2\xb6\x43\x3d\x0b\x30\x52\x72\xc3\xd2\x92\xb0\x66\x86\x49\xe1\xc3\x9c\xe5\x18\x59\x9d\x52\x12\x32\xb3\x2e\x45\x7b\x2c\x62\xbb\x7c\xb5\x2a\xc3\xb3\xd1\x60\x3c\xb0\x48\xa9\x22\x54\xae\x22\x11\xcb\xb4\x0f\x63\x4b\xb6\x13\xc8\xdc\xd5\x31\x89\xac\xea\x1e\x78\xd0\xf7\xd2\x1c\x14\x0d\xc8\x81\x77\x64\x7f\xdd\xf1\xab\x89\xd3\xb1\x79\xbb\x75\x19\x27\x8d\x96\xe8\x6f\x8a\xe4\x43\x7f\x90\xe6\xad\x12\x75\x12\x92\xd7\x1f\x8d\x8b\xd2\x5b\xcb\xa6\x2d\xc7\xad\xae\x74\xd7\x8f\x7d\xf9\xe0\x38\xfb\x86\x89\xb5\xdb\x14\xa1\xea\x19\xcb\xaf\x80\x44\x6c\xb9\x5f\xc9\xf8\xa3\x35\x06\xcd\xfe\xb2\xbe\x34\x97\x32\xe5\x38\x37\x82\x2c\x9f\x1f\x93\xe1\xa0\xf0\x5c\x7d\xed\xaa\x12\xb4\xb1\x36\x79\x92\xcc\xc8\xd2\x73\x98\x29\x85\xc2\x9c\x4b\x51\x0d\x43\xe9\xac\xf4\x6c\x07\x08\x39\x86\x8d\x17\x50\xbf\x79\x32\xbd\xb6\x97\xaa\xd8\x46\xa6\x55\xa6\x55\xd5\x2c\x7f\x1f\x0a\x89\x25\x67\x11\x04\x9c\x84\x8b\xc9\x93\x64\x5e\x34\xe5\xfb\x83\xd9\x70\x34\xf2\x1a\x3d\x72\xf1\xe6\x62\x36\x3b\xf9\xed\xcc\x6f\xab\xb8\xc3\x6d\xdd\x69\x55\x1e\x25\xe9\x7e\x5b\xd8\x66\x72\xcd\xe1\x19\x16\x96\x1d\xb3\xdc\x2e\x20\xf1\x39\x13\x0b\xf8\x05\x1b\x24\xb7\xf9\x53\x45\xd6\xf0\xf0\x04\xb9\x64\x9a\x19\x8c\x5e\x06\x8e\xad\x76\x8f\xd0\x62\x96\x76\xc0\x48\x68\xd8\x12\x77\xbb\x74\xba\x61\xa6\x8d\x4c\x7e\xa4\x4a\x52\x85\xba\x58\x38\x11\xd3\x29\x27\x6b\x1f\x98\x28\xc6\x28\xe0\xb2\xa8\xdc\x12\x95\x61\x21\xe1\x2e\xe1\x8c\x0a\x1f\x8c\x4c\x27\x4e\xc7\x36\x52\x65\x09\xb1\x5c\x08\x5b\x45\x7e\x70\x1c\xf2\xcd\x10\x45\xd1\x9c\xee\xfd\x08\x38\x11\x8b\xbd\xef\x3e\x99\x9b\xb2\xfd\x6d\x53\xa1\x1d\xc8\x4c\xf1\x83\x88\x18\xe2\xb3\x84\x50\xec\xa5\x82\x4e\xec\x0e\x3b\x1e\x1d\xb1\xaf\x67\x9f\xaf\x57\xde\x87\x77\x54\x4e\xa7\xd3\xe9\xa7\x9b\xbb\x78\x76\x47\xed\x63\xf1\xff\xc3\xf9\xf4\xbf\xd3\xe9\xf4\xfc\xd3\x7f\xf4\xeb\x13\x6b\xb8\x9a\xf1\xd9\xd5\xd7\xeb\xd1\xe0\xaf\xfb\x0f\xab\xab\xc5\xf4\x72\x9a\x5f\xdc\xdd\x45\xb9\xf9\x7c\xdc\xbb\x3e\xbb\x5a\x5c\xfd\x6f\x79\xc3\xde\x5c\xf6\xd2\x8f\xa3\x33\xf9\x6e\xd5\xbb\xff\xb2\x88\x47\xf7\x8c\x7e\x49\xf4\x1d\x8d\xbd\xe3\xc1\xf1\xf4\xff\xd7\x9a\xe6\xff\xbe\x5d\xdc\xdd\xc6\xfa\xdd\xe0\xb6\xa7\x2f\xf9\xcf\xe8\x56\xa7\xe3\xc1\xe2\xe6\xa6\xbf\xb2\x51\xce\xde\x5f\xdf\x8d\x67\x6a\xf1\x9e\x52\x7a\x7a\xfa\xaa\x79\x38\xc0\x30\xcd\xc1\x2b\x57\xd6\x83\xe3\x30\x91\x66\xe6\x9b\x59\xa7\x78\xba\x17\x11\x83\x86\x25\xe8\x72\x19\x12\xbe\xf7\xbd\x31\x6c\x03\xaf\xec\xb2\x5a\xbe\xee\x50\x61\xd2\x6e\x3b\xaf\xfb\x66\x6c\x6d\x5b\x5e\x83\xcc\x18\x29\x5a\xde\x86\xe3\x97\x38\xf3\x76\x38\xb3\x35\x6d\x13\x1b\xed\xf6\xf5\xe0\x38\xbd\x43\xb8\x95\x94\x72\x04\xbd\x62\x26\x8c\x41\x9b\x35\x67\x82\xda\x6b\x41\xb7\x34\xb5\x0f\xfd\xdd\xed\x05\x95\x78\xe5\xb8\x0d\xaa\xad\xf9\xd4\x45\xda\x74\xf2\x82\x16\x85\x86\x9b\xf6\xf1\xa4\x90\x13\x3b\x1b\x93\xe7\x7b\xbe\xde\xb5\xad\xf4\x37\x3b\x76\x43\xb8\x5c\x1a\xe5\x92\xad\x6c\x9b\x65\x5c\xec\x03\x80\x3a\x7c\x21\x72\x4b\x84\xea\x34\x2f\x40\x9c\x45\x9b\x13\xa1\xe6\x48\x02\x2d\x79\x66\x8a\xf3\x71\xfb\xdc\xed\x14\x52\xd9\xb5\x58\x52\xb0\x4f\x8f\x81\x3b\x81\x34\x46\x26\xdb\x87\x6e\xbd\xfc\xc2\x30\x9c\x38\x1d\x77\x85\xc1\x82\x19\xd7\x28\x22\xaa\x98\xdd\x91\xb6\xce\xb7\x2d\x4d\x92\x7e\x80\x73\xa9\xf0\x79\xae\xd5\x4c\xef\xed\x35\xdb\xa6\xb8\x6f\xd4\x47\x4b\xf9\xaf\x3e\x28\x1a\x94\xcb\xd5\xfa\xcc\x75\xef\x1f\xb0\x2e\x74\xf7\xc3\x18\xc3\x05\x46\xaf\x1b\x42\xef\xd0\xe5\x38\x20\xc1\x70\xdc\xfa\x70\x2e\xc3\x4c\xb7\x3e\xdb\xbe\x84\xa4\xf9\xce\x0f\xb7\x22\x36\x54\x6b\x65\x30\x97\x2a\xf1\xa1\x78\xe4\xc4\xe0\xfd\x81\x95\xc6\xee\x13\x37\xd1\x7f\x40\xfc\xf6\xed\x83\x9d\xce\x6b\x9b\x1d\x46\x50\x52\xd0\x70\xd8\x7b\x2c\x63\xb7\x48\xbd\xcc\xa8\x75\xd7\x1a\x6e\x6e\x86\xdb\xd0\x46\x06\xdb\xb7\xb3\x72\xd3\xff\x1d\x00\x00\xff\xff\x3a\xd5\xa1\xf2\xee\x0c\x00\x00") +var _webfilesSloopCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x5b\x6f\xdb\x3a\x12\x7e\xb6\x7e\xc5\x20\xc1\x02\x69\x4e\x64\xcb\xb7\x20\x91\x91\x07\x27\xf1\xe9\xe6\x34\xdb\x36\xb7\x22\xbb\x45\x51\x50\xe2\x58\xe2\x9a\x22\xb5\x24\x7d\x6b\x91\xff\xbe\xa0\x28\x39\x92\xe3\xb4\xc1\x41\xf2\x20\x8f\x46\x33\xdf\x7c\x73\xed\x1c\x7a\x70\x08\x17\x32\x5f\x2b\x96\xa4\x06\x0e\xe2\x77\xd0\x0b\xba\xa7\x47\xa0\x09\x47\x3d\x95\x2a\xc6\x76\x2c\xb3\x23\x60\x22\x6e\x5b\xdd\x31\xe7\x50\xe8\x6a\x50\xa8\x51\x2d\x90\x16\xf2\xbb\xcf\x97\x8f\xfe\x35\x8b\x51\x68\xf4\xaf\x28\x0a\xc3\xa6\x0c\x55\x08\xe7\x77\x97\x7e\xdf\xbf\xe0\x64\xae\xd1\x2a\xfe\x29\x15\x4c\xe7\x9c\x03\x77\xca\x60\x70\x65\x8e\x40\x23\xc2\xf5\xd5\xc5\xe4\xe3\xdd\xa4\x6d\x56\x06\xa6\x8c\x23\x30\x01\x26\x45\x50\x98\x4b\x50\x52\x1a\x90\x0a\x52\x63\x72\x1d\x76\x3a\x32\x47\xa1\xe5\xdc\x02\x94\x2a\xe9\x94\xd6\x74\x67\xcb\x5f\xc7\xf3\x22\x49\xd7\xf0\xd3\x6b\x4d\xa5\x30\xfe\x94\x64\x8c\xaf\x43\xd0\x44\x68\x5f\xa3\x62\xd3\x91\xf7\xe4\x79\x6d\xbd\x48\xfc\x58\x0a\x43\x98\x40\x65\xb5\x53\xb4\x51\x86\xd0\x0d\x82\x7f\x8c\xbc\xd6\x92\x51\x93\x6e\x7e\xc9\x05\xaa\x29\x97\xcb\x10\x74\xac\x24\xe7\x23\xaf\x15\x91\x78\x96\x28\x39\x17\xd4\x8f\x25\x97\x2a\x84\x65\xca\x0c\xea\x4c\xce\xb0\x70\xa1\x17\x89\xb5\xfb\xc3\x67\x82\xe2\x2a\x04\xbf\xeb\x3c\x1b\x16\xcf\x0a\x12\x36\x18\x35\xfb\x81\x21\x74\x07\xf9\xaa\xd0\x48\x4d\xc6\x8f\xa0\x8a\x62\x0b\x57\x4e\x28\x65\x22\x09\x21\x18\x79\xad\x8c\xa8\x84\x09\xf7\xfc\x0c\x31\x65\x94\xa2\x18\xfd\x86\x80\x02\xc6\x4f\xaf\x55\x82\xdf\x9f\x0c\x27\xa7\x7f\x06\xee\x1d\x4b\x84\x54\xe8\xe7\x92\x09\x83\xca\xc7\x05\x0a\xa3\xad\x72\x53\x12\x82\x90\xc2\x05\xdb\x56\xe8\x92\xe3\x47\x44\xf9\x9c\x44\xc8\xad\x3e\x95\x19\x13\x44\x18\x3f\x22\x1a\x39\x13\x18\x42\x4a\x44\xc2\x44\x32\xf2\x00\x00\x76\x85\xdf\x4e\x91\x98\x8c\xe4\x05\xb8\xb9\xd2\x16\x5d\xe9\xb7\xe9\xea\x55\x05\x23\x25\x37\x2c\x77\x80\x35\x33\x4c\x8a\x10\xa6\x6c\x85\xd4\xf2\x94\x93\x98\x99\xb5\x23\xed\x39\x89\xcd\xf4\x6d\x58\xe9\x9f\x0f\x7a\xc3\x9e\xd5\x94\x8a\xa2\xf2\x15\xa1\x6c\xae\x43\x18\x5a\xb0\xad\x48\xae\x7c\x9d\x12\x6a\x59\x0f\x20\x80\x6e\x90\xaf\x40\x25\x11\x39\x08\x8e\xec\x5f\x7b\xf8\x6e\xe4\xb5\x6c\xdc\xfe\x26\x8d\xa3\x5a\x49\x74\xcb\x24\x85\xd0\xed\xe5\xab\x46\x8a\x5a\x19\x59\x6d\x3e\x1a\x16\xa9\xb7\x92\xb2\x2c\x87\x8d\xaa\xf4\xd7\xcf\x75\xf9\xe4\x79\xfb\x86\x89\xb5\x5f\x27\xa1\xaa\x19\x8b\xaf\x50\xa1\x6c\xb1\x5f\xd1\xf8\xbd\xd1\x06\xf5\xfa\xb2\xb6\x34\x97\x32\xe7\x38\x35\x82\x2c\x5e\x6f\x93\x7e\xaf\xb0\x5c\x7d\xed\x2b\xa7\x54\x4a\xeb\x38\xc9\xdc\x48\x67\x39\x9e\x2b\x85\xc2\x5c\x48\x51\x35\x83\x33\xe6\x2c\xdb\x06\x42\x8e\x71\xed\x05\x6c\xde\xbc\xe8\x5e\x5b\x4b\x95\x6f\x23\xf3\x2a\xd2\x2a\x6b\x16\x7f\x08\x05\xc5\x92\x33\x0a\x11\x27\xf1\x6c\xf4\x22\x98\x37\x75\xf9\x7e\x6f\xd2\x1f\x0c\x82\x5a\x8d\x5c\x9e\x5c\x4e\x26\xa7\xbf\xec\xf9\x6d\x16\x77\x98\xdd\x54\x5a\x15\x87\x03\xdd\x6d\x12\x5b\x0f\xae\xde\x3c\xfd\x42\xb2\xa3\x97\x9b\x09\x24\x21\x67\x62\x06\x3f\xa1\xd4\xe4\x36\xfe\x44\x91\x35\x3c\xbd\xd0\x5c\x30\xcd\x0c\xd2\xb7\x29\xa7\x96\xbb\x67\xd5\xa2\x97\x76\xa8\x91\xd8\xb0\x05\xee\x36\xe9\xb5\xe3\xb9\x36\x32\xfb\x9e\x2b\x99\x28\xd4\xc5\xc0\xa1\x4c\xe7\x9c\xac\x43\x60\xa2\x68\xa3\x88\xcb\x22\x73\x0b\x54\x86\xc5\x84\xfb\x84\xb3\x44\x84\x60\x64\x3e\xf2\x5a\xb6\x90\x2a\x49\x8c\x6e\x20\x6c\x25\xf9\xc9\xf3\xc8\x57\x43\x54\x82\xe6\x6c\xef\x7b\xc4\x89\x98\xed\x7d\x0b\xc9\xd4\xb8\xf2\xb7\x45\x85\xb6\x21\xe7\x8a\x1f\x50\x62\x48\xc8\x32\x92\x60\x27\x17\xc9\xc8\xce\xb0\xe3\xc1\x11\xfb\x72\xfe\xe9\x76\x19\x7c\x78\x9f\xc8\xf1\x78\x3c\xfe\x78\xf7\x90\x4e\x1e\x12\xfb\x58\xfc\xfe\x70\x31\xfe\xf7\x78\x3c\xbe\xf8\xf8\x2f\xfd\xc7\xa9\x15\xdc\x4c\xf8\xe4\xe6\xcb\xed\xa0\xf7\xbf\xc7\x0f\xcb\x9b\xd9\xf8\x6a\xbc\xba\x7c\x78\xa0\x2b\xf3\xe9\xb8\x73\x7b\x7e\x33\xbb\xf9\xcf\xe2\x8e\x9d\x5c\x75\xf2\xeb\xc1\xb9\x7c\xbf\xec\x3c\x7e\x9e\xa5\x83\x47\x96\x7c\xce\xf4\x43\x92\x06\xc7\xbd\xe3\xf1\x7f\x6f\x75\xb2\xfa\xe7\xfd\xec\xe1\x3e\xd5\xef\x7b\xf7\x1d\x7d\xc5\x7f\xd0\x7b\x9d\x0f\x7b\xb3\xbb\xbb\xee\xd2\x7a\x39\xff\xeb\xf6\x61\x38\x51\xb3\xbf\x92\x24\x39\x3b\x7b\x57\x5f\x0e\xd0\xcf\x57\x10\xb8\x91\xf5\xe4\x79\x4c\xe4\x73\xf3\xd5\xac\x73\x3c\xdb\xa3\xc4\xa0\x61\x19\xfa\x5c\xc6\x84\xef\x7d\xab\x35\x5b\x2f\x70\x55\xb6\xa1\xaf\xdd\x57\x98\x35\xcb\x2e\x68\x9f\x0c\xad\x6c\xcb\x6a\x34\x37\x46\x8a\x86\xb5\xfe\xf0\x2d\xc6\x82\xd2\x58\xe7\x10\x26\x82\xfa\x16\x19\x28\xdb\x8f\x33\xc4\xbc\x38\x0d\x2a\xc0\x50\xf8\x03\x22\x68\x21\xbe\x26\x06\xb5\x01\xe7\x18\x8a\x7f\x04\x5b\x30\xb0\x64\x26\x95\x73\x03\x31\x67\x79\xce\x44\x62\x2f\x84\x7d\x37\x59\x90\x4e\x04\xbd\xb7\xc6\x6a\x23\xe6\xa4\xa2\x69\x9f\x3b\x9b\xcf\xef\xdc\xe8\xaa\x4d\x48\x38\xd9\x41\xa9\xad\xc1\x26\x91\x83\xdd\xb1\xbb\x38\xef\x65\x92\x70\x04\xbd\x64\x26\x4e\x41\x9b\x35\x2f\x41\xb6\x9d\xa8\x79\xa4\xec\x6e\x07\xa8\x92\xed\xc6\x43\xaf\x9a\xf2\x2f\x4d\xe4\x75\x23\x6f\x68\x29\xa8\x99\x69\xae\x53\x85\x9c\xd8\x5e\x1e\xbd\xde\xa3\x9b\xdd\xd0\x08\xbf\xdc\x09\x25\x60\x37\xe4\x4a\x66\x4b\x59\xb9\x3c\x8a\xf9\x05\xb0\x71\xef\x32\x5e\x27\xa1\xba\x3e\x0a\x25\xce\x68\xb9\xc1\x36\x18\x49\xa4\x25\x9f\x9b\x62\x9f\x6f\xdf\x09\xad\x82\x2a\x3b\xc6\x1d\x04\xfb\xf4\xec\xb8\x15\x49\x63\x64\xb6\x7d\x24\x6c\x86\x75\x1c\xc7\x23\xaf\xe5\x2f\x31\x9a\x31\xe3\x1b\x45\x44\xe5\xb3\x3d\xd0\xd6\xf8\xb6\xa4\x0e\x32\x8c\x70\x2a\x15\xbe\x8e\xb5\x9a\x41\x7b\x7b\xf5\xb2\x29\xee\xa3\x4d\x9d\xba\x5f\x9b\xc5\x56\x83\xec\x56\xc1\x2b\xe7\xe9\xdf\x40\x5d\xf0\x1e\xc6\x29\xc6\x33\xa4\x7f\xd4\x88\xde\xc1\xcb\x71\x44\xa2\xfe\xb0\xf1\xe1\x54\xc6\x73\xdd\xf8\x6c\xfb\x68\xca\x57\x3b\x3f\xdc\xf2\x58\x63\xad\x11\xc1\x54\xaa\x2c\x84\xe2\xd1\x76\xec\xe3\x81\xa5\xc6\xce\x3f\x3f\xd3\xbf\xd1\xf8\xe5\xdb\x27\xdb\x9d\xb7\x36\x3a\xa4\xe0\x20\x68\x38\xec\x3c\xa7\xb1\x5d\x84\xee\x22\x6a\xdc\x86\xfd\xf2\x92\xdd\x56\xad\x45\xb0\x7d\x4d\xba\xcd\xf4\xff\x00\x00\x00\xff\xff\xbb\x76\x2b\xd5\x9e\x0d\x00\x00") func webfilesSloopCssBytes() ([]byte, error) { return bindataRead( @@ -345,12 +345,12 @@ func webfilesSloopCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/sloop.css", size: 3310, mode: os.FileMode(416), modTime: time.Unix(1780070296, 0)} + info := bindataFileInfo{name: "webfiles/sloop.css", size: 3486, mode: os.FileMode(416), modTime: time.Unix(1781211012, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _webfilesSloop_uiJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x7c\xfb\x73\xdb\x36\xf2\xf8\xef\xfe\x2b\xf6\x98\xcc\x99\x8a\x25\x4a\xb6\x93\xd4\xf5\xeb\xc6\xb2\x9d\x6b\xbe\x97\xb4\xfd\xd6\xe9\xb5\x19\x8f\xa7\x81\xc8\x95\x84\x33\x45\xf0\x00\xc8\x96\x9a\xfa\x7f\xff\xcc\x02\x7c\x80\x2f\x3f\x72\x6d\xef\xdc\x99\x86\x22\x16\x8b\xc5\x62\x77\xb1\x0f\x10\xc3\x17\x1b\xf0\x02\x4e\x45\xba\x96\x7c\x36\xd7\xe0\x87\x3d\xd8\x19\x6d\x7f\xdd\x07\xc5\x62\x54\x53\x21\x43\x0c\x42\xb1\xe8\x03\x4f\xc2\x80\x60\x4f\xe2\x18\x0c\xac\x02\x89\x0a\xe5\x0d\x46\xe6\xfd\xc5\xf7\x67\x3f\x0f\xde\xf1\x10\x13\x85\x83\xb7\x11\x26\x9a\x4f\x39\xca\x7d\x18\x5f\x9c\x0d\x76\x07\xa7\x31\x5b\x2a\x24\xc0\x37\x42\xc2\x74\x19\xc7\x10\x5b\x60\xd0\xb8\xd2\x7d\x50\x88\xf0\xee\xed\xe9\xf9\xb7\x17\xe7\x81\x5e\x69\x98\xf2\x18\x81\x27\xa0\xe7\x08\x12\x53\x01\x52\x08\x0d\x42\xc2\x5c\xeb\x54\xed\x0f\x87\x22\xc5\x44\x89\x25\x11\x28\xe4\x6c\x98\x61\x53\xc3\xda\x78\xc3\x8d\x8d\x50\x24\x4a\x43\xca\x62\xd4\x1a\xe1\x08\x3e\x6f\x00\x00\x4c\x98\xc2\x33\x26\xaf\xf7\xe1\xd2\x7b\xb6\x73\xbe\xfb\xf2\xe5\xc8\xeb\x83\xf7\x6c\x77\xfc\x72\xe7\xd5\x8e\x79\x7c\xb9\xfb\xf2\xf4\xd5\xb9\x7d\x3c\x7d\xf5\xfa\xf5\x89\x77\xd5\x2f\xfa\xbe\x23\x26\x98\xce\x67\x7b\x67\xe7\xe7\x5f\x1b\xb0\xf3\x57\xe7\x5f\xbf\xb1\x78\xce\x4f\xcf\xdf\xbc\x79\x69\x1e\xdf\xec\xbe\xd9\x7d\x73\x9e\x77\x4e\x25\x5f\x30\xb9\x36\x5d\xf7\xde\x8c\x4f\xc7\x63\x03\xb4\xb7\x77\x3a\x3a\xb3\x5d\xf7\xb6\x4f\xb6\x4f\xb7\xcd\xe3\xab\xf3\xbd\xed\x93\xd3\xbc\xeb\x9c\xcf\xe6\x71\x31\xee\xf8\xcd\xeb\xed\xd7\x27\x06\xec\x6c\xb4\xf7\xd5\x57\xd9\xb8\xe3\xd3\xf1\x9e\x45\x79\xb2\x3b\x3e\xdf\x3b\xf5\x6c\x5f\xfa\xf3\x9e\x8d\x5f\xee\x9d\x9f\x9c\x79\x7d\xef\xd9\xc9\xd9\xc9\xde\xf8\x35\x3d\x45\xec\xab\xd7\xaf\x46\xf4\x74\xf6\xf2\xeb\xd7\x27\x5f\x99\xd6\xf1\xe9\xcb\x93\x71\xa5\xeb\xc9\xcb\x93\xd7\x67\x3b\xd4\xf8\xf5\xf6\xf8\xfc\x8d\x7d\xfa\x6a\xbc\x7d\x62\x90\xec\x9d\x7c\x3d\x7e\xbd\x97\x13\xaa\xf0\x06\x25\xd7\x34\xc9\xcd\x67\x2f\xc7\x67\x7b\xaf\x5e\x6d\xf6\x61\xf3\xd9\xf9\xe8\x7c\x34\x1a\x99\xc7\xb3\xbd\x97\xe3\x97\xe3\xcd\xab\xfe\xc6\xdd\xc1\xc6\xc6\xc6\x70\x08\x7f\x8f\xc5\x84\xc5\x0a\xde\xf1\x1b\x84\x6f\x50\xe2\x46\x8c\x1a\xb4\x48\x4f\x56\x5c\xf5\x61\x22\xb4\x16\x0b\x7a\x3e\x30\xe0\x1f\xe6\xa8\x10\xa6\xcb\x24\xd4\x5c\x24\x0a\x66\xa8\x21\x64\x71\x8c\x11\xdc\xce\x31\x21\x0a\x8c\xf4\xa4\x52\xa4\x28\x35\x47\x05\x62\x0a\xc8\xf5\x1c\x25\xb0\x15\x57\xc0\x24\x42\x38\x67\xc9\x0c\x23\x77\xa8\x33\xc9\x6e\xdf\x2c\x93\xd0\x1d\x32\x7f\xe7\x0e\x4d\xdd\xa3\x5d\x50\x5a\x2e\x43\xad\x0c\x86\x15\xc1\x5e\x84\x2c\xc6\x3e\xac\xe9\x79\xcc\x92\xc8\xf6\x39\x91\x92\xad\x21\x14\x89\x66\x3c\xe1\xc9\x0c\x22\xa6\x19\x48\xd4\x92\xe3\x0d\x46\x30\x95\x62\x01\x2a\x16\x22\x05\xa3\x56\xd2\x20\x24\xa0\x62\x4c\xd0\x7c\x81\x10\x71\x95\xc6\x6c\x8d\x11\x88\x04\x42\x94\x84\x0f\x16\x62\xa9\x50\xd0\x94\x59\x12\xd9\x5f\x0b\x71\x83\x80\x37\x98\x64\xb4\xe9\x39\x7e\xe0\x0b\x74\x67\x10\xe1\x94\x27\x68\xb8\xb4\x60\x2b\xbe\x58\x2e\x20\x92\xec\x96\xa8\x53\x29\x0b\x91\x46\xa0\xc6\x5b\x9e\x44\xe2\x36\x80\xb7\x10\x89\x64\x93\x50\xf1\xe4\x9a\xd0\xe8\x39\x57\xc0\x95\x01\x0a\x85\x94\x18\x6a\xb8\x65\x6b\x62\xf4\x52\x11\x1a\x6d\xc6\xb9\x61\x52\xc1\x00\xb8\x86\x48\xa0\x22\x0c\x12\x59\x1c\xaf\xc9\x84\xa4\xa6\x8f\x19\x80\x7e\xf2\x5f\x79\x32\x23\xd4\x34\x8f\x5b\xe4\x32\x82\x05\x4f\x88\x34\x65\x5e\x65\xb3\x07\x15\xb2\x98\x06\x08\xc5\x32\x8e\x20\x15\x9a\x2c\x8e\xc1\x19\x92\xe6\xd3\xaa\x4f\x62\x5c\xa8\xc0\xb2\xd1\xf6\x7a\xcf\x56\x3f\xf7\x9d\x1f\x1f\x2d\x33\xfe\x49\xe2\x11\xb2\xd8\x4c\x9a\x90\x4e\x50\xdf\x22\x26\x30\x61\x52\x65\xe6\x43\xa2\x35\x36\x63\x26\x73\xf0\x8b\x0c\xfa\x08\x46\xc1\x8e\xc5\xa4\x6e\x66\x20\x71\x8a\x12\x93\x10\x61\x2a\x24\x48\x4c\x22\x94\x86\xa3\x37\xb3\x8c\x29\xd1\xae\x21\x4a\xdd\xcc\x6c\xaf\x0b\x4e\xd0\xb7\xb8\x49\x02\x95\xf1\x9f\x86\x26\xf6\x9b\x7f\x6f\x39\x71\xdc\x70\x59\xb1\x05\x96\xa2\x75\xcb\x23\x3d\x87\x81\x5d\x51\xae\x60\xc1\xe4\x8c\x27\xd9\xba\xda\x65\xb1\x0b\x99\xcf\xc8\x9a\x53\x3b\x15\xc2\x0d\x03\xc3\x55\xae\x37\x95\x23\x9b\x84\x6f\x62\x16\xc0\x0e\x9c\x8d\x5d\x0c\x6b\xc9\x5f\xb0\x38\x1e\x33\xf9\xde\x8c\x79\xb0\x61\x5e\x66\x04\xe4\x46\x56\x8b\x74\x1f\x76\x46\xd6\x28\xc4\x38\xd5\xfb\xb0\x3d\x1a\x19\x8d\xcf\x64\x4a\x24\x66\xd1\xc9\x2e\xc7\x82\x45\x17\xff\xfc\xfb\xc1\xc6\x46\xae\xd4\xc0\x13\x4e\xab\xca\x7f\xc5\x33\xbe\xc0\x44\x91\xa2\xfb\xbd\x0c\xb9\xb3\xa8\x70\x04\x91\x08\x97\x0b\x4c\x74\x90\x3f\x9c\xc7\x68\x7e\x87\x31\xc7\x44\xff\x44\x9c\x3a\xa8\xf5\xfb\xf8\x70\xbf\x6f\x90\xec\xed\xc1\xc6\xdd\xc6\x46\x84\x9a\xf1\x18\xa3\x0f\x42\xc4\x1f\x78\xfa\x56\xfd\x93\x2b\x3e\x89\x89\xf4\x29\x8b\x15\x66\x2c\x48\xc4\x85\x90\xfa\x0d\x31\xa1\x98\x47\x41\xb3\x44\xbd\x94\x09\x58\x16\x58\xc9\x0a\xc5\x22\x65\x12\x2f\x34\x6b\xf4\x62\x7d\x98\xe4\x3d\xf9\x14\x7c\x16\x5c\xf3\x24\x82\xbf\x1c\xc1\xc4\x3c\xe5\x6d\x0e\xe6\x0c\xdb\x3f\x78\x12\xd9\xee\x06\xe0\xce\x1d\x9c\x05\x8a\xc6\x82\x01\x4c\xec\xd3\x01\x51\x53\x21\xe6\xbd\x50\xfa\xdc\x98\x8e\x3f\x85\xa2\x49\x40\xa6\x2b\x66\x6b\x15\xc4\x98\xcc\x48\xa4\x81\xd5\xdf\x35\xa9\xfc\x96\x2d\xf0\x4f\xa1\xcf\xdf\xdc\x84\x2d\x60\x01\xb9\x2a\xbd\x20\x16\x64\xe0\x4f\x6d\x37\x7f\x62\xdf\x1a\xea\x68\xf9\xc3\x45\x6a\x68\xca\xc5\xc0\x15\xe7\x4c\xc2\x0b\x69\x48\xd9\x9a\x5e\x91\x14\xee\x06\xff\x52\x22\xf1\xc9\xde\xff\xff\x25\xca\xf5\x8f\x32\xee\x1d\xb8\x40\x81\x9e\x63\xe2\x97\x33\x95\xa8\x96\xb1\x76\xe7\xd3\xae\x2c\x07\x45\x3b\x19\xa0\xa3\xcc\x20\xe5\xdd\xcb\xd6\x09\x4f\xa2\xf7\xb4\x6f\xd8\x75\xf7\xd5\xcd\xcc\x69\x65\x69\x8a\x49\x74\xb2\xc2\x7a\x83\x45\x47\x2a\xa1\x79\x9a\x8f\x76\x47\xec\xd8\x28\x66\x6b\xad\xdc\xf7\xd9\x64\xb5\x98\xcd\x62\x04\x75\xcb\x75\x38\x37\x7b\x98\xd9\x82\x41\x8b\xc2\xb8\xe7\x7c\xc9\x5b\x78\x78\xad\x4a\x2e\x66\xad\xa7\x73\x0c\xaf\x51\xfa\xe5\x72\xfb\x85\x2e\xcf\x30\x57\xe3\xf1\xfa\x6d\xe4\x7b\x6e\x17\xaf\x17\x84\xa6\x6b\x04\x47\x47\xa0\xe5\x12\x5d\x26\x9a\x6d\x3a\xa0\xcd\xb8\x0d\x9b\x1a\xaf\x4f\x63\xa6\x14\x49\x9e\x83\x95\xa8\xf4\x7a\xbd\x02\x09\xfd\x05\x0b\x96\xfa\x08\x47\xc7\x80\x81\xd2\xeb\x18\x83\x7c\x76\x47\xe0\x4d\x62\x41\x84\x64\xdc\x02\x8c\x15\xfe\x11\x34\xdc\x4f\x44\x22\x12\x2c\x68\x20\x03\x37\x1c\x02\x9c\x65\xed\x11\x9f\x9a\x6d\x4c\xc3\xbf\x49\x1c\x61\x81\x7a\x2e\x22\x65\x5c\x5f\xe3\x79\x48\x16\x71\x01\x37\x2c\x5e\x62\xb9\x34\x06\xd6\xd2\xe2\x1b\x00\x57\x17\xcd\x8b\xc0\xf4\x80\xa3\xa3\x23\xf0\x24\xce\x70\xe5\x7d\x29\xf7\xb3\xde\x5f\xca\xf5\xa7\x33\x5a\x6a\x4e\x93\x7c\xd2\x90\x55\x1e\x77\x72\xc2\x41\xfe\xa7\x71\xc3\x25\xed\xcf\x61\x46\x55\xea\x33\x89\xbb\x98\x8b\x5b\xe3\x5d\x60\x12\x91\xdf\x48\x8f\xa5\x8b\x9b\x39\x86\xbe\xf1\x8e\x8d\x3b\x63\x7c\xe3\x4d\x05\x38\x9d\x62\xa8\x29\x54\xb0\x02\x2a\x49\xe8\x7a\x99\xab\x42\x88\x31\x89\x06\xc6\x61\x9e\x88\x55\x9f\x9c\x9b\x1b\x94\x1a\xc9\xfe\x18\x44\x13\xb1\xda\x54\x60\x6c\xb9\x05\x33\x10\x09\x4d\x2a\x30\xce\xb6\xd2\x42\x62\x64\x25\x9c\x7c\x5c\x72\x5f\x8c\x63\x1a\x8b\x04\xf7\x81\x25\x80\x8b\x54\xaf\xab\x70\xd7\x88\xa9\x02\x2d\x59\x78\x9d\xb9\xbf\x90\xe0\x2d\x2a\xeb\xc9\x1b\xbd\x41\x63\xcd\x4b\x9d\x59\xa6\x11\xd3\x78\x9e\x44\xe4\x9d\x8f\xc5\xca\xc7\x24\xfa\x31\xe1\xab\x0b\x0c\x45\x12\xa9\x5c\x20\x68\x6f\xc1\x24\x3a\x63\x26\x86\x4d\xf0\x16\xe8\xb1\x06\x0c\x2f\xc8\xbf\x1a\x65\x2c\xce\xc0\x03\x85\xfa\x3d\x4f\x96\x1a\x95\x9f\xbf\x9a\x95\xaf\x7a\x30\x00\xe7\x35\x51\xf1\xab\x48\xf0\xbb\xe9\x54\xa1\xf6\x7b\x6d\xb8\xe2\x98\x2b\x3b\xa0\x9f\x2c\xe3\x7c\xa3\xea\xb2\xbe\x9b\x0a\x63\x0c\x35\x46\xd9\x1c\x37\x7b\xb9\xe8\x17\x58\xb5\x78\x7b\xf1\xdd\x85\x26\x3f\xd9\xef\x05\x8a\x82\x79\x7f\xd4\x87\xc1\xb6\xd9\x48\x4a\x5e\x55\x37\x2f\x87\x33\x86\xbb\x47\xe4\xf5\x87\xa8\xd4\x49\x12\xd1\xe6\xfb\x43\xe6\xe8\xaa\xea\x6e\x97\xc3\x8f\xd7\xb4\xe7\xf7\x81\xfc\x02\xd5\x87\x29\x8f\x35\x4a\x24\x82\x28\xe4\x22\x48\xda\xb5\x8c\x3b\xef\x88\xde\x80\xfc\x85\x25\x09\x52\x5d\x02\x33\x59\x25\xaf\x5f\xe7\xc1\x1a\xc5\x99\xfb\x14\xf8\x48\x9c\x12\x13\x28\x88\x59\xe7\xb8\xc3\x98\x2d\x52\x23\x26\x56\x24\xcd\x24\xd8\x0d\xe3\x31\x9b\x94\xd9\x0f\x23\x5f\x7d\x50\xc2\x84\xb5\x70\xc3\xd1\x04\x08\x14\x3b\x66\xa2\x37\x61\xe1\xf5\x32\x35\x72\x9f\x61\x36\xe1\x2d\x92\x40\x30\xed\x0a\xa1\xc4\x50\xc8\x08\x23\x3b\x14\x4f\x94\x46\x66\xb4\x4e\x69\x89\x3a\x9c\x3b\xc4\x48\xfc\xf7\x12\x95\x51\x18\xbe\xc0\x82\x71\x34\xfc\x77\xa9\x8d\xb8\xc9\x99\x20\xbe\x06\xf4\xf2\x17\x91\xbd\xfd\xed\x37\xf8\x7c\x57\x72\xda\xf0\xe6\x27\xcb\x9a\x23\x20\x71\x39\x28\xec\xa0\x83\x2c\x30\x70\xbf\x58\xcf\xf4\xaf\x7f\x85\x66\x13\x56\xbd\xb7\x2a\xde\xcb\x2e\x54\x56\x21\xfa\xed\xf8\xb2\xd6\xab\xd2\x08\x36\x94\xb1\x9d\x8e\xdc\x84\x15\x33\xf9\x0b\x31\xd4\x25\xaf\xcc\x04\x58\xef\x8e\xe2\x55\xfc\x51\x87\x7e\x2f\x30\x96\xca\xbf\xb4\xa1\x52\x40\x66\xa5\x5f\x89\x65\x06\xe0\x34\x5d\x39\x16\x9a\x06\x72\xa6\xed\x0e\x57\x1d\x32\x88\xc4\x82\xf1\xa4\x02\x5c\xa2\xb9\x2b\x9e\x8a\x80\xce\xa1\x91\x7e\xfa\xbd\x20\x65\x51\x44\xda\xd8\x1d\xf7\xf6\x32\x25\x01\x1b\xe7\xb9\x59\x12\x8b\x8e\x84\xf0\x83\x48\xfd\x92\x2e\xd7\xdd\x6c\xa4\x56\xca\x4e\x63\xd3\xd6\xde\xcf\xd5\x52\x5a\xf7\xab\x76\x17\xaa\xd4\x6f\x8b\x36\x41\xa5\xfd\x5e\x70\x8d\x6b\x3f\xa2\xdd\x29\xb2\xd1\x40\x80\x89\x96\x1c\x95\xf1\xbb\x9d\x51\x8c\x49\xa0\x9e\x05\x1a\xb3\xb1\xe5\x5d\x71\xed\x4e\x7e\xc2\xe4\xa9\x88\x85\xfc\x3b\x26\xe5\x3c\x0c\x2f\xbf\x93\x11\x4f\x58\xec\xf7\xf2\x05\x31\x78\x73\x09\xc8\x32\x92\x41\x91\xd5\x73\x7d\xf5\x2c\x81\xd6\x81\xf8\x1d\x4f\x90\xc9\x12\xef\xe5\xa8\x0f\xdb\x7d\xd8\xb9\xaa\xe3\xce\xf1\xb8\xf4\x76\x8b\x66\x75\x2b\x6f\x0a\x11\xe9\xf6\x65\xb4\x1b\x2c\xb8\x8d\x54\xfa\x90\x71\xc4\xe8\x5a\xaf\x4f\xd8\x16\x6c\x55\x6d\x23\x7d\xb9\xaa\xa1\x7e\xb2\x0a\x3c\x42\x64\x5b\x89\x8f\x76\xb3\xb1\x88\xa4\x2c\x90\xac\xbb\x2c\x55\x62\xb4\x48\xfb\xe0\x82\xc3\x0b\xf0\x77\x47\xbd\x5e\x49\x94\x16\x69\x7d\x42\x4f\x53\x97\x6a\xea\xc4\x24\x90\xb6\xe1\x45\x39\xb7\x60\x92\xe7\x76\x4c\xf0\xd4\x2d\xfc\x41\x28\x92\x90\xe9\x80\xa5\x69\xbc\xf6\x2f\xaf\xfa\x1d\x12\x6b\xf6\x5b\xd5\xeb\xd0\xa3\x60\x2a\xe4\x39\x0b\xe7\x39\x74\x48\x42\x67\xf9\x6b\x1e\xfd\x9a\x84\xfb\x99\xf6\xf4\xaa\x76\xf0\x69\x46\xe0\xa9\x06\xa0\xd8\x50\xd4\xcd\xcc\x24\x73\xe0\xc8\xb5\x78\x76\x11\x7b\x97\xdb\x57\xb0\x05\xfe\x0e\xbc\x70\x25\xc8\xd9\xf8\xd5\xcd\xcc\xa6\x74\xe0\xc8\xe1\x77\x67\x6f\x2d\xd2\x5e\xe9\x0c\xc8\x2c\xa9\xba\xe2\x4a\xe7\x29\xbd\x22\xdd\x67\xf3\x93\x12\x43\x89\xe4\xa3\x71\x1d\x40\x1e\x97\x52\xc8\xec\x18\x27\x1b\x88\x93\xf4\x1a\xc7\xc8\xf7\x9e\x45\xbb\xbf\xcc\x51\x56\xdc\x71\x75\x33\xcb\xda\x4f\xe2\xd8\xdf\x7c\xb1\xd9\x0b\xec\xf0\x7e\x25\x9c\xb8\x07\x57\x81\x2a\xb0\xd1\xbb\xef\xa9\x9b\x59\xe5\xb5\xd6\xd2\xf7\x68\x87\x1b\x8b\x95\xd7\x87\x4f\x23\x18\xc1\xf3\xcf\x39\x83\xef\xec\xb3\x65\xd7\xdd\x27\xa7\x63\x48\x91\x00\x5a\x84\x83\x50\x24\x1a\x13\xed\xf5\x6d\x2c\x4d\xf2\x6a\x20\x89\x2e\x9a\x44\x3e\xf8\x2c\x9f\xdd\x70\x08\xa7\x96\x47\xe4\x67\xcc\x24\x4b\xe7\x26\xfb\x2a\x31\x95\xa8\x30\xd1\xcc\xf8\x7a\x62\x0a\xc8\xc2\x79\x91\xae\xb4\x48\xa5\x58\xa6\x64\x99\x67\x25\x35\x25\x97\xbc\xca\xf4\x48\x15\x7c\x57\xce\x9d\x36\x4c\x34\x4a\xbf\x85\x45\x2d\x0c\xd2\x92\x25\x6a\x2a\xe4\xc2\x23\xc3\xd0\x07\xde\x23\x35\xf9\x64\x5e\xc7\xe4\x83\x13\xd3\x0a\x59\xf2\x79\x0f\xb6\x6a\x1a\x7e\xd7\x73\xb9\x47\xb3\xf2\xad\x94\xfc\x50\x9a\x8b\x5c\xcc\x0a\x2f\xda\xd8\xdd\x0b\x33\x37\x21\x7d\x6f\x22\xa2\xb5\xd7\x0b\x4a\x06\x98\x87\x03\x37\x4d\xa5\x6e\x66\xe4\x2d\xe7\x36\x3f\x0b\x13\xde\xb3\xd4\xbf\xbc\xf4\xbe\x15\x72\xc1\x62\xaf\x3f\xba\xea\x5f\x7a\x3f\x31\x99\xf0\x64\xe6\xf5\xb7\xe9\xd7\xb9\x94\x42\x7a\xfd\x9d\x2b\x63\x69\xcb\x3c\xcb\xfd\xce\xb4\xe3\x7d\x3f\xe8\x14\x1e\x38\x9e\x52\xd6\x2c\xc5\xad\xea\xd5\x76\x6c\x38\x82\xcf\x77\xdd\x1b\x7a\x89\x9b\x3a\x97\xf6\xad\xea\x06\xe5\x09\xb8\x6a\x5e\xf5\xa0\x02\x93\x25\x9f\x2a\xde\x9d\x12\x52\xd7\x5d\x2a\x83\x8f\x29\x04\xcf\xec\x70\xe4\x09\x7b\xfb\x0d\x88\xc7\x8e\x9a\xff\x4d\x24\xb2\xeb\x66\x93\x1d\x28\x61\x8f\x1d\xc3\xa6\x3f\xbf\x60\x88\x85\x50\xda\x16\x86\x1e\x37\x90\x9b\x0d\x7e\xd2\x70\x11\x4e\xd9\x32\xd6\x1d\x83\x88\x44\x89\x18\x83\x58\xcc\x7c\xef\xc7\xe4\x3a\x11\xb7\x09\xd0\x22\xec\x83\x07\x5b\xd0\x58\x9a\x47\x8f\x7c\xb7\x51\xf9\x69\x45\xa6\x28\x49\xb8\x7f\x41\x10\x44\xfd\xc6\x5b\xb3\xd4\xfb\xb9\x57\xf3\x0b\x05\x04\x79\x18\xd1\x80\xc5\x24\xda\x07\xbf\x05\x94\x8c\x80\x1f\x05\xd1\x52\x5a\x6b\x96\xbd\x6d\x62\xc8\xb3\xdc\x34\x60\x91\xf1\x2e\xb2\x28\x4d\x9a\xc1\x5a\x50\xcc\xcb\x6e\xdf\xd9\x3e\x59\x19\x32\x2b\xfd\x44\xc0\x93\xae\x9e\xe9\xf5\x6c\x68\xea\x8c\x43\xb2\x30\x1c\xd5\x50\xaf\x53\x54\xc1\x4c\xb4\xf6\x30\x9b\x66\x1a\x73\xfd\x01\x57\xc4\x45\x34\xf9\xee\xc0\xbc\xf2\x3d\xf0\x7a\x9d\xbd\x6e\x85\x54\xfa\xa2\x34\x46\x99\x73\x58\x20\xeb\x9b\xd2\x7f\xf7\x2c\xc1\xb1\x6c\x19\x96\x60\x86\xda\x77\xc7\xdf\xf7\x68\xd3\x6e\xa7\xe1\xce\x75\xb9\xea\xc4\x65\xac\x6e\x15\x8b\xfc\x2f\x08\x02\x6c\x2e\x58\xfe\x97\x89\x89\x8f\x2d\x8b\xdf\xdd\xcb\x0a\x4c\x5b\x1f\x12\x18\x7c\x84\xc0\x14\xe3\x17\x35\xf6\x0a\xa3\xbb\x3b\x48\x64\x4a\x24\xfb\xd9\x0a\x76\xc3\x85\x62\x99\xe8\xfd\x72\xd1\x2f\x77\xae\xda\x81\xef\xda\x55\x32\x5b\xb3\x8c\xc3\x0d\x90\xbb\xea\x6a\xd5\x90\x64\x9d\xad\xd2\x96\x21\x6b\xcf\xd8\x00\xdf\x18\xa6\x4a\xf5\xc1\x40\xd3\xe6\x50\x26\x15\x8b\x0d\xac\x51\xd9\xa9\x16\xe1\xf2\xaa\x8e\x8d\x04\xeb\x55\x1d\xf3\xb6\x82\xae\x56\x03\xc9\xf7\x3f\x9e\x60\xcd\xd3\xa1\x57\x4d\x37\x62\xbd\xed\xf5\x5b\x5c\xce\xd1\x55\x13\x72\xa7\x15\x72\xbb\x09\xa9\xb4\x14\xd7\xe8\xf5\xc1\x93\xb3\x09\xf3\x47\x7d\xf3\x5f\xf0\xaa\xe7\x0e\x6f\xf2\xb0\xbe\x97\x0a\x4e\x4e\xcf\x20\xb3\xfc\xfd\x32\x03\xec\x7a\xef\x76\x2a\x4f\xf7\x8b\xee\xf5\x89\x9c\xc9\x56\x5d\xa1\x90\xc5\xb1\x5f\x8b\x1b\xba\x27\x99\x07\xb5\xc5\xf1\x9b\x2a\x4b\x0a\xaf\x34\x43\xe8\x78\xa4\x50\x09\x38\xfe\xd8\x39\x6e\xb7\xcd\xb1\x19\xed\xfc\xe7\xd3\x2c\x71\x3a\x33\x6d\x66\x4b\x8b\xda\x5c\x51\x93\x37\xbf\xab\x51\x83\xf5\x2e\x9b\x2c\x89\xf8\x8d\xd7\xce\x62\x83\x24\x1f\xb8\x32\x6c\x5b\x25\x31\x1b\x9b\xb4\x44\x24\xbe\x57\x1c\x50\xf1\xfa\x2d\x45\x72\xc8\x6c\xf4\xe5\xaa\x0f\xeb\xab\x6c\xe7\xa0\x1e\xbe\x9e\x73\xe5\x5a\x75\x72\x28\x9d\x20\x90\x9b\x1c\xbf\xbf\xea\xc1\x61\x4b\x36\x8c\xc4\x0f\x7e\xfb\xad\xa3\xc7\x71\x6b\x8f\xed\xab\x5e\xdd\x27\xac\xf8\x2d\xc5\xd1\x91\x09\x93\x20\x96\x9a\xa2\x96\x89\x58\x26\x91\x82\x95\xc3\xb8\xcc\x9d\x25\x72\xd7\x70\xd8\x6a\x05\x0c\x65\x6b\x38\x6e\x57\xfc\x2f\x25\x42\x8b\xb4\x49\x46\x15\x15\x59\xab\x16\x69\x77\xe4\xfc\xf9\xe7\xd5\x1d\x8c\x7a\x9f\x6a\x2e\x58\x76\xa0\xa8\x1a\x87\x17\x0c\xad\xc2\xda\x1c\x69\xc7\x01\x8a\x36\xaf\xdb\x9e\xc7\x32\x42\xf6\xb3\x95\x00\x63\xb7\x82\x94\xcd\xf0\xe7\xe6\xbe\xe3\x80\x7f\xac\x83\x7f\x6c\x82\xa7\x42\x99\xf2\x55\xae\x1b\xf9\x48\xfd\x02\x49\xaf\xee\x53\x56\x9f\xee\x8a\xbc\x8c\x1b\xa5\x7b\x41\x1e\xac\x7a\xbd\x52\xce\x69\x23\xac\xc8\x79\x25\x8f\xfd\x24\xce\x94\x1a\x6b\x34\x21\x5b\xb6\x29\x8f\x63\xaf\x9f\x27\x6e\x82\x88\x49\x53\x17\xaf\x2f\x97\x9d\x59\xbe\x1d\x88\x94\x85\x5c\xaf\xbd\x3e\x6c\xf7\x1a\x93\x2b\x89\x8f\x91\xd5\xb4\xf4\x8f\xa2\xfe\x91\xc9\xa6\x07\xa7\x33\xba\x6f\x3a\x0d\x9b\xf3\xe5\xb3\xc9\x09\x98\xeb\x45\xec\xcf\x50\x3b\xb1\xfc\xa9\x4d\x89\xf8\x0d\xb9\x6b\xf7\x35\x35\xd7\x31\x92\xff\xdf\xed\x97\x11\x0b\xf6\xb3\xac\x75\x3b\x04\xc5\x8d\xe6\xac\x17\x81\x15\x3f\xda\x61\x29\x8e\xdd\xcf\xf5\xb7\xe9\xa0\x55\xde\xf4\x3a\xd8\x19\xc6\x3c\xbc\xee\x66\xa5\x9a\x8b\xdb\x33\x87\x93\xa4\x65\x51\xbf\x50\xcc\x3e\x64\xa6\x1c\x32\x65\x02\x1b\x9c\xbc\x4d\xf4\x92\x6b\x7e\x83\xf1\x1a\x36\xa3\x4d\x42\xb3\x8c\x23\x98\xd8\x5c\xd1\xe6\x1c\x99\x5e\xb0\x74\x13\xd0\xd6\x17\x61\x00\x93\xa5\x36\x25\xb7\xdb\x39\xd3\xe6\xcc\xa7\x75\x73\x73\x84\xa6\xb2\x4c\x23\x9a\x6d\x49\xe5\xa7\x14\xe3\xb5\xe9\x48\x43\x64\x71\x54\x71\x2a\x2e\x43\x1d\xc0\xb7\x42\x83\x5a\x4a\x84\xdb\xf9\x1a\x06\xf0\x36\x3b\xf6\x98\x21\x8e\x76\x33\x8c\xd6\x9f\xa2\xf8\x8b\xcc\x75\xbc\x86\x98\x5f\x13\xb9\x4c\x07\x2d\x06\x22\x9b\xc1\x1f\x64\x1f\xc8\x0c\x92\xff\x9a\xe8\xd3\x3c\x87\x5b\x33\x0a\x07\x0d\xf8\xcc\x4f\x7f\x9b\x44\xb8\x82\x23\xea\xae\xf0\x6d\x62\x75\x94\xe2\xad\x13\xad\x25\x9f\x2c\x35\xfa\x1e\x27\x18\xaf\xae\x89\xf6\x70\x29\x57\xdf\x15\x21\x55\x19\xc9\x5e\xba\xd8\xaf\x6a\xf1\x58\xd5\x1e\x04\x96\xf0\xac\x72\xdc\x2b\x5c\x13\xd7\xa6\x56\x2c\x86\x33\xd1\x1a\x45\x5f\x66\x68\x9c\x39\xd8\x33\x5d\x3d\xd7\x94\x36\xa6\x9c\xe5\x3d\x5b\x23\x48\xea\xbe\x0f\x75\x84\x4d\x65\xbc\x5f\xad\x1f\xab\xd2\x0f\xd8\x8f\x2c\x50\x75\xa9\x31\xaf\x3a\xb2\x19\x2e\x1c\xd6\xc9\xba\xab\x31\xe2\xb1\xeb\xfe\xf4\xd5\x69\xab\x80\x55\x96\xa8\x28\x6d\xf5\xba\x76\xbc\x2e\x72\x02\xc3\x30\x38\x82\x16\x11\x37\x4d\x5e\xfb\x5e\xd3\xcc\x1f\xdd\xb7\x97\x16\x40\xf9\x06\xf1\x8d\x55\xfd\x7c\x73\xc8\xe4\xa7\xd7\xa8\xcc\xfe\x39\xdb\xef\x93\xd5\x2d\xb3\x24\x6d\xaa\xf0\xa7\x9a\x90\x47\x8b\xd2\x13\x24\xe8\x3f\x74\x2d\x7e\xe7\xbd\xb0\x65\xdb\xa8\x1d\xf3\xfb\xc3\x36\x8f\xd5\xf7\x82\xc2\xe3\xad\x76\xc6\xae\xea\x8a\x61\xd2\x7c\x59\x31\xae\xa3\x8f\x69\x6e\xeb\x37\xcf\xcb\x70\x1d\x1d\x6d\x7b\x5b\x4f\x82\xb2\x9c\x78\xa4\xb0\x65\xc9\xb4\x2a\xa6\x1b\x26\xb3\x03\xa6\x63\x21\xe2\x66\xb8\xd2\x4e\x15\x8f\xbc\x7a\xae\xc8\x4b\x44\x98\xad\xcb\xd1\x11\x8c\x5a\x6b\x08\xc5\x38\xe5\x61\x71\xb7\xbd\x35\x30\x6b\x74\xa4\x50\xfb\xde\x54\xf7\x83\xdb\xd2\xfd\x1b\x45\xee\x16\xe6\xdc\xed\x43\x07\x3d\xfb\x2e\x5d\xf7\xee\x0f\x5d\x72\xd4\xb7\x92\x36\x80\x57\x55\x39\xe9\x67\xe2\xb4\x05\xdb\xa3\x47\x6d\xea\x99\x94\xf4\x73\x71\x6a\xe9\xf8\xfb\x58\x6f\xcb\x92\xff\x9a\xf1\xfe\x9f\x55\xce\xa7\x2c\xf7\x56\xc7\x72\x0f\xb6\x47\x1d\xeb\x39\xe8\x5a\xcd\x47\x19\xe7\x5a\x3e\xac\xb9\x07\x47\x6e\x15\x93\xc5\xf1\x0f\x26\x76\x30\x27\x7f\xea\x65\x8e\x40\x62\xb4\x0c\xd1\xf7\x65\x1f\xe2\x3e\xf0\x3e\xb0\x5e\xb5\x76\x51\xaf\x94\xc4\x4e\x91\xe2\xa0\x0a\x95\x6d\x3c\x19\x60\x99\x69\xdf\xbe\x6a\x07\x3c\x15\x91\x49\x32\xbb\x65\x10\xb7\x57\x07\xfe\x3c\x08\xa8\x9f\x06\xba\x74\xf1\x5e\x35\xd2\xe9\x9f\x0e\xb5\x3c\x6e\x06\x8e\x87\x3a\x3a\x86\xc3\xc9\x31\x3c\xff\x5c\x8e\x3d\xba\xba\x83\xc3\xe1\xe4\x18\x0e\x87\x3a\x7a\x6c\xa7\x9d\x4a\xa7\xa6\x95\xc9\x7b\x81\x59\xe4\x23\xcf\x38\x1e\xfb\xcf\x3f\x57\xe6\x75\xe7\x1d\x97\x6f\x08\xed\xdd\xbd\x74\x0c\xb5\x3c\xfe\x04\x5b\x20\xad\x6c\xf4\xc1\xf3\xdc\x53\x25\x9a\xd9\x2f\x79\x3e\x1d\x9a\xa7\x63\x20\x1e\x18\x3a\xac\x4c\x58\x4a\xe9\x37\xc5\xcc\x0a\x2e\x10\x9d\x77\x79\xf1\x25\x7b\x43\x63\xc1\xf3\xcf\xa5\x40\xd1\x74\x2d\xde\x4f\x95\x8a\xfd\xa7\x6f\x19\x99\xdc\xc3\xc9\xf1\xf3\xcf\x91\x75\x4b\xcd\x2c\x0e\x27\x72\x58\x4e\xe2\x1f\x26\x4a\xc8\x80\x28\x54\x68\x81\xf9\xb6\x8c\x15\x32\xc0\x22\x60\xc8\xa1\xc1\x01\x7f\xfe\xd9\x90\x73\xe7\xbc\x98\x0a\xb9\x60\xfa\x8c\x69\x93\x15\xc8\x6b\x9a\xbd\x3b\x18\xb4\x35\x62\x12\xf5\xee\x3e\xd5\xd5\xab\x25\x07\x12\xd5\xaa\x2e\x9f\x0e\x23\x7e\x03\x3c\x3a\xf2\x34\x4f\xd6\x83\x3c\x91\x7c\x7c\x1f\x27\x3e\xc1\x56\x41\xe8\xa7\x7b\xb8\x51\x81\x7b\x04\x47\x6a\x3d\xcc\x9b\x96\xb9\xd2\xbe\xd8\xbb\x3b\x1c\x46\xfc\x86\xd6\xaf\x36\xe7\xea\xc6\x10\xb9\x5f\x3c\x44\x81\xdd\x27\x5b\xbe\x3a\xfa\x8f\xd9\xf0\x7d\xf5\x1b\x19\xa6\xdb\x56\xc9\x52\x0e\x19\xe9\x56\xf2\xeb\xae\xc6\xef\x45\xd0\xb7\xa2\xfe\xdd\xce\xe3\x69\xaa\xf0\xb4\xde\xa3\x26\x40\xc5\xd1\xf7\xa8\x17\x68\xf1\xe3\x87\xd3\xfc\xdc\x78\xb5\xf6\x57\x3f\x5f\x53\xe2\xb1\xdf\x90\x61\x5c\xa9\x80\x38\x2e\xb8\x6d\x57\xab\x4a\x62\xbb\xd0\x07\xc7\x66\xdc\xc2\x11\xbc\x67\x7a\x6e\xca\xda\x15\x50\x73\x56\x79\xd0\xd6\xbd\x5f\xfa\x27\x76\x1c\xae\xde\xb1\x09\xc6\x3f\x64\xfb\xad\xaf\x56\x70\x5c\x39\x0b\x39\x84\x1d\xf8\x1b\x91\xb3\x05\xb7\x70\x58\x69\xda\xa7\xd7\x03\xb8\x85\x63\x18\xe5\x84\x61\x5c\x2c\x49\x51\xc5\x91\x18\xea\x66\x6d\x8b\xb6\x65\xb5\x6a\xbc\x2e\x76\xe0\xd6\xe3\x88\x30\xb0\xe7\xe3\xaa\x07\x9c\x7a\x0d\x2c\xc5\xfe\xde\x68\xc9\xa2\xb3\xae\x34\x6f\x09\x5e\x14\x9b\x8a\x88\xb4\x5a\xd0\x33\x1f\x5b\xc2\x11\x8c\xdc\xd3\xfa\x3c\x29\x6b\xfb\x59\xae\xcd\xa4\x07\xcd\x51\x32\x31\xf9\x17\x86\xb6\xaa\xec\x1c\xb6\xc8\x4f\x3f\x96\x6e\x5a\xd6\xe4\xaa\xad\x5d\xac\xac\xe1\xe2\xe7\xaa\x6c\x08\x37\xad\xe2\xec\xc5\x95\x4e\x3f\xb5\xf7\x69\x8a\x4a\x1d\x5b\xc5\x61\xf4\x4b\x12\x0e\x69\xf5\x4c\xd9\xc8\x79\xb9\x55\x0c\xd7\x83\x63\x23\x4d\x5b\x70\xdb\x6b\xd4\x8f\x92\xad\xad\xaa\x5b\x55\x29\x28\xe5\x61\x78\xb5\x96\x64\x3f\x67\xce\x93\x03\x8e\xe3\xdb\x5a\x55\xa2\x3d\xd5\xba\x37\x9e\xd7\x12\x5c\xd9\x0c\x5b\x47\xea\xac\xf0\xbf\xee\x0b\x76\x1c\x41\x7f\x48\xe0\x6b\x12\x48\x82\x5f\x70\xac\x13\x6a\xdd\xa9\x02\x2f\x60\x14\x6c\xbf\xea\xec\x28\x09\xff\xeb\xee\xe6\xf5\xbd\xcd\x0f\xa8\x1f\x8d\xdd\xdd\x39\xd7\xba\x42\xe4\x08\xfc\xab\x6e\x52\x1f\x95\x74\x13\x8d\x74\x49\x27\xbe\xd6\x1a\xf6\x19\x93\xd7\x97\xbb\x2d\x87\x74\x2a\x9d\x06\x39\xed\xde\x76\xba\xea\x5e\x3b\x9b\x9f\xb3\x47\x87\xba\x81\xda\xeb\x98\x23\x78\xfe\x79\x70\xcf\xc9\xcc\x1a\x16\x9b\x3d\xe8\x93\xae\xb4\xc0\x14\xd6\x29\xcf\xe8\xe7\xa5\xf0\x1c\xe2\xae\x9a\xcf\xb1\x52\x9f\xa7\x0a\x98\x86\xbf\xd8\xaf\x61\x2a\x67\x20\x9d\xf6\x16\xb3\x44\x3b\xa7\xd2\x6c\x91\xd6\xf5\x66\x38\x04\x16\x45\x30\x89\x59\x78\x6d\xbe\x96\x85\x05\x93\xd7\xb4\xff\xda\x33\x02\x46\x89\x59\x12\xc1\x00\xb6\x87\xdb\xa3\xfc\xe7\xef\xa8\x4e\x8e\xf9\x2a\xa8\x7c\x61\x0e\x30\xdd\xab\x5f\x5f\xc3\x0b\xf0\xdb\x05\x7d\x48\x1b\xe5\x97\x6a\xc9\x10\xba\x65\x3e\x97\xb3\x9d\x87\xb4\xc2\xbb\x9d\x73\x8d\xdd\xf3\xce\xe5\xa3\x5c\x96\x7b\xa4\xa4\x9a\xc0\xab\xcb\x4a\x1d\x73\x64\x8f\xe7\xe4\x69\xa5\x52\xa6\x9a\x5f\x1e\xe5\x3e\x66\xd4\x25\x52\x45\xf3\x17\x48\x94\x34\x9f\x7f\x39\xf2\xa4\x45\x5a\x11\xa6\x57\xff\x1b\xb2\xf4\xa7\x88\x83\xc4\xe8\xbf\x27\x0c\xb9\x28\xe4\x8d\x5d\x22\x81\x71\xc1\x69\x32\x91\xae\xd7\x47\xbf\xf3\x8d\xb7\xcd\x17\xac\x78\xa2\x7f\xb3\xae\xe5\x2b\xeb\x63\x92\xeb\xb9\xe5\x32\xb1\x5e\x89\xab\x9f\x58\x1a\xb5\x9e\x58\xca\xbd\x87\xc1\x84\xc9\x41\x4c\x83\x35\x26\x9f\xe7\x75\x88\xca\x01\x4b\xc2\xb9\x90\x4d\xd2\x3c\x4c\x22\x0f\xf6\xb3\x53\xd9\x5e\xed\x23\x51\xbc\x61\xf1\xff\xbb\x78\x23\xc5\xe2\x1b\xbd\x88\xfd\xb9\x5e\xc4\x6e\x9a\x27\xc1\xdb\xac\xe8\xe1\xde\xfe\x61\xe3\x85\xac\xc1\xdf\x8c\xf8\xcd\x66\xc6\xd8\x12\x3e\xe0\x49\x82\xf2\x9b\x0f\xef\xdf\xc1\x11\x10\x5a\xe7\xb3\x92\x50\xf2\x54\x2b\x7b\xe4\x3e\x07\xaf\x7c\x3d\xfd\x81\xcd\xec\xb7\xd3\x16\x34\x77\xa0\xc8\xa9\xf2\x09\x03\x37\x9e\x2c\x70\x72\xeb\x2c\xb2\xfc\xde\x0b\xd8\xda\xe2\xae\x7e\xd2\xfc\xfc\x0c\xe6\x92\x5f\x95\x54\xb9\x5f\x56\x97\xa7\xf8\x6b\x47\x5d\x56\x7d\x58\xbb\xec\x70\x0e\xd9\xac\x0e\xea\x6f\x3f\xc2\x11\xac\x9d\x0d\xac\x25\x36\x71\x29\xab\xe5\xe6\x64\xa6\x94\x7e\xf5\xd3\xae\x7c\xc4\x1e\x6c\x81\x97\x56\xd2\x96\x35\x04\x31\x4e\xa9\xbf\xb1\x69\xed\xc1\x6b\x7b\x87\x62\x4e\x0f\x0d\x90\x53\xe8\x8c\x50\x4e\x76\x5d\x99\xec\xc7\x07\x26\x6b\x77\xda\xea\x6c\x3f\x96\xb3\xfd\xf8\xf0\x6c\xb5\x48\xef\x9f\xec\x70\x08\x6f\x35\xc4\x42\x5c\xab\xfc\x02\xa5\x99\x10\xd3\x35\x51\xbb\x16\x4b\x7b\x39\x53\x00\x3b\xa3\x74\x05\x5c\x01\x9b\x90\xff\x6e\x3e\x21\xe6\xbf\x62\xfe\x6d\xbd\xc9\x4c\x83\x48\x80\xc1\xf6\x68\x6f\x64\x2e\x52\xc2\xe2\x5e\xa5\xfb\x69\x2b\xa4\x62\x0b\x76\x46\x0f\xce\xa7\xe0\x48\x2b\x77\x1f\x93\xf8\xce\x11\x16\x06\x84\xcf\x12\x21\x71\xd0\x38\xca\x6a\x4a\x2a\x0f\x88\xc8\x83\x48\x4a\x43\x54\xd5\xa0\x8e\xf2\x5d\x56\xbb\xb3\x65\xd4\x0e\x8d\x6a\x9c\x59\xab\xe9\x56\xe3\x90\xda\x63\x39\x43\x78\x9c\x6f\x0d\xc9\xd0\xc1\x51\x47\x06\xae\xb2\xb1\x3c\xb9\x28\xf4\x7b\x1d\x51\xe8\x3a\x71\x54\xa6\x20\x5b\x24\xc9\x14\x5f\x6a\xf3\x74\xc0\x9e\x74\x8c\xef\xa1\xeb\x9b\xda\xa5\xa7\xfd\x1c\x6a\xb6\xe8\x4e\x6c\xfe\xd0\xc2\x3f\x66\xf1\xa1\x48\x19\xe4\x53\xfe\xc1\x7e\x84\xff\x3d\x33\x45\x9c\x32\x11\x52\xc2\x3f\x0f\xd8\xbf\xd8\xca\xaf\x2e\xeb\x52\xc6\xfb\x6d\x38\xaa\xeb\x12\x31\xcd\xf6\xdb\x6a\x8e\x31\x0f\xaf\x7f\xb1\x2b\xd6\x76\xb2\x33\xbf\x25\xc2\x6f\xf9\x38\x21\x31\xd9\xc2\x2e\x59\x7a\xac\xb4\x74\xcb\xdc\x5d\xf5\xa7\x5a\x86\x21\x2a\xb5\x0f\xf7\xdd\x8b\xf4\x08\x01\x68\x56\x56\xa1\x45\x0a\xab\x17\x26\xe5\x7f\x35\x77\xa3\x13\xee\x11\xc2\xda\xa1\x18\x77\xee\xc6\xfe\xbc\xb8\x9d\xa5\x17\x48\x64\xd1\xba\x70\xe7\x8b\xf3\xd3\xc3\x61\x71\x8d\x0f\x59\xfc\xa5\x42\x39\xc8\xef\xe0\x30\xd7\xac\xd8\xab\x29\xa6\x1a\x25\xa8\xe5\x64\xc1\xf5\x50\xe2\x54\xa2\x9a\x07\xf0\xd3\x1c\x13\x48\x44\x62\xbe\x2f\xb2\xf7\x4b\xf4\xdd\x9b\x25\x26\x62\x05\x4a\xb3\xb5\xca\x6e\x3f\x59\x26\x9a\xc7\xe5\xed\x15\xe4\xd6\x2a\xd3\xc1\xda\x4d\xd5\x75\x69\x4b\x4e\x46\x8e\xd7\x77\xae\x80\xa9\xdc\x52\xd1\x83\x81\xb9\x1c\xb4\x71\x33\x43\xaf\x74\xbe\x0c\x99\x59\x93\x29\x93\x29\xc5\x45\x72\xa1\x85\x64\x33\x73\xa9\xc9\x5b\x8d\x8b\x96\x7b\x48\x4a\x9b\x5b\x41\x51\x37\xb4\xc4\xc0\xfa\xbd\x2b\xd5\x0e\xce\x05\x12\x19\xac\x7b\xe9\x4a\xf1\xae\x76\xeb\x8a\xfb\xbe\xe3\xda\x95\x26\xca\xf6\xbb\x57\xe0\xcb\xee\x5f\x29\x50\xdf\x77\x01\x0b\x94\x1b\xf7\x70\x08\xde\x3b\xa6\x51\x69\x0f\x24\x66\xfe\xb9\x5d\xe3\x1b\x8e\xb7\xf9\xdd\x21\x6d\xeb\xb8\x0f\x61\x8c\xcc\x5e\x8d\x82\xab\x34\xe6\x21\x37\x17\xda\xe4\x78\x8d\x4c\x2a\xe1\xc8\x0b\xa4\x3c\xbc\x56\x8d\x3b\x74\xdc\x6b\x51\x80\x29\xe7\x82\xca\x02\xdd\x73\x7f\xf3\x59\x6c\xc8\xdc\xec\x05\xc6\x9c\x39\x4a\xe2\x9c\xcb\xa9\xca\x89\xfd\xbc\xfa\x5e\x51\xf9\x42\x36\x6f\x6e\x3a\x87\x7b\xe8\x7f\xff\x17\x00\x00\xff\xff\x80\x7a\x97\x2e\x78\x57\x00\x00") +var _webfilesSloop_uiJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x7c\xfb\x73\xdb\x36\xf2\xf8\xef\xfe\x2b\xf6\x98\xcc\x99\x8a\x25\x4a\xb6\x93\xd4\xf5\xeb\xc6\xb2\x9d\x6b\xbe\x97\xb4\xfd\xd6\xe9\xb5\x19\x8f\xa7\x81\xc8\x95\x84\x33\x45\xf0\x00\xc8\x96\x9a\xfa\x7f\xff\xcc\x02\x7c\x80\x2f\x3f\x72\x6d\xef\xdc\x99\x86\x22\x16\x8b\xc5\x62\x77\xb1\x0f\x10\xc3\x17\x1b\xf0\x02\x4e\x45\xba\x96\x7c\x36\xd7\xe0\x87\x3d\xd8\x19\x6d\x7f\xdd\x07\xc5\x62\x54\x53\x21\x43\x0c\x42\xb1\xe8\x03\x4f\xc2\x80\x60\x4f\xe2\x18\x0c\xac\x02\x89\x0a\xe5\x0d\x46\xe6\xfd\xc5\xf7\x67\x3f\x0f\xde\xf1\x10\x13\x85\x83\xb7\x11\x26\x9a\x4f\x39\xca\x7d\x18\x5f\x9c\x0d\x76\x07\xa7\x31\x5b\x2a\x24\xc0\x37\x42\xc2\x74\x19\xc7\x10\x5b\x60\xd0\xb8\xd2\x7d\x50\x88\xf0\xee\xed\xe9\xf9\xb7\x17\xe7\x81\x5e\x69\x98\xf2\x18\x81\x27\xa0\xe7\x08\x12\x53\x01\x52\x08\x0d\x42\xc2\x5c\xeb\x54\xed\x0f\x87\x22\xc5\x44\x89\x25\x11\x28\xe4\x6c\x98\x61\x53\xc3\xda\x78\xc3\x8d\x8d\x50\x24\x4a\x43\xca\x62\xd4\x1a\xe1\x08\x3e\x6f\x00\x00\x4c\x98\xc2\x33\x26\xaf\xf7\xe1\xd2\x7b\xb6\x73\xbe\xfb\xf2\xe5\xc8\xeb\x83\xf7\x6c\x77\xfc\x72\xe7\xd5\x8e\x79\x7c\xb9\xfb\xf2\xf4\xd5\xb9\x7d\x3c\x7d\xf5\xfa\xf5\x89\x77\xd5\x2f\xfa\xbe\x23\x26\x98\xce\x67\x7b\x67\xe7\xe7\x5f\x1b\xb0\xf3\x57\xe7\x5f\xbf\xb1\x78\xce\x4f\xcf\xdf\xbc\x79\x69\x1e\xdf\xec\xbe\xd9\x7d\x73\x9e\x77\x4e\x25\x5f\x30\xb9\x36\x5d\xf7\xde\x8c\x4f\xc7\x63\x03\xb4\xb7\x77\x3a\x3a\xb3\x5d\xf7\xb6\x4f\xb6\x4f\xb7\xcd\xe3\xab\xf3\xbd\xed\x93\xd3\xbc\xeb\x9c\xcf\xe6\x71\x31\xee\xf8\xcd\xeb\xed\xd7\x27\x06\xec\x6c\xb4\xf7\xd5\x57\xd9\xb8\xe3\xd3\xf1\x9e\x45\x79\xb2\x3b\x3e\xdf\x3b\xf5\x6c\x5f\xfa\xf3\x9e\x8d\x5f\xee\x9d\x9f\x9c\x79\x7d\xef\xd9\xc9\xd9\xc9\xde\xf8\x35\x3d\x45\xec\xab\xd7\xaf\x46\xf4\x74\xf6\xf2\xeb\xd7\x27\x5f\x99\xd6\xf1\xe9\xcb\x93\x71\xa5\xeb\xc9\xcb\x93\xd7\x67\x3b\xd4\xf8\xf5\xf6\xf8\xfc\x8d\x7d\xfa\x6a\xbc\x7d\x62\x90\xec\x9d\x7c\x3d\x7e\xbd\x97\x13\xaa\xf0\x06\x25\xd7\x34\xc9\xcd\x67\x2f\xc7\x67\x7b\xaf\x5e\x6d\xf6\x61\xf3\xd9\xf9\xe8\x7c\x34\x1a\x99\xc7\xb3\xbd\x97\xe3\x97\xe3\xcd\xab\xfe\xc6\xdd\xc1\xc6\xc6\xc6\x70\x08\x7f\x8f\xc5\x84\xc5\x0a\xde\xf1\x1b\x84\x6f\x50\xe2\x46\x8c\x1a\xb4\x48\x4f\x56\x5c\xf5\x61\x22\xb4\x16\x0b\x7a\x3e\x30\xe0\x1f\xe6\xa8\x10\xa6\xcb\x24\xd4\x5c\x24\x0a\x66\xa8\x21\x64\x71\x8c\x11\xdc\xce\x31\x21\x0a\x8c\xf4\xa4\x52\xa4\x28\x35\x47\x05\x62\x0a\xc8\xf5\x1c\x25\xb0\x15\x57\xc0\x24\x42\x38\x67\xc9\x0c\x23\x77\xa8\x33\xc9\x6e\xdf\x2c\x93\xd0\x1d\x32\x7f\xe7\x0e\x4d\xdd\xa3\x5d\x50\x5a\x2e\x43\xad\x0c\x86\x15\xc1\x5e\x84\x2c\xc6\x3e\xac\xe9\x79\xcc\x92\xc8\xf6\x39\x91\x92\xad\x21\x14\x89\x66\x3c\xe1\xc9\x0c\x22\xa6\x19\x48\xd4\x92\xe3\x0d\x46\x30\x95\x62\x01\x2a\x16\x22\x05\xa3\x56\xd2\x20\x24\xa0\x62\x4c\xd0\x7c\x81\x10\x71\x95\xc6\x6c\x8d\x11\x88\x04\x42\x94\x84\x0f\x16\x62\xa9\x50\xd0\x94\x59\x12\xd9\x5f\x0b\x71\x83\x80\x37\x98\x64\xb4\xe9\x39\x7e\xe0\x0b\x74\x67\x10\xe1\x94\x27\x68\xb8\xb4\x60\x2b\xbe\x58\x2e\x20\x92\xec\x96\xa8\x53\x29\x0b\x91\x46\xa0\xc6\x5b\x9e\x44\xe2\x36\x80\xb7\x10\x89\x64\x93\x50\xf1\xe4\x9a\xd0\xe8\x39\x57\xc0\x95\x01\x0a\x85\x94\x18\x6a\xb8\x65\x6b\x62\xf4\x52\x11\x1a\x6d\xc6\xb9\x61\x52\xc1\x00\xb8\x86\x48\xa0\x22\x0c\x12\x59\x1c\xaf\xc9\x84\xa4\xa6\x8f\x19\x80\x7e\xf2\x5f\x79\x32\x23\xd4\x34\x8f\x5b\xe4\x32\x82\x05\x4f\x88\x34\x65\x5e\x65\xb3\x07\x15\xb2\x98\x06\x08\xc5\x32\x8e\x20\x15\x9a\x2c\x8e\xc1\x19\x92\xe6\xd3\xaa\x4f\x62\x5c\xa8\xc0\xb2\xd1\xf6\x7a\xcf\x56\x3f\xf7\x9d\x1f\x1f\x2d\x33\xfe\x49\xe2\x11\xb2\xd8\x4c\x9a\x90\x4e\x50\xdf\x22\x26\x30\x61\x52\x65\xe6\x43\xa2\x35\x36\x63\x26\x73\xf0\x8b\x0c\xfa\x08\x46\xc1\x8e\xc5\xa4\x6e\x66\x20\x71\x8a\x12\x93\x10\x61\x2a\x24\x48\x4c\x22\x94\x86\xa3\x37\xb3\x8c\x29\xd1\xae\x21\x4a\xdd\xcc\x6c\xaf\x0b\x4e\xd0\xb7\xb8\x49\x02\x95\xf1\x9f\x86\x26\xf6\x9b\x7f\x6f\x39\x71\xdc\x70\x59\xb1\x05\x96\xa2\x75\xcb\x23\x3d\x87\x81\x5d\x51\xae\x60\xc1\xe4\x8c\x27\xd9\xba\xda\x65\xb1\x0b\x99\xcf\xc8\x9a\x53\x3b\x15\xc2\x0d\x03\xc3\x55\xae\x37\x95\x23\x9b\x84\x6f\x62\x16\xc0\x0e\x9c\x8d\x5d\x0c\x6b\xc9\x5f\xb0\x38\x1e\x33\xf9\xde\x8c\x79\xb0\x61\x5e\x66\x04\xe4\x46\x56\x8b\x74\x1f\x76\x46\xd6\x28\xc4\x38\xd5\xfb\xb0\x3d\x1a\x19\x8d\xcf\x64\x4a\x24\x66\xd1\xc9\x2e\xc7\x82\x45\x17\xff\xfc\xfb\xc1\xc6\x46\xae\xd4\xc0\x13\x4e\xab\xca\x7f\xc5\x33\xbe\xc0\x44\x91\xa2\xfb\xbd\x0c\xb9\xb3\xa8\x70\x04\x91\x08\x97\x0b\x4c\x74\x90\x3f\x9c\xc7\x68\x7e\x87\x31\xc7\x44\xff\x44\x9c\x3a\xa8\xf5\xfb\xf8\x70\xbf\x6f\x90\xec\xed\xc1\xc6\xdd\xc6\x46\x84\x9a\xf1\x18\xa3\x0f\x42\xc4\x1f\x78\xfa\x56\xfd\x93\x2b\x3e\x89\x89\xf4\x29\x8b\x15\x66\x2c\x48\xc4\x85\x90\xfa\x0d\x31\xa1\x98\x47\x41\xb3\x44\xbd\x94\x09\x58\x16\x58\xc9\x0a\xc5\x22\x65\x12\x2f\x34\x6b\xf4\x62\x7d\x98\xe4\x3d\xf9\x14\x7c\x16\x5c\xf3\x24\x82\xbf\x1c\xc1\xc4\x3c\xe5\x6d\x0e\xe6\x0c\xdb\x3f\x78\x12\xd9\xee\x06\xe0\xce\x1d\x9c\x05\x8a\xc6\x82\x01\x4c\xec\xd3\x01\x51\x53\x21\xe6\xbd\x50\xfa\xdc\x98\x8e\x3f\x85\xa2\x49\x40\xa6\x2b\x66\x6b\x15\xc4\x98\xcc\x48\xa4\x81\xd5\xdf\x35\xa9\xfc\x96\x2d\xf0\x4f\xa1\xcf\xdf\xdc\x84\x2d\x60\x01\xb9\x2a\xbd\x20\x16\x64\xe0\x4f\x6d\x37\x7f\x62\xdf\x1a\xea\x68\xf9\xc3\x45\x6a\x68\xca\xc5\xc0\x15\xe7\x4c\xc2\x0b\x69\x48\xd9\x9a\x5e\x91\x14\xee\x06\xff\x52\x22\xf1\xc9\xde\xff\xff\x25\xca\xf5\x8f\x32\xee\x1d\xb8\x40\x81\x9e\x63\xe2\x97\x33\x95\xa8\x96\xb1\x76\xe7\xd3\xae\x2c\x07\x45\x3b\x19\xa0\xa3\xcc\x20\xe5\xdd\xcb\xd6\x09\x4f\xa2\xf7\xb4\x6f\xd8\x75\xf7\xd5\xcd\xcc\x69\x65\x69\x8a\x49\x74\xb2\xc2\x7a\x83\x45\x47\x2a\xa1\x79\x9a\x8f\x76\x47\xec\xd8\x28\x66\x6b\xad\xdc\xf7\xd9\x64\xb5\x98\xcd\x62\x04\x75\xcb\x75\x38\x37\x7b\x98\xd9\x82\x41\x8b\xc2\xb8\xe7\x7c\xc9\x5b\x78\x78\xad\x4a\x2e\x66\xad\xa7\x73\x0c\xaf\x51\xfa\xe5\x72\xfb\x85\x2e\xcf\x30\x57\xe3\xf1\xfa\x6d\xe4\x7b\x6e\x17\xaf\x17\x84\xa6\x6b\x04\x47\x47\xa0\xe5\x12\x5d\x26\x9a\x6d\x3a\xa0\xcd\xb8\x0d\x9b\x1a\xaf\x4f\x63\xa6\x14\x49\x9e\x83\x95\xa8\xf4\x7a\xbd\x02\x09\xfd\x05\x0b\x96\xfa\x08\x47\xc7\x80\x81\xd2\xeb\x18\x83\x7c\x76\x47\xe0\x4d\x62\x41\x84\x64\xdc\x02\x8c\x15\xfe\x11\x34\xdc\x4f\x44\x22\x12\x2c\x68\x20\x03\x37\x1c\x02\x9c\x65\xed\x11\x9f\x9a\x6d\x4c\xc3\xbf\x49\x1c\x61\x81\x7a\x2e\x22\x65\x5c\x5f\xe3\x79\x48\x16\x71\x01\x37\x2c\x5e\x62\xb9\x34\x06\xd6\xd2\xe2\x1b\x00\x57\x17\xcd\x8b\xc0\xf4\x80\xa3\xa3\x23\xf0\x24\xce\x70\xe5\x7d\x29\xf7\xb3\xde\x5f\xca\xf5\xa7\x33\x5a\x6a\x4e\x93\x7c\xd2\x90\x55\x1e\x77\x72\xc2\x41\xfe\xa7\x71\xc3\x25\xed\xcf\x61\x46\x55\xea\x33\x89\xbb\x98\x8b\x5b\xe3\x5d\x60\x12\x91\xdf\x48\x8f\xa5\x8b\x9b\x39\x86\xbe\xf1\x8e\x8d\x3b\x63\x7c\xe3\x4d\x05\x38\x9d\x62\xa8\x29\x54\xb0\x02\x2a\x49\xe8\x7a\x99\xab\x42\x88\x31\x89\x06\xc6\x61\x9e\x88\x55\x9f\x9c\x9b\x1b\x94\x1a\xc9\xfe\x18\x44\x13\xb1\xda\x54\x60\x6c\xb9\x05\x33\x10\x09\x4d\x2a\x30\xce\xb6\xd2\x42\x62\x64\x25\x9c\x7c\x5c\x72\x5f\x8c\x63\x1a\x8b\x04\xf7\x81\x25\x80\x8b\x54\xaf\xab\x70\xd7\x88\xa9\x02\x2d\x59\x78\x9d\xb9\xbf\x90\xe0\x2d\x2a\xeb\xc9\x1b\xbd\x41\x63\xcd\x4b\x9d\x59\xa6\x11\xd3\x78\x9e\x44\xe4\x9d\x8f\xc5\xca\xc7\x24\xfa\x31\xe1\xab\x0b\x0c\x45\x12\xa9\x5c\x20\x68\x6f\xc1\x24\x3a\x63\x26\x86\x4d\xf0\x16\xe8\xb1\x06\x0c\x2f\xc8\xbf\x1a\x65\x2c\xce\xc0\x03\x85\xfa\x3d\x4f\x96\x1a\x95\x9f\xbf\x9a\x95\xaf\x7a\x30\x00\xe7\x35\x51\xf1\xab\x48\xf0\xbb\xe9\x54\xa1\xf6\x7b\x6d\xb8\xe2\x98\x2b\x3b\xa0\x9f\x2c\xe3\x7c\xa3\xea\xb2\xbe\x9b\x0a\x63\x0c\x35\x46\xd9\x1c\x37\x7b\xb9\xe8\x17\x58\xb5\x78\x7b\xf1\xdd\x85\x26\x3f\xd9\xef\x05\x8a\x82\x79\x7f\xd4\x87\xc1\xb6\xd9\x48\x4a\x5e\x55\x37\x2f\x87\x33\x86\xbb\x47\xe4\xf5\x87\xa8\xd4\x49\x12\xd1\xe6\xfb\x43\xe6\xe8\xaa\xea\x6e\x97\xc3\x8f\xd7\xb4\xe7\xf7\x81\xfc\x02\xd5\x87\x29\x8f\x35\x4a\x24\x82\x28\xe4\x22\x48\xda\xb5\x8c\x3b\xef\x88\xde\x80\xfc\x85\x25\x09\x52\x5d\x02\x33\x59\x25\xaf\x5f\xe7\xc1\x1a\xc5\x99\xfb\x14\xf8\x48\x9c\x12\x13\x28\x88\x59\xe7\xb8\xc3\x98\x2d\x52\x23\x26\x56\x24\xcd\x24\xd8\x0d\xe3\x31\x9b\x94\xd9\x0f\x23\x5f\x7d\x50\xc2\x84\xb5\x70\xc3\xd1\x04\x08\x14\x3b\x66\xa2\x37\x61\xe1\xf5\x32\x35\x72\x9f\x61\x36\xe1\x2d\x92\x40\x30\xed\x0a\xa1\xc4\x50\xc8\x08\x23\x3b\x14\x4f\x94\x46\x66\xb4\x4e\x69\x89\x3a\x9c\x3b\xc4\x48\xfc\xf7\x12\x95\x51\x18\xbe\xc0\x82\x71\x34\xfc\x77\xa9\x8d\xb8\xc9\x99\x20\xbe\x06\xf4\xf2\x17\x91\xbd\xfd\xed\x37\xf8\x7c\x57\x72\xda\xf0\xe6\x27\xcb\x9a\x23\x20\x71\x39\x28\xec\xa0\x83\x2c\x30\x70\xbf\x58\xcf\xf4\xaf\x7f\x85\x66\x13\x56\xbd\xb7\x2a\xde\xcb\x2e\x54\x56\x21\xfa\xed\xf8\xb2\xd6\xab\xd2\x08\x36\x94\xb1\x9d\x8e\xdc\x84\x15\x33\xf9\x0b\x31\xd4\x25\xaf\xcc\x04\x58\xef\x8e\xe2\x55\xfc\x51\x87\x7e\x2f\x30\x96\xca\xbf\xb4\xa1\x52\x40\x66\xa5\x5f\x89\x65\x06\xe0\x34\x5d\x39\x16\x9a\x06\x72\xa6\xed\x0e\x57\x1d\x32\x88\xc4\x82\xf1\xa4\x02\x5c\xa2\xb9\x2b\x9e\x8a\x80\xce\xa1\x91\x7e\xfa\xbd\x20\x65\x51\x44\xda\xd8\x1d\xf7\xf6\x32\x25\x01\x1b\xe7\xb9\x59\x12\x8b\x8e\x84\xf0\x83\x48\xfd\x92\x2e\xd7\xdd\x6c\xa4\x56\xca\x4e\x63\xd3\xd6\xde\xcf\xd5\x52\x5a\xf7\xab\x76\x17\xaa\xd4\x6f\x8b\x36\x41\xa5\xfd\x5e\x70\x8d\x6b\x3f\xa2\xdd\x29\xb2\xd1\x40\x80\x89\x96\x1c\x95\xf1\xbb\x9d\x51\x8c\x49\xa0\x9e\x05\x1a\xb3\xb1\xe5\x5d\x71\xed\x4e\x7e\xc2\xe4\xa9\x88\x85\xfc\x3b\x26\xe5\x3c\x0c\x2f\xbf\x93\x11\x4f\x58\xec\xf7\xf2\x05\x31\x78\x73\x09\xc8\x32\x92\x41\x91\xd5\x73\x7d\xf5\x2c\x81\xd6\x81\xf8\x1d\x4f\x90\xc9\x12\xef\xe5\xa8\x0f\xdb\x7d\xd8\xb9\xaa\xe3\xce\xf1\xb8\xf4\x76\x8b\x66\x75\x2b\x6f\x0a\x11\xe9\xf6\x65\xb4\x1b\x2c\xb8\x8d\x54\xfa\x90\x71\xc4\xe8\x5a\xaf\x4f\xd8\x16\x6c\x55\x6d\x23\x7d\xb9\xaa\xa1\x7e\xb2\x0a\x3c\x42\x64\x5b\x89\x8f\x76\xb3\xb1\x88\xa4\x2c\x90\xac\xbb\x2c\x55\x62\xb4\x48\xfb\xe0\x82\xc3\x0b\xf0\x77\x47\xbd\x5e\x49\x94\x16\x69\x7d\x42\x4f\x53\x97\x6a\xea\xc4\x24\x90\xb6\xe1\x45\x39\xb7\x60\x92\xe7\x76\x4c\xf0\xd4\x2d\xfc\x41\x28\x92\x90\xe9\x80\xa5\x69\xbc\xf6\x2f\xaf\xfa\x1d\x12\x6b\xf6\x5b\xd5\xeb\xd0\xa3\x60\x2a\xe4\x39\x0b\xe7\x39\x74\x48\x42\x67\xf9\x6b\x1e\xfd\x9a\x84\xfb\x99\xf6\xf4\xaa\x76\xf0\x69\x46\xe0\xa9\x06\xa0\xd8\x50\xd4\xcd\xcc\x24\x73\xe0\xc8\xb5\x78\x76\x11\x7b\x97\xdb\x57\xb0\x05\xfe\x0e\xbc\x70\x25\xc8\xd9\xf8\xd5\xcd\xcc\xa6\x74\xe0\xc8\xe1\x77\x67\x6f\x2d\xd2\x5e\xe9\x0c\xc8\x2c\xa9\xba\xe2\x4a\xe7\x29\xbd\x22\xdd\x67\xf3\x93\x12\x43\x89\xe4\xa3\x71\x1d\x40\x1e\x97\x52\xc8\xec\x18\x27\x1b\x88\x93\xf4\x1a\xc7\xc8\xf7\x9e\x45\xbb\xbf\xcc\x51\x56\xdc\x71\x75\x33\xcb\xda\x4f\xe2\xd8\xdf\x7c\xb1\xd9\x0b\xec\xf0\x7e\x25\x9c\xb8\x07\x57\x81\x2a\xb0\xd1\xbb\xef\xa9\x9b\x59\xe5\xb5\xd6\xd2\xf7\x68\x87\x1b\x8b\x95\xd7\x87\x4f\x23\x18\xc1\xf3\xcf\x39\x83\xef\xec\xb3\x65\xd7\xdd\x27\xa7\x63\x48\x91\x00\x5a\x84\x83\x50\x24\x1a\x13\xed\xf5\x6d\x2c\x4d\xf2\x6a\x20\x89\x2e\x9a\x44\x3e\xf8\x2c\x9f\xdd\x70\x08\xa7\x96\x47\xe4\x67\xcc\x24\x4b\xe7\x26\xfb\x2a\x31\x95\xa8\x30\xd1\xcc\xf8\x7a\x62\x0a\xc8\xc2\x79\x91\xae\xb4\x48\xa5\x58\xa6\x64\x99\x67\x25\x35\x25\x97\xbc\xca\xf4\x48\x15\x7c\x57\xce\x9d\x36\x4c\x34\x4a\xbf\x85\x45\x2d\x0c\xd2\x92\x25\x6a\x2a\xe4\xc2\x23\xc3\xd0\x07\xde\x23\x35\xf9\x64\x5e\xc7\xe4\x83\x13\xd3\x0a\x59\xf2\x79\x0f\xb6\x6a\x1a\x7e\xd7\x73\xb9\x47\xb3\xf2\xad\x94\xfc\x50\x9a\x8b\x5c\xcc\x0a\x2f\xda\xd8\xdd\x0b\x33\x37\x21\x7d\x6f\x22\xa2\xb5\xd7\x0b\x4a\x06\x98\x87\x03\x37\x4d\xa5\x6e\x66\xe4\x2d\xe7\x36\x3f\x0b\x13\xde\xb3\xd4\xbf\xbc\xf4\xbe\x15\x72\xc1\x62\xaf\x3f\xba\xea\x5f\x7a\x3f\x31\x99\xf0\x64\xe6\xf5\xb7\xe9\xd7\xb9\x94\x42\x7a\xfd\x9d\x2b\x63\x69\xcb\x3c\xcb\xfd\xce\xb4\xe3\x7d\x3f\xe8\x14\x1e\x38\x9e\x52\xd6\x2c\xc5\xad\xea\xd5\x76\x6c\x38\x82\xcf\x77\xdd\x1b\x7a\x89\x9b\x3a\x97\xf6\xad\xea\x06\xe5\x09\xb8\x6a\x5e\xf5\xa0\x02\x93\x25\x9f\x2a\xde\x9d\x12\x52\xd7\x5d\x2a\x83\x8f\x29\x04\xcf\xec\x70\xe4\x09\x7b\xfb\x0d\x88\xc7\x8e\x9a\xff\x4d\x24\xb2\xeb\x66\x93\x1d\x28\x61\x8f\x1d\xc3\xa6\x3f\xbf\x60\x88\x85\x50\xda\x16\x86\x1e\x37\x90\x9b\x0d\x7e\xd2\x70\x11\x4e\xd9\x32\xd6\x1d\x83\x88\x44\x89\x18\x83\x58\xcc\x7c\xef\xc7\xe4\x3a\x11\xb7\x09\xd0\x22\xec\x83\x07\x5b\xd0\x58\x9a\x47\x8f\x7c\xb7\x51\xf9\x69\x45\xa6\x28\x49\xb8\x7f\x41\x10\x44\xfd\xc6\x5b\xb3\xd4\xfb\xb9\x57\xf3\x0b\x05\x04\x79\x18\xd1\x80\xc5\x24\xda\x07\xbf\x05\x94\x8c\x80\x1f\x05\xd1\x52\x5a\x6b\x96\xbd\x6d\x62\xc8\xb3\xdc\x34\x60\x91\xf1\x2e\xb2\x28\x4d\x9a\xc1\x5a\x50\xcc\xcb\x6e\xdf\xd9\x3e\x59\x19\x32\x2b\xfd\x44\xc0\x93\xae\x9e\xe9\xf5\x6c\x68\xea\x8c\x43\xb2\x30\x1c\xd5\x50\xaf\x53\x54\xc1\x4c\xb4\xf6\x30\x9b\x66\x1a\x73\xfd\x01\x57\xc4\x45\x34\xf9\xee\xc0\xbc\xf2\x3d\xf0\x7a\x9d\xbd\x6e\x85\x54\xfa\xa2\x34\x46\x99\x73\x58\x20\xeb\x9b\xd2\x7f\xf7\x2c\xc1\xb1\x6c\x19\x96\x60\x86\xda\x77\xc7\xdf\xf7\x68\xd3\x6e\xa7\xe1\xce\x75\xb9\xea\xc4\x65\xac\x6e\x15\x8b\xfc\x2f\x08\x02\x6c\x2e\x58\xfe\x97\x89\x89\x8f\x2d\x8b\xdf\xdd\xcb\x0a\x4c\x5b\x1f\x12\x18\x7c\x84\xc0\x14\xe3\x17\x35\xf6\x0a\xa3\xbb\x3b\x48\x64\x4a\x24\xfb\xd9\x0a\x76\xc3\x85\x62\x99\xe8\xfd\x72\xd1\x2f\x77\xae\xda\x81\xef\xda\x55\x32\x5b\xb3\x8c\xc3\x0d\x90\xbb\xea\x6a\xd5\x90\x64\x9d\xad\xd2\x96\x21\x6b\xcf\xd8\x00\xdf\x18\xa6\x4a\xf5\xc1\x40\xd3\xe6\x50\x26\x15\x8b\x0d\xac\x51\xd9\xa9\x16\xe1\xf2\xaa\x8e\x8d\x04\xeb\x55\x1d\xf3\xb6\x82\xae\x56\x03\xc9\xf7\x3f\x9e\x60\xcd\xd3\xa1\x57\x4d\x37\x62\xbd\xed\xf5\x5b\x5c\xce\xd1\x55\x13\x72\xa7\x15\x72\xbb\x09\xa9\xb4\x14\xd7\xe8\xf5\xc1\x93\xb3\x09\xf3\x47\x7d\xf3\x5f\xf0\xaa\xe7\x0e\x6f\xf2\xb0\xbe\x97\x0a\x4e\x4e\xcf\x20\xb3\xfc\xfd\x32\x03\xec\x7a\xef\x76\x2a\x4f\xf7\x8b\xee\xf5\x89\x9c\xc9\x56\x5d\xa1\x90\xc5\xb1\x5f\x8b\x1b\xba\x27\x99\x07\xb5\xc5\xf1\x9b\x2a\x4b\x0a\xaf\x34\x43\xe8\x78\xa4\x50\x09\x38\xfe\xd8\x39\x6e\xb7\xcd\xb1\x19\xed\xfc\xe7\xd3\x2c\x71\x3a\x33\x6d\x66\x4b\x8b\xda\x5c\x51\x93\x37\xbf\xab\x51\x83\xf5\x2e\x9b\x2c\x89\xf8\x8d\xd7\xce\x62\x83\x24\x1f\xb8\x32\x6c\x5b\x25\x31\x1b\x9b\xb4\x44\x24\xbe\x57\x1c\x50\xf1\xfa\x2d\x45\x72\xc8\x6c\xf4\xe5\xaa\x0f\xeb\xab\x6c\xe7\xa0\x1e\xbe\x9e\x73\xe5\x5a\x75\x72\x28\x9d\x20\x90\x9b\x1c\xbf\xbf\xea\xc1\x61\x4b\x36\x8c\xc4\x0f\x7e\xfb\xad\xa3\xc7\x71\x6b\x8f\xed\xab\x5e\xdd\x27\xac\xf8\x2d\xc5\xd1\x91\x09\x93\x20\x96\x9a\xa2\x96\x89\x58\x26\x91\x82\x95\xc3\xb8\xcc\x9d\x25\x72\xd7\x70\xd8\x6a\x05\x0c\x65\x6b\x38\x6e\x57\xfc\x2f\x25\x42\x8b\xb4\x49\x46\x15\x15\x59\xab\x16\x69\x77\xe4\xfc\xf9\xe7\xd5\x1d\x8c\x7a\x9f\x6a\x2e\x58\x76\xa0\xa8\x1a\x87\x17\x0c\xad\xc2\xda\x1c\x69\xc7\x01\x8a\x36\xaf\xdb\x9e\xc7\x32\x42\xf6\xb3\x95\x00\x63\xb7\x82\x94\xcd\xf0\xe7\xe6\xbe\xe3\x80\x7f\xac\x83\x7f\x6c\x82\xa7\x42\x99\xf2\x55\xae\x1b\xf9\x48\xfd\x02\x49\xaf\xee\x53\x56\x9f\xee\x8a\xbc\x8c\x1b\xa5\x7b\x41\x1e\xac\x7a\xbd\x52\xce\x69\x23\xac\xc8\x79\x25\x8f\xfd\x24\xce\x94\x1a\x6b\x34\x21\x5b\xb6\x29\x8f\x63\xaf\x9f\x27\x6e\x82\x88\x49\x53\x17\xaf\x2f\x97\x9d\x59\xbe\x1d\x88\x94\x85\x5c\xaf\xbd\x3e\x6c\xf7\x1a\x93\x2b\x89\x8f\x91\xd5\xb4\xf4\x8f\xa2\xfe\x91\xc9\xa6\x07\xa7\x33\xba\x6f\x3a\x0d\x9b\xf3\xe5\xb3\xc9\x09\x98\xeb\x45\xec\xcf\x50\x3b\xb1\xfc\xa9\x4d\x89\xf8\x0d\xb9\x6b\xf7\x35\x35\xd7\x31\x92\xff\xdf\xed\x97\x11\x0b\xf6\xb3\xac\x75\x3b\x04\xc5\x8d\xe6\xac\x17\x81\x15\x3f\xda\x61\x29\x8e\xdd\xcf\xf5\xb7\xe9\xa0\x55\xde\xf4\x3a\xd8\x19\xc6\x3c\xbc\xee\x66\xa5\x9a\x8b\xdb\x33\x87\x93\xa4\x65\x51\xbf\x50\xcc\x3e\x64\xa6\x1c\x32\x65\x02\x1b\x9c\xbc\x4d\xf4\x92\x6b\x7e\x83\xf1\x1a\x36\xa3\x4d\x42\xb3\x8c\x23\x98\xd8\x5c\xd1\xe6\x1c\x99\x5e\xb0\x74\x13\xd0\xd6\x17\x61\x00\x93\xa5\x36\x25\xb7\xdb\x39\xd3\xe6\xcc\xa7\x75\x73\x73\x84\xa6\xb2\x4c\x23\x9a\x6d\x49\xe5\xa7\x14\xe3\xb5\xe9\x48\x43\x64\x71\x54\x71\x2a\x2e\x43\x1d\xc0\xb7\x42\x83\x5a\x4a\x84\xdb\xf9\x1a\x06\xf0\x36\x3b\xf6\x98\x21\x8e\x76\x33\x8c\xd6\x9f\xa2\xf8\x8b\xcc\x75\xbc\x86\x98\x5f\x13\xb9\x4c\x07\x2d\x06\x22\x9b\xc1\x1f\x64\x1f\xc8\x0c\x92\xff\x9a\xe8\xd3\x3c\x87\x5b\x33\x0a\x07\x0d\xf8\xcc\x4f\x7f\x9b\x44\xb8\x82\x23\xea\xae\xf0\x6d\x62\x75\x94\xe2\xad\x13\xad\x25\x9f\x2c\x35\xfa\x1e\x27\x18\xaf\xae\x89\xf6\x70\x29\x57\xdf\x15\x21\x55\x19\xc9\x5e\xba\xd8\xaf\x6a\xf1\x58\xd5\x1e\x04\x96\xf0\xac\x72\xdc\x2b\x5c\x13\xd7\xa6\x56\x2c\x86\x33\xd1\x1a\x45\x5f\x66\x68\x9c\x39\xd8\x33\x5d\x3d\xd7\x94\x36\xa6\x9c\xe5\x3d\x5b\x23\x48\xea\xbe\x0f\x75\x84\x4d\x65\xbc\x5f\xad\x1f\xab\xd2\x0f\xd8\x8f\x2c\x50\x75\xa9\x31\xaf\x3a\xb2\x19\x2e\x1c\xd6\xc9\xba\xab\x31\xe2\xb1\xeb\xfe\xf4\xd5\x69\xab\x80\x55\x96\xa8\x28\x6d\xf5\xba\x76\xbc\x2e\x72\x02\xc3\x30\x38\x82\x16\x11\x37\x4d\x5e\xfb\x5e\xd3\xcc\x1f\xdd\xb7\x97\x16\x40\xf9\x06\xf1\x8d\x55\xfd\x7c\x73\xc8\xe4\xa7\xd7\xa8\xcc\xfe\x39\xdb\xef\x93\xd5\x2d\xb3\x24\x6d\xaa\xf0\xa7\x9a\x90\x47\x8b\xd2\x13\x24\xe8\x3f\x74\x2d\x7e\xe7\xbd\xb0\x65\xdb\xa8\x1d\xf3\xfb\xc3\x36\x8f\xd5\xf7\x82\xc2\xe3\xad\x76\xc6\xae\xea\x8a\x61\xd2\x7c\x59\x31\xae\xa3\x8f\x69\x6e\xeb\x37\xcf\xcb\x70\x1d\x1d\x6d\x7b\x5b\x4f\x82\xb2\x9c\x78\xa4\xb0\x65\xc9\xb4\x2a\xa6\x1b\x26\xb3\x03\xa6\x63\x21\xe2\x66\xb8\xd2\x4e\x15\x8f\xbc\x7a\xae\xc8\x4b\x44\x98\xad\xcb\xd1\x11\x8c\x5a\x6b\x08\xc5\x38\xe5\x61\x71\xb7\xbd\x35\x30\x6b\x74\xa4\x50\xfb\xde\x54\xf7\x83\xdb\xd2\xfd\x1b\x45\xee\x16\xe6\xdc\xed\x43\x07\x3d\xfb\x2e\x5d\xf7\xee\x0f\x5d\x72\xd4\xb7\x92\x36\x80\x57\x55\x39\xe9\x67\xe2\xb4\x05\xdb\xa3\x47\x6d\xea\x99\x94\xf4\x73\x71\x6a\xe9\xf8\xfb\x58\x6f\xcb\x92\xff\x9a\xf1\xfe\x9f\x55\xce\xa7\x2c\xf7\x56\xc7\x72\x0f\xb6\x47\x1d\xeb\x39\xe8\x5a\xcd\x47\x19\xe7\x5a\x3e\xac\xb9\x07\x47\x6e\x15\x93\xc5\xf1\x0f\x26\x76\x30\x27\x7f\xea\x65\x8e\x40\x62\xb4\x0c\xd1\xf7\x65\x1f\xe2\x3e\xf0\x3e\xb0\x5e\xb5\x76\x51\xaf\x94\xc4\x4e\x91\xe2\xa0\x0a\x95\x6d\x3c\x19\x60\x99\x69\xdf\xbe\x6a\x07\x3c\x15\x91\x49\x32\xbb\x65\x10\xb7\x57\x07\xfe\x3c\x08\xa8\x9f\x06\xba\x74\xf1\x5e\x35\xd2\xe9\x9f\x0e\xb5\x3c\x6e\x06\x8e\x87\x3a\x3a\x86\xc3\xc9\x31\x3c\xff\x5c\x8e\x3d\xba\xba\x83\xc3\xe1\xe4\x18\x0e\x87\x3a\x7a\x6c\xa7\x9d\x4a\xa7\xa6\x95\xc9\x7b\x81\x59\xe4\x23\xcf\x38\x1e\xfb\xcf\x3f\x57\xe6\x75\xe7\x1d\x97\x6f\x08\xed\xdd\xbd\x74\x0c\xb5\x3c\xfe\x04\x5b\x20\xad\x6c\xf4\xc1\xf3\xdc\x53\x25\x9a\xd9\x2f\x79\x3e\x1d\x9a\xa7\x63\x20\x1e\x18\x3a\xac\x4c\x58\x4a\xe9\x37\xc5\xcc\x0a\x2e\x10\x9d\x77\x79\xf1\x25\x7b\x43\x63\xc1\xf3\xcf\xa5\x40\xd1\x74\x2d\xde\x4f\x95\x8a\xfd\xa7\x6f\x19\x99\xdc\xc3\xc9\xf1\xf3\xcf\x91\x75\x4b\xcd\x2c\x0e\x27\x72\x58\x4e\xe2\x1f\x26\x4a\xc8\x80\x28\x54\x68\x81\xf9\xb6\x8c\x15\x32\xc0\x22\x60\xc8\xa1\xc1\x01\x7f\xfe\xd9\x90\x73\xe7\xbc\x98\x0a\xb9\x60\xfa\x8c\x69\x93\x15\xc8\x6b\x9a\xbd\x3b\x18\xb4\x35\x62\x12\xf5\xee\x3e\xd5\xd5\xab\x25\x07\x12\xd5\xaa\x2e\x9f\x0e\x23\x7e\x03\x3c\x3a\xf2\x34\x4f\xd6\x83\x3c\x91\x7c\x7c\x1f\x27\x3e\xc1\x56\x41\xe8\xa7\x7b\xb8\x51\x81\x7b\x04\x47\x6a\x3d\xcc\x9b\x96\xb9\xd2\xbe\xd8\xbb\x3b\x1c\x46\xfc\x86\xd6\xaf\x36\xe7\xea\xc6\x10\xb9\x5f\x3c\x44\x81\xdd\x27\x5b\xbe\x3a\xfa\x8f\xd9\xf0\x7d\xf5\x1b\x19\xa6\xdb\x56\xc9\x52\x0e\x19\xe9\x56\xf2\xeb\xae\xc6\xef\x45\xd0\xb7\xa2\xfe\xdd\xce\xe3\x69\xaa\xf0\xb4\xde\xa3\x26\x40\xc5\xd1\xf7\xa8\x17\x68\xf1\xe3\x87\xd3\xfc\xdc\x78\xb5\xf6\x57\x3f\x5f\x53\xe2\xb1\xdf\x90\x61\x5c\xa9\x80\x38\x2e\xb8\x6d\x57\xab\x4a\x62\xbb\xd0\x07\xc7\x66\xdc\xc2\x11\xbc\x67\x7a\x6e\xca\xda\x15\x50\x73\x56\x79\xd0\xd6\xbd\x5f\xfa\x27\x76\x1c\xae\xde\xb1\x09\xc6\x3f\x64\xfb\xad\xaf\x56\x70\x5c\x39\x0b\x39\x84\x1d\xf8\x1b\x91\xb3\x05\xb7\x70\x58\x69\xda\xa7\xd7\x03\xb8\x85\x63\x18\xe5\x84\x61\x5c\x2c\x49\x51\xc5\x91\x18\xea\x66\x6d\x8b\xb6\x65\xb5\x6a\xbc\x2e\x76\xe0\xd6\xe3\x88\x30\xb0\xe7\xe3\xaa\x07\x9c\x7a\x0d\x2c\xc5\xfe\xde\x68\xc9\xa2\xb3\xae\x34\x6f\x09\x5e\x14\x9b\x8a\x88\xb4\x5a\xd0\x33\x1f\x5b\xc2\x11\x8c\xdc\xd3\xfa\x3c\x29\x6b\xfb\x59\xae\xcd\xa4\x07\xcd\x51\x32\x31\xf9\x17\x86\xb6\xaa\xec\x1c\xb6\xc8\x4f\x3f\x96\x6e\x5a\xd6\xe4\xaa\xad\x5d\xac\xac\xe1\xe2\xe7\xaa\x6c\x08\x37\xad\xe2\xec\xc5\x95\x4e\x3f\xb5\xf7\x69\x8a\x4a\x1d\x5b\xc5\x61\xf4\x4b\x12\x0e\x69\xf5\x4c\xd9\xc8\x79\xb9\x55\x0c\xd7\x83\x63\x23\x4d\x5b\x70\xdb\x6b\xd4\x8f\x92\xad\xad\xaa\x5b\x55\x29\x28\xe5\x61\x78\xb5\x96\x64\x3f\x67\xce\x93\x03\x8e\xe3\xdb\x5a\x55\xa2\x3d\xd5\xba\x37\x9e\xd7\x12\x5c\xd9\x0c\x5b\x47\xea\xac\xf0\xbf\xee\x0b\x76\x1c\x41\x7f\x48\xe0\x6b\x12\x48\x82\x5f\x70\xac\x13\x6a\xdd\xa9\x02\x2f\x60\x14\x6c\xbf\xea\xec\x28\x09\xff\xeb\xee\xe6\xf5\xbd\xcd\x0f\xa8\x1f\x8d\xdd\xdd\x39\xd7\xba\x42\xe4\x08\xfc\xab\x6e\x52\x1f\x95\x74\x13\x8d\x74\x49\x27\xbe\xd6\x1a\xf6\x19\x93\xd7\x97\xbb\x2d\x87\x74\x2a\x9d\x06\x39\xed\xde\x76\xba\xea\x5e\x3b\x9b\x9f\xb3\x47\x87\xba\x81\xda\xeb\x98\x23\x78\xfe\x79\x70\xcf\xc9\xcc\x1a\x16\x9b\x3d\xe8\x93\xae\xb4\xc0\x14\xd6\x29\xcf\xe8\xe7\xa5\xf0\x1c\xe2\xae\x9a\xcf\xb1\x52\x9f\xa7\x0a\x98\x86\xbf\xd8\xaf\x61\x2a\x67\x20\x9d\xf6\x16\xb3\x44\x3b\xa7\xd2\x6c\x91\xd6\xf5\x66\x38\x04\x16\x45\x30\x89\x59\x78\x6d\xbe\x96\x85\x05\x93\xd7\xb4\xff\xda\x33\x02\x46\x89\x59\x12\xc1\x00\xb6\x87\xdb\xa3\xfc\xe7\xef\xa8\x4e\x8e\xf9\x2a\xa8\x7c\x61\x0e\x30\xdd\xab\x5f\x5f\xc3\x0b\xf0\xdb\x05\x7d\x48\x1b\xe5\x97\x6a\xc9\x10\xba\x65\x3e\x97\xb3\x9d\x87\xb4\xc2\xbb\x9d\x73\x8d\xdd\xf3\xce\xe5\xa3\x5c\x96\x7b\xa4\xa4\x9a\xc0\xab\xcb\x4a\x1d\x73\x64\x8f\xe7\xe4\x69\xa5\x52\xa6\x9a\x5f\x1e\xe5\x3e\x66\xd4\x25\x52\x45\xf3\x17\x48\x94\x34\x9f\x7f\x39\xf2\xa4\x45\x5a\x11\xa6\x57\xff\x1b\xb2\xf4\xa7\x88\x83\xc4\xe8\xbf\x27\x0c\xb9\x28\xe4\x8d\x5d\x22\x81\x71\xc1\x69\x32\x91\xae\xd7\x47\xbf\xf3\x8d\xb7\xcd\x17\xac\x78\xa2\x7f\xb3\xae\xe5\x2b\xeb\x63\x92\xeb\xb9\xe5\x32\xb1\x5e\x89\xab\x9f\x58\x1a\xb5\x9e\x58\xca\xbd\x87\xc1\x84\xc9\x41\x4c\x83\x35\x26\x9f\xe7\x75\x88\xca\x01\x4b\xc2\xb9\x90\x4d\xd2\x3c\x4c\x22\x0f\xf6\xb3\x53\xd9\x5e\xed\x23\x51\xbc\x61\xf1\xff\xbb\x78\x23\xc5\xe2\x1b\xbd\x88\xfd\xb9\x5e\xc4\x6e\x9a\x27\xc1\xdb\xac\xe8\xe1\xde\xfe\x61\xe3\x85\xac\xc1\xdf\x8c\xf8\xcd\x66\xc6\xd8\x12\x3e\xe0\x49\x82\xf2\x9b\x0f\xef\xdf\xc1\x11\x10\x5a\xe7\xb3\x92\x50\xf2\x54\x2b\x7b\xe4\x3e\x07\xaf\x7c\x3d\xfd\x81\xcd\xec\xb7\xd3\x16\x34\x77\xa0\xc8\xa9\xf2\x09\x03\x37\x9e\x2c\x70\x72\xeb\x2c\xb2\xfc\xde\x0b\xd8\xda\xe2\xae\x7e\xd2\xfc\xfc\x0c\xe6\x92\x5f\x95\x54\xb9\x5f\x56\x97\xa7\xf8\x6b\x47\x5d\x56\x7d\x58\xbb\xec\x70\x0e\xd9\xac\x0e\xea\x6f\x3f\xc2\x11\xac\x9d\x0d\xac\x25\x36\x71\x29\xab\xe5\xe6\x64\xa6\x94\x7e\xf5\xd3\xae\x7c\xc4\x1e\x6c\x81\x97\x56\xd2\x96\x35\x04\x31\x4e\xa9\xbf\xb1\x69\xed\xc1\x6b\x7b\x87\x62\x4e\x0f\x0d\x90\x53\xe8\x8c\x50\x4e\x76\x5d\x99\xec\xc7\x07\x26\x6b\x77\xda\xea\x6c\x3f\x96\xb3\xfd\xf8\xf0\x6c\xb5\x48\xef\x9f\xec\x70\x08\x6f\x35\xc4\x42\x5c\xab\xfc\x02\xa5\x99\x10\xd3\x35\x51\xbb\x16\x4b\x7b\x39\x53\x00\x3b\xa3\x74\x05\x5c\x01\x9b\x90\xff\x6e\x3e\x21\xe6\xbf\x62\xfe\x6d\xbd\xc9\x4c\x83\x48\x80\xc1\xf6\x68\x6f\x64\x2e\x52\xc2\xe2\x5e\xa5\xfb\x69\x2b\xa4\x62\x0b\x76\x46\x0f\xce\xa7\xe0\x48\x2b\x77\x1f\x93\xf8\xce\x11\x16\x06\x84\xcf\x12\x21\x71\xd0\x38\xca\x6a\x4a\x2a\x0f\x88\xc8\x83\x48\x4a\x43\x54\xd5\xa0\x8e\xf2\x5d\x56\xbb\xb3\x65\xd4\x0e\x8d\x6a\x9c\x59\xab\xe9\x56\xe3\x90\xda\x63\x39\x43\x78\x9c\x6f\x0d\xc9\xd0\xc1\x51\x47\x06\xae\xb2\xb1\x3c\xb9\x28\xf4\x7b\x1d\x51\xe8\x3a\x71\x54\xa6\x20\x5b\x24\xc9\x14\x5f\x6a\xf3\x74\xc0\x9e\x74\x8c\xef\xa1\xeb\x9b\xda\xa5\xa7\xfd\x1c\x6a\xb6\xe8\x4e\x6c\xfe\xd0\xc2\x3f\x66\xf1\xa1\x48\x19\xe4\x53\xfe\xc1\x7e\x84\xff\x3d\x33\x45\x9c\x32\x11\x52\xc2\x3f\x0f\xd8\xbf\xd8\xca\xaf\x2e\xeb\x52\xc6\xfb\x6d\x38\xaa\xeb\x12\x31\xcd\xf6\xdb\x6a\x8e\x31\x0f\xaf\x7f\xb1\x2b\xd6\x76\xb2\x33\xbf\x25\xc2\x6f\xf9\x38\x21\x31\xd9\xc2\x2e\x59\x7a\xac\xb4\x74\xcb\xdc\x5d\xf5\xa7\x5a\x86\x21\x2a\xb5\x0f\xf7\xdd\x8b\xf4\x08\x01\x68\x56\x56\xa1\x45\x0a\xab\x17\x26\xe5\x7f\x35\x77\xa3\x13\xee\x11\xc2\xda\xa1\x18\x77\xee\xc6\xfe\xbc\xb8\x9d\xa5\x17\x48\x64\xd1\xba\x70\xe7\x8b\xf3\xd3\xc3\x61\x71\x8d\x0f\x59\xfc\xa5\x42\x39\xc8\xef\xe0\x30\xd7\xac\xd8\xab\x29\xa6\x1a\x25\xa8\xe5\x64\xc1\xf5\x50\xe2\x54\xa2\x9a\x07\xf0\xd3\x1c\x13\x48\x44\x62\xbe\x2f\xb2\xf7\x4b\xf4\xdd\x9b\x25\x26\x62\x05\x4a\xb3\xb5\xca\x6e\x3f\x59\x26\x9a\xc7\xe5\xed\x15\xe4\xd6\x2a\xd3\xc1\xda\x4d\xd5\x75\x69\x4b\x4e\x46\x8e\xd7\x77\xae\x80\xa9\xdc\x52\xd1\x83\x81\xb9\x1c\xb4\x71\x33\x43\xaf\x74\xbe\x0c\x99\x59\x93\x29\x93\x29\xc5\x45\x72\xa1\x85\x64\x33\x73\xa9\xc9\x5b\x8d\x8b\x96\x7b\x48\x4a\x9b\x5b\x41\x51\x37\xb4\xc4\xc0\xfa\xbd\x2b\xd5\x0e\xce\x05\x12\x19\xac\x7b\xe9\x4a\xf1\xae\x76\xeb\x8a\xfb\xbe\xe3\xda\x95\x26\xca\xf6\xbb\x57\xe0\xcb\xee\x5f\x29\x50\xdf\x77\x01\x0b\x94\x1b\xf7\x70\x08\xde\x3b\xa6\x51\x69\x0f\x24\x66\xfe\xb9\x5d\xe3\x1b\x8e\xb7\xf9\xdd\x21\x6d\xeb\xb8\x0f\x61\x8c\xcc\x5e\x8d\x82\xab\x34\xe6\x21\x37\x17\xda\xe4\x78\xad\x4c\x9a\x2f\xa8\xad\x4c\x9a\x2b\x4f\x4a\xe9\x81\x94\x87\xd7\xaa\x71\xa3\x8e\x7b\x49\x0a\x30\xe5\x5c\x57\x99\x23\x26\x62\x08\x6f\x76\xe9\x0f\xc9\xb5\x44\x0a\x5c\xd0\xde\x6f\x08\x5c\x83\x48\x42\xac\x09\xb1\xe9\xfe\xdc\xdf\x7c\x16\x9b\xf9\x6e\xf6\x02\x63\x17\x1d\x6d\x73\x0e\xf8\x54\x05\xce\x7e\xa7\x7d\xaf\xcc\x7d\xe1\x7a\x6d\x6e\x3a\x7b\xe4\x9c\x9b\xdc\xf5\x22\xb0\xfc\x72\x2f\x5f\xdb\xa0\xff\xfd\x5f\x00\x00\x00\xff\xff\xbf\x43\x1c\x64\xdd\x57\x00\x00") func webfilesSloop_uiJsBytes() ([]byte, error) { return bindataRead( @@ -365,7 +365,7 @@ func webfilesSloop_uiJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webfiles/sloop_ui.js", size: 22392, mode: os.FileMode(416), modTime: time.Unix(1781201511, 0)} + info := bindataFileInfo{name: "webfiles/sloop_ui.js", size: 22493, mode: os.FileMode(416), modTime: time.Unix(1781211009, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/pkg/sloop/webserver/webfiles/sloop.css b/pkg/sloop/webserver/webfiles/sloop.css index 2844333..c171253 100644 --- a/pkg/sloop/webserver/webfiles/sloop.css +++ b/pkg/sloop/webserver/webfiles/sloop.css @@ -141,6 +141,16 @@ input[type="button"] { font-size: 0.80em; } +/* End-time row: keep the datetime input and the Latest button on one line without clipping */ +#selectedEndTime { + width: 185px; +} + +#latest { + width: auto; + padding: 0 8px; +} + input[type="text"] { width: 245px; height: 1.3rem; diff --git a/pkg/sloop/webserver/webfiles/sloop_ui.js b/pkg/sloop/webserver/webfiles/sloop_ui.js index 1f2d7c0..277aab7 100644 --- a/pkg/sloop/webserver/webfiles/sloop_ui.js +++ b/pkg/sloop/webserver/webfiles/sloop_ui.js @@ -642,10 +642,12 @@ $(document).ready(function() { } // "Latest" re-anchors the view to the end of recorded data: clear the explicit end - // time so the server picks the newest data in the store as the window end + // time and resubmit, so the server picks the newest data in the store as the window + // end and the box is refilled with it once the data loads $('#latest').click(function(){ sessionStorage.removeItem('selectedEndTime'); document.getElementById('selectedEndTime').value = ''; + this.form.submit(); }); }); From ef021a3fced76051a409a2e7934bda185e2d20b4 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Thu, 30 Jul 2026 20:21:29 +0000 Subject: [PATCH 06/10] feat(chart): mount a remote kubeconfig to watch another cluster Add the optional remoteKubeconfigSecret value: when set the statefulset mounts that Secret at /remote-kube read-only and points KUBECONFIG at it, so the instance records the cluster described by the kubeconfig instead of the cluster it runs on. Needed to watch node-less clusters (e.g. the GDC L1 management plane) from a cluster that has nodes. The default render is unchanged from 0.2.0. --- helm/sloop/Chart.yaml | 2 +- helm/sloop/templates/statefulset.yaml | 15 +++++++++++++++ helm/sloop/values.yaml | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/helm/sloop/Chart.yaml b/helm/sloop/Chart.yaml index be018fd..9f9c4d3 100644 --- a/helm/sloop/Chart.yaml +++ b/helm/sloop/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 appVersion: "1.0" description: Sloop is a kubernetes history visualization tool. name: sloop -version: 0.2.0 +version: 0.3.0 icon: https://raw.githubusercontent.com/salesforce/sloop/master/other/sloop_logo_color.png diff --git a/helm/sloop/templates/statefulset.yaml b/helm/sloop/templates/statefulset.yaml index e56069f..4ee0f41 100644 --- a/helm/sloop/templates/statefulset.yaml +++ b/helm/sloop/templates/statefulset.yaml @@ -31,6 +31,11 @@ spec: - --config=/sloopconfig/sloop.json command: - /sloop + {{- if .Values.remoteKubeconfigSecret }} + env: + - name: KUBECONFIG + value: /remote-kube/config + {{- end }} image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} name: sloop @@ -66,6 +71,11 @@ spec: name: sloop-data - mountPath: /sloopconfig/ name: sloopconfig + {{- if .Values.remoteKubeconfigSecret }} + - mountPath: /remote-kube/ + name: remote-kube + readOnly: true + {{- end }} {{- with .Values.image.pullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} @@ -77,6 +87,11 @@ spec: - configMap: name: {{ .Values.name }} name: sloopconfig + {{- if .Values.remoteKubeconfigSecret }} + - name: remote-kube + secret: + secretName: {{ .Values.remoteKubeconfigSecret }} + {{- end }} serviceAccountName: {{ .Values.serviceAccountName }} {{- if .Values.persistentVolume.enabled }} volumeClaimTemplates: diff --git a/helm/sloop/values.yaml b/helm/sloop/values.yaml index 07d6fc8..338b791 100644 --- a/helm/sloop/values.yaml +++ b/helm/sloop/values.yaml @@ -6,6 +6,12 @@ podLabels: {} podAnnotations: {} name: sloop replicas: 1 +## If set, mounts this Secret (expected to hold a kubeconfig under the key +## "config") at /remote-kube and points sloop's KUBECONFIG at it, so this +## instance watches the cluster described by that kubeconfig instead of the +## cluster it runs on. Used to watch node-less clusters (e.g. a management +## plane) from a cluster that has nodes. +remoteKubeconfigSecret: "" image: tag: latest repository: ghcr.io/salesforce/sloop From 8e889292c1908b8e7c5b3eeff2a14f4f0bee5370 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:58:20 +0000 Subject: [PATCH 07/10] Return config errors instead of panicking on them MakeKubernetesClient logged config.Host before checking the error from ClientConfig, so any config problem (missing kubeconfig, unresolvable context) dereferenced a nil *rest.Config and killed the process instead of returning an error the caller could act on. Observed as a CrashLoopBackOff when a mounted kubeconfig was absent. --- pkg/sloop/ingress/kubeclient.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/sloop/ingress/kubeclient.go b/pkg/sloop/ingress/kubeclient.go index 7eee066..df5bd83 100644 --- a/pkg/sloop/ingress/kubeclient.go +++ b/pkg/sloop/ingress/kubeclient.go @@ -54,6 +54,14 @@ func MakeKubernetesClient(masterURL string, kubeContext string, privilegedAccess if privilegedAccess { clientConfig := getConfig(masterURL, kubeContext) config, err = ClientConfig(clientConfig) + // Check err before touching config: on failure config is nil and the + // former unconditional config.Host deref turned every config problem + // (missing kubeconfig, unresolvable context) into a panic/restart loop + // instead of an error the caller can retry. + if err != nil { + glog.Errorf("Cannot create config from kubeconfig (context=%v, masterURL=%v): %v", kubeContext, masterURL, err) + return nil, err + } glog.Infof("Building k8sclient with context=%v, masterURL=%v, configFile=%v.", kubeContext, config.Host, clientConfig.ConfigAccess().GetLoadingPrecedence()) } else { glog.Infof("Creating Config using BuildConfigFromFlags") From 050aa910492352c367bf4002984ea4119d69ed50 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:58:20 +0000 Subject: [PATCH 08/10] Retry kube watcher initialization instead of giving up The watcher goroutine logged one line and returned on the first error, so a transient API-server failure at startup left the process running with zero watchers, an empty database and a green /healthz for the rest of its life. Retry every minute until initialization succeeds. --- pkg/sloop/server/server.go | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/pkg/sloop/server/server.go b/pkg/sloop/server/server.go index 33d054e..4293ddb 100644 --- a/pkg/sloop/server/server.go +++ b/pkg/sloop/server/server.go @@ -109,20 +109,28 @@ func RealMain() error { var kubeWatcherMu sync.Mutex if !conf.DisableKubeWatcher { go func() { - kubeClient, err := ingress.MakeKubernetesClient(conf.ApiServerHost, kubeContext, conf.PrivilegedAccess) - if err != nil { - glog.Errorf("failed to create kubernetes client: %v", err) - return + // Retry forever instead of giving up on the first error: a + // transient API-server failure at startup (throttling, TLS + // timeout - common on management planes during a rollout, which + // is exactly when sloop starts) previously left the process + // running healthily for its whole life with zero watchers and an + // empty database, and nothing ever retried. + const retryDelay = time.Minute + for attempt := 1; ; attempt++ { + kubeClient, err := ingress.MakeKubernetesClient(conf.ApiServerHost, kubeContext, conf.PrivilegedAccess) + if err == nil { + var kw ingress.KubeWatcher + kw, err = ingress.NewKubeWatcherSource(kubeClient, kubeWatchChan, conf.KubeWatchResyncInterval, conf.WatchCrds, conf.CrdRefreshInterval, conf.ApiServerHost, kubeContext, conf.EnableGranularMetrics, conf.ExclusionRules) + if err == nil { + kubeWatcherMu.Lock() + kubeWatcherSource = kw + kubeWatcherMu.Unlock() + return + } + } + glog.Errorf("failed to initialize kubeWatcher (attempt %d, retrying in %v): %v", attempt, retryDelay, err) + time.Sleep(retryDelay) } - - kw, err := ingress.NewKubeWatcherSource(kubeClient, kubeWatchChan, conf.KubeWatchResyncInterval, conf.WatchCrds, conf.CrdRefreshInterval, conf.ApiServerHost, kubeContext, conf.EnableGranularMetrics, conf.ExclusionRules) - if err != nil { - glog.Errorf("failed to initialize kubeWatcher: %v", err) - return - } - kubeWatcherMu.Lock() - kubeWatcherSource = kw - kubeWatcherMu.Unlock() }() } From ea49854ee5b37c5777daa56fbcd39ed617b08d01 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:58:21 +0000 Subject: [PATCH 09/10] Arm the CRD refresh ticker before the first discovery The ticker that retries CRD discovery was created after the call it would retry, so a single transient CustomResourceDefinitions().List() error left CRD watching off for the life of the process while the well-known informers kept running and /healthz stayed green. Arm the ticker first and let the refresh loop retry discovery; the refresh goroutine still starts after the first attempt returns so two startCustomInformers calls cannot race over the informer map. --- pkg/sloop/ingress/kubewatcher.go | 80 +++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 11 deletions(-) diff --git a/pkg/sloop/ingress/kubewatcher.go b/pkg/sloop/ingress/kubewatcher.go index 9b70737..643f9c2 100644 --- a/pkg/sloop/ingress/kubewatcher.go +++ b/pkg/sloop/ingress/kubewatcher.go @@ -81,6 +81,7 @@ var ( metricIngressKubewatchbytes = promauto.NewCounterVec(prometheus.CounterOpts{Name: "sloop_ingress_kubewatchbytes"}, []string{"kind", "watchtype"}) metricCrdInformerStarted = promauto.NewGauge(prometheus.GaugeOpts{Name: "sloop_crd_informer_started"}) metricCrdInformerRunning = promauto.NewGauge(prometheus.GaugeOpts{Name: "sloop_crd_informer_running"}) + metricCrdInformerWatchErrors = promauto.NewCounterVec(prometheus.CounterOpts{Name: "sloop_crd_informer_watch_errors"}, []string{"kind", "group", "version"}) ) // Todo: Add additional parameters for filtering @@ -93,12 +94,18 @@ func NewKubeWatcherSource(kubeClient kubernetes.Interface, outChan chan typed.Ku kw.startWellKnownInformers(kubeClient, enableGranularMetrics) if includeCrds { - err := kw.startCustomInformers(masterURL, kubeContext, enableGranularMetrics) - if err != nil { - return nil, err - } - + // Arm the ticker BEFORE the first attempt: startCustomInformers fails + // wholesale on a transient CRD List error, and bailing out here meant + // the ticker was never created, so CRD watching stayed off for the + // life of the process while the well-known informers kept running and + // /healthz stayed green. With the ticker armed first, the refresh + // loop retries discovery every crdRefreshInterval until it succeeds. + // The goroutine is started only after the first attempt returns, so + // two startCustomInformers calls never race over the informer map. kw.refreshCrd = time.NewTicker(crdRefreshInterval) + if err := kw.startCustomInformers(masterURL, kubeContext, enableGranularMetrics); err != nil { + glog.Errorf("Initial CRD discovery failed, retrying every %v: %v", crdRefreshInterval, err) + } go kw.refreshCrdInformers(masterURL, kubeContext, enableGranularMetrics) } @@ -197,6 +204,18 @@ func (i *kubeWatcherImpl) startNewCrdInformer(crdInformer *crdInformerInfo, fact kind := crdInformer.crd.kind informer := factory.ForResource(gvr) informer.Informer().AddEventHandler(i.getEventHandlerForResource(kind, enableGranularMetrics)) + // Reflector list/watch failures are otherwise invisible: Run() never + // returns an error and retries forever, and metricCrdInformerRunning is + // incremented before Run(), so a permanently failing informer (RBAC + // denied, unreachable apiserver) looks healthy from the outside while + // recording nothing. Count and log the failures so an empty database can + // be traced to its cause. + if err := informer.Informer().SetWatchErrorHandler(func(_ *cache.Reflector, err error) { + metricCrdInformerWatchErrors.WithLabelValues(kind, gvr.Group, gvr.Version).Inc() + glog.Errorf("CRD informer list/watch failed for %s (%v): %v", kind, gvr, err) + }); err != nil { + glog.Errorf("Failed to install watch error handler for %s (%v): %v", kind, gvr, err) + } go func() { glog.V(2).Infof("Starting CRD informer for: %s (%v)", kind, gvr) @@ -227,11 +246,33 @@ func getCrdList(crdClient clientset.Interface) ([]crdGroupVersionResourceKind, e var resources []crdGroupVersionResourceKind for _, crd := range crdList.Items { + // Watch exactly one served version per CRD. The apiserver returns the + // same objects through every served version, so watching all of them + // wrote each object N times (observed: 220 watch events for 110 + // Projects on a v1+v1alpha1 CRD), and an unserved version has no + // endpoint at all - its informer 404-loops forever while being + // counted as running. Prefer the storage version when it is served, + // else fall back to the first served one. + chosen := "" for _, version := range crd.Spec.Versions { - gvrk := crdGroupVersionResourceKind{group: crd.Spec.Group, version: version.Name, resource: crd.Spec.Names.Plural, kind: crd.Spec.Names.Kind} - glog.V(2).Infof("CRD: group: %s, version: %s, kind: %s, plural:%s, singular:%s, short names:%v", crd.Spec.Group, version.Name, crd.Spec.Names.Kind, crd.Spec.Names.Plural, crd.Spec.Names.Singular, crd.Spec.Names.ShortNames) - resources = append(resources, gvrk) + if !version.Served { + continue + } + if chosen == "" { + chosen = version.Name + } + if version.Storage { + chosen = version.Name + break + } + } + if chosen == "" { + glog.V(2).Infof("CRD %s kind %s has no served versions; skipping", crd.Spec.Group, crd.Spec.Names.Kind) + continue } + gvrk := crdGroupVersionResourceKind{group: crd.Spec.Group, version: chosen, resource: crd.Spec.Names.Plural, kind: crd.Spec.Names.Kind} + glog.V(2).Infof("CRD: group: %s, version: %s, kind: %s, plural:%s, singular:%s, short names:%v", crd.Spec.Group, chosen, crd.Spec.Names.Kind, crd.Spec.Names.Plural, crd.Spec.Names.Singular, crd.Spec.Names.ShortNames) + resources = append(resources, gvrk) } return resources, nil } @@ -245,11 +286,28 @@ func getCrdListV1beta1(crdClient clientset.Interface) ([]crdGroupVersionResource // duplicated code (see getCrdList), the types for crdList are different var resources []crdGroupVersionResourceKind for _, crd := range crdList.Items { + // See getCrdList: watch exactly one served version per CRD, + // preferring the storage version. + chosen := "" for _, version := range crd.Spec.Versions { - gvrk := crdGroupVersionResourceKind{group: crd.Spec.Group, version: version.Name, resource: crd.Spec.Names.Plural, kind: crd.Spec.Names.Kind} - glog.V(2).Infof("CRD: group: %s, version: %s, kind: %s, plural:%s, singular:%s, short names:%v", crd.Spec.Group, version.Name, crd.Spec.Names.Kind, crd.Spec.Names.Plural, crd.Spec.Names.Singular, crd.Spec.Names.ShortNames) - resources = append(resources, gvrk) + if !version.Served { + continue + } + if chosen == "" { + chosen = version.Name + } + if version.Storage { + chosen = version.Name + break + } + } + if chosen == "" { + glog.V(2).Infof("CRD %s kind %s has no served versions; skipping", crd.Spec.Group, crd.Spec.Names.Kind) + continue } + gvrk := crdGroupVersionResourceKind{group: crd.Spec.Group, version: chosen, resource: crd.Spec.Names.Plural, kind: crd.Spec.Names.Kind} + glog.V(2).Infof("CRD: group: %s, version: %s, kind: %s, plural:%s, singular:%s, short names:%v", crd.Spec.Group, chosen, crd.Spec.Names.Kind, crd.Spec.Names.Plural, crd.Spec.Names.Singular, crd.Spec.Names.ShortNames) + resources = append(resources, gvrk) } return resources, nil } From 936355a78ac9e8d893fca7f5ecd6e6e74be0a9a4 Mon Sep 17 00:00:00 2001 From: RezaMash <15625518+RezaMash@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:58:21 +0000 Subject: [PATCH 10/10] Watch one served version per CRD Every entry of crd.Spec.Versions got its own informer. An unserved version has no endpoint and 404-loops forever while counting as running, and the apiserver returns the same objects through each served version, so multi-version CRDs recorded every object once per version (observed: 220 watch events for 110 Projects on a v1+v1alpha1 CRD). Pick the served storage version, falling back to the first served one, and skip CRDs that serve nothing. --- pkg/sloop/ingress/kubewatcher_test.go | 35 ++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/pkg/sloop/ingress/kubewatcher_test.go b/pkg/sloop/ingress/kubewatcher_test.go index d0fe6e0..61328c5 100644 --- a/pkg/sloop/ingress/kubewatcher_test.go +++ b/pkg/sloop/ingress/kubewatcher_test.go @@ -39,7 +39,7 @@ type dummyData struct { // when fake client tries to list CRDs, return a list with one defined func reactionListOfOne(_ k8sTesting.Action) (bool, runtime.Object, error) { - versions := []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1"}} + versions := []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1", Served: true, Storage: true}} name := apiextensionsv1.CustomResourceDefinitionNames{Plural: "things", Kind: "k"} spec := apiextensionsv1.CustomResourceDefinitionSpec{Group: "g", Versions: versions, Names: name} crd := apiextensionsv1.CustomResourceDefinition{Spec: spec} @@ -47,6 +47,30 @@ func reactionListOfOne(_ k8sTesting.Action) (bool, runtime.Object, error) { return true, &list, nil } +// when fake client tries to list CRDs, return one CRD that serves two +// versions (storage version listed second) plus one CRD with no served +// version at all: getCrdList must pick exactly the storage version of the +// first and skip the second entirely. +func reactionMultiVersion(_ k8sTesting.Action) (bool, runtime.Object, error) { + dual := apiextensionsv1.CustomResourceDefinition{Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "g", + Names: apiextensionsv1.CustomResourceDefinitionNames{Plural: "things", Kind: "k"}, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + {Name: "v1alpha1", Served: true, Storage: false}, + {Name: "v1", Served: true, Storage: true}, + }, + }} + unserved := apiextensionsv1.CustomResourceDefinition{Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "g2", + Names: apiextensionsv1.CustomResourceDefinitionNames{Plural: "others", Kind: "o"}, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + {Name: "v1", Served: false, Storage: true}, + }, + }} + list := apiextensionsv1.CustomResourceDefinitionList{Items: []apiextensionsv1.CustomResourceDefinition{dual, unserved}} + return true, &list, nil +} + // when fake client tries to list CRDs, return an error func reactionError(_ k8sTesting.Action) (bool, runtime.Object, error) { return true, nil, fmt.Errorf("failed") @@ -185,6 +209,15 @@ func Test_getCrdList(t *testing.T) { crdList, err = getCrdList(crdClient) assert.Len(t, crdList, 1) assert.NoError(t, err) + + // One informer per CRD, on the served storage version; CRDs with no + // served version are skipped entirely. + crdClient, _ = newTestCrdClient(reactionMultiVersion)(&rest.Config{}) + crdList, err = getCrdList(crdClient) + assert.NoError(t, err) + assert.Len(t, crdList, 1) + assert.Equal(t, "v1", crdList[0].version) + assert.Equal(t, "k", crdList[0].kind) } func Test_getEventHandlerForResource(t *testing.T) {