From 2634b2cbe793d5a422d2fd882de3a34ba05c8cd4 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Sun, 22 May 2016 23:21:45 -0700 Subject: [PATCH 01/42] Add banner indicating that guide for creating new beat is out of date (#1692) --- libbeat/docs/index.asciidoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libbeat/docs/index.asciidoc b/libbeat/docs/index.asciidoc index c467ad8d1201..84227c9b6bc1 100644 --- a/libbeat/docs/index.asciidoc +++ b/libbeat/docs/index.asciidoc @@ -26,8 +26,12 @@ include::./visualizing-data.asciidoc[] include::./dashboards.asciidoc[] +pass::[PLEASE NOTE:
We are working on updating this section. Some content might be out of date. While you're waiting for updates, you might want to try out the Beat generator at https://github.com/elastic/beat-generator.?>] + include::./newbeat.asciidoc[] +pass::[] + include::./release.asciidoc[] //include::./../../../beats/CHANGELOG.asciidoc[] From 0cee3c097721bc8add827ddc063471f7394d348d Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Mon, 23 May 2016 13:15:57 -0700 Subject: [PATCH 02/42] Point to instructions for building Beats from the source (#1706) --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 6bbee45c5a23..8cafd6c925fb 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,8 @@ guide](https://www.elastic.co/guide/en/beats/libbeat/current/new-beat.html). After you have a working prototype, open a pull request to add your Beat to the list of [community Beats](https://github.com/elastic/beats/blob/master/libbeat/docs/communitybeats.asciidoc). + +## Building Beats from the Source + +See our [CONTRIBUTING](CONTRIBUTING.md) file for information about setting up your dev +environment to build Beats from the source. From 0a6182372aa16eec942120a2d5848598a4a46150 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Mon, 23 May 2016 13:16:16 -0700 Subject: [PATCH 03/42] Fix example config to include fields_under_root (#1708) --- filebeat/docs/migration.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/filebeat/docs/migration.asciidoc b/filebeat/docs/migration.asciidoc index a16372074962..316df2f7122f 100644 --- a/filebeat/docs/migration.asciidoc +++ b/filebeat/docs/migration.asciidoc @@ -136,6 +136,7 @@ filebeat: fields: service: apache zone: us-east-1 + fields_under_root: true - input_type: stdin <2> document_type: stdin From 24ebcc0448f95b52feec1ad68a93c89e6e4de109 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Mon, 23 May 2016 13:16:54 -0700 Subject: [PATCH 04/42] Fix mismatch between lists of supported protocols (#1707) --- packetbeat/docs/overview.asciidoc | 9 +-------- .../configuration/packetbeat-options.asciidoc | 10 +--------- packetbeat/docs/shared-protocol-list.asciidoc | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 17 deletions(-) create mode 100644 packetbeat/docs/shared-protocol-list.asciidoc diff --git a/packetbeat/docs/overview.asciidoc b/packetbeat/docs/overview.asciidoc index 7f0f64c30472..0f2a15891cf6 100644 --- a/packetbeat/docs/overview.asciidoc +++ b/packetbeat/docs/overview.asciidoc @@ -19,14 +19,7 @@ Packetbeat sniffs the traffic between your servers, parses the application-level protocols on the fly, and correlates the messages into transactions. Currently, Packetbeat supports the following protocols: - * HTTP - * MySQL - * PostgreSQL - * Redis - * Thrift-RPC - * MongoDB - * DNS - * Memcache +include::shared-protocol-list.asciidoc[] Packetbeat can insert the correlated transactions directly into Elasticsearch or into a central queue created with Redis and Logstash. diff --git a/packetbeat/docs/reference/configuration/packetbeat-options.asciidoc b/packetbeat/docs/reference/configuration/packetbeat-options.asciidoc index 77127dfcc283..27551f609436 100644 --- a/packetbeat/docs/reference/configuration/packetbeat-options.asciidoc +++ b/packetbeat/docs/reference/configuration/packetbeat-options.asciidoc @@ -186,15 +186,7 @@ common options like `ports`, `send_request`, `send_response`, and options that a Currently, Packetbeat supports the following protocols: - - ICMP (v4 and v6) - - DNS - - HTTP - - Mysql - - PostgreSQL - - Redis - - Thrift-RPC - - MongoDB - - Memcache +include::../../shared-protocol-list.asciidoc[] Example configuration: diff --git a/packetbeat/docs/shared-protocol-list.asciidoc b/packetbeat/docs/shared-protocol-list.asciidoc new file mode 100644 index 000000000000..6ad4af75c86c --- /dev/null +++ b/packetbeat/docs/shared-protocol-list.asciidoc @@ -0,0 +1,16 @@ +////////////////////////////////////////////////////////////////////////// +//// This content is shared by multiple files. +//// Use the following include to pull this content into a doc file: +//// include::shared-protocol-list.asciidoc[] +////////////////////////////////////////////////////////////////////////// + + - ICMP (v4 and v6) + - DNS + - HTTP + - Mysql + - PostgreSQL + - Redis + - Thrift-RPC + - MongoDB + - Memcache + \ No newline at end of file From 664f2735c4859d967db5f51275465b74c3814948 Mon Sep 17 00:00:00 2001 From: Aidan Rowe Date: Thu, 26 May 2016 21:03:44 +1000 Subject: [PATCH 05/42] add cloudtrailbeat to community beats list (#1737) CloudTrailBeat is a beat that processes AWS CloudTrail events. --- libbeat/docs/communitybeats.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/libbeat/docs/communitybeats.asciidoc b/libbeat/docs/communitybeats.asciidoc index 1ac4739401c9..68bf183253bc 100644 --- a/libbeat/docs/communitybeats.asciidoc +++ b/libbeat/docs/communitybeats.asciidoc @@ -6,6 +6,7 @@ out some of them here: [horizontal] https://github.com/radoondas/apachebeat[apachebeat]:: Reads status from Apache HTTPD server-status. +https://github.com/aidan-/cloudtrailbeat[cloudtrailbeat]:: Read events from Amazon Web Services' https://aws.amazon.com/cloudtrail/[CloudTrail] https://github.com/Ingensi/dockerbeat[dockerbeat]:: Reads Docker container statistics and indexes them in Elasticsearch. https://github.com/radoondas/elasticbeat[elasticbeat]:: Reads status from an Elasticsearch cluster and indexes them in Elasticsearch. From 793065013faedfaff030641988657b33c4076df4 Mon Sep 17 00:00:00 2001 From: adioss Date: Fri, 3 Jun 2016 19:05:12 +0200 Subject: [PATCH 06/42] Reset backoffCount after correct ACK received --- libbeat/outputs/mode/single.go | 1 + 1 file changed, 1 insertion(+) diff --git a/libbeat/outputs/mode/single.go b/libbeat/outputs/mode/single.go index 4ecf454d2104..8d2b2d8478d8 100644 --- a/libbeat/outputs/mode/single.go +++ b/libbeat/outputs/mode/single.go @@ -141,6 +141,7 @@ func (s *SingleConnectionMode) publish( if resetFail { debug("reset fails") fails = 0 + backoffCount = 0 } if !guaranteed && (s.maxAttempts > 0 && fails == s.maxAttempts) { From 9c7dcc28c8f9bb25dbb78d38236b34c48694614c Mon Sep 17 00:00:00 2001 From: adioss Date: Mon, 6 Jun 2016 17:38:31 +0200 Subject: [PATCH 07/42] Reset backoffCount after send completed --- libbeat/outputs/mode/single.go | 1 + 1 file changed, 1 insertion(+) diff --git a/libbeat/outputs/mode/single.go b/libbeat/outputs/mode/single.go index 8d2b2d8478d8..a0cd1f3fde66 100644 --- a/libbeat/outputs/mode/single.go +++ b/libbeat/outputs/mode/single.go @@ -132,6 +132,7 @@ func (s *SingleConnectionMode) publish( goto sendFail } + backoffCount = 0 debug("send completed") outputs.SignalCompleted(signaler) return nil From eeefcdf166e58aea4927d94258dfd890ed4c59c5 Mon Sep 17 00:00:00 2001 From: Steffen Siering Date: Wed, 8 Jun 2016 17:18:32 +0200 Subject: [PATCH 08/42] Backport: remember backoff counts (#1818) Remember backoff counts between calls to publish, so backoff is not reset in between multiple calls to publish --- CHANGELOG.asciidoc | 3 ++- libbeat/outputs/mode/balance.go | 9 ++++++--- libbeat/outputs/mode/single.go | 10 +++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index ca3f548d5780..b7e804803971 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -8,7 +8,7 @@ // Template, add newest changes here === Beats version HEAD -https://github.com/elastic/beats/compare/v1.2.3...1.2[Check the HEAD diff] +https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] ==== Breaking changes @@ -26,6 +26,7 @@ https://github.com/elastic/beats/compare/v1.2.3...1.2[Check the HEAD diff] ==== Bugfixes *Affecting all Beats* +- Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] *Packetbeat* diff --git a/libbeat/outputs/mode/balance.go b/libbeat/outputs/mode/balance.go index 8b8b5a2106b9..6404dc421e07 100644 --- a/libbeat/outputs/mode/balance.go +++ b/libbeat/outputs/mode/balance.go @@ -40,6 +40,8 @@ type LoadBalancerMode struct { // block until event has been successfully published. maxAttempts int + backoffCount uint // number of consecutive failed retry attempts. + // waitGroup + signaling channel for handling shutdown wg sync.WaitGroup done chan struct{} @@ -191,7 +193,6 @@ func (m *LoadBalancerMode) onMessage(client ProtocolClient, msg eventsMessage) { } else { events := msg.events total := len(events) - var backoffCount uint for len(events) > 0 { var err error @@ -222,11 +223,11 @@ func (m *LoadBalancerMode) onMessage(client ProtocolClient, msg eventsMessage) { } // wait before retry - backoff := time.Duration(int64(m.waitRetry) * (1 << backoffCount)) + backoff := time.Duration(int64(m.waitRetry) * (1 << m.backoffCount)) if backoff > m.maxWaitRetry { backoff = m.maxWaitRetry } else { - backoffCount++ + m.backoffCount++ } select { case <-m.done: // shutdown @@ -240,6 +241,8 @@ func (m *LoadBalancerMode) onMessage(client ProtocolClient, msg eventsMessage) { } } } + + m.backoffCount = 0 outputs.SignalCompleted(msg.signaler) } diff --git a/libbeat/outputs/mode/single.go b/libbeat/outputs/mode/single.go index a0cd1f3fde66..f486365299e3 100644 --- a/libbeat/outputs/mode/single.go +++ b/libbeat/outputs/mode/single.go @@ -19,6 +19,7 @@ type SingleConnectionMode struct { timeout time.Duration // connection timeout waitRetry time.Duration // wait time until reconnect maxWaitRetry time.Duration // Maximum send/retry timeout in backoff case. + backoffCount uint // number of consecutive failed retry attempts. // maximum number of configured send attempts. If set to 0, publisher will // block until event has been successfully published. @@ -113,7 +114,6 @@ func (s *SingleConnectionMode) publish( send func() (ok bool, resetFail bool), ) error { fails := 0 - var backoffCount uint var err error guaranteed := opts.Guaranteed || s.maxAttempts == 0 @@ -132,8 +132,8 @@ func (s *SingleConnectionMode) publish( goto sendFail } - backoffCount = 0 debug("send completed") + s.backoffCount = 0 outputs.SignalCompleted(signaler) return nil @@ -142,7 +142,7 @@ func (s *SingleConnectionMode) publish( if resetFail { debug("reset fails") fails = 0 - backoffCount = 0 + s.backoffCount = 0 } if !guaranteed && (s.maxAttempts > 0 && fails == s.maxAttempts) { @@ -152,11 +152,11 @@ func (s *SingleConnectionMode) publish( } logp.Info("send fail") - backoff := time.Duration(int64(s.waitRetry) * (1 << backoffCount)) + backoff := time.Duration(int64(s.waitRetry) * (1 << s.backoffCount)) if backoff > s.maxWaitRetry { backoff = s.maxWaitRetry } else { - backoffCount++ + s.backoffCount++ } logp.Info("backoff retry: %v", backoff) time.Sleep(backoff) From ce8e536dc0f69437ccfb16aedf48f91bac8951f8 Mon Sep 17 00:00:00 2001 From: Steffen Siering Date: Fri, 10 Jun 2016 08:16:37 +0200 Subject: [PATCH 09/42] Backport: Initialize random number generator seed. (#1827) Initialize random number generator using cryptographic seed read from OS. Fixes issues with random number generator always returning same sequence, e.g. when using random endpoint connecting to logstash in failover mode. --- CHANGELOG.asciidoc | 7 +++++++ libbeat/beat/beat.go | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index b7e804803971..d61b966ffad1 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -28,6 +28,13 @@ https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] *Affecting all Beats* - Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] +- Drain response buffers when pipelining is used by redis output. {pull}1353[1353] +- Unterminated environment variable expressions in config files will now cause an error {pull}1389[1389] +- Fix issue with the automatic template loading when Elasticsearch is not available on Beat start. {issue}1321[1321] +- Fix bug affecting -cpuprofile, -memprofile, and -httpprof CLI flags {pull}1415[1415] +- Fix race when multiple outputs access the same event with logstash output manipulating event {issue}1410[1410] {pull}1428[1428] +- Seed random number generator using crypto.rand package. {pull}1503{1503] + *Packetbeat* *Topbeat* diff --git a/libbeat/beat/beat.go b/libbeat/beat/beat.go index 371f00487003..b1717a320313 100644 --- a/libbeat/beat/beat.go +++ b/libbeat/beat/beat.go @@ -1,10 +1,15 @@ package beat import ( + cryptRand "crypto/rand" "flag" "fmt" + "math" + "math/big" + "math/rand" "os" "runtime" + "time" "github.com/elastic/beats/libbeat/cfgfile" "github.com/elastic/beats/libbeat/logp" @@ -51,6 +56,22 @@ var printVersion *bool func init() { printVersion = flag.Bool("version", false, "Print version and exit") + + // Initialize runtime random number generator seed using global, shared + // cryptographically strong pseudo random number generator. + // + // On linux Reader might use getrandom(2) or /udev/random. On windows systems + // CryptGenRandom is used. + n, err := cryptRand.Int(cryptRand.Reader, big.NewInt(math.MaxInt64)) + var seed int64 + if err != nil { + // fallback to current timestamp on error + seed = time.Now().UnixNano() + } else { + seed = n.Int64() + } + + rand.Seed(seed) } // Initiates a new beat object From 8ea266f80b6af4b76edbe7b88c263829c13eede8 Mon Sep 17 00:00:00 2001 From: Steffen Siering Date: Fri, 10 Jun 2016 16:08:46 +0200 Subject: [PATCH 10/42] Fix logstash default bulk max size (#1828) --- CHANGELOG.asciidoc | 1 + filebeat/etc/filebeat.yml | 4 ++++ libbeat/etc/libbeat.yml | 4 ++++ libbeat/outputs/logstash/logstash.go | 2 +- packetbeat/etc/packetbeat.yml | 4 ++++ topbeat/etc/topbeat.yml | 4 ++++ winlogbeat/etc/winlogbeat.yml | 4 ++++ 7 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index d61b966ffad1..bb0ed46d3793 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -27,6 +27,7 @@ https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] *Affecting all Beats* - Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] +- Set logstash output default bulk_max_size to 2048. {issue}1662[1662] - Drain response buffers when pipelining is used by redis output. {pull}1353[1353] - Unterminated environment variable expressions in config files will now cause an error {pull}1389[1389] diff --git a/filebeat/etc/filebeat.yml b/filebeat/etc/filebeat.yml index 3f3caede47f9..eb81c6d5d020 100644 --- a/filebeat/etc/filebeat.yml +++ b/filebeat/etc/filebeat.yml @@ -282,6 +282,10 @@ output: # Number of workers per Logstash host. #worker: 1 + # The maximum number of events to bulk into a single batch window. The + # default is 2048. + #bulk_max_size: 2048 + # Set gzip compression level. #compression_level: 3 diff --git a/libbeat/etc/libbeat.yml b/libbeat/etc/libbeat.yml index 81f4002088e8..3483d4d240b7 100644 --- a/libbeat/etc/libbeat.yml +++ b/libbeat/etc/libbeat.yml @@ -111,6 +111,10 @@ output: # Number of workers per Logstash host. #worker: 1 + # The maximum number of events to bulk into a single batch window. The + # default is 2048. + #bulk_max_size: 2048 + # Set gzip compression level. #compression_level: 3 diff --git a/libbeat/outputs/logstash/logstash.go b/libbeat/outputs/logstash/logstash.go index 51a3ffeddf5e..4394832c57e1 100644 --- a/libbeat/outputs/logstash/logstash.go +++ b/libbeat/outputs/logstash/logstash.go @@ -44,7 +44,7 @@ const ( logstashDefaultTimeout = 30 * time.Second logstasDefaultMaxTimeout = 90 * time.Second defaultSendRetries = 3 - defaultMaxWindowSize = 1024 + defaultMaxWindowSize = 2048 defaultCompressionLevel = 3 ) diff --git a/packetbeat/etc/packetbeat.yml b/packetbeat/etc/packetbeat.yml index 5334d6c6e6fc..082cfb68058c 100644 --- a/packetbeat/etc/packetbeat.yml +++ b/packetbeat/etc/packetbeat.yml @@ -250,6 +250,10 @@ output: # Number of workers per Logstash host. #worker: 1 + # The maximum number of events to bulk into a single batch window. The + # default is 2048. + #bulk_max_size: 2048 + # Set gzip compression level. #compression_level: 3 diff --git a/topbeat/etc/topbeat.yml b/topbeat/etc/topbeat.yml index 7c7dfbff6c76..c856b1fe0a3c 100644 --- a/topbeat/etc/topbeat.yml +++ b/topbeat/etc/topbeat.yml @@ -137,6 +137,10 @@ output: # Number of workers per Logstash host. #worker: 1 + # The maximum number of events to bulk into a single batch window. The + # default is 2048. + #bulk_max_size: 2048 + # Set gzip compression level. #compression_level: 3 diff --git a/winlogbeat/etc/winlogbeat.yml b/winlogbeat/etc/winlogbeat.yml index 67aa3d0789a2..8a75513866f7 100644 --- a/winlogbeat/etc/winlogbeat.yml +++ b/winlogbeat/etc/winlogbeat.yml @@ -136,6 +136,10 @@ output: # Number of workers per Logstash host. #worker: 1 + # The maximum number of events to bulk into a single batch window. The + # default is 2048. + #bulk_max_size: 2048 + # Set gzip compression level. #compression_level: 3 From 9b5592f31218c2dc22b00d09cf675e7738ce9ead Mon Sep 17 00:00:00 2001 From: Steffen Siering Date: Mon, 13 Jun 2016 08:40:30 +0200 Subject: [PATCH 11/42] Backport fix for loadbalancer deadlock on too many retries being queued up (#1833) --- CHANGELOG.asciidoc | 7 +------ libbeat/outputs/mode/balance.go | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index bb0ed46d3793..e99c18cf927b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -26,14 +26,9 @@ https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] ==== Bugfixes *Affecting all Beats* +- Fix beats load balancer deadlock if max_retries: -1 or publish_async is enabled in filebeat. {issue}1829[1829] - Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] - Set logstash output default bulk_max_size to 2048. {issue}1662[1662] - -- Drain response buffers when pipelining is used by redis output. {pull}1353[1353] -- Unterminated environment variable expressions in config files will now cause an error {pull}1389[1389] -- Fix issue with the automatic template loading when Elasticsearch is not available on Beat start. {issue}1321[1321] -- Fix bug affecting -cpuprofile, -memprofile, and -httpprof CLI flags {pull}1415[1415] -- Fix race when multiple outputs access the same event with logstash output manipulating event {issue}1410[1410] {pull}1428[1428] - Seed random number generator using crypto.rand package. {pull}1503{1503] *Packetbeat* diff --git a/libbeat/outputs/mode/balance.go b/libbeat/outputs/mode/balance.go index 6404dc421e07..0683a9a942bd 100644 --- a/libbeat/outputs/mode/balance.go +++ b/libbeat/outputs/mode/balance.go @@ -162,14 +162,20 @@ func (m *LoadBalancerMode) start(clients []ProtocolClient) { } // receive and process messages - var msg eventsMessage select { - case <-m.done: - return - case msg = <-m.retries: // receive message from other failed worker - case msg = <-m.work: // receive message from publisher + case msg := <-m.retries: + m.onMessage(client, msg) + + default: + var msg eventsMessage + select { + case <-m.done: + return + case msg = <-m.retries: // receive message from other failed worker + case msg = <-m.work: // receive message from publisher + } + m.onMessage(client, msg) } - m.onMessage(client, msg) } } From d72f9137dcda81ce39bf149118c2cbd8e2e71908 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 14 Jun 2016 09:14:07 +0200 Subject: [PATCH 12/42] Add missing periods (#1849) --- libbeat/docs/communitybeats.asciidoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libbeat/docs/communitybeats.asciidoc b/libbeat/docs/communitybeats.asciidoc index 68bf183253bc..4dd1f5adf87b 100644 --- a/libbeat/docs/communitybeats.asciidoc +++ b/libbeat/docs/communitybeats.asciidoc @@ -6,7 +6,7 @@ out some of them here: [horizontal] https://github.com/radoondas/apachebeat[apachebeat]:: Reads status from Apache HTTPD server-status. -https://github.com/aidan-/cloudtrailbeat[cloudtrailbeat]:: Read events from Amazon Web Services' https://aws.amazon.com/cloudtrail/[CloudTrail] +https://github.com/aidan-/cloudtrailbeat[cloudtrailbeat]:: Reads events from Amazon Web Services' https://aws.amazon.com/cloudtrail/[CloudTrail]. https://github.com/Ingensi/dockerbeat[dockerbeat]:: Reads Docker container statistics and indexes them in Elasticsearch. https://github.com/radoondas/elasticbeat[elasticbeat]:: Reads status from an Elasticsearch cluster and indexes them in Elasticsearch. @@ -19,7 +19,7 @@ https://github.com/christiangalsterer/httpbeat[httpbeat]:: Polls multiple HTTP(S Logstash or Elasticsearch. Supports all HTTP methods and proxies. https://github.com/jasperla/hwsensorsbeat[hwsensorsbeat]:: Reads sensors information from OpenBSD. https://github.com/radoondas/jmxproxybeat[jmxproxybeat]:: Reads Tomcat JMX metrics exposed over 'JMX Proxy Servlet' to HTTP. -https://github.com/eskibars/lmsensorsbeat[lmsensorsbeat]:: Collects data from lm-sensors (such as CPU temperatures, fan speeds, and voltages from i2c and smbus) +https://github.com/eskibars/lmsensorsbeat[lmsensorsbeat]:: Collects data from lm-sensors (such as CPU temperatures, fan speeds, and voltages from i2c and smbus). https://github.com/adibendahan/mysqlbeat[mysqlbeat]:: Run any query on MySQL and send results to Elasticsearch. https://github.com/PhaedrusTheGreek/nagioscheckbeat[nagioscheckbeat]:: For Nagios checks and performance data. https://github.com/mrkschan/nginxbeat[nginxbeat]:: Reads status from Nginx. @@ -38,7 +38,7 @@ https://github.com/eskibars/wmibeat[wmibeat]:: Uses WMI to grab your favorite, c -Have you created a Beat that's not listed? If so, add the name and description of your Beat to the source document for +Have you created a Beat that's not listed? If so, add the name and description of your Beat to the source document for https://github.com/elastic/beats/blob/master/libbeat/docs/communitybeats.asciidoc[Community Beats] and https://help.github.com/articles/using-pull-requests[open a pull request] in the https://github.com/elastic/beats[Beats GitHub repository] to get your change merged. When you're ready, go ahead and https://discuss.elastic.co/c/annoucements[announce] your new Beat in the Elastic discussion forum. From cfd4bfc4d8b09b9aa03e117039f53e1194bab661 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Tue, 14 Jun 2016 13:44:36 +0200 Subject: [PATCH 13/42] Add info about testing the config file (#1846) --- filebeat/docs/getting-started.asciidoc | 3 +++ libbeat/docs/shared-logstash-config.asciidoc | 6 +++++- packetbeat/docs/gettingstarted.asciidoc | 3 +++ topbeat/docs/gettingstarted.asciidoc | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/filebeat/docs/getting-started.asciidoc b/filebeat/docs/getting-started.asciidoc index 5b2ae80a645c..da38eee48189 100644 --- a/filebeat/docs/getting-started.asciidoc +++ b/filebeat/docs/getting-started.asciidoc @@ -149,6 +149,9 @@ output: + If you are sending output to Logstash, see <> instead. +TIP: To test your configuration file, run Filebeat in the foreground with the following options specified: ++./filebeat -configtest -e+. + See <> for more details about each configuration option. [[config-filebeat-logstash]] diff --git a/libbeat/docs/shared-logstash-config.asciidoc b/libbeat/docs/shared-logstash-config.asciidoc index e455c45b29a3..6d571ed3719a 100644 --- a/libbeat/docs/shared-logstash-config.asciidoc +++ b/libbeat/docs/shared-logstash-config.asciidoc @@ -29,6 +29,10 @@ output: In this configuration, `hosts` specifies the Logstash server and the port (`5044`) where Logstash is configured to listen for incoming Beats connections. +TIP: To test your configuration file, run {beatname_uc} in the foreground with the following options specified: ++./{beatname_lc} -configtest -e+. + To use this configuration, you must also {libbeat}/logstash-installation.html#logstash-setup[set up Logstash] to receive events -from Beats. \ No newline at end of file +from Beats. + diff --git a/packetbeat/docs/gettingstarted.asciidoc b/packetbeat/docs/gettingstarted.asciidoc index 6fddc6a33426..38d075ecbb29 100644 --- a/packetbeat/docs/gettingstarted.asciidoc +++ b/packetbeat/docs/gettingstarted.asciidoc @@ -186,6 +186,9 @@ output: + If you are sending output to Logstash, see <> instead. +TIP: To test your configuration file, run Packetbeat in the foreground with the following options specified: ++sudo ./packetbeat -configtest -e+. + [[packetbeat-template]] === Step 3: Loading the Index Template in Elasticsearch diff --git a/topbeat/docs/gettingstarted.asciidoc b/topbeat/docs/gettingstarted.asciidoc index 2ca46e5d44d0..133c0f801057 100644 --- a/topbeat/docs/gettingstarted.asciidoc +++ b/topbeat/docs/gettingstarted.asciidoc @@ -131,6 +131,9 @@ output: + If you are sending output to Logstash, see <> instead. +TIP: To test your configuration file, run Topbeat in the foreground with the following options specified: ++./topbeat -configtest -e+. + [[topbeat-template]] === Step 3: Loading the Index Template in Elasticsearch From d739215fdc189c41b7c64a366559a873920ef025 Mon Sep 17 00:00:00 2001 From: Steffen Siering Date: Wed, 15 Jun 2016 07:50:41 +0200 Subject: [PATCH 14/42] Memcache gap handler: add missing nil-check (#1853) --- CHANGELOG.asciidoc | 1 + packetbeat/protos/memcache/plugin_tcp.go | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index e99c18cf927b..1fe63af6f60d 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -32,6 +32,7 @@ https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] - Seed random number generator using crypto.rand package. {pull}1503{1503] *Packetbeat* +- Add missing nil-check to memcached GapInStream handler. {issue}1162[1162] *Topbeat* diff --git a/packetbeat/protos/memcache/plugin_tcp.go b/packetbeat/protos/memcache/plugin_tcp.go index 51f497fd6d74..de451efc1dbf 100644 --- a/packetbeat/protos/memcache/plugin_tcp.go +++ b/packetbeat/protos/memcache/plugin_tcp.go @@ -332,6 +332,11 @@ func (mc *Memcache) GapInStream( conn := private.(*tcpConnectionData) stream := conn.Streams[dir] + if stream == nil { + debug("Inactive stream. Dropping connection state.") + return private, true + } + parser := stream.parser msg := parser.message From 3b94426ad5e249b83314bf4537e84ba5d52aaa3f Mon Sep 17 00:00:00 2001 From: Tudor Golubenco Date: Wed, 15 Jun 2016 15:39:58 +0200 Subject: [PATCH 15/42] Prepare the 1.3.0 release (#1864) * Close the changelog * Bump versions in code * Bump versions in docs --- CHANGELOG.asciidoc | 22 +++++++++++++++++----- filebeat/docs/index.asciidoc | 4 ++-- filebeat/main.go | 2 +- libbeat/docs/index.asciidoc | 16 ++++++++-------- libbeat/docs/release.asciidoc | 1 + packetbeat/docs/index.asciidoc | 4 ++-- packetbeat/main.go | 2 +- topbeat/docs/index.asciidoc | 4 ++-- topbeat/main.go | 2 +- winlogbeat/docs/index.asciidoc | 4 ++-- winlogbeat/main.go | 2 +- 11 files changed, 38 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 1fe63af6f60d..c23e88c509c5 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -26,13 +26,8 @@ https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] ==== Bugfixes *Affecting all Beats* -- Fix beats load balancer deadlock if max_retries: -1 or publish_async is enabled in filebeat. {issue}1829[1829] -- Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] -- Set logstash output default bulk_max_size to 2048. {issue}1662[1662] -- Seed random number generator using crypto.rand package. {pull}1503{1503] *Packetbeat* -- Add missing nil-check to memcached GapInStream handler. {issue}1162[1162] *Topbeat* @@ -66,6 +61,23 @@ https://github.com/elastic/beats/compare/v1.2.3...1.3[Check the HEAD diff] //////////////////////////////////////////////////////////// +[[release-notes-1.3.0]] +=== Beats version 1.3.0 +https://github.com/elastic/beats/compare/v1.2.3...v1.3.0[View commits] + +==== Bugfixes + +*Affecting all Beats* + +- Fix beats load balancer deadlock if `max_retries: -1` or `publish_async` is enabled in filebeat. {issue}1829[1829] +- Fix output modes backoff counter reset. {issue}1803[1803] {pull}1814[1814] {pull}1818[1818] +- Set logstash output default bulk_max_size to 2048. {issue}1662[1662] +- Seed random number generator using crypto.rand package. {pull}1503[1503] + +*Packetbeat* + +- Add missing nil-check to memcached GapInStream handler. {issue}1162[1162] + [[release-notes-1.2.3]] === Beats version 1.2.3 https://github.com/elastic/beats/compare/v1.2.2...v1.2.3[View commits] diff --git a/filebeat/docs/index.asciidoc b/filebeat/docs/index.asciidoc index 2ff7656082e8..868432d690c5 100644 --- a/filebeat/docs/index.asciidoc +++ b/filebeat/docs/index.asciidoc @@ -1,6 +1,6 @@ = Filebeat Reference -:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.2 -:version: 1.2.3 +:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.3 +:version: 1.3.0 :beatname_lc: filebeat :beatname_uc: Filebeat diff --git a/filebeat/main.go b/filebeat/main.go index 781e083f6989..0a46af9fcdd6 100644 --- a/filebeat/main.go +++ b/filebeat/main.go @@ -5,7 +5,7 @@ import ( "github.com/elastic/beats/libbeat/beat" ) -var Version = "1.2.3" +var Version = "1.3.0" var Name = "filebeat" // The basic model of execution: diff --git a/libbeat/docs/index.asciidoc b/libbeat/docs/index.asciidoc index 84227c9b6bc1..e8ee09754426 100644 --- a/libbeat/docs/index.asciidoc +++ b/libbeat/docs/index.asciidoc @@ -1,13 +1,13 @@ [[beats-reference]] = Beats Platform Reference -:packetbeat: http://www.elastic.co/guide/en/beats/packetbeat/1.2 -:topbeat: http://www.elastic.co/guide/en/beats/topbeat/1.2 -:filebeat: http://www.elastic.co/guide/en/beats/filebeat/1.2 -:winlogbeat: http://www.elastic.co/guide/en/beats/winlogbeat/1.2 -:ES-version: 2.3.3 -:LS-version: 2.3.2 -:Kibana-version: 4.5.1 -:Dashboards-version: 1.2.3 +:packetbeat: http://www.elastic.co/guide/en/beats/packetbeat/1.3 +:topbeat: http://www.elastic.co/guide/en/beats/topbeat/1.3 +:filebeat: http://www.elastic.co/guide/en/beats/filebeat/1.3 +:winlogbeat: http://www.elastic.co/guide/en/beats/winlogbeat/1.3 +:ES-version: 2.4.0 +:LS-version: 2.4.0 +:Kibana-version: 4.6.0 +:Dashboards-version: 1.3.0 include::./overview.asciidoc[] diff --git a/libbeat/docs/release.asciidoc b/libbeat/docs/release.asciidoc index bdd8dc2f99aa..266007a1e0cb 100644 --- a/libbeat/docs/release.asciidoc +++ b/libbeat/docs/release.asciidoc @@ -6,6 +6,7 @@ -- This section summarizes the changes in each release. +* <> * <> * <> * <> diff --git a/packetbeat/docs/index.asciidoc b/packetbeat/docs/index.asciidoc index b38e73736bcc..39e1f9f0e937 100644 --- a/packetbeat/docs/index.asciidoc +++ b/packetbeat/docs/index.asciidoc @@ -1,6 +1,6 @@ = Packetbeat Reference -:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.2 -:version: 1.2.3 +:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.3 +:version: 1.3.0 :beatname_lc: packetbeat :beatname_uc: Packetbeat diff --git a/packetbeat/main.go b/packetbeat/main.go index a56a62eef720..10beb427fe98 100644 --- a/packetbeat/main.go +++ b/packetbeat/main.go @@ -7,7 +7,7 @@ import ( ) // You can overwrite these, e.g.: go build -ldflags "-X main.Version 1.0.0-beta3" -var Version = "1.2.3" +var Version = "1.3.0" var Name = "packetbeat" // Setups and Runs Packetbeat diff --git a/topbeat/docs/index.asciidoc b/topbeat/docs/index.asciidoc index 620f1f4fc99f..2704c705e99a 100644 --- a/topbeat/docs/index.asciidoc +++ b/topbeat/docs/index.asciidoc @@ -1,6 +1,6 @@ = Topbeat Reference -:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.2 -:version: 1.2.3 +:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.3 +:version: 1.3.0 :beatname_lc: topbeat :beatname_uc: Topbeat diff --git a/topbeat/main.go b/topbeat/main.go index fbdc03b8a3fa..15c79cd73799 100644 --- a/topbeat/main.go +++ b/topbeat/main.go @@ -7,7 +7,7 @@ import ( ) // You can overwrite these, e.g.: go build -ldflags "-X main.Version 1.0.0-beta3" -var Version = "1.2.3" +var Version = "1.3.0" var Name = "topbeat" func main() { diff --git a/winlogbeat/docs/index.asciidoc b/winlogbeat/docs/index.asciidoc index 90d6c55adc02..e54bb42295aa 100644 --- a/winlogbeat/docs/index.asciidoc +++ b/winlogbeat/docs/index.asciidoc @@ -1,6 +1,6 @@ = Winlogbeat Reference -:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.2 -:version: 1.2.3 +:libbeat: http://www.elastic.co/guide/en/beats/libbeat/1.3 +:version: 1.3.0 :beatname_lc: winlogbeat :beatname_uc: Winlogbeat diff --git a/winlogbeat/main.go b/winlogbeat/main.go index 2f8c09910273..7fad8f3c9f13 100644 --- a/winlogbeat/main.go +++ b/winlogbeat/main.go @@ -6,7 +6,7 @@ import ( ) // Version of Winlogbeat. -var Version = "1.2.3" +var Version = "1.3.0" // Name of this beat. var Name = "winlogbeat" From 296ebc6f5f7dc086facdd8569f930f0fb17d451d Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Thu, 16 Jun 2016 19:06:49 +0200 Subject: [PATCH 16/42] Add build docs script (#1878) Backport #1873 --- Makefile | 5 +++++ libbeat/scripts/build_docs.sh | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 libbeat/scripts/build_docs.sh diff --git a/Makefile b/Makefile index 22e6665428b4..227c922e28d8 100644 --- a/Makefile +++ b/Makefile @@ -34,3 +34,8 @@ fmt: simplify: $(foreach var,$(PROJECTS),make -C $(var) simplify || exit 1;) + +# Builds the documents for each beat +.PHONY: docs +docs: + sh libbeat/scripts/build_docs.sh ${PROJECTS} diff --git a/libbeat/scripts/build_docs.sh b/libbeat/scripts/build_docs.sh new file mode 100644 index 000000000000..8c86544cc4ca --- /dev/null +++ b/libbeat/scripts/build_docs.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# Checks if docs clone already exists +if [ ! -d "build/docs" ]; then + # Only head is cloned + git clone --depth=1 https://github.com/elastic/docs.git build/docs +else + echo "build/docs already exists. Not cloning." +fi + +# beatnames must be passed as parameters. Example: packetbeat filebeat +for name in $* +do + index="$GOPATH/src/github.com/elastic/beats/${name}/docs/index.asciidoc" + echo $index + if [ -f "$index" ]; then + echo "Building docs for ${name}..." + dest_dir="build/html_docs/${name}" + mkdir -p "$dest_dir" + ./build/docs/build_docs.pl --doc "$index" -out "$dest_dir" + fi +done From 7be94c3095589b13dab31ffeceb5829337c5a8a1 Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Sun, 19 Jun 2016 23:26:46 -0700 Subject: [PATCH 17/42] Cherry pick multiline doc (#1880) --- filebeat/docs/images/go-playground.png | Bin 0 -> 169937 bytes filebeat/docs/index.asciidoc | 3 + filebeat/docs/multiline.asciidoc | 138 ++++++++++++++++++ .../configuration/filebeat-options.asciidoc | 41 ++---- libbeat/docs/regexp.asciidoc | 4 + libbeat/docs/yaml.asciidoc | 1 + topbeat/docs/index.asciidoc | 1 + 7 files changed, 158 insertions(+), 30 deletions(-) create mode 100644 filebeat/docs/images/go-playground.png create mode 100644 filebeat/docs/multiline.asciidoc diff --git a/filebeat/docs/images/go-playground.png b/filebeat/docs/images/go-playground.png new file mode 100644 index 0000000000000000000000000000000000000000..7a7063d011bd3a92013776fb12f1136acb8b5102 GIT binary patch literal 169937 zcmd43WpG^0&Ms;@=ETe#+cCt<42clhldMY1WIIZl5dc|z)(Iz2>HN*{*fgC-$#`!iv08a-!BCDlyno* z(EJGEnwcCLg2N4iei`&b-5+=+mVG~bq1I3D=YM^r*7x;#Ke*3$dvCdi`~CjD`waSw zB;zJK|0ei-JLBywt^>)IhT}pe z!+`7cZSp+hDrEx3A9Y`pFxIvLAL057ILv$Yr8eV0hw#AS%r~X0SVlEPMgP&!9|i^n zpSij5nwpv@X=q}Dm8dXyczHKZPZ6}WwH3=XaOmjhBxdzQg&VGbazDNeBE!VXY8>U7 zMC9FB#9<+zABXJfEk*NYx0abs5=x#fQqeDw&S8!8)sndjxdNuMdE=LAl(cF^OX=f7 zOeODrUDf9cyVKMem$aHhsA|(-O~;?0>{?2N+^L#PD7#J)R<*0r<tAI zmtAG^>Umaa`~Xyo#x}6hF6kHX0(OPnd!O{066*~jD6P%aYX{`r>xV<`e%Y|?_f94`$AbkF0xx)aGIOu5uWetS99LRh(Ugi6zt@?~$`(iyxVXA@ zjg3ha%gf68q^9EM78H;&GNSBHWQg7#&7z>ALpnP<3)acM+?_5@DUtDCbt0%-xu}~i zuS{x)x@ww3%$FRe&CD zn&r*(<@&N~Ac%?FMIA?UFFd{AKc7s)yOabR)r$r!z? zYC_|AZYQD6%iMxeJiqjm+WeL5b}YHNy1t_H7BD>!Z7{slUOlHRzh3&4+WdJ~y@S=0 z=KpfwMD$x@BgfE>v~7(NWm--@&W7NcQRdjjE%a*~13vSU?QK7!vE)O1qdX0H`ED%s zQ18YMo>x2K28M=N-~FI3E-oU?f=<iOT&#tQd&zD=;q2(40i*@B^n%M?} z3f1-K*0zzpyQ24g?+y~8s18-SE41A|gUMXo6GBdx%`)IP(-JuR$?#hbD4@Y|!2iwQ4vY7<3e6UBV)iCQzl004Qb@A#c{)*H;Vj*rz(PPn z`Inp@Mby>t;Tl-)7kT)W%k{z*7Bu6joPOa1+}-Qz>++6N6#sNL|8z0C65ni7L&~CL zQw{pMl)^m%6S>EvQrP0+jckBwQEg}=uA1e3^w%3)_vh>MWdZGInu@^x^iZ*^;Az{X z9D}XjCyDnE&jLPTTYG zn@khr^_-*$=xg9(sbi}5(;-DEpg~%`Pdk`NrxQ%BY>36$ufcJ57=y)ZW-vFjXw=^y za%gjJdHb@np>g~6F^b<%!uP*q68|lTdHf~J=OvF!S6A10hsAz7o?hF^QS&VEy8gk< zY^^@8b6vjCZdbz881c<#vr@MwSH{2~H@3lSmg-O{F#d*eSGZwT)&7e5$3s)hjhek3 z+)TqR`)4X9hcEvw!$y9%1EbW(W+TFfPqY!&q~6;^-lUnV^z56C2*$~-$-pZ8fhCsX zk>#!Bsms^2*OwOqGV*rU$3O(U-woEr>bq}jl?vujJJ*US4@;pd6~pt(JjU(oEloZN-l6{M z!IjAa7t67onw0dlO=LNl3^zY@?{a$}$NT+_?H1V3r@fjM9j#YSn6TLD%KUVDYzz{R zsM~gbShJf_iED=5_7TJhVa1tw?2xwH{B zHTAiq$H|PEkn$`Jamlq2T-L*X*+l8*O#9R({jXjRq4wf6?ZIC5(lvGFDHy!NQ4LAS zW^1lH=E;xhCVY5SUoRF9mg>wUD`4owowg6HbGN=CwT2w=5l`)_Veada+80X_tbjSA zNmv=D^|kwX3mjSwPli2g8#KcWO&J=duKBSj0UY3!#e;imIZw++t;RHyEsQ7fsv~^? zwd(yVhglwfhXI-Ra0mFt3YJ&wP;RcSNmNt2Np{Juo6hT=z$`%^=JRMWtE9@jhJQm+ ze7sRPw(&%|@axlUNE{L_3+x9NM4EW*3N7BlUD`hQPfYSweUe4RTC5IDzH43bJe>Q< zbm!ruP+u2X9$`k)xD!12y7J#qqp%wAh~6)V6x4j;&b@;z@j7~tC^R!9HxZaV^wq)p)dB(7`X8#HNdOX+3C22 zpSAv4YUA!!IP&2;O|B%;_N;?mp7$=RJM}DmV8$JWw|^~P5^ikV$I^7S=YPb6*}9TV zti;L~eZ-W5o<78Cpzq0cG!B#1Tz{qwWO0s;KmC+?i=u_k0)0%sC&@H4;MKK5XqTjL zU!`g*>ouq#_qplGHKFPz09@X)J=A35hR8MvFTwlgp&JTbgEugpMw`n0nVmAHAlC`w zb&8Q1K0_L}aCRMHy8Y?nlu$$NyWg>~l;51=!xqfv+0~`K*1`qyL(H-H&F!AgPOE1)`NLAXY241^iuH1Y)-l|t zdl2h{6Ei;=8x;kMCgy)!tC`tv#!2-!2)}k925yRebupZ_Av1f9l3C>H(>oWY=NX>! zxHt2_8(=H#k*W|mSZdDCr7yL2pRt@lr7bSWELwx`g zT7q)4`JiYY+;f)0UVFuUaoz=~hyXV=OW)j#*oDLwG$T4+{W0`15RV=ik!m@ssD=6=b|>Y8F8#L)vdnZc7vadSSm7}{od1ZOjp${ zps~~l=J!N5aKIn2xlj+a!165j;z0#06JcC0ALsZQ{YwUhwf|c3^>V~FXQ4$87L$LP zpr?KN+0Op;`gcu_j=_XRs2cCerQCeI%dHFE2@g(y<|{m-^&{a+jLnEDS>E5lxUYM- z&l!2^7EQ=Nw42AVa-SXM!<_3LL`Dz`*7(}Xyhaq=`^lKM!zFh}xB#&xtfGF^#rb=;-MbY{|1jHS_59^?chE)x z^67iSM-|MOZi-`>&8&2dpFodBHb8h9#Z!(kGrs|uVa|tM);AK3YAgrGbk0O;o@@m52Jr zz0eAg4u#I<2btf@i5RS}_$BpTA&Y_VU#0)fk5*zJ9l~p-xX(E3DPo8oN9i*h_nxU! z-~|IeMa?0;KkjGb2TSb*0D&o^?4vuDZf?UN@Sm>ZIMy?g=yx}`jaAVaX)5gJf1&{t zGEKu7@+9e~Oxco_6=Vkqo*>XMDnC#sVA2=f)|8pW6UnD=``cX<;vib%_bbgKVz1Jo zbiC9NYM%lo;M*pTqEHIavc;$dTuwOU{jJdOOql&^4FIqLFX*mwS~1Wz(R1Gqt~ID0 zb13grT3a~fGKw_&(B`t3ZEUEsYX}41qx46`i3;tf$TnXbbVNjlOyj4#ZZBa&#O~2^ ztF@x1X{gJCfJWfv_6YP2E0c|`w5_~jL`asAc@NIsr`eZ3Fp;jVe`BH#esV3&b*h_s zkyRZmLi%2l{G@b%(9Ab{#i#Fi1YQ0fMaa~#66+$)Ce+Zn_JQ`f4yaI^)%L?5;$Kc{ z;xDK5gZVrQ^&S-8-hF4gM<#TxEclT`@}1EkJuNNm^5uFW$6Up=UOG4b0P8xA<&Qio z7_dl4NNnC-TuTUy=|+xMPBZ;1hmlW5D-;br59Z7(B!;Mo9%JYCk)|}Qeka7S`AGCD zNs~y>%8f_*wGMoltwQ9rpPpF2_P5&V39~y&foaI*5)h)V_GTwzS}M0X1%}nrpl539 z0e2hhf~;4fvGo{m!l!@{A(iI)3yh6!{Ka2}&4lbFIVa>D6MwA+X^kTIx7SZbbJN{h z5jN7-t`CvPVi8?N`7S)qVusfdpHKbDBPU$Q$1U`ravtLRQBg0PRM}5nbzo4v&wRfj zv3i|s1{qE%1u6$>gTZFyIzh?BhYHJMa+@%&^GwV!>2nBpvP2i6rF89m-yNZ!nbu*Z1o&;QBl_nS&;3bJO9kEOhc=f>y_eg0 zZ7$7VX-R2j>yQT1akc&3uCA^|w_CHSH1=YZif~-k8>D+%we~Vi4ULu6G~2zv#E%y5 zCVbl-*Jj0MzOCKnSdo!*V*>(xMvfI0k5Hlu)&46tB@5NbV`t{Lo%Gj49?!EL7Tlf$ zbbP+BaBz_~7e?@C;TtLR?3KU|A8k%1C?WY*l$})7xcg1%#stCV%GUx?nxMowYLPlB z^GM^=1I>>IQH582G=M!Q+leT5+rCtj#~Y%P2qxn@3my}WMY=e!>#@>KGWxF;{ayrP zIp9k!8%hjjSH>5Sm;V$meHs{3t={yBUVq&A{qt8^IG}P{cu|3mDH7|9M5Uk?(|EOD zkNRw)c1p-JH|EB>Q;p%aE2sJdfZhz7x=3@UuM!BJ(eDf+zd^7DL%#t@=yt^{M3%St zRCJ5Ye_`)GaT=&I^gL(oSg{;11cB66`3Wl~+Qws++C}d}jTF5A(u&@=y(Ca~gZ|ql62lc4S?jnaLcU5%Cn*OiLR-Y<1V#pl<;*7@Resbn(Zvrw z+UT2oYO9M(5Jq**eDySdU$pWtKN&8Pz89)#hJlY+>r5}@apaz=_6p`qMvk#zt^Me% z>%}&pAnG}*9mbxP(3+Bub(^82Rf;h(GtbPLX7sq-)cPu^RPeF?zHDTxY2(8V+cTo& zEYzE*_dqq$;}06y5=_9d?J2)UP1RQ|B6+NK6ieiv3WMh>xTTP;P}K;Wqg9Au9++4S z#@TB87|R=u#Ko1TW8O!J(M++CUnIxDvZ z=jW(z;qCd6+A$eP1$Va2r}z1am*g4}#!(*@oUE2q1F4d*=Pk=M3#Y5h51GEOr~kYp zP~Uh>q!lY)CkiW(+6~Jd>djl=EJ1Uhy7KR0Le)YIjM#dIcybbaHIrcm^y|noZ+xQ9 z{%0}=O3YTKAyW~F_-I!3+3Hw+a(8%Og%a|*iCH7n3jLfQ_rC1I;@VFdxn>8yQqczB zU0q*Sx!+q25j#23PF5tuM_pj0`v(U8tVmNfDte@`cW|g>p&lc!;Ir3~-)J#Yb^BIn zdn^55(pf=P)Rn|+{5w}X2G!7l+JOGEt2dt&{~H(d%w%PnNbpAgoY%3YP<|L~_&6;? z)C3;YpnzLD_lrlZR!gE0$;&RywThe0Ug?_6*Fi)339AbSW;0*&sX!7VL2!)~o-Sed zhjEG}4tYfVGh+aw&5}j!PI}Gv!H!0Z5Vn?$Bva2FwUcAO2KozZyRQ3!6zqIDo+Dwk z-69=bI^P9@^AZ_O=K!#xK(?kqvbfIHum4lFa-I3-i5%CHu-E`9nTJH?pJR&jk0#W~ z{EswTkoM9=s{Mo#FSfsJPYjWeV%oIim z!{-~NTYAF5TZf!aS`3-)_1gelb_S!Sl zWO)^J0|{oYDg3;IHbd#fLRJQ90K5S#yK4x@r_kme+^TuJgg88J9YNXXO znDDf}c^qvrWHMFLhp2^wkakQ$s_WRf!WOz`}_Xexg(qzZIUoNkX$8%kMeNcWd zNbys1ncFpE9-0pKXRC5W@?_@4ij+9d6C7B?n=4RvGg^X>&j;~2%XJgNYL~x)okfIP zA}@c`&z7NAVco~_gMfkdcgBn;_ASYFj&r=d-Ga6#DKb5sj`w1|+0mRC z^=@cS4i0gtUVqT6mx&wHRLmHXQm%HOwwOb4AblVe<2O5d)4iJv zTzSm#9`n+kR=u90?|;E2nW=E-_NlJVE56D9nBdu_$sb3QGE&+(u$liA@YtXSve1lDhNh?cyRdx6-Px`Oz76HuB1V} zecmWiC|HQsQ`0VeuQx1dRn`8n49F;4mtUH@vy5wSevZFcRJStswuoym zh-kZ2Gn1idsPhEu_TBZ?w%rCj(dJoNt}DB`H&}~jlba9((nMTP2h#Vq<`4JBx|A%PMS5|?C0SW0SU z6}7j2L|?cb4MN=|P31Z$t&7^G=CGF0rn9|3@ck`_(bw$OygLbiHc0d#Pavp%4z#t~ zkgND5YD>>5UPjs@&{3*_gfT-u4EXZaZzZGedrY=CPYZPVrIT^JctNlq%i0Zf8$nvxp; zr~LaaKcOgJLH$B`s`IYce#UsmrfQ`j4QF=gl*+EyHV8l7RJG}4vB?x*NNvsnGw)JF>l4BYat*k+M z8mze&-s%aOOe2bYblaAZ(s67EK-JIy(%C*bd(pLa`2mLVLA<@oM(o(;y&c*(knt|0 z>m@XiT5A{SW2@{ST)Sv|lF+ojiXT2Lld+Jg8d-^IsF-04rM?Pu<)MSlE9Z2T+`XHl zs4rMBJR4kAIl}J8aP8qC#PXA$Pi@V!b3aB~RybjD-Z`aq{Inh1`u}!Y3LvIu=<_9)wM>tfmkH%E@*GT0=`B4c z`9OT#h8#}St1La;)r-y;f7MifmIP?mf~-~ORj;}BG_JnA?G)u!O(J3L4P+pvH4S`n z9f@?7?s;X_*6u={@l$zq9iSziPySC!%ooZD4o`88OL56C<-c;Bzn&z& zAO~$RgJhHc&Vc@+CVu`FUIRxNEBv4A2tn*{gb4jNlRuC@4=h5W50m^IxBLaekbv8z z3X{Z=|0k6k_FxU)Bs;YFucue%1Ykmcd5yX;uAn|^ZWXO;XEV56(`@_F3qg{ld-6$1 z&-g6!x4N`*W^%FW_YE&>ZlEuCA?}wSau}7nbuvLYZ~`1<#Y#TT zev1c5q3Zxer*SX-tm)oO(`hTx)@V)6{m2^W2tGw#+Ow{a;-R@|#N24*TEzCm6gD-j zbFmEMuWyHNzj61cn7<(0bAq??^i28{@g)x1-+0B(dD;JX7(H0xr{fxBN}IBywDfFG z4Z7Z18HKVh9UEGwe!MsDIFGv)eQmr4otVdYhW?Q*4w_9Y>lm3X!z_$~E7@Tq(eMw( zCL&{zQ^)c+9A$;4A60B*&K0|>6|e2{P%0}*DRNJX|C(n57RH6V=MvFloN1=%VfY=7LTGhgx=`Bj3o zwG~?RLIyRE<)%72zfEYW@*Q}8(L17zu7Z6Dxt9Eh+J9&H2@ec?UY}(DD1ZKP!#@qy znugb2?MF9#EiWMsJ5I#CMYeg%XCn+~ClA!4Nq(KzpPLtS${|dpnr7lx=C;HDyIcd*ux(>Z61AgVsTGpMaBr?67@~9bWrf|8Q4kV?a)YF;7Y}QzpciD=vP_cB75>25oJOx$d(q&42v4=zukOL=Cjh^_%Zn_43i(5J3krSCG+0=C9 zx~j3#8t-$W!3MQ4Yy@=#c{m(K8X(qWn>K{eJzK*BVFszrOP$(i4Yy}I5F3CJ60Y+$ z*l+jKyTvWrXq(SvcYxBxA*_?)#QTbD{Vkw~R}>3C7-hRnQeH5ufI+C#jjY_$4~1Tb zmu>6U-0z0xPg=b#-gs|8J{EY+<<^wAUCOQ;zWasZGpD3EP{vWQ!Yqd%TOi%&xLqOo z@uVK!OXT7;y3h_}?t#q`8PLUNQzN^%{XWr}QnCvE(G$dW~A zA`3G;0(;E$LX%?v)^SKfu;y>hZ?gMXBr=`=>!K3)wX<}Sg=S9WQAdGP=HNtG1Fxo*V5kFbO{GyO{Sk~*KR<={!10fEH1qeM4CxU|)u99B z8Puj%xe?tLG4kp6P>XvRidu8m$bdLBmz11J$8#<}#@`aS)VCC#A$S5v`VHQpm66F7 zKW1Z|P;q7mL)sVpDZiJKkWaic6Y!E-PkN`TM;sobk}0g3LuX3~vn>6TqL{NB@Y|l> z2G5zWcG+km#jvTzv5}yT#D8toXfG^B;KlQ!WI`c((KAn8Do6b|~+JT!;Kz!_xh z>3B@WKJG1wdBy|Qrog`G?6rPZP%tT?0JV=fcpPe-rWru4nKASAl=Z}Rr}Po$T@MKm zvjQ=x{RVvOk#OO)xnn(9r%=hbyRvyWWWk6~Jbodkqi8eLh{OtTKCbPbUs}1-FCam! zde|GFZLD;{d@AQ1BXoJel`2cRnJr&nu<|L`LTM8jAEVTw+%MF>kQ)(oaJs?e2KN=m zsG^8)hx-H^+B{)eFQ&IuSa0-XB9E8_<9Y;R-#b``%PEC8zG&;-YQUr@PmtI*sU zj4#)8y=FGgYKrh`d@7!Lc8^T5T9T<52`y~7r0eDFjsLo9J-QM{A--CU`V+&N9k@KC zk6pzAUdP2g&=8^0AHQyu>H01LTd~)V|7*F?>4yK4ri)rhlLsPIqpHP0R+i=Ekq`3e z>CLiOGcK@#k26@R$futadwt9ryZ~*oQMQZ@n*FjXXqVfzNYmZHuFY4BTf%cI-+sob}@i?TY^h_y)_cM6ZxA+?daQ=Je2^`wUa!;%6j<%O8b$)81wqqJZ z1caUs?O-igJPB??Y7t*`@_3rVFYwt?`QF$h(e?7E)TVq zK7&-QC*hrlhvA)rmqk(@($$2Dt(Q6uNc1D)nrf@`&Zoy5N5sp_@!POs${>Io zppNOo#p)%|@3wfJ80P0Cr%-FoSWPjHFa;HUf!F3U6E>Gm4DVp>ugl9ExX%zzH9Ukf z>_{68p4I(PuK-4wZR|bsw7n;pcb|-XL{X)={n(lgU9R+K6ZT6wNmhKSrK=he<-JreP zUNT$o@<3j+5ni0F;Y&FvbLBWm5ka~=>Ii7YC&h$VV9B_s zeC$fG28ziarFs-zx!gqHiYY=qQG zB@SG;yA63$+c=AUzV0t;BAiPyG|bh#`}hnZHokpyju7g6ZR4b&LsU$P5O0 z+Zfg!tYLP{DrU8G$)k{e`_n%JL-zTJ*>EllJOtA;&1lV^g6rnsgUx{Jd&jSlbRP-Z zV+I*Fw?b-VZ&m`7;dj0AF6_G@T>SScoMk-=vTz}K0Z8}E0mVkgLxwqVs1L|$DN>Bs z{s1g5fdaw`oSlQ5inG@6uVd4f&+O*8ql84B1@_6VBD?w9mF7d>H;Ff-i0>!?7JD4j zdxv$fRR>6nwYxxpd_J{^(*wrVphK@lsQPYnwvm%Hx72adJ=Rt88R(QR@u@2_G<+Wp z5gVS`E>TBzj_c;%Ji|H1$C@b1&)$^QigGr29CXJWw%Tdcfp%Z`JQbXhn>4;{XQ@7n zIMljZ5X)eGbktrA?2BnOyRKO1J&?AhL((yyHY`YDKaL>W7OCnx7`2@Xj|05Z%%|^1 zEi^`Qj;VL_G<1Qrc36=+eRAzk<)=~?X(J@4tR({&mfIO2&8!6u58#Cf>@HS(bRXY@ zWo|U}UCWwWoRDcLip==sthGupwo;FO0T$1r{K1#?@j-%(Oq1L-40zv_wV8cnL6dgJ z9lr|Sg+63D-q#=Dys?VbYCW3eUcvqppxhTSZKm6Ux>&RsJ{PbGWUyC)C|}Vt_W%xZ zS>yAD`hMKD;VvX}@>?-;$`rP;A$mG47GXhU+7wMn*P4%cTm!cE!=b^r{ddkg*c)Acc5u*&8nfWWi_2xEtZj@_sds1Mr(WPHm@L4Bu=cX5v+~BVh zOuI7x<OBOHS5WgVwg$&b*K`Cfm@4aC%YT+%yb|;Gw5G|8effY z-?%YD0?e&pPcgS9$haBpwaXm}^iLBAkca8UyVY1F^#=~5qqxvIydII_)2KR6p=qmP zxW_o>FULPVR|Sn}U2_X{crIXOA&@fg9*|%vcd~*|b@acI{cla2dzWgTuN=${x2+<8C{q_c<3jDpv`K(=;$WfafKe)hu}(Po7TscRjT6f&I+3 z3}5{tb+t9`X4_nviTVKUg0in;2?hllwL6XMecMRvQ-_KqbtDh(68sY50E;z9mKwci zN)1y_k3)|q8;8`O>>9-k_-otmqqW&P2hy>?h;0?h<1OIWr`!)vC^E-IR$Vt zCSk5}7q=y9G~Qg%@Y>wlJi+vnOFg^f2jlE;ait?^_tu3_&${rQg(g)KyL>0bd(5YN z3j;-M?dg2gmc6>LomDdyc3f&x_T4u1BPkF3uz+jXJSlJT=k}p??5}MjaOWG}YGK(d zdv7HzFh~1soR)1tHJsV-Gs$mU_NfR74oih+;k~n?azo?H4tHsbsPKEzt|rK9Z0NIz zb1&D%b)f1q36iy^6Cy8PsKLakghJqyrM-bh->5a3zaiS=!kd1oL4razLh6KRxKsK3 zWfn`$u+?}$4Ukr?2ndug+rJp^ak(tUYB{0mCQUQXQm&KuWnt~XSavx-zEkqa=q3;I z0WB*l%f|NWn#k^OoE-f_qh;8ov;=VmrOEft&r4uP0mETqAZ}qxVmGVucieq453t8BJ@G0b@#g_K(4TQs;L-g34tcM?SoCRvcP zW*4pqoG6GXYXff%pFb}z8ZI%W8l7Ig-vpP7h)dVZcvwMORla)(ECvYc*9(~eG4w?l zpQp+N9}Xg0+x5QyM0y4LcT>bZe(WUWqZ^!P4wz=2wfNMSBMe|$t(J4m7o7Yi3c}j( z!~W54YSv$lFQ3fWq$_!tEoFtV3`eNe zPS^mJYit<8Y3B|DL7@8p}M8jo` zTNc;DsudxY@%lDVVdPkAh~>evqalfsY80Q85h_?DU)7b66;nQDq+?Z8*k1upE@j~- z(*C5T?$UnASx(*0tHfk zSBixn^erm=Ir5R}vJ_jSAd;G}%lS6tjUJ%pF;G#kpj^w@LpMjGW%&5cK61=ydo$~} zhWB!^s)WPghCE;TF>LIiIWt&M@0=b>2(qfftpLKKarX) zPz5HvZ=uajS1aChFSSrfUvyc-D9{7ZMSd}DutEIeOGS`!=SF8B1QbXI&cGp{wI)|j z!;F2luEKkRy^X7YD>wXND@-bVUbbhoJ`T$f*RqVYpJ{mn8eU| zykHnzG%oF{bHfTf{WPlg=uH$Vq7YGbHR_NdZUPW=8ja3gkcYu!x^4mx`?un+pjY3B zKk^%XwGOTK&7V4TueK$PMjZ~~4LUxu_@omCXU5Mto5SmAy>>WRm}hDKxpdfmd;zj%I-!-|fY$*rsP7p6aGtm3IxG8XSzo^hen1MtAd z<#t$ANN{02htpepx_NteHFZdv#LsH?I#^2c_EA|l-%n~2Wq1Qzcd$THSp;9@aZ4^} zenh%;48`lvzPB;K2Z(lXI1xot-w)hizO-k*S@*7BZ;t>iaJU1JdYhYuyeo!8Wpuha z8afGuBmGi70+7nO4!wilXP0K=P(k2xrU0_+n{oSb|I9CwqB`P_e8i56>AyFjGpH6` z7tLKx0|GbO~;~Crs&$>4*aBC`L~KQ31E-d{(U|zOT{4%yB7|mhY_J8EwRq zP%1RF7j!xj3sZHixVf0Oo-FPHMauX&4)?EJ%%^l}%~oJp%^$kzC^0)eO4n#i5Ur-C z(g>^2d!e0sUFV<^u@^U3^#ht1IIsGRezk?HHU3a%FKg)faUzZLcrgE6BAFRc_nM8_ zav{?5p{MQ_?pJM(K*RNX32~2?RyYjJ*^|~6gZmJJ4*9N2OQS<+O?fFY&1Up zJFxoKdLwa5Te~i6uH%ygUc_zLSI%)Y(>n*Ml}&0*ZLI2!>m1cuQo@dbJ<@EtjvXCp z#Q+%QS&^FCU_*>&leJ6gA*)xYM3UWMQXI9$EXOMed)=IaAI9z*NGUIP{o~6KyWDid zTv1~}l|c3s2Wz0p@i3Nba4B!NG@N*2_q&Zo$#xUpR1mxDakrCF)cag%%B5qC=?ONA zKlUjqbsP}a8^1Z6^?64ohOdm_txEYoef7w1}Jt@8)3Xgk|Fk|(Gf@UvR!F*1o zJnkm4zcEZ7JBbD3Oh|Ii9c+0^!8!kdAybkz?c1vKYwaZx2^5;zda1y@VJ3r*J`DMneWLSjE>Q$Vpar`X_zbTIs@wt1MTAl_EZ{gbX6-lDD5Obe9Aydl4* zdaTxMPt}3#Zg@iGv6e(L%;x3ZQ^t#ypWto_)}h)j+S!1x(irVXvE!r;>|jCdhJmue zW7XCdj{eqKj1n|XF$`SMCGXv~7zJGA*AZi?)JY=;A`90VRxKQLB72JZo}~%sYR8qA z3M#x7=adc(h5kgmmIVFTh0Rrz?s3-1jhuyq)y0J?qmMk(1>k%s@32oWHFx%?RcU4S z`5^StXB+MJd+?gLcA~z)?dde?jby`V8(=fwoLo{Kh{@}V=}USs?q0EVSU!6Rx$fx~ z03O2k{WzMgHx0v?qXHKHZxzdg$AiUcz zKf6UFQ7s~4qK2#SAI-P5KaQfCVoDVZRUq^uPUrbdz61BFGd>$DpNA+ha}B$#6aEsr zn?is4nE(?w&QREUr!toxn=d8?xITiRTYK$9~)x0(VYZAmY zmfwi#`>(VrVM5gByFOTSY#mpLPX%PEyO@d^728@rF6g(!#+g$#HSx4w&4H&HA(olP z;aWVm-no<_WbhhG#>AgYwWCysEhT-g<(^+5if$epJ(odgSHmLJl!clr3zHKhnG7!@ z;IDZvt_@!DvovJS%%ey}WwJ?nmbah?41dLo9g;NOT5LYKxpCN&H4FB9D95$nY?%Gt zbZzYzp!buC=f#d_6i*$dWMB{$5AUW;W^Z5o1m1jUp_qaMu^}#ut#R~#&uK$8~?Du__I;^hw$~9B; z#p(d}C2K-kCy%kk93Nq@Prd86ZmoT z{=22Tp3c5;IV>5j)Kxp$%U+Sf^-dm;FmdPL;mTdlqV9iB-byz1kgm@i@_7rc_5KH% zh3gx_%W@^DnOT}8`)=!33v^yK2D`F12IZ3{h@1t&g%|l9fH{ssDt$?Nq z52K6z1zyt_SF0m?qidlVq!6+hukY@>UkOCfZrWTQALId)%o(a5cJkm8$2fv2!`v$9!fThBRH za*8)dKVL)E^Y^8%yRQ59r#)&KA|uD4Aydfq!!u&KlqBl!5Xz4<1U0W_1AP;7x#-u? zkPu9ZEcfbb=dS@%b3RuAWB1k##-Jb4VX-Z(Gah#D(LZ+gYqwW2TBJ}fHF5in?ajli zf6aGKap7q_VIf&88TDHvT#X^0WivVU8F!sETDq;YTjVQMJqrLQSQOl{NEzU%2fob~ zvYdL2+bQ(*!;QrEFR=Js8uTqR!B2Y+;OvjBdnsHRboNUIl<%P~DM@MOob+19Uu_W5L2?9A}D$@dGUQu5*530iL$dYar{m z+dK1P_I(l!?#>W>b4QGG14q_JD)T|L&%*h{brBlRi(-^uo4YF7%7jmqV<+ZI%0p*U z;C0<7IszruvpU%4Vj}@tRbEv*!ta9#q)-J(Wh8B_glS8>UrnE1ba36}f+I?k$~d(y z;p~&u3bAmCX`W+8Bwp%$qeNNnGL7p{>sC#(RA$|NDO$O&6rmQ2LY~1ul+#Vc+dm_U ze+(bHdsqlM<}j+CaqvY09CsSu+-AXgpS0x5$b-%toWv#qxiB&Onirx$qdDpyC3U&_ z;9Y!x7DQ-oO#}(3yMf*DXB@?J1yZpQ|SD6o`QuGaKq)J?Kr{X zNG2=TIYyXgz+E(sr%5pTe0d-8s+*}NT;HD=Eg+<&T~%+#fNWx1t^-7#uP zG}WUO?igDl{QjSJ0c-{XT&K1R>Q%}=v$_!V+R)!fo+y}3=X1m!Mslo-AP {T)Q2bx<#REg`<}Hp2&VV_mU?vrqg>IQ8@}+ z)q4-Cpazl^Y-$4CVoHg%&*cWz#^}fZ zf!otyv-~Jck9=#Ld#*&b<^Z{N-ENd;Lz52Pt#}S$HrURf>mf1mefJ!N$^bBDbki5` z`2IxNAL8*KM^Q~|L(MBLufeG8BhThZUIq%ak$ss+FRtgV7wYeWdn%minZH2?H{}c( zCrhm!G9c$rf~t~2ncc{;T0R2d_5qw^27h`p{@e%tM@_y7e*rbC*7i4%q!UyJ{ge3D zYY;NKK?mK`orcQv>p#dOs30;)I>!GWM%yTb7HhI<1x-c$JBxqzMhkKXcK$}Gregot z=ihI3p#EbPP+w4q|0RPz*LFCjvHwjhe@M!IdZFOOKn+SDb@$`Mbq7?w*?0B@wmnWPZ=^OTx>(?md*lT~c&-#E;C zf#m@8KYV{0gAmFX7o1t-(HNoRmz}FsblJuxm(lVGX}T}kPIZU!6m9z@W&1d{L4xz= z82`x)2RiubM_H=Y*@h5g`+8(o=s;zT3hmwT(rdrsY^eY|2I}cTXUh7rhflu5sUQA8 zBL8#e3IGy+z}9H|z>*_NLW&)dqr{fD{8t_=jHBBpC&I>nUwc{{)wV=*d)!&lBWKua zWWAYoe5lzuHajLXbQA?(XWvaG>(B^4-LpqVlMW6@ENd^m%Run0Kg#qAz2*%apsw_XY5AJ6M< zP-fQJV?aoyGZgfJKKGyW&Ndu!Lolv!J z1Feqa0b5s2)F0>>WWx1edt-S-s#HC`_9=DA9sE!>OWg$)f+vjLG}iuiv!G+@TJuL> z%tyHrUBD;LMn;~{C(RY<;eS()Z^FbI9N{$~A8|#75sSG-+&o+p?lP^{k^JG$b#_!z zD)r3Ko%x5g>WFx`T-*1sVT+LL7x7<^ACU8}3U#qLKmZrv^wHoz{`|AfM(b9^H}CgO+t#_Y zl-VEsQ;Yy?L(`GHAB+o_Th>ChTRtvLz*i?VMFudCbIZfx6))v&Q` z+qP||L1Q$wlLn2A9iy>rtFiH==bWd_^Zxt(?rX2L=9mL>jC){uQ{$V?I3jJtSqHV1 zY1{})`JO=?Pg;yGQJN<6KmdqgSPiFYMIKxzMgA}z(H~k0;AT+?jN{Q?DE^b&j|_!Z zB$o^v``YFcK4@9`6D559;EL*feNO`p3z6c;5HrTS=?{_`x4YZWNuK>AAFrlkrs&iV zNp}V|`%Pen_~grHOHuv$d5HGRAhxT6%eW~ny%%Uy+LI#3GR>!EP}8YVv!y0K#Wh}N ztMs5O*&PY(;pkN=_7Q~kwg~p^;mlUvGs2oA2!sT$2%YQLZKkn1=QNcub1UB>Y8F|X zuxr(_ln_&oS}m1+A>yNX%ec*3gmi&bN_<^^#Uz+~F3B4Sfz|TLyqJa5dTegBV1pv1 zzK&XJ=FECI9tig(`fzPGD;*b5^JCioV1oZB02{Es=bHU&W>8V#4gbe1G?$Vfh8mOV zG;#Y&MKJEGTBSxw@^WLGjm>lo%UyB>wpYZ%MU_?F+YwPqJ z%QNE=hX@1Q7GGRHdEKbj`ugBB55I!p=vte~od%6|dt_T2f?4gISn>Kv-Y1aYT)@ms zo_A$NPTFq{Kp2}Yal;b#MZ{ff|G+&~e@;Wac9ra`IPpwr>z9|KQ5xd3BbwlwRj6e> z3~B->?vO#LTsnu8O6cUq#&i;#)mZ(Q3@D{G+$<3=ChhLA-;C$paa`9S=*~O@PQS;P zSlDJu;}cdF`eXmWNc4^`mH9wUj1|<37udHSyuPcjDx?uSLOjf*vcur&$Z^BlN?#2v?oBEfuvWHJ zS}UFxO!KfFH_P+N9H5E8J2Le-$ylU@KVWMy^Oi7mOjAz=;3Va{rf)^#C6FvDUwrZ8xs`0W5%FE2 z#b&KMG3Dtl162hLVKV*dJnumvJ@_qJIG|w=_l(dRJMVGY-7Tbi>)Aw!?#V&khfr+! zKv5yX-+RFZ*(wAMpZ2Lmm4ix`8T%sS@y2kC@;NTt@zL1R7)$l;YzEcyrR$uj&5