From 6cb0f2d392ed8a90e62a1e797438b7322049ef93 Mon Sep 17 00:00:00 2001 From: Cameron Sparr Date: Thu, 17 Sep 2015 00:57:39 -0700 Subject: [PATCH] Revert godep updates, needs a fix in influxdb repo --- Godeps/Godeps.json | 4 +- .../github.com/influxdb/influxdb/.gitignore | 7 - .../github.com/influxdb/influxdb/CHANGELOG.md | 77 +- .../influxdb/influxdb/CONTRIBUTING.md | 40 +- .../github.com/influxdb/influxdb/DOCKER.md | 6 +- .../influxdb/Dockerfile_test_ubuntu32 | 12 - .../influxdb/LICENSE_OF_DEPENDENCIES.md | 19 - .../github.com/influxdb/influxdb/README.md | 1 - .../influxdb/influxdb/build-docker.sh | 6 +- .../influxdb/influxdb/circle-test.sh | 36 +- .../github.com/influxdb/influxdb/circle.yml | 8 +- .../influxdb/influxdb/client/README.md | 7 +- .../influxdb/influxdb/client/influxdb.go | 17 +- .../influxdb/influxdb/client/influxdb_test.go | 37 +- .../influxdb/cluster/internal/data.pb.go | 135 +++- .../influxdb/cluster/internal/data.proto | 28 +- .../influxdb/cluster/points_writer.go | 76 +- .../influxdb/cluster/points_writer_test.go | 56 +- .../influxdb/influxdb/cluster/rpc.go | 87 +- .../influxdb/influxdb/cluster/service.go | 21 +- .../influxdb/influxdb/cluster/service_test.go | 7 +- .../influxdb/influxdb/cluster/shard_mapper.go | 77 +- .../influxdb/cluster/shard_mapper_test.go | 26 +- .../influxdb/influxdb/cmd/influx/main.go | 93 +-- .../influxdb/influxdb/cmd/influx/main_test.go | 25 - .../cmd/influx_stress/influx_stress.go | 141 +++- .../influxdb/cmd/influxd/run/command.go | 18 +- .../influxdb/cmd/influxd/run/config.go | 8 +- .../cmd/influxd/run/config_command.go | 10 - .../influxdb/cmd/influxd/run/config_test.go | 2 + .../influxdb/cmd/influxd/run/server.go | 77 +- .../cmd/influxd/run/server_helpers_test.go | 52 +- .../influxdb/cmd/influxd/run/server_test.go | 705 +--------------- .../influxdb/influxdb/cmd/inspect/main.go | 142 ---- .../influxdb/influxdb/diagnostics.go | 143 ++++ .../influxdb/influxdb/etc/config.sample.toml | 40 +- .../influxdb/influxdb/importer/README.md | 7 - .../influxdb/influxdb/influxql/INFLUXQL.md | 40 +- .../influxdb/influxdb/influxql/ast.go | 259 ++---- .../influxdb/influxdb/influxql/ast_test.go | 2 +- .../influxdb/{tsdb => influxql}/functions.go | 729 +++++------------ .../influxdb/influxql/functions_test.go | 534 +++++++++++++ .../influxdb/influxdb/influxql/parser.go | 81 +- .../influxdb/influxdb/influxql/parser_test.go | 223 +----- .../influxdb/influxdb/influxql/scanner.go | 2 - .../influxdb/influxql/scanner_test.go | 2 - .../influxdb/influxdb/influxql/token.go | 6 - .../github.com/influxdb/influxdb/influxvar.go | 45 -- .../github.com/influxdb/influxdb/meta/data.go | 111 +-- .../influxdb/influxdb/meta/data_test.go | 60 +- .../influxdb/influxdb/meta/errors.go | 4 - .../influxdb/meta/internal/meta.pb.go | 31 +- .../influxdb/meta/internal/meta.proto | 9 +- .../influxdb/influxdb/meta/rpc_test.go | 2 +- .../influxdb/meta/statement_executor.go | 52 -- .../influxdb/meta/statement_executor_test.go | 71 +- .../influxdb/influxdb/meta/store.go | 55 +- .../influxdb/influxdb/meta/store_test.go | 58 +- .../influxdb/influxdb/monitor/README.md | 47 -- .../influxdb/influxdb/monitor/build_info.go | 18 - .../influxdb/influxdb/monitor/config.go | 35 - .../influxdb/influxdb/monitor/config_test.go | 30 - .../influxdb/influxdb/monitor/go_runtime.go | 19 - .../influxdb/influxdb/monitor/network.go | 21 - .../influxdb/influxdb/monitor/service.go | 406 ---------- .../influxdb/influxdb/monitor/service_test.go | 71 -- .../influxdb/monitor/statement_executor.go | 65 -- .../influxdb/influxdb/monitor/system.go | 26 - .../github.com/influxdb/influxdb/nightly.sh | 2 +- .../github.com/influxdb/influxdb/package.sh | 218 ++--- .../influxdb/scripts/influxdb.service | 3 - .../influxdb/influxdb/scripts/init.sh | 19 +- .../influxdb/influxdb/scripts/logrotate | 8 - .../influxdb/services/collectd/config.go | 6 +- .../influxdb/services/collectd/service.go | 41 +- .../services/collectd/service_test.go | 52 +- .../services/continuous_querier/service.go | 99 +-- .../continuous_querier/service_test.go | 79 +- .../services/copier/internal/internal.pb.go | 57 -- .../services/copier/internal/internal.proto | 9 - .../influxdb/services/copier/service.go | 261 ------ .../influxdb/services/copier/service_test.go | 184 ----- .../influxdb/services/graphite/README.md | 10 +- .../influxdb/services/graphite/config.go | 26 +- .../influxdb/services/graphite/config_test.go | 17 +- .../influxdb/services/graphite/parser.go | 9 +- .../influxdb/services/graphite/service.go | 127 +-- .../services/graphite/service_test.go | 4 +- .../influxdb/services/httpd/handler.go | 79 +- .../influxdb/services/httpd/handler_test.go | 4 +- .../influxdb/services/httpd/service.go | 27 +- .../influxdb/services/monitor/config.go | 25 + .../influxdb/services/monitor/monitor.go | 83 ++ .../influxdb/services/opentsdb/README.md | 2 - .../influxdb/services/opentsdb/config.go | 35 +- .../influxdb/services/opentsdb/service.go | 119 +-- .../influxdb/services/precreator/service.go | 8 +- .../services/precreator/service_test.go | 8 +- .../influxdb/services/retention/config.go | 2 +- .../influxdb/services/retention/service.go | 2 +- .../influxdb/influxdb/services/udp/config.go | 34 +- .../influxdb/services/udp/config_test.go | 3 - .../influxdb/influxdb/services/udp/service.go | 43 +- .../influxdb/influxdb/shared/admin/index.html | 20 +- .../influxdb/shared/admin/js/admin.js | 2 +- .../influxdb/influxdb/statik/statik.go | 2 +- .../influxdb/influxdb/stress/runner.go | 269 ------- .../influxdb/influxdb/stress/runner_test.go | 208 ----- .../github.com/influxdb/influxdb/tcp/mux.go | 82 +- .../influxdb/influxdb/test-32bit-docker.sh | 4 - .../influxdb/influxdb/tsdb/batcher.go | 9 +- .../influxdb/influxdb/tsdb/batcher_test.go | 31 +- .../influxdb/influxdb/tsdb/config.go | 6 +- .../influxdb/influxdb/tsdb/cursor.go | 47 +- .../influxdb/influxdb/tsdb/cursor_test.go | 146 +--- .../influxdb/influxdb/tsdb/engine.go | 5 +- .../influxdb/influxdb/tsdb/engine/b1/b1.go | 98 +-- .../influxdb/tsdb/engine/b1/b1_test.go | 70 +- .../influxdb/influxdb/tsdb/engine/bz1/bz1.go | 169 +--- .../influxdb/tsdb/engine/bz1/bz1_test.go | 93 +-- .../influxdb/influxdb/tsdb/engine/wal/wal.go | 753 +++++++++-------- .../influxdb/tsdb/engine/wal/wal_test.go | 637 ++++++++++----- .../influxdb/influxdb/tsdb/executor.go | 186 +---- .../influxdb/influxdb/tsdb/executor_test.go | 120 +-- .../influxdb/influxdb/tsdb/functions_test.go | 754 ------------------ .../influxdb/influxdb/tsdb/mapper.go | 631 ++++++--------- .../influxdb/influxdb/tsdb/mapper_test.go | 23 +- .../github.com/influxdb/influxdb/tsdb/meta.go | 30 +- .../influxdb/influxdb/tsdb/monitor.go | 83 ++ .../influxdb/influxdb/tsdb/points.go | 59 +- .../influxdb/influxdb/tsdb/points_test.go | 92 +-- .../influxdb/influxdb/tsdb/query_executor.go | 152 ++-- .../influxdb/tsdb/query_executor_test.go | 44 +- .../influxdb/influxdb/tsdb/shard.go | 56 +- .../influxdb/influxdb/tsdb/shard_test.go | 6 + .../influxdb/tsdb/show_measurements.go | 237 ------ .../influxdb/influxdb/tsdb/store.go | 66 +- 137 files changed, 3485 insertions(+), 8777 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/Dockerfile_test_ubuntu32 delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/LICENSE_OF_DEPENDENCIES.md delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/inspect/main.go create mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/diagnostics.go rename Godeps/_workspace/src/github.com/influxdb/influxdb/{tsdb => influxql}/functions.go (62%) create mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions_test.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/influxvar.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/README.md delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/build_info.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config_test.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/go_runtime.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/network.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service_test.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/statement_executor.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/system.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/logrotate delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.pb.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.proto delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service_test.go create mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/config.go create mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/monitor.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/stress/runner.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/stress/runner_test.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/test-32bit-docker.sh delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/tsdb/functions_test.go create mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/tsdb/monitor.go delete mode 100644 Godeps/_workspace/src/github.com/influxdb/influxdb/tsdb/show_measurements.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ffd67e498..9edccea83 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -97,8 +97,8 @@ }, { "ImportPath": "github.com/influxdb/influxdb", - "Comment": "v0.9.4-rc1-84-g6d4319d", - "Rev": "6d4319d244b47db94b79c505a16e00e7ac02ebed" + "Comment": "v0.9.3", + "Rev": "5d42b212fca8facfe9db0c83822f09b88be643ec" }, { "ImportPath": "github.com/lib/pq", diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/.gitignore b/Godeps/_workspace/src/github.com/influxdb/influxdb/.gitignore index 7f3f51d4d..147b88122 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/.gitignore +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/.gitignore @@ -20,10 +20,6 @@ cmd/influxd/version.go # executables -influx_stress -**/influx_stress -!**/influx_stress/ - influxd **/influxd !**/influxd/ @@ -69,6 +65,3 @@ integration/migration_data/ # goconvey config files *.goconvey - -// Ingnore SourceGraph directory -.srclib-store/ diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/CHANGELOG.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/CHANGELOG.md index bb3a63866..89eb85a48 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/CHANGELOG.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/CHANGELOG.md @@ -1,83 +1,14 @@ -## v0.9.5 [unreleased] - -### Features -- [#4065](https://github.com/influxdb/influxdb/pull/4065): Added precision support in cmd client. Thanks @sbouchex - -### Bugfixes -- [#3457](https://github.com/influxdb/influxdb/issues/3457): [0.9.3] cannot select field names with prefix + "." that match the measurement name -- [#4111](https://github.com/influxdb/influxdb/pull/4111): Update pre-commit hook for go vet composites - -## v0.9.4 [2015-09-14] - -### Release Notes -With this release InfluxDB is moving to Go 1.5. - -### Features -- [#4050](https://github.com/influxdb/influxdb/pull/4050): Add stats to collectd -- [#3771](https://github.com/influxdb/influxdb/pull/3771): Close idle Graphite TCP connections -- [#3755](https://github.com/influxdb/influxdb/issues/3755): Add option to build script. Thanks @fg2it -- [#3863](https://github.com/influxdb/influxdb/pull/3863): Move to Go 1.5 -- [#3892](https://github.com/influxdb/influxdb/pull/3892): Support IF NOT EXISTS for CREATE DATABASE -- [#3916](https://github.com/influxdb/influxdb/pull/3916): New statistics and diagnostics support. Graphite first to be instrumented. -- [#3901](https://github.com/influxdb/influxdb/pull/3901): Add consistency level option to influx cli Thanks @takayuki -- [#4048](https://github.com/influxdb/influxdb/pull/4048): Add statistics to Continuous Query service -- [#4049](https://github.com/influxdb/influxdb/pull/4049): Add stats to the UDP input -- [#3876](https://github.com/influxdb/influxdb/pull/3876): Allow the following syntax in CQs: INTO "1hPolicy".:MEASUREMENT -- [#3975](https://github.com/influxdb/influxdb/pull/3975): Add shard copy service -- [#3986](https://github.com/influxdb/influxdb/pull/3986): Support sorting by time desc -- [#3930](https://github.com/influxdb/influxdb/pull/3930): Wire up TOP aggregate function - fixes [#1821](https://github.com/influxdb/influxdb/issues/1821) -- [#4045](https://github.com/influxdb/influxdb/pull/4045): Instrument cluster-level points writer -- [#3996](https://github.com/influxdb/influxdb/pull/3996): Add statistics to httpd package -- [#4003](https://github.com/influxdb/influxdb/pull/4033): Add logrotate configuration. -- [#4043](https://github.com/influxdb/influxdb/pull/4043): Add stats and batching to openTSDB input -- [#4042](https://github.com/influxdb/influxdb/pull/4042): Add pending batches control to batcher -- [#4006](https://github.com/influxdb/influxdb/pull/4006): Add basic statistics for shards -- [#4072](https://github.com/influxdb/influxdb/pull/4072): Add statistics for the WAL. - -### Bugfixes -- [#4042](https://github.com/influxdb/influxdb/pull/4042): Set UDP input batching defaults as needed. -- [#3785](https://github.com/influxdb/influxdb/issues/3785): Invalid time stamp in graphite metric causes panic -- [#3804](https://github.com/influxdb/influxdb/pull/3804): init.d script fixes, fixes issue 3803. -- [#3823](https://github.com/influxdb/influxdb/pull/3823): Deterministic ordering for first() and last() -- [#3869](https://github.com/influxdb/influxdb/issues/3869): Seemingly deadlocked when ingesting metrics via graphite plugin -- [#3856](https://github.com/influxdb/influxdb/pull/3856): Minor changes to retention enforcement. -- [#3884](https://github.com/influxdb/influxdb/pull/3884): Fix two panics in WAL that can happen at server startup -- [#3868](https://github.com/influxdb/influxdb/pull/3868): Add shell option to start the daemon on CentOS. Thanks @SwannCroiset. -- [#3886](https://github.com/influxdb/influxdb/pull/3886): Prevent write timeouts due to lock contention in WAL -- [#3574](https://github.com/influxdb/influxdb/issues/3574): Querying data node causes panic -- [#3913](https://github.com/influxdb/influxdb/issues/3913): Convert meta shard owners to objects -- [#4026](https://github.com/influxdb/influxdb/pull/4026): Support multiple Graphite inputs. Fixes issue [#3636](https://github.com/influxdb/influxdb/issues/3636) -- [#3927](https://github.com/influxdb/influxdb/issues/3927): Add WAL lock to prevent timing lock contention -- [#3928](https://github.com/influxdb/influxdb/issues/3928): Write fails for multiple points when tag starts with quote -- [#3901](https://github.com/influxdb/influxdb/pull/3901): Unblock relaxed write consistency level Thanks @takayuki! -- [#3950](https://github.com/influxdb/influxdb/pull/3950): Limit bz1 quickcheck tests to 10 iterations on CI -- [#3977](https://github.com/influxdb/influxdb/pull/3977): Silence wal logging during testing -- [#3931](https://github.com/influxdb/influxdb/pull/3931): Don't precreate shard groups entirely in the past -- [#3960](https://github.com/influxdb/influxdb/issues/3960): possible "catch up" bug with nodes down in a cluster -- [#3980](https://github.com/influxdb/influxdb/pull/3980): 'service stop' waits until service actually stops. Fixes issue #3548. -- [#4016](https://github.com/influxdb/influxdb/pull/4016): Shutdown Graphite UDP on SIGTERM. -- [#4034](https://github.com/influxdb/influxdb/pull/4034): Rollback bolt tx on mapper open error -- [#3848](https://github.com/influxdb/influxdb/issues/3848): restart influxdb causing panic -- [#3881](https://github.com/influxdb/influxdb/issues/3881): panic: runtime error: invalid memory address or nil pointer dereference -- [#3926](https://github.com/influxdb/influxdb/issues/3926): First or last value of `GROUP BY time(x)` is often null. Fixed by [#4038](https://github.com/influxdb/influxdb/pull/4038) -- [#4053](https://github.com/influxdb/influxdb/pull/4053): Prohibit dropping default retention policy. -- [#4060](https://github.com/influxdb/influxdb/pull/4060): Don't log EOF error in openTSDB input. -- [#3978](https://github.com/influxdb/influxdb/issues/3978): [0.9.3] (regression) cannot use GROUP BY * with more than a single field in SELECT clause -- [#4058](https://github.com/influxdb/influxdb/pull/4058): Disable bz1 recompression -- [#3902](https://github.com/influxdb/influxdb/issues/3902): [0.9.3] DB should not crash when using invalid expression "GROUP BY time" -- [#3718](https://github.com/influxdb/influxdb/issues/3718): Derivative query with group by time but no aggregate function should fail parse - -## v0.9.3 [2015-08-26] +## v0.9.3 [unreleased] ### Release Notes There are breaking changes in this release. - - To store data points as integers you must now append `i` to the number if using the line protocol. - - If you have a UDP input configured, you should check the UDP section of [the new sample configuration file](https://github.com/influxdb/influxdb/blob/master/etc/config.sample.toml) to learn how to modify existing configuration files, as 0.9.3 now expects multiple UDP inputs. + - To store data points as integers you must now append i to the number if using the line protocol. + - If you have a UDP input configured, you should check the UDP section of [the new sample configuration file](https://github.com/influxdb/influxdb/blob/master/etc/config.sample.toml) to learn how to modify existing configuration files, as 0.9.3 now expects multiple UDP inputs. - Configuration files must now have an entry for `wal-dir` in the `[data]` section. Check [new sample configuration file](https://github.com/influxdb/influxdb/blob/master/etc/config.sample.toml) for more details. - The implicit `GROUP BY *` that was added to every `SELECT *` has been removed. Instead any tags in the data are now part of the columns in the returned query. -Please see the *Features* section below for full details. +Please see the *Features* section below for full details. ### Features - [#3376](https://github.com/influxdb/influxdb/pull/3376): Support for remote shard query mapping diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/CONTRIBUTING.md index 5b619ac64..56d188693 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/CONTRIBUTING.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/CONTRIBUTING.md @@ -79,7 +79,7 @@ second to sign our CLA, which can be found Installing Go ------------- -InfluxDB requires Go 1.5 or greater. +InfluxDB requires Go 1.4 or greater. At InfluxDB we find gvm, a Go version manager, useful for installing Go. For instructions on how to install it see [the gvm page on github](https://github.com/moovweb/gvm). @@ -87,40 +87,29 @@ on how to install it see [the gvm page on github](https://github.com/moovweb/gvm After installing gvm you can install and set the default go version by running the following: - gvm install go1.5 - gvm use go1.5 --default + gvm install go1.4 + gvm use go1.4 --default Revision Control Systems -------------- +------ Go has the ability to import remote packages via revision control systems with the `go get` command. To ensure that you can retrieve any remote package, be sure to install the following rcs software to your system. Currently the project only depends on `git` and `mercurial`. * [Install Git](http://git-scm.com/book/en/Getting-Started-Installing-Git) * [Install Mercurial](http://mercurial.selenic.com/wiki/Download) -Getting the source ------- -Setup the project structure and fetch the repo like so: - - mkdir $HOME/gocodez - export GOPATH=$HOME/gocodez - go get github.com/influxdb/influxdb - -You can add the line `export GOPATH=$HOME/gocodez` to your bash/zsh file to be set for every shell instead of having to manually run it everytime. - -Cloning a fork -------------- -If you wish to work with fork of InfluxDB, your own fork for example, you must still follow the directory structure above. But instead of cloning the main repo, instead clone your fork. Follow the steps below to work with a fork: +Project structure +----------------- +First you need to setup the project structure: export GOPATH=$HOME/gocodez mkdir -p $GOPATH/src/github.com/influxdb cd $GOPATH/src/github.com/influxdb - git clone git@github.com:/influxdb + git clone git@github.com:influxdb/influxdb -Retaining the directory structure `$GOPATH/src/github.com/influxdb` is necessary so that Go imports work correctly. - -Pre-commit checks -------------- +You can add the line `export GOPATH=$HOME/gocodez` to your bash/zsh +file to be set for every shell instead of having to manually run it +everytime. We have a pre commit hook to make sure code is formatted properly and vetted before you commit any changes. We strongly recommend using the pre @@ -167,16 +156,11 @@ go install ./... To set the version and commit flags during the build pass the following to the build command: ```bash --ldflags="-X main.version=$VERSION -X main.branch=$BRANCH -X main.commit=$COMMIT" +-ldflags="-X main.version $VERSION -X main.branch $BRANCH -X main.commit $COMMIT" ``` where `$VERSION` is the version, `$BRANCH` is the branch, and `$COMMIT` is the git commit hash. -If you want to build packages, see `package.sh` help: -```bash -package.sh -h -``` - To run the tests, execute the following command: ```bash diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/DOCKER.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/DOCKER.md index e78187d9b..adb33a416 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/DOCKER.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/DOCKER.md @@ -37,8 +37,8 @@ The `HOST_IP` env variable should be your host IP if running under linux or the ``` $ export HOST_IP= -$ docker run -it -p 8086:8086 -p 8088:8088 influxdb -hostname $HOST_IP:8088 -$ docker run -it -p 8186:8086 -p 8188:8088 influxdb -hostname $HOST_IP:8188 -join $HOST_IP:8088 -$ docker run -it -p 8286:8086 -p 8288:8088 influxdb -hostname $HOST_IP:8288 -join $HOST_IP:8088 +$ docker run -it -p 8086:8088 -p 8088:8088 influxdb -hostname $HOST_IP:8088 +$ docker run -it -p 8186:8088 -p 8188:8088 influxdb -hostname $HOST_IP:8188 -join $HOST_IP:8088 +$ docker run -it -p 8286:8088 -p 8288:8088 influxdb -hostname $HOST_IP:8288 -join $HOST_IP:8088 ``` diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/Dockerfile_test_ubuntu32 b/Godeps/_workspace/src/github.com/influxdb/influxdb/Dockerfile_test_ubuntu32 deleted file mode 100644 index caaf81dc9..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/Dockerfile_test_ubuntu32 +++ /dev/null @@ -1,12 +0,0 @@ -FROM 32bit/ubuntu:14.04 - -RUN apt-get update && apt-get install -y python-software-properties software-properties-common git -RUN add-apt-repository ppa:evarlast/golang1.5 -RUN apt-get update && apt-get install -y -o Dpkg::Options::="--force-overwrite" golang-go - -ENV GOPATH=/root/go -RUN mkdir -p /root/go/src/github.com/influxdb/influxdb -RUN mkdir -p /tmp/artifacts - -VOLUME /root/go/src/github.com/influxdb/influxdb -VOLUME /tmp/artifacts diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/LICENSE_OF_DEPENDENCIES.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/LICENSE_OF_DEPENDENCIES.md deleted file mode 100644 index abba2b241..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/LICENSE_OF_DEPENDENCIES.md +++ /dev/null @@ -1,19 +0,0 @@ -# List -- github.com/gogo/protobuf/proto [BSD LICENSE](https://github.com/gogo/protobuf/blob/master/LICENSE) -- gopkg.in/fatih/pool.v2 [MIT LICENSE](https://github.com/fatih/pool/blob/v2.0.0/LICENSE) -- github.com/BurntSushi/toml [WTFPL LICENSE](https://github.com/BurntSushi/toml/blob/master/COPYING) -- github.com/peterh/liner [MIT LICENSE](https://github.com/peterh/liner/blob/master/COPYING) -- github.com/davecgh/go-spew/spew [ISC LICENSE](https://github.com/davecgh/go-spew/blob/master/LICENSE) -- github.com/hashicorp/raft [MPL LICENSE](https://github.com/hashicorp/raft/blob/master/LICENSE) -- github.com/rakyll/statik/fs [APACHE LICENSE](https://github.com/rakyll/statik/blob/master/LICENSE) -- github.com/kimor79/gollectd [BSD LICENSE](https://github.com/kimor79/gollectd/blob/master/LICENSE) -- github.com/bmizerany/pat [MIT LICENSE](https://github.com/bmizerany/pat#license) -- react 0.13.3 [BSD LICENSE](https://github.com/facebook/react/blob/master/LICENSE) -- bootstrap 3.3.5 [MIT LICENSE](https://github.com/twbs/bootstrap/blob/master/LICENSE) -- jquery 2.1.4 [MIT LICENSE](https://github.com/jquery/jquery/blob/master/LICENSE.txt) -- glyphicons [LICENSE](http://glyphicons.com/license/) -- github.com/golang/snappy [BSD LICENSE](https://github.com/golang/snappy/blob/master/LICENSE) -- github.com/boltdb/bolt [MIT LICENSE](https://github.com/boltdb/bolt/blob/master/LICENSE) -- collectd.org [ISC LICENSE](https://github.com/collectd/go-collectd/blob/master/LICENSE) -- golang.org/x/crypto/bcrypt [BSD LICENSE](https://go.googlesource.com/crypto/+/master/LICENSE) - diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/README.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/README.md index 586b5613d..a13be4127 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/README.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/README.md @@ -32,7 +32,6 @@ For those adventurous enough, you can ### Starting InfluxDB * `service influxdb start` if you have installed InfluxDB using an official Debian or RPM package. -* `systemctl start influxdb` if you have installed InfluxDB using an official Debian or RPM package, and are running a distro with `systemd`. For example, Ubuntu 15 or later. * `$GOPATH/bin/influxd` if you have built InfluxDB from source. ### Creating your first database diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/build-docker.sh b/Godeps/_workspace/src/github.com/influxdb/influxdb/build-docker.sh index 0dea62d2a..6f303201e 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/build-docker.sh +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/build-docker.sh @@ -1,9 +1,7 @@ -#!/bin/sh - -set -e -x +#!/bin/sh -x -e GO_VER=${GO_VER:-1.5} -docker run -it -v "${GOPATH}":/gopath -v "$(pwd)":/app -e "GOPATH=/gopath" -w /app golang:$GO_VER sh -c 'CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags="-s" -o influxd ./cmd/influxd' +docker run -it -v "$GOPATH":/gopath -v "$(pwd)":/app -e "GOPATH=/gopath" -w /app golang:$GO_VER sh -c 'CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags="-s" -o influxd ./cmd/influxd' docker build -t influxdb . diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/circle-test.sh b/Godeps/_workspace/src/github.com/influxdb/influxdb/circle-test.sh index 092582c44..a53ac6487 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/circle-test.sh +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/circle-test.sh @@ -5,7 +5,7 @@ # build process for InfluxDB. BUILD_DIR=$HOME/influxdb-build -GO_VERSION=go1.5 +GO_VERSION=go1.4.2 PARALLELISM="-parallel 256" TIMEOUT="-timeout 480s" @@ -21,25 +21,6 @@ function exit_if_fail { fi } -# Check that go fmt has been run. -function check_go_fmt { - fmtcount=`git ls-files | grep '.go$' | xargs gofmt -l 2>&1 | wc -l` - if [ $fmtcount -gt 0 ]; then - echo "run 'go fmt ./...' to format your source code." - exit 1 - fi -} - -# Check that go vet passes. -function check_go_vet { - # Due to the way composites work, vet will fail for some of our tests so we ignore it - vetcount=`go tool vet --composites=false ./ 2>&1 | wc -l` - if [ $vetcount -gt 0 ]; then - echo "run 'go tool vet --composites=false ./' to see the errors it flags and correct your source code." - exit 1 - fi -} - source $HOME/.gvm/scripts/gvm exit_if_fail gvm use $GO_VERSION @@ -64,29 +45,16 @@ exit_if_fail git branch --set-upstream-to=origin/$CIRCLE_BRANCH $CIRCLE_BRANCH exit_if_fail cd $GOPATH/src/github.com/influxdb/influxdb exit_if_fail go get -t -d -v ./... exit_if_fail git checkout $CIRCLE_BRANCH # 'go get' switches to master. Who knew? Switch back. -check_go_fmt -check_go_vet exit_if_fail go build -v ./... # Run the tests. +exit_if_fail go tool vet --composites=false . case $CIRCLE_NODE_INDEX in 0) go test $PARALLELISM $TIMEOUT -v ./... 2>&1 | tee $CIRCLE_ARTIFACTS/test_logs.txt rc=${PIPESTATUS[0]} ;; 1) - # 32bit tests. - if [[ -e ~/docker/image.tar ]]; then docker load -i ~/docker/image.tar; fi - docker build -f Dockerfile_test_ubuntu32 -t ubuntu-32-influxdb-test . - mkdir -p ~/docker; docker save ubuntu-32-influxdb-test > ~/docker/image.tar - exit_if_fail docker build -f Dockerfile_test_ubuntu32 -t ubuntu-32-influxdb-test . - docker run -v $(pwd):/root/go/src/github.com/influxdb/influxdb -e "CI=${CI}" \ - -v ${CIRCLE_ARTIFACTS}:/tmp/artifacts \ - -t ubuntu-32-influxdb-test bash \ - -c "cd /root/go/src/github.com/influxdb/influxdb && go get -t -d -v ./... && go build -v ./... && go test ${PARALLELISM} ${TIMEOUT} -v ./... 2>&1 | tee /tmp/artifacts/test_logs_i386.txt && exit \${PIPESTATUS[0]}" - rc=$? - ;; - 2) GORACE="halt_on_error=1" go test $PARALLELISM $TIMEOUT -v -race ./... 2>&1 | tee $CIRCLE_ARTIFACTS/test_logs_race.txt rc=${PIPESTATUS[0]} ;; diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/circle.yml b/Godeps/_workspace/src/github.com/influxdb/influxdb/circle.yml index 01a5a161a..141e26fda 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/circle.yml +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/circle.yml @@ -1,15 +1,11 @@ machine: - services: - - docker pre: - bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) - - source $HOME/.gvm/scripts/gvm; gvm install go1.5 --binary + - source $HOME/.gvm/scripts/gvm; gvm install go1.4.2 --binary dependencies: override: - - mkdir -p ~/docker - cache_directories: - - "~/docker" + - echo "Dummy override, so no Circle dependencies execute" test: override: - bash circle-test.sh: diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/client/README.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/client/README.md index 8d94a7579..883941e90 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/client/README.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/client/README.md @@ -45,12 +45,7 @@ the configuration below. package main import "github.com/influxdb/influxdb/client" -import ( - "net/url" - "fmt" - "log" - "os" -) +import "net/url" const ( MyHost = "localhost" diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb.go index 2100fb920..c4f34d84c 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb.go @@ -79,7 +79,6 @@ type Config struct { Password string UserAgent string Timeout time.Duration - Precision string } // NewConfig will create a config to be used in connecting to the client @@ -96,7 +95,6 @@ type Client struct { password string httpClient *http.Client userAgent string - precision string } const ( @@ -114,7 +112,6 @@ func NewClient(c Config) (*Client, error) { password: c.Password, httpClient: &http.Client{Timeout: c.Timeout}, userAgent: c.UserAgent, - precision: c.Precision, } if client.userAgent == "" { client.userAgent = "InfluxDBClient" @@ -128,11 +125,6 @@ func (c *Client) SetAuth(u, p string) { c.password = p } -// SetPrecision will update the precision -func (c *Client) SetPrecision(precision string) { - c.precision = precision -} - // Query sends a command to the server and returns the Response func (c *Client) Query(q Query) (*Response, error) { u := c.url @@ -141,9 +133,6 @@ func (c *Client) Query(q Query) (*Response, error) { values := u.Query() values.Set("q", q.Command) values.Set("db", q.Database) - if c.precision != "" { - values.Set("epoch", c.precision) - } u.RawQuery = values.Encode() req, err := http.NewRequest("GET", u.String(), nil) @@ -460,11 +449,7 @@ func (p *Point) MarshalJSON() ([]byte, error) { } func (p *Point) MarshalString() string { - pt := tsdb.NewPoint(p.Measurement, p.Tags, p.Fields, p.Time) - if p.Precision == "" || p.Precision == "ns" || p.Precision == "n" { - return pt.String() - } - return pt.PrecisionString(p.Precision) + return tsdb.NewPoint(p.Measurement, p.Tags, p.Fields, p.Time).String() } // UnmarshalJSON decodes the data into the Point struct diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb_test.go index 34cedc446..0a6df042e 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/client/influxdb_test.go @@ -498,12 +498,13 @@ func TestBatchPoints_Normal(t *testing.T) { } func TestClient_Timeout(t *testing.T) { - done := make(chan bool) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - <-done + time.Sleep(1 * time.Second) + var data client.Response + w.WriteHeader(http.StatusOK) + _ = json.NewEncoder(w).Encode(data) })) defer ts.Close() - defer func() { done <- true }() u, _ := url.Parse(ts.URL) config := client.Config{URL: *u, Timeout: 500 * time.Millisecond} @@ -516,33 +517,13 @@ func TestClient_Timeout(t *testing.T) { _, err = c.Query(query) if err == nil { t.Fatalf("unexpected success. expected timeout error") - } else if !strings.Contains(err.Error(), "request canceled") && - !strings.Contains(err.Error(), "use of closed network connection") { - t.Fatalf("unexpected error. expected 'request canceled' error, got %v", err) - } -} - -func TestClient_NoTimeout(t *testing.T) { - if testing.Short() { - t.Skip("skipping in short mode") - } - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - time.Sleep(1 * time.Second) - var data client.Response - w.WriteHeader(http.StatusOK) - _ = json.NewEncoder(w).Encode(data) - })) - defer ts.Close() - - u, _ := url.Parse(ts.URL) - config := client.Config{URL: *u} - c, err := client.NewClient(config) - if err != nil { - t.Fatalf("unexpected error. expected %v, actual %v", nil, err) + } else if !strings.Contains(err.Error(), "use of closed network connection") { + t.Fatalf("unexpected error. expected 'use of closed network connection' error, got %v", err) } - query := client.Query{} - _, err = c.Query(query) + confignotimeout := client.Config{URL: *u} + cnotimeout, err := client.NewClient(confignotimeout) + _, err = cnotimeout.Query(query) if err != nil { t.Fatalf("unexpected error. expected %v, actual %v", nil, err) } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.pb.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.pb.go index 4fa3f34b8..1d53707c8 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.pb.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.pb.go @@ -10,6 +10,9 @@ It is generated from these files: It has these top-level messages: WriteShardRequest + Field + Tag + Point WriteShardResponse MapShardRequest MapShardResponse @@ -25,7 +28,7 @@ var _ = math.Inf type WriteShardRequest struct { ShardID *uint64 `protobuf:"varint,1,req" json:"ShardID,omitempty"` - Points [][]byte `protobuf:"bytes,2,rep" json:"Points,omitempty"` + Points []*Point `protobuf:"bytes,2,rep" json:"Points,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -40,13 +43,141 @@ func (m *WriteShardRequest) GetShardID() uint64 { return 0 } -func (m *WriteShardRequest) GetPoints() [][]byte { +func (m *WriteShardRequest) GetPoints() []*Point { if m != nil { return m.Points } return nil } +type Field struct { + Name *string `protobuf:"bytes,1,req" json:"Name,omitempty"` + Int32 *int32 `protobuf:"varint,2,opt" json:"Int32,omitempty"` + Int64 *int64 `protobuf:"varint,3,opt" json:"Int64,omitempty"` + Float64 *float64 `protobuf:"fixed64,4,opt" json:"Float64,omitempty"` + Bool *bool `protobuf:"varint,5,opt" json:"Bool,omitempty"` + String_ *string `protobuf:"bytes,6,opt" json:"String,omitempty"` + Bytes []byte `protobuf:"bytes,7,opt" json:"Bytes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Field) Reset() { *m = Field{} } +func (m *Field) String() string { return proto.CompactTextString(m) } +func (*Field) ProtoMessage() {} + +func (m *Field) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Field) GetInt32() int32 { + if m != nil && m.Int32 != nil { + return *m.Int32 + } + return 0 +} + +func (m *Field) GetInt64() int64 { + if m != nil && m.Int64 != nil { + return *m.Int64 + } + return 0 +} + +func (m *Field) GetFloat64() float64 { + if m != nil && m.Float64 != nil { + return *m.Float64 + } + return 0 +} + +func (m *Field) GetBool() bool { + if m != nil && m.Bool != nil { + return *m.Bool + } + return false +} + +func (m *Field) GetString_() string { + if m != nil && m.String_ != nil { + return *m.String_ + } + return "" +} + +func (m *Field) GetBytes() []byte { + if m != nil { + return m.Bytes + } + return nil +} + +type Tag struct { + Key *string `protobuf:"bytes,1,req" json:"Key,omitempty"` + Value *string `protobuf:"bytes,2,req" json:"Value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Tag) Reset() { *m = Tag{} } +func (m *Tag) String() string { return proto.CompactTextString(m) } +func (*Tag) ProtoMessage() {} + +func (m *Tag) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *Tag) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +type Point struct { + Name *string `protobuf:"bytes,1,req" json:"Name,omitempty"` + Time *int64 `protobuf:"varint,2,req" json:"Time,omitempty"` + Fields []*Field `protobuf:"bytes,3,rep" json:"Fields,omitempty"` + Tags []*Tag `protobuf:"bytes,4,rep" json:"Tags,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Point) Reset() { *m = Point{} } +func (m *Point) String() string { return proto.CompactTextString(m) } +func (*Point) ProtoMessage() {} + +func (m *Point) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Point) GetTime() int64 { + if m != nil && m.Time != nil { + return *m.Time + } + return 0 +} + +func (m *Point) GetFields() []*Field { + if m != nil { + return m.Fields + } + return nil +} + +func (m *Point) GetTags() []*Tag { + if m != nil { + return m.Tags + } + return nil +} + type WriteShardResponse struct { Code *int32 `protobuf:"varint,1,req" json:"Code,omitempty"` Message *string `protobuf:"bytes,2,opt" json:"Message,omitempty"` diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.proto b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.proto index fed14bad9..e38a9de5b 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.proto +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/internal/data.proto @@ -2,7 +2,31 @@ package internal; message WriteShardRequest { required uint64 ShardID = 1; - repeated bytes Points = 2; + repeated Point Points = 2; +} + +message Field { + required string Name = 1; + oneof Value { + int32 Int32 = 2; + int64 Int64 = 3; + double Float64 = 4; + bool Bool = 5; + string String = 6; + bytes Bytes = 7; + } +} + +message Tag { + required string Key = 1; + required string Value = 2; +} + +message Point { + required string Name = 1; + required int64 Time = 2; + repeated Field Fields = 3; + repeated Tag Tags = 4; } message WriteShardResponse { @@ -22,4 +46,4 @@ message MapShardResponse { optional bytes Data = 3; repeated string TagSets = 4; repeated string Fields = 5; -} +} \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer.go index 157b80d0a..b5a78636d 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer.go @@ -2,7 +2,6 @@ package cluster import ( "errors" - "expvar" "fmt" "log" "os" @@ -19,19 +18,6 @@ import ( // be returned as successful type ConsistencyLevel int -// The statistics generated by the "write" mdoule -const ( - statWriteReq = "req" - statPointWriteReq = "point_req" - statPointWriteReqLocal = "point_req_local" - statPointWriteReqRemote = "point_req_remote" - statWriteOK = "write_ok" - statWritePartial = "write_partial" - statWriteTimeout = "write_timeout" - statWriteErr = "write_error" - statWritePointReqHH = "point_req_hh" -) - const ( // ConsistencyLevelAny allows for hinted hand off, potentially no write happened yet ConsistencyLevelAny ConsistencyLevel = iota @@ -104,8 +90,6 @@ type PointsWriter struct { HintedHandoff interface { WriteShard(shardID, ownerID uint64, points []tsdb.Point) error } - - statMap *expvar.Map } // NewPointsWriter returns a new instance of PointsWriter for a node. @@ -114,7 +98,6 @@ func NewPointsWriter() *PointsWriter { closing: make(chan struct{}), WriteTimeout: DefaultWriteTimeout, Logger: log.New(os.Stderr, "[write] ", log.LstdFlags), - statMap: influxdb.NewStatistics("write", "write", nil), } } @@ -199,9 +182,6 @@ func (w *PointsWriter) MapShards(wp *WritePointsRequest) (*ShardMapping, error) // WritePoints writes across multiple local and remote data nodes according the consistency level. func (w *PointsWriter) WritePoints(p *WritePointsRequest) error { - w.statMap.Add(statWriteReq, 1) - w.statMap.Add(statPointWriteReq, int64(len(p.Points))) - if p.RetentionPolicy == "" { db, err := w.MetaStore.Database(p.Database) if err != nil { @@ -244,7 +224,7 @@ func (w *PointsWriter) WritePoints(p *WritePointsRequest) error { func (w *PointsWriter) writeToShard(shard *meta.ShardInfo, database, retentionPolicy string, consistency ConsistencyLevel, points []tsdb.Point) error { // The required number of writes to achieve the requested consistency level - required := len(shard.Owners) + required := len(shard.OwnerIDs) switch consistency { case ConsistencyLevelAny, ConsistencyLevelOne: required = 1 @@ -253,88 +233,76 @@ func (w *PointsWriter) writeToShard(shard *meta.ShardInfo, database, retentionPo } // response channel for each shard writer go routine - type AsyncWriteResult struct { - Owner meta.ShardOwner - Err error - } - ch := make(chan *AsyncWriteResult, len(shard.Owners)) - - for _, owner := range shard.Owners { - go func(shardID uint64, owner meta.ShardOwner, points []tsdb.Point) { - if w.MetaStore.NodeID() == owner.NodeID { - w.statMap.Add(statPointWriteReqLocal, int64(len(points))) + ch := make(chan error, len(shard.OwnerIDs)) + for _, nodeID := range shard.OwnerIDs { + go func(shardID, nodeID uint64, points []tsdb.Point) { + if w.MetaStore.NodeID() == nodeID { err := w.TSDBStore.WriteToShard(shardID, points) // If we've written to shard that should exist on the current node, but the store has // not actually created this shard, tell it to create it and retry the write if err == tsdb.ErrShardNotFound { err = w.TSDBStore.CreateShard(database, retentionPolicy, shardID) if err != nil { - ch <- &AsyncWriteResult{owner, err} + ch <- err return } err = w.TSDBStore.WriteToShard(shardID, points) } - ch <- &AsyncWriteResult{owner, err} + ch <- err return } - w.statMap.Add(statPointWriteReqRemote, int64(len(points))) - err := w.ShardWriter.WriteShard(shardID, owner.NodeID, points) + err := w.ShardWriter.WriteShard(shardID, nodeID, points) if err != nil && tsdb.IsRetryable(err) { // The remote write failed so queue it via hinted handoff - w.statMap.Add(statWritePointReqHH, int64(len(points))) - hherr := w.HintedHandoff.WriteShard(shardID, owner.NodeID, points) + hherr := w.HintedHandoff.WriteShard(shardID, nodeID, points) // If the write consistency level is ANY, then a successful hinted handoff can // be considered a successful write so send nil to the response channel // otherwise, let the original error propogate to the response channel if hherr == nil && consistency == ConsistencyLevelAny { - ch <- &AsyncWriteResult{owner, nil} + ch <- nil return } } - ch <- &AsyncWriteResult{owner, err} + ch <- err - }(shard.ID, owner, points) + }(shard.ID, nodeID, points) } var wrote int timeout := time.After(w.WriteTimeout) var writeError error - for range shard.Owners { + for _, nodeID := range shard.OwnerIDs { select { case <-w.closing: return ErrWriteFailed case <-timeout: - w.statMap.Add(statWriteTimeout, 1) // return timeout error to caller return ErrTimeout - case result := <-ch: + case err := <-ch: // If the write returned an error, continue to the next response - if result.Err != nil { - w.statMap.Add(statWriteErr, 1) - w.Logger.Printf("write failed for shard %d on node %d: %v", shard.ID, result.Owner.NodeID, result.Err) + if err != nil { + w.Logger.Printf("write failed for shard %d on node %d: %v", shard.ID, nodeID, err) // Keep track of the first error we see to return back to the client if writeError == nil { - writeError = result.Err + writeError = err } continue } wrote += 1 - - // We wrote the required consistency level - if wrote >= required { - w.statMap.Add(statWriteOK, 1) - return nil - } } } + // We wrote the required consistency level + if wrote >= required { + return nil + } + if wrote > 0 { - w.statMap.Add(statWritePartial, 1) return ErrPartialWrite } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer_test.go index 902a1d1de..321f731d0 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/points_writer_test.go @@ -51,16 +51,8 @@ func TestPointsWriter_MapShards_One(t *testing.T) { func TestPointsWriter_MapShards_Multiple(t *testing.T) { ms := MetaStore{} rp := NewRetentionPolicy("myp", time.Hour, 3) - AttachShardGroupInfo(rp, []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }) - AttachShardGroupInfo(rp, []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }) + AttachShardGroupInfo(rp, []uint64{1, 2, 3}) + AttachShardGroupInfo(rp, []uint64{1, 2, 3}) ms.NodeIDFn = func() uint64 { return 1 } ms.RetentionPolicyFn = func(db, retentionPolicy string) (*meta.RetentionPolicyInfo, error) { @@ -257,25 +249,13 @@ func TestPointsWriter_WritePoints(t *testing.T) { theTest := test sm := cluster.NewShardMapping() sm.MapPoint( - &meta.ShardInfo{ID: uint64(1), Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }}, + &meta.ShardInfo{ID: uint64(1), OwnerIDs: []uint64{uint64(1), uint64(2), uint64(3)}}, pr.Points[0]) sm.MapPoint( - &meta.ShardInfo{ID: uint64(2), Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }}, + &meta.ShardInfo{ID: uint64(2), OwnerIDs: []uint64{uint64(1), uint64(2), uint64(3)}}, pr.Points[1]) sm.MapPoint( - &meta.ShardInfo{ID: uint64(2), Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }}, + &meta.ShardInfo{ID: uint64(2), OwnerIDs: []uint64{uint64(1), uint64(2), uint64(3)}}, pr.Points[2]) // Local cluster.Node ShardWriter @@ -354,16 +334,8 @@ func (f *fakeStore) CreateShard(database, retentionPolicy string, shardID uint64 func NewMetaStore() *MetaStore { ms := &MetaStore{} rp := NewRetentionPolicy("myp", time.Hour, 3) - AttachShardGroupInfo(rp, []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }) - AttachShardGroupInfo(rp, []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }) + AttachShardGroupInfo(rp, []uint64{1, 2, 3}) + AttachShardGroupInfo(rp, []uint64{1, 2, 3}) ms.RetentionPolicyFn = func(db, retentionPolicy string) (*meta.RetentionPolicyInfo, error) { return rp, nil @@ -408,15 +380,15 @@ func (m MetaStore) ShardOwner(shardID uint64) (string, string, *meta.ShardGroupI func NewRetentionPolicy(name string, duration time.Duration, nodeCount int) *meta.RetentionPolicyInfo { shards := []meta.ShardInfo{} - owners := []meta.ShardOwner{} + ownerIDs := []uint64{} for i := 1; i <= nodeCount; i++ { - owners = append(owners, meta.ShardOwner{NodeID: uint64(i)}) + ownerIDs = append(ownerIDs, uint64(i)) } // each node is fully replicated with each other shards = append(shards, meta.ShardInfo{ - ID: nextShardID(), - Owners: owners, + ID: nextShardID(), + OwnerIDs: ownerIDs, }) rp := &meta.RetentionPolicyInfo{ @@ -436,7 +408,7 @@ func NewRetentionPolicy(name string, duration time.Duration, nodeCount int) *met return rp } -func AttachShardGroupInfo(rp *meta.RetentionPolicyInfo, owners []meta.ShardOwner) { +func AttachShardGroupInfo(rp *meta.RetentionPolicyInfo, ownerIDs []uint64) { var startTime, endTime time.Time if len(rp.ShardGroups) == 0 { startTime = time.Unix(0, 0) @@ -451,8 +423,8 @@ func AttachShardGroupInfo(rp *meta.RetentionPolicyInfo, owners []meta.ShardOwner EndTime: endTime, Shards: []meta.ShardInfo{ meta.ShardInfo{ - ID: nextShardID(), - Owners: owners, + ID: nextShardID(), + OwnerIDs: ownerIDs, }, }, } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/rpc.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/rpc.go index 09dcc4a1c..f3eca790c 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/rpc.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/rpc.go @@ -1,7 +1,6 @@ package cluster import ( - "fmt" "time" "github.com/gogo/protobuf/proto" @@ -111,9 +110,7 @@ func (w *WriteShardRequest) AddPoint(name string, value interface{}, timestamp t } func (w *WriteShardRequest) AddPoints(points []tsdb.Point) { - for _, p := range points { - w.pb.Points = append(w.pb.Points, []byte(p.String())) - } + w.pb.Points = append(w.pb.Points, w.marshalPoints(points)...) } // MarshalBinary encodes the object to a binary format. @@ -121,6 +118,55 @@ func (w *WriteShardRequest) MarshalBinary() ([]byte, error) { return proto.Marshal(&w.pb) } +func (w *WriteShardRequest) marshalPoints(points []tsdb.Point) []*internal.Point { + pts := make([]*internal.Point, len(points)) + for i, p := range points { + fields := []*internal.Field{} + for k, v := range p.Fields() { + name := k + f := &internal.Field{ + Name: &name, + } + switch t := v.(type) { + case int: + f.Int64 = proto.Int64(int64(t)) + case int32: + f.Int32 = proto.Int32(t) + case int64: + f.Int64 = proto.Int64(t) + case float64: + f.Float64 = proto.Float64(t) + case bool: + f.Bool = proto.Bool(t) + case string: + f.String_ = proto.String(t) + case []byte: + f.Bytes = t + } + fields = append(fields, f) + } + + tags := []*internal.Tag{} + for k, v := range p.Tags() { + key := k + value := v + tags = append(tags, &internal.Tag{ + Key: &key, + Value: &value, + }) + } + name := p.Name() + pts[i] = &internal.Point{ + Name: &name, + Time: proto.Int64(p.Time().UnixNano()), + Fields: fields, + Tags: tags, + } + + } + return pts +} + // UnmarshalBinary populates WritePointRequest from a binary format. func (w *WriteShardRequest) UnmarshalBinary(buf []byte) error { if err := proto.Unmarshal(buf, &w.pb); err != nil { @@ -132,14 +178,33 @@ func (w *WriteShardRequest) UnmarshalBinary(buf []byte) error { func (w *WriteShardRequest) unmarshalPoints() []tsdb.Point { points := make([]tsdb.Point, len(w.pb.GetPoints())) for i, p := range w.pb.GetPoints() { - pt, err := tsdb.ParsePoints(p) - if err != nil { - // A error here means that one node parsed the point correctly but sent an - // unparseable version to another node. We could log and drop the point and allow - // anti-entropy to resolve the discrepancy but this shouldn't ever happen. - panic(fmt.Sprintf("failed to parse point: `%v`: %v", string(p), err)) + pt := tsdb.NewPoint( + p.GetName(), map[string]string{}, + map[string]interface{}{}, time.Unix(0, p.GetTime())) + + for _, f := range p.GetFields() { + n := f.GetName() + if f.Int32 != nil { + pt.AddField(n, f.GetInt32()) + } else if f.Int64 != nil { + pt.AddField(n, f.GetInt64()) + } else if f.Float64 != nil { + pt.AddField(n, f.GetFloat64()) + } else if f.Bool != nil { + pt.AddField(n, f.GetBool()) + } else if f.String_ != nil { + pt.AddField(n, f.GetString_()) + } else { + pt.AddField(n, f.GetBytes()) + } } - points[i] = pt[0] + + tags := tsdb.Tags{} + for _, t := range p.GetTags() { + tags[t.GetKey()] = t.GetValue() + } + pt.SetTags(tags) + points[i] = pt } return points } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service.go index 325144929..896b0ce1e 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service.go @@ -11,7 +11,6 @@ import ( "strings" "sync" - "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/meta" "github.com/influxdb/influxdb/tsdb" ) @@ -38,7 +37,7 @@ type Service struct { TSDBStore interface { CreateShard(database, policy string, shardID uint64) error WriteToShard(shardID uint64, points []tsdb.Point) error - CreateMapper(shardID uint64, stmt influxql.Statement, chunkSize int) (tsdb.Mapper, error) + CreateMapper(shardID uint64, query string, chunkSize int) (tsdb.Mapper, error) } Logger *log.Logger @@ -108,7 +107,7 @@ func (s *Service) Close() error { // Shut down all handlers. close(s.closing) - s.wg.Wait() + // s.wg.Wait() // FIXME(benbjohnson) return nil } @@ -185,7 +184,7 @@ func (s *Service) processWriteShardRequest(buf []byte) error { // If we can't find it, then we need to drop this request // as it is no longer valid. This could happen if writes were queued via // hinted handoff and delivered after a shard group was deleted. - s.Logger.Printf("drop write request: shard=%d. shard group does not exist or was deleted", req.ShardID()) + s.Logger.Printf("drop write request: shard=%d", req.ShardID()) return nil } @@ -233,15 +232,7 @@ func (s *Service) processMapShardRequest(w io.Writer, buf []byte) error { return err } - // Parse the statement. - q, err := influxql.ParseQuery(req.Query()) - if err != nil { - return fmt.Errorf("processing map shard: %s", err) - } else if len(q.Statements) != 1 { - return fmt.Errorf("processing map shard: expected 1 statement but got %d", len(q.Statements)) - } - - m, err := s.TSDBStore.CreateMapper(req.ShardID(), q.Statements[0], int(req.ChunkSize())) + m, err := s.TSDBStore.CreateMapper(req.ShardID(), req.Query(), int(req.ChunkSize())) if err != nil { return fmt.Errorf("create mapper: %s", err) } @@ -268,10 +259,6 @@ func (s *Service) processMapShardRequest(w io.Writer, buf []byte) error { if err != nil { return fmt.Errorf("next chunk: %s", err) } - - // NOTE: Even if the chunk is nil, we still need to send one - // empty response to let the other side know we're out of data. - if chunk != nil { b, err := json.Marshal(chunk) if err != nil { diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service_test.go index 3006bc4fe..114135db8 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/service_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/influxdb/influxdb/cluster" - "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/meta" "github.com/influxdb/influxdb/tcp" "github.com/influxdb/influxdb/tsdb" @@ -29,7 +28,7 @@ type testService struct { muxln net.Listener writeShardFunc func(shardID uint64, points []tsdb.Point) error createShardFunc func(database, policy string, shardID uint64) error - createMapperFunc func(shardID uint64, stmt influxql.Statement, chunkSize int) (tsdb.Mapper, error) + createMapperFunc func(shardID uint64, query string, chunkSize int) (tsdb.Mapper, error) } func newTestWriteService(f func(shardID uint64, points []tsdb.Point) error) testService { @@ -70,8 +69,8 @@ func (t testService) CreateShard(database, policy string, shardID uint64) error return t.createShardFunc(database, policy, shardID) } -func (t testService) CreateMapper(shardID uint64, stmt influxql.Statement, chunkSize int) (tsdb.Mapper, error) { - return t.createMapperFunc(shardID, stmt, chunkSize) +func (t testService) CreateMapper(shardID uint64, query string, chunkSize int) (tsdb.Mapper, error) { + return t.createMapperFunc(shardID, query, chunkSize) } func writeShardSuccess(shardID uint64, points []tsdb.Point) error { diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper.go index 88000bde7..8756002d2 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper.go @@ -1,14 +1,16 @@ package cluster import ( + "encoding/json" "fmt" + "io" "math/rand" "net" "time" - "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/meta" "github.com/influxdb/influxdb/tsdb" + "gopkg.in/fatih/pool.v2" ) // ShardMapper is responsible for providing mappers for requested shards. It is @@ -23,7 +25,7 @@ type ShardMapper struct { } TSDBStore interface { - CreateMapper(shardID uint64, stmt influxql.Statement, chunkSize int) (tsdb.Mapper, error) + CreateMapper(shardID uint64, query string, chunkSize int) (tsdb.Mapper, error) } timeout time.Duration @@ -39,58 +41,67 @@ func NewShardMapper(timeout time.Duration) *ShardMapper { } // CreateMapper returns a Mapper for the given shard ID. -func (s *ShardMapper) CreateMapper(sh meta.ShardInfo, stmt influxql.Statement, chunkSize int) (tsdb.Mapper, error) { - m, err := s.TSDBStore.CreateMapper(sh.ID, stmt, chunkSize) - if err != nil { - return nil, err - } - - if !sh.OwnedBy(s.MetaStore.NodeID()) || s.ForceRemoteMapping { +func (s *ShardMapper) CreateMapper(sh meta.ShardInfo, stmt string, chunkSize int) (tsdb.Mapper, error) { + var err error + var m tsdb.Mapper + if sh.OwnedBy(s.MetaStore.NodeID()) && !s.ForceRemoteMapping { + m, err = s.TSDBStore.CreateMapper(sh.ID, stmt, chunkSize) + if err != nil { + return nil, err + } + } else { // Pick a node in a pseudo-random manner. - conn, err := s.dial(sh.Owners[rand.Intn(len(sh.Owners))].NodeID) + conn, err := s.dial(sh.OwnerIDs[rand.Intn(len(sh.OwnerIDs))]) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(s.timeout)) - m.SetRemote(NewRemoteMapper(conn, sh.ID, stmt, chunkSize)) + rm := NewRemoteMapper(conn.(*pool.PoolConn), sh.ID, stmt, chunkSize) + m = rm } return m, nil } func (s *ShardMapper) dial(nodeID uint64) (net.Conn, error) { - ni, err := s.MetaStore.Node(nodeID) - if err != nil { - return nil, err - } - conn, err := net.Dial("tcp", ni.Host) - if err != nil { - return nil, err - } + // If we don't have a connection pool for that addr yet, create one + _, ok := s.pool.getPool(nodeID) + if !ok { + factory := &connFactory{nodeID: nodeID, clientPool: s.pool, timeout: s.timeout} + factory.metaStore = s.MetaStore - // Write the cluster multiplexing header byte - conn.Write([]byte{MuxHeader}) + p, err := pool.NewChannelPool(1, 3, factory.dial) + if err != nil { + return nil, err + } + s.pool.setPool(nodeID, p) + } + return s.pool.conn(nodeID) +} - return conn, nil +type remoteShardConn interface { + io.ReadWriter + Close() error + MarkUnusable() } // RemoteMapper implements the tsdb.Mapper interface. It connects to a remote node, // sends a query, and interprets the stream of data that comes back. type RemoteMapper struct { shardID uint64 - stmt influxql.Statement + stmt string chunkSize int tagsets []string fields []string - conn net.Conn + conn remoteShardConn bufferedResponse *MapShardResponse } // NewRemoteMapper returns a new remote mapper using the given connection. -func NewRemoteMapper(c net.Conn, shardID uint64, stmt influxql.Statement, chunkSize int) *RemoteMapper { +func NewRemoteMapper(c remoteShardConn, shardID uint64, stmt string, chunkSize int) *RemoteMapper { return &RemoteMapper{ conn: c, shardID: shardID, @@ -109,7 +120,7 @@ func (r *RemoteMapper) Open() (err error) { // Build Map request. var request MapShardRequest request.SetShardID(r.shardID) - request.SetQuery(r.stmt.String()) + request.SetQuery(r.stmt) request.SetChunkSize(int32(r.chunkSize)) // Marshal into protocol buffers. @@ -120,12 +131,14 @@ func (r *RemoteMapper) Open() (err error) { // Write request. if err := WriteTLV(r.conn, mapShardRequestMessage, buf); err != nil { + r.conn.MarkUnusable() return err } // Read the response. _, buf, err = ReadTLV(r.conn) if err != nil { + r.conn.MarkUnusable() return err } @@ -141,15 +154,10 @@ func (r *RemoteMapper) Open() (err error) { // Decode the first response to get the TagSets. r.tagsets = r.bufferedResponse.TagSets() - r.fields = r.bufferedResponse.Fields() return nil } -func (r *RemoteMapper) SetRemote(m tsdb.Mapper) error { - return fmt.Errorf("cannot set remote mapper on a remote mapper") -} - func (r *RemoteMapper) TagSets() []string { return r.tagsets } @@ -160,7 +168,9 @@ func (r *RemoteMapper) Fields() []string { // NextChunk returns the next chunk read from the remote node to the client. func (r *RemoteMapper) NextChunk() (chunk interface{}, err error) { + output := &tsdb.MapperOutput{} var response *MapShardResponse + if r.bufferedResponse != nil { response = r.bufferedResponse r.bufferedResponse = nil @@ -170,6 +180,7 @@ func (r *RemoteMapper) NextChunk() (chunk interface{}, err error) { // Read the response. _, buf, err := ReadTLV(r.conn) if err != nil { + r.conn.MarkUnusable() return nil, err } @@ -186,8 +197,8 @@ func (r *RemoteMapper) NextChunk() (chunk interface{}, err error) { if response.Data() == nil { return nil, nil } - - return response.Data(), err + err = json.Unmarshal(response.Data(), output) + return output, err } // Close the Mapper diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper_test.go index 955735299..afb35ef15 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cluster/shard_mapper_test.go @@ -3,18 +3,14 @@ package cluster import ( "bytes" "encoding/json" - "fmt" "io" - "net" "testing" - "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/tsdb" ) // remoteShardResponder implements the remoteShardConn interface. type remoteShardResponder struct { - net.Conn t *testing.T rxBytes []byte @@ -43,7 +39,8 @@ func newRemoteShardResponder(outputs []*tsdb.MapperOutput, tagsets []string) *re return r } -func (r remoteShardResponder) Close() error { return nil } +func (r remoteShardResponder) MarkUnusable() { return } +func (r remoteShardResponder) Close() error { return nil } func (r remoteShardResponder) Read(p []byte) (n int, err error) { return io.ReadFull(r.buffer, p) } @@ -66,7 +63,7 @@ func TestShardWriter_RemoteMapper_Success(t *testing.T) { c := newRemoteShardResponder([]*tsdb.MapperOutput{expOutput, nil}, expTagSets) - r := NewRemoteMapper(c, 1234, mustParseStmt("SELECT * FROM CPU"), 10) + r := NewRemoteMapper(c, 1234, "SELECT * FROM CPU", 10) if err := r.Open(); err != nil { t.Fatalf("failed to open remote mapper: %s", err.Error()) } @@ -80,14 +77,10 @@ func TestShardWriter_RemoteMapper_Success(t *testing.T) { if err != nil { t.Fatalf("failed to get next chunk from mapper: %s", err.Error()) } - b, ok := chunk.([]byte) + output, ok := chunk.(*tsdb.MapperOutput) if !ok { t.Fatal("chunk is not of expected type") } - output := &tsdb.MapperOutput{} - if err := json.Unmarshal(b, output); err != nil { - t.Fatal(err) - } if output.Name != "cpu" { t.Fatalf("received output incorrect, exp: %v, got %v", expOutput, output) } @@ -101,14 +94,3 @@ func TestShardWriter_RemoteMapper_Success(t *testing.T) { t.Fatal("received more chunks when none expected") } } - -// mustParseStmt parses a single statement or panics. -func mustParseStmt(stmt string) influxql.Statement { - q, err := influxql.ParseQuery(stmt) - if err != nil { - panic(err) - } else if len(q.Statements) != 1 { - panic(fmt.Sprintf("expected 1 statement but got %d", len(q.Statements))) - } - return q.Statements[0] -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main.go index 06064eced..24af8efa4 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main.go @@ -17,7 +17,6 @@ import ( "text/tabwriter" "github.com/influxdb/influxdb/client" - "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/importer/v8" "github.com/peterh/liner" ) @@ -31,35 +30,30 @@ const ( // defaultFormat is the default format of the results when issuing queries defaultFormat = "column" - // defaultPrecision is the default timestamp format of the results when issuing queries - defaultPrecision = "ns" - // defaultPPS is the default points per second that the import will throttle at // by default it's 0, which means it will not throttle defaultPPS = 0 ) type CommandLine struct { - Client *client.Client - Line *liner.State - Host string - Port int - Username string - Password string - Database string - Ssl bool - RetentionPolicy string - Version string - Pretty bool // controls pretty print for json - Format string // controls the output format. Valid values are json, csv, or column - Precision string - WriteConsistency string - Execute string - ShowVersion bool - Import bool - PPS int // Controls how many points per second the import will allow via throttling - Path string - Compressed bool + Client *client.Client + Line *liner.State + Host string + Port int + Username string + Password string + Database string + Ssl bool + RetentionPolicy string + Version string + Pretty bool // controls pretty print for json + Format string // controls the output format. Valid values are json, csv, or column + Execute string + ShowVersion bool + Import bool + PPS int // Controls how many points per second the import will allow via throttling + Path string + Compressed bool } func main() { @@ -73,8 +67,6 @@ func main() { fs.StringVar(&c.Database, "database", c.Database, "Database to connect to the server.") fs.BoolVar(&c.Ssl, "ssl", false, "Use https for connecting to cluster.") fs.StringVar(&c.Format, "format", defaultFormat, "Format specifies the format of the server responses: json, csv, or column.") - fs.StringVar(&c.Precision, "precision", defaultPrecision, "Precision specifies the format of the timestamp: rfc3339,h,m,s,ms,u or ns.") - fs.StringVar(&c.WriteConsistency, "consistency", "any", "Set write consistency level: any, one, quorum, or all.") fs.BoolVar(&c.Pretty, "pretty", false, "Turns on pretty print for the json format.") fs.StringVar(&c.Execute, "execute", c.Execute, "Execute command and quit.") fs.BoolVar(&c.ShowVersion, "version", false, "Displays the InfluxDB version.") @@ -104,10 +96,6 @@ func main() { Execute command and quit. -format 'json|csv|column' Format specifies the format of the server responses: json, csv, or column. - -precision 'rfc3339|h|m|s|ms|u|ns' - Precision specifies the format of the timestamp: rfc3339, h, m, s, ms, u or ns. - -consistency 'any|one|quorum|all' - Set write consistency level: any, one, quorum, or all -pretty Turns on pretty print for the json format. -import @@ -165,8 +153,6 @@ Examples: } if c.Execute != "" { - // Modify precision before executing query - c.SetPrecision(c.Precision) if err := c.ExecuteQuery(c.Execute); err != nil { c.Line.Close() os.Exit(1) @@ -193,7 +179,6 @@ Examples: config.URL = u config.Compressed = c.Compressed config.PPS = c.PPS - config.Precision = c.Precision i := v8.NewImporter(config) if err := i.Import(); err != nil { @@ -259,10 +244,6 @@ func (c *CommandLine) ParseCommand(cmd string) bool { c.help() case strings.HasPrefix(lcmd, "format"): c.SetFormat(cmd) - case strings.HasPrefix(lcmd, "precision"): - c.SetPrecision(cmd) - case strings.HasPrefix(lcmd, "consistency"): - c.SetWriteConsistency(cmd) case strings.HasPrefix(lcmd, "settings"): c.Settings() case strings.HasPrefix(lcmd, "pretty"): @@ -307,7 +288,6 @@ func (c *CommandLine) connect(cmd string) error { config.Username = c.Username config.Password = c.Password config.UserAgent = "InfluxDBShell/" + version - config.Precision = c.Precision cl, err := client.NewClient(config) if err != nil { return fmt.Errorf("Could not create client %s", err) @@ -364,24 +344,6 @@ func (c *CommandLine) use(cmd string) { fmt.Printf("Using database %s\n", d) } -func (c *CommandLine) SetPrecision(cmd string) { - // Remove the "precision" keyword if it exists - cmd = strings.TrimSpace(strings.Replace(cmd, "precision", "", -1)) - // normalize cmd - cmd = strings.ToLower(cmd) - - switch cmd { - case "h", "m", "s", "ms", "u", "ns": - c.Precision = cmd - c.Client.SetPrecision(c.Precision) - case "rfc3339": - c.Precision = "" - c.Client.SetPrecision(c.Precision) - default: - fmt.Printf("Unknown precision %q. Please use rfc3339, h, m, s, ms, u or ns.\n", cmd) - } -} - func (c *CommandLine) SetFormat(cmd string) { // Remove the "format" keyword if it exists cmd = strings.TrimSpace(strings.Replace(cmd, "format", "", -1)) @@ -396,20 +358,6 @@ func (c *CommandLine) SetFormat(cmd string) { } } -func (c *CommandLine) SetWriteConsistency(cmd string) { - // Remove the "consistency" keyword if it exists - cmd = strings.TrimSpace(strings.Replace(cmd, "consistency", "", -1)) - // normalize cmd - cmd = strings.ToLower(cmd) - - _, err := cluster.ParseConsistencyLevel(cmd) - if err != nil { - fmt.Printf("Unknown consistency level %q. Please use any, one, quorum, or all.\n", cmd) - return - } - c.WriteConsistency = cmd -} - // isWhitespace returns true if the rune is a space, tab, or newline. func isWhitespace(ch rune) bool { return ch == ' ' || ch == '\t' || ch == '\n' } @@ -496,7 +444,7 @@ func (c *CommandLine) Insert(stmt string) error { Database: c.Database, RetentionPolicy: c.RetentionPolicy, Precision: "n", - WriteConsistency: c.WriteConsistency, + WriteConsistency: client.ConsistencyAny, }) if err != nil { fmt.Printf("ERR: %s\n", err) @@ -693,7 +641,6 @@ func (c *CommandLine) Settings() { fmt.Fprintf(w, "Database\t%s\n", c.Database) fmt.Fprintf(w, "Pretty\t%v\n", c.Pretty) fmt.Fprintf(w, "Format\t%s\n", c.Format) - fmt.Fprintf(w, "Write Consistency\t%s\n", c.WriteConsistency) fmt.Fprintln(w) w.Flush() } @@ -705,8 +652,6 @@ func (c *CommandLine) help() { pretty toggle pretty print use set current databases format set the output format: json, csv, or column - precision set the timestamp format: h,m,s,ms,u,ns - consistency set write consistency level: any, one, quorum, or all settings output the current settings for the shell exit quit the influx shell diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main_test.go index 045fa319e..eb58cb1e8 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx/main_test.go @@ -91,31 +91,6 @@ func TestParseCommand_Use(t *testing.T) { } } -func TestParseCommand_Consistency(t *testing.T) { - t.Parallel() - c := main.CommandLine{} - tests := []struct { - cmd string - }{ - {cmd: "consistency one"}, - {cmd: " consistency one"}, - {cmd: "consistency one "}, - {cmd: "consistency one;"}, - {cmd: "consistency one; "}, - {cmd: "Consistency one"}, - } - - for _, test := range tests { - if !c.ParseCommand(test.cmd) { - t.Fatalf(`Command "consistency" failed for %q.`, test.cmd) - } - - if c.WriteConsistency != "one" { - t.Fatalf(`Command "consistency" changed consistency to %q. Expected one`, c.WriteConsistency) - } - } -} - func TestParseCommand_Insert(t *testing.T) { t.Parallel() ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx_stress/influx_stress.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx_stress/influx_stress.go index 9292fb02d..7b9bc9873 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx_stress/influx_stress.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influx_stress/influx_stress.go @@ -3,11 +3,14 @@ package main import ( "flag" "fmt" + "math/rand" + "net/url" "runtime" "sort" + "sync" "time" - "github.com/influxdb/influxdb/stress" + "github.com/influxdb/influxdb/client" ) var ( @@ -18,50 +21,134 @@ var ( batchInterval = flag.Duration("batchinterval", 0*time.Second, "duration between batches") database = flag.String("database", "stress", "name of database") address = flag.String("addr", "localhost:8086", "IP address and port of database (e.g., localhost:8086)") - precision = flag.String("precision", "n", "The precision that points in the database will be with") ) -var ms runner.Measurements - -func init() { - flag.Var(&ms, "m", "comma-separated list of intervals to use between events") -} - func main() { flag.Parse() runtime.GOMAXPROCS(runtime.NumCPU()) - if len(ms) == 0 { - ms = append(ms, "cpu") + startTime := time.Now() + counter := NewConcurrencyLimiter(*concurrency) + + u, _ := url.Parse(fmt.Sprintf("http://%s", *address)) + c, err := client.NewClient(client.Config{URL: *u}) + if err != nil { + panic(err) } - cfg := &runner.Config{ - BatchSize: *batchSize, - Measurements: ms, - SeriesCount: *seriesCount, - PointCount: *pointCount, - Concurrency: *concurrency, - BatchInterval: *batchInterval, - Database: *database, - Address: *address, - Precision: *precision, + var mu sync.Mutex + var wg sync.WaitGroup + responseTimes := make([]int, 0) + + totalPoints := 0 + + batch := &client.BatchPoints{ + Database: *database, + WriteConsistency: "any", + Time: time.Now(), + Precision: "n", + } + for i := 1; i <= *pointCount; i++ { + for j := 1; j <= *seriesCount; j++ { + p := client.Point{ + Measurement: "cpu", + Tags: map[string]string{"region": "uswest", "host": fmt.Sprintf("host-%d", j)}, + Fields: map[string]interface{}{"value": rand.Float64()}, + } + batch.Points = append(batch.Points, p) + if len(batch.Points) >= *batchSize { + wg.Add(1) + counter.Increment() + totalPoints += len(batch.Points) + go func(b *client.BatchPoints, total int) { + st := time.Now() + if _, err := c.Write(*b); err != nil { + fmt.Println("ERROR: ", err.Error()) + } else { + mu.Lock() + responseTimes = append(responseTimes, int(time.Since(st).Nanoseconds())) + mu.Unlock() + } + wg.Done() + counter.Decrement() + if total%500000 == 0 { + fmt.Printf("%d total points. %d in %s\n", total, *batchSize, time.Since(st)) + } + }(batch, totalPoints) + + batch = &client.BatchPoints{ + Database: *database, + WriteConsistency: "any", + Precision: "n", + Time: time.Now(), + } + } + } } - totalPoints, failedRequests, responseTimes, timer := runner.Run(cfg) - - sort.Sort(sort.Reverse(sort.Interface(responseTimes))) + wg.Wait() + sort.Sort(sort.Reverse(sort.IntSlice(responseTimes))) total := int64(0) for _, t := range responseTimes { - total += int64(t.Value) + total += int64(t) } mean := total / int64(len(responseTimes)) - fmt.Printf("Wrote %d points at average rate of %.0f\n", totalPoints, float64(totalPoints)/timer.Elapsed().Seconds()) - fmt.Printf("%d requests failed for %d total points that didn't get posted.\n", failedRequests, failedRequests**batchSize) + fmt.Printf("Wrote %d points at average rate of %.0f\n", totalPoints, float64(totalPoints)/time.Since(startTime).Seconds()) fmt.Println("Average response time: ", time.Duration(mean)) fmt.Println("Slowest response times:") for _, r := range responseTimes[:100] { - fmt.Println(time.Duration(r.Value)) + fmt.Println(time.Duration(r)) + } +} + +// ConcurrencyLimiter is a go routine safe struct that can be used to +// ensure that no more than a specifid max number of goroutines are +// executing. +type ConcurrencyLimiter struct { + inc chan chan struct{} + dec chan struct{} + max int + count int +} + +// NewConcurrencyLimiter returns a configured limiter that will +// ensure that calls to Increment will block if the max is hit. +func NewConcurrencyLimiter(max int) *ConcurrencyLimiter { + c := &ConcurrencyLimiter{ + inc: make(chan chan struct{}), + dec: make(chan struct{}, max), + max: max, + } + go c.handleLimits() + return c +} + +// Increment will increase the count of running goroutines by 1. +// if the number is currently at the max, the call to Increment +// will block until another goroutine decrements. +func (c *ConcurrencyLimiter) Increment() { + r := make(chan struct{}) + c.inc <- r + <-r +} + +// Decrement will reduce the count of running goroutines by 1 +func (c *ConcurrencyLimiter) Decrement() { + c.dec <- struct{}{} +} + +// handleLimits runs in a goroutine to manage the count of +// running goroutines. +func (c *ConcurrencyLimiter) handleLimits() { + for { + r := <-c.inc + if c.count >= c.max { + <-c.dec + c.count-- + } + c.count++ + r <- struct{}{} } } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/command.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/command.go index 021435be2..629fd3eec 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/command.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/command.go @@ -66,15 +66,14 @@ func (cmd *Command) Run(args ...string) error { // Print sweet InfluxDB logo. fmt.Print(logo) - // Mark start-up in log. - log.Printf("InfluxDB starting, version %s, branch %s, commit %s", cmd.Version, cmd.Branch, cmd.Commit) - log.Printf("Go version %s, GOMAXPROCS set to %d", runtime.Version(), runtime.GOMAXPROCS(0)) - // Write the PID file. if err := cmd.writePIDFile(options.PIDFile); err != nil { return fmt.Errorf("write pid file: %s", err) } + // Set parallelism. + runtime.GOMAXPROCS(runtime.NumCPU()) + // Turn on block profiling to debug stuck databases runtime.SetBlockProfileRate(int(1 * time.Second)) @@ -104,8 +103,7 @@ func (cmd *Command) Run(args ...string) error { } // Create server from config and start it. - buildInfo := &BuildInfo{Version: cmd.Version, Commit: cmd.Commit, Branch: cmd.Branch} - s, err := NewServer(config, buildInfo) + s, err := NewServer(config, cmd.Version) if err != nil { return fmt.Errorf("create server: %s", err) } @@ -116,6 +114,10 @@ func (cmd *Command) Run(args ...string) error { } cmd.Server = s + // Mark start-up in log. + log.Printf("InfluxDB starting, version %s, branch %s, commit %s", cmd.Version, cmd.Branch, cmd.Commit) + log.Println("GOMAXPROCS set to", runtime.GOMAXPROCS(0)) + // Begin monitoring the server's error channel. go cmd.monitorServerErrors() @@ -188,11 +190,11 @@ func (cmd *Command) writePIDFile(path string) error { func (cmd *Command) ParseConfig(path string) (*Config, error) { // Use demo configuration if no config path is specified. if path == "" { - log.Println("no configuration provided, using default settings") + fmt.Fprintln(cmd.Stdout, "no configuration provided, using default settings") return NewDemoConfig() } - log.Printf("Using configuration at: %s\n", path) + fmt.Fprintf(cmd.Stdout, "Using configuration at: %s\n", path) config := NewConfig() if _, err := toml.DecodeFile(path, &config); err != nil { diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config.go index 0b35fd95b..77515ca60 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config.go @@ -13,13 +13,13 @@ import ( "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/meta" - "github.com/influxdb/influxdb/monitor" "github.com/influxdb/influxdb/services/admin" "github.com/influxdb/influxdb/services/collectd" "github.com/influxdb/influxdb/services/continuous_querier" "github.com/influxdb/influxdb/services/graphite" "github.com/influxdb/influxdb/services/hh" "github.com/influxdb/influxdb/services/httpd" + "github.com/influxdb/influxdb/services/monitor" "github.com/influxdb/influxdb/services/opentsdb" "github.com/influxdb/influxdb/services/precreator" "github.com/influxdb/influxdb/services/retention" @@ -36,7 +36,6 @@ type Config struct { Precreator precreator.Config `toml:"shard-precreation"` Admin admin.Config `toml:"admin"` - Monitor monitor.Config `toml:"monitor"` HTTPD httpd.Config `toml:"http"` Graphites []graphite.Config `toml:"graphite"` Collectd collectd.Config `toml:"collectd"` @@ -44,6 +43,7 @@ type Config struct { UDPs []udp.Config `toml:"udp"` // Snapshot SnapshotConfig `toml:"snapshot"` + Monitoring monitor.Config `toml:"monitoring"` ContinuousQuery continuous_querier.Config `toml:"continuous_queries"` HintedHandoff hh.Config `toml:"hinted-handoff"` @@ -61,11 +61,12 @@ func NewConfig() *Config { c.Precreator = precreator.NewConfig() c.Admin = admin.NewConfig() - c.Monitor = monitor.NewConfig() c.HTTPD = httpd.NewConfig() c.Collectd = collectd.NewConfig() c.OpenTSDB = opentsdb.NewConfig() + c.Graphites = append(c.Graphites, graphite.NewConfig()) + c.Monitoring = monitor.NewConfig() c.ContinuousQuery = continuous_querier.NewConfig() c.Retention = retention.NewConfig() c.HintedHandoff = hh.NewConfig() @@ -94,6 +95,7 @@ func NewDemoConfig() (*Config, error) { c.Data.WALDir = filepath.Join(homeDir, ".influxdb/wal") c.Admin.Enabled = true + c.Monitoring.Enabled = false return c, nil } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_command.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_command.go index 364cf61b3..8135aa014 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_command.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_command.go @@ -42,21 +42,11 @@ func (cmd *PrintConfigCommand) Run(args ...string) error { return fmt.Errorf("parse config: %s", err) } - // Apply any environment variables on top of the parsed config - if err := config.ApplyEnvOverrides(); err != nil { - return fmt.Errorf("apply env config: %v", err) - } - // Override config properties. if *hostname != "" { config.Meta.Hostname = *hostname } - // Validate the configuration. - if err := config.Validate(); err != nil { - return fmt.Errorf("%s. To generate a valid configuration file run `influxd config > influxdb.generated.conf`.", err) - } - toml.NewEncoder(cmd.Stdout).Encode(config) fmt.Fprint(cmd.Stdout, "\n") diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_test.go index 7ecbb4f65..ffcaf2533 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/config_test.go @@ -72,6 +72,8 @@ enabled = true t.Fatalf("unexpected opentsdb bind address: %s", c.OpenTSDB.BindAddress) } else if c.UDPs[0].BindAddress != ":4444" { t.Fatalf("unexpected udp bind address: %s", c.UDPs[0].BindAddress) + } else if c.Monitoring.Enabled != true { + t.Fatalf("unexpected monitoring enabled: %v", c.Monitoring.Enabled) } else if c.ContinuousQuery.Enabled != true { t.Fatalf("unexpected continuous query enabled: %v", c.ContinuousQuery.Enabled) } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server.go index 068868b36..ab65817d7 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server.go @@ -14,11 +14,9 @@ import ( "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/meta" - "github.com/influxdb/influxdb/monitor" "github.com/influxdb/influxdb/services/admin" "github.com/influxdb/influxdb/services/collectd" "github.com/influxdb/influxdb/services/continuous_querier" - "github.com/influxdb/influxdb/services/copier" "github.com/influxdb/influxdb/services/graphite" "github.com/influxdb/influxdb/services/hh" "github.com/influxdb/influxdb/services/httpd" @@ -32,18 +30,11 @@ import ( _ "github.com/influxdb/influxdb/tsdb/engine" ) -// BuildInfo represents the build details for the server code. -type BuildInfo struct { - Version string - Commit string - Branch string -} - // Server represents a container for the metadata and storage data and services. // It is built using a Config and it manages the startup and shutdown of all // services in the proper order. type Server struct { - buildInfo BuildInfo + version string // Build version err chan error closing chan struct{} @@ -65,9 +56,6 @@ type Server struct { // These references are required for the tcp muxer. ClusterService *cluster.Service SnapshotterService *snapshotter.Service - CopierService *copier.Service - - Monitor *monitor.Monitor // Server reporting reportingDisabled bool @@ -78,15 +66,15 @@ type Server struct { } // NewServer returns a new instance of Server built from a config. -func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) { +func NewServer(c *Config, version string) (*Server, error) { // Construct base meta store and data store. tsdbStore := tsdb.NewStore(c.Data.Dir) tsdbStore.EngineOptions.Config = c.Data s := &Server{ - buildInfo: *buildInfo, - err: make(chan error), - closing: make(chan struct{}), + version: version, + err: make(chan error), + closing: make(chan struct{}), Hostname: c.Meta.Hostname, BindAddress: c.Meta.BindAddress, @@ -94,8 +82,6 @@ func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) { MetaStore: meta.NewStore(c.Meta), TSDBStore: tsdbStore, - Monitor: monitor.New(c.Monitor), - reportingDisabled: c.ReportingDisabled, } @@ -114,7 +100,6 @@ func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) { s.QueryExecutor = tsdb.NewQueryExecutor(s.TSDBStore) s.QueryExecutor.MetaStore = s.MetaStore s.QueryExecutor.MetaStatementExecutor = &meta.StatementExecutor{Store: s.MetaStore} - s.QueryExecutor.MonitorStatementExecutor = &monitor.StatementExecutor{Monitor: s.Monitor} s.QueryExecutor.ShardMapper = s.ShardMapper // Set the shard writer @@ -132,18 +117,10 @@ func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) { s.PointsWriter.ShardWriter = s.ShardWriter s.PointsWriter.HintedHandoff = s.HintedHandoff - // Initialize the monitor - s.Monitor.Version = s.buildInfo.Version - s.Monitor.Commit = s.buildInfo.Commit - s.Monitor.Branch = s.buildInfo.Branch - s.Monitor.MetaStore = s.MetaStore - s.Monitor.PointsWriter = s.PointsWriter - // Append services. s.appendClusterService(c.Cluster) s.appendPrecreatorService(c.Precreator) s.appendSnapshotterService() - s.appendCopierService() s.appendAdminService(c.Admin) s.appendContinuousQueryService(c.ContinuousQuery) s.appendHTTPDService(c.HTTPD) @@ -180,13 +157,6 @@ func (s *Server) appendSnapshotterService() { s.SnapshotterService = srv } -func (s *Server) appendCopierService() { - srv := copier.NewService() - srv.TSDBStore = s.TSDBStore - s.Services = append(s.Services, srv) - s.CopierService = srv -} - func (s *Server) appendRetentionPolicyService(c retention.Config) { if !c.Enabled { return @@ -213,7 +183,7 @@ func (s *Server) appendHTTPDService(c httpd.Config) { srv.Handler.MetaStore = s.MetaStore srv.Handler.QueryExecutor = s.QueryExecutor srv.Handler.PointsWriter = s.PointsWriter - srv.Handler.Version = s.buildInfo.Version + srv.Handler.Version = s.version // If a ContinuousQuerier service has been started, attach it. for _, srvc := range s.Services { @@ -260,7 +230,6 @@ func (s *Server) appendGraphiteService(c graphite.Config) error { srv.PointsWriter = s.PointsWriter srv.MetaStore = s.MetaStore - srv.Monitor = s.Monitor s.Services = append(s.Services, srv) return nil } @@ -341,7 +310,6 @@ func (s *Server) Open() error { s.ClusterService.Listener = mux.Listen(cluster.MuxHeader) s.SnapshotterService.Listener = mux.Listen(snapshotter.MuxHeader) - s.CopierService.Listener = mux.Listen(copier.MuxHeader) go mux.Serve(ln) // Open meta store. @@ -353,10 +321,6 @@ func (s *Server) Open() error { // Wait for the store to initialize. <-s.MetaStore.Ready() - if err := s.Monitor.Open(); err != nil { - return fmt.Errorf("open monitor: %v", err) - } - // Open TSDB store. if err := s.TSDBStore.Open(); err != nil { return fmt.Errorf("open tsdb store: %s", err) @@ -392,33 +356,20 @@ func (s *Server) Open() error { func (s *Server) Close() error { stopProfile() - // Close the listener first to stop any new connections if s.Listener != nil { s.Listener.Close() } - - // Close services to allow any inflight requests to complete - // and prevent new requests from being accepted. - for _, service := range s.Services { - service.Close() + if s.MetaStore != nil { + s.MetaStore.Close() } - - if s.Monitor != nil { - s.Monitor.Close() - } - - if s.HintedHandoff != nil { - s.HintedHandoff.Close() - } - - // Close the TSDBStore, no more reads or writes at this point if s.TSDBStore != nil { s.TSDBStore.Close() } - - // Finally close the meta-store since everything else depends on it - if s.MetaStore != nil { - s.MetaStore.Close() + if s.HintedHandoff != nil { + s.HintedHandoff.Close() + } + for _, service := range s.Services { + service.Close() } close(s.closing) @@ -475,7 +426,7 @@ func (s *Server) reportServer() { "name":"reports", "columns":["os", "arch", "version", "server_id", "cluster_id", "num_series", "num_measurements", "num_databases"], "points":[["%s", "%s", "%s", "%x", "%x", "%d", "%d", "%d"]] - }]`, runtime.GOOS, runtime.GOARCH, s.buildInfo.Version, s.MetaStore.NodeID(), clusterID, numSeries, numMeasurements, numDatabases) + }]`, runtime.GOOS, runtime.GOARCH, s.version, s.MetaStore.NodeID(), clusterID, numSeries, numMeasurements, numDatabases) data := bytes.NewBufferString(json) diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_helpers_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_helpers_test.go index aeb81826d..adabdc19e 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_helpers_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_helpers_test.go @@ -2,7 +2,6 @@ package run_test import ( - "bytes" "encoding/json" "fmt" "io" @@ -31,12 +30,7 @@ type Server struct { // NewServer returns a new instance of Server. func NewServer(c *run.Config) *Server { - buildInfo := &run.BuildInfo{ - Version: "testServer", - Commit: "testCommit", - Branch: "testBranch", - } - srv, _ := run.NewServer(c, buildInfo) + srv, _ := run.NewServer(c, "testServer") s := Server{ Server: srv, Config: c, @@ -59,12 +53,7 @@ func OpenServer(c *run.Config, joinURLs string) *Server { // OpenServerWithVersion opens a test server with a specific version. func OpenServerWithVersion(c *run.Config, version string) *Server { - buildInfo := &run.BuildInfo{ - Version: version, - Commit: "", - Branch: "", - } - srv, _ := run.NewServer(c, buildInfo) + srv, _ := run.NewServer(c, version) s := Server{ Server: srv, Config: c, @@ -116,14 +105,10 @@ func (s *Server) QueryWithParams(query string, values url.Values) (results strin values = url.Values{} } values.Set("q", query) - return s.HTTPGet(s.URL() + "/query?" + values.Encode()) -} - -// HTTPGet makes an HTTP GET request to the server and returns the response. -func (s *Server) HTTPGet(url string) (results string, err error) { - resp, err := http.Get(url) + resp, err := http.Get(s.URL() + "/query?" + values.Encode()) if err != nil { return "", err + //} else if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusBadRequest { } body := string(MustReadAll(resp.Body)) switch resp.StatusCode { @@ -139,27 +124,6 @@ func (s *Server) HTTPGet(url string) (results string, err error) { } } -// HTTPPost makes an HTTP POST request to the server and returns the response. -func (s *Server) HTTPPost(url string, content []byte) (results string, err error) { - buf := bytes.NewBuffer(content) - resp, err := http.Post(url, "application/json", buf) - if err != nil { - return "", err - } - body := string(MustReadAll(resp.Body)) - switch resp.StatusCode { - case http.StatusBadRequest: - if !expectPattern(".*error parsing query*.", body) { - return "", fmt.Errorf("unexpected status code: code=%d, body=%s", resp.StatusCode, body) - } - return body, nil - case http.StatusOK, http.StatusNoContent: - return body, nil - default: - return "", fmt.Errorf("unexpected status code: code=%d, body=%s", resp.StatusCode, body) - } -} - // Write executes a write against the server and returns the results. func (s *Server) Write(db, rp, body string, params url.Values) (results string, err error) { if params == nil { @@ -184,8 +148,6 @@ func (s *Server) Write(db, rp, body string, params url.Values) (results string, func NewConfig() *run.Config { c := run.NewConfig() c.ReportingDisabled = true - c.Cluster.ShardWriterTimeout = toml.Duration(30 * time.Second) - c.Cluster.WriteTimeout = toml.Duration(30 * time.Second) c.Meta.Dir = MustTempFile() c.Meta.BindAddress = "127.0.0.1:0" c.Meta.HeartbeatTimeout = toml.Duration(50 * time.Millisecond) @@ -195,7 +157,6 @@ func NewConfig() *run.Config { c.Data.Dir = MustTempFile() c.Data.WALDir = MustTempFile() - c.Data.WALLoggingEnabled = false c.HintedHandoff.Dir = MustTempFile() @@ -203,8 +164,6 @@ func NewConfig() *run.Config { c.HTTPD.BindAddress = "127.0.0.1:0" c.HTTPD.LogEnabled = testing.Verbose() - c.Monitor.StoreEnabled = false - return c } @@ -273,7 +232,6 @@ type Query struct { exp, act string pattern bool skip bool - repeat int } // Execute runs the command and returns an err if it fails @@ -345,8 +303,6 @@ func configureLogging(s *Server) { s.MetaStore.Logger = nullLogger s.TSDBStore.Logger = nullLogger s.HintedHandoff.SetLogger(nullLogger) - s.Monitor.SetLogger(nullLogger) - s.QueryExecutor.SetLogger(nullLogger) for _, service := range s.Services { if service, ok := service.(logSetter); ok { service.SetLogger(nullLogger) diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_test.go index 6639f378f..10d67c7de 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/influxd/run/server_test.go @@ -52,30 +52,10 @@ func TestServer_DatabaseCommands(t *testing.T) { exp: `{"results":[{"error":"database already exists"}]}`, }, &Query{ - name: "create database should not error with existing database with IF NOT EXISTS", - command: `CREATE DATABASE IF NOT EXISTS db0`, - exp: `{"results":[{}]}`, - }, - &Query{ - name: "create database should create non-existing database with IF NOT EXISTS", - command: `CREATE DATABASE IF NOT EXISTS db1`, - exp: `{"results":[{}]}`, - }, - &Query{ - name: "show database should succeed", - command: `SHOW DATABASES`, - exp: `{"results":[{"series":[{"name":"databases","columns":["name"],"values":[["db0"],["db1"]]}]}]}`, - }, - &Query{ - name: "drop database db0 should succeed", + name: "drop database should succeed", command: `DROP DATABASE db0`, exp: `{"results":[{}]}`, }, - &Query{ - name: "drop database db1 should succeed", - command: `DROP DATABASE db1`, - exp: `{"results":[{}]}`, - }, &Query{ name: "show database should have no results", command: `SHOW DATABASES`, @@ -370,34 +350,14 @@ func TestServer_RetentionPolicyCommands(t *testing.T) { exp: `{"results":[{"series":[{"columns":["name","duration","replicaN","default"],"values":[["rp0","2h0m0s",3,true]]}]}]}`, }, &Query{ - name: "dropping default retention policy should not succeed", + name: "drop retention policy should succeed", command: `DROP RETENTION POLICY rp0 ON db0`, - exp: `{"results":[{"error":"retention policy is default"}]}`, - }, - &Query{ - name: "show retention policy should still show policy", - command: `SHOW RETENTION POLICIES ON db0`, - exp: `{"results":[{"series":[{"columns":["name","duration","replicaN","default"],"values":[["rp0","2h0m0s",3,true]]}]}]}`, - }, - &Query{ - name: "create a second non-default retention policy", - command: `CREATE RETENTION POLICY rp2 ON db0 DURATION 1h REPLICATION 1`, exp: `{"results":[{}]}`, }, &Query{ - name: "show retention policy should show both", + name: "show retention policy should be empty after dropping them", command: `SHOW RETENTION POLICIES ON db0`, - exp: `{"results":[{"series":[{"columns":["name","duration","replicaN","default"],"values":[["rp0","2h0m0s",3,true],["rp2","1h0m0s",1,false]]}]}]}`, - }, - &Query{ - name: "dropping non-default retention policy succeed", - command: `DROP RETENTION POLICY rp2 ON db0`, - exp: `{"results":[{}]}`, - }, - &Query{ - name: "show retention policy should show just default", - command: `SHOW RETENTION POLICIES ON db0`, - exp: `{"results":[{"series":[{"columns":["name","duration","replicaN","default"],"values":[["rp0","2h0m0s",3,true]]}]}]}`, + exp: `{"results":[{"series":[{"columns":["name","duration","replicaN","default"]}]}]}`, }, &Query{ name: "Ensure retention policy with unacceptable retention cannot be created", @@ -1013,7 +973,7 @@ func TestServer_Query_Count(t *testing.T) { &Query{ name: "selecting count(*) should error", command: `SELECT count(*) FROM db0.rp0.cpu`, - exp: `{"error":"error parsing query: expected field argument in count()"}`, + exp: `{"results":[{"error":"expected field argument in count()"}]}`, }, }...) @@ -2221,348 +2181,6 @@ func TestServer_Query_Aggregates(t *testing.T) { command: `SELECT sum(value)/2 FROM load`, exp: `{"results":[{"series":[{"name":"load","columns":["time",""],"values":[["1970-01-01T00:00:00Z",75]]}]}]}`, }, - - // order by time desc - &Query{ - name: "aggregate order by time desc", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT max(value) FROM intmany where time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T00:01:00Z' group by time(10s) order by time desc`, - exp: `{"results":[{"series":[{"name":"intmany","columns":["time","max"],"values":[["2000-01-01T00:01:00Z",7],["2000-01-01T00:00:50Z",5],["2000-01-01T00:00:40Z",5],["2000-01-01T00:00:30Z",4],["2000-01-01T00:00:20Z",4],["2000-01-01T00:00:10Z",4],["2000-01-01T00:00:00Z",2]]}]}]}`, - }, - }...) - - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP:: %s", query.name) - continue - } - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } -} - -func TestServer_Query_AggregatesTopInt(t *testing.T) { - t.Parallel() - s := OpenServer(NewConfig(), "") - defer s.Close() - - if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 0)); err != nil { - t.Fatal(err) - } - if err := s.MetaStore.SetDefaultRetentionPolicy("db0", "rp0"); err != nil { - t.Fatal(err) - } - - writes := []string{ - // cpu data with overlapping duplicate values - // hour 0 - fmt.Sprintf(`cpu,host=server01 value=2.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`cpu,host=server02 value=3.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), - fmt.Sprintf(`cpu,host=server03 value=4.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), - // hour 1 - fmt.Sprintf(`cpu,host=server04 value=5.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), - fmt.Sprintf(`cpu,host=server05 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:10Z").UnixNano()), - fmt.Sprintf(`cpu,host=server06 value=6.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:20Z").UnixNano()), - // hour 2 - fmt.Sprintf(`cpu,host=server07 value=7.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), - fmt.Sprintf(`cpu,host=server08 value=9.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:10Z").UnixNano()), - - // memory data - // hour 0 - fmt.Sprintf(`memory,host=a,service=redis value=1000i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`memory,host=b,service=mysql value=2000i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`memory,host=b,service=redis value=1500i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - // hour 1 - fmt.Sprintf(`memory,host=a,service=redis value=1001i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), - fmt.Sprintf(`memory,host=b,service=mysql value=2001i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), - fmt.Sprintf(`memory,host=b,service=redis value=1501i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T01:00:00Z").UnixNano()), - // hour 2 - fmt.Sprintf(`memory,host=a,service=redis value=1002i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), - fmt.Sprintf(`memory,host=b,service=mysql value=2002i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), - fmt.Sprintf(`memory,host=b,service=redis value=1502i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T02:00:00Z").UnixNano()), - } - - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") - - test.addQueries([]*Query{ - &Query{ - name: "top - cpu", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 1) FROM cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - 2 values", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 2) FROM cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - 3 values - sorts on tie properly", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 3) FROM cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - with tag", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, host, 2) FROM cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top","host"],"values":[["2000-01-01T01:00:10Z",7,"server05"],["2000-01-01T02:00:10Z",9,"server08"]]}]}]}`, - }, - &Query{ - name: "top - cpu - 3 values with limit 2", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 3) FROM cpu limit 2`, - exp: `{"error":"error parsing query: limit (3) in top function can not be larger than the LIMIT (2) in the select statement"}`, - }, - &Query{ - name: "top - cpu - hourly", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 1) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T01:00:00Z",7],["2000-01-01T02:00:00Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - time specified - hourly", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT time, TOP(value, 1) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - time specified (not first) - hourly", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 1), time FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:10Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - 2 values hourly", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 2) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T00:00:00Z",3],["2000-01-01T01:00:00Z",7],["2000-01-01T01:00:00Z",6],["2000-01-01T02:00:00Z",9],["2000-01-01T02:00:00Z",7]]}]}]}`, - }, - &Query{ - name: "top - cpu - time specified - 2 values hourly", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 2), time FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:10Z",3],["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:10Z",7],["2000-01-01T01:00:20Z",6],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - cpu - 3 values hourly - validates that a bucket can have less than limit if no values exist in that time bucket", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 3) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:00Z",4],["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:00Z",2],["2000-01-01T01:00:00Z",7],["2000-01-01T01:00:00Z",6],["2000-01-01T01:00:00Z",5],["2000-01-01T02:00:00Z",9],["2000-01-01T02:00:00Z",7]]}]}]}`, - }, - &Query{ - name: "top - cpu - time specified - 3 values hourly - validates that a bucket can have less than limit if no values exist in that time bucket", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 3), time FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T02:00:10Z' group by time(1h)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","top"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:10Z",3],["2000-01-01T00:00:20Z",4],["2000-01-01T01:00:00Z",5],["2000-01-01T01:00:10Z",7],["2000-01-01T01:00:20Z",6],["2000-01-01T02:00:00Z",7],["2000-01-01T02:00:10Z",9]]}]}]}`, - }, - &Query{ - name: "top - memory - 2 values, two tags", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, 2), host, service FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T01:00:00Z",2001,"b","mysql"],["2000-01-01T02:00:00Z",2002,"b","mysql"]]}]}]}`, - }, - &Query{ - name: "top - memory - host tag with limit 2", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, host, 2) FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","host"],"values":[["2000-01-01T02:00:00Z",2002,"b"],["2000-01-01T02:00:00Z",1002,"a"]]}]}]}`, - }, - &Query{ - name: "top - memory - host tag with limit 2, service tag in select", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, host, 2), service FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1002,"a","redis"]]}]}]}`, - }, - &Query{ - name: "top - memory - service tag with limit 2, host tag in select", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, service, 2), host FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","service","host"],"values":[["2000-01-01T02:00:00Z",2002,"mysql","b"],["2000-01-01T02:00:00Z",1502,"redis","b"]]}]}]}`, - }, - &Query{ - name: "top - memory - host and service tag with limit 2", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, host, service, 2) FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1502,"b","redis"]]}]}]}`, - }, - &Query{ - name: "top - memory - host tag with limit 2 with service tag in select", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, host, 2), service FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1002,"a","redis"]]}]}]}`, - }, - &Query{ - name: "top - memory - host and service tag with limit 3", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT TOP(value, host, service, 3) FROM memory`, - exp: `{"results":[{"series":[{"name":"memory","columns":["time","top","host","service"],"values":[["2000-01-01T02:00:00Z",2002,"b","mysql"],["2000-01-01T02:00:00Z",1502,"b","redis"],["2000-01-01T02:00:00Z",1002,"a","redis"]]}]}]}`, - }, - - // TODO - // - Test that specifiying fields or tags in the function will rewrite the query to expand them to the fields - // - Test that a field can be used in the top function - // - Test that asking for a field will come back before a tag if they have the same name for a tag and a field - // - Test that `select top(value, host, 2)` when there is only one value for `host` it will only bring back one value - // - Test that `select top(value, host, 4) from foo where time > now() - 1d and time < now() group by time(1h)` and host is unique in some time buckets that it returns only the unique ones, and not always 4 values - - }...) - - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP: %s", query.name) - continue - } - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } -} - -// Test various aggregates when different series only have data for the same timestamp. -func TestServer_Query_AggregatesIdenticalTime(t *testing.T) { - t.Parallel() - s := OpenServer(NewConfig(), "") - defer s.Close() - - if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 0)); err != nil { - t.Fatal(err) - } - if err := s.MetaStore.SetDefaultRetentionPolicy("db0", "rp0"); err != nil { - t.Fatal(err) - } - - writes := []string{ - fmt.Sprintf(`series,host=a value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=b value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=c value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=d value=4 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=e value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=f value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=g value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=h value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`series,host=i value=5 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - } - - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") - - test.addQueries([]*Query{ - &Query{ - name: "last from multiple series with identical timestamp", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT last(value) FROM "series"`, - exp: `{"results":[{"series":[{"name":"series","columns":["time","last"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`, - repeat: 100, - }, - &Query{ - name: "first from multiple series with identical timestamp", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT first(value) FROM "series"`, - exp: `{"results":[{"series":[{"name":"series","columns":["time","first"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`, - repeat: 100, - }, - }...) - - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP:: %s", query.name) - continue - } - for n := 0; n <= query.repeat; n++ { - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } - } -} - -// This will test that when using a group by, that it observes the time you asked for -// but will only put the values in the bucket that match the time range -func TestServer_Query_GroupByTimeCutoffs(t *testing.T) { - t.Parallel() - s := OpenServer(NewConfig(), "") - defer s.Close() - - if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 0)); err != nil { - t.Fatal(err) - } - if err := s.MetaStore.SetDefaultRetentionPolicy("db0", "rp0"); err != nil { - t.Fatal(err) - } - - writes := []string{ - fmt.Sprintf(`cpu value=1i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`cpu value=2i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), - fmt.Sprintf(`cpu value=3i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:05Z").UnixNano()), - fmt.Sprintf(`cpu value=4i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:08Z").UnixNano()), - fmt.Sprintf(`cpu value=5i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:09Z").UnixNano()), - fmt.Sprintf(`cpu value=6i %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), - } - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") - - test.addQueries([]*Query{ - &Query{ - name: "sum all time", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT SUM(value) FROM cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","sum"],"values":[["1970-01-01T00:00:00Z",21]]}]}]}`, - }, - &Query{ - name: "sum all time grouped by time 5s", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T00:00:10Z' group by time(5s)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:05Z",12],["2000-01-01T00:00:10Z",6]]}]}]}`, - }, - &Query{ - name: "sum all time grouped by time 5s missing first point", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:01Z' and time <= '2000-01-01T00:00:10Z' group by time(5s)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",2],["2000-01-01T00:00:05Z",12],["2000-01-01T00:00:10Z",6]]}]}]}`, - }, - &Query{ - name: "sum all time grouped by time 5s missing first points (null for bucket)", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:02Z' and time <= '2000-01-01T00:00:10Z' group by time(5s)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",null],["2000-01-01T00:00:05Z",12],["2000-01-01T00:00:10Z",6]]}]}]}`, - }, - &Query{ - name: "sum all time grouped by time 5s missing last point - 2 time intervals", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T00:00:09Z' group by time(5s)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:05Z",12]]}]}]}`, - }, - &Query{ - name: "sum all time grouped by time 5s missing last 2 points - 2 time intervals", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT SUM(value) FROM cpu where time >= '2000-01-01T00:00:00Z' and time <= '2000-01-01T00:00:08Z' group by time(5s)`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","sum"],"values":[["2000-01-01T00:00:00Z",3],["2000-01-01T00:00:05Z",7]]}]}]}`, - }, }...) for i, query := range test.queries { @@ -2718,9 +2336,6 @@ func TestServer_Query_Wildcards(t *testing.T) { fmt.Sprintf(`wgroup,region=us-east value=10.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), fmt.Sprintf(`wgroup,region=us-east value=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:10Z").UnixNano()), fmt.Sprintf(`wgroup,region=us-west value=30.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:20Z").UnixNano()), - - fmt.Sprintf(`m1,region=us-east value=10.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - fmt.Sprintf(`m2,host=server01 field=20.0 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), } test := NewTest("db0", "rp0") @@ -2751,48 +2366,6 @@ func TestServer_Query_Wildcards(t *testing.T) { command: `SELECT mean(value) FROM wgroup WHERE time >= '2000-01-01T00:00:00Z' AND time < '2000-01-01T00:01:00Z' GROUP BY *,TIME(1m)`, exp: `{"results":[{"series":[{"name":"wgroup","tags":{"region":"us-east"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",15]]},{"name":"wgroup","tags":{"region":"us-west"},"columns":["time","mean"],"values":[["2000-01-01T00:00:00Z",30]]}]}]}`, }, - &Query{ - name: "wildcard and field in select", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT value, * FROM wildcard`, - exp: `{"results":[{"series":[{"name":"wildcard","columns":["time","region","value","valx"],"values":[["2000-01-01T00:00:00Z","us-east",10,null],["2000-01-01T00:00:10Z","us-east",null,20],["2000-01-01T00:00:20Z","us-east",30,40]]}]}]}`, - }, - &Query{ - name: "field and wildcard in select", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT value, * FROM wildcard`, - exp: `{"results":[{"series":[{"name":"wildcard","columns":["time","region","value","valx"],"values":[["2000-01-01T00:00:00Z","us-east",10,null],["2000-01-01T00:00:10Z","us-east",null,20],["2000-01-01T00:00:20Z","us-east",30,40]]}]}]}`, - }, - &Query{ - name: "field and wildcard in group by", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT * FROM wildcard GROUP BY region, *`, - exp: `{"results":[{"series":[{"name":"wildcard","tags":{"region":"us-east"},"columns":["time","value","valx"],"values":[["2000-01-01T00:00:00Z",10,null],["2000-01-01T00:00:10Z",null,20],["2000-01-01T00:00:20Z",30,40]]}]}]}`, - }, - &Query{ - name: "wildcard and field in group by", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT * FROM wildcard GROUP BY *, region`, - exp: `{"results":[{"series":[{"name":"wildcard","tags":{"region":"us-east"},"columns":["time","value","valx"],"values":[["2000-01-01T00:00:00Z",10,null],["2000-01-01T00:00:10Z",null,20],["2000-01-01T00:00:20Z",30,40]]}]}]}`, - }, - &Query{ - name: "wildcard with multiple measurements", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT * FROM m1, m2`, - exp: `{"results":[{"series":[{"name":"m1","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:00Z",null,null,"us-east",10]]},{"name":"m2","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:01Z",20,"server01",null,null]]}]}]}`, - }, - &Query{ - name: "wildcard with multiple measurements via regex", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT * FROM /^m.*/`, - exp: `{"results":[{"series":[{"name":"m1","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:00Z",null,null,"us-east",10]]},{"name":"m2","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:01Z",20,"server01",null,null]]}]}]}`, - }, - &Query{ - name: "wildcard with multiple measurements via regex and limit", - params: url.Values{"db": []string{"db0"}}, - command: `SELECT * FROM db0../^m.*/ LIMIT 2`, - exp: `{"results":[{"series":[{"name":"m1","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:00Z",null,null,"us-east",10]]},{"name":"m2","columns":["time","field","host","region","value"],"values":[["2000-01-01T00:00:01Z",20,"server01",null,null]]}]}]}`, - }, }...) for i, query := range test.queries { @@ -3973,8 +3546,7 @@ func TestServer_Query_ShowFieldKeys(t *testing.T) { } } -func TestServer_ContinuousQuery(t *testing.T) { - t.Skip() +func TestServer_Query_CreateContinuousQuery(t *testing.T) { t.Parallel() s := OpenServer(NewConfig(), "") defer s.Close() @@ -3986,112 +3558,37 @@ func TestServer_ContinuousQuery(t *testing.T) { t.Fatal(err) } - runTest := func(test *Test, t *testing.T) { - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP:: %s", query.name) - continue - } - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } - } - - // Start times of CQ intervals. - interval0 := time.Now().Add(-time.Second).Round(time.Second * 5) - interval1 := interval0.Add(-time.Second * 5) - interval2 := interval0.Add(-time.Second * 10) - interval3 := interval0.Add(-time.Second * 15) - - writes := []string{ - // Point too far in the past for CQ to pick up. - fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, interval3.Add(time.Second).UnixNano()), - - // Points two intervals ago. - fmt.Sprintf(`cpu,host=server01 value=100 %d`, interval2.Add(time.Second).UnixNano()), - fmt.Sprintf(`cpu,host=server01,region=uswest value=100 %d`, interval2.Add(time.Second*2).UnixNano()), - fmt.Sprintf(`cpu,host=server01,region=useast value=100 %d`, interval2.Add(time.Second*3).UnixNano()), - - // Points one interval ago. - fmt.Sprintf(`gpu,host=server02,region=useast value=100 %d`, interval1.Add(time.Second).UnixNano()), - fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, interval1.Add(time.Second*2).UnixNano()), - - // Points in the current interval. - fmt.Sprintf(`gpu,host=server03,region=caeast value=100 %d`, interval0.Add(time.Second).UnixNano()), - fmt.Sprintf(`disk,host=server03,region=caeast value=100 %d`, interval0.Add(time.Second*2).UnixNano()), - } - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") + test.addQueries([]*Query{ &Query{ - name: `create another retention policy for CQ to write into`, - command: `CREATE RETENTION POLICY rp1 ON db0 DURATION 1h REPLICATION 1`, - exp: `{"results":[{}]}`, - }, - &Query{ - name: "create continuous query with backreference", - command: `CREATE CONTINUOUS QUERY "cq1" ON db0 BEGIN SELECT count(value) INTO "rp1".:MEASUREMENT FROM /[cg]pu/ GROUP BY time(5s) END`, - exp: `{"results":[{}]}`, - }, - &Query{ - name: `create another retention policy for CQ to write into`, - command: `CREATE RETENTION POLICY rp2 ON db0 DURATION 1h REPLICATION 1`, - exp: `{"results":[{}]}`, - }, - &Query{ - name: "create continuous query with backreference and group by time", - command: `CREATE CONTINUOUS QUERY "cq2" ON db0 BEGIN SELECT count(value) INTO "rp2".:MEASUREMENT FROM /[cg]pu/ GROUP BY time(5s), * END`, + name: "create continuous query", + command: `CREATE CONTINUOUS QUERY "my.query" ON db0 BEGIN SELECT count(value) INTO measure1 FROM myseries GROUP BY time(10m) END`, exp: `{"results":[{}]}`, }, &Query{ name: `show continuous queries`, command: `SHOW CONTINUOUS QUERIES`, - exp: `{"results":[{"series":[{"name":"db0","columns":["name","query"],"values":[["cq1","CREATE CONTINUOUS QUERY cq1 ON db0 BEGIN SELECT count(value) INTO \"db0\".\"rp1\".:MEASUREMENT FROM \"db0\".\"rp0\"./[cg]pu/ GROUP BY time(5s) END"],["cq2","CREATE CONTINUOUS QUERY cq2 ON db0 BEGIN SELECT count(value) INTO \"db0\".\"rp2\".:MEASUREMENT FROM \"db0\".\"rp0\"./[cg]pu/ GROUP BY time(5s), * END"]]}]}]}`, + exp: `{"results":[{"series":[{"name":"db0","columns":["name","query"],"values":[["my.query","CREATE CONTINUOUS QUERY \"my.query\" ON db0 BEGIN SELECT count(value) INTO \"db0\".\"rp0\".measure1 FROM \"db0\".\"rp0\".myseries GROUP BY time(10m) END"]]}]}]}`, }, }...) - // Run first test to create CQs. - runTest(&test, t) - - // Trigger CQs to run. - u := fmt.Sprintf("%s/data/process_continuous_queries?time=%d", s.URL(), interval0.UnixNano()) - if _, err := s.HTTPPost(u, nil); err != nil { - t.Fatal(err) + for i, query := range test.queries { + if i == 0 { + if err := test.init(s); err != nil { + t.Fatalf("test init failed: %s", err) + } + } + if query.skip { + t.Logf("SKIP:: %s", query.name) + continue + } + if err := query.Execute(s); err != nil { + t.Error(query.Error(err)) + } else if !query.success() { + t.Error(query.failureMessage()) + } } - - // Wait for CQs to run. TODO: fix this ugly hack - time.Sleep(time.Second * 5) - - // Setup tests to check the CQ results. - test2 := NewTest("db0", "rp1") - test2.addQueries([]*Query{ - &Query{ - name: "check results of cq1", - command: `SELECT * FROM "rp1"./[cg]pu/`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","count","host","region","value"],"values":[["` + interval2.UTC().Format(time.RFC3339Nano) + `",3,null,null,null]]},{"name":"gpu","columns":["time","count","host","region","value"],"values":[["` + interval1.UTC().Format(time.RFC3339Nano) + `",2,null,null,null],["` + interval0.UTC().Format(time.RFC3339Nano) + `",1,null,null,null]]}]}]}`, - params: url.Values{"db": []string{"db0"}}, - }, - // TODO: restore this test once this is fixed: https://github.com/influxdb/influxdb/issues/3968 - &Query{ - skip: true, - name: "check results of cq2", - command: `SELECT * FROM "rp2"./[cg]pu/`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","count","host","region","value"],"values":[["` + interval2.UTC().Format(time.RFC3339Nano) + `",1,"server01","uswest",null],["` + interval2.UTC().Format(time.RFC3339Nano) + `",1,"server01","",null],["` + interval2.UTC().Format(time.RFC3339Nano) + `",1,"server01","useast",null]]},{"name":"gpu","columns":["time","count","host","region","value"],"values":[["` + interval1.UTC().Format(time.RFC3339Nano) + `",1,"server02","useast",null],["` + interval1.UTC().Format(time.RFC3339Nano) + `",1,"server03","caeast",null],["` + interval0.UTC().Format(time.RFC3339Nano) + `",1,"server03","caeast",null]]}]}]}`, - params: url.Values{"db": []string{"db0"}}, - }, - }...) - - // Run second test to check CQ results. - runTest(&test2, t) } // Tests that a known CQ query with concurrent writes does not deadlock the server @@ -4220,155 +3717,3 @@ func TestServer_Query_EvilIdentifiers(t *testing.T) { } } } - -func TestServer_Query_OrderByTime(t *testing.T) { - t.Parallel() - s := OpenServer(NewConfig(), "") - defer s.Close() - - if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 0)); err != nil { - t.Fatal(err) - } - if err := s.MetaStore.SetDefaultRetentionPolicy("db0", "rp0"); err != nil { - t.Fatal(err) - } - - writes := []string{ - fmt.Sprintf(`cpu,host=server1 value=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:01Z").UnixNano()), - fmt.Sprintf(`cpu,host=server1 value=2 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:02Z").UnixNano()), - fmt.Sprintf(`cpu,host=server1 value=3 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:03Z").UnixNano()), - } - - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") - - test.addQueries([]*Query{ - &Query{ - name: "order on points", - params: url.Values{"db": []string{"db0"}}, - command: `select value from "cpu" ORDER BY time DESC`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","value"],"values":[["2000-01-01T00:00:03Z",3],["2000-01-01T00:00:02Z",2],["2000-01-01T00:00:01Z",1]]}]}]}`, - }, - }...) - - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP:: %s", query.name) - continue - } - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } -} - -func TestServer_Query_FieldWithMultiplePeriods(t *testing.T) { - t.Parallel() - s := OpenServer(NewConfig(), "") - defer s.Close() - - if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 0)); err != nil { - t.Fatal(err) - } - if err := s.MetaStore.SetDefaultRetentionPolicy("db0", "rp0"); err != nil { - t.Fatal(err) - } - - writes := []string{ - fmt.Sprintf(`cpu foo.bar.baz=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - } - - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") - - test.addQueries([]*Query{ - &Query{ - name: "baseline", - params: url.Values{"db": []string{"db0"}}, - command: `select * from cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, - }, - &Query{ - name: "select field with periods", - params: url.Values{"db": []string{"db0"}}, - command: `select "foo.bar.baz" from cpu`, - exp: `{"results":[{"series":[{"name":"cpu","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, - }, - }...) - - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP:: %s", query.name) - continue - } - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } -} - -func TestServer_Query_FieldWithMultiplePeriodsMeasurementPrefixMatch(t *testing.T) { - t.Parallel() - s := OpenServer(NewConfig(), "") - defer s.Close() - - if err := s.CreateDatabaseAndRetentionPolicy("db0", newRetentionPolicyInfo("rp0", 1, 0)); err != nil { - t.Fatal(err) - } - if err := s.MetaStore.SetDefaultRetentionPolicy("db0", "rp0"); err != nil { - t.Fatal(err) - } - - writes := []string{ - fmt.Sprintf(`foo foo.bar.baz=1 %d`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()), - } - - test := NewTest("db0", "rp0") - test.write = strings.Join(writes, "\n") - - test.addQueries([]*Query{ - &Query{ - name: "baseline", - params: url.Values{"db": []string{"db0"}}, - command: `select * from foo`, - exp: `{"results":[{"series":[{"name":"foo","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, - }, - &Query{ - name: "select field with periods", - params: url.Values{"db": []string{"db0"}}, - command: `select "foo.bar.baz" from foo`, - exp: `{"results":[{"series":[{"name":"foo","columns":["time","foo.bar.baz"],"values":[["2000-01-01T00:00:00Z",1]]}]}]}`, - }, - }...) - - for i, query := range test.queries { - if i == 0 { - if err := test.init(s); err != nil { - t.Fatalf("test init failed: %s", err) - } - } - if query.skip { - t.Logf("SKIP:: %s", query.name) - continue - } - if err := query.Execute(s); err != nil { - t.Error(query.Error(err)) - } else if !query.success() { - t.Error(query.failureMessage()) - } - } -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/inspect/main.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/inspect/main.go deleted file mode 100644 index 43b233f54..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/cmd/inspect/main.go +++ /dev/null @@ -1,142 +0,0 @@ -package main - -import ( - "encoding/binary" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "sort" - "strings" - "text/tabwriter" - - "github.com/influxdb/influxdb/tsdb" - _ "github.com/influxdb/influxdb/tsdb/engine" -) - -func main() { - - var path string - flag.StringVar(&path, "p", os.Getenv("HOME")+"/.influxdb", "Root storage path. [$HOME/.influxdb]") - flag.Parse() - - tstore := tsdb.NewStore(filepath.Join(path, "data")) - tstore.Logger = log.New(ioutil.Discard, "", log.LstdFlags) - tstore.EngineOptions.Config.Dir = filepath.Join(path, "data") - tstore.EngineOptions.Config.WALLoggingEnabled = false - tstore.EngineOptions.Config.WALDir = filepath.Join(path, "wal") - if err := tstore.Open(); err != nil { - fmt.Printf("Failed to open dir: %v\n", err) - os.Exit(1) - } - - size, err := tstore.DiskSize() - if err != nil { - fmt.Printf("Failed to determine disk usage: %v\n", err) - } - - // Summary stats - fmt.Printf("Shards: %d, Indexes: %d, Databases: %d, Disk Size: %d, Series: %d\n", - tstore.ShardN(), tstore.DatabaseIndexN(), len(tstore.Databases()), size, countSeries(tstore)) - fmt.Println() - - tw := tabwriter.NewWriter(os.Stdout, 16, 8, 0, '\t', 0) - - fmt.Fprintln(tw, strings.Join([]string{"Shard", "DB", "Measurement", "Tags [#K/#V]", "Fields [Name:Type]", "Series"}, "\t")) - - shardIDs := tstore.ShardIDs() - - databases := tstore.Databases() - sort.Strings(databases) - - for _, db := range databases { - index := tstore.DatabaseIndex(db) - measurements := index.Measurements() - sort.Sort(measurements) - for _, m := range measurements { - tags := m.TagKeys() - tagValues := 0 - for _, tag := range tags { - tagValues += len(m.TagValues(tag)) - } - fields := m.FieldNames() - sort.Strings(fields) - series := m.SeriesKeys() - sort.Strings(series) - sort.Sort(ShardIDs(shardIDs)) - - // Sample a point from each measurement to determine the field types - for _, shardID := range shardIDs { - shard := tstore.Shard(shardID) - tx, err := shard.ReadOnlyTx() - if err != nil { - fmt.Printf("Failed to get transaction: %v", err) - } - - for _, key := range series { - fieldSummary := []string{} - - cursor := tx.Cursor(key, tsdb.Forward) - - // Series doesn't exist in this shard - if cursor == nil { - continue - } - - // Seek to the beginning - _, value := cursor.Seek([]byte{}) - codec := shard.FieldCodec(m.Name) - if codec != nil { - fields, err := codec.DecodeFieldsWithNames(value) - if err != nil { - fmt.Printf("Failed to decode values: %v", err) - } - - for field, value := range fields { - fieldSummary = append(fieldSummary, fmt.Sprintf("%s:%T", field, value)) - } - sort.Strings(fieldSummary) - } - fmt.Fprintf(tw, "%d\t%s\t%s\t%d/%d\t%d [%s]\t%d\n", shardID, db, m.Name, len(tags), tagValues, - len(fields), strings.Join(fieldSummary, ","), len(series)) - break - } - tx.Rollback() - } - } - } - tw.Flush() -} - -func countSeries(tstore *tsdb.Store) int { - var count int - for _, shardID := range tstore.ShardIDs() { - shard := tstore.Shard(shardID) - cnt, err := shard.SeriesCount() - if err != nil { - fmt.Printf("series count failed: %v\n", err) - continue - } - count += cnt - } - return count -} - -func btou64(b []byte) uint64 { - return binary.BigEndian.Uint64(b) -} - -// u64tob converts a uint64 into an 8-byte slice. -func u64tob(v uint64) []byte { - b := make([]byte, 8) - binary.BigEndian.PutUint64(b, v) - return b -} - -type ShardIDs []uint64 - -func (a ShardIDs) Len() int { return len(a) } -func (a ShardIDs) Less(i, j int) bool { return a[i] < a[j] } -func (a ShardIDs) Swap(i, j int) { a[i], a[j] = a[j], a[i] } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/diagnostics.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/diagnostics.go new file mode 100644 index 000000000..c1e02565b --- /dev/null +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/diagnostics.go @@ -0,0 +1,143 @@ +package influxdb + +import ( + "os" + "runtime" + "time" + + "github.com/influxdb/influxdb/influxql" +) + +// GoDiagnostics captures basic information about the runtime. +type GoDiagnostics struct { + GoMaxProcs int + NumGoroutine int + Version string +} + +// NewGoDiagnostics returns a GoDiagnostics object. +func NewGoDiagnostics() *GoDiagnostics { + return &GoDiagnostics{ + GoMaxProcs: runtime.GOMAXPROCS(0), + NumGoroutine: runtime.NumGoroutine(), + Version: runtime.Version(), + } +} + +// AsRow returns the GoDiagnostic object as an InfluxQL row. +func (g *GoDiagnostics) AsRow(measurement string, tags map[string]string) *influxql.Row { + return &influxql.Row{ + Name: measurement, + Columns: []string{"time", "goMaxProcs", "numGoRoutine", "version"}, + Tags: tags, + Values: [][]interface{}{[]interface{}{time.Now().UTC(), + g.GoMaxProcs, g.NumGoroutine, g.Version}}, + } +} + +// SystemDiagnostics captures basic machine data. +type SystemDiagnostics struct { + Hostname string + PID int + OS string + Arch string + NumCPU int +} + +// NewSystemDiagnostics returns a SystemDiagnostics object. +func NewSystemDiagnostics() *SystemDiagnostics { + hostname, err := os.Hostname() + if err != nil { + hostname = "unknown" + } + + return &SystemDiagnostics{ + Hostname: hostname, + PID: os.Getpid(), + OS: runtime.GOOS, + Arch: runtime.GOARCH, + NumCPU: runtime.NumCPU(), + } +} + +// AsRow returns the GoDiagnostic object as an InfluxQL row. +func (s *SystemDiagnostics) AsRow(measurement string, tags map[string]string) *influxql.Row { + return &influxql.Row{ + Name: measurement, + Columns: []string{"time", "hostname", "pid", "os", "arch", "numCPU"}, + Tags: tags, + Values: [][]interface{}{[]interface{}{time.Now().UTC(), + s.Hostname, s.PID, s.OS, s.Arch, s.NumCPU}}, + } +} + +// MemoryDiagnostics captures Go memory stats. +type MemoryDiagnostics struct { + Alloc int64 + TotalAlloc int64 + Sys int64 + Lookups int64 + Mallocs int64 + Frees int64 + HeapAlloc int64 + HeapSys int64 + HeapIdle int64 + HeapInUse int64 + HeapReleased int64 + HeapObjects int64 + PauseTotalNs int64 + NumGC int64 +} + +// NewMemoryDiagnostics returns a MemoryDiagnostics object. +func NewMemoryDiagnostics() *MemoryDiagnostics { + var m runtime.MemStats + runtime.ReadMemStats(&m) + + return &MemoryDiagnostics{ + Alloc: int64(m.Alloc), + TotalAlloc: int64(m.TotalAlloc), + Sys: int64(m.Sys), + Lookups: int64(m.Lookups), + Mallocs: int64(m.Mallocs), + Frees: int64(m.Frees), + HeapAlloc: int64(m.HeapAlloc), + HeapSys: int64(m.HeapSys), + HeapIdle: int64(m.HeapIdle), + HeapInUse: int64(m.HeapInuse), + HeapReleased: int64(m.HeapReleased), + HeapObjects: int64(m.HeapObjects), + PauseTotalNs: int64(m.PauseTotalNs), + NumGC: int64(m.NumGC), + } +} + +// AsRow returns the MemoryDiagnostics object as an InfluxQL row. +func (m *MemoryDiagnostics) AsRow(measurement string, tags map[string]string) *influxql.Row { + return &influxql.Row{ + Name: measurement, + Columns: []string{"time", "alloc", "totalAlloc", "sys", "lookups", "mallocs", "frees", "heapAlloc", + "heapSys", "heapIdle", "heapInUse", "heapReleased", "heapObjects", "pauseTotalNs", "numGG"}, + Tags: tags, + Values: [][]interface{}{[]interface{}{time.Now().UTC(), + m.Alloc, m.TotalAlloc, m.Sys, m.Lookups, m.Mallocs, m.Frees, m.HeapAlloc, + m.HeapSys, m.HeapIdle, m.HeapInUse, m.HeapReleased, m.HeapObjects, m.PauseTotalNs, m.NumGC}}, + } +} + +// BuildDiagnostics capture basic build version information. +type BuildDiagnostics struct { + Version string + CommitHash string +} + +// AsRow returns the BuildDiagnostics object as an InfluxQL row. +func (b *BuildDiagnostics) AsRow(measurement string, tags map[string]string) *influxql.Row { + return &influxql.Row{ + Name: measurement, + Columns: []string{"time", "version", "commitHash"}, + Tags: tags, + Values: [][]interface{}{[]interface{}{time.Now().UTC(), + b.Version, b.CommitHash}}, + } +} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/etc/config.sample.toml b/Godeps/_workspace/src/github.com/influxdb/influxdb/etc/config.sample.toml index 3065252b0..9614277ab 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/etc/config.sample.toml +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/etc/config.sample.toml @@ -86,20 +86,7 @@ reporting-disabled = false [retention] enabled = true - check-interval = "30m" - -### -### Controls the system self-monitoring, statistics and diagnostics. -### -### The retention policy for this data is the default retention policy within -### the internal database. The internal database is created automatically if -### if it does not already exist, as is the default retention policy. If you -### want to use a non-default retention policy, it must be explicitly created. - -[monitor] - store-enabled = true # Whether to record statistics internally. - store-database = "_internal" # The destination database for recorded statistics - store-interval = "10s" # The interval at which to record statistics + check-interval = "10m" ### ### [admin] @@ -145,11 +132,10 @@ reporting-disabled = false # name-separator = "." # These next lines control how batching works. You should have this enabled - # otherwise you could get dropped metrics or poor performance. Batching + # otherwise you could get dropped metrics or poor performance. Batching # will buffer points in memory if you have many coming in. # batch-size = 1000 # will flush if this many points get buffered - # batch-pending = 5 # number of batches that may be pending in memory # batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit ## "name-schema" configures tag names for parsing the metric name from graphite protocol; @@ -185,11 +171,10 @@ reporting-disabled = false # typesdb = "" # These next lines control how batching works. You should have this enabled - # otherwise you could get dropped metrics or poor performance. Batching + # otherwise you could get dropped metrics or poor performance. Batching # will buffer points in memory if you have many coming in. # batch-size = 1000 # will flush if this many points get buffered - # batch-pending = 5 # number of batches that may be pending in memory # batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit ### @@ -204,14 +189,6 @@ reporting-disabled = false # database = "" # retention-policy = "" - # These next lines control how batching works. You should have this enabled - # otherwise you could get dropped metrics or poor performance. Only points - # metrics received over the telnet protocol undergo batching. - - # batch-size = 1000 # will flush if this many points get buffered - # batch-pending = 5 # number of batches that may be pending in memory - # batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit - ### ### [[udp]] ### @@ -224,13 +201,20 @@ reporting-disabled = false # database = "" # These next lines control how batching works. You should have this enabled - # otherwise you could get dropped metrics or poor performance. Batching + # otherwise you could get dropped metrics or poor performance. Batching # will buffer points in memory if you have many coming in. # batch-size = 1000 # will flush if this many points get buffered - # batch-pending = 5 # number of batches that may be pending in memory # batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit +### +### [monitoring] +### + +[monitoring] + enabled = true + write-interval = "24h" + ### ### [continuous_queries] ### diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/importer/README.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/importer/README.md index b8cd9ad8e..272fedf6c 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/importer/README.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/importer/README.md @@ -4,13 +4,6 @@ Version `0.8.9` of InfluxDB adds support to export your data to a format that can be imported into `0.9.3` and later. -Note that `0.8.9` can be found here: - -``` -http://get.influxdb.org.s3.amazonaws.com/influxdb_0.8.9_amd64.deb -http://get.influxdb.org.s3.amazonaws.com/influxdb-0.8.9-1.x86_64.rpm -``` - ### Design `0.8.9` exports raw data to a flat file that includes two sections, `DDL` and `DML`. You can choose to export them independently (see below). diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/INFLUXQL.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/INFLUXQL.md index c7ce2aeb4..3ef272f41 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/INFLUXQL.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/INFLUXQL.md @@ -87,11 +87,11 @@ CREATE CONTINUOUS DATABASE DATABASES DEFAULT DELETE DESC DROP DURATION END EXISTS EXPLAIN FIELD FROM GRANT GROUP IF IN INNER INSERT INTO KEY KEYS LIMIT -SHOW MEASUREMENT MEASUREMENTS NOT OFFSET ON -ORDER PASSWORD POLICY POLICIES PRIVILEGES QUERIES -QUERY READ REPLICATION RETENTION REVOKE SELECT -SERIES SLIMIT SOFFSET TAG TO USER -USERS VALUES WHERE WITH WRITE +SHOW MEASUREMENT MEASUREMENTS OFFSET ON ORDER +PASSWORD POLICY POLICIES PRIVILEGES QUERIES QUERY +READ REPLICATION RETENTION REVOKE SELECT SERIES +SLIMIT SOFFSET TAG TO USER USERS +VALUES WHERE WITH WRITE ``` ## Literals @@ -124,7 +124,9 @@ string_lit = `'` { unicode_char } `'`' . Duration literals specify a length of time. An integer literal followed immediately (with no spaces) by a duration unit listed below is interpreted as a duration literal. -### Duration units +``` +Duration unit definitions +------------------------- | Units | Meaning | |--------|-----------------------------------------| | u or µ | microseconds (1 millionth of a second) | @@ -134,6 +136,7 @@ Duration literals specify a length of time. An integer literal followed immedia | h | hour | | d | day | | w | week | +``` ``` duration_lit = int_lit duration_unit . @@ -188,7 +191,6 @@ statement = alter_retention_policy_stmt | show_measurements_stmt | show_retention_policies | show_series_stmt | - show_shards_stmt | show_tag_keys_stmt | show_tag_values_stmt | show_users_stmt | @@ -453,7 +455,7 @@ SHOW FIELD KEYS FROM cpu; ### SHOW MEASUREMENTS -show_measurements_stmt = "SHOW MEASUREMENTS" [ where_clause ] [ group_by_clause ] [ limit_clause ] +show_measurements_stmt = [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ] . ```sql @@ -480,7 +482,7 @@ SHOW RETENTION POLICIES ON mydb; ### SHOW SERIES ``` -show_series_stmt = "SHOW SERIES" [ from_clause ] [ where_clause ] [ group_by_clause ] +show_series_stmt = [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ] . ``` @@ -490,22 +492,10 @@ show_series_stmt = "SHOW SERIES" [ from_clause ] [ where_clause ] [ group_by_cla ``` -### SHOW SHARDS - -``` -show_shards_stmt = "SHOW SHARDS" . -``` - -#### Example: - -```sql -SHOW SHARDS; -``` - ### SHOW TAG KEYS ``` -show_tag_keys_stmt = "SHOW TAG KEYS" [ from_clause ] [ where_clause ] [ group_by_clause ] +show_tag_keys_stmt = [ from_clause ] [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ] . ``` @@ -528,7 +518,7 @@ SHOW TAG KEYS WHERE host = 'serverA'; ### SHOW TAG VALUES ``` -show_tag_values_stmt = "SHOW TAG VALUES" [ from_clause ] with_tag_clause [ where_clause ] +show_tag_values_stmt = [ from_clause ] with_tag_clause [ where_clause ] [ group_by_clause ] [ limit_clause ] [ offset_clause ] . ``` @@ -561,7 +551,7 @@ SHOW USERS; ### REVOKE ``` -revoke_stmt = "REVOKE" privilege [ "ON" db_name ] "FROM" user_name +revoke_stmt = privilege [ "ON" db_name ] "FROM" user_name ``` #### Examples: @@ -577,7 +567,7 @@ REVOKE READ ON mydb FROM jdoe; ### SELECT ``` -select_stmt = "SELECT" fields from_clause [ into_clause ] [ where_clause ] +select_stmt = fields from_clause [ into_clause ] [ where_clause ] [ group_by_clause ] [ order_by_clause ] [ limit_clause ] [ offset_clause ] [ slimit_clause ] [ soffset_clause ]. ``` diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast.go index 56eb8683e..31cf82e24 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast.go @@ -9,8 +9,6 @@ import ( "strconv" "strings" "time" - - "github.com/influxdb/influxdb/pkg/slices" ) // DataType represents the primitive data types available in InfluxQL. @@ -107,7 +105,6 @@ func (*ShowFieldKeysStatement) node() {} func (*ShowRetentionPoliciesStatement) node() {} func (*ShowMeasurementsStatement) node() {} func (*ShowSeriesStatement) node() {} -func (*ShowShardsStatement) node() {} func (*ShowStatsStatement) node() {} func (*ShowDiagnosticsStatement) node() {} func (*ShowTagKeysStatement) node() {} @@ -209,7 +206,6 @@ func (*ShowFieldKeysStatement) stmt() {} func (*ShowMeasurementsStatement) stmt() {} func (*ShowRetentionPoliciesStatement) stmt() {} func (*ShowSeriesStatement) stmt() {} -func (*ShowShardsStatement) stmt() {} func (*ShowStatsStatement) stmt() {} func (*ShowDiagnosticsStatement) stmt() {} func (*ShowTagKeysStatement) stmt() {} @@ -278,7 +274,7 @@ type SortField struct { // String returns a string representation of a sort field func (field *SortField) String() string { var buf bytes.Buffer - if field.Name != "" { + if field.Name == "" { _, _ = buf.WriteString(field.Name) _, _ = buf.WriteString(" ") } @@ -306,19 +302,12 @@ func (a SortFields) String() string { type CreateDatabaseStatement struct { // Name of the database to be created. Name string - - // IfNotExists indicates whether to return without error if the database - // already exists. - IfNotExists bool } // String returns a string representation of the create database statement. func (s *CreateDatabaseStatement) String() string { var buf bytes.Buffer _, _ = buf.WriteString("CREATE DATABASE ") - if s.IfNotExists { - _, _ = buf.WriteString("IF NOT EXISTS ") - } _, _ = buf.WriteString(s.Name) return buf.String() } @@ -859,48 +848,6 @@ func (s *SelectStatement) RewriteDistinct() { } } -// ColumnNames will walk all fields and functions and return the appropriate field names for the select statement -// while maintaining order of the field names -func (s *SelectStatement) ColumnNames() []string { - // Always set the first column to be time, even if they didn't specify it - columnNames := []string{"time"} - - // First walk each field - for _, field := range s.Fields { - switch f := field.Expr.(type) { - case *Call: - if f.Name == "top" || f.Name == "bottom" { - if len(f.Args) == 2 { - columnNames = append(columnNames, f.Name) - continue - } - // We have a special case now where we have to add the column names for the fields TOP or BOTTOM asked for as well - columnNames = slices.Union(columnNames, f.Fields(), true) - continue - } - columnNames = append(columnNames, field.Name()) - default: - // time is always first, and we already added it, so ignore it if they asked for it anywhere else. - if field.Name() != "time" { - columnNames = append(columnNames, field.Name()) - } - } - } - - return columnNames -} - -// HasTimeFieldSpecified will walk all fields and determine if the user explicitly asked for time -// This is needed to determine re-write behaviors for functions like TOP and BOTTOM -func (s *SelectStatement) HasTimeFieldSpecified() bool { - for _, f := range s.Fields { - if f.Name() == "time" { - return true - } - } - return false -} - // String returns a string representation of the select statement. func (s *SelectStatement) String() string { var buf bytes.Buffer @@ -1042,10 +989,6 @@ func (s *SelectStatement) validate(tr targetRequirement) error { return err } - if err := s.validateDimensions(); err != nil { - return err - } - if err := s.validateDistinct(); err != nil { return err } @@ -1062,6 +1005,10 @@ func (s *SelectStatement) validate(tr targetRequirement) error { return err } + if err := s.validateWildcard(); err != nil { + return err + } + return nil } @@ -1073,133 +1020,40 @@ func (s *SelectStatement) validateFields() error { return nil } -func (s *SelectStatement) validateDimensions() error { - var dur time.Duration - for _, dim := range s.Dimensions { - switch expr := dim.Expr.(type) { - case *Call: - // Ensure the call is time() and it only has one duration argument. - // If we already have a duration - if expr.Name != "time" { - return errors.New("only time() calls allowed in dimensions") - } else if len(expr.Args) != 1 { - return errors.New("time dimension expected one argument") - } else if lit, ok := expr.Args[0].(*DurationLiteral); !ok { - return errors.New("time dimension must have one duration argument") - } else if dur != 0 { - return errors.New("multiple time dimensions not allowed") - } else { - dur = lit.Val - } - case *VarRef: - if strings.ToLower(expr.Val) == "time" { - return errors.New("time() is a function and expects at least one argument") - } - case *Wildcard: - default: - return errors.New("only time and tag dimensions allowed") - } - } - return nil -} - -// validSelectWithAggregate determines if a SELECT statement has the correct -// combination of aggregate functions combined with selected fields and tags -// Currently we don't have support for all aggregates, but aggregates that -// can be combined with fields/tags are: -// TOP, BOTTOM, MAX, MIN, FIRST, LAST -func (s *SelectStatement) validSelectWithAggregate(numAggregates int) error { - if numAggregates != 0 && numAggregates != len(s.Fields) { - return fmt.Errorf("mixing aggregate and non-aggregate queries is not supported") - } - return nil -} - func (s *SelectStatement) validateAggregates(tr targetRequirement) error { - // Curently most aggregates can be the ONLY thing in a select statement - // Others, like TOP/BOTTOM can mix aggregates and tags/fields + // First, if 1 field is an aggregate, then all fields must be an aggregate. This is + // a explicit limitation of the current system. numAggregates := 0 for _, f := range s.Fields { if _, ok := f.Expr.(*Call); ok { numAggregates++ } } + if numAggregates != 0 && numAggregates != len(s.Fields) { + return fmt.Errorf("mixing aggregate and non-aggregate queries is not supported") + } + // Secondly, determine if specific calls have at least one and only one argument for _, f := range s.Fields { - switch expr := f.Expr.(type) { - case *Call: - switch expr.Name { + if c, ok := f.Expr.(*Call); ok { + switch c.Name { case "derivative", "non_negative_derivative": - if err := s.validSelectWithAggregate(numAggregates); err != nil { - return err + if min, max, got := 1, 2, len(c.Args); got > max || got < min { + return fmt.Errorf("invalid number of arguments for %s, expected at least %d but no more than %d, got %d", c.Name, min, max, got) } - if min, max, got := 1, 2, len(expr.Args); got > max || got < min { - return fmt.Errorf("invalid number of arguments for %s, expected at least %d but no more than %d, got %d", expr.Name, min, max, got) - } - // Validate that if they have a time dimension, they need a sub-call like min/max, etc. - if s.hasTimeDimensions(s.Condition) { - if _, ok := expr.Args[0].(*Call); !ok { - return fmt.Errorf("aggregate function required inside the call to %s", expr.Name) - } - } - case "percentile": - if err := s.validSelectWithAggregate(numAggregates); err != nil { - return err - } - if exp, got := 2, len(expr.Args); got != exp { - return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", expr.Name, exp, got) - } - _, ok := expr.Args[1].(*NumberLiteral) - if !ok { - return fmt.Errorf("expected float argument in percentile()") - } - case "top", "bottom": - if exp, got := 2, len(expr.Args); got < exp { - return fmt.Errorf("invalid number of arguments for %s, expected at least %d, got %d", expr.Name, exp, got) - } - if len(expr.Args) > 1 { - callLimit, ok := expr.Args[len(expr.Args)-1].(*NumberLiteral) - if !ok { - return fmt.Errorf("expected integer as last argument in %s(), found %s", expr.Name, expr.Args[len(expr.Args)-1]) - } - // Check if they asked for a limit smaller than what they passed into the call - if int64(callLimit.Val) > int64(s.Limit) && s.Limit != 0 { - return fmt.Errorf("limit (%d) in %s function can not be larger than the LIMIT (%d) in the select statement", int64(callLimit.Val), expr.Name, int64(s.Limit)) - } - - for _, v := range expr.Args[:len(expr.Args)-1] { - if _, ok := v.(*VarRef); !ok { - return fmt.Errorf("only fields or tags are allowed in %s(), found %s", expr.Name, v) - } - } + if exp, got := 2, len(c.Args); got != exp { + return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", c.Name, exp, got) } default: - if err := s.validSelectWithAggregate(numAggregates); err != nil { - return err - } - if exp, got := 1, len(expr.Args); got != exp { - return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", expr.Name, exp, got) - } - switch fc := expr.Args[0].(type) { - case *VarRef: - // do nothing - case *Call: - if fc.Name != "distinct" { - return fmt.Errorf("expected field argument in %s()", expr.Name) - } - case *Distinct: - if expr.Name != "count" { - return fmt.Errorf("expected field argument in %s()", expr.Name) - } - default: - return fmt.Errorf("expected field argument in %s()", expr.Name) + if exp, got := 1, len(c.Args); got != exp { + return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", c.Name, exp, got) } } } } - // Check that we have valid duration and where clauses for aggregates + // Now, check that we have valid duration and where clauses for aggregates // fetch the group by duration groupByDuration, _ := s.GroupByInterval() @@ -1218,6 +1072,13 @@ func (s *SelectStatement) validateAggregates(tr targetRequirement) error { return nil } +func (s *SelectStatement) validateWildcard() error { + if s.HasWildcard() && len(s.Fields) > 1 { + return fmt.Errorf("wildcards can not be combined with other fields") + } + return nil +} + func (s *SelectStatement) HasDistinct() bool { // determine if we have a call named distinct for _, f := range s.Fields { @@ -1640,9 +1501,6 @@ func (t *Target) String() string { var buf bytes.Buffer _, _ = buf.WriteString("INTO ") _, _ = buf.WriteString(t.Measurement.String()) - if t.Measurement.Name == "" { - _, _ = buf.WriteString(":MEASUREMENT") - } return buf.String() } @@ -1973,17 +1831,6 @@ func (s *ShowStatsStatement) RequiredPrivileges() ExecutionPrivileges { return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}} } -// ShowShardsStatement represents a command for displaying shards in the cluster. -type ShowShardsStatement struct{} - -// String returns a string representation. -func (s *ShowShardsStatement) String() string { return "SHOW SHARDS" } - -// RequiredPrivileges returns the privileges required to execute the statement. -func (s *ShowShardsStatement) RequiredPrivileges() ExecutionPrivileges { - return ExecutionPrivileges{{Admin: true, Name: "", Privilege: AllPrivileges}} -} - // ShowDiagnosticsStatement represents a command for show node diagnostics. type ShowDiagnosticsStatement struct{} @@ -2253,21 +2100,37 @@ func (a Dimensions) String() string { // Normalize returns the interval and tag dimensions separately. // Returns 0 if no time interval is specified. -func (a Dimensions) Normalize() (time.Duration, []string) { +// Returns an error if multiple time dimensions exist or if non-VarRef dimensions are specified. +func (a Dimensions) Normalize() (time.Duration, []string, error) { var dur time.Duration var tags []string for _, dim := range a { switch expr := dim.Expr.(type) { case *Call: - lit, _ := expr.Args[0].(*DurationLiteral) - dur = lit.Val + // Ensure the call is time() and it only has one duration argument. + // If we already have a duration + if expr.Name != "time" { + return 0, nil, errors.New("only time() calls allowed in dimensions") + } else if len(expr.Args) != 1 { + return 0, nil, errors.New("time dimension expected one argument") + } else if lit, ok := expr.Args[0].(*DurationLiteral); !ok { + return 0, nil, errors.New("time dimension must have one duration argument") + } else if dur != 0 { + return 0, nil, errors.New("multiple time dimensions not allowed") + } else { + dur = lit.Val + } + case *VarRef: tags = append(tags, expr.Val) + + default: + return 0, nil, errors.New("only time and tag dimensions allowed") } } - return dur, tags + return dur, tags, nil } // Dimension represents an expression that a select statement is grouped by. @@ -2296,7 +2159,6 @@ type Measurement struct { RetentionPolicy string Name string Regex *RegexLiteral - IsTarget bool } // String returns a string representation of the measurement. @@ -2355,33 +2217,6 @@ func (c *Call) String() string { return fmt.Sprintf("%s(%s)", c.Name, strings.Join(str, ", ")) } -// Fields will extract any field names from the call. Only specific calls support this. -func (c *Call) Fields() []string { - switch c.Name { - case "top", "bottom": - // maintain the order the user specified in the query - keyMap := make(map[string]struct{}) - keys := []string{} - for i, a := range c.Args { - if i == 0 { - // special case, first argument is always the name of the function regardless of the field name - keys = append(keys, c.Name) - continue - } - switch v := a.(type) { - case *VarRef: - if _, ok := keyMap[v.Val]; !ok { - keyMap[v.Val] = struct{}{} - keys = append(keys, v.Val) - } - } - } - return keys - default: - return []string{} - } -} - // Distinct represents a DISTINCT expression. type Distinct struct { // Identifier following DISTINCT diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast_test.go index ca2836111..b58e7353b 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/ast_test.go @@ -451,7 +451,7 @@ func TestSelectStatement_IsRawQuerySet(t *testing.T) { isRaw: false, }, { - stmt: "select mean(value) from foo group by *", + stmt: "select mean(*) from foo group by *", isRaw: false, }, } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/tsdb/functions.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions.go similarity index 62% rename from Godeps/_workspace/src/github.com/influxdb/influxdb/tsdb/functions.go rename to Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions.go index f7341de63..3d75c5a27 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/tsdb/functions.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions.go @@ -1,10 +1,10 @@ -package tsdb +package influxql // All aggregate and query functions are defined in this file along with any intermediate data objects they need to process. // Query functions are represented as two discreet functions: Map and Reduce. These roughly follow the MapReduce // paradigm popularized by Google and Hadoop. // -// When adding an aggregate function, define a mapper, a reducer, and add them in the switch statement in the MapreduceFuncs function +// When adding an aggregate function, define a mapper, a reducer, and add them in the switch statement in the MapReduceFuncs function import ( "encoding/json" @@ -13,43 +13,72 @@ import ( "math/rand" "sort" "strings" - - "github.com/influxdb/influxdb/influxql" ) -// iterator represents a forward-only iterator over a set of points. -// These are used by the mapFunctions in this file -type iterator interface { +// Iterator represents a forward-only iterator over a set of points. +// These are used by the MapFunctions in this file +type Iterator interface { Next() (time int64, value interface{}) - Tags() map[string]string - TMin() int64 } -// mapFunc represents a function used for mapping over a sequential series of data. +// MapFunc represents a function used for mapping over a sequential series of data. // The iterator represents a single group by interval -type mapFunc func(iterator) interface{} +type MapFunc func(Iterator) interface{} -// reduceFunc represents a function used for reducing mapper output. -type reduceFunc func([]interface{}) interface{} +// ReduceFunc represents a function used for reducing mapper output. +type ReduceFunc func([]interface{}) interface{} // UnmarshalFunc represents a function that can take bytes from a mapper from remote // server and marshal it into an interface the reducer can use -type unmarshalFunc func([]byte) (interface{}, error) +type UnmarshalFunc func([]byte) (interface{}, error) -// initializemapFunc takes an aggregate call from the query and returns the mapFunc -func initializeMapFunc(c *influxql.Call) (mapFunc, error) { +// InitializeMapFunc takes an aggregate call from the query and returns the MapFunc +func InitializeMapFunc(c *Call) (MapFunc, error) { // see if it's a query for raw data if c == nil { return MapRawQuery, nil } + // Ensure that there is either a single argument or if for percentile, two + if c.Name == "percentile" { + if len(c.Args) != 2 { + return nil, fmt.Errorf("expected two arguments for %s()", c.Name) + } + } else if strings.HasSuffix(c.Name, "derivative") { + // derivatives require a field name and optional duration + if len(c.Args) == 0 { + return nil, fmt.Errorf("expected field name argument for %s()", c.Name) + } + } else if len(c.Args) != 1 { + return nil, fmt.Errorf("expected one argument for %s()", c.Name) + } + + // derivative can take a nested aggregate function, everything else expects + // a variable reference as the first arg + if !strings.HasSuffix(c.Name, "derivative") { + // Ensure the argument is appropriate for the aggregate function. + switch fc := c.Args[0].(type) { + case *VarRef: + case *Distinct: + if c.Name != "count" { + return nil, fmt.Errorf("expected field argument in %s()", c.Name) + } + case *Call: + if fc.Name != "distinct" { + return nil, fmt.Errorf("expected field argument in %s()", c.Name) + } + default: + return nil, fmt.Errorf("expected field argument in %s()", c.Name) + } + } + // Retrieve map function by name. switch c.Name { case "count": - if _, ok := c.Args[0].(*influxql.Distinct); ok { + if _, ok := c.Args[0].(*Distinct); ok { return MapCountDistinct, nil } - if c, ok := c.Args[0].(*influxql.Call); ok { + if c, ok := c.Args[0].(*Call); ok { if c.Name == "distinct" { return MapCountDistinct, nil } @@ -75,17 +104,17 @@ func initializeMapFunc(c *influxql.Call) (mapFunc, error) { return MapFirst, nil case "last": return MapLast, nil - case "top": - return func(itr iterator) interface{} { - return MapTop(itr, c) - }, nil case "percentile": + _, ok := c.Args[1].(*NumberLiteral) + if !ok { + return nil, fmt.Errorf("expected float argument in percentile()") + } return MapEcho, nil case "derivative", "non_negative_derivative": // If the arg is another aggregate e.g. derivative(mean(value)), then // use the map func for that nested aggregate - if fn, ok := c.Args[0].(*influxql.Call); ok { - return initializeMapFunc(fn) + if fn, ok := c.Args[0].(*Call); ok { + return InitializeMapFunc(fn) } return MapRawQuery, nil default: @@ -93,15 +122,15 @@ func initializeMapFunc(c *influxql.Call) (mapFunc, error) { } } -// InitializereduceFunc takes an aggregate call from the query and returns the reduceFunc -func initializeReduceFunc(c *influxql.Call) (reduceFunc, error) { +// InitializeReduceFunc takes an aggregate call from the query and returns the ReduceFunc +func InitializeReduceFunc(c *Call) (ReduceFunc, error) { // Retrieve reduce function by name. switch c.Name { case "count": - if _, ok := c.Args[0].(*influxql.Distinct); ok { + if _, ok := c.Args[0].(*Distinct); ok { return ReduceCountDistinct, nil } - if c, ok := c.Args[0].(*influxql.Call); ok { + if c, ok := c.Args[0].(*Call); ok { if c.Name == "distinct" { return ReduceCountDistinct, nil } @@ -127,19 +156,21 @@ func initializeReduceFunc(c *influxql.Call) (reduceFunc, error) { return ReduceFirst, nil case "last": return ReduceLast, nil - case "top": - return func(values []interface{}) interface{} { - return ReduceTop(values, c) - }, nil case "percentile": - return func(values []interface{}) interface{} { - return ReducePercentile(values, c) - }, nil + if len(c.Args) != 2 { + return nil, fmt.Errorf("expected float argument in percentile()") + } + + lit, ok := c.Args[1].(*NumberLiteral) + if !ok { + return nil, fmt.Errorf("expected float argument in percentile()") + } + return ReducePercentile(lit.Val), nil case "derivative", "non_negative_derivative": // If the arg is another aggregate e.g. derivative(mean(value)), then // use the map func for that nested aggregate - if fn, ok := c.Args[0].(*influxql.Call); ok { - return initializeReduceFunc(fn) + if fn, ok := c.Args[0].(*Call); ok { + return InitializeReduceFunc(fn) } return nil, fmt.Errorf("expected function argument to %s", c.Name) default: @@ -147,7 +178,7 @@ func initializeReduceFunc(c *influxql.Call) (reduceFunc, error) { } } -func initializeUnmarshaller(c *influxql.Call) (unmarshalFunc, error) { +func InitializeUnmarshaller(c *Call) (UnmarshalFunc, error) { // if c is nil it's a raw data query if c == nil { return func(b []byte) (interface{}, error) { @@ -173,7 +204,7 @@ func initializeUnmarshaller(c *influxql.Call) (unmarshalFunc, error) { }, nil case "distinct": return func(b []byte) (interface{}, error) { - var val interfaceValues + var val distinctValues err := json.Unmarshal(b, &val) return val, err }, nil @@ -211,7 +242,7 @@ func initializeUnmarshaller(c *influxql.Call) (unmarshalFunc, error) { } // MapCount computes the number of values in an iterator. -func MapCount(itr iterator) interface{} { +func MapCount(itr Iterator) interface{} { n := float64(0) for k, _ := itr.Next(); k != -1; k, _ = itr.Next() { n++ @@ -222,16 +253,81 @@ func MapCount(itr iterator) interface{} { return nil } -type interfaceValues []interface{} +type distinctValues []interface{} -func (d interfaceValues) Len() int { return len(d) } -func (d interfaceValues) Swap(i, j int) { d[i], d[j] = d[j], d[i] } -func (d interfaceValues) Less(i, j int) bool { - return interfaceCompare(d[i], d[j]) < 0 +func (d distinctValues) Len() int { return len(d) } +func (d distinctValues) Swap(i, j int) { d[i], d[j] = d[j], d[i] } +func (d distinctValues) Less(i, j int) bool { + // Sort by type if types match + { + d1, ok1 := d[i].(float64) + d2, ok2 := d[j].(float64) + if ok1 && ok2 { + return d1 < d2 + } + } + + { + d1, ok1 := d[i].(uint64) + d2, ok2 := d[j].(uint64) + if ok1 && ok2 { + return d1 < d2 + } + } + + { + d1, ok1 := d[i].(bool) + d2, ok2 := d[j].(bool) + if ok1 && ok2 { + return d1 == false && d2 == true + } + } + + { + d1, ok1 := d[i].(string) + d2, ok2 := d[j].(string) + if ok1 && ok2 { + return d1 < d2 + } + } + + // Types did not match, need to sort based on arbitrary weighting of type + const ( + intWeight = iota + floatWeight + boolWeight + stringWeight + ) + + infer := func(val interface{}) (int, float64) { + switch v := val.(type) { + case uint64: + return intWeight, float64(v) + case int64: + return intWeight, float64(v) + case float64: + return floatWeight, v + case bool: + return boolWeight, 0 + case string: + return stringWeight, 0 + } + panic("unreachable code") + } + + w1, n1 := infer(d[i]) + w2, n2 := infer(d[j]) + + // If we had "numeric" data, use that for comparison + if n1 != n2 && (w1 == intWeight && w2 == floatWeight) || (w1 == floatWeight && w2 == intWeight) { + return n1 < n2 + } + + return w1 < w2 } // MapDistinct computes the unique values in an iterator. -func MapDistinct(itr iterator) interface{} { +func MapDistinct(itr Iterator) interface{} { var index = make(map[interface{}]struct{}) for time, value := itr.Next(); time != -1; time, value = itr.Next() { @@ -242,7 +338,7 @@ func MapDistinct(itr iterator) interface{} { return nil } - results := make(interfaceValues, len(index)) + results := make(distinctValues, len(index)) var i int for value, _ := range index { results[i] = value @@ -260,7 +356,7 @@ func ReduceDistinct(values []interface{}) interface{} { if v == nil { continue } - d, ok := v.(interfaceValues) + d, ok := v.(distinctValues) if !ok { msg := fmt.Sprintf("expected distinctValues, got: %T", v) panic(msg) @@ -271,7 +367,7 @@ func ReduceDistinct(values []interface{}) interface{} { } // convert map keys to an array - results := make(interfaceValues, len(index)) + results := make(distinctValues, len(index)) var i int for k, _ := range index { results[i] = k @@ -285,7 +381,7 @@ func ReduceDistinct(values []interface{}) interface{} { } // MapCountDistinct computes the unique count of values in an iterator. -func MapCountDistinct(itr iterator) interface{} { +func MapCountDistinct(itr Iterator) interface{} { var index = make(map[interface{}]struct{}) for time, value := itr.Next(); time != -1; time, value = itr.Next() { @@ -329,7 +425,7 @@ const ( ) // MapSum computes the summation of values in an iterator. -func MapSum(itr iterator) interface{} { +func MapSum(itr Iterator) interface{} { n := float64(0) count := 0 var resultType NumberType @@ -384,7 +480,7 @@ func ReduceSum(values []interface{}) interface{} { } // MapMean computes the count and sum of values in an iterator to be combined by the reducer. -func MapMean(itr iterator) interface{} { +func MapMean(itr Iterator) interface{} { out := &meanMapOutput{} for k, v := itr.Next(); k != -1; k, v = itr.Next() { @@ -590,7 +686,7 @@ type minMaxMapOut struct { } // MapMin collects the values to pass to the reducer -func MapMin(itr iterator) interface{} { +func MapMin(itr Iterator) interface{} { min := &minMaxMapOut{} pointsYielded := false @@ -653,7 +749,7 @@ func ReduceMin(values []interface{}) interface{} { } // MapMax collects the values to pass to the reducer -func MapMax(itr iterator) interface{} { +func MapMax(itr Iterator) interface{} { max := &minMaxMapOut{} pointsYielded := false @@ -721,7 +817,7 @@ type spreadMapOutput struct { } // MapSpread collects the values to pass to the reducer -func MapSpread(itr iterator) interface{} { +func MapSpread(itr Iterator) interface{} { out := &spreadMapOutput{} pointsYielded := false var val float64 @@ -782,7 +878,7 @@ func ReduceSpread(values []interface{}) interface{} { } // MapStddev collects the values to pass to the reducer -func MapStddev(itr iterator) interface{} { +func MapStddev(itr Iterator) interface{} { var values []float64 for k, v := itr.Next(); k != -1; k, v = itr.Next() { @@ -839,20 +935,26 @@ type firstLastMapOutput struct { } // MapFirst collects the values to pass to the reducer -// This function assumes time ordered input -func MapFirst(itr iterator) interface{} { - k, v := itr.Next() - if k == -1 { - return nil - } - nextk, nextv := itr.Next() - for nextk == k { - if greaterThan(nextv, v) { - v = nextv +func MapFirst(itr Iterator) interface{} { + out := &firstLastMapOutput{} + pointsYielded := false + + for k, v := itr.Next(); k != -1; k, v = itr.Next() { + // Initialize first + if !pointsYielded { + out.Time = k + out.Val = v + pointsYielded = true + } + if k < out.Time { + out.Time = k + out.Val = v } - nextk, nextv = itr.Next() } - return &firstLastMapOutput{k, v} + if pointsYielded { + return out + } + return nil } // ReduceFirst computes the first of value. @@ -874,8 +976,6 @@ func ReduceFirst(values []interface{}) interface{} { if val.Time < out.Time { out.Time = val.Time out.Val = val.Val - } else if val.Time == out.Time && greaterThan(val.Val, out.Val) { - out.Val = val.Val } } if pointsYielded { @@ -885,7 +985,7 @@ func ReduceFirst(values []interface{}) interface{} { } // MapLast collects the values to pass to the reducer -func MapLast(itr iterator) interface{} { +func MapLast(itr Iterator) interface{} { out := &firstLastMapOutput{} pointsYielded := false @@ -899,8 +999,6 @@ func MapLast(itr iterator) interface{} { if k > out.Time { out.Time = k out.Val = v - } else if k == out.Time && greaterThan(v, out.Val) { - out.Val = v } } if pointsYielded { @@ -929,8 +1027,6 @@ func ReduceLast(values []interface{}) interface{} { if val.Time > out.Time { out.Time = val.Time out.Val = val.Val - } else if val.Time == out.Time && greaterThan(val.Val, out.Val) { - out.Val = val.Val } } if pointsYielded { @@ -939,418 +1035,8 @@ func ReduceLast(values []interface{}) interface{} { return nil } -type positionOut struct { - points PositionPoints - callArgs []string // ordered args in the call -} - -func (p *positionOut) lessKey(i, j int) bool { - t1, t2 := p.points[i].Tags, p.points[j].Tags - for _, k := range p.callArgs { - if t1[k] != t2[k] { - return t1[k] < t2[k] - } - } - return false -} - -func cmpFloat(a, b float64) int { - if a == b { - return 0 - } else if a < b { - return -1 - } - return 1 -} - -func cmpInt(a, b int64) int { - if a == b { - return 0 - } else if a < b { - return -1 - } - return 1 -} - -func cmpUint(a, b uint64) int { - if a == b { - return 0 - } else if a < b { - return -1 - } - return 1 -} - -func interfaceCompare(a, b interface{}) int { - // compare by float64/int64 first as that is the most likely match - { - d1, ok1 := a.(float64) - d2, ok2 := b.(float64) - if ok1 && ok2 { - return cmpFloat(d1, d2) - } - } - - { - d1, ok1 := a.(int64) - d2, ok2 := b.(int64) - if ok1 && ok2 { - return cmpInt(d1, d2) - } - } - - // compare by every numeric type left - { - d1, ok1 := a.(float32) - d2, ok2 := b.(float32) - if ok1 && ok2 { - return cmpFloat(float64(d1), float64(d2)) - } - } - - { - d1, ok1 := a.(uint64) - d2, ok2 := b.(uint64) - if ok1 && ok2 { - return cmpUint(d1, d2) - } - } - - { - d1, ok1 := a.(uint32) - d2, ok2 := b.(uint32) - if ok1 && ok2 { - return cmpUint(uint64(d1), uint64(d2)) - } - } - - { - d1, ok1 := a.(uint16) - d2, ok2 := b.(uint16) - if ok1 && ok2 { - return cmpUint(uint64(d1), uint64(d2)) - } - } - - { - d1, ok1 := a.(uint8) - d2, ok2 := b.(uint8) - if ok1 && ok2 { - return cmpUint(uint64(d1), uint64(d2)) - } - } - - { - d1, ok1 := a.(int32) - d2, ok2 := b.(int32) - if ok1 && ok2 { - return cmpInt(int64(d1), int64(d2)) - } - } - - { - d1, ok1 := a.(int16) - d2, ok2 := b.(int16) - if ok1 && ok2 { - return cmpInt(int64(d1), int64(d2)) - } - } - - { - d1, ok1 := a.(int8) - d2, ok2 := b.(int8) - if ok1 && ok2 { - return cmpInt(int64(d1), int64(d2)) - } - } - - { - d1, ok1 := a.(bool) - d2, ok2 := b.(bool) - if ok1 && ok2 { - if d1 == d2 { - return 0 - } else if d1 == true && d2 == false { - return 1 - } - return -1 - } - } - - { - d1, ok1 := a.(string) - d2, ok2 := b.(string) - if ok1 && ok2 { - return strings.Compare(d1, d2) - } - } - - // Types did not match, need to sort based on arbitrary weighting of type - const ( - stringWeight = iota - boolWeight - intWeight - floatWeight - ) - - infer := func(val interface{}) (int, float64) { - switch v := val.(type) { - case uint64: - return intWeight, float64(v) - case uint32: - return intWeight, float64(v) - case uint16: - return intWeight, float64(v) - case uint8: - return intWeight, float64(v) - case int64: - return intWeight, float64(v) - case int32: - return intWeight, float64(v) - case int16: - return intWeight, float64(v) - case int8: - return intWeight, float64(v) - case float64: - return floatWeight, float64(v) - case float32: - return floatWeight, float64(v) - case bool: - return boolWeight, 0 - case string: - return stringWeight, 0 - } - panic("interfaceValues.Less - unreachable code") - } - - w1, n1 := infer(a) - w2, n2 := infer(b) - - // If we had "numeric" data, use that for comparison - if (w1 == floatWeight || w1 == intWeight) && (w2 == floatWeight || w2 == intWeight) { - cmp := cmpFloat(n1, n2) - // break ties - if cmp == 0 { - if w1 < w2 { - return -1 - } - return 1 - } - return cmp - } - - if w1 == w2 { - // this should never happen, since equal weight means - // it should have been handled at the start of this function. - panic("unreachable") - } else if w1 < w2 { - return -1 - } - return 1 -} - -type PositionPoints []PositionPoint -type PositionPoint struct { - Time int64 - Value interface{} - Tags map[string]string -} - -type topMapOut struct { - positionOut -} - -func (t topMapOut) Len() int { return len(t.points) } -func (t topMapOut) Swap(i, j int) { t.points[i], t.points[j] = t.points[j], t.points[i] } -func (t topMapOut) Less(i, j int) bool { - // old C trick makes this code easier to read. Imagine - // that the OP in "cmp(i, j) OP 0" is the comparison you want - // between i and j - cmp := interfaceCompare(t.points[i].Value, t.points[j].Value) - if cmp != 0 { - return cmp > 0 - } - k1, k2 := t.points[i].Time, t.points[j].Time - if k1 != k2 { - return k1 < k2 - } - return t.lessKey(i, j) -} - -type topReduceOut struct { - positionOut -} - -func (t topReduceOut) Len() int { return len(t.points) } -func (t topReduceOut) Swap(i, j int) { t.points[i], t.points[j] = t.points[j], t.points[i] } -func (t topReduceOut) Less(i, j int) bool { - // Now sort by time first, not value - - k1, k2 := t.points[i].Time, t.points[j].Time - if k1 != k2 { - return k1 < k2 - } - cmp := interfaceCompare(t.points[i].Value, t.points[j].Value) - if cmp != 0 { - return cmp > 0 - } - return t.lessKey(i, j) -} - -// callArgs will get any additional field/tag names that may be needed to sort with -// it is important to maintain the order of these that they were asked for in the call -// for sorting purposes -func topCallArgs(c *influxql.Call) []string { - var names []string - for _, v := range c.Args[1 : len(c.Args)-1] { - if f, ok := v.(*influxql.VarRef); ok { - names = append(names, f.Val) - } - } - return names -} - -// MapTop emits the top data points for each group by interval -func MapTop(itr iterator, c *influxql.Call) interface{} { - // Capture the limit if it was specified in the call - lit, _ := c.Args[len(c.Args)-1].(*influxql.NumberLiteral) - limit := int64(lit.Val) - - // Simple case where only value and limit are specified. - if len(c.Args) == 2 { - out := positionOut{callArgs: topCallArgs(c)} - - for k, v := itr.Next(); k != -1; k, v = itr.Next() { - t := k - if bt := itr.TMin(); bt > -1 { - t = bt - } - out.points = append(out.points, PositionPoint{t, v, itr.Tags()}) - } - - // If we have more than we asked for, only send back the top values - if int64(len(out.points)) > limit { - sort.Sort(topMapOut{out}) - out.points = out.points[:limit] - } - if len(out.points) > 0 { - return out.points - } - return nil - } - // They specified tags in the call to get unique sets, so we need to map them as we accumulate them - outMap := make(map[string]positionOut) - - mapKey := func(args []string, fields map[string]interface{}, keys map[string]string) string { - key := "" - for _, a := range args { - if v, ok := fields[a]; ok { - key += a + ":" + fmt.Sprintf("%v", v) + "," - continue - } - if v, ok := keys[a]; ok { - key += a + ":" + v + "," - continue - } - } - return key - } - - for k, v := itr.Next(); k != -1; k, v = itr.Next() { - t := k - if bt := itr.TMin(); bt > -1 { - t = bt - } - callArgs := c.Fields() - tags := itr.Tags() - // TODO in the future we need to send in fields as well - // this will allow a user to query on both fields and tags - // fields will take the priority over tags if there is a name collision - key := mapKey(callArgs, nil, tags) - if out, ok := outMap[key]; ok { - out.points = append(out.points, PositionPoint{t, v, itr.Tags()}) - outMap[key] = out - } else { - out = positionOut{callArgs: topCallArgs(c)} - out.points = append(out.points, PositionPoint{t, v, itr.Tags()}) - outMap[key] = out - } - } - // Sort all the maps - for k, v := range outMap { - sort.Sort(topMapOut{v}) - outMap[k] = v - } - - slice := func(needed int64, m map[string]positionOut) PositionPoints { - points := PositionPoints{} - var collected int64 - for k, v := range m { - if len(v.points) > 0 { - points = append(points, v.points[0]) - v.points = v.points[1:] - m[k] = v - collected++ - } - } - o := positionOut{callArgs: topCallArgs(c), points: points} - sort.Sort(topMapOut{o}) - points = o.points - // If we got more than we needed, sort them and return the top - if collected > needed { - points = o.points[:needed] - } - - return points - } - - points := PositionPoints{} - var collected int64 - for collected < limit { - p := slice(limit-collected, outMap) - if len(p) == 0 { - break - } - points = append(points, p...) - collected += int64(len(p)) - } - if len(points) > 0 { - return points - } - return nil -} - -// ReduceTop computes the top values for each key. -func ReduceTop(values []interface{}, c *influxql.Call) interface{} { - lit, _ := c.Args[len(c.Args)-1].(*influxql.NumberLiteral) - limit := int64(lit.Val) - - out := positionOut{callArgs: topCallArgs(c)} - for _, v := range values { - if v == nil { - continue - } - o, _ := v.(PositionPoints) - out.points = append(out.points, o...) - } - - // Get the top of the top values - sort.Sort(topMapOut{out}) - // If we have more than we asked for, only send back the top values - if int64(len(out.points)) > limit { - out.points = out.points[:limit] - } - - // now we need to resort the tops by time - sort.Sort(topReduceOut{out}) - if len(out.points) > 0 { - return out.points - } - return nil -} - // MapEcho emits the data points for each group by interval -func MapEcho(itr iterator) interface{} { +func MapEcho(itr Iterator) interface{} { var values []interface{} for k, v := itr.Next(); k != -1; k, v = itr.Next() { @@ -1360,43 +1046,40 @@ func MapEcho(itr iterator) interface{} { } // ReducePercentile computes the percentile of values for each key. -func ReducePercentile(values []interface{}, c *influxql.Call) interface{} { - // Checks that this arg exists and is a valid type are done in the parsing validation - // and have test coverage there - lit, _ := c.Args[1].(*influxql.NumberLiteral) - percentile := lit.Val +func ReducePercentile(percentile float64) ReduceFunc { + return func(values []interface{}) interface{} { + var allValues []float64 - var allValues []float64 + for _, v := range values { + if v == nil { + continue + } - for _, v := range values { - if v == nil { - continue - } - - vals := v.([]interface{}) - for _, v := range vals { - switch v.(type) { - case int64: - allValues = append(allValues, float64(v.(int64))) - case float64: - allValues = append(allValues, v.(float64)) + vals := v.([]interface{}) + for _, v := range vals { + switch v.(type) { + case int64: + allValues = append(allValues, float64(v.(int64))) + case float64: + allValues = append(allValues, v.(float64)) + } } } + + sort.Float64s(allValues) + length := len(allValues) + index := int(math.Floor(float64(length)*percentile/100.0+0.5)) - 1 + + if index < 0 || index >= len(allValues) { + return nil + } + + return allValues[index] } - - sort.Float64s(allValues) - length := len(allValues) - index := int(math.Floor(float64(length)*percentile/100.0+0.5)) - 1 - - if index < 0 || index >= len(allValues) { - return nil - } - - return allValues[index] } // IsNumeric returns whether a given aggregate can only be run on numeric fields. -func IsNumeric(c *influxql.Call) bool { +func IsNumeric(c *Call) bool { switch c.Name { case "count", "first", "last", "distinct": return false @@ -1406,7 +1089,7 @@ func IsNumeric(c *influxql.Call) bool { } // MapRawQuery is for queries without aggregates -func MapRawQuery(itr iterator) interface{} { +func MapRawQuery(itr Iterator) interface{} { var values []*rawQueryMapOutput for k, v := itr.Next(); k != -1; k, v = itr.Next() { val := &rawQueryMapOutput{k, v} @@ -1429,17 +1112,3 @@ type rawOutputs []*rawQueryMapOutput func (a rawOutputs) Len() int { return len(a) } func (a rawOutputs) Less(i, j int) bool { return a[i].Time < a[j].Time } func (a rawOutputs) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -func greaterThan(a, b interface{}) bool { - switch t := a.(type) { - case int64: - return t > b.(int64) - case float64: - return t > b.(float64) - case string: - return t > b.(string) - case bool: - return t == true - } - return false -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions_test.go new file mode 100644 index 000000000..56303d8d9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/functions_test.go @@ -0,0 +1,534 @@ +package influxql + +import ( + "reflect" + "testing" + "time" + + "github.com/davecgh/go-spew/spew" +) + +import "sort" + +type point struct { + seriesKey string + time int64 + value interface{} +} + +type testIterator struct { + values []point +} + +func (t *testIterator) Next() (timestamp int64, value interface{}) { + if len(t.values) > 0 { + v := t.values[0] + t.values = t.values[1:] + return v.time, v.value + } + + return -1, nil +} + +func TestMapMeanNoValues(t *testing.T) { + iter := &testIterator{} + if got := MapMean(iter); got != nil { + t.Errorf("output mismatch: exp nil got %v", got) + } +} + +func TestMapMean(t *testing.T) { + + tests := []struct { + input []point + output *meanMapOutput + }{ + { // Single point + input: []point{point{"0", 1, 1.0}}, + output: &meanMapOutput{1, 1, Float64Type}, + }, + { // Two points + input: []point{ + point{"0", 1, 2.0}, + point{"0", 2, 8.0}, + }, + output: &meanMapOutput{2, 5.0, Float64Type}, + }, + } + + for _, test := range tests { + iter := &testIterator{ + values: test.input, + } + + got := MapMean(iter) + if got == nil { + t.Fatalf("MapMean(%v): output mismatch: exp %v got %v", test.input, test.output, got) + } + + if got.(*meanMapOutput).Count != test.output.Count || got.(*meanMapOutput).Mean != test.output.Mean { + t.Errorf("output mismatch: exp %v got %v", test.output, got) + } + } +} +func TestInitializeMapFuncPercentile(t *testing.T) { + // No args + c := &Call{ + Name: "percentile", + Args: []Expr{}, + } + _, err := InitializeMapFunc(c) + if err == nil { + t.Errorf("InitializeMapFunc(%v) expected error. got nil", c) + } + + if exp := "expected two arguments for percentile()"; err.Error() != exp { + t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error()) + } + + // No percentile arg + c = &Call{ + Name: "percentile", + Args: []Expr{ + &VarRef{Val: "field1"}, + }, + } + + _, err = InitializeMapFunc(c) + if err == nil { + t.Errorf("InitializeMapFunc(%v) expected error. got nil", c) + } + + if exp := "expected two arguments for percentile()"; err.Error() != exp { + t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error()) + } +} + +func TestInitializeMapFuncDerivative(t *testing.T) { + + for _, fn := range []string{"derivative", "non_negative_derivative"} { + // No args should fail + c := &Call{ + Name: fn, + Args: []Expr{}, + } + + _, err := InitializeMapFunc(c) + if err == nil { + t.Errorf("InitializeMapFunc(%v) expected error. got nil", c) + } + + // Single field arg should return MapEcho + c = &Call{ + Name: fn, + Args: []Expr{ + &VarRef{Val: " field1"}, + &DurationLiteral{Val: time.Hour}, + }, + } + + _, err = InitializeMapFunc(c) + if err != nil { + t.Errorf("InitializeMapFunc(%v) unexpected error. got %v", c, err) + } + + // Nested Aggregate func should return the map func for the nested aggregate + c = &Call{ + Name: fn, + Args: []Expr{ + &Call{Name: "mean", Args: []Expr{&VarRef{Val: "field1"}}}, + &DurationLiteral{Val: time.Hour}, + }, + } + + _, err = InitializeMapFunc(c) + if err != nil { + t.Errorf("InitializeMapFunc(%v) unexpected error. got %v", c, err) + } + } +} + +func TestInitializeReduceFuncPercentile(t *testing.T) { + // No args + c := &Call{ + Name: "percentile", + Args: []Expr{}, + } + _, err := InitializeReduceFunc(c) + if err == nil { + t.Errorf("InitializedReduceFunc(%v) expected error. got nil", c) + } + + if exp := "expected float argument in percentile()"; err.Error() != exp { + t.Errorf("InitializedReduceFunc(%v) mismatch. exp %v got %v", c, exp, err.Error()) + } + + // No percentile arg + c = &Call{ + Name: "percentile", + Args: []Expr{ + &VarRef{Val: "field1"}, + }, + } + + _, err = InitializeReduceFunc(c) + if err == nil { + t.Errorf("InitializedReduceFunc(%v) expected error. got nil", c) + } + + if exp := "expected float argument in percentile()"; err.Error() != exp { + t.Errorf("InitializedReduceFunc(%v) mismatch. exp %v got %v", c, exp, err.Error()) + } +} + +func TestReducePercentileNil(t *testing.T) { + + // ReducePercentile should ignore nil values when calculating the percentile + fn := ReducePercentile(100) + input := []interface{}{ + nil, + } + + got := fn(input) + if got != nil { + t.Fatalf("ReducePercentile(100) returned wrong type. exp nil got %v", got) + } +} + +func TestMapDistinct(t *testing.T) { + const ( // prove that we're ignoring seriesKey + seriesKey1 = "1" + seriesKey2 = "2" + ) + + const ( // prove that we're ignoring time + timeId1 = iota + 1 + timeId2 + timeId3 + timeId4 + timeId5 + timeId6 + ) + + iter := &testIterator{ + values: []point{ + {seriesKey1, timeId1, uint64(1)}, + {seriesKey1, timeId2, uint64(1)}, + {seriesKey1, timeId3, "1"}, + {seriesKey2, timeId4, uint64(1)}, + {seriesKey2, timeId5, float64(1.0)}, + {seriesKey2, timeId6, "1"}, + }, + } + + values := MapDistinct(iter).(distinctValues) + + if exp, got := 3, len(values); exp != got { + t.Errorf("Wrong number of values. exp %v got %v", exp, got) + } + + sort.Sort(values) + + exp := distinctValues{ + uint64(1), + float64(1), + "1", + } + + if !reflect.DeepEqual(values, exp) { + t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(values)) + } +} + +func TestMapDistinctNil(t *testing.T) { + iter := &testIterator{ + values: []point{}, + } + + values := MapDistinct(iter) + + if values != nil { + t.Errorf("Wrong values. exp nil got %v", spew.Sdump(values)) + } +} + +func TestReduceDistinct(t *testing.T) { + v1 := distinctValues{ + "2", + "1", + float64(2.0), + float64(1), + uint64(2), + uint64(1), + true, + false, + } + + expect := distinctValues{ + uint64(1), + float64(1), + uint64(2), + float64(2), + false, + true, + "1", + "2", + } + + got := ReduceDistinct([]interface{}{v1, v1, expect}) + + if !reflect.DeepEqual(got, expect) { + t.Errorf("Wrong values. exp %v got %v", spew.Sdump(expect), spew.Sdump(got)) + } +} + +func TestReduceDistinctNil(t *testing.T) { + tests := []struct { + name string + values []interface{} + }{ + { + name: "nil values", + values: nil, + }, + { + name: "nil mapper", + values: []interface{}{nil}, + }, + { + name: "no mappers", + values: []interface{}{}, + }, + { + name: "empty mappper (len 1)", + values: []interface{}{distinctValues{}}, + }, + { + name: "empty mappper (len 2)", + values: []interface{}{distinctValues{}, distinctValues{}}, + }, + } + + for _, test := range tests { + t.Log(test.name) + got := ReduceDistinct(test.values) + if got != nil { + t.Errorf("Wrong values. exp nil got %v", spew.Sdump(got)) + } + } +} + +func Test_distinctValues_Sort(t *testing.T) { + values := distinctValues{ + "2", + "1", + float64(2.0), + float64(1), + uint64(2), + uint64(1), + true, + false, + } + + expect := distinctValues{ + uint64(1), + float64(1), + uint64(2), + float64(2), + false, + true, + "1", + "2", + } + + sort.Sort(values) + + if !reflect.DeepEqual(values, expect) { + t.Errorf("Wrong values. exp %v got %v", spew.Sdump(expect), spew.Sdump(values)) + } +} + +func TestMapCountDistinct(t *testing.T) { + const ( // prove that we're ignoring seriesKey + seriesKey1 = "1" + seriesKey2 = "2" + ) + + const ( // prove that we're ignoring time + timeId1 = iota + 1 + timeId2 + timeId3 + timeId4 + timeId5 + timeId6 + timeId7 + ) + + iter := &testIterator{ + values: []point{ + {seriesKey1, timeId1, uint64(1)}, + {seriesKey1, timeId2, uint64(1)}, + {seriesKey1, timeId3, "1"}, + {seriesKey2, timeId4, uint64(1)}, + {seriesKey2, timeId5, float64(1.0)}, + {seriesKey2, timeId6, "1"}, + {seriesKey2, timeId7, true}, + }, + } + + values := MapCountDistinct(iter).(map[interface{}]struct{}) + + if exp, got := 4, len(values); exp != got { + t.Errorf("Wrong number of values. exp %v got %v", exp, got) + } + + exp := map[interface{}]struct{}{ + uint64(1): struct{}{}, + float64(1): struct{}{}, + "1": struct{}{}, + true: struct{}{}, + } + + if !reflect.DeepEqual(values, exp) { + t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(values)) + } +} + +func TestMapCountDistinctNil(t *testing.T) { + iter := &testIterator{ + values: []point{}, + } + + values := MapCountDistinct(iter) + + if values != nil { + t.Errorf("Wrong values. exp nil got %v", spew.Sdump(values)) + } +} + +func TestReduceCountDistinct(t *testing.T) { + v1 := map[interface{}]struct{}{ + "2": struct{}{}, + "1": struct{}{}, + float64(2.0): struct{}{}, + float64(1): struct{}{}, + uint64(2): struct{}{}, + uint64(1): struct{}{}, + true: struct{}{}, + false: struct{}{}, + } + + v2 := map[interface{}]struct{}{ + uint64(1): struct{}{}, + float64(1): struct{}{}, + uint64(2): struct{}{}, + float64(2): struct{}{}, + false: struct{}{}, + true: struct{}{}, + "1": struct{}{}, + "2": struct{}{}, + } + + exp := 8 + got := ReduceCountDistinct([]interface{}{v1, v1, v2}) + + if !reflect.DeepEqual(got, exp) { + t.Errorf("Wrong values. exp %v got %v", spew.Sdump(exp), spew.Sdump(got)) + } +} + +func TestReduceCountDistinctNil(t *testing.T) { + emptyResults := make(map[interface{}]struct{}) + tests := []struct { + name string + values []interface{} + }{ + { + name: "nil values", + values: nil, + }, + { + name: "nil mapper", + values: []interface{}{nil}, + }, + { + name: "no mappers", + values: []interface{}{}, + }, + { + name: "empty mappper (len 1)", + values: []interface{}{emptyResults}, + }, + { + name: "empty mappper (len 2)", + values: []interface{}{emptyResults, emptyResults}, + }, + } + + for _, test := range tests { + t.Log(test.name) + got := ReduceCountDistinct(test.values) + if got != 0 { + t.Errorf("Wrong values. exp nil got %v", spew.Sdump(got)) + } + } +} + +var getSortedRangeData = []float64{ + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, +} + +var getSortedRangeTests = []struct { + name string + data []float64 + start int + count int + expected []float64 +}{ + {"first 5", getSortedRangeData, 0, 5, []float64{0, 1, 2, 3, 4}}, + {"0 length", getSortedRangeData, 8, 0, []float64{}}, + {"past end of data", getSortedRangeData, len(getSortedRangeData) - 3, 5, []float64{67, 68, 69}}, +} + +func TestGetSortedRange(t *testing.T) { + for _, tt := range getSortedRangeTests { + results := getSortedRange(tt.data, tt.start, tt.count) + if len(results) != len(tt.expected) { + t.Errorf("Test %s error. Expected getSortedRange to return %v but got %v", tt.name, tt.expected, results) + } + for i, point := range tt.expected { + if point != results[i] { + t.Errorf("Test %s error. getSortedRange returned wrong result for index %v. Expected %v but got %v", tt.name, i, point, results[i]) + } + } + } +} + +var benchGetSortedRangeResults []float64 + +func BenchmarkGetSortedRangeByPivot(b *testing.B) { + data := make([]float64, len(getSortedRangeData)) + var results []float64 + for i := 0; i < b.N; i++ { + copy(data, getSortedRangeData) + results = getSortedRange(data, 8, 15) + } + benchGetSortedRangeResults = results +} + +func BenchmarkGetSortedRangeBySort(b *testing.B) { + data := make([]float64, len(getSortedRangeData)) + var results []float64 + for i := 0; i < b.N; i++ { + copy(data, getSortedRangeData) + sort.Float64s(data) + results = data[8:23] + } + benchGetSortedRangeResults = results +} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser.go index 4c55e5e84..b2c51e595 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser.go @@ -129,8 +129,6 @@ func (p *Parser) parseShowStatement() (Statement, error) { return nil, newParseError(tokstr(tok, lit), []string{"POLICIES"}, pos) case SERIES: return p.parseShowSeriesStatement() - case SHARDS: - return p.parseShowShardsStatement() case STATS: return p.parseShowStatsStatement() case DIAGNOSTICS: @@ -490,9 +488,6 @@ func (p *Parser) parseSegmentedIdents() ([]string, error) { if ch := p.peekRune(); ch == '/' { // Next segment is a regex so we're done. break - } else if ch == ':' { - // Next segment is context-specific so let caller handle it. - break } else if ch == '.' { // Add an empty identifier. idents = append(idents, "") @@ -804,18 +799,7 @@ func (p *Parser) parseTarget(tr targetRequirement) (*Target, error) { return nil, err } - if len(idents) < 3 { - // Check for source measurement reference. - if ch := p.peekRune(); ch == ':' { - if err := p.parseTokens([]Token{COLON, MEASUREMENT}); err != nil { - return nil, err - } - // Append empty measurement name. - idents = append(idents, "") - } - } - - t := &Target{Measurement: &Measurement{IsTarget: true}} + t := &Target{Measurement: &Measurement{}} switch len(idents) { case 1: @@ -1266,16 +1250,6 @@ func (p *Parser) parseCreateContinuousQueryStatement() (*CreateContinuousQuerySt func (p *Parser) parseCreateDatabaseStatement() (*CreateDatabaseStatement, error) { stmt := &CreateDatabaseStatement{} - // Look for "IF NOT EXISTS" - if tok, _, _ := p.scanIgnoreWhitespace(); tok == IF { - if err := p.parseTokens([]Token{NOT, EXISTS}); err != nil { - return nil, err - } - stmt.IfNotExists = true - } else { - p.unscan() - } - // Parse the name of the database to be created. lit, err := p.parseIdent() if err != nil { @@ -1411,12 +1385,6 @@ func (p *Parser) parseRetentionPolicy() (name string, dfault bool, err error) { return } -// parseShowShardsStatement parses a string for "SHOW SHARDS" statement. -// This function assumes the "SHOW SHARDS" tokens have already been consumed. -func (p *Parser) parseShowShardsStatement() (*ShowShardsStatement, error) { - return &ShowShardsStatement{}, nil -} - // parseShowStatsStatement parses a string and returns a ShowStatsStatement. // This function assumes the "SHOW STATS" tokens have already been consumed. func (p *Parser) parseShowStatsStatement() (*ShowStatsStatement, error) { @@ -1473,6 +1441,13 @@ func (p *Parser) parseDropContinuousQueryStatement() (*DropContinuousQueryStatem func (p *Parser) parseFields() (Fields, error) { var fields Fields + // Check for "*" (i.e., "all fields") + if tok, _, _ := p.scanIgnoreWhitespace(); tok == MUL { + fields = append(fields, &Field{&Wildcard{}, ""}) + return fields, nil + } + p.unscan() + for { // Parse the field. f, err := p.parseField() @@ -1802,29 +1777,24 @@ func (p *Parser) parseOrderBy() (SortFields, error) { func (p *Parser) parseSortFields() (SortFields, error) { var fields SortFields - tok, pos, lit := p.scanIgnoreWhitespace() - - switch tok { - // The first field after an order by may not have a field name (e.g. ORDER BY ASC) - case ASC, DESC: - fields = append(fields, &SortField{Ascending: (tok == ASC)}) - // If it's a token, parse it as a sort field. At least one is required. - case IDENT: - p.unscan() - field, err := p.parseSortField() - if err != nil { - return nil, err + // If first token is ASC or DESC, all fields are sorted. + if tok, pos, lit := p.scanIgnoreWhitespace(); tok == ASC || tok == DESC { + if tok == DESC { + // Token must be ASC, until other sort orders are supported. + return nil, errors.New("only ORDER BY time ASC supported at this time") } - - if lit != "time" { - return nil, errors.New("only ORDER BY time supported at this time") - } - - fields = append(fields, field) - // Parse error... - default: + return append(fields, &SortField{Ascending: (tok == ASC)}), nil + } else if tok != IDENT { return nil, newParseError(tokstr(tok, lit), []string{"identifier", "ASC", "DESC"}, pos) } + p.unscan() + + // At least one field is required. + field, err := p.parseSortField() + if err != nil { + return nil, err + } + fields = append(fields, field) // Parse additional fields. for { @@ -1843,8 +1813,9 @@ func (p *Parser) parseSortFields() (SortFields, error) { fields = append(fields, field) } - if len(fields) > 1 { - return nil, errors.New("only ORDER BY time supported at this time") + // First SortField must be time ASC, until other sort orders are supported. + if len(fields) > 1 || fields[0].Name != "time" || !fields[0].Ascending { + return nil, errors.New("only ORDER BY time ASC supported at this time") } return fields, nil diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser_test.go index 94944398a..b9bb9756d 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/parser_test.go @@ -73,45 +73,11 @@ func TestParser_ParseStatement(t *testing.T) { Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, }, }, - { - s: `SELECT * FROM myseries GROUP BY *`, - stmt: &influxql.SelectStatement{ - IsRawQuery: true, - Fields: []*influxql.Field{ - {Expr: &influxql.Wildcard{}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, - Dimensions: []*influxql.Dimension{{Expr: &influxql.Wildcard{}}}, - }, - }, - { - s: `SELECT field1, * FROM myseries GROUP BY *`, - stmt: &influxql.SelectStatement{ - IsRawQuery: true, - Fields: []*influxql.Field{ - {Expr: &influxql.VarRef{Val: "field1"}}, - {Expr: &influxql.Wildcard{}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, - Dimensions: []*influxql.Dimension{{Expr: &influxql.Wildcard{}}}, - }, - }, - { - s: `SELECT *, field1 FROM myseries GROUP BY *`, - stmt: &influxql.SelectStatement{ - IsRawQuery: true, - Fields: []*influxql.Field{ - {Expr: &influxql.Wildcard{}}, - {Expr: &influxql.VarRef{Val: "field1"}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, - Dimensions: []*influxql.Dimension{{Expr: &influxql.Wildcard{}}}, - }, - }, // SELECT statement { - s: fmt.Sprintf(`SELECT mean(field1), sum(field2) ,count(field3) AS field_x FROM myseries WHERE host = 'hosta.influxdb.org' and time > '%s' GROUP BY time(10h) ORDER BY DESC LIMIT 20 OFFSET 10;`, now.UTC().Format(time.RFC3339Nano)), + skip: true, + s: fmt.Sprintf(`SELECT mean(field1), sum(field2) ,count(field3) AS field_x FROM myseries WHERE host = 'hosta.influxdb.org' and time > '%s' GROUP BY time(10h) ORDER BY ASC LIMIT 20 OFFSET 10;`, now.UTC().Format(time.RFC3339Nano)), stmt: &influxql.SelectStatement{ IsRawQuery: false, Fields: []*influxql.Field{ @@ -135,32 +101,12 @@ func TestParser_ParseStatement(t *testing.T) { }, Dimensions: []*influxql.Dimension{{Expr: &influxql.Call{Name: "time", Args: []influxql.Expr{&influxql.DurationLiteral{Val: 10 * time.Hour}}}}}, SortFields: []*influxql.SortField{ - {Ascending: false}, + {Ascending: true}, }, Limit: 20, Offset: 10, }, }, - { - s: `SELECT "foo.bar.baz" AS foo FROM myseries`, - stmt: &influxql.SelectStatement{ - IsRawQuery: true, - Fields: []*influxql.Field{ - {Expr: &influxql.VarRef{Val: "foo.bar.baz"}, Alias: "foo"}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, - }, - }, - { - s: `SELECT "foo.bar.baz" AS foo FROM foo`, - stmt: &influxql.SelectStatement{ - IsRawQuery: true, - Fields: []*influxql.Field{ - {Expr: &influxql.VarRef{Val: "foo.bar.baz"}, Alias: "foo"}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "foo"}}, - }, - }, // derivative { @@ -268,65 +214,6 @@ func TestParser_ParseStatement(t *testing.T) { }, }, - // select percentile statements - { - s: `select percentile("field1", 2.0) from cpu`, - stmt: &influxql.SelectStatement{ - IsRawQuery: false, - Fields: []*influxql.Field{ - {Expr: &influxql.Call{Name: "percentile", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}, &influxql.NumberLiteral{Val: 2.0}}}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}}, - }, - }, - - // select top statements - { - s: `select top("field1", 2) from cpu`, - stmt: &influxql.SelectStatement{ - IsRawQuery: false, - Fields: []*influxql.Field{ - {Expr: &influxql.Call{Name: "top", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}, &influxql.NumberLiteral{Val: 2}}}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}}, - }, - }, - - { - s: `select top(field1, 2) from cpu`, - stmt: &influxql.SelectStatement{ - IsRawQuery: false, - Fields: []*influxql.Field{ - {Expr: &influxql.Call{Name: "top", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}, &influxql.NumberLiteral{Val: 2}}}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}}, - }, - }, - - { - s: `select top(field1, 2), tag1 from cpu`, - stmt: &influxql.SelectStatement{ - IsRawQuery: false, - Fields: []*influxql.Field{ - {Expr: &influxql.Call{Name: "top", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}, &influxql.NumberLiteral{Val: 2}}}}, - {Expr: &influxql.VarRef{Val: "tag1"}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}}, - }, - }, - - { - s: `select top(field1, tag1, 2), tag1 from cpu`, - stmt: &influxql.SelectStatement{ - IsRawQuery: false, - Fields: []*influxql.Field{ - {Expr: &influxql.Call{Name: "top", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}, &influxql.VarRef{Val: "tag1"}, &influxql.NumberLiteral{Val: 2}}}}, - {Expr: &influxql.VarRef{Val: "tag1"}}, - }, - Sources: []influxql.Source{&influxql.Measurement{Name: "cpu"}}, - }, - }, - // select distinct statements { s: `select distinct(field1) from cpu`, @@ -700,17 +587,17 @@ func TestParser_ParseStatement(t *testing.T) { // SHOW SERIES WHERE with ORDER BY and LIMIT { skip: true, - s: `SHOW SERIES WHERE region = 'order by desc' ORDER BY DESC, field1, field2 DESC LIMIT 10`, + s: `SHOW SERIES WHERE region = 'uswest' ORDER BY ASC, field1, field2 DESC LIMIT 10`, stmt: &influxql.ShowSeriesStatement{ Condition: &influxql.BinaryExpr{ Op: influxql.EQ, LHS: &influxql.VarRef{Val: "region"}, - RHS: &influxql.StringLiteral{Val: "order by desc"}, + RHS: &influxql.StringLiteral{Val: "uswest"}, }, SortFields: []*influxql.SortField{ - &influxql.SortField{Ascending: false}, - &influxql.SortField{Name: "field1", Ascending: true}, - &influxql.SortField{Name: "field2"}, + {Ascending: true}, + {Name: "field1"}, + {Name: "field2"}, }, Limit: 10, }, @@ -943,7 +830,7 @@ func TestParser_ParseStatement(t *testing.T) { Database: "testdb", Source: &influxql.SelectStatement{ Fields: []*influxql.Field{{Expr: &influxql.Call{Name: "count", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}}}}}, - Target: &influxql.Target{Measurement: &influxql.Measurement{Name: "measure1", IsTarget: true}}, + Target: &influxql.Target{Measurement: &influxql.Measurement{Name: "measure1"}}, Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, Dimensions: []*influxql.Dimension{ { @@ -967,7 +854,7 @@ func TestParser_ParseStatement(t *testing.T) { Source: &influxql.SelectStatement{ IsRawQuery: true, Fields: []*influxql.Field{{Expr: &influxql.Wildcard{}}}, - Target: &influxql.Target{Measurement: &influxql.Measurement{Name: "measure1", IsTarget: true}}, + Target: &influxql.Target{Measurement: &influxql.Measurement{Name: "measure1"}}, Sources: []influxql.Source{&influxql.Measurement{Name: "cpu_load_short"}}, }, }, @@ -982,7 +869,7 @@ func TestParser_ParseStatement(t *testing.T) { Source: &influxql.SelectStatement{ Fields: []*influxql.Field{{Expr: &influxql.Call{Name: "count", Args: []influxql.Expr{&influxql.VarRef{Val: "field1"}}}}}, Target: &influxql.Target{ - Measurement: &influxql.Measurement{RetentionPolicy: "1h.policy1", Name: "cpu.load", IsTarget: true}, + Measurement: &influxql.Measurement{RetentionPolicy: "1h.policy1", Name: "cpu.load"}, }, Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, Dimensions: []*influxql.Dimension{ @@ -1009,7 +896,7 @@ func TestParser_ParseStatement(t *testing.T) { IsRawQuery: true, Fields: []*influxql.Field{{Expr: &influxql.VarRef{Val: "value"}}}, Target: &influxql.Target{ - Measurement: &influxql.Measurement{RetentionPolicy: "policy1", Name: "value", IsTarget: true}, + Measurement: &influxql.Measurement{RetentionPolicy: "policy1", Name: "value"}, }, Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, }, @@ -1027,52 +914,18 @@ func TestParser_ParseStatement(t *testing.T) { Fields: []*influxql.Field{{Expr: &influxql.VarRef{Val: "transmit_rx"}}, {Expr: &influxql.VarRef{Val: "transmit_tx"}}}, Target: &influxql.Target{ - Measurement: &influxql.Measurement{RetentionPolicy: "policy1", Name: "network", IsTarget: true}, + Measurement: &influxql.Measurement{RetentionPolicy: "policy1", Name: "network"}, }, Sources: []influxql.Source{&influxql.Measurement{Name: "myseries"}}, }, }, }, - // CREATE CONTINUOUS QUERY with backreference measurement name - { - s: `CREATE CONTINUOUS QUERY myquery ON testdb BEGIN SELECT mean(value) INTO "policy1".:measurement FROM /^[a-z]+.*/ GROUP BY time(1m) END`, - stmt: &influxql.CreateContinuousQueryStatement{ - Name: "myquery", - Database: "testdb", - Source: &influxql.SelectStatement{ - Fields: []*influxql.Field{{Expr: &influxql.Call{Name: "mean", Args: []influxql.Expr{&influxql.VarRef{Val: "value"}}}}}, - Target: &influxql.Target{ - Measurement: &influxql.Measurement{RetentionPolicy: "policy1", IsTarget: true}, - }, - Sources: []influxql.Source{&influxql.Measurement{Regex: &influxql.RegexLiteral{Val: regexp.MustCompile(`^[a-z]+.*`)}}}, - Dimensions: []*influxql.Dimension{ - { - Expr: &influxql.Call{ - Name: "time", - Args: []influxql.Expr{ - &influxql.DurationLiteral{Val: 1 * time.Minute}, - }, - }, - }, - }, - }, - }, - }, - // CREATE DATABASE statement { s: `CREATE DATABASE testdb`, stmt: &influxql.CreateDatabaseStatement{ - Name: "testdb", - IfNotExists: false, - }, - }, - { - s: `CREATE DATABASE IF NOT EXISTS testdb`, - stmt: &influxql.CreateDatabaseStatement{ - Name: "testdb", - IfNotExists: true, + Name: "testdb", }, }, @@ -1344,12 +1197,6 @@ func TestParser_ParseStatement(t *testing.T) { }, }, - // SHOW SHARDS - { - s: `SHOW SHARDS`, - stmt: &influxql.ShowShardsStatement{}, - }, - // SHOW DIAGNOSTICS { s: `SHOW DIAGNOSTICS`, @@ -1366,21 +1213,6 @@ func TestParser_ParseStatement(t *testing.T) { {s: `SELECT field1 FROM myseries GROUP`, err: `found EOF, expected BY at line 1, char 35`}, {s: `SELECT field1 FROM myseries LIMIT`, err: `found EOF, expected number at line 1, char 35`}, {s: `SELECT field1 FROM myseries LIMIT 10.5`, err: `fractional parts not allowed in LIMIT at line 1, char 35`}, - {s: `SELECT top() FROM myseries`, err: `invalid number of arguments for top, expected at least 2, got 0`}, - {s: `SELECT top(field1) FROM myseries`, err: `invalid number of arguments for top, expected at least 2, got 1`}, - {s: `SELECT top(field1,foo) FROM myseries`, err: `expected integer as last argument in top(), found foo`}, - {s: `SELECT top(field1,host,server,foo) FROM myseries`, err: `expected integer as last argument in top(), found foo`}, - {s: `SELECT top(field1,5,server,2) FROM myseries`, err: `only fields or tags are allowed in top(), found 5.000`}, - {s: `SELECT top(field1,max(foo),server,2) FROM myseries`, err: `only fields or tags are allowed in top(), found max(foo)`}, - {s: `SELECT bottom() FROM myseries`, err: `invalid number of arguments for bottom, expected at least 2, got 0`}, - {s: `SELECT bottom(field1) FROM myseries`, err: `invalid number of arguments for bottom, expected at least 2, got 1`}, - {s: `SELECT bottom(field1,foo) FROM myseries`, err: `expected integer as last argument in bottom(), found foo`}, - {s: `SELECT bottom(field1,host,server,foo) FROM myseries`, err: `expected integer as last argument in bottom(), found foo`}, - {s: `SELECT bottom(field1,5,server,2) FROM myseries`, err: `only fields or tags are allowed in bottom(), found 5.000`}, - {s: `SELECT bottom(field1,max(foo),server,2) FROM myseries`, err: `only fields or tags are allowed in bottom(), found max(foo)`}, - {s: `SELECT percentile() FROM myseries`, err: `invalid number of arguments for percentile, expected 2, got 0`}, - {s: `SELECT percentile(field1) FROM myseries`, err: `invalid number of arguments for percentile, expected 2, got 1`}, - {s: `SELECT percentile(field1, foo) FROM myseries`, err: `expected float argument in percentile()`}, {s: `SELECT field1 FROM myseries OFFSET`, err: `found EOF, expected number at line 1, char 36`}, {s: `SELECT field1 FROM myseries OFFSET 10.5`, err: `fractional parts not allowed in OFFSET at line 1, char 36`}, {s: `SELECT field1 FROM myseries ORDER`, err: `found EOF, expected BY at line 1, char 35`}, @@ -1388,20 +1220,19 @@ func TestParser_ParseStatement(t *testing.T) { {s: `SELECT field1 FROM myseries ORDER BY /`, err: `found /, expected identifier, ASC, DESC at line 1, char 38`}, {s: `SELECT field1 FROM myseries ORDER BY 1`, err: `found 1, expected identifier, ASC, DESC at line 1, char 38`}, {s: `SELECT field1 FROM myseries ORDER BY time ASC,`, err: `found EOF, expected identifier at line 1, char 47`}, - {s: `SELECT field1 FROM myseries ORDER BY time, field1`, err: `only ORDER BY time supported at this time`}, + {s: `SELECT field1 FROM myseries ORDER BY DESC`, err: `only ORDER BY time ASC supported at this time`}, + {s: `SELECT field1 FROM myseries ORDER BY field1`, err: `only ORDER BY time ASC supported at this time`}, + {s: `SELECT field1 FROM myseries ORDER BY time DESC`, err: `only ORDER BY time ASC supported at this time`}, + {s: `SELECT field1 FROM myseries ORDER BY time, field1`, err: `only ORDER BY time ASC supported at this time`}, {s: `SELECT field1 AS`, err: `found EOF, expected identifier at line 1, char 18`}, {s: `SELECT field1 FROM foo group by time(1s)`, err: `GROUP BY requires at least one aggregate function`}, {s: `SELECT count(value), value FROM foo`, err: `mixing aggregate and non-aggregate queries is not supported`}, {s: `SELECT count(value) FROM foo group by time(1s)`, err: `aggregate functions with GROUP BY time require a WHERE time clause`}, {s: `SELECT count(value) FROM foo group by time(1s) where host = 'hosta.influxdb.org'`, err: `aggregate functions with GROUP BY time require a WHERE time clause`}, - {s: `SELECT count(value) FROM foo group by time`, err: `time() is a function and expects at least one argument`}, - {s: `SELECT count(value) FROM foo group by 'time'`, err: `only time and tag dimensions allowed`}, - {s: `SELECT count(value) FROM foo where time > now() and time < now() group by time()`, err: `time dimension expected one argument`}, - {s: `SELECT count(value) FROM foo where time > now() and time < now() group by time(b)`, err: `time dimension must have one duration argument`}, - {s: `SELECT count(value) FROM foo where time > now() and time < now() group by time(1s), time(2s)`, err: `multiple time dimensions not allowed`}, {s: `SELECT field1 FROM 12`, err: `found 12, expected identifier at line 1, char 20`}, {s: `SELECT 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 FROM myseries`, err: `unable to parse number at line 1, char 8`}, {s: `SELECT 10.5h FROM myseries`, err: `found h, expected FROM at line 1, char 12`}, + {s: `SELECT derivative(field1), field1 FROM myseries`, err: `mixing aggregate and non-aggregate queries is not supported`}, {s: `SELECT distinct(field1), sum(field1) FROM myseries`, err: `aggregate function distinct() can not be combined with other functions or fields`}, {s: `SELECT distinct(field1), field2 FROM myseries`, err: `aggregate function distinct() can not be combined with other functions or fields`}, {s: `SELECT distinct(field1, field2) FROM myseries`, err: `distinct function can only have one argument`}, @@ -1412,18 +1243,15 @@ func TestParser_ParseStatement(t *testing.T) { {s: `SELECT count(distinct field1, field2) FROM myseries`, err: `count(distinct ) can only have one argument`}, {s: `select count(distinct(too, many, arguments)) from myseries`, err: `count(distinct ) can only have one argument`}, {s: `select count() from myseries`, err: `invalid number of arguments for count, expected 1, got 0`}, - {s: `SELECT derivative(), field1 FROM myseries`, err: `mixing aggregate and non-aggregate queries is not supported`}, {s: `select derivative() from myseries`, err: `invalid number of arguments for derivative, expected at least 1 but no more than 2, got 0`}, {s: `select derivative(mean(value), 1h, 3) from myseries`, err: `invalid number of arguments for derivative, expected at least 1 but no more than 2, got 3`}, - {s: `SELECT derivative(value) FROM myseries where time < now() and time > now() - 1d`, err: `aggregate function required inside the call to derivative`}, - {s: `SELECT non_negative_derivative(), field1 FROM myseries`, err: `mixing aggregate and non-aggregate queries is not supported`}, - {s: `select non_negative_derivative() from myseries`, err: `invalid number of arguments for non_negative_derivative, expected at least 1 but no more than 2, got 0`}, - {s: `select non_negative_derivative(mean(value), 1h, 3) from myseries`, err: `invalid number of arguments for non_negative_derivative, expected at least 1 but no more than 2, got 3`}, - {s: `SELECT non_negative_derivative(value) FROM myseries where time < now() and time > now() - 1d`, err: `aggregate function required inside the call to non_negative_derivative`}, {s: `SELECT field1 from myseries WHERE host =~ 'asd' LIMIT 1`, err: `found asd, expected regex at line 1, char 42`}, {s: `SELECT value > 2 FROM cpu`, err: `invalid operator > in SELECT clause at line 1, char 8; operator is intended for WHERE clause`}, {s: `SELECT value = 2 FROM cpu`, err: `invalid operator = in SELECT clause at line 1, char 8; operator is intended for WHERE clause`}, {s: `SELECT s =~ /foo/ FROM cpu`, err: `invalid operator =~ in SELECT clause at line 1, char 8; operator is intended for WHERE clause`}, + {s: `SELECT foo, * from cpu`, err: `wildcards can not be combined with other fields`}, + {s: `SELECT *, * from cpu`, err: `found ,, expected FROM at line 1, char 9`}, + {s: `SELECT *, foo from cpu`, err: `found ,, expected FROM at line 1, char 9`}, {s: `DELETE`, err: `found EOF, expected FROM at line 1, char 8`}, {s: `DELETE FROM`, err: `found EOF, expected identifier at line 1, char 13`}, {s: `DELETE FROM myseries WHERE`, err: `found EOF, expected identifier, string, number, bool at line 1, char 28`}, @@ -1448,10 +1276,6 @@ func TestParser_ParseStatement(t *testing.T) { {s: `CREATE CONTINUOUS`, err: `found EOF, expected QUERY at line 1, char 19`}, {s: `CREATE CONTINUOUS QUERY`, err: `found EOF, expected identifier at line 1, char 25`}, {s: `DROP FOO`, err: `found FOO, expected SERIES, CONTINUOUS, MEASUREMENT at line 1, char 6`}, - {s: `CREATE DATABASE`, err: `found EOF, expected identifier at line 1, char 17`}, - {s: `CREATE DATABASE IF`, err: `found EOF, expected NOT at line 1, char 20`}, - {s: `CREATE DATABASE IF NOT`, err: `found EOF, expected EXISTS at line 1, char 24`}, - {s: `CREATE DATABASE IF NOT EXISTS`, err: `found EOF, expected identifier at line 1, char 31`}, {s: `DROP DATABASE`, err: `found EOF, expected identifier at line 1, char 15`}, {s: `DROP RETENTION`, err: `found EOF, expected POLICY at line 1, char 16`}, {s: `DROP RETENTION POLICY`, err: `found EOF, expected identifier at line 1, char 23`}, @@ -1572,8 +1396,7 @@ func TestParser_ParseStatement(t *testing.T) { if !reflect.DeepEqual(tt.err, errstring(err)) { t.Errorf("%d. %q: error mismatch:\n exp=%s\n got=%s\n\n", i, tt.s, tt.err, err) } else if tt.err == "" && !reflect.DeepEqual(tt.stmt, stmt) { - t.Logf("\n# %s\nexp=%s\ngot=%s\n", tt.s, mustMarshalJSON(tt.stmt), mustMarshalJSON(stmt)) - t.Logf("\nSQL exp=%s\nSQL got=%s\n", tt.stmt.String(), stmt.String()) + t.Logf("\nexp=%s\ngot=%s\n", mustMarshalJSON(tt.stmt), mustMarshalJSON(stmt)) t.Errorf("%d. %q\n\nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.s, tt.stmt, stmt) } } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner.go index d071c8571..c6dab019c 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner.go @@ -95,8 +95,6 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) { return COMMA, pos, "" case ';': return SEMICOLON, pos, "" - case ':': - return COLON, pos, "" } return ILLEGAL, pos, string(ch0) diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner_test.go index b365a1b55..4a0124d53 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/scanner_test.go @@ -136,10 +136,8 @@ func TestScanner_Scan(t *testing.T) { {s: `KEYS`, tok: influxql.KEYS}, {s: `LIMIT`, tok: influxql.LIMIT}, {s: `SHOW`, tok: influxql.SHOW}, - {s: `SHARDS`, tok: influxql.SHARDS}, {s: `MEASUREMENT`, tok: influxql.MEASUREMENT}, {s: `MEASUREMENTS`, tok: influxql.MEASUREMENTS}, - {s: `NOT`, tok: influxql.NOT}, {s: `OFFSET`, tok: influxql.OFFSET}, {s: `ON`, tok: influxql.ON}, {s: `ORDER`, tok: influxql.ORDER}, diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/token.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/token.go index 795c7b169..0eb5b7a9a 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/token.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxql/token.go @@ -50,7 +50,6 @@ const ( LPAREN // ( RPAREN // ) COMMA // , - COLON // : SEMICOLON // ; DOT // . @@ -92,7 +91,6 @@ const ( LIMIT MEASUREMENT MEASUREMENTS - NOT OFFSET ON ORDER @@ -111,7 +109,6 @@ const ( SERVERS SET SHOW - SHARDS SLIMIT STATS DIAGNOSTICS @@ -162,7 +159,6 @@ var tokens = [...]string{ LPAREN: "(", RPAREN: ")", COMMA: ",", - COLON: ":", SEMICOLON: ";", DOT: ".", @@ -202,7 +198,6 @@ var tokens = [...]string{ LIMIT: "LIMIT", MEASUREMENT: "MEASUREMENT", MEASUREMENTS: "MEASUREMENTS", - NOT: "NOT", OFFSET: "OFFSET", ON: "ON", ORDER: "ORDER", @@ -221,7 +216,6 @@ var tokens = [...]string{ SERVERS: "SERVERS", SET: "SET", SHOW: "SHOW", - SHARDS: "SHARDS", SLIMIT: "SLIMIT", SOFFSET: "SOFFSET", STATS: "STATS", diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxvar.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/influxvar.go deleted file mode 100644 index 58455515a..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/influxvar.go +++ /dev/null @@ -1,45 +0,0 @@ -package influxdb - -import ( - "expvar" - "sync" -) - -var expvarMu sync.Mutex - -// NewStatistics returns an expvar-based map with the given key. Within that map -// is another map. Within there "name" is the Measurement name, "tags" are the tags, -// and values are placed at the key "values". -func NewStatistics(key, name string, tags map[string]string) *expvar.Map { - expvarMu.Lock() - defer expvarMu.Unlock() - - // Add expvar for this service. - var v expvar.Var - if v = expvar.Get(key); v == nil { - v = expvar.NewMap(key) - } - m := v.(*expvar.Map) - - // Set the name - nameVar := &expvar.String{} - nameVar.Set(name) - m.Set("name", nameVar) - - // Set the tags - tagsVar := &expvar.Map{} - tagsVar.Init() - for k, v := range tags { - value := &expvar.String{} - value.Set(v) - tagsVar.Set(k, value) - } - m.Set("tags", tagsVar) - - // Create and set the values entry used for actual stats. - statMap := &expvar.Map{} - statMap.Init() - m.Set("values", statMap) - - return statMap -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data.go index 71c278eeb..2b9168901 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data.go @@ -132,7 +132,7 @@ func (data *Data) RetentionPolicy(database, name string) (*RetentionPolicyInfo, return &di.RetentionPolicies[i], nil } } - return nil, nil + return nil, ErrRetentionPolicyNotFound } // CreateRetentionPolicy creates a new retention policy on a database. @@ -172,11 +172,6 @@ func (data *Data) DropRetentionPolicy(database, name string) error { return ErrDatabaseNotFound } - // Prohibit dropping the default retention policy. - if di.DefaultRetentionPolicy == name { - return ErrRetentionPolicyDefault - } - // Remove from list. for i := range di.RetentionPolicies { if di.RetentionPolicies[i].Name == name { @@ -278,6 +273,7 @@ func (data *Data) ShardGroupsByTimeRange(database, policy string, tmin, tmax tim } groups = append(groups, g) } + sort.Sort(ShardGroupInfos(groups)) return groups, nil } @@ -348,16 +344,13 @@ func (data *Data) CreateShardGroup(database, policy string, timestamp time.Time) si := &sgi.Shards[i] for j := 0; j < replicaN; j++ { nodeID := data.Nodes[nodeIndex%len(data.Nodes)].ID - si.Owners = append(si.Owners, ShardOwner{NodeID: nodeID}) + si.OwnerIDs = append(si.OwnerIDs, nodeID) nodeIndex++ } } - // Retention policy has a new shard group, so update the policy. Shard - // Groups must be stored in sorted order, as other parts of the system - // assume this to be the case. + // Retention policy has a new shard group, so update the policy. rpi.ShardGroups = append(rpi.ShardGroups, sgi) - sort.Sort(ShardGroupInfos(rpi.ShardGroups)) return nil } @@ -669,31 +662,6 @@ func (di DatabaseInfo) RetentionPolicy(name string) *RetentionPolicyInfo { return nil } -// ShardInfos returns a list of all shards' info for the database. -func (di DatabaseInfo) ShardInfos() []ShardInfo { - shards := map[uint64]*ShardInfo{} - for i := range di.RetentionPolicies { - for j := range di.RetentionPolicies[i].ShardGroups { - sg := di.RetentionPolicies[i].ShardGroups[j] - // Skip deleted shard groups - if sg.Deleted() { - continue - } - for k := range sg.Shards { - si := &di.RetentionPolicies[i].ShardGroups[j].Shards[k] - shards[si.ID] = si - } - } - } - - infos := make([]ShardInfo, 0, len(shards)) - for _, info := range shards { - infos = append(infos, *info) - } - - return infos -} - // clone returns a deep copy of di. func (di DatabaseInfo) clone() DatabaseInfo { other := di @@ -949,14 +917,14 @@ func (sgi *ShardGroupInfo) unmarshal(pb *internal.ShardGroupInfo) { // ShardInfo represents metadata about a shard. type ShardInfo struct { - ID uint64 - Owners []ShardOwner + ID uint64 + OwnerIDs []uint64 } // OwnedBy returns whether the shard's owner IDs includes nodeID. func (si ShardInfo) OwnedBy(nodeID uint64) bool { - for _, so := range si.Owners { - if so.NodeID == nodeID { + for _, id := range si.OwnerIDs { + if id == nodeID { return true } } @@ -967,11 +935,9 @@ func (si ShardInfo) OwnedBy(nodeID uint64) bool { func (si ShardInfo) clone() ShardInfo { other := si - if si.Owners != nil { - other.Owners = make([]ShardOwner, len(si.Owners)) - for i := range si.Owners { - other.Owners[i] = si.Owners[i].clone() - } + if si.OwnerIDs != nil { + other.OwnerIDs = make([]uint64, len(si.OwnerIDs)) + copy(other.OwnerIDs, si.OwnerIDs) } return other @@ -983,64 +949,17 @@ func (si ShardInfo) marshal() *internal.ShardInfo { ID: proto.Uint64(si.ID), } - pb.Owners = make([]*internal.ShardOwner, len(si.Owners)) - for i := range si.Owners { - pb.Owners[i] = si.Owners[i].marshal() - } + pb.OwnerIDs = make([]uint64, len(si.OwnerIDs)) + copy(pb.OwnerIDs, si.OwnerIDs) return pb } -// UnmarshalBinary decodes the object from a binary format. -func (si *ShardInfo) UnmarshalBinary(buf []byte) error { - var pb internal.ShardInfo - if err := proto.Unmarshal(buf, &pb); err != nil { - return err - } - si.unmarshal(&pb) - return nil -} - // unmarshal deserializes from a protobuf representation. func (si *ShardInfo) unmarshal(pb *internal.ShardInfo) { si.ID = pb.GetID() - - // If deprecated "OwnerIDs" exists then convert it to "Owners" format. - if len(pb.GetOwnerIDs()) > 0 { - si.Owners = make([]ShardOwner, len(pb.GetOwnerIDs())) - for i, x := range pb.GetOwnerIDs() { - si.Owners[i].unmarshal(&internal.ShardOwner{ - NodeID: proto.Uint64(x), - }) - } - } else if len(pb.GetOwners()) > 0 { - si.Owners = make([]ShardOwner, len(pb.GetOwners())) - for i, x := range pb.GetOwners() { - si.Owners[i].unmarshal(x) - } - } -} - -// ShardOwner represents a node that owns a shard. -type ShardOwner struct { - NodeID uint64 -} - -// clone returns a deep copy of so. -func (so ShardOwner) clone() ShardOwner { - return so -} - -// marshal serializes to a protobuf representation. -func (so ShardOwner) marshal() *internal.ShardOwner { - return &internal.ShardOwner{ - NodeID: proto.Uint64(so.NodeID), - } -} - -// unmarshal deserializes from a protobuf representation. -func (so *ShardOwner) unmarshal(pb *internal.ShardOwner) { - so.NodeID = pb.GetNodeID() + si.OwnerIDs = make([]uint64, len(pb.GetOwnerIDs())) + copy(si.OwnerIDs, pb.GetOwnerIDs()) } // ContinuousQueryInfo represents metadata about a continuous query. diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data_test.go index d26eb9467..6e0314c76 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/data_test.go @@ -9,10 +9,8 @@ import ( "time" "github.com/davecgh/go-spew/spew" - "github.com/gogo/protobuf/proto" "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/meta" - "github.com/influxdb/influxdb/meta/internal" ) // Ensure a node can be created. @@ -301,13 +299,7 @@ func TestData_CreateShardGroup(t *testing.T) { StartTime: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), EndTime: time.Date(2000, time.January, 1, 1, 0, 0, 0, time.UTC), Shards: []meta.ShardInfo{ - { - ID: 1, - Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - }, - }, + {ID: 1, OwnerIDs: []uint64{1, 2}}, }, }) { t.Fatalf("unexpected shard group: %#v", sgi) @@ -578,12 +570,8 @@ func TestData_Clone(t *testing.T) { EndTime: time.Date(2000, time.February, 1, 0, 0, 0, 0, time.UTC), Shards: []meta.ShardInfo{ { - ID: 200, - Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 3}, - {NodeID: 4}, - }, + ID: 200, + OwnerIDs: []uint64{1, 3, 4}, }, }, }, @@ -617,8 +605,8 @@ func TestData_Clone(t *testing.T) { } // Ensure that changing data in the clone does not affect the original. - other.Databases[0].RetentionPolicies[0].ShardGroups[0].Shards[0].Owners[1].NodeID = 9 - if v := data.Databases[0].RetentionPolicies[0].ShardGroups[0].Shards[0].Owners[1].NodeID; v != 3 { + other.Databases[0].RetentionPolicies[0].ShardGroups[0].Shards[0].OwnerIDs[1] = 9 + if v := data.Databases[0].RetentionPolicies[0].ShardGroups[0].Shards[0].OwnerIDs[1]; v != 3 { t.Fatalf("editing clone changed original: %v", v) } } @@ -649,12 +637,8 @@ func TestData_MarshalBinary(t *testing.T) { EndTime: time.Date(2000, time.February, 1, 0, 0, 0, 0, time.UTC), Shards: []meta.ShardInfo{ { - ID: 200, - Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 3}, - {NodeID: 4}, - }, + ID: 200, + OwnerIDs: []uint64{1, 3, 4}, }, }, }, @@ -698,33 +682,3 @@ func TestData_MarshalBinary(t *testing.T) { t.Fatalf("unexpected users: %#v", other.Users) } } - -// Ensure shards with deprecated "OwnerIDs" can be decoded. -func TestShardInfo_UnmarshalBinary_OwnerIDs(t *testing.T) { - // Encode deprecated form to bytes. - buf, err := proto.Marshal(&internal.ShardInfo{ - ID: proto.Uint64(1), - OwnerIDs: []uint64{10, 20, 30}, - }) - if err != nil { - t.Fatal(err) - } - - // Decode deprecated form. - var si meta.ShardInfo - if err := si.UnmarshalBinary(buf); err != nil { - t.Fatal(err) - } - - // Verify data is migrated correctly. - if !reflect.DeepEqual(si, meta.ShardInfo{ - ID: 1, - Owners: []meta.ShardOwner{ - {NodeID: 10}, - {NodeID: 20}, - {NodeID: 30}, - }, - }) { - t.Fatalf("unexpected shard info: %s", spew.Sdump(si)) - } -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/errors.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/errors.go index 5945c727d..44c54f964 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/errors.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/errors.go @@ -43,10 +43,6 @@ var ( // ErrRetentionPolicyExists is returned when creating an already existing policy. ErrRetentionPolicyExists = errors.New("retention policy already exists") - // ErrRetentionPolicyDefault is returned when attempting a prohibited operation - // on a default retention policy. - ErrRetentionPolicyDefault = errors.New("retention policy is default") - // ErrRetentionPolicyNotFound is returned when mutating a policy that doesn't exist. ErrRetentionPolicyNotFound = errors.New("retention policy not found") diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.pb.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.pb.go index 4d6752d85..fbd8cc504 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.pb.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.pb.go @@ -15,7 +15,6 @@ It has these top-level messages: RetentionPolicyInfo ShardGroupInfo ShardInfo - ShardOwner ContinuousQueryInfo UserInfo UserPrivilege @@ -417,10 +416,9 @@ func (m *ShardGroupInfo) GetShards() []*ShardInfo { } type ShardInfo struct { - ID *uint64 `protobuf:"varint,1,req" json:"ID,omitempty"` - OwnerIDs []uint64 `protobuf:"varint,2,rep" json:"OwnerIDs,omitempty"` - Owners []*ShardOwner `protobuf:"bytes,3,rep" json:"Owners,omitempty"` - XXX_unrecognized []byte `json:"-"` + ID *uint64 `protobuf:"varint,1,req" json:"ID,omitempty"` + OwnerIDs []uint64 `protobuf:"varint,2,rep" json:"OwnerIDs,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *ShardInfo) Reset() { *m = ShardInfo{} } @@ -441,29 +439,6 @@ func (m *ShardInfo) GetOwnerIDs() []uint64 { return nil } -func (m *ShardInfo) GetOwners() []*ShardOwner { - if m != nil { - return m.Owners - } - return nil -} - -type ShardOwner struct { - NodeID *uint64 `protobuf:"varint,1,req" json:"NodeID,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ShardOwner) Reset() { *m = ShardOwner{} } -func (m *ShardOwner) String() string { return proto.CompactTextString(m) } -func (*ShardOwner) ProtoMessage() {} - -func (m *ShardOwner) GetNodeID() uint64 { - if m != nil && m.NodeID != nil { - return *m.NodeID - } - return 0 -} - type ContinuousQueryInfo struct { Name *string `protobuf:"bytes,1,req" json:"Name,omitempty"` Query *string `protobuf:"bytes,2,req" json:"Query,omitempty"` diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.proto b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.proto index 311147225..2aa50244b 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.proto +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/internal/meta.proto @@ -49,13 +49,8 @@ message ShardGroupInfo { } message ShardInfo { - required uint64 ID = 1; - repeated uint64 OwnerIDs = 2 [deprecated=true]; - repeated ShardOwner Owners = 3; -} - -message ShardOwner { - required uint64 NodeID = 1; + required uint64 ID = 1; + repeated uint64 OwnerIDs = 2; } message ContinuousQueryInfo { diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/rpc_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/rpc_test.go index 40f3540af..3f60c6bd0 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/rpc_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/rpc_test.go @@ -122,7 +122,7 @@ func TestRPCFetchDataMatchesBlocking(t *testing.T) { // Simulate the rmote index changing and unblocking fs.mu.Lock() - fs.md = &Data{Index: 100} + fs.md.Index = 100 fs.mu.Unlock() close(fs.blockChan) wg.Wait() diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor.go index a5e5655c7..08207a1b2 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor.go @@ -1,10 +1,7 @@ package meta import ( - "bytes" "fmt" - "strconv" - "time" "github.com/influxdb/influxdb/influxql" ) @@ -83,8 +80,6 @@ func (e *StatementExecutor) ExecuteStatement(stmt influxql.Statement) *influxql. return e.executeDropContinuousQueryStatement(stmt) case *influxql.ShowContinuousQueriesStatement: return e.executeShowContinuousQueriesStatement(stmt) - case *influxql.ShowShardsStatement: - return e.executeShowShardsStatement(stmt) case *influxql.ShowStatsStatement: return e.executeShowStatsStatement(stmt) default: @@ -94,9 +89,6 @@ func (e *StatementExecutor) ExecuteStatement(stmt influxql.Statement) *influxql. func (e *StatementExecutor) executeCreateDatabaseStatement(q *influxql.CreateDatabaseStatement) *influxql.Result { _, err := e.Store.CreateDatabase(q.Name) - if err == ErrDatabaseExists && q.IfNotExists { - err = nil - } return &influxql.Result{Err: err} } @@ -289,50 +281,6 @@ func (e *StatementExecutor) executeShowContinuousQueriesStatement(stmt *influxql return &influxql.Result{Series: rows} } -func (e *StatementExecutor) executeShowShardsStatement(stmt *influxql.ShowShardsStatement) *influxql.Result { - dis, err := e.Store.Databases() - if err != nil { - return &influxql.Result{Err: err} - } - - rows := []*influxql.Row{} - for _, di := range dis { - row := &influxql.Row{Columns: []string{"id", "start_time", "end_time", "expiry_time", "owners"}, Name: di.Name} - for _, rpi := range di.RetentionPolicies { - for _, sgi := range rpi.ShardGroups { - for _, si := range sgi.Shards { - ownerIDs := make([]uint64, len(si.Owners)) - for i, owner := range si.Owners { - ownerIDs[i] = owner.NodeID - } - - row.Values = append(row.Values, []interface{}{ - si.ID, - sgi.StartTime.UTC().Format(time.RFC3339), - sgi.EndTime.UTC().Format(time.RFC3339), - sgi.EndTime.Add(rpi.Duration).UTC().Format(time.RFC3339), - joinUint64(ownerIDs), - }) - } - } - } - rows = append(rows, row) - } - return &influxql.Result{Series: rows} -} - func (e *StatementExecutor) executeShowStatsStatement(stmt *influxql.ShowStatsStatement) *influxql.Result { return &influxql.Result{Err: fmt.Errorf("SHOW STATS is not implemented yet")} } - -// joinUint64 returns a comma-delimited string of uint64 numbers. -func joinUint64(a []uint64) string { - var buf bytes.Buffer - for i, x := range a { - buf.WriteString(strconv.FormatUint(x, 10)) - if i < len(a)-1 { - buf.WriteRune(',') - } - } - return buf.String() -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor_test.go index 7ad290084..64894aaea 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/statement_executor_test.go @@ -625,13 +625,13 @@ func TestStatementExecutor_ExecuteStatement_CreateContinuousQuery(t *testing.T) t.Fatalf("unexpected database: %s", database) } else if name != "cq0" { t.Fatalf("unexpected name: %s", name) - } else if query != `CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(field1) INTO db1 FROM db0 GROUP BY time(1h) END` { + } else if query != `CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(*) INTO db1 FROM db0 GROUP BY time(1h) END` { t.Fatalf("unexpected query: %s", query) } return nil } - stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(field1) INTO db1 FROM db0 GROUP BY time(1h) END`) + stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(*) INTO db1 FROM db0 GROUP BY time(1h) END`) if res := e.ExecuteStatement(stmt); res.Err != nil { t.Fatal(res.Err) } else if res.Series != nil { @@ -646,7 +646,7 @@ func TestStatementExecutor_ExecuteStatement_CreateContinuousQuery_Err(t *testing return errors.New("marker") } - stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(field1) INTO db1 FROM db0 GROUP BY time(1h) END`) + stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(*) INTO db1 FROM db0 GROUP BY time(1h) END`) if res := e.ExecuteStatement(stmt); res.Err == nil || res.Err.Error() != "marker" { t.Fatalf("unexpected error: %s", res.Err) } @@ -693,14 +693,14 @@ func TestStatementExecutor_ExecuteStatement_ShowContinuousQueries(t *testing.T) { Name: "db0", ContinuousQueries: []meta.ContinuousQueryInfo{ - {Name: "cq0", Query: "SELECT count(field1) INTO db1 FROM db0"}, - {Name: "cq1", Query: "SELECT count(field1) INTO db2 FROM db0"}, + {Name: "cq0", Query: "SELECT count(*) INTO db1 FROM db0"}, + {Name: "cq1", Query: "SELECT count(*) INTO db2 FROM db0"}, }, }, { Name: "db1", ContinuousQueries: []meta.ContinuousQueryInfo{ - {Name: "cq2", Query: "SELECT count(field1) INTO db3 FROM db1"}, + {Name: "cq2", Query: "SELECT count(*) INTO db3 FROM db1"}, }, }, }, nil @@ -714,15 +714,15 @@ func TestStatementExecutor_ExecuteStatement_ShowContinuousQueries(t *testing.T) Name: "db0", Columns: []string{"name", "query"}, Values: [][]interface{}{ - {"cq0", "SELECT count(field1) INTO db1 FROM db0"}, - {"cq1", "SELECT count(field1) INTO db2 FROM db0"}, + {"cq0", "SELECT count(*) INTO db1 FROM db0"}, + {"cq1", "SELECT count(*) INTO db2 FROM db0"}, }, }, { Name: "db1", Columns: []string{"name", "query"}, Values: [][]interface{}{ - {"cq2", "SELECT count(field1) INTO db3 FROM db1"}, + {"cq2", "SELECT count(*) INTO db3 FROM db1"}, }, }, }) { @@ -755,7 +755,7 @@ func TestStatementExecutor_ExecuteStatement_Unsupported(t *testing.T) { // Execute a SELECT statement. NewStatementExecutor().ExecuteStatement( - influxql.MustParseStatement(`SELECT count(field1) FROM db0`), + influxql.MustParseStatement(`SELECT count(*) FROM db0`), ) }() @@ -765,57 +765,6 @@ func TestStatementExecutor_ExecuteStatement_Unsupported(t *testing.T) { } } -// Ensure a SHOW SHARDS statement can be executed. -func TestStatementExecutor_ExecuteStatement_ShowShards(t *testing.T) { - e := NewStatementExecutor() - e.Store.DatabasesFn = func() ([]meta.DatabaseInfo, error) { - return []meta.DatabaseInfo{ - { - Name: "foo", - RetentionPolicies: []meta.RetentionPolicyInfo{ - { - Duration: time.Second, - ShardGroups: []meta.ShardGroupInfo{ - { - StartTime: time.Unix(0, 0), - EndTime: time.Unix(1, 0), - Shards: []meta.ShardInfo{ - { - ID: 1, - Owners: []meta.ShardOwner{ - {NodeID: 1}, - {NodeID: 2}, - {NodeID: 3}, - }, - }, - { - ID: 2, - }, - }, - }, - }, - }, - }, - }, - }, nil - } - - if res := e.ExecuteStatement(influxql.MustParseStatement(`SHOW SHARDS`)); res.Err != nil { - t.Fatal(res.Err) - } else if !reflect.DeepEqual(res.Series, influxql.Rows{ - { - Name: "foo", - Columns: []string{"id", "start_time", "end_time", "expiry_time", "owners"}, - Values: [][]interface{}{ - {uint64(1), "1970-01-01T00:00:00Z", "1970-01-01T00:00:01Z", "1970-01-01T00:00:02Z", "1,2,3"}, - {uint64(2), "1970-01-01T00:00:00Z", "1970-01-01T00:00:01Z", "1970-01-01T00:00:02Z", ""}, - }, - }, - }) { - t.Fatalf("unexpected rows: %s", spew.Sdump(res.Series)) - } -} - // StatementExecutor represents a test wrapper for meta.StatementExecutor. type StatementExecutor struct { *meta.StatementExecutor diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store.go index a2d7ce8f6..23bac17f2 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store.go @@ -254,10 +254,7 @@ func (s *Store) Open() error { close(s.ready) } - // Wait for a leader to be elected so we know the raft log is loaded - // and up to date - <-s.ready - return s.WaitForLeader(0) + return nil } // syncNodeInfo continuously tries to update the current nodes hostname @@ -861,7 +858,6 @@ func (s *Store) CreateDatabase(name string) (*DatabaseInfo, error) { ); err != nil { return nil, err } - s.Logger.Printf("database '%s' created", name) if s.retentionAutoCreate { // Read node count. @@ -981,7 +977,6 @@ func (s *Store) CreateRetentionPolicy(database string, rpi *RetentionPolicyInfo) return nil, err } - s.Logger.Printf("retention policy '%s' for database '%s' created", rpi.Name, database) return s.RetentionPolicy(database, rpi.Name) } @@ -1394,34 +1389,38 @@ func (s *Store) UserCount() (count int, err error) { return } -// PrecreateShardGroups creates shard groups whose endtime is before the 'to' time passed in, but -// is yet to expire before 'from'. This is to avoid the need for these shards to be created when data -// for the corresponding time range arrives. Shard creation involves Raft consensus, and precreation -// avoids taking the hit at write-time. -func (s *Store) PrecreateShardGroups(from, to time.Time) error { +// PrecreateShardGroups creates shard groups whose endtime is before the cutoff time passed in. This +// avoid the need for these shards to be created when data for the corresponding time range arrives. +// Shard creation involves Raft consensus, and precreation avoids taking the hit at write-time. +func (s *Store) PrecreateShardGroups(cutoff time.Time) error { s.read(func(data *Data) error { for _, di := range data.Databases { for _, rp := range di.RetentionPolicies { - if len(rp.ShardGroups) == 0 { - // No data was ever written to this group, or all groups have been deleted. - continue - } - g := rp.ShardGroups[len(rp.ShardGroups)-1] // Get the last group in time. - if !g.Deleted() && g.EndTime.Before(to) && g.EndTime.After(from) { - // Group is not deleted, will end before the future time, but is still yet to expire. - // This last check is important, so the system doesn't create shards groups wholly - // in the past. + for _, g := range rp.ShardGroups { + // Check to see if it is not deleted and going to end before our interval + if !g.Deleted() && g.EndTime.Before(cutoff) { + nextShardGroupTime := g.EndTime.Add(1 * time.Nanosecond) - // Create successive shard group. - nextShardGroupTime := g.EndTime.Add(1 * time.Nanosecond) - if newGroup, err := s.CreateShardGroupIfNotExists(di.Name, rp.Name, nextShardGroupTime); err != nil { - s.Logger.Printf("failed to create successive shard group for group %d: %s", - g.ID, err.Error()) - } else { - s.Logger.Printf("new shard group %d successfully created for database %s, retention policy %s", - newGroup.ID, di.Name, rp.Name) + // Check if successive shard group exists. + if sgi, err := s.ShardGroupByTimestamp(di.Name, rp.Name, nextShardGroupTime); err != nil { + s.Logger.Printf("failed to check if successive shard group for group exists %d: %s", + g.ID, err.Error()) + continue + } else if sgi != nil && !sgi.Deleted() { + continue + } + + // It doesn't. Create it. + if newGroup, err := s.CreateShardGroupIfNotExists(di.Name, rp.Name, nextShardGroupTime); err != nil { + s.Logger.Printf("failed to create successive shard group for group %d: %s", + g.ID, err.Error()) + } else { + s.Logger.Printf("new shard group %d successfully created for database %s, retention policy %s", + newGroup.ID, di.Name, rp.Name) + } } } + } } return nil diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store_test.go index d287303d8..ef79306b7 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/meta/store_test.go @@ -489,57 +489,30 @@ func TestStore_PrecreateShardGroup(t *testing.T) { s := MustOpenStore() defer s.Close() - // Create node, database, policy, & groups. + // Create node, database, policy, & group. if _, err := s.CreateNode("host0"); err != nil { t.Fatal(err) } else if _, err := s.CreateDatabase("db0"); err != nil { t.Fatal(err) } else if _, err = s.CreateRetentionPolicy("db0", &meta.RetentionPolicyInfo{Name: "rp0", ReplicaN: 2, Duration: 1 * time.Hour}); err != nil { t.Fatal(err) - } else if _, err = s.CreateRetentionPolicy("db0", &meta.RetentionPolicyInfo{Name: "rp1", ReplicaN: 2, Duration: 1 * time.Hour}); err != nil { + } else if _, err := s.CreateShardGroup("db0", "rp0", time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)); err != nil { t.Fatal(err) - } else if _, err = s.CreateRetentionPolicy("db0", &meta.RetentionPolicyInfo{Name: "rp2", ReplicaN: 2, Duration: 1 * time.Hour}); err != nil { - t.Fatal(err) - } else if _, err := s.CreateShardGroup("db0", "rp0", time.Date(2001, time.January, 1, 1, 0, 0, 0, time.UTC)); err != nil { - t.Fatal(err) - } else if _, err := s.CreateShardGroup("db0", "rp1", time.Date(2000, time.January, 1, 1, 0, 0, 0, time.UTC)); err != nil { + } else if err := s.PrecreateShardGroups(time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC)); err != nil { t.Fatal(err) } - if err := s.PrecreateShardGroups(time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC), time.Date(2001, time.January, 1, 3, 0, 0, 0, time.UTC)); err != nil { - t.Fatal(err) - } - - // rp0 should undergo precreation. groups, err := s.ShardGroups("db0", "rp0") if err != nil { t.Fatal(err) } if len(groups) != 2 { - t.Fatalf("shard group precreation failed to create new shard group for rp0") + t.Fatalf("shard group precreation failed to create new shard group") } - if groups[1].StartTime != time.Date(2001, time.January, 1, 2, 0, 0, 0, time.UTC) { + if groups[1].StartTime != time.Date(2000, time.January, 1, 1, 0, 0, 0, time.UTC) { t.Fatalf("precreated shard group has wrong start time, exp %s, got %s", time.Date(2000, time.January, 1, 1, 0, 0, 0, time.UTC), groups[1].StartTime) } - - // rp1 should not undergo precreation since it is completely in the past. - groups, err = s.ShardGroups("db0", "rp1") - if err != nil { - t.Fatal(err) - } - if len(groups) != 1 { - t.Fatalf("shard group precreation created new shard group for rp1") - } - - // rp2 should not undergo precreation since it has no shards. - groups, err = s.ShardGroups("db0", "rp2") - if err != nil { - t.Fatal(err) - } - if len(groups) != 0 { - t.Fatalf("shard group precreation created new shard group for rp2") - } } // Ensure the store can create a new continuous query. @@ -855,14 +828,14 @@ func TestCluster_Restart(t *testing.T) { t.Fatal("no leader found") } - // Add 5 more nodes, 2 should become raft peers, 3 remote raft clients + // Add 5 more ndes, 2 should become raft peers, 3 remote raft clients for i := 0; i < 5; i++ { if err := c.Join(); err != nil { t.Fatalf("failed to join cluster: %v", err) } } - // The tests use a host assigned listener port. We need to re-use + // The tests use a host host assigned listener port. We need to re-use // the original ports when the new cluster is restarted so that the existing // peer store addresses can be reached. addrs := []string{} @@ -885,25 +858,10 @@ func TestCluster_Restart(t *testing.T) { // Re-create the cluster nodes from existing disk paths and addresses stores := []*Store{} - storeChan := make(chan *Store) for i, s := range c.Stores { - - // Need to start each instance asynchronously because they have existing raft peers - // store. Starting one will block indefinitely because it will not be able to become - // leader until another peer is available to hold an election. - go func(addr, path string) { - store := MustOpenStoreWithPath(addr, path) - storeChan <- store - }(addrs[i], s.Path()) - - } - - // Collect up our restart meta-stores - for range c.Stores { - store := <-storeChan + store := MustOpenStoreWithPath(addrs[i], s.Path()) stores = append(stores, store) } - c.Stores = stores // Wait for the cluster to stabilize diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/README.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/README.md deleted file mode 100644 index 97fac284d..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# System Monitoring -_This functionality should be considered experimental and is subject to change._ - -_System Monitoring_ means all statistical and diagnostic information made availabe to the user of InfluxDB system, about the system itself. Its purpose is to assist with troubleshooting and performance analysis of the database itself. - -## Statistics vs. Diagnostics -A distinction is made between _statistics_ and _diagnostics_ for the purposes of monitoring. Generally a statistical quality is something that is being counted, and for which it makes sense to store persistently for historical analysis. Diagnostic information is not necessarily numerical, and may not make sense to store. - -An example of statistical information would be the number of points received over UDP, or the number of queries executed. Examples of diagnostic information would be a list of current Graphite TCP connections, the version of InfluxDB, or the uptime of the process. - -## System Statistics -`SHOW STATS` displays statisics about subsystems within the running `influxd` process. Statistics include points received, points indexed, bytes written to disk, TCP connections handled etc. These statistics are all zero when the InfluxDB process starts. - -All statistics are written, by default, by each node to a "monitor" database within the InfluxDB system, allowing analysis of aggregated statistical data using the standard InfluxQL language. This allows users to track the performance of their system. Importantly, this allows cluster-level statistics to be viewed, since by querying the monitor database, statistics from all nodes may be queried. This can be a very powerful approach for troubleshooting your InfluxDB system and understanding its behaviour. - -## System Diagnostics -`SHOW DIAGNOSTICS` displays various diagnostic information about the `influxd` process. This information is not stored persistently within the InfluxDB system. - -## Standard expvar support -All statistical information is available at HTTP API endpoint `/debug/vars`, in [expvar](https://golang.org/pkg/expvar/) format, allowing external systems to monitor an InfluxDB node. By default, the full path to this endpoint is `http://localhost:8086/debug/vars`. - -## Configuration -The `monitor` module allows the following configuration: - - * Whether to write statistical and diagnostic information to an InfluxDB system. This is enabled by default. - * The name of the database to where this information should be written. Defaults to `_internal`. The information is written to the default retention policy for the given database. - * The name of the retention policy, along with full configuration control of the retention policy, if the default retention policy is not suitable. - * The rate at which this information should be written. The default rate is once every 10 seconds. - -# Design and Implementation - -A new module named `monitor` supports all basic statistics and diagnostic functionality. This includes: - - * Allowing other modules to register statistics and diagnostics information, allowing it to be accessed on demand by the `monitor` module. - * Serving the statistics and diagnostic information to the user, in response to commands such as `SHOW DIAGNOSTICS`. - * Expose standard Go runtime information such as garbage collection statistics. - * Make all collected expvar data via HTTP, for collection by 3rd-party tools. - * Writing the statistical information to the "monitor" database, for query purposes. - -## Registering statistics and diagnostics - -To export statistical information with the `monitor` system, code simply calls `influxdb.NewStatistics()` and receives an `expvar.Map` instance in response. This object can then be used to store statistics. To register diagnostic information, `monitor.RegisterDiagnosticsClient` is called, passing a `influxdb.monitor.DiagsClient` object to `monitor`. - -## expvar -Statistical information is gathered by each package using [expvar](https://golang.org/pkg/expvar). Each package registers a map using its package name. - -Due to the nature of `expvar`, statistical information is reset to its initial state when a server is restarted. diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/build_info.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/build_info.go deleted file mode 100644 index 283038bfb..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/build_info.go +++ /dev/null @@ -1,18 +0,0 @@ -package monitor - -// system captures build diagnostics -type build struct { - Version string - Commit string - Branch string -} - -func (b *build) Diagnostics() (*Diagnostic, error) { - diagnostics := map[string]interface{}{ - "Version": b.Version, - "Commit": b.Commit, - "Branch": b.Branch, - } - - return DiagnosticFromMap(diagnostics), nil -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config.go deleted file mode 100644 index a5a78bf28..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config.go +++ /dev/null @@ -1,35 +0,0 @@ -package monitor - -import ( - "time" - - "github.com/influxdb/influxdb/toml" -) - -const ( - // DefaultStoreEnabled is whether the system writes gathered information in - // an InfluxDB system for historical analysis. - DefaultStoreEnabled = true - - // DefaultStoreDatabase is the name of the database where gathered information is written - DefaultStoreDatabase = "_internal" - - // DefaultStoreInterval is the period between storing gathered information. - DefaultStoreInterval = 10 * time.Second -) - -// Config represents the configuration for the monitor service. -type Config struct { - StoreEnabled bool `toml:"store-enabled"` - StoreDatabase string `toml:"store-database"` - StoreInterval toml.Duration `toml:"store-interval"` -} - -// NewConfig returns an instance of Config with defaults. -func NewConfig() Config { - return Config{ - StoreEnabled: true, - StoreDatabase: DefaultStoreDatabase, - StoreInterval: toml.Duration(DefaultStoreInterval), - } -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config_test.go deleted file mode 100644 index ee62e7346..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/config_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package monitor_test - -import ( - "testing" - "time" - - "github.com/BurntSushi/toml" - "github.com/influxdb/influxdb/monitor" -) - -func TestConfig_Parse(t *testing.T) { - // Parse configuration. - var c monitor.Config - if _, err := toml.Decode(` -store-enabled=true -store-database="the_db" -store-interval="10m" -`, &c); err != nil { - t.Fatal(err) - } - - // Validate configuration. - if !c.StoreEnabled { - t.Fatalf("unexpected store-enabled: %v", c.StoreEnabled) - } else if c.StoreDatabase != "the_db" { - t.Fatalf("unexpected store-database: %s", c.StoreDatabase) - } else if time.Duration(c.StoreInterval) != 10*time.Minute { - t.Fatalf("unexpected store-interval: %s", c.StoreInterval) - } -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/go_runtime.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/go_runtime.go deleted file mode 100644 index f45f4fce2..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/go_runtime.go +++ /dev/null @@ -1,19 +0,0 @@ -package monitor - -import ( - "runtime" -) - -// goRuntime captures Go runtime diagnostics -type goRuntime struct{} - -func (g *goRuntime) Diagnostics() (*Diagnostic, error) { - diagnostics := map[string]interface{}{ - "GOARCH": runtime.GOARCH, - "GOOS": runtime.GOOS, - "GOMAXPROCS": runtime.GOMAXPROCS(-1), - "version": runtime.Version(), - } - - return DiagnosticFromMap(diagnostics), nil -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/network.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/network.go deleted file mode 100644 index 80c0f6c9c..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/network.go +++ /dev/null @@ -1,21 +0,0 @@ -package monitor - -import ( - "os" -) - -// network captures network diagnostics -type network struct{} - -func (n *network) Diagnostics() (*Diagnostic, error) { - h, err := os.Hostname() - if err != nil { - return nil, err - } - - diagnostics := map[string]interface{}{ - "hostname": h, - } - - return DiagnosticFromMap(diagnostics), nil -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service.go deleted file mode 100644 index d76e31d5c..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service.go +++ /dev/null @@ -1,406 +0,0 @@ -package monitor - -import ( - "expvar" - "fmt" - "log" - "os" - "runtime" - "sort" - "strconv" - "sync" - "time" - - "github.com/influxdb/influxdb/cluster" - "github.com/influxdb/influxdb/meta" - "github.com/influxdb/influxdb/tsdb" -) - -const leaderWaitTimeout = 30 * time.Second - -const ( - MonitorRetentionPolicy = "monitor" - MonitorRetentionPolicyDuration = 7 * 24 * time.Hour -) - -// DiagsClient is the interface modules implement if they register diags with monitor. -type DiagsClient interface { - Diagnostics() (*Diagnostic, error) -} - -// The DiagsClientFunc type is an adapter to allow the use of -// ordinary functions as Diagnostis clients. -type DiagsClientFunc func() (*Diagnostic, error) - -// Diagnostics calls f(). -func (f DiagsClientFunc) Diagnostics() (*Diagnostic, error) { - return f() -} - -// Diagnostic represents a table of diagnostic information. The first value -// is the name of the columns, the second is a slice of interface slices containing -// the values for each column, by row. This information is never written to an InfluxDB -// system and is display-only. An example showing, say, connections follows: -// -// source_ip source_port dest_ip dest_port -// 182.1.0.2 2890 127.0.0.1 38901 -// 174.33.1.2 2924 127.0.0.1 38902 -type Diagnostic struct { - Columns []string - Rows [][]interface{} -} - -func NewDiagnostic(columns []string) *Diagnostic { - return &Diagnostic{ - Columns: columns, - Rows: make([][]interface{}, 0), - } -} - -func (d *Diagnostic) AddRow(r []interface{}) { - d.Rows = append(d.Rows, r) -} - -// Monitor represents an instance of the monitor system. -type Monitor struct { - // Build information for diagnostics. - Version string - Commit string - Branch string - - wg sync.WaitGroup - done chan struct{} - mu sync.Mutex - - diagRegistrations map[string]DiagsClient - - storeEnabled bool - storeDatabase string - storeRetentionPolicy string - storeRetentionDuration time.Duration - storeReplicationFactor int - storeAddress string - storeInterval time.Duration - - MetaStore interface { - ClusterID() (uint64, error) - NodeID() uint64 - WaitForLeader(d time.Duration) error - CreateDatabaseIfNotExists(name string) (*meta.DatabaseInfo, error) - CreateRetentionPolicyIfNotExists(database string, rpi *meta.RetentionPolicyInfo) (*meta.RetentionPolicyInfo, error) - SetDefaultRetentionPolicy(database, name string) error - DropRetentionPolicy(database, name string) error - } - - PointsWriter interface { - WritePoints(p *cluster.WritePointsRequest) error - } - - Logger *log.Logger -} - -// New returns a new instance of the monitor system. -func New(c Config) *Monitor { - return &Monitor{ - done: make(chan struct{}), - diagRegistrations: make(map[string]DiagsClient), - storeEnabled: c.StoreEnabled, - storeDatabase: c.StoreDatabase, - storeInterval: time.Duration(c.StoreInterval), - Logger: log.New(os.Stderr, "[monitor] ", log.LstdFlags), - } -} - -// Open opens the monitoring system, using the given clusterID, node ID, and hostname -// for identification purposem. -func (m *Monitor) Open() error { - m.Logger.Printf("Starting monitor system") - - // Self-register various stats and diagnostics. - m.RegisterDiagnosticsClient("build", &build{ - Version: m.Version, - Commit: m.Commit, - Branch: m.Branch, - }) - m.RegisterDiagnosticsClient("runtime", &goRuntime{}) - m.RegisterDiagnosticsClient("network", &network{}) - m.RegisterDiagnosticsClient("system", &system{}) - - // If enabled, record stats in a InfluxDB system. - if m.storeEnabled { - - // Start periodic writes to system. - m.wg.Add(1) - go m.storeStatistics() - } - - return nil -} - -// Close closes the monitor system. -func (m *Monitor) Close() { - m.Logger.Println("shutting down monitor system") - close(m.done) - m.wg.Wait() - m.done = nil -} - -// SetLogger sets the internal logger to the logger passed in. -func (m *Monitor) SetLogger(l *log.Logger) { - m.Logger = l -} - -// RegisterDiagnosticsClient registers a diagnostics client with the given name and tags. -func (m *Monitor) RegisterDiagnosticsClient(name string, client DiagsClient) error { - m.mu.Lock() - defer m.mu.Unlock() - m.diagRegistrations[name] = client - m.Logger.Printf(`'%s' registered for diagnostics monitoring`, name) - return nil -} - -// Statistics returns the combined statistics for all expvar data. The given -// tags are added to each of the returned statistics. -func (m *Monitor) Statistics(tags map[string]string) ([]*statistic, error) { - statistics := make([]*statistic, 0) - - expvar.Do(func(kv expvar.KeyValue) { - // Skip built-in expvar stats. - if kv.Key == "memstats" || kv.Key == "cmdline" { - return - } - - statistic := &statistic{ - Tags: make(map[string]string), - Values: make(map[string]interface{}), - } - - // Add any supplied tags. - for k, v := range tags { - statistic.Tags[k] = v - } - - // Every other top-level expvar value is a map. - m := kv.Value.(*expvar.Map) - - m.Do(func(subKV expvar.KeyValue) { - switch subKV.Key { - case "name": - // straight to string name. - u, err := strconv.Unquote(subKV.Value.String()) - if err != nil { - return - } - statistic.Name = u - case "tags": - // string-string tags map. - n := subKV.Value.(*expvar.Map) - n.Do(func(t expvar.KeyValue) { - u, err := strconv.Unquote(t.Value.String()) - if err != nil { - return - } - statistic.Tags[t.Key] = u - }) - case "values": - // string-interface map. - n := subKV.Value.(*expvar.Map) - n.Do(func(kv expvar.KeyValue) { - var f interface{} - var err error - switch v := kv.Value.(type) { - case *expvar.Float: - f, err = strconv.ParseFloat(v.String(), 64) - if err != nil { - return - } - case *expvar.Int: - f, err = strconv.ParseInt(v.String(), 10, 64) - if err != nil { - return - } - default: - return - } - statistic.Values[kv.Key] = f - }) - } - }) - - // If a registered client has no field data, don't include it in the results - if len(statistic.Values) == 0 { - return - } - - statistics = append(statistics, statistic) - }) - - // Add Go memstats. - statistic := &statistic{ - Name: "runtime", - Tags: make(map[string]string), - Values: make(map[string]interface{}), - } - var rt runtime.MemStats - runtime.ReadMemStats(&rt) - statistic.Values = map[string]interface{}{ - "Alloc": int64(rt.Alloc), - "TotalAlloc": int64(rt.TotalAlloc), - "Sys": int64(rt.Sys), - "Lookups": int64(rt.Lookups), - "Mallocs": int64(rt.Mallocs), - "Frees": int64(rt.Frees), - "HeapAlloc": int64(rt.HeapAlloc), - "HeapSys": int64(rt.HeapSys), - "HeapIdle": int64(rt.HeapIdle), - "HeapInUse": int64(rt.HeapInuse), - "HeapReleased": int64(rt.HeapReleased), - "HeapObjects": int64(rt.HeapObjects), - "PauseTotalNs": int64(rt.PauseTotalNs), - "NumGC": int64(rt.NumGC), - "NumGoroutine": int64(runtime.NumGoroutine()), - } - statistics = append(statistics, statistic) - - return statistics, nil -} - -func (m *Monitor) Diagnostics() (map[string]*Diagnostic, error) { - m.mu.Lock() - defer m.mu.Unlock() - - diags := make(map[string]*Diagnostic, len(m.diagRegistrations)) - for k, v := range m.diagRegistrations { - d, err := v.Diagnostics() - if err != nil { - continue - } - diags[k] = d - } - return diags, nil -} - -// storeStatistics writes the statistics to an InfluxDB system. -func (m *Monitor) storeStatistics() { - defer m.wg.Done() - m.Logger.Printf("Storing statistics in database '%s' retention policy '%s', at interval %s", - m.storeDatabase, m.storeRetentionPolicy, m.storeInterval) - - if err := m.MetaStore.WaitForLeader(leaderWaitTimeout); err != nil { - m.Logger.Printf("failed to detect a cluster leader, terminating storage: %s", err.Error()) - return - } - - // Get cluster-level metadata. Nothing different is going to happen if errors occur. - clusterID, _ := m.MetaStore.ClusterID() - nodeID := m.MetaStore.NodeID() - hostname, _ := os.Hostname() - clusterTags := map[string]string{ - "clusterID": fmt.Sprintf("%d", clusterID), - "nodeID": fmt.Sprintf("%d", nodeID), - "hostname": hostname, - } - - if _, err := m.MetaStore.CreateDatabaseIfNotExists(m.storeDatabase); err != nil { - m.Logger.Printf("failed to create database '%s', terminating storage: %s", - m.storeDatabase, err.Error()) - return - } - - rpi := meta.NewRetentionPolicyInfo(MonitorRetentionPolicy) - rpi.Duration = MonitorRetentionPolicyDuration - rpi.ReplicaN = 1 - if _, err := m.MetaStore.CreateRetentionPolicyIfNotExists(m.storeDatabase, rpi); err != nil { - m.Logger.Printf("failed to create retention policy '%s', terminating storage: %s", - rpi.Name, err.Error()) - return - } - - if err := m.MetaStore.SetDefaultRetentionPolicy(m.storeDatabase, rpi.Name); err != nil { - m.Logger.Printf("failed to set default retention policy on '%s', terminating storage: %s", - m.storeDatabase, err.Error()) - return - } - - if err := m.MetaStore.DropRetentionPolicy(m.storeDatabase, "default"); err != nil && err != meta.ErrRetentionPolicyNotFound { - m.Logger.Printf("failed to delete retention policy 'default', terminating storage: %s", err.Error()) - return - } - - tick := time.NewTicker(m.storeInterval) - defer tick.Stop() - for { - select { - case <-tick.C: - stats, err := m.Statistics(clusterTags) - if err != nil { - m.Logger.Printf("failed to retrieve registered statistics: %s", err) - continue - } - - points := make(tsdb.Points, 0, len(stats)) - for _, s := range stats { - points = append(points, tsdb.NewPoint(s.Name, s.Tags, s.Values, time.Now())) - } - - err = m.PointsWriter.WritePoints(&cluster.WritePointsRequest{ - Database: m.storeDatabase, - RetentionPolicy: m.storeRetentionPolicy, - ConsistencyLevel: cluster.ConsistencyLevelOne, - Points: points, - }) - if err != nil { - m.Logger.Printf("failed to store statistics: %s", err) - } - case <-m.done: - m.Logger.Printf("terminating storage of statistics") - return - } - - } -} - -// statistic represents the information returned by a single monitor client. -type statistic struct { - Name string - Tags map[string]string - Values map[string]interface{} -} - -// newStatistic returns a new statistic object. -func newStatistic(name string, tags map[string]string, values map[string]interface{}) *statistic { - return &statistic{ - Name: name, - Tags: tags, - Values: values, - } -} - -// valueNames returns a sorted list of the value names, if any. -func (s *statistic) valueNames() []string { - a := make([]string, 0, len(s.Values)) - for k, _ := range s.Values { - a = append(a, k) - } - sort.Strings(a) - return a -} - -// DiagnosticFromMap returns a Diagnostic from a map. -func DiagnosticFromMap(m map[string]interface{}) *Diagnostic { - // Display columns in deterministic order. - sortedKeys := make([]string, 0, len(m)) - for k, _ := range m { - sortedKeys = append(sortedKeys, k) - } - sort.Strings(sortedKeys) - - d := NewDiagnostic(sortedKeys) - row := make([]interface{}, len(sortedKeys)) - for i, k := range sortedKeys { - row[i] = m[k] - } - d.AddRow(row) - - return d -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service_test.go deleted file mode 100644 index e84358592..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/service_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package monitor - -import ( - "strings" - "testing" - "time" - - "github.com/influxdb/influxdb" - "github.com/influxdb/influxdb/influxql" - "github.com/influxdb/influxdb/meta" -) - -// Test that a registered stats client results in the correct SHOW STATS output. -func Test_RegisterStats(t *testing.T) { - monitor := openMonitor(t) - executor := &StatementExecutor{Monitor: monitor} - - // Register stats without tags. - statMap := influxdb.NewStatistics("foo", "foo", nil) - statMap.Add("bar", 1) - statMap.AddFloat("qux", 2.4) - json := executeShowStatsJSON(t, executor) - if !strings.Contains(json, `"columns":["bar","qux"],"values":[[1,2.4]]`) || !strings.Contains(json, `"name":"foo"`) { - t.Fatalf("SHOW STATS response incorrect, got: %s\n", json) - } - - // Register a client with tags. - statMap = influxdb.NewStatistics("bar", "baz", map[string]string{"proto": "tcp"}) - statMap.Add("bar", 1) - statMap.AddFloat("qux", 2.4) - json = executeShowStatsJSON(t, executor) - if !strings.Contains(json, `"columns":["bar","qux"],"values":[[1,2.4]]`) || - !strings.Contains(json, `"name":"baz"`) || - !strings.Contains(json, `"proto":"tcp"`) { - t.Fatalf("SHOW STATS response incorrect, got: %s\n", json) - - } -} - -type mockMetastore struct{} - -func (m *mockMetastore) ClusterID() (uint64, error) { return 1, nil } -func (m *mockMetastore) NodeID() uint64 { return 2 } -func (m *mockMetastore) WaitForLeader(d time.Duration) error { return nil } -func (m *mockMetastore) SetDefaultRetentionPolicy(database, name string) error { return nil } -func (m *mockMetastore) DropRetentionPolicy(database, name string) error { return nil } -func (m *mockMetastore) CreateDatabaseIfNotExists(name string) (*meta.DatabaseInfo, error) { - return nil, nil -} -func (m *mockMetastore) CreateRetentionPolicyIfNotExists(database string, rpi *meta.RetentionPolicyInfo) (*meta.RetentionPolicyInfo, error) { - return nil, nil -} - -func openMonitor(t *testing.T) *Monitor { - monitor := New(NewConfig()) - monitor.MetaStore = &mockMetastore{} - err := monitor.Open() - if err != nil { - t.Fatalf("failed to open monitor: %s", err.Error()) - } - return monitor -} - -func executeShowStatsJSON(t *testing.T, s *StatementExecutor) string { - r := s.ExecuteStatement(&influxql.ShowStatsStatement{}) - b, err := r.MarshalJSON() - if err != nil { - t.Fatalf("failed to decode SHOW STATS response: %s", err.Error()) - } - return string(b) -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/statement_executor.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/statement_executor.go deleted file mode 100644 index d6fa1c1b3..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/statement_executor.go +++ /dev/null @@ -1,65 +0,0 @@ -package monitor - -import ( - "fmt" - - "github.com/influxdb/influxdb/influxql" -) - -// StatementExecutor translates InfluxQL queries to Monitor methods. -type StatementExecutor struct { - Monitor interface { - Statistics(map[string]string) ([]*statistic, error) - Diagnostics() (map[string]*Diagnostic, error) - } -} - -// ExecuteStatement executes monitor-related query statements. -func (s *StatementExecutor) ExecuteStatement(stmt influxql.Statement) *influxql.Result { - switch stmt := stmt.(type) { - case *influxql.ShowStatsStatement: - return s.executeShowStatistics() - case *influxql.ShowDiagnosticsStatement: - return s.executeShowDiagnostics() - default: - panic(fmt.Sprintf("unsupported statement type: %T", stmt)) - } -} - -func (s *StatementExecutor) executeShowStatistics() *influxql.Result { - stats, err := s.Monitor.Statistics(nil) - if err != nil { - return &influxql.Result{Err: err} - } - rows := make([]*influxql.Row, len(stats)) - - for n, stat := range stats { - row := &influxql.Row{Name: stat.Name, Tags: stat.Tags} - - values := make([]interface{}, 0, len(stat.Values)) - for _, k := range stat.valueNames() { - row.Columns = append(row.Columns, k) - values = append(values, stat.Values[k]) - } - row.Values = [][]interface{}{values} - rows[n] = row - } - return &influxql.Result{Series: rows} -} - -func (s *StatementExecutor) executeShowDiagnostics() *influxql.Result { - diags, err := s.Monitor.Diagnostics() - if err != nil { - return &influxql.Result{Err: err} - } - rows := make([]*influxql.Row, 0, len(diags)) - - for k, v := range diags { - row := &influxql.Row{Name: k} - - row.Columns = v.Columns - row.Values = v.Rows - rows = append(rows, row) - } - return &influxql.Result{Series: rows} -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/system.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/system.go deleted file mode 100644 index 1f113f176..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/monitor/system.go +++ /dev/null @@ -1,26 +0,0 @@ -package monitor - -import ( - "os" - "time" -) - -var startTime time.Time - -func init() { - startTime = time.Now().UTC() -} - -// system captures system-level diagnostics -type system struct{} - -func (s *system) Diagnostics() (*Diagnostic, error) { - diagnostics := map[string]interface{}{ - "PID": os.Getpid(), - "currentTime": time.Now().UTC(), - "started": startTime, - "uptime": time.Since(startTime).String(), - } - - return DiagnosticFromMap(diagnostics), nil -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/nightly.sh b/Godeps/_workspace/src/github.com/influxdb/influxdb/nightly.sh index f41a083de..9052201a2 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/nightly.sh +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/nightly.sh @@ -10,5 +10,5 @@ cd $GOPATH/src/github.com/influxdb git clone https://github.com/influxdb/influxdb.git cd $GOPATH/src/github.com/influxdb/influxdb -NIGHTLY_BUILD=true ./package.sh 0.9.5-nightly-`git log --pretty=format:'%h' -n 1` +NIGHTLY_BUILD=true ./package.sh 0.9.3-nightly-`git log --pretty=format:'%h' -n 1` rm -rf $REPO_DIR diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/package.sh b/Godeps/_workspace/src/github.com/influxdb/influxdb/package.sh index e3761a143..c86a8b3eb 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/package.sh +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/package.sh @@ -18,8 +18,6 @@ # package is successful, the script will offer to tag the repo using the # supplied version string. # -# See package.sh -h for options -# # AWS upload: the script will also offer to upload the packages to S3. If # this option is selected, the credentials should be present in the file # ~/aws.conf. The contents should be of the form: @@ -40,12 +38,9 @@ INSTALL_ROOT_DIR=/opt/influxdb INFLUXDB_LOG_DIR=/var/log/influxdb INFLUXDB_DATA_DIR=/var/opt/influxdb CONFIG_ROOT_DIR=/etc/opt/influxdb -LOGROTATE_DIR=/etc/logrotate.d SAMPLE_CONFIGURATION=etc/config.sample.toml INITD_SCRIPT=scripts/init.sh -SYSTEMD_SCRIPT=scripts/influxdb.service -LOGROTATE=scripts/logrotate TMP_WORK_DIR=`mktemp -d` POST_INSTALL_PATH=`mktemp` @@ -62,7 +57,7 @@ if [ -z "$FPM" ]; then FPM=`which fpm` fi -GO_VERSION="go1.5" +GO_VERSION="go1.4.2" GOPATH_INSTALL= BINS=( influxd @@ -74,16 +69,7 @@ BINS=( # usage prints simple usage information. usage() { - cat << EOF >&2 -$0 [-h] [-p|-w] [-t ] - -p just build packages - -w build packages for current working directory - imply -p - -t - build package for - can be rpm, tar or deb - can have multiple -t -EOF + echo -e "$0 [] [-h]\n" cleanup_exit $1 } @@ -182,41 +168,20 @@ make_dir_tree() { echo "Failed to create configuration directory -- aborting." cleanup_exit 1 fi - mkdir -p $work_dir/$LOGROTATE_DIR - if [ $? -ne 0 ]; then - echo "Failed to create logrotate directory -- aborting." - cleanup_exit 1 - fi } + # do_build builds the code. The version and commit must be passed in. do_build() { for b in ${BINS[*]}; do rm -f $GOPATH_INSTALL/bin/$b done - - if [ -n "$WORKING_DIR" ]; then - STASH=`git stash create -a` - if [ $? -ne 0 ]; then - echo "WARNING: failed to stash uncommited local changes" - fi - git reset --hard - fi - go get -u -f -d ./... if [ $? -ne 0 ]; then echo "WARNING: failed to 'go get' packages." fi git checkout $TARGET_BRANCH # go get switches to master, so ensure we're back. - - if [ -n "$WORKING_DIR" ]; then - git stash apply $STASH - if [ $? -ne 0 ]; then #and apply previous uncommited local changes - echo "WARNING: failed to restore uncommited local changes" - fi - fi - version=$1 commit=`git rev-parse HEAD` branch=`current_branch` @@ -225,7 +190,7 @@ do_build() { cleanup_exit 1 fi - go install -a -ldflags="-X main.version=$version -X main.branch=$branch -X main.commit=$commit" ./... + go install -a -ldflags="-X main.version $version -X main.branch $branch -X main.commit $commit" ./... if [ $? -ne 0 ]; then echo "Build failed, unable to create package -- aborting" cleanup_exit 1 @@ -245,29 +210,19 @@ ln -s $INSTALL_ROOT_DIR/versions/$version/influxd $INSTALL_ROOT_DIR/influxd ln -s $INSTALL_ROOT_DIR/versions/$version/influx $INSTALL_ROOT_DIR/influx ln -s $INSTALL_ROOT_DIR/versions/$version/scripts/init.sh $INSTALL_ROOT_DIR/init.sh +rm -f /etc/init.d/influxdb +ln -sfn $INSTALL_ROOT_DIR/init.sh /etc/init.d/influxdb +chmod +x /etc/init.d/influxdb +if which update-rc.d > /dev/null 2>&1 ; then + update-rc.d -f influxdb remove + update-rc.d influxdb defaults +else + chkconfig --add influxdb +fi + if ! id influxdb >/dev/null 2>&1; then useradd --system -U -M influxdb fi - -# Systemd -if which systemctl > /dev/null 2>&1 ; then - cp $INSTALL_ROOT_DIR/versions/$version/scripts/influxdb.service \ - /lib/systemd/system/influxdb.service - systemctl enable influxdb - -# Sysv -else - rm -f /etc/init.d/influxdb - ln -sfn $INSTALL_ROOT_DIR/init.sh /etc/init.d/influxdb - chmod +x /etc/init.d/influxdb - if which update-rc.d > /dev/null 2>&1 ; then - update-rc.d -f influxdb remove - update-rc.d influxdb defaults - else - chkconfig --add influxdb - fi -fi - chown -R -L influxdb:influxdb $INSTALL_ROOT_DIR chmod -R a+rX $INSTALL_ROOT_DIR @@ -279,81 +234,23 @@ EOF echo "Post-install script created successfully at $POST_INSTALL_PATH" } -########################################################################### -# Process options -while : -do - case $1 in - -h | --help) - usage 0 - ;; - - -p | --packages-only) - PACKAGES_ONLY="PACKAGES_ONLY" - shift - ;; - - -t | --target) - case "$2" in - 'tar') TAR_WANTED="gz" - ;; - 'deb') DEB_WANTED="deb" - ;; - 'rpm') RPM_WANTED="rpm" - ;; - *) - echo "Unknown target distribution $2" - usage 1 - ;; - esac - shift 2 - ;; - - -w | --working-directory) - PACKAGES_ONLY="PACKAGES_ONLY" - WORKING_DIR="WORKING_DIR" - shift - ;; - - -*) - echo "Unknown option $1" - usage 1 - ;; - - ?*) - if [ -z $VERSION ]; then - VERSION=$1 - VERSION_UNDERSCORED=`echo "$VERSION" | tr - _` - shift - else - echo "$1 : aborting version already set to $VERSION" - usage 1 - fi - ;; - - *) break - esac -done - -if [ -z "$DEB_WANTED$RPM_WANTED$TAR_WANTED" ]; then - TAR_WANTED="gz" - DEB_WANTED="deb" - RPM_WANTED="rpm" -fi - -if [ -z "$VERSION" ]; then - echo -e "Missing version" - usage 1 -fi - ########################################################################### # Start the packaging process. +if [ $# -ne 1 ]; then + usage 1 +elif [ $1 == "-h" ]; then + usage 0 +else + VERSION=$1 + VERSION_UNDERSCORED=`echo "$VERSION" | tr - _` +fi + echo -e "\nStarting package process...\n" # Ensure the current is correct. TARGET_BRANCH=`current_branch` -if [ -z "$NIGHTLY_BUILD" -a -z "$PACKAGES_ONLY" ]; then +if [ -z "$NIGHTLY_BUILD" ]; then echo -n "Current branch is $TARGET_BRANCH. Start packaging this branch? [Y/n] " read response response=`echo $response | tr 'A-Z' 'a-z'` @@ -365,7 +262,7 @@ fi check_gvm check_gopath -if [ -z "$NIGHTLY_BUILD" -a -z "$PACKAGES_ONLY" ]; then +if [ -z "$NIGHTLY_BUILD" ]; then check_clean_tree update_tree check_tag_exists $VERSION @@ -393,31 +290,18 @@ if [ $? -ne 0 ]; then fi echo "$INITD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts" -cp $SYSTEMD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts -if [ $? -ne 0 ]; then - echo "Failed to copy systemd script to packaging directory -- aborting." - cleanup_exit 1 -fi -echo "$SYSTEMD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts" - cp $SAMPLE_CONFIGURATION $TMP_WORK_DIR/$CONFIG_ROOT_DIR/influxdb.conf if [ $? -ne 0 ]; then echo "Failed to copy $SAMPLE_CONFIGURATION to packaging directory -- aborting." cleanup_exit 1 fi -cp $LOGROTATE $TMP_WORK_DIR/$LOGROTATE_DIR/influxd -if [ $? -ne 0 ]; then - echo "Failed to copy logrotate configuration to packaging directory -- aborting." - cleanup_exit 1 -fi - generate_postinstall_script $VERSION ########################################################################### # Create the actual packages. -if [ -z "$NIGHTLY_BUILD" -a -z "$PACKAGES_ONLY" ]; then +if [ -z "$NIGHTLY_BUILD" ]; then echo -n "Commence creation of $ARCH packages, version $VERSION? [Y/n] " read response response=`echo $response | tr 'A-Z' 'a-z'` @@ -440,39 +324,32 @@ else debian_package=influxdb_${VERSION}_amd64.deb fi -COMMON_FPM_ARGS="--log error -C $TMP_WORK_DIR --vendor $VENDOR --url $URL --license $LICENSE --maintainer $MAINTAINER --after-install $POST_INSTALL_PATH --name influxdb --version $VERSION --config-files $CONFIG_ROOT_DIR --config-files $LOGROTATE_DIR ." - -if [ -n "$DEB_WANTED" ]; then - $FPM -s dir -t deb $deb_args --description "$DESCRIPTION" $COMMON_FPM_ARGS - if [ $? -ne 0 ]; then - echo "Failed to create Debian package -- aborting." - cleanup_exit 1 - fi - echo "Debian package created successfully." +COMMON_FPM_ARGS="-C $TMP_WORK_DIR --vendor $VENDOR --url $URL --license $LICENSE --maintainer $MAINTAINER --after-install $POST_INSTALL_PATH --name influxdb --version $VERSION --config-files $CONFIG_ROOT_DIR ." +$rpm_args $FPM -s dir -t rpm --description "$DESCRIPTION" $COMMON_FPM_ARGS +if [ $? -ne 0 ]; then + echo "Failed to create RPM package -- aborting." + cleanup_exit 1 fi +echo "RPM package created successfully." -if [ -n "$TAR_WANTED" ]; then - $FPM -s dir -t tar --prefix influxdb_${VERSION}_${ARCH} -p influxdb_${VERSION}_${ARCH}.tar.gz --description "$DESCRIPTION" $COMMON_FPM_ARGS - if [ $? -ne 0 ]; then - echo "Failed to create Tar package -- aborting." - cleanup_exit 1 - fi - echo "Tar package created successfully." +$FPM -s dir -t deb $deb_args --description "$DESCRIPTION" $COMMON_FPM_ARGS +if [ $? -ne 0 ]; then + echo "Failed to create Debian package -- aborting." + cleanup_exit 1 fi +echo "Debian package created successfully." -if [ -n "$RPM_WANTED" ]; then - $rpm_args $FPM -s dir -t rpm --description "$DESCRIPTION" $COMMON_FPM_ARGS - if [ $? -ne 0 ]; then - echo "Failed to create RPM package -- aborting." - cleanup_exit 1 - fi - echo "RPM package created successfully." +$FPM -s dir -t tar --prefix influxdb_${VERSION}_${ARCH} -p influxdb_${VERSION}_${ARCH}.tar.gz --description "$DESCRIPTION" $COMMON_FPM_ARGS +if [ $? -ne 0 ]; then + echo "Failed to create Tar package -- aborting." + cleanup_exit 1 fi +echo "Tar package created successfully." ########################################################################### # Offer to tag the repo. -if [ -z "$NIGHTLY_BUILD" -a -z "$PACKAGES_ONLY" ]; then +if [ -z "$NIGHTLY_BUILD" ]; then echo -n "Tag source tree with v$VERSION and push to repo? [y/N] " read response response=`echo $response | tr 'A-Z' 'a-z'` @@ -483,13 +360,11 @@ if [ -z "$NIGHTLY_BUILD" -a -z "$PACKAGES_ONLY" ]; then echo "Failed to create tag v$VERSION -- aborting" cleanup_exit 1 fi - echo "Tag v$VERSION created" git push origin v$VERSION if [ $? -ne 0 ]; then echo "Failed to push tag v$VERSION to repo -- aborting" cleanup_exit 1 fi - echo "Tag v$VERSION pushed to repo" else echo "Not creating tag v$VERSION." fi @@ -498,7 +373,7 @@ fi ########################################################################### # Offer to publish the packages. -if [ -z "$NIGHTLY_BUILD" -a -z "$PACKAGES_ONLY" ]; then +if [ -z "$NIGHTLY_BUILD" ]; then echo -n "Publish packages to S3? [y/N] " read response response=`echo $response | tr 'A-Z' 'a-z'` @@ -511,7 +386,7 @@ if [ "x$response" == "xy" -o -n "$NIGHTLY_BUILD" ]; then cleanup_exit 1 fi - for filepath in `ls *.{$DEB_WANTED,$RPM_WANTED,$TAR_WANTED} 2> /dev/null`; do + for filepath in `ls *.{deb,rpm,gz}`; do filename=`basename $filepath` if [ -n "$NIGHTLY_BUILD" ]; then filename=`echo $filename | sed s/$VERSION/nightly/` @@ -519,10 +394,9 @@ if [ "x$response" == "xy" -o -n "$NIGHTLY_BUILD" ]; then fi AWS_CONFIG_FILE=$AWS_FILE aws s3 cp $filepath s3://influxdb/$filename --acl public-read --region us-east-1 if [ $? -ne 0 ]; then - echo "Upload failed ($filename) -- aborting". + echo "Upload failed -- aborting". cleanup_exit 1 fi - echo "$filename uploaded" done else echo "Not publishing packages to S3." diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/influxdb.service b/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/influxdb.service index e8633acb0..c164ed3b2 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/influxdb.service +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/influxdb.service @@ -2,7 +2,6 @@ [Unit] Description=InfluxDB is an open-source, distributed, time series database -Documentation=https://influxdb.com/docs/ After=network.target [Service] @@ -11,9 +10,7 @@ Group=influxdb LimitNOFILE=65536 EnvironmentFile=-/etc/default/influxdb ExecStart=/opt/influxdb/influxd -config /etc/opt/influxdb/influxdb.conf $INFLUXD_OPTS -KillMode=process Restart=on-failure [Install] WantedBy=multi-user.target -Alias=influxd.service diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/init.sh b/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/init.sh index 4cdc136bc..7e97b0def 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/init.sh +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/init.sh @@ -45,7 +45,7 @@ PIDFILE=/var/run/influxdb/influxd.pid PIDDIR=`dirname $PIDFILE` if [ ! -d "$PIDDIR" ]; then mkdir -p $PIDDIR - chown $USER:$GROUP $PIDDIR + chown $GROUP:$USER $PIDDIR fi # Max open files @@ -103,20 +103,7 @@ function killproc() { PID=`cat $2` - /bin/kill -s $3 $PID - while true; do - pidof `basename $DAEMON` >/dev/null - if [ $? -ne 0 ]; then - return 0 - fi - - sleep 1 - n=$(expr $n + 1) - if [ $n -eq 30 ]; then - /bin/kill -s SIGKILL $PID - return 0 - fi - done + kill -s $3 $PID } function log_failure_msg() { @@ -164,7 +151,7 @@ case $1 in if which start-stop-daemon > /dev/null 2>&1; then start-stop-daemon --chuid $GROUP:$USER --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -pidfile $PIDFILE -config $CONFIG $INFLUXD_OPTS >>$STDOUT 2>>$STDERR & else - su -s /bin/sh -c "nohup $DAEMON -pidfile $PIDFILE -config $CONFIG $INFLUXD_OPTS >>$STDOUT 2>>$STDERR &" $USER + nohup $DAEMON -pidfile $PIDFILE -config $CONFIG $INFLUXD_OPTS >>$STDOUT 2>>$STDERR & fi log_success_msg "$NAME process was started" ;; diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/logrotate b/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/logrotate deleted file mode 100644 index de410d48c..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/scripts/logrotate +++ /dev/null @@ -1,8 +0,0 @@ -/var/log/influxdb/influxd.log { - daily - rotate 7 - missingok - dateext - copytruncate - compress -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/config.go index 427598ca6..3129c3378 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/config.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/config.go @@ -13,9 +13,7 @@ const ( DefaultRetentionPolicy = "" - DefaultBatchSize = 1000 - - DefaultBatchPending = 5 + DefaultBatchSize = 5000 DefaultBatchDuration = toml.Duration(10 * time.Second) @@ -29,7 +27,6 @@ type Config struct { Database string `toml:"database"` RetentionPolicy string `toml:"retention-policy"` BatchSize int `toml:"batch-size"` - BatchPending int `toml:"batch-pending"` BatchDuration toml.Duration `toml:"batch-timeout"` TypesDB string `toml:"typesdb"` } @@ -41,7 +38,6 @@ func NewConfig() Config { Database: DefaultDatabase, RetentionPolicy: DefaultRetentionPolicy, BatchSize: DefaultBatchSize, - BatchPending: DefaultBatchPending, BatchDuration: DefaultBatchDuration, TypesDB: DefaultTypesDB, } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service.go index 35a31049a..b0fee0bc4 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service.go @@ -1,16 +1,13 @@ package collectd import ( - "expvar" "fmt" "log" "net" "os" - "strings" "sync" "time" - "github.com/influxdb/influxdb" "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/meta" "github.com/influxdb/influxdb/tsdb" @@ -19,17 +16,6 @@ import ( const leaderWaitTimeout = 30 * time.Second -// statistics gathered by the collectd service. -const ( - statPointsReceived = "points_rx" - statBytesReceived = "bytes_rx" - statPointsParseFail = "points_parse_fail" - statReadFail = "read_fail" - statBatchesTrasmitted = "batches_tx" - statPointsTransmitted = "points_tx" - statBatchesTransmitFail = "batches_tx_fail" -) - // pointsWriter is an internal interface to make testing easier. type pointsWriter interface { WritePoints(p *cluster.WritePointsRequest) error @@ -56,9 +42,6 @@ type Service struct { batcher *tsdb.PointBatcher typesdb gollectd.Types addr net.Addr - - // expvar-based stats. - statMap *expvar.Map } // NewService returns a new instance of the collectd service. @@ -76,12 +59,6 @@ func NewService(c Config) *Service { func (s *Service) Open() error { s.Logger.Printf("Starting collectd service") - // Configure expvar monitoring. It's OK to do this even if the service fails to open and - // should be done before any data could arrive for the service. - key := strings.Join([]string{"collectd", s.Config.BindAddress}, ":") - tags := map[string]string{"bind": s.Config.BindAddress} - s.statMap = influxdb.NewStatistics(key, "collectd", tags) - if s.Config.BindAddress == "" { return fmt.Errorf("bind address is blank") } else if s.Config.Database == "" { @@ -126,7 +103,7 @@ func (s *Service) Open() error { s.Logger.Println("Listening on UDP: ", ln.LocalAddr().String()) // Start the points batcher. - s.batcher = tsdb.NewPointBatcher(s.Config.BatchSize, s.Config.BatchPending, time.Duration(s.Config.BatchDuration)) + s.batcher = tsdb.NewPointBatcher(s.Config.BatchSize, time.Duration(s.Config.BatchDuration)) s.batcher.Start() // Create channel and wait group for signalling goroutines to stop. @@ -205,12 +182,10 @@ func (s *Service) serve() { n, _, err := s.ln.ReadFromUDP(buffer) if err != nil { - s.statMap.Add(statReadFail, 1) s.Logger.Printf("collectd ReadFromUDP error: %s", err) continue } if n > 0 { - s.statMap.Add(statBytesReceived, int64(n)) s.handleMessage(buffer[:n]) } } @@ -219,7 +194,6 @@ func (s *Service) serve() { func (s *Service) handleMessage(buffer []byte) { packets, err := gollectd.Packets(buffer, s.typesdb) if err != nil { - s.statMap.Add(statPointsParseFail, 1) s.Logger.Printf("Collectd parse error: %s", err) return } @@ -228,7 +202,6 @@ func (s *Service) handleMessage(buffer []byte) { for _, p := range points { s.batcher.In() <- p } - s.statMap.Add(statPointsReceived, int64(len(points))) } } @@ -240,17 +213,15 @@ func (s *Service) writePoints() { case <-s.stop: return case batch := <-s.batcher.Out(): - if err := s.PointsWriter.WritePoints(&cluster.WritePointsRequest{ + req := &cluster.WritePointsRequest{ Database: s.Config.Database, RetentionPolicy: s.Config.RetentionPolicy, ConsistencyLevel: cluster.ConsistencyLevelAny, Points: batch, - }); err == nil { - s.statMap.Add(statBatchesTrasmitted, 1) - s.statMap.Add(statPointsTransmitted, int64(len(batch))) - } else { - s.Logger.Printf("failed to write point batch to database %q: %s", s.Config.Database, err) - s.statMap.Add(statBatchesTransmitFail, 1) + } + if err := s.PointsWriter.WritePoints(req); err != nil { + s.Logger.Printf("failed to write batch: %s", err) + continue } } } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service_test.go index 05e969041..a24c9d29f 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/collectd/service_test.go @@ -261,32 +261,32 @@ var testData = func() []byte { }() var expPoints = []string{ - "entropy_value,host=pf1-62-210-94-173,type=entropy value=288 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=idle value=10908770 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=wait value=0 1414080767000000000", - "df_used,host=pf1-62-210-94-173,type=df,type_instance=live-cow value=378576896 1414080767000000000", - "df_free,host=pf1-62-210-94-173,type=df,type_instance=live-cow value=50287988736 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=interrupt value=254 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=softirq value=0 1414080767000000000", - "df_used,host=pf1-62-210-94-173,type=df,type_instance=live value=0 1414080767000000000", - "df_free,host=pf1-62-210-94-173,type=df,type_instance=live value=50666565632 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=steal value=0 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=user value=24374 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=nice value=2776 1414080767000000000", - "interface_rx,host=pf1-62-210-94-173,type=if_octets,type_instance=dummy0 value=0 1414080767000000000", - "interface_tx,host=pf1-62-210-94-173,type=if_octets,type_instance=dummy0 value=1050 1414080767000000000", - "df_used,host=pf1-62-210-94-173,type=df,type_instance=tmp value=73728 1414080767000000000", - "df_free,host=pf1-62-210-94-173,type=df,type_instance=tmp value=50666491904 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=system value=17875 1414080767000000000", - "interface_rx,host=pf1-62-210-94-173,type=if_packets,type_instance=dummy0 value=0 1414080767000000000", - "interface_tx,host=pf1-62-210-94-173,type=if_packets,type_instance=dummy0 value=15 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=idle value=10904704 1414080767000000000", - "df_used,host=pf1-62-210-94-173,type=df,type_instance=run-lock value=0 1414080767000000000", - "df_free,host=pf1-62-210-94-173,type=df,type_instance=run-lock value=5242880 1414080767000000000", - "interface_rx,host=pf1-62-210-94-173,type=if_errors,type_instance=dummy0 value=0 1414080767000000000", - "interface_tx,host=pf1-62-210-94-173,type=if_errors,type_instance=dummy0 value=0 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=wait value=0 1414080767000000000", - "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=interrupt value=306 1414080767000000000", + "entropy_value,host=pf1-62-210-94-173,type=entropy value=288.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=idle value=10908770.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=wait value=0.0 1414080767000000000", + "df_used,host=pf1-62-210-94-173,type=df,type_instance=live-cow value=378576896.0 1414080767000000000", + "df_free,host=pf1-62-210-94-173,type=df,type_instance=live-cow value=50287988736.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=interrupt value=254.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=softirq value=0.0 1414080767000000000", + "df_used,host=pf1-62-210-94-173,type=df,type_instance=live value=0.0 1414080767000000000", + "df_free,host=pf1-62-210-94-173,type=df,type_instance=live value=50666565632.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=1,type=cpu,type_instance=steal value=0.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=user value=24374.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=nice value=2776.0 1414080767000000000", + "interface_rx,host=pf1-62-210-94-173,type=if_octets,type_instance=dummy0 value=0.0 1414080767000000000", + "interface_tx,host=pf1-62-210-94-173,type=if_octets,type_instance=dummy0 value=1050.0 1414080767000000000", + "df_used,host=pf1-62-210-94-173,type=df,type_instance=tmp value=73728.0 1414080767000000000", + "df_free,host=pf1-62-210-94-173,type=df,type_instance=tmp value=50666491904.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=system value=17875.0 1414080767000000000", + "interface_rx,host=pf1-62-210-94-173,type=if_packets,type_instance=dummy0 value=0.0 1414080767000000000", + "interface_tx,host=pf1-62-210-94-173,type=if_packets,type_instance=dummy0 value=15.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=idle value=10904704.0 1414080767000000000", + "df_used,host=pf1-62-210-94-173,type=df,type_instance=run-lock value=0.0 1414080767000000000", + "df_free,host=pf1-62-210-94-173,type=df,type_instance=run-lock value=5242880.0 1414080767000000000", + "interface_rx,host=pf1-62-210-94-173,type=if_errors,type_instance=dummy0 value=0.0 1414080767000000000", + "interface_tx,host=pf1-62-210-94-173,type=if_errors,type_instance=dummy0 value=0.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=wait value=0.0 1414080767000000000", + "cpu_value,host=pf1-62-210-94-173,instance=2,type=cpu,type_instance=interrupt value=306.0 1414080767000000000", } // Taken from /usr/share/collectd/types.db on a Ubuntu system diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service.go index a469bc869..77c1ae66a 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service.go @@ -2,7 +2,6 @@ package continuous_querier import ( "errors" - "expvar" "fmt" "log" "os" @@ -10,7 +9,6 @@ import ( "sync" "time" - "github.com/influxdb/influxdb" "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/meta" @@ -22,17 +20,10 @@ const ( NoChunkingSize = 0 ) -// Statistics for the CQ service. -const ( - statQueryOK = "query_ok" - statQueryFail = "query_fail" - statPointsWritten = "points_written" -) - // ContinuousQuerier represents a service that executes continuous queries. type ContinuousQuerier interface { // Run executes the named query in the named database. Blank database or name matches all. - Run(database, name string, t time.Time) error + Run(database, name string) error } // queryExecutor is an internal interface to make testing easier. @@ -52,28 +43,6 @@ type pointsWriter interface { WritePoints(p *cluster.WritePointsRequest) error } -// RunRequest is a request to run one or more CQs. -type RunRequest struct { - // Now tells the CQ serivce what the current time is. - Now time.Time - // CQs tells the CQ service which queries to run. - // If nil, all queries will be run. - CQs []string -} - -// matches returns true if the CQ matches one of the requested CQs. -func (rr *RunRequest) matches(cq *meta.ContinuousQueryInfo) bool { - if rr.CQs == nil { - return true - } - for _, q := range rr.CQs { - if q == cq.Name { - return true - } - } - return false -} - // Service manages continuous query execution. type Service struct { MetaStore metaStore @@ -82,12 +51,10 @@ type Service struct { Config *Config RunInterval time.Duration // RunCh can be used by clients to signal service to run CQs. - RunCh chan *RunRequest + RunCh chan struct{} Logger *log.Logger loggingEnabled bool - statMap *expvar.Map // lastRuns maps CQ name to last time it was run. - mu sync.RWMutex lastRuns map[string]time.Time stop chan struct{} wg *sync.WaitGroup @@ -98,9 +65,8 @@ func NewService(c Config) *Service { s := &Service{ Config: &c, RunInterval: time.Second, - RunCh: make(chan *RunRequest), + RunCh: make(chan struct{}), loggingEnabled: c.LogEnabled, - statMap: influxdb.NewStatistics("cq", "cq", nil), Logger: log.New(os.Stderr, "[continuous_querier] ", log.LstdFlags), lastRuns: map[string]time.Time{}, } @@ -110,6 +76,7 @@ func NewService(c Config) *Service { // Open starts the service. func (s *Service) Open() error { + s.Logger.Println("Starting continuous query service") if s.stop != nil { @@ -145,7 +112,7 @@ func (s *Service) SetLogger(l *log.Logger) { } // Run runs the specified continuous query, or all CQs if none is specified. -func (s *Service) Run(database, name string, t time.Time) error { +func (s *Service) Run(database, name string) error { var dbs []meta.DatabaseInfo if database != "" { @@ -167,8 +134,6 @@ func (s *Service) Run(database, name string, t time.Time) error { } // Loop through databases. - s.mu.Lock() - defer s.mu.Unlock() for _, db := range dbs { // Loop through CQs in each DB executing the ones that match name. for _, cq := range db.ContinuousQueries { @@ -180,7 +145,7 @@ func (s *Service) Run(database, name string, t time.Time) error { } // Signal the background routine to run CQs. - s.RunCh <- &RunRequest{Now: t} + s.RunCh <- struct{}{} return nil } @@ -193,21 +158,21 @@ func (s *Service) backgroundLoop() { case <-s.stop: s.Logger.Println("continuous query service terminating") return - case req := <-s.RunCh: + case <-s.RunCh: if s.MetaStore.IsLeader() { - s.Logger.Printf("running continuous queries by request for time: %v", req.Now.UnixNano()) - s.runContinuousQueries(req) + s.Logger.Print("running continuous queries by request") + s.runContinuousQueries() } case <-time.After(s.RunInterval): if s.MetaStore.IsLeader() { - s.runContinuousQueries(&RunRequest{Now: time.Now()}) + s.runContinuousQueries() } } } } // runContinuousQueries gets CQs from the meta store and runs them. -func (s *Service) runContinuousQueries(req *RunRequest) { +func (s *Service) runContinuousQueries() { // Get list of all databases. dbs, err := s.MetaStore.Databases() if err != nil { @@ -218,21 +183,15 @@ func (s *Service) runContinuousQueries(req *RunRequest) { for _, db := range dbs { // TODO: distribute across nodes for _, cq := range db.ContinuousQueries { - if !req.matches(&cq) { - continue - } - if err := s.ExecuteContinuousQuery(&db, &cq, req.Now); err != nil { + if err := s.ExecuteContinuousQuery(&db, &cq); err != nil { s.Logger.Printf("error executing query: %s: err = %s", cq.Query, err) - s.statMap.Add(statQueryFail, 1) - } else { - s.statMap.Add(statQueryOK, 1) } } } } // ExecuteContinuousQuery executes a single CQ. -func (s *Service) ExecuteContinuousQuery(dbi *meta.DatabaseInfo, cqi *meta.ContinuousQueryInfo, now time.Time) error { +func (s *Service) ExecuteContinuousQuery(dbi *meta.DatabaseInfo, cqi *meta.ContinuousQueryInfo) error { // TODO: re-enable stats //s.stats.Inc("continuousQueryExecuted") @@ -243,8 +202,6 @@ func (s *Service) ExecuteContinuousQuery(dbi *meta.DatabaseInfo, cqi *meta.Conti } // Get the last time this CQ was run from the service's cache. - s.mu.Lock() - defer s.mu.Unlock() cq.LastRun = s.lastRuns[cqi.Name] // Set the retention policy to default if it wasn't specified in the query. @@ -262,9 +219,9 @@ func (s *Service) ExecuteContinuousQuery(dbi *meta.DatabaseInfo, cqi *meta.Conti } // We're about to run the query so store the time. - lastRun := time.Now() - cq.LastRun = lastRun - s.lastRuns[cqi.Name] = lastRun + now := time.Now() + cq.LastRun = now + s.lastRuns[cqi.Name] = now // Get the group by interval. interval, err := cq.q.GroupByInterval() @@ -331,6 +288,12 @@ func (s *Service) runContinuousQueryAndWriteResult(cq *ContinuousQuery) error { return err } + // Drain results + defer func() { + for _ = range ch { + } + }() + // Read all rows from the result channel. points := make([]tsdb.Point, 0, 100) for result := range ch { @@ -339,13 +302,8 @@ func (s *Service) runContinuousQueryAndWriteResult(cq *ContinuousQuery) error { } for _, row := range result.Series { - // Get the measurement name for the result. - measurement := cq.intoMeasurement() - if measurement == "" { - measurement = row.Name - } // Convert the result row to points. - part, err := s.convertRowToPoints(measurement, row) + part, err := s.convertRowToPoints(cq.intoMeasurement(), row) if err != nil { log.Println(err) continue @@ -387,9 +345,8 @@ func (s *Service) runContinuousQueryAndWriteResult(cq *ContinuousQuery) error { return err } - s.statMap.Add(statPointsWritten, int64(len(points))) if s.loggingEnabled { - s.Logger.Printf("wrote %d point(s) to %s.%s", len(points), cq.intoDB(), cq.intoRP()) + s.Logger.Printf("wrote %d point(s) to %s.%s.%s", len(points), cq.intoDB(), cq.intoRP(), cq.Info.Name) } return nil @@ -436,13 +393,7 @@ type ContinuousQuery struct { q *influxql.SelectStatement } -func (cq *ContinuousQuery) intoDB() string { - if cq.q.Target.Measurement.Database != "" { - return cq.q.Target.Measurement.Database - } - return cq.Database -} - +func (cq *ContinuousQuery) intoDB() string { return cq.q.Target.Measurement.Database } func (cq *ContinuousQuery) intoRP() string { return cq.q.Target.Measurement.RetentionPolicy } func (cq *ContinuousQuery) setIntoRP(rp string) { cq.q.Target.Measurement.RetentionPolicy = rp } func (cq *ContinuousQuery) intoMeasurement() string { return cq.q.Target.Measurement.Name } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service_test.go index 30c498797..dfe0f7611 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/continuous_querier/service_test.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "log" - "strings" "sync" "testing" "time" @@ -37,8 +36,8 @@ func TestOpenAndClose(t *testing.T) { } } -// Test ExecuteContinuousQuery. -func TestExecuteContinuousQuery(t *testing.T) { +// Test ExecuteContinuousQuery happy path. +func TestExecuteContinuousQuery_HappyPath(t *testing.T) { s := NewTestService(t) dbis, _ := s.MetaStore.Databases() dbi := dbis[0] @@ -56,53 +55,14 @@ func TestExecuteContinuousQuery(t *testing.T) { return nil } - err := s.ExecuteContinuousQuery(&dbi, &cqi, time.Now()) - if err != nil { - t.Error(err) - } -} - -// Test ExecuteContinuousQuery when INTO measurements are taken from the FROM clause. -func TestExecuteContinuousQuery_ReferenceSource(t *testing.T) { - s := NewTestService(t) - dbis, _ := s.MetaStore.Databases() - dbi := dbis[2] - cqi := dbi.ContinuousQueries[0] - - rowCnt := 2 - pointCnt := 1 - qe := s.QueryExecutor.(*QueryExecutor) - qe.Results = []*influxql.Result{genResult(rowCnt, pointCnt)} - - pw := s.PointsWriter.(*PointsWriter) - pw.WritePointsFn = func(p *cluster.WritePointsRequest) error { - if len(p.Points) != pointCnt*rowCnt { - return fmt.Errorf("exp = %d, got = %d", pointCnt, len(p.Points)) - } - - exp := "cpu,host=server01 value=0" - got := p.Points[0].String() - if !strings.Contains(got, exp) { - return fmt.Errorf("\n\tExpected ':MEASUREMENT' to be expanded to the measurement name(s) in the FROM regexp.\n\tqry = %s\n\texp = %s\n\tgot = %s\n", cqi.Query, got, exp) - } - - exp = "cpu2,host=server01 value=0" - got = p.Points[1].String() - if !strings.Contains(got, exp) { - return fmt.Errorf("\n\tExpected ':MEASUREMENT' to be expanded to the measurement name(s) in the FROM regexp.\n\tqry = %s\n\texp = %s\n\tgot = %s\n", cqi.Query, got, exp) - } - - return nil - } - - err := s.ExecuteContinuousQuery(&dbi, &cqi, time.Now()) + err := s.ExecuteContinuousQuery(&dbi, &cqi) if err != nil { t.Error(err) } } // Test the service happy path. -func TestContinuousQueryService(t *testing.T) { +func TestService_HappyPath(t *testing.T) { s := NewTestService(t) pointCnt := 100 @@ -110,7 +70,7 @@ func TestContinuousQueryService(t *testing.T) { qe.Results = []*influxql.Result{genResult(1, pointCnt)} pw := s.PointsWriter.(*PointsWriter) - ch := make(chan int, 10) + ch := make(chan int, 5) defer close(ch) pw.WritePointsFn = func(p *cluster.WritePointsRequest) error { ch <- len(p.Points) @@ -127,7 +87,7 @@ func TestContinuousQueryService(t *testing.T) { } // Test Run method. -func TestContinuousQueryService_Run(t *testing.T) { +func TestService_Run(t *testing.T) { s := NewTestService(t) // Set RunInterval high so we can trigger using Run method. @@ -137,7 +97,7 @@ func TestContinuousQueryService_Run(t *testing.T) { s.Config.RecomputePreviousN = 0 done := make(chan struct{}) - expectCallCnt := 3 + expectCallCnt := 2 callCnt := 0 // Set a callback for ExecuteQuery. @@ -152,7 +112,7 @@ func TestContinuousQueryService_Run(t *testing.T) { s.Open() // Trigger service to run all CQs. - s.Run("", "", time.Now()) + s.Run("", "") // Shouldn't time out. if err := wait(done, 100*time.Millisecond); err != nil { t.Error(err) @@ -167,7 +127,7 @@ func TestContinuousQueryService_Run(t *testing.T) { expectCallCnt = 1 callCnt = 0 s.Open() - s.Run("db", "cq", time.Now()) + s.Run("db", "cq") // Shouldn't time out. if err := wait(done, 100*time.Millisecond); err != nil { t.Error(err) @@ -180,7 +140,7 @@ func TestContinuousQueryService_Run(t *testing.T) { } // Test service when not the cluster leader (CQs shouldn't run). -func TestContinuousQueryService_NotLeader(t *testing.T) { +func TestService_NotLeader(t *testing.T) { s := NewTestService(t) // Set RunInterval high so we can test triggering with the RunCh below. s.RunInterval = 10 * time.Second @@ -196,7 +156,7 @@ func TestContinuousQueryService_NotLeader(t *testing.T) { s.Open() // Trigger service to run CQs. - s.RunCh <- &RunRequest{Now: time.Now()} + s.RunCh <- struct{}{} // Expect timeout error because ExecuteQuery callback wasn't called. if err := wait(done, 100*time.Millisecond); err == nil { t.Error(err) @@ -205,7 +165,7 @@ func TestContinuousQueryService_NotLeader(t *testing.T) { } // Test service behavior when meta store fails to get databases. -func TestContinuousQueryService_MetaStoreFailsToGetDatabases(t *testing.T) { +func TestService_MetaStoreFailsToGetDatabases(t *testing.T) { s := NewTestService(t) // Set RunInterval high so we can test triggering with the RunCh below. s.RunInterval = 10 * time.Second @@ -221,7 +181,7 @@ func TestContinuousQueryService_MetaStoreFailsToGetDatabases(t *testing.T) { s.Open() // Trigger service to run CQs. - s.RunCh <- &RunRequest{Now: time.Now()} + s.RunCh <- struct{}{} // Expect timeout error because ExecuteQuery callback wasn't called. if err := wait(done, 100*time.Millisecond); err == nil { t.Error(err) @@ -237,21 +197,21 @@ func TestExecuteContinuousQuery_InvalidQueries(t *testing.T) { cqi := dbi.ContinuousQueries[0] cqi.Query = `this is not a query` - err := s.ExecuteContinuousQuery(&dbi, &cqi, time.Now()) + err := s.ExecuteContinuousQuery(&dbi, &cqi) if err == nil { t.Error("expected error but got nil") } // Valid query but invalid continuous query. cqi.Query = `SELECT * FROM cpu` - err = s.ExecuteContinuousQuery(&dbi, &cqi, time.Now()) + err = s.ExecuteContinuousQuery(&dbi, &cqi) if err == nil { t.Error("expected error but got nil") } // Group by requires aggregate. cqi.Query = `SELECT value INTO other_value FROM cpu WHERE time > now() - 1h GROUP BY time(1s)` - err = s.ExecuteContinuousQuery(&dbi, &cqi, time.Now()) + err = s.ExecuteContinuousQuery(&dbi, &cqi) if err == nil { t.Error("expected error but got nil") } @@ -267,7 +227,7 @@ func TestExecuteContinuousQuery_QueryExecutor_Error(t *testing.T) { dbi := dbis[0] cqi := dbi.ContinuousQueries[0] - err := s.ExecuteContinuousQuery(&dbi, &cqi, time.Now()) + err := s.ExecuteContinuousQuery(&dbi, &cqi) if err != expectedErr { t.Errorf("exp = %s, got = %v", expectedErr, err) } @@ -292,8 +252,6 @@ func NewTestService(t *testing.T) *Service { ms.CreateContinuousQuery("db", "cq", `CREATE CONTINUOUS QUERY cq ON db BEGIN SELECT count(cpu) INTO cpu_count FROM cpu WHERE time > now() - 1h GROUP BY time(1s) END`) ms.CreateDatabase("db2", "default") ms.CreateContinuousQuery("db2", "cq2", `CREATE CONTINUOUS QUERY cq2 ON db2 BEGIN SELECT mean(value) INTO cpu_mean FROM cpu WHERE time > now() - 10m GROUP BY time(1m) END`) - ms.CreateDatabase("db3", "default") - ms.CreateContinuousQuery("db3", "cq3", `CREATE CONTINUOUS QUERY cq3 ON db3 BEGIN SELECT mean(value) INTO "1hAverages".:MEASUREMENT FROM /cpu[0-9]?/ GROUP BY time(10s) END`) return s } @@ -513,9 +471,6 @@ func genResult(rowCnt, valCnt int) *influxql.Result { Columns: []string{"time", "value"}, Values: vals, } - if len(rows) > 0 { - row.Name = fmt.Sprintf("cpu%d", len(rows)+1) - } rows = append(rows, row) } return &influxql.Result{ diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.pb.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.pb.go deleted file mode 100644 index 81732a93b..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.pb.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by protoc-gen-gogo. -// source: internal/internal.proto -// DO NOT EDIT! - -/* -Package internal is a generated protocol buffer package. - -It is generated from these files: - internal/internal.proto - -It has these top-level messages: - Request - Response -*/ -package internal - -import proto "github.com/gogo/protobuf/proto" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = math.Inf - -type Request struct { - ShardID *uint64 `protobuf:"varint,1,req" json:"ShardID,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} - -func (m *Request) GetShardID() uint64 { - if m != nil && m.ShardID != nil { - return *m.ShardID - } - return 0 -} - -type Response struct { - Error *string `protobuf:"bytes,1,opt" json:"Error,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} - -func (m *Response) GetError() string { - if m != nil && m.Error != nil { - return *m.Error - } - return "" -} - -func init() { -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.proto b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.proto deleted file mode 100644 index fb14c6812..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/internal/internal.proto +++ /dev/null @@ -1,9 +0,0 @@ -package internal; - -message Request { - required uint64 ShardID = 1; -} - -message Response { - optional string Error = 1; -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service.go deleted file mode 100644 index e245fac72..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service.go +++ /dev/null @@ -1,261 +0,0 @@ -package copier - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "log" - "net" - "os" - "strings" - "sync" - - "github.com/gogo/protobuf/proto" - "github.com/influxdb/influxdb/services/copier/internal" - "github.com/influxdb/influxdb/tcp" - "github.com/influxdb/influxdb/tsdb" -) - -//go:generate protoc --gogo_out=. internal/internal.proto - -// MuxHeader is the header byte used for the TCP muxer. -const MuxHeader = 6 - -// Service manages the listener for the endpoint. -type Service struct { - wg sync.WaitGroup - err chan error - - TSDBStore interface { - Shard(id uint64) *tsdb.Shard - } - - Listener net.Listener - Logger *log.Logger -} - -// NewService returns a new instance of Service. -func NewService() *Service { - return &Service{ - err: make(chan error), - Logger: log.New(os.Stderr, "[copier] ", log.LstdFlags), - } -} - -// Open starts the service. -func (s *Service) Open() error { - s.Logger.Println("Starting copier service") - - s.wg.Add(1) - go s.serve() - return nil -} - -// Close implements the Service interface. -func (s *Service) Close() error { - if s.Listener != nil { - s.Listener.Close() - } - s.wg.Wait() - return nil -} - -// SetLogger sets the internal logger to the logger passed in. -func (s *Service) SetLogger(l *log.Logger) { - s.Logger = l -} - -// Err returns a channel for fatal out-of-band errors. -func (s *Service) Err() <-chan error { return s.err } - -// serve serves shard copy requests from the listener. -func (s *Service) serve() { - defer s.wg.Done() - - for { - // Wait for next connection. - conn, err := s.Listener.Accept() - if err != nil && strings.Contains(err.Error(), "connection closed") { - s.Logger.Println("copier listener closed") - return - } else if err != nil { - s.Logger.Println("error accepting copier request: ", err.Error()) - continue - } - - // Handle connection in separate goroutine. - s.wg.Add(1) - go func(conn net.Conn) { - defer s.wg.Done() - defer conn.Close() - if err := s.handleConn(conn); err != nil { - s.Logger.Println(err) - } - }(conn) - } -} - -// handleConn processes conn. This is run in a separate goroutine. -func (s *Service) handleConn(conn net.Conn) error { - // Read request from connection. - req, err := s.readRequest(conn) - if err != nil { - return fmt.Errorf("read request: %s", err) - } - - // Retrieve shard. - sh := s.TSDBStore.Shard(req.GetShardID()) - - // Return error response if the shard doesn't exist. - if sh == nil { - if err := s.writeResponse(conn, &internal.Response{ - Error: proto.String(fmt.Sprintf("shard not found: id=%d", req.GetShardID())), - }); err != nil { - return fmt.Errorf("write error response: %s", err) - } - return nil - } - - // Write successful response. - if err := s.writeResponse(conn, &internal.Response{}); err != nil { - return fmt.Errorf("write response: %s", err) - } - - // Write shard to response. - if _, err := sh.WriteTo(conn); err != nil { - return fmt.Errorf("write shard: %s", err) - } - - return nil -} - -// readRequest reads and unmarshals a Request from r. -func (s *Service) readRequest(r io.Reader) (*internal.Request, error) { - // Read request length. - var n uint32 - if err := binary.Read(r, binary.BigEndian, &n); err != nil { - return nil, fmt.Errorf("read request length: %s", err) - } - - // Read body. - buf := make([]byte, n) - if _, err := io.ReadFull(r, buf); err != nil { - return nil, fmt.Errorf("read request: %s", err) - } - - // Unmarshal request. - req := &internal.Request{} - if err := proto.Unmarshal(buf, req); err != nil { - return nil, fmt.Errorf("unmarshal request: %s", err) - } - - return req, nil -} - -// writeResponse marshals and writes a Response to w. -func (s *Service) writeResponse(w io.Writer, resp *internal.Response) error { - // Marshal the response to a byte slice. - buf, err := proto.Marshal(resp) - if err != nil { - return fmt.Errorf("marshal error: %s", err) - } - - // Write response length to writer. - if err := binary.Write(w, binary.BigEndian, uint32(len(buf))); err != nil { - return fmt.Errorf("write response length error: %s", err) - } - - // Write body to writer. - if _, err := w.Write(buf); err != nil { - return fmt.Errorf("write body error: %s", err) - } - - return nil -} - -// Client represents a client for connecting remotely to a copier service. -type Client struct { - host string -} - -// NewClient return a new instance of Client. -func NewClient(host string) *Client { - return &Client{ - host: host, - } -} - -// ShardReader returns a reader for streaming shard data. -// Returned ReadCloser must be closed by the caller. -func (c *Client) ShardReader(id uint64) (io.ReadCloser, error) { - // Connect to remote server. - conn, err := tcp.Dial("tcp", c.host, MuxHeader) - if err != nil { - return nil, err - } - - // Send request to server. - if err := c.writeRequest(conn, &internal.Request{ShardID: proto.Uint64(id)}); err != nil { - return nil, fmt.Errorf("write request: %s", err) - } - - // Read response from the server. - resp, err := c.readResponse(conn) - if err != nil { - return nil, fmt.Errorf("read response: %s", err) - } - - // If there was an error then return it and close connection. - if resp.GetError() != "" { - conn.Close() - return nil, errors.New(resp.GetError()) - } - - // Returning remaining stream for caller to consume. - return conn, nil -} - -// writeRequest marshals and writes req to w. -func (c *Client) writeRequest(w io.Writer, req *internal.Request) error { - // Marshal request. - buf, err := proto.Marshal(req) - if err != nil { - return fmt.Errorf("marshal request: %s", err) - } - - // Write request length. - if err := binary.Write(w, binary.BigEndian, uint32(len(buf))); err != nil { - return fmt.Errorf("write request length: %s", err) - } - - // Send request to server. - if _, err := w.Write(buf); err != nil { - return fmt.Errorf("write request body: %s", err) - } - - return nil -} - -// readResponse reads and unmarshals a Response from r. -func (c *Client) readResponse(r io.Reader) (*internal.Response, error) { - // Read response length. - var n uint32 - if err := binary.Read(r, binary.BigEndian, &n); err != nil { - return nil, fmt.Errorf("read response length: %s", err) - } - - // Read response. - buf := make([]byte, n) - if _, err := io.ReadFull(r, buf); err != nil { - return nil, fmt.Errorf("read response: %s", err) - } - - // Unmarshal response. - resp := &internal.Response{} - if err := proto.Unmarshal(buf, resp); err != nil { - return nil, fmt.Errorf("unmarshal response: %s", err) - } - - return resp, nil -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service_test.go deleted file mode 100644 index a5266087d..000000000 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/copier/service_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package copier_test - -import ( - "bytes" - "encoding/binary" - "io" - "io/ioutil" - "log" - "net" - "os" - "path/filepath" - "testing" - - "github.com/influxdb/influxdb/services/copier" - "github.com/influxdb/influxdb/tcp" - "github.com/influxdb/influxdb/tsdb" - _ "github.com/influxdb/influxdb/tsdb/engine" -) - -// Ensure the service can return shard data. -func TestService_handleConn(t *testing.T) { - s := MustOpenService() - defer s.Close() - - // Mock shard. - sh := MustOpenShard(123) - defer sh.Close() - s.TSDBStore.ShardFn = func(id uint64) *tsdb.Shard { - if id != 123 { - t.Fatalf("unexpected id: %d", id) - } - return sh.Shard - } - - // Create client and request shard from service. - c := copier.NewClient(s.Addr().String()) - r, err := c.ShardReader(123) - if err != nil { - t.Fatal(err) - } else if r == nil { - t.Fatal("expected reader") - } - defer r.Close() - - // Slurp from reader. - var n uint64 - if err := binary.Read(r, binary.BigEndian, &n); err != nil { - t.Fatal(err) - } - buf := make([]byte, n) - if _, err := io.ReadFull(r, buf); err != nil { - t.Fatal(err) - } - - // Read database from disk. - exp, err := ioutil.ReadFile(sh.Path()) - if err != nil { - t.Fatal(err) - } - - // Trim expected bytes since bolt won't read beyond the HWM. - exp = exp[0:len(buf)] - - // Compare disk and reader contents. - if !bytes.Equal(exp, buf) { - t.Fatalf("data mismatch: exp=len(%d), got=len(%d)", len(exp), len(buf)) - } -} - -// Ensure the service can return an error to the client. -func TestService_handleConn_Error(t *testing.T) { - s := MustOpenService() - defer s.Close() - - // Mock missing shard. - s.TSDBStore.ShardFn = func(id uint64) *tsdb.Shard { return nil } - - // Create client and request shard from service. - c := copier.NewClient(s.Addr().String()) - r, err := c.ShardReader(123) - if err == nil || err.Error() != `shard not found: id=123` { - t.Fatalf("unexpected error: %s", err) - } else if r != nil { - t.Fatal("expected nil reader") - } -} - -// Service represents a test wrapper for copier.Service. -type Service struct { - *copier.Service - - ln net.Listener - TSDBStore ServiceTSDBStore -} - -// NewService returns a new instance of Service. -func NewService() *Service { - s := &Service{ - Service: copier.NewService(), - } - s.Service.TSDBStore = &s.TSDBStore - - if !testing.Verbose() { - s.SetLogger(log.New(ioutil.Discard, "", 0)) - } - return s -} - -// MustOpenService returns a new, opened service. Panic on error. -func MustOpenService() *Service { - // Open randomly assigned port. - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - panic(err) - } - - // Start muxer. - mux := tcp.NewMux() - - // Create new service and attach mux'd listener. - s := NewService() - s.ln = ln - s.Listener = mux.Listen(copier.MuxHeader) - go mux.Serve(ln) - - if err := s.Open(); err != nil { - panic(err) - } - - return s -} - -// Close shuts down the service and the attached listener. -func (s *Service) Close() error { - s.ln.Close() - err := s.Service.Close() - return err -} - -// Addr returns the address of the service. -func (s *Service) Addr() net.Addr { return s.ln.Addr() } - -// ServiceTSDBStore is a mock that implements copier.Service.TSDBStore. -type ServiceTSDBStore struct { - ShardFn func(id uint64) *tsdb.Shard -} - -func (ss *ServiceTSDBStore) Shard(id uint64) *tsdb.Shard { return ss.ShardFn(id) } - -// Shard is a test wrapper for tsdb.Shard. -type Shard struct { - *tsdb.Shard - path string -} - -// MustOpenShard returns a temporary, opened shard. -func MustOpenShard(id uint64) *Shard { - path, err := ioutil.TempDir("", "copier-") - if err != nil { - panic(err) - } - - sh := &Shard{ - Shard: tsdb.NewShard(id, - tsdb.NewDatabaseIndex(), - filepath.Join(path, "data"), - filepath.Join(path, "wal"), - tsdb.NewEngineOptions(), - ), - path: path, - } - if err := sh.Open(); err != nil { - sh.Close() - panic(err) - } - - return sh -} - -func (sh *Shard) Close() error { - err := sh.Shard.Close() - os.RemoveAll(sh.Path()) - return err -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/README.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/README.md index 664440bc1..318ef24c5 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/README.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/README.md @@ -1,10 +1,4 @@ -# Configuration - -Each Graphite input allows the binding address, target database, and protocol to be set. If the database does not exist, it will be created automatically when the input is initialized. The write-consistency-level can also be set. If any write operations do not meet the configured consistency guarantees, an error will occur and the data will not be indexed. The default consistency-level is `ONE`. - -Each Graphite input also performs internal batching of the points it receives, as batched writes to the database are more efficient. The default _batch size_ is 1000, _pending batch_ factor is 5, with a _batch timeout_ of 1 second. This means the input will write batches of maximum size 1000, but if a batch has not reached 1000 points within 1 second of the first point being added to a batch, it will emit that batch regardless of size. The pending batch factor controls how many batches can be in memory at once, allowing the input to transmit a batch, while still building other batches. - -# Parsing Metrics +## Introduction The graphite plugin allows measurements to be saved using the graphite line protocol. By default, enabling the graphite plugin will allow you to collect metrics and store them using the metric name as the measurement. If you send a metric named `servers.localhost.cpu.loadavg.10`, it will store the full metric name as the measurement with no extracted tags. @@ -46,7 +40,7 @@ Additional tags can be added to a metric that don't exist on the received metric `servers.localhost.cpu.loadavg.10` * Template: `.host.resource.measurement* region=us-west,zone=1a` -* Output: _measurement_ = `loadavg.10` _tags_ = `host=localhost resource=cpu region=us-west zone=1a` +* Output: _measurement_ = `loading.10` _tags_ = `host=localhost resource=cpu region=us-west zone=1a` ## Multiple Templates diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config.go index b7b5df149..298e5f7d1 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config.go @@ -29,9 +29,6 @@ const ( // DefaultBatchSize is the default Graphite batch size. DefaultBatchSize = 1000 - // DefaultBatchPending is the default number of pending Graphite batches. - DefaultBatchPending = 5 - // DefaultBatchTimeout is the default Graphite batch timeout. DefaultBatchTimeout = time.Second ) @@ -43,7 +40,6 @@ type Config struct { Enabled bool `toml:"enabled"` Protocol string `toml:"protocol"` BatchSize int `toml:"batch-size"` - BatchPending int `toml:"batch-pending"` BatchTimeout toml.Duration `toml:"batch-timeout"` ConsistencyLevel string `toml:"consistency-level"` Templates []string `toml:"templates"` @@ -51,6 +47,19 @@ type Config struct { Separator string `toml:"separator"` } +// NewConfig returns a new Config with defaults. +func NewConfig() Config { + return Config{ + BindAddress: DefaultBindAddress, + Database: DefaultDatabase, + Protocol: DefaultProtocol, + BatchSize: DefaultBatchSize, + BatchTimeout: toml.Duration(DefaultBatchTimeout), + ConsistencyLevel: DefaultConsistencyLevel, + Separator: DefaultSeparator, + } +} + // WithDefaults takes the given config and returns a new config with any required // default values set. func (c *Config) WithDefaults() *Config { @@ -64,15 +73,6 @@ func (c *Config) WithDefaults() *Config { if d.Protocol == "" { d.Protocol = DefaultProtocol } - if d.BatchSize == 0 { - d.BatchSize = DefaultBatchSize - } - if d.BatchPending == 0 { - d.BatchPending = DefaultBatchPending - } - if d.BatchTimeout == 0 { - d.BatchTimeout = toml.Duration(DefaultBatchTimeout) - } if d.ConsistencyLevel == "" { d.ConsistencyLevel = DefaultConsistencyLevel } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config_test.go index e9efc6466..635cf3909 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/config_test.go @@ -17,7 +17,6 @@ database = "mydb" enabled = true protocol = "tcp" batch-size=100 -batch-pending=77 batch-timeout="1s" consistency-level="one" templates=["servers.* .host.measurement*"] @@ -37,8 +36,6 @@ tags=["region=us-east"] t.Fatalf("unexpected graphite protocol: %s", c.Protocol) } else if c.BatchSize != 100 { t.Fatalf("unexpected graphite batch size: %d", c.BatchSize) - } else if c.BatchPending != 77 { - t.Fatalf("unexpected graphite batch pending: %d", c.BatchPending) } else if time.Duration(c.BatchTimeout) != time.Second { t.Fatalf("unexpected graphite batch timeout: %v", c.BatchTimeout) } else if c.ConsistencyLevel != "one" { @@ -54,7 +51,7 @@ tags=["region=us-east"] } func TestConfigValidateEmptyTemplate(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Templates = []string{""} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") @@ -67,7 +64,7 @@ func TestConfigValidateEmptyTemplate(t *testing.T) { } func TestConfigValidateTooManyField(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Templates = []string{"a measurement b c"} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") @@ -75,7 +72,7 @@ func TestConfigValidateTooManyField(t *testing.T) { } func TestConfigValidateTemplatePatterns(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Templates = []string{"*measurement"} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") @@ -88,7 +85,7 @@ func TestConfigValidateTemplatePatterns(t *testing.T) { } func TestConfigValidateFilter(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Templates = []string{".server measurement*"} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") @@ -106,7 +103,7 @@ func TestConfigValidateFilter(t *testing.T) { } func TestConfigValidateTemplateTags(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Templates = []string{"*.server measurement* foo"} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") @@ -129,7 +126,7 @@ func TestConfigValidateTemplateTags(t *testing.T) { } func TestConfigValidateDefaultTags(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Tags = []string{"foo"} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") @@ -152,7 +149,7 @@ func TestConfigValidateDefaultTags(t *testing.T) { } func TestConfigValidateFilterDuplicates(t *testing.T) { - c := &graphite.Config{} + c := graphite.NewConfig() c.Templates = []string{"foo measurement*", "foo .host.measurement"} if err := c.Validate(); err == nil { t.Errorf("config validate expected error. got nil") diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/parser.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/parser.go index 9d4f28b8c..4c685609e 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/parser.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/parser.go @@ -11,11 +11,7 @@ import ( "github.com/influxdb/influxdb/tsdb" ) -var ( - defaultTemplate *template - MinDate = time.Date(1901, 12, 13, 0, 0, 0, 0, time.UTC) - MaxDate = time.Date(2038, 1, 19, 0, 0, 0, 0, time.UTC) -) +var defaultTemplate *template func init() { var err error @@ -128,9 +124,6 @@ func (p *Parser) Parse(line string) (tsdb.Point, error) { if unixTime != float64(-1) { // Check if we have fractional seconds timestamp = time.Unix(int64(unixTime), int64((unixTime-math.Floor(unixTime))*float64(time.Second))) - if timestamp.Before(MinDate) || timestamp.After(MaxDate) { - return nil, fmt.Errorf("timestamp out of range") - } } } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service.go index 25db6f7ba..683c75811 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service.go @@ -2,7 +2,6 @@ package graphite import ( "bufio" - "expvar" "fmt" "log" "math" @@ -12,10 +11,8 @@ import ( "sync" "time" - "github.com/influxdb/influxdb" "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/meta" - "github.com/influxdb/influxdb/monitor" "github.com/influxdb/influxdb/tsdb" ) @@ -24,89 +21,25 @@ const ( leaderWaitTimeout = 30 * time.Second ) -// Initialize the graphite stats and diags -func init() { - tcpConnections = make(map[string]*tcpConnectionDiag) -} - -// Package-level tracking of connections for diagnostics. -var monitorOnce sync.Once - -type tcpConnectionDiag struct { - conn net.Conn - connectTime time.Time -} - -var tcpConnectionsMu sync.Mutex -var tcpConnections map[string]*tcpConnectionDiag - -func addConnection(c net.Conn) { - tcpConnectionsMu.Lock() - defer tcpConnectionsMu.Unlock() - tcpConnections[c.RemoteAddr().String()] = &tcpConnectionDiag{ - conn: c, - connectTime: time.Now().UTC(), - } -} -func removeConnection(c net.Conn) { - tcpConnectionsMu.Lock() - defer tcpConnectionsMu.Unlock() - delete(tcpConnections, c.RemoteAddr().String()) -} - -func handleDiagnostics() (*monitor.Diagnostic, error) { - tcpConnectionsMu.Lock() - defer tcpConnectionsMu.Unlock() - - d := &monitor.Diagnostic{ - Columns: []string{"local", "remote", "connect time"}, - Rows: make([][]interface{}, 0, len(tcpConnections)), - } - for _, v := range tcpConnections { - _ = v - d.Rows = append(d.Rows, []interface{}{v.conn.LocalAddr().String(), v.conn.RemoteAddr().String(), v.connectTime}) - } - return d, nil -} - -// statistics gathered by the graphite package. -const ( - statPointsReceived = "points_rx" - statBytesReceived = "bytes_rx" - statPointsParseFail = "points_parse_fail" - statPointsUnsupported = "points_unsupported_fail" - statBatchesTrasmitted = "batches_tx" - statPointsTransmitted = "points_tx" - statBatchesTransmitFail = "batches_tx_fail" - statConnectionsActive = "connections_active" - statConnectionsHandled = "connections_handled" -) - type Service struct { bindAddress string database string protocol string batchSize int - batchPending int batchTimeout time.Duration consistencyLevel cluster.ConsistencyLevel batcher *tsdb.PointBatcher parser *Parser - logger *log.Logger - statMap *expvar.Map + logger *log.Logger - ln net.Listener - addr net.Addr - udpConn *net.UDPConn + ln net.Listener + addr net.Addr wg sync.WaitGroup done chan struct{} - Monitor interface { - RegisterDiagnosticsClient(name string, client monitor.DiagsClient) error - } PointsWriter interface { WritePoints(p *cluster.WritePointsRequest) error } @@ -126,7 +59,6 @@ func NewService(c Config) (*Service, error) { database: d.Database, protocol: d.Protocol, batchSize: d.BatchSize, - batchPending: d.BatchPending, batchTimeout: time.Duration(d.BatchTimeout), logger: log.New(os.Stderr, "[graphite] ", log.LstdFlags), done: make(chan struct{}), @@ -155,21 +87,6 @@ func NewService(c Config) (*Service, error) { func (s *Service) Open() error { s.logger.Printf("Starting graphite service, batch size %d, batch timeout %s", s.batchSize, s.batchTimeout) - // Configure expvar monitoring. It's OK to do this even if the service fails to open and - // should be done before any data could arrive for the service. - key := strings.Join([]string{"graphite", s.protocol, s.bindAddress}, ":") - tags := map[string]string{"proto": s.protocol, "bind": s.bindAddress} - s.statMap = influxdb.NewStatistics(key, "graphite", tags) - - // One Graphite service hooks up diagnostics for all Graphite functionality. - monitorOnce.Do(func() { - if s.Monitor == nil { - s.logger.Println("no monitor service available, no monitoring will be performed") - return - } - s.Monitor.RegisterDiagnosticsClient("graphite", monitor.DiagsClientFunc(handleDiagnostics)) - }) - if err := s.MetaStore.WaitForLeader(leaderWaitTimeout); err != nil { s.logger.Printf("Failed to detect a cluster leader: %s", err.Error()) return err @@ -180,7 +97,7 @@ func (s *Service) Open() error { return err } - s.batcher = tsdb.NewPointBatcher(s.batchSize, s.batchPending, s.batchTimeout) + s.batcher = tsdb.NewPointBatcher(s.batchSize, s.batchTimeout) s.batcher.Start() // Start processing batches. @@ -208,9 +125,6 @@ func (s *Service) Close() error { if s.ln != nil { s.ln.Close() } - if s.udpConn != nil { - s.udpConn.Close() - } s.batcher.Stop() close(s.done) @@ -260,13 +174,8 @@ func (s *Service) openTCPServer() (net.Addr, error) { // handleTCPConnection services an individual TCP connection for the Graphite input. func (s *Service) handleTCPConnection(conn net.Conn) { - defer s.wg.Done() defer conn.Close() - defer removeConnection(conn) - defer s.statMap.Add(statConnectionsActive, -1) - addConnection(conn) - s.statMap.Add(statConnectionsActive, 1) - s.statMap.Add(statConnectionsHandled, 1) + defer s.wg.Done() reader := bufio.NewReader(conn) @@ -280,8 +189,6 @@ func (s *Service) handleTCPConnection(conn net.Conn) { // Trim the buffer, even though there should be no padding line := strings.TrimSpace(string(buf)) - s.statMap.Add(statPointsReceived, 1) - s.statMap.Add(statBytesReceived, int64(len(buf))) s.handleLine(line) } } @@ -293,7 +200,7 @@ func (s *Service) openUDPServer() (net.Addr, error) { return nil, err } - s.udpConn, err = net.ListenUDP("udp", addr) + conn, err := net.ListenUDP("udp", addr) if err != nil { return nil, err } @@ -303,33 +210,27 @@ func (s *Service) openUDPServer() (net.Addr, error) { go func() { defer s.wg.Done() for { - n, _, err := s.udpConn.ReadFromUDP(buf) + n, _, err := conn.ReadFromUDP(buf) if err != nil { - s.udpConn.Close() + conn.Close() return } - - lines := strings.Split(string(buf[:n]), "\n") - for _, line := range lines { + for _, line := range strings.Split(string(buf[:n]), "\n") { s.handleLine(line) } - s.statMap.Add(statPointsReceived, int64(len(lines))) - s.statMap.Add(statBytesReceived, int64(n)) } }() - return s.udpConn.LocalAddr(), nil + return conn.LocalAddr(), nil } func (s *Service) handleLine(line string) { if line == "" { return } - // Parse it. point, err := s.parser.Parse(line) if err != nil { s.logger.Printf("unable to parse line: %s", err) - s.statMap.Add(statPointsParseFail, 1) return } @@ -338,7 +239,6 @@ func (s *Service) handleLine(line string) { // Drop NaN and +/-Inf data points since they are not supported values if math.IsNaN(f) || math.IsInf(f, 0) { s.logger.Printf("dropping unsupported value: '%v'", line) - s.statMap.Add(statPointsUnsupported, 1) return } } @@ -357,14 +257,9 @@ func (s *Service) processBatches(batcher *tsdb.PointBatcher) { RetentionPolicy: "", ConsistencyLevel: s.consistencyLevel, Points: batch, - }); err == nil { - s.statMap.Add(statBatchesTrasmitted, 1) - s.statMap.Add(statPointsTransmitted, int64(len(batch))) - } else { + }); err != nil { s.logger.Printf("failed to write point batch to database %q: %s", s.database, err) - s.statMap.Add(statBatchesTransmitFail, 1) } - case <-s.done: return } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service_test.go index f041dfd95..b7e59c492 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/graphite/service_test.go @@ -19,7 +19,7 @@ func Test_ServerGraphiteTCP(t *testing.T) { now := time.Now().UTC().Round(time.Second) - config := graphite.Config{} + config := graphite.NewConfig() config.Database = "graphitedb" config.BatchSize = 0 // No batching. config.BatchTimeout = toml.Duration(time.Second) @@ -87,7 +87,7 @@ func Test_ServerGraphiteUDP(t *testing.T) { now := time.Now().UTC().Round(time.Second) - config := graphite.Config{} + config := graphite.NewConfig() config.Database = "graphitedb" config.BatchSize = 0 // No batching. config.BatchTimeout = toml.Duration(time.Second) diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler.go index 3e6042b63..61684d6f7 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler.go @@ -5,7 +5,6 @@ import ( "compress/gzip" "encoding/json" "errors" - "expvar" "fmt" "io" "io/ioutil" @@ -74,18 +73,16 @@ type Handler struct { Logger *log.Logger loggingEnabled bool // Log every HTTP access. WriteTrace bool // Detailed logging of write path - statMap *expvar.Map } // NewHandler returns a new instance of handler with routes. -func NewHandler(requireAuthentication, loggingEnabled, writeTrace bool, statMap *expvar.Map) *Handler { +func NewHandler(requireAuthentication, loggingEnabled, writeTrace bool) *Handler { h := &Handler{ mux: pat.New(), requireAuthentication: requireAuthentication, Logger: log.New(os.Stderr, "[http] ", log.LstdFlags), loggingEnabled: loggingEnabled, WriteTrace: writeTrace, - statMap: statMap, } h.SetRoutes([]route{ @@ -152,8 +149,6 @@ func (h *Handler) SetRoutes(routes []route) { // ServeHTTP responds to HTTP request to the handler. func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - h.statMap.Add(statRequest, 1) - // FIXME(benbjohnson): Add pprof enabled flag. if strings.HasPrefix(r.URL.Path, "/debug/pprof") { switch r.URL.Path { @@ -166,16 +161,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { default: pprof.Index(w, r) } - } else if strings.HasPrefix(r.URL.Path, "/debug/vars") { - serveExpvar(w, r) - } else { - h.mux.ServeHTTP(w, r) + return } + + h.mux.ServeHTTP(w, r) } func (h *Handler) serveProcessContinuousQueries(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) { - h.statMap.Add(statCQRequest, 1) - // If the continuous query service isn't configured, return 404. if h.ContinuousQuerier == nil { w.WriteHeader(http.StatusNotImplemented) @@ -188,25 +180,9 @@ func (h *Handler) serveProcessContinuousQueries(w http.ResponseWriter, r *http.R db := q.Get("db") // Get the name of the CQ to run (blank means run all). name := q.Get("name") - // Get the time for which the CQ should be evaluated. - var t time.Time - var err error - s := q.Get("time") - if s != "" { - t, err = time.Parse(time.RFC3339Nano, s) - if err != nil { - // Try parsing as an int64 nanosecond timestamp. - i, err := strconv.ParseInt(s, 10, 64) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - return - } - t = time.Unix(0, i) - } - } // Pass the request to the CQ service. - if err := h.ContinuousQuerier.Run(db, name, t); err != nil { + if err := h.ContinuousQuerier.Run(db, name); err != nil { w.WriteHeader(http.StatusBadRequest) return } @@ -216,8 +192,6 @@ func (h *Handler) serveProcessContinuousQueries(w http.ResponseWriter, r *http.R // serveQuery parses an incoming query and, if valid, executes the query. func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) { - h.statMap.Add(statQueryRequest, 1) - q := r.URL.Query() pretty := q.Get("pretty") == "true" @@ -296,10 +270,9 @@ func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta. // Write out result immediately if chunked. if chunked { - n, _ := w.Write(MarshalJSON(Response{ + w.Write(MarshalJSON(Response{ Results: []*influxql.Result{r}, }, pretty)) - h.statMap.Add(statQueryRequestBytesTransmitted, int64(n)) w.(http.Flusher).Flush() continue } @@ -336,13 +309,11 @@ func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user *meta. // If it's not chunked we buffered everything in memory, so write it out if !chunked { - n, _ := w.Write(MarshalJSON(resp, pretty)) - h.statMap.Add(statQueryRequestBytesTransmitted, int64(n)) + w.Write(MarshalJSON(resp, pretty)) } } func (h *Handler) serveWrite(w http.ResponseWriter, r *http.Request, user *meta.UserInfo) { - h.statMap.Add(statWriteRequest, 1) // Handle gzip decoding of the body body := r.Body @@ -364,7 +335,6 @@ func (h *Handler) serveWrite(w http.ResponseWriter, r *http.Request, user *meta. h.writeError(w, influxql.Result{Err: err}, http.StatusBadRequest) return } - h.statMap.Add(statWriteRequestBytesReceived, int64(len(b))) if h.WriteTrace { h.Logger.Printf("write body received by handler: %s", string(b)) } @@ -427,16 +397,13 @@ func (h *Handler) serveWriteJSON(w http.ResponseWriter, r *http.Request, body [] RetentionPolicy: bp.RetentionPolicy, ConsistencyLevel: cluster.ConsistencyLevelOne, Points: points, - }); err != nil { - h.statMap.Add(statPointsWrittenFail, int64(len(points))) - if influxdb.IsClientError(err) { - h.writeError(w, influxql.Result{Err: err}, http.StatusBadRequest) - } else { - h.writeError(w, influxql.Result{Err: err}, http.StatusInternalServerError) - } + }); influxdb.IsClientError(err) { + resultError(w, influxql.Result{Err: err}, http.StatusBadRequest) + return + } else if err != nil { + resultError(w, influxql.Result{Err: err}, http.StatusInternalServerError) return } - h.statMap.Add(statPointsWrittenOK, int64(len(points))) w.WriteHeader(http.StatusNoContent) } @@ -527,16 +494,13 @@ func (h *Handler) serveWriteLine(w http.ResponseWriter, r *http.Request, body [] ConsistencyLevel: consistency, Points: points, }); influxdb.IsClientError(err) { - h.statMap.Add(statPointsWrittenFail, int64(len(points))) h.writeError(w, influxql.Result{Err: err}, http.StatusBadRequest) return } else if err != nil { - h.statMap.Add(statPointsWrittenFail, int64(len(points))) h.writeError(w, influxql.Result{Err: err}, http.StatusInternalServerError) return } - h.statMap.Add(statPointsWrittenOK, int64(len(points))) w.WriteHeader(http.StatusNoContent) } @@ -547,7 +511,6 @@ func (h *Handler) serveOptions(w http.ResponseWriter, r *http.Request) { // servePing returns a simple response to let the client know the server is running. func (h *Handler) servePing(w http.ResponseWriter, r *http.Request) { - h.statMap.Add(statPingRequest, 1) w.WriteHeader(http.StatusNoContent) } @@ -606,21 +569,6 @@ type Batch struct { Points []Point `json:"points"` } -// serveExpvar serves registered expvar information over HTTP. -func serveExpvar(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=utf-8") - fmt.Fprintf(w, "{\n") - first := true - expvar.Do(func(kv expvar.KeyValue) { - if !first { - fmt.Fprintf(w, ",\n") - } - first = false - fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) - }) - fmt.Fprintf(w, "\n}\n") -} - // httpError writes an error to the client in a standard format. func httpError(w http.ResponseWriter, error string, pretty bool, code int) { w.Header().Add("content-type", "application/json") @@ -686,19 +634,16 @@ func authenticate(inner func(http.ResponseWriter, *http.Request, *meta.UserInfo) if requireAuthentication && len(uis) > 0 { username, password, err := parseCredentials(r) if err != nil { - h.statMap.Add(statAuthFail, 1) httpError(w, err.Error(), false, http.StatusUnauthorized) return } if username == "" { - h.statMap.Add(statAuthFail, 1) httpError(w, "username required", false, http.StatusUnauthorized) return } user, err = h.MetaStore.Authenticate(username, password) if err != nil { - h.statMap.Add(statAuthFail, 1) httpError(w, err.Error(), false, http.StatusUnauthorized) return } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler_test.go index c945d1223..228b3bf77 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/handler_test.go @@ -12,7 +12,6 @@ import ( "testing" "time" - "github.com/influxdb/influxdb" "github.com/influxdb/influxdb/client" "github.com/influxdb/influxdb/influxql" "github.com/influxdb/influxdb/meta" @@ -366,9 +365,8 @@ type Handler struct { // NewHandler returns a new instance of Handler. func NewHandler(requireAuthentication bool) *Handler { - statMap := influxdb.NewStatistics("httpd", "httpd", nil) h := &Handler{ - Handler: httpd.NewHandler(requireAuthentication, true, false, statMap), + Handler: httpd.NewHandler(requireAuthentication, true, false), } h.Handler.MetaStore = &h.MetaStore h.Handler.QueryExecutor = &h.QueryExecutor diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/service.go index 6e0db0bfc..7ada11e76 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/httpd/service.go @@ -2,29 +2,12 @@ package httpd import ( "crypto/tls" - "expvar" "fmt" "log" "net" "net/http" "os" "strings" - - "github.com/influxdb/influxdb" -) - -// statistics gathered by the httpd package. -const ( - statRequest = "req" // Number of HTTP requests served - statCQRequest = "cq_req" // Number of CQ-execute requests served - statQueryRequest = "query_req" // Number of query requests served - statWriteRequest = "write_req" // Number of write requests serverd - statPingRequest = "ping_req" // Number of ping requests served - statWriteRequestBytesReceived = "write_req_bytes" // Sum of all bytes in write requests - statQueryRequestBytesTransmitted = "query_resp_bytes" // Sum of all bytes returned in query reponses - statPointsWrittenOK = "points_written_ok" // Number of points written OK - statPointsWrittenFail = "points_written_fail" // Number of points that failed to be written - statAuthFail = "auth_fail" // Number of authentication failures ) // Service manages the listener and handler for an HTTP endpoint. @@ -37,18 +20,11 @@ type Service struct { Handler *Handler - Logger *log.Logger - statMap *expvar.Map + Logger *log.Logger } // NewService returns a new instance of Service. func NewService(c Config) *Service { - // Configure expvar monitoring. It's OK to do this even if the service fails to open and - // should be done before any data could arrive for the service. - key := strings.Join([]string{"httpd", c.BindAddress}, ":") - tags := map[string]string{"bind": c.BindAddress} - statMap := influxdb.NewStatistics(key, "httpd", tags) - s := &Service{ addr: c.BindAddress, https: c.HttpsEnabled, @@ -58,7 +34,6 @@ func NewService(c Config) *Service { c.AuthEnabled, c.LogEnabled, c.WriteTracing, - statMap, ), Logger: log.New(os.Stderr, "[httpd] ", log.LstdFlags), } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/config.go new file mode 100644 index 000000000..1e3798700 --- /dev/null +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/config.go @@ -0,0 +1,25 @@ +package monitor + +import ( + "time" + + "github.com/influxdb/influxdb/toml" +) + +const ( + // DefaultStatisticsWriteInterval is the interval of time between internal stats are written + DefaultStatisticsWriteInterval = 1 * time.Minute +) + +// Config represents a configuration for the monitor. +type Config struct { + Enabled bool `toml:"enabled"` + WriteInterval toml.Duration `toml:"write-interval"` +} + +func NewConfig() Config { + return Config{ + Enabled: false, + WriteInterval: toml.Duration(DefaultStatisticsWriteInterval), + } +} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/monitor.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/monitor.go new file mode 100644 index 000000000..2568e6eb1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/monitor/monitor.go @@ -0,0 +1,83 @@ +package monitor + +// Monitor represents a TSDB monitoring service. +type Monitor struct { + Store interface{} +} + +func (m *Monitor) Open() error { return nil } +func (m *Monitor) Close() error { return nil } + +// StartSelfMonitoring starts a goroutine which monitors the InfluxDB server +// itself and stores the results in the specified database at a given interval. +/* +func (s *Server) StartSelfMonitoring(database, retention string, interval time.Duration) error { + if interval == 0 { + return fmt.Errorf("statistics check interval must be non-zero") + } + + go func() { + tick := time.NewTicker(interval) + for { + <-tick.C + + // Create the batch and tags + tags := map[string]string{"serverID": strconv.FormatUint(s.ID(), 10)} + if h, err := os.Hostname(); err == nil { + tags["host"] = h + } + batch := pointsFromStats(s.stats, tags) + + // Shard-level stats. + tags["shardID"] = strconv.FormatUint(s.id, 10) + s.mu.RLock() + for _, sh := range s.shards { + if !sh.HasDataNodeID(s.id) { + // No stats for non-local shards. + continue + } + batch = append(batch, pointsFromStats(sh.stats, tags)...) + } + s.mu.RUnlock() + + // Server diagnostics. + for _, row := range s.DiagnosticsAsRows() { + points, err := s.convertRowToPoints(row.Name, row) + if err != nil { + s.Logger.Printf("failed to write diagnostic row for %s: %s", row.Name, err.Error()) + continue + } + for _, p := range points { + p.AddTag("serverID", strconv.FormatUint(s.ID(), 10)) + } + batch = append(batch, points...) + } + + s.WriteSeries(database, retention, batch) + } + }() + return nil +} + +// Function for local use turns stats into a slice of points +func pointsFromStats(st *Stats, tags map[string]string) []tsdb.Point { + var points []tsdb.Point + now := time.Now() + st.Walk(func(k string, v int64) { + point := tsdb.NewPoint( + st.name+"_"+k, + make(map[string]string), + map[string]interface{}{"value": int(v)}, + now, + ) + // Specifically create a new map. + for k, v := range tags { + tags[k] = v + point.AddTag(k, v) + } + points = append(points, point) + }) + + return points +} +*/ diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/README.md b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/README.md index fe84a3065..033a194ae 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/README.md +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/README.md @@ -6,5 +6,3 @@ InfluxDB supports both the telnet and HTTP openTSDB protocol. This means that In The openTSDB input allows the binding address, target database, and target retention policy within that database, to be set. If the database does not exist, it will be created automatically when the input is initialized. If you also decide to configure retention policy (without configuration the input will use the auto-created default retention policy), both the database and retention policy must already exist. The write-consistency-level can also be set. If any write operations do not meet the configured consistency guarantees, an error will occur and the data will not be indexed. The default consistency-level is `ONE`. - -The openTSDB input also performs internal batching of the points it receives, as batched writes to the database are more efficient. The default _batch size_ is 1000, _pending batch_ factor is 5, with a _batch timeout_ of 1 second. This means the input will write batches of maximum size 1000, but if a batch has not reached 1000 points within 1 second of the first point being added to a batch, it will emit that batch regardless of size. The pending batch factor controls how many batches can be in memory at once, allowing the input to transmit a batch, while still building other batches. diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/config.go index 5c17ba675..35d379581 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/config.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/config.go @@ -1,11 +1,5 @@ package opentsdb -import ( - "time" - - "github.com/influxdb/influxdb/toml" -) - const ( // DefaultBindAddress is the default address that the service binds to. DefaultBindAddress = ":4242" @@ -18,28 +12,16 @@ const ( // DefaultConsistencyLevel is the default write consistency level. DefaultConsistencyLevel = "one" - - // DefaultBatchSize is the default Graphite batch size. - DefaultBatchSize = 1000 - - // DefaultBatchTimeout is the default Graphite batch timeout. - DefaultBatchTimeout = time.Second - - // DefaultBatchPending is the default number of batches that can be in the queue. - DefaultBatchPending = 5 ) type Config struct { - Enabled bool `toml:"enabled"` - BindAddress string `toml:"bind-address"` - Database string `toml:"database"` - RetentionPolicy string `toml:"retention-policy"` - ConsistencyLevel string `toml:"consistency-level"` - TLSEnabled bool `toml:"tls-enabled"` - Certificate string `toml:"certificate"` - BatchSize int `toml:"batch-size"` - BatchPending int `toml:"batch-pending"` - BatchTimeout toml.Duration `toml:"batch-timeout"` + Enabled bool `toml:"enabled"` + BindAddress string `toml:"bind-address"` + Database string `toml:"database"` + RetentionPolicy string `toml:"retention-policy"` + ConsistencyLevel string `toml:"consistency-level"` + TLSEnabled bool `toml:"tls-enabled"` + Certificate string `toml:"certificate"` } func NewConfig() Config { @@ -50,8 +32,5 @@ func NewConfig() Config { ConsistencyLevel: DefaultConsistencyLevel, TLSEnabled: false, Certificate: "/etc/ssl/influxdb.pem", - BatchSize: DefaultBatchSize, - BatchPending: DefaultBatchPending, - BatchTimeout: toml.Duration(DefaultBatchTimeout), } } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/service.go index dba6800a5..3179adb57 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/opentsdb/service.go @@ -4,7 +4,6 @@ import ( "bufio" "bytes" "crypto/tls" - "expvar" "io" "log" "net" @@ -16,7 +15,6 @@ import ( "sync" "time" - "github.com/influxdb/influxdb" "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/meta" "github.com/influxdb/influxdb/tsdb" @@ -24,32 +22,12 @@ import ( const leaderWaitTimeout = 30 * time.Second -// statistics gathered by the openTSDB package. -const ( - statHTTPConnectionsHandled = "http_connections_handled" - statTelnetConnectionsActive = "tl_connections_active" - statTelnetConnectionsHandled = "tl_connections_handled" - statTelnetPointsReceived = "tl_points_rx" - statTelnetBytesReceived = "tl_bytes_rx" - statTelnetReadError = "tl_read_err" - statTelnetBadLine = "tl_bad_line" - statTelnetBadTime = "tl_bad_time" - statTelnetBadTag = "tl_bad_tag" - statTelnetBadFloat = "tl_bad_float" - statBatchesTrasmitted = "batches_tx" - statPointsTransmitted = "points_tx" - statBatchesTransmitFail = "batches_tx_fail" - statConnectionsActive = "connections_active" - statConnectionsHandled = "connections_handled" -) - // Service manages the listener and handler for an HTTP endpoint. type Service struct { ln net.Listener // main listener httpln *chanListener // http channel-based listener wg sync.WaitGroup - done chan struct{} err chan error tls bool cert string @@ -67,14 +45,7 @@ type Service struct { CreateDatabaseIfNotExists(name string) (*meta.DatabaseInfo, error) } - // Points received over the telnet protocol are batched. - batchSize int - batchPending int - batchTimeout time.Duration - batcher *tsdb.PointBatcher - - Logger *log.Logger - statMap *expvar.Map + Logger *log.Logger } // NewService returns a new instance of Service. @@ -85,7 +56,6 @@ func NewService(c Config) (*Service, error) { } s := &Service{ - done: make(chan struct{}), tls: c.TLSEnabled, cert: c.Certificate, err: make(chan error), @@ -93,9 +63,6 @@ func NewService(c Config) (*Service, error) { Database: c.Database, RetentionPolicy: c.RetentionPolicy, ConsistencyLevel: consistencyLevel, - batchSize: c.BatchSize, - batchPending: c.BatchPending, - batchTimeout: time.Duration(c.BatchTimeout), Logger: log.New(os.Stderr, "[opentsdb] ", log.LstdFlags), } return s, nil @@ -105,12 +72,6 @@ func NewService(c Config) (*Service, error) { func (s *Service) Open() error { s.Logger.Println("Starting OpenTSDB service") - // Configure expvar monitoring. It's OK to do this even if the service fails to open and - // should be done before any data could arrive for the service. - key := strings.Join([]string{"opentsdb", s.BindAddress}, ":") - tags := map[string]string{"bind": s.BindAddress} - s.statMap = influxdb.NewStatistics(key, "opentsdb", tags) - if err := s.MetaStore.WaitForLeader(leaderWaitTimeout); err != nil { s.Logger.Printf("Failed to detect a cluster leader: %s", err.Error()) return err @@ -121,13 +82,6 @@ func (s *Service) Open() error { return err } - s.batcher = tsdb.NewPointBatcher(s.batchSize, s.batchPending, s.batchTimeout) - s.batcher.Start() - - // Start processing batches. - s.wg.Add(1) - go s.processBatches(s.batcher) - // Open listener. if s.tls { cert, err := tls.LoadX509KeyPair(s.cert, s.cert) @@ -169,8 +123,6 @@ func (s *Service) Close() error { return s.ln.Close() } - s.batcher.Stop() - close(s.done) s.wg.Wait() return nil } @@ -211,10 +163,6 @@ func (s *Service) serve() { // handleConn processes conn. This is run in a separate goroutine. func (s *Service) handleConn(conn net.Conn) { - defer s.statMap.Add(statConnectionsActive, -1) - s.statMap.Add(statConnectionsActive, 1) - s.statMap.Add(statConnectionsHandled, 1) - // Read header into buffer to check if it's HTTP. var buf bytes.Buffer r := bufio.NewReader(io.TeeReader(conn, &buf)) @@ -228,7 +176,6 @@ func (s *Service) handleConn(conn net.Conn) { // If no HTTP parsing error occurred then process as HTTP. if err == nil { - s.statMap.Add(statHTTPConnectionsHandled, 1) s.httpln.ch <- conn return } @@ -244,26 +191,15 @@ func (s *Service) handleConn(conn net.Conn) { func (s *Service) handleTelnetConn(conn net.Conn) { defer conn.Close() defer s.wg.Done() - defer s.statMap.Add(statTelnetConnectionsActive, -1) - s.statMap.Add(statTelnetConnectionsActive, 1) - s.statMap.Add(statTelnetConnectionsHandled, 1) - - // Get connection details. - remoteAddr := conn.RemoteAddr().String() // Wrap connection in a text protocol reader. r := textproto.NewReader(bufio.NewReader(conn)) for { line, err := r.ReadLine() if err != nil { - if err != io.EOF { - s.statMap.Add(statTelnetReadError, 1) - s.Logger.Println("error reading from openTSDB connection", err.Error()) - } + s.Logger.Println("error reading from openTSDB connection", err.Error()) return } - s.statMap.Add(statTelnetPointsReceived, 1) - s.statMap.Add(statTelnetBytesReceived, int64(len(line))) inputStrs := strings.Fields(line) @@ -273,8 +209,7 @@ func (s *Service) handleTelnetConn(conn net.Conn) { } if len(inputStrs) < 4 || inputStrs[0] != "put" { - s.statMap.Add(statTelnetBadLine, 1) - s.Logger.Printf("malformed line '%s' from %s", line, remoteAddr) + s.Logger.Println("TSDBServer: malformed line, skipping: ", line) continue } @@ -286,8 +221,7 @@ func (s *Service) handleTelnetConn(conn net.Conn) { var t time.Time ts, err := strconv.ParseInt(tsStr, 10, 64) if err != nil { - s.statMap.Add(statTelnetBadTime, 1) - s.Logger.Printf("malformed time '%s' from %s", tsStr, remoteAddr) + s.Logger.Println("TSDBServer: malformed time, skipping: ", tsStr) } switch len(tsStr) { @@ -298,8 +232,7 @@ func (s *Service) handleTelnetConn(conn net.Conn) { t = time.Unix(ts/1000, (ts%1000)*1000) break default: - s.statMap.Add(statTelnetBadTime, 1) - s.Logger.Printf("bad time '%s' must be 10 or 13 chars, from %s ", tsStr, remoteAddr) + s.Logger.Println("TSDBServer: time must be 10 or 13 chars, skipping: ", tsStr) continue } @@ -307,8 +240,7 @@ func (s *Service) handleTelnetConn(conn net.Conn) { for t := range tagStrs { parts := strings.SplitN(tagStrs[t], "=", 2) if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - s.statMap.Add(statTelnetBadTag, 1) - s.Logger.Printf("malformed tag data '%v' from %s", tagStrs[t], remoteAddr) + s.Logger.Println("TSDBServer: malformed tag data", tagStrs[t]) continue } k := parts[0] @@ -319,12 +251,20 @@ func (s *Service) handleTelnetConn(conn net.Conn) { fields := make(map[string]interface{}) fields["value"], err = strconv.ParseFloat(valueStr, 64) if err != nil { - s.statMap.Add(statTelnetBadFloat, 1) - s.Logger.Printf("bad float '%s' from %s", valueStr, remoteAddr) + s.Logger.Println("TSDBServer: could not parse value as float: ", valueStr) continue } - s.batcher.In() <- tsdb.NewPoint(measurement, tags, fields, t) + p := tsdb.NewPoint(measurement, tags, fields, t) + if err := s.PointsWriter.WritePoints(&cluster.WritePointsRequest{ + Database: s.Database, + RetentionPolicy: s.RetentionPolicy, + ConsistencyLevel: s.ConsistencyLevel, + Points: []tsdb.Point{p}, + }); err != nil { + s.Logger.Println("TSDB cannot write data: ", err) + continue + } } } @@ -339,28 +279,3 @@ func (s *Service) serveHTTP() { }} srv.Serve(s.httpln) } - -// processBatches continually drains the given batcher and writes the batches to the database. -func (s *Service) processBatches(batcher *tsdb.PointBatcher) { - defer s.wg.Done() - for { - select { - case batch := <-batcher.Out(): - if err := s.PointsWriter.WritePoints(&cluster.WritePointsRequest{ - Database: s.Database, - RetentionPolicy: s.RetentionPolicy, - ConsistencyLevel: s.ConsistencyLevel, - Points: batch, - }); err == nil { - s.statMap.Add(statBatchesTrasmitted, 1) - s.statMap.Add(statPointsTransmitted, int64(len(batch))) - } else { - s.Logger.Printf("failed to write point batch to database %q: %s", s.Database, err) - s.statMap.Add(statBatchesTransmitFail, 1) - } - - case <-s.done: - return - } - } -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service.go index 9643a3ea2..180b5ec9a 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service.go @@ -18,7 +18,7 @@ type Service struct { MetaStore interface { IsLeader() bool - PrecreateShardGroups(now, cutoff time.Time) error + PrecreateShardGroups(cutoff time.Time) error } } @@ -91,9 +91,9 @@ func (s *Service) runPrecreation() { } // precreate performs actual resource precreation. -func (s *Service) precreate(now time.Time) error { - cutoff := now.Add(s.advancePeriod).UTC() - if err := s.MetaStore.PrecreateShardGroups(now, cutoff); err != nil { +func (s *Service) precreate(t time.Time) error { + cutoff := t.Add(s.advancePeriod).UTC() + if err := s.MetaStore.PrecreateShardGroups(cutoff); err != nil { return err } return nil diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service_test.go index d8667ba4c..da73a7ea6 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/precreator/service_test.go @@ -18,7 +18,7 @@ func Test_ShardPrecreation(t *testing.T) { var wg sync.WaitGroup wg.Add(1) ms := metaStore{ - PrecreateShardGroupsFn: func(v, u time.Time) error { + PrecreateShardGroupsFn: func(u time.Time) error { wg.Done() if u != now.Add(advancePeriod) { t.Fatalf("precreation called with wrong time, got %s, exp %s", u, now) @@ -47,13 +47,13 @@ func Test_ShardPrecreation(t *testing.T) { // PointsWriter represents a mock impl of PointsWriter. type metaStore struct { - PrecreateShardGroupsFn func(now, cutoff time.Time) error + PrecreateShardGroupsFn func(cutoff time.Time) error } func (m metaStore) IsLeader() bool { return true } -func (m metaStore) PrecreateShardGroups(now, cutoff time.Time) error { - return m.PrecreateShardGroupsFn(now, cutoff) +func (m metaStore) PrecreateShardGroups(timestamp time.Time) error { + return m.PrecreateShardGroupsFn(timestamp) } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/config.go index 10822fccd..4a5d598cb 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/config.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/config.go @@ -12,5 +12,5 @@ type Config struct { } func NewConfig() Config { - return Config{Enabled: true, CheckInterval: toml.Duration(30 * time.Minute)} + return Config{Enabled: true, CheckInterval: toml.Duration(10 * time.Minute)} } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/service.go index a7096af9d..295b0578e 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/retention/service.go @@ -40,7 +40,7 @@ func NewService(c Config) *Service { // Open starts retention policy enforcement. func (s *Service) Open() error { - s.logger.Println("Starting retention policy enforcement service with check interval of", s.checkInterval) + s.logger.Println("Starting rentention policy enforcement service") s.wg.Add(2) go s.deleteShardGroups() go s.deleteShards() diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config.go index 2cb16ae6c..0e5a2b1b0 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config.go @@ -1,21 +1,6 @@ package udp -import ( - "time" - - "github.com/influxdb/influxdb/toml" -) - -const ( - // DefaultBatchSize is the default UDP batch size. - DefaultBatchSize = 1000 - - // DefaultBatchPending is the default number of pending UDP batches. - DefaultBatchPending = 5 - - // DefaultBatchTimeout is the default UDP batch timeout. - DefaultBatchTimeout = time.Second -) +import "github.com/influxdb/influxdb/toml" type Config struct { Enabled bool `toml:"enabled"` @@ -23,22 +8,5 @@ type Config struct { Database string `toml:"database"` BatchSize int `toml:"batch-size"` - BatchPending int `toml:"batch-pending"` BatchTimeout toml.Duration `toml:"batch-timeout"` } - -// WithDefaults takes the given config and returns a new config with any required -// default values set. -func (c *Config) WithDefaults() *Config { - d := *c - if d.BatchSize == 0 { - d.BatchSize = DefaultBatchSize - } - if d.BatchPending == 0 { - d.BatchPending = DefaultBatchPending - } - if d.BatchTimeout == 0 { - d.BatchTimeout = toml.Duration(DefaultBatchTimeout) - } - return &d -} diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config_test.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config_test.go index cbec79f5a..d094c74c9 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config_test.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/config_test.go @@ -16,7 +16,6 @@ enabled = true bind-address = ":4444" database = "awesomedb" batch-size = 100 -batch-pending = 9 batch-timeout = "10ms" `, &c); err != nil { t.Fatal(err) @@ -31,8 +30,6 @@ batch-timeout = "10ms" t.Fatalf("unexpected database: %s", c.Database) } else if c.BatchSize != 100 { t.Fatalf("unexpected batch size: %d", c.BatchSize) - } else if c.BatchPending != 9 { - t.Fatalf("unexpected batch pending: %d", c.BatchPending) } else if time.Duration(c.BatchTimeout) != (10 * time.Millisecond) { t.Fatalf("unexpected batch timeout: %v", c.BatchTimeout) } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/service.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/service.go index cf0dfe94b..04568ddda 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/service.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/services/udp/service.go @@ -2,15 +2,12 @@ package udp import ( "errors" - "expvar" "log" "net" "os" - "strings" "sync" "time" - "github.com/influxdb/influxdb" "github.com/influxdb/influxdb/cluster" "github.com/influxdb/influxdb/tsdb" ) @@ -19,17 +16,6 @@ const ( UDPBufferSize = 65536 ) -// statistics gathered by the UDP package. -const ( - statPointsReceived = "points_rx" - statBytesReceived = "bytes_rx" - statPointsParseFail = "points_parse_fail" - statReadFail = "read_fail" - statBatchesTrasmitted = "batches_tx" - statPointsTransmitted = "points_tx" - statBatchesTransmitFail = "batches_tx_fail" -) - // // Service represents here an UDP service // that will listen for incoming packets @@ -48,27 +34,19 @@ type Service struct { WritePoints(p *cluster.WritePointsRequest) error } - Logger *log.Logger - statMap *expvar.Map + Logger *log.Logger } func NewService(c Config) *Service { - d := *c.WithDefaults() return &Service{ - config: d, + config: c, done: make(chan struct{}), - batcher: tsdb.NewPointBatcher(d.BatchSize, d.BatchPending, time.Duration(d.BatchTimeout)), + batcher: tsdb.NewPointBatcher(c.BatchSize, time.Duration(c.BatchTimeout)), Logger: log.New(os.Stderr, "[udp] ", log.LstdFlags), } } func (s *Service) Open() (err error) { - // Configure expvar monitoring. It's OK to do this even if the service fails to open and - // should be done before any data could arrive for the service. - key := strings.Join([]string{"udp", s.config.BindAddress}, ":") - tags := map[string]string{"bind": s.config.BindAddress} - s.statMap = influxdb.NewStatistics(key, "udp", tags) - if s.config.BindAddress == "" { return errors.New("bind address has to be specified in config") } @@ -103,17 +81,14 @@ func (s *Service) writePoints() { for { select { case batch := <-s.batcher.Out(): - if err := s.PointsWriter.WritePoints(&cluster.WritePointsRequest{ + err := s.PointsWriter.WritePoints(&cluster.WritePointsRequest{ Database: s.config.Database, RetentionPolicy: "", ConsistencyLevel: cluster.ConsistencyLevelOne, Points: batch, - }); err == nil { - s.statMap.Add(statBatchesTrasmitted, 1) - s.statMap.Add(statPointsTransmitted, int64(len(batch))) - } else { - s.Logger.Printf("failed to write point batch to database %q: %s", s.config.Database, err) - s.statMap.Add(statBatchesTransmitFail, 1) + }) + if err != nil { + s.Logger.Printf("Failed to write points batch to database %s: %s", s.config.Database, err) } case <-s.done: @@ -139,15 +114,12 @@ func (s *Service) serve() { n, _, err := s.conn.ReadFromUDP(buf) if err != nil { - s.statMap.Add(statReadFail, 1) s.Logger.Printf("Failed to read UDP message: %s", err) continue } - s.statMap.Add(statBytesReceived, int64(n)) points, err := tsdb.ParsePoints(buf[:n]) if err != nil { - s.statMap.Add(statPointsParseFail, 1) s.Logger.Printf("Failed to parse points: %s", err) continue } @@ -155,7 +127,6 @@ func (s *Service) serve() { for _, point := range points { s.batcher.In() <- point } - s.statMap.Add(statPointsReceived, int64(len(points))) } } diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/index.html b/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/index.html index e69c4d321..68f9811b5 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/index.html +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/index.html @@ -120,21 +120,21 @@ diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/js/admin.js b/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/js/admin.js index 10da97b0e..afe681525 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/js/admin.js +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/shared/admin/js/admin.js @@ -12,7 +12,7 @@ var connectionSettings = { port: "8086", username: "", password: "", - ssl: ('https:' == window.location.protocol ? true : false) + ssl: false } var connectionString = function() { diff --git a/Godeps/_workspace/src/github.com/influxdb/influxdb/statik/statik.go b/Godeps/_workspace/src/github.com/influxdb/influxdb/statik/statik.go index e43b2dff9..1b914b86b 100644 --- a/Godeps/_workspace/src/github.com/influxdb/influxdb/statik/statik.go +++ b/Godeps/_workspace/src/github.com/influxdb/influxdb/statik/statik.go @@ -5,6 +5,6 @@ import ( ) func init() { - data := "PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00README.md# InfluxDB Admin Interface\n\nThis is the built-in admin interface that ships with InfluxDB. An emphasis has been placed on making it minimalistic and able to be bundled with the server without adding lots of overhead or preprocessing steps.\n\n## Building\n\nThe only step required to bundle this with InfluxDB is to create a compressed file system using `statik` as follows:\n\n```\ngo get github.com/rakyll/statik\n$GOPATH/bin/statik -src=./shared/admin\ngo fmt statik/statik.go\n```\n\nThat should update the file located at `statik/statik.go`, which will get automatically build into the InfluxDB binary when it is compiled. This step should also be completed in any pull requests that make modifications to the admin interface, as it won't be run as a separate step in the release process.\nPK\x07\x08Hx6\x84\x0e\x03\x00\x00\x0e\x03\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00css/admin.cssbody {\n padding-top: 70px;\n /* Required padding for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */\n}\n\nhtml,\nbody {\n height: 100%;\n /* The html and body elements cannot have any padding or margin. */\n}\n\ncode {\n display: block;\n}\n\n#settings {\n display: none;\n}\n\n#settings form > div {\n margin-right: 20px;\n}\n\n#settings form input#port {\n width: 80px;\n}\n\n#settings form label {\n padding-right: 5px;\n}\n\ndiv#content {\n margin-bottom: -10px;\n}\n\ndiv#table h2 {\n color: #999;\n margin-top: -8px;\n font-size: 16px\n}\n\ntextarea#content-data {\n font-family: \"Courier New\";\n height: 200px;\n}\n\ndiv#query-alerts {\n margin-top: 30px;\n}\n\ndiv#modal-error, div#modal-success, div#query-error, div#query-success {\n display: none; \n}\n\n/* Wrapper for page content to push down footer */\n#wrap {\n min-height: 100%;\n height: auto !important;\n height: 100%;\n /* Negative indent footer by it's height */\n margin: 0 auto -60px;\n}\n\n/* Set the fixed height of the footer here */\n#push,\n#footer {\n height: 60px;\n}\n#footer {\n background-color: #f5f5f5;\n border-top: 1px solid #dfdfdf;\n}\n\n#footer p {\n margin: 20px 0;\n}\n\n/* Lastly, apply responsive CSS fixes as necessary */\n@media (max-width: 767px) {\n #footer {\n margin-left: -20px;\n margin-right: -20px;\n padding-left: 20px;\n padding-right: 20px;\n }\n}\n\nPK\x07\x08\x9c\x84U>\x8e\x05\x00\x00\x8e\x05\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00css/bootstrap.css/*!\n * Bootstrap v3.3.4 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\nhtml {\n font-family: sans-serif;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n margin: .67em 0;\n font-size: 2em;\n}\nmark {\n color: #000;\n background: #ff0;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\nsup {\n top: -.5em;\n}\nsub {\n bottom: -.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n height: 0;\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n margin: 0;\n font: inherit;\n color: inherit;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n padding: 0;\n border: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n padding: .35em .625em .75em;\n margin: 0 2px;\n border: 1px solid #c0c0c0;\n}\nlegend {\n padding: 0;\n border: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-spacing: 0;\n border-collapse: collapse;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n -webkit-box-shadow: none !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n select {\n background: #fff !important;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\2a\";\n}\n.glyphicon-plus:before {\n content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n display: inline-block;\n max-width: 100%;\n height: auto;\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all .2s ease-in-out;\n -o-transition: all .2s ease-in-out;\n transition: all .2s ease-in-out;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: .2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n margin-left: -5px;\n list-style: none;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n overflow: hidden;\n clear: left;\n text-align: right;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: .01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.form-group-sm .form-control {\n height: 30px;\n line-height: 30px;\n}\ntextarea.form-group-sm .form-control,\nselect[multiple].form-group-sm .form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.form-group-lg .form-control {\n height: 46px;\n line-height: 46px;\n}\ntextarea.form-group-lg .form-control,\nselect[multiple].form-group-lg .form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 14.333333px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n }\n}\n.btn {\n display: inline-block;\n padding: 6px 12px;\n margin-bottom: 0;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n pointer-events: none;\n cursor: not-allowed;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n opacity: .65;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus,\n.btn-default.focus,\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary.focus,\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:hover,\n.btn-success:focus,\n.btn-success.focus,\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:hover,\n.btn-info:focus,\n.btn-info.focus,\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning.focus,\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger.focus,\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: normal;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity .15s linear;\n -o-transition: opacity .15s linear;\n transition: opacity .15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-timing-function: ease;\n -o-transition-timing-function: ease;\n transition-timing-function: ease;\n -webkit-transition-duration: .35s;\n -o-transition-duration: .35s;\n transition-duration: .35s;\n -webkit-transition-property: height, visibility;\n -o-transition-property: height, visibility;\n transition-property: height, visibility;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, .15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px solid;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555;\n text-align: center;\n background-color: #eee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eee;\n}\n.nav > li.disabled > a {\n color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n -webkit-overflow-scrolling: touch;\n border-top: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-top: 8px;\n margin-right: 15px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-top: 8px;\n margin-right: -15px;\n margin-bottom: 8px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n color: #23527c;\n background-color: #eee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 2;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n background-color: #777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding: 30px 15px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding: 48px 0;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border .2s ease-in-out;\n -o-transition: border .2s ease-in-out;\n transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@-o-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n float: left;\n width: 0;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n -webkit-transition: width .6s ease;\n -o-transition: width .6s ease;\n transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n -webkit-background-size: 40px 40px;\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\na.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777;\n cursor: not-allowed;\n background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\na.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\na.list-group-item-success.active:hover,\na.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\na.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\na.list-group-item-info.active:hover,\na.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\na.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\na.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: .2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: .5;\n}\nbutton.close {\n -webkit-appearance: none;\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transition: -webkit-transform .3s ease-out;\n -o-transition: -o-transform .3s ease-out;\n transition: transform .3s ease-out;\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, .2);\n border-radius: 6px;\n outline: 0;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: .5;\n}\n.modal-header {\n min-height: 16.42857143px;\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 12px;\n font-weight: normal;\n line-height: 1.4;\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: .9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n text-decoration: none;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n white-space: normal;\n background-color: #fff;\n -webkit-background-clip: padding-box;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, .2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999;\n border-top-color: rgba(0, 0, 0, .25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999;\n border-right-color: rgba(0, 0, 0, .25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999;\n border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999;\n border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: .6s ease-in-out left;\n -o-transition: .6s ease-in-out left;\n transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform .6s ease-in-out;\n -o-transition: -o-transform .6s ease-in-out;\n transition: transform .6s ease-in-out;\n\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000;\n perspective: 1000;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n left: 0;\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n left: 0;\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n left: 0;\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n filter: alpha(opacity=50);\n opacity: .5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n filter: alpha(opacity=90);\n outline: 0;\n opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -15px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -15px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */\nPK\x07\x08\xbeO[\x0b6)\x02\x006)\x02\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00css/dropdowns-enhancement.css.dropdown-menu > li > label {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > label:hover,\n.dropdown-menu > li > label:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > li > input:checked ~ label,\n.dropdown-menu > li > input:checked ~ label:hover,\n.dropdown-menu > li > input:checked ~ label:focus,\n.dropdown-menu > .active > label,\n.dropdown-menu > .active > label:hover,\n.dropdown-menu > .active > label:focus {\n color: #ffffff;\n text-decoration: none;\n outline: 0;\n background-color: #428bca;\n}\n.dropdown-menu > li > input[disabled] ~ label,\n.dropdown-menu > li > input[disabled] ~ label:hover,\n.dropdown-menu > li > input[disabled] ~ label:focus,\n.dropdown-menu > .disabled > label,\n.dropdown-menu > .disabled > label:hover,\n.dropdown-menu > .disabled > label:focus {\n color: #999999;\n}\n.dropdown-menu > li > input[disabled] ~ label:hover,\n.dropdown-menu > li > input[disabled] ~ label:focus,\n.dropdown-menu > .disabled > label:hover,\n.dropdown-menu > .disabled > label:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.dropdown-menu > li > label {\n margin-bottom: 0;\n cursor: pointer;\n}\n.dropdown-menu > li > input[type=\"radio\"],\n.dropdown-menu > li > input[type=\"checkbox\"] {\n display: none;\n position: absolute;\n top: -9999em;\n left: -9999em;\n}\n.dropdown-menu > li > label:focus,\n.dropdown-menu > li > input:focus ~ label {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu.pull-top {\n bottom: 100%;\n top: auto;\n margin: 0 0 2px;\n -webkit-box-shadow: 0 -6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 -6px 12px rgba(0, 0, 0, 0.175);\n}\n.dropdown-menu.pull-center {\n right: 50%;\n left: auto;\n}\n.dropdown-menu.pull-middle {\n right: 100%;\n margin: 0 2px 0 0;\n box-shadow: -5px 0 10px rgba(0, 0, 0, 0.2);\n left: auto;\n}\n.dropdown-menu.pull-middle.pull-right {\n right: auto;\n left: 100%;\n margin: 0 0 0 2px;\n box-shadow: 5px 0 10px rgba(0, 0, 0, 0.2);\n}\n.dropdown-menu.pull-middle.pull-center {\n right: 50%;\n margin: 0;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);\n}\n.dropdown-menu.bullet {\n margin-top: 8px;\n}\n.dropdown-menu.bullet:before {\n width: 0;\n height: 0;\n content: '';\n display: inline-block;\n position: absolute;\n border-color: transparent;\n border-style: solid;\n -webkit-transform: rotate(360deg);\n border-width: 0 7px 7px;\n border-bottom-color: #cccccc;\n border-bottom-color: rgba(0, 0, 0, 0.15);\n top: -7px;\n left: 9px;\n}\n.dropdown-menu.bullet:after {\n width: 0;\n height: 0;\n content: '';\n display: inline-block;\n position: absolute;\n border-color: transparent;\n border-style: solid;\n -webkit-transform: rotate(360deg);\n border-width: 0 6px 6px;\n border-bottom-color: #ffffff;\n top: -6px;\n left: 10px;\n}\n.dropdown-menu.bullet.pull-right:before {\n left: auto;\n right: 9px;\n}\n.dropdown-menu.bullet.pull-right:after {\n left: auto;\n right: 10px;\n}\n.dropdown-menu.bullet.pull-top {\n margin-top: 0;\n margin-bottom: 8px;\n}\n.dropdown-menu.bullet.pull-top:before {\n top: auto;\n bottom: -7px;\n border-bottom-width: 0;\n border-top-width: 7px;\n border-top-color: #cccccc;\n border-top-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu.bullet.pull-top:after {\n top: auto;\n bottom: -6px;\n border-bottom: none;\n border-top-width: 6px;\n border-top-color: #ffffff;\n}\n.dropdown-menu.bullet.pull-center:before {\n left: auto;\n right: 50%;\n margin-right: -7px;\n}\n.dropdown-menu.bullet.pull-center:after {\n left: auto;\n right: 50%;\n margin-right: -6px;\n}\n.dropdown-menu.bullet.pull-middle {\n margin-right: 8px;\n}\n.dropdown-menu.bullet.pull-middle:before {\n top: 50%;\n left: 100%;\n right: auto;\n margin-top: -7px;\n border-right-width: 0;\n border-bottom-color: transparent;\n border-top-width: 7px;\n border-left-color: #cccccc;\n border-left-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu.bullet.pull-middle:after {\n top: 50%;\n left: 100%;\n right: auto;\n margin-top: -6px;\n border-right-width: 0;\n border-bottom-color: transparent;\n border-top-width: 6px;\n border-left-color: #ffffff;\n}\n.dropdown-menu.bullet.pull-middle.pull-right {\n margin-right: 0;\n margin-left: 8px;\n}\n.dropdown-menu.bullet.pull-middle.pull-right:before {\n left: -7px;\n border-left-width: 0;\n border-right-width: 7px;\n border-right-color: #cccccc;\n border-right-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu.bullet.pull-middle.pull-right:after {\n left: -6px;\n border-left-width: 0;\n border-right-width: 6px;\n border-right-color: #ffffff;\n}\n.dropdown-menu.bullet.pull-middle.pull-center {\n margin-left: 0;\n margin-right: 0;\n}\n.dropdown-menu.bullet.pull-middle.pull-center:before {\n border: none;\n display: none;\n}\n.dropdown-menu.bullet.pull-middle.pull-center:after {\n border: none;\n display: none;\n}\n.dropdown-submenu {\n position: relative;\n}\n.dropdown-submenu > .dropdown-menu {\n top: 0;\n left: 100%;\n margin-top: -6px;\n margin-left: -1px;\n border-top-left-radius: 0;\n}\n.dropdown-submenu > a:before {\n display: block;\n float: right;\n width: 0;\n height: 0;\n content: \"\";\n margin-top: 6px;\n margin-right: -8px;\n border-width: 4px 0 4px 4px;\n border-style: solid;\n border-left-style: dashed;\n border-top-color: transparent;\n border-bottom-color: transparent;\n}\n@media (max-width: 767px) {\n .navbar-nav .dropdown-submenu > a:before {\n margin-top: 8px;\n border-color: inherit;\n border-style: solid;\n border-width: 4px 4px 0;\n border-left-color: transparent;\n border-right-color: transparent;\n }\n .navbar-nav .dropdown-submenu > a {\n padding-left: 40px;\n }\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > a,\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > label {\n padding-left: 35px;\n }\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > a,\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > label {\n padding-left: 45px;\n }\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > a,\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > label {\n padding-left: 55px;\n }\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > a,\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > label {\n padding-left: 65px;\n }\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > a,\n .navbar-nav > .open > .dropdown-menu > .dropdown-submenu > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > .dropdown-menu > li > label {\n padding-left: 75px;\n }\n}\n.navbar-default .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a,\n.navbar-default .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:hover,\n.navbar-default .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:focus {\n background-color: #e7e7e7;\n color: #555555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:before {\n border-top-color: #555555;\n }\n}\n.navbar-inverse .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a,\n.navbar-inverse .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:hover,\n.navbar-inverse .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:focus {\n background-color: #080808;\n color: #ffffff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open > .dropdown-menu > .dropdown-submenu.open > a:before {\n border-top-color: #ffffff;\n }\n}\nPK\x07\x08\x9a\x90:SN \x00\x00N \x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00fonts/glyphicons-halflings-regular.eot\x9fN\x00\x00AM\x00\x00\x02\x00\x02\x00\x04\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x90\x01\x00\x00\x04\x00LP\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'\x12\x7f,\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\x00G\x00L\x00Y\x00P\x00H\x00I\x00C\x00O\x00N\x00S\x00 \x00H\x00a\x00l\x00f\x00l\x00i\x00n\x00g\x00s\x00\x00\x00\x0e\x00R\x00e\x00g\x00u\x00l\x00a\x00r\x00\x00\x00x\x00V\x00e\x00r\x00s\x00i\x00o\x00n\x00 \x001\x00.\x000\x000\x009\x00;\x00P\x00S\x00 \x000\x000\x001\x00.\x000\x000\x009\x00;\x00h\x00o\x00t\x00c\x00o\x00n\x00v\x00 \x001\x00.\x000\x00.\x007\x000\x00;\x00m\x00a\x00k\x00e\x00o\x00t\x00f\x00.\x00l\x00i\x00b\x002\x00.\x005\x00.\x005\x008\x003\x002\x009\x00\x00\x008\x00G\x00L\x00Y\x00P\x00H\x00I\x00C\x00O\x00N\x00S\x00 \x00H\x00a\x00l\x00f\x00l\x00i\x00n\x00g\x00s\x00 \x00R\x00e\x00g\x00u\x00l\x00a\x00r\x00\x00\x00\x00\x00BSGP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\xa9\xdc\x00M\x13\x00M\x19\x00F\xee\x14\xcd\xe9\x8c\xcf\xd2\x11\xd9\xa3(u\x1b\xca\x8c<\x010D\xe3B/X\x0d\xefN\xef\x0b\x88\x00CC\xea^\xc7\x05\x0crmR2sk\xc9\xcbPJ\"5+\x96gl\xe9W*i\xd5W\x96/E\xee\x91\x9c\xd3\x054#\xac\xd4\xa3U\xa6~\xb2f\x10\x89\x91\x1bUD\xdc\xc4\xb9\xf7\x88\xab\xb1\xe0J\xb71\xe1/!\xfe\xfe/\x9e\xba\xcas\xaa\x027\x19\x92\x93k\x8a\x95\x94\x07\x06(\xba\x88\xa1h\x1fN\xf8\xe98o\x90\xedd$yq\x8e\xb91\xb3\xe2\xd69\x16\x83@\x11-\x89\x82HG\x92\x01\xf4\x18\xb5S\"\xf8Fj\xf4\x04\xd8\xa06C3\x94\xa4&\x9e\x87\xc1\x1e\xf8\xaaW51\xc1\xd3\x1b\xdc\xd7B\x9f\xafa\xcb\xeaQaR\x86U/\xf5\xb6{*\xbf\x82\xcb\xef\x00\x82=\x96@d\xf4\xf8h$\xa1\x1e1\xc9T\xdb\x97nc+c\x92\xdeA\xa1\xa7\xbc \x17\x95Z\xc9\x80\xa4@Q\xd1c\xada\x1a\x87\xd5\xdel\xf7\x902>\xcaK\xb0\xc8\x04\x01m\xf3' \x0b\x93\xcb\x19C\x87HM\xc4\xacfB\x89X\x8d,\xbeY\x01\x17\xf2\xc2p\xa8e\xa2\x90\n\xee\x8d\xb8U\xf8\xd8\x01\x1e*\xd2\x94\x1az\xff\nm\x82\xcb\xcbi\x16\x10O1nE\xc6.\x10\x9b\x84\xe4\x0dhx!aC\nXT\xda\x14V\xa2\xc5\x16\xa9\xc2\x8b\x96\x0c\x97\x07\xe9R\x1d\xa5\x9a\x1e%\xa5\x04\x04|I\xe4\xa0H\xf0\x90\xc5\xd5P\x835\"\xc5b\x92N\xb2\x10\x11\xb5=\xe2\xf8\x83r\xd9/_\xe5R\x8c\x9b\x94\x99_\x0b\xe0%\xd2\x84\x8duz\xc9\xe9\xd2\x98\xd65\x922\xc4\xa1\xd2\xe3\x05P\xda)\x9e\xd4\xfe\x11\x9e\x1b\xc6\xc3F\x837S\x8b\x01q\x84F\xc0{n\xe1i\x14a\x81\x02\xb7\xb8@D\x11\xd0s\x88;\x9a\x18\x1f}9\x1b\xe2\xac\xa5?\xc5\xba\x91\x06\x19\xa7\xc2\x0b\x0cR{\xa6Tk\xed;\xde\xb5\xc7\x9c\xd7U\\N\x9eZ\xf8\x9bQ-\xbb^\xd4s\x90\x7f7\xf2f\x0b0\x19\x98\xca\xc6S3A\x0c\xdc\x0d_n\x90\x81`W\x1c7P\x7f\x12p\x98\xbb\xf4\xe0\x08i\xab\xed\xb3!\xf0g\xd8/\xe0_p\xbb\xc1\xd2\x04Z\x80-=\xc3\xd7\xa5~WZ#/\xe14 KF\x00`\xb4 \xbb\x8c\x01z\xdf\x02\xd20\x07\xdb| D\x82\x06\x14\xd1\xb5\x00\xec\x00\x82&d\xc3\xa4I\x89\xb4\x8e\xfc\xc3\x8f\xc1;\xb7M\xec\x94{'\xb6om\x86\x94m\xa2\x0bI\x0b\x11\x06!w\x1ci9|H:\xa7\xdb\xa7\xc0\xbb\xe7\xf7\xca\xfe\xbe{\x15\xfb~\xf6\xb9\xfdq\x04\xba\xb8\xa9O\xf8\xe5\xf4\xee\xa9\xa0\x0f\xfa\x9b,\x98 \x82L]&\x84J0\xf1\x95\xd99/\x03\xed\x0f9&\xccY\xf8\x0c\xe8\x93\xb0{;\xf7\xfa'\xc03`\x1c\x92e\x00\x7f@v\x14H\x0f\x84y\x08DZ$\xba\x00\x843\x81\xcb\x03\x88Dx28\x0c\x04\x05\x83W\x80 Cx5x\x18\x08w\x07\x82B`\xa3$C$'\xe3\xcaEl\x85\x1cy\xa0\xd5h\xbf\xeb\x1c\xd4\x80\x0d\x0bDJ\n$(p\x9d\x06\xbd\x07\xeeQA\x94A\xdc\x89A\x96@'\xc7$\x0dh\x03p\x1c\xca0\xceV\x120 `\x9d\xbas\xbe\xaae\xd2$\xc94$\"t2=f\xb4\x984\x84A\x84{Tk\x96\x070|r\x18H\xa4\xf6\x10\xc4\xd0\x02\xa3\xef`\x1bL&\xb1\xb4s\xd4h\xa6]\x01\x94\xa7A<\xa3\x1a\xa1\x8b\xb2`R\xb4'\xa3\x02\x95!\x83\x8b\x811N\xa6\x01;\xa3\x12_\x8at3\xdb#\xa0 \xe2\xf2\xeb\xfa\x18\xd8\xeaV\xe3\x05\xea\x0b*ve\xd1F`E\x7f O$\x8e{)\xd9W=p:\xae\xde\xd6\x11F`\x8a\xbe2\x1a\xc6\xc42\xda\x93C\xeb\xc1\x8c\xd2^\xd7.\xca\x15\xc4\x87\x03\x98\xa1\xf8\x96\xf8G\x08\xfe<\xfb.p\x1e\xe7Ne2\xea\x8b\xef\xd6\xb4\xba\xde+Y\xecs\x16\xdbl:\xc2\xc3\xcb\xbc\xef\xb5\x0c\xdc\xabu5\xa9\xa6\xde\xee\xd0t\xc0u\x95^8\xbe\xcc6\xe8\xf3\x1f\x07\xc8\x84Tmy\xf0Q\xc9%\x16\xfeu~\xf4\xf2\x9a%~1r\xd2\x98a\xfdw\xdf\x9a^\x90\xf9_\xa9Z\xa3\x8dZ\x9da\xa2\x83\xb20!\xd9\xe8\x05\x8d\xa1\xb7\xfaN\xf6`\xa5.\x8e\x0duq\xc0\xb1\xe7\xeaYB\xa5\\\x99\x1b\xa8\xf3\x85\x84\xca\x11\xe1\xa8\x80\xd4\x15\xea\x85\x13[\x07e\xf0\x8b\xee\xee\xfe:@\xa0\xeaJ'E\x17\xdb\x81,\xaf3\x1f\x1dubj@\x8dp\xa8\xc1\xc6\xe4\x17\xf0\x13\xb4f\xa8\xc9\xdf\x15\xf3\x7f\xee\xb5\xb7eW9( \xf3\x1b\xba\xe5\x02\xa0\xb4\xde\x85\x89\xb3\xe6=\x8b\x17l\x94G\x1e\xa6\xe0\x017\x12g\x10j\x1a \xe2S\x83M6\xc6\x01\xb0\xa0\xf40\x83\xff9\xf2\xa7\x96O\xcb\x91\xa8\x9d\xfc\xed\x8dl\xa7\xaeB\xbc\x0e\x07a\xaa\xdd\x81\xf2\xaf\xa0\x0b\x83<\xa6\xe7\x02\x01\x9e\xc7B\xd5\x99(\x04VRAp\xa1f\xf9^\xb0\xfa\xaf+g9\xa0q\xd3\xdd\x0e\xb9\x8d\x8aM\xc6t\x1c\x18]\x04\x1d\xbb\xd8\xaa\x81p\xebE\x8d\x95r\x07@]\x87@\x1e\xf3\x0f\xa9V\x8d\x9fkV\xa5\n\x05u\x13\xea\x1a\xe4d\xe9^\xd1\x11X \x8d\x15\xe5\x96\x06\x97R@?E\x1d\xd5\xf6Y2\xf4\xa8\x98\x1c\xc9\xef]#\xe0\xc7\xbc\x9a4\x03\xc0J\xde\xe5K\xf6\xc1\x07\xe4\xd6'\xc3\xc1\xbed\xb2\xe2PC|m\xe3m\xe5n\xe4#\xbe\x82\x10\x07$+48u'\x11\x85\x90\xe7e&\xfb\xbf\x80[n[L\x11\xe1\xc8\x1d\xf9\x92\x9e\xb1%{BCD\xdaL:\x01^!\xa0\x8b\x82\xd3b\xc6\x99:&\xc9\xff\x0f\x88\xee\x82g3\x93-3\xd0\xf8u\xb4\xe8\x7f\xad\xc7\xe6\xd0\xf0\xb9\x83b\x0diLZ\xe9\xda\x82W\x82FS\xc9\xe4Id\xcd\x02\xf1\xa16.\x91k5P\xee\x84\x04l7\x9e7\xfcUz\x92T:N\xfdN\xa1\x91\x97.\xfd\"\x80\xaa\xe5\xfc)\x89\xc5\x19\x97\xec\x92['\xdf|U\"\x0fA\x1c\x83\x04\x80\xb3\x97\x82I\x95\x81\xdbv\xa9w\xd0\xdb\xd8p\xeb\x99\xed\xadt\xb9dk\x82\x88\x9e9\xd8\x08\x9b\x8a\xe5\xab\xab\xcd9\x00n\xa8D\x8bmq\xb9\x977I\x18|6\x9bK\x03bc\x83]\xb6\x06M\xf4\x93\x19\x12\xa9\xb2\xc4\xce\xf7\x97\xe8\xb6\x12B\x8dA\x90\x80B\xf8\xc8\xaa\x06\x00_\xf4J\xbaT\x0c\xd9\xfc\x08\x18\x01q \xd0\x07 \x1e6@\x97\xa7\x84\xb8F\x8d\x97\x87\x83\x9ehd`G\xae\x8fT\xeb\x14\xf1\xb7:M\x1e\x7f\xc57'\xe0\x85L,\xe9\x17Ih\x97\xc6FP \xbb\xca~j\x00\xbd\x06\x8a\x8c\xed\xc4\x0c\xac$\xc2\xa1\xc2\x84 \xc43\x99hA\x13\xdd\xe4\x00\x81\x92-S\x8c^\xfb\xda\x86\x90\x85\x06\xd0\xe4-%qe\xcf\x14\xec\xeb~\xc0\xc6Qq\xab\xa7\x16\xacln\"i\xbe\x9e\x07&\x90\x91\x07\xe6\xd1Qe?Fl\x0eK\xef\xa8\"\xfaAs\x14\xc0(\xdd3\x1dY;\"\xa1L\x9e\xda\xd4e\x80t\xe5\x1c'\xc4RzM\x1a\x9c\xaa1\x0c\x110\xa8{=\xe6\x90\xf7)\x9e\x80\x0b\xb3K\xa0%\x8f$C\n\xc2\xf8\x919\x8aM\xf0\xf6\xbc\xeb\xbc4c\x01 \xea\x80Eotj\xcd\xc2V\xa7GD\x8e)l\xf18\x93\xaf,\x98\\w\xc0\xa5\xe0\x0b!\x00%$\xbf\xd73t\xc9 T\x12B\x1az\x92\x9e\xd2\xb4 iU\x1aJ\xd2\xdd\x12[\xa2\xc7x\x12g\x13d\x1c\x84\x1eBr\xef$\xc5\x18!eq\x88\x81\x92\"J>\xe0\x10\xa3 \x0c)\\\x9d~\xa1\x82\x8a\x893\x08\x90\x0e(\x08^\x0d\xe2\xa0R\xc2\x808#>\xd6\x07b\x9b\x05\xe4H\x80\xe2G'7_\x0cf\xd3\xabc\xce\xbatD\x00oAA\xdf\x83\x86(q\x99B<\x16\xfd`\xc7\x03\xad\x1c`V\x88\xfc\xf8\xe9\xce\xab\x94\xa9\xd6\x98\x19\xc2*\xfab\xde\xcfu\x8b\x14P\xad4\x13v@\x97+\x95\xca\x04.\x08\x8f\x92\xeeQ\xe5\xd4\xa5$V\x82\x12\xa1\x19\x95\xed@C0\n\x0b\xedR\xa2\xd3\x1c\x04\xdc\x90P[\x91\x1d\x11z:X\xa6H\x18#e\xe4\xc1\x0b\x02\xf2s\xa0>?\xfa\x05E\xc8WO>@\x0eI\xd8$|s\xac\x9ei\x1a\xe2\nE\x02\x12S\xa5\xb2)0A\x8c?\x16\xa39\x95ab,\xb6\x8d@K\x9a\xf1\xcc\xa9o&\xee\x04\xfe\xfc\x0e\x88\xacQ\xb4%\xac\x0c\xcf\x9eLu+\x9b\n\xc2+\x90H|\xcc\xc6\x90?\xb4\x16NK\xcc\x1b4\x8c\xc6\x17\x92\xd3CnPt\xe8\xb3\x0d'OT\xf2\x9c\xd2.j5\xe0\xc4\xb48\xc8\xdcv\xb6w\xd6\x9c\x90\xab\x12I\xa5\x12&\x95+\xdf`\x02\xbc\x8ay\x18S\x9d\x90caO\x11[#\xa1g\xb0\xa7\x08Q\xa7\x9c\x80\xb8\xdad\xaa\x17[\xeeK\xbdI\xe7\x9f\x97`\xf4\x07\xc4\x8cLP\xfd\xd3\x18\xb8 #\xb0\xc1\x9c\xbd \xa9)2\xd27\x16aT\x83\x7f\xe4\x16\xebi@c\\\xde\x90\x91\xee\x0b\xc2\xe2\xc80n\xeaC\xbbp\xf2\x10\xdf\x96\xe9\x81\x8b4\xcd\xb5\x8e\x90x\xf6*\xf1\xcb\xd0R\x94z\xd5\x0eY\xe2\x84b\x87\xc0\xfa\xdbT[\\\xfa\x1dkU\x02\x99v\xecH\xca\x88\xdcq\x92\x08p\xe0\xa6\x84I\xc2\xedI\x18\xeb\xc5\x97)\x08\x0b\x8bbB\x0d \x10X\x94P\xbaN\xb4\x85\x9at\x0fz\xed 2\x0dI\xe6=\x12=\xa4 \xa6\x1f\x1b\x1c\x0e\xb3\x88\xfd\xa8\xc3;}\x86b\x8a\x9c\xe0q\xfe\xd3ji\xde\x86\xa7a\xb2#\" \xac\x17\x9f>1\x01\xbc\x82\x90\xb01\xe4A\x9b\xa3p1\xd6\xed\xddP\x82\xa7O\x12\x1a\xc7\x04\x13\x1d\xe8O\x97ux\xf7Q\xf4\xf9\xb0\xb9\xce\nF\xcf\xb2(\xfah\xdd\x84\xa9O'MDx\xcaL\xedK\x11$\xc8\xb5\x9ch\xe6&\x0d\xf9\x8b\xa6\xd0\x04\x001\x8c\xef\xc44\x9b\x9bSi\xa0\xdc\xe3rHJ\x16\x92P\xb0t\x00DM\xcb;rM\xe3\x82+\x94\xf6\x97\n*\x96\xe0\x9f\xed\xd8\x975u\x172$\x07\xaaf\x103\x92K \xdf<\xf9P\xb2L\xe7r\xd1c\x8bI)\x81\x98\xd6\xe5\x16^\xeb\x1fda>\n%\xc5\xe0\xd1\xb3b\x0b(\x9f\xfa\x96@\x08,\x912f,~\"\xa67\xdbR;\xaeE\xd1\x1d\x8e;\xac\xad\x94HX\xe5(\xfa\xb9\x12\x9f\x17\x1c4\x8a2Z\x03\x1f\xe4\xdd\x08'\x00T\xaa\xdb\xbf\xf6\x8b\x81\x84\x04\x0f\x94\xbd2J+\xff^!#o\x1b\x8e\x84\x9b\x94Y~4\xd8-\xd7\x83\xf2GW\x1f*\xf0!\xdf\xc3A\x95\x1a0&8\x80f\xe4{`\xbc\xbd\xf8\xe0W\xf6=\x92DP8\x92'\xff\x13= \xd6R\xa6 g\xa9}\x10\xf4iP>\x93\xca\x03#\xb9\xcb\xe5\xb94\xc3\xd2E\xd0BRY\xae\xc6^4e\xf3\x02\x9d\xfd\x82\xa7N8\xb8\x8fV,[B\x8b\x86\x15\xc4\xa8\xeeD#\x81X\x86\xf8]\xb2,\x19\xd6\xe8\xe2\xabLBsNC>\x17\x0d+\xa2\xedo\xcd\xea^x\xa8\xec\xa7\n\xa0\xf7\x0e\x95\x90\xfajC\xec.4\x0f\xc0Y\x11a\x89_{e\x01\xa6A2=r\x8e\xf0\xd8+\x00\x89\x05\xad\xb4\xd6\xee\xa7\x04\xa19PO\xbbA!!\x0b\n\xd7}\xb4Y\xcaP\x1a\x02Je\x84\x15\x97\xe7Gn\x9a\xb1%x\xfc\x8d1\x16\x14\xac/}Rg\x12H\xd8\x08\x9a\x11a\x0c\x8e\x01^3-\x8a\xa9 \x8b5\x06\n\xb6|\x8b\x01qS\xa7\xd0\xf0a\x07\x08WK{\x0c1al`I\xc0\x181\xd3\x0b\x99\xc6Q\xe9\xbe\xebf_yy\x05C\x19Z\x14)\xc4L3X\xb1]\x0bW6@DM\x99\x15T\xf8<.\x84\xabu\xebG\xceK\x8c\xec8\xd9Ds\xf4\xda\xd0\xb1\x03W\xe6\x91r\x85\xdd\\\xdf7Z\\\xd5\xcb\xff\xf2V\xd3\"I\x18\xa6\xa2\x8c\xf5S\xa1\xa7\xaed\xb5\x89>C\x8e\xa6\xc8U\x81j\x90\xdf\xc9e\x02\x9e\xc9\xc8\xd3D\x13\x05 \xae\x163\x19M\xc7tWcP\xef\xaf\x05\x86\x96\xf2\xd3\x896#3Q\xd7\x02\x9an\xe1\x89\xa9\x85\xb0J\\\xba\xa1\xc3\x05\x197\x9e#\xe7\xa3\xb1`\xd8\x80K\xeb\xeb\xa4 \xa9\xd7\x08lV\x036\x0b&\xd3\x1fT\x1d\x8e\x92 \xde~\xee\xdal.\x92\x9d\xbe\x16\xa1 <\x98\x98BP\n\xa3*\xb4!zRZ\xc4\xe4e\xd1\x99\xbb\xbe\xbe\xd9\xb7\x04T\xb1#\xa3C\xe9LH\x13\xb1\xac\x18\xc8\x16\xaa\x08W\xc5)\xdaD\x9b\x86\x16\xf7\x93p\xaeYU#\xc9\xca51{WJ\x80\x8e\xa44^\xc4f\x12\x19\xb3\xcc\xbc\x15Z\xb0\x11\xf6\xcc\xd1y6\x96\xd3\x91T2\x99d\xce4H=\xeaB\x84\x1e\xd2\x8a\xc9\x10\xac\x0f}\x9c&\xdd\x83\xea\xc2,aP\xc3\xa7v+:2\x16\xe6~\xf2\xc1*0\xbc\xb0\xa2\x88d\xa6\xc9\x93\xc2\xf5\xd6\x83d \x0c\xc2\x82\xf8\xe1\xcb!\"A+\x89r\x00\x90Hn\x0c\xa1\xc7\xe0sA\xe4\xc1\xc8\xda\x97U\x0d\x80\xfd\x02\x04\xf8\xa4b\xa0H\x93\xdbN6\xfe$.\xd0l\xc0};\xbd@\xa3\x11\xa1\xe2\x14iK\x7f\xc3 \\\xac\xd2\x82:v\x1e\x89QE\xc7\x00:\x1d\x08,|\xfd\xaaQ\xa0 Y0\x02|\xc7%\x18\xd6\x16\x19@\xed\x13\xb0 \xdc\x81\xe4qc\xe7\xd3\xd1dqh\xaf\xab\xe8\xab\xb9v\xdcC\xcdG\x07V\x86\x06\xb0\xa9\xb8\xaf-(\xd1\x03\x88m\x11\x85\x05\x921\x12\xbb\xae\xe2q89KF\x96\xd6\xc3\xa4\n\"2\xb1\xf2}Rr\x16z\xf3\x8e,j^\xa5\xc0q\xcb\\\x04\x85\xdd\x96#p\x19\x83\xbb+\xf5`f\x1dl\x9a\xb3\x13\x1c\xbd\x8f\xe2:k\x0b\xb4t\x965E\x84\x1aOaI\xc3\x0fJ\x16\xacP\x0d@ps\xadE\x99j1\xe44;6\x12\xf6\xf4/aH\xce.\xbc\xcf\xd3\xb0T\x00X\xa4p\x93L\x8b\xb8\x08\xc4L8\xa4\xbdF\xe7\x84\xdc\x9ai\xa8\x01\x0el\xed1\x96\x12\xb2Y\xd8\x8a8\xc9\x0d%\x8d\x16!/\xc1\xf9{\xad\xa8\x0e\xd2\xc5\xf1\xa0\xe9\x9c\x8b\xd9\xe5\x1d\xc6X\x9c\x80\xba\x07b\x88\x95\xbd\x85\x00\x15N\xc9\xc2\x04xp\xbb\xba\xe4\x06PW\xea\xbd\xdb\xed\xe8\xc4cI9\x18g\xb2*\xfe\xba\xbf\xee\x9d\x83\xb9\x9c%:\xd6\x1d\xbbL\xcb\x06\xdeu\x8a\x82CAO\xc2\x8c\xad\x99%\xac/\xc5\x93\xb4(Y\x08\xa2\xb3\x10^\xef?\xa0\xde\xe3\x1d\x81&I'\x88\xc8\x12uh[x\x14\x8b\xb4\x96Q\xf4$\xc7z\xd2\xb5\xc5\xbd\xf8\x01\x82 \xdf\xb3\x9e\x81\x82(=V\xd7\x80\x9f\xea\x0d\x02\xbem\xf0\xad\xc5\x04U)\x0b\xbb\xedl\xce\xa0\xce\x92\x18\xbe\xcci\x9c\x02\x18\x95d\xe3\xa6\x88\x99\xa8\xbd~f\xa6\xf9jG\x1b\xed\x01\xb5\x03\xd6R\x06{D\x80%>\xae\xa5\x90@\x94\x85\x946\x82\xa5\xa41\x82\x9c`\xc6\x1a!\xce ` \xc5\x1d\x86\xb6wY\xf3\xa7\x7f\x89\xd5\xe0\x81k/\x08a\x9d0A\x12\x86\x02\xab\xc2\xb9\x9f\xd4\x81\xb4\x0f\xcaYh\xb2\xaf\x97\xb5\xf2\x88d\xec\xe6x\x9a\x91k:f\x9a\x83\xff\xef\xa6\x1f\x92<\xd5\xd8\xd9WL4\x81`\x1d8IYMB\xc1Slc\xe4\xd6\xdf\xc8\xe0\x99-\xbbE\xd2\x82'\xce\xda\x8c\xc5:,\x1d\xffD\xac\xb0\x90\xe7\xd1\xd9\xf8\xc6\xa98\x184\xd3)~\xf7\xff\x042\x04\xb7j\x80\x9f\x96\xc7\xa0\x10i\xb6\xb7\x04\x0fB(L\xe3\xb5\x06\x08|\x0b\"a\xa9\x9a\xa6\xaf4,\x06\xa6b8\xa7\x94\xa5\xd4\x93\x17i 94\xa6\xe5\xd4\x11\x8c\xd2jW\xd1\x89\xb0\x1e\x0c\x02\xa96*\x90\xd0T\xf0\xa3\x1b\x86c4g\x8a\xcc\x93\xa2\xd7UM\xc9b\xb3R\xc7E\x00\xb2\xfe\xaa\x8b\xf2\x85\x1aC5\x91\xc6)j\xe4\xc8\xb4 \x91\xad1\x8d6pb\xc3\xeb\xdb\xc6\x8eH\xf7\xa7\xaaFx\xf2\x88\xf1\xb9\x01\xbf\x97\xaf\xab\xc4\xa3\x8f%4\xe2\xf2Q\xd9\xc4\x17C\x04\x89\xca\x88\xa7\x0e\xc5 \x1c$9\xd2:\xc5M>\xf2E\xd6\xdda\x03\x01\xdc\xc6\x02o\xab\x81\xcc\x9f^\xc2\x15\xd8<\x02\x19Iw\xde\x11\x00Ygq\x8f7s[\x86\x1f\xf0\x92\xf0 -y\xd01\xd8\xb95\x86\x19\xe4a\xc4\xe3M\x06K\x9a\xd7\x90\xe6RB\xc7Y\x80\x86\xf3Fq}\xb9\xe2\xe7\xb1\xf48\xef\x01\xc0\xb2*\xc8Nt\xe5\x90'.Yb\x14\x84\x94\x9b\xa4\xcd\xf0Z\x15\xcd\x1e\xfbv\xc5K\n(\xca]\x05&\xc9\x9c\x13\x1c\x8a\x19(\x0e\xa0\x1d\xd5\x99\xa5\xfd\x1e2\xaf:0\xd5\x0d\x80\xe4o\xa4\xce\x8f\xd1\x85\x1cPKiBH4U\xf0\xb9X,\x13\x8e\xa2\x8d[\x17\x88\xf0$\x0c\n0\xadmX\xb1\xe5\xbb\xd8\xb4\x8f\x82 \xf2\xa5f\xeb\x015\x0f\x15\xf0\x03\x040\xb1\xa0VR\x0d\xa98\xea%\xd9\xd1\xf1\xca\xde\xa7\xa7\x02Dt\xb0\xc3U\x8c\x91s`\xf4\x1d\xb7\x1b-BP\x8f\xc8\x0fz\xf4\x01P\x13\x94\x1ds\xeb\xb0\x03\xc1\x11\x12\x02\xa6v\x04I\xeb\xb68z-\xa5t1DiB\n\xd2\xdd\"\xcb\xb6\xdc\xc8YTJ \x83\xc4.\x9a?\xd40\xc77\xe0\x80jL\xa2\xc3N\x9e\xfa[2\xfft\xc8\xc2\xc4\xae\xcc\x8e\x18\x86\x8d\xe6\x00\x0b\xf9#\xfe6?E\xd7\xbb\x86\x94\x8c\xd7\x10\xa1\xae\x88:\xc9\x9e\xceY;\x83\xe7\xacA&q\x85\x13\xeaS\xd8IR\xc8)\xc9s\x05s\n9*x\xd2\xdf0Bj)m\x06\xec\xe1H\xa7A\xbe\xf6hy\xd0\x8fh\xf2Mm\xa4&4\xc5\x8a\x854\x80\x0b\x80\x87\xdc\xdag\xb8\x9fV\xe6&tY\xf3\xda\x1e\xa6\x02\xcfOCS0\xb3Y\xb2\xf4\x82d\x077Mv\x8d\x07N\xefj)w\xeb\xf7A\xc9(\xac\xe2o\x7f\x0d\x1f\"\xcd\xa2\xc9[\xa6\xd6\nE`\x9b\x94\xfe\x8a\xeb7ez\xb8\xc4\x8f\x86\x9d\xbb\xde-\xb7Q\xc0]\xa66\xdb+\x13Bca\xcd@^I\xc2:\xb2\xd2\xbb\xb4\xde\xfe\xbe\x1d=\x83\x02\x97\x9a\xad\x88sS\x9f\xe4\xcfn\x1dc\x08\x11\xc7\xf9\xd3 6\x1c\x0d\x82\xcd\xe7O\xe3\xa1B\x844\xbd\x88\x9f\xe7\xa0L\x1b\xa5\xa8\xc0\x07\x07Gp\xe3B\x89q/<\x95zA\xe3\xd3C\xc1\x01\xa5\xbb \x80\x05\xd4A~\xb9\x12\x16\xc9x\xd00\x0b6r\x17ih\xa3\xcdh\x1f\xa4I\xec\xd8\xb7O\x82\x03N,:\x0eo\xc7\xc1k\xec\xe7\xda\xf6\xc5/\xf3\xb8{H\xb0\x14\x15,\xdbz\xd0\x82g\xdaf\xc8\xbbz\x97\xaf\xd3\xce\x805\xfd\x90F\xf5\xb2\x14Tr\xc0n/\xe4t\x11``l\x86\xc1\x14\x06\x06\x99*\x08H6j\x1fT\x0f\xa1\x1etG\x04/x\xf8\xcb@P@(\x84\xc4I\xe8p\x0d\xd2e\xba!\xf9\xea`wv,:A\xec\x91\x9c\x0f\xb9\x0eN\xa3 4}09\x01z\xc7qC\x90\x17\xec\xe4$r\x00\xec\xfc\x02\x0eM`\x19Y\x86Q\x94\x92\xa0\xf8M\x7f\xe4\xe4\x95\xab\xb3\xf7\xc4(|\xe9B!\x0f\xed\x08>\x1d\xa2\xc1\xd8>\xabO pwj\x08 A\x02*@\x9b\x12\x90\x1f\xaa\x9fJ\xe4C[h&3\x8d\xfc\xebB \x1fQb\xfd\xcf\xa9\x108\x0b\x85:\xf1\x93%f~\x81v\x01/\x8bl\xe2S\xe4\xd0\xe8\xd20\xdd\xe8\xfe\x02\xd0\xf00a\x19\x93\xb7\xb6\"\x8eB\xe68(f \xfauGo\xc7\x9a\xc8\x0egy\xf1\xc5\xd7t\xa3_\xc3y~\xc0\xcd\x94\x8e\n\xc3%\xe4\x07\x85\xb0\xfb\x1dm\x90\x0e\x86L\n\xe8\xe0!I$\xe4Xt0\x83\xcf\x12\x80~\x16\xc0e\x8cP\x88z\xcb\xcd]\xa2U\xecg\x0d\x7f\xd0\x9d=_\xb1?\xf1\xba\x1b\xb5\xba.j#+`li\x91\xa1 \x1eB\x8a\x0e\xf1\xe2M5\x9b\x1f\xd2 \x0b\xba\xbf\x10\xc5\x91G\xd2p\x8c\x9e7\xaba\n\x86\xd6\x92\x1f\x8f%Y[\x18UG9\xe6\x99\xf2\xc6\xd3@\\\x05bD\xea\x1c\xd0Y\x1c\x85\x92{\x89\x9d{\xa4\xf0\x0eED0\xae\x97\n\xd6\x01$\x8d\xa0\x1bQ\xf8+FvC\xf0`\xdd\xa8\xec3\xb0\xfdQ\xa5 \x93\xee\xb1\x10E\\\xe0\xd0uC9\xcd\xe1\xc3![\x80$\x12\xeal\xef\xdf\xf5\x0b\x9a\xfa\x90\xea\x10\xf96\xdfD\xa8o\xd9Dg\xc0G\x88*+\x8dX!\xb8\x8d%#\x82C\x80q\x91\x0c?\xe9\xad\x0f8\x07ZU\x1aB)U@\x07\x08o\xa2\xcfpg\xde\xa9\xb6\x01Z\xd8q\x85\xa1\xa1\xc98\x8e\xca9\xf8\x9e\xc7|uc\xe1c\x08A\xd1\x9c\xb6\xad\xe9\xb0\x10\x95W;\xa9@\xe1\"\xa0\x11\x80\xd8\x19>P\x82\xd3\xef\xe5h_\x99\x9d\xc7\x109}.6\x80\x84\x90V/\xc7O:\xe03\x1b\xb4}\x8e\xa1\x13Z\x1cS\x0c\x1b\xb1\xb5\x9c{:\xd8\xda~\x92\xf3\xfe\x9c\xc5y\x0e\x1f\x8ak\xa6c\xee\x16\x88\xa4O6;O\xceB\xe1=\x97bV\xf1. R\xbfk\x8b\n\x01o\xf1\x0b\xa4\xff\x07^\xb1GV=\xe1\xd8 }\x11\xefoI\"+\x0d\xf4\n]w\x87\x81\xd7F\xaa\xc1z\xcf\xb7\xe4\xae\xf6`<\x93\xc9\xf5\xb230\x9d\xfb\x1f\x17h\xf7\x8c\xc53]\xeaR\x1ef\x7f\x05\xfa\x97\xbf8\x145\x04\x169s\xbc`K\x85\x06\x1e\x10M\x80\xa48\x03\xf1\xcb\nX\xbbUq\x88<\x89\x98\xa5\\\x98\x93\xc6ZO\xe0ss\xe8\xbfM\x92\xb7&\x03j\x1c&\xcf\x0d\xc4\xd6\x06\x02\xf7 .\xa7%\x9f\x0e\xa0\xd2P\xcaBL~^\xe4\xdf\x01\xff\xf9G\x88\xcb\x88\x913p\xe1D\x87\xac\x95:\xed\xb8\xd7\x1a\xa3Z\xbf\xa3\xc1\xb9\x04\xa8\xa9<\\\xf1\xab\xc7\xa0i\xaf\xa8\xdbW\xcc\x86\xa8\xc8\xc2\x10\"(\x94\x1c\x83:\xe1\xc5\xe2z\x8b\xa9\x96\x13X\x96~\xea\x81\xce0\x05P\x18G]8\x90\xef\x82\xbc\xaa\xac\x83\x8c\x88RQMN\x15T\x00\xa6qf\xddW\x03~!\xdd0\x94R%\xd5\x91\x9d0\xf0xvGFy/F\xf8-\x9b\xcfw\xfau\x82/\xf4\xee\x1f*\x7f\x01\xeb\x07+\x92\xc6 \\\xf5\xc28@\x886\xa2\xab\xc2\xfe\xa9\xb4\x8b\xbbc<\xb4\xe0\x0e\x1a\x16L\x02\x83;c\x8d[\x9a\x1e\xfb\xf7\x8a\x07\xdb\xd9\x07\xc2\xba\x0bnr \x9fQ\x15S'o\xa3Qu\x18\xf2T\xae{\x08q\xd2\x90\x90_\x9c\xcd\xbf\x8f\x83\x83S\x04d\xaa\xbbA\x04*\xc3\xb0:m\xf28Yuz2\xffPB\xab\x0d\xecHh`\x18l\xb4k\x92p\xe8\x13\xffLLh\ncEb6e\xdb\x8f\x00\xd2\x8b ?!\x84\x99\x10>|\x0b*=V\x8d\x01\xfc\xad\xbbK\xee@\x9e\xeb\x93rx\x910\xd3G`%\x08ryr[6\xea\x8aY3\x8c7\x8c\xc5\x0b\x87f\x17*\x97*\x18\x1bn\x95\xe0%9\x99\xdadf\xc3\xe81\xf31\xde\xa2\xda\x81^'\xcc\xfd]\x89\x9a\x96\x0dR\xcd\xdf\xe8q\x90\xdc\xd4.\xd8\xea\xf7\x00,\x9c\xf6\x95\x89\xd3^%\x84\xafl\x1a\xc2\xda\x11\xe2\x0d\xe3\xbde\x14\xd8\xd8#wW\x1e\xc2\xd1s\x12\xf356!\xd9=\xe2\xe5!q[\x04\xf6\xb0\xc4\xd8\x0c\xc3\x00%\xc8\xd4\xae\x18]\xf3\x8b5^:\x80\xbdm\xa85\xa9\x10\x10)\x01?\x11\x90V\x0bb|\x9au\xc07f\x93\x05\xba\x19\xecw\xb0\x9c\xe6\xc4\xf0,\x11:\xe7Y\x1ee\x0c\xe6\x86\x7fR\x07\x7f%\x94\n\xf2[\xc0\x9b\x8d\xee\x0d\x10\x1b\xc9o g\xe6F\xabA\x15z\xb5FP\xa5\x12\x9b\xf2\x1d\x9f\xc0\x10\x1d\xd4x\x9b\xb6\xee{\xcf\x16\x07\x07\xed\xf6d\x82x\xc3\xad\xd6w\x01\xc38\x8e\x98\x96\x08\xd9\x94{{\x03L> \xae\x82d\xac\x13\x812C\xe4\x00L\x91\xba\xa8\xe4L\x19\xde,\x9cL\xdc\xe8\x1e,\x84\xf2(\xe0mS\xec\xf8\x12\x9b\xc3\xd8\xe5\xe5$=\xd1|%\x9d\x15\x06\xd6\x9dlu\xe8& \xc4\x85\x94\x1a83\xe3\xda\nN\x0c\xa2X\xe5\x8ax\x0c\xeb\x0b\x04\\Vn\xf5\xcd\xef\x9eJ[)I\x9b\xea\x0ew\x8c\xc4/\xd1\xe9\xb9\xbb\xb2\xda\x0c\xb2\x7f\x18|\xa0G\xc5\xba\xd9\xd8Y\xd7\xc1\xf0\xf7DH\xb5\x98\xbd*\x9b\x12S\xfd\xaa\x8d\xee\xe8\xa4\xe6\x92\x1a\x1ap6\xae0\xd3c\x8fJ2\xe3@\xc5W\xb4%\xd1\xa6c\xef\xbc_\x1a^\xd3$\xd1\xe7#\x08*:G\xa7\xae\xe6\x186\x8e\xa1\xefn>\xcdD;\xfa\xf9\x02\xa5\x90~\xa4`9\xebhXB \xf1\x1dU\x8e\xabJ\x03B_\xd0\xb2\x88\x98\xf9\xcb\x88\xee%\xaa\xfd\x92\x01\xb4w\x17'\xb9$\xb3\xe8v|#T<\x0f6\x078\xe7\xaaKM\xb6\xcf\x91-\xd95U+\xbe\xb6\xa1'\xed\x06B\n\xcb\xc4\xaaN\x85\x91\xf8\x8ebJ\xec\xc3Ov'\xc8\xec|\x8b\x84+*M\x8c\xbck(\x0fd\x88\x0d}\x9b\x10C\xda\xcb\xb1@\xa0\xb3\xc1q\xb0\xb3\xb9\x04&\xf9aR%}\xb4\n\xcb!\xd6V\xd0\x83\x91s\x113w2\xa6\x8e\xd1a\xb22\xb2\xff\x8e\x17awH\xe6z\x10\xa1\x17/\x8d\x9dQ0\xf0\x02F\xa6 \xd9]~;\x03\x9e\xa5\xc3\xa4\x9d\x12\xcb\x15\xd6 ND\xf9P\nm\xfc\x98K3x\xde\x15\x8ake_\x99\xa3\x0d\xa0\xf1\xf3\xfeS\xaf!\x90\xa1V&=\xb2\x05\xb2\xaa\xb2\xbav\xe7\x19\x19_P\xc0\x8dL9\xd8\x83\x18Y\xa3\xa1i\xbf\n\xa7NU\xad\xd3_\xb6\xac\x11\xaf)\x96\x17\x83\x90J6\xdd\x7f9\x91f*\xca\xf0S \x10\xb1 \x11\x1d\x8f\x1e1\x007\xdaF|\xb8BR$\xc9\x15\xb7y,\x19\x0e\x04\xc6\xb1.\xbf\xc0\xd5&=uqs\xe1\x18\xf3\xa1OD\xc5\xf2B\x9b\x1f\xc8\xf4R\x84\x19=\xe7\xd9\xc9\xb3\x97e\xf8\xd8\xbd\xc9\x87\xe0\x1bB\xae\xac\x03\xe4\xac\xd6H\xad\xa1\xae\x13\x01\x88\n\x1d\xaa2lu\x03'\x9dh\x117^#\xffS\x85)\xa3Xi2..P\x00e\xa1/@F\xd5K\x13\xc9\x11\x91$\xe9](\x1a\xd8%\xe0|\x962\xc9\x1d\xf0\x13Y1\x10\x05pC\x9d\x07\xb18t\xc1\xf9I\xf8\xe311\x14N//+\\\xbb\x93p\xa5j\xd4\xc4\xef\xf4d\x80\x94\x18\xce\xe1\x18\x00W\xcam\x15\xe9\x9b\xc3I=\x04\xdf\xbd\x12\xb7\xd3\x08Y\x03\x93Zx\x1e\xa1\x01\xd4M\xd0\x89P\xfd8\xb2\x93\x011/\x0bJG\xab\xf5\xc4^U \x14,P\xc8d1O\xae\x14\xf3\x06^\xacy\xdfpq\x94\x13l\xbf\x81\x0e\xa32h\xdd\xd1$\xf8\x7fjv\xf1\xf8\x8b\xfe\xaa\x04\x1d\x01\xad\xcc\xf5\x9eI\x9a\xf6%\x87\x8a\xa8\xa7\xe1\xe8\xd4]V\xe6\x06\xce\x13\xd6\n.\x00'[+W\x12U8\x1b\xc1\xad[\x8e\xe5\x86\x01D\xea\x06\x92\xb3\xe8,\xdf\xbb\x05\xbe-\x0f=[\xc0\xe5\xd9\xc2\x06\x02\x0bO\n\nw\xff\x83\xa0\xbfE\xea)\xe53\xb1\xf8\xac\xe4\xf3\x0f\xbfJ&\x02\xa5d\xef\xd9\x82\xdd\xb6R\xc2\xa1\xac\x06\x97S\x96\\.\xb0 \x955J$I\x8d&\xf3\x91\x18\xddo\xaa\xb7\x1fH\xc8\xb3~\x9b l\x87\xbd\xcez>\x80\x1a\nUx\x08/\xf5H\xf1\xd0u;\x9a?Gt\xae{?\xe0\x0f\xb3;\xf3T\xa1\x8c\xaaH \xe4L\xfe|F\xfa8\xe1\x86\x03\xf0\xb2}\x88\xa1{\x0f\x18\xfa\x98\x1dp:\xdf2t\xec\xcd\x86a\xb7\xcb\xd1\xa7p6\xd1\xcf\xed\xd4\xfb\xb7\xb6\xf8\xe85Y\"L\xdaD\x93\x8c\xf9.\x8ar\xbc\xd8V\x0f\x93\xdf\x04\x91\x15\x14\x1a\xb2\x18\xdfS_\x0d\xba\xda\xcak\xfe\xcf]\xbbn&\xfaH\x8d\xb8\x0fz\xa7~\xa69\x91\xc3\xa6\n\xa6p\x0d\x15$\x1c\xa74\xd9\x82\x94\x8d'\xa2{\xba&\xa0\x01\xb8\xab\xff\xcbM\\\x9f\xce\xb0\xe9\xd1\x87\xa8\xae!\xecq\xaei\x08\x9d\xe0 \xcf\xc4(.h\x9a'\xcb\x0bB\xb1\x0bT\xad\xb2\x9f|\x0e\x1e\x9e{\x04\x06I\x846cL\x1c\xf2\xa1\x10.\xb9\x9e\x1e\xa3\x11\xeb\xb9\x8diI\xbe\xea\xab\xbf\\!\xe0\x1d;\x08\xa7\xe0g`1\xe2\x0c\x1d\xe1\xbe\x15\x95\x98j%\x10C \xb9o\x9d3*60\xf7\xb7E\x8c\x07\x98\xd8\x8e\x01\x9e]t\xe4\x89.\xd7-%0\x0dY\x1e\x89K\xc7_nft] \xb7\x17*VFC\x1f\xc6tJ\x92\xb0\xc4T\xd4\x12+\x16\xa4\\WZ\x908\xe1\xf2\xc4\xe2\xd7\x10g\x1bF\xd0\x04\xb2\xe0\x02\xd9^\n\xde\x9ef\x14\x9d\xb6 5\x9a\x12I=\xb6\xd7\xf9#6\xf6.@\xf52z\xd2\xc3;W\x9a`\xffB/\xc4\x99Q\x05\x05\xf8\x8a\x1ag\xed\xb0\xfc\x15h\x8a\x19jyJ\x9d\xd3\x19\xb0\x80N\xb2AX\xa43\xaa\xdd\x05,\xf5\xa4\x9b\x00\x0bK\xe46\xe8\x92\xeb6\x1b\x8f\xda\xb2\xd8M0\xaeT@\xa0\x8e\x85O{\xa1\xa3\x984k\x13j\x1f\xa3|\"\xacft\xd1\x9f\x94\xdb\x84U\xfc\x82\x18<\x08\x16-\xfc\x18\xdea\x86\x14\xae\xd5\x19\xe65b\x8f\xfa)\xed^R\xb1\xb08\x99\x84\xce\xc1\x9e:\x86\xa7il\x1e\x90\xbe\xad\xc0Ka\xc76@\xb5\xe6\x94\xc3!\xc0\xcd\x1a\xc3\x0f]\xa0buv\x0f\x1d\xce\x8f$ \x11\x87oU\xc7\xc2\x9c\x81~:.\x85\x10\x06\x14L\xfbt\x96\xe8\xeae\x97\xfc \xc7\x1b\x0f\x80\xa2J\xce\xbeP\nl$S\x13[z\x0e\x96\x8f~\x12Rq39\xe9\x92\xba\xf4\xb69\xebQ\x08\xef\x13\xcb/\x90m\"\x95%\xca\xa4\x89\xaf\x86\xbc7\x9f\x17\x03\x0e\x9a \xc3\xee\x1f5MKL\x9f\xe9\x91\xa7\"I\xdf\x8fG\x84 \xe8XT\xde\x8e\x1aXL\xbfF\xf0\xdd\xa7V\x0dj\x91p^\xa1/M\xc3g\xc1\xdb\xbb{\xb6\xb9\xbbw\xf4\n\xec*\xf8\xba\x80\x9e9\x0e\xff\xf0\x97\xcaO\xbe\xca\x88<\xcb\"a\x12\x1f\x0f\xf4\xc1\xfe\xf7A\xe1\xee\xef\x88q\xbf\xbb\xa2\x86.\x1fM\x7f\x97\x13\x002@m\xf6\xeb\x87p\xbf^\xda'\x93w\xdf\x95m\xf6\xc7k\x01xO8\x0b\xfc$[\xf3\xab&\x17\xc1\xfc|Y\x82Zy\xfd`2_|%\x11r\x97\x93/\xe5J?\xa1Q\xf9\xc3\x0eN\xcc\xb1l\x893\xc3\x9e\xce\xdfK\xa1\x14E$\x96w\xffv\x07\x13\x18C\xcb\x01h\x7f\xa3\xfb\x0ba@\xf7U\x801\xa9M\xf8\xbe%\x02\x160?1*\xa5\x0b\x96$G\xd3Z\xd3{!|\xc7\xca\xbf\x18\x11\x04\x10\x1a\xc0$\xc3\xdf\xdb\x95\x10\xc2-\x1b\xf2\xd9\xaaEv;\x90\x8b\xcd\x93:\xe4\xbd\x15\x8b\x9f\x1a\x06`Bl\xcf\xcb\xb8\xa0\xec\x8c\xa7\xc7\x07\xc9\xac\x9boQ\xdd0&\x8b\x02\x95\x04\xfb\xfe\xf1,\x86F?\xa1\xfd\xc6\xe4\x84^\x9ds,\x87c\x93\x99\xc1h\xcb\x95\xff$\xc3E\x13\xfccl0\xe5\x13\xbaw`\xfd\xe2\x8f\xba\xb9\xc5\x88\xa9@/\x80r\x07^\x16l\x988cT\xb73\x99\x9d\xdck@\x9b\xdc\xfaJ\xc2\xdd\x94\xb4uP\xd0\x18\x05&\xca\xaaN\xc9\xf3d\xf9Jj\x14T\x90K\xb8\xaai \xb7\xe9*u\xa7\xbb\xe9X\x96{t\x93j~\xbd\xc9\xa1}\xf9\xf1\x12\x0fi\\B\xc8K\x1den\xe2\x8b\xc8\xb5|N\xeb\xd6\xea\x0b\x9au\x9d\x92\xef#\xc3]@\x1fl\xf5CZ$iP\xe6a\xbd\xe3\xb8\xa9t04y20\xfc\x0ds\x11\xd8\xd6\xaa\xe2,Au\xc6!Q\x07\xd2\xd8B\xe4\xcf\x96\xf6\x96^\xec\x88@Vs\xc9\x91\x80\x82\\\xdeZ\xdfa\xe37\xa9\xec\xbe\x89\x04\xa9\x14\xb8\xe2\xd1\x88\xb3\xbb6-T\xefr\xb1\xc0\x17\xe4U\x98\x8f\x0b\xe0u\x18\x93\x8c~\xeb\xb01H\xc2J\xa8(<\xce\xb1\x8e\x82\xf2\xbd\x90\xd3\x1d\x0e\xb3bR\xd4\x96\xb8qi\x0b\xcf\xe9\xe6\xa2\x10\xacJ?\x1f\xede\xffG\x00\xc1\x0d\xa7*jV\xc4\xa7\x0c\"\xe1\xd8\xe3\x86:\x0eY);\x8f-F\xe5\x06\x05d\xf4\x17!\xf0H\xa3\xbb\xd9G~\xb4\x95\x1fu\xa6x cb\x8f6m\x95\x16\xbc\xf8)&;\xf10\x1d\x87\xcfdU?\x878\xc5X~\xef\x9f1\xd12\x8f\x9a\x17\xdb\xbc\xa8t\x80\x88I\x00\xd8x\xe85\x03\xc4\xc0{\x03(\xebz\x84\xea\n\xdc'\xbf\xfb\xff[\xa0\xc5\x83k\x8e\x08\xe8Z\xd0\x85\xd8\x12\xec\xe9\xcdi,\xf0\xc5b\x991\xcc\x87\x8b\xa2\xcd\xe1`\xba\xb1(\xf4\xaam\x8fH\xe1\x81N\xf0\xec\xfce\x89K\xa4\xb0\x10\xdf\xd4/\n[\xe0\xb4(\xf5\xf6#Q\xf4\x97G\x06d\xcau\x1a\xceT\xa9\xbd\x7f^\xf8m\xb3\xa2\xbf%\xf9\x86\x8c\xc5!(\x987K\x1cg\x03\xe9\x85P=\xe8\x13h\x0e\xf8\x1f\xcf\x95\xe1k\xc9\x90U+\x8c\xc2\xc6.[\xd2e\x05\xaf\x8b\xcf\xd0\x03\xbc\xb3C\xc1\x8f\x9e\x8f\xff\xe5\"GD\xff\xce\xa8\xa3\x9b<*<\xd6\xcf\xfe\xe9h\x0b\xab)\x18\xa4` A\x98U\x0c@O]h\x14\xfdl\xc5f2\x94\x85!H\x9e\xe7\xcfF#\x00QB\xc2\xe9=u\xc8\xbe9f\xb4h\x07\x80\xf3;\"R\x84\xa5\xda\x00\x92\x01K\xdc3-\x82(\x08G )\x05\xbc\x19P\xb1\xe1\xf8\xa1\xa8\x9e\xa6\xb2\x10T],7\xc1ec\xde\n\xeb\x1d F4hH\x0c\xd3s\xb3\x1473\xe1\x96\x9f\xa0\x12\xa1\xb2\x16\x0b\xe2\xdb`\xe0\xbaR\x96\xa1T\xedwf\xcd\xb3;6B\xf3>\xc5\x98\x0d9&\x15\x06\xc8\x1b\x05\xe2\xdb\x06\xd1\xda\xdc\x82\x02\x05\xce\x08?\x92\x97\xf7\xf8)\xc0\\\xa8\x8c\x80\x81<&O\xcc\x86\x99\x1c\xf05 \x11L\xc3Ju\xa5@Y\x9e\xdd\xdd,\x1d\x90\xeb\x83\xb2\xda\xbe\xdb\x04_w\x07\xc20\x98\x03^\xe917\xf1\xf0\x08\xf0\xf6\x11\xecp\xde\xbb\x87*>D\x948\xe3\x9f\x11\x98\xfc\xb0_)$U\xc5\xba\xf3\xca\x15R\xb4!j\x1aOF\xf4\xd6>{\x88\xd0\x1f\x92\x91\x0b\xbbt,\xaf-\x1c\x85bP\xb5,m`D\"/\x9fz\xf0A\xe2\x0d\xcd\x94\x02\xd8\xa5\xea\xdfQZG\xd5&U]\x90xej\x04x\xe6\x13\xe5Lwv\xf5~\x10\xb2\x9c=)@\xd8B\x1b\xaf\xd6\x086\xca?!;5\x143/ps@\x02t\x83OZS7\x10\x03\xa9\x94\xa7\xd8\x99\x14\xae\x92n\x9f\xd8lx\xe8\xfb\xee\xffZ?\x12\xe1\x83Z\xf9\x97j\x03\x0da\x0e\xb2\x96\x15{\xfd\xfb6\x97\xa5\xff\x19L4\x9b\x8a\xab1\x9f\x03\x7f\x0b2\xb9\xb4\xf9\x0e\xaf\x8bQ\x87i\x18\xdc\x19\xfd&\xd6\xa5l\x83\x88\xe1\xbd\xc5\xec]o=\x03\x1f\xa07\x1d\xc4\xc4\xbc of\xfc\xd0\x96\xfcr\x0bMEV@\x83\xe2\x0fH\xf5\x03\xa6\xe8\xf2\xfb/\xe8\xfda\x08D\xa5\xd9\xa6\xebH\x95\x83\xae\xaelK5)\xc2\x8cZ OE\xb4\x9c\x98\x1f\x84\x053\x10\xc1\xa6I\x01G\xa9'\xd0\xb3\x0f;\xeeD'\xb6zl(\x91\xa0\xf7\x9dE\x9f\xcf\xd1$\x9d\x8a.\xd9\x9c\xf0-W\x0c\x07R'\\w+)\xc2w3\xe6\xea\xba\xbe\xf9\xb8 @\xdb%R\xd4\x14)\xff.\xf2\x07~\x8a\x14\x059\x05;]\xf4\x14.\xc2\x9ag+)\xd8\x03%\xc8\x9d\xf6k\xd5\xce\xc0\xd2\x89\xb3\xa8^\xd2\x1f\xf6N\x80\x06W\xb7>b1z:\x1ds\x86\xa8oD\nK\x8d\xf6\xb2\xba\xc22w[|>9\xe2\xaevWMF\xe2\xafu\xde`\xb9\x1c\xeb\x13\xcdax\x87ch\xd5\xab\xf5U\xb7\x14\x81`*\xca\x86e\xfb]O\xa0V'6\xfd\x87\xc0\x03\x83x\xd4d\x1e?\xbcH]_r\xf5A\xbb\xa3+z\x11\xc0d\xadF\x9b\xafH \xc4\xca\x8b<\xa4\x1e\x01\x85\xc7\xb4\x1d\xa3\x04\xd5\x02\xc6\x04\x17kUsFz\xc0\xba\xf2\xcfaH\xd6\xc79\x07-\xb3\x9c\x90\x00\x98\x83gv\x82b\x07\x8b\x1f=\xd3\xebL/\x11\x9eE\xbb)\x10\xb0\xc4.\x98\xbdx9j\x13%B\xe3)\xa0$\x97\x8c\xe9A\xcbB\xa2\x8f\xe6\xec \x83\xdb\x1a\x9f\x01t b.b\xd2\x02A\x10E\xa8\x9eZ\x8dRb\xf6H(\x91\xa3\xf5J\xffya\xe3\x88\x1e\xd29Wj0\x05f\xa4\x1b\xdfF'\x9b\xb0X\xe0z\xbe\xc3\x0b\xef$DQ\xad6\xb4\xeb\x9eq\x83\xd8` o\xca\xd0 i\x14=\x81\xe1\xc1{#4\x14\xa4\x13\xa9FYH\xf9@\xd8J\xd03\x0d3i~\x91tY\xd0\xa2\xd9hk\x05H\x87P\xcf\xf1\xd7\x0f\x17\xf7\xfd17\xd3\xe0\xe0\x04\xa5\x86Y\xdcD\x97\"\xdcp\x97\xc4\xa6;'\xb31\x026\x80\xc6f\x97pu\x18\x02\x8b\x17\xa0\xf4\xbe\x04>\x11\xfeF\x9boD\xc5Qi\xa8n\xe1\xcc\x92\x8d-\xcf\xe7\x0c@P#\xe4\x9a\x7f\xab\x87 \x12\xa6h\x93j \xde\x82\x06\x88\xc5\x80f\xb4\xb6C\x0e\x18\x96 \x96\x81\x837\xc2\xb0\x01\x94\x17T5HVX\xc9p\xed\xf6\xc9\x02k\x12l\xc4\xad\x8c\xb3\xae]\x99\xdayX\x06r\xc6)?\xcd\xba\xd3BNJ\x9a\x0cB\x83\xf7\xf8\xe4\xbd#\xcb\x07\x9b9e\x18\x14\x94\x00&&\xbb_0\x95\xd3\x1f=\xae\x9a\x7f\x7fp\x15Z\x14\x8f\xc96\xa7\xaah\xa4\xd9)\x03\xf0\x0d\xcc\x97\x83a b\xc0\x8c\x15\xed=(p)\x87\xe2\xd9\xe5\xed\xac;\x8a.N\x10\x95,\x93\xc3W\xed^\x0c*\x03h\xd4\xba\x8aC\x97\xeem}E\x997\x00i\x10\xf5\xe0\x876\xc1\x82\x06\x02\xc3\xf7a\xcbI\xedv\xcd\xb2xp\x83*A\x7fc\x14#4\x82\xff\x17\xfd\xfb\x8c\xb3\xc7\x08\xa0N\xf6&\xf0`)\xae\xc4\x89\x88\xa3H\xa3We\x9b\x83y\x127jl\xa1\xef\x08\xb0\x00o\xdd\x13Eh_n3 \xad \x8bjp?\xaa4\xe8p2W\xc0E\x05\x1d'kT_\xe3\x0d&\xa3\xb0!\xc8\x96jVl\x98H\xed\xd3\xbb_k\xc9\x9a\xe1\xc8\xe2\xf6\xca\xb3\xf9\x0faY\xf9\x8c\xa0\xa1\x1b s\xce@\xe4[\x85\x04G\"\xca\xd3bY\xd5L\xdb\xdc\xabX\xa6\xaai\x8f\x0d\xd5C\x90\x98\x11q8\x01\xf1&\xfaz\x90\x90VaY{\xe8\xc6\x0e#I@\xb5\xa7\x7f\x1f\x9d\xad2\x98\x8em\x06\xf3!\xf4d\x01\x8c[1 \x85A\x10\xe0\xc6\xa2\x9a\x07\xffnK\xe8\xf0\xf2\xd5\x06\xc6e\xd7\x9d\xb2\xe5/>\x1d\x10\xdfd\x83\x02m\x86uX:x\xca\xb7\\\x84\xe2p\xf2N\x91\xfb\xfd\xa9\x1el\x9d+\x83H+c\xc7tS\xc7\xb6\x82\xe6\x1f\x14C\xc0\xb1[\xed\xe0~3\x8c\xcde\xc0}6\xb0 \x8d\\\xb3,\xce\xf1\xc9\x84\x98\xd7|\xa4Y\xf2\x04\x11\xdd\xa7\xe7\xf8\x98\xa7v]\xac'\xfb|\xbf\x9e\x9f\xeb\x08&\xed\x96\xecM\xf42\xb0 d\x10\xf5\xac\x00\x1bds\xe0x\x03-((76\x94\xa9a\x05\x03X\x9b\xbdm=\xd5\xee\xd3\x8a\xbf\xe3Q\x88\x97<$\x02\xaa\xaa\x00\x80\xfc\xf3Q\x05\x1e\xc2\x86\x98\x84\xba\\\x90\x02\x93\n\xd4\x0c\xaaqi\xe9H\xe9\x98\x87\xac\x8b\x89i\x06'i\xa4\x94$\x8f\"\xa3{S*V\x8fwF\x8b\x93/\xb0t<\xec\xca\xc1\xe1Q`\xca\x92Z\x16\xb8\x9a\x1e+\xf0pr)\x9b(\xb9.\x13j\xb5\xe9\xb8\xabI\xfck\x035\xf5 <\x04\xe4\xb4\x12\xca\x86\xb1\xcb\xae\xc9\xd6, k\x1bO\x91\x87\x9cDT\x88\xcaJ&^\x0e7\xba\xa3\x07\x87\xc4\xaaQ\x8d\xfe\x10\xa4\xcb\xcfv\xdfe\x10\n&\x9eZ\x90\xd8\x08\x92\x0d^4\xfa\xc6^\x06s\xb0\xf1D+`WH\xb5\x99\xae\x11\x81b\xec6\xd9\xc4\x05\x14\x05\xa9\x98 \x08\xb8\xae\xc8L\x9d\x98W{ZZ \xa6@\xb0\xe4mq\xe1\xfbv\xa6\xc9\xb7(\x04D\xc1\\+\xd4l\xe5\xe9\x14\xfb\x140*\xa5V\xa5\xdf\x87\xb0Vm\xd5\x1f\x8a\xa7\xe6h\xc6\x8f\xe6\xd8/S`|\xb3^\\<-\x99\x84\xa9\xc36\xeb\xb82\xa9N3\x9d\x82\"\x07\x0dT\x12o\x9f\xf3\x06\x04\x8clr\xe4\xc5e\xa0\x82\x12!\xf5\x04\xc5H2\x0b\x8b\x15p\x83A \xd6\x9b\xa8\xa0\x18\x87\x02\xde\xc3\xcf\x02{\x9b\xc8\xbc\xfe/\xa3\x1e\xf2\x9f\xd1\x00\xe7\x9cudU2*2\xf2\x10\"c\xab\xcc\"p\x85${\xa9\x80y\x81,\x0b\xe9\xa5\x8b\xf6\x11\x11\x1c&\\\xe0m\xbe&\xba`\x1c\xd0|x \xa6p\x85\x88C\xaa\xd2w#\xc2\xc9\xfbW\x909D\xadI\x07i\xf1\xd1\x96C\x88\x8f\x11\x9b\x02Ks\xef\x96\xe7\x87\x9d\x1dS\xb6\x07\x93\xe33\xef\x0c,\xb6\x0e\x91\x15\x96\xfeM\x9b\x92;\x1dj\xa8\xfeB\xeb\xa74\x9a\x9bP\x9b2\x02\xd9\xd9i\xb5\xee\xeff\xb6\xae\x00\xc9\xbf\xed\x17\xc1bA\xad]a\xa2id\xed\xc2\xf0\x10\x8a\xad\xa8\x0f\x86\"\xc4\xf2\xd7\x13i!\x07aQh\xd4CNO\xbd\xb1\x9e\x8a\xef\x82\x1a\xf5Y\xed\n\x93x\x06\x12F$\xc4\xf8g\x979\x16\x14\x9e\xa5\x10\x91Z`W\xab\x1f\xb0\x85VB\xe2g\xb8\xb1\xa0\xec\xda#j\\\xcb\x82\x97\xa8\x80e\xf9G\xf1\xfb\x1c\x0b[\x13\xb3.\x0f\x1d\xe0\xbe]\x8b\xaa0\x13\x14\xba~X{2\x9bD\xa9\x84?\x0b\x8a\xf8\"\xf3\x8a3\xc4B\x07\xe1j\x14,\xc0\x10K~\x0f\xc6\x06\x00b#\x840\x02\xac\xc9\x92L\x98\x01kc\xcd(6 \xb8\x0c\x02\n\xb1a\xfc\x04E\x1a7\xce\xbb\x81/\xd5\x8e\xaf%\x00\xad \xfc\xb1\x03\x9c\x0f\xb7\xef \xe0\xc9\xc4\xa1R\xeb^J\x14\xfb\x1b\xeb\xc5\x12\x04C\xcf\x8fZ+71X\xdb\x1a\x13\xb4\xd0UO,\xc1\x84\xf6\xe1\x14}\x0f#\x90-\x94\x90e\xd9\xa4\xa04\xf63\xc5\x82\xf0\xedt\xc3\x048\xa7\x99Z\x047\x08\x86\xcei\xe0\xac\xca<:i\xd1?Ft\x8bFk\x96\x7fC\x0cW'\x98\xea\x01f0\x01i\x02\x1b<\xe2Xdj\x97\xf9\x10\x8c\x940\xdb\x12W#i\x13\x8b\x0e\x8b\x9a\x96e\x08C\xcf\nzI7\x88\xce\x0eB\xb0\x03s\x18\xb7\xac\x98.K\x83\x0e \x12 *\x05\xeb\x8d\xddV\x91\xb0\x9d\xab\x12d\xff\x87\x9fD\x81lj\xf6@\xec\xab\xef%\n\xa9\xdc\x88\x9d\xe5\x9d\x0d\x15\xceZ\x88\xc4s\x18\xdd\xef\xae\x90sh\xcc\xb8%\x87^\xdf\n\xfd\xe8\xf8\xcd\xf7@\x188\x86\xf2\xa7\xa4\xf8\xce?\x0b\xa0N\xba8g\x17\xd4G\xf8gr\xa8X\xb0\x14\x17\x80S\x83\xbb\xa0\xfc\x06\xe4\x1b\x95\x0dAp\x0c\x91\x07\xb3\xba4\x87z*\xf6\xb94\xe1\x81\xdd\xe0\xa7,\xc3\xad\xb9\xc4t4G\xd9n\xd4\xe8\xf7\x91\xbc\x15\xf5dS\x0f\xe5\x13>f\xee\x94Q\x96C\xf2\x10\xcf\x1eWUZ{S\x08\xd9;N\x8f\x08x\xe5\xbd\xca}\xb0\xc7H&\xba\xbc*\x0b\xad\x009\xd7\xb8\xafq\x13\x8b\x9aU1 \xca\xf3\x0ca\xa0`(\x11\x7fM-a\xc8G}\xd5n\xb6\xcc\xbd\xe8\xa2\xda0 \x96\xbcp\xca\xd4\xc7mcn\xf1\x8e\x0d\xf2\xf0\x82\xc9\x98\xc0_\xfa\\\xb1\xfc\x17l\xbc\xde\xdb\xe0\xfe\xbb}\xce\x18\x1a \xc8\x00\x0b\xde9\xf7F\xe1\x1cv\x9eH\x7f\xc3\xbek\x83JZ\xfcNO \xe5\xb4m\x08Z\x81\xe1\xc1Q\x9e\xed\xd2\xa4 aS\xfb\xebf\xfa\x16\x81\n)\x11QC+2\x16\nd\x92\x98\xa1[\xaf\xfd\xbb \xcc\xef\x03\xc1\xf5H\"t*\xde\x0d\xc1c*b\xcf\xc6\xda\xa2\x01\xf7\xafq\xb0\xa8,\x05\xb5\x99\xf3\xe3\x13#\x01S\x98\x9f#\xa2\xe4u\x9b\x14\x0f'\xd2\xac\xf5:4\xa9\x1das\xa5\x03\xa9\xbeCDM\x90F\xa7\x13|\xc9\xb8m\xa9_\xc31L]\xf6\xe1Y\x98\x17\xca\\\xc0\xa7\xfd*\xa4X\x9c\x8a>t\xfa\x96\xaf\xb8\xcc\x16g\x8b\xa7\xd8D\x1c\x89\x9f\xa3\x8a\xf8\xe8\x0f\x04d@&[\xb0\x19)8\xc3\x18\xce;<\x9c{\xf3\xca8<\x11\x96\xc8+VG\\\xb0H\x98\xae\xa6\x1d^\x8d\x04\xafa\x97\x8ba\x90e\xdd-4\x94\xfas\xdaJ\xd4A \x1b\\\xe0\x0c\x90hM[\x82\\`\x14\xf0\x12\x93\xbc#\xbfpD5Z97g;\xb2\xf7BW\xe2m\xce\xe4\x89qTXX\x91%0\xb9\x00v\xba\x9e\xe3\x86\xf9&\xf9\xb7]E\x0b\xb9\x17\xdb4]\xfbF\x10\x9fIJ\xe4\xa4\xf9\x96\x9c\x84&\xddS\x8e_\x12\xa6\xee\x834\xc8R\x890\xa0\x02\xaf\xa5D\x05\xfc+\xcbme\xb9\x04\xd4\x05\xa8Y \x83g\xf7\xd0O\xf8\xf1+M{\x940\x06\x0f3\xcfv\x00'\xcd\x85f\x85\xc1\xc5t\xaf\xe1\x00\xe8\xa0:;\xf4\xd8\xb1\xca N\xf4\x07\xa6n\xe0\\\xc7\x94^\xdc,\x0e)1\xdel\xe3\xe1\x92aB\xef\x03ZZ\xda\x01\x84[\x95\xe0 \x04\xb8\x9d \xfbZS\xd2\xd2\xe4\xbcUYh\xdc\xdf\x86\xcf\xcaw\x7f\x80\xf5\x8b\x08\x9aS\xb8\\\xae/\xa4*?zQ\xd0\x8b\xff`\x90X4\xef\x1cg\xb9r\xed\xdb[\xa7\x08\x8aCW\xe6\xdbG\x16\xfb\x14.\xa7Y\x84\xec0Q|\xfbR\xd4\x83\x82E\x8d[w\xbe\xa6\xee\x84y\x83)\xb8\x10\xe1\xef\x91\x1a,\xd1\x88\xef$\xcbNK@c\x1d/b\n-#Z\xafI\x0d\x1b\xb9G$\xc6\x97\xaf\x99\x8btm\xe7\xcaH#\xea\xf0\x7f)X\xa3wP\x11ZAD\x7f|\xa2S\x0do\xfdf\x90\x8a\xf5T\xa4\x80\xddH\xda\xeb)\xb8\xce\xe4\xd3\xe7\xc7>\xaaM1\xa0b\x0d7\x1e\x03\xe1\x0e\xb0\x85\xc9\x86S\x8bu\xd0\xc3q\xd7\n\xf6\xb7\xf6jK4[s\xf0\x08\x84\x87\x10 \x1e\x95\x97\xd7x\x02L\x0c \x9b\xd6\x13\xbc\xc7\xa2\xa9\xeb]5\x0b\xfa!M!\x1fA\xbed\xc6\xa7N\xa0\xcb><\xab:\xc7\xbbZ(\xb08\x90\x86\xf8\x9d)e\x85\x0b\x84\xdf\x0d \xbb\xa5\x99\x86/\x99W\x15\xd8\xc8\xc0|\x0d\xfd\xb0b\xaa\x19\xd8\xe9\x88\xfa<\xe9\xf7\x9c\x83\xaeT?%\xc3 \x03\xb2:@\xb1\xe4\xd4,-\xe0\xf8\x80ecMP\xf08u\xa4m\xb0V\xd0g\x8d\x8c9\x1cH\xe9\xf66\xae\x1c\x12\xcb\x0f\xe7\x8b}\x0f\xbe=\x03\xb35\x00\x83\x81\x97Ab\xd2\xc4\x8e\xe6\xfd\xcf\xec\xb0\x81\xac\xce\x99\xc0V:\x92\x9d\x85_\xa0\x1cle\x1d\xc9\xb9\xdf\n\x11\xcf\xca\xee\x96\x95\x16v\x17\x0b\xfd`\xcd\x110\x8e\xe4!$`G\xc1\xe9A\"I;$\xdf^?\xfa\x81\x02\xae\x8a\x13\xed\x89Ke \x05O\xa2\x15 \xcd\xf7\xb3N\x0f(\xd5\xbd\xe7\xf6\x93Yy\xca5B\xe7\x1a\xa1w\xb8\xd0V\xb9%\x88ju;)\x16lF\xb5oa\xe5\xec\xcb\x15\x9b7\x8f\xf3x\xe9\xff\x92\xda\xb8\xd84-\x89\xc9%\xeb\x9d \x05\x86\xf0$\xcf\xd6\xb9/zsk\xc7\x98(sh>\xbb\xc1DD\xa9\xc5\x83\xc9t\xa5T\xc4\x117\xf6rur\x1a\xc0\x16\x9c\xb80\xc9\x1f\xd2\xa2\xa0`\x02\xdc\xb4h5\x0d\x025\x90\x8c\xa6\xc9\xe4\xb6\x00\x93S\xe1}\xb8\xd1\xdd\xc8\x15\x06\xff\xd24\x1bhrva\x12\xbc\x03\xe9l\xe9c!ZjB]\x81\xb9\x8e\xa6\xa9\x1a\xce\x7fx\xe2D\xaf\x18\xb6\xffb\x96Tx\x8fzYS\x82\x1f\xdf6_\xf6)\x83\xcao\xb0\xd4p\x08>\x98#\x8f@P\xa2S\xd3*\xfdb\xdcS\\q\x0b\xc6\x8bx\xf1YfQ><\"\xf3\x7f\xb7\xb2\xe3\xa2\x0dY\x1c6\x91\xc5\xf2I\x1fE\x0e\x00r_7\xf1\x88\xd2\xb0\x0cV\xd4H\xc3!\x00\xb3\xc5I\xe7r\x8cEL\xe7\x8e6\x19\x9e!N\xbb\x00\x12\xf6q\"'\x92\x1cd\xa0\x93\x01a\xfeqMv\xba\xc5\x0f\x8bA\x1f\x82%\xed\xf5\xba\xba\xbe \xf1v\xb3\xed\x15\xbd\x8e\x0bn\x1f\xf0.;\x1f\x9a\x1f\xebA/\xcf\x07\xe7\xb0\xf42\xca\xb2\x89\x9ca8D$\x17\xff\x03GWv\x85#\xcc\x8f\xfb\x0d9\xaek\xc5\xc5'\x06\x01\xfc\x89\xcbo\xd8\x9f\x9co\x80@\xe2\xfd\xcc (]gk\xed+}/\x03 (nq\x16\x87\xba\xecK(f\xa2\xcd\xd6\x0b\xdd\xc6\x9f\xd0\xb8\x9ep\x1d\xfc\xf8\xcc2\xd4\x1f\xc83Y\xb0\xe3\xdd\xe9w\x00\xb2pD\xfedG\xb4q2$\xcc\xc9}\x91K\x13\xd3\xafA\xad\"\xf6E&N\x82tg\x19'N\x07e\xfds\xd5\xf3\x1a!\xd0\xae\xf04q\xec\x9c\x17o\x14}\xec\xbf\x9d\xa5S\xb5\x05\xb5\xeb\x1e,o\xd5jr/s\x0c\x9cT\x0e\xfe\x04MT\x97&\xf6\xd0\x1b\xf0Qf\\12\xa1h'&ctN\xa6\xfa'T\xc5x7\xbc\x81]2\xfb ;G\xcd\x0e\x02 \xca\x85\xeb\xa2\xe3\x17|T\xaa\x01++:%/ \x86\xe8\xa6\xfb\x8a\xb3\xff1T\xc2\x0b\x01\x91\xc5\xfa\xcf\x1a\x93\x0c\x1a\xf3\xcb\x80\x9f<\xd4\xf1\xcc4\xc2\x0e\xd3\xd4\xf9\x8a\x0e\xc0\xcd\x94\xd7\xff\x93\xcb\x97 \xc9,0\x0f~\xe1\xf2\x9d!\xa1W\x8bO\xa9\x1d\xe0'\x89 \xe1\xcd:s\xf1u\x01\xc8\xc6\xca\xd2\xa6\xd9\x86\xf9\x8f\x03(\xb4^\xef\xae\x8e\x18\x0c\xb5\xa5\x9c\xc2)\x98\xf87\xe8\xd8\x00f\xc1\x80\xd1ml\xa5\xf2\xd2\xb9\xee1\xc5\xabt\x19\xdc\x1d\xd2Z\x83\x04\xe8\x08h\xc0\x0d\xcaL0\x0c\xa7\xa3\xb7\x96\x1a6\xd2X\"J\xd2\x82\xed\n\x8c\x884\xa79\xd8\xd1 \x9d\xd6\xa9B\xe9\x1d}\x83\xde\xd4\xad`\xe8`\x91\xa5\xae\xf0\x84\xd3\x92\x7f\xe7 #\xa6J\xde\xefn\xe9\xe4\xf4\xd1_\x91F\xad H|\x9a\xa1$O\xc8K\xce\xfa=\xa1\xc5\x93\x1fi\x191\xf7\xa1\xa67\x8c\x94o-\x7fH\xcbq\x1d\xa1\xaa\xfbp[\xc9\xab%%:\x10\x04\x88\xe4\x80\xc9\x88\x15\x10i3\x1d\xdb\xa0\xfa\x84G C\x97\x00LL\x894\x8aS\xd0:\x9edB\xf2j|\x89\x88pY\xd3\xf6S\xfeD\x90P\x1d>\xb6p\xd3v\x00\xde\x04\xb25KLe\xe8{t0\xae\xf2\x91y\xc7END$\xe0*\x9d;z\x1c\xbb5\x9a\x8aN\x92\x02\xe1BI\xf3\xd9gn\x8c\x80\x7f.N\xc9|\xd7\xb6\xe0\xd1n\xd0\x05\x8d\x94R\xc8aS\xa4Z\xd7\xc2JcH\xb2\x10 m\xcd\xd1X\xf8\x06\xdc\xca\xdf\x07e\x90\x12k;_\x0c6\xc8,y\x1e\x01\xca\xc2b\x94\x8d0#\xa6Z\x84\xb8A\x14\x0d\x17\x06e|w\x82\xd4\xccG\x0dU\xbd1l\xb8\xcbLD\xd87\xc3\x84V\xa3q\x92\xddt[\xadxu\xddE\x94QUL\x88\x01\xef\xf0PB\x9dlZSh\x96\x92.\xe1\xe91Q0U\xec\xd9\xb18R\x84\x06i\x8d\xfap;\xa6\xf1{\xf3\xf4H#\x96G\x03ON\x02!?\xeb\xa3\x05\xe8t>\xa9Q \x08|p\xcak\xa4\x90\xdb\xf3\xa8q!\xe7gT,\xf6\xd5j\xc7\xd02\x04\xc3\xc8\x16s\xc7\x8d4\xed\x88\x8at\x1b\x94j\xe4\x0e\xb7n\xc6\x9b/\x08I\xc9O\x98E\x02!\xcb\x8bnF\xf5\x9b4\x12\xa8\x86\xb7\x88M\x0f&\x1e\xd41\x84\x1b\x92\x97\xbe\x85x\xd3$\xa7ew+v\x99S\xf0\xcb\n\x0e\x0cbm\x05]e%8\x0c\xb2\xe4\x90\x06P\xcc\xc2\x11\n!\xfa\xef\xb3\x11\x90\x8cs\xc2\x11\xf3_0\x066\xa3\x1b\xf2)\xc2\x8fQ\xb42JB\x86\xea\xd8\xfd\x01\x0c\x84[t9\xae\x96\x83'\x94\xa7\xb3\xd4\x9c,\xa7\xa2\xcc\xf4[\xbdf\x00\xc3\x86\xd7\x92\xb6]\x98\x1e\xc2B\x8aB\x1f\xc3@\x9a\xa6\xeer&B\x84s|\x95Q\x9a\x0d\xb0\xa7\x99\xd7g\xa8\xedOC\x88\x9e1\x87\xdcJ D\xe7<\xcc\xcf\xe2U\xff\x87\xb2\xce\xbc\xd3\x11(o\xa9!\xb3\x81h\xa6\x90\xdcK\xbdH\xfc\xea 0q\x9b\x88\x92\xa7A\xd1V\x88\x07\xbc'p\xb4f\xccy\"Q\nO\x04\x85\xdb\x0c2\xc7\x06Z\xbb\xbe\x9fq\xc2\xe0\xbd\x02#d\"\x9b@bQ\xbb\x06,\xae\x93\xc2\x0bw)\xeeP\xcd\\\x1db`x\x1f\x8a\xdf\x00O\xfe)\xde\xa2\x0cd\xbc\x13MC\x80$[Ho\xa4\x13\x90\x18W\xde\xa6\xd1va4{\xe4\xc7\xb1`52\xed\x0f\xfd\xba\x87\x06\xb3\x1e5;\x82\x19\x85X\xb0\xffao\x00K\x86;\x986\x93%\xc1R(\xc0\x82\x05\x8c\xd3\xc6\xd1\x85x9\x8a8\x0c\xc02r\xe3D\x1ec\xf7\x10\xa5@\xd9\x88\x8c\xe6\xbe\xc9\x10\xa4\xeeF\xd7<\x86d\x0f\x16\x07(\xc8AN#F\x81I\xb7\x9e\x9bz\x1cm\x1dE\x04\xfe\x89\xbbF=\xa9\xb1\x85\xc6\x9a\xad\xe5\x95S\x82\x80f\n4\xca8\xa7<'\xb4\x84\xedj\x90\xea\x8e\xf4-\xaa\x98\xda'\x08\xc7\x98<\xd2Tb\xf12\xddv\x80E\xc0t\xb8\xbfq\xa1\xd23qODd_\xed\xd0{`/\x9c\x0fhh\xea\x82\xf6\xcc`\xc2\x929_\xfc1hAY|\x19/\xf9\xeb\x0b\xab\xde\xb7U\xea\x08-\xcd\x95\xba\xd0\xc4A\xde\x0f\x94\xd5o(\xf1\xcb\xea\"\x93$r\xd8\x86T\xcc\xd7PR;\x15\xa7\x05.\xb8-w>&LJ\xf8i\x10\x1aC`\x05A\xa3^\x1b\xb1\x97\xd3#\x89\x80\xc4X\x178\x97t\x97\xf6\xe2H?\x80\x14\x08d\xc1\xbfa\xc3\xc4\x96TST\xda\x03a\x1e\xa8H\x9f0@\xd2\xee\x8a\x17\xf0\xf3U)\x88\xa3\xe6\xef^\x1be}Jb7\x17%\xd7\xdc\x94%\x0e:\x9b\xd3\xc6\xbf@\x00\x97\xafM\x8e\x07+\xf1\xbb\x17y\x94sq\x8e\x00\xaa\xa1\xebL\xcc\xd2\xfd\xf8\xbf\xe1\x0b\xca\x12Y\xaa\x19\x1a0\x0f\x140\xc3\x94\xf7G\xfcD\xa1 \x16>\xc4\xa9\xeaAW\x0b\x11\x88\xb6\xf02\x8dI\xdb:\xc4\xd9F \x9e\xc8\x08\x02\xc7\x03\x9a3\xe3\x9f2\xca\xa0\xedq\x17\x80\xf7\xc0\x94:6S\x95\x97\x8e\xd1]K\xce\xcf\"\xa0\xa5\x08\xaeg[\xa6\x9d \xe5\xcf\x91H\x93\x1b\x1d\x1e\x98\xe2\x03B\xac5\xc8V\x06\x1cEq\xdbLJ\x8c\x95X{C\xbc\x88\xb9\xa7B\xbd\xc5\x03\xd9\xd2!\x08\xa5P\xabI\xe1\x90\x1dq9\xbb\xf8Llx\x96\xae\xca\xaa7\xd2\x1b>\xd6\xa4\x96\xdb]@\xd5!@9H\x03\x94!\xaa\xed\xe4\xc8p\xc0\x1e\xc9\x99\x15\xd5$ \xe2?\xde\xd5)\x9b\xab\x81\xdc\x8e\xa8\x05l\xb0\x06/\"\xb1\x94\xc0\xcc\x81\x96\xaf+\x93@`}}:\\\xf7\x95\xaf\xd0 8\x95zQgS\xa3\xbf\x18+\xf2\x92\xa4\xbf\xc1\x92C\x84\xa3}\x80\x1bR:\x9f\xf5H\xfeUF\x02\\\xa1X\xfe\x92g\xf6\xc0\x18/\xe2\x08\xeb\x80\x04AZ%\x11c\x1f1\x10\xd5wlET\x00\x05\x96\x0fwX\x0c\xa0\x08ZNh\xa5\xa0\x85\x08\xc4yf2D\xc6 \x80\xc3\xb8\x18\x89&v\xaeL\x93q\xee\x1e4\xc67\x95\xf1\xa7\xfb\xcaz\xfa\xf0\\\x90iJ\x11y\xc0\xe8J-k\xafN\xc43\xbd\xa0\xeb \xa3-\xbc\x05s\x91\xd1J\x175\x16\x89\x0f\x97\x1e)\xd9V0\x99N\x170\xddd\xda\\\xd3\x9bd0d-\xa9\xe3E\xda[mf\xa3\\\xa3Um\xc1x\x11\xb2\xd2\xd2C\xabR<(`\xaa\xd1\x95\xe6\x1d\x83p4^!\x06\x9dh\xd4Q\xe8\x0b\x00`\xa2\xf9\x81!l\x08\x93 ~\xc6\x99\xec:J\x87\xc9\xa0\xf1l\xfcW\xb1\xfe\x809\xcb\xb8\xccZXB\x14=\xeb\xc8l)`j\x9e\x1d\xaaeVJ\xb3\xe0U\x80\xb3\x02\x86G!\xaes\xd8\xe71\xd4?\xc6\xbc3\x84\xa8\xc3\x8a.\xb3\x1e}b\x1bIa\xd9\xea6\xe0\x03\xca\x95\x06\x16\x0d\x1e\x9ct?\xe8\xc0\x80\xdeS\x07xZJ'\xc3p\ni\xeb,\xa6\x12.\x88\x8f\xf1\xac\x12\x90\xd8R\x07\x07\x012T`5\x00\x98-R\nBxr\xe6WH\x03\xf6\x0cJP\xb0e#Bb\x89|\x93\xaf\x94-\xb1\xfe\x90\xa1\x90\xec\x8b[\xb2\x84\xa0\xc6\x1c\xe4P\xc2\xe2\xfd\x85\x1a\xa4\xa8Eh\x8b\xb1\xb3\xc2\x8b(5S\x9c\xa2\x1d\x95f\xd5r\xe4\x1c\xc3\x19/]\x7f\xcb\x1c\xb0\xd1I\xc6\x8a\x0d\xcc\x15\xd6d\x94\xdeE#\xfa\xa2O\xaeS\xfa3\x979\xd3\xbb]\xb8\x16\xba\xb3\x80e\x1e\x82\xbf\xdb\xae\xd5\xc9\xb9.9\x17_\x8cb\xeae\xa7\xe6\xbeM\x8c\x14\xb4\x819b\x1e\x13\x19#e\x8d\xa9(\x92\xa6\x11-\x88 0\x9d\xa7\xd2\xd7Ra\xb1\xe0\xc6\x1d\x849\xf9\xba\x96\x88\x06\"\x02\xfe\x89\xb1\xfe\xfd\xfdU,\xe1\xc2%\xfa~\xbeX\xe8\xdc\x80\x1f\xf6\x97\x94\xebz\x80\x15\xdb\xbd{'6[@\x84t[W%\xfd\xd1*\x0b.d'vR {\x94\xd2\xf0h\x1e\x8a\x04\xa6!\xdeAed\x92C\xaaE}\xbbx=E[\x0e\x01|\xefB$7J\xa1* B-\xe1\x00\x0c,=\x11k7\x94[_\xb6\xea-\xd0I\xf4\x96\x0c\xa2\x15\xab\x80\x92\x87J5e\xd6\xcc\xb6\xc4\x01\xb4\x13{\x0d\xc8\xed( \xb4\x86;\x10\x8d\x05\x14WMw\xa7`\xab\xb0\x02\x80\xcb~p\xdcA\xa0\xb0z\x15\x0e 8\x87\x02\xeef\xe6\x13))\xe2\x8c\xe2\xc2(\xde\xfc@ \xa9\x08\xc4\xaa\x07\xd9\x85\x85\xd9\x03<\xe1\xee\x85\xe4.a%N \xf2\xecn\x14\xe9@bz\xad\xc3\x19\x87\xc8\xd1\x1a\xc0\xb5\xbf>\x1a\x1a\xc0\x90\xeb\x18\x03\xf4%\x85\x87\x80\x05T\x07*?lgb\xbfd\xf6\x10\xc8<\x82\xc4\xb5\xe3\xfa\xc0w9Na\xac\xc5\x13\xbc8;<^*%\x9d\x9by\xd2:t\x11D\xa5\xd2\x95Z<\x1c@\x1b\x05\xfc\x890\xaa\xa8\xab\xe4\x82q4\xb1\xe4\xd0\xedl\\\x0d\x96\x1f\x15\x861\x86\x0e\xee\xc9\x1b\x9f\xd3\x00`/\x9e$\x12IJ \xd2\x93sN)\xbc;\x07:A;\x92)$\xd7\x95\n\xb0Ww\xa2\x12y%Kr\xdeIv\x0f\\b\xb6V\x07\x99\x06\xa3\\\x1cn\xadd{\xc0\xde\xf4\xc86\x15t\x10\xbb\x90v\x9d\xed\xd7/~\xa2\x00\xfc*O\xd6\xed\n\x117U\x16>\xa38\xfb\x17r\x82AC<\xba\x13j\xe9\x8aE\xe2\xa2-j\x0f\x1c\xe7\xd8\xe7\x89\xb7\xa8\xfcxs\xee)\x81\x8d\xccD\xa2\x9b\x961\xbc\xc3\x8c/\xcf\xcaq\x93p**\xcc\xb8\x18\xc0$\x02\xd9\x91\x8d\x13,\x0b\x16\xdb\xe1\x0d\x83\xb3B\x1a\xf5\xc8\xbcp\xc4\xfa\x0ek \x1bM\x17hp\x88K\xea7\x17\xc6\x15U\xe8\xa4\xc3]\xf0\xf8\xe1\x03h&\x18\x84-\x19\x13\x9e$\x03\x88\xe9\x8e\xbb\x81\xaf\x94\x93Y\xea\x90\x1b\xa3;\xe0q\xcb\xe96w\x95z\xdd\xf7\xd6W\xfb\xee\xcb\x84\xd6\xadA\xa6h\xb2\xecD\x7f\x9c\x91\x03^R\xf6\x03\xde\x1e\xc9\x01\"\xad\xc6s\x0f5\x00f\xfd\xfc\xeew\x0d\x88\xbf\xe4+\x10\xe7Q&\x12\x1f\x11\x92\x0e/9\xc8\x82\x96\x9c\xb8wN\x1eb\xc7\xeb\xe9\xfc\x90\x90\x19\xad\x0f\xe3\xfc\xb0\xd8z{\xe5\xd8\x1c\x95\xd3\xfeY\x17\xc5>\n]NE\xda\xc1\xb1c,\xdf\x9e#\x0cBF\xfd:0\xcd\xd8/-E\x18\x13\xc8\xbe\xc6\xc2\x8c\xc7\xd7\x83\xeb\x11F\\\xea\x8c\xf4\xe4I\xa7{t\xec\xe4A\xbbZ\x89C\x99O\x0e\x07R\xc3\x1buk\xa5\x0ci\xfa\x94\xf4)\x85ytkd\x9dN\xb8&\x16\x9bv\xa7\x15A\xb1\x99\x88\x0cP\x02{\xcd\xd6\xee\xf4\xcbP'\x9a\xf3\x92>\x02\xc8\xea\xe0x\x02\xe0\xc6\x86`.\xdc\x04\xe4%,;:\xd4\xbf\xd9:\x0f\x8e\xa9\x1a\xab\xad\xbf\xedaF\xf1\xa7o\x1aTQ\xab\x10}v#\xf4\xec\x9a\xd7\xa3\x02\x91\xf6\xdaQk\xe8\xc6'\xdds\xc4\xd4\xd3\xd6\x1f\x08\xd8\xf7\x12~\x85\x0f\xb5\xde\xcdz5h\x1fM\xc4Q\xca\x92\x06\xe1Y>C\x19\x85\xe8\x07\xca\x8d\x99\x00\x84\xe8\xbei\xb7\xcc\x02\x1d\x18U\xb1\xa0\xd3NF#\x11J\x180u\x8c\x05\xceC\xf0\xe4\xf08k\x93\x08!\nf\xab\xe9\xec\xa7v\x0c\xb9{\x7f\x1aE\xf1/\x1f\xcf\xeb\xe6IKIE\xcb>\x0c\xbap\xb7yd\x86\x13\xcce \n\xca\xbe\x12\x94=z\xf4\x86:@7\xd6J\xe0\xf7\xc4\x0e\xb3\xcc|\xc6\xc65g\x07\x0f8\xc0\xeex\x0c\xc53\xe7O\xb1\x8c\x1d\xaa\xfe\x80\xc4\x10\xdc\xdc\x07\n\xfe3\x1f\x80H1\x8b\xf3\xb1\xd8\x84F.\xa0y\xb4fz\xb4\xecW\x06IM\x1b\x0b\xf1\xd9\x19\x83\x18\x11\xc6j[\x81\x17.w\xe6%\x08\x84i?\x01\xd2\x86U\x12\xc2\xe8\xa9f|}@+\x04[8\x95k7Cx\xa4\x98S\x90\x85\xedEO\x02\x12\xde\xafp\xa0$\xe4\x17\x97\xfc\xe1\xe7\xbeQ\xe6\xbb+\x99\x19\xca\x03:\xb8<\xe1]\x81\xb6\x01\xb8K\xe23\x8f\x8bT-y\xb2\xc2\xcd\x16\x08[N\xd1\xd6z\xb4\xb5\x84;y\xb3\x8a\xa4-HZ\xfe\xaaY^\x15\xa1\xd4.\xa5M\x00*\x08\xd4'h8\xd2\xedA\x85\x04.\xb0N\xef2\x16r\x89\x9cLB\x9c\x0b7:Or\x8f\x92\xa9}\x91\x12C\x89S\xcb\x9aS\x199\xe4\x01Jq#\xec\xa3\x12WI}*8\xcbD!\x1b\x88\xb8# \x11\x14g#Y\x8f>\x138\x18`\x95\n\xec\x15\xd0\x92\xc2\xf1\x03\x0c?a\x85\x812\x12H,\x1f^\xf1\xe3\xc4'\x83\x8f\xef?\xb8\xff\x03\x90\x0e^\xb8\x88\xe6\x03\xa7n\x83h\xe3O\xc6\x92\xad\x07\x1a\xbfi<\xd1\x19\xaa\xe6\xddY\x0fa2\xc9+\x1e\x99\xfc\xcc6a\xb0F\xb1\xe2a<\xcc!\x84\xdb0\xac\x892\xbd]\x81c:\xefe\xbcK\xa4\xac\x1cX\x98X\x98[Ug\xe9O\x12\xafu\x175i\xd4yPcV\xd9T\xba\x9e5\x1fR\x01I\xfa\x9fA6\xf2O\xd4\xb8i\x0d\xa4\xfdC\x04\x8e\\\x87\xf1\x1e\x85\x97\xe3Q\x0fZ\x13\x8dM\x84D\xc4\xc6\x83\xd3\xda\x01\x90\xcfB!X\x96\xc4:\xf4\xd0\xe3\x08\x1c\\!\xc7\x14\x18^\xc1\x85\"\x14{\xa1E \x14Va\x07x$P\x1d \x17\x18\\$\x02\x0c\xb3DBBT\xde\xd3Ft\xe8\x9f~\x99\xc3{O\x87\x1e\x04\x00\xbc\x0dw\x00\xef\xf8\x9e5a#\xf8\x07`\x90\xab=\x04\x16\x00\x11g\x81\x12\x80\x11\xd0\x81\x13\xb0\x01Y\xfd\x192>\x1d\x87\xb1MG\xaf-G\xadk\x8f\xc3\xa8\xaa\xdb1T\xbeb\xa6\xfc\x85L\x18\n\xb9`*\xd9\x80\xabV\x02\xacX\n\xad\xde*\xa5x\xaae\xc2\xa7\xd6\x8a\x9dZ*c`\xaaV\xc1S\xd5b\xa5\xba\xc5JU\x8a\x92\xaa\x15\x1d\xd0*6\xa0TK@\xa8zqP\xc4\xe2\xb6\xc9\xc5h\x93\x8a\xc7g\x15\x86\xcc*\xdf\x94U\xa7(\xaa\xf6QU4\x82\xa79\x05L\x92\n\xadc\x15M\xc6*\x90\x8cT\xbb\x18\xa9R!R,B\xa3\xc8\x85E\xb0\x8a\x88\xa0\x15\x0f\xbe*C|Tz\xf8\xf4p\xf0\xf4F\xe8\xf4@\xe8\xf44\xe8\xf4*\xe0\xf4\x10\xe0\xf7\xf5\xb1\xee\x05\xb1\xed\x85\xb0\x96\x86\xd8\xac\xe1\xb1X\xf3b\xb0\x06\x80\x1cL\x80.\x99\x00T2\x00y`\x00\xae\xc0\x01Up\x02b\xe0\x03\xe5\xc0\x05\xeb\x00\n\x15\x00\x10\xaa\x00\x1bT\x00,\xa0\x00%@\x05\x1a`\x07\xe4\xc0\x0b\xe8\x80\x15\x90\x00#\xa0\x00?@\x00t\x80\x00\xa4\xf8\x19GL\x88\xeb\xc5\x9e\x00S\xc0)\xf6\x01\x9e\xc3\xbf\xa0z\x93\xfft\x07\xcf\xb2Fy\x15\xd7\x8e\x00 \x1a\x0014\x00Lh\x00\x8c\xd0\x00\xe1\x80\x01\x83\x00\x01f\x00\x7f\x99\x00\xb0\xc8\x05e\xc0(.\x01)p\x08K\x80@\\\x01\xe2\xe0\x0c\x97\x00X\xb8\x02e@\x05\x15\x00\x08T\x0fb\xa0v\x95\x03h\x98\x1aD\xc0\xc5&\x05\xf90-I\x81bD\x02\x89\x10 d@\x1f\x11\x00ZD\x011\x10\x03\xa4@\x0c\x91\x00\x18D\xe0\x04y\xc0\xb8\xf3\x80\xd1\xa7\x00CN|\x0d9\xdc4\xe6\xd8\xd3\x9a#Nc\x0bl\xc2\x16\x05\xc0\xb0;\x05\x81\xb8,\x0d\x81`c\x8b\x03\x04X\x16\xe2\xc0\xb3\x16\x05@\x90(\x84\x812$\x030\x90\x0c\"@- \x00\x98$\x01\xe8\x90\x06B@\x16\x89\x00<$\x00\xd0\x90\x01\xc1\xc0\xf8\x0e\x078p7C\x81\xa6\x1c\x0c\x80\xe0b\x05\x02\xe8(\x16\x81@\xa5\n\x05\x18P\x05A@\x13\x85\x00F\x0c\x00\xb80\x02\x00\xc0\xf5\x06\x00t\x89\xfc\x01\x9c\xde\x04\x1d\x8b\xe4G\x16\xad\xe9\xd4OR\x97\x89\xe9\xc4\xb2\xe2I\xef\x1eT\xf1yS\x8d\xcdMW52\\T\xc6oR\xe5\xa5KV\x950\xc8\x8e\xac\x04\xe0\xbb\x1a\x82\x8c(\n-\xa0$\xb2\x80\x92\x9a\x01\x80\x94\x0d\xa4\x02!6\xa6\x84\xa2w\x88\xeaH\xa2\xa9\x0e\x86\xa3\xf9\xfa\x8fG\x12\xf9\xad\xa0\x11O r~\x07\x07\xe0e~\x06/\xe0]\xfe\x05\xb7\xe0V~\x05/\xe0P~\x057\xa0Sz\x04\xef\xa0K\xfa\x04\x97\xa0Fv\x04\x17`;\xf6\x03\xaf`9v\x05\xd1#\nJ\xa4\x1a\xdc\x17\xa7B\xcdN\x82,\x90\xe4\xd7\xce\x1f\xc5\xd3\xad\xb2'\xb0\x00\x00\x01\x03\x01`\x00\x00\x15\xa1'\xe2\x8f\x10\x82`\x04\\LT\xfe\xf0\xd9\x02A\x18p\x12Bs\x81)r\x85!\xd5\n\xe2(\n\x03\xd2\x04i\x82`PK\x07\x08X\xc7\xb1\x9c\x9fN\x00\x00\x9fN\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00fonts/glyphicons-halflings-regular.svg\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n PK\x07\x08|\xee\xc6\xc9\xc2\xa8\x01\x00\xc2\xa8\x01\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00fonts/glyphicons-halflings-regular.ttf\x00\x01\x00\x00\x00\x0f\x00\x80\x00\x03\x00pFFTMm*\x97\xdc\x00\x00\x00\xfc\x00\x00\x00\x1cGDEF\x01D\x00\x04\x00\x00\x01\x18\x00\x00\x00 OS/2g\xb9k\x89\x00\x00\x018\x00\x00\x00`cmap\xda\xad\xe3\x81\x00\x00\x01\x98\x00\x00\x06rcvt \x00(\x02\xf8\x00\x00\x08\x0c\x00\x00\x00\x04gasp\xff\xff\x00\x03\x00\x00\x08\x10\x00\x00\x00\x08glyf}]\xc2o\x00\x00\x08\x18\x00\x00\x94\xa4head\x05M/\xd8\x00\x00\x9c\xbc\x00\x00\x006hhea\nD\x04\x11\x00\x00\x9c\xf4\x00\x00\x00$hmtx\xd2\xc7 `\x00\x00\x9d\x18\x00\x00\x03tlocao\xfb\x95\xce\x00\x00\xa0\x8c\x00\x00\x020maxp\x01j\x00\xd8\x00\x00\xa2\xbc\x00\x00\x00 name\xb3,\xa0\x9b\x00\x00\xa2\xdc\x00\x00\x03\xa2post\xba\xa3\xe55\x00\x00\xa6\x80\x00\x00\n\xd1webf\xc3\x18TP\x00\x00\xb1T\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x00\xcc=\xa2\xcf\x00\x00\x00\x00\xd0v\x81u\x00\x00\x00\x00\xd0vs\x97\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x18\x00\x00\x00\x00\x00\x02\x00\x01\x00\x01\x01\x16\x00\x01\x00\x04\x00\x00\x00\x02\x00\x00\x00\x03\x04\x8b\x01\x90\x00\x05\x00\x04\x03\x0c\x02\xd0\x00\x00\x00Z\x03\x0c\x02\xd0\x00\x00\x01\xa4\x002\x02\xb8\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UKWN\x00@\x00 \xff\xff\x03\xc0\xff\x10\x00\x00\x05\x14\x00{\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x01\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00,\x00\x00\x00\n\x00\x00\x01\xdc\x00\x01\x00\x00\x00\x00\x04h\x00\x03\x00\x01\x00\x00\x00,\x00\x03\x00\n\x00\x00\x01\xdc\x00\x04\x01\xb0\x00\x00\x00h\x00@\x00\x05\x00(\x00 \x00+\x00\xa0\x00\xa5 \n / _ \xac \xbd\"\x12#\x1b%\xfc&\x01&\xfa' '\x0f\xe0\x03\xe0 \xe0\x19\xe0)\xe09\xe0I\xe0Y\xe0`\xe0i\xe0y\xe0\x89\xe0\x97\xe1 \xe1\x19\xe1)\xe19\xe1F\xe1I\xe1Y\xe1i\xe1y\xe1\x89\xe1\x95\xe1\x99\xe2\x06\xe2 \xe2\x16\xe2\x19\xe2!\xe2'\xe29\xe2I\xe2Y\xe2`\xf8\xff\xff\xff\x00\x00\x00 \x00*\x00\xa0\x00\xa5 \x00 / _ \xac \xbd\"\x12#\x1b%\xfc&\x01&\xfa' '\x0f\xe0\x01\xe0\x05\xe0\x10\xe0 \xe00\xe0@\xe0P\xe0`\xe0b\xe0p\xe0\x80\xe0\x90\xe1\x01\xe1\x10\xe1 \xe10\xe1@\xe1H\xe1P\xe1`\xe1p\xe1\x80\xe1\x90\xe1\x97\xe2\x00\xe2 \xe2\x10\xe2\x18\xe2!\xe2#\xe20\xe2@\xe2P\xe2`\xf8\xff\xff\xff\xff\xe3\xff\xda\xfff\xffb\xe0\x08\xdf\xe4\xdf\xb5\xdfi\xdfY\xde\x05\xdc\xfd\xda\x1d\xda\x19\xd9!\xd9\x13\xd9\x0e \x1d \x1c \x16 \x10 \n \x04\x1f\xfe\x1f\xf8\x1f\xf7\x1f\xf1\x1f\xeb\x1f\xe5\x1f|\x1fv\x1fp\x1fj\x1fd\x1fc\x1f]\x1fW\x1fQ\x1fK\x1fE\x1fD\x1e\xde\x1e\xdc\x1e\xd6\x1e\xd5\x1e\xce\x1e\xcd\x1e\xc5\x1e\xbf\x1e\xb9\x1e\xb3\x08\x15\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x02\x8c\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00 \x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00*\x00\x00\x00+\x00\x00\x00\x04\x00\x00\x00\xa0\x00\x00\x00\xa0\x00\x00\x00\x06\x00\x00\x00\xa5\x00\x00\x00\xa5\x00\x00\x00\x07\x00\x00 \x00\x00\x00 \n\x00\x00\x00\x08\x00\x00 /\x00\x00 /\x00\x00\x00\x13\x00\x00 _\x00\x00 _\x00\x00\x00\x14\x00\x00 \xac\x00\x00 \xac\x00\x00\x00\x15\x00\x00 \xbd\x00\x00 \xbd\x00\x00\x00\x16\x00\x00\"\x12\x00\x00\"\x12\x00\x00\x00\x17\x00\x00#\x1b\x00\x00#\x1b\x00\x00\x00\x18\x00\x00%\xfc\x00\x00%\xfc\x00\x00\x00\x19\x00\x00&\x01\x00\x00&\x01\x00\x00\x00\x1a\x00\x00&\xfa\x00\x00&\xfa\x00\x00\x00\x1b\x00\x00' \x00\x00' \x00\x00\x00\x1c\x00\x00'\x0f\x00\x00'\x0f\x00\x00\x00\x1d\x00\x00\xe0\x01\x00\x00\xe0\x03\x00\x00\x00\x1e\x00\x00\xe0\x05\x00\x00\xe0 \x00\x00\x00!\x00\x00\xe0\x10\x00\x00\xe0\x19\x00\x00\x00&\x00\x00\xe0 \x00\x00\xe0)\x00\x00\x000\x00\x00\xe00\x00\x00\xe09\x00\x00\x00:\x00\x00\xe0@\x00\x00\xe0I\x00\x00\x00D\x00\x00\xe0P\x00\x00\xe0Y\x00\x00\x00N\x00\x00\xe0`\x00\x00\xe0`\x00\x00\x00X\x00\x00\xe0b\x00\x00\xe0i\x00\x00\x00Y\x00\x00\xe0p\x00\x00\xe0y\x00\x00\x00a\x00\x00\xe0\x80\x00\x00\xe0\x89\x00\x00\x00k\x00\x00\xe0\x90\x00\x00\xe0\x97\x00\x00\x00u\x00\x00\xe1\x01\x00\x00\xe1 \x00\x00\x00}\x00\x00\xe1\x10\x00\x00\xe1\x19\x00\x00\x00\x86\x00\x00\xe1 \x00\x00\xe1)\x00\x00\x00\x90\x00\x00\xe10\x00\x00\xe19\x00\x00\x00\x9a\x00\x00\xe1@\x00\x00\xe1F\x00\x00\x00\xa4\x00\x00\xe1H\x00\x00\xe1I\x00\x00\x00\xab\x00\x00\xe1P\x00\x00\xe1Y\x00\x00\x00\xad\x00\x00\xe1`\x00\x00\xe1i\x00\x00\x00\xb7\x00\x00\xe1p\x00\x00\xe1y\x00\x00\x00\xc1\x00\x00\xe1\x80\x00\x00\xe1\x89\x00\x00\x00\xcb\x00\x00\xe1\x90\x00\x00\xe1\x95\x00\x00\x00\xd5\x00\x00\xe1\x97\x00\x00\xe1\x99\x00\x00\x00\xdb\x00\x00\xe2\x00\x00\x00\xe2\x06\x00\x00\x00\xde\x00\x00\xe2 \x00\x00\xe2 \x00\x00\x00\xe5\x00\x00\xe2\x10\x00\x00\xe2\x16\x00\x00\x00\xe6\x00\x00\xe2\x18\x00\x00\xe2\x19\x00\x00\x00\xed\x00\x00\xe2!\x00\x00\xe2!\x00\x00\x00\xef\x00\x00\xe2#\x00\x00\xe2'\x00\x00\x00\xf0\x00\x00\xe20\x00\x00\xe29\x00\x00\x00\xf5\x00\x00\xe2@\x00\x00\xe2I\x00\x00\x00\xff\x00\x00\xe2P\x00\x00\xe2Y\x00\x00\x01 \x00\x00\xe2`\x00\x00\xe2`\x00\x00\x01\x13\x00\x00\xf8\xff\x00\x00\xf8\xff\x00\x00\x01\x14\x00\x01\xf5\x11\x00\x01\xf5\x11\x00\x00\x01\x15\x00\x01\xf6\xaa\x00\x01\xf6\xaa\x00\x00\x01\x16\x00\x06\x02\n\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\x02\xf8\x00\x00\x00\x01\xff\xff\x00\x02\x00\x02\x00(\x00\x00\x01h\x03 \x00\x03\x00\x07\x00.\xb1\x01\x00/<\xb2\x07\x04\x00\xed2\xb1\x06\x05\xdc<\xb2\x03\x02\x00\xed2\x00\xb1\x03\x00/<\xb2\x05\x04\x00\xed2\xb2\x07\x06\x01\xfc<\xb2\x01\x02\x00\xed23\x11!\x11%3\x11#(\x01@\xfe\xe8\xf0\xf0\x03 \xfc\xe0(\x02\xd0\x00\x01\x00d\x00d\x04L\x04L\x00[\x00\x00\x012\x16\x1f\x01\x1e\x01\x1d\x017>\x01\x1f\x01\x16\x06\x0f\x0132\x16\x17\x16\x15\x14\x06\x0f\x01\x0e\x01+\x01\x17\x1e\x01\x0f\x01\x06&/\x01\x15\x14\x06\x07\x06#\"&/\x01.\x01=\x01\x07\x0e\x01/\x01&6?\x01#\"&'&546?\x01>\x01;\x01'.\x01?\x016\x16\x1f\x0154676\x02X\x0f&\x0b\x0b\n\x0f\x9e\x07\x16\x08j\x07\x02\x07\x9e\xe0\n\x11\x02\x06\x03\x02\x01\x02\x11\n\xe0\x9e\x07\x02\x07j\x08\x16\x07\x9e\x0f\n)\"\x0f&\x0b\x0b\n\x0f\x9e\x07\x16\x08j\x07\x02\x07\x9e\xe0\n\x11\x02\x06\x03\x02\x01\x02\x11\n\xe0\x9e\x07\x02\x07j\x08\x16\x07\x9e\x0f\n)\x04L\x03\x02\x01\x02\x11\n\xe0\x9e\x07\x02\x07j\x08\x16\x07\x9e\x0f\n)\"\x0f&\x0b\x0b\n\x0f\x9e\x07\x16\x08j\x07\x02\x07\x9e\xe0\n\x11\x02\x06\x03\x02\x01\x02\x11\n\xe0\x9e\x07\x02\x07j\x08\x16\x07\x9e\x0f\n)\"\x0f&\x0b\x0b\n\x0f\x9e\x07\x16\x08j\x07\x02\x07\x9e\xe0\n\x11\x02\x06\x00\x00\x00\x00\x01\x00\x00\x00\x00\x04L\x04L\x00#\x00\x00\x0132\x16\x15\x11!2\x16\x1d\x01\x14\x06#!\x11\x14\x06+\x01\"&5\x11!\"&=\x01463!\x1146\x01\xc2\xc8\x15\x1d\x01^\x15\x1d\x1d\x15\xfe\xa2\x1d\x15\xc8\x15\x1d\xfe\xa2\x15\x1d\x1d\x15\x01^\x1d\x04L\x1d\x15\xfe\xa2\x1d\x15\xc8\x15\x1d\xfe\xa2\x15\x1d\x1d\x15\x01^\x1d\x15\xc8\x15\x1d\x01^\x15\x1d\x00\x00\x00\x00\x01\x00p\x00\x00\x04@\x04L\x00E\x00\x00\x0132\x16\x07\x01\x06\x07!2\x16\x0f\x01\x0e\x01+\x01\x15!2\x16\x0f\x01\x0e\x01+\x01\x15\x14\x06+\x01\"&=\x01!\"&?\x01>\x01;\x015!\"&?\x01>\x01;\x01&'\x01&6;\x012\x1f\x01\x162?\x016\x039\xfa\n\x05\x08\xfe\x94\x06\x05\x01\x0c\n\x06\x06x\x06\x18\n}\x01\x13\n\x06\x06x\x06\x18\n}\x0f\x0b\x94\x0b\x0f\xfe\xed\n\x06\x06x\x06\x18\n}\xfe\xed\n\x06\x06x\x06\x18\nv\x05\x06\xfe\x94\x08\x05\n\xfa\x19\x12\xa4\x08\x14\x08\xa4\x12\x04L\n\x08\xfe\x94\x06\x0c\x0c\x08\xa0\x08\x0cd\x0c\x08\xa0\x08\x0c\xae\x0b\x0f\x0f\x0b\xae\x0c\x08\xa0\x08\x0cd\x0c\x08\xa0\x08\x0c\x0c\x06\x01l\x08\n\x12\xa4\x08\x08\xa4\x12\x00\x00\x01\x00d\x00\x05\x04\x8c\x04\xae\x00;\x00\x00\x012\x17\x16\x17#4.\x03#\"\x0e\x03\x07!\x07!\x06\x15!\x07!\x1e\x0432>\x0353\x06\x07\x06#\"'.\x01'#7367#73>\x0176\x02\xe8\xf2p<\x06\xb5#4@9\x17\x13+820\x0f\x01{d\xfe\xd4\x06\x01\x96d\xfe\xd4 09B4\x15\x169@4#\xae\x1ebk\xa7\xcev$B\x0c\xd9dp\x01\x05\xdad\x86\x14>\x1fu\x04\xae\xbdhi-K0!\x0f\x0b\x1e.O2d22dJtB+\x0f\x0f\"0J+\xabku\x9e0\xaawd/5dW\x85%\x8d\x00\x00\x02\x00{\x00\x00\x04L\x04\xb0\x00>\x00G\x00\x00\x01!2\x1e\x05\x15\x1c\x01\x15\x14\x0e\x05+\x01\x07!2\x16\x0f\x01\x0e\x01+\x01\x15\x14\x06+\x01\"&=\x01!\"&?\x01>\x01;\x015!\"&?\x01>\x01;\x01\x1146\x17\x1132654&#\x01\xac\x01^CjB0\x16\x0c\x01\x01\x0c\x160BjC\xb2\x02\x01 \n\x06\x06x\x06\x18\n\x8a\x0b\n\x95\n\x0f\xfe\xf5\n\x06\x06x\x06\x18\nu\xfe\xf5\n\x06\x06x\x06\x18\nu\x0f\xb6\xcb@--@\x04\xb0\x1a$?2O*$\x0b\x0b\x0b$*P2@%\x1ad\x0c\x08\xa0\x08\x0c\xaf\x0b\x0e\x0f\n\xaf\x0c\x08\xa0\x08\x0cd\x0c\x08\xa0\x08\x0c\x01\xdb\n\x0f\xc8\xfe\xd4BVT@\x00\x00\x01\x00\xc8\x01\x90\x04L\x02\xbc\x00\x0f\x00\x00\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\xfa\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\x02\xbc\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x00\x00\x00\x02\x00\xc8\x00\x00\x03\xe8\x04\xb0\x00%\x00A\x00\x00\x01\x15\x14\x06+\x01\x15\x14\x06\x07\x1e\x01\x1d\x0132\x16\x1d\x01!546;\x015467.\x01=\x01#\"&=\x01\x17\x15\x14\x16\x17\x1e\x01\x14\x06\x07\x0e\x01\x1d\x01!54&'.\x01467>\x01=\x01\x03\xe8\x1d\x152cQQc2\x15\x1d\xfc\xe0\x1d\x152cQQc2\x15\x1d\xc8A7\x1c \x1c7A\x01\x90A7\x1c \x1c7A\x04\xb0\x96\x15\x1dd[\x95##\x95[\x96\x1d\x15\x96\x96\x15\x1d\x96[\x95##\x95[d\x1d\x15\x96\xc8d\x01\x16\x1f\x0176\x03!'\x03\x02\xf6 \n\x88\x01\xd3\x1e\x14\x1e\xfbP\x1e\x14\x1e\x01\xd4\x87\n $\nop z\x01y\xb6\xc3\x04\xb3\x13#\x10\xbb\xfd\x16%\x15**\x15%\x02\xea\xb7\x10$\x14 \x10\x94\x96\x10\xfc\x1ep\x02\x16\x00\x00\x00\x00\x04\x00\x00\x00d\x04\xb0\x04L\x00\x0b\x00\x17\x00#\x007\x00\x00\x13!2\x16\x07\x01\x06\"'\x01&6\x17\x01\x16\x14\x07\x01\x06&5\x1146 \x016\x16\x15\x11\x14\x06'\x01&4\x07\x01\x16\x06#!\"&7\x0162\x1f\x01\x162?\x0162\x19\x04~\n\x05\x08\xfd\xcc\x08\x14\x08\xfd\xcc\x08\x05\x03\x01\x08\x08\x08\xfe\xf8\x08\n\n\x03\x8c\x01\x08\x08\n\n\x08\xfe\xf8\x08\\\x01l\x08\x05\n\xfb\x82\n\x05\x08\x01l\x08\x14\x08\xa4\x08\x14\x08\xa4\x08\x14\x04L\n\x08\xfd\xc9\x08\x08\x027\x08\n\xda\xfe\xf8\x08\x14\x08\xfe\xf8\x08\x05\n\x02&\n\x05\xfe\xf0\x01\x08\x08\x05\n\xfd\xda\n\x05\x08\x01\x08\x08\x14\x80\xfe\x94\x08\n\n\x08\x01l\x08\x08\xa4\x08\x08\xa4\x08\x00\x00\x00\x03\xff\xf0\xff\xf0\x04\xba\x04\xba\x00 \x00\x0d\x00\x10\x00\x00\x002\x1f\x01\x16\x14\x0f\x01'7\x13\x01' \x01\x05\x13\x03\xe0&\x0e\x99\x0d\x0dc\xd6_\"\xfd\x99\xd6\x02f\xfe\x1f\xfe\xb3n\x04\xba\x0d\x99\x0e&\x0e\\\xd6`\xfet\xfd\x9a\xd6\x02f\xfcjp\x01O\x00\x00\x00\x01\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x0f\x00\x00\x01\x1132\x16\x1d\x01!546;\x01\x11\x01!\x02\xbc\xfa\x15\x1d\xfc\xe0\x1d\x15\xfa\xfe\x0c\x04\xb0\x02\x8a\xfd\xda\x1d\x1522\x15\x1d\x02&\x02&\x00\x00\x00\x01\x00\x0e\x00\x08\x04L\x04\x9c\x00\x1f\x00\x00\x01%6\x16\x15\x11\x14\x06\x07\x06.\x01676\x17\x11\x05\x11\x14\x06\x07\x06.\x01676\x17\x1146\x01p\x02\x85'0SFO\x88$WOHB\xfd\xa8XAO\x88$WOHB\x1d\x03\xf9\xa3\x0f\x1e\"\xfc\xc17Q\x17\x19)mr\x19\x18\x10\x02 \x9b\xfd\xa2*`\x15\x1a)nq\x1a\x18\x11\x02\x7f&*\x00\x00\x00\x02\x00 \xff\xf8\x04\xbb\x04\xa7\x00\x1d\x00)\x00\x00\x002\x1e\x02\x15\x07\x17\x14\x07\x01\x16\x06\x0f\x01\x06\"'\x01\x06#'\x07\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x01\x90\xc8\xb6\x83N\x01\x01N\x01\x13\x17\x01\x16;\x1a)\x13\xfe\xedw\x8e\x05\x02d\xb6\x83NN\x83\x01r\xb0\x94VV\x94\xb0\x94VV\x04\xa7N\x83\xb6d\x02\x05\x8dy\xfe\xee\x1a%\x18:\x14\x14\x01\x12M\x01\x01N\x83\xb6\xc8\xb6\x83[V\x94\xb0\x94VV\x94\xb0\x94\x00\x01\x00d\x00X\x04\xaf\x04D\x00\x19\x00\x00\x01>\x02\x1e\x02\x15\x14\x0e\x03\x07.\x0454>\x02\x1e\x01\x02\x890{xuX6Cy\x84\xa8>>\xa7\x85xC8Zvxy\x03\xb5DH\x05-Sv@9y\x80\x7f\xb2UU\xb2\x7f\x80y9@vS-\x05H\x00\x00\x00\x01\xff\xd3\x00^\x04{\x04\x94\x00\x18\x00\x00\x01\x1362\x17\x13!2\x16\x07\x05\x13\x16\x06'%\x05\x06&7\x13%&63\x01\x97\x83\x07\x15\x07\x81\x01\xa5\x15\x06\x11\xfe\xaa\x82\x07\x0f\x11\xfe\xa9\xfe\xaa\x11\x0f\x07\x82\xfe\xa5\x11\x06\x14\x03 \x01a\x13\x13\xfe\x9f\x11\x0c\xf9\xfeo\x14\x0b\x0c\xf6\xf7\x0c\x0b\x14\x01\x90\xfb\x0c\x11\x00\x02\xff\xd3\x00^\x04{\x04\x94\x00\x18\x00\"\x00\x00\x01\x1362\x17\x13!2\x16\x07\x05\x13\x16\x06'%\x05\x06&7\x13%&63\x05#\x17\x077\x17'7#'\x01\x97\x83\x07\x15\x07\x81\x01\xa5\x15\x06\x11\xfe\xaa\x82\x07\x0f\x11\xfe\xa9\xfe\xaa\x11\x0f\x07\x82\xfe\xa5\x11\x06\x14\x01\xf3\xf0\xc5J\xc1\xc3J\xc0\xeaN\x03 \x01a\x13\x13\xfe\x9f\x11\x0c\xf9\xfeo\x14\x0b\x0c\xf6\xf7\x0c\x0b\x14\x01\x90\xfb\x0c\x11d\x8e\xe2\x8b\x8c\xe5\x8c\xd3\x00\x00\x01\x00\x00\x00\x00\x04\xb0\x04\xb0\x00&\x00\x00\x012\x16\x1d\x01\x14\x06#\x15\x14\x16\x17\x05\x1e\x01\x1d\x01\x14\x06#!\"&=\x01467%>\x01=\x01\"&=\x0146\x02X|\xb0>&\x0c \x01f \x0c\x0f\n\xfb\x82\n\x0f\x0c \x01f \x0c&>\xb0\x04\xb0\xb0|\xfa.hK\n\x17\x06\xe6\x05\x17\n]\n\x0f\x0f\n]\n\x17\x05\xe6\x06\x17\nKh.\xfa|\xb0\x00\x00\x00\x0d\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00#\x00'\x00+\x00/\x003\x007\x00G\x00K\x00O\x00S\x00W\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x1535)\x01\"\x06\x15\x11\x14\x163!265\x114&3\x1535\x05\x1535!\x1535\x05\x1535!\x1535\x07!\"\x06\x15\x11\x14\x163!265\x114&\x05\x1535!\x1535\x05\x1535!\x1535\x19\x04~\n\x0f\x0f\n\xfb\x82\n\x0f\x0fUd\x02\xa3\xfd\xda\n\x0f\x0f\n\x02&\n\x0f\x0fsd\xfc\x18d\x03 d\xfc\x18d\x03 d\xe1\xfd\xda\n\x0f\x0f\n\x02&\n\x0f\x0f\xfc\xefd\x03 d\xfc\x18d\x03 d\x04L\x0f\n\xfb\xe6\n\x0f\x0f\n\x04\x1a\n\x0fddd\x0f\n\xfe\xa2\n\x0f\x0f\n\x01^\n\x0fdd\xc8dddd\xc8ddddd\x0f\n\xfe\xa2\n\x0f\x0f\n\x01^\n\x0fddddd\xc8dddd\x00\x00\x04\x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00/\x00?\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146)\x012\x16\x15\x11\x14\x06#!\"&5\x1146\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146)\x012\x16\x15\x11\x14\x06#!\"&5\x11462\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x02m\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\xfd\xbd\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x02m\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x04L\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\xfd\xa8\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\x00\x00 \x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00/\x00?\x00O\x00_\x00o\x00\x7f\x00\x8f\x00\x00\x1332\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x01462\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\xfc\xf5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\xfc\xf5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x04L\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\xfep\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\xfep\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x00\x06\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x1f\x00/\x00?\x00O\x00_\x00\x00\x1332\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x01462\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\x02\xbc\x15\x1d\x1d\x15\xfdD\x15\x1d\x1d\xfe\x85\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\x02\xbc\x15\x1d\x1d\x15\xfdD\x15\x1d\x1d\xfe\x85\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\x02\xbc\x15\x1d\x1d\x15\xfdD\x15\x1d\x1d\x04L\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\xfep\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\xfep\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x00\x00\x00\x00\x01\x00&\x00,\x04\xe8\x04 \x00\x17\x00\x00 \x0162\x1f\x01\x16\x14\x07\x01\x06\"'\x01&4?\x0162\x1f\x01\x162\x01\xd1\x02;\x08\x14\x07\xb1\x08\x08\xfc\xf1\x07\x15\x07\xfe\x80\x08\x08\xb1\x07\x14\x08\xab\x07\x16\x01\xdd\x02;\x08\x08\xb1\x07\x14\x08\xfc\xf0\x08\x08\x01\x80\x08\x14\x07\xb1\x08\x08\xab\x07\x00\x01\x00n\x00n\x04B\x04B\x00#\x00\x00\x01\x17\x16\x14\x07 \x01\x16\x14\x0f\x01\x06\"' \x01\x06\"/\x01&47 \x01&4?\x0162\x17 \x0162\x03\x88\xb2\x08\x08\xfe\xf5\x01\x0b\x08\x08\xb2\x08\x15\x07\xfe\xf4\xfe\xf4\x07\x15\x08\xb2\x08\x08\x01\x0b\xfe\xf5\x08\x08\xb2\x08\x15\x07\x01\x0c\x01\x0c\x07\x15\x04;\xb3\x08\x15\x07\xfe\xf4\xfe\xf4\x07\x15\x08\xb2\x08\x08\x01\x0b\xfe\xf5\x08\x08\xb2\x08\x15\x07\x01\x0c\x01\x0c\x07\x15\x08\xb2\x08\x08\xfe\xf5\x01\x0c\x07\x00\x03\x00\x17\xff\xeb\x04\xc5\x04\x99\x00\x19\x00%\x00I\x00\x00\x002\x1e\x02\x15\x14\x07\x01\x16\x14\x0f\x01\x06\"'\x01\x06#\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x0532\x16\x1d\x0132\x16\x1d\x01\x14\x06+\x01\x15\x14\x06+\x01\"&=\x01#\"&=\x0146;\x01546\x01\x99\xc4\xb3\x82MN\x01,\x08\x08m\x07\x15\x08\xfe\xd4w\x8eb\xb4\x81MM\x81\x01o\xb3\x98XX\x98\xb3\x99XX\xfe\xbc\x96\n\x0fK\n\x0f\x0f\nK\x0f\n\x96\n\x0fK\n\x0f\x0f\nK\x0f\x04\x99M\x82\xb3b\x8dy\xfe\xd5\x08\x15\x08l\x08\x08\x01+MM\x81\xb4\xc4\xb3\x82MX\x99\xb3\x98XX\x98\xb3\x99#\x0f\nK\x0f\n\x96\n\x0fK\n\x0f\x0f\nK\x0f\n\x96\n\x0fK\n\x0f\x00\x00\x03\x00\x17\xff\xeb\x04\xc5\x04\x99\x00\x19\x00%\x005\x00\x00\x002\x1e\x02\x15\x14\x07\x01\x16\x14\x0f\x01\x06\"'\x01\x06#\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x05!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x01\x99\xc4\xb3\x82MN\x01,\x08\x08m\x07\x15\x08\xfe\xd4w\x8eb\xb4\x81MM\x81\x01o\xb3\x98XX\x98\xb3\x99XX\xfeX\x01^\n\x0f\x0f\n\xfe\xa2\n\x0f\x0f\x04\x99M\x82\xb3b\x8dy\xfe\xd5\x08\x15\x08l\x08\x08\x01+MM\x81\xb4\xc4\xb3\x82MX\x99\xb3\x98XX\x98\xb3\x99\x87\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x00\x00\x00\x00\x02\x00\x17\x00\x17\x04\x99\x04\xb0\x00\x0f\x00-\x00\x00\x0132\x16\x15\x11\x14\x06+\x01\"&5\x1146\x055\x16\x12\x15\x14\x0e\x02\".\x0254\x127\x15\x0e\x01\x15\x14\x1e\x012>\x0154&\x02&d\x15\x1d\x1d\x15d\x15\x1d\x1d\x01\x0f\xa7\xd2[\x9b\xd6\xea\xd6\x9b[\xd2\xa7g|r\xc5\xe8\xc5r|\x04\xb0\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\xe1\xa6>\xfe\xd9\xb8u\xd6\x9b[[\x9b\xd6u\xb8\x01'>\xa67\xc8xt\xc5rr\xc5tx\xc8\x00\x04\x00d\x00\x00\x04\xb0\x04\xb0\x00\x0f\x00\x1f\x00/\x00?\x00\x00\x0132\x16\x15\x11\x14\x06+\x01\"&5\x1146\x0132\x16\x15\x11\x14\x06+\x01\"&5\x1146\x0132\x16\x15\x11\x14\x06+\x01\"&5\x1146\x0532\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x04\x01\x96\n\x0f\x0f\n\x96\n\x0f\x0f\xfe\xde\x96\n\x0f\x0f\n\x96\n\x0f\x0f\xfe\xde\x96\n\x0f\x0f\n\x96\n\x0f\x0f\xfe\xde\x96\n\x0f\x0f\n\x96\n\x0f\x0f\x04\xb0\x0f\n\xfb\x82\n\x0f\x0f\n\x04~\n\x0f\xfep\x0f\n\xfd\x12\n\x0f\x0f\n\x02\xee\n\x0f\xfe\xd4\x0f\n\xfe>\n\x0f\x0f\n\x01\xc2\n\x0f\xc8\x0f\n\xfa\n\x0f\x0f\n\xfa\n\x0f\x00\x00\x00\x00\x02\x00\x1a\x00\x1b\x04\x96\x04\x96\x00G\x00O\x00\x00\x012\x1f\x02\x16\x1f\x017\x16\x17\x07\x17\x16\x1f\x02\x16\x15\x14\x0f\x02\x06\x0f\x01\x17\x06\x07'\x07\x06\x0f\x02\x06#\"/\x02&/\x01\x07&'7'&/\x02&54?\x026?\x01'67\x1776?\x026\x12\"\x06\x14\x16264\x02X!)&\x051-\x05\x86=+P\x03\x19\x0e\x01\x98\x05\x05\x98\x01\x0f\x18\x03P08\x86\x05,2\x05&+\x1f!)&\x051-\x05\x86<,P\x03\x19\x0d\x02\x97\x06\x06\x97\x02\x0d\x19\x03P/:\x85\x05-1\x05&+x\xb2~~\xb2~\x04\x96\x05\x98\x01\x0e\x19\x02P09\x86\x05,1\x06&+\x1e\"(&\x061,\x05\x86=,Q\x03\x19\x0e\x02\x97\x05\x05\x97\x02\x0e\x19\x03Q09\x86\x05-0\x06&* !(&\x060-\x05\x86=,P\x02\x19\x0e\x01\x98\x05\xfe\x99~\xb1~~\xb1\x00\x07\x00d\x00\x00\x04\xb0\x05\x14\x00\x13\x00\x17\x00!\x00%\x00)\x00-\x001\x00\x00\x01!2\x16\x1d\x01!2\x16\x1d\x01!5463!546\x17\x15!5\x01\x11\x14\x06#!\"&5\x11\x17\x113\x113\x113\x113\x113\x113\x113\x11\x01\xf4\x01,);\x01\x13\n\x0f\xfb\xb4\x0f\n\x01\x13;)\x01,\x01,;)\xfdD);dddddddd\x05\x14;)d\x0f\nKK\n\x0fd);ddd\xfe\xd4\xfc\xe0);;)\x03 d\xfdD\x02\xbc\xfdD\x02\xbc\xfdD\x02\xbc\xfdD\x02\xbc\x00\x01\x00\x0c\x00\x00\x05\x08\x04\xd1\x00\x1f\x00\x00\x13\x0162\x17\x01\x16\x06+\x01\x11\x14\x06+\x01\"&5\x11!\x11\x14\x06+\x01\"&5\x11#\"&\x12\x02l\x08\x15\x07\x02`\x08\x05\n\xaf\x0f\n\xfa\n\x0f\xfe\xd4\x0f\n\xfa\n\x0f\xaf\n\x05\x02j\x02`\x07\x07\xfd\xa0\x08\n\xfd\xc1\n\x0f\x0f\n\x01w\xfe\x89\n\x0f\x0f\n\x02?\n\x00\x02\x00d\x00\x00\x03\xe8\x04\xb0\x00\x11\x00\x17\x00\x00\x01\x11\x14\x163!\x11\x14\x06#!\"&5\x11463\x01#\"&=\x01\x02X;)\x01,\x1d\x15\xfc\xe0\x15\x1d\x1d\x15\x03R\xfa\x15\x1d\x04\xb0\xfep);\xfdv\x15\x1d\x1d\x15\x04L\x15\x1d\xfep\x1d\x15\xfa\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1b\x000\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x0532\x16\x15\x1132\x16\x1d\x01\x14\x06+\x01\"&5\x1146\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xbf\xe8\xc5rr\xc5\xe8\xc5rr\xfe|2\n\x0f\xaf\n\x0f\x0f\n\xfa\n\x0f\x0f\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5\xe8\xc5rr\xc5\xe8\xc5\x0d\x0f\n\xfe\xed\x0f\n2\n\x0f\x0f\n\x01^\n\x0f\x00\x00\x00\x00\x02\xff\x9c\x00\x00\x05\x14\x04\xb0\x00\x0b\x00\x0f\x00\x00)\x01\x03#\x03!\x013\x033\x033\x01\x033\x03\x05\x14\xfd\xe6)\xf2)\xfd\xe6\x01\xaf\xd1\x15\xa2\x14\xd0\xfe\x9e\x1b\xe0\x1b\x01\x90\xfep\x04\xb0\xfe\xd4\x01,\xfep\xfe\xd4\x01,\x00\x00\x00\x00\x02\x00d\x00\x00\x04\xb0\x04\xb0\x00\x15\x00/\x00\x00\x0132\x16\x15\x1132\x16\x07\x01\x06\"'\x01&6;\x01\x1146\x0132\x16\x15\x11\x14\x06#!\"&5\x1146;\x012\x16\x1d\x01!546\x02&\xc8\x15\x1d\xbf\x14\x0b\x0d\xfe\xb9\x0d&\x0d\xfe\xb9\x0d\x0b\x14\xbf\x1d\x02T2\n\x0f\x0f\n\xfb\xe6\n\x0f\x0f\n2\n\x0f\x03\x84\x0f\x04\xb0\x1d\x15\xfe>\x17\x10\xfep\x10\x10\x01\x90\x10\x17\x01\xc2\x15\x1d\xfc\xe0\x0f\n\xfe\xa2\n\x0f\x0f\n\x01^\n\x0f\x0f\n\xaf\xaf\n\x0f\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1b\x001\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x0532\x16\x15\x1132\x16\x07\x03\x06\"'\x03&6;\x01\x1146\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xbf\xe8\xc5rr\xc5\xe8\xc5rr\xfe|\x96\n\x0f\x89\x15\n\x0d\xdf\x0d&\x0d\xdf\x0d\n\x15\x89\x0f\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5\xe8\xc5rr\xc5\xe8\xc5\x0d\x0f\n\xfe\xed\x17\x10\xfe\xed\x10\x10\x01\x13\x10\x17\x01\x13\n\x0f\x00\x00\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1b\x001\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&%\x13\x16\x06+\x01\x11\x14\x06+\x01\"&5\x11#\"&7\x1362\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xbf\xe8\xc5rr\xc5\xe8\xc5rr\xfe\xe7\xdf\x0d\n\x15\x89\x0f\n\x96\n\x0f\x89\x15\n\x0d\xdf\x0d&\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5\xe8\xc5rr\xc5\xe8\xc5\x01\xfe\xed\x10\x17\xfe\xed\n\x0f\x0f\n\x01\x13\x17\x10\x01\x13\x10\x00\x00\x00\x00\x02\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x19\x009\x00\x00\x13!2\x16\x17\x13\x16\x15\x11\x14\x06\x07\x06#!\"&'&5\x1347\x13>\x01\x05!\"\x06\x07\x03\x06\x16;\x012\x16\x1f\x01\x1e\x01;\x0126?\x01>\x01;\x0126'\x03.\x01\xe1\x02\xee\n\x13\x03\xba\x07\x08\x05\x0c\x19\xfb\xb4\x0c\x1e\x02\x06\x01\x07\xb9\x03\x13\x02\x97\xfd\xd4\n\x12\x02W\x02\x0c\n\x96\n\x13\x02&\x02\x13\n\xfa\n\x13\x02&\x02\x13\n\x96\n\x0c\x02W\x02\x12\x04\xb0\x0e\n\xfdt\x18\x19\xfeW\x0c\x1e\x02\x06\x08\x04\x0d\x19\x01\xa9\x19\x18\x02\x8c\n\x0e\xc8\x0e\x0b\xfe>\x0b\x0e\x0e\n\x98\n\x0e\x0e\n\x98\n\x0e\x0e\x0b\x01\xc2\x0b\x0e\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1b\x00'\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x05\x17\x16\x14\x0f\x01\x06&5\x1146\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xbf\xe8\xc5rr\xc5\xe8\xc5rr\xfe\x8b\xfd\x11\x11\xfd\x10\x18\x18\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5\xe8\xc5rr\xc5\xe8\xc5]\xbe\x0c$\x0c\xbe\x0c\x0b\x15\x01\x90\x15\x0b\x00\x01\x00\x17\x00\x17\x04\x99\x04\xb0\x00(\x00\x00\x0176\x16\x15\x11\x14\x06#!\"&?\x01&#\"\x0e\x01\x14\x1e\x012>\x0153\x14\x0e\x02\".\x024>\x0232\x03\xb3\x87\x07\x0b\x0f\n\xfe\x96\x0b\x04\x07\x85m\x81t\xc5rr\xc5\xe8\xc5r\x96[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6u\xc0\x04$\x87\x07\x04\x0b\xfe\x96\n\x0f\x0b\x07\x85Lr\xc5\xe8\xc5rr\xc5tu\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[\x00\x00\x00\x00\x02\x00\x17\x00\x01\x04\x99\x04\xb0\x00\x1a\x005\x00\x00\x0176\x16\x15\x11\x14\x06#!\"&?\x01&#\"\x0e\x01\x15#4>\x0232\x133\x14\x0e\x02#\"'\x07\x06&5\x11463!2\x16\x0f\x01\x1632>\x01\x03\xb3\x87\x07\x0b\x0f\x0b\xfe\x97\x0b\x04\x07\x86n\x81t\xc5r\x96[\x9b\xd6u\xc0\xeb\x96[\x9b\xd6u\xc0\x9c\x86\x07\x0b\x0f\x0b\x01h\n\x05\x08\x85n\x82t\xc5r\x04$\x87\x07\x04\x0b\xfe\x97\x0b\x0f\x0b\x07\x86Kr\xc5tu\xd6\x9b[\xfd\xbfu\xd6\x9b[v\x86\x08\x05\n\x01h\x0b\x0f\x0b\x07\x85Lr\xc5\x00\x00\x00\n\x00d\x00\x00\x04\xb0\x04\xb0\x00\x0f\x00\x1f\x00/\x00?\x00O\x00_\x00o\x00\x7f\x00\x8f\x00\x9f\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05!\"\x06\x15\x11\x14\x163!265\x114&\x0532\x16\x1d\x01\x14\x06+\x01\"&=\x01463!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x0732\x16\x1d\x01\x14\x06+\x01\"&=\x01463!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x0732\x16\x1d\x01\x14\x06+\x01\"&=\x01463!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x0732\x16\x1d\x01\x14\x06+\x01\"&=\x01463!2\x16\x1d\x01\x14\x06#!\"&=\x0146}\x04\x1a\n\x0f\x0f\n\xfb\xe6\n\x0f\x0f\x03\xc0\xfc\xae\n\x0f\x0f\n\x03R\n\x0f\x0f\xfd\x082\n\x0f\x0f\n2\n\x0f\x0f\xd2\x01\xc2\n\x0f\x0f\n\xfe>\n\x0f\x0f\xbe2\n\x0f\x0f\n2\n\x0f\x0f\xd2\x01\xc2\n\x0f\x0f\n\xfe>\n\x0f\x0f\xbe2\n\x0f\x0f\n2\n\x0f\x0f\xd2\x01\xc2\n\x0f\x0f\n\xfe>\n\x0f\x0f\xbe2\n\x0f\x0f\n2\n\x0f\x0f\xd2\x01\xc2\n\x0f\x0f\n\xfe>\n\x0f\x0f\x04\xb0\x0f\n\xfb\x82\n\x0f\x0f\n\x04~\n\x0f\xc8\x0f\n\xfc\xae\n\x0f\x0f\n\x03R\n\x0fd\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\xc8\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\xc8\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\xc8\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\x0f\n2\n\x0f\x00\x00\x00\x00\x02\x00\x00\x00\x00\x04L\x04\xb0\x00\x19\x00#\x00\x00\x0154&#!\"\x06\x1d\x01#\"\x06\x15\x11\x14\x163!265\x114&#!546;\x012\x16\x1d\x01\x03\x84uS\xfe\xd4Rvd);;)\x03\x84);;)\xfd\xa8\x1e\x14\xc8\x14\x1e\x03 \xc8SuvR\xc8;)\xfd\xa8);;)\x02X);\x96\x15\x1d\x1d\x15\x96\x00\x02\x00d\x00\x00\x04L\x04L\x00 \x007\x00\x00\x1332\x16\x15\x11#\x1146\x052\x17\x16\x15\x11\x14\x07\x0e\x03#\".\x01'.\x02#\"\x07\x06#\"'&5\x11>\x0176\x1e\x03\x17\x1e\x023276}2\n\x0fd\x0f\x03\xc0\x04\x05\x10\x03!C@1\x1c\x1a?*'),G\x1eUK\x07\x08\x06\x05\x0e\x16x;\x17(.\x139\x04)-E\x1dgP\x07\x04L\x0f\n\xfb\xcd\x043\n\x0f0\x02\x06\x11\xfe[\x06\x06;P$\x0d\x0d\x0e\x0e\x0f\x0f\x0f9\x05\x03\x07\x0f\x01\xb67W\x03\x02\x03\x0b\x06\x14\x01\x0e\x0e\x0eW\x08\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x04\x97\x00!\x001\x00A\x00\x00\x002\x1e\x02\x15\x11\x14\x06+\x01\"&5\x114.\x01 \x0e\x01\x15\x11\x14\x06+\x01\"&5\x114>\x01\x0332\x16\x15\x11\x14\x06+\x01\"&5\x1146!32\x16\x15\x11\x14\x06+\x01\"&5\x1146\x01\xe4\xe8\xde\xa3c\x0f\n2\n\x0f\x8d\xe4\xfe\xfa\xe4\x8d\x0f\n2\n\x0fc\xa3*\xa0\x08\x0c\x0c\x08\xa0\x08\x0c\x0c\x02`\xa0\x08\x0c\x0c\x08\xa0\x08\x0c\x0c\x04\x97c\xa3\xdet\xfe\xd4\n\x0f\x0f\n\x01,\x7f\xd1rr\xd1\x7f\xfe\xd4\n\x0f\x0f\n\x01,t\xde\xa3\xfd\xc0\x0c\x08\xfe4\x08\x0c\x0c\x08\x01\xcc\x08\x0c\x0c\x08\xfe4\x08\x0c\x0c\x08\x01\xcc\x08\x0c\x00\x00\x00\x00\x02\x00\x00\x00\xd3\x04G\x03\xdd\x00\x15\x009\x00\x00\x01%6\x16\x15\x11\x14\x06'%&+\x01\"&5\x1146;\x012\x05762\x1f\x01\x16\x14\x0f\x01\x17\x16\x14\x0f\x01\x06\"/\x01\x07\x06\"/\x01&4?\x01'&4?\x0162\x17\x01A\x01\x02 \x0c\x0c \xfe\xfe\x15\x19\xfa\n\x0f\x0f\n\xfa\x19\x02Xx\x07\x14\x07\"\x07\x07xx\x07\x07\"\x07\x14\x07xx\x07\x14\x07\"\x07\x07ww\x07\x07\"\x07\x14\x07\x03.\xac\x06\x07\n\xfd\x12\n\x07\x06\xac\x0e\x0f\n\x01^\n\x0f\x84x\x07\x07\"\x07\x14\x07xx\x07\x14\x07\"\x07\x07ww\x07\x07\"\x07\x14\x07xx\x07\x14\x07\"\x08\x08\x00\x00\x00\x00\x02\x00\x00\x00\xd3\x03r\x03\xdd\x00\x15\x00/\x00\x00\x01%6\x16\x15\x11\x14\x06'%&+\x01\"&5\x1146;\x012%3\x16\x17\x16\x15\x14\x07\x06\x0f\x01\"/\x01.\x017654'&6?\x016\x01A\x01\x02 \x0c\x0c \xfe\xfe\x15\x19\xfa\n\x0f\x0f\n\xfa\x19\x01\xd2\x04\n\x06`Z\x06\x0b\x03 \x07\x1d\x07\x03\x06HN\x06\x03\x08\x1d\x07\x03.\xac\x06\x07\n\xfd\x12\n\x07\x06\xac\x0e\x0f\n\x01^\n\x0fd\x01 \x81\xa1\x9a\x7f \x01\x01\x06\x17\x07\x13\x08g~\x84j\x08\x14\x07\x16\x05\x00\x00\x00\x00\x03\x00\x00\x00\xc4\x04b\x03\xec\x00\x1b\x001\x00K\x00\x00\x013\x16\x17\x16\x15\x14\x06\x07\x06\x07#\"/\x01.\x017654&'&6?\x016\x05%6\x16\x15\x11\x14\x06'%&+\x01\"&5\x1146;\x012%3\x16\x17\x16\x15\x14\x07\x06\x0f\x01\"/\x01.\x017654'&6?\x016\x03\xc7\x03\x0b\x06\x87D@\x07\n\x03 \x07*\x08\x02\x06o;7\x06\x02 *\x07\xfd\x82\x01\x02 \x0c\x0c \xfe\xfe\x15\x19\xfa\n\x0f\x0f\n\xfa\x19\x01\xd2\x04\n\x06`Z\x06\x0b\x03 \x07\x1d\x07\x03\x06HN\x06\x03\x08\x1d\x07\x03\xec\x01 \xb3\xd9i\xcbT \x01\x06\"\x06\x14\x08\x96\xb2Z\xacG \x14\x06!\x05\xbe\xac\x06\x07\n\xfd\x12\n\x07\x06\xac\x0e\x0f\n\x01^\n\x0fd\x01 \x81\xa1\x9a\x7f \x01\x01\x06\x17\x07\x13\x08g~\x84j\x08\x15\x06\x16\x05\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x04\xb0\x04\xb0\x00 \x00\x15\x00\x19\x00\x1d\x00!\x00%\x00-\x00;\x00?\x00C\x00G\x00K\x00O\x00\x00\x013\x15#\x15!\x15#\x11!\x01#\x153\x15!\x11#\x11#5!\x05\x11!\x11!\x11!\x11\x05#53\x05#53\x013\x11!\x11353\x013\x15#\x15#5#535#5!\x05\x11!\x11\x07#53\x05#53\x01#53\x05!5!\x01\xf4dd\xfepd\x01\xf4\x02\xbc\xc8\xc8\xfe\xd4\xc8d\x02X\xfb\xb4\x01,\x01\x90\x01,\xfc\xe0dd\x02\xbcdd\xfdD\xc8\xfe\x0c\xc8d\x01\xf4\xc8d\xc8dd\xc8\x01,\xfdD\x01,ddd\x03\x84dd\xfe\x0cdd\x01\xf4\xfe\xd4\x01,\x03\x84ddd\x02X\xfe\x0cd\xc8\x01,\x01,\xc8d\xfe\xd4\x01,\xfe\xd4\x01,\xc8ddd\xfe\x0c\xfe\x0c\x01\xf4d\xfe\xd4dddd\xc8d\xc8\xfe\xd4\x01,\xc8ddd\xfe\xd4ddd\x00\x00\x00\x00 \x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x03\x00\x07\x00\x0b\x00\x0f\x00\x13\x00\x17\x00\x1b\x00\x1f\x00#\x00\x007#\x113\x13#\x113\x01#\x113\x13#\x113\x01#\x113\x01!5!\x17#53\x17#53\x05#53ddd\xc8dd\x01\x90\xc8\xc8\xc8dd\x01,\xc8\xc8\xfc\xe0\xfe\xd4\x01,\xc8dd\xc8dd\x01,\xc8\xc8\xc8\x03\xe8\xfc\x18\x03\xe8\xfc\x18\x03\xe8\xfc\x18\x03\xe8\xfc\x18\x03\xe8\xfbPdd[[[[[\x00\x00\x02\x00\x00\x00\n\x04\xa6\x04\xb0\x00\x0d\x00\x15\x00\x00 \x01\x16\x14\x07\x01\x06\"'\x01\x13463\x04&\"\x06\x14\x1626\x01\xf4\x02\xaa\x08\x08\xfe0\x08\x14\x08\xfdV\x01\x0f\n\x01C;S;;S;\x04\xb0\xfdV\x08\x14\x08\xfe0\x08\x08\x02\xaa\x01\xdb\n\x0f\xcd;;T;;\x00\x00\x00\x00\x03\x00\x00\x00\n\x05\xd2\x04\xb0\x00\x0d\x00\x19\x00!\x00\x00 \x01\x16\x14\x07\x01\x06\"'\x01\x13463!\x01\x16\x14\x07\x01\x06\"/\x01 \x01\x04&\"\x06\x14\x1626\x01\xf4\x02\xaa\x08\x08\xfe0\x08\x14\x08\xfdV\x01\x0f\n\x03\x06\x02\xaa\x08\x08\xfe0\x08\x14\x088\x01\xa8\xfdD\xfe\xd3;S;;S;\x04\xb0\xfdV\x08\x14\x08\xfe0\x08\x08\x02\xaa\x01\xdb\n\x0f\xfdV\x08\x14\x08\xfe0\x08\x088\x01\xaa\x02\xbc\xcd;;T;;\x00\x00\x00\x00\x01\x00d\x00\x00\x04\xb0\x04\xb0\x00&\x00\x00\x01!2\x15\x11\x14\x0f\x01\x06&5\x114&#!\"\x0f\x01\x06\x163!2\x16\x15\x11\x14\x06#!\"&5\x114?\x016\x01,\x039K\x12@\x08\n\x0f\n\xfdD\x19\x12@\x08\x05\n\x02\xbc\n\x0f\x0f\n\xfc\xae\n\x0f\x12\x8b\x12\x04\xb0K\xfc|\x19\x12@\x08\x05\n\x03\xb6\n\x0f\x12@\x08\n\x0f\n\xfcJ\n\x0f\x0f\n\x03\xcf\x19\x12\x8b\x12\x00\x00\x00\x01\x00\xc8\xff\xff\x04L\x04\xb0\x00\n\x00\x00\x13!2\x16\x15\x11 \x01\x1146\xfa\x03 \x15\x1d\xfe>\xfe>\x1d\x04\xb0\x1d\x15\xfb\x82\x01\xbc\xfeC\x04\x7f\x15\x1d\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x15\x00E\x00U\x00\x00\x01!\"\x06\x07\x03\x06\x1f\x01\x1e\x013!26?\x016'\x03.\x01\x01#\"\x06\x0f\x01\x0e\x01#!\"&/\x01.\x01+\x01\"\x06\x15\x11\x14\x16;\x0126=\x01463!2\x16\x1d\x01\x14\x16;\x01265\x114&\x01!\"\x06\x0f\x01\x06\x163!26/\x01.\x01\x036\xfeD\x0b\x10\x01N\x07\x0e9\x06\x17\n\x01\xc2\n\x17\x06>\x0e\x07S\x01\x10\x01V\x96\n\x16\x04N\x04\x16\n\xfd\xda\n\x16\x04N\x04\x16\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x02\xee\n\x0f\x0f\n\x96\n\x0f\x0f\xfe\xb1\xfe\x0c\n\x13\x02&\x02\x0b\n\x02X\n\x0b\x02&\x02\x13\x04\xb0\x0f\n\xfe\xd3\x18\x15l \x0c\x0c l\x15\x18\x01-\n\x0f\xfep\x0d \x9c \x0d\x0d \x9c \x0d\x0f\n\xfdv\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x02\x8a\n\x0f\xfd\xa8\x0e\n\x98\n\x0e\x0e\n\x98\n\x0e\x00\x00\x00\x00\x04\x00\x00\x00d\x04\xb0\x04L\x00\x1d\x00!\x00)\x001\x00\x00\x0132\x1e\x02\x1f\x0132\x16\x15\x11\x14\x06#!\"&5\x1146;\x01>\x04\x01\x1535\x04\"\x06\x14\x16264$2\x16\x14\x06\"&4\x01\xf4\xc88]4$\x07\x06\x96);;)\xfc\x18);;)\x96\x02 '3]\x01\xc8d\xfe\xcf\xbe\x87\x87\xbe\x87\xfe\xefV<\x01?\x01\x01\x03!\x03\x02\xa9\x01\x81\x14(\x12% \n\xfe_5,\x11R\xfey:\"\x0b *2\x1e\xfe\x938\x1c\x0c\x1a\x07\x07\x01\x8f\xac\x01T\xa2\x04\xaf\xfc\x1a2*\x13\x15\x01\x02BBW-\xde\x91Y\".\x1c\x0cBB\x18\x1c\x0c%\x0d\x0d\x03\xee\xfdZ\x01\xc9\x00\x00\x00\x00\x03\x00d\x00\x00\x03\xf0\x04\xb0\x00'\x002\x00;\x00\x00\x01\x1e\x06\x15\x14\x0e\x03#!5>\x015\x114.\x04'5\x052\x1e\x02\x15\x14\x0e\x02\x07%32654.\x02+\x01\x1132654&+\x01\x02\xf1\x05\x1350;*\x1d7Xml0\xfe\x0c);\x01\x06\x0b\x17!\x1a\x01\xd79uc>\x1f--\x10\xfe\x8f\x8bNi\x11*S>v\xd8PR}^\x9f\x02\x81\x01\x07\x18\x1d3:R.CuN7\x1aY\x073(\x03;\x18\x14\x1c\x0b\x10 \x07G\x01)IsC3[:+ 1aJ);4\x1b\xfc\xaeePZ\x81\x00\x00\x01\x00\xc8\x00\x00\x03o\x04\xb0\x00\x19\x00\x00\x01\x17\x0e\x01\x07\x03\x06\x16\x17\x15!567\x1364.\x04'&'5\x03m\x02SB\x07\x84 ,J\xfe\x0c\xba\x0e\xad\x03\x03\x0f\x0c\x1f\x15\x17\x0d\x06\x04\xb09\x135(\xfc\xb91(\x06aa\x10R\x03@\x11\x1a\x13\x10 \x0b\x06\x07\x03\x029\x00\x00\x00\x00\x02\xff\xb5\x00\x00\x05\x14\x04\xb0\x00%\x00/\x00\x00\x01#4.\x05+\x01\x11\x14\x16\x1f\x01\x15!52>\x035\x11#\"\x0e\x05\x15#\x11!\x05#\x113\x07'3\x11#7\x05\x142\x08\x0b\x19\x13&\x18\x19\xc82\x19\x19\xfep\x04\x0e\"\x1a\x16\xc8\x19\x18&\x13\x19\x0b\x082\x03\xe8\xfb\x9bKK}}KK}\x03\x84\x15 \x15\x0e\x08\x03\x01\xfc\xae\x16\x19\x01\x02dd\x01\x05 \x15\x0e\x03R\x01\x03\x08\x0e\x15 \x15\x01,\xc8\xfc\xe0\xa7\xa7\x03 \xa7\x00\x02\x00!\xff\xb5\x04\x8f\x04\xb0\x00%\x00/\x00\x00\x01#4.\x05+\x01\x11\x14\x16\x1f\x01\x15!52>\x035\x11#\"\x0e\x05\x15#\x11!\x13\x075!\x15'7\x15!5\x04L2\x08\x0b\x19\x13&\x18\x19\xc82\x19\x19\xfep\x04\x0e\"\x1a\x16\xc8\x19\x18&\x13\x19\x0b\x082\x03\xe8C\xa7\xfc\xe0\xa7\xa7\x03 \x03\x84\x15 \x15\x0e\x08\x03\x01\xfdv\x16\x19\x01\x02dd\x01\x05 \x15\x0e\x02\x8a\x01\x03\x08\x0e\x15 \x15\x01,\xfb\x82}KK}}KK\x00\x04\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x1f\x00/\x00?\x00\x00\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x01462\x02X\x15\x1d\x1d\x15\xfd\xa8\x15\x1d\x1d\x15\x03\xe8\x15\x1d\x1d\x15\xfc\x18\x15\x1d\x1d\x15\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\x15\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x04\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x1f\x00/\x00?\x00\x00\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x03!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x03!2\x16\x1d\x01\x14\x06#!\"&=\x0146\xfa\x02\xbc\x15\x1d\x1d\x15\xfdD\x15\x1d\x1d\xb3\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\xdd\x02\xbc\x15\x1d\x1d\x15\xfdD\x15\x1d\x1d\xb3\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x04\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x1f\x00/\x00?\x00\x00\x015463!2\x16\x1d\x01\x14\x06#!\"&\x015463!2\x16\x1d\x01\x14\x06#!\"&\x135463!2\x16\x1d\x01\x14\x06#!\"&\x015463!2\x16\x1d\x01\x14\x06#!\"&\x01\xf4\x1d\x15\x02X\x15\x1d\x1d\x15\xfd\xa8\x15\x1d\xfep\x1d\x15\x03\xe8\x15\x1d\x1d\x15\xfc\x18\x15\x1d\xc8\x1d\x15\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\xfe\xd4\x1d\x15\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x03\xb6d\x15\x1d\x1d\x15d\x15\x1d\x1d\xfe\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\xfe\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\xfe\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x1f\x00/\x00?\x00\x00\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x01462\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x15\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x15\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x15\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x08\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x1f\x00/\x00?\x00O\x00_\x00o\x00\x7f\x00\x00\x1332\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146)\x012\x16\x1d\x01\x14\x06#!\"&=\x01462d\x15\x1d\x1d\x15d\x15\x1d\x1d\x01A\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\xfe\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\x01A\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\xfe\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\x01A\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\xfe\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\x01A\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x00\x06\xff\x9c\x00\x00\x04\xb0\x04L\x00\x03\x00\x13\x00#\x00*\x00:\x00J\x00\x00!#\x11;\x022\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x05\x075#535\x05!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x01\x90dd\x96d\x15\x1d\x1d\x15d\x15\x1d\x1d\x15\x01\xf4\x15\x1d\x1d\x15\xfe\x0c\x15\x1d\x1d\xfe\xfa\xa7\xc8\xc8\x01\xc2\x01,\x15\x1d\x1d\x15\xfe\xd4\x15\x1d\x1d\x15\x02X\x15\x1d\x1d\x15\xfd\xa8\x15\x1d\x1d\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfa}KdK\xaf\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x00\x00\x06\x00\x00\x00\x00\x05\x14\x04L\x00\x0f\x00\x13\x00#\x00*\x00:\x00J\x00\x00\x1332\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x01#\x113\x01!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x053\x15#\x15'7\x05!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x01462d\x15\x1d\x1d\x15d\x15\x1d\x1d\x03gdd\xfc\xae\x01\xf4\x15\x1d\x1d\x15\xfe\x0c\x15\x1d\x1d\x04/\xc8\xc8\xa7\xa7\xfb\xe6\x01,\x15\x1d\x1d\x15\xfe\xd4\x15\x1d\x1d\x15\x02X\x15\x1d\x1d\x15\xfd\xa8\x15\x1d\x1d\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfb\xb4\x04L\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xc8dK}}\xaf\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfe\xd4\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x00\x00\x00\x02\x00\x00\x00\xc8\x04\xb0\x03\xe8\x00\x0f\x00\x12\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146 \x02K\x02\xee\x1f,,\x1f\xfd\x12\x1f,,\x04\x84\xfe\xd4\x01,\x03\xe8,\x1f\xfdv\x1f,,\x1f\x02\x8a\x1f,\xfdD\x01,\x01,\x00\x03\x00\x00\x00\x00\x04\xb0\x04L\x00\x0f\x00\x17\x00\x1f\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x117\x05'\x01\x13\x11\x042\x16\x14\x06\"&4,\x04X\x12\x1a\x1a\x12\xfb\xa8\x12\x1a\x1aJ\xf7\x01*J\x01%\xec\xfc\xd2pNNpN\x04L\x1a\x12\xfc\x0c\x12\x1a\x1a\x12\x03\xf4\x12\x1ad\xfd\x1f\xb6\x83\x9c\x01>\xfe\xe0\x01\xf4tNoOOo\x00\x00\x00\x00\x02\x00\xdb\x00\x05\x046\x04\x91\x00\x16\x00\x1e\x00\x00\x012\x1e\x01\x15\x14\x07\x0e\x01\x0f\x01.\x04'&54>\x02\x16\"\x06\x14\x16264\x02\x88u\xc6sFE\xb266 !^Xm)\x08!fh\x98H\x84uX\xa3yH\xc3\x82\xb8\x81\x81\xb8\x00\x00\x00\x02\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x17\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x01\x11\"\x0e\x01\x14\x1e\x01\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01Kt\xc5rr\xc5\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b\xfco\x03Vr\xc5\xe8\xc5r\x00\x00\x02\x00u\x00\x03\x03\xdf\x05\x0f\x00\x1a\x005\x00\x00\x01\x1e\x06\x15\x14\x0e\x03\x07.\x0354>\x05\x03\x0e\x02\x17\x1e\x04\x17\x166?\x016&'.\x02'&76#&\x02*\x15IOWN>%3Vp}?T\x9b|J$?LWPI\xbc\x17)(\x03\x01\x1b!1\x1c\x13\x15\x16\x02\x06\x02 \x05\x12)\x0c\x1a \x02\x08\x08\x05\x0fH\x8fuwsu\x87EG\x80^F&\x04\x05:c\x97YE\x87vsxv\x90\xfd\xfe!K\x82:%A'#\x0e\x08\x07\x0c\x10\"\n\x18\x07\x04\x10A)Y\xb6\x0b\x01\x00\x00\x00\x03\x00\x00\x00\x00\x04\xcb\x04l\x00\x0c\x00*\x00/\x00\x00\x017>\x02\x1e\x01\x17\x1e\x01\x0f\x02%!2\x17\x07!\"\x06\x15\x11\x14\x163!26=\x017\x11\x14\x06#!\"&5\x1146 \x01\x077\x01\x03\xe8l\x02\x06\x14\x15\x1d\x0e\x16\n\x05\x06l\xfd\x05\x01\x9027\xbb\xfe\x90);;)\x01\xf4);\xc8\xbb\xa3\xfep\xa5\xb9\xb9\x038\xfe\x96\xa17\x01c\x03\xf5s\x01\x02\x02\x04\x0f\x0e\x16*\x0b\ns\xc8\x0d\xbb;)\xfe\x0c);;)\xb6\xc8\xfe\xb4\xa5\xb9\xb9\xa5\x01\x90\xa5\xb9\xfe\xd7\xfe\x962\xaa\x01c\x00\x02\x00\x00\x00\x00\x04\x93\x04L\x00\x1b\x006\x00\x00\x01!\x06\x07#\"\x06\x15\x11\x14\x163!2657\x15\x14\x06#!\"&5\x1146\x05\x01\x16\x14\x07\x01\x06&'5&\x0e\x03\x07>\x0675>\x01\x01^\x01i\xa44\xc3);;)\x01\xf4);\xc8\xb9\xa5\xfep\xa5\xb9\xb9\x02\x7f\x01S\x08\x08\xfe\xac\x07\x0b\x01\x1a9dTX\x1a\n.9I@F*\x13\x01\x0b\x04L\x926;)\xfe\x0c);;)\x99g\xa5\xb9\xb9\xa5\x01\x90\xa5\xb9\x1b\xfe\xd3\x07\x15\x07\xfe\xce\x06\x04 \xcb\x01\x02\x0d\x160!;bA4\x1d\x14\x07\x01\xd2\n\x05\x00\x00\x00\x00\x02\x00\x00\x00\x00\x04\x9d\x04L\x00\x1d\x005\x00\x00\x01!2\x17\x07!\"\x06\x15\x11\x14\x163!26=\x017\x15\x14\x06#!\"&5\x1146 \x0162\x1f\x01\x16\x14\x07\x01\x06\"/\x01&4?\x0162\x1f\x01\x162\x01^\x01^\x01\x08\x08\x14\x08\x01\x04\x07\x05\n\xaa\xc8\n\x08\x01\x08\x08\x08\xfe\xf8\x08\n\xc8\xaa\n\x05\x07\xfe\xfc\x08\x14\x08\xfe\xf8\x08\x05\n\xaf\xc8\n\x08\xfe\xf8\x08\x08\x01\x08\x08\n\xc8\xaf\n\x05\x03\x96\x01\x08\x08\x08\xfe\xf8\x08\n\xc8\xad\n\x04\x07\xfe\xfc\x07\x15\x07\xfe\xf7\x07\x04\n\xad\xc8\n\x08\xfe\xf8\x08\x08\x01\x08\x08\n\xc8\xad\n\x04\x07\x01 \x07\x15\x07\x01\x04\x07\x04\n\xad\xc8\n\x00\x01\x00\xc8\x00\x00\x03\x84\x04L\x00\x19\x00\x00\x1332\x16\x15\x11\x016\x16\x15\x11\x14\x06'\x01\x11\x14\x06+\x01\"&5\x1146\xfad\x15\x1d\x01\xd0\x0f\x15\x15\x0f\xfe0\x1d\x15d\x15\x1d\x1d\x04L\x1d\x15\xfeJ\x01\xc5\x0e\x08\x15\xfc\x18\x15\x08\x0e\x01\xc5\xfeJ\x15\x1d\x1d\x15\x03\xe8\x15\x1d\x00\x00\x00\x01\x00\x00\x00\x00\x04\xb0\x04L\x00#\x00\x00\x1332\x16\x15\x11\x016\x16\x15\x11\x016\x16\x15\x11\x14\x06'\x01\x11\x14\x06'\x01\x11\x14\x06+\x01\"&5\x11462d\x15\x1d\x01\xd0\x0f\x15\x01\xd0\x0f\x15\x15\x0f\xfe0\x15\x0f\xfe0\x1d\x15d\x15\x1d\x1d\x04L\x1d\x15\xfeJ\x01\xc5\x0e\x08\x15\xfeJ\x01\xc5\x0e\x08\x15\xfc\x18\x15\x08\x0e\x01\xc5\xfeJ\x15\x08\x0e\x01\xc5\xfeJ\x15\x1d\x1d\x15\x03\xe8\x15\x1d\x00\x00\x00\x01\x00\x9d\x00\x19\x04\xb0\x043\x00\x15\x00\x00\x01\x11\x14\x06'\x01\x11\x14\x06'\x01&47\x016\x16\x15\x11\x016\x16\x04\xb0\x15\x0f\xfe0\x15\x0f\xfe\x14\x0f\x0f\x01\xec\x0f\x15\x01\xd0\x0f\x15\x04\x1a\xfc\x18\x15\x08\x0e\x01\xc5\xfeJ\x15\x08\x0e\x01\xe0\x0e*\x0e\x01\xe0\x0e\x08\x15\xfeJ\x01\xc5\x0e\x08\x00\x00\x00\x01\x00\xc8\x00\x16\x043\x046\x00\x0b\x00\x00\x13\x01\x16\x14\x07\x01\x06&5\x1146\xf3\x03.\x12\x12\xfc\xd2\x12\x19\x19\x042\xfe\x0e\x0b\x1e\x0b\xfe\x0e\x0b\x0e\x15\x03\xe8\x15\x0e\x00\x02\x00\xc8\x00d\x03\x84\x03\xe8\x00\x0f\x00\x1f\x00\x00\x1332\x16\x15\x11\x14\x06+\x01\"&5\x1146!32\x16\x15\x11\x14\x06+\x01\"&5\x1146\xfa\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x01\xa5\xc8\x15\x1d\x1d\x15\xc8\x15\x1d\x1d\x03\xe8\x1d\x15\xfc\xe0\x15\x1d\x1d\x15\x03 \x15\x1d\x1d\x15\xfc\xe0\x15\x1d\x1d\x15\x03 \x15\x1d\x00\x00\x01\x00\xc8\x00d\x04L\x03\xe8\x00\x0f\x00\x00\x01\x11\x14\x06#!\"&5\x11463!2\x16\x04L\x1d\x15\xfc\xe0\x15\x1d\x1d\x15\x03 \x15\x1d\x03\xb6\xfc\xe0\x15\x1d\x1d\x15\x03 \x15\x1d\x1d\x00\x00\x00\x00\x01\x00\x00\x00\x19\x04\x13\x043\x00\x15\x00\x00\x01\x1146\x17\x01\x16\x14\x07\x01\x06&5\x11\x01\x06&5\x1146\x17\x01\xf4\x15\x0f\x01\xec\x0f\x0f\xfe\x14\x0f\x15\xfe0\x0f\x15\x15\x0f\x02d\x01\xb6\x15\x08\x0e\xfe \x0e*\x0e\xfe \x0e\x08\x15\x01\xb6\xfe;\x0e\x08\x15\x03\xe8\x15\x08\x0e\x00\x00\x01\xff\xfe\x00\x02\x04\xb3\x04O\x00#\x00\x00\x0172\x16\x15\x13\x14\x06#\x07\"&5\x03\x01\x06&5\x03\x01\x06&5\x0346\x17\x01\x0346\x17\x01\x0346\x04\x18d\x14\x1e\x05\x1d\x15d\x15\x1d\x02\xfe1\x0e\x15\x02\xfe2\x0f\x15\x05\x15\x0f\x01\xd2\x02\x15\x0f\x01\xd2\x02\x1d\x04N\x01\x1d\x15\xfc\x18\x15\x1d\x01\x1d\x15\x01\xb5\xfe:\x0f \x15\x01\xb5\xfe9\x0e \x14\x03\xe8\x15 \x0f\xfe>\x01\xb6\x14 \x0e\xfe=\x01\xb6\x15\x1d\x00\x00\x01\x01,\x00\x00\x03\xe8\x04L\x00\x19\x00\x00\x0132\x16\x15\x11\x14\x06+\x01\"&5\x11\x01\x06&5\x1146\x17\x01\x1146\x03Rd\x15\x1d\x1d\x15d\x15\x1d\xfe0\x0f\x15\x15\x0f\x01\xd0\x1d\x04L\x1d\x15\xfc\x18\x15\x1d\x1d\x15\x01\xb6\xfe;\x0e\x08\x15\x03\xe8\x15\x08\x0e\xfe;\x01\xb6\x15\x1d\x00\x00\x02\x00d\x00\xc8\x04\xb0\x04H\x00\x0b\x00\x1b\x00\x00 \x01\x16\x06#!\"&7\x0162\x01!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x02\xae\x01\xf5\x0f \x16\xfb\xee\x16 \x0f\x01\xf5\x0f*\xfd\xf7\x03\xe8\x15\x1d\x1d\x15\xfc\x18\x15\x1d\x1d\x049\xfd\xe4\x0f\x16\x16\x0f\x02\x1c\x0f\xfdH\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x01\x00\x88\xff\xfc\x03u\x04J\x00\x05\x00\x00 \x02\x07 \x01\x03u\xfe\xa0\x01`\xc5\xfd\xd8\x02(\x03\x84\xfe\x9f\xfe\x9f\xc6\x02(\x02&\x00\x00\x00\x00\x01\x01;\xff\xfc\x04(\x04J\x00\x05\x00\x00 \x01' \x017\x04(\xfd\xd9\xc6\x01a\xfe\x9f\xc6\x02#\xfd\xd9\xc6\x01a\x01a\xc6\x00\x02\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x003\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x05#\"\x06\x1d\x01#\"\x06\x1d\x01\x14\x16;\x01\x15\x14\x16;\x0126=\x01326=\x014&+\x0154&\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01}d\x15\x1d\x96\x15\x1d\x1d\x15\x96\x1d\x15d\x15\x1d\x96\x15\x1d\x1d\x15\x96\x1d\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b\xba\x1d\x15\x96\x1d\x15d\x15\x1d\x96\x15\x1d\x1d\x15\x96\x1d\x15d\x15\x1d\x96\x15\x1d\x00\x00\x00\x00\x02\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1f\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x01!\"\x06\x1d\x01\x14\x163!26=\x014&\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x02E\xfe\x0c\x15\x1d\x1d\x15\x01\xf4\x15\x1d\x1d\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b\xfe~\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x02\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x003\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0f\x01'&\"\x0f\x01\x06\x14\x1f\x01\x07\x06\x14\x1f\x01\x162?\x01\x17\x162?\x0164/\x01764/\x01\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xe5\x19 xx \x19 \x8d xx \x8d \x19 xx \x19 \x8d xx \x8d\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b\xad xx \x8d \x19 xx \x19 \x8d xx \x8d \x19 xx \x19 \x8d\x00\x02\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00$\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x01'&\"\x0f\x01\x06\x14\x1f\x01\x1627\x0164/\x01&\"\x07\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\x15T\x07\x15\x08\x8b\x07\x07\xf2\x07\x15\x07\x01w\x07\x07\x8b\x07\x15\x07\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b\xfe1U\x07\x07\x8b\x08\x14\x08\xf1\x08\x08\x01w\x07\x15\x08\x8b\x07\x07\x00\x00\x00\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00;\x00K\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x05\"\x0e\x03\x15\x14;\x01\x167>\x0132\x16\x15\x14\x06\x07\"\x0e\x05\x07\x06\x16;\x012>\x0354.\x03\x13#\"\x06\x1d\x01\x14\x16;\x0126=\x014&\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01?\x1d\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x05#\"\x06\x1d\x01\x14\x16;\x0126=\x014&\x03#\"\x06\x1d\x01\x14\x16;\x01\x15#\"\x06\x1d\x01\x14\x163!26=\x014&+\x01\x114&\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\x96\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\xfa\n\x0f\x0f\nKK\n\x0f\x0f\n\x01^\n\x0f\x0f\nK\x0f\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9bV\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\xfe\xd4\x0f\n2\n\x0f\xc8\x0f\n2\n\x0f\x0f\n2\n\x0f\x01\x13\n\x0f\x00\x02\x00\x00\x00\x00\x04\xb0\x04\xb0\x00/\x00_\x00\x00\x0132\x16\x1d\x01\x1e\x01\x1732\x16\x1d\x01\x14\x06+\x01\x0e\x01\x07\x15\x14\x06+\x01\"&=\x01.\x01'#\"&=\x0146;\x01>\x017546\x13\x15\x14\x06+\x01\"&=\x01\x0e\x01\x0732\x16\x1d\x01\x14\x06+\x01\x1e\x01\x17546;\x012\x16\x1d\x01>\x017#\"&=\x0146;\x01.\x01\x02\x0d\x96\n\x0fg\x97\x1b\xc2\n\x0f\x0f\n\xc2\x1b\x97g\x0f\n\x96\n\x0fg\x97\x1b\xc2\n\x0f\x0f\n\xc2\x1b\x97g\x0f\xb9\x0f\n\x96\n\x0fDf\x17\xa8\n\x0f\x0f\n\xa8\x17fD\x0f\n\x96\n\x0fDf\x17\xa8\n\x0f\x0f\n\xa8\x17f\x04\xb0\x0f\n\xc2\x1b\x97g\x0f\n\x96\n\x0fg\x97\x1b\xc2\n\x0f\x0f\n\xc2\x1b\x97g\x0f\n\x96\n\x0fg\x97\x1b\xc2\n\x0f\xfe\xcd\xa8\n\x0f\x0f\n\xa8\x17fD\x0f\n\x96\n\x0fDf\x17\xa8\n\x0f\x0f\n\xa8\x17fD\x0f\n\x96\n\x0fDf\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1b\x00?\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x07\x17\x16\x14\x0f\x01\x17\x16\x14\x0f\x01\x06\"/\x01\x07\x06\"/\x01&4?\x01'&4?\x0162\x1f\x01762\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xbf\xe8\xc5rr\xc5\xe8\xc5rr\x9a@\x07\x07||\x07\x07@\x07\x15\x07||\x07\x15\x07@\x07\x07||\x07\x07@\x07\x15\x07||\x07\x15\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5\xe8\xc5rr\xc5\xe8\xc5Z@\x07\x15\x07||\x07\x15\x07@\x07\x07||\x07\x07@\x07\x15\x07||\x07\x15\x07@\x07\x07||\x07\x00\x00\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1b\x000\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x07\x17\x16\x14\x07\x01\x06\"/\x01&4?\x0162\x1f\x01762\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xbf\xe8\xc5rr\xc5\xe8\xc5rr\x83j\x07\x07\xfe\xc0\x08\x14\x08\xca\x08\x08j\x07\x15\x07O\xc5\x07\x15\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5\xe8\xc5rr\xc5\xe8\xc5}j\x07\x15\x07\xfe\xbf\x07\x07\xcb\x07\x15\x07j\x08\x08O\xc5\x07\x00\x00\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x18\x00!\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x05\"\x0e\x01\x15\x14\x17\x01&\x17\x01\x1632>\x0154\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01Kt\xc5rA\x02Ki\xf5\xfd\xb8hst\xc5r\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b;r\xc5txi\x02KA\xd0\xfd\xb8>r\xc5ts\x00\x00\x00\x00\x01\x00\x17\x00S\x04\xb0\x03\xf9\x00\x15\x00\x00\x13\x016\x16\x15\x11!2\x16\x1d\x01\x14\x06#!\x11\x14\x06'\x01&4'\x02\n\x10\x17\x02&\x15\x1d\x1d\x15\xfd\xda\x17\x10\xfd\xf6\x10\x02F\x01\xab\x0d\n\x15\xfe\xdd\x1d\x15\xc8\x15\x1d\xfe\xdd\x15\n\x0d\x01\xab\x0d&\x00\x00\x00\x00\x01\x00\x00\x00S\x04\x99\x03\xf9\x00\x15\x00\x00 \x01\x16\x14\x07\x01\x06&5\x11!\"&=\x01463!\x1146\x02\x7f\x02\n\x10\x10\xfd\xf6\x10\x17\xfd\xda\x15\x1d\x1d\x15\x02&\x17\x03\xf1\xfeU\x0d&\x0d\xfeU\x0d\n\x15\x01#\x1d\x15\xc8\x15\x1d\x01#\x15\n\x00\x00\x00\x01\x00\xb7\x00\x00\x04]\x04\x99\x00\x15\x00\x00 \x01\x16\x06#!\x11\x14\x06+\x01\"&5\x11!\"&7\x0162\x02\xaa\x01\xab\x0d\n\x15\xfe\xdd\x1d\x15\xc8\x15\x1d\xfe\xdd\x15\n\x0d\x01\xab\x0d&\x04\x89\xfd\xf6\x10\x17\xfd\xda\x15\x1d\x1d\x15\x02&\x17\x10\x02\n\x10\x00\x00\x00\x01\x00\xb7\x00\x17\x04]\x04\xb0\x00\x15\x00\x00\x0132\x16\x15\x11!2\x16\x07\x01\x06\"'\x01&63!\x1146\x02&\xc8\x15\x1d\x01#\x15\n\x0d\xfeU\x0d&\x0d\xfeU\x0d\n\x15\x01#\x1d\x04\xb0\x1d\x15\xfd\xda\x17\x10\xfd\xf6\x10\x10\x02\n\x10\x17\x02&\x15\x1d\x00\x00\x01\x00\x00\x00\xb7\x04\x99\x04]\x00\x17\x00\x00 \x01\x16\x14\x07\x01\x06&5\x11\x0e\x03\x07>\x047\x1146\x02\x7f\x02\n\x10\x10\xfd\xf6\x10\x17^\xb0\xa5\x81$\x05,[\x87\xc7~\x17\x04U\xfeU\x0d&\x0d\xfeU\x0d\n\x15\x01#\x02$DuMi\xb1\x9dqF\x07\x01\x06\x15\n\x00\x02\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x15\x00+\x00\x00\x01!2\x16\x15\x11\x14\x06/\x01\x07\x06\"/\x01&4?\x01'&6\x01!\"&5\x1146\x1f\x01762\x1f\x01\x16\x14\x0f\x01\x17\x16\x06\x03R\x01,\x15\x1d\x15\x0e^\xf9\x08\x14\x08j\x07\x07\xf9^\x0e\x08\xfe!\xfe\xd4\x15\x1d\x15\x0e^\xf9\x08\x14\x08j\x07\x07\xf9^\x0e\x08\x04\xb0\x1d\x15\xfe\xd4\x15\x08\x0e^\xf9\x07\x07j\x08\x14\x08\xf9^\x0e\x15\xfbP\x1d\x15\x01,\x15\x08\x0e^\xf9\x07\x07j\x08\x14\x08\xf9^\x0e\x15\x00\x00\x00\x02\x00I\x00I\x04g\x04g\x00\x15\x00+\x00\x00\x01\x17\x16\x14\x0f\x01\x17\x16\x06#!\"&5\x1146\x1f\x01762\x01!2\x16\x15\x11\x14\x06/\x01\x07\x06\"/\x01&4?\x01'&6\x03\xf6j\x07\x07\xf9^\x0e\x08\x15\xfe\xd4\x15\x1d\x15\x0e^\xf9\x08\x14\xfd\x0c\x01,\x15\x1d\x15\x0e^\xf9\x08\x14\x08j\x07\x07\xf9^\x0e\x08\x04`j\x08\x14\x08\xf9^\x0e\x15\x1d\x15\x01,\x15\x08\x0e^\xf9\x07\xfd\xf1\x1d\x15\xfe\xd4\x15\x08\x0e^\xf9\x07\x07j\x08\x14\x08\xf9^\x0e\x15\x00\x00\x00\x00\x03\x00\x17\x00\x17\x04\x99\x04\x99\x00\x0f\x00\x1f\x00/\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x05#\"\x06\x17\x13\x1e\x01;\x01267\x136&\x03#\"\x06\x1d\x01\x14\x16;\x0126=\x014&\x01\xe3\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b[[\x9b\x01\xb3\xd0\x14\x18\x04:\x04#\x146\x14#\x04:\x04\x181\x96\n\x0f\x0f\n\x96\n\x0f\x0f\x04\x99[\x9b\xd6\xea\xd6\x9b[[\x9b\xd6\xea\xd6\x9b\xba\x1d\x14\xfe\xd2\x14\x1d\x1d\x14\x01.\x14\x1d\xfe\x0c\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x00\x00\x00\x00\x05\x00\x00\x00\x00\x04\xb0\x04\xb0\x00I\x00U\x00a\x00h\x00o\x00\x00\x012\x16\x1f\x01\x16\x1f\x01\x16\x17\x1676?\x0167632\x16\x1f\x01\x16\x1f\x02\x1e\x01;\x012\x16\x1d\x01\x14\x06+\x01\"\x06\x1d\x01!\x11#\x11!54&+\x01\"&=\x0146;\x012654?\x0167>\x04\x05\x07\x06\x16;\x0126/\x01.\x01\x05'&\x06\x0f\x01\x06\x16;\x0126\x13!\"&5\x11)\x01\x11\x14\x06#!\x11\x01\x04 \x14\x05\x05\x16\x16\xc4\x15\x0f\x1d\x08\x0b&\xc4\x16\x17\x11\x15\x170\x0d\x0d\x0e\x04\x19\x08\x01\x0f\n=\n\x0f\x0f\n2\n\x0f\xfep\xc8\xfep\x0f\n2\n\x0f\x0f\n=\x0b\x0e \x19\x05\x0e\x02\x06\x15\x16\x1f\x02\x9d\xa6\x07\x04\n\xdb\n\n\x033\x03\x10\xfe5\xb1\x08\x10\x033\x03\n\n\xe7\x0b\x03\x1e\xfe\x89\n\x0f\x01\x90\x02X\x0f\n\xfe\x89\x04\xb0\x04\x02\x02\n\x0dv\x0d\x0b\x15 \x0d\x16v\x0d\n\x07!\x11\x10\x15\x18{, \x0b\x0f\n2\n\x0f\x0f\n\xaf\x01,\xfe\xd4\xaf\n\x0f\x0f\n2\n\x0f\x06\x05\x040\x80\x19\x14\x03\x08\x16\x11\x0ey\xa2\x07\n\x0e\n\x95\n\x04\xaa\x9d\x07\x04\n\x8f\n\x0e\n\xfcr\x0f\n\x01w\xfe\x89\n\x0f\x01\x90\x00\x00\x00\x00\x02\x00\x00\x00\x0c\x04\xaf\x04\xa6\x00+\x00I\x00\x00\x016\x16\x15\x06\x02\x0e\x04.\x01'&\x07&\x0e\x01\x0f\x01\x06&547>\x017>\x01'.\x01>\x017>\x06\x17&\x06\x07\x0e\x01\x0f\x01\x0e\x04\x07\x0e\x01\x1667>\x027>\x037>\x01\x04\x8d\x08\x1a\x02-Bla\x8bb\x8eD8=\x11\x04\x113\x1b\x99\x1a\x16*\x08U\x18\x13 \x03 \x02\x10:1'Ra\\\x87{\xc0%\x08\x1d\x1f&\xa2=>8\\tYR\x17\x18\x0e\x12-!\x19\x8aq[Fak[)\x16\x04\x04\xa6\x03\x13\x08\xb2\xfe\xdd\xc8\x95X1\x11\x08\x0b\x0b\x0c\x01\x01\x02\x1b\x1b\x99\x18\x13\"@&\x08J\x15\x11<\x1f7_\x7f\x85?3J5%#\x1b/D \x18&/q!!\x1e6ROg58<\x04'(\x1e[@1%@_\x7fU2\x14\x00\x01\x00]\x00\x1e\x04r\x04\xcf\x00O\x00\x00\x01\x0e\x01\x1e\x04\x17.\x07>\x017\x1e\x03\x06\x07\x0e\x04\x07\x06'&767>\x04.\x01'\x16\x0e\x03&'.\x01'&>\x047\x06\x1e\x037>\x01.\x02'&>\x03\x02\x8d'\x1f\n'8GB \x04\x1b\n\x18\n\x10\x03\x01 \x12\x0e`\x8aH \x06\x10\x0d>JS>\x16H7\x1f\x12\x06\x0b\x0d'+\" \x16NA\n\x155M[`/Pg\x02\x02\x04\x05\x16!;(\x08\x06\x1d'2\x18\x1f\x0f\x18\"&\x07\x0f\"IbY\x04\xcfC\x80e\\D9$\x0c\x078\x178\x1e6#1%)\x12*\x83\x91\xa7\x97J7gG: \x06\x16\x0b\x06\x0d\x03\x04\x05 8G\\au9h\xaaoK\x1d\x07\x15$\x9c]\x1754<\x04\x05&\x06\x17\x16\x15\x14\x06\"&5476&\x07\x06\x07\x0e\x01\x17\x1e\x042>\x0376&'&\x05\x07\x0e\x01\x17\x16\x17\x166?\x016&'&'.\x01\x02\x06\xa4\x9d{nO9\x1c\x1c:On{\x9d\xa2\x9d{nO:\x1c\x1c9On{\x02\x0f\x0f\x06\x08\x19\xb0\xf8\xb0\x17\x08\x07\x0eFZ\x0d\x04\x0b\x162Z_\x83\x88\x83_Z2\x16\x0b\x04\x0cZ\xfd\xff#\x0f %8\x10-\x0e#\x0e\x03\x0f,-\x0b\"\x04F-I\\b\\I*I\\b\\I--I\\b\\I*I\\b\\I\xdc\x0f\x06\x139>|\xb0\xb0|;7\x13\x06\x0fEs\x101\x12$F^D10E^E$\x121\x11u\x1e$\x0f/\x12D0\x0d\x04\x0f\"\x0f%\x0f,I\x12\x04\x00\x00\x00\x04\xff\xdc\x00\x00\x04\xd4\x04\xb0\x00\x14\x00'\x00;\x00L\x00\x00!#7.\x0454>\x0532\x1773\x137\x1e\x01\x15\x14\x0e\x03\x077>\x0176&'&%\x06\x07\x0e\x01\x17\x1e\x04\x177.\x015476&\x17\x07\x0e\x01\x17\x16\x17\x166?\x02'&'.\x01\x02P\x94\x1f[\xa9vY,\x1c9On{\x9dR=A \x94&/l\x89'Pj\x98R.Mv&\x0b\x04\x0c6\xfdQFZ\x0d\x04\x0b\x12*HLh5)k\x8f\x17\x08\x07|#\x0f %8\x10-\x0e\x0c\x16\x03,-\x0b\"x\x14atzb\x1b\x15I\\b\\I-\x0fy\xfeR\xb5U\xd64\x1aZrnc\x1a\xad1\x88?\x121\x11FrEs\x101\x12\x1e\xfe\xad\xfe\xbb\x0e1\x14)\x14\x0d\x0c\xf9\xfe\xf9]\x14@\x15\x10 \x80\x80 \x10\x15@\x14]\x01\x07\xf9\x0c\x0d\x14)\x141\x0e\x01E\x01S>\x00\x00\x00\x11\x00\x00\x00\x00\x04L\x04\xb0\x00\x1d\x00'\x00+\x00/\x003\x007\x00;\x00?\x00C\x00G\x00K\x00O\x00S\x00W\x00[\x00_\x00c\x00\x00\x0132\x16\x1d\x0132\x16\x1d\x01!546;\x01546;\x012\x16\x1d\x01!546\x01\x11\x14\x06#!\"&5\x11\x17\x15353\x15353\x15353\x15353\x1535\x05\x15353\x15353\x15353\x15353\x1535\x05\x15353\x15353\x15353\x15353\x1535\x03Rd\x15\x1d2\x15\x1d\xfb\xb4\x1d\x152\x1d\x15d\x15\x1d\x01\xf4\x1d\x01\x0f\x1d\x15\xfc\x18\x15\x1ddddddddddd\xfc|ddddddddd\xfc|ddddddddd\x04\xb0\x1d\x152\x1d\x15\x96\x96\x15\x1d2\x15\x1d\x1d\x1522\x15\x1d\xfep\xfd\x12\x15\x1d\x1d\x15\x02\xee\xc8dddddddddd\xc8dddddddddd\xc8dddddddddd\x00\x00\x00\x03\x00\x00\x00\x19\x05w\x04\x97\x00\x19\x00%\x007\x00\x00\x01\x17\x16\x14\x0f\x01\x06&=\x01#\x01!\"&=\x0146;\x01\x013546\x01\x07'#\"&=\x01463!\x01\x17\x16\x14\x0f\x01\x06&=\x01#'7\x173546\x04o\xf9\x0f\x0f\xf9\x0e\x15\x9f\xfd\xa8\xfe\xdd\x15\x1d\x1d\x15\xd1\x02X\xf1\x15\xfd\xa9\x8dz\xd1\x15\x1d\x1d\x15\x01#\x03\x1a\xf9\x0f\x0f\xf9\x0e\x15\xf1\xb5\x8dz\x9f\x15\x04\x8d\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xfd\xa8\x1d\x15d\x15\x1d\x02X\x96\x15\x08\xfe\x98\x8dz\x1d\x15d\x15\x1d\xfeM\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xb5\x8dz\x96\x15\x08\x00\x00\x00\x01\x00\x00\x00\x00\x04\xb0\x04L\x00\x12\x00\x00\x13!2\x16\x15\x11\x14\x06#!\x01\x11#\"&5\x1146d\x03\xe8);;)\xfd\xac\xfe\xd0d);;\x04L;)\xfd\xa8);\xfe\xd4\x01,;)\x02X);\x00\x00\x00\x03\x00d\x00\x00\x04L\x04\xb0\x00 \x00\x13\x00?\x00\x00\x1332\x16\x1d\x01!546!32\x16\x1d\x01!546\x01\x11\x14\x0e\x05\".\x055\x11!\x15\x14\x15\x1c\x01\x1e\x062>\x06&54=\x01\x96\xc8\x15\x1d\xfe\xd4\x1d\x02\xd1\xc8\x15\x1d\xfe\xd4\x1d\x01\x0f\x06\x18(Lf\x9c\xc0\x9cfL(\x18\x06\x01,\x03\x07\x0d\x14\x1f'6B6'\x1f\x13\x0f\x05\x05\x01\x04\xb0\x1d\x15\xfa\xfa\x15\x1d\x1d\x15\xfa\xfa\x15\x1d\xfep\xfe\xd4)IjV\\>((>\\VjI)\x01,\xfa \x12\x15+'%!\x1b\x16\x10\x08 \x10\x17\x1c!%'*\x15\x11\x08\xfa\x00\x00\x00\x01\xff\xff\x00\xd4\x04L\x03\xc2\x00\x05\x00\x00\x01\x07 \x01'\x01\x04L\xc6\xfe\x9f\xfe\x9f\xc5\x02'\x01\x9b\xc7\x01a\xfe\x9f\xc7\x02'\x00\x01\x00\x00\x00\xee\x04M\x03\xdc\x00\x05\x00\x00 \x027 \x01\x04M\xfd\xda\xfd\xd9\xc6\x01a\x01a\x03\x15\xfd\xd9\x02'\xc7\xfe\x9f\x01a\x00\x00\x00\x00\x02\xffQ\x00d\x05_\x03\xe8\x00\x14\x00)\x00\x00\x01!2\x16\x15\x1132\x16\x0f\x01\x06\"/\x01&6;\x01\x11!%\x17\x16\x06+\x01\x11!\x17!\"&5\x11#\"&?\x0162\x01\x94\x02\xea\x15\x1d\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xfe\x83\xfe\x1c\xe6\x0e\x08\x15\x96\x01\x81\xd7\xfd\x12\x15\x1d\x96\x15\x08\x0e\xe6\x0e*\x03\xe8\x1d\x15\xfd\xd9\x15\x0e\xf9\x0f\x0f\xf9\x0e\x15\x01\x91\xb8\xf9\x0e\x15\xfep\xc8\x1d\x15\x02&\x15\x0e\xf9\x0f\x00\x00\x01\x00\x06\x00\x00\x04\x9e\x04\xb0\x000\x00\x00\x1332\x16\x1f\x01!2\x16\x07\x03\x0e\x01#!\x17!2\x16\x14\x06+\x01\x15\x14\x06\"&=\x01!\x15\x14\x06\"&=\x01#\"&/\x01\x03#\"&468^\x11\x1c\x04&\x03\x80\x18\x1e\x05d\x05,!\xfd\x870\x02\x17\x15\x1d\x1d\x152\x1d*\x1d\xfe\xd4\x1d*\x1d\x1f\x12\x1d\x06\x05\xc96\x14\x1e\x1e\x04\xb0\x16\x10\xa2%\x18\xfe%\x15+\xc8\x1d*\x1d2\x15\x1d\x1d\x1522\x15\x1d\x1d\x152\x14 \n\x03\xc1\x1d*\x1d\x00\x00\x00\x00\x02\x00\x00\x00\x00\x04\xb0\x04L\x00\x0b\x00\x0f\x00\x00\x01\x15!53463!2\x16\x15\x05!\x11!\x04\xb0\xfbP\xc8;)\x01,);\xfdD\x04\xb0\xfbP\x03\xe8dd);;)\xc8\xfc\xe0\x00\x02\x00\x00\x00\x00\x05\xdc\x04L\x00\x0c\x00\x10\x00\x00\x13\x03\x113463!2\x16\x15!\x15\x05\x01!\x01\xc8\xc8\xc8;)\x01,*:\x01\xf4\x01,\xfe\xd4\xfbP\x01,\x03 \xfep\x02X);;)\xc8d\xfdD\x02\xbc\x00\x01\x01E\x00\x00\x03k\x04\xaf\x00\x1b\x00\x00\x01\x17\x16\x06+\x01\x1132\x16\x0f\x01\x06\"/\x01&6;\x01\x11#\"&?\x0162\x02{\xe6\x0e\x08\x15\x96\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\x96\x15\x08\x0e\xe6\x0e*\x04\xa0\xf9\x0e\x15\xfd\xa7\x15\x0e\xf9\x0f\x0f\xf9\x0e\x15\x02Y\x15\x0e\xf9\x0f\x00\x00\x00\x01\x00\x01\x01D\x04\xaf\x03k\x00\x1b\x00\x00\x01\x17\x16\x14\x0f\x01\x06&=\x01!\x15\x14\x06/\x01&4?\x016\x16\x1d\x01!546\x03\xa8\xf9\x0e\x0e\xf9\x0f\x15\xfd\xa8\x15\x0f\xf9\x0e\x0e\xf9\x0f\x15\x02X\x15\x03`\xe5\x0f)\x0f\xe5\x0f \x14\x97\x97\x14 \x0f\xe5\x0f)\x0f\xe5\x0f \x15\x95\x95\x15 \x00\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00 \x00\x19\x00\x1d\x00!\x00\x00\x01\x03.\x01#!\"\x06\x07\x03\x05!\"\x06\x1d\x01\x14\x163!26=\x014&\x0553\x15353\x15\x04\x91\xac\x05$\x14\xfd`\x14$\x05\xac\x04-\xfc\x18);;)\x03\xe8);;\xfe\xabddd\x01\x90\x02\xdc\x17-(\x15\xfd\x1dd;)d);;)d);\xc8dddd\x00\x00\x00\x03\xff\x9c\x00d\x04\xb0\x04L\x00\x0b\x00#\x001\x00\x00\x002\x16\x15\x11\x14\x06\"&5\x114\x03%#\x13\x16\x06#\"+\x01\"&'\x02=\x01454>\x01;\x01%\x01\x15\".\x03=\x014>\x027\x04i*\x1d\x1d*\x1dd\xfd]&/\x03\x11\x15\x05\x02T\x14\x1d\x047\x02\x0b\x0c\xc8\x02\xa3\xfc\x18\x04\x0e\"\x1a\x16\x15\x1d\x1d\x0b\x04L\x1d\x15\xfc\xae\x15\x1d\x1d\x15\x03R\x15\xfc\x99\xc8\xfe\xec\x10\x08\x1c\x15\x01Q\x0e\xfa\x02\x04\x10\x0f\x0d\xfa\xfe\xd4\xfa\x01\x0b\x13)\x1c2\x1a(\x14\x0c\x01\x00\x00\x00\x02\x00J\x00\x00\x04f\x04\xb0\x00,\x005\x00\x00\x0132\x16\x0f\x01\x1e\x01\x17\x13\x1732\x16\x14\x06\x07\x0e\x04#\".\x04/\x01.\x0146;\x017\x13>\x017'&6\x03\x16327\x0e\x01\"&\x02)^\x14\x12\x06\x12Sz\x0f?v\x11\x13\x1c\x1a\x12\x08\x1edj\x9fO9t\\U>/\x0c\x0b\x12\x1a\x1c\x13\x11v?\x0fzS\x12\x06\x13$2451\x0c7F8\x04\xb0\x15\x13%\x13\x7fM\xfe\xb9\xad\x1d)(\x07\x04\x0b\x1c\x16\x12\n\x0e\x11\x12\x0e\x05\x04\x08()\x1d\xad\x01GM~\x14 \x13\x1a\xfb\xbe\x06\x061==\x00\x01\x00\x14\x00\x14\x04\x9c\x04\x9c\x00\x17\x00\x00\x017\x07\x17\x07\x17\x07\x17'\x07'\x07'\x077'7'7'\x177\x177\x03 \xe0N\xea\xb4\xb4\xeaN\xe0-\x9b\x9b-\xe0N\xea\xb4\xb4\xeaN\xe0-\x9b\x9b\x03\xb2N\xe0-\x9b\x9b-\xe0N\xea\xb4\xb4\xeaN\xe0-\x9b\x9b-\xe0N\xea\xb4\xb4\x00\x03\x00\x00\x00d\x04\xb0\x04\xb0\x00!\x00-\x00=\x00\x00\x0132\x16\x1d\x01\x07!2\x16\x1d\x01\x14\x07\x03\x0e\x01+\x01\"&/\x01#\"&5\x114?\x02>\x01\x17\x0f\x01\x113\x173\x135!75\x0132\x16\x15\x11\x14\x06+\x01\"&5\x1146\x02\x8a2(<\x1c\x01H(<\x1d\xee\x10,\x17\xfa\x07F\x1f\x1f=-7\x14\x91`\x0d1\x1bd\x96d\x88\xd6\xfa\xfe>2\xfdvd\x15\x1d\x1d\x15d\x15\x1d\x1d\x04\xb0Q,\x96}Q,d-\x1d\xfe\xa8\x18!2\x19\x19$'\x01\x90$\x1b\xc4\xc6\x1c(d\xd4\xd5\xfe\x89d\x01w}\xe1\xaf\xfe\xd4\x1d\x15\xfe\x0c\x15\x1d\x1d\x15\x01\xf4\x15\x1d\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x04L\x00 \x000\x00<\x00\x00\x0132\x16\x17\x13\x16\x1d\x01\x14\x06#!\x16\x1d\x01\x14\x06+\x01\"&/\x02&5\x1146;\x016\x0532\x16\x15\x11\x14\x06+\x01\"&5\x1146!\x07#\x11\x1f\x0135'!5\x03\x02X\xfa\x17,\x10\xee\x1d<(\xfe\xb8\x1c<(2\x1b1\x0d`\x91\x147-=|\xfd\xe9d\x15\x1d\x1d\x15d\x15\x1d\x1d\x02_\x88d\x96d22\x01\xc2\xfa\x04L!\x18\xfe\xa8\x1d-d,Qv\x07\x96,Q(\x1c\xc6\xc4\x1b$\x01\x90'$dd\x1d\x15\xfe\x0c\x15\x1d\x1d\x15\x01\xf4\x15\x1dd\xfe\x89\xd5\xd4\xaf\xe1}\x01w\x00\x03\x00\x00\x00d\x05\x0e\x04O\x00\x1b\x007\x00G\x00\x00\x01%6\x1f\x01\x1e\x01\x0f\x01!2\x16\x14\x06+\x01\x03\x0e\x01#!\"&5\x11467\x17\x11\x17!\x13>\x01;\x0126&#!*\x03.\x04'&?\x01'\x0532\x16\x15\x11\x14\x06+\x01\"&5\x1146\x01d\x01k\x1f\x16n\x0d\x01\x0cT\x01.TlnTj\x83\x06\x1b\x0f\xfe\xaa\x07\xa6\x1c\x0e:d\x01%\x83\x06\x1b\x0f\xcb\x15\x13\x12\x16\xfe8\x02\n\x02 \x03\x07\x03\x05\x03\x01\x0c\x11\x92V\xfdOd\x15\x1d\x1d\x15d\x15\x1d\x1d\x03i\xe6\x10\x16p\x0d&\x0fyL\x90N\xfe\xad\x15(\xa2\x0d\x02\x0d\x11%\nH\xfe Y\x01S\x15(22\x01\x02\x02\x03\x05\x02\x19\x16\xb7S\xe4\x1d\x15\xfe\x0c\x15\x1d\x1d\x15\x01\xf4\x15\x1d\x00\x00\x00\x03\xff\x9c\x00d\x04\xb0\x04O\x00\x1d\x006\x00F\x00\x00\x01\x05\x1e\x04\x15\x11\x14\x06#!\"&'\x03#\"&463!'&6?\x016\x07\x17\x16\x07\x0e\x05*\x02#!\x1532\x16\x17\x13!7\x11%\x0532\x16\x15\x11\x14\x06+\x01\"&5\x1146\x01\xdb\x01n\x02\x08\x14\x10\x0d\xac\x07\xfe\xaa\x0f\x1b\x06\x83jUmlT\x01.U\x0b\x01\x0dn\x16J\x92\x11\x0c\x02\x03\x05\x03\x07\x03 \x03\n\x01\xfe%\xdd\x0f\x1c\x06\x82\x01&j\xfe\xaa\x02Pd\x15\x1d\x1d\x15d\x15\x1d\x1d\x04O\xe6\x01\x05\x10\x11\x17\x0b\xfd\xf3\x0d\xa2(\x15\x01SN\x90Ly\x0f&\x0dp\x16\xae\xb7\x16\x19\x02\x05\x03\x02\x02\x01d(\x15\xfe\xadY\x01\xf7\xec\xe4\x1d\x15\xfe\x0c\x15\x1d\x1d\x15\x01\xf4\x15\x1d\x00\x00\x00\x03\x00a\x00\x00\x04L\x05\x0e\x00\x1b\x007\x00G\x00\x00\x002\x16\x1d\x01\x05\x1e\x01\x15\x11\x14\x06#!\"&/\x01\x03&?\x01>\x01\x1f\x01\x114\x1754&\x06\x15\x11\x1c\x03\x0e\x04\x07\x06/\x01\x07\x13!7\x11%.\x01\x03!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x01\xde\x90N\x01S\x15(\xa2\x0d\xfd\xf3\x11%\n \xe6\x10\x16p\x0d&\x0fy\xc622\x01\x02\x02\x03\x05\x02\x19\x16\xb7S\xec\x01\xf7Y\xfe\xad\x15(\x96\x01\xf4\x15\x1d\x1d\x15\xfe\x0c\x15\x1d\x1d\x05\x0enTj\x83\x06\x1b\x0f\xfe\xaa\x07\xa6\x1c\x0e\x0e\x01k\x1f\x16n\x0d\x01\x0cT\x01.T\xd6\xcb\x15\x13\x12\x16\xfe8\x02\n\x02 \x03\x07\x03\x05\x03\x01\x0c\x11\x92V\xfe\xadd\x01%\x83\x06\x1b\xfd\x0b\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\x00\x03\xff\xfd\x00\x06\x03\xe8\x05\x14\x00\x0f\x00-\x00I\x00\x00\x01!26=\x014&#!\"\x06\x1d\x01\x14\x16\x01\x15\x14\x06\"&5\x11\x07\x06&/\x01&7\x13>\x043!2\x16\x15\x11\x14\x06\x07\x01\x03\x1776\x17\x1e\x05\x1c\x02\x15\x11\x14\x166=\x01467%\x11'\x01^\x01\xf4\x15\x1d\x1d\x15\xfe\x0c\x15\x1d\x1d\x01\x0fN\x90Ly\x0f&\x0dp\x16\x10\xe6\x01\x05\x10\x11\x17\x0b\x02\x0d\x0d\xa2(\x15\xfd\x89\xecS\xb7\x16\x19\x02\x05\x03\x02\x02\x0122(\x15\x01SY\x04L\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d\xfc\xe6jTnlT\x01.T\x0c\x01\x0dn\x16\x1f\x01k\x02\x08\x13\x0f\x0c\xa6\x07\xfe\xaa\x0f\x1b\x06\x01\xcf\xfe\xadV\x92\x11\x0c\x01\x03\x05\x03\x07\x03 \x02\n\x02\xfe8\x16\x12\x13\x15\xcb\x0f\x1b\x06\x83\x01%d\x00\x02\x00\x16\x00\x16\x04\x9a\x04\x9a\x00\x0f\x00%\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x01%&\x06\x1d\x01!\"\x06\x1d\x01\x14\x163!\x15\x14\x167%64\x01\xe2\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b[[\x9b\x02\x86\xfe\xed\x10\x17\xfe\xed\n\x0f\x0f\n\x01\x13\x17\x10\x01\x13\x10\x04\x9a[\x9b\xd6\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b\xfe9\xdf\x0d\n\x15\x89\x0f\n\x96\n\x0f\x89\x15\n\x0d\xdf\x0d&\x00\x00\x02\x00\x16\x00\x16\x04\x9a\x04\x9a\x00\x0f\x00%\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x0d\x01\x06\x14\x17\x05\x166=\x01!26=\x014&#!54&\x01\xe2\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b[[\x9b\x01%\xfe\xed\x10\x10\x01\x13\x10\x17\x01\x13\n\x0f\x0f\n\xfe\xed\x17\x04\x9a[\x9b\xd6\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b\xe8\xdf\x0d&\x0d\xdf\x0d\n\x15\x89\x0f\n\x96\n\x0f\x89\x15\n\x00\x00\x00\x02\x00\x16\x00\x16\x04\x9a\x04\x9a\x00\x0f\x00%\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x01\x03&\"\x07\x03\x06\x16;\x01\x11\x14\x16;\x01265\x11326\x01\xe2\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b[[\x9b\x02K\xdf\x0d&\x0d\xdf\x0d\n\x15\x89\x0f\n\x96\n\x0f\x89\x15\n\x04\x9a[\x9b\xd6\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b\xfe@\x01\x13\x10\x10\xfe\xed\x10\x17\xfe\xed\n\x0f\x0f\n\x01\x13\x17\x00\x00\x02\x00\x16\x00\x16\x04\x9a\x04\x9a\x00\x0f\x00%\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x05#\"\x06\x15\x11#\"\x06\x17\x13\x1627\x136&+\x01\x114&\x01\xe2\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b[[\x9b\x01\x97\x96\n\x0f\x89\x15\n\x0d\xdf\x0d&\x0d\xdf\x0d\n\x15\x89\x0f\x04\x9a[\x9b\xd6\xec\xd6\x9b[[\x9b\xd6\xec\xd6\x9b\xbb\x0f\n\xfe\xed\x17\x10\xfe\xed\x10\x10\x01\x13\x10\x17\x01\x13\n\x0f\x00\x00\x03\x00\x18\x00\x18\x04\x98\x04\x98\x00\x0f\x00\x96\x00\xa6\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01%\x0e\x03\x07\x06&\x07\x0e\x01\x07\x06\x16\x07\x0e\x01\x07\x06\x16\x07\x14\x16\x072\x1e\x01\x17\x1e\x02\x17\x1e\x027\x16\x0e\x01\x17\x1e\x02\x17\x14\x06\x14\x17\x167>\x027.\x01'.\x01'\"\x0e\x02\x07\x06'&65.\x01'6.\x01\x06\x07\x06'&767\x1e\x02\x17\x1e\x03\x1f\x01>\x02'&>\x017>\x037&72\x16267.\x03'4>\x02&'\x1e\x01?\x016.\x02'\x06\x07\x14\x1e\x01\x15.\x02'>\x017\x162>\x01\x01\xe4\xe8\xd5\x9b\\\\\x9b\xd5\xe8\xd5\x9b\\\\\x9b\x01d\x0f+\x1c:\n\x0f=\x0f\x14?\x03\x03\x13\x01\x031\x05 \x1c\x06\"\x01\x0c\x16\x19\x07\x10\"/\x0b\x15?9\x1d\x07\x14\x19\x03\x0d\x14#\x13\x07\x05hu\x1e!$\x03\x0d0\x0c\x0fE\x11\x12.(,\x103\x0f\x04\x01\x06)\x04\x01\x03\x0b\x1a\x12\x17\x13\x13\x0b\x06\x10\x06(\x1b\x06\x07\x16\x15\x13\x06\x05\x02\x0b\x05\x03\x03\x0d\x17\x04\x06 \x07\x18\x16\x06\x10\x08 \x11\x17 \n*!A\x0b\x04\x02\x01\x03\x03\x1f7\x0b\x0c\x05\x1d,8\x0d\x12!\x10\x12\x08?*\x10\x03\x1a\x03\n\x12\n\x11\x04\x98\\\x9b\xd5\xe8\xd5\x9b\\\\\x9b\xd5\xe8\xd5\x9b\x11\x0c\x11\x07 \x02\x03\x06\x05\x07'\x0f\x0b\x17\x07\"r\x16\"v\x1c G\x18\n\x14\x04\x08\x0e\x10\x04 .\x1e\x04\x0f&*\x11\x15\x1b\x1c\x04\x07\x12\n\x0c\x02r\x1d$> \x08\x01\x07\x07\x10\x0b\x01\x02\x0b\x0b#\x17\x011\x01\x0d \x02\x0f\x1f\x19\x02\x14\x19\x1d\x1c\x1e\x10\x06\x01\x01\x07\n\x0c\x18\x11\x0d\x04\x03\x0c% \x10\x12\x16\x17\x0d\x0e*\x14\x19\n\x12\x12\x03 \x0b\x17'\x14\"\x06\x01\x0e \x0c\x07\x01\x0d\x03\x04\x05\x1c$\x0c\x12\x0b\x04g\x112(\x03\x01 \x0b\x0b\x0b%\x07\n\x0c\x11\x00\x00\x00\x00\x01\x00\x00\x00\x02\x04\xaf\x04\x85\x00\x16\x00\x00\x016\x17\x05\x177\x16\x06\x07\x0e\x01'\x01\x06\"/\x01&47\x01&6\x02\xf4\xa4\x8e\xfe\xfd\x91\xfb\x06PM<\x86;\xfd\xac\x0f+\x0fo\x0f\x0f\x02X\"O\x04\x85\\e\x8a\xe8~Y\x87+\"\x0b\x16\xfd\xac\x10\x10n\x0f+\x10\x02We\xc9\x00\x06\x00\x00\x00`\x04\xb0\x04\xac\x00\x0f\x00\x13\x00#\x00'\x007\x00;\x00\x00\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x05#\x153\x05!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x05!\x15!\x05!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x05!\x15!d\x03\xe8);;)\xfc\x18);;\x04\x11\xc8\xc8\xfc\x18\x03\xe8);;)\xfc\x18);;\x04\x11\xfe\x0c\x01\xf4\xfc\x18\x03\xe8);;)\xfc\x18);;\x04\x11\xfe\xd4\x01,\x04\xac;)d);;)d);dd\xc8;)d);;)d);dd\xc8;)d);;)d);dd\x00\x00\x00\x02\x00d\x00\x00\x04L\x04\xb0\x00\x0b\x00\x11\x00\x00\x13!2\x16\x14\x06#!\"&46\x01\x11\x07\x11\x01!\x96\x03\x84\x15\x1d\x1d\x15\xfc|\x15\x1d\x1d\x02;\xc8\xfe\xa2\x03\x84\x04\xb0\x1d*\x1d\x1d*\x1d\xfdD\xfe\xd4\xc8\x01\xf4\x01\xf4\x00\x00\x00\x03\x00\x00\x00d\x04\xb0\x04\xb0\x00\x17\x00\x1b\x00%\x00\x00\x0132\x16\x1d\x01!2\x16\x15\x11!5#\x15!\x11463!546\x17\x1535\x01\x15\x14\x06#!\"&=\x01\x01\xf4\xc8);\x01,);\xfe\x0c\xc8\xfe\x0c;)\x01,;)\xc8\x01\xf4;)\xfc\x18);\x04\xb0;)d;)\xfepdd\x01\x90);d);ddd\xfdD\xc8);;)\xc8\x00\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x15\x00+\x00A\x00W\x00\x00\x13!2\x16\x0f\x01\x17\x16\x14\x0f\x01\x06\"/\x01\x07\x06&5\x1146)\x012\x16\x15\x11\x14\x06/\x01\x07\x06\"/\x01&4?\x01'&6\x01\x17\x16\x14\x0f\x01\x17\x16\x06#!\"&5\x1146\x1f\x01762\x0576\x16\x15\x11\x14\x06#!\"&?\x01'&4?\x0162\x172\x01,\x15\x08\x0e^\xc7\x07\x07j\x08\x14\x08\xc7^\x0e\x15\x1d\x035\x01,\x15\x1d\x15\x0e^\xc7\x08\x14\x08j\x07\x07\xc7^\x0e\x08\xfe/j\x07\x07\xc7^\x0e\x08\x15\xfe\xd4\x15\x1d\x15\x0e^\xc7\x08\x14\x02\xcb^\x0e\x15\x1d\x15\xfe\xd4\x15\x08\x0e^\xc7\x07\x07j\x08\x14\x08\x04\xb0\x15\x0e^\xc7\x08\x14\x08j\x07\x07\xc7^\x0e\x08\x15\x01,\x15\x1d\x1d\x15\xfe\xd4\x15\x08\x0e^\xc7\x07\x07j\x08\x14\x08\xc7^\x0e\x15\xfd&j\x08\x14\x08\xc7^\x0e\x15\x1d\x15\x01,\x15\x08\x0e^\xc7\x07\xce^\x0e\x08\x15\xfe\xd4\x15\x1d\x15\x0e^\xc7\x08\x14\x08j\x07\x07\x00\x00\x00\x06\x00\x00\x00\x00\x04\xa8\x04\xa8\x00\x0f\x00\x1b\x00#\x00;\x00C\x00K\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&$2\x16\x14\x06\"&4$2\x16\x14\x06#\"'\x07\x16\x15\x14\x06\"&546?\x02&54\x042\x16\x14\x06\"&4$2\x16\x14\x06\"&4\x01\xdb\xf2\xdd\x9f__\x9f\xdd\xf2\xdd\xa0^^\xa0\x01\xc6\xe0\xbfoo\xbf\xe0\xbfoo\xfe-- - \x01L- \x16\x0e\x0f7\x113H3)\x1fz\x01 \xfe\x87- - \x02\x1d- - \x04\xa8_\x9f\xdd\xf2\xdd\xa0^^\xa0\xdd\xf2\xdd\x9fWo\xbf\xe0\xbfoo\xbf\xe0\xbf\x06 -!!- -!\n\x91\x17\x1c$33$ 1\x05~\x01\x0e\x0e\x17\xa4 - - - -\x00\x01\xff\xd8\x00Z\x04\xb9\x04\xbc\x00[\x00\x00%\x01676&'&#\"\x0e\x03\x07\x00\x07\x0e\x04\x17\x1e\x01327\x016'.\x01#\"\x07\x06\x07\x01\x0e\x01&47\x007>\x0132\x17\x1e\x01\x17\x16\x06\x07\x0e\x06\x07\x06#\"&'&67\x0167632\x17\x1e\x01\x17\x16\x06\x07\x01\x0e\x01'.\x01\x02\"\x01\xd5[\x08\x07v_\x16\x19\"A0?! \xfe\x88\x0f\x1e\x1e-\x13\x0d\x05 Y7J3\x02$$\x10\x07\x1d\x12\x1a\x18\x0d\x1a\xfe\xab\x0f)\x1c\x0e\x01G\"#A.\x0e\x0f,=\x0d\x0e\x18#\x0c(wn\x8bkV\x0e8@Fv\"0\x1aD\x01\xffG([kPHNg\x0f\x118B\xfe\x1e\x0f*\x10\x10\x03\xad\x01\xd6[eb\x9b\x11\x04\x14\x1a2!\x1f\xfe\x89\x0f\x1b\x1d5(7\x1d>B3\x02$$'\x10\x14\x17\x0c\x1a\xfe\xae\x0f\x01\x1c)\x0e\x01M\"#!\x01\x087)/c#\x0b*xn\x89fL\x07\x1b@9N\xbeD\x01\xffH\x187!$\x86W]\xb5B\xfe$\x0f\x02\x0f\x0f&\x00\x00\x00\x02\x00d\x00X\x04\xaf\x04D\x00\x19\x00D\x00\x00\x01>\x02\x1e\x02\x15\x14\x0e\x03\x07.\x0454>\x02\x1e\x01\x05\"\x0e\x03\".\x03#\"\x06\x15\x14\x1e\x02\x17\x16\x17\x1e\x042>\x03767>\x0454&\x02\x890{xuX6Cy\x84\xa8>>\xa7\x85xC8Zvxy\x01#!?2-*!')-?\"Co\x1bA23\x0f\x07\x0f:+1!\x0d\"3)@\x0c\x04\x08+)?\x1d\x17j\x03\xb5DH\x05-Sv@9y\x80\x7f\xb2UU\xb2\x7f\x80y9@vS-\x05H-&65&&56&oM\x178J41\x0f\x07\x0e<*.\x18\x180(@\x0b\x04 )*D*2\x13Om\x00\x02\x009\xff\xf2\x04w\x04\xbe\x00\x17\x00.\x00\x00\x002\x1f\x01\x16\x15\x14\x06\x0f\x01&/\x017'\x01\x17\x07/\x01&47\x01\x037\x16\x1f\x01\x16\x14\x07\x01\x06\"/\x01&4?\x01\x16\x1f\x01\x07\x17\x01\x02\xab\xbbB\x8dB8\"\x1d\x1f.\x12_\xf7\xfe{\xd4i\x13\x8dBB\x01\x1b\x12i\n \x8dBB\xfe\xe5B\xbaB\x8dBB7\x1d.\x12_\xf7\x01\x85\x04\xbeB\x8dB^*k\"\x1d5.\x12_\xf8\xfe{\xd4j\x12\x8dB\xbaB\x01\x1b\xfeFi\x08 \x8dB\xbaB\xfe\xe5BB\x8dB\xbbB77/\x11_\xf8\x01\x85\x00\x00\x00\x00\x03\x00\xc8\x00\x00\x03\xe8\x04\xb0\x00\x11\x00\x15\x00\x1d\x00\x00\x002\x1e\x02\x15\x11\x14\x06#!\"&5\x114>\x01\x07\x11!\x11\x00\"\x06\x14\x16264\x02\x06\xaa\x9ad:;)\xfd\xa8);\x02X\xfe\xffV==V=\x04\xb0\x1e.2\x15\xfcG);;)\x03\xb9\x153-\xaa\xfdD\x02\xbc\xfd\x16=V==V\x00\x01\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x16\x00\x00 \x01\x16\x14\x06\"/\x01\x01\x11'\x01\x05\x13\x01'!\x01'&462\x03\x86\x01\x1b\x0f\x1d*\x0e$\xfe\xe9\xd4\xfe\xcc\xfe\xe8\xcb\x013\xd2\x01,\x01\x0b#\x0f\x1d*\x04\xa1\xfe\xe6\x0f*\x1d\x0f#\xfe\xf5\xfe\xd4\xd2\xfe\xcd\xcb\x01\x18\x014\xd4\x01\x17$\x0e*\x1d\x00\x00\x00\x00\x03\x01'\x00\x11\x04 \x04\xe0\x002\x00@\x00K\x00\x00\x01\x15\x1e\x04\x17#.\x03'\x11\x17\x1e\x04\x15\x14\x06\x07\x15#5&'.\x01'3\x1e\x01\x17\x11'.\x0454>\x0275\x19\x01\x0e\x03\x15\x14\x1e\x03\x17\x16\x17\x11>\x044.\x02\x02\xbc&ER<,\x02\x9f\x04\x0d\x1d3'@\"\x8b\xaa\x0cMO\x10W(kVMb\x10\x01O\x08\x0e\x19/9X6FpH*\x06M\xfe\x12\x01\x12\x04\x0e\x1d6&\x1d+\x19\x14\x08\x06\x03\xd0\xfe\xca\x02 \x16 4C4%\x19\x00\x00\x00\x01\x00d\x00f\x03\x94\x04\xad\x00J\x00\x00\x012\x1e\x01\x15#4.\x02#\"\x06\x07\x06\x15\x14\x1e\x01\x17\x16\x173\x15#\x16\x06\x07\x06\x07>\x0136\x16327\x17\x0e\x03#\".\x01\x07\x0e\x01\x0f\x01'>\x057>\x01'#53&'.\x02>\x0176\x021T\x99^\x99'<;\x1a%T\x14)\x1b\x1a\x18\x06\x03\xf1\xc5\x08\x15\x15-6\"b\x16 \x8c\"S52\x1f68\x1c \x17jt&'V\x18\x177\x04\x18\x07\x13\x0c\x11 0\x0c$\xdd\xa6\x17\x15\x07\n\x02\x0e-$a\x04\xadP\x8bN(?\"\x12\x1d\x15,9\x1aJ0* \x05d2\x82\x1e>2\n\x0f\x01\"\x1e\x93\x13\x17\x08\x01\"\x1f\x04\x03\x1a\x0c\x0b\x91\x03\x10\x05\x0d\x0b\x11\n7\x8fGd/9\x14+DAL!X\x00\x00\x00\x02\x00\x19\xff\xff\x04\x97\x04\xb0\x00\x0f\x00\x1f\x00\x00\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x05\x17\x16\x06+\x01\x11#\x11#\"&?\x0162\x01\x90\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x02\x17\xe6\x0e\x08\x15\x96\xc8\x96\x15\x08\x0e\xe6\x0e*\x01,\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84\x10\xf9\x0e\x15\xfc|\x03\x84\x15\x0e\xf9\x0f\x00\x00\x04\x00\x19\xff\xff\x03\xe8\x04\xb0\x00\x07\x00\x17\x00\x1b\x00%\x00\x00\x01#5#\x15#\x11!\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x05\x1535\x13\x073\x15!57#5!\x03\xe8ddd\x01,\xfd\xa8\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x01\x91dc\xc8\xc8\xfe\xd4\xc8\xc8\x01,\x02\xbcdd\x01\xf4\xfc|\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84d\xc8\xc8\xfd\x12\xfad\x96\xfad\x00\x00\x00\x00\x04\x00\x19\xff\xff\x03\xe8\x04\xb0\x00\x0f\x00\x19\x00!\x00%\x00\x00\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x05\x073\x15!57#5!\x11#5#\x15#\x11!\x07\x1535\x01\x90\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x02X\xc8\xc8\xfe\xd4\xc8\xc8\x01,ddd\x01,\xc7d\x01,\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84\x96\xfad\x96\xfad\xfbPdd\x01\xf4d\xc8\xc8\x00\x00\x00\x04\x00\x19\xff\xff\x04L\x04\xb0\x00\x0f\x00\x15\x00\x1b\x00\x1f\x00\x00\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x01#\x11#53\x13#5#\x11!\x07\x1535\x01\x90\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x02Xdd\xc8dd\xc8\x01,\xc7d\x01,\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84\xfe\x0c\x01\x90d\xfbPd\x01\x90d\xc8\xc8\x00\x00\x00\x00\x04\x00\x19\xff\xff\x04L\x04\xb0\x00\x0f\x00\x15\x00\x19\x00\x1f\x00\x00\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x01#5#\x11!\x07\x1535\x03#\x11#53\x01\x90\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x02\xbcd\xc8\x01,\xc7d\x01dd\xc8\x01,\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84\xfe\x0cd\x01\x90d\xc8\xc8\xfb\xb4\x01\x90d\x00\x00\x00\x00\x05\x00\x19\xff\xff\x04\xb0\x04\xb0\x00\x0f\x00\x13\x00\x17\x00\x1b\x00\x1f\x00\x00\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x05#53\x13!5!\x13!5!\x13!5!\x01\x90\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x01\xf4\xc8\xc8d\xfe\xd4\x01,d\xfep\x01\x90d\xfe\x0c\x01\xf4\x01,\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84\xc8\xc8\xfe\x0c\xc8\xfe\x0c\xc8\xfe\x0c\xc8\x00\x05\x00\x19\xff\xff\x04\xb0\x04\xb0\x00\x0f\x00\x13\x00\x17\x00\x1b\x00\x1f\x00\x00\x0132\x16\x0f\x01\x06\"/\x01&6;\x01\x113\x05!5!\x03!5!\x03!5!\x03#53\x01\x90\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x03 \xfe\x0c\x01\xf4d\xfep\x01\x90d\xfe\xd4\x01,d\xc8\xc8\x01,\x16\x0e\xfa\x0f\x0f\xfa\x0e\x16\x03\x84\xc8\xc8\xfe\x0c\xc8\xfe\x0c\xc8\xfe\x0c\xc8\x00\x02\x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00\x00\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05!\"\x06\x15\x11\x14\x163!265\x114&\x01^\x01\x90\xa2\xbc\xbb\xa3\xfep\xa5\xb9\xb9\x02g\xfe\x0c);;)\x01\xf4);;\x04L\xbb\xa3\xfep\xa5\xb9\xb9\xa5\x01\x90\xa5\xb9\xc8;)\xfe\x0c);;)\x01\xf4);\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00+\x00\x00\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05!\"\x06\x15\x11\x14\x163!265\x114&\x05\x17\x16\x14\x0f\x01\x06&5\x1146\x01^\x01\x90\xa5\xb9\xb9\xa5\xfep\xa3\xbb\xbc\x02d\xfe\x0c);;)\x01\xf4);;\xfeo\xfd\x11\x11\xfd\x10\x18\x18\x04L\xb9\xa5\xfep\xa5\xb9\xb9\xa5\x01\x90\xa3\xbb\xc8;)\xfe\x0c);;)\x01\xf4);\x82\xbe\x0c$\x0c\xbe\x0c\x0b\x15\x01\x90\x15\x0b\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00+\x00\x00\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05!\"\x06\x15\x11\x14\x163!265\x114&\x05!2\x16\x0f\x01\x06\"/\x01&6\x01^\x01\x90\xa3\xbb\xb9\xa5\xfep\xa5\xb9\xb9\x02g\xfe\x0c);;)\x01\xf4);;\xfe\x15\x01\x90\x15\x0b\x0c\xbe\x0c$\x0c\xbe\x0c\x0b\x04L\xbc\xa2\xfep\xa5\xb9\xb9\xa5\x01\x90\xa3\xbb\xc8;)\xfe\x0c);;)\x01\xf4);\xc8\x18\x10\xfd\x11\x11\xfd\x10\x18\x00\x00\x00\x03\x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00+\x00\x00\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05!\"\x06\x15\x11\x14\x163!265\x114&\x05\x17\x16\x06#!\"&?\x0162\x01^\x01\x90\xa5\xb9\xb9\xa5\xfep\xa3\xbb\xb9\x02g\xfe\x0c);;)\x01\xf4);;\xfe\xfb\xbe\x0c\x0b\x15\xfep\x15\x0b\x0c\xbe\x0c$\x04L\xb9\xa5\xfep\xa3\xbb\xbc\xa2\x01\x90\xa5\xb9\xc8;)\xfe\x0c);;)\x01\xf4);\xcf\xfd\x10\x18\x18\x10\xfd\x11\x00\x00\x00\x00\x02\x00\x00\x00\x00\x05\x14\x04L\x00\x1f\x005\x00\x00\x01!2\x16\x15\x11\x14\x06#!\"&=\x01463!265\x114&#!\"&=\x0146\x07\x01\x16\x14\x07\x01\x06&=\x01#\"&=\x0146;\x01546\x02&\x01\x90\xa5\xb9\xb9\xa5\xfep\x15\x1d\x1d\x15\x01\xc2);;)\xfe>\x15\x1d\x1d\xbf\x01D\x10\x10\xfe\xbc\x10\x16\xfa\x15\x1d\x1d\x15\xfa\x16\x04L\xb9\xa5\xfep\xa5\xb9\x1d\x15d\x15\x1d;)\x01\xf4);\x1d\x15d\x15\x1d\xe9\xfe\xe4\x0e&\x0e\xfe\xe4\x0e\n\x15\x96\x1d\x15\xc8\x15\x1d\x96\x15\n\x00\x00\x01\x00\xd9\x00\x02\x03\xd7\x04\x9e\x00#\x00\x00\x01\x17\x16\x07\x06\x02\x07%2\x16\x07\"\x08\x01\x07\x06+\x01'&7>\x01?\x01!\"'&76\x006763\x03\x19 \x08\x03\x03\x98\x02\x01,\x18\x11\x0e\x01\xfe\xf7\xfe\xf3\x04\x0c\x0e \x05\x02P''\xfe\xd2\x17\x08\n\x10K\x01\x0d\xbb\x05 \x10\x04\x9e \n\x11\x0b\xfeS\x07\x01#\x12\xfe\xca\xfe\xc5\x05\x0f\x08\x0b\x15 \xe5nn\x13\x15\x14V\x01/\xd3\x06\x10\x00\x00\x00\x02\x00\x00\x00\x00\x04\xfe\x04L\x00\x1f\x005\x00\x00\x01!2\x16\x1d\x01\x14\x06#!\"\x06\x15\x11\x14\x163!2\x16\x1d\x01\x14\x06#!\"&5\x1146\x05\x01\x16\x14\x07\x01\x06&=\x01#\"&=\x0146;\x01546\x01^\x01\x90\x15\x1d\x1d\x15\xfe>);;)\x01\xc2\x15\x1d\x1d\x15\xfep\xa5\xb9\xb9\x02\xf1\x01D\x10\x10\xfe\xbc\x10\x16\xfa\x15\x1d\x1d\x15\xfa\x16\x04L\x1d\x15d\x15\x1d;)\xfe\x0c);\x1d\x15d\x15\x1d\xb9\xa5\x01\x90\xa5\xb9\xe9\xfe\xe4\x0e&\x0e\xfe\xe4\x0e\n\x15\x96\x1d\x15\xc8\x15\x1d\x96\x15\n\x00\x02\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x15\x001\x00\x00\x01!2\x16\x15\x11\x14\x06/\x01\x01\x06\"/\x01&47\x01'&6\x01#\"\x06\x15\x11\x14\x163!26=\x017\x11\x14\x06#!\"&5\x11463!\x02\xee\x01\x90\x15\x1d\x15\x0em\xfe\xc8\x0f)\x0f\x8d\x0f\x0f\x018m\x0e\x08\xfe\xef\x9c);;)\x01\xf4);\xc8\xbb\xa3\xfep\xa5\xb9\xb9\xa5\x01,\x04\xb0\x1d\x15\xfep\x15\x08\x0em\xfe\xc8\x0f\x0f\x8d\x0f)\x0f\x018m\x0e\x15\xfe\xd4;)\xfe\x0c);;)\x94\xc8\xfe\xd6\xa5\xb9\xb9\xa5\x01\x90\xa5\xb9\x00\x00\x03\x00\x0e\x00\x0e\x04\xa2\x04\xa2\x00\x0f\x00\x1b\x00#\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x042\x16\x14\x06\"&4\x01\xe1\xee\xd9\x9d]]\x9d\xd9\xee\xd9\x9d]]\x9d\x01\xc3\xe6\xc2qq\xc2\xe6\xc2qq\xfe{\xa0rr\xa0r\x04\xa2]\x9d\xd9\xee\xd9\x9d]]\x9d\xd9\xee\xd9\x9dGq\xc2\xe6\xc2qq\xc2\xe6\xc2sr\xa0rr\xa0\x00\x00\x03\x00\x00\x00\x00\x04L\x04\xb0\x00\x15\x00\x1f\x00#\x00\x00\x0132\x16\x15\x1132\x16\x07\x01\x06\"'\x01&6;\x01\x1146\x01!2\x16\x1d\x01!546\x05\x1535\x01\xc2\xc8\x15\x1d\xf5\x14\n\x0e\xfe\x81\x0e'\x0d\xfe\x85\x0d \x15\xfa\x1d\xfe\x85\x03\xe8\x15\x1d\xfb\xb4\x1d\x03gd\x04\xb0\x1d\x15\xfe\xa2\x16\x0f\xfeV\x0f\x0f\x01\xaa\x0f\x16\x01^\x15\x1d\xfc|\x1d\x15\xfa\xfa\x15\x1dd22\x00\x00\x00\x03\x00\x00\x00\x00\x04L\x04\xac\x00\x15\x00\x1f\x00#\x00\x00 \x01\x16\x06+\x01\x15\x14\x06+\x01\"&=\x01#\"&7\x01>\x01\x01!2\x16\x1d\x01!546\x05\x1535\x02G\x01z\x0e\n\x15\xf4\"\x16\xc8\x14\x18\xfa\x14\x0b\x0e\x01\x7f\x0e'\xfd\xf9\x03\xe8\x15\x1d\xfb\xb4\x1d\x03gd\x04\x9e\xfeM\x0f \xfa\x14\x1e\x1d\x15\xfa!\x0f\x01\xaf\x10\x02\xfc\x7f\x1d\x15\xfa\xfa\x15\x1dd22\x00\x03\x00\x00\x00\x00\x04L\x04K\x00\x14\x00\x1e\x00\"\x00\x00 \x0162\x1f\x01\x16\x14\x07\x01\x06\"'\x01&4?\x0162\x17\x03!2\x16\x1d\x01!546\x05\x1535\x01\x8c\x01q\x07\x15\x07\x8b\x07\x07\xfd\xf3\x07\x15\x07\xfe\xdc\x07\x07\x8b\x08\x15\x07\xd4\x03\xe8\x15\x1d\xfb\xb4\x1d\x03gd\x02\xd3\x01q\x07\x07\x8b\x08\x15\x07\xfd\xf3\x08\x08\x01#\x08\x14\x08\x8b\x07\x07\xfd\xd2\x1d\x15\xfa\xfa\x15\x1dd22\x00\x04\x00\x00\x00\x00\x04L\x04\x9b\x00 \x00\x19\x00#\x00'\x00\x00\x13762\x1f\x01\x07'&4\x0576\x16\x15\x03\x0e\x01#\x05\"&?\x01'7\x01!2\x16\x1d\x01!546\x05\x1535\x87\x8e\x0e*\x0eM\xd4M\x0e\x02\x16\xd2\x0e\x15\x02\x01\x1d\x15\xfd\xab\x15\x08\x0e\xd0\x9a\xd4\xfe=\x03\xe8\x15\x1d\xfb\xb4\x1d\x03gd\x03\xff\x8e\x0e\x0eM\xd4L\x0f*\x9a\xd2\x0e\x08\x15\xfd\xa9\x14\x1e\x01\x15\x0e\xd0\x9b\xd4\xfd:\x1d\x15\xfa\xfa\x15\x1dd22\x00\x00\x00\x04\x00\x00\x00\x00\x04L\x04\xb0\x00\x0f\x00\x19\x00#\x00'\x00\x00\x01\x05\x1e\x01\x15\x13\x14\x06/\x01\x07'7'&6\x13\x07\x06\"/\x01&4?\x01\x01!2\x16\x1d\x01!546\x05\x1535\x01^\x02W\x14\x1e\x01\x15\x0e\xd0\x9b\xd4\x9b\xd2\x0e\x08\xc3L\x0f*\x0e\x8e\x0e\x0eM\xfe\xfa\x03\xe8\x15\x1d\xfb\xb4\x1d\x03gd\x04\xb0\x02\x01\x1d\x15\xfd\xab\x15\x08\x0e\xd0\x9a\xd4\x9a\xd2\x0e\x15\xfdPM\x0e\x0e\x8e\x0e*\x0eM\xfeX\x1d\x15\xfa\xfa\x15\x1dd22\x00\x02\x00\x04\xff\xec\x04\xb0\x04\xaf\x00\x05\x00\x08\x00\x00% \x01\x11! \x01\x15\x01\x04\xb0\xfe\x1d\xfe\xc6\xfeq\x04\xac\xfd3\x02\xabg\x01\x14\xfeq\x01\xa7\x03\x1c\xfc\xf9\xe6\x03\xb9\x00\x00\x00\x00\x02\x00\x00\x00d\x04L\x04\xb0\x00\x15\x00\x19\x00\x00\x01\x11\x14\x06+\x01\x11!\x11#\"&5\x1146;\x01\x11!\x113\x07#53\x04L\x1d\x15\x96\xfdD\x96\x15\x1d\x1d\x15\xfa\x01\xf4d\xc8dd\x03\xe8\xfc\xae\x15\x1d\x01\x90\xfep\x1d\x15\x03\xe8\x14\x1e\xfe\xd4\x01,\xc8\xc8\x00\x00\x03\x00\x00\x00E\x04\xdd\x04\xb0\x00\x16\x00\x1a\x00/\x00\x00\x01\x07\x01'&\"\x0f\x01!\x11#\"&5\x1146;\x01\x11!\x113\x07#53\x01\x17\x16\x14\x07\x01\x06\"/\x01&4?\x0162\x1f\x01\x0162\x04L\x02\xfe\xd5_ \x19 \x95\xfe\xc8\x96\x15\x1d\x1d\x15\xfa\x01\xf4d\xc8dd\x01\xb0j\x07\x07\xfe\\\x08\x14\x08\xca\x08\x08j\x07\x15\x07O\x01)\x07\x15\x03\xe8\x95\xfe\xd5_ \x93\xfep\x1d\x15\x03\xe8\x14\x1e\xfe\xd4\x01,\xc8\xc8\xfd\xcej\x07\x15\x07\xfe[\x07\x07\xcb\x07\x15\x07j\x08\x08O\x01)\x07\x00\x03\x00\x00\x00\x0d\x05\x07\x04\xb0\x00\x16\x00\x1a\x00>\x00\x00\x01\x11\x07'.\x01\x07\x01!\x11#\"&5\x1146;\x01\x11!\x113\x07#53\x01\x17\x16\x14\x0f\x01\x17\x16\x14\x0f\x01\x06\"/\x01\x07\x06\"/\x01&4?\x01'&4?\x0162\x1f\x01762\x04Lg\x86\x0f%\x10\xfe\xf6\xfe\xb7\x96\x15\x1d\x1d\x15\xfa\x01\xf4d\xc8dd\x01\xf6F\x0f\x0f\x83\x83\x0f\x0fF\x0f)\x0f\x83\x83\x0f)\x0fF\x0f\x0f\x83\x83\x0f\x0fF\x0f)\x0f\x83\x83\x0f)\x03\xe8\xfe\xf3g\x86\x0f\x03\x0e\xfe\xf6\xfep\x1d\x15\x03\xe8\x14\x1e\xfe\xd4\x01,\xc8\xc8\xfd\x8cF\x0f)\x0f\x83\x83\x0f)\x0fF\x0f\x0f\x83\x83\x0f\x0fF\x0f)\x0f\x83\x83\x0f)\x0fF\x0f\x0f\x83\x83\x0f\x00\x00\x03\x00\x00\x00\x15\x04\x97\x04\xb0\x00\x15\x00\x19\x00/\x00\x00\x01\x11!\"\x06\x1d\x01!\x11#\"&5\x1146;\x01\x11!\x113\x07#53\x1332\x16\x1d\x0132\x16\x0f\x01\x06\"/\x01&6;\x01546\x04L\xfe\xa2\x15\x1d\xfe\x0c\x96\x15\x1d\x1d\x15\xfa\x01\xf4d\xc8dd\x96d\x15\x1d\x96\x15\x08\x0e\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\x1d\x03\xe8\xfe\xd4\x1d\x15\x96\xfep\x1d\x15\x03\xe8\x14\x1e\xfe\xd4\x01,\xc8\xc8\xfd\xa8\x1d\x15\xfa\x15\x0e\xe6\x0e\x0e\xe6\x0e\x15\xfa\x15\x1d\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04\x97\x04\xb0\x00\x15\x00\x19\x00/\x00\x00\x01\x11'&\"\x07\x01!\x11#\"&5\x1146;\x01\x11!\x113\x07#53\x13\x17\x16\x06+\x01\x15\x14\x06+\x01\"&=\x01#\"&?\x0162\x04L\xa5\x0e*\x0e\xfe\xf9\xfen\x96\x15\x1d\x1d\x15\xfa\x01\xf4d\xc8dd\xeb\xe6\x0e\x08\x15\x96\x1d\x15d\x15\x1d\x96\x15\x08\x0e\xe6\x0e*\x03\xe8\xfep\xa5\x0f\x0f\xfe\xf7\xfep\x1d\x15\x03\xe8\x14\x1e\xfe\xd4\x01,\xc8\xc8\xfd\x85\xe5\x0f\x15\xfa\x14\x1e\x1e\x14\xfa\x15\x0f\xe5\x0f\x00\x03\x00\x00\x00\xc8\x04\xb0\x04L\x00 \x00\x13\x00\x17\x00\x00\x13!2\x16\x1d\x01!546\x01\x11\x14\x06#!\"&5\x11\x13\x15!52\x04L\x15\x1d\xfbP\x1d\x04\x93\x1d\x15\xfb\xb4\x15\x1dd\x01\x90\x04L\x1d\x15\x96\x96\x15\x1d\xfe\xd4\xfd\xda\x15\x1d\x1d\x15\x02&\xfe\xd4\xc8\xc8\x00\x00\x06\x00\x03\x00}\x04\xad\x04\x97\x00\x0f\x00\x19\x00\x1d\x00-\x001\x00;\x00\x00\x01\x17\x16\x14\x0f\x01\x06&=\x01!5!546\x01#\"&=\x0146;\x01\x17#53\x0176\x16\x1d\x01!\x15!\x15\x14\x06/\x01&4\x05#5;\x022\x16\x1d\x01\x14\x06+\x01\x03\xa7\xf8\x0e\x0e\xf8\x0e\x15\xfep\x01\x90\x15\xfd/2\x15\x1d\x1d\x152\xc8dd\xfe\x82\xf7\x0e\x15\x01\x90\xfep\x15\x0e\xf7\x0f\x03\x81ddd3\x14\x1d\x1d\x143\x04\x8d\xe6\x0e*\x0e\xe6\x0e\x08\x15\x96\xc8\x96\x15\x08\xfe\x85\x1d\x15d\x15\x1d\xc8\xc8\xfd\xcb\xe6\x0e\x08\x15\x96\xc8\x96\x15\x08\x0e\xe6\x0e*y\xc8\x1d\x15d\x15\x1d\x00\x00\x00\x00\x02\x00d\x00\x00\x04\xb0\x04\xb0\x00\x16\x00Q\x00\x00\x01%6\x16\x15\x11\x14\x06+\x01\"&5\x11.\x045\x1146%2\x16\x1f\x01\x11\x14\x0e\x02\x0f\x01\x11\x14\x06+\x01\"&5\x11.\x045\x114>\x0332\x16\x1f\x01\x113\x11<\x01>\x0232\x16\x1f\x01\x113\x114>\x03\x03^\x01\x14\x19%\x1d\x15\xc8\x15\x1d\x04\x0e\"\x1a\x16%\xfe\xe1\x16\x19\x02\x01\x15\x1d\x1d\x0b\n\x1d\x15\xc8\x15\x1d\x04\x0e\"\x1a\x16\x01\x07\n\x13\x0d\x14\x19\x02\x03d\x05 \x15\x0f\x17\x19\x01\x01d\x01\x05 \x15\x041t\x12\x14\x1f\xfb\xae\x15\x1d\x1d\x15\x01\x8d\x01\x08\x1b\x1f5\x1e\x01g\x1fD\x91\x19\x0c\x0d\xfe>\x1c?1)\x0b\x0b\xfeA\x15\x1d\x1d\x15\x01\xbf\x04\x0f..@\x1c\x01\xc2\x02\x07\x11\x0d\x0b\x19\x0c\x0d\xfe\xa2\x01^\x02\x07\x11\x0d\x0b\x19\x0c\x0d\xfe\xa2\x01^\x02\x07\x11\x0d\x0b\x00\x01\x00d\x00\x00\x04\xb0\x04L\x003\x00\x00\x01\x15\"\x0e\x03\x15\x11\x14\x16\x1f\x01\x15!5265\x11!\x11\x14\x163\x15!52>\x035\x114&/\x015!\x15\"\x06\x15\x11!\x114\x04\xb0\x04\x0e\"\x1a\x162\x19\x19\xfepK\x19\xfe\x0c\x19K\xfep\x04\x0e\"\x1a\x162\x19\x19\x01\x90K\x19\x01\xf4\x19K\x04L8\x01\x05\n\x14\x0e\xfc\x88\x16\x19\x01\x0288\x0d%\x01\x8a\xfev%\x0d88\x01\x05\n\x14\x0e\x03x\x16\x19\x01\x0288\x0d%\xfev\x01\x8a%\x0d8\x00\x00\x00\x06\x00\x00\x00\x00\x04L\x04L\x00\x0c\x00\x1c\x00 \x00$\x00(\x004\x00\x00\x01!2\x16\x1d\x01#\x055'!7!\x05!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x15!5\x01\x055%\x05\x15!5\x05\x15\x14\x06#!\x07!'!73\x02\xa3\x01w\x15\x1di\xfe\xd9\xc8\xfepd\x01w\xfe%\x01,);;)\xfe\xd4);;)\x01,\x02\xbc\xfep\x01\x90\xfc\x18\x01,\x02\xbc\x1d\x15\xfe\x89d\xfe\x89d\x01\x90\xc8i\x03\xe8\x1d\x15\x96bb\xc8d\xc8;)\xfe\x0c);;)\x01\xf4);d\xc8\xc8\xfe\xf7\x85\xa3\x85\xc6\xc8\xc8f\xf8\x15\x1ddd\xc8\x00\x01\x00\x10\x00\x10\x04\x9f\x04\x9f\x00&\x00\x00\x1376\x16\x1f\x01\x16\x06\x0f\x01\x1e\x01\x177>\x01\x1f\x01\x1e\x01\x0f\x01\x06\".\x06'.\x057\x11\xa2\x11.\x0e\x8b\x0e\x06\x11wf\xfc\x8dw\x113\x13\xc0\x13\x07\x11\xa3\x03\x0d.1LOefx;JwF2\x13\x0b\x01\x03\xef\xa2\x11\x06\x13\xc2\x141\x11v\x8e\xfcev\x11\x04\x0e\x88\x0e/\x11\xa2\x01\x04\x08\x15 5Cc;J\x99|sU@\x10\x00\x00\x00\x02\x00\x00\x00\x00\x04\xb0\x04L\x00#\x00A\x00\x00\x002\x1e\x04\x1f\x01\x15\x14\x06/\x01.\x01=\x01& \x07\x15\x14\x06\x0f\x01\x06&=\x01>\x05\x122\x1e\x02\x1f\x01\x15\x01\x1e\x01\x1d\x01\x14\x06#!\"&=\x01467\x0154>\x02\x01\xfc\xb8\xa6ud?, \x1d\x14\xca\x14\x1d\x8d\xfe\xc2\x8d\x1d\x14\xca\x14\x1d\x03\x0d1;ft\xcapR&\x16\x01\x01\x01m\x0e\x15\x1d\x15\xfb\xb4\x15\x1d\x15\x0e\x01m\x02\x16&\x04L\x15!((\"\n\n\xc8\x15\x18\x03\"\x03\"\x15\x92\x18\x18\x92\x15\"\x03\"\x03\x18\x15\xc8\x04\x0d'$+ \xfe\xe4\x13\x1c\x1c\n\n2\xfe\xd1\x0f2\x14\xd4\x15\x1d\x1d\x15\xd4\x142\x0f\x01/2\x04\x0d!\x19\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x0d\x00\x1d\x00'\x00\x00\x01\x07!'\x113\x15353\x15353\x01!2\x16\x14\x06+\x01\x17!7#\"&46\x03!2\x16\x1d\x01!546\x04L\xc8\xfd\xa8\xc8\xc8\xc8\xc8\xc8\xc8\xfc\xae\x02\xbc\x15\x1d\x1d\x15\x0c\x89\xfcJ\x89\x0c\x15\x1d\x1d\xb3\x04L\x15\x1d\xfbP\x1d\x02\xbc\xc8\xc8\x01\xf4\xc8\xc8\xc8\xc8\xfc\xe0\x1d*\x1ddd\x1d*\x1d\xfe\xd4\x1d\x1522\x15\x1d\x00\x00\x00\x03\x00d\x00\x00\x04\xb0\x04L\x00 \x00\x13\x00\x1d\x00\x00\x01#\"\x06\x15\x11!\x114&\x01#\"\x06\x15\x11!\x114&\x01!\x1146;\x012\x16\x15\x02\xbcd);\x01,;\x01gd);\x01,;\xfd\x1b\xfe\xd4;)d);\x04L;)\xfc\x18\x03\xe8);\xfe\xd4;)\xfdD\x02\xbc);\xfc\xe0\x01\x90);;)\x00\x00\x00\x00\x05\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x1f\x00%\x00)\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x05#\x153\x11!535#\x11!\x05\x11\x07#\x113\x07\x113\x11\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfe\x0c\xc8\xc8\xfe\xd4\xc8\xc8\x01,\x01\x90d\xc8\xc8dd\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xc8d\xfe\xd4dd\x01,d\xfe\xd4d\x01\xf4d\xfe\xd4\x01,\x00\x00\x00\x05\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x1f\x00%\x00)\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x01#5#\x15#\x113\x15353\x05\x11\x07#\x113\x07\x113\x11\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfe\x0cdddddd\x01\x90d\xc8\xc8dd\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xfd\xa8\xc8\xc8\x01\xf4\xc8\xc8d\xfe\xd4d\x01\xf4d\xfe\xd4\x01,\x00\x04\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x1b\x00#\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x05#\x113\x15!\x11!\x05#\x113\x15!\x11!\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfe\x0c\xc8\xc8\xfe\xd4\x01,\x01\x90\xc8\xc8\xfe\xd4\x01,\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xc8\xfe\xd4d\x01\xf4d\xfe\xd4d\x01\xf4\x00\x00\x00\x04\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x16\x00\x19\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x01-\x01\x0d\x01\x11\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfe\x0c\xfe\xd4\x01,\x01\x90\xfe\xd4\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xfe\x0c\x96\x96\x96\x96\x01,\x00\x00\x00\x05\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x17\x00 \x00)\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x03!\x11!\x07#\"\x06\x15\x14\x16;\x01\x01\x1132654&#\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84d\xfdD\x02\xbcd\x82&96)\x82\xfe\x0c\x82)69&\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xfd\xa8\x01\xf4dVAAT\x01,\xfe\xd4TAAV\x00\x00\x00\x05\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x1f\x00%\x00)\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x05#\x153\x11!535#\x11!\x01#\x11#53\x03#53\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfe\x0c\xc8\xc8\xfe\xd4\xc8\xc8\x01,\x01\x90dd\xc8\xc8dd\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xc8d\xfe\xd4dd\x01,\xfe\x0c\x01\x90d\xfe\x0cd\x00\x06\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x19\x00\x1f\x00#\x00'\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x053\x11!\x113\x01#\x11#53\x05\x1535\x01#53\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfdD\xc8\xfe\xd4d\x02Xdd\xc8\xfd\xa8d\x01,dd\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xc8\xfep\x01\xf4\xfe\x0c\x01\x90d\xc8\xc8\xc8\xfe\xd4d\x00\x05\xff\x9c\x00\x00\x04\xb0\x04L\x00\x0f\x00\x13\x00\x1c\x00\"\x00&\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x01\x07#575#5!\x01#\x11#53\x03#53\xc8\x02\xbc|\xb0\xb0|\xfdD|\xb0\xb0\x18\x03\x84\xfe\x0c\xc7d\xc7\xc8\x01,\x01\x90dd\xc8\xc7dd\x04L\xb0|\xfe\x0c|\xb0\xb0|\x01\xf4|\xb0\xc8\xfdD\x02\xbc\xfep\xc82\xc8\x96d\xfe\x0c\x01\x90d\xfe\x0cd\x00\x00\x00\x03\x00 \x00 \x04\xa7\x04\xa7\x00\x0f\x00\x1b\x00%\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x07!\x15!\x15!'57!\x01\xe0\xf0\xdb\x9e^^\x9e\xdb\xf0\xdb\x9e^^\x9e\x01\xc5\xe4\xc2qq\xc2\xe4\xc2qql\xfe\xd4\x01,\xfe\xd4dd\x01,\x04\xa7^\x9e\xdb\xf0\xdb\x9e^^\x9e\xdb\xf0\xdb\x9eLq\xc2\xe4\xc2qq\xc2\xe4\xc2\xd0\xc8dd\xc8d\x00\x00\x00\x00\x04\x00 \x00 \x04\xa7\x04\xa7\x00\x0f\x00\x1b\x00'\x00+\x00\x00\x002\x1e\x02\x14\x0e\x02\".\x024>\x01\x04\"\x0e\x01\x14\x1e\x012>\x014&\x07\x15\x07\x17\x15#'#\x15#\x11!\x07\x1535\x01\xe0\xf0\xdb\x9e^^\x9e\xdb\xf0\xdb\x9e^^\x9e\x01\xc5\xe4\xc2qq\xc2\xe4\xc2qql2ddd\x96d\x01,\xc8\xc8\x04\xa7^\x9e\xdb\xf0\xdb\x9e^^\x9e\xdb\xf0\xdb\x9eLq\xc2\xe4\xc2qq\xc2\xe4\xc2\xd0d2d2dd\x01\x90ddd\x00\x00\x02\xff\xf2\xff\x9d\x04\xc2\x04A\x00 \x006\x00\x00\x012\x16\x17632\x16\x14\x06+\x0154&#!\"\x06\x1d\x01#\"&5467&54>\x01\x1332\x16\x15\x1132\x16\x0f\x01\x06\"/\x01&6;\x01\x1146\x01\xf7n\xb5,,.x\xaa\xaax\x80\x1d\x15\xfe\xd4\x15\x1d\xdePpVA\x02b\xaaz\x96\n\x0f\x89\x15\n\x0d\xdf\x0d&\x0d\xdf\x0d\n\x15\x89\x0f\x04Awa\x0e\xad\xf1\xad\xfa\x15\x1d\x1d\x15\xfasOEk\x0e\x13\x12d\xaab\xfd\xb3\x0f\n\xfe\xed\x17\x10\xf4\x10\x10\xf4\x10\x17\x01\x13\n\x0f\x00\x00\x00\x00\x02\xff\xf2\xff\x9c\x04\xc3\x04A\x00\x1c\x003\x00\x00\x012\x16\x17632\x16\x17\x14\x06\x07\x01&\"\x07\x01#\"&5467&54>\x01\x13\x17\x16\x06+\x01\x11\x14\x06+\x01\"&5\x11#\"&76762\x01\xf6n\xb6,+.y\xaa\x01xZ\xfe\x86\x0d%\x0d\xfe\x83 OqVA\x02b\xa9\xe6\xdf\x0d\n\x15\x89\x0f\n\x96\n\x0f\x89\x15\n\x0d\xc7\x18\x13\x19\x04Awa\x0f\xadxc\xa4\x1c\x01h\x10\x10\xfe\x93sOEk\x0e\x13\x13d\xa9c\xfd\x92\xe4\x10\x17\xfe\xed\n\x0f\x0f\n\x01\x13\x17\x10\xcc\x18\x13\x00\x00\x00\x01\x00d\x00\x00\x04L\x04m\x00\x18\x00\x00%5!\x013\x013 \x013\x013\x01!\x15#\"\x06\x1d\x01!54&#\x02\xbc\x01\x90\xfe\xf2\xaa\xfe\xf2\xaa\xfe\xd4\xfe\xd4\xaa\xfe\xf2\xaa\xfe\xf2\x01\x902\x15\x1d\x01\x90\x1d\x15dd\x01,\x01,\x01M\xfe\xb3\xfe\xd4\xfe\xd4d\x1d\x1522\x15\x1d\x00\x00\x00\x00\x01\x00y\x00\x00\x047\x04\x9b\x00/\x00\x00\x012\x16\x17\x1e\x01\x15\x14\x06\x07\x16\x15\x14\x06#\"'\x152\x16\x1d\x01!54635\x06#\"&547.\x0154632\x174&546\x02X^\x93\x1aY{;2 iJ7-\x15\x1d\xfe\xd4\x1d\x15-7Ji\x04/9iJ\x05\x12\x02\xa3\x04\x9bqY\x06\x83Z=g\x1f\x1d\x1aJi\x1e\xfb\x1d\x1522\x15\x1d\xfb\x1eiJ\x12\x14\x15X5Ji\x02\x02\x10\x05t\xa3\x00\x00\x00\x06\x00'\x00\x14\x04\x89\x04\x9c\x00\x11\x00*\x00B\x00J\x00b\x00{\x00\x00\x01\x16\x12\x02\x07\x0e\x01\"&'&\x02\x127>\x012\x16\x05\"\x07\x0e\x01\x07\x06\x16\x1f\x01\x163276767>\x01/\x01&'&\x17\"\x07\x0e\x01\x07\x06\x16\x1f\x01\x16327>\x017>\x01/\x01&'&\x16&\"\x06\x14\x16267\"\x07\x0e\x01\x07\x0e\x01\x1f\x01\x16\x17\x16327>\x0176&/\x01&\x17\"\x07\x06\x07\x06\x07\x0e\x01\x1f\x01\x16\x17\x16327>\x0176&/\x01&\x03\xf2oOOoS\xd9\xdc\xd9SoOOoS\xd9\xdc\xd9\xfe=\x04\x04y\xb1\"\x04\x0d\x0c$\x03\x04\x17\x06\x1bGF`\x0b\x0d\x03 \x03\x0b\x07\x1c\x04\x05Pu\x18\x04\x0c\x0d\"\x04\x04\x16\x06\x12Q9\x0c\x0c\x03 \x03\x0b\x07\xf9c\x8ccc\x8ccV\x16\x06\x12Q:\x0b\x0c\x03 \x03\x0b\x07\x08\x04\x05Pu\x18\x04\x0d\x0c\"\x04\x8d\x17\x06\x1bGF`\x0b\x0d\x03 \x03\x0b\x07\x08\x04\x04y\xb1\"\x04\x0d\x0c$\x03\x03\xf2o\xfe\xd5\xfe\xd5oSWWSo\x01+\x01+oSWW\x1c\x01\"\xb1y\x0c\x16\x03 \x01\x16`FG\x1b\x03\x15\x0c#\x0d\x06\x04\x91\x02\x18uP\x0d\x16\x03 \x01\x15:Q\x12\x03\x15\x0b#\x0c\x07\x04\xfacc\x8ccc\x15\x15:Q\x11\x04\x15\x0b#\x0c\x07\x04\x02\x18uP\x0d\x16\x03 \x01$\x16`FG\x1b\x03\x15\x0c#\x0d\x06\x04\x01\"\xb1y\x0c\x16\x03 \x01\x00\x00\x00\x05\x00d\x00\x00\x03\xe8\x04\xb0\x00\x0c\x00\x0f\x00\x16\x00\x1c\x00\"\x00\x00\x01!\x11#5!\x15!\x11463!\x01#5\x033\x07'353\x03!\"&5\x11\x05\x15\x14\x06+\x01\x02\xbc\x01,\xb4\xfe\xac\xfe\x84\x0f\n\x02?\x01,\xc8d\xa2\xd4\xd4\xa2d\xb4\xfeu\n\x0f\x03\x84\x0f\n\xc3\x03 \xfe\x84\xc8\xc8\x02\xf3\n\x0f\xfe\xd4\xc8\xfc\xe0\xd4\xd4\xc8\xfe\x0c\x0f\n\x01\x8b\xc8\xc3\n\x0f\x00\x00\x00\x00\x05\x00d\x00\x00\x03\xe8\x04\xb0\x00 \x00\x0c\x00\x13\x00\x1a\x00!\x00\x00\x01!\x11 \x01\x11463!\x01#5\x13#\x15#5#7\x03!\"&=\x01)\x01\x15\x14\x06+\x015\x02\xbc\x01,\xfe\xa2\xfd\xda\x0f\n\x02?\x01,\xc8>\xa2d\xa2\xd4\xaa\xfe\x9d\n\x0f\x01|\x02\x08\x0f\n\x9b\x03 \xfd\xf8\x01^\xfd\xda\x04G\n\x0f\xfe\xd4\xc8\xfc|\xc8\xc8\xd4\xfed\x0f\n77\n\x0fP\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x03\xf4\x00\x08\x00\x19\x00\x1f\x00\x00\x01#\x153\x17!\x11#7\x0532\x1e\x02\x15!\x15!\x03\x1134>\x02\x013\x03!\x01!\x04\x8a\xa2dd\xfe\xd4\xa2\xd4\xfd\x12\xc8\x1b\x1a!\x0e\x01,\xfd\xa8\xc8d\x0e!\x1a\x02s\xf0\xf0\xfc\xe0\x01,\x01\xf4\x03 \xc8d\x01,\xd4\xd4\x04\x11+$d\xfe\xa2\x01\xc2$+\x11\x04\xfep\xfep\x01\xf4\x00\x00\x00\x03\x00\x00\x00\x00\x04L\x04L\x00\x19\x002\x009\x00\x00\x0132\x16\x1d\x0132\x16\x1d\x01\x14\x06#!\"&=\x0146;\x01546\x0552\x16\x15\x11\x14\x06#!\"'7\x01\x11463\x15\x14\x163!26\x01\x075#535\x02\x8ad\x15\x1d2\x15\x1d\x1d\x15\xfe\xd4\x15\x1d\x1d\x152\x1d\x01s);;)\xfd\xa8\x01\x13\xf6\xfe\xba;)X>\x01,>X\xfd\xb4\xd4\xc8\xc8\x04L\x1d\x152\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d2\x15\x1d\xfa\x96;)\xfc\xe0);\x04\xf6\x01F\x01D);\x96>XX\xfd\xe6\xd4\xa2d\xa2\x00\x03\x00d\x00\x00\x04\xbc\x04L\x00\x19\x006\x00=\x00\x00\x0132\x16\x1d\x0132\x16\x1d\x01\x14\x06#!\"&=\x0146;\x01546\x0552\x16\x15\x11#\x113\x14\x0e\x02#!\"&5\x11463\x15\x14\x163!26\x01\x075#535\x01\xc2d\x15\x1d2\x15\x1d\x1d\x15\xfe\xd4\x15\x1d\x1d\x152\x1d\x01s);\xc8\xc8\x0e!\x1a\x1b\xfd\xa8);;)X>\x01,>X\x01\x9c\xd4\xc8\xc8\x04L\x1d\x152\x1d\x15d\x15\x1d\x1d\x15d\x15\x1d2\x15\x1d\xfa\x96;)\xfe\x0c\xfe\xd4$+\x11\x04;)\x03 );\x96>XX\xfd\xe6\xd4\xa2d\xa2\x00\x00\x00\x03\xff\xa2\x00\x00\x05\x16\x04\xd4\x00\x0b\x00\x1b\x00\x1f\x00\x00 \x01\x16\x06#!\"&7\x0162\x13#\"\x06\x17\x13\x1e\x01;\x01267\x136&\x03\x1535\x02\x92\x02}\x17 ,\xfb\x04, \x17\x02}\x16@D\xd0\x14\x18\x04:\x04#\x146\x14#\x04:\x04\x18\xe0\xc8\x04\xad\xfb\xb0&77&\x04P'\xfeL\x1d\x14\xfe\xd2\x14\x1d\x1d\x14\x01.\x14\x1d\xfe\x0cdd\x00\x00\x00\x00 \x00\x00\x00\x00\x04L\x04L\x00\x0f\x00\x1f\x00/\x00?\x00O\x00_\x00o\x00\x7f\x00\x8f\x00\x00\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x1332\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x0132\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146!32\x16\x1d\x01\x14\x06+\x01\"&=\x0146\x01\xa9\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x01\x9a\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\xfc\xea\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x01\x9a\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x01\x9a\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\xfc\xea\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x01\x9a\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x01\x9a\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x04L\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\xfe\xd4\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\xfe\xd4\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\xfe\xd4\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x00\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x05\x14\x00\x19\x00)\x003\x00\x00\x013\x15#\x15!2\x16\x0f\x01\x06\x07!&/\x01&63!5#5353\x01!2\x16\x14\x06+\x01\x17!7#\"&46\x03!2\x16\x1d\x01!546\x02\xbcdd\x01^>1\x1cB)(\xfc\xfc()B\x1c1>\x01^dd\xc8\xfe>\x02\xbc\x15\x1d\x1d\x15\x0c\x89\xfcJ\x8a\x0d\x15\x1d\x1d\xb3\x04L\x15\x1d\xfbP\x1d\x04\xb0\xc8dO7\x84S33S\x847Od\xc8d\xfc|\x1d*\x1ddd\x1d*\x1d\xfe\xd4\x1d\x1522\x15\x1d\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x05\x14\x00\x05\x00\x19\x00+\x005\x00\x00\x002\x16\x15#4\x07!\x16\x15\x14\x07!2\x16\x0f\x01!'&63!&54\x03!2\x16\x14\x06+\x01\x15\x05!%5#\"&46\x03!2\x16\x1d\x01!546\x020P9\xc2<\x01:\x12\x03\x01H)\x07\"\xaf\xfdZ\xb2\"\n)\x01H\x03\xaf\x02\xbc\x15\x1d\x1d\x15\x96\x01\x13\xfcJ\x01\x13\x96\x15\x1d\x1d\xb3\x04L\x15\x1d\xfbP\x1d\x05\x14;))\x8d%&\x08\x11!\x16\x91\x91\x16!\x11\x08&\xfe\x95\x1d*\x1d\xc8\xc8\xc8\xc8\x1d*\x1d\xfd\xa8\x1d\x1522\x15\x1d\x00\x04\x00\x00\x00\x00\x04\xb0\x04\x9d\x00\x07\x00\x14\x00$\x00.\x00\x00\x002\x16\x14\x06\"&4\x1332\x16\x15\x14\x17!65463\x01!2\x16\x14\x06+\x01\x17!7#\"&46\x03!2\x16\x1d\x01!546\x02\x0d\x96jj\x96j\xb7.\"+'\xfe\xbc'+#\xfe\xcd\x02\xbc\x15\x1d\x1d\x15\x0d\x8a\xfcJ\x89\x0c\x15\x1d\x1d\xb3\x04L\x15\x1d\xfbP\x1d\x04\x9dj\x96jj\x96\xfe\xeb9:LkkL:9\xfer\x1d*\x1ddd\x1d*\x1d\xfe\xd4\x1d\x1522\x15\x1d\x00\x04\x00\x00\x00\x00\x04\xb0\x05\x14\x00\x0f\x00\x1c\x00,\x006\x00\x00\x012\x1e\x01\x15\x14\x06\"&547\x177'6\x1332\x16\x15\x14\x17!65463\x01!2\x16\x14\x06+\x01\x17!7#\"&46\x03!2\x16\x1d\x01!546\x02X/[3o\x9co\"\x90o\xa3\"\x1f.\"+'\xfe\xbc'+#\xfe\xcd\x02\xbc\x15\x1d\x1d\x15\x0d\x8a\xfcJ\x89\x0c\x15\x1d\x1d\xb3\x04L\x15\x1d\xfbP\x1d\x05\x14k\x8b6NooN>Q\x8fo\xa3\x1a\xfe\n9:LkkL:9\xfer\x1d*\x1ddd\x1d*\x1d\xfe\xd4\x1d\x1522\x15\x1d\x00\x00\x00\x03\x00\x00\x00\x00\x04\xb0\x05\x12\x00\x12\x00\"\x00,\x00\x00\x01\x05\x15!\x14\x1e\x03\x17!.\x0154>\x027\x01!2\x16\x14\x06+\x01\x17!7#\"&46\x03!2\x16\x1d\x01!546\x02X\x01,\xfe\xd4%??M\x13\xfd\xee<=Bm\x8fJ\xfe\xa2\x02\xbc\x15\x1d\x1d\x15\x0d\x8a\xfcJ\x89\x0c\x15\x1d\x1d\xb3\x04L\x15\x1d\xfbP\x1d\x04\xb0\xa1\x8b9fQ?H\x19S\xbdTT\xa1vK\x04\xfc~\x1d*\x1ddd\x1d*\x1d\xfe\xd4\x1d\x1522\x15\x1d\x00\x02\x00\xc8\x00\x00\x03\xe8\x05\x14\x00\x0f\x00)\x00\x00\x002\x16\x1d\x01\x1e\x01\x1d\x01!546754\x03!2\x16\x17#\x153\x15#\x153\x15#\x153\x14\x06#!\"&5\x1146\x02/R;.6\xfep6.d\x01\x906\\\x1a\xac\xc8\xc8\xc8\xc8\xc8uS\xfepSuu\x05\x14;)N\x1a\\6226\\\x1aN)\xfeG6.dddddSuuS\x01\x90Su\x00\x00\x03\x00d\xff\xff\x04L\x04L\x00\x0f\x00/\x003\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x03!2\x16\x1d\x01\x14\x06#!\x17\x16\x14\x06\"/\x01!\x07\x06\"&4?\x01!\"&=\x0146\x05\x07!'\x96\x03\x84\x15\x1d\x1d\x15\xfc|\x15\x1d\x1d\x04\x03\xb6\n\x0f\x0f\n\xfe\xe5\xe0\x0d\x1a%\x0dX\xfd\xf4W\x0d&\x1a\x0d\xe0\xfe\xdf\n\x0f\x0f\x01\xaad\x01Dd\x04L\x1d\x15\xfe\x0c\x15\x1d\x1d\x15\x01\xf4\x15\x1d\xfdD\x0f\n2\n\x0f\xe0\x0d%\x1b\x0dXX\x0d\x1b%\x0d\xe0\x0f\n2\n\x0fddd\x00\x00\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04L\x00\x19\x00#\x00-\x007\x00\x00\x13!2\x16\x1d\x01#4&+\x01\"\x06\x15#4&+\x01\"\x06\x15#546\x03!2\x16\x15\x11!\x1146\x13\x15\x14\x06+\x01\"&=\x01!\x15\x14\x06+\x01\"&=\x01\xc8\x03 Sud;)\xfa);d;)\xfa);du\x11\x03\xe8);\xfbP;\xf1\x1d\x15d\x15\x1d\x03\xe8\x1d\x15d\x15\x1d\x04LuS\xc8);;));;)\xc8Su\xfe\x0c;)\xfe\xd4\x01,);\xfe\x0c2\x15\x1d\x1d\x1522\x15\x1d\x1d\x152\x00\x03\x00\x01\x00\x00\x04\xa9\x04\xac\x00\x0d\x00\x11\x00\x1b\x00\x00 \x01\x16\x14\x0f\x01!\x01&47\x0162 \x03\x03!2\x16\x1d\x01!546\x01\xe0\x02\xaa\x1f\x1f\x83\xfe\x1f\xfd\xfb \x01'\x1fY\xfe\xac\x01V\x01/\xfe\xab\xa2\x03 \x15\x1d\xfc|\x1d\x04\x8d\xfdU\x1fY\x1f\x83\x02\x06\x1fY\x1f\x01(\x1f\xfen\xfe\xaa\x010\x01U\xfc\x1b\x1d\x1522\x15\x1d\x00\x00\x00\x00\x02\x00\x8f\x00\x00\x04!\x04\xb0\x00\x17\x00/\x00\x00\x01\x03.\x01#!\"\x06\x07\x03\x06\x163!\x15\x14\x1626=\x01326\x03!546;\x01546;\x01\x113\x1132\x16\x1d\x0132\x16\x15\x04!\xbd\x08'\x15\xfep\x15'\x08\xbd\x08\x13\x15\x02q\x1d*\x1d}\x15\x13\xa8\xfd\xad\x1d\x152\x1d\x150\xc8/\x15\x1d2\x15\x1d\x02\x87\x01\xfa\x13\x1c\x1c\x13\xfe\x06\x13\x1c\x96\x15\x1d\x1d\x15\x96\x1c\xfd\x8c2\x15\x1d2\x15\x1d\x01,\xfe\xd4\x1d\x152\x1d\x15\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x0d\x00\x10\x00\x1f\x00\"\x00\x00\x01!\x11\x14\x06#!\x11\x015463!\x01#5\x01!\x11\x14\x06#!\"&5\x11463!\x01#5\x03\x84\x01,\x0f\n\xfe\x89\xfe\xd4\x0f\n\x01w\x01,\xc8\xfd\xa8\x01,\x0f\n\xfdv\n\x0f\x0f\n\x01w\x01,\xc8\x03 \xfd\xc1\n\x0f\x02O\x01,T\n\x0f\xfe\xd4\xc8\xfe\x0c\xfd\xc1\n\x0f\x0f\n\x03\xb6\n\x0f\xfe\xd4\xc8\x00\x02\xff\x9c\x00d\x05\x14\x04G\x00F\x00V\x00\x00\x0132\x1e\x02\x17\x16\x17\x16676'&7>\x01\x16\x17\x16\x07\x0e\x01+\x01\x0e\x01\x0f\x01\x0e\x01+\x01\"&?\x01\x06+\x01\"'\x07\x0e\x01+\x01\"&?\x01&/\x01.\x01=\x0146;\x0167'&6;\x016\x05#\"\x06\x1d\x01\x14\x16;\x0126=\x014&\x01\xe4\xc3K\x8ejI\x0c\x12\x11\x1fC\n\n\x19\x13\n\x05\x0f\x17\x0c)\x02\x03V=>\x078\x1c'\x03\"\x15d\x15\x18\x03\x0c1*\xc3\x18)\x0b\x03\"\x15d\x15\x18\x03\x1aT,\x9f\x13\x1c\x1d\x15|\x0b-o\x10\x07\x15\xcbt\x01E\xfa\n\x0f\x0f\n\xfa\n\x0f\x0f\x04GAk\x8aI\x0e\x06\n! \"%\x1b\x10\x08\x06\x08\x0c,=?W7|&\xea\x14\x1d\x1d\x14F\x0e\x08@\x14\x1d\x1d\x14\x9dJe5\x07&\x152\x15\x1dWO_\x0e\x13e_\x0f\n2\n\x0f\x0f\n2\n\x0f\x00\x06\xff\x9c\xff\xe6\x05\x14\x04~\x00 \x00$\x004\x00<\x00R\x00b\x00\x00\x01%6\x16\x1f\x01\x16\x06\x0f\x01%32\x16\x1f\x01!2\x16\x1d\x01\x14\x06\x07\x05\x06&'&#!\"&=\x0146\x17#\"\x06\x1d\x01\x14;\x012654&'&\x04\"\x06\x14\x16264\x017>\x01\x1e\x01\x17\x1e\x01?\x01\x17\x16\x06\x0f\x01\x06&/\x01&6%\x07\x06\x1f\x01\x1e\x01?\x016'.\x01'.\x01\x02\x81\x01\xa7\x13.\x0e \x0e\x03\x10\x8b\xfc+jCH\x1ef\x037\x15\x1d\x1c\x13\xfd\x1f\x17\" *:\xfe\xd4>XX\xb9P\x13\x12*\x86\x10\x0b \x0b\x12\x01\x80@--@-\xfe\x0f\x98\x12 \x1e\x13\x10\x1c-\x1a?0\x0d!3P/|)\x82( \x01)f\x1f!%\x0d\x1d\x11=\x13\x05\x02\x14\x07\x0b\x10\x03\x84\xf7\x08\x0b\x10&\x0f*\x0dx\xc8\"6\xd4\x1d\x152\x15&\x07\x84\x04\x14\x0fCX>\xc8>X\xac\x1c\x1583\x10\x10\x0bD\x11\x1c\xc9-@--@\xfe\xdb\x82\x13\n\x11\x12\x13# \x03\x05\xb3=I+E( /\x97/}\x1cX\x1b&+\x0f \x0b5\x10!\x14H \x0c\x04\x00\x00\x00\x00\x03\x00d\x00\x00\x049\x04\xb0\x00Q\x00`\x00o\x00\x00\x0132\x16\x1d\x01\x1e\x01\x17\x16\x0e\x02\x0f\x012\x1e\x05\x15\x14\x0e\x05#\x15\x14\x06+\x01\"&=\x01#\x15\x14\x06+\x01\"&=\x01#\"&=\x0146;\x01\x11#\"&=\x0146;\x01546;\x012\x16\x1d\x013546\x03\x15!2>\x02574.\x03#\x01\x15!2>\x02574.\x03#\x02q\x96\n\x0fOh\x01\x01 ..\x10\x11\x06\x1240:*\x1d\x17\"6-@#\x1a\x0f\n\x96\n\x0fd\x0f\n\x96\n\x0f\xaf\n\x0f\x0f\nKK\n\x0f\x0f\n\xaf\x0f\n\x96\n\x0fd\x0f\xd7\x01\x07\x1c)\x13\x0b\x01\x01\x0b\x13)\x1c\xfe\xf9\x01k\x1c)\x13\x0b\x01\x01\x0b\x13)\x1c\x04\xb0\x0f\nm!mJ.M-\x1f\x06\x06\x03\x0f\x14(2N-;]<*\x15\x0b\x02K\n\x0f\x0f\nKK\n\x0f\x0f\nK\x0f\n\x96\n\x0f\x02X\x0f\n\x96\n\x0fK\n\x0f\x0f\nKK\n\x0f\xfe\xd4\xc8\x15\x1d\x1d\x0b\n\x04\x0e\"\x1a\x16\xfep\xc8\x15\x1d\x1d\x0b\n\x04\x0e\"\x1a\x16\x00\x00\x03\x00\x04\x00\x02\x04\xb0\x04\xae\x00\x17\x00)\x00,\x00\x00\x13!2\x16\x15\x11\x14\x06\x0f\x01\x0e\x01#!\"&'.\x025\x1146\x04\"\x0e\x04\x0f\x01\x17!7.\x05\x03#\x13\xd4\x03\x0cVz$\x12\x12\x1d\x81R\xfd\xc4R\x82\x1c\x08\x18(z\x02 \x8c}VG+\x1d\x06\x06\x9c\x020\x9c\x02\x08 )IU!\x9d\xc3\x04\xaezV\xfe`3\xb7BBWwvX\x1cZ\xc53\x01\xa0Vz\x99\x17&--%\x0c\x0c\xf3\xf3\x05\x0f,(1#\xfe\xc2\x01\x05\x00\x02\x00\xc8\x00\x00\x03\x84\x05\x14\x00\x0f\x00\x19\x00\x00\x0132\x16\x15\x11\x14\x06#!\"&5\x1146\x01\x15\x14\x06+\x01\"&=\x01\x01\xdb\x96g\xacT)\xfe>)T\xac\x01H6\x15\x96\x156\x05\x14\xacg\xfe\x0c)TT)\x01\xf4g\xac\xfc\x18\xe1\x1566\x15\xe1\x00\x00\x02\x00\xc8\x00\x00\x03\x84\x05\x14\x00\x0f\x00\x19\x00\x00\x013\x14\x163\x11\x14\x06#!\"&5\x1146\x01\x15\x14\x06+\x01\"&=\x01\x01\xdb`\xb3\x96T)\xfe>)T\xac\x01H6\x15\x96\x156\x05\x14\x96\xb3\xfeB)TT)\x01\xf4g\xac\xfc\x18\xe1\x1566\x15\xe1\x00\x00\x02\x00\x00\x00\x14\x05\x0e\x04\x1a\x00\x14\x00\x1a\x00\x00 \x01%\x07\x15\x17\x15'\x075754&>\x02?\x01' \x01\x05%5\x05%\x05\x0e\xfd\x82\xfe\x86Nd\x96\x96d\x01\x01\x01\x05\x04/\x93\x02\x82\x01\\\xfe\xa2\xfe\xa2\x01^\x01^\x02\xff\xfe\xe5\xaa<\xe0\x96\xc7\x94\x95\xc8\x96\xfa\x04\x0d\x06\n\x06\x03(A\x01\x1b\xfdb\xa6\xa6\x93\xa5\xa5\x00\x00\x03\x00d\x01\xf4\x04\xb0\x03 \x00\x07\x00\x0f\x00\x17\x00\x00\x122\x16\x14\x06\"&4$2\x16\x14\x06\"&4$2\x16\x14\x06\"&4\xbc|XX|X\x01\xe8|XX|X\x01\xe8|XX|X\x03 X|XX|XX|XX|XX|XX|\x00\x00\x00\x00\x03\x01\x90\x00\x00\x02\xbc\x04L\x00\x07\x00\x0f\x00\x17\x00\x00\x002\x16\x14\x06\"&4\x122\x16\x14\x06\"&4\x122\x16\x14\x06\"&4\x01\xe8|XX|XX|XX|XX|XX|X\x04LX|XX|\xfe\xc8X|XX|\xfe\xc8X|XX|\x00\x00\x00\x03\x00d\x00d\x04L\x04L\x00\x0f\x00\x1f\x00/\x00\x00\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146\x13!2\x16\x1d\x01\x14\x06#!\"&=\x0146}\x03\xb6\n\x0f\x0f\n\xfcJ\n\x0f\x0f\n\x03\xb6\n\x0f\x0f\n\xfcJ\n\x0f\x0f\n\x03\xb6\n\x0f\x0f\n\xfcJ\n\x0f\x0f\x04L\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\xfep\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\xfep\x0f\n\x96\n\x0f\x0f\n\x96\n\x0f\x00\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x0f\x00\x1f\x00/\x003\x00\x00\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05!\"\x06\x15\x11\x14\x163!265\x114&\x05!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x15!5\x01^\x01\xf4\xa2\xbc\xbb\xa3\xfe\x0c\xa5\xb9\xb9\x02\xcb\xfd\xa8);;)\x02X);;\xfd\xb1\x01\xf4\x15\x1d\x1d\x15\xfe\x0c\x15\x1d\x1dG\x01\x90\x04\xb0\xbb\xa3\xfe\x0c\xa5\xb9\xb9\xa5\x01\xf4\xa5\xb9\xc8;)\xfd\xa8);;)\x02X);d\x1d\x15\xfe\xd4\x15\x1d\x1d\x15\x01,\x15\x1dd\xc8\xc8\x00\x00\x00\x00\x01\x00d\x00d\x04\xb0\x04L\x00;\x00\x00\x13!2\x16\x14\x06+\x01\x1532\x16\x14\x06+\x01\x1532\x16\x14\x06+\x01\x1532\x16\x14\x06#!\"&46;\x015#\"&46;\x015#\"&46;\x015#\"&46\x96\x03\xe8\x15\x1d\x1d\x1522\x15\x1d\x1d\x1522\x15\x1d\x1d\x1522\x15\x1d\x1d\x15\xfc\x18\x15\x1d\x1d\x1522\x15\x1d\x1d\x1522\x15\x1d\x1d\x1522\x15\x1d\x1d\x04L\x1d*\x1d\xc8\x1d*\x1d\xc8\x1d*\x1d\xc8\x1d*\x1d\x1d*\x1d\xc8\x1d*\x1d\xc8\x1d*\x1d\xc8\x1d*\x1d\x00\x00\x00\x06\x01,\x00\x05\x03\xe8\x04\xa3\x00\x07\x00\x0d\x00\x13\x00\x19\x00\x1f\x00*\x00\x00\x01\x1e\x01\x06\x07.\x016\x012\x16\x15\"&%\x14\x06#46\x012\x16\x15\"&%\x14\x06#46\x03\x15\x14\x06\"&=\x01\x1632\x02\x8aW??WW??\xfe\xf9|\xb0|\xb0\x02\xbc\xb0|\xb0\xfd\xc0|\xb0|\xb0\x02\xbc\xb0|\xb0\xb0\x1d*\x1d(\x03\x11\x04\xa3C\xb2\xb2BB\xb2\xb2\xfe\xc0\xb0|\xb0||\xb0|\xb0\xfe\xd4\xb0|\xb0||\xb0|\xb0\xfe\xd3\x90\x15\x1d\x1d\x15\x8e\x04\x00\x00\x01\xff\xb5\x00\xc8\x04\x94\x03\x81\x00B\x00\x00\x0176\x17\x01\x1e\x01\x07\x0e\x01+\x012\x15\x14\x0e\x04+\x01\"\x1147&\"\x07\x16\x15\x10+\x01\".\x03543#\"&'&67\x016\x1f\x01\x1e\x01\x0e\x01/\x01\x07!'\x07\x06.\x016\x02\xe9E\x19\x14\x01*\x0b\x08\x06\x05\x1a\x0f\x08\x01\x04\x0d\x1b'?)\x92\xb8\n\x14T\x15\x0b\xb8\x8e0I'\x19\x07\x02\x07\x0f\x19\x06\x06\x08\x0b\x01*\x14\x1aL\x14\x15\n#\x143\xb6\x03{\xb6,\x14#\n\x16\x03n\x13\x06\x12\xfe\xd9\x0b\x1f\x0f\x0e\x13\x0d\x1d6F82\x1c\x01 \x18\x17\x04\x04\x18\x17\xfe\xe0*\x035\x11#\"\x0e\x05\x15#\x11!\x01#4.\x03+\x01\x11\x14\x16\x173\x15#525\x11#\"\x0e\x03\x15#5!\x04\xb02\x08\x0b\x19\x13&\x18\x19\xc82\x19\x19\xfep\x04\x0e\"\x1a\x16\xc8\x19\x18&\x13\x19\x0b\x082\x03\xe8\xfdD\x19\x08\n\x18\x10\x11d\x19\x0d\x0c\xc82d\x11\x10\x18\n\x08\x19\x01\xf4\x03\x84\x15 \x15\x0e\x08\x03\x01\xfc\xae\x16\x19\x01\x02dd\x01\x05 \x15\x0e\x03R\x01\x03\x08\x0e\x15 \x15\x01,\xfd\x12\x0f\x13\n\x05\x01\xfeW\x0b\x0d\x0122\x19\x01\xa9\x01\x05\n\x13\x0f\x96\x00\x00\x00\x00\x03\x00\x00\x00\x00\x04L\x04\xae\x00\x1d\x00 \x000\x00\x00\x015\"'.\x01/\x01\x01#\x01\x06\x07\x0e\x01\x0f\x01\x15!5\"&?\x01!\x17\x16\x06#\x15\x01\x1b\x01\x01\x15\x14\x06#!\"&=\x01463!2\x16\x03\xe8\x19\x1e\x0e\x16\x05\x04\xfe\xdfE\xfe\xd4\x12\x15 \x1f\x0b\x0b\x01\x111;\x12E\x01%=\x0d!'\xfe\xec\x86y\x01\xb1\x1d\x15\xfc\x18\x15\x1d\x1d\x15\x03\xe8\x15\x1d\x01,2 \x0e\"\n\x0b\x02\xeb\xfd\x0e#\x15 \x13\x05\x0522+.\xb0\xa6\"A2\x01\x87\x01V\xfe\xaa\xfd\xe3d\x15\x1d\x1d\x15d\x15\x1d\x1d\x00\x03\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x0f\x00G\x00J\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x05#\"\x07\x01\x06\x07\x06\x07\x06\x1d\x01\x14\x163!26=\x014&#\"'&?\x01!\x17\x16\x07\x06#\"\x06\x1d\x01\x14\x163!26=\x014&'\"'&'#\x01&\x13#\x132\x04L\x15\x1d\x1d\x15\xfb\xb4\x15\x1d\x1d\x02FF\x0d\x05\xfe\xd5\x11\x12\x12&\x0c\x0b \x01\x11\x08\x0c\x0c\x087\x10\n\n?\x01\n9\x0b\x11\x0c\x18\x08\x0c\x0c\x08\x019\x08\x0c\x0b\x08\x11\x19\x19\x0f\x01\xfe\xe0\x05\x0e\xc5g\x04\xb0\x1d\x15\xfb\xb4\x15\x1d\x1d\x15\x04L\x15\x1dR\x0c\xfd\x0f \x13\x12\x10\x05\x0d2\x08\x0c\x0c\x082\x08\x0c\x17\x0e\x19\xa3\x99\x1f\x18\x11\x0c\x082\x08\x0c\x0c\x082\x07\x0c\x01\x19\x1b$\x02\xec\x0c\xfe\x05\x01\x08\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x03\x00\x13\x00#\x00'\x00\x00\x01!5!\x05!2\x16\x15\x11\x14\x06#!\"&5\x1146)\x012\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x04\xb0\xfbP\x04\xb0\xfb\x82\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x02m\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1dG\x01,\x04Ld\xc8\x1d\x15\xfc|\x15\x1d\x1d\x15\x03\x84\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1dd\xfe\xd4\x01,\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x0f\x00\x1f\x00#\x00'\x00\x00\x13!2\x16\x15\x11\x14\x06#!\"&5\x1146\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x13!5!2\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1d\x02m\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1dG\x01,\xc8\xfbP\x04\xb0\x04\xb0\x1d\x15\xfc|\x15\x1d\x1d\x15\x03\x84\x15\x1d\xfe\x0c\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1dd\xfe\xd4\x01,\xfd\xa8d\x00\x00\x00\x00\x02\x00\x00\x00d\x04\xb0\x03\xe8\x00'\x00+\x00\x00\x13!2\x16\x15\x1135463!2\x16\x1d\x013\x15#\x15\x14\x06#!\"&=\x01#\x11\x14\x06#!\"&5\x1146\x01\x11!\x112\x01\x90\x15\x1dd\x1d\x15\x01\x90\x15\x1ddd\x1d\x15\xfep\x15\x1dd\x1d\x15\xfep\x15\x1d\x1d\x02\x9f\x01,\x03\xe8\x1d\x15\xfe\xa2\x96\x15\x1d\x1d\x15\x96d\x96\x15\x1d\x1d\x15\x96\xfe\xa2\x15\x1d\x1d\x15\x03 \x15\x1d\xfe\xd4\xfe\xd4\x01,\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x03\x00\x13\x00\x17\x00'\x00\x003#\x113\x17!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146ddd\x96\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1dG\x01,\xfe\xa2\x03\x84\x15\x1d\x1d\x15\xfc|\x15\x1d\x1d\x04\xb0d\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1dd\xfe\xd4\x01,\xfe\x0c\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\x00\x00\x00\x00\x02\x00d\x00\x00\x04L\x04\xb0\x00'\x00+\x00\x00\x0132\x16\x15\x11\x14\x06+\x01\x15!2\x16\x15\x11\x14\x06#!\"&5\x11463!5#\"&5\x1146;\x0153\x07\x11!\x11\x02X\x96\x15\x1d\x1d\x15\x96\x01\xc2\x15\x1d\x1d\x15\xfc|\x15\x1d\x1d\x15\x01^\x96\x15\x1d\x1d\x15\x96d\xc8\x01,\x04L\x1d\x15\xfep\x15\x1dd\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1dd\x1d\x15\x01\x90\x15\x1dd\xc8\xfe\xd4\x01,\x00\x00\x00\x04\x00\x00\x00\x00\x04\xb0\x04\xb0\x00\x03\x00\x13\x00\x17\x00'\x00\x00!#\x113\x05!2\x16\x15\x11\x14\x06#!\"&5\x1146\x17\x11!\x11\x01!2\x16\x15\x11\x14\x06#!\"&5\x1146\x04\xb0dd\xfdv\x01\x90\x15\x1d\x1d\x15\xfep\x15\x1d\x1dG\x01,\xfc\xae\x03\x84\x15\x1d\x1d\x15\xfc|\x15\x1d\x1d\x04\xb0d\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1dd\xfe\xd4\x01,\xfe\x0c\x1d\x15\xfep\x15\x1d\x1d\x15\x01\x90\x15\x1d\x00\x00\x01\x01,\x000\x03o\x04\x80\x00\x0f\x00\x00 \x01\x06#\"&5\x114632\x17\x01\x16\x14\x03a\xfe\x12\x17\x12\x0e\x10\x10\x0e\x12\x17\x01\xee\x0e\x025\xfe\x12\x17\x1b\x19\x03\xe8\x19\x1b\x17\xfe\x12\x0e*\x00\x00\x00\x00\x01\x01A\x002\x03\x84\x04~\x00\x0b\x00\x00 \x016\x16\x15\x11\x14\x06'\x01&4\x01O\x01\xee\x1d**\x1d\xfe\x12\x0e\x02{\x01\xee\x1d\x11)\xfc\x18)\x11\x1d\x01\xee\x0e*\x00\x00\x00\x00\x01\x002\x01A\x04~\x03\x84\x00\x0b\x00\x00\x13!2\x16\x07\x01\x06\"'\x01&6d\x03\xe8)\x11\x1d\xfe\x12\x0e*\x0e\xfe\x12\x1d\x11\x03\x84*\x1d\xfe\x12\x0e\x0e\x01\xee\x1d*\x00\x00\x00\x00\x01\x002\x01,\x04~\x03o\x00\x0b\x00\x00 \x01\x16\x06#!\"&7\x0162\x02{\x01\xee\x1d\x11)\xfc\x18)\x11\x1d\x01\xee\x0e*\x03a\xfe\x12\x1d**\x1d\x01\xee\x0e\x00\x00\x00\x00\x02\x00\x08\x00\x00\x04\xb0\x04(\x00\x06\x00\n\x00\x00\x01\x15\x015-\x015\x01!5!\x02\xbc\xfdL\x01\x9d\xfec\x04\xa8\xfc\xe0\x03 \x02\xe5\xb6\xfe\xbd\xdd\xc1\xc1\xdd\xfb\xd8\xc8\x00\x00\x00\x00\x02\x00\x00\x00d\x04\xb0\x04\xb0\x00\x0b\x001\x00\x00\x01#\x153\x15!\x1135#5!\x0134>\x05;\x01\x11\x14\x06\x0f\x01\x15!5\".\x035\x1132\x1e\x05\x153\x11!\x04\xb0\xc8\xc8\xfe\xd4\xc8\xc8\x01,\xfbP2\x08\x0b\x19\x13&\x18\x19d2\x19\x19\x01\x90\x04\x0e\"\x1a\x16d\x19\x18&\x13\x19\x0b\x082\xfc\xe0\x03\x84dd\x01,dd\xfe\x0c\x15 \x15\x0e\x08\x03\x01\xfd\xda\x16\x19\x01\x02dd\x01\x05 \x15\x0e\x02&\x01\x03\x08\x0e\x15 \x15\x01,\x00\x00\x02\x00\x00\x00\x00\x04L\x03\xe8\x00%\x001\x00\x00\x01#4.\x05+\x01\x11\x14\x16\x1f\x01\x15!52>\x035\x11#\"\x0e\x05\x15#\x11!\x01#\x153\x15!\x1135#5!\x03 2\x08\x0b\x19\x13&\x18\x19d2\x19\x19\xfep\x04\x0e\"\x1a\x16d\x19\x18&\x13\x19\x0b\x082\x03 \x01,\xc8\xc8\xfe\xd4\xc8\xc8\x01,\x02\xbc\x15 \x15\x0e\x08\x03\x01\xfd\xda\x16\x19\x02\x01dd\x01\x05 \x15\x0e\x02&\x01\x03\x08\x0e\x15 \x15\x01,\xfc\xe0dd\x01,dd\x00\x00\x01\x00\xc8\x00f\x03r\x04J\x00\x12\x00\x00\x0132\x16\x07 \x01\x16\x06+\x01\"'\x01&47\x016\x02\xbd\xa0\x10\n\x0c\xfe0\x01\xd0\x0c\n\x10\xa0\x0d\n\xfe)\x07\x07\x01\xd7\n\x04J\x16\x0c\xfe0\xfe0\x0c\x16 \x01\xd7\x08\x14\x08\x01\xd7 \x00\x00\x01\x01>\x00f\x03\xe8\x04J\x00\x12\x00\x00\x0132\x17\x01\x16\x14\x07\x01\x06+\x01\"&7 \x01&6\x01S\xa0\x0d\n\x01\xd7\x07\x07\xfe)\n\x0d\xa0\x10\n\x0c\x01\xd0\xfe0\x0c\n\x04J \xfe)\x08\x14\x08\xfe) \x16\x0c\x01\xd0\x01\xd0\x0c\x16\x00\x00\x01\x00f\x00\xc8\x04J\x03r\x00\x12\x00\x00\x00\x16\x1d\x01\x14\x07\x01\x06\"'\x01&=\x0146\x17 \x01\x044\x16 \xfe)\x08\x14\x08\xfe) \x16\x0c\x01\xd0\x01\xd0\x03w\n\x10\xa0\x0d\n\xfe)\x07\x07\x01\xd7\n\x0d\xa0\x10\n\x0c\xfe0\x01\xd0\x00\x00\x00\x01\x00f\x01>\x04J\x03\xe8\x00\x12\x00\x00 \x01\x16\x1d\x01\x14\x06' \x01\x06&=\x0147\x0162\x02j\x01\xd7 \x16\x0c\xfe0\xfe0\x0c\x16 \x01\xd7\x08\x14\x03\xe1\xfe)\n\x0d\xa0\x10\n\x0c\x01\xd0\xfe0\x0c\n\x10\xa0\x0d\n\x01\xd7\x07\x00\x00\x00\x02\x00\xd9\xff\xf9\x04=\x04\xb0\x00\x05\x00:\x00\x00\x01\x14\x06#46\x0532\x16\x1f\x0167>\x02\x1e\x04\x06\x07\x0e\x06\x07\x06\"&#\"\x06\"'.\x03/\x01.\x01>\x04\x1e\x01\x17'&6\x03\xe8\xb0|\xb0\xfeVd\x15&\x07O\x05\x0b\"(P3G*+\x0f\x05\x11\x01\x04\x12\x17*3M,\x0d:I\x0b\x0eG7\x109_7&\x07\x07\x0f\x06\x0f%*>7F1\x1f\x93\x0c\x0d\x04\xb0|\xb0|\xb0\xc8\x1c\x13\xc2\x01\x02\x06\x07\x07\x05\x0f\x1f5KmC\x07\x19KG\\JB\x11\x05\x05\x07\x07\x19ktl$#?hI7 \x13\x07\x03\x06\x05\xc0\x12\x18\x00\x00\x00\x00\x02\x00\xc8\x00\x15\x03\x84\x04\xb0\x00\x16\x00\x1a\x00\x00\x13!2\x16\x15\x11\x14\x06+\x01\x11\x07\x06&5\x11#\"&5\x1146\x17\x15!5\xfa\x02X\x15\x1d\x1d\x15\x96\xff\x13\x1a\x96\x15\x1d\x1d\xab\x01,\x04\xb0\x1d\x15\xfep\x15\x1d\xfe\x0c\xb2 \x10\x15\x02\x8a\x1d\x15\x01\x90\x15\x1dddd\x00\x00\x00\x02\x00\xc8\x00\x19\x04L\x04\xb0\x00\x0e\x00\x12\x00\x00\x13!2\x16\x15\x11\x05\x11%!\x11#\x1146\x01\x1575\xfa\x02\xee'=\xfdD\x02X\xfdDd\x1f\x01\x0dd\x04\xb0Q,\xfc[u\x03\xb6}\xfc\x18\x04\x01\x174\xfd]d\x14d\x00\x01\x00\x00\x00\x01\x02Mo\xc3\x04__\x0f<\xf5\x00\x1f\x04\xb0\x00\x00\x00\x00\xd0vs\x97\x00\x00\x00\x00\xd0vs\x97\xffQ\xff\x9c\x05\xdc\x05\x14\x00\x00\x00\x08\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x05\x14\xff\x85\x00\x00\x05\x14\xffQ\xfe\xd4\x05\xdc\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x01\xb8\x00(\x00\x00\x00\x00\x01\x90\x00\x00\x04\xb0\x00\x00\x04\xb0\x00d\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00p\x02\x8a\x00\x00\x05\x14\x00\x00\x02\x8a\x00\x00\x05\x14\x00\x00\x01\xb1\x00\x00\x01E\x00\x00\x00\xd8\x00\x00\x00\xd8\x00\x00\x00\xa2\x00\x00\x01\x04\x00\x00\x00H\x00\x00\x01\x04\x00\x00\x01E\x00\x00\x04\xb0\x00d\x04\xb0\x00{\x04\xb0\x00\xc8\x04\xb0\x00\xc8\x01\xf4\x00\x00\x04\xb0\xff\xf2\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\xff\xf0\x04\xb0\x00\x00\x04\xb0\x00\x0e\x04\xb0\x00 \x04\xb0\x00d\x04\xb0\xff\xd3\x04\xb0\xff\xd3\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00&\x04\xb0\x00n\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00d\x04\xb0\x00\x1a\x04\xb0\x00d\x04\xb0\x00\x0c\x04\xb0\x00d\x04\xb0\x00\x17\x04\xb0\xff\x9c\x04\xb0\x00d\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x00\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00d\x04\xb0\x00\x00\x04\xb0\x00d\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00d\x04\xb0\x00\xc8\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x005\x04\xb0\x00d\x04\xb0\x00\xc8\x04\xb0\xff\xb5\x04\xb0\x00!\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\xff\x9c\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\xdb\x04\xb0\x00\x17\x04\xb0\x00u\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\n\x04\xb0\x00\xc8\x04\xb0\x00\x00\x04\xb0\x00\x9d\x04\xb0\x00\xc8\x04\xb0\x00\xc8\x04\xb0\x00\xc8\x04\xb0\x00\x00\x04\xb0\xff\xfe\x04\xb0\x01,\x04\xb0\x00d\x04\xb0\x00\x88\x04\xb0\x01;\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x00\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x17\x04\xb0\x00\x00\x04\xb0\x00\xb7\x04\xb0\x00\xb7\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00I\x04\xb0\x00\x17\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00]\x04\xb0\xff\xdc\x04\xb0\xff\xdc\x04\xb0\xff\x9f\x04\xb0\x00d\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00d\x04\xb0\xff\xff\x04\xb0\x00\x00\x04\xb0\xffQ\x04\xb0\x00\x06\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x01E\x04\xb0\x00\x01\x04\xb0\x00\x00\x04\xb0\xff\x9c\x04\xb0\x00J\x04\xb0\x00\x14\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\x00\x00\x04\xb0\xff\x9c\x04\xb0\x00a\x04\xb0\xff\xfd\x04\xb0\x00\x16\x04\xb0\x00\x16\x04\xb0\x00\x16\x04\xb0\x00\x16\x04\xb0\x00\x18\x04\xb0\x00\x00\x04\xc4\x00\x00\x04\xb0\x00d\x00\x00\x00\x00\x00\x00\xff\xd8\x00d\x009\x00\xc8\x00\x00\x01'\x00d\x00\x19\x00\x19\x00\x19\x00\x19\x00\x19\x00\x19\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00d\x00d\x00\x00\x00\x10\x00\x00\x00\x00\x00d\xff\x9c\xff\x9c\xff\x9c\xff\x9c\xff\x9c\xff\x9c\xff\x9c\xff\x9c\x00 \x00 \xff\xf2\xff\xf2\x00d\x00y\x00'\x00d\x00d\x00\x00\x00\x00\x00d\xff\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x00d\x00\x00\x00\x01\x00\x8f\x00\x00\xff\x9c\xff\x9c\x00d\x00\x04\x00\xc8\x00\xc8\x00\x00\x00d\x01\x90\x00d\x00\x00\x00d\x01,\xff\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x01,\x01A\x002\x002\x00\x08\x00\x00\x00\x00\x00\xc8\x01>\x00f\x00f\x00\xd9\x00\xc8\x00\xc8\x00\x00\x00*\x00*\x00*\x00*\x00\xb2\x00\xe8\x00\xe8\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01N\x01\xa4\x02\x06\x02\"\x02~\x02\x86\x02\xac\x02\xe4\x03F\x03n\x03\x8c\x03\xc4\x04\x08\x042\x04b\x04\xa2\x04\xdc\x05\\\x05\xba\x06r\x06\xf4\x07 \x07b\x07\xca\x08\x1e\x08b\x08\xbe 6 \x84 \xb6 \xde\n(\nL\n\x94\n\xe2\x0b0\x0b\x8a\x0b\xca\x0c\x08\x0cX\x0d*\x0d^\x0d\xb0\x0e\x0e\x0eh\x0e\xb4\x0f(\x0f\xa6\x0f\xe6\x10\x12\x10T\x10\x90\x10\xaa\x11*\x11v\x11\xb6\x12\n\x128\x12|\x12\xc0\x13\x1a\x13t\x13\xd0\x14*\x14\xd4\x15<\x15\xa8\x15\xcc\x16\x04\x166\x16`\x16\xb0\x16\xfe\x17R\x17\xa6\x18\x02\x18.\x18j\x18\x96\x18\xb0\x18\xe0\x18\xfe\x19(\x19h\x19\x94\x19\xc4\x19\xda\x19\xee\x1a6\x1ah\x1a\xb8\x1a\xf6\x1b^\x1b\xb4\x1c2\x1c\x94\x1c\xe2\x1d\x1c\x1dD\x1dl\x1d\x94\x1d\xbc\x1d\xe6\x1e.\x1ev\x1e\xc0\x1fb\x1f\xd2 F \xbe!2!v!\xb8\"@\"\x96\"\xb8#\x0e#\"#8#z#\xc2#\xe0$\x02$0$^$\x96$\xe2%4%`%\xbc&\x14&~&\xe6'P'\xbc'\xf8(4(p(\xac)\xa0)\xcc*&*J*\x84+\n+z,\x08,h,\xba,\xec-\x1c-\x88-\xf4.(.f.\xa2.\xd8/\x0e/F/~/\xb2/\xf80>0\x840\xd21\x121`1\xae1\xe82$2^2\x9a2\xde3\"3>3h3\xb64\x184`4\xa84\xd25,5\x9e5\xe86>6|6\xdc7\x1a7N7\x927\xd48\x108B8\x868\xc89\n9J9\x889\xcc:\x1c:l:\x9a:\xde;\xa0;\xdc<\x18:>\x8c>\xd4?(?n?\xaa?\xfa@H@\x80@\xc6A\x02A~B\x18B\xa8B\xeeC\x18CBCvC\xa0C\xcaD\x10D`D\xaeD\xf6EZE\xb6F\x06FtF\xb4F\xf6G6GvG\xb6G\xf6H\x16H2HNHjH\x86H\xccI\x12I8I^I\x84I\xaaJ\x02J.JR\x00\x01\x00\x00\x01\x17\x00\xa7\x00\x11\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x01\x00\x00\x00@\x00.\x00\x00\x00\x00\x00\x00\x00\x10\x00\xc6\x00\x01\x00\x00\x00\x00\x00\x13\x00\x12\x00\x00\x00\x03\x00\x01\x04 \x00\x00\x00j\x00\x12\x00\x03\x00\x01\x04 \x00\x01\x00(\x00|\x00\x03\x00\x01\x04 \x00\x02\x00\x0e\x00\xa4\x00\x03\x00\x01\x04 \x00\x03\x00L\x00\xb2\x00\x03\x00\x01\x04 \x00\x04\x008\x00\xfe\x00\x03\x00\x01\x04 \x00\x05\x00x\x016\x00\x03\x00\x01\x04 \x00\x06\x006\x01\xae\x00\x03\x00\x01\x04 \x00\x08\x00\x16\x01\xe4\x00\x03\x00\x01\x04 \x00 \x00\x16\x01\xfa\x00\x03\x00\x01\x04 \x00\x0b\x00$\x02\x10\x00\x03\x00\x01\x04 \x00\x0c\x00$\x024\x00\x03\x00\x01\x04 \x00\x13\x00$\x02X\x00\x03\x00\x01\x04 \x00\xc8\x00\x16\x02|\x00\x03\x00\x01\x04 \x00\xc9\x000\x02\x92\x00\x03\x00\x01\x04 \xd9\x03\x00\x1a\x02\xc2www.glyphicons.com\x00C\x00o\x00p\x00y\x00r\x00i\x00g\x00h\x00t\x00 \x00\xa9\x00 \x002\x000\x001\x004\x00 \x00b\x00y\x00 \x00J\x00a\x00n\x00 \x00K\x00o\x00v\x00a\x00r\x00i\x00k\x00.\x00 \x00A\x00l\x00l\x00 \x00r\x00i\x00g\x00h\x00t\x00s\x00 \x00r\x00e\x00s\x00e\x00r\x00v\x00e\x00d\x00.\x00G\x00L\x00Y\x00P\x00H\x00I\x00C\x00O\x00N\x00S\x00 \x00H\x00a\x00l\x00f\x00l\x00i\x00n\x00g\x00s\x00R\x00e\x00g\x00u\x00l\x00a\x00r\x001\x00.\x000\x000\x009\x00;\x00U\x00K\x00W\x00N\x00;\x00G\x00L\x00Y\x00P\x00H\x00I\x00C\x00O\x00N\x00S\x00H\x00a\x00l\x00f\x00l\x00i\x00n\x00g\x00s\x00-\x00R\x00e\x00g\x00u\x00l\x00a\x00r\x00G\x00L\x00Y\x00P\x00H\x00I\x00C\x00O\x00N\x00S\x00 \x00H\x00a\x00l\x00f\x00l\x00i\x00n\x00g\x00s\x00 \x00R\x00e\x00g\x00u\x00l\x00a\x00r\x00V\x00e\x00r\x00s\x00i\x00o\x00n\x00 \x001\x00.\x000\x000\x009\x00;\x00P\x00S\x00 \x000\x000\x001\x00.\x000\x000\x009\x00;\x00h\x00o\x00t\x00c\x00o\x00n\x00v\x00 \x001\x00.\x000\x00.\x007\x000\x00;\x00m\x00a\x00k\x00e\x00o\x00t\x00f\x00.\x00l\x00i\x00b\x002\x00.\x005\x00.\x005\x008\x003\x002\x009\x00G\x00L\x00Y\x00P\x00H\x00I\x00C\x00O\x00N\x00S\x00H\x00a\x00l\x00f\x00l\x00i\x00n\x00g\x00s\x00-\x00R\x00e\x00g\x00u\x00l\x00a\x00r\x00J\x00a\x00n\x00 \x00K\x00o\x00v\x00a\x00r\x00i\x00k\x00J\x00a\x00n\x00 \x00K\x00o\x00v\x00a\x00r\x00i\x00k\x00w\x00w\x00w\x00.\x00g\x00l\x00y\x00p\x00h\x00i\x00c\x00o\x00n\x00s\x00.\x00c\x00o\x00m\x00w\x00w\x00w\x00.\x00g\x00l\x00y\x00p\x00h\x00i\x00c\x00o\x00n\x00s\x00.\x00c\x00o\x00m\x00w\x00w\x00w\x00.\x00g\x00l\x00y\x00p\x00h\x00i\x00c\x00o\x00n\x00s\x00.\x00c\x00o\x00m\x00W\x00e\x00b\x00f\x00o\x00n\x00t\x00 \x001\x00.\x000\x00W\x00e\x00d\x00 \x00O\x00c\x00t\x00 \x002\x009\x00 \x000\x006\x00:\x003\x006\x00:\x000\x007\x00 \x002\x000\x001\x004\x00F\x00o\x00n\x00t\x00 \x00S\x00q\x00u\x00i\x00r\x00r\x00e\x00l\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\xff\xb5\x002\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x17\x00\x00\x01\x02\x01\x03\x00\x03\x00\x0d\x00\x0e\x01\x04\x00\x96\x01\x05\x01\x06\x01\x07\x01\x08\x01 \x01\n\x01\x0b\x01\x0c\x01\x0d\x01\x0e\x01\x0f\x01\x10\x01\x11\x01\x12\x01\x13\x00\xef\x01\x14\x01\x15\x01\x16\x01\x17\x01\x18\x01\x19\x01\x1a\x01\x1b\x01\x1c\x01\x1d\x01\x1e\x01\x1f\x01 \x01!\x01\"\x01#\x01$\x01%\x01&\x01'\x01(\x01)\x01*\x01+\x01,\x01-\x01.\x01/\x010\x011\x012\x013\x014\x015\x016\x017\x018\x019\x01:\x01;\x01<\x01=\x01>\x01?\x01@\x01A\x01B\x01C\x01D\x01E\x01F\x01G\x01H\x01I\x01J\x01K\x01L\x01M\x01N\x01O\x01P\x01Q\x01R\x01S\x01T\x01U\x01V\x01W\x01X\x01Y\x01Z\x01[\x01\\\x01]\x01^\x01_\x01`\x01a\x01b\x01c\x01d\x01e\x01f\x01g\x01h\x01i\x01j\x01k\x01l\x01m\x01n\x01o\x01p\x01q\x01r\x01s\x01t\x01u\x01v\x01w\x01x\x01y\x01z\x01{\x01|\x01}\x01~\x01\x7f\x01\x80\x01\x81\x01\x82\x01\x83\x01\x84\x01\x85\x01\x86\x01\x87\x01\x88\x01\x89\x01\x8a\x01\x8b\x01\x8c\x01\x8d\x01\x8e\x01\x8f\x01\x90\x01\x91\x01\x92\x01\x93\x01\x94\x01\x95\x01\x96\x01\x97\x01\x98\x01\x99\x01\x9a\x01\x9b\x01\x9c\x01\x9d\x01\x9e\x01\x9f\x01\xa0\x01\xa1\x01\xa2\x01\xa3\x01\xa4\x01\xa5\x01\xa6\x01\xa7\x01\xa8\x01\xa9\x01\xaa\x01\xab\x01\xac\x01\xad\x01\xae\x01\xaf\x01\xb0\x01\xb1\x01\xb2\x01\xb3\x01\xb4\x01\xb5\x01\xb6\x01\xb7\x01\xb8\x01\xb9\x01\xba\x01\xbb\x01\xbc\x01\xbd\x01\xbe\x01\xbf\x01\xc0\x01\xc1\x01\xc2\x01\xc3\x01\xc4\x01\xc5\x01\xc6\x01\xc7\x01\xc8\x01\xc9\x01\xca\x01\xcb\x01\xcc\x01\xcd\x01\xce\x01\xcf\x01\xd0\x01\xd1\x01\xd2\x01\xd3\x01\xd4\x01\xd5\x01\xd6\x01\xd7\x01\xd8\x01\xd9\x01\xda\x01\xdb\x01\xdc\x01\xdd\x01\xde\x01\xdf\x01\xe0\x01\xe1\x01\xe2\x01\xe3\x01\xe4\x01\xe5\x01\xe6\x01\xe7\x01\xe8\x01\xe9\x01\xea\x01\xeb\x01\xec\x01\xed\x01\xee\x01\xef\x01\xf0\x01\xf1\x01\xf2\x01\xf3\x01\xf4\x01\xf5\x01\xf6\x01\xf7\x01\xf8\x01\xf9\x01\xfa\x01\xfb\x01\xfc\x01\xfd\x01\xfe\x01\xff\x02\x00\x02\x01\x02\x02\x02\x03\x02\x04\x02\x05\x02\x06\x02\x07\x02\x08\x02 \x02\n\x02\x0b\x02\x0c\x02\x0d\x02\x0e\x02\x0f\x02\x10\x02\x11\x02\x12\x06glyph1\x06glyph2\x07uni00A0\x07uni2000\x07uni2001\x07uni2002\x07uni2003\x07uni2004\x07uni2005\x07uni2006\x07uni2007\x07uni2008\x07uni2009\x07uni200A\x07uni202F\x07uni205F\x04Euro\x07uni20BD\x07uni231B\x07uni25FC\x07uni2601\x07uni26FA\x07uni2709\x07uni270F\x07uniE001\x07uniE002\x07uniE003\x07uniE005\x07uniE006\x07uniE007\x07uniE008\x07uniE009\x07uniE010\x07uniE011\x07uniE012\x07uniE013\x07uniE014\x07uniE015\x07uniE016\x07uniE017\x07uniE018\x07uniE019\x07uniE020\x07uniE021\x07uniE022\x07uniE023\x07uniE024\x07uniE025\x07uniE026\x07uniE027\x07uniE028\x07uniE029\x07uniE030\x07uniE031\x07uniE032\x07uniE033\x07uniE034\x07uniE035\x07uniE036\x07uniE037\x07uniE038\x07uniE039\x07uniE040\x07uniE041\x07uniE042\x07uniE043\x07uniE044\x07uniE045\x07uniE046\x07uniE047\x07uniE048\x07uniE049\x07uniE050\x07uniE051\x07uniE052\x07uniE053\x07uniE054\x07uniE055\x07uniE056\x07uniE057\x07uniE058\x07uniE059\x07uniE060\x07uniE062\x07uniE063\x07uniE064\x07uniE065\x07uniE066\x07uniE067\x07uniE068\x07uniE069\x07uniE070\x07uniE071\x07uniE072\x07uniE073\x07uniE074\x07uniE075\x07uniE076\x07uniE077\x07uniE078\x07uniE079\x07uniE080\x07uniE081\x07uniE082\x07uniE083\x07uniE084\x07uniE085\x07uniE086\x07uniE087\x07uniE088\x07uniE089\x07uniE090\x07uniE091\x07uniE092\x07uniE093\x07uniE094\x07uniE095\x07uniE096\x07uniE097\x07uniE101\x07uniE102\x07uniE103\x07uniE104\x07uniE105\x07uniE106\x07uniE107\x07uniE108\x07uniE109\x07uniE110\x07uniE111\x07uniE112\x07uniE113\x07uniE114\x07uniE115\x07uniE116\x07uniE117\x07uniE118\x07uniE119\x07uniE120\x07uniE121\x07uniE122\x07uniE123\x07uniE124\x07uniE125\x07uniE126\x07uniE127\x07uniE128\x07uniE129\x07uniE130\x07uniE131\x07uniE132\x07uniE133\x07uniE134\x07uniE135\x07uniE136\x07uniE137\x07uniE138\x07uniE139\x07uniE140\x07uniE141\x07uniE142\x07uniE143\x07uniE144\x07uniE145\x07uniE146\x07uniE148\x07uniE149\x07uniE150\x07uniE151\x07uniE152\x07uniE153\x07uniE154\x07uniE155\x07uniE156\x07uniE157\x07uniE158\x07uniE159\x07uniE160\x07uniE161\x07uniE162\x07uniE163\x07uniE164\x07uniE165\x07uniE166\x07uniE167\x07uniE168\x07uniE169\x07uniE170\x07uniE171\x07uniE172\x07uniE173\x07uniE174\x07uniE175\x07uniE176\x07uniE177\x07uniE178\x07uniE179\x07uniE180\x07uniE181\x07uniE182\x07uniE183\x07uniE184\x07uniE185\x07uniE186\x07uniE187\x07uniE188\x07uniE189\x07uniE190\x07uniE191\x07uniE192\x07uniE193\x07uniE194\x07uniE195\x07uniE197\x07uniE198\x07uniE199\x07uniE200\x07uniE201\x07uniE202\x07uniE203\x07uniE204\x07uniE205\x07uniE206\x07uniE209\x07uniE210\x07uniE211\x07uniE212\x07uniE213\x07uniE214\x07uniE215\x07uniE216\x07uniE218\x07uniE219\x07uniE221\x07uniE223\x07uniE224\x07uniE225\x07uniE226\x07uniE227\x07uniE230\x07uniE231\x07uniE232\x07uniE233\x07uniE234\x07uniE235\x07uniE236\x07uniE237\x07uniE238\x07uniE239\x07uniE240\x07uniE241\x07uniE242\x07uniE243\x07uniE244\x07uniE245\x07uniE246\x07uniE247\x07uniE248\x07uniE249\x07uniE250\x07uniE251\x07uniE252\x07uniE253\x07uniE254\x07uniE255\x07uniE256\x07uniE257\x07uniE258\x07uniE259\x07uniE260\x07uniF8FF\x06u1F511\x06u1F6AA\x00\x00\x00\x00\x01TP\xc3\x17\x00\x00PK\x07\x08\x9a\x17<\x9c\\\xb1\x00\x00\\\xb1\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00fonts/glyphicons-halflings-regular.woffwOFF\x00\x01\x00\x00\x00\x00[\x80\x00\x0f\x00\x00\x00\x00\xb1\\\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FFTM\x00\x00\x01X\x00\x00\x00\x1c\x00\x00\x00\x1cm*\x97\xdcGDEF\x00\x00\x01t\x00\x00\x00\x1f\x00\x00\x00 \x01D\x00\x04OS/2\x00\x00\x01\x94\x00\x00\x00E\x00\x00\x00`g\xb9k\x89cmap\x00\x00\x01\xdc\x00\x00\x02\xc0\x00\x00\x06r\xda\xad\xe3\x81cvt \x00\x00\x04\x9c\x00\x00\x00\x04\x00\x00\x00\x04\x00(\x02\xf8gasp\x00\x00\x04\xa0\x00\x00\x00\x08\x00\x00\x00\x08\xff\xff\x00\x03glyf\x00\x00\x04\xa8\x00\x00M\x17\x00\x00\x94\xa4}]\xc2ohead\x00\x00Q\xc0\x00\x00\x004\x00\x00\x006\x05M/\xd8hhea\x00\x00Q\xf4\x00\x00\x00\x1c\x00\x00\x00$\nD\x04\x11hmtx\x00\x00R\x10\x00\x00\x01O\x00\x00\x03t\xd2\xc7 `loca\x00\x00S`\x00\x00\x02'\x00\x00\x020o\xfb\x95\xcemaxp\x00\x00U\x88\x00\x00\x00 \x00\x00\x00 \x01j\x00\xd8name\x00\x00U\xa8\x00\x00\x01\x9e\x00\x00\x03\xa2\xb3,\xa0\x9bpost\x00\x00WH\x00\x00\x04-\x00\x00\n\xd1\xba\xa3\xe55webf\x00\x00[x\x00\x00\x00\x06\x00\x00\x00\x06\xc3\x18TP\x00\x00\x00\x01\x00\x00\x00\x00\xcc=\xa2\xcf\x00\x00\x00\x00\xd0v\x81u\x00\x00\x00\x00\xd0vs\x97x\xdac`d``\xe0\x03b \x06\x10`b`d`d\x14\x03\x92,`\x1e\x03\x00\x05H\x00J\x00x\xdac`f\xe9f\x9c\xc0\xc0\xca\xc0\xc2\xcc\xc3t\x81\x81\x81!\nB3.a0b\xda\x01\xe4\x03\xa5\x10\x80 \x89\x1d\xea\x1d\xee\xc7\xe0\xc0\xa0\xf0\xff?\xf3\x81\xff\x02@u\"\x0c\xd5@aF$%\n\x0c\x8c\x001\x96\x0b\x0c\x00\x00\x00x\xda\xed\x94?hSA\x1c\xc7\x7f\x97\xa4iS\xc4\xc6\xfe\x89\x8dm\xdf\xbd44\xb1\xad\xd0,\x0eq\xcaPK\x83 q\xd2\x0c\xd2XE\x1a]\xb2(\x04\x142 \x01\x87.\xa5\xd4\xa9\x83]\xb4\x82 \"\x0eE\x1c\x9cD\xb7\n\xad\xa5\xb9\xdfi]D\xd4\xa1ZJ\xf5\xf9\xbd\\\x06\x11\xb5\xba8\xf9\xe0\x93\xcf\xef\xbdw\xef\xee\x9bw\xbf\x84\x88\x9a\x88\xc8\x0f\x0e\x81V\"\xb1F\x02\x15\x05\xa6pU\xd4\xaf\xfb\x1b\xd7\x03\xe2.\xce\xa7(\x83g\x0e\x92K\xc34O\x0bn\xab;\xe2N\xb8\x8b\xeeR\x7f{\xbcg`'!\x12\xdb\xc9P\xb2M\xf9UHE\xd5\xa0J\xab\xac\xca\xab\x82*\xaa\xb2\xaa\xaaY\x0eq\x94\x079\xcdc\x9c\xe5<\x17\xb9\xccU\x9e\xe19\x1d\xd4!\x1d\xd1Q\x1d\xd3I\x9d\xd6Y\x9d\xd7\x85-\xcf\xf3\xb0\xa2KC\xf5\x95\xe8\x17+ \xd5\xa4\xc2\xcaU)\x95Q9\xac4\xa9J\xaa\xa2\xa6Yp\x98]Nq\x86\xc79\xc7\x05.q\x85\xa7yV\x13V\n\xebn\xac\x14\xd7)\x9d\xd19\xbb\x92\xf7\xca[\xf5\xce{\x93\xaa\xa5\xf6\xbav\xbfV\xac\xe5\xd7\x9b\xd6\xbe\xac\xf6\xadFWb+\x1d+{\xdd>\xb7\xd7\x8d\xb8a|\xe3\x80\xfc*\xb7\xe4g\xf9Q\xbe\x95\x1b\xf2\x8a\xbc,K\xf2\x82<'\xcf\xca\xd3\xf2\xa4\x03W@\x15\xf5Ex\x1a\xcc\xa2\xbeD\xc4\xc8\xc3&\xc3U\x18\x19\xd8d\xb8\x06#\x03\x9b\x0c\x18\xcb\xc8\xc0&\xc3\x0d\x18\x19x\x0c\xf5Mx\x1c\x98<\xb7a\xe4a\x93\xe7\x0e\x8c,l2<\x80\x91\x81M\x86\xc702\xb0\xc9\xf0\x146\xf3\xce\xa0^\x86\x91\x85\xe7P\xbf$\xd2\x906{\xb8\x0e\x87,\xb4\x01#\x9b\xc6\x9e\xd0\x1b\x18{\xa0M\xcewp\xccB\xef\xe18H\xa2\xfe\x00#\xb36\x997ad\xd6&'~\x89\x1a95r\n3w\xc1\"\xd0\x0f[\x9eEt\x92\xd8\xdcW\x87\x04:\xfd\xd3\xad:$\"\x14\xf4\x99>2\xcd\xffc\xff\x0b\xf25*\xdf.\xfdl\x9f\xf4\xff\xe4N\xa0\xfe/\xf6\xff\xf8\xfeh\xfe\x8b\xb1\xc1]Gt\xfd\xe9T\xe8\x81\xdf\x1e\xdf\x00\x8f\xd1\x0f\x18\x00(\x02\xf8\x00\x00\x00\x01\xff\xff\x00\x02x\xda\xc5\xbd |\x1b\xd5\xb50>w\x16\x8d\xd6\x19m#Y\xb6e[\x92%Y\xde-YR\x1c'r\xf6\x84\xc4Y\xc8j\xb6\xb0D%\x10 \x81,@\xd8B\xd8K\x1bZjH\xd9\xda\xa4@\x1a\x12b\x02\xa5\xa5\xa4-\x85R\xf4\xca\xeb+\xa5n\xfbhK\x9b~\xaf\xe5\xcb\xeb\xa3\xbc\x96\xa6\xa5$\xd6\xe4;\xe7\xceh\xb5\x13\xe8\xeb\xff\xfd\xfe^f\xee\xdc\xb9s\xef\xb9\xe7n\xe7\x9c{\xce\xb9\x0c\xcb\xb40\x0c\xb9\x8ckb8Fd:\x9f%L\xd7\x94\xc3\"\xcf\xfc1\xfe\xacA\xf8\xd5\x94\xc3\x1c\x0bA\xe6Y\x0e\xa3\x05\x8c>,\x1a\xc8\xd8\x94\xc3\x04\xe3\x13\x8e\x80#\x9cp\x84Z\xc84\xf5\xd8\x9f\xfe\xc45\x8d\x1dma\xdfd\x08\x93e\xb2\xfc ?\xc8\x9c\x07y\xc7=\x8d\xa4\x81\xf8I:C\x1a\x89\xc7 \x93D\xdc\xe3\xf5(n\x08I\xa4\x8dx\x1b\x88L\x0c\x91.\x021\xa2!\x14\x84P'\x99JD\x89t\x91Hj\x80@L4\x92\xec\x85P\x86\xf4\x93h'\x19 )\xc8\x11b\xd2)vH\x8eX,f\xf91\xd1c\\'\xb2\xe2cG\xcd\x0e\xd6\xc0\xb1\x84u\x98\x8f>\x06\x11\xeb\x8c\x1e\xf11\xd9\x1c\x0b~\xc2t\xfc\xe0?\xf1\xf1\x84\xe9\x18\xf8!x\xa1\xf8\x08\xc1\x03T_q\x04\xe2\x1e?q\x1bB\x01\x87\xdb\xd0F\x82\x91\xa4#\x10\x8cL%\xbd\xa9D\xc0\xd1\x9b\"\xaf\xe4\x14?Y\xad\xf8\xfd\x8a\xba\xc7\xaf\xc0\x83\xba\x07\x1f\xc8j??8>N\xd1Skem\x84\xb2\xa6AY\xb3\xb5\xb2Db\x10\xa14\x0d\xd9J)\xa4\x95;\x95@\xb9\x1aj\x93\xc5P$\n\x98\xef'qh\xae8`\x9b\xeb;a\x16\x8c\xea\x03\x06\x81X\xcd\x06\xc36C\x8d\xf9F\xe2*\x84d\xcb\x03\x16Y\xfdc\xe1\xb1\x18\xda\"\x18\xd4\x07\x8c\x82\xf9\x84\xcf\xf9\x15\xa3\xdb\xf8\x15'?h\xc6L\xacV\xe3\x97\x8c\xd6,\xbd>c\x91e\xcb3e\x11V\x03\xb9\xd2h\x86\x0f =C\xfb\x91\xc0\x7f\x9a\x7f\x86\xe9\xc7~\xe4\xf5xC\xbd\x9d\\((qb@\x0c\x18\x14\xb84\xf0\x89x\x86K&h\xd7\x81\xce\x11\x0d\xa5\x13\xa94\\2\x04\xba\xc7\xb1\x0f6N1|-\xd4;\xad\xcf\xebj\x9b\x14\xef\x96\xc9\x0dYu\xd4@\x86\xe1j\xea\xee\x9b\xd1\xabx\xfa\xa6\xf5\x86\x9ei\xb8\xe4\x8a\xa7\xfemK\xf3\x0c\xeb\xdb\xd9\x8dD\xf8E\xf6\x0ew\xa6q3\xff\xcc\xb7.\xbb\xbccAw@\xb64t.\x8eg\xe3\xf1\xec\xfckg\xb4\xc9r\xb0{~\xdb\xd3Wl~\xac{\xff\xd6lW2\xbb\xea\xf6\xf0}\x0c\xc327\xd06\x1ea2\xcc\\\x806\x10o\x10\x94z@\xb3$\xb4\x11\xf1\x13\xa1\x1d\x1a\xde\xebH\xc4S\xc9\xdeH\x88\x1c \xabg\xae\x9b\xd1\xed\xb1\x12b\xf5t\xcfX7\xf30K\x9at\xd4\xdec1\x7f\xc1,\xab\x7f\xd5\x1f7\x97B\xf2\x0boL\xeb\xe8\x98\xc6\x8f\xd46\x0f\xc4\x17\xb76[,\x96\xe6\xd6%\xf1i\xe1Z\x0d\xbf\x87,\x92l>T\x86p\xf2K\xb3\x9cSGg\xac\\>\x0d\xf1\x9d#\xbb\xf8A\xf6\x08#3\x8c\xab\xd8E\xb5\x8ey\x82k\xc2\xee6v\x14\xae\xec\x11\xda\xe7\xe8\x85\xc1\xba\xe7\x18\x86;\x06u\x0f3\xd3!\x1bZI\x1c\xce8\xec\x13\x98M\x00\x86k?\x1d\xb38\xb6C\x98\xa3Wq{`\xecC*\x89\xd0\x04\x11h>H\x90\x81\x04\xdc1\xbf\x12_s\xf6\xd9k\xe2\x8a\x7f\xech)\x9c\x9b\x9e\xaeoj\xaaOO'\xbb\n!~dX\xf1g\xcf\xfbB(\xf4\x85\xf3\x86\xfd\xca0<\x0dkOYx\xcae\xa7\xac\xa9\xb1\xc6\xa7\xc4\xad5k\xa6\x0c\x0f\x97=d\x0b\xe3\xb2\xf0\xd3\x03\xcf\xa7> \xed\xfc+\xfct\xc6C\xe7-o\n\xc7\xaa\x86\x02\x84\x1d/\xe4\xc3\xf5_ko\xef\xdc\xb6\x7f\xff\xb6\xbcs\xf1\xd5+f\xb0\xff\xceO\xdfz\xb1tp\xdbu\x077-\x99}\x85d\xf5\xed\xfe9\xc5 \x03s\xe0\x08\x7f\x88\xa9e\x1a \x8c\xb3\\9.H4\x92!0\x8f\xa5S\\ \xca\xb1\x7fk2\x99\xef\"?ip7\x9c\\\x02\x172z\xa7\xd9\xd4\xd4l\xde\xb0\xd1t=\xb9\xee\x85W\xf9\xe7\\!\xfbKyOXimU\xc2\xec\x1f\xbenov\x9b\xec\x0f\x0c\xdb\xc7\x1a6\xb2\x1e:\xbd\xe8\xe5\x0d2\x16\xc6\x0b\xf3LZkA\x18\xfdA\x1c\xcd^\xe2qC\x18\xe6\x99\xde\x94 &P\x05\xe6\x1d\x88\xef\x15aF\xc6\xea\xa5I\xaa0\xdc\xe3>\xfe&\x18\xef\xf9\x7f\x85Q\x0b\x17\x81#F\xa3Q\xfd\xbb\xd1l\xe6>\x0dA\xb3\x19\x1f\xce\x87q*\x98O\xee\x80\x84\x10\x82\xe1\xad\xfd\xe3\x18\xcf\xff\x8b\xd1\xc8\xa6\x8d\xe6_@27\xa6\x15\xccl\xc4,\xa8\x7f\x82\x8f\x05s\xfe\x17\xf8\x89\xd1\xe8\xbe\x05f\x07\xc8\x0b\xbe6\xe2p7\x02\xfc\xdc\xa9?\x9d\xfa\x13\xffM\xfe\x9b\x8c\x89\xb11v\x88A\x98\xdc2\x89\xa6]$j\"\x82\x8b;\x1a\x91v\xdblk~va0\xbf\xfbg\xec\xa5j\xa3\xfa\xdcz\xfe\x9b\xb6\xddRD:\xffg\x17\xa9\xd7\xe6\xbf\x08\xb1c\xeb6\x92\xc5\xc5yw\x04\xfa%\xf4g\xe2(\xc3\xbe\x83\x04\xd8#'\xb4\xceuB\xb5\xf2#\xec=\xf9_@?\x83>\xc6F\xd8\x08\xfdVb\x8c0\x9e\x1fa\x1a\xe1!\xacaL4t\x12Xv\xbc\x0e\xa1\xfc\x01:\xc5F\xf6\xf6h\xf7\xb29\x8b\xefj^\xb5x\xde\x8c\xfc\xbe\xa1\xe9z\xd0\xcf}\xb4Wn\x08\x8e}7}\xb6\xd7\x17\xbbj\x93\xaf\xc6\xce\x9a\x1e\xce\xefi\xbdH\xa9\x8d\xad\xbf\xba\xb6\xc6\xc1\xde\x1ci\xa5\xfd\xc5t\xea\xef\xfcK\xfcS\x8c\x9f\x89a\xcd\x1bXE\xf4\xbaE\xbabb\x1b\x1aBQ1\xd8\xc9\xf6f\x08\x1f\x94\x08t\x91x\x86\xf4F\xc8\xae\xdc\x0b\xb7-\"d\x11qA\x13\xf7\xd7\xc6\\\xea\x1f\xb7~F`\xb3\x10\xbb\xe86\xb2i\xe4\x81\x95+\x1f\xc0\x0b\xff\xd4\xa2\xdb^\xc8\xb2\xc2}\xd7\xa9\xef\xd7\x86k&\xbb\xdd\xc4\xb9\x10\xbe\xbb\xed\x05\xc8\xe0<-\x0d\\\xe8\x9c;\xc4\x1f\xe2g1>\xa8w\x86\x050\xdc0\xdfv\xf2\xc9^x \xec\xdd\xdd7l\xdb<\x94\x9ay\xdd\xce}\x99\xccS\xb7o\x9b9\xe9\xdc-\xdb\xae\xe3\xbe6k\x9e\xd0\xb1l\xcb\xb4\xbe\xebn\xb9\xf9\xf0\x8a\x15\x87o\xbe\xe5\xba\xbei[\x96u\x08\xf3\x10\x97\xa7~\xc2\xac\xe6o\xe0\x1f`j\xe0\xc1\x95\x8a{i\xd7\x14\\\x1eC4,\x18\"iW8\x92J\x90\x07o\x13\x15\xf1V\xf2\x84bp\xa8\xfbw\x88\xb2C\xfd\xaa\xba\xdf!\x8b;\xd4'\x1c\x067\xd7D.v\xb9\xd4\xc7\x1d\xd6\x8f\xd4\x0dn\x8b\xf5o\x1fZ-n\xb2\xeb\xa4\xd5\xc1\xb0e\xf9\x07\xcfP\x82\x10\xf2\x8aio4\x1d\x8a~LY\xe4/\x7fzm\xfew_\x9d\xff\xf2\x1f\x16\x9d\xbe\xd8\xecg\xfe\xcf\xbd\x9f\xfe\xfd\xa7\x7fR\xde\xcf\"t\xde\xa0\xd3&No\x02N\x80\xa5)4\x1d\xc6\xc9M\x0b\xb3C\xdbG2\x11\xab\x89\\j\xb2\xca8\x90d-\x1c\xc9@>#\xdbOt^\xb6\xc0\xec5\xbc+x\xcd\x17\x98e\x19.^\xe1]\x83\xd7\xbc\xe0\xb2\xce\x13\xdbG\xa08\x9b^\xe6 \xf4m\x17\x8c\xf7(\xd3\xc6t1 \x18\xf7s\x99\x05\xccbf\x19\xb3J\x9b\x01\xb0\xdf\xd2 \x0c\x97\x17%\x91\x8c\x91\xa0\x01\xe2<\x89\x00\xac4\x8e\xdeH\x02\xe2\x04\xf8\x0f\x94\xdd\xc5@e\x9a\xea\xf78C\xc8\x1a\xd4\xf2\x8a,\xbb\x17\x065<\xc2(\x97\xe5k\xb2c5Y\xaeI\xbf\xfe\xb6\xec\xcd\xd8\x7f\x97\xe2\xf9A\xf8\xfa]|\xc5\xd7\x9a\xe5l6+\x9b\xd5=\xf8HV\xe3c\x0eb\xb4K\xd5\x8bB\xb46\xdfi4\x95\x0c#\xb4\x8b\x19\x18_\xdb\x18\xa9|&\x1f\xf3>NvQ\x8ak#\xaepW\x95=\xe4\xbfu\xba7\x94\x1a\xdbH\xc9\xb0R$\x0d\xe7\xf7\x9d\xee\x0d\x03\xb3[5\xec\x8b\x99\x0b\x99\x0d\xcc\xcd\xccg\xa1\x16 \xad\x03\xb5\xe9\x1d%\xf01\xcf\xe4\x7f9}\xbc\xb0\xd0\xfb\xc9\x13\x13\x05\xc7\xfe\xfa\xcf&@$\x16\x1f&\xb8\xa8\x1b\xff\xb9\xf7\x8c\xa1l\xac\x94\xf0=\x0e\xd31RI\xf1\x90\x7f\xf2}9\xe6\xd8#\x18\xce\xcf\x82\xabz\xfb?\x16?1z&\xae\xf4\xc4\xb1\x1a_\x10a\xda\xf9c|\x13P\x07\x8cI[\xed\xdd:u\xd0;\xa0\xaf\xfe\xe4\xc7l\xbf\xd1->k4\x8e\xfd\x19\xe6G\xf5\x16\xa3\xf1Y\xd1m|Z\xf4\x90w\xe0\x0d}\x18\xfb\x93\xd1Hn\xd1R=-B\xbe\xeb\x99\xf5\xfc\x0c~\x06\xe5m\xbc\x90\xa7\x89.\xd9\x90\xb1 .\xc0\xc3\xf5\xa6Mz\x11^,\x97\xbb\xeb0\x90\x13\x7f%\x16\xa3\xf1\xb0\x11\xca8\xae\x1e\x17\x15\x08\x1a\x89E\xfd\xab\x16G\xac\xc4**|\xffsg|o\xd4\xf2\xb1\x8a\xc0\xb9zO\xfd\x17\xff\x1a\xbf\x1b\xd6\xac0s\x96\xbez\xe2\xda\xe9.\xac\x9d\xe3WN\x81\xb6^\xb1 \x8b\x84yHk<\x8d\x02v3t\x01{\x058-\xd9|\x02\xc3'\n\xf8\xabe\xea\xf8a~\x18\xd6\xec\xc5H94\xb2\xc8\x11x\xbc\xa2\xd7\x03A\xc5-\xb3@\xfcy\x0dbT4@0\x14\xecb#]D\x8cD\xd3\xd1\x08\x04\x93\xbd\x03lj\x80DSio:\x05Ag\xd0\xe0\xf6\xc4S\xbd\xecP \x16\x11z:\x84;\xa6\xb6-\xe1|\x12yH\x10\x1e\"r\x0d\xb7\xa4{\xd2\x1dB{\\\x88\xb45\x16RLi\x87\x146\xf6A\x83\xe1A\xd6\xe6\xe3\x96tM\xbe]\xe8\xe8\x81\x14\xdb\x0e\xdft\xd3\xe1\x9b\xf8a\xf8R\xf2\xb1K\xba\xfb\xe0\xcb\x1eC\xa4\xad!\xd8\x121\xf4\xb4C\xde\xedgC\xde\xec\x83\x82\xf0 +\xf9\xb8\xb31EG\xb7!\xd2\xda\x14\x80\x14\xddXz\xfb\x12\x96\x96\xae\xee\xbe\xe9\xd9\x9bnz\x96\x11\xb5v\x12\xdc@\xb1x\x99\x00\xf4\xed\x18\xf4\x9b\x1e\xca-#i^\xa0\xcf\x13x\xf1*\x81$)\xae\xce\xc0\x18W\xfc\x92\xe3\xa4=\xd6O\\f\xf9\xe4\xf3\x80[W\x7f\x8c\xb4\x93\xf6\xfeX~V\xac?\xab\xff\x08\xee\xfe\x18\xd0\x0f\x0b`Lei\xac::v4\xd6\xdf\x1f\x03\x02$?\x8b=R\xfe\x0f\xf3\x98\x95a\x04#\xffc\xa4\xf7]8Y\x01\xe5\xddFJ\xe2\x99b\x08&\x08'{%LC\xecE\xc0\xcf\x1c\xa2\xad\x89\xcd\x0c\xb7Cf\x81]\xc7^$\x8a\xf9/\x19\xcd\xf9\xef\xd2f\xdf\xaa\xdeM;\xc3\x80\x19\xda;\xab\xf3\xc9\x0e\x9c\x85 \xa5\xb0\xca\x08\x90\x846\xf9\xb0CX\x1b\x9d\xd5V\xb8\xa5\xc0\xa7\xf0#\xea\xc6X\x7f~\x0bF\xf0\x83\xda<\x7f\x02\xe7 :\xfevC\xbf\xafc\xba\xb5yB\x1bp\x13Lv\x8a\xa3\xac\x8f\xd31\xf0\x1f\x7f\xd0F\x94v#\xdf9\x86\x03\n/\xea\xf68VF\xeb\xa901\x14\xd3\xe0\xad_K\x03\x17\x1b\xf4\xed?\xca\xe6x\x81>\xa3}\xfa\xd4#\x80G7\xd4\xd1\x82\\W\x8cp!.@\x12\x1c\xfc\x12\xb8\x08\xee\xfc\xbb\xb1\x0fb\xf9w\xc9\xa1\x1f+{\xdco\xaa\x8f\xd5\x1d\xad#\xbb\xd4\x8dP\xc3Q\xd2\xaen\xc4\xab66\ncZ\x81\x11\xad\x8f\xe7D\x89\xa1\xa5\xe2\x92\xc2(. \xb0\x9f\x14\xba\x10\x1b\x81u\xef;n\x8bM}\xd1\x16\xc1\x8b\xc5\xfd\x1d?\xbb\x9c\x82\xaa\x11\x9e\x10\xe4v\xcat\x9e\xc9x\xed\xeaF\xbb\x9d\xec\xb2{\xc9+\xc8\x14\x96\x13\x9d\xb2\xf9\x10`\xa2\n\xd7=\x9f\x04\xd7\"\x07\xa0r\x05P\xcf\x80l\x98D\xeeV\xcc\xb6\xdf\x00\xa4\xbf\xb1\x99\x95\xbb?\x06\xe3\x00\xed\x1f\x01Z\x17@\xeb\xa2H\xff\xe4\xb0\x85]\x15\x9d\x1a\xba[\x1a\x98\xa53\xc0\xf6\x7f5\x80\xcc%\x10O\x0b\x1b\x01\xa8\xbc\xea\x1f)\xde\\^\x84\x8f\xd1\xe5 Z;\xfa\x98>\x8dF\xf7\xbatf\x1a\x9b-\x1aI\xbaz\xd3\xae\x0c\x11\x80\xe7\x00\x8cy\xfau\x811\xdcu\x99o<\x15\xe5:\xc9oa:uq\xdf\x14\x8d\x82\xd5w\xf2yk\x03k \xe2\x8b\x9c\x8b}0?jv\xb2\xabX+\xc0\xe8\x02\xe6\xdd\x05}V\xbb\x0f\x9b\xad\x10\xef\xe4G$s\xfe\xda\x1a\x9f\xba\n?2\xf26\x1f\xf9\xaa\xaf\x86\xfd\xb4Y\xcaI\x165c\x91$\xf3Cf\xfdb!\xafX\xa4*|F\xcf\xd4\xd6^\xba$\x7f\xdcp\xba7\xefp\xe4\xed55\xa7\xc5\xdd\x05\xdf\xb66[\xbfm\xb5\xe0jg\x81\xb9\xa8\xb0\xae\xa2l>\x9d*\xf6\xf1\x01\x12 \x15KO&\n \xb1\x898\xf7\xdc\x9d\xa2\x05:\xc7\xb0\x85\x17o\xbf\xea\xd6k\xf5\xa2\x87K\xe5m~\x99o\xbeS\xe4-*4\xa5E\xbc}P/\xfb\xda\xcd%\xa0\x0bk:\xa1e\xd7\"\xe51A\xe9J\x88\x96\xe8\xc2\xe2CAX\x9a\xb4\xb9\x8b\x8a8= \x00L\x83\xc5\xa2>\x08\xb0\xdc\xb1\x1ea\x19\xa6\xe5\xff\x97v{\xe4\x0e|K.3\x0b\xc6\xdb\xd7\xef\x80\xb7:\\\x0fB\xacx\xc7\x02\x1d\xa4\xfcw\xf0\xba\xe5\x0e\x98b\xc9e\x16\x1db\x80\xcf>\xd61\xdb\xbfv\x89H\xc5\x16?\xe4\x13f\xb9\x9b58\xd4\xf3\x0c\x86\xfe%\xcd6\x9b$\xc9\xb2\xdc'p\xa2L^H\xaf\xe2X\xcebp\x13I\x92V\x19qn\xd6\xe6\xbf\x07\x81\xde\xe9A\xe98\xa5\xe5K\x94g'i\x82!Uz\x86\xe1SE\x9a\x06\xaaI\xd7\xdf\x1d\xfb\xf5\xde5\x14\xd9\xf7\xfdN=\xf1\xbb\xfbhp\xcd\xdeV\xdc?\xa1\x9b(\xecE\xc5 \xff\xe0\x9a\xbd\xbf\xbeV\x1d\xa5\xb3r\xfb\xcd?\xde\xb4\xe9\xc77\x17\x9e\xae\xfd\xf5\xde\xfc\xcbV\xa3\xda\x8b\x89\xc9\xbf\xe2\xb5\x14.\xb4\xe3O\xf8\xb9\xdc;\xb0\x06\xf7\x95\xa4\xa0\xd1p\xa4\x00\x0b4\x9e\x90N\xe9RZm.\x04\x96O\xd4\xf8> Mu\xbe\x8fL'\xac\xc9j5\xa9\xaa\xe2\xd3\x08`\x1f;\xb4Mt\x8bAQ\xdc\xb6M\x84\x9b\x1b\xef\xf4y\xebV\xed\x99\xeb<`\x10\x91\x92\x16\x0d\x07$m)\xdey\x9a\xa4\xda\xb3\xd1X\x84\x99\xdbDa\xee:\x1d\xcc\xe1\x04\xdd\x81\x04\xaa\x9a\x04q\xbb1\x9dJ\xf6Fq\xb315\x01\xa4\xe4-\xdel\xb8\xe8\\\x83\x853\x89~X\xa1\xe6-2pF\xffD\xf0e\x89\xe9\xd6/\x7f\xf1f\x13!\x06\xaf\xe82\xae\xbdi\xe7:\xe0\x93=\x02\xc3h\xfd\xe0{\xfc%\xdc{t\x85^\x80\x14\x8d\xb6\x0b*\x1a\xc4P\x11\x88\x88\x06\x85\xf0\x0fB\xcd\xbd\x0e]\xee\xceY\xd3D3\xc0\xd8jd\x0d\x1b\xfa\xd3\x06\xd6\xd4*\xe6w|\xe2\xea\xbcGL\xcf\xbd}\xf9\x1b\xcb\x91k7\xb8\x8d\xc3\x87\xcf=0\xd7\xe46\x04\x84o\x7f\xa2z*\x06\xad\x9e\xb6\xe2zo\x82\x16\xf01~J\xe7w0\xfd0S\xcf\xd4e\x93Pw%\xa4\x04\x94\x90#@BJB \xc0\xa0\x0d%\x03\x02\x10\xd9\xf8+\x84\x92 \xfc'\xb8\xbd\x9c\xc0;\xa4\x0e%!&\xa9\xa7\x12\x0b)\xf0\x1eH\x06\xc8q \xee7f\xc9q\xf6H.\xa7\x8e\xe6\xb2\xec\xd0\xc9\xe7\x81!\xd8E\xda\xc7\x8ef\xb3\xec\x91,\x10\xfc9\xd5\x9a\x83$9\x94 \xe6H{~\x16i\x07\x9e\x80\xdb \x9fZ\xb3\xf0\x02)O|\x82\x8f!\"\x87\xfcD.K\x89\xd2Q\x0ca2\xd5\n%\xa9\xa3\x9a\x182W\x8c\x1f\xa5\x12\xc9\x82\\\x0f\xeb\x8e{\xe9\x16*\x99\xf5B{7\xe2,\x98\x0e9\x12.\xf8'ew U\x03^\xa8\x83W\xaf\x8f&\xde$\xbbr9\xbc\xb5\xe7rcG\xf5B\xf4\xe7\x1cwl\xac\xa6\xf2\xff\xe4\x92l\xf6<\xfc\xd1\xfa\xbe\x99\x7f\x12\xca\xb7\x01\xee\x19SQ\xc2\xe3\x82\x85\x88\x8fh\xec! i\xbf\xd1\xa8v\xe3\xee\xceJ\x02\x0d:\xb3\x7fY?\xfc\xf1#\xf9\x95\xb8_\xd3m4\xb2\xfbq[\xf0\x87\xfd\xfd\xcb\xfb\xfb\x0b}\xd7,\xbcE\xf3\xf5A{V\xe5\x1c\xd0\x9f\xba\x88\x89\x9c\xae\x14\xceP|\x9eD\xf6\xe5g\xa9?9M\xa9\xc5\xc7Id?{\xa4\x04\x03)\xae\xfb\x11\xca/\xc2\xf0\xd0 /\\[ \x88\xabJ\xf9\xd2\x8f\x83\xb9\x9d\xeb[\xe0\x9cf4\x03G>\xcb\x07\x01\xc1\xcc\x1e\xc1Q\x80K\xa0\xf3^\xa0\x0c\x17\x8cm\xd7\xe2\xb9\x17 \x86\xa6\x1c\x9bO\x97\xc7\x1f\xf9 \x01-7w\xea\x14]\xcb\xcc\x05\xea\xc2\x84\xf4<\xdd\x0eU3j\xc6\x8f,\xc4\xc9\x1d\xe4\x88:\x93\xbfY\x93\xb5q\xc5~\xa00\xb3\x99\x15\x08/\xa5m\x91\xac\xc5\xb5\x0f@C\x8a\x16\x97C\xdc\x15F\x80q<\xb7\xe9\x92y\xa4x\xcbh\x07\xfa\x8c\xf5\xc4\\\xf4\x8a\xa60=\x97RgY\xecd\x91(\xf5\x19\xbc(_\xf0\x1a2\x92\xb8\x8c\xd8\xc9\xcaa\xb3\x87_\xc4{p\xb7M\x0b\x14\x85\x15T*\xa1\x8b0\x9eU\xad\x94T\xb6\x98\xd9!\xb3\x05if$\x16\xd4\x9f\xd4(W\xe2\xa4q\xa5RC:P\xa0a3=b\xb2\xd1\x0b rK1'-\xbb{\xa0\xcd\xf6\x95H\xe8\xca\xbdH\x1c\xfd1\xca\xe1'`\xd9k\x1c\xcf\xafex\xa2$\x92\xbc.\xb9h\x8e{\xdc\x86`\xa4\x17F\xe9\xa4\x0bz\x9bE\xc30\xae\xf8c5x\x1dfM\xd1\xc4\x05\x04\x86\xe4\x8f\xbe}\xe7\x9d\xdf\xbeS\xfd\xef\x95S\xa6\xac\x9c\xc2\x0f\xc2K\xc5]N\x1d\x18\xebf'\xdbpP\xce\xb9\x13S\x1a\xa7`BmmH\xd2v9\xc44\xe1\x88\x84^\xecm \x8dD $\x11\xa1\x01\x98\x8a\x81,\x80'\xdc\x84\x1e \x84\x0bp\xecW\xc9\xad\xee\x16g\xd8dV/L\xb6;\x96\xaa\xd7M\x0eZL\xad\xf1\x06\xf5\xf3\x93\xea\xad\xb5\xa2H>{\x80,\xdf\xc3\x1f\x1a\xab\x8d\xb7\xba\x14\xc2\xce\x98\xb1\xaa\xe3\xd7\xf7\x9f\x13\xec\xac\xb7\xce\x98QSo\x0d\xdbl\xdc\xfb\xf9s\xc9\xbfh\xfd\x02\xf9\xff?A\xbf\x882q\xaa\xd3\xd0`\xc0\xdd5\xa0\x83\x80\x9c\x07Z\x80\x8f&\x05*\xea\x93X1L5\x01:\xd96\xa2\xeb\x04\xb4\x11\xf6\xcf\x82+\xd9\xdd\xdf\xeaO\x0f]ue\xb7j\x8d\xf5\x13\x83\xc5\x1b\xa8%?\xef\xdb\xbc&\xd3\xd8\xd1aW?{\xef\xa2\xcb\x1d\xad\xcb2[\xfe}\xc9\xd2\x1bW?\xce\xdeJ\xc4\x1a\x7fb\xf2\xd2\xce\x99\x9b\x17\xa5k\xcf\x11\x13-\\\x7f\x8d\xbb\xdeb7\x89sI\xec\xackf&\xce\x9b\xdcf\xea\xb9x~\xac\xbf\xb7n\xec\x99O-9\xf7V\xda\xe7\x01\xce\x0d\x94~c\x88W\"\xc8\x97y)b\\)\x842\x12MrW\xb1\xcbf\x88;M\xed\xf3U\xeb7\xa5\x83\x1c'[\x1b\x15\xaf\xcd\xc0\x8f\xf4\xb9\x92-c/\xf6\xb4\x18.\xbe\xd8\xbe\x94\x9b\xe6\xa8u\xd9M\x16\xe8\xfel\x9f&\x1f\xf8\x9a.\x1f\x08\xd3\xf59\xd4\xdb) G\xea\xd1\xda!\xc3!W* \xb86\x080C\x8a\xd1\x84#\x94\x16\xdcq\xa3\xc5\xe7\x8a\xd4\xf8rq\x9fO\xdd\xc8K\xc1ZO\xceW\x13q\xf9,\xc68\xcc\x81\x0f/Xp\xe3\x8d\xf0\xcf\xedT\x9a\x14\xc9\xc8\x91\xb1g<>\xc2\xc2\xa4)\x98\x14\x89[J8\xa3\x04o`\n\x1d;\xfa\xd4S\\\xd3S\xd0\x17\x02\xa7\xbe\xc6\x7f\xf6\x93\xc0\xe1\x12\x93\x01%\x9a\x86h~\xf0\xccp\xcc|J\xcb\xbe\x08F~K\x19\x18\xec=E0N\xee\xb8Q\x83X\xdf\xc7\x1a\xa9\xde\xc7*\xe7\x19\xfe\xd1\xe78;D7\x0f\xf6Q\xf1\xd11\xaa\xb5QC\xc3%\x0d\x0e*E\x82y\xeby}\x83\xa1 \x8dUG?>\xfcI`\xe6>\x06\xc6\xea\xf7'\xca6<\x9e+\x83\xed\x9d\xd3\xc4\xff\x7f\x013IV\xf2g\xd5\xcf\xae\x8fyO\x8e\xfb\x95\x12\xaaQ$WBv\xae\x1c\xdb\x08H v\xee\x85\xa2\xe8[\xfd\xcf\x8f 2\xff+\xfd\xa3\x0c\x8f\xca'\x08\xff\xc3\xb86N\xb8\xdf\x86<\xfa\xff\xfa\x9e\xdb\xc7\xee\xc9\x95\xb6\x1d\xa6\x97\x0d\x872\x94\xffS\xf1\xe5\xa8\x9a\x189\xff\xb3X\x861\xa0\\\x95\xe2\x94\xa3\xfb\xfd\xad\xccdf>\xc3\x04B\x8e~\xb6\xb2\xca\xd5\xcd-\x88\x94t\x16>\xa6W\x90]\xd9\xecp\xa9Pr\x9c\xeeZ[\xb1\xb2'\x9e\xca\xe5\xc8+\xa4\x9d\xc6\x8c\xe2\xb5l\x869]\xef8q\xe3\x82\xec\x82C\xa7\xe9!\x8c\xb6'\x0b\xeb@A\x7fA\xafOu\xff\xd0\xa8\xe4\xaa\n!?\x10M\x7f\\\x85JM\xcd\xad\xcdf\xc7\x9e)\xab\x11\xdf\x95\xcb=\xf5\xd4\xc9w?A\x95N>\xcf\x0f\x96\x83\x9e\xcb\xc2\xbc}\xfajQ\x1a<\xc7\x8fp\xc7\xa0^\xce\xf1\xf2(\x13\xbb\x80}\xbf\xb1\xbd\xbd1\xef\x84+\xbf\x932\x1d\xc7\xe0q\x0bF\xb2\xf74R\xbe\x84\xb4\x17iH\xc4\x8f\x97\xeeIT\xebr8\xd2\x02\xd0\xdf\x0e^\xa7\x99\xda\xf9!gm\xad\xf3\xe4>\xb8\xce\xff\x90\xb4\xce'\xe1\xf7\xc6\xde\xda\xb8h\xd1\xc6E\xfc`\xads\xcc\x8ao\xb9\xe3\xce\xdal\xbe\xf1\x85\xdb\x1e!\x19\xf5(9~\xed\xa2\x0d\x8b\x17o\xd0\xe0\xfe%#\xf0)\xfe~\xc6\x83\xfaj$\xde@\x80\xd5\x94\x88Lp\xbdG\xe5\x1fOa{\xe9\xae\xcd\xdf\xbff\xce\xec\xc3\xa9\x94)\xb0z\xe8\xaa\xd8\x94Y\xd7<\xfe\xf5\xaf\xef\xd8\xf1\xf5\x1d\xfc\xfd\xdb~\xb0\xf9\x9a\xcf^\xf5\x9f\x03\x19c\xe0\xd2\xcb\x1e\x9a\xb7s\xf3\xd0\xde\xeb\xe6\xbd\xba\xe3\x1b\xb7\xde\xfa\x8d\xb2\xfd\xc2\xdd\xb4N\x95RU\xe2\xd0\x04\x9b\xd5R\xd4\x05T\x94Y%8\x1d\xdb\xc0\xad\xa4\xf2K\xccs3\xc3q\xbf\x11d]^\xa9QTb'\x07 \x0b\x9c\xc4z\x1bx\xaf\x07)\xeeH\xb4\x93\x8dF\xd2\xa9P\x84mU\xceZ\xbcjQ&\x9cX\xb9\xf1\xc6\x81\xe5\x0fo\x9f\xdf<0\xb8j\xc9YG\xbc\xb1\x16\x8e\xd4\x05z\xea]\x8a\x87\x05\xfe\xd9$8c\xd6\xda&\xd6h\x14\xe4y\x9f\xdd\xbc\xf5\x9a\xcdw\xce\x9e{\xcb\xea9\x11^\x98\xbc\xe6\xc1sf\xdf\xb9\xe5\x9am[v\xe5\xd5\xc0\x82\x1d\x93\xc3\xd3\xa3!\xc9(Z\xedAs\x8d\xc8\xdb\xa7\xc7\xcey\xc1B\x8a\xbc\xc0\x1b\xfc\x95\x8c\x15\xfa8R\x1ai\xd4\xa3B\xadg6\x1c\x88{\xcbUm\xa6\x92tyW!b\x9ap\xc7\xaed\x0dn\xc5/y\xcc\x82\xe1\xca\xbc@v\xc5\xd3/\xa9\xbb\x90\xd4%\xc7c\xfd\xb9\x97\xf6\xaa\x1b\x9fx\xf1En\x92:\xfc\xe54Y\xc3\xfd\xf5\x1a\xc2\xb2\xbc,yZ-\xe6kr\xb6\x97\xfacH&\xf6\xc7^\xc8\xa9\xcfC\xba'\xc8\xae'^T\x7f\xae\x0e\xc7\xf7\x935\xba\x9c\xee\xf3\xd0\xc7\xea\x98\x14r)(\x8a(I\xe8\xd2J\x99\x1cU\xd7\x1f\x8c&#\x80\xdd\x8c!\x0d\x14+YM.\xffJ\xef\xabEX^|\x82\xc2\xc2\xdeL\x96\x01\xabw@\xb4\x90\xda\xbe\xec\xf2\xa1Zsg\xdfY\xd3\xe6\xb4\xba\x88\x85\x1f\xfc\\\xaa\x00\xd1\xee\xb5\x05x\xea\xd4\x9f\xa0\xb2\xc1\xbf\x19x\xd3\x1b\x84\xb5y\xba\x03\xfd\x97L\xef\xf5Cyo\x99\x85\x92<\xf1Q\xcaO$)\xf7W\x8d6\xa5\x1cm%\xdd\x86\xaer\xdd\x86\xd5d\xf5\x94\x99\x87\xd5\xbd\xd5\xf0\x92\x1f\x90{\xa1\xfcO\x89b\xfe\x8fp\xff\xbb\x08AE\xdc\x80\xca\x8c\xdeg\x0b\xd0\xce\xce\xfd\xb2\x88\xbe\x04\xa4\xa7i\xf2\xef\x89\x90\x9c~\xbaA\xa4\xbc\xa2\x99\xf2\xdfO\"mo*\xee!\x02\x83\xd3[T\xc0\x9c\x8a\x12\x8f\xf2m\xacdH\xd1T1\xd3$\x85\n \xc9\x10P\x16\x19\xd4\x904\x12^\x14\xcc\xfbsfcA\x033\xb7\xdf,\x88\xeaXA\xad\xf2P\x8e\xeab\xe2ks\xee\x90Y\xe0\x86\x8b \x0f\x9ayH\x88h\xfdP\xe4\xcd\x07\xcb\x13\xe2+b\x82W\x90=}\xa5\xd3\xfb;\x01\xbf\xbe\x82\x14\xb5\xa8\"Z&x<\x01S\x1cySV\x14Y\xed\xd6&=\xaa\xfe4\x9f\xbc&\x19\x91\xe81J\xe45u~\x81\xe8,\xd3\xbf\xa4z\xefe\xf9\x96g^QB\\/\xa1P\xca\x84%\x8d+p\x82r\x1fe|Pn\x02\xa5 \xa4T\x92\x86cZ>?\xa2\xe7\xef\x96e\xf2\x9eV\"_[\x91\xe7Q\xa9\x15/\x85\x025Y\x00\xe3\xe1\x13|\x8a\xb1\xe0\x1eqI\xa3\xf6/\\\xa7\xd39\xf6\x96\xd3\xe7\xe3\xe3\xaadi\xb0\xc0EBh$\xaa\x1b\x9d\xe5v\xd2\xf5\xa0\xb1\x80\x85\xd3\x0bwOL\xa4 \x85\xea\xd0\xfafp\x19\x05\x8fa\x0d\xa6,?H\xf3gH\xf9f2\xac\x17\x88\xb5Rb\xee\x85\xb2L\nv >\xdeU\xc0So\x99\x96\xb0^1/,\x9a\x88\x1f\xc4\x93\xa2vc\xab\xb0Y\xf2\x02\xa0Gm\x02\xf4\xc0\xc5\xa8\x90\x17\xd4~\xb8Am\x8d\x12\xeaz\xaa\x0c\xcb?\xc7/\xa6\x92\xff4\xd4\xce\x050\x89\x00\x13\x87yj\x17\xcc\xb8p\xe1k\xb2\xee\x06\x81\xb62\xab\xf6H\n\xab\xc6eE\x80R\xdfb\xe9\xc5\xcf/\"\x1aM\x0d7\xf25u\xb2l\xc2[\x9fdrC\x91&Y\xcd\x90\x17\xdc&I\x9d\n`!>p\xfb\x98;\xa6\xf5\xe5J-\x8fb\x9d\xe0\xc2--.\xe0\xb4V\xe4M\xda\xc54>\xa9\xbcFj\xbf\x96/\xee5\xc0\xba\xce\xcf\x83\xb6\xaf\xa3\xb2\x83\xa2\xdet5}\xc2>C\xfe*\x9b<'\xdf\xf7\x98d\x08\xb5\xe6?,c\xc2\xf8\xbe\xfc\xefd\x8fGf\xeb\xe5\xfc\xbc2\xd2\x810w\x9d\x1a\xe36\xf3\xf3\x19\x98\xf2L\xach\"\xdcf\xf5K\xe4\xa2\xd7\xf2\xff\xce\xb6p;\xd5\xc7\xd5\xc7\xbf\xcf\xb6P\xd5d\xa8c\xff\xa91\xbeEO\x8b\x9a\xd1i\xbe%\xff\xf6\xf7\xc9\xc5\x98(DC\xe4\xe2\xefW\xac\xb7\x89\xaa\xf5V\x08\xe9\x1b2\x9a\x84I)\x88\x9d\x12T\xf6\x14i\xc3M\x9b\xea\xb5\xf8F\x00T\xdbz\xa10\xeb\xc1\xaa\xb5\xf9\x9bU\xaf\xf5 S\xb5\xfe7V\xaf\xff\x01\x0d\x14mB\x1fW6;\x9b\x12n\x1aYZU\xa2zS\x19\x1e\xcfTg>(\x93h\x04\x85\x85\xeeF\"\xe2\x05\x15\xde\xbdT\xeb\xbd\xb7\x8b\xa4\xf1R]\xe7\xdf\xfbL\xdb\xb6\x99|\xa6\xfbLx\x87[\xd5s\x15,\x07'NU|\xae\x80\xaf\xb9\x1a\x07E\xe0<\xf14\x05)\x12\x14\xab\x01R\x96\x8b\x8a\x11\x16\xa0\x0fp\x06\xdf*\x8a\xb8vU#\xa4g\x05\xc4\xc3*\xf1g\x98\xf2\xb7j\xc9\x99*=\x81~\xdc\x83\xa8\xec\x11A\x89S\xdc\xfd\xc4\x93\xce\x10\xcd\xeeA\x0cJ\x82Hw\xe43@Nur\xaebw\x99\xb0\x8d\xc8\x80\x7f\xca\x8cx\xc0}[\x83`\xf07\xba\xbd\x92\x8b\xf8\xa4Z\xa7\xcb\xca\x12\x9btPlh \xd5\x04\x13\xb3\xa6L.)NU\x82}\xbf\xa5\xa1kq\xdc'\xd8\xddv\xc5\xe9\xf5\x88FQr\xd7\xb7\xfa\x8c\x0e{\xcb\xa4\xf3S]\xf3Z\xebL\xf9\xff(\xd7@\xe3*\xfaSf\xc2\x1e^\x82\x96+u\xf6Pe_k#\x8e\xf1\x95\x19.\xc98\xe9\xce\xc9\x82\x05%\x8d\x90\x05\xd5\xa0\xaf,\x81\x85\xaa@\x95\x9b\xa3TK\xa3\xa4\x07\xd1\x85\xba\xa7\x1a\x9f\nt`\x91\xdf\x91\x88X\xd4AD;\xa6\x82\x1ab\x86\xa4\x81|p\x15\xdfA\xba\xe27\xf0}q\x07\x15\xd2\x15\xbf\xe9\x042\n@Y\xfb`\x1d\xdd\x07~\xa5\xee\xc1\xb5\x14\xb6\x8a\x88\x17i\xd4\xacK\xbd\xfb0j\x9f\xf7\xd2Y\xd5\x11(\x0d\x9e\xf8\xdbR\x84\xfa\xc3\xd3~^\x88\xa8\xd2\xa7\x188\x83>\x85\xe8=\xe3F\"\x9a\xcb\x9cA[\xe5\x8b\xd3Dq\xfbvQ\x9c\x06C\x02\xee\x8aX\xf5|Z\xf5\x8bsO\xf7\x85\xfe \\\xe4/\xcdf.\xc1\xd9\xd5\xe4\xb3F;\x04\xcc\xe6\xffk\xe1\x1aP\xf1\x95\xecb\x87d\xb3z7\xd4\x90e\xcd\xb6-6\x8bb\xb2y\xb6\xd8\xccb\xc0aWjnh7Y\xf4L\x0f\xe1F\xfb!\xbd4\x83\xc0w\xdf\xe2ssF\x8fC\xban\x8fh\x96\xcc_0\xf3\xfb\x1f\x85\x92>\x0b\xe1\xb1M\x05\xbdZ\xb2\xab \x1f\xb0\xf2\x87\x80\xefnC\xed\x7f\x9c\x8c\x0c\xac\xc4\xc3*\x1a\x11#\x125/O\xf6\x02U\x03\x7f\xd1N\\(3\x06o\xc4@\x85[\x12\x0f7\x0f`\x8bMg8x\xcf\xdfg\xace;f\\y\xf1\xbd\x97|f\xd6\xa4\xa9\x0e\xde\x91\xa8\xdb]\xebi5\xae\xa8q5q&\xd6>\xb9'\xba\xf4\xe2\xf3\xef\xbc\xe1\xe5\xb0\xd1\xdf\x18\xd9353\xe9\xfck\xcfY\xea\xad\x91\x9c\x1d\x01\xdf=W\x9f7\xe7\xe2+\xce\x8byx\xfeI\xcee<\xac\xbe\x93\xfb\xc2P\x8f\xc3h\xb1X a\xeb\xeav\xd7\xb8\x82\xd3\"\xc6\xf9\x8acJc\xfa\xc2\x9bo\x1fH\xccO\x86Cu]\xb3L5\x91\xae\xab\x03\x81\x86\xd4\xd2\xc5k\x93\x93\xa6\xf0\xd1\x96\x86\xf3\xa6\xf5\x84\xa7]x\xf3\x8a\xb8\x1b\xe6\x8a\x0b\x98\x06~\x13\xff#\xaa;!\x91\x06\xde\xdb)B5\x1a8\xa8\x04/\x1aP\xac\x05\xed\x0d\xf5\xf5H\x1c\x9a\xd1F#0\x89\x18\x1a\xb0B(\xf4\xcap\xec}\xd1Fst\xd2\xdc\x19M|\x9d\xb9\xc6l\xe7\x88\xc9)]t\xcf\xbc&\x83\xdd\x96\x99\xbf,\xe3\x99\x97nt\x1a,\xb6h[\xd0\xe4Y4\xdd\xac$\x17\x9ewQ\xd7\x92\xb5,\xcb\x0b\x9e@\x7f\x8b\xd1\xe0\x8f\xc6k\x1a\xe5\x9a`D\x94\x83g]r\x0e\xff\xa3\x99\xb7|\xea\xfcY}\xcdVq\x92wRC*\xd4\x13\x8e9[o\xbb\xff\xa9\x07\xe7\xa7\xd7\xce\x9d\xdcd\xf0X\x0c6\x8e\x17\x9a&\xcd=\xff\xe2\xcd}\x97\xed\xdf\xb0\xc0/*\xcd\x8f\\\x00\x04\xcb\x94)\xb3\x83\xc95gO\xf2\x98l\x9d\xd3\xa6\xaf\x08\xac\xd8}\xd9\xd91:>O\xfd\x8aY\xc7\x8f\xf2s(\x95p6\x1d\x9f\x82[\x12\x82\x9dB/t\xe7\x88\x81*\xcc\xa0-n:\x15\x11\xb1\x01\xbd\x0d<\xd0\xa6\xf0\x14\x8d\x08\xf8\xe8)\xc8\xfa\x10\x0b\xac\xe1+\x8f\xde\xb0~q_}\xfd\xe4\xc5\xeboxt\x0f>L\xae\xaf\xef\x83\x07V\x96\x0dF\xdf\xc8\xdfG\xbc@d\xce9\xd7\xc6[<\xf1s/\xbc\xed\xae\xdb.<7\xee\xb1\xf0\xd6s\xf3\xa7B\xb2\xc9\x14\x9ed\xef\x90B\x12'\xb7wX\x82\xfc\x9c\x8e\xb3\xce\xbf\xe4\xfc\xb3Z\xe9\xb5\xa3\xfc\xe1W\xb2\xc1\xd5\x97\xd9>2\xb2\xbd?\xed2\xc8\xb3\xaf\xb1\xf78\x9b\xe7\xac\x9e\xd5\xd3={\xf5\xecfg\x8fcsC\xb3\xdc\xe5\x9c\xd5m\xe3\xe5\xa0\x1c\x96\xdb\xcfr\xe2\xbe\x0e\x0f\xf5e\xa0\xbe#\x8c\x9b\x89\x02E>\x88\xf2\xfc45\xb5\x14\x12qo:\xe1J\xa3\x14\x16\xd6\x04\xec\xbcX\xab\xb0^io\xba\x93P,x\x8b\xb5f\xb5:/y\xa0\xf1\xbc\xafn9\xa7\x9dV\xf3\xd1\xa5S\xa77=\x10\xe9\xba\xf2\xee\xe8\x92u\x0f-\xed\\\xb8%\x02\x95K\xe5\xcf\xa6Uv\xb6\xce\x1b\xbc,\x19\xbb\xe2\xb3\x80\x84\xed\xc5\xeaZ=\x1c\xd6v\x9b\xfb\xe2k\xaf\xbf\xa4N\xd1*+_\xa7.\xfd\xda\x8a\x9f\xf5\xd6\x9e\xbbi\xfd\x9a\xda\x83=w\x0d@\xa5\xe6l\xa2\x15m\x98r\xf6\xf4>\xdb\x17\x9dO\xad\xc7\xcao,V\xd4\xb2\x92\xd7\xeb\xc9\x9dz\x0c&:'\xff4\xf0\xce5\xa8\xd3\x1a\x85!\xea\xd59\xe8pI 0@I[\xcdP\x1eU\"\"\xa9s\xd9\x1d\xeeInv\x87R\x17>\xf1A\xb8\x8e\x98\xc99t\xe6$\xe7\xa83/\xab\x9a\x7f\xb3|k\xa3\x108y\xb4i\xee\xac\x9d\x9aE\x0d\xfb\x93\xdf\xf8\xddc8\xf3\xc2E\xd7!Q\xe8\\\xdb\x82}\x0b%A\x9a\x81f4\xec\xa0s*\xaeA8\x8d\xa6\x1d\x82A\xb3\xd8\x04\xce\x80\x1d\xdc>D\xae\x90=5\x0euw\xb6\xd6\xf5\xc3\x1f\xbaj\xb3\xeanG\x0d\x00z\x05?2\x94Q\x0f\xaa/I=\xee\x98\xdbf\xfdH\xfd\xe8\x02\xf74\xc5n\xba\xe5\x16\x93]\x99\xe6\xbe\x80\x88\x1fYm\xf0\xaaG\"\xb3\xc92\xe4P\x1cE\xddH\x7f\x99\xcdf\xb9v\x14Zn\x9e\x07<\xc2\x9a\x02\x97PiA_\xd2q/\xb3\x8eP\x12\xc9D\xd5\xbf\xf0 \xe3\xa8$$\x8e\x1b\x1d~%Nyhr\xdcOdM\\\x91-\xfe\x8cm\x9f(\x88\xe4@\\\xb3\xba\x8f#\xbd\x84\x06\xd4\xea\xc6\xbc\x93\xd2N\xef\xe7J\x9fO\x1c\xd4\xe5\xe3>a+\xff \xb5uJ\x17\xa8\x04*(%\x81\xc2\xa2FP\x84J\xc4\x02W\x94\x08\x94\xa5\x8a\xa6\xbd\xf8\x96\xdf\xf0\x91,\x7f$)\x8f\xe7\xf7\x01)\x07\xe5\xff\x98\x1d\xfa\xb3\x92\xff\xea}\xd7\xff\x98\n\x0eB\\\xad\x96\xe0\xcf_\xbb\xef\xfa\xc7\x15\xfe\xbew\xa5V\xe9] 0\x86\xd1T\x13\xa5OC\xc3\x8aQ}\xe8\xbe\xeb5\xb1\xd0\xc2\xe2{H\x0fo*\xe4\x99\x15;;\x04\xf5\xe8\x91\x9e\xc9r\xc7\xa8\xe2\xea\x01\xf5M\xd4c\xe5\x075\xad\x14\xdc\xe3\xd14S\n: \xb4\xfdM\x8c\x8b\xee\xe6\x16\x9b7\x90(kY:\xeb\x01\xa9\xaa\xb8\x95z\xd2`\x88gp\x0d\x9bJ\x86st\xcb\x89\xfd\xb1v'\xb2\xa1\xa6e\xf0\xd2G^~\xe4\xd2\xc1\x96\x1a\x03i\xe7D\x9b\xbb1\x9a\x9a\x91\x8a6\xbadA \xd8@'N \x02\xf0\x8a\xe6\x15\xb1\xb3\xd6\xadN.\xd6\xf4?\xcef\xb2\xc2\x85\xdc1\x98\xf3b\x05\x1a\x95\x8ezJ\xfd\xa1\xb1D \xec\xa5V\n\x01o@7R@6\x8a<\xc0\xfe\x01%IF\xa9\xd80\xeamj=\x0d\x90[\x7f\x8e}N\x7f\x89\xe2\xd2\xfc\xdb\x8a\xa457\xb9\xff\x1bp\x05\xf2\x05\xa9y\x8c\xc4v4@\x1b<\x06m\xd0\xad\xe1\xbf\x11\xc1\x109T\xc5\xf2\x06p?\x8d\xda\x03R7\x1d\xfa\x9d\xfa\xa5\x01\x8a0\xd2\x9b\x9a\xb4\xdaQ\xcfG\xb8[j\x1a\x84\xac\xd0\x1e\xc8\xdf\xd9\xcdzi\xdf\xf7\xb7b\x93\xb4\xfa\x1b\x9d~\x83\xf0/)wC\x03?\xe2\xb1\xef \xd7\xa8a\xa5-\x07/\x8aC\x04\xaen\x93\x99\xfb.\xc4\x95\xdbH\x0cj63\xa8\x80\x92\xd0\x04\xb8\x8a\x10p\x04\xf8\x91\x93Krh\x12\x14\xeb\xcf\xcf\xc2\x07\xeeX\x96\xeaI\xe7\xc6\x8ej\xdf\n\xbf\x82o\xad\xe81\xc1\xc59\n\x9f\x06\x14\x01f\xd4\\\x8e~\xda:\x19-\xa6\xd4\xd1\x93K\xa0\x8f4\xa9\x1b\xb17B\x06Y\xcd\xf6\x89\xcc\x86\x8ey\x05\x7f\x08%\x9bDC~e\x93\xe8m\xc0\xde@\xd1]\xd1\x08\xfa\x03\xff%\xc0r\xfe\xa9\x02\xd6\xd9s4T\x03\xae \x99\xc5\x1f\xe2\xae\xd0\xf3\xd6G-\xe2Ug\x90\xf5>\xcf\xed\xfbH\x82Op\x07V\xd6B\xec\x90\xc2]\xf4{9&\xff^6\xb9\x1f|\xd0m\x92\xf5\x07\xe5\x0b_PLLI7\x02\xc7\x92\xa6i\xca\x10\xae\x13\xf5\xe9\x0c\"'T \x14\x05}\xc6\xe3\xef? 4\xbb\xf3\x17\xb9\x9b\x85\x03|\x87\xa6[F\xc7\xad\xfat\x16u/\xd9_y;Z\x94\xbc?\xdb\x1f\xa3H\x86K\xae0W\x9dz\xa4\xe8c#\xa4\xd9\xd9\xd0)\x80\x8e~.\x1cr\xc1\x8a\x16\xc4\xa5+\xcaB\x89\xb0\x8a\x03\xb1\x1e&J\xb0\x93\x83G\xa00\xf9\xcb[\xfd\xd0\xe4\xd9\xfc\x05\x91.\xce\xa1\x08\xecr\xb7\x9fO\xb3\x16k\x8e\xdd;VC\x95\x89\xa0oX\xa8 \xfa\x19\xcd\xf6K\x19\xdb\x9dS\xdf\xb3\x1b\xeb\x15r\xb6t\x82\xe5\xed\xb2\xed\x84:z\x82X\\\xb1\xfaxm\x8b\xdbJh\xff\x99\x0fx\xb8\x14\xf0\xd0N\xf7\xc7h\xdb5\x10\xaf\x0b\xa5K\xe8`\x85\x0f\x05;yd\x03p.Ec\x9b4\xb2X\x9eD<-\x01\xb4ll\xb5\xdbip.\xbb^\x1e\xd8\xe2p\xd5\xd7:\x8d\x0d\xd9u\x8f/\xee\xbb\xf6\xfc\x15\x99.\xab\xc5Y[\xefrl\x19\x90\xaf_\xe64\xb8\x9a\xe3\xbd\xc9\x1ekz\xce$~Dq\x85]7/T_<\xe8\x8f\xb5\x88\xbc\xa5\xde\xe34K\x0e\xa7$\xf0\xc6\x96\x98\xff \x99\xbb\xf0&w\x93\xab\xf6\xe4\xb7\x0d\x86\x9e\xa9S\xa1\x1f\xb8\x197\xff\x08\xff\x08\xb5|K\x8b^\xfc\x8d\x8a\xf8\x9b\x8e\xe2\xaf7\xedMsMG\x17\xfd\xe1\xf9\xe7\xff\xb0\xe8h\xc7\xc3\x0fw\x94\x85\xb9\xc3\xe3\xa2\xb40]?\xb2\xb4\x0f\x04\x98\x0efja\xcd\x145a\x04\x8ei\x8d\x96\xd0\xa6\xe8\x016C\xbc2\xf4no\xc2\x95\x0c\xa4\x93\xd5f\xa0\xec=\xf1\x96)\xf5d^\xcb\x14\xff\xfb\xf6v\xef qNc\xe3\xd4\x8e\xb4\xfb\xfe\x8bl=u\xd9\xe1\xec]?;\xa1f\xe2\xf9-E\xd5\x02~\xe4\xec\xf6\xe1\x1b\xcfn\xcfv\xf8\xd5}5\x81\xb8\xcf\xd7\x1c%\xbb\x9a\xeb\xbe\xf7\xfd\xfa\x96\xec\xe8O\xd5\xbb\xb3d\xeb\x8d\xbf=\x84Z\x02%\x01v\xb9\x8e\xe8 \xd3\x04\xb3\xd0\x14\x0dn\xafK\x97\xa0\x14u \xd0\xcc\x93*J\xa6\x84\xea\x9d#1\xe4h\x84u1\x1aHr\xec\xd0 o\xbb\xfd}\xff\x94\x16\xf5\x1b\xf5SZ\xe2u=\xb6\x8b\xeew\xa7;\xa6n\xcf\x97\x14U\xd8\x0b\xef\x82\x1a\xc4\xe3\xe4\x95\x13\xfc`\xa0F\xdd\xe7\xef\xc8\xb6\x9f\xbdE\x1cn?\xbb\xa5\xfe\xfb\xdf\xabk&\xbb\xa2\xcd\xd9l9\xa0Y\xf5\xee\x9f\x8e\x1e\xfa\xed\x8dd\xab\x86gA\xe2\x17\xc38NS\x0fG\xe1\x14\xea\xb3\xcaD\x9f09M\x91\x15AK{\x1d\xde\x80K3\xdd\x8a\x84\x02\xad\x1c\xaa\x10\x00[_]\x05\x92%W4z\xd6\xdb\x88u9\xe9\\~\xe5\xfa\xe5\xebn3\xd4\xc9\xea~\xf1\xc9zir\x96\x84\xf1\xe9\x0d\xc5\xe5\xf4\xa8\x93X3k\xe2`Ps\xc4\xea\xf8\xdc\xca\xfc\xe2\x92n\xc7\xe5\xef\xda=\x1bm\x11\xf9\xba\xc1]\x8b\xd4\x83J\xcb\x1e\x1bks\x84\xcd\xf3T\xd39d\x99\xd2\x02\xf5eYN`}\x9e\xaf/\xfb]U#\x14\xc6\xf3b\x98;R\xcc\x1c\xa8\x93\xd0\xc0\x17t,\xa2\xdal\x9f\x08h*\xf6\xa2\xd7#JB+\x1b\n(\xb4\xa1\x02iGx\\}~I\xd6\xb3F\xb7\xddv@T\xf7\xcbu\x86\xdb\xd6\xad\xb8\xeaJ\xa8\xda\n\x0b\xb1\xad\xf7\xcc\xff\x9c\xc3\n\x90@-L\x9c\x99\xa8\xe1w\xe4z\xc3\x0e\x12Y\xa7\xeeg\x97\x94\xfa\xd3\xe2w\x89`wx-\xf9\xbf\xd8\xf6\xb4(d\xd9\xa2]\x83\xd7\xc9\x11\xdbF\xcf3_\xf7\xf8X\x81cY\x92mQ\xd4\x83\xe7\x90\x0f\xdf\x1bW\x1f\xe6b\xa4-\x04\xa9\xd0F\x0c\x0e\x02\xa1\x81\x14\xea\x04K\x18\xf55\xd5\x08d-0b\x11\x83\xe2\xa8\xe7\x90\x83\x04\xc2\x97\xd6\xa8\x93T+\xe6\x91_\xefZ\x84x\xdcc\xcb\xff\x05\xd0j*`\xfb\xfb\xe5\x88}\x8f|x\x0e\xe2~\xb8L\xc7F\x90*\xdaS*o\xea\x9fM\xd8\xaa\xeaA\xad\xcd\xf3\x96\xb2\xfd\x1c\xeeT\x9e1p\xc7\x047\xb51?\x8bR\x0ct>\x0f\xe9\xf3\xbb\xb6R'\x1d\"\xfa\x90\x8b\xc0\xe4\xc6\x17\x14\xc1E\xc2y\xd3)o\x83P\x8f\x067\x9e\x94\xe6\x82\xc5\x11%\xab\xcb\xc0$r\x11\xc3v\x1d\xf5\xac\x0dQ\x9f\xbf\xfb\xbdeE\x94\xc7\xe3\xd8\x16\xe7\x94+\x06\x8d\xbd\xbbn\xf9zl\xdd\xe5Vl\xddFr\x05kt\xc9\xd6'\xb5\xa6'?R\x0f\xae\x84\x06'Z\x83CE\xd5I\x1e\xa7Ky\x03\xbb\x05 ga\xce\xf60\x1e\xfe\x8b\xfc\x17\xa1^\xe1\xea}\xa0p\x04E;\x85\xf5Kq{\xd2\xe1T/\xf9?\xefi\"%\xed\xc6\xde1\xce\xde\x92\xffb\xf1-\xde\xd4\xbeq\xc6\x9b\xcc\x19\xcb\xb5\x11\x83\xdb+ \xa2\x8a8\xc6]\xc0\xcarI\xb8\xdc\xfa\x94\xda\xa3V\x95{\xacd\xc8\xaa\x17\xcd\x9c\xb9\\\xe8\x95A\xcd\xf4\xd3Q\xd0vO\xc4S\xd5\xf5]0.\xdb\xea\xfaN\x03\xa8\xec\x15X9s\xb9\x02\xd5v\xa1b?O\x1cE~\xdaFPU}\x1f\x1co\x9e[Y\xeeK\x13\x19\xe5r\xc0\xe9\xd6\xf0\x0f\xf1\x0fA\xb9\xc3\xcc\x93U%\x87\x81\xa77D\x80w\x17\x0d\x1e\xfd\xea\xf6\x88q\xd4\x0bb\xe1/\xed\x91h\xc8\x0d\xed\xe1A\xd9\x14\x1a\xb1\x91hPbQ\xd8\x93JB8\xd5I\x0c\xba\xe4\x07?\xe1\x1aI\x06%=\x04\xc5X\x91t\xdc\x13O\xa5;\xb9(P\x1d\x91h\x03\xbaL\xecd\xa3\x06\xd1\x0dS\x01\x04 \x95'\x0eh\xff\xdd\xb1\x9f>|\xfe\xf9\x0f\xffT\xbb\x91\xac\xdcV?\xd9,O\x95\xdd\x03\x1c\xe7\"\\\x8f`\xaa7\x04\x89\xd5\xe3\x13\xed\xc1.\x8b2\xd0\xe7\x17\xdd>\xce\xe6\x0e\xb9D\xe1\xb2\xcd\x0d\x81f\xce\xd6m\x95g;\x9c\x9d-\xed\xf6\x84\xcc\x13C\x8c'\x9c\xa5\xd6\xe9u\xb9,\x06\xbb\xa1\xa5\xce z\x14\x97A`-\x02\xc7\xd9\xbc\xbc\xc1$\xd6x\x0cvc\x93\xc3k2\xb7\x06\xa6[x\x96p\\c\xdab\x15\xfc\xed\x93l\xce\x80\xddi\x1ch\xb5s\xb5\x9c\xd9iv\xf0\x0f\x15a\xc3\x9b\xc3\xea\x10M,g\x10\xc4\xa8l\xf1\x8a\xc1M\x9e\xe0\x96z\xd3\xdc\x1a\xb3\x9b7Jv\xde\xd4\xd9\xc0\xcb\x91V\x87RW\xcf\x8bN\xb3\x95\xdd\xe4o\xce4\x19\x89(\xda-\x84\xb5XB^\xd2Cl&Vn\xf4\xb1n\x9f\xbf\xbe\xc1n D4[k\x1c6\x9e\xb3\x86\x9b\xecN\x8f\xd7&\xb5\xba}f\xa7\x933Y\xbcQw\xd0@$\x93U$(\xc7\xaao\xb6:-\xfcZG\xbc\x85#&\x8b\xc5\x12\x86/\x1d\x85}\x0b\x96?\xc4\xdfN}\xc6\xa5\xbc\x827\xedA!M\xb4\xe0\xfc\x04\x08h\xf6\xf8W>\xa3\xe6\xef?iX\xb2p\xca\x1d\xfd\xf9\x03r\x9b\xbcA\x96\xd9\xa1\xe0b\xfe\xf6\xf3?u\xcf\xb1\x9b\xce\xb9\xb3-h\xf1\xe4\x0f\xd8\xed\xeb\xe56;\xbb\xeaS\xffB\xf5#/\x82\xb5\xe9@\xd1\xbf\x13J \xc6\xe9\xfe\n!%Q\xad\x08)\x04\x94\xc0Dq:{JI^\xde\x91\xcb\xa1\xf5PY\x04\x1a7UG\x01\xe7\xca\x1f(\x11\xc2\xc0\xbc\x9f\xf6\xa1h\xb3?Hm\xff\x1d\x1a\xac\x1a\x04\xc8\xd1\x8a\x0e\x12\x18\xe6vRE\x88\xedH\x8e\xf4\xe7\xd4=\xdcN`P)Q\x9c\x9f\xa5\x8e\xe6\x80G9\xae\xd3F\x1aM\x87\xd6S\xe1\x02MG\xa7\xf5@2\xa4\x04\x1cE\x1f\x11\x89$Q\n\xb5$\xc7s\xb1~\xe4\x92TkN\xb5\"\xd7\x03\x1c\x0e9\xae\xd5\x86\x1f\x018\xfbc\xeaF\xa4\xf1\x01^\xea\x10\"?+G\xd9\xa0\n^\x02\xf7*\xa6\x17\xbcgUlFVx\x8d\xaa\xdaU\x99poC\xa8\xb0\x9e.XC\xc6\xb5\x8d\x8a\xd7\xb5\xcd\x89\xd7q\xef\x82K\xea[\x1b\xafk[\x1b\xaf\xe3\xf6K\x97\x1e(l\x81\xc0;\xf6\x0d\xba\xd3\xa1\xedn\xe8\x19\x00%^\xf1\x9dR\xd4j\xad,$\x1f)\x16\xa7\x14 \xf8\xb7\xca\xec1\x8b\x82n.\xbf\x8f\xdfG\xf7:C\xd0\xeff\x8e\xd3\x16(\xdf\xf1,\x98\xed\xd0;\x9a\x84\x17\xc4\xb4\xa9\x01\xf4R\xc2\x97\xbfF\xeb\x9e_~\xf0\xce\xe3\x17^\xf8\xf8;\x1f\xbc\xf3\xa5\xd5\xab\xbfD\xbe\x7f\xf4;\x1b6|\x07/jGGSSG\x13\x19\x84\x9bG\x92\xd3\x8e\xc4\xbcD\xac\xf1zbR\xef\xa4/X?\xbd\xf1\xfb\x8a\x1f\xc3\xed\xf1U\xda\xc7p14u\x04\x02\x98$`\xbe\xdf[\xdf\x9cH47\xf5\x087\x11I\xf2~\xa5\x89~I\xff\x18r\xea\xdf\x99s\xf9\x17\xf9#\xe8\x9f6\x8c\xdb+\x91h\x84\xba\x15e\x80W\xf26@wK\x93\x14\xcc\xb8h6,\x12 \x871C\xb5\"\xe0\x9d\x17\x87\xb7\xe6\xa9\x16\xda=\xadm\xce\xe8\xf1\x90\x14e\xb0A\xf2\xd3\xf3\x8c\xe2\x96\x0b=\xbe\xe0\xf4\xee\x81@\x93z\x97\xdc\xd0\xd0\xe1\xb2 \xa6s\xd2\xf3\x13ls\xb3]\xf4;kkl\xb5\xea\xd3r\xac^\"s\x83\xa1\xe9\x9d\x92\xdc>\xd5&\xd5\x84\xac-[\xd7\xdf{\xc5Ji\xd2\xb49[\x82\xdd\xb5\xb3\xc8\xa9\xb9-\xe7]\xb1d\xde\xa2\xb5\xb2c\xd2\x0c\xb5An\xb5\xdb\xb9\x83\xe4g\xe7}\xea\x92\x87\x1d\xbc\xbb6\x1ehT\xef\x96\xeb\xfc\xc9\x96\xb4?3\x03s\x8f\xda\xdd^k\xad\xfa\x8cL\xeac\x12Y\x18\x0c\x05\x881\x1d\xebZ\x13\xb2\xb4n[\x7f\xf7\xa5\x83b\xdd\xb4\xbeE\xdf\x86\x8c\xe7\xd5\xa4\x03\xcdw\xac\xba\xe0k3\xd4f\x99\x95\xe5\x88>\x86\x0b\xfe\xfffM\xe4\x01\x10\xd5D\x82\xe8\x85\xd5\xa0\xb8a\xe5\xf1\x14D\xf0\xe9\x0c\x8f~}&\xf6\x0f\x08\xac\xc1@\xbc\xa35\x10\x8du\x0c\x04gn\xa8\x9b\x1eO\xc8\xa2<\xb9\xad'`\x0b&b\xd3\xac\xbc\xb1-6\xe0\xf7\xae;\x83\x1f\xc1\x0eX\xf7\"\x91d*\xb2a\xa1w\xd2\xfc\xde\x1eY\x94\xa6\xb4v\xd6\xd4t\xb7L\xb3\xf0\xa6X\xeb\xac\xd6\xb8k\xf1U\x00\x7f\xdf\xa9\x0f\xf8\xad\xfc\xb7a\xee\xe8\xd4=HR_\xc3@\x1d\xa6\xa3\xc4+j\x932\x97\xf6T*\x89\xc2\xa3\xe8%\xec\xd3/\xcd\xb8o\xc6\xa4\xa0\xbf\xb1\xd3y\xe1\x87\xea\x0d\xa3\x97\xbb\xee\x9b1\x83\xd49/7\x9b \xa0\xfe~\xc67\xe1\xfd\x8c\xb4\x1f_\x93\xdb\xf9o\xc3\xd3\xea\xd6+\x82\xfe$D\xfc\x1d\xd2\xafs\xde\x07IH\x9d:\xe7r\xa3 \x83\xf0 \xa4yiF:\xdd\xe5\xb8\xf0\xef\xe4v\x8d\xf7\xcb\x15\xfd\xc0(\x8c\xbfd\x13\xaeO\x1e\x19\":\x02\x0e\xa6\xa0om\xd8\xff\xc5\xecdM\x948\xe5\xd2\x0c;\xa4\x9eZ9u\xea\xca\xa9\xfcHCg\\\x19\x9bK\x05\x18/*\x89\x8e\xfd\xd4\x99\x8dg*\xbe-\xf3I\xe8\xd1\xf6\x97\xb1\xa2\x04\x88_\xc1E\xa2\x01\x9c\x8bRq\xee\x0eR'\xfb[\xa5f\xf5?G\xd5\x7fU\x8f\xbdA\x12o\x91vb A$\xffe\xf5]\xb9\xd5/\x87\xd4\xbf\xaa\xa3o\xa9?|\x83\xd4\x90\xdeQ\xe2m\x964\x99\x15G\xa2\x8c\x837\xf1G\x9983\x8d\xda3+\x0d\xbc7\x044\x87\x03z\x04*\x0f)\xa1$\xdd\x8bJ\xc0\xd8pD\xb5\xee\x93N\xfa\x08j\x195p\xd0q\x1c\x19\xbe\xb7\x93e\x8fDf/\x9d\xd2\xce>\xce\xdb\xfc\x89\xe8\xb4\xe0\x94%\xe9\x96\xc3\x0fg\x87W\xb5\xf8\xb8{\x85U\xf3\xeb:g,\xean\x8a\xaf\xb8l\xb2\xbf\xb5U\x91\\\x11\x9f\xcft\x99'\xd6\x13\xac\xf1%\xd2\xfc\xd1E\x82\xab}\xe0\xf2\x19\xcd\x9d\xedu\xa2\xfaC\x9b\xe8\xea\x98\x92\xcd\xdc\xbb\xdf\xbap\xb1}U\xcb\x15+\x17^b'\x8b\x8d\x92\xaf\xabo(5g\xe3\xbcV\xc3B\xd5I\x9c\xbc\xe4OE\xfcm>\xb7\xd1\xc0\xbd\xa9\xfe\x805y\x9azg\xf6\x86}\xfa\x1e\xc1\xa5\xdc\x03\xfcA\x94\xa9P-\xf8P/\xfa\x0f\x80\x11\x8f\xde\xab\x00\xec\x84\x12\xf2\xa0\xd56\xcc\x07)\x14\xa1x5/\x03t;1\x9a\x11p\x931\x94L\xa0\xba9\xf5A\xdc\xb3|\xf7\xea\xdd\xd1)\xfd\xb5\xe1\xe5\xeeX]m\x8d\x81\xfb\xf3kFE\xe9H\x05/\xf14}:\xb8,\x19oLM\xaao\xf2\xae\xbb6\x12]Y\xe3M\xf35\xa2\xcb\xea0u[\x9b\xdfy\xd2\xab\x88fV\xeah\xbe\x98?\xb8\xe4\xdeE-\x03A\xa7_i\xef\xab\x9d\xdf\xddj\x12\xb2\xf1\x1d\x0d\x19\xd4.\n6|\xde\xe55\x92`#\xcf\xd5Z-\xf7sv\xc1fq\x98\xd3\x9f\x9d\x9b\xed\xeas\xb7\xcd\x9a>\x18\x18\xa2\xe3\xdaw\xea\x14\xff\xa0\xee7C\x97\x11\x15\xe5{ A\x93\xfa\x85\x8a\xd2\xd6]\x15B\xbe\x1c\xeb\xd5\xeez,i\xf7H'd\xf9\x84\xe4\xe1v\xda?\x92`E\x87\x95\x9d\n\xfcx,\x87\xf6m\xb1\xb8z\x87`\xcdF[\xef\xea2a\xf5v\x89hp\x99\x0e%\x03(\xd4\xcc\x92\xf6\xfc\xbe\xca\x82\xc9\xfd\xd95\xd4\xa6;G\xda\xd1\x8e\x1bh\x94\xed\xa5\xb2\xb3\xb9\\\xdey\";|\"\xab\xd9\x9d\x16\xca\x96\xa9\x9drx\x82z\x16\xcbs\xe8P\x89HCT\xd7v\xa8P$\x85\xe9\xf5ly}\x87iyhvM\x8eC\xf9\x85r)\xdd#\xc3x\xae\x9b\x08\xbf\x04-\xdc\x13.(\xf3t%fu\xbb\xf4\xca\xc2\x80(\xdb\x85e\xc1\x95\x16UU\x96o\xe2\xb2\n\xa5p\xb4\xd4qe\x1d\xd1\xcb\xa1\xe5\x95\x97\xa5\x15s\xf2y\xb8i\xba X\x96\xe6k\xa5`\xc9>\x1e\xa3X\xaf@2P\xf8\xaf.\x0d\xa82\xcd\x8c>\xabn\x84|\x91\xca,/4\x97\xa3\xd4\x1a\xfe}\xc2\xf2\xa0\x0c\xae\xf0?A\xed\xb8&\xcdJ\x9f\x16\x86\xc5\xe6r\xa7+\x8f\xad\xf0\xc3\xc9\x90\x8f\xf1\x1dCV\x93]{\x8e\xe8\x16\x17\xecZ\xcd0\x00- \xfa\xf9A=\x96\x1a\x08\xe4\nF\x03\xf8\xae$\xeb+\x94\xd3\xf6\xf1%U\xb8\x15Z\x8dy\xa2\xad\xc2\xde\x97\x8e\xb0\xd9\xb2R\xd5\x0d\x05\xb7B\x83\xba)\x03\x14\xbf\xf7\xa5\x8a\xe2wT8\x16\xfa\x1f\xc1\x12(\xe1\x1fa\xd9\xfbR\xc1\xce\xa3\x1c\x03*-\xc0\xaa\x97\xc6\x0f\x1e\xd9s\x1a\x80r5v\x0d\xea\xff!^tZ:\x15/\xc7K\x15,'\xb1\xc2\xeaF\x0d\x1e\x0d9\x80\xbb=\xe3\xda\xe6G\x88<\x00\xa7\xb8\x07C\xed\xd1\x1au\x1b\x93\"$\xba-\xbe\xee\xb2F\xf7\xf3S2\xe7(\xf3\x17\xc9F\n0Q\xa9\xdc+X\x90\x9a\x81\xf0w\xc8,\xbb]=b\xf7h[q\x9eB\x8bQI\x92\x06\x0c\x0d\xfe\xa7\xfa;)\"\xc1\xc5\x8c\x9a\xd39\xdc\xd22\xe3\x9a\xf46\xc3r?\xe7\x1f\xd3}l\x8a\x06V\x0c\xc7=b\x10\xb8[\x98\xb5\xa3\x11j\xaf\x1e\x08\xa24\x80Az\x94\xf3\x99\x8c\x1c\xf7\x10K\xdak\x1c\x12Q?T\xff\xc2[%\x93\xc9$\xb0K\xa2Q\xf5-\xaf\xd1l_@l/ &;\xff\x98\xc9\xec\xb0\xa8\xcbD\x12r\xaa?P_\x13d\xa3E1\xfd~\xfdz\x97\xe2^I\xba~b\xb0\x17\xf7\xa7\xd4r\xdc\xe8\xbce\xa1u\x8a\xbcf\xb9\xadP\x95/\xcd\xd5\xba#\xdc\x0cE\xff+\x9aS\\\xecG\x7f\x1e\x87\x1c\x1d-\xd8R4\xa8\x8d\xab \x91S\xae\xf3\xd6S\xae\xf3V\xe4\xbf\x91;\x0b\x9d\xce\xc8*\x11`\xdfG\xb8\x14\xe9*5'\xc7\xe4\xfbd\x99L\xba\n\x98\xaf\xff~\xa4\xda\xc6\xea \xe0\x855\xaf\x94F\x9a\x18\xd2\xc6hb`\xa0\n\xbd\xea\x81\x9c\xfa\xb3\xc24\x80\xfd[b$~\x0f\xbfG\xe7\xa3N\xcfA\x15X$\xf2\xdb\xf7\xdf~\xf4\x82\x0b\x1e}[\xbb\x91W\xdf}\xe5\xea\xab_\xc1\x8bz\xc3\x976m\xfa\xd2&~O\xf1%\xde\xe6j/\xe1r\xcd&|_\x1aS\x88\x8f\xc6\xd2y\x13\xe3<\xe7\x15\x9d-\xe2*L\xcf\x9b\xf8\xab\xdb,\xa9\xb7JQ\x9bz\xbb\xcd\xa4\x9c\xf0\xab\xb7\xa3\xd9\xc2\xc9\xe7\xd1|\x92V|\x8fGVW\x02~\xf6\xcb\x1e\xcdz \xb7\xfd\x0b\xea\x14\xa8\n\xe0H\xa0\xaf\x1f\x9c\x11\x86\xf3\xb3\xa8E\xc9 \xa4\xba\xb2Y\xee\x18n\x91\xa2\xe7H4\xfbr7P?99\xad\x1f\xce\xe6\xdf\xa1|O-\xb5\xb7\x145\xb3\x8a \xb2%\xe34\xb5 \x1a\xc7\xb3\xeaO/4\xf9L_Ps\xe5\x05\x92\x11T\xd4>\xbfLQ\x9b\xc4D(\xfa\x0b\x98\xda\xf4\xf9J8\xf2\xffF\x15\xb5\xcf+)jCb\n\x9bM\x10u\xd82Xc\x118$\xf1t\xb0}\x9c&\xa7@\x80\xabQr\xbc-\xda\xdc\xd6\xa4\xfe\xceU_o6\xc7\xd5\x1f\xcbq7\xf5P1\xea\x8e\xcb\xa4+\xce\xdb\x02\xber\x1fc6\xaaI\n\xeb\\ \xea(*v\x16\xb42\xbc\x814Uc(\x11A\xfc \xcc\xa39\xfa3\xf6\x8c\xe6]\xc7z\xf7\xd8\xfc\xbb\xad\x05\x0f;0'\xa1\x1b=\xe4\xdb\xd1\x01\x1d*,e5\xd56\xaa\xbbV\xd4a,\xccqh\xcc\x12*\xf4\xeb\xb2P@w\xc8\xac\xb0G\xb2\xb8/\xd3O\xd6j\xf7|\x1d\x12\xcc\x10F\x05Im\xc7 #Pz\x19\xeb\x1f;J\xa8w\x03\xca\x8e\x15}\x9e\xa0<\xa0\x91\xfa\x0b\x9f\xc0\x0f\x06z\x0cT\x12\x8e\x00\xfa\x07t\x04\x04\x87\x88~\xa3`\xc2\xc8\xb1GP%;?\x0b\xae5(\xde(\x08u\xa8\x94#\x0b\x94\xc7\xc8v\xd5\x8aI\xc8\xf1\xed#9,?G\x9d\xf9\xa1\xacb4K]\xfdQg\xd4\x9f\x18\x0e]\xd2E[\xe0\x0cph\xca\xaf\xa7\x87\x02\xdbG\x17\x9b\x14\xa1\xe0+`\xa0\xdc\xc4\xc4\x98p\xa0?\xc5@\xe1>!\x0e\x10\x03\xda}\"\x14\x14\n\xcd\xd2\xbd\xb8\xcar=\xd4C\xc0D5\xef 62\xbe\xa6ZY\xea\xe8\x04\xe5\x00\x05\x00?\x13\xe0\xd7\x0b\xb3\xd6i\xf0\xcbA\x8d\xa8\x8b\nT\x13(\xf8E\x0bU\x95Ju\x1a\xb3;\"}\xa9\xd8\x0e\xd5\xba#\x96\xea\x8bL\x88c\xa8\xe4\xca\xe9\xd3\x97\xa3V\xe4\xf2\xe9\xd3W\xfeO\xfb\x9b&\xd9CI\xd4\x99\xfa\xdb\xc7u8*\xe7\x83\x9eQ\xe6\xe7\x07a\xf0Q^*z\x1a(\xa8\x7fL\xad|J\xd3\x8f\x87\x01\xbd^\x8ef\xa9p1\xbf\x0f\xfb\xf5\x840\xc04~\x9c\x02\x90C\x88\xb3Ux\xa8\x07\xce*r\x9aV\x07\xb2*\x8dN9\xcf\x80\x84\xd7\xb3\xaf\x17P\xf0\xfa\x84\xc5\xab\x1bs\xf1\xdcp\xb6\x88\x01\x9c_L\x8c\x89\x7f\x8a\x7f\x8a\xf2\xcd\xe13\xd9Z\"}\x13\x88&\xd3\x01r\xf4O\xbf|l\xf5\xea\xc7~\xa9\xdd\xc8k\xbfC\xbe\x18/Wj><\x11\xcb\xfcS\xc5\x04x\x1b\xd4\x12\xc0\xe5M\xeabS\x93\xaf\x96\x97\x8d\x1a\xfag(]\x11\xbdJ(Z\x12#\x9f\x1e\x86x\x16\xa9\\$\x18O\x0fC6\x0e\xbf8-\xe0f:{\xea\x83S\x8f\xd2\xb3\xe8\x9a\xa8o\x16\xfd4:\x9c\xd3\xcb\xdc)\x17\x8e\xa5\xcb\x10Wb\xbc\"u\xc5iu\xb7h\x8e\x8e~\xbdd\xe3\xca\xe9\xec%\xfb\xaf\x1f\xaf\xd5B\x8f\xb1\xfb\xf3AM\ns\xcd\xe2\xd9WH.gv\xff%\xf9\xe74\xfd\x96\xe3v\xf8+\xb8\x9c\xa7\xf0=\xc2\xbf\n\xf0\xd5S\xeaG\x87\xcf\x8bjWH\x7fW\xc0\xe6\x1d\xe7u>\x85\x96\x7f\x7f[\xffB{[\xe7u\xfb\xc9\xb6s\xd5;la\x9bz\x9bi\xf1\xd5\x08\xddW\xdf\xad\xd4\\z\xbd\xc6\xe5C\xf0\xe4\x83\xdb\xd6|\xa5\x9e\\f\xb7\xab\x9f\xd7\x00te\xbf\xba&\xff\xb9\xdf\x95+B\xfdk\x8d\xab\xe8/t\x90\xbf\n\xcf\x1c\x0bC\x0fM\x90\x84 /@\x12S\xc3>Tm\n\xb1G`v\xfa`?\xfe\x8d\xaa\xa3\xf4\xfe\x01\xd9\x15G\xc6\x12(\xd9,zb\"\x0b\xd5\xe7\xf0e\xb6\xb8\xfcA\xde\xd7A\xdei\xe0\xff\xbb\xb4\x9a7\xd0\xd3\x0e\xe9Q\x81\xc1\xa8R<\xc6\"i\xa0X\xa0\xb6:\xb8I\xdc\x8b(a\x87V\x7f\xbe\xf6\x9c\x1b\xfa\xe3\xa6\xcb\xe7\xa7;4\x07R\x1d\xe9\xf9\x97\xf3]}\x97\xcf\x17\x9c\xec^\xfe\xe1\xab\xcf1\xdcv\xee\xd4\xb5\x8d\xfe\xda\xf9\x977\x9c\xd4\xca=\xd9p\xf9|\xa7[\x19J\xce\xbf\x9ce\xed\xc2\xb5{)\xad\x17e\xdc\xfc\xdd\xfc#\x8c\x83ief0\xf3\x99K\xf0\x14J\xe2q\xb2\"*\xf6F#\xac\x13(\xa9\xb8G\x08jJF\x8dh\x01\x8c\xb8\x87X\xe8#\xd1\x88\xb7\xe2\x05\xb5\x90\xa3\xf1\x1e\xdd\x8dk\x9a\xbe\x97\x085E\xd4R\xa4P\xcd\xce\x8b\x1b\xe3\x86 ^p\x1f\xa0C\xa9eo\xff\xea\xede\x85\x80:\x95\xe7\xaf{6\xc8\xdb\xac\xcd\x1c\xef5\xd4\xcd\x9ds\x91\xc5\xc6\x998\x8bX\xcf\x0bK6\xd7\xf0V[\x90\xe7=\x06\xe7\xd9}V+\x8d\xffh\xcd\xa7\xd7\xc0\xdfJ\x8c\x9bl\xd1\xe2\x8cZZ\x9b5\xc8\xdfW\x91\x89\xb1\x94;\x14\xae\xfeT\xfd\xe9\x86e\xabV-\xdb@\xdaH\x1b\x86\xeaI\xf0\xd9\xeb\xac\x1e\xceD<\x17\xcd\x99[\xc7)\xd6\x90\xcd\xc0\xdf\xcf\xd6l^b\xc3Xe\xf2\xd9NN\xb1\x84\xac\"\x7f\x02K]\xa3@\x8c\x83\xd7b\x8a\xa9\x9a\xcb?.\xe6H\xf7H\ngzXa\xc6\xf0\xd0\xd9\x92A\xee\x13\x88}MO\x05\xa6e\x0e\xfdX\xc2\xfcH\xa7N\x81r\xa0\xd0\xf3\xda\x9fW\x0f\xa8;\xf1h\x10t\xf1\xbbgttO\xf6yu3=\x96\xc2\xfc*\xd7\xa4\xee\xcc\xe5\xd8\xbf\xa0C\x01\xa0\xc2FGsh9J\xee\xcd\xbdZ\xb0\x1b-\x94k\x82\x92]L-\xd5~\x0fh\xceii\xa1.\xea49\xcdQr5\xa6\xf1\xbdI,V\xdd\x93\xff\x85^jf\x0f\x94\xbb_}\xd4,\x93\xed\xacQ6?\xcc5\xe5\xffNV\xe7\x7f\xc1\xcf\xd5\n\xde\x9e\xcb\x8d\xaaY\xd9\x9cN\x9b\xe5%ez\xcb\xdcq\xc6\xa8\xef>\xc1Z\xe8\x0d\xa0\x93Nt\xf1\x8a\xd31\x9a \x00a\x0c\xd5%\x01\xfe\x9e=\xe8 y\xcfh\xde\x99\xab\xab\x0dH\xb8\xc1\x97\xcbJ\x81Z\xf6\x9a?\xfd h\xbdvr\x9ck\xca\xc1@\x1b\x1d\xe5\x1dm\xcdY`\xae^ins\xf0\xeaF\\\x94*\xf6\x08|L\x9cz!/?\xb7)\x14(\x930\x0b\xc9\xe2\n\x15MS4(\x9a\xc8\x97h\x1e\xf0\xd8{\xb2\xba\x99\x92\xe6\xf1-\xee'\xd7h\x8e\xe6\x89\xebo\xea7\xfbcC\x19\xd2\x9e\x19\xca?\x0f\x8b6\xb2\xe2\xf1\x92\xb2'|ub\x18\x88\xd5\xa3@\xb4\xfe\x8d\xcc!\xb3b\xfd\xc3\x99\xa1\xa1\xfc\xbb\xd0f{tz\xf8\x08\x851U\xd2A?=\x8c@\x9c\xe1\xe1 \x05\x19t%\x98\xe4\x95\x89\xc0\xcc\xe5\x00iu\x9a\x93[\x0dN\xf2\xc8i\xe1D\xc2\x0b\xb1\x88G\xddT@\x8a:\xcfp\x15<\xfc(\xf5c\xd3X\xe9\xc9\xc6Um\x02\x8d2\xda\xcf\xb17z\x9b\xdaO\xf2\xedM^\xf6F\xcf\xb4YUfwGs\xfc\xc1\x93#\x91t:\xc2/\x89\xaa\x83\x95\xb6\xce\xe5~\xb1Os\xde]\xb5\xc7F\xd7\xff\xcf\xe7\xdd\x91\xaf\x9e(\xfa\xfc(^\xc8\x17\x8b\xc1\xb1?L\x14\xfb\x8f$\xc0S\x04\xca\xbd\x85\x0cWzT>m\xec'\x7f_\x1a\xa7\x82\x1b\xfad\x8c\xae\xd0\xd4\xe7:\xa5\x0f\xc4\x005\xaeL\x04h\x7f;\x03\xafH7\xdcWgz\xeag\xc4Z\xc6\xc6Zb3\xea{2d5\x90Jj\xa6\xc49\xdec+\xe3\x1c\xf9\x91\\vqz\xe7\xb2Db\xd9\xce\xf4b\xa0\xa9\xc6\xb6\x8fg \xf9\"l\x02@\xd7\xa6\x9dp\xe6QB\xbdb\x00\xfd\xdbS Q\xed>\x11\x80\x05\x93+\x18d \x81p\xb2\x1a\xbe\xee%}\xafL!\x93\x9d\x1c\x99\x17\x13\x83\x87\xf2\xe7\x1e\x0e\x9acd\x1ewH\x03o\x98\xb8\xc6\xe6\x13\xd7p\x19\x80x(T\xec\xbep\xc4\xe8\x08x\xee\xbf\xdf\x13p\x18#\xea\x17\x00:dvQ\x0dq\x9f\x0edA\x1f\xf0QFd\xdcL\xb3\xa6K\xa4m\xd2PR\xcb\xed\x0d\xa4pU?\x03\xf2l\xc3\xeb\xd6\x0d\xaf\xfbzg\xb0-\xaa\x1e\x89\xb6\x85\xd4\x1fjP\xd9\xee\xa9b\xb7\xf9G\xd7aR\xf5\xbf\xfa&\x0f^q\xc5\xe0\xe4>u\xd38\xa4\x95p&\xc3\x1a\xd3\xae\xd1\x84\x0d\xa4`\x0f\xedMGS\x9f\x14\xae\xa1\xae\xf3\x12\x1b\x1e\xd9\x10\xdc\xb5ao\xb0\xf1\xe3\xa1\x13\xdcW\xdc\x9bZ\xb4a\xc3\xa2\xcc\xd9\x9f\xdd\xb0\xb7V5\x9f\x01\xcaR\xbfs2NX \xdbqGB \xa0\xbeO\xa0\x93\xcaK\xd2g\x02\x0c\xe9\xf4\xf0\xc0\xc0BW\xfe\xfd)Sg\\\xf5\xd9\xf9\xea\x9e\xd3\xa1l\xe4\xcb\xf7\xf6]z\xf6\xc0<\xdf\xb2o-_\xfe\xe5-\x0b\xf8\xb1\x9b\xc6A\xa3\x9fKMq\x16\xd3\xad!\x1a\xb4\xc3\xa6Si\xadgy\xf1\xfc\x01\xfd\xbf\xc4\xdb\xb0]K\xfb;S\xea\xc6T'\x90\xe3\xa9\xf3k\x0fPq\xc9\xe6e\xea\xc6e\x9b7c\x0fZT{~*\x1e\x877\x8bb\xea\\H\x85?\xf0j\x19\xd9\xb5l3\x95\x8fP\x1d\x0d\x9c\xef\xd0\xbew\x1c\xefT2\xb2\xf0j\x8aY\x01\x11;\xd6\x00)\xbal\x0dD\xcbueytO\x0fT\xf8\xef\x8f\xdaj\xc3\xb6\xa1\xfc\xf1U\xb6H\xad\xed\xa8\xfa\x1b\x9cX\xf6g\xc9\xac,\xf5\x8fW\xb4\x05\xc9\xcf\xa2^\x14\x8e\xda\xc2u\xb6\xa1![]\xd8v\x94F\xe8\xe7\x14\x94|\n\xe3\xaeQG\xe1\xach`(\xa8# \x83R\xbc'5X\xa9D\xa7\xcc\x07Q\xa0\x18\xcaqM\xcb6g\xfbc'b\xfd\xfau\xb3\x03\x05:'\x97\xf4\xff\x99\xaeH(\x0c\x84\x1b?\xb8y\x19\xd5\xb5\xa5\xfa\xb6\xcb6\xa3~.\xf2e\xa8\xac[n\x16 \xb8\x03\xaa\x8a\xff*\x7f\x80\xb1\x01U\xabyZs\xc3t\xa09\xef\x8b\x9b\xb8R\x7f!G\xd9\xfd\x8d\x8d\xb7\xa9\x8d\xf9\x93MM$\xdax\x8ez\x80\xac$]\xea\xd3{\xd0\xc3\x1dL<\xfc}\xf9\x15\x8d\xe74\xde\xc6\x1a\xe0JZ\x1a\xd5\xf5\xea~\xd2MV\x8c\xd5\x95hy\x16\xd7 >@u\x8d\xbb\xca\xed\x07\x0d\x9a\xe5\x85\xee\x13\x8d+\xb3\xbf\xc6\x03\xe8\xf4\xf5]\xe1\x03\xdf2FqO8j\xfc\x96\xd1\xa5\xb0WC\xff\xbbQq\xed\xcb\x1f\xa4\xebrw\xae\x8b.\xca\xec\x9d\xe4\x84\xab\xbe\xde\xa5\x1a\\\xf5\x9a_\xb4\xfa\xfc\xa7\xe3\xf4\x15\xf6y\x9a\xb6\\\x07\x19O\xbfn\xd4)I\xcdKGR\xa7\xeaH\xc5\x81q\x94\xb8\xdcI\xda\xd1\xc5\x06.\nd+\x10u@\xcf\xb4\x17\x1c\xf5\xd3\x08 \xea\xbek\x96\xd9\xc5\xa4}9\xa5\xeaT\xabv6\x1d\xf6*x\xa4g\xb6e\x057?\x97\x99\xc3\xac\xd4}\xf5S\xa7\x02\xe9\x14\xd5-\xf0\xa0\xed\x13A\x17U\x05\xdb\xfc\x01\x82\xed\x1f\x15\x0bO\x11MlJ\x0d\xd5p\xdb\x11\xed\xd5\xaa\xdd\xa7\xfc\xee\xd5\x05\x9fYw\x96\xd5\xe9h\x9ci6\xfb\\fA\xf6Zc,\xb7rjF\x9cT\x1f\xe5\x82\xd0Mj8kO\xeb\xab51\x8b\xfeT\xbb\xbc\xfdqW\xbd_\xd9n\xe9\xd8`\x17\x957\xae%\xb3K\xab\xe8\xdc\xe9W\xdcs\x96d0\x07\x9a\x82\xe1:\xbb\xd1`\xb4\xb6O\x1dX\x95\xde\x1e\xf9\x03\xd2\x1fs$\xe34\xbc?:\xffSI1\xa2\x00\xa2W-\xbePr}\xea\xc2\xb2\xa3\x8a\x0c\xa7\x1e9\xf5.\xd4\xfb&\xa0P\x9a\x99^f\n\xb3\x148(\xbaW\xa1I\xa2\xc3\x05\xdb`\x1c\xac\xa2`@5a}\x88z\xb5\xeai\xfeV \xbep\x84\x01\xb2P\xd4\xbd+:\x96\xa3\x12d\\j\xc3\"=\xfca\x80j\x15\xa3\x8a\xf0\xad\xe4)W\xa7\xd4$q\xf6{\xc7\xda\xd6\xcd\x9c\xd7p)\x97V\xfc\xf5\xae|\xa37hj\x9d\xac\x8e\x02\xcd\xf6\xe2\x12\x97\xb3\xf5\x0e\xbb\xa5\xc9\xe2$\xb7L\xeb\xe8\x98\xd6\xa1\xca\x0f9\x9b\x1a\\\xf6\xfa\x8e\xda\x81n[ \xb1\xa4k{lG\x8b\x89\xc4.m\x0c\x84m~\xc7T\x97\xc0\xbaE\x8b\x9d\xdb\xf9\xa1\xd1b\x8f\xc8\xad\xb6m\xb9`\n\xbb\x97\x12\x11w\xf2ny\xe6P&\x97\x19:P\xafLJ\xd8\xed\x96Y\x8e\xfa\x7f\xe9\xc0\x8c\xd5_\xeep\x99\x1dNW\xa8\x89\x13\x9e\x9bzV\xdb\xec\x16S\xd7\x83]7\xd6\x0f\xd5E\xdad\x93%i\x0f\xb8\xe7\x99\xac|\xf1\x0c\x03\xbe\x0f\xfa\xe8\xd9\xccE\xd4WM\xc1\x93\x99\x077r\xe2\x0d\xc0\xdeHB\xa8\xb4\xcb6\xfe`UG\xb9Z\x88\xe6\xce\x00\x0d\xf89\xa0N2l2\xdd\xdb\xc9\x85HY\x98\xbd\x1a(\x9a\xc5\x97\x11\xd2\xd4\xd9iw\x18\x9c\xbd\xdd\x93[\xfd\xde`\xaacZ\xa8\x96R;Yz=Tr\xd2vH\x8f\xfe9\x11\xebc.\x0b\xa1\xd6\xb2\xeaG\xe4\x8a\xd2\x13\xba6\xbb*p\xd5\xfc\xce\x85\x1d\x8d\x06\x03'\xbb[\xe2\x8b:\xfa/\x98\xd2\xaaX\xd8\x05\xa5\x9c\xb4CY\xd1\x85M\xf1\x98\xd6\x05t\xcc\xd0-'\xba]\xa3n,{@\xfc\xf0\x0c\x0bc\xf8\x19\x98Ob\xb8\xfe\x15\xe6\xfe\xc2I\x1f\xd1N\x16\x87.\x1f\x94x\x19\x17\xc1N\x81\x0b\xb9F9\xeb\xca\xeb\x9b\x9dN\xff\xadK\xf3\xdf[\xba\xa3\xdeX\xd3r=\xdb\xf4\xe9\x1bW\xcem\xf3\x1b\x0c\x8f\xb0\xdd\x8f\xb0\xc6\xa6\xd8Y+\x02\x8f\xbe\xca?s\xfdJ\xf5\xa2\xc4\xd7g\xccX\xb5u\xcbP\xfd\xb9\xaf%\xc8\x97V^\xbf\xdb\x1b\xe9\xe8\x08[\xad\x7f\xf9\x8b \xb7\xb7\xf4\x84\xd4W\x88\xa0\xaf\x7f;\xe9\xfaW\xe6\x0d\xb3x\x1ev\xb1i\xc8/\x87\xd7\x1eX\x1eS3\xb1\xe5\x07\xc8\xbc\x942\xac\xa4\x04\xf7\x01\xd4\xa9Z\xbe\xc1\xdb\x0cf\x03\xd72\x9d\xd4\xe5/y\xf2\xc9\xcf?\xf1\x04\xed\xbb\xe48\xf0\xaeM@\xd3Q\x0f\xd4\xce*\xcb\x84\xc2\xfd\xc8\xf6\xa1\xa1\xedC\xe4X\xf9\x8dk\x1a\xa2\xf7\xb2?M\x0fz\x17T\x00y?\xb1\xe0\xd5Z\xcb\xc3Yu\xd7\xb3)\xff\xe3\x07\xe9]\xcd\x95\xdf\xf41\x96-\xe3\x97\xfea\x8f\xff7j\xf4\x82~\x94\xcd\xc4\xe1\n.d\xe3\xc4\xe1\n\xbb\x18\x0d\x96\xc4'\xd3\x18\x1c\xb7\xbd\xb8\x9a\x1c\xa7\xba\x93V\xd4\xf8z\xa3tXK\x7f\xfe\xd92k\xcc\xb9d\x17?\xa2\xa7z\x82\x1c\xa7\xfaz\xa5\xb4\xd9\x02K\x8c\x16.\xba>,\xa1\xb8BZ\xa6\xbf`q\x84\x1e\x97'\xbak\x96H\xe8qy\xa2\xfb\xb0\xe6\xa45\x1e\xaf\xbej>a\xc7\xc5\x03\xc5\x05\\C\xd9\x7f\xd5#\xca\xe7H;#p\xc7\xf8\xbd\xd07l\xba4\xbf\x15}\x94\x03\x0b\xd6IR\xb87\x16\x8c\x84\x01\xb0\xde\x8a0\xa7\xfb\x9c\xf0$\xe2\xec=\xab\x06\x06V\xc1\xbf\xfa\xd1\xf6\x91\xed#\xec\x11\xb8\xe4_.\x06\xd1v\xaa\x85s\xf0{g\x1e>\x83\xc1h!\xad\xee\xdaA\xb7b\x0e\xb9\x13/p7\xbc\xd0\xee\x0e\x99=\xdcz\x97\xc1\xa9\xbemi\x94%\x97\xcd\x9f\x9a3)^O\x9aj\xbc<_\xe3U\x8f\xb6NY63dsIr\xa3\x99\xb48E\x97\x10j\xf1\x18\xac\xdf\xfd\xaeU\xf0\xb4\x84*\xcf\x14\x0d33\xcf|v\x0b\xbe\xe3\xe8;\xd4\xdbO\xc6\xe9\x1b\x0eB@\xf1\x9d\xf9,\x97\xfc,\x9f\xd1\\cwd}6k.\x9eu\xd8k\xccF\x1f9\xfe\xb1'\xcc\xe4\x9d2\xd06D]e\xb1\x91x\xdcG\xbeJ\x04\xb3K\x1e.\xd7\xbd}\x86\xf1S\xab\x7f\x86$\x83@\x0ct\x11\x12\"\x9a;2\x00\x1f\xc9\xa9\x00\xea\xb9*\xa4\x8e\x94\x8c\xdb4\xa7\x1e\xdc1_\x83\xe4\x11x\xf57\xb3\xd5Q\xa7bj\xb4X\x88\xa3\xa7\xdf9\x9b\x84\xa7\xda\x02Q\xf5\xbd;\xae#\xcf\x16\x8f{9\x86\xd4e\xbcI\n\x9a-\xec\x7f\xe5\xa5\x90br B<\xde\xd69\xf2dpz\x9c\xdcIV\xaa\xfb\xf3\xffQ:l\x84+\x1b\xebs\xe9i\x0c\xd5#=\x14\x14\xd1\xecT\xac\xf0\xac\x81\x07+R\x98\xd1(\xaa\xe2M\x14\xdeDC$\xe2\n\xb9\xca\x0f\x1da\xe7\xcc\xb1 \xeaO\x1dNg\xc4j1\x11\x07\x9e9\x98\xb6\x9b\xcd\x03\xc4\xdcgqXk\xe8\x19\x84}F\xab\xc5\xe8\xf0\xf9d\xa2\x1e\x15\xa4\xd7\xd6\xd2c\xb6\x8aG\x93,\xb5\xe6\xe5&\x97\xd3.\xd8\xe2\x98\x1a.^\xc9\xb7wwc\x8d\x83>\xc0E\xb4\x12_]3\xfb\x9eU\x15\x88\xb1|\x1e\xe3t{J\x06\xd5f\xaa\xe7\xaa\x82u_\xf9.\x17\xba\\\x81\xff\x1d\xba\xfe*\xea\xf6\xb2W\x95=\xcc\xc5}\xd4lN\xe7\xd5\x14\x8do+\x1d^\xae\xef\xdfV\xcc\xa3\x13\xee\xe9\x91 v\xd8P\xa3>~\x86\x82s\x08\x1a\xa2\xa6T\xb6j\x1dWz~_\xb6\xa4o\x87gS\xd0}-\xad\xfcD\xf1T\x1bd\x82\x0b\xdd-T\x0e\x17\xc0Aa\xc8\xeaYf\xb5\x02\xb2\x05\x98\x1e\xc73,PATcm\xb2\xda\x0d\xd5\xbc4g\xe3\xb8}\x82\x1b\xbd\x95m\xe0E\x1c$B\x8e\x84w\xa2\x9d\xc5\xaa8\xdc>\xab\xac9\x1a\x8f\x96\x18\xe4\x91\xec\xb8JW\xe2\x81\xa9\xb0O\xa5\xf5/9\xffP\xaaJC\xc9XA{,\x99@c,t\x0eE\x05J\xaf\x14\xcbT\xc8j\xbd\xbe9\xec\x00\x958Q\xca\xf1\x95\xd3\xf5\x08&\xa8\x7f \xe4H\x08\x9f\xa0\xfeP\xc1l~K%\x06\xc6\x9e\xf9\x071\x80\xbe\xd1\xbb\xb9\x0d\xfc-\xe8e\xc8D\x0cz\x1d\x13xN\x81\x9b\xbbXuz\x9d\x92\xdd.9\xbd\xe4}\x89M\xc2c\x9d\x0f&\x9c:\xaf\xea\x94Z5\xbf\xe3\xd3\x998\xb7\x13\xf8%\x0b\xd5\xb5\xd5\xbd\xf8\x03m\xb3\x98\xbc\xefom\xf5CB\xf6\x06\x08:\xd0\xe4\xd6\xe1\x87l\xb4\xef\x988\x99\xce\xdf\xc4\xed\xa4~\xf3\xcb\xdc\xa6\xa2E\xb2\x03\xbfj\x95T\xa7\xdf\xc1\xed\xa4YH\x98Y\xe1\xbbv\xf8n\x83V^IN]]\x08\xc2\x8e\xe5CXkg#\xc5s\x0bc\xc0S\xfb\x88B\x92\x1d$\x89\xc3\x9d=\x92\x1f$\x8f\xaak\xf8}cG\xb9&\xf6\xf7/\xa8\xdfz\xe7\xbb\xdf}\xe7\xe4\xbf\xe7\xca\xc6\x07\xb5_\xee\xd1v6\x14<\x81\x127\xb8\x13\xbd\x19\x01\xfd\x13\x18\xb4I\x1aVGG\x02\x99\x9d\x04\xfag*l\xf4\x9f\\RXS\xb2T\x8b\x8b\xae)\xd9\xc2\x9a\x02E\xee\xa4\xca%Y\xa0u\xf4\xf3\xc1~Q~>X\xa4\xb8\x88\x14\xcf\xd0\x85\xb1\x1a\xd6`9\xd3\x1aW\x82\x93k*\x87@_\xd5\x8a\x10pM\xb8\x03]0\xa6*\x83\x81%\xe3a\xc0\x933\x11X\xed\x8c\x81K\xb9M\xfc|\xf4{\x86\xa3F\xd4\x94\xbb\x83\xfa\x91\n\xec\xb7\xbed7[\xd5n\xf2\xa6\xd5l\xff\x92\xcd\xac\xc6D\x91\xfc\xdc\xcc\xcf\xf7@\xa4\xdam\xf5\x98\xc8\xcf\xf18\x8b\x9f\x9b\xb0\x0fe \xafc\xc5\xbc\xf4#\x07\x90gH\x9b\xd0\xc4d\x19d@~.\x8aj\xccl\xc3l\xc9\x9b\x90\x03\xe4eRcx\xeeE\xcc\xe4\x81(( \xcd\xed\x99K\x81\x9e\x99\xcfm\xc2\xbc\x18\xea\xefG\xebX\x94A7\x11\xbe\xd7S\xf5\x15\xb7\xb5\x1c@[\x01l\xda\xd7.%\x19\xc8\xeb\x18\xe6\x05\xd5\xa3n\x01MDs\x07\x88]n\x1d\x80_Q\x1f\xee\xb7\x95 \xda5\xc0i?z\xfb\xd4G\xfcT\xe8G\x023\x19\xb2\xa6T\x9d@e \xe8i\xb4\x81\xd7,\x88\x83\xb0r\x02\xb8\x9d\x1c\nO2<\xb0\xd0\xe8\x95\xe9\x18\xd2l+\xb3\xc0\xb0/\x16,\xc1\x96%\x89\xb9\xadm\xb2\xe0 \xbc\xd3\xdb\x9aX\xd8n\x9b|\x96E\x9a\x9b\xb6\xf7]\x98\x8e\x88\xa2l\x90\xc3\xad\x99\xf4\x9c\x9e\xc6\xcf[m<\x92|#\xb9z\xd7+\x845\x88\xa2 7&\x17\\5S\xf4-\x98{\xfe\xfc\x19\x0eA\x10E\xdf\x15\xd7^\xd9\x1c\x1a\xb8\xec\xact\x93K\xe4\x0c\xc2\xcb\xce\x1a\xad\xdf\xe7\x18\x05M\xf1\xa9^rq]\x82\xeeFm\xdeC%2\xfe\x84vJ\xd2\xf0)W-\xce}O\x17M\"`\xd59l\xb2+\xec=\x85%\"\xab\xe7\xeb\xa3\xf3\xadT\xf2\x98'8\xc2\x01zH3Q\xd2\x90\xdf\xfb\xd1\xa9\xf9Y\xecP~V\xb6\x91\xd8\xb2\xe8Ni\xec\xbc\xcd\xdc\x0b7\x8e\xd5\xf0\xc4\xdb\x9b\xbf \xeb\xce\xfe?w1\xea\xd7\x00x\xdac`d```d\xf2\xcd?\xcc\x12\x1f\xcfo\xf3\x95A\x9ee\x03P\x84\xe1BY\xf1t\x18\xfd?\xf0\xff\x1c\xd6;\xac\"@.\x07\x03\x13H\x14\x00c\x04\x0c\xe8x\xdac`d``\x15\xf9\xdf\n&\x03\xff]a\xbd\xc3\x00\x14A\x01\x8b\x01\x8a\x8f\x06_x\xda}S\xbdJ\x03A\x10\x9e\xd5S<\x91`\x11\x8c\xda\xd9\x18\x8b\xab\x04\x0b\x11\x04\x8b\x80\xda\xf9\x00\x16\xc2b)6\x16\xe2\x0b\x88\x8d>@D\xc8\x13\xc4\"\xe8\x03X\\o\x93\xa0\x0f!\x87\xad\x8e\xdf\xec\xce\xb9{\xc7\xe9,_\xbe\xd9o\xe7gg\x93\x98g\xda \x98\xb9#J\x86\x0eVYp>uC4\xd3&*\xd9<\x02=$\x8c\x15\x03\xec\x13\xf0\xbeg9\xd3\x1aW@.0\x9f\xa2q\x11\xea\xf2\x87\xfa- \xf5\xf1\xfc\xea\xf1\xdb;\xc6:p\x06t\"H\x8fU\xe5\x05e\xe8\xdc\x0f\xbe\x035\xe4\xd5\xe7\xfc\x0bVg(\xf7[A\xe3\x11x\xad9\xcf\xdd!\xd6\xde\xb4\xf7EM\x9f\x8f\xea\xdf\x97\xef\x154\xfeN\x86&\xd3\x9e\xd7\xf0wj\xb3t\xfe\x99\xb3\xd4\x9e\x14e\xcf\x83\xe8Lp\x8c>\xef\x8a\x87\x86w\x91\xef\x86\xf5>G\xe0\xd9pfz`\x13\xcd|\x08\xb4\x1b\xde\xe2\x04\xfc\x05^\xaaa\xd9\xc5\xbc\xf8>\xe4\x8c\xc7\xf0\xb6)\xc7o\xa9\x0bo\xa5\xb2\x82M\xdcg+R\x12\x8am\x1a\xb9Rq\xd1\xed,\xf7\xab\x8bRJ\xb9\xe0\x021\x97\xd4\xd5X\x89\x1bT\xaa\xe4N7t\x8b{I\x96E\x97\\\xeeF\x16\xff\x18\xeb8\xe3\x11U\x0d\xba\xc9\xcc\x1emb\xcd\xf9:f\x97N\xb1&\x92\xfd\x03j9\xccY\x00x\xdac``\xd0\x82\xc2M\x0c/\x18^0\xfa\xe1\x81K\x98\xd8\x98\x94\x98\xea\x98\xda\x98\xd60=avc\xcec\xeea>\xc2\xc2\xc1b\xc4\x92\xc4\xb2\x88\xe5\x0ek\x0c\xeb.\xb6\"\xb6/\xec\n\xecI\xec\xa78\xe48\x928\xf6q\x9aq\xb6pn\xe3\xbc\xc7\xa5\xc1\xe5\xc35\x85\xeb\x11\xb7\x01w\x17\xf7)\x1e\x0e\x9e\x08^-\xde8\xde\x0d|||\x19|[\xf85\xf8\x97\xf1?\x13\x10\x12\x08\x11\x98 \xb0JPK\xb0Lp\x9b\x10\x97\x90\x85P\x8d\xd0\x01a)\xe1\x12\xe1\x0b\"Z\"WDmDW\x88\x9e\x11c\x113\x13K\x10\xdb \xf6O\xcf~\x95\xfd/\x07\x0f\x87\x06\x87c\x8eL\x8euN\x12N+\x9c\xde9K8;9\x979/p>\xe5\"\xe0\x92\xe0\xb2\xce\xe5\x9bk\x94\xeb676\xb7\x12\xb7-n\xdf\xdc\xcd\xdc\xcb\xdc\xb7\xb9\x7f\xf3\x10\xf30\xf2\xf0\xf3\xc8\xf2h\xf38\xe3)\xe4i\xe1\x19\xe7\xd9\xe2\xb9\xca\x8b\xc9K\xcf+\x08\x00\x9fs\xaa9\x00\x00\x01\x00\x00\x01\x17\x00\xa7\x00\x11\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x01\x00\x00\x00@\x00.\x00\x00\x00\x00x\xda\xad\x92\xbdN\x02A\x10\xc7\xffw\xa0\x91h\x0c\x91\x84\xc2\xea\n\x0b\x1b/\x87\"\x82T\xc6D\xf1#J$\x8a\x96r\xf2qr|\xe8!'\x89O\xe13\xd8\xd8X\xf8\x08\x16F\x1f\xc1\xde\xa7\xb00\xfewY\x81 \x851\xdefg\x7f;73;3\xbb\x00\xc2x\x86\x06\xf1E0C\x19\x80\x16\x0cq=\xe7\xae\xcb\x1a\xe6q\xa3X\xc74\xee\x14\x07\xb0\x8bG\xc5A$\xf1\xa9x\x0c\xd7ZB\xf18\x12\xda\x83\xe2 D\xb5w\xc5!\xf2\x87\xe2I\xcc\xe9a\xc5S\xe4\xb8\xe2\x08\xf9X\xf1\x0b\xa2\xfaw\x0e\xaf\xb0\xf4\xdb.\xbf\x050\xab?\xf9\xbeo\x96\xddN\xb3\xe2\xd8\x8d\xbag\xda\x8d\x1a\xd6\xd1@\x13\x1d\\\xc2A\x19\x15\xb4`\xe0\x9es\x11\x16b\x88\x93\n\xfck`\x1b\xa7\xa8s\xdd\xa1}\x9b,\xec\xab0\xa9Y\x83\xcba\x0cD\xf0\xe4\xae\xc8\xb5\xc8\xb5MyF\xcbMv\xe1\x04Yd\xb0\xc5S\xf7\xb1\x87\x1c\xed2\x8c\xe5\xa2\xc4\xe90~\x99>\x07\xb4/\xe3\x8a\x1aqJ\x8c\x9e\x16G\ni\x1c\xf2\xf4<\xfd\xd2#c\xfd\x8c\xb40\x14\xeb\xb7\x19\x18C~G\xb2\x0e\x8f\xff\x1b\xb2\x07\x839ee\x0cKv\xab\xaf\xad\xd0\xb2\x05[\xda\xb7{\x1e&V(\xd3\xa81j\x951\x85M\x89Zqr\x81\x1d7\xb1,g\x12K\xdc\xa5\xfeX\xe5\xe8\x9b\x1a\xad\xf5\xe50\xe9\xed\xf2\x96\x9b\xcc\xdbQY{\xd4\n\xaa\xfd\x9bM\x9eY\x16\x98\xb9\xd0\xb6z=\xc9\xcb\xd7a\xb0:[jE\xdd\xa2\x9f \xac\xb2\x0bBZ\xecZ\xff=n\xf4\xfcs\xb8`\xcd\x0e+\x11o\xcd\xfd\x02\xd4\xcc\x8f\x8f\x00\x00x\xdam\xd5U\x94Sg\x18F\xe1\xec\x83\x17\xa7B\xdd]\xf3\xfd\xc99I\xea\x03$uw\xf7\x02-\x05J;m\xa9\xbb\xbbPwwwwwwww\x17\x98l\xee\x9a\xb5\xb2\xde\x95\x8b\xb3\xf3]<3)e\xa5\xae\xd7\xbf7\x97R\xe9\x7f^\x0c\x9d\xfc\xce\xe8V\xeaV\xea_\x1a@\xf7\xd2$z\xd0\x93^\xf4\xa6\x0f\xd3\xd0\x97~\xf4g\x00\x03\x19\xc4`\x860m\xe9[\xa6czf`(32\x1333\x0b\xb32\x1b\xb33\x07s2\x17s3\x0f\xf32\x1f\xf3\xb3\x00\x0b\xb2\x10\x0b\xb3\x08\x8b\xb2\x18\x8b\xb3\x04e\x82D\x85*9\x055\xea4X\x92\xa5X\x9aeX\x96\xe5X\x9e\x0e\x861\x9c\x114i\xb1\x02+\xb2\x12+\xb3\n\xab\xb2\x1a\xab\xb3\x06k\xb2\x16k\xb3\x0e\xeb\xb2\x1e\xeb\xb3\x01\x1b\xb2\x11\x1b\xb3 \x9b\xb2\x19\x9b\xb3\x05[\xb2\x15[\xb3\x0d\xdb\xb2\x1d\xdb3\x92Q\x8cf\x07vd\x0c;1\x96q\x8cgg&\xb0\x0b\xbb\xd2\xc9n\xec\xce\x1eLdO\xf6bo\xf6a_\xf6c\x7f\x0e\xe0@\x0e\xe2`\x0e\xe1P\x0e\xe3p\x8e\xe0H\x8e\xe2h\x8e\xe1X\x8e\xe3xN\xe0DN\xe2dNa\x12\xa7r\x1a\xa7s\x06gr\x16gs\x0e\xe7r\x1e\xe7s\x01\x17r\x11\x17s \x97r\x19\x97s\x05Wr\x15Ws\x0d\xd7r\x1d\xd7s\x037r\x137s\x0b\xb7r\x1b\xb7s\x07wr\x17ws\x0f\xf7r\x1f\xf7\xf3\x00\x0f\xf2\x10\x0f\xf3\x08\x8f\xf2\x18\x8f\xf3\x04O\xf2\x14O\xf3\x0c\xcf\xf2\x1c\xcf\xf3\x02/\xf2\x12/\xf3\n\xaf\xf2\x1a\xaf\xf3\x06o\xf2\x16o\xf3\x0e\xef\xf2\x1e\xef\xf3\x01\x1f\xf2\x11\x1f\xf3 \x9f\xf2\x19\x9f\xf3\x05_\xf2\x15_\xf3\x0d\xdf\xf2\x1d\xdf\xf3\x03?\xf2\x13?\xf3\x0b\xbf\xf2\x1b\xbf\xf3\x07\x7f\xf2\x17\x7f\xf3\x0f\xfff\xa5\x8c,\xcb\xbae\xdd\xb3\x1eY\xcf\xacW\xd6;\xeb\x93M\x93\xf5\xcd\xfae\xfd\xb3\x01\xd9\xc0lP68\x1b\xd2s\xe4\x98\x89\xe3GE{R\xaf\xce\xb1\xa3\xcb\xe5\x8e\xf2\x94M\xe5\xf2\xd4\x0d7\xb9\x15\xb7\xea\xe6n\xe1\xd6\xdc\xba\xdbp;\xda\x9bZ\xed\xcd[\xdd\x9b\x9d\x13\xc6\xb5?\x0c\x1b\xd1\xb5\x95\x18\xd6\xb5ykx\xd7\x16~y\xd1j?\\3V+wE\x9a\x1e\xd7\xf4\xb8\xa6\xc75=\xaa\xe9QM\x8fjzT\xd3\xa3\x9a\xe5(\xbbv\xc2N\xd8\x89\xaak/\xec\x85\xbd\xb0\x17\xf6\x92\xbdd/\xd9K\xf6\x92\xbdd/\xd9K\xf6\x92\xbdd\xafb\xafb\xafb\xafb\xafb\xafb\xafb\xafb\xafb\xafb\xafj\xafj\xafj\xafj\xafj\xafj\xafj\xafj\xafj\xafj/\xb7\x97\xdb\xcb\xed\xe5\xf6r{\xb9\xbd\xdc^n/\xb7\x97\xdb+\xec\x15v\n;\x85\x9d\xc2Na\xa7\xb0S\xd8)\xec\xd4\xec\xd4\xbc\xabf\xaff\xaff\xaff\xaff\xaff\xaff\xaff\xafn\xafn\xafn\xafn\xafn\xafn\xafn\xafn\xafn\xafn\xafa\xafa\xafa\xafa\xafa\xafa\xafa\xaf\xd1\xee\x85\xeeC\xf7\xa1\xfbh\xffQN\xde\xdc-\xdc\xa9\xcf\xd5\xdd\xf6\x1d\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xdd\x87\xeeC\xf7\xa1\xfb\xd0}\xe8>t\x1f\xba\x0f\xdd\x87\xeeC\xf7\xa1\xfb\xd0}\x14\xf6\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x0f\xfd\x87\xfeC\xff\xa1\xff\xd0\x7f\xe8?\xf4\x1f\xfa\x8f\xa9\xee\x1bv\x1a\xedNj\xffHM\xdep\x93[q\xabn\xee\x16\xae\xcf\xeb?\xe9?\xe9?\xe9?\xe9?\xe9?\xe9?\xe9>\xe9>\xe9=\xe9<\xe9<\xe9<\xe9<\xe9<\xe9:\xe9:\xe9:\xe9:\xe9:\xe9:\xe9:U\xa6>\xef\xf7\xeb:\xe9:\xe9:\xe9:\xe9:\xe9:\xe9:\xe9:\xf9\x7f=\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xe9;\xb5}\xb7\xea\xadV\xcf\xceh\xe5\x11S\xa6\xe8\xe8\xf8\x0f\xb7\xaa\xd9o\x00\x00\x00\x00\x01TP\xc3\x17\x00\x00PK\x07\x08\xea\x14{\xf5\x80[\x00\x00\x80[\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00fonts/glyphicons-halflings-regular.woff2wOF2\x00\x01\x00\x00\x00\x00Fl\x00\x0f\x00\x00\x00\x00\xb1\\\x00\x00F \x00\x01\x02M\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?FFTM\x1c\x1a \x06`\x00\x8cr\x08\x04\x11\x08\n\x82\xa9$\x81\xe5e\x016\x02$\x03\x86t\x0b\x840\x00\x04 \x05\x87\"\x07\x95Q?webf\x06\x1be\x8c5\xec\x98\x8f\x80\xf3@\xa0\xc2?\xfe\xbe\x08\n\xda\xf6\x88 \x1b\xact\xf6\xff\x9f\x94\xa0\x86\x8c\xc1\x93\xc7\xd8\xdc,3+\x0f2q\x0d\xcbF\x16\xaeYO\x1b\xec\x04&>\xb1\xe9\xb1b\xd2m\xa45\x81Z\x8e\xe6H$\xb1\xaaY\x8a\x19\x9c\xbd{\xecH jd\x86\x0b\xd5\x89\x0c\xfc\xb2%\xf7\xb9\xd9\xa7\x7fy\"\xa7\x04\x03\xf7\xf6\xd7+\x8d@\xb9\x8c]\xbd\xabe\x9f\xfb{\xfa\xd2\xfbv\x90\xa0Nc\x8b)\x0e\xbbn\xf9\x93\xc9?~?\xe8\x90\xa4h\xf2\x00\xff\x9e_\xe7&i\x1f\xc6\xca\xc8\x1d\xd1\x9d\x05\xc1\xa4\x8b?\xba>\xfc\xe5^K \xfbv\xb4-\x1bc\xdb\x8d1\xed\xf4\x80\x12\x892K\xa0\xe1y\xb7\xf5,'n\xe4\xab\xe0\x00\x07(\xf03Ewi\xe0B\x05\x17\x82\xa0&\xa9\xff\x0b\xe9\xceT\xb4lh\xd80M\x1a\xd2\xd8\xda\xd2\x86d\xe5Y\xd8r\xf1\xef\xb2\xac\xb3nti\xde]\xddyur\x95\xb4\xbc\xae\xfb\x99\xee\x13VXsj\x0e\xa1\xa2\x9e\xe5gMn\x19\xaa\xd3\x99H\x81W\x95\xa9\xc3\xd4\x08 r2\xf4>iT`V7\xb8\xcdR(\xb1\xa8\xc9\xcf\x1a\xe0\xff+\xa0o6\xf3'c\xc5\xc8B\xb0\x8f\xe6\x06\xeb4\xe7\xb7\xd6\xce\xb9\xdd\x7f\x87\x83\x8b\xe3\xbf\x9a\xaeT ]a[Qd<3wq8,\x8e\x85\xeerTI\x16\xa18\xe1\x12\x1c\x8e0>E\xb8?\xf9*E\xa8\xe7\x97\xa6\x95#\xcf\xfa7'\x8d\xec\xdd\xfd\x86S \x0c\x0boc\xfb\xca\xb7\xed_\x8b7&#*\xd1+)\xbd\xb3\xa0\xd0+4a\x01\xb0A6\xb6c\x8c\xe7y\xb1\xd9\xa3\x86f(b\x19F\xe9\xe6\xe4\xff\xe9\xb4$;{ YA\xc31vP-tG\xf8\xff\x8c\xe1\xc0\xb1\x15\xcd\"\xfb\xb0\x95\xdb\x01C\xc2f- W\x82\xf7\xae\x02\x9a\xd4\x99\xceuK\xd6\xb0K\x08\xe3#\xad\xed\x0e\xe4\xac\xd6*K\x86<\xdb\xfc\x04 (\xd1\xdf\xeb\xd4\xf7\xd7\xffZ\xfe`\xd9\xab\x0c\xe5\xb5[\x97%\xeaY\x05T\x8a\xac{%\xaf\xc9\x8a$\x88\xad\x10\xa0s{o\xef\xed\x19\x9c\x17\xf2\x88\x83\x18\xd5\xbb\xefvt\"p\xe0\x9c4`\xc8\xea\xdf\xa9\x8a\xcf\xa4}o\x0c`\xe3\xb3\xdd\x14\xfa'n\x14e\xdc>\n\xe4G\x1e5s\x00z\xf3_N\xf3\n\x92PK\xd3\xa6vmU\xde\x0b\xc9\xbe{z\xbd\xdc\xf2\xee\xf3\xff\x9f\x19\xf8\x7f\xf8\x8c\x87\"3`l\x0d\x92\x1c\x03\x96W#\xd4\x90\xbd^\x18@+\x8d,\x07c\xb9\xc9ko\xa9\x8dAO\x1bp\x15nu\xb5\xa7\xd4z\xf3\x96zJ)\xf5\xdc\xce\xa5\x1e\xf7\x98\xdb1\xc7}\xe1\xe1\xffO=\xde\x7f\xad\xb6\x80x\xbeR\xc6\xc4`\xc1J\x89`\xa7q\x83\x15\xa5\x82Us/\xbf+\xf8k\xd2v\xc71xl\x1a\xdd\xdf\xe7j\x12l\x05\x96El\xec\\nD\x8c\xc8\xc3\xc6\xb6\xafV\x86\xb1\xe6\xff\xd0jg\x9b{Zd\xe5\x89\x08z7\x8f\x0b\x145\xff\xdf!\x04xm\xc25o\xc2[\x07\x1c\xbd\xbfu\xef\xfb&\xb7\xaf1\xda\x82H\x10BkA\xe2\xec\x08qr\xea\xceR\x90\xc4\x0d\xa3\xb7\xb0\x16\x8f(\\gh\xf4\x10\x14\xc87\x89\xec\xd2\x8ay\x8f=\x86H\xb5Z\xf3UPh\xe9\xd0$8\x10Rg\xd3\x05\xc4\x18\x80z\xc2g\xcd\xad\xc9N:\x8b\xe0\x001u\xac$\xdc\x85\xaf\xa4\xa1\x9e>R\xfd]\xe5\xfa\x14\x97\x0e\xa6\xac\"\x9f\xf4f7\xbc\x97\x0b\xf5K\xaf^\x7f'\x98\xaa\xeb\xbd3\x93+E/\xbc\xc4^\x89YU5]\xa8NB\x17.\xde\xca\x8b\xa5\xd28\xdf\xc5+\xce\xcd\x8f8\x8f\xf9,|\x89{M|\x8cA\x8a\x11\xe5ua|\xd0a\x88\x92\x7f\xec\x8e\xd5\xde\xcb\x85\xd5\x9d%\x00\n\x7flKG\xa2P\xed,\x17Nu\x14\xe6\xdc\xd4k\xfec\xef8mX@\xda\xd3d\xff\x17\xcc\x98?\x7f\xf1\xfc\xda\xf3\xa2\xe7Y\xd3&\xcf\xfe{\xea\xf6\x94\xf8\xb3\xc7\xcf\x0e?\xdbP\xdc(\xae\x14G\x8a]\xb6\xbf\xcf\xc6\xe4\xaf\xe4O\xe4\x8f\xe4\xb7\xe4\xd7\xe4\x97\xe4\x06r-\xb9\x92\\LF\xc9\x089\x97,&\xa7\x93y\xe48r\xac\xfb\xb4\xfb3\xf7\x1f\xdc\x9f\xb8?p\xbf\xef>\xea~\xdb\xfd\xba\xfb\x15s\xe8\xe4\xff\x05\x8b\x9e\x12\xd0\x10\xa2\xd3D\xc7\x08\xa4z\xf31\xfa\xa1?\x12\\U5\x16q=\xad\xd9t\xd1z\xd4\x92\x0e\x86&Z\x90nj\xa2%\xe9mM\xb4\"}\xbc\x89\xd6tk\xdeD\x1b\xbawh\xa2-=\xffm\xa2\x1d\xbdB\x13\xed\xe9\xf576\xf1\xf4\xae\x83&:\xd2\xbb\xc9qt\"\x0b\xd61:\x93\x15\xac\xeb\xd0\x95\xac\xa9u;\xf4\"K_\xa1/Jd\xd6c0\x96l\xb2\xf5\x1c0\x1d\xb2\xc5'^\x03\x16B\xb6\xf98VC\xb6\xd5zg\xb0\x06\xb2\xbd\xac\x0f\x06[ ;\xca\xfad\xec\n\xd9Y\xd6\x17b\x7f\xc8\x83u\x1d\x0e\x87\xbc\xa9u;\x9c@\x9e*}\x01\x06y\x89|\x0c.\xa9\xac'C>\x13\\g=\x1b\xf29\xe0V\xeb\xc5\x90\xaf\x01\xb7[o\x86|g\xf0\xa0\xf5^\x90\x1f\x0c\x9e\xb6>\x8a\xfcd\xbc\n9\xad\xcf\xc7\xfb\xe4\x17\xee\xd8\xc5\xf8\x94\n*E|A\xa5\x0e\x8f\xe3\x1b*M\xad[\xe3[*mO\xdc\x0e\xdfQ\xe9z\x1c?P\xe9n\xdd\x1b?R)Y\x8f\xc1oT&[\xcf\x01U*\x8b\x955\x10\xc0S\xd9\x0cMB\x0b\xfe\xec\x04\xa1\xa5\xf0[\xb3\x13\n\xad\x84\xdfoYDh\xad\x18\xd5{\xec\xd1,}1f\x12?\x9b\x00\xab\x93N\x8fN\x9c\xa2 ]\xd4O/^;\\\xda\x0e\xc2J\xca\x0d\xcfB\x06\xc7EsJr\x19\x04\xaa\x90\x19\x01\xa0\xc4\x9a\xf5\xc6\x0f\x14'\xf2\x85g\x12/\xe3\xe3\xd1B\x17%\x9f\xa1\x1eo \x1fC\xf5\xea\xban\x957\x8b\xdc:\x05|\xf5y\x83Kt\xb2&\xf7$\xa7\xd8s\xaf|\xb9\xf5wP\x88\xf9\xc4\\i]\xbe$Z\x12@+\x01\xcd\x0c\xb6\xb6\xd5\x8090x]\xbbr\xb8\xad%\xbe\xc8\xd5+\xf6\x07RU\xacEm\x87+\x16\xdc\xb0\xaa\xa3;w\xa0u\xac\xc09/I\xbc\x05\xd47\xc87\xd5\xa6\xb9Q\xfelu\\\xa6y\xd0\x0eW\x8b\x10N)\xeb8\x89\xdc\xb0vY\xee*u\xb4m\x02\x94\xa1\xb1\xbf\xe9\xe2\xa9\xe2\x04\xbam( f\x06\xcaE\xbd\xf2\xffG8\xb2\x0c\xa2j#I\xac\xbdR\x8e\xcc\x17\xf9z\x0c#q\xb8\xdf\xb7\xdf\x01\x06 \x84)Y\xa0\xd7$\x8b\x0b\xe1\xd0\x9b\x86c_%\xbfm-{!0-`\x0b;\xe1\xe5\x85\xac\xf1\x14hyV\xf5\xe4\xc1]Hv! \xcf\x1ft\x1ca\xbd\\K\xef\xc5\x10\x1e\x06\xa5[\xcc1{\x1a\x03\"\xe7j 6@\xec\x963T0%\xa5\x13\xbf\x0f\xe9\xce\x98\"\xc7\xd4\x99\xc6ZI\x86G\xe4\x06\x9bS\x93\xf7\x8d\x82.\xb3\x11\xc4\xce\xa3p\x07\x81\xc6\xd3\xacS\xc61e\xe9\xfb\xd9\x93\xc4\xd8\x9b\x9d\xf9\x0cY\xc1\x1e\xffv\xbb8\x1a\x08d\xb1\\\xb1B\xa1\x17l\xa1S\xfb\xfeR)\x06\xd2\x13\xd3\x86\xe7\xf9\xaf\x96\xae\x80\x0b{\x02I\x8a\xd3\x86\xf4\xd2%\x9d\x94\xaf>\xfb0\xd0\x8e\xda\xa6\xb3\\\xf0'\x94cg\xbd2%4\xa0Q\x8eD\xa1\n0\xcd\x923B\xb2\"\xc9M\x8e\xd5\x8e&\x80\xdb\x8ahI\x15\xc7\xc2\xda\xa7\xd2Rg\x10\xb7ME\xa4\xa1\xa9\xa1\xb6\x9a\x0dI\xbd\xce(\x07\xa9\xde\xd55U\x96D]\x0c}\xf2\x1d\x99\x07b\xed8$\x97\x87\xec8\xa8>\xf3\xe1X \x01\xb2\x07h\x95\"l\x1e\xb5\xce\x80\xe2j\x1c\x9d.%\x88\xdb\x80\x18HH\xc7-\x0bI\x9a\xa6\xdd\xb8#1\x92\x1dC\x014\xf5\xdeY\xde\x017\x84\xed\xee\xae\x12\xedY\xdd\x96\xa1V\x0co\x08\x1a>P\xca]\xa16\xbf\xb7\x07\x98\xf6\x99O4\xff7f\x1a\x0d\xbd~\x00\x18\x1eAJdYF\xd5\xc2\x80\xca.\x96\xdeo\xf5\xc3\xfey) \xc68l\xc6\x0b\xb622\x8ee\x8a\x9c\x1f\xa6\xd21H\x1b\xa1[\x01t\x89\xb0@!\xc8\x85\x0c2\\\x80@\xb8\x085\x06\xc4\xd9\x93\xca%Z\xd7\xee\xfc\xdbk\xde\x92\x08\x06a\xf5\x9d\xae\xdc@\xfa.`n\xa83\xcaOF\x8c\xa2\x10R(\xf3\x85\xa5\xb6\xf7\xff\xbdZ\x01kLk\x05F \xedHWjY\x1f\x0dI\xa4\xea5\xd7\xe7*\x13\xf16\xda\xcee\xb5Sbk.\xa4\xbc5F,\x17\xec.\x95\x02N0\xdf\xd4\x99\x92\xb9\x80|\x94\x86V\xa6\x80||~\x05N\xf4\x87( 4\xb7\x9d\xec\xda],\xec\x1aJp|~\xf9xe\xd3\xc9A\xa8\xd4\x1c\xa1\xaf5\x88\x88/\xbb\xda\xbbS\xa4\xfd\x04\xe4\xf4\x94\xd0v\xf2\xd7\xdcy?\x9b\xf9\xb2'_v|r\xea\x84\xcbX\xdc\x06\xf8\xeeH\xe9Q\xca\x05\xb0\xb5\x15\x05\xc4\x93B@=\x0b\xddX\xac\xdf\xfa\xacB\x13\x189\xcb4\xb3\x98\xab\xc3T\xa9\xd8B\x89B\xa9c\xa0\xad\xc1\x18\xabH\x91P\xa3\xce+\x82\xf2\x89\x81_\x93\x93\xd5YH\xd9#\xac$\xaa\xcb\xca`\xa0\xecF\xf8\xa3\xf1B;\xe3\xb5\xc2+\xdb\x11\x94\x85BPR\xb04\xcc\xbc t\x04\xad:t\x08\xf5\"Z\x13E\xbaJ^!X\xc2\xc7\x93\xe0\xacq4_dTW(5\xe4\xdc\x80\x04\xa7\xe5\xff\xe4\x1f\xb8\xdaI\xb1\x94U\xc5\x87\xd2A\xcdz\xfe@U6\xffn.WGX\xfd\xc0\xc1\x05\xe8H\xecRK\xc0\x16\xdb\x1a&\x08'swM\xb1j\x8a\xca\x8e\x98\x8b\xb1<\x9f\x94\xb1\x983\xa6)\x80\x96\x9d`#F@\x12\x0c\x18\x0cF \xd4\xa2\xe0\x08\xfe\xd8v\x8do\xcdb$x\x0c\x07\xef+\xb2\xe0\xbcu\xfb&\xb4}\x89|\xcaX\x18&[\xd9\xaa\x908F\x8b-\xb9E&/>\x8a/\x17\xd1G\xc5.a\xeaz^\x8a\xde/\x83\xd4\xfe})\x9c\x11\xb2\x13\x92\xf3'\x93x\xa9\x91$O=<\x01\xc7\xc2z\x99\xa4o\xe4\xa7\xe1A9M\x1f\xd8\x9d&\x1d\xf2~\xee\xa1\x99\xb93\x19r\xb5\x053g\x9f\x9c\xa6'\xbf8\xd2\xa3\\\xb0-\xb6MDz\xc8\xe8\x11\x98\xf8k\xba\xcd5\x86\xf9\xb1\xb4A\n\xdd\xc2\xfd\xaaG9\xa9\xe4|1-\xd8! \xc787\xfb\x10[\x9c\x7f\xf4\xa4,mR\xeeu|\xa657\xae\n\x1c=X\xfe\x91\xa4,\x98aJ\xa7\xd9\x1b\x16\x9b\xb8^t\xb4N\x9b4\xd3\xd8\\f\x10\xd0\x84]Az\x1bH^\x027\xb7\xaaF\x95\xe8\x1c\xfe\x95\x99\x84&k\"\x1bLU>}\xec>\xe7rB\xe5X(\xdb\x82\xaa\xeb\x82\x02T\x9a%\xbf\xab\x0bJ\xaa\x08\xbf\x84\xaddhK\xc4\x1f\x94\xf3\xb6P\x93\xb2K\xc1\x1eTFaA\x873HH\x86C[r;a\x9b\xc0\xb6d\x02\xb7\x99\x17\x87\x1a\x9554\xc8\xcc\x0c\x89\x97lL\x84k\x03jG\x0f\x1a{\xa1\xec8\x9fh~\xe4\x8f\x07\x0dfR@\x03\xd0\xec\xfc\x1e9w\xe0B\xa8\xa4\xe0\xd00\xeb\x0bzS\xf5\xf4\xb0\xe2\xff'\x97\xa0\x14\x02a7\x03\x82@\xdd@N\x9b\xb1\x8a\xdd\xc6\xb9l\x91b\x18j3\x0fhN\x04\x13\xee\xb2X\xf6\x8bF/\xc9\xede\xa2s\xa3\xd9'\xfa\x8aDsQ\xab\xf1<\xfek^\xd3\xed\x1d\xf2\xd7\xbc\xb2\xfd\x88ZASO\xa8i\x17d\xbaSJ\xe3x\x1cN4D\xbd\xb3\xc0K\xd3!\xb4\xb9\xd4\xf9 !\xd9\xabv\x89\xachA`\xdbE\x96\xb7X\x10\x90\x95\x00\x02\xbc\xca-\x0d\xa2P\x0d\xed\xc4:\x9f\x82\xdb\xd1\xa4\x1b\x7fC\xea:\xc2\xc2W\xcdzS\xbds\xc4dO\x0c:\x08\x10\xb6_\xbf\xab\xd4\xcb`\x8a:t\xc1a\xce\xb7\xd0\x91\x0b\x1e\xa5\x86\xb2\xcd\xd8\xb3\xfa\xa2\x16\x81\xae\x0d\xbcIY\xf0\x044\xc7\x0c# \x10\x90\xf8*\xd2\x1c\xcd+<\x03\xeaq\x00n\xb0o\xd4\x00\xb8u\nU\x08\x04\xcccww\x8f\xf3x$d\xb5\xb3\xf0\x1b\xc6\xbf\x0e\x9d}\xcf\x81\xfb\xd6\xc194\xcc\xfd\x9a\xed\xfc\x039p\xac*T:\xfa%G\x15Q\xe6\x85^a\x9f\x8b\x15\x87\x10\xe4\x03\xdd\xcb'\xa8\xe7e\x83\x1e\xf4b\xf6\xa8\x04\x14\x14\x8al-\xd5\xdc*X\xddL\xe7%*\xc5\xba\x08\x19\xb8.\x85\xda\x8a\xc8\\\x8a@pR$T\xe5*K\xd6\x18\xcd\x05\xbd\x08\xb8hp\x87\xc0\x88\xc8\xe8\xc1\x82\xdf\xe3\xa6m\xfa\xc1\x1b\x91\xe2-/\x93oS\xda3\x8e\xdf\xc2E\x8d\xe0\xcf\xceto\x7f\xb8\x07\x9e}\xe7\xd0\xb6V\x87o\xf5\x07eJ\x0b`<\x99$\xf6\xd9t\xed\xd8\x12\xbd\xdf\xfc\x1f \xaa]g*\xdfZ\x9b\x0f\x84\xb56q\xb0\xc0\xf9l\x92\x04\xf8~\x1b\xf7E\xaf\xab\n\x86S\xfa\xb8/\x8a\x92\xf9i\xa3\xc4T\xc6t\xcdk\x82\xc7\xae\xe0\xb2W\xdd\xc3\xbe\x0c\xdc=?j\xb9\x00G\xa2\xd2\xcc\xd4UU\x05AJ\xc6\xf5\x0e\xfd\x9b\x02\x1c`\x86\xd2b\xd4\xcb\x91\x97\x83G\xc2\x88\xf5Q\xcdA\xcf\xab\xa9\x81\xf1\xc3\x96\xce\x15\xc6\xda\xecc\x83\xfb\xea\xbdW\xcb\xef\xa9\x15\xe8\x03WSm\x08\xdd\xc0\xadg\xb3\xba\xdaF\xcb\xf1\xaa\x91&\xa9^\x16\xf5\xfa\xd8\x98\xd4\xa1\x886;C1:=\xdb\x88P\x89\xe4\xba\x14\xd5`\xca\xda\x9c\x90VV\xff\x93\x1d\xd4E\x9d\xc65\"\xb4hO\xabX\xe0~\x14\x1b\xab\xde\xd8N3_5\xd3\x81]\xbaz-\xfe\xad\xe4\x92CW\xd3\xddt\xd4\xa5\x8d\x82\xd3\x88\xb4\xd0\x18\xcbe\xdc]\xb0\\\xb6\x94\xa9\xbf\x1dV\xaf\x19\x13\x96\x8b\xffc\xd4#\x1dm[\xc6ku\xde\x97\xad_\xca\xb1\"\xa9\xc9\xf6s\x8dH\xb3\x7f\xf4<}x\xef\xb1\x02\x85m0b\xe5x\x01H\xd3qb\x1f\x91a3tf\xe7MT\xdb\xd1\xcf*]I\xbb\x18\x1c\n\x15\xde}\xd7(\x1c\xfa\xbe\x9c,M\x94\x84\x8d\x96=\x8a \xdd@\x8cJA\xdb\xc6\xd0d\x89\x90\xa0\xac\xcb?\xc2\xa76PV\xb1\xf6[\x0ddV\xe3v\xf4\xe64j\x9e\xd2\xdf\x9b\x91lH\\\xe2\xf7\xd4\x16\x8c\xc5\xe8{\x98\xd8\xf2\x02M\xf4\xe5\xbd\xc8\x98\\\xba\x9d\x8d\xe5\x01Y\xfe\xdc\x81\x80\x1c\x1d\x81`9M\xc3`D\x13b\x87<\xc1\x05\x12;a#z\xf2\x86\x91<\x8ax\"\x06\xf3,\xa8d\x82gCi\xbf`\x91c\x92\x9b\x16:\xc1\x01\x05\xc8\xe2I\xb4\xe2>jw\xb7\xcc}J\x05\xc8\xc9z\xa7\x8d^:V.\x1d\xfd:\xd7\xfe\xda\x8b\x13{\xbf\xcd\xbc\x06(\xc8\xb2B\xf7\xe6\xcb\x1c\xc9\xa6\x03\x92\xc9\xf3x\x8e<\x18\x1eDb#\"S\xa3\xa1{\xf4\x92P\xf9Hu\xbdN\x81/\x13\xeb{r6\x05;wU\xb6\x13\xe6\xd0\xf2\x12s\xd6P\x17\xd0\x9e\x93<\xa4\xe7X\xc0\xe0Y\xe2s\xd4\xc4\xf7\xdeMxu\xb0\x87\x14\\\x9ab\x00\x91\xdas\xb8$\x11\x8e\x98\x11x\x8e\xca(\xa2\x89/^|\x03^*\x180j~m\xe0\xac;#\xb7%J\x84\xdeM4\x9d\xc7p\x98QM\xd7\xac\xf0::\x1ab\\C2gf\x01\xb0\xb0]\xbdz\xd2P8T\x99 U\xaa\x93Qb\xd6\xe8t\xba\x83\x1dC\x1c\xbdT\x9f>\np\xa08+6g_2\x96l\xce\xa16\xa7H\xf2\x11\x08 \xda\xce\x00\xc7\x86\x0fH\x9d:\xf7\x0dd\x9b<\xe6C\xcd\xe96\xb3\xaf\xd8\xa4\xea/\xab\xbf6\x7f\xe3E:\xc2K\x8b\x94\"\xcb`kJ\xa9<\x9b\xcf\xc6\xa2\xe4=\x08\xf9v\x9e7\x84\xa5\xe2N5\xb7\xb5`\xb0\xf2\x9b\xb6Jt\x8b\x12\xd9\\j\xb96\xcd\x85%\x03\x0e\xcb\x9e7\xf4*\xa5'\x0f\xa5\x10\x95U\x95\xd94\xb1:\xe2\x1bX+\x0d\xe4\\\x02b\x00\xfc\x92E\n\x11\xe4\xec\xf4\xdeaf\xae\x8ax\x8c\x1f\x93}\xc1\x891+p\x99\x8bB\xa5\xcb0\xee6\xf2\x17\xe2\x94\xe5\xfd\x9e3r\xf5A$\x1bN\x14\x9a~\xb6\x12\xf4#\xb3d\xaa}\x08\xc7\xd7\xa4\x9fP7h\xf7H7b\xa3F\xaa\x9e\xc2\xa7\x85\x82\xac8\xf0\x11\x0d\x1e\xb3P>\xf8Bt\x19\x1eGN\xd0\x14\x15\x8e\xa2\xf0m\xe4\x01\x82x\xf4@\x8fj \x85\x91\xb8|{\xc0s9\x12\x19\xe0\xbb=\x0f\xfewR\xd9/\xad\xaboDJs5\x16z>\x93;\x8a'x\xdd\xf1E\x06\xd0q\x15^\x06r\xe9^=G\x1a?\xbd\x859A\xea\xa1\x06\x7f\xe6\x96\xc7A\xe4_\x97\xa3\x06\xedK%\xb5D\xc9\xae:uikjk\xeeI\x18e\xc9\xe6\xbd\x1a\xacG\xfa\xd5\x9d#*\xa1\x86)\xb5jm\x06\x91\xe1|\xbdt\xa3\xb9}`\x01J\xe6\xa9Z\xd8\x88\xe9\xd6\xf7\x17\x07\x03H\x0f=4\xee\x9d{g\xdf\x81\xa2\xbe)\xa1qX\x88MA,\x17\x9aH\xf8\x8c7\x18\xfb1\x89\xebV\"\xa5\xd9\x14\x0fo,\xe7Y#h\x12\xfd\xfc\xf7\xdd\xa8S\x17\xf2_\xea;\x8b\xcda_\xd4\x97Z^cn4\xa2\xad\x10\x8d\xa0\x82H\xb8E\xab\xae?\x89\xab\xb0\x11}\xd1\n\xc8\x9d\xa1\xbb\xad\xdc\xee\xbc\xd9\xa4=}B\x9eWv\xde\xaaUe\xf0\xe5h\x9a\x17\x83\xda\x00G\x1d\x8a\x93F\x90\x85\x89\x91\xe6;\x9d@2S\xa5\xd8\x01\x9c\x80@\xcbf \x05\xfe\xc2\xcb\xfcn\xcd\xe22\xd0#\x8d\x8e\xe6\x1e\xb9\xf1\x13f\xddY:]\xbfJy\xe5\x08H]\x1a\xad\x95-\xb7\x98G\xd7\x8cwgv'\xa1\x07\x04\xe2|\x88\xc40e\xf1\n\xc3_7\x88\xf0\xd2\x90\xabn+f\x1e\xdf\xd9\xb8\xe2\xe0Y<\xab\xe7(\xcd\n\xaa?\xf6\xec\x92\x10\xa9\x91y\xf2\xf9\xa1%wm\xac+j\x0e\x83&&!\xe8\xa2c\x93^\xa1u'\x9db\xfc&\xf1h\x9fm6\x10\x04\xc2\xa4\x9a\xce\xfb\xb9*2\x0c?\x1c\xb4A\xc7I\x1c\xab\xb6\xc6\xb25F\x06W\xbe\xd8\x99[\xe2\xc6\x9c\x06\xa8B\xf5Uz\xefI\xceE\x94\x93!\x92m:\x8b\xd2\xfb\x9cxh\xd4e\x97\xdd\xc7\xaen\xbcz|]%\x0c\x8d\x90m\x11\xd9r\xc1U\xb8F\x8d\xda\xaf\x90\x05\x94\xf9\x11\x7f\xae1\xc6\x0b\x1d\x89};!\x0fn F\xbe&\xa0g\xf2\xda\xf1\xffP\x89\x86\xdd\x01\xaf\xaf\x1b\x1b;&\xd7\xf6\xa9\x9c\xf8\xef\x18$$\xb8\x1a\xe9F\xab)\x1a.t\x9bB\xedQ\xa83\xa6\x8e\xbd\x15(\x9eC=\xfa\xb7\xd3\xe4\xa6X\xc0\xce\xd8es\xd4;\xddi\xfb\xab\xb6\xad\xd9\x8a@\xbc\xd1\x08~\xfcN\xed\xc9\x1b\x1b\xce\xa1E\x01\x7f\xeb \xd4SR\x8b\x14\x04\x14\xa1\x88h\x9d\\\xe9\xe8\xa3\xfa\xc1Be\xf1o\x18\xba\x86\xbd\x9c\xa0\xb4\xb9\xce\x01bT\xd1\x16\x84\x06n\xce\x92\x11ju\x02\xb9\xbe\xc0\x1b \x07g@\xe4\xf7'\x04qQ\xeb\x94\x8enx.u6bVU&\xd4\x0c\x9b]\xb9;\xdb\xef\xaa\x15!C_\x0c\x84\x16\x06\x0b\x08\x9e\x8d5\xc6*\xdez\xb9\x1d\xc9\xba\xfbm\x80RQu\x91\xaaq\x82\x92\xe0\x16\xa6\xb1P\xfc\xdaZ0\x83\xb6}m\xf1\xbc\xa1\xcc\x06\xca\xf5n\xbd\xa6^n\xd5Or\xc9T\xa6\xe2\xc1\x91\xb5\xce:\x9fU\xe3'\xd7h\xc0\xe6\xa70n\x0fZ\xa1p^\x19R\xe9|DF\xaa_b\\\xf2@\x96\xd6m\x81\x82\xe8DE\xeb8\x81\x00\xc6{o\xe8\x1eGM\x89\xe1\xa0\x9c\x01q\xb8\xdd\xcf\x06}\xdc\xeeSd \x16\x14\xae\x0fC,\x1b\xfb\x04i\xc0\xdc\x9aE\xea\x1d\x12\x8a\xe9/\xb0\xde\xc3\x8b[\x18d8]\x8e\xd7,MCI\x9a\xce\xd0\xf3_u\x97,]V\x99\x81c\xf1\"\x97\xe4\xa4p\x18\xb0\x06g\x1d@\xec`\"y)\x8b,;B\xb3^e\xad\x9el\x10\xda\x08\x04\xa1\xaa2'\x80.(\x9d\xcd\xd0\xc4\x98\xe2y>\xe0-\x1a|\xceh\xad\x18\xdc\x13\xd3\xc4w\x9a\xfa\xfe\xea;\xa9j\xe5\xa5\xe8\x1d\x92\xed\xd5\x8d\x18\xd1\xd2i\xd4\xbd\xb1\xe4\xaf\xea_\x19\x08o|!@\xf6)\xc9\xa2\xdd\x1e\xaa\xc4=\x7f\xd9\xcc\x8cSPz\x9d\x97\xe9\x1d\x1f\x88*!z})\xbc|\xc6\xa7T}\xbdj\x18\x91\x86E\xa3tC\xacZ\xe5\xa1n\x8c\x8d\x17\xbd\x7f\xc3\xbd\x9c*\xd5\x9e\xf5\xc94\xdb\x86\xd7\xbd[\xb9\xa9\xb1\x0b\xbe9\x1a\xbb\xd0\xae\x05\xa8\x8e\xe8\x88\x17\x91\x06\x92\xdd\x93\xf5\x8cz`W\x08m\x14e\xf4o\x82\x8b|j8j\xad\xef5\xe1\x18\x909\xbc\xf6\xb5@.\xfa\x9aE\xbf\x18V\xcc/\xccZW\x05@\x17|\x97\x81f_\xe7\x10\\\"$\x1d{\xe1\x05\x9c\x91v\x10\xa1\xe0\xf2\x83\xf3\x9c\xc0\xc8/\xb8\x06\xf2\xb6;a\xd7\x16\x1c:Se\xa6i3T\xe4G\xcb\x10*\xeb\xce\xfd\x83]\xb8\xc6\xa1/\xcch\x14\xc02\x1dC32$\xbf\xd3\x01\x0e\xf4\xbf\xfc1}\xbf\x8cD\xa4\xcdNX\xc9\xf8\xfet\xec?F\xcf\x9d\xed~n,Pj9\x0f.\xee\x96>\xd7\xa3\xfc\xa8\xcd{\n9\xfd\x7f\xc9EN-v|3h\x86\x14\xf2\x91C\xc5\xd0\xb8E\x94\x95\x87 XT\xe0\xe2\xcb;P\x96$\xc3=\x8dJ\xd6-\x0f\xdd\xd5g\xdd\x95\xfd\xf9igz~q\x97(A\xe9<:h\x131\xb19\xb33\xe1N\xec\xcc\xbd\xf5Q\x89\x8b\xe3\xc7}CL\xd8\x7f\x90W\xf9\xdf\xa7\xc2\xd7\x8e\xdc~\x83\x12\x1b\xe1\x0d\x12\xdab\x99\xa5\"\x86\x81\x87\xcd|\xc74u}\xee\xf0\xad\xd7\x01\xd9c\x99y\x80\x04\xe0\x8b\xc86\xb0\xa12\xff[ \xa5\xd8\xd6\\d\xb8,\xb5\xd2\x8e\xd5\xb3b\x81\x11k\xf9\xa4\xccD\xe5\xe4\xbe%0T\xdcx\xad\xae{=;\xf6\xd4\xb7\x8b\x86\x01(\x84i\x08\x87\x0b\x8d\xd8LS\xb7\xf8\x13\xdf1\xbd\x98\xf8\xfd\xa9\xd13\xffN\xcfh/\xa46?\xe6'E^\xf6~\xff\xc6\xd4P\xae\x7f{sZ\xec\x1b\x99Z\xd3K\x94\xc4\x9e\x13B{\x92D\xcct\xf8&\x89\xbd\xd4z\x92\xd3\xf7)\xb5\x17Uoa\xf95Q\xa63\x8f\x91\xc8\x97\x88r~\xbf\x8e\x91\xbe\n\xa6\x01\xf4\xd9\xf9F]\x11\xa0$\xba<\xe8\x04\xfatm(\x9a}\x0c\xfb\xc3\xcfMB@\x87\x9e[\x9cGx\xec\x08\xceF\xd3\x05h\x108\x00\x9b#}\x88\xf4,\xa3#\xc0\x98u\x0b\xfdLaz(\xdeQh\xb14%\xd3x\x01m\x04`U\x13\xe0\x95\xd5\xb9.E\x11\xa8\xe3v1a\x92\x9e4\x0e_'/[\xa8d\xb1{Fx\xa8I\xca59\x9e\x8c\x0c\x83D\xf5\x11<\xea\xec&\x908V\x88E\xf3Fg\xc9\xc8\xd9\x0b\xe8\x8a\x98#\xf5I\x91\xe4\x9f\x8d2S\xb2\xcd\xee\xff_\x06\x0f\xe3\xa9]QqA\x13\x9an\x88\xd1_\xf0Q\x19\xe7\x07\x12>b\xde\x984g\xa1\x19\xa8\xad\x13\xb1-\xae\x010&\x07E#c\xa6\xdci8\xbf vR/\xd54\xff\x18r\x9e\x8a\xeb\x08\x9aP7\x95\xa3K\x03sOW\x05\xb5N3\xd5\x8f\x1evE\\bq\x86\x7f\xfbQ\xdf5\x18\x12\x8dZ\xb9\xda\xbdVy5\x07]\x8d\x13\xbd\xd6\xf6\xe0h/ i)\xc5\xfb\x9d\xa6\x8e-/\xb4\xb0\xe3\xa1k\xb5N\xac\xd1\x8e\xbe\xc8\xc4\x1c\x13#e\xec)\"P\x17\xed\xf1\xfc\x08 {\xfdKSQ\x90x\x89\xb2\xb8\x9d\xa6>a\xe3&\xb5\xed\xb6\x8e,\x84\x17\xa0\x0e\x0d_\xe8g\xa5\xb4\xf1-m\xe1c<\xd7\x18n]\xd0\xa7-\x14\xae5\x912c\xa8\xb9\xa1\xae\xf1z\x0d\xac7d P\x9cz\xf3\x13\xe5\x01\xb5\x19\xe0\xf2\xf0\xb2V\x84\xf6\x93\xfb\xa5O\x1dPvf\xbcR\xfe\x0cR\xa4\xd3\xc6\xe0\xb0\x939\x86Z\x0d-\x9f\xc1\x1e\xded\x12\x86\xf7\xae\x9a\x88\xbfC\x9b\x9a\xf1\xf3\xc7`,\xf6at\xc1=\x13\x14\x87k?v\xa2\xed4#P\x0d\xe8\xa4B\xcc\x16\x08\xa1\x9a\xd8\xa5\xb8/[\x17\xf5\x06s.-bH)\x11\x11\xc9\xbaz\xef '}\xb6\xd7\xb6\xdd\xeew\x9c!\x04\x17r\xc1X\xce\x11Z\x8a\xb5 \xb4.:\x92Vn\xd7\x13;\xee-\xee>\x8a:\xe1\n\x1d\x026\x01\xe0r\xff\xbd\x87\x0e\x1dU\xc1cs\xd54k\xac\x11VW\xac{\x92\xfa\x89\xf0#\xad\x0f\x985\xdf\x910\xc1B\xdd\xe3\xec\xc7`\xdc\x9d\xff0u\x9a\xd1\".Q\xca\xc6\x1f\xac\x9bdB\xb4\x980\xa3\x94\x1d\xf5\x98C\x9e\xd0r\xf5\x1e]\xed\xef\xe0#\xed\xbaQ9\x08lq\x9c\xe0\x02N^\xf4\xd6\xb3\x8d\xaf\xe9\xf4h~\xa0NU\\\xb4 \xbc16\x9a\n~\xe9\xe8\x15\x93\x1c\xe1\x94S\x91n\x87T\xf2\x04l\xa2\x91\\\xfeTH\xd2\xb2\xda\x9b-\xd9\xc9~\xaaG~)$\x85oQ7\x1e-\xeb\xafC\xef\x11\xb0\xcc\x01\xc8\xec}q\x12%/\x1ca\x99\xa6\xb3vO\xb0\xaa|[q4\x96\x82\x8a\x92\xb3~Bc-$N\xdc\x1b7\x9e6\x1c\xbd\x9f\x90w\xd2{\x0f\x9cV\xe9\xa4\x83.&\x13\xa3\xf6(\x86\x0eo\xb9\xa9*\xf5n<\xa7\xd8n9\x06\xa1\x06\xc1J\x96\n\"a\x87\x07\xa9\x0b\xd0\x94\x08\xcd\xdd+\xa1\x86\x0ba\xca/\xbb\xfd\xba\xba\xf0;7zD\xd8Z\xce\xb7\x11{\xd7t\x8fM Mp\x97\xa3 i\xd8\x9ak\xbcNPw\x88\xd8\x91\xcd\xba\xf0H`T\x0d\xf6$23\x1b\x96\x86f\x1e\xd3\xf6\xc0\xd0\xda0\x9az\x1f\xc6\xc8;\xad\xa1\xa6\x9e\xe7\"\xf0]\x8c\xf2\xaa\x82*\x8eY\xb2\xa4\xe9\x10,\xe4Q\xa1W\x81\xd8\x1b\xe0\x0e\xf4\xb8lS\xe9\xb5\xc6\xc5O\x8erW$5\x06]K\xa1V\xd9\xbbB\xe2\x16\x85\xdc\x9a\x85I\xb8\x18\x8a\x18k\xda|\xdf=\xb2&\xc1[\xd4\xe8\xea\xde\xd1\xde\xc558E\xd3R\xa40\xde\x8bGk\xabs\x1bS\xee\xf1\xc1n\xe3\xf2n\x11nu\xe3\xfa\xf1ExK\x8d\xd0\x7fr\xf4\xa2\xac\x8c}\x87~m\x1f\xf1\xd9`\x10\x8eG4\x02u{\xd0\xd1\xf1=]6f\xa4\x00\xf7\xe2\x08\xd7\xa8\nBo\xd6\x1e&<\x0d\x99\xc3\xb1c;2\xa0\xae\x10P$\xc3\xc7\x83{mW_c\x1b\x9e\xf5\xc2\xaa'B6\xd0\x8a?$\xbd^z[\x8fC\x03\x97\x1dY\xb9\xdd\xad\x99\xe9\xa5j\xd0N\xf3~\x0b\xfe\xa6\xdb\xae0\x05\xbe\xbb\x9b\xfat\xa2\xaf\x06\xfa\xb0\xdb\xe2\x846/)-\x891\x7f:p$D\xea\xa5\x85\xc8\x97\n\xae\x10\x1a\x0e\n,'\xb3\x86\xfcy\xe0\xf5\xb1\xf8\xc1v\x98\xc4 \x85n\x9c\x8bF\xb3T\xd7\xd1\x81\x99[\x04'a\xa6Mb\xceJ]\xbb%\x90&\xc3\xae\x10\xaclc6\x02&\xc2\xe8IpF\xe5\x90\xc4\x0d\xa8\xdco\xf0\x8ci\x83\x06\xaa\xc4\xc9\xfe\xe3\x155\xb1\xa0\xf8'r\xa8\xe4\xcb\xe5r\x91(q\xbc\xef\xe8\x90\xfa\xae\xeb\xee\xbez6\xc1\xb0\xf6\x9e\xee\xc9(5\xf3\xd0\xe1E\x0e\xf4\xe0\xc9\xa2\xd5\x9fl\x13\\\x1d\x85L\xf1\x9dk\xba7\xab\xb01\xc5Y4^)\x02b\xd9\x97\xc2\xa68\xf9\xbcy\xf8\xc6\x8f\xaa\xe4\xdb\nN\x9e\xd8=\x83\x9b9zT\x96^[T$\x87dk\xc2\x19\x9c\x0dQ\xe2iK%\xe1\x886\x8e\xb5\x90\xfcq\xb5\xe9\xe7\xf5\xcc\xeefO|\x03\xe0\xda\xe0c\xd08$\x95ji^v\x1b\x04r\xfe\x02.QQR\"\xe2Y\xe1r\xc4\x8a\xe3\xe2\xf5\xb8\x0d\xa8\xc3k\xf8\x92\xa5\xder\x9f\xba\xbcK\x0e\x88\xa2\xb5\xfb\xa0\xe6\xe8\nN\xb7e\xed\xcf\x08Ri\x13\xfb4\xa6\xbe\xd5!3R\xf9\xa2\xba\x15\x90\"\x8d4\xa6\x88\xc8\xf1\xfa\x9an\x99b\xe1m\xc9-y[X\xa6\xa6\xff\xcf\xf1.\"\xc6\xf4\x19!\x94\xf8\xdcQK\xaf\xe5E\\\x07N\x8f\xeb\xb54g\xd5\xa0\xd7\x9d\xf8\x05\xa7\xbf\xa6\x83\xef\xb1aN\xa6p\x82\x0d>k)9\xc1\xc10\x88B\x8dZ\xea\xccBs\n\xf6\xa5y\x8a\x19r\x8e\x9aer\xab)v\xaf\xa2\xaeD\xf3\xebt\xe8rv\x81\\\xfbv\xf9[\xad\xfc>\xf3r\xb5Jm\x9c\x81\x02\x96\na\x9c\xf2\xab\xb5\xcc\xbc\x9b~u\xdd\x17\xea\xea\xd5\x8f\xba>\xb5rMZ\x9c\xb0\x98c\xedB<\xf8\xe3\x0f`)\\y\xd7t|\xdb\x8d\xef\xffr'<\x86\x18\x1a\x06\xf4\x98\xe0>\xf9\xd7\xd6\xfe\xe3[\xe6\xc3\x8e\x97\xef\xad\xe8h7\xeb\xfa\xad\xfeZ\xc5\x10\x04\x8c8\x7fcaI\x81!\xb9\x0d\xb4p\xe2\xa2\x9f\xcd\xcc\xae\x00,\xb6\x0fG\xc3\xed\x0b\xbbk\x07\xa05@\xc8\xd9\xf4\xf7\x08\x1b\xff`\xf4\xc9iw\x0d\x88\xd2n\xd0\x9e\x1d8p\x9fv\xbf \xe7\xc9\x13\xe9*\x8f\x9d\xb2\xc2'O\n\x0b\xdd\x1d\xd4\xfc\x8a\xb2\x14\xa0\xddA[\xc8.\xa1\xa4r\x8f\x16h\xf3T\x0dpR?+;\xcb\xff\xf3\\\x11*H\x8bsLq\xde\xe6\xebU\x9a\xb9f\x96\xe2:ql-\xc4\x87\xa4\x0c\xf1*6!\x85h\xe7+\xcb\xac\x04\x00{h\xb7\x89\xf6- jg\xb1k\xc9MM\xc9\xd7P#\xe3\xb6\xe4:\xbc}\x91\xb1\xb8{/\xdd\xeb\xeeV\xcb\xdf\xc5\xb6C]\xec\x98\x99\xea\xb7&[\xb3W$\xda\xab\x01\x03^\xdf#\xe0\xfb\xb8\xb64f\x1dWa\\\x0d\x8b\x05\xc15\xec\xf0\xe8\xba\xbaM[6\x9e\xbd\x1c)T\xa73\x97\x95\x1b\x15\x9b~\xfc\xda\x1d\xce\x0e\xad\xc9\x12\xd4\xc0\n\xe3:. Z\x94\xa6\xbc\x02\xa8`s\xdei(\xcdR\xf4\xa9Q\x85\xbc\xb2\xcc|/\xfa`\xf9\nil\xcf^\xb0L#\xa0\xa7\xf7\x1d\xf2f\xa4-\xf1\xd7;-C;\x13_\xdc\xde\xf9*\xf9{@EMCoo\xc3\x82_\xa4\x9c\xc6\xc3\xf57\x17\xbeT\xf6\xe3rqz\xdcF\xb5%\x17\xd7\xaf|\x99\x9aUE\xc6\xabUs^\x14\xdd\x9cv{\xa0\x7f\xeb\x04\xa4\xa6fQ<\xc4\x90\xa1\x89VP\xfc\xef\xc3\xcaT\x0ef\xcd\xa6\xee?\xa5\x90\xf5m\xd8p\xd9P*\x00\xc8&\x01\xa6\xf7\xd0Q\x87G\x89\xf9{c\x9c\x03J\xef\xf1EP\x18e2)\x8exP\xbd0\x05A\x06\xd1\xdf\xcd\x01\xfbM\xc9\xaaZH\xb6j\x95\"\x11\xd7\xbb\"\xd9A\x05\xac\xd0C+zq\x89m\x04V\x11z\xe1\x96\x9e\x05\xf3U%\xd8C\xb5\x00:\x16@1\x0e\xe6\xe3\xf0W\xb9\x8a\x0c\xee[\x11y)\xceJ@\xf7o\xb1b%\x0c\xf7j\x94\x15A>)N\x0f\xd2\xc7\x80\xd4i\x7f\xe7\xbc$\x92A\xf3\x88\xc0\xect`>\xcc?f0g\x00\xffH36p\xe86\xe1\xccD|\xfb\x04M\x9b\xe4\x0c\xe1\xf6\x104N\x8d\xa1\xb0\n\x9c\x92 4J\xbdJ\xda\x83\x1e\xaf\n\xb5j\x07\xa4\x9e\x98\xc6\x87\x01\xb4\xf3\\\x0d\xedp\xa03\xd3\x19\xf8\x1c\x8e\xa38\x8d\xc0\xa6\xaa\xd1\xe3\x96\xd0\xaf\xef\x94\x13\xbb\xad6p\xae\x11\xf9V?:\xac$\x82sD\xf9\xc0N\xfa\x12\xb5\x0e\xc6\xb9\x912\xef\x92n\x92,\xb6\x84H\xddO\\\x82[\xb8\xf8\xd5\xb8\x9b\xf6K\xd9-)\x9d\xabW~\xb9i\xe9m\x99?\x18\xff\xae\x83T\xd0:\xb0\xcc\xf0\xde\xbaU\xd6eY\x8c\xd3\xe3\x8a-#dJe)\xaf\xb1\xda\xcfZ\xaa\xd55\x94?\xf8$\xbb\xe6\x0e\xa1\\d\xa9W\x19<\xb7\xb9\xb9,\xc9\x86\x7f\x86\x9a;\xaf\xd8\xb7\xb8\xc35\xcd\xcd\xf2S\xb8\xd5\xb8\xaf\xbc\x1a\x97T\xabT\x96\xf1\x9a\xce\x08\xcc\x84f(\x81PY\x0e\xb0v=Q\x0d~DX\x7f*\x07\xbc\xdf\x0f\xdd8\xf8\xe8\xbe\xa9s- \xc2\x08\x05\xcb\xa8\xae\xce\x80\x0555\x02\x0c\xad\x0dX\xa2R\xa5l QC\xcf\x08\x18\xe1\x19\xa4\xce\x0c\xe1\x93\xf8\x03\xd1\xc0l|\xf2\xfd5\xce{\xfb\xd3\xa6T\\t\xea\xbc\x95+\xe9\xef\xa3e\xbbn\xc5\xdb\xb8\x8b\x92\xc2Ps\xd3\xe8\x1fl\xfb3\x15\x99\x9d\xf9UO\xa9[\xfc\xdb\xee\xc7Z\xbb\xc9S3\xe5\xc0\x9d\xee\x9f\x9d*\xe8\xec,\x98\xaa\x86\xdf:\xc3\x9bZ\x1f\xfe\xbe\xc6\xd4L\x89\x9b\xac\x86\xd5\x05S\x9d\x9d\xf4\x15'\xcc\xb5\xe6\xe3*\x07\xf5\xf2\x8c*@\xa8\xf8\x19\x9d\x1f\xc4\xb1~xgno2\xb1\xb9\x19\xe1\x16\x88\xe2-\n\x85\x8c \xb3W\xb3\x14\x8a\xab\xbdV\x1c\x00;\xe4pZ\xe5\x049\x8d?\x13~\x84\x18\xab$\xab6\x9f<\x94\xb5Qr\x82bQ8&\xf3\x14se\x1b\x95\xc9Eb\xaf\xdaQ\x14,\xb7\xfe^|B\xb2\xb5\xef\xe7\xa2\x98\xefVd\xacV-\xb6(\xdc]\xe3 .\xef\xe8\xcb\x8e8\x1f\x12/qhV\xa1\x1bnR\xae\xf3\xaeQ\xc8D\x89*\xf9U(*1h\xe71\x14\xc3`\xd8\x9dQL\x12{\x07\x85\x81Uj\x0b\x0b`\x17\xe0\xd2\"\x9ao\x1e3\x00\xdc\xbb\xe6\x99V\xa8\x02l\x05\x85\xb5:\x1c \xd1\xed\xea\xc2\xd8\xc0\x0dja\x04Fa\xe0\x10\x9eE\xad\xb6\xcc\x9eZ\x88\x8bg1\xb1\xb7z\xfc\xb0\xcc2\xd6\xa0\xd5:\x04\xcdAu\xd9ZIf6\x96\x83\x012\xd5tw+\x08\x8a\x89\x89\x17f\x19\x81\xa7D\x8f\x8b\x1e\xef\xc9\xe8\x11\xaa\xa9\x11CL-}\x14g\xbb\xb5Z\x18\xb30>\xd2\x84\xf3xJ\xa2\xfd\xff\xc5>\\\xee\x90\xc1\xebQ\x89\xb8A\xda_C\xb6i\x82h\xdf\xd2b\x0fl]\x0d\x05\x1a\x876\xde\xd5\xde\x1d\xdc4\x1e*\x0e\x9aA\xcb\xaf\x16\xc9\xb0\xfcqX\x89\xa4\x047\x84\x1b\xbb\x14Y\xf2X.\x80-\xbe\x8a\xda\xd5\xb8\x95a\xc9\x87\xc3V\xe2h\x17\xac\x96iKg\x95\xd4\xcfqN\xb3R\xc4\x86N(r\x11'\xc1]\xbc\xe0%\xd9\x98\x84\x8f\x85\xad\xf4\x8d\x88@3\xd4\xcd\x80\xce\xc2\x81j\xa7\x16Z\xac\xf7J\x86.\x1f;\xfc\xe3nm\xdd\xfa\xaf\xd5\xce,S\xfb\xfb\xd8\x040x\xaf\xb3\xc3\x1f\x01\xf5\xf8\xd8\xcd\xbb\xa3OF\x0733\xad\xd2\xa7\xb6\x85\xab<$'\xdb\x0e\xbb\xb8G\x97E+\xb4\xda}\xa5\xa5\xce\xf3\xfa\xf3\xa7\x85'1\xf0f3\x9b\xc6\xfd\xd2y\xd05\xdd/&\xa4Z\x9c\\\x1aRB\xf47dm\xed\xf4]\xe6\xbc8\xa7\xa7\xc2\\\xcd\xfd\x01\x843\xdf\x82\x84\xc8\xaa\x98@\xf7\xeco\xbf\xfbT\xe9\xbf3eu^\x12\x1d\xb7W@\x8a\xaa\x15\xfc\x94\x96\x8e\xa6e7l\x96\x1e\x07!B\xe3,\xc0s\x82\xe4\xe61\xdc\xcd\xdf$\x9a\xe4\x1b\xf2\xaf\xdbZ\xa7\xe3&\xd9\x14\x92\xe7?\x03\xaf\xe2dC\xe9\xe1 \x9d(Y\xd0\xa6Sm>\x82J\"&pt\xde\xdc\x88\xaaP\xe3\x87\x84\x03B\x1b\x01F\xac\x14\xf8\xb4\x9d\xda\x04\xb1\xe0\xd9\xf84\x8cG\xe15\x9c t^\x1d\xc4\x86$\xaf\xde\xf2j-a\xe3\xa0\x8dg\x1a^\xc1\x0e\xca\x90C\xa4\x12\x96\x85\x83A\x02s\xd6T=k\xa1TS,|\x0e\x80r\xe0\xe5\x0f\x9a9I\xb7\x0f\xbdB\xcf\x98\x07\xd0\xac\x86\xf6'\x01\xc2\xecvG\x00A\xb6\xce\x11@\x90\xcdt\x04\x10\xc0\xcchQ\xd5Nj\x86&\x18\x80\x05\xe5T=\xce\x03xt;2]\xaf\x12P\xa1|T-\x07 L\xc3\x9e\x83\x92\xc9\xe7\xbf\xf1e1\x14\xe3\xdd\xbd\x04W\xc3Z\xc5\x9a*MrH5?\x84\xf1\x82=\xe0\x00\xfd\xd1o\xb0\x03\xac\"\xeb\xc69\xd1K5\xce\xf8=\xab'k\xc9-*\x07\x95\x84\xe8A\xa6\x12\x0f\x16E| \xfe \xde q\xd2\x94\x13\x91_?\\\xa37%\x1e\xf6\x8e|M6\xb0f\xaa+\x93\x93+\x92S*}\xe7W\x00_\xdc]3\xaa\xa8\xfa\xb6fm\xdc\xae\xd8\xd2\xcb\xb3\xd2\xdcm w!\x96\x97\xee\xf7\xe5.\xdbR#\x89\xe9\xac\xaa;\xc6\xed\x1f\xfa\xa6\xb1q\xa0q\xf371\x8a\x01\xd6\xe4$\xc2\x95\xdd\x99\xd5\xaf_\x19\xc0\xf3iK\xe0&\xecJ\xa9\xce\xacM\xae\x8a\xac\xf6\xde\x1a\xc7em\x12\xe5V\xc45P\x7f\xcf0>\x14\xbe\xbe Q\x9d\x15\xe7\xb55\xaa\x86W\x95\xa9H\xadIh\xd7\x1a\xe5\xf9&\xf94\xd2\x8dIl\xd3E7}\xe2s\xc8\xe9\xc4m[c\xc8\xbe\xec\x01\xa2\x84|\x8dd^ \xa2\xec\xf7%Uv\xe9\x011\x0f\xa6D\x07\x93\xb2>\x93.\xe8T\xac\xd2\x1b7*\xe9=t\x83Z\xb8_\xa7\xe3\x9f\xbe1\xd0\xa5:=0pZ\xfb\x9a\x066\xd2\x8b\x8aN\x04\x84t\x17\x14\x00(\xe5\x17u\xed\x0e\x1e\xc6\x9d\xad; \xc7B\xd2]\xb3\x91$\x80k\xa1\xda\x8c\x80\xc2.\xf3{\xaaF\xc4*\x03\x12/U\x1dZ\x92\x1f\xc6N\x08\xfc\x12\xe7\xa0\xa6|oq\x8a\xca\x15K\x97G;^\xd6\xe4\xbe\x9e9N\xa7\xfbe\x1f\xff\xedxK\x8b\x0c\x92\xa1\xa8\\\x87wh\xfe\xf8\xf1~\xa1\xf2\xf2Z\x02pH\xd4b\x91\x12\x8b\xcd\xe4\x89\xb8\x1e\x0c\xbb\x88\xdb[k\xb68\xe2\xc9\xcd\xcck\xf7\xe2.bX\x0f.Q\xbeXp\x02\xb8x\x0eYa^\xb5\x18\x02\xd0\"\x98\xd1#\xeb\x9f\x18\x99\xe3B\xb3\x10wnb\xa4\xbf\x11\xf3\xe5\x90u\xd3\xf0\xa0\xe9m5\x9eF\xb2\x0f\xbd~>\xc7\xd08\x1f\x05\x80\xad\xc1b\xfd\xfa\x8e\xe4N:\xddp\x1b4\x0b\xb5\x01[gv^\nB\xbd\xd3F\xd0Uz\xfb)?\x9c\xbc60\x8f\xd0F\xc9\xc9\x078\x98\x82\x00\xc2/\x042\xa0\x8cC\x088\xa8\x8c\xae>\x18\x9dN8G\xee\x8f\xcd%\x10l\xf3%\xe8\x1f\xdd5\xbaFH\x98{4\x846h\x1c\x04\xa7\x8e\xef\xb84\x8e%\xc6\x01#\x0d7\xb8\xe8\x9b\x1d\xf1\x8e\xcd\xfa\xcbx\x0c\xf3o\xba\xdcN t\xaa\\\x95'\xdf\xc8\xa8\x0f\x0d\xa8 \xfa\xe6E\xa3\x8d\x8e\xe6\xbd0#\x83\x12\xefj\xb8N\xc3\xa3V\xef\xd3\xb9d\xe0?WlcW\x90\x81\xd7\xf0\x8b\x0b\xc4\xed\n\xc5\xbe\xbd\xd6\xb5\xb5u\xfb-\x93\x06\xbb}\x0f2\x842\xa8\xb6\xa5EN\x90\xbf}#\x87\xe4\xb5\xb52H^a3\xf0\xf5\xbb\x19\xa5r\xbb\xc1qs\xa7\xa4\xb0\x88\x84-\x8fS3&\xc8\x04\x14\xef\xf4\x84f\xb4\xed\x87\xa3\x0e\xcc\xeb\xcefwl.\x9a=W\xf88\xe5\x84,\xf5\xe0\xd2cH\x03\xe1\xaej\x9ecT\xea\xb1W\xae\x0e\x91\xd7\xa0\x05s\x819\x0e\xf20\x9e\xee\x94Z\xe0D\xceM\x11\x93\xfa\xbeC2\x92ZM\x92\x8d\xdd\xfb\x90dj\xb5\x8ct\x9f\x16\"8\xc0:g\xed{.\xc6\xb1\xb0\xd01Fb6\x831\xc78\"\x06y\xd4\xa6>\x98\xf5\xbf\x0c\x92\xadW\xc09\xa3\xeb \xd3V\x9a\x1a\x8a\x8a\xf6\x0b\xaf`\xd7\x12j\xbf\xfd\xae\x16\x9a\x8f\xbfT\xf2\x94\x94\x91\x91\x80\xb2\xb5r,n\x83\xa9i\xc0\xad\xc1\x0d\x0d\xa5\x16d\xb3\x85 \xff\xf4\xe9qN\xa7\xaa\xdd\x0c.g\x04+ \xefS\x07\xc2\x1a\xeb\xbc\x0dQ\xfa\xf9\xb7\x81\xbe\xeb\x0f \x0d\x81\xe1K\x02aB\x08\x01\xbe\x8c\xdb\xe0?_\xed\x8b\xdbQ\x8dE \x87\x93\xb5r\xb8\x86\xffj\xa4\xee\x82h>\xf4\x95E\xa6\x90\xd3\x9b;\x13\x8fC\x9d\xd7\xad7\x7f\x85\x8b\x1c\xb7^q\xaf\n\xc6`U\xafe\xfa#-\x9f\x98\x18\xb7;oJ\x98\xc4\x8b\xe3\xd2\xe6\x8e\xd4\x9d>)\x0b\xc7\xfd\x82;Jg\xed\xa3\xcf\x7f\xd7\xad9R;Og\xed\xa2\x1f\xc5\xfdiI7\xfa}\x97\xe28K\xa1\x92\x9c\x1f\xdb\x81\x04q\xa6j\x8f\xb9\xd1e\xd8\x93\xa3+\xd9\x97'n\xf1\xcf\xb7k3\x8b\xc1\xad\xbb\x07\xfceF\xcf\x81\x03\xfb\x05\x9e\xec\x0e\x850\xb1\x9a\xf2\xaf\xdfV#\xa9\xed\xc6p\xa5MAzb^P\x8e\xf7V\xcfu\xa4\xdb~\xde1u\xba\x97\xd2\x93\x95w\x1en\xc8 ^\x9b.II\x97\xa1\x8a_\x1c\xc6\xcc\xdavdW\xae\xc8\xf6\x8f\xf3\xce[Q,\xcd\xde\xe8+L\x0f\x04\xbeb\x82\x16\xed\xbe\xc9\x02\xa5\xe5\x84\xc6\xc4\x87q\xbc\xfe\x0d9\xabV\x1c}\xef \x94\xce\x8fV\xd1w4qU\xe43&j\xdb\xc4\xb1HYb\xbc \xfc\xb9\x88\x0b\x15\xbft\x15t\x8dT\x9c\xf5\x887\xcf\x81\xf2\x92\xab\xd9a\x16rBwP9?)\xdbu\x95\xe9\x8bT/\xd9a\xa3\x95\x8eA19\x96\x11\xb1k\xaaM\n\\\xd3\xe4P\xdd\xdfs\x9b<\xd8Ta\x9e\x8d\xd0\xe3@\x82\x85\x0e\xf5q\xb1\xd8+\x1c\xfb\xa3=\xd9[5\xc4\xcd\x94\xb7\xb6\xd6\xd7?\xb29\xa3W\xc0\xc9+^\xfdo\xaf^E\xe0\xe38s\x81)\xe5\x8ff\xe7\x0b\x972a\xf4\xe6\x01\x16\xadQ\x9f\x05x\x01\x1a\x7f\xa4\x17\xb7i\x87\xe9& NE>\"^Na\xe4a\x9f;f\x8a\xd9\xcc9]NE& t\x18^\xb0\xc0CL\x1az'\xe2e\x858ZR\xf1\x07s&6\xde\x02\xb27_\x00\x1f\xfc\xc3\xa3cyJ\x9e\x911\x1a\x0d\xc4\xfe@TZ\xb0?S\x00D2\xfb\n\x1a\x87|\xd4P\xf5\xd4\xcbO\xd3\x8c\xe9\\d\xaa\x1aR\xef\xde\xf0\xfb7zH\xd5\xf8\x83\xee\xb19i\xc8\x03\x00\x8bQ#\xb5\xbf\xb6\x82zr\xb3\xf3c.\xf24\xf6\x86G\xfdR\x9d\x134\xce\xc8qx\xa6\xf0\xbe<2~X\x92h\xb5\xf7n\x08\xe1\x19\xe3\x19\xe0\xa9\xb3\xa8\x06\xc52\x88auB\xadNC\xd1\x00+\x9b\xa2k\x97X\xf30\x0e\xd1\x0d\x18\x13aj5n\x03>\xde\x89\xa8\xf5\xb2\x12e3\xf6\x07\x11v\xde\xa7\x17\xd3\xf4\xe9<\xa5>\x81\xb0_\xb2\x9f\x90\xa0\x07\xdb\x0cuH:\xa0\x04\x90XR\x9d\xff%~9\xe1\x04!4\xf6\xfco\xd1\x0f\xd1\xbc\xa6\xe8\x1c\x02\x003\x85\xba\xe2\x948?\xb6\x82 \xce\x1f1\x01d\x1a#\xef\xd4\xd1\xfc\x1c\x96\x9aA&\x8b\x84\x84{A!i6\x0b\x8b\x8c\xed\xdc/Xa\x9d\x9f\xa3\x1a\xe1\x05\xe3\x87\xa4=\x12W\x16\x89;|\xef\x04\xf0\xe4\x1a)\x81 \xd0g\x16\xbe~\xa3\x0d?*\xbe\xe6\x82\xbd\xc3 }\xbf\xe3\xda\xa7\x88K\x11t\xcc>5|\xadE\x8e\xb5\xd0\xee\xd1\xdc\xd5.\xa7\xfd\xf4A\x07\xfb\x9a\x0bQ\xf16\xfc\xfa\x0d\x02\x07\xb2\x80\xbe(6\x1a\n\n6\xd1\x94\xc67\x00\x96\xda\xf7<9\xf9\xf9_\xf0\x95C\xc1\x0cf1\x0f\x19\xfe\xeb\xd0\x8e\xe9i8\x15\x06\xbe\xae\x86\xe5\xbb,\x0dV\xbb4$\xc0\x9fut\xc9\xf8\x9c\xf8\xa3\xc6i\xc1,.`v6r \xe2\xa3\xf2\x8eP\x0d\xaf\x1a\xbdgFB\x90\xc9\x8e\xc7\nt\x1b\xf2\xc3\xe7\xda\x0dC\x013\xbd;\x98\x0c\x1f\x04\x18,\xbco\xc3\x82\x93\xe6\xe3\x9cx| \n/K\xf3Mp\xa91S_\xbe\x91X.f\xf7V\x8d\xaa\x86#\xbcU>\xc8\x92\xc8\xf5\x88#B\xf6\xf1]\xb5\x0dA\x15\x1d\x8f\x91IVo\xc0\xcc\xd0\x86\xcf\xb5\xc0\x91\x14\x15\xbf\xfcGTV1nr+\xa3\xceOX\xc2S\x95%\x0b\x8b\x9b\x04\xc2\xb3\xb6\x99f\xa7OZ[\xdb_\xfd9\x9c\xfb\x11\x91P\xad\xdf\xb0\xf7 \x0f{Gl\x11n\x91\x05%\xdf#\xda\xdbh\xc0dw\xbfH\xa0\xf9=\x86\x7f \xb8y\xa9e/\xed\xaaW\xbc\x19\xb3\xb4\xb6>\x7f\xd2,\xd3\xf6\xac\xb0IP,*MV\x95\xf0\x84~\xc2\xbaK&\xe3e\x15\xa2\xc4\x8b\xbb\xfbM\x06\xec\xbd\xa3=\xf2)\x16\x8bqF\xbf\xa0S\xb6\xdf\x08\x1b\x05\xb4\"\xc9G\xd1\xebT\x9aF\x99\x8d*\xb9LX,h\x8a[\x97\xb4\xba\x93\xa7w\x8ew\xb4\xede\xf1WQE\xd9x\xda\xeb\xba\x0c?\xe1\xe8\x93{\x10^\xda\x86E\x8ex\xefh\xbb\x9di\xfd\xbb\x05\xa2\xd7\x82\x8f\x12\x84J\x94\xb3\xc3\xc0H\x8f\x07\xa5|\xf3^\xd9\xcd\x93\x8a\x85\xc9e*^\x89\xd0\xaf.\xe3u\xdaxE\x99\xe8\xeb\xcbb#\xee;\x9b\x92\xf4\xd4\x9d<]z]\\\xed\x83\xd7\x02\x81\xa8\x7fw\xdaN\xbbho\xbcchq\xb8E\x98\xa3=\x1e\xba\xe7\xe2\x134Q1\x1f\xb87\x0e\xfd\xdd\xe7W\xfc\xbd\xcc\x93l\xc3\x956\x8f\xe1\xa7\xbf\x14\xad\x12HE_\xcc\xa3\xa0\xf9qy\xff\x89\x1e\xe1\x0bY\x06R\x8e\xa4\xdb\xab\x1a\x18\xe49~l4s\xe6Vy\xf9\xad\x99`\x8a\xd7U\xdf\x9b,\xf9\x9f\xfe\xf1\xd7\xc5#_\xcau\xb4\xf9+De\xea\xea\xed\x99\xe0\xe9M\xd9\xfc\xa2~\x03h\xb3q\xaa\xeb\xb2\x87\x92\xb7#Y\xfa\xca\xe6\xf1z\xfc$;\xdb\x0c5\xcd\xaf9$\xb5\xcb z\xb2\x1d>\xff\n\xbe*j\xf5O\x9f\x8d\xf8\x8c\xf1\xdb$\x9c\xd0$O/\xaf\xc0\x0f\x15\xc3xR\xed\xbd\x83\xc2t\xfdf-}*\x9eo\xef\xc9\xa6\xf8\xd9\xcc|3\x86M;\x15x\xde\xa8\xafU\x94\x95\xb5l/.\x14\xf1~X\xc7\x8e\xafY\xe1\xbc4\x99x3&\xe6\xeb\xd7x\xae\";\xa4$\x8dKI\xf6\x925\xdbd\xda\xad\x0c\xbd\xca\xe1\xfc\xfa\x8b~w[\xca\xd4M\x19\x1f9O\xd8\xe3%4\xd2\xe1Q\xa8\x1c}\xe9\x19S^\x9e\xect\x96\x9d\xe8@\xd1\xcb\xe6\x0ew[\x9bY;-\xdd\xf6\xff\x8d\xc0\xbas;\xa2b\xbe\xcdwH-*\x05\x0c\xef\x96\x96\xc3im\xbd\xb6I\xca\x08-\xb6\x1f\x7f1e/\x95~\xf8\xa8TNN\xae.\xf2p\xb2\xdf\xf0)H$\xfb\xeb\xabW\xef\xdf~\x8f\xce\xf0\x03\x90\xb5\xc9\xc6\xa6\xed\xbcO\n(\xa0\xe99\xe8\x86,\xd9\x0d]gM6r\x1d\xea+\x84#\xbb\x07%\x83\xe0/s\xfcw\xafA\x18\x9c$\x11\xf5\x8cq\xc64\xcb\x11\x07O>\nd9}\xf7\x9d\x13+\xf0\xd1$\x8cs\xf4\x9a\xb3\xfd?\x030\xa3\x99\x14a,>\x9dy\x8b\xb9\xda\x88s<\xf0\xfe=\x86,\xf0\x8bc_*\\\xe2\x83D\xed\xbc\xdc}\xc82\x19M\xed\xb0\xcd\xccT8\x17/\x12\xed4\xe6g\xe6'\xda\xa6\x9e\x9d\xe28'\xfb}\"\x8bC\xe2\x03*\x84\\9\xbd#Y\x8f\x1f>z$\x8e\xe6\xf6\xd47c[s\x93|\"$}\xbb ym\xcc\x16\xef\xd5\xc0\xabzQx 5\xb7%\xe5\xa0o\xf9\xe5\x93$j\x86k\xd0\xcep\x12)\xf1x\xbd\xc4\xfb-:\xba\x86\xd0\x98|?\x9d\x98o\xe3\xf8f\xa7\x87gFr\xc0\x9e\xdf2\x15\x1a\x8aS\x91\xc7Z\xf7\x8c\x02\x11q}q\x88\x8a\xb5 \x85o\x80\x1d\x1f,wy\xc5O\xa1g\xca\x13\x90CF1\xd6l\x98\xe7\x9f'\x06\xedL5T3\xf5\xf23\xfb\xd1\xf0y\xaa\xa6M\x899\xda2\"s\x94\x98\xf25\x14u\x1bD\x95\x8b6\xc0\xd4-J\xec\x89U\x08\x86b\x05s\xba\xcf\x18\n\xabO)\x83\xcc\x16w\xb8R\x0d-2\xe6/5f\xdc<\xaaBQ\xcc4\x16k\x8c\x98\xea\x90\xad\x9dG\xb9 \x13\x1f)%\xdf\xbc\x0e\xe3\x7fr\x92\xcf\x9bf@\x07\x1f=\x9a\xe2BF\x99\x8b\xefCB\x00\xb1\xa9\x89\x89\x83\x87&'\x87F}\x19@\xa9&\xd3\xc8\xff\x19\x04\x84y\xd7ub\xe2\xd0\xc1\xc9\xc9C?'\xab\x1e\xea\xe5\xf1\xe7\x18S\x01\xe649+\x97\xc3\x93\xe4\xb1C\xf8\xae\xb3\xedI\xc3\xae\xf0\xa4\xd9\x1f\x8c+\xd7\xe7\x98\xebf\x05/R\xab\x06U\xea\x0d\xcc\x12\xeeC\x0b\xb0\x01Fu:\x14C\x11*\xa3}\x0c\x86T:\x1f\xba\xb6}{\xc2\xdc\xdd\xbd\x01\xe2\xb2\xb7\xd4u\xaa\xce\xd7\x17\xf8\x95\xace[!\xae\x96>\xfa?\x0b\x8b\xc4\x0f\xe5\xfd\xda\xb8\xb8\"\xc7M\n8gz\x83\xf40\\Hk\x83\xd4\x06Z\xb3:\xc4h\xe5\x02\xad\x1b~\x99\x03@\x13\xaa+\x1d\xf4#\xabN\x9d\xea\x0c\xd6fj\xbe\xe7\x18y\xb5\xee\xe5\x8bio\xc0!\x84B\xf7 \xfe\xf1\xf4\xb7\x93\xb1R'\xa95>\xda\x13\x03`\xda\xf2[!\x1a\xc2\xc4T\x18\x88`m\x1fC\x01\x9a\x9d\x0bI\x85\xd1\x9d\xc3}\xb8n\n\x8f>W\xdf\x10\xf4\x01!M}\x18U\xcbav\xf5\xb6\x014\x90\x803)!\x10\x04\xa7\x01\x0ek\x1bc\xc8\x82\x1a\xb2\xf3m\xfe?\x92\x8e \xdd\xe5d\xef\x18w\x95\xe3v\x17\xab!\xd7\x94;X\xcf\xa1\xdb\xa8}\xbd\x1d8\xedvt\x95\xeb\xd0\"\xd3\xbc#\x0ck\xc2v\x17X\x8aJ\x17\x99\xb1[\x93l\x9d\xb6[Z\xdd\x99M\xc3\x80\xa7\xf1\xc3\x16XC\x073l\xea\x96[\x0d\xc3Ta\xbcVj\x8b\xa1\x85\xda\xca\xbb\xa5\xe5\x18\x01\x8c\xd1\xac\"\xc5\x93\x17\xd1\xf2\x0bt:\x15\x82(\x9e\xea\xe0\xa6\xc8\xc1<\xbe\x08\x06cZ\xf3ve\x97\xfdQ\x9b\xc7\xeeT\x85\x9f\xa0qH\xe1\x91i{\xa0\xd2\xe9\x8a\x80Q\xe5\x9f\x93'\xc1\x93\xc3\x96\xbb\x93i\xa0\xf6P\xd8\xf6\xef\xbf\xad\xe8\xfc\xc8\x03\xaf\xe1\xedmK\xcaA\xe7I\x8a\xf5\xa4\x19\x8f\x90BF\x83\n\xa3\x15\x05=\x89\x89\xb5\x07\xe2\xd6\x07T\xe1\x85\xbd\xb6\xe0(\xe2\x0f\x9c&TS\x10\x9f?/\xef\xd8\x81A:\xd6\xb7\x1e\xac\xbb\xd0\x9eV\xa7(\xf8\xf7@w\xef\x0fF\x07a^\xe3\xa6]\x85\x8c\xb5\xe4o]*\xd3\xf199\x16\x16\xacR\xbfi\x0e\xe1\xf1_\xd4\xf2\x98\xc0\x99\xfe\xce\xcb2vM\x93\x80\xd8`P\xa7\x93\xf4f\x03\xa6\xb4\x06{Q\x06Y\xcf\x16\xab\xedH\x7f#V7v\xc57\xcc\xd2\xb0\xa0q>@\xe0\xf3\xab\x18~u\xc9\x98\xd7\x86Ax\xb0\xc3/\x83\x02\xabx\xd9\x08\xb0B\xfe\xe03\xa3\xc4\xa0\xd9\xf4\x89\x9dt\x83\xca\xc1y\x1d\x86b0\x8c\x9e\x16nG`\x04\xc1\x0c\x18\xf2\x04E\xda\x04D\xec\xd9\x8d\x1a\xe4A\x92\xd4:\x0c\xc6P\xd8\x10\x05wI\x1f\xd37\xcf\xec\x10nW\xd3\xf72ED}.(h\x95\xdc\"\x82\xf3\xe3U]\xa29I\xedh_\xeeV\xaf@\x87\x9bGZ\x100C\n\xdcp\x15\x13b\x0d\xf3\x1b:\xe3\x99L\x0c3\x8d\xa1tN*\xaaN\x0c\xbd2\xbf\xd3!\xbc3\x8c\x8d\x0dCa\x18\xb3\x97yn.\x95\xca\xdd\xc9\x8b\x7fW\xe2`\xcc\xb3\xdc}\x18\xb1QB\x1b\xccC\x8f\xaa\xc3i \xc1\xa18*\x08\x02\xc3\xef{57\x89\xb9\xec\x05O#aT\xa2\xcb\x1dB\xbd\x9f\x82\xbdU\xedo\xfei\xa70\xe7\x0d\xf3_\xcb\xf0\xd1\xf9^\nChrU}~r\xc8L\x19 1\xf2z\xff>..\xf6=\x1c%\x16G\xc1\x9a\x9bG\x8c\xa3\x0b\xeb\xfco \x99\x90\x87\x0c\x18\x8cE\xe9u\x91P\xb3\x05Ps\xd8\x98\xde\xb8\xe8\xf38\xad\xf0\x03\xfc\x05\xfeP\xa8\x9fu&;\xe6\xca*\x8c\xeb\xf9|i&\xa4\xffPb\xdb\xc8\x9b\xb0\xb2\x98h\xd2;\xb4[\x97\x80|\x18y*c\x83V\x9ah\x86\xd2\xbc\xd2(\xff\x94~\xce\x16_A\x95qU2\xb7\xbd\xff\xf4GIQ\xc73`\xae^\xcav\xfe=\xee@\xac\x0f\xdcK'\xa4\xb5\xd0\x87\xe8\xcbZ#\x084sJ\x02=\x0f\xba\xa4:sY\x05\xa9\xe8 \x14s\xda\xa5b\xc2yj\x0c\xaf\xeb\xb7\x1bS\x1f_E\xdc\x83\"\x8e\xaa\x8b\x8a@\x9e~\x82\x9f\xe7\xb9\x08>\xad86\xba\xf1#\xcey\xb1\xda\xe4\xe5[\xef\xe8c\xf2S\xef\x84\xa5\xd9\xc5\xac\x96\x90\x94\xf2\xf2#\xadSJ\x94GZ\xfb\xaey\x19vv\x12\xdd\xdfS\xf9\xd1\x8f\x1a\xe6\x89\x9dp\xb8waT\x9a\x9e\xcf\xf5\xc5/\x13,\x1f\x14\n9'Jkv%%.\x86~o\xf2[\xcc\xf3\x9f \xe8\xa1\xa7\xfc\x1c\x9c\x13\xc2R\xb1Bj\xa2\x9fS\xe8\xc8\x80*$'\xf8\xe8\x85\x81\x08\xa9p\xc3\xa7S\xa5u\x00\x0b\xe0+\xe7\x079\x18\\\xac\xed_f+\xe5\xf2\xfc\xf98\xf5\x10u\\,\xb6\xca\x14\x8f\xd3t\xe6\xe5\xf0p\x9e\xd1\x8d\xd0\x1ek\xd8\xae\x13J0h\xf3(]\x18N\x11\x84Q\xc8v\xf3\xb3W\x1f\xac\x81\xc7\xcc7\xf3\x0c\x958\xab\x836:\xdc\xd6\xdd\xa3\xcf\xe2\x0b\xb7\xf1Wc\x93\xafY_i>\xfa\xac\x8c\xdd\"\x91\xdfR\xa1\x10\xe7\xf5\x92\xe2\x81(\xd3e\x18]\xde6\xf8\xb9\xaa\x04RA%U\x976&\xb4F]\x94\xbd7@\xcc\xb3k3X\x0dh\x81?\x8c\xc1K\xef\xe0\x13\xae\x04\xde\x00\x1eQ\xa42\x99B\x08k\xbe[?\x0f.\xff\x1f\x80\xc3.K\xa1\xc8KAb\x8e\xcc\x7f6\xfd\xde\xc4\x14\x1f5\xbf\x7f\xb7k\xf2\x92e\x8e+]\xb2F\x16\x8e\xb0e\xf6WH\x04\xa9U\xf2\xab\xfb\x070O\xdd\xd7\xa7\xbe5\x85\xb4\xf8\xff\x0d\xa4\xfa\xee\xe4e3H\x87\xaeco\xc7>l\x16]0\xb62\xb1\x88c\xfd\xb9\x87\xddH\xca9\x9a{Z\x0d{sO\xf5\x04\x96!\xa5A,\xfe7\x86?\xc5\xb73\x00w\xe4\xbf\x8eA\x1c\n\xe0Fj\xda\xff\xb88\xb8B\x16\xed&8U$\x06\x11G\x85\xa1\xc2\x00\xb5\xd9\xdf\xe9$\x1b\xb5Y5\x98\x82\x18\x86\x0f\x0eF\xe2\x11L\x855n\xc7\xec\xb2\xd8\xf21\x96\x94>\x02\x0cq\xf3\xba2\xa3\xa3.\xab6\x93\x03e\x97\xe9\n\xee\x0d\xec\xbc\xda\xf5\x97\x9c+\x98\x96@/\xac\xa2\xf0\x99\xb5k\xedb{\xe0\xf7(\x8f\xc57\x07\xd0i=\x1b\xa5\xc9{l\xcd\x8d\xac\xdd\x82\xad\xe2\xce\xe6\xbf\xa6\xef\x19\xa08\xab\x03\x851g\x9d(\x03\xbb\xfc\x13\xe8%\xce\x02\xd3h/\xebEf\xb6M\xb9\xd2\x8d\xddt\x9f\x005\x0f\x1f\x14\xbd\x9f\x1a\xcc\xbcvg\xbdo\x03\xda \xea~\x01\xe0\xa9\x9bWKi\xe7\x88\xb6U\x07\xab\xdf\xd8\xa3\xdd\x96\xadw\xacRS\x82E\xecF\xed\xdfT\x1f\xac\xb2%\xaa\x0d`=\xed\x17\x18\x8b\xf8|*=1\x82\xf2*\x8e\xf9\x16\x1f\xbb\xfd\xb7S\xa7X\xf6\xac\x80\x1e\xb7\xd8^\xea\xf2\xd3w)l\x1f\x96\xc3\xd6fQ\x9dH\xe3\xfa\x8c(\x14YS\xfe\xf4\x84S\xcb\x8cK\x8f\xb7\xe61\xde\xd8\xe2\xedW]\xb5f\x99\x9f\xb7\xb07\xd7\x9a\xb3^&\x0f\xfdp\xf4@T'.\xec\xc0%3\x8d\xb3\x95\x84\xc3\x0d\x9a\x9d\xaf\xb4\xdf\xde\xf2\xbb\x11\xf95\xcfzaTf6\xd1\xeb\xa9A5\xdc\x19L\x95\xf3X\xcc\xa1\xe6\xb7\xc1|\xf1\x08L\xb8\x7f-\x9f\xe5\x96\xce\xb7\x07\xea\xc4\x1aT\x03\x16\xd7g{A)\xaa\xee\xad\xaeF\xd1\x15\x95.\"\x14h\xfc\x18\x93\xf9j\xa2\xa0A;\x10.\xf0\xe2~\xc2\xfe\xa0\x85o\xde%\xb0\xe8\x0c\xfdG#\x1a\xd1}&]\x02\x1a\xde\xd7\xbec\xdc`\x0fC\xbbhH9xnN\x86\xb7Y \xce\x12\x17l\xf0\xb2c\xde\x14\x03\xa4\\+v\\E\x9f\xa5\xab\xc6\xa71\xa6D9K\xb7X\xe1)2b\x01.\xbf\xf3\xad\x93N\xf4\x07\xda\x17\xfdW\xa2\xa7\x8e\xdcQ\xd7\xa9$\xa5/\x05\xa3\x94\x10|6t\xc3\xb0\x99\xc332\x14\xd4\x9b\xa3\xb47\xa1\xa1\x17\xa6\x00\x962\xb8\xd1\xdb\xd0\xb8yu\xfc0e\xd7\xf1\x80)\x92N\xd8uh'd\x9c\xb6\xc3\xee\x84\xf5\x81\x1f~xY\x89\xc9\x0b\x1e\x00\x90\x91\xb4>\xc4\xda#\x0cb\x88\"k3\xd3\x0e\xf0\xc2\x0c\x03\xbc\x83\xae\xcc:\x13\xa09\xbf\xba\xa2v\x13\x0f\x88\xfa\x06$\xd0\x9fC\xdd:\x14\xca)H\xb9\xcb> \xd5\xa6\x9az\xc7\xdb\x1c;e\x93d\\j\x17m\x1af\x9f\xe4\x18O\xcfa%\xf29\x9a\x91\x88\x04cK\x9bx\xd3\xd0\x0f\xdb\xa5\xc5!k\xa9%H\x81\xdeDn\x93\x10\x7f\xfc{Y\xdc\"\x93\x17{n_\xd6}\n\xdf)9\x83=\x0d_/\xfb\x1e\x87Z\xce(\xe9\xf9>\x16l\xfa\xb6\xad\xf7Y\x9e\x06\x9f\xd6V\xf7\x8b\x1b\x06gQ#\xa7\xdf\xad:Q\xc4\x01\x95\x17\xc8bw\x07\x83\xc7\xf7\xd5$\xbe\x1bzw\xb1\xf0\xd9\xae\x8b#\xbf\xbb\xe3\x7fU\x14\x98?|\xc5\xf0\xefG\x08\xd4\xce\x05\x84h\xc1\x1e\x7fz\xfc{\xf9o\xba$w\xf1\xd7\xcf\x9c\x9d\xb4\xba\x04\x1c)|Vh\x89\xda?\xbb\x8c\x0d\x14ZV\x8f7\xbe%\x9f\xfcG\xfbo/\xa3\xd7\x86\x87\xf4\xe9E\xcf\"\xb9K\xd3\xb2\x85\xa0\xec\x15\xb5\x08l\x06\xa5p76\xce\x00\x1f-z\x0d!\xc1l\x804\x17n>\x94\xbc$\\\xe1\xd7zV?sz\xfbqej\xecQ\xe7\xeb\xe9]m\x8b\x9b\x04\xe6^\xe6=^\xb5\x0d\xe4\xa7\xed\xad\xa5!\xa0\xb2\xbal\x85\xf4HB4sL\x0bi9}\xde\x1d2\xa2^\xd7\xfdK\xd05\x04\xc5OB\xfa)\xe8\xedO\x0d\xad\xe7v^~\xaa\x12\xea\xb5\xfd\xef\xdd\x80x\xa6\x93rm\\\x1eK\xda&G^\xd0\x075\x8fC\xe7\xd0\x10L\x1b\xbc}&F\xba\xf2\x94\xc0\xcb\xe2\xa8B]K\x86\x14\xa1n3\x86\x86|\xcdsGjy\x1a\xf0\x16k\xfeO\xaf\xb5\x16\xdab\xe5s\xdc\xbd\xe6aW?R6\xf0\x12\xa1\xb7\xb2\xbeJ\x90\xc2\xc7fh\xe3\xda2 \x0c\xc4\xcalBS\x1c\xa7\\=\xa2j\xd5\xd5V\x97\x1e\xca*\x94\x1f\xf4Y\xa6\x93\x14^\xa2\xa2\xc1\x99\x04\x84\xcb\xba^\x1aE)\x07\xd5\xe8*\x94\x03\\\xbd\x9f\x04\xa0\n\x03\xc2\x14\x82r\xd4r(a\xa2\x1d@\xf8\x05\x16\x08\x846n\xd4\x8c\x14\xa3?\xa5}\xdadL\xb0\xa9\x17\x1e\xa6\x81\x16\x9ag\xa2\x0eI\x1dvq\xd8Nc\xd0\xc7a\x8d\x91\xc6\xaek\x8c\xcd\xf7mL\x8c\xf6\x7fc\xc1A!\xa4\xb1hd\xb8\xa3\xb1V\xeb\xf0\xb5\xb9\xce\xf2wc\x03=\xa2\xa6\xe6\x86\x96\xe1\xe6\x16\x96\xd5s_\xd2:\x8a\xff\xd2\x97\x95\xa2sL\x1f\xcb\xed\xa3g>\x91\x9c\x971\xdc*4-%\xf0\x13&\xcb\xf50\x11\x08Ub\x16\x83)E\xdc\xac\x8d\x86*\x19b\xb8\xd4\xd6\x0651\x97\xc4\xef\x84\xe7 \xe4+\xe8+;\x98\x8e<\x85\xab\x86\x92`!q\xb0f\xcd\x1a\xceM\xf9*\xc6,[/GK+\x13\x07{\x17\x04\xc3\x12\x97\xae\x8d,>C\xe2L\x13\x81\x8c\x1b\x01\xf3\x9dR%%c\x8c\xb3\xc2\xc6\xc3~\x91\x92'EG\x8f\x86A\x89\xaeG\xba\xc2=\x87h\xc2\x12\xe4\x9f\x94\x8e\xb08\x1c:ID\xecN\x02)\xc5W\xcc\xbb\xe1AF)ucw'qh\xcdX\x1f\xc3\xa8\xb2L@a\x84\xbe~\x8c6\xccPc2L\xe3\"\xa5A\x08\x852b\xec\xc8U \x99\xc0&\x8c\x13\x80\x8b\xff\x0c\xaf9\xf6A#\xd3QLO\x07\x04\xac:\x81E\x14\x809k\xa7\xa9\x92\x91\xc6\x1af\xdeKF\x95b93t\xbaL$c\x89\xcb\xacp\xffLz\xff\xa0\xbf5\xd4d\x12\xdap\x08\xa2\xfe\xf0\xf9\xdb\xb0>$`\x9c.\xf7\xef\xab\x1d~X\xf3\x07=\xb6\x17\x00\xa1\xe3?\x84\xa0\x18N\x90\x14\xcd\xb0\x1c/\x10\x8a\xc4\x12\xa9L\xaeP\xaa\xd4\x1a\xadNo0\x9a\xcc\x16\xab\xcd\xeep\xba\xdc\x1e\xaf\xcf\x0f \x82b8AR4\xc3r\xbc J\xb2\xa2j\xbf}\xf8\x9f\xd0\x0d\xd3\xb2\x1d\xd7\xf3\x830\x8a\x934\xcb\x8b\xb2\xaa\x9b\xb6\xeb\x87q\x9a\x97u\xdb\x8f\xf3\xba\x9f\xf7\xfbA\x08FP\x0c'H\x8afX\x8e\x17DIVTM7L\xcbv\\\xcf\x0f\xc2(N\xd2,/\xca\xaan\xda\xae\x1f\xc6i^\xd6m?\xce\xeb~\xde\xef\xf7\x87\x11\x14\xc3 \x92\xa2\x19\x96\xe3\x05Q\x92\x15U\xd3\x0d\xd3\xb2\x1d\xd7\xf3\x830\x8a\x934\xcb\x8b\xb2\xaa\x9b\xb6\xeb\x87q\x9a\x97u\xdb\x8f\xf3\xba\x9f\xf7\xf7\xff\x00b$\x9c\xabtV&g\xae\xcf\x96\xed\x7f\xc1r>\xbf<\xd9y\xf3\xe5?\x8f\x92\x19\x93\x98\x8d\xfbf\xfe{\x9d\xe7\xb4\xb7\x9d\xa3\x00\x89\xb5\x11\x9b\x9e%\xee\xb5\xef\xc7\xcc~\xdfZ\xfb\xfea\xc5zW\xbe\xbf\xbc\xf7\xdc\xf5\xdd2\x9f\x1d\xb5sv\x90\xef\xc0\xcc\xf2\x1d\x90\x99\xd9eW\x1d\xab\x00\x89\xb5\x91\xe0\x02\x00\x00\x00\x00@DDDD$\"\"\"\"bffff\xd6}\x03\x90X\x1b \x0e\xd3O\x01\x840\xc6\x18cDDDDD\xac\xb5\xd6Z\x9b6W\xf208B\xd6\xe7\x10I\x1b\xa5\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x90\x13\x00\x00\x00\x83.\x01H\xac\x8d\x04W\x08\x00\x00\x00\x00\x00\x00\n\xa2\xdf\x88\x13\xc7\xd09\xa0\x00\x89u\x84*\xa5\x94R*J^}\x80\x1e\x14\xc4:M\x94\xb4$I\x92$I\xd2\x0eF\x82\x8b\x99\x99\x99\x99y\xd1\x9f\x9e\xfb\xde\xf3\xc0_W\xcd\xc6\xfd{\xef\xed=\xebSAE@\x10EQ:\xd2{ -$$$\xa4\xf7d\xfb\xee|\xe7\xcc.\x1a @v\x130\x819\xbf\xdf%d2\xf7\xce\x9d\x99;\xe7\x7f\xce\xb9\xa7\x08xc1\xfeB\xeaD\xedJ\x88\x18\x06Q\x8c\xa1\xff\xdb\xa1\x10\x0e\xd2\xcfE\xd4\xbe\xa6V\x85\xd6N6'\x82\x83\xf5\x983\xa97\xa2\x8d\x1aT\xd9]\x90I\xa6s\x91\x92y\x9d\xef/\xc4?\x17m\x03\xb4j\xd0\xb7,?\x94s\x9cT\x7f\xd9\x95\x05\xe1Ux<\xf7\xa2\xc6\x06\x02\x0f@\xad\xf2\xfet\xb8\xba@\xab\x9a\x0c\xa3\xee\xdft\xe0>\x02\x97/\xe5\xd7$\x93L2\xc9$\x03\x88\x97\x14\xc2O\xb0:\xc6\xb1t\xde\xa7m\x0cF\xa7F\"\xce\xa8\x83\xd3#b\x7fE-\xe6\xec-@IQe\x14\x82\x0d_@\xa9\x88&`yU~U2\xc9$\x93L\xe7;\x80\x08\xc2[\xb0\x10x\x10X<6\xba+n\xe9\x99\x8c\x04\x9d\xf2\x8f?{\xa8\xdd\xda= \x0f/\xdf\x8bE;r\x81`\xfd+\x048\x9b\xe8\xf0\n\xf9u\xc9$\x93L2\x9d\xbf\x00\xd2\x0e\x1e\xcf\xddp\xb8\xf0/\x02\x8f\x7f\x0fh\x83JB\x8c\xf7v\x17`\xfe\x9e|\x98u\x1a\\\xdf3\x05\xa3\xe3\x83\xf1\xbf\x89=1\xd5\xed\xc6\xca\xddy@h\xd0\xe7\xa4\x85\xa4\xc8\xafK&\x99d\x92\xa9\xe5\x90\xe2,_\xef\xef\xa8\xb1\xa2g\xbb\x18\xdc\xdb;\x05\x15.\xe0!\xd24\xee\x9c\xbf\x19%\x16\x076\x1d\xa9\xc0\x84Yk\xf0\xf9\xde\"D\x10\xb4=:\xa8=\xb4!F\xc0\xeeL\xa6\xbe#\xe5\xd7%\x93L2\xc9t\xbe\x02\x88\xe4m%`rj4\xa2\xd4\x02>\xdf\x9d\x8f\x0f\xd7\x1c\xc0;\x17\xf7\xc4\xaak\x06a\xcb\xcd\xc3qQZ\x14n\\\xb4\x1d\x9b\xca\xac\xe8\x1bm\xc2\xa0\x94H\xc0\xea\xe0\xde\xa3\xe5\xd7%\x93L2\xc9t~\x02\x88\x16\x1eO<\x0c\x1a\xa4\x04\xeb\xa4\x03\x9fg\xe4\xa1Wz4n\xef\x16\x8f\xadE\xb5\xc8\xad\xb2\xe1\x8d\xd1\xdd\xa0\xd3(1{\xdf\x11\x98\x95@G\xb3\xde\xeb\x9d\x05\xa44\xe1\xda4\x08\xd2\xa9\xa5\xe2\xaf\xf4<\x93I&\x99d\x92\x01$@\xfd\x83\xf7\xc8 \x0cD\xdf\x01\xb5B\x80\xc3\xe5\x91\xfe\xafQ\n\x92\x17V~\x8d\x15\x0e\xb7\x08\xad\xd2;5\xb7\xf8G\x7fO\x00\xd7\x9cN\xedG\xb8=\xd9t\xa1\xfd\xd4\x0e\xc2#f\xd31v\x0d\x1e*\xbf~\x99d\x92I\xa6\xd6\x01 \x0e(\x14\x87aq \xb3\xd2\"\x1d\xb8\xb5[2v\x1d*\xc1\x13k\x0e\">\xc4\x88\xb6\xa4m\xcc\xdc\x9b\x8f \xb5\x12\x97\xa6\xc7\xa2\xcc\x05\xec\xae\xa8c\xcf->=\xd3\x8fk\x05A!,\x84\xd3\xfd-*\xea\xc6\xd3\xcfh\x8d^\x03%\x077Y\x1d \xa8\xb4\xfc\x8d\x80d%\x8d\xfb\xb6\xbc\x04d\x92I&\x99\x02\xa3\xb3k\xce\x11\xf0\x1b1\xf6\x9es\x0e\x14\xe2\xb6\xee\xc9\xb8\xbcC4\xb2.\xec\x8cg\x96\xee\xc6\x97\xdbs\xf1\xf2\xd8n\xb8\xac],F%E\xa0C\x98\x0e\xbf\x1e\xae\xc4\xba\xec\x12\xc0\xa0\x85\xa4I4\x8e\xd4t\x8d\x0d\xa8\xb1ud\xe0\xb9\xbc_\x1a\xc6\xa4F!\xc6\xa8%EDDn\xb5\x15\xf3\xf6\x17`IF>\xa0U\xdd\x05\xbd&\x96\xc0d\x9a\xbc\x14d\x92I&\x99Z2\x80\x00o!X\xff\xc0\xde\x83\xc5xf\xdd\x01\xbc}A{<:0\x15\xdd\xa3C\xf0#1\xf4\x12\xab\x03\xfdb\xccl\xe7\xc2\xf6\xd2:<\xb9j/\\u6\xc0l\\\x07Q\\\xdf8\x90\x12f\xa1\xd6\xd6Q\xa5U\xe1\xbdq\xddqe\xa7X\x18\xe9p\x0d5\x8e61 \x14\x97w\x8c\xc3\xeb\xb1\xa1xny\x06\xa7\x1a\x99J@r\x0f]\xf2My9\xc8$\x93L2\xb5\\\x00\xc9#\x06\xff\x18i\x14O\x7f\xb8z\x1f\x94\xa4\x11\xdc\xd5;\x15\xd3S\xc3q\x19\xb5j\x0fPbs!R\xa7\xc2\xb3\xeb\x0ez\xb6l\xcfU >\x8c7\xd1\xefl\xe4\xf8\xbd\xe1rO\xe5 \xc5\x17Fw\xc5\xcd\x04\x1e\x87\xadn<\xb1)\x0b\xf3\xf7\x1e\x81Z\xa9\xc4\x8d=\x93qC\xb7D<=(\x15Ev'>^\xb9\x07\xd0\xa8^\xa3\xbe\x1fS\xab\x95\x97\x84L2\xc9$S\xcb\x04\x10\x06\x83g\xa0S\xa5C\xc05\xef\x91\x86\xb1\xe8P F\xb5\x89D|\x90\x1e\xd56'r*\xeb\xc4\x07\x07\xa6\xe3\xae\x1e\x89\xc27\x19ybM\x95E\x80I\x7f-\xf5\xdb\xd2\x88\xd1o#\xed\x03\x83:'\xe0\xfaN\xf1(\xb4\x8b\xb8\xf9\x97\x1d\xf8\x85\xb4\x9b+z$K\xe3\xdf\xff\xe3V\xe4\xd29/\x0eM\xc7=\xbd\xda\xe0\xc7\x83E(,\xa9V\x10\xa8]\xee\x03\x11\x99d\x92I&\x99Z$\x800y\xc4kI\xea\xdf \xb5\xf1\xf1\xec\xc2*\xd3\x7fs\xcbh&J>\x0eT\xd5 5\x80\xfb\x97\x89\xdd\x15\xcf\x8e\xe8$\xfc\xfd\xbb\x0d \xad\xe2\xefP*\x96Q\xcf\xdf\xe1\xb5D\x15\x9e\x04\x9cz\xf1\xbe\xc7\xd8\xe4\x08\x84\xd1\x9d=\xb1%\x07\xbf\xec\xca\xc3\x82k\x86`|R\xa8\xd4\xf1\x99\xc4p<\xb6t7F\xd0\xcf\x8bS\xc20\")\x02\xb3\xf2\xcay\x9fe\xa8\x1f\x002\x9cZWj\x9cA8\x9f\xda6jkO2'(\x94\n\xc91\xc0-\x8a\xf2\x8a\x93\xe9\x9c%\xb5B\x81j\x87K\xca@\x0d\xbdF~ 2\x80\x9cQM\xe4\x15\xfa\xf7\x0b\x18\xb5S\xa9]@\xbf\x87\x11\xf3\xd7\xc2\xa8\x19\xb2x\xeb!\xc5\x87mc\xbd9\xd4^;O\xd7,\x83v7x\xe3\x82\x92\x1bX\xc3u\xd4\xaa}-\x8b\xdar\xdf\xf1\x9e\xd4\xde\xf1\xe3:?P{Af\x11\x8d\xa7\n\xbb\x13}\xa3C\xa0\n\xd1\xc3\xc5\x9e\x96aA\xf4M\xfa\xed}\xaf\xf0\xad\xef\xa8\xb39u\xb0y\x1d(\xa0\xb6\x8bZ\x06\xb5=g\xf0zm|\xdf\xfd_AVj\xa5>\xc1\xf7\x08\xbc\xde\xade\xad\x0f@\xbcTD\xed=\xa9 >\xae\xaaQ\xcd\x82\xc51\xe3\xa1\xe5\x19\xc2\xa5\xa9\x11\x9e\x8fGuR\xb4\xcf.\x86XP\x01el\xa8\x8eA\xc0Z^\xdb\x1bjeo\x18u3h\x81\xde\x0e\xde\xfb`\xe6\xeet\xc5\xa3\xb4\x06\xb9\xd56\xd4\xb8\xd9M8 qA:X\xe9\xff!\x04,Q\x04,G,\x0e\x94\xd6\xda\x90h\xf2\x063\xda\xdd\x1e\xf8\x02S\x9c\xa7^\xd6\xc2l\x02\xb0i\xa8\xb5C\x17aB\xef\xd4H\x98i\xcc2\xab\x03\xeb\x0b*!\x96\xd7u\x87I?\x8bPj\x08iRw\xfd\xd1O\xa3\x82\xa3\xac\x06\xef\xef\xc8\xc5\x17\xf1\xdd\x1b*\x91\xd0\x9b\xda ?\x9f[\xdey\xc6\x9bB\xa8]Em*\xb5\x81\xd4t\x8d\xec\xb7\xd3\x076G\x81\xc7\x9f\xe7\\\x06\x99\xfc\xfb\x98IH\xea\x12i\xc2wS\xfbc\xda7k\xe1\xaa\xa8\x05B\x8d^\xcbB\xe3\x89\xbf\x90)-\xe0v\xf6Q[Cm\xa1\xaf9\x9aq\xec\x8e\xd4\x1el!\xaf\xad\xce\x07\x96\x1b\xa8\xfd\x02\xaf\xb7\xab\xfb\xaf\x06\x10\x96\x1eb\xa9q\xc0\x07\x07\xee5\xbe\x8a\x12\x9b\xb7B\x0c\x93*\xf3+\x0c7/\xdd\xe3\xfe~\\\x17<>\xac\x03\x0e\x16T\x8a\x7f\xeb\x91\xe2\xd1\xaa\x14\xc2\x86\xc2J\xc5\xb3\xab\xf7\xa1\xa6\xd6\xda\x0d\x06\xed\xef\xa8\xb6\xb2\x99\x0bZZ\xac\xa3\x06\xb4\xf5\x0c\x8a\x0f\x15\x8eX\x9c\xc2\x94\xb61\xd8E\x80\xf2\xc4\x8a\xbd\xb8\xa8],*IB\xbar\xdeF\xc4\x98\xf4\xb8\xaac\x1c\xca\x0826\x95\xd4x\x97\xacWZ=\x19x|\x8b:\xfb4\xfe\x10n\x1d\xda\x01Wt\x8eG\x07\x92\xae\x824\x02i\x14\x1e\xe9\x1a\x1fo\xcb\xc57[\xe9V=\xea;I\x0b\xb2\x93\xa6t\xdfQ\x13\x16\x08\xc4~\xcb*\xc6\xd6\xa2*$\x93tVn=\x06\xabJ\x03x\xbe\xc5\xe7\x11_b\x01\xe1)j\x91\x01\n(\xf5%\xaf@\xfb\xca\xd4\x18fB\xd2QV\x95\x05\xc3\xe2\xcd\xf8n\xc6@L\xfdz-\xdc\x1c\xc7\xe5?\x88\x1c\xa6\x96\xf8\x17\xdfN{_\xbb\xde'\xb0\xb1e\xe1C\xf8\x17\x8fv2jI\xce:\xec\xa4\xda\xc7\xd7\xee\xa0\x96C\xedSj\xec\x95Z\xd9\x18u\xb19\x89'\xb0\x8a\x98y\x0el\xcem\xb0\xbb\xf6\xd3\xc2\xc9\"\x06\xfd\x19\x1d\x1f\xd0\xc81\xd86t\x0d\x81\x08\xe6o9\xa4\xfc`w\x81\xe7\x9f=\x93\xf1\xf4\x98\xaeB\x9a\xd9\xa0\x8c1h\x15\xf7\xf7L\xc4g\x13{\x91\xce@@YV\x8bN\x89\xe1xpT\x17\xfc~\xf5\x10,\x9c\xda[h\x1bj\x14Km\x0e(I\xab)&\x8dc\xee\xfe\x02\\5w\x03\xc6\xcdZCZ\x83\x06_O\xec\x89\xb4 5\x16\x1f.\xc3\x9a\x03\x85\xf4\x08\xa58\x93oO2\x9f\xc9p\xb8\xa6\x834\x95\xa7\xc7t\xc3;#;`P\x8c \x07HE\xffao\x11\xf2H\xea\x1a\x15\x1f\x82O&t\xc5]CI\xb0`pp{\xee=\xe6~I\x0bA\xb5\x05+\x0e\x97#\\'\xdb\x86\xfd\xa0\xaf}\x1ajd\x80\xfd=\xf2#<\xbb\xa4\xa0on\x07 e\xc3b D.\x1f\x08%\xaf\xf7\nKk\xafN\x98@\xed~j\xfb\xc1\xa1\x08@\xc49\xfc\n\xd9,\xfc\xa4\xef^\xaf9[\x1aH;IJ\xb78\xbaK\x89\x0fM:\xa9\x8c+\x9b\x87\xecU\x96Db\xa8\xd7J\x9eTJ\xc5\xf3$\x91?|\xda\xd1D\xcc\x81N\xf5=jmS\xde\xdezH\x18\x9d\x12\x892\x02\x02\xbb\xc7#)\x0bk \x1c\xbaE\x98\xf0\x001\xf4\x18\x95\x02\xb7\xf7I\xe6dW\x9e\xadeV\xcfC\xab2\xc5Y\xdbr\x14i\xb1!\xf8\xfc\xe2^\xb8\xbc}\x14\xbaF\x05\xe3\xf7\x9c\x12hUJ\x8c!\xad$E\xa7\xc0\xb6J;\x1e]\xba\x9b+ \x02z\xc3\x1a\x9a\xd7\xe6\x93(\xd4/p\xd5\xc4\xa9\x03\xda\xe2\xc1>I(w\x88xi]&\xde\xdd\x94\x8d\x10\x8d\x02\xb5.\x0f\x1e\x1a\xdc\x0ew\xf7J\xc13C\xd3\xb1\xa3\xac\x06+w\x92\x00e6\xfc\x9bz\x8f\xa9\xa7Y!\xa7\xc6\nA\xdeGo,\xb1*=^~\x0c\xad\x8b\x84\xa3 BZ\xf9\xf083f\xcf\x18\x80i_\xaf\x83\x87A$\xd4\xe0\xaf&\xd2\x12o\xefnx\xcd\xa9,$~v\x0e\xbfJ\x16\xda>\xa7\xd6\xd7w\xcfg\x0c@\x12i\xc5lA\xa5\xc5(\x18\xb4\xb8\xf3\x82\x8e\x18L\x1aA,I\xf5\x0c \xfb\xca\xeb\xf0MF>~\xdfw\x84=3\xfe\x0f:\xb5\x99\x16\xd1\x1d\x8d0e}M:\xf1\x14%\xadF'\x01\x87\x07G-M\x90\xbc\x99\nI\xf2\x7fi@\x1b\xb1\x8a\xce\xfc:\xa3\xc03w_\xa1\xf0[n\xa9\xcaF\xd7#\xa0Bny-\xae\xa4\xeb\xffk`\xba\x14\x9cxg\x8fDi\x8c|\x8b\x0b_\xee+\xc1\xa3+\xf6\"\xa7\xa0\xd2\xab^\x8b\xe2\x95'Uc\x1d\xee\x0eJ\xd2\x86\xae\xeb\x14\x0f\xd6\x1d^\xdc\x98\x85\xd7\x96g\xe0\xf1\xd1]1,%\x02s\xe8\xde\x1e\xfbi;\xdd\x96\x12\xf7\xd35n\xe8\x92\x80\x95\xfb\x0bY\x0b\x19E\xf3\x08\x85w\x83N\xdaL?DZH\xa5\xc3)\xa9\xfa.\x8f\x8c$\xa7\xa0\x17e\xf0h\xdd\\V\xe9\x03\x91\x0b\xe2B%\x10\x99\xfe\xf5Z\x02\x91\x80\xccY-\x91B}f\x9e\xe1>\x13\xd7\xb9L\xbc\x9f\xab\xf4Y\x97\xce\x00\x80py\xda*\x8b1*<\x08\x9f\x92\xc4?6\xc9,]\xad\x98=\xf9\xd4$\x82\xc7\x87\xe0\xb2\xf6\xb1xn\xed\x01\xbc\xb5j/\x9f\x7f;\xd4\xca\xa5\xa4e|w\x9a\x91\xeb\x98\xe9\xf2\xc6\x9c\x93\x80\xc0\xacU\xa1\xd8b\xa7\xc5)H\xdeTI&=\x9e\xdc\x94\xe3\x99\xb5\xe5\x10\xf6\x97T\xab%M\xc2\xa8\x03\xc2\x8c\x1b!\x08\xdbh\x91\xde\xbczo\x01V\xe7U`hr\x04\x12\x83u\x12\xd3\xdeO\x8bx\xdb\xa1Ri\xcf\x84\x16\xb3\x95\xc0c\xbc\xcf\xee\xd7\x10\xf5\x82\xdd\x894\xea\xdf>,\x08\xbb\xab\xecxcs\x16\xee\xb8\xa0\x13\x9e\x1a\x98\x8a=\xd5\x0e\xbc7\xb2#\xf2\xacN<\xb7\xfe \xae\xee\x18\x8f\x8et^\x18=\x8b\xf2\xb2\x1a\x81\x00\x937\xcb\xd6\x1c\x1d\xccN\xda\x8a\x8c\x1b\xa7%v\x8f~P~\x0c\xe7\x889\x8b@dD|(\xbe\xbd|\xa0\x04\"\"{g\x99\x8d\x81xg\xb5D\xba\x8eZgj\x17\xe2\xdc\x0eB\xe6}H\x0e\xa1\xf8\xea\x84w\xdc\xc4\x81/\x83\xcd\xd9E\xa5S\xe3\xbd =1\x9e\xc0#\xa3\xd2\x8e\xab\x17\xedD\xefO\x96c\xf0\xa7\xab\xf1\xfe\xae\x02\x18\xd4\x02^\x1a\xde\x0e\x97\xf4N\x05\x9b\x83HFy\xbf\x11c/\x83Ac-.\xaa\xc2\xab$\xf53\xdf\xd5\x13\xa0\xb41\x1b\xd0/\xd2\x88\x05\x99Ex\xea\x87\xad\xca\xfd\xf9\xe5J\x18\xb5V\x84\x9bfA\xab\x1aG\xa7\xf5#P\xb8\x85p\xe6B\x02\x88\xdfy\x13{UF\x1ef\xae\xcd\xc4\xb7\xc4\xe4\xb7\x1d,f\x97[ \xc40\x97\xfe\xd6\x05\x7f\xbay6D&\xeeo\xd6(\xa58\x0e\xd6z<\x0e7\xd2B\xf4\xc8\xb1\xb8QL\xbfs\xc2\xc7! \xa1\xb08\xe9w\xab\x0bF:/D\xad<*e\x1d\xe3-\xc4\x9a\x87 \xc8\x8c\xe54$\xa7\x949\xd7\xccY%5\xb8\x90Ad\xc6@\x08\xbc\x1fXI\x9a\x88Bq\xae\xdc&\x9bx\xd8\x83)\xe8\x1c\x7f\x9d\x9f5t\x8fM}\x8b7\x83\x98\xe8\xd4n\xc9\x98\x98\x1cJ\x12\xb9\x1d3\x16l\xc6\xec\x8c|LJ\x8fA3\xd4\xcf\xc7\x00\x90(\x0e!mg\x08\x81\xc5\xbf`6\xbc)5\x93\xee.(\x15]\xe9o\xec\x12\x9au\x9a9\x14\xb19,\xaf\xce\x81R\xd22\xc2\x08(\xa7uN@(\xcd)D\xabD\xd7(\x13\x0ctc\x1fm\xcbAr\xb0\x1e\xa9\xc1\x1a\xe9\xbc\"\xde\x07RI\x8f\xf6\x18/\x06\x87\x9b5\x10\x112\x86\x9c\x94\xb8^\xcb\x88f\x1c/M~\xa4-\x04DH\x13\x19I\x82\xd67\x97\x0f8\x17A\xa4\xa3OB?\x97\x89Y\xf8\x03\xcdi\xc2\xd2\x107\xec\xc1L|dB\x98\xb4?\xf0\x95>\xfc{\x13^\xee:\x020\xcb\x91\xe2j\xc3\xda#\x15\x18\xdf&\x12\xcf\x0dm/\xb9\xe1\xde\xb34\x03A\xa4Q,\xcf)Cfy\x0d\xe6O\x1f\x00#}\x0f\x1b\x8b*a)\xaba\xd7]\xce\xdf\xb8\xbb\xde\xbd \x88>\x1c\x8e\xd6\x95]\x83NJ\x97\x06\xd0\x87\xfd\xf3\xffGm+5\x9b\x8fg\xf1rL\xa1\x96+?\xd2\x96\xa5\x89\x8c\"^\xf15\x81\xc8\xe5\xdf\xac\xf5\x82\x88\xd9\x80s\xc4\xae\xcb\xf1Fs\x03\\\xc3\xad\x858\xf8\xf1\x89\xe6\x02\x103\xdc\xa2 \x1a5BI2\xe7@\x8f\xa5\xb9e\x98\xd8!\x0e\xed\x08'\x8d\xe47b\xb4\x83\xa3\x83\x10\xc7\xa9\xd9\xbd\x0b\xe6\xf4\xae\x99\x82p;\xa7E\x18\x9d\x12\xe1I6\xa8\x15\xf7\x1e(\xf4\xc0\xe1R \xd2\xc4\x11\x94\xcf\xd38\xef\x9c\xe1\x07VD\x1a\xcc\nT[\xc7=\xbf>\x13\xc3i\xf1+\xb9\x08\x16i\x12\xec\xef\x9eYP\x85\xa4P\x03\xbe\xbfl\x80\x94*e_\xad\x13\xefo\xce\xf6~2\na&D\xd8\xff\x18\xc9\xe3\x91bGB\xe8y\xb1)L\xa6\x06i\xa0\xdf\xef\xc7[\x18\xec\x80\xfc\xe8Z\x07\x88\xec$Md4 \x91__6\x103\xbe]G b9\x97@\xe4\x12x\xf7\x0b\xde?\x03c\xb35c\x96\x9f}\xe8\xc1Jr<\xbb!'\xa1\xe9\xb15\x1c\xdf\xc7\xf1\"\x9b\x9a\x03@,\xb4*\x9cp{\xb4\xecm\xc5\x03\xb1\xe7\xd5\x9e\xd2\x1a/\xba\x10x\xf0\x9e\xc5v\xd2H,v'RB\xf4R\xa8\xb7\x857\xaf\xbd6\x9c\xd3sQ\xb7g\x02\x9b\xb0\xc6$G\n\xe5NQ\\]P\xa9\x807M\xc9?q\xf2\xb8\x8d\xe6ehnO\x1f\xb6;\xb5\x0b\x0b\x12\xf5j\xa5\xc2E\x93o\xcb\xa01\xa5\x8f\x94\xf7'\xca\xa0\x92\"qxC\xfd\xd6E\xdb\x91u\xb8\xdc\xbbI(\x8a\xc7 5\xab\xeb\xa9!\x068EY\xff8\x05\xb5\xf5\xf3\xfc\x07d\xf0h] \xc2\x9b\x80;I\x13\x19C 2sz\x7f\\5{=<\xbc/\xca\x16\x85\xa6\x81\x08\x7fo\xd9\xa79G\xe7\xd3N9\xf0+\x9eZ\x1c\xbc\x9b\xe0]\x80f\xb3,s\xdc\x12\xa7bi\xee`_\x0ef\xbc\xa3 \xfd\xd5>\xe6\xcfIc\xefi\xc28\x83\x9b\x0b@j\xa1R\x1cB\x95\xa5KFy\xad\xa4P<\xd4\xbf\xad\x94\xc2\xe0\x9a\xef\xb7\xe2\x91\x0b:J\xdeRW\xff\xb4\x1d]\xa3C01-\x12\xd95Nla\x80\xe1M\xe6\xfa\xe6\x9dc\x89m\xe0\x13Hz\xbf\x00\x16\x87\xde\x1ci\xf2\\\x9c\x1a)\xfc\x98]*\x16\x17W\xb3g\x13\x9b)\x16\x9eb^\xc3\xe0\x8d\xbfH\xf7-\x18NI\xb1\x9a\xda<\x1cu\xa9m\x1c\x85\xd3b_\x8c\xd2\x9a\xa0n\x1d\xe3=\xbfL\xee\x81e\x855\x9eg\x97e\x08\xc3\xd2\xa2\x85\xa1\x89\xe10iT8P^\x87\x1d\xc5Uxwk\x0e\x0eqRF\x02J\x08\xe2t\x9a\x7f\xd1\x1f_M\xad\x1d!\x91\xc1\x92\x19\x8f=\xc9d:)\x85\xf9q.#\xf1/\xf2#k\xa5 B|`|J8>$A\xec\xe6y\x1b\xd9E\xf1(_\x08\x94\xd8\xf9\xa2*\xc0\xbe\x9c\x9bj\x14\xd8)\xc8\xfb\xb3\xa9\xf4 \xb5\x8b\x9b\xf9\xd155\x02\x99\xe5\xf7\xb5\xbe\xf6\x11\xb5E>\xcd\xc4_j\xd7\\&,H\x8c\\\xa9\xe82sw\x1e\xae\xed\x9c\x88\x89m\xc2\xf0\xfe\xc5\xbdp\xf7\xfcMH%\xd0\xb8\xbaS\x02\xa6\xb7\x8b\xc1\xf5]\x12\x11\xa6\x12\xf0\x9f\x83E8\x94[*\xa5\xf6 Zp\xdcXq\xa4\xe3~\x00\x87k\"3\\\xc9]\xa9\xda\x82\xc1\xdd\x12\xc5\x18\xad\x02\xf3\x0f\x16\x8a\xecR\x0b\xa3\xf6[\x92\xee-\x0dJ\xaf\\\xa2\xd6\xe9\xba\x887\xf6\xffHt\xc8\xb9\xae4\xaa\xeb\xa9\xdfK\xb4z\x9f\xa3\xe3\x8dKB\xa8\x10~Cy]Ph\x8c\xd9\xbdpJo\xc1&Bq\xc7/;\xc4\xbd\xbb\xf3\x84%\xd9%0\x85\x1a\x11B\x00Rju\xc0\xc6\xfe\xed|\xadP\x03\xcf\xeb\x86c]\x94\x05.\xa3\x8bk\x87v@\x87p#id5\x92\x8f\xbcL'\xe7/~\x98\xafJ\xe4G\xd6\x9a5\x91Z\\\xd5>\n\xf3\xba%\xe2\xa7\xb5\x99$\x83\x06{S\xff\x04F\xe9\xf5%c?\x895\x97\xff\xfa\x1a\x0b\xa0O\xa2i\xce\x1c\x13\xe0M\xde\xb9\xb5\x85\xbe\x02N\x189\xc8\xa7\xbdk\xfd\xec\x1b\xdd\x9c\x00\xf2:\x81\xc1C\x87\x0e\x97\xe1\x81e\xbb\xf1\xc9\xf8\xee\xb8\xadK,\xba\xc6\x8cDa\x8d\x15\x9cN\xe4U\xd2D\x18\x00~\xca\xab\xc2\xf3+\xf6x=/\x14\x8aOi\xa1\x14\x1d\xf3\xf2\x15\xc2ZTY\xc3Y\n\x19\xdb# }\xa2\xcdP\xd2b\x1a\x98\x10\xa68T\xeb\xc4OY\xc5\xde\xd8\x0d\x01\xdd\x89A\xb3\x17W\xfd\x1cR\xfdhA.'\xc0\xd1C\xad\xc2\x05\x04X]\"L\xd0\x92\x06TB\x12\xffr\x02\xad\xdc\xbc\xf2p\x02\x91W\xa1U\xf7\"U\xf9\xaaS\xdc\x13\x07F\xbe\x8e\x1a[\x0fhU\xe2\xac)\xbd\x91hP)F\xcf\xdf&\xee\xcd,\x12|\x05\xae\xb2jj\xac\xa95\x0cNJ%\xab\xdfYt\xfd\x054\xaf7P?\xa6D\xd2>l\x08\x89\x0b\xc5\xb5\x9d\xe2q\x98Tu\x85\x0c\x1e\xa7\xd3*\x1aK\xac\x89\xcaQ5\xad\x18D\x18+\n\xea\\\xb8\x95\x84\xcf\x9fv\xe7C\x12\x105\x7fu~W\xac\x847\xae\xe3_hZ6\xe6\x97\xa8\x8dn\xc1\xaf\x80\xf3\x8d\xbdL\xedQ?\xfb\x19\x9b\x13@\x8ai%\xdc\x0c\x93\xfe\xbf\x0b\xb6\x1e\xc2\x0c\x87\x0b\xf7\xf5KC\xaf83\x12\x0cZ\x1c\xaa\xb6\xd2\x02\xb1\xe3\xeb\xbd\xe5xly\x06j T\x10b(&\x06~\xe71\xb69\x85\xb0\x02\x95\x96\xf0\x98\xf0 \xbc5\xb6\x1b\x86%\x86#R#H\xd9\xef\xb2*lB\x91\xcd\x89W\x86w\x12\x1e\\\xba\x0buU\xd6\xee\x08\xd1\xffJc\xf4\xf4\xf5\x8f\xa4\xfe\xabPQ\xa7I\x8e1\xe3\x95\x91\x9d1\x90\x98|\x84N!\xdd\\\x1daNN\xb5\x0d\x1fn\xcb\xc1\xbbk\xf6\xb3\x9d\xf5o\xd0i\x8e\xd0\xea=1XM\x10^\x82\xc7\xf3w\xd2<\xb4py\xf0\xd2\xf4\xfe\x9e\xb1\xf1!\xca\xbf\xaf9\x88\xdf6g R\x14\xad\x80\xe9\xf4\xcfw\x04D\xdd}\xcf\x8f\xa7\x99q\xd2\xcf\x84\xe6~\x0d\x01Z\x9aY\x8fm\xadO\xfbP\xf9TV\x96\xee\x0c\xf5\x8e\xb3\x1d\x8e\x1d\x19\xf2\xd0\xbc\x99\x81\xdd\x90\xe9\xfc\x01\x11\xfa\x14\xf2j\xad\x18\x18\x1b\x8aK\xe8\x1b\x99\xb7\xe1`K\x00\x90\xa3\xc4\xd9\x10hB\x98\x1d`\xffQ>\xd3Xv\x0b~\x05\xdf\x04\x00 \x8a\xe6\x04\x10\x96\x01?\x82J\x19C \xf2\xf4o\xbb\xf2\xf0\x1bI\xfb\x03\xc3M\x98\xd4%A\xbc\xb3{\xa2\xe7\xc6\xc5\xbb=\xb3W\xecQ#X\xcf\xe0\x91C\x0c|$\xeagF\x15\xf08I\xe9\xb1\x9c;\xeb\xabK\xfbb@\x8c \x15v\x0f\xbe\xc9,\x85\x85\x98x\x9f\xe8\x10\x84\xeb\xd4\xb8\x8e4\x9b\x08\xa3\x16W~\xb7\x1en\xab\x93\xb5\x03N!\xf0)\xad\xc2\x0fHs\xd1\xc4E\x85`\xf6\xd4~\xe8\x1c\xaeG\xa5C\xc4/9\x15(&\xe9\xbf7\x81I\x9b`\x1d^\x1c\xd1\x1eZZ\x9c\xafq\xfe+\xb5\xea\x01\x02\x9d\xef|*\xaf\xc2\x07b\x1f\x13\xb3\xbf\x82m\xb1\xa9\xa4JO\xeb\xd5\xc6\xf3@\xb7x\xc5\x93\x1b\x0e\xe1\xed_v\x90\x96\xa1\xe7t$\x8f\x12\xf0\x1c5Om?\xad\x88E\xd7\x0f\x8e5\xe3\xda\xce\xf1\x12\x88\x9da\xed\x83=$:\xc0\x9b\xf9\xf8T\x929\x1b\x9a\xebN\xa1^\xf3\xf3 \x90\x94\xb6\xe6\x05\x10\xe9S\x15\x9f!\xee\xb8\x8d$\xf4\xc7\xe0p\xf5[K\xda\x88\xa0\xd7\x08\x0f\xf5J\x12\xcbl\x0e'I\x15j\x04\xe9Xk\xe0\xe0\xbd\x9ac\xb4\x0f\x0f\xee\x81\xc3\x8d\xbbG\xa6c0\x81G\xa1\xc5\x8d\xe7IS\xf8p\xd5^\xbc0\xa5\x0f\xac.7\x96\x10(\x8dN\x8e\x90*\x08^\xd77\x0d\x1f\xaf\xc8\xe08\x92\xcb\xa4\x85\xee\xf6\\\xca\xfb\x0f\x8f\x0f\xef\x80\xae\x04\x1ey\xb5N<\xbdz\x1f\xbe!\x95X\xa7V@\xa7R\xe2\xe5Q]0&%\x12\xffG\xda\xd1\xca\xfcrl\xda\x9d\xc7\x9eR\x9c@\xf1\xb0\xc4\xcc\x04AC\xc0\x11\xc3\xfb%\x0f\x8e\xe8\x88\x9bz\xa4@\xa7\x10\x14\xb9\x16\x17j\x9c.\x91\x83 %\xff]Q\\\xed\x97\x92n%\xedch\x02\xda\x86\x9c\x15\xed\x83\x9f\xed{\x8d\xd6\x1c\x8f\xb3e\xfa\x88\xbd\xdb\xee\xf6IN\x8dc\x00@'_\xbb\xde\xa7\x89\xb1\xda\xff\xc5I\xce7\xf8\x807\xb41\xd2\xcdi\x88\xbdh\x0e\x9d\x86\x11\xa6\xfa@\xa4\xb9h\x81\xef\x9e\xfd\xd1\xe0\x9a\x02`\x13\xe1\xcd\xfe\xdaXz\xe58\x86ERO@ \xffn\x81w?\xc0_b\xc0\x1c\xe6\xa7-\xeb\x05\xfa.fI\xae\xedl\xa2n9\x1a\xc8Q\xe2\x9cW\x17\xc1\xbb\xc1\xee/]\xd9\xc2\x01\xc4\xed\x13t\xfc\x01\x90\xc2@?\xd8\xd3\xd1Bb\xb0\xfd\xa1V\xbe\xce\xa6\x1e\x9dW\x8aPF\x19\xb4:i\x83Y\x14\x97\x1d\x07\x1eL\xfd`w\x9a\x82\xa2\x82q\x11\x01\x84\x93d\xb5\x0f\xb6\xe7\xe0\xc3u\x99x\xfb\x92\xbe\xb8\x86\xeb\x9a\xd3\xc2\xbao\xc9n\xfc\x9c]\"\xa9\xbc\x93\xdbD\x82\x93\x1b\xc2\xe9f&w\x1f,v\xb4M\n\xc7\x05 \xe1\xa8s\x02\xcfR\xdf\xffm\xce\xc6\x9bc\xbb\xe2\xa7+\x06\xa2#iC\xd7\xcc\xdb\xc4\x91\xec\x08W\xd3*h\x17\xebu\x17\xb4;\x95\xb4`S\xa8%\x11\xe8\xc5pP\xd3\xe5\xbdR\xf0\xfc\xe0\xb6\xa4\x88\xb8$\xf3[N\x8d\x0dO\x0cl\x8bk\x87\xb4\x97\xb4 \xbf\xd4=\x9awH\x1ci\x1f\x1d\xe3\x91{v\xf6>\xfc\xd9?8\xbe8\x0e\x9b\x03\xb9,\xefk~\x80GC\xc4@\xc2A}?\xa0\xe1\xd4\x0e\x82\x0f<\x14'i\xfe\x92\xe2\x14M\x87\xe6/W\x90\xef\xc7\xb9\xcd\x01\\\xfe\xe6W:\xbe~\xc3O\xd4\x1e \xe0\xba\xff\x81\xff\x15\x01o\xf2\x1b<\x80\xc5\xd4\xfeOM\xfc\xe1\x07\xde\xe3d\x0fEe\x8b4\xf1^\x87\xc0\nJ\xc5\xf9\xa9A\x9emR\xe3X\xd3tchO\xf3k \xc7\xd2z\xe6\xf4V\x97Gdx\xd3\xab\x14\n\x9foMC>\xfe\xed8 b\xba\xd9\x88\x18\xa3\x16\x956\xb7\x04 \xd3\xfb\xa6\xe2\xae\x1e \xf8\xbd\xa8\x16\x83\xe2B\xd1/!\x0c\x1f\xed<\x8c\x9b\xbb%\"\xde\xa4Cl\x88\x11y\x85\x15\x11\x04V\xe3Yj\xe9\x16\x16\x84H\xbd\x1a\x99\x95\x16|\xb6+\x0f\x0f\x8f\xee\x8a\x9b\xbb\xc4!\xb3\xc6\x81\x8f&\xf6\xc2\x92C%\xb0\xb9\xdd\xd8Vn\xc1`\x1ao\xd6u\xc3|\xde\x1eB}-\n\xa9\x04|\xdb\xca\xac\xa8%\x00a\x86/\x95h\xb7\xbb\x85 \xa4\xbd|\xbe%\x9b\xd5\xebNRB\xab\xd3\x99%xl\x9a\xd7?\xe9>8fd[q\x8d\xaf\xdb\x19%\x97\x1f\xe7\xda\x8f\x93r\x174\xf3\\.\xf6i\x1a\xecw^q\x9cY\xa9\xea\x14\x1aHs\x92\x03\xcd_\x0f\xc4}\x86\xce=\x95\x19\xae\xa9\xe7?\xe73G\xf6\xf1s,\x8ee\x18\xda\xc8s#\x02\xd0XX\xf2\x9d\x12\xacV\xe2`U\x1dV\xe7\x97{\xeb\xa8\xb7L\xb7\x08\x9e\xeb\xab\x0cv\x01\xf4e\xb3\xe7\xc6\x16\n I\x01\x00\xc8\x923\xa5\x81\x1c\xa5j\x06\x10\x8b\xd3\xcd\xae\xafB\xa8V\xed\x92<\xaf\xc4\x93\xd7\x1cg\xe1\xbc>WV\xf9x\xadV\xa9D\x94\xc6\x9b}\xd7Y/\xc8H\xf0~*\x1b\xab\xf7\xe4\xe3\xee\x9e\xc9\x04(\xc0\x91Z\x1b\x8eT\xd7\xb1\xad\x94\x03\x04W\xf1\xfe\xc4\x81*+*\xe8b\xedI\x83\x18H\xda\xca\x83\xbf\xee\xc4\x81J+\xda\x87\x1b\xf1\xde\xa6l\xf4\xfax9\xcalN\xf4\x8f1aKQ5\xfa\xffg)\xfa\x7f\xb1\x1a\xfd\xbfZ\xe3m_\xfe\x8e\xfe\xef\xfe\x8a\x0fI{\xe9\x1f\x1d\x04\xb5\xb4\xdd\x01)\xf1a\x8cQ\x85\xd5\x85\x95R0 ]+\xbbQR-\xdf/\x81\xd1\x9b\x1b\x0fboY\x1d\"\x0d\x9a\x96&X\xf1^\x85 \xa7\xcbE\xd6t\xe2\xfc@\xff\x96\xf9\xf7_NlN\xbb9\x80~\\\xc25\xa6\x11\xe6\x9d\xe1~\x8e\xcb\xfb\n?\xb1\\\xc9\x02\xda\x02\xc9E\xdfsf\xc4\xd9\xe6#\xe67\xbf\x05\xd0\xaf'Z\xe6\x9d1?\xbe\xcf\xcf>O\x1d\x7f\xa0\xf9nL\x10\xc6\x12\x97\\\x85*k?N?\xd21IZ\xed\xa7 \xe6V\x9f6r\xfe\x03\xebNL\xf29\xb8\xdc\xe3%\x8f\x08\x97\xcfZ\xa3\xa25\xc2I\x0cUJ.\xc2\xc4\x11\x9a\x99\xc7\xf5\xfb'j\xac\x8a\xae)\x91\x989\xa97\xad(\x01y5V)\xf2zbj4V\xf7O\xc3\x17\xbf\xef\xe78\x90\xa7\x8f\x03\x10o\xd2A\x93\xee\xa6\xca\x8a\xba\xb0+\xe6l\xc4;\x17u\xc3\x90\xf80LO\x8f\xc4\x15\xd4xg\xb8\xcc!\xe2\xbb}\xc5\xb8\xfb\x97\x1dp\xda\x9c\x9coj/\x89\xf4\x1f\xfb\xfa\xdf\x88`\xc3\xd6\x0d\xfb\nq\xdd\x0f[\xf02i m\xcd:<\xdc/E\xfa3\xf7\xaf\xa2._d\x14\xe2\xef\\C\x84oI\xab\xfa\x8d\xfa\x1f\xbb\xe9\xe7\x11\x87\xc0\xa8\xfd\x86\x80n\xd2\x12b\xfaK\x0e\x14!B?\xc8\xf3\xc6\x90\xb6\xcab\x9b\x0b\xb3\xd8u8<\xe8}z>\x19>\xe0 \xf3\xbd\x10N\xa7Q\xde\xe0c7jaa-dw\x1e^\x1c\xd2N\x8a\xccoe\x81\x84\xcd\xb5\x85s\xad\x0f@x3r\x91O\x03j\x88\xfa\xa2\xf1\xa9\x15\xf8\x83:\xd5\xe6\xa4\x94\xbbS\xc6\x8cc\x88\xbd g\x9cF\xabh\x88>\xf0I\xdf\xf5=\xcb\xae\xa06\xd6\xcfq\x9e\x83/\xdd\x08o)\xda=n,\xcb+\xf3\xa2I\xeb\xc8)\xc0\xf9\xfb\xd83\xce\xdf\xe2QI\xcdp\xedXj\x0f\x05\xd0O\xef\xe3U\xed\xe1\x8d\xeb\n\xa4\xf0\xd5p\x9c$ \xf2O\x00\x110\x19\x1c\x0c\xc69\xfa\xb5*\xf4L\x8b&i\xde y\"\x1d\xa8\xa8\xc3\xce\xdc2vM\xbd\x94@`\x02\xbdp\xce\xf5\xb2\xa4\x1e\x08\\\xcc\x0b\xe0\xaa\xce \x1e\xa3J\xa18\xeau$\xf2.\x99\xdb\x83\xab;\xc4\xe3kb\xcaN\xa7;\x85$\x7fv\xaf\xac\x1f\x8cb\xa3\x8b\x0cG\xa8q]^I\xb5q\xca\xec\xf5\xb8\xa4c\x9f\xce\xbf\xa0^\xffm\xb4\x1a\xef@\xb0\xfe\xbd\xc5t\x8d\xed\xa4\x12\xcf\xe8\x94\x80N\xe1F\xe8\x94J\x14[\xedX\x99S\x86\x1f2\xf2\xbc\x8b4X\xb7\x8f\xfaOn\xe0Y\xd8\xa4\xe3*\xc5p\xc4\x98\x9fG\xa5e\xe0\x0d\xf37{:_?\xcc=sT\x07\xe5\x01\x1aw\xd3\xee\xc3\x9c\xafg\x11\xdd\xd86\x02\xd9\xaet\xbe\x89\xaeM7\xab\xdc\x0bo\xf0\xd5\x9b\xa8\xefz\xe9\xd3B\xbe\xdcy\x187\xd0\x9c\"\xf4\x1a\xe9~Z0\x84\xac\x827 \x90]zs}\xf8\xab\xf4}\x00\xbc\xf8\xae\xf3IS\xfe\x12'm\xeb\xec\xfb\x00OU\xeb\xfc\x10\xb5\xe4F\x8e\xc9\x91\xf0C!\x93\xbf\xc4\x9a\xfb\xb7\xf0?\xaea.\xfeL\xb7\x1f\xdc\x909\xa3\x11\xcc\xf7\x0f\x97\xe20\xbd\x1a\xfb\xcb\xeb\xb0!\xbf\xc2k\xbej\x1d\xc4\x02\x10\x9b\xce{\xf9\xd9/\xa6\x19\xae\xcd\x1a\xc3\xf3g\xf9~9-\xd3\xf4S jG\x01\xa4\x171\xd7\xef97\x7f\xc7\xe4\x08<6\xb8\x1d\x06\x91\x16\x10gPJ<7\xaf\xce\x85\xd5$)<\xb1r\x1f\x0e\x1d\xa9\xd0\x12\xb3\xff\x8d\x98#\x9b\xa3\xdaH\x0c\xc1\xe5\xe9\x0e\xbbS\xb4\xb9<\x1e\x9b[T\x1cuYeWX\xbb\xcb\x0d\xab\xd3\x05\xa7[<\x9a(\x8d\x0b\xae\xcc\xcf\x0ei\x8f2\xab\xb3%\x96\xb5e\x0d\xea\xfaS\xd8x9\xa5\x03\xc7\xf1p\x90\xe0\xbb\xf0\x16\x96\xf1\x97\x06\xe3\xe4\x19\x98\xff\x14c\x1aO\xe7L9\xbb\xbf\x80\xfe\x06o\x9e&\x7f\xcc\x89\x03\xa8]\x03o\x9c\xcfW~\x9a\xc1\x98&\xd6\x97\xab\xd8|\xf5\xd9\xae|8*j\xbd\xe5\x0fZ\x0f\xe5\x04\x00 a\xadl}\x94\xf9x\xf4\xc38M,\x92\xca\xc7\xe9\xe7\x81\xa4\x81\x1e\xa9Q\x98}i_\xb45\xaa\x90iq\xe3\xd3]G\x88\x07+0\x92\x8e_\xd3>\x9a\xb4\x023\xa6\xcf\xdd\x88}\xac\x8d\xe85_r\x96YI\xac\xa7\xc5\x90\x14\x17*\x84hU*\xc2\x10\xc9L\xc3\xde\x15\xcc\x0e\xb4\x04\x02\xa1z\x8dh\xd2\xa9\xc5\x9a#\x15\nD\x98\xbe\x82B\xc1%h\x9f\xfe\xc3l\xe6\xddo\xe1\n\x87\xb9\xa4\xa1\xac!\x80\xe2=\x95\x02p\xf5W\x9d&\x8a\xfe\xdd(I\xc6\x1eq\xe5)\x8c-t\xc3\xe2\"b\xd87\xd2U\xc7\xd0\xb9\xe94F\x0d\xfd\x9e\xe1\xe3\xd8\x07\xe8\x18\x9b\xde8:\x94\x139n\xc0\x89\x81\x8dG\xc9E\xe7\x8e@X\xd0\xbe\x9cC%\xca\x8b\xe7ou/\xbf\xa4\xa7\xf8\xc1\xb8\xee\xf8\xbf\x9f\xb7\x8b\xfd\xdbD \xa3R\"a&M\xad\x82\x00j{q\xb5T\xd6\xb6\xac\xa4&\x96\x80g\x11\xcdw<\xcdg\xd1\x1fV \x02\x9aY{\x0bpS\xd7D\x984J\xd49[T\xca\xa7jj\xbdq\xea\xa8\xee?\x0c}\xf0\x16\xcca\x8d\xc2\xdft\xd5]\x1aq\x8e?\x00\"o\xc8\x07N.\x9f \xb7\xcc\xcf~,@\xa4\x06\xf0\xee\xef\xaao\x02Q)\x05T\xd3w\xf3Cv\xf1\x89>\xfc-\x9f\x02 \x105\xb4\xb2\xb5\xc1\xdeVo7\xe6d\x06\x90)\x04\x04I\xba\x10=^\x1a\xd5E\x02\x8f\x1fs+q\xd7\xcf\xdbQN\x00\xc1f(\xaem\xfe\xdc\xc8\xce\x98\x94\x12\x86\x97\xe8\xe7\xe4\x99k\xc4 \x8dJ\xe8\x97\x1a\x89>\x04*\x83\x13\xc2\xa4R\xb5$\x92\x88\xb9UV.,%\x18\xd4JIq\xc8\xaa\xb2\x88\xe9aA\xe2\xda+\x07\xe3\xd6\x9f\xb7\xbb\x7f\xdf\x9d\xa7$m\xe0\xdf$\xc5\xb3\xd6\xe3\x80\xd3u\x19,\x0eo\xdau&\xa5B$\x95\xf60\x01\xc9\x01\xba\xf8\xe3\xf0\xaf,)\x07\xad\xbd\"5I\x0b\x12Ri\x81\xde\x0c\x8f\xe7BR\x83.\"m&DZ\xac\xbc\xa9\xaf\xd3\x94\x90\x0c\xfb)\xcd\xe1I\xd4\xcf\xcd\xf5'\xed\xa7s\xa7\x10\x98\xcdZ\xb1\xed\x90\xfe\n\x83\xd6\xf5\xca\xb0\x0e\xca//\x1f\x80\x08\x8d\x1a1:\x05j\xe9\xfeBh\xbc+\xdaFbZ\xfbX\xdc\xb2h;\xb6\x1e\xa4\x8f\"\xd4\xf8\x13=\n\xf6<*\x91>\x0c\x83\x06\xd5e5XF\xc0{E\xc7x\xd4U\xb5(\xd3\xfc\xa5\x8d\x04\x8f\xfat=\xfcO\xa5\x9e*\xf3\xed\x16E\xcb\xe1\xdd\xdb\xf0G\x9bd;\xfc\x13~^g\x99Ok\xfd\x83\"I\xa0\xdaZR\x8d=\xa4\x99\xb3\x86\xde\xcar*\x97\x07\xd0\xa75\xa9XJ\x9f\xe6\xc1\x0e\x17\x9f\xe14\xa9p\x18@.g\x06>\xa1[\x12\x86\xc5\x9a\xb0\xa5\xdc\x8ai\x0b6#\xd5@*\xe6\xe5\x03\xc1\x1a\xc5\x8d?l\xc1\xddKv\xa3\xdd\xb4~H!0\xf9\xea\xb2\x01bWR;\xbb\x86Iu=\xc4}\xd5\x0e,\xd8[ \xae \x06\xb9\xab\xa8J\x91\x1e\x1d\"\xb9\xcd\xe6T[\xb1`W\x9e\xd0%\xd6\xec\xf9zJOa\xf5\x8c~\x8a\xfbV\x86\xba_[\xbdO\x89\n\xcb\x14\x89\xc9kT\xe8G\xcc7\x85\x93-2'\xab\xb2\n\x1brJ\x92`\xb1_\x8b\x10\xfde\xd2\x8d\xfc!\xcd\xfbE\x1di\xfc\xb9\xa8\xb6v`$\x8b\x8d5#\xd5l\x90\xd4g\xde\xd3))\xac\x8c$ y\x90\xc0l\x1a\xfd\x9d\xf7t\xf66\xa0\xd5\xcc\xa7s~\"\x10\x9a\xfaKv\xb1\xea\xe1\xfe\xa9R@b.\xdd\xd7\x1dK\x0ebW^9\xdaG\x06\xe3\xfeA\xe9\x18\x11c\xc2\xff&\xf5\xc6\x84o\xd6!\x97?\x8c`\xfd3t\xb1[}\x1a\x1e8\xe2\x9e]\x16\xafS\xb4(\xcb\x0b\xd7\x8a\x0f$\x16\x84S\xe9/\xf4S\x12\x8d\x95yv\x8b\xa3\xdb}\xef0\xe1\x0c\x8d\xcf\x8e\x0c\x97\x1c\xa3\xc2\xd2\xf7\x17\xa6Sc\x15\xef}\xb0 \xc5\x1e\x91\xad\x0b@\x02\xf1\x86\xd2\xb6\xa2\xfbc\x11;\xc6\xd7x\xf3\x9c3\xa7\xdf\x0f\xaf\x17n\x03\x00\"\x8ai\x9c\xfd\xb2\x07\xd7\xcf\xa0\x03\xefl9$\xbd\xcf_\xae\x1a\x0c\x97\xd3\x0d\xde\xba\x98s\xd9\x00\x14\xd5\xda$\xd3\x0b\xff\xde?:X\xb1\xb3\xb4\xd6\xf3\xc9\xae\\\xcf\xe6\xc2*\x81\x18\xa3\xb2\x92]\xf1\x88I\xf2\xbe\x03\xc7e\xcc\x96\x8a9\x89\x92\xa5:\xbb\xb0R\xd9\xaf\xbc\xce\xf5\xee\x84\x1e\xc2\xab\xc3\xd2\x15\x03\x12\xc2\xdc\xb7\xfe\xb0Y0\x1bu\x8a\x97FtBo\xd2b\xc2\xf5^kZ\x99\xd5\x85\xcd\x85\x95xb\xd5>d\xe4\x94\xeaa6p>\x9f\xa3\xb9\x9a\x1aK)\xc4\xf4w\xa3\xa2N\x88\xa4\xfbzdP;IK\x8a0xS%\x14Y\xecX\x96S\x8ag\xd7\xecGm\xa5%\x95\xae\xb1\x8eVv\x1a\x8e\xdf[\xe1\x17\xef\xf6\xf4f\x8d\xe5\xbe>mh\xe1k$@\xe5<_\xbc\xa7\xd3\x85\xc0csq\x15&\x11h\xcc\x9d\xda\x0fc\x12Bpw\xff4<@\x00LZ\xcf54\x87{\xc1\xd9.\xf9\x81*\x958XY\x87*\x87S\xca\xcb\xe8n\x195\xa0\x9bR\xbby\x9e\x9f\x00\x12\x8a\xd6f\xac8?\x88\xddj\xb7\x9c\xa1\xb1\xd9\xe3\xeb\x98*\x81\x1c\xa4[C|b)W\xefT*Z\xe3j\x08\xc4|\xd0\x9a\xebX\xf7\xf1i\xab\\\xfe\xe2\xe5\x864\x10-\xa7\x1aa\x8f%\xa6\xec\x1a\x0b\xda\x84\x18\x10\xaa\x16\xb0\x99\xb4\x11\xe6smIr?BRwFY-.I\x8b\xc4[\xdbr\xf1\xf8\xc2\xad\xde\xfe\x0c\x14Z5\x9bi\nI\x1deu\x95\x93mu%`jO\xfc\"\x87\xfe\x9eM\xff\xbf}wN\xa9z\xc4\xe7\xab\xc4gFv\xf6<\xdc;I\x119c\x90\xb4x\xd2C\x0d\xa8\xa3\x05\xb5\xa5\xa4V\xda]k\x1f\x16\x84q\xa9\x11\xe8\xee\xdbo\xd9\xcevR\xb3\xf1;\xfa[\xe3\xebe+\x04v\x08\x10\xb8>\xc8\xb7S\xfb\xa2K\xb8\x01Nz\x85\xc5\x16\xa7\x94\xa6\x84+\x03v\x8d4\xa2_|\x18f\xd05J*\xebB`\xd2\xcf\xa2k\x8c9\xe1\xe1\xd9])!\x04B#\x92\"\x08@]xgk\x0ez\x93\x86\xf5\xc5\xf8\xee\x12;\xe4\xdb\xef\xf9\xc9J\xfc}\xe9nl\xbcj \x06\xd35\xb9|mU\xa5E\x07\x9d\x9a7\xdbV\x1d\xc5uN\x93\xe2$\x00jA\xc6\xfb\xdf\x9a\xd0w\x9b\x9f\xe7\xb3\xe7\x8e\x1e\xb2kmK#\xfe\x90\x9fE`I\x17OE_\xc3\xeb\xb9u\x0cE\x1b5XWP\x89\x9d\x0c Fmk|^\x81@\xde\xb9\xb0\xe6_\xf2 \x81\x0f\x1f\xc3j\x89\xb3U\xb0\xa7S\x89\xcd\x9bl\xf2\xe2\xd4h\xec\xa5\x97\xfbSv\x19\x06\xc6\x9804\xd6\x84\xc5$\xadO\xfa\xdf*Ir\x08Q lf\xe2d\x81\n\x84\x1a\x0b\x10bx\x9c\x18\xe5\x08\xe2\xccl\xe3\xe6\x0dj\xde\x1c\xbf\x8c~\xefN\x9cr\x121e.\xe0\xde\x03\x11A\x1bE\xb7[x\xe4\xfbM\x8aK~\xdc!\xb6\x0d1\x08\xb1\xbc7`w\xe1\x95M\xd9\x982s\x0d&\xccZ+\xc5z\xe4T\xdb\x11kP\xe1\x85\x0b;C\xcd\xdeWv'k\x07\x8d\xad30\x92\x98~w\x85^\x8d\xd7\xc7vC\x970\x03\n\xeb\\x|\xd5~\x8c\xa0{\xe0\xf6\xca\x86,\xd2t\xdc\x18D\xf7\xf6\xfc\xa8.^\x14p\xb9\xd9+\xa5\xfbqc\xc5sR\xc48Z\xe81\xb4\xf0+h\xaeoo\xce\xc6AR\xbd\xad\x84H\xbbJj\xc0\xd9\xde\xef\x1b\xd0VJ\xe4\xb8\xbb\xcc*\xa5-\x89e\xb7D\xefFy\xec\xb1\xd2\x97\xa2%U$d\x93]Q\x13\xfas*|\x7f2\x94\xeaZ\x99*\x7f>\x11\xc7\xe8d4\xe3xl\xe2\xfc\xdb \x9c\x97X\xaf\x99\x84\xcd\x1f9uI5g\x93h\x95q\x9e\x81\xecg\xd4\x9d#\xeb\x84\x93I^\x7f\xac\x06\"`\x1dq\xb5\xe1\xbf\xe6\x96\xe1\x9f\xbd\xdb\xe0\x9a\x8e \xe0\xbd\x8c\xcb\xbe^\x8b\xbf\xf5H\x86\x9b\xde\xfa\xd7\xdbrp)\xfd\xed\xca\x8eq\xc8\xb6\xb8\xb1\xeaH\xc5\xd1hp\xae\xda\xf5f#.\x9cA\xaaL?\x04\xe9\x96\xc1\xe6\xbc\xe0P\xb5U\xb0\xb9<\xb0\xb9=\xbc\xe1\x8eT\xd2x\xee\xe9\x97\x8aPb\xbc\xff\\\xbc\x03\xa5$\xe9\x7f1\xae\x07\xfaF\x07cL\xfbX\xfc\xb8)\x8b\xf7JxS\xa71{!W\xa1\xce\x86\xb1\xbdS1<>T*N\xf5\xd0\xaa\xbd\x98M\x8c\xff\x8e\x01\xe9\xb0\x11 <\xf3\xdbn\x94\xda\x9cxrP;)\x8d|\xbf\xf4Xl\xe0b6!z\x06\xc0\xfa\x85\xa2\xa4<^\x16\x9a'\xcf\xd7\xac!\x85K)Hy\xb5\x12\xf4\n\x14YTR\xe5\xc4\xfd\x15u\x120\x84\xe9T\xb0\xd3\xb9\x16)u\x8b\x10\xa8\xbd\xf4l\xd1\xbe&\xf6/\xf7\x01P\xa2\x1f\x92\x9bl\xbej\xd9\xa6\xac\xccf\x1akJCf\x1b\xadJ\x81#\xb5v\xac\xe0\xfd\x0f\x8d\xba)\xf5\xcf\xffJ\xd2\x07\xd0\xa7\xaa\x19\xae\xcb\xdf\xda\x93\x01\xf65\xf8\x80/E\x12\xe6\xfdwC\xaeO\\\\\x8b\xc3\x14\n\x8e\x9a\xb0>%\xc6\xfe\xaf\xad\x07\n\xf1\xf1\xee<<\xd23\x11\xef\x92T\xde\xcel\xc0\x9c=G$\x97\xdcGH\x13\xb8\xabW\x1b\x84\xd3\xd9/o\xce\xc5\x81\xec\x12\x0e\xc8\xe3\xfe\xfe\x95{t{\xca9\xb6\x83\xa3\xd3\x93\x82Tt\xbd\x12\xec*\xad\x91\n=\x89t\x9dH\x9d\x02\xf1f#.\x9b\xb3\x01K \xc4\xaen\x1f\x85^\x11&\xfc\xe8\xcd\xe6\xdb\xbeQ\xb6\x1f\x11]\xd8\xb6: :\x84\xb4%\x90\xb4S\x8a\xd9\xdbs\xf1\xf1\xd4~\xb8\xa1\x83\xb7\x86R\xbb\xc8`<\xb4d\x97\xa4m\x8dI2cPL\x086\xec\x96*\xb3v=n\xb4\x9d\x1cTy\xb8\xac\x8e4\x8c:LJ\x0e\xc3m\xdd\x93\xf1\xde\x8a=\xe8H\xcf\xe7\x82\xa4p\xbc\xbb#\x1f\xef\xd0\xefw\x0d\xed\x80v&\x0d\x16\xe4T \xaf\xa2\xeeha\x9cc\xa4:\x06!\x06\xe4\x16\xa2\x83\xe47\xb1\xbf\xbb\x85\x03\xa4L\xfe\x11\xc7\xfa\xf0\x9e\xddkM\x1c\xe7ux\x9d3N\xa0h\x12\x10\x97\x1d.\xf3:\x99\x184\xad\xf59\x05\x12\x14X\xda\x0c\xd7\xe5\"p\x1f4\xd3=\xb0\xa5\x85\x93k\xde\x19`\x7f\xae\x173\xf1(\x80\xec#\x86\xfb9T\x8ak\x9f \xa6\x1aI\x8c\xef\xaa\xce\xb1xeh:\x1e\x1e\x9c\xee\xad\x00D\xfc\xbb\x86\x84\x85\xd7\xb7\xe5\xe1\xc5\xe5{\xa4Hu(\x14/\x93\x04q\xc4\xcf\x0b'\xf1~\x8b\x96\x18\x0e\x08\xb0\xff~\x1f\x085\xa8~\x1a\xe9\x9b\\A\x00\"\xa5I\n7\xb5V\x0d$9\x80>\xf9\xcdp\xdd\xe64\xff\xb2\x95\x85cs\xb8r(\xa7\xb5\x89\xf7\xb3?;\xcf\xb4\xe3\xf7\xed\xf5)\x15\xc5\xeba\xd4nw;\xdc\xb8u\xc1\x16\xdc\xb4h'>\xdfW\x8cm\x85\xd5\xd8B\xed\xd3\xbdE\xb8n\xe1v\xdc\xfb\xe3V_z\x0e\xcdj\xfa\xf9\xa0\xdf\xd3\x16\x84\x12\xdeS\xe0\x9cP\x9c\xcbdBj\xa4\x14m\xfe\xc2\xda\x03H3k\xd16T\x87\xc7I\x9a\xb7\xd8\x9d\x18\x99\x14!\x9dSt\xb4\xd4%\xf7m\xdc5\xaa\xf9\xfcJ\x87K\xe2n\xc3\x12\xc3PUm\xc1W{\xf2\xd13\xc2\xc0\xc9\x1d\xf1\xd6\xd6C\xa8\xb3:00.T\x12\xa1+9\xef<\x9b\x9d\x84\x06|\xbc9N$H\x87o7g\xe3\xad\xed\xf9\x88\xd5*\xf0\xe6\x98N\x98;\xbd?n'\xadl\xde\xb4~x}T'\xc4\xf0q\xfa\xfb7\x9b\xb3\xbcQ\xf3\xde,\xb4G'%=\xb7\xce\xe1A0\xd0\xfd\xba[\xc6wS\xdb\x0cc\xc8\x1b\xe2\xe7\x1e\x8d\xf5i#\x81\xac\xa7\xfe'\xfb#\x83\x07k\xf1?\xb1S\x8c\xb6\xd5\x9a\xaf\x98:\x05\xd0'\xbb\x85\xde\xcbzx\xd3\xd3\x04Rm\xf1\x8e\xa3\x1a\x88\x97Mz\xc4\x010\xe9\xbe\x86\xdd5y\xd6\xfa\x83\x98\xb5\xe30\x82LzpI\xa4\xbaj+\xc0R3\xfd\x0e\x8dr\x16\x9d{e\x80\x13^\x03\xa50\x8e7\xe5\xffA\xcc\xb7]h\x10\xde\x1c\xdd\x15\xf7\xfc\xb4\x0d\xbbI\xade\x8f\xaf\xdd\xc5\xd5x{|\x0f\xa9\xb6\xc7\x91:\x17~\xe1T\xcf*\xc9C\xac~\x14\xfa\x10\x9f\x1a\xc6\x9b\xd4\\\xa3\x97=\x82\x8e\xd6+_M\x03\xf5_\x9e_\x81\xbb\x1c\xc9\x18\x18\x1b\x8a\xbbH;xh\xeeFl*\xa8\xc2\x87c:\xa3\x92\x00\xea\xfa\x1e\xc9\x12C\xe7\x1a\xec\xcb\xf3}.\x85\xc0\xe6\x06\xe6\xfc-\xa9A\xd7\xc2\xe9\x1e\x7f\xff\xcf\xdbQJ\x9a\xd1\x15\x9d\xe31&9\x14\x93\xa91\xc8\x1d\xa8\xb0afF\x1e^X\xb5\x0f\xbe\xf0\xfbE4\x87?\x8b\xec\xb8\x08\xa0\x8cz\xf4\x8b1\xa3\xdc\xeeh)&\xac\xe60?\xc9\xe9D\xce=b\xcd\x94\xed\xdb\xfe\xa6 \xe7e\xcd\x89\xfa*\x1b\\(\xbe\xec\x14\x0ew\xab\xde\x06k\x07\xff\xe3\x99\\>\xcd\xac\xa5\x12;\xc3p\xe4\xf9\xb3~\xf6\xe3}\xae\x7f\xd4w\x83\xe0d\x82S\xa0V^\x8aP\xe3\x8d$\x91\x0f\xa9\xad\xb5\x06K\x7f\xe1\xe2Mz\x0d\x07\x92|J\xe7,l\xc2d?#\xe9\xfc\xe9\x8c\xacbi\xbf\xe5\xd1\xbe\xc9\xb8\xbc},\x12L:|\xb9=\x97V\xa0\x88\xa7/\xec\x8c\xc1\xb1f\x04\x91\x90\xf2\xca\x96\xc3\xd8\xcf\x12K\xb0\x81\xa5\x1bN\xa3\xc0AI\xcf\x10\xc8u\x92\x00M\xf4\xa6K\x916\xf4\xb5\xaa\xbd\xf4\xff\x87i\x88\xe7\xe8\x1aw\xad\xda{D\xbb\x90\x18\xfd\x95\xed\xa2\xf0`\xdf4DhT\xf89\xb7\x0c[\x8bk\xf0\x18\x01\n/\xe8\x10\x8d\x80\xcf\xf7\x14`\xe7\xc1\xa2\xa3Z\xc3\x17\x0d\xce\x9a\x03\x0d\x83\xb4K`u\\\xf8\xc2\x92\xdd\xf8b\xef\x11)\xc5<\x07DU\xd0<\xd6\x17T\"\x8f\xdd\x12\xf5jN[\xb2\x94\xce\x1f_O#\x02\x08tzt\x8c\x97\xca\xf3\x1e\xae\xb1\xb6\x94\x85\xa3\x94ye\x8b\xa7\xbf\"~\xe0~\x04\x96\xee\x9f7i9\xddy\x83N\x15\xec\xc1\xc9uz\xa6\xb5\x8b\xc1G+\xf6\xd0\xf7\xa6m\x8d.\x15#\x03\xe8\xc3Rey\x0b\xbf\xaf\xb7\xe0\xdd\xa0\xf7'\xbf\x19\x9b\xf2\xd2\x1a\xf2\xa3\x9b+5\xa5\"\x94Z\xb4o\x11\x1fi&\x93G\x1e\x14\x8a\xd7\xa0V\xdd\xfb\xf4\xd2\xdd\x08'\xa6~51\xf9\x8bS\xc20!%\xec\x0f1\xa6\x860\xfb\xdd\xad$\xd1K\xfb-j\x16_\x9e\xa0?\xdc\x07\x87\xeb\x15\xd4\xd8\xa0!\xcd\xa1O\x9bH\x84\x12\x03gmbSa\x15\xec\xa55\x1d\x08\x04\xe6\x12\x90\xff\xc8/\xa9 \x9b\x9bWoM\xf0\x9e\x90\xd9PA`\xf1&\x9dwl\xd5.6\x8d)\x95\xb8\xbdk\x12a\xb3B\x92\xc2\x14\x82\x9c\xc6I\xa6FQ\xd0Y\xbe\x1e\xbb\xe2\xbf\xdc\x84\xfe\x1c\xd1\xce\xc1\xa9\xb77\xa4\x9e0\x88\\\x98\x14\x81\x8fXX\xe3\x04\xa7\xcaV\xa7\xc0^\x1d@\x9f\xcd\xad\xe0\xbe\x98\xb7o\xc2\x9f\xd9\x96\x1bK=O\xe5\x88]\xe1k\xcdK\xa2x\x1f\x8c\x9a\x01\xa8\xb5\x0f\xfa\xc7\xc2-X\x9a[\x8a\x8b\xd3\xa2\x11O\x8b\x8a\x05\x92\xfcZ\x1b\x16d\x16\xe2\xc7\x9d\x87\xbd\x0b\xcc\xa8\xfd\x0c\x1c\xc0bu\xe1\xfb~\x9b\x83\xe6\xf9\xf8\xc01\xdf\x94\x9d\xb4\x8eH\xb3\x06#\x13\xc2\x90IB\xa2\xf4Q\xb4\x9e\xcd\xf4\x17\x03\xec\xf7K+\xb9\xbf@\\\x8d\xc3\x9bC\x87\x9c@\x9f\xc9\n\xb8\xdc\x19\xa8\xb5\xcdF\x95\xf5}\xe9\xa7\xcb\xbd\x87\x8es\x1a\x8f\xc9'\x01\x91+H\x1d\x98@\x080\x1bZU\x81\x83\xa4\x13n\xc4\xd9\x8f\xc0l\xfc\x96\xfe6\x9e\xcey\x84\x16\xd9\x13\xa8\xb1\xaa\xc7vK\xc6\xbf\xfa\xa7\x92\xc6!\xe2\xb7\x9cr\x8c\x9f\xb9\x06c\xbfZ#\xfd\\|\xa8\x0c\x16:~\x7f\xdf6\x18\xdf#\x99\xf7\x1c\xf4\xd4o:\xf5\x9f\x06\x9d\xfa\x9ft\x8d=n\xbb\x139\xc5U\xd8\xbb'\x1f\xdf\x1f(\xf4\\\xdb!JHM\x8e\x10i\xae<\x9b~gF1\xb4\xa1\x7f\x878\x8co\x13%k\x1f\xe7\x1f\xf1\x9e@S]/#\xcf\xd2\\\xd9\xb3\xe8\xc9f\x1c\x8fk\xa5\x1f_\xf3G\xf2\x94\xe7\xcc\x13\xc3\x08@`\xd4y\xbd+[\x07q\xf0\xdd%\x01\xf4c!:\xf7\\^\xe3M\x03\x10\x85\xf0:I\xd9\x0bQ^7LRA\x92\"\xa4\xcc\xba\xfcS\xa2\xf2\xba!\xf4\xf7\xef\x89\x99\xbfu\x92\x118Q\xe2eP(R\xa1Qy\x1b\xff\x9f3\x04{\xa3\xce#Hl\x9f\xc6\x15\xcb\xae\xef\x1c\x0f-\xcdvSQ\x15\xa6\xce\xdb(%4|ph{\x04k\xd4\x986w#\xd6\x17V\xb2\xb0\x8f\xeb;%x7\xc4I\xbb\xf1}\x80oH\x1f\x88F\xd5\x99T\xe6\x9f\xe9\xa7\xf03\xa9\xcf\xacz\x8dN\x0c\xf7H\xb6X!\xe0\x80\x9aS\x99\xea$ \xeb\x96.\x89\x08\xd2(\xa5\x08u\x99\xce+\nB\xd3\xf70\x12\xcf\xd2\\\xe7\x9f\x811\xb9\x92\xdd\xa5\xc7\x1f,\xb28\xd0+:\x04)\xd1\xc1\\\xe1\xb4\xb5\xbc\xcby\x01\xf6\xfb\xaa\x15\xad\xd7\xe8\x00\xfa8\x02\x07\x10Ax\x99\xd4\x81\x7f\xf0\"\x98\xd43\x05s\xa7\xf6\xc5\xfcK\xfax\xdb\x94>\x98{i?L\xa4\xe3\xd2\"q8\xef\xa6\xf3_=\xc5h\xac\x06d\xfbZ\xfdU\xd5\x9b+\n\xc6\x85\x9b\xd0\xd6l\x94x\xfd\xfd+\xf6 \xc2\xa8\xc5\xbak\x06\xe1\xe6n\x89Xy\xd5\x00\xb4\x8d\x08\xc2\xa3\xab\xf7\xf3\x16 \xd2C\x8dH\x8a0y+\x11\x1ek\xd3\xcb\x80\x88\xa7\xb8\xb8\xd3\xba\x82JeV\x9dK\x18\x97\x1a-\xc0\xa8\xe1\x0d\xbdA\xa8W1\xady\x0c\x18^\xf5|uA\xa5o\xe3\\\xe6\xa8\xe7\x00\xf9\xf3\xbd\xa8\x03\xfc(\xebS\x97\xb3pOl\x9ai{\x86\xc6\xe6\x84\x8a\xc1\xc7\x98\xb1H\x90\xe2\xd2\xce\x17\xa7F\x1d\x8d\xbdj\xe9\xc4%\x9eS\x02\xec\xfbI+Z\xdb\x81Xa*\x03\x05\x90\x81\xf4\xf2\xef\x87\xd5\x89\xdb\x87\xb4\xc7\x17\x93z\xe0\x92\x94p\xb8H\xe8\xdeYX%\x19>/i\x13\x86/\xe9\xf8m\xf4w_\xc1\xa8{\xe1\xff&\x8d\x91\x83C8\x07\x95\x9e4\x8ej\x87\x07\x95\xa4\x02\x8fj\x13\x89Z\xba\xc8\xe6\xa2ji\xfd\x0d%\x8d'\xa7\xda\x82Z\xa77\xd5:\x9f/\xd5O?Q\x02\\\x07\xad\xfa\x80\xa5\xbc\x16\xdfg\x16y&$\x9ba6\x1b\xdd\xe0\xdc<.\xf7\x02b\xfa\x9c\xe3\xa5\xf9\xeaV\xe8\xd4\xf8tK\xb64O\xc9I@\xce\x04\xd5\xda\xc9_\x919\xbd \xd7\x8aB`Ak\xfe\x10\xe7Dz\xf0\x0c\x8e\xcf :\xf7x3V\xb9\xcd\x81q)\x91P\x98\x0d\x90\xa4\xbe\x96K\xec\x0c0\xb9 ZKq+Y\xd7l\xa2k\x17@\xbf\xc2\xc0\x00D\x10\x9eC\xb5\x15\xc3\xbb$\xe0\xf9\xe1\xed\xa5M\xed\xd7\xb6\xe6a\xe8\xe7+q\xc5\xf7\x9b\xa4\x9f/o9\x0c\x81\x8e\xbf@\x7f\x1f\xd6\x854q\x0eF\x14\xa4X\x0e\x7f\xe8w\xae\xc5\x91_g\x93T\xdf*\xd2*\x9e\x1f\xda\x1e7\xd2xUN7\xba\x93\x1a\x9c]\xeb\xc4\x97;\x0ecxB8B4\n)\xaa<\x9fS%x\x83\x0fO,?\xa9\x14\xf6\x82@\xe8\xd3]\x87\x05\x0e\\|\xbc\x7f[a\x18\xef\x9b\xf0/\xb5\xb6\xb1\xb4\xc2\xd9\x9d\xcd|\x9ayqr2\xce\x93\x7f\x01\xbc\xe5`u\x0d\x9e\xc5.\xc8\x95\x16|\xb8\xf30\xc2\xf5j)(S\xa6VM\xfe&\xc5\x1b\xd4\x84kM\xc0\x99\x0f\xd4\xfc>\x80\xfb\xdf\xe5g\x1f\x8e\x9d\xb8\xa5\xfe\x81R\x12<;\x85\x05\xa1gl\xa87\xadI\xcb#\x06V.y=\xbd c<\xda\x8a\xd6\xf5\x7f\x03\xec\xb7'\x90\x05\x1aI\xd2\xfa\x05\x1c4wc\xd7D\x84\xd0\x08\x1f\xef\xcc\xc7}?n\xc1\xb8\xb4(\xbc5\xae;&\xa7\xc7\xe2A\x02\x92g\xd7gI\x7f\xbf\xad[\x927\xc8\xce\xe5\xe1\xbd\x92\xc6\xe7]\x11\x84\xfb\x18\x08\xaarJ\xf1{~\xb9h\"\xcdbtr\x84\xc4\xeb'\x7f\xb7\x1eS\xbe\xdd\x80\x9e\x1f-CZ\x88\x1eO\x0eJ\x97\xf6@\xb6\x95T\xa3\xac\xb8\x9a\x997\xab \xc7\x17\xca\xe9C\x9a\xd08\x8e\xdb\xe8\x1b\x13\xa2\xc8\xaau*&\xb7\x8dV|=c \xbe\xbd\xb4/\x8c\\\x9f\xa0\xbc6\x0e^\xb7\\\xae\x8f\xd0\xe6\x04\x93\x82@\x0f[\x14\xb3`snD\x9d\x9d\xb3\x0bo\xa2 e\xd1qN0\xd6\xf1\x98\xb3Y\xe50\xe91?#\x0f\xeb\x0b\xaa\x10o\x92\xb5\x90VN\xfeJ\x94\xd3\x9ap\xad{\xcf\xf0\xbdp\xcdk\x7f\xf7X\xfe\xe1\x13\x98\xfc\xa5\x0f\xa9\xc5\x1d\xfd\x85\x8b\xa9\xf1\xb7<\x827\xd3=bs\x99\xb1\x8e4\xc3\x18\x0c\xf8\x1f\xc3\x1b\xbb\xd1\xb7 \xe3\xb0\xf6\x91\xd1J\xd6\xf4\xc7>a\xd8_\xe2\x88\xe8\xcd\x81\x00HO\x96\xe0\xa3\xc3M\xe8\x12\x1e\x84|\x9b\x1bO\xad\xdd\x8fI$\xc5\x7f1\xae+\x06\xc5\x87\xe2\xbfc;\xe1oC\xda\xe3\xdb}Gp\xd8\xeaB\xc7p#GhK\xd28qPN;2\x8b\xda\xad\xc71\xdctxm\xbe*ia+\x84\x95$\x9d<\x80j\x8bxa\xcf\x14\xf7(\x02\x0e\x93N)\x05#qU\xc0\xee\x91\xc1\xc4\xbb]\x98\xd1)\x1e_M\xe9#\x95\xc4-\xb2\xba\xf1\x16\xe7\xa2\x92\x82\xf7\x14\xf3\x1a\x90\x18\xefB\xb5M5\xb8c<^\x1c\xda\x01U6'\xf2kl8TQ\x87Ii\x11R\xfd\x10\xadN#\xa2\xac6\x894\xa6gh\x9cLZ\xdc,\xa5\x8d\xa5\x9f\x9c\x07\x7f'\xaa\xac7\xa1\xd6\x1em\xa2\xeb%\xc7\x9a\x11\xcc\xbe\xec\x16{,\x1d\xbfYZ4\xc2\xb1\xd2\x16\x9b\xb1D\xba\xef\x0fv\xe4J\x1b\xfe\xb2#V\xab\xa6\xd7\xe5x\xff\x0c\xdfG ^E\xf5=\xaa\xde\xa5v\x9d\x9f\x92+k.\x0f\xc1\x9b\x92\x08eV\x87\xf4\x0d\xf5$!l\xcb\xbe\x02\xce\xe4\xd0\xd4{\xfa\xba\x85\xac\x11\x8e\xc2/=\x03\xe3\x1aO\xb0p4\x8e\xd8\x96\xcf\x11\x9b\xbc\x1f\x9c\x04o\xc9\x8aaM\xd4\xb0\xe0\x03]\x04\x02 U\x1c!^JL\xb0\xc2\xeeD\xdb\x10\x1dB\x89\xd1\x7f\x93\x91\x8f\xdb:\xc5@IZ\x89\x82\x98\xf3\x1b\x9b\x0e!T\xa7\x91\xf2?1}5\xbe+\x0e\x0cj\x87\xdfsK\x9d\\\xd2r[q\x952\xa3\xacV\xe1\xaa\xb2\xf4\xe5\xad\x01U\x98Q\xca\xd8YU^\x97\xc4\xf1\x13i)\x91\xee\xb7\xc6\xf7\xc0\xf8\x84\x10\xc5\xcf\xf9U\x9e\xdb\x16nENv\x89\xe2\x87\xdcR\xdc\xde3\x19\x9d#\x82%\xf7\xd8Z\x02\xaf\x8c\x92\x1a|\xb05\x07\xfbr\x99\x81\x1bX\xc4\xb9\x89\x18\xf7\x89\x19E\x15B\x02k'\xc4\xc0E\xa7G\x14\x94>u\x80\xff\xe54#\x87I\x1b\x11\x88^\x18\x9a\xae|jh\xbag\xde\x81\x12\xcf\xf7\xb4\xb8\x17f\x17+\xebh\xce\x17\xf7k\x8b7\xc7tA\xaaA\x85J\x9asa\x8d\x03)\xd1z\x0c\x8f1\xe1\xe2\xf4\x18\xdc\xbdx\x07\x16n\xcb\xe5\x8f\x81\xcdY\x1c\x89\xeb-\xd0C\xcf\xc7Um\xc1\xc6\xc2*\\\xdd)A\x06\x90\xd6K\xdb\x03\xe8\xc3\x1f\xc0V\x9fVq\xaa\\\xcetw\x03\x80\xe2o\x8c\xc3\xf3\xf0\xee\xbb\xece\xcf\xc4`\xb5\n#\x12\xc3\xb1e\xef\x11\xefG\xd8\xfa\xcd\xbb?\xa2\xf9jv4\xb4>Z\x8aY\x8c\xf9\xda\xcf\x81\x02\xc8V\xdeC(%\xa6\xbd\x9dZ\x9fp\x03\x9e\x1b\xda\x017\xcf\xdd\x80\xd1\xdf\x89\x98H\x8c\xf4\xe7\x83\xc5X\xb43\x17\xcfM\xec\x8d.\xe1z\xcc=X*~\xb69[\x18\x91\x1e\xa3\x9a\xd19\x1e\xb7w\x8b\xf7X\x01\xcf\xe6\xc2\x1a\xcf\xf7\xfb\x0b\xc5:\x97G965R\xc1\xc9 \x7f&)\xfe`I\xb5\xe7\x85\xd1]\x856z\xa5\xf0\xe8\xda,\xcf\xb3+\xf6(9\x12\x1d\x04F\x07\x8eT\xe0\xde\xfcr\xe8C\x83\x08\xb8TR\x99YkE\xad\x17\x06\xccF\x17\xfd\xb8\x8d\xc0\xe3\xe3\x13f-\xe0\x01X\x1c\xeda\xd2\x89\xfdbB<:\xa5\xa0d;,o\xcc\xab\x08\xf0\xfaF\x19\xf1\xfa\xf6<\xf1\xf1\x1f\xb7 \x83\xe8\x1e.\xef\x10\xa7\x98\xde1\x0e3\xd2#\xc5\xcde\x16\xcf\xcf\x07\x8a\x84\xb1\xedb\x04=\x01\xcd\xcb\xdb\x0e\xe3\xab\xed\xb9R\xaa\xf9(\xd2(\x1e\x1e\xda\x9e4\xac\x08\xbc?\xb6;\x0e\x11\x08\xed\xca*a\x10y\x9e\xe61\xfd\x0f\x84r\xb9q\xa0\xd2\x02\x8d\xec\xcf\xdb\x9a\x897V]\x01|7\xbc\xef\xf7\x03\xbc\xf9\x868\xb86\xcbg\x92P\xfa\xcc\\=|&\x853\x9d\xbadd\x00&\x8bC\xd4\xfe\xd5\xc0q\xce\xe2z\x1f\xb5W\xfd\x1c\x8f\x9fC:\xc9i(\xb4\xd8qQJ$\xde\x8b0\xc1\xca\x9e\x9aZUk^\x1b\x99>\xed\xf1|\xa0?\xca\xda\x06\xf2\xc6\xca\xa0T.\x82\xd36\xee\xfdm9R\x1e\xab\xbfu\x8c&y\xa4/\x9e_\xbd\x1fO\xae\xdc\x8b\x10\x92\xb8?\x98\xd6\x1fWv\x8c\x95\x12#>\xb7.S\xd8\xb9\xe5\x10^\x893#-,\x08=\xa2\x82\x15\xfdbC\x15\x03\xe2C\xa5z\xe2\xbc\x11\xc3E\x96H+\xc0m=\x92a\xd4(\x85\xecJ\xabx\xeb\xa2=\x9e_\xb7\xe5(\xa5\xeae\xa1F\xcer\xfb\x02\x01\xc0\x85\xf4s\xba\xb5\xce\x9efe\xcf.\xce\x97\x15\xa4\xcb&\xed\xe2'\x92`\xde\xa4\xd6\x90\x99!\x8e\x8e\xbf\x84:\x07\xee\x18\xdb\xd5=--B\xf9\xe9\xfeb\xa4\x9a\xf4\xe8J\x8b\x97\xbd\xa3\xe6\x1f,\xc5\xcb4\x7f;i4\xcbv\xe7a\xd9\xbe#xq\xbd\x19cS\xa30\xbdC\x9cpc\xef6Bq\xad\xd7\\\xb7\xbd\xb8F2\x81\xdd\xda+\x05?e\x16c\xc6\xec\xf5\x989\xad\x1f\xaeh\x1b)Un\xbc-\xb7\x8c\xf7a.\xa59\x85\xe0\xe8>\x8cB\x81}\xe5\xb5\xa8\" \xe4\xbe\xbc\x91(S\xab\xa3j\x9ff9:\xc0\xfe}\x10\xd8\x86es\x10\x7f\xeb\xdf\x05\xd0\xefT{8\\\xbd\xf0Zj\xdd\xfc\x18\x8fcN^\xa1v?g\xb2\xee\x12\x11\x84\x01 aX\xb65\x87\xb3P\xb4V-\x84\x0bF\x0d\xc6_\x93=\xf9l\x13;D\xacn\n\x80\xb0]\xff!\x04\xeb\xc7m\xde_\x80{~\xdd\x897Fu\xc1M\x1dc0\xa1m4\xf2\xaa\xacH\x08\xd6#VC\x12\x86C\xa4\xbf\xef\xf2\xa6KO\x0cc\xa6\xea>x\xa4By0\xa7\x14s\x88\x11\xc7\xb6\x89\xc2\x9cI\xbd\xa4\x18\x0f6EI\xf61\xd2\x08\xd2C\x8d\xc2k\x9b\xb2\xf0\xeb\xda\xfd\n\xc4\x85\xb9\x89\xe3\xbeB\xa0\xf1\x90\xf7\xda\xf8\x15\x82\xf0\x7f$\xad\xb0=\x90\xddg\xd9\x0fp\xcf)}d\x15\xc2\xb7(\xabErZ\x94\xfb\xed!m\x15\xcb\x0bj\x84\x9b\xe6nD\x0c\x81\xd9H\x92\x80J\xacv,>P\xc4\xfb0\x02\xc2\x8c<\xd6Zx8\xc9!\xff\xce\xc7\xbf% \x90\xf2\xde(\x14\x0fB\xa5L\xa3>W\x916\xb1\x98\xd5U\xbdZ \xb3N}L\x9a\x0f\x16\xcc\xd9\xa4\x14m\xd0\n\xde~\xc22 \xb0N\xa4=\xf0\xda\x963p\xe2\xd2c\x97\xc1q\x92\xf4$\xe0)\xd8\x9c\x83\xa1Q\x89o]\xd8I\xa4\x1bV\xfc}Y\x86\x14\xdcXH\xa0\xf2\xd5\xef\xfb\xb0x\x9b\xcf\x94k\xd2\xcd\x91\nk\x89\xe2\x8d\xc4\xf0Si\xae\xefp\xc6\xd0 \x8dJ0k\xd5\x82\x95\xe6y\xcb\xe2\x9dXWP\x01\x17\xfd\x7fwi-\x8a\xed\x1e\xdc\xd0=\x89@\xc8\x81}\x156)\xc5|\xa4N\xedMW\xed\xb5\x7f\xffA\x1a\xd2\x96\xe4|X\xad\x9e\xbe\xf7\x99o\xce\x06q\x94\xf87\xcd0\x0egY\x98\xe1g\x1fv\x8b\xfdg#\x19h 1\x0f\xf3\xf9S\xe0\xf8\xae\xc1q\xa1\xd0\x910\x87\x96Q\xea\xd9\x1fbO\xa4\x9eh\x1e\x17\xe2\x96N\xeb\xe0\x8d{;A\xad\x0d\x8cD\xf1\x05\x02\x04\x01!\xfa\xe7\xd6\x1d(\xc0\xbaC%\x88\x894I\x1b\xea\\\xa3\xa3\xa0\xa4\x06p\xba\x00v\xd3S\x08\x8f\xd2\xf9G\xeb\x0c\x90\xae\x8a_\xa0S\x97\x94\xd4Z%\x8d#\xda\xa8E.\x81\x0eK#\xbc\xa8x\x9b \x93\x0b/y\xf7\x0b\xb2\xfc\x98\xd5\x854\xc0\xbd\xc4\xddG\xc3\xee\xd4H\xb5cU\\\xd0\xdd\x86+FtrOJ\nU>\xb21\x07\xbby\xd3.\xcc\xc8Z\xc1\xc30hX\xc2\xab\xa3\xb6\x9c\xc0\xa3~\xf6\xe0BI]S\x08w\xb1n\xc4\x9aC\x9b`\x1d\xf6\x14U\xe1\xbb\xfd\x85\xb8\xa6]\x14\x9d.J%n\x97\x1f.\x83F\xa1@|\x90F2Qq\x90#\xdd\x0c\x8fa=\xf6\x91\xc9\xdc\xf7\x1c\xa1\xeb\xa8-9\xc3\xd7\xe0\xb5\xf8P\x80f\xa7\xfa\xc4\x1e8\x81x(\xf9\x13\xc3\xc2\xd5\xec\xfe\x06\xff\xbc\x848\xcd\xcb\xa7\xc4+\xae\xef@\xe01\x80@d\xf9\xf6\\o\xbcX\xeb\xf8N\xb8\xb4\xc3\xe3\xe7\xc9zg\xed\xf5\x9a\x06\x8d;M\x1aV\x14\x9f'&<\x10f\xc3w\xd0\xa9\xac\x85\xa55\xd8\x93[\xea\x05\x0f\xad\xcaJ\xc7\xe7\x92\x060\x88\xce;\xbe\\b)\xb4\xea\xcc\x1a\xd2\x00^X\x97\x89p\x9d\n]\xa3LRp\x11\xd7\xec\x98\xb9\xa7\x00?\xed\xce\xe3Z |n\xe3\\\x0e\x05\xe1\xdft\x9d%\xa8\xa8\x9b\x00\x87[\x93\x18mF\xb7\xd4(\x98h\xbc\xa4\xd4(\xf7\x1b\xc3\xda+vTX\x85\x97~\xdf'J\xee\xc3\n\x05Kw\xec\x15\xc2\x9b\x80\x1f\xa0\xe1\xd4\xf3\x84\x0c\xa4Q\x95\xd1}\xd1\\\x13\xf5*<5\xbc#~\xd8\x9c\x8d\x7f,\xdb\x87\xac*\x0b\xee\xa1\x9f\xdf\xac\xcf\xc4#\xfd\xd3\x90lP\xd1yu(\xa0\xf3\xb9\x9f\xa4\xa9\xd5#\xb7(\xca rn\xd0Rx\xed\xffg\x8a\xb8\xae\xccp\xdf\xffS\x9a8\x16\x83\x87\xbf>\xb2\xecF\xbc\xd6\xcf>\x97\x06\x02\xc4\xf49\\\xc4\x1e\x90\xc39\xa8\x90\x05F\xb1\xc5k\xe8\x8b\xe1\xcd\x1bu>\x80\x07g\xf2\xb8\xf6d\xe0\xd14\x0d\xa4\xbej#b:1\xe4h\xe85\\O\x80\x93\xa7U\xc3\x9b\xbc\xb0\xf0\xe4\x0c\x1f\xd7\x13w_5\x9f\xa4\x8e\x89v\x97gzz4\xda\x84\x05)\xfaD\x07\xbb?\xdc\x91\x0bO\xb5U\x89\xa8\xe0%$\xe6\xff\xdc\x08\xf0x\x82\xb4\x9d\xc78q\xe3\xb0Nq\xb8\xa5{2\xbaD\x06K\x80\x94YQ\x07\x8dJ\xa9d\xd3\xd1\xb4\x1f\xb6z\\%5\n\xc4\x9a\xb3\xe0\xf6<\xd4\xa8\x07\xa8V\xaeF\x85u\xc8G\xbb\xf20>5\x02w\xf7J\x86\xdb\xed\xc1\xab\x04|\xb3v\x1d\x86\xc5#\xe2\xc9\xb1\xddqg\xcfd\xd4\xd2\xd7\xf0\x11\x1d\x93\x12H\x86\x06\xad\xa7\xaf!\xffO\xf4p#)X\x8f\x10\x9a\x13\x07Q\xc9\xd4\xea\x89\xed\xf8\xec[\xdf\xdcAc\xbc\x9f0\x06\x7f\xda\xd4\x9b\xb2X\xd8\x0b\xd0_\xcf \x8eW\xb9#@\x8d\x89\x05\xc5G\xfc\xe9Dp\xf1]a\x9d-\xe2\x82\xc4p\xdb+\x91&\xd4q= \x9d\xba%\xbe\xefe>\xa1a\xe1y\xb0\xb6\xd9$\xf7\x1f\x9fp}\xcaJ\xb4\xcd\xe97W\xe4k\x8d\xd4^\xb0\x1aJ\xc5-\x08\xd2\xfeg\xe5\x9e|\xc5\xca\xf5\x99\xe2\xcd\xe3\xbbcL\xa2\xd9-\xc9 Z\x95\x92\xc0\xe3\xedF\x8c\xd4\x0b\x1e\xcf\x93\xa8\xb5\xe3\xaa\x01m\xf1\xc6\xc8\xce\x08\xa7\xbb\xcaq\x88\xc8&M \x8c4\x10v\x0f.\xb1:\x91n6*\x0e\xa8\x95\xbc?\x11B+7\x0d^\xfb\xed\xe9\xb4\xacG\x08\xe8V\xfcJ\xa0\xf6d\x84 \xcf\x0cN\xc3\x93\x03\xda`b\xbb\x18\xe4\xf0\xc6|x\x10z\x87\xe9\xa5t\xc2\x8f\xae\xce\xc4o\xbc\x19(UZ\xab\xb7o\xc3Z\x07IY\xdd\"\x82\xa5\x18\x99\xe3\xb27\x18\x03x\xd6\x0d\xa5 \xd7\xf99\x86\xa1\x19\xdey\xa8\x9fs>\x9dx\x19\xe6\xc7xa~\xce\xd5_\xaedj\xc49\x1c\xc5\xcc\xb9\xa1^\xf4\x99\x8a\x9aJ\x9fR\xe3\xd2\x02\xf5M\x9f1~\xf4\x0f\xa9\xf7\x7f^\xdf\xdf\x060\x87\xcb\x9b0\x7f\xde\x0b\x99\xe1\xbbvc\xc9Xas.\xe9\x1aa\x1a<&%\x12\xf3H\x9b'A4\xac\x85\xa8\xea{|\x1a\xc7\xd7\xf0\xee\x014\x17\xb5D\x84\xac\x04\x9b\xf1\xbd{|\xb3\xa9Y\x1a\xd3\xe9\xafu\xbc\xe6hmA\xd8A\x0cz&\x81@j\x88F\x0d\xab\x07J\x9b\xdb#\xf8\xf6?N\xef\x16'\xe0%TZ\xd1\xbfc\x9c\x04\x1ez\xc2\x87\x0fv\x15\xe0\xdf\x8bw &:\x04\xef\x8d\xe9*\xedU\xf0\x1e\xc5\x7f\xc7v\xc5$\xab\x1d\x9b\xf7\x15\x84\xc3lx\x9b\x18\xfb\xf8F\xccr%i!\x1fB\xab\xbe\xf5\xd5e\x19(\xa8\xb2\xe0\xba\xeeI\xe8L`\xd2.T\x8f\x1a\xbb\x07\xbf\xe6W\xe1s\xd2\xa4fn\xc9\xf6\xfa\xb2\xab\x95\x1f\xd0E\x97\xff1\x82\xd3%\xc5\xad\x0c\x8e7K\x11\xb8\xc2\x89\xe6\x8a\x1a?\x9f\\Y\x03\xc7j\xfc\x1c\xa7\xb2\x19\xde`\xbe\x1f\x8c\xbc\xae\x11\xef\x937\xa7\x1b\x9b+\xcd\xdf\xb4\"6?\x9fOc#\xc7Y\xc8a3\xeb\xfd\xd4\xae\x84\xffE\xa0x\xe7x\x0e\xbc\xd1\xdd\x0d\x95?]\xcf\xfa+N_1\x93\x99R\xd6\x9f\x82\xbd\x14\xfc\x07?\xef\xf9K4P\x8a\xd6O\xba\xc47F\xa3=\xc7\x04A\x18ds\xbb/\x1f\x9d\x1c\xf1\xcd\xbc\x1d\xb9\"\xdc\x9e\xc3\xf4\xfd\xc7\x9fENT\xe3\xd3\xf8\xb8\xed\x86\xd71\x87c~v\x9c\xa1\xeb\xd9\x02\xf8\xe6\x9b\x8b<>\xfe\xc1\xdfn\xaeO\x00\xda\xe2\xbb_\xbfyBK\x88\xdcaS\xcf\x1e\xa8\x94\xa9\xa1:\xb5hq\x89J\x8e\xb5\x80\xa08\xfa\xa0OE\x91\xa4M\x8cd\xff\xf1\xdb{$K\x9a\xc7{\x04\x1ew\xce\xdb(i\x08W\xf6I\x95\xd2\xa8\xdc\xfe\xdb.\xf4\x8b1\xe3\xc9~)\xb8\xbd{2n\xe2t'.\xf1\"(\x05\x96\xa0O_\xf7\x9d\xeb\xa5\xeb\xd5j:\xff\x86\x99\x1b\x0eb\xd6\x81B\xf4\x8d5K\x0e\x03\xe56'6\x15VB\xac\xa8\xf3\x96\xe1\xd5(?\xa1\xf3o?\xb6\xbf\x07j5\xa7\xa4WJ\x9b\xf1\xc7\x11K\xafo\xf8\xf9\xcc\x1aJa\xcaR\xd2\x02?\x17qS\xe9\"x\x83\xe1\x1a\xa7szM\x9b\xa7\xa2\xfeh\xfc\xbe\x9c\xbf>\xf7l\xd3O\xf2\xe3|\x7fLG\x0cf\x1cA\xfe\x98\xcf\xfc\xc4y\x96\xba\xf9\xc0\x90\xcb\x03h\x8f{wY\xbe\x0f\x97\x01\xe3\x17\x9c\xda\xab\xeb\x8a\x00\xdf\x0d\x07\xff\xdd\x18\x80\x14\xdaT\xda \xef\xbeM\xa3y\x0b\xa1\x1d\x7f\xf3A\x9c\xe6\x07:\xb5\x07.w\x7f(T\x8a\xb3\xc8\x83,M4\x15\x06\xc0\xf3\xfcZ\x8b\xcd\x0d \xd5\xcd5XK \xfd\x0c\xe7e\x14DL\x96\xeb\x86\xdb\xb8\xd4\xa5W\x039\xdd\x82\x96\nN\xc5\x128\xf4\x8c\x0cF\xbe\xcd\x85\x87W\xef\xc5\xd8n\x89X0\xb9'2k\x9d\x12\xd7*\xac\xb3\xe3\xddm9\xb8\xa3G\"zD\x9a\xbcq\x1a\xa55\x02\xa9\xca\xec\x82\xb7\xb4q\x8f]\xbc\x91@n \xc2\x8c\x0f\x8avW\xf7\x0d\x9c\xbf\x87mQY\x81N\xe1A\xd8VX\x89 \x1d\xe3\xf0\xf8\x80t)\xde\x7fAv\x89T\x10\n\xa1F\xde\xf4.\x94_\x99L2\xc9$\xd3\xf9 uP(\xde\x86Ry\xdf\xab\xbf\xef\xc3\x90\x840\x0c\x8f2b\xce\xf4~\xf8rG.\xf6\x96\xd6\xe0\xeanI\x98\xd19\x01q\x1a\x01\x9f\xed/\xc1\xcc\xcd\xd9G\x0bK\xbd\"\xbf.\x99d\x92I\xa6\xf3\x17@x\xf3\xe3Q\x98t7TT\xd4\x85^1g\x03\xde\x1e\xdb\x15\xa3\x92#\xf0\xcc\xa0?K\x08\x14\xdaE\xbc\xb3#\x1f\xf7\xff\xb6\x8b\xbd\xaf\xd8{j]\x83I\ne\x92I&\x99d:\x8f\x00\x84\xd3\x88{\xc4\xe10\x1b\xd7\x15\x94\xd6\x18\xa6}\xb7\x01\x13\xda\xc7\xa1Gt\x88TA\x90\xab\xf5\xad\xcd+\xc7\xea\x03\x85\xde\x0d\xf7`\xfd^:\x7f\x8c\xfc\xaad\x92I&\x99d\x00a\xdaI\x9aH7\x98\x0d\x1f\xc2\xee\x1a\xf9\xe3\xb6C\xf8\x91\xeb\x7fp \x00\x97\xdb{F\x90\x8e~W~N\xe0\xc1U\xdf\xec\xf2\xab\x92I&\x99d\x92\x01\xe4(\x1d$p\x18\x05\xb5r\x14i#\x17CDw@4\x92\xdaQ A\xaa\x8e5\x8f@f\xb3\xfc\x8ad\x92I&\x99Z&\xfd\xbf\x00\x03\x00\x93\x19\xf9\xc5\x1e\x83\x05U\x00\x00\x00\x00IEND\xaeB`\x82PK\x07\x08z\x1b\xa9\xd9?M\x00\x00?M\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\x93\n#G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00index.html\n\n\n \n \n \n \n \n\n InfluxDB - Admin Interface\n\n \n \n \n \n\n\n\n\n
\n \n \n\n\n \n
\n\n \n
\n
\n
\n

Connection Settings

\n
\n
\n
\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n
\n
\n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n
\n
\n\n
\n \n
    \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n\n
\n
\n
\n\n \n
\n
\n

InfluxDB v0.9.3

\n
\n
\n\n \n
\n
\n
\n
\n \n

Write Data to InfluxDB

\n
\n
\n
\n
\n \n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n\n \n \n \n \n\n\n\nPK\x07\x08\xb1y\"\x84\xdc$\x00\x00\xdc$\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\x94\n#G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00js/admin.js// allow the user to store recent queries for quick retrieval\nvar recentQueries = [];\nvar queryPointer = null;\n\n// keep track of the databases that exist on the server\nvar availableDatabases = [];\nvar currentlySelectedDatabase = null;\n\n// connection settings for the server, with sensible defaults\nvar connectionSettings = {\n hostname: (window.location.hostname ? window.location.hostname: \"localhost\"),\n port: \"8086\",\n username: \"\",\n password: \"\",\n ssl: ('https:' == window.location.protocol ? true : false)\n}\n\nvar connectionString = function() {\n var protocol = (connectionSettings.ssl ? \"https\" : \"http\");\n var host = connectionSettings.hostname + \":\" + connectionSettings.port;\n\n if (connectionSettings.username !== \"\") {\n $.ajaxSetup({\n headers: {\n 'Authorization': \"Basic \" + btoa(connectionSettings.username + \":\" + connectionSettings.password)\n }\n });\n }\n\n return protocol + \"://\" + host;\n}\n\nvar getSeriesFromJSON = function(data) {\n var results = data.results[0].series;\n return results;\n}\n\n// gets settings from the browser's localStorage and sets defaults if they aren't found\nvar loadSettings = function() {\n var cs = localStorage.getItem(\"connectionSettings\");\n\n if (cs != null) { connectionSettings = JSON.parse(cs); }\n\n document.getElementById('hostname').value = connectionSettings.hostname;\n document.getElementById('port').value = connectionSettings.port;\n document.getElementById('username').value = connectionSettings.username;\n document.getElementById('password').value = connectionSettings.password;\n document.getElementById('ssl').checked = connectionSettings.ssl;\n\n getDatabases();\n}\n\nvar updateSettings = function() {\n var hostname = document.getElementById('hostname').value;\n var port = document.getElementById('port').value;\n var username = document.getElementById('username').value;\n var password = document.getElementById('password').value;\n var ssl = document.getElementById('ssl').checked;\n\n if (hostname == \"\") { hostname = \"localhost\"; }\n\n if (port == \"\") { port = \"8086\"; }\n\n connectionSettings.hostname = hostname;\n connectionSettings.port = port;\n connectionSettings.username = username;\n connectionSettings.password = password;\n connectionSettings.ssl = ssl;\n\n localStorage.setItem(\"connectionSettings\", JSON.stringify(connectionSettings));\n\n getDatabases();\n}\n\nvar showSettings = function() {\n $(\"#settings\").show();\n $(\"input#query\").prop('disabled', true);\n}\n\nvar hideSettings = function() {\n $(\"#settings\").hide();\n $(\"input#query\").prop('disabled', false);\n}\n\n// hide errors within the Write Data modal\nvar hideModalError = function() {\n $(\"div#modal-error\").empty().hide();\n}\n\n// show errors within the Write Data modal\nvar showModalError = function(message) {\n hideModalSuccess();\n\n $(\"div#modal-error\").html(\"

\" + message + \"

\").show();\n}\n\n// hide success messages within the Write Data modal\nvar hideModalSuccess = function() {\n $(\"div#modal-success\").empty().hide();\n}\n\n// show success messages within the Write Data modal\nvar showModalSuccess = function(message) {\n hideModalError();\n\n $(\"div#modal-success\").html(\"

\" + message + \"

\").show();\n}\n\n// hide errors from queries\nvar hideQueryError = function() {\n $(\"div#query-error\").empty().hide();\n}\n\n// show errors from queries\nvar showQueryError = function(message) {\n hideQuerySuccess();\n\n $(\"div#query-error\").html(\"

\" + message + \"

\").show();\n}\n\n// hide success messages from queries\nvar hideQuerySuccess = function() {\n $(\"div#query-success\").empty().hide();\n}\n\n// show success messages from queries\nvar showQuerySuccess = function(message) {\n hideQueryError();\n\n $(\"div#query-success\").html(\"

\" + message + \"

\").show();\n}\n\n// hide warning from database lookup\nvar hideDatabaseWarning = function() {\n $(\"div#database-warning\").empty().hide();\n}\n\n// show warning from database lookup\nvar showDatabaseWarning = function(message) {\n $(\"div#database-warning\").html(\"

\" + message + \"

\").show();\n}\n\n// clear out the results table\nvar clearResults = function() {\n $(\"div#table\").empty();\n}\n\n// handle submissions of the query bar\nvar handleSubmit = function(e) {\n var queryElement = document.getElementById('query');\n var q = queryElement.value;\n\n clearResults();\n\n if (q == \"\") { return };\n\n var query = $.get(connectionString() + \"/query\", {q: q, db: currentlySelectedDatabase}, function() {\n hideQueryError();\n hideQuerySuccess();\n });\n\n recentQueries.push(q);\n queryPointer = recentQueries.length - 1;\n\n query.fail(handleRequestError);\n\n query.done(function (data) {\n var firstRow = data.results[0];\n if (firstRow.error) {\n showQueryError(\"Server returned error: \" + firstRow.error);\n return\n }\n\n var series = getSeriesFromJSON(data);\n\n if (series == null) {\n showQuerySuccess(\"Success! (no results to display)\");\n getDatabases();\n return\n }\n\n var values = series[0].values;\n\n if ((values == null) || (values.length == 0)) {\n showQueryError(\"Query returned no results!\");\n } else {\n availableDatabases = values.map(function(value) {\n return value[0];\n });\n\n hideDatabaseWarning();\n React.render(\n React.createElement(DataTable, {series: series}),\n document.getElementById('table')\n );\n }\n });\n\n if (e != null) { e.preventDefault(); }\n return false;\n};\n\nvar handleRequestError = function(e) {\n var errorText = e.status + \" \" + e.statusText;\n showDatabaseWarning(\"Unable to fetch list of databases.\");\n\n if (\"responseText\" in e) {\n try { errorText = \"Server returned error: \" + JSON.parse(e.responseText).error; } catch(e) {}\n }\n\n if (e.status == 400) {\n hideSettings();\n } else if (e.status == 401) {\n if (errorText.indexOf(\"error authorizing query\") > -1) {\n hideSettings();\n $(\"input#query\").val(\"CREATE USER WITH PASSWORD '' WITH ALL PRIVILEGES\").focus();\n } else {\n showSettings();\n $(\"input#username\").focus();\n }\n } else {\n showSettings();\n $(\"input#hostname\").focus();\n showDatabaseWarning(\"Hint: the InfluxDB API runs on port 8086 by default\");\n errorText = e.status + \" \" + e.statusText + \" - Could not connect to \" + connectionString();\n }\n showQueryError(errorText);\n};\n\nvar handleKeypress = function(e) {\n var queryElement = document.getElementById('query');\n\n // key press == enter\n if (e.keyCode == 13) {\n e.preventDefault();\n handleSubmit();\n return false;\n }\n\n // if we don't have any recent queries, ignore the arrow keys\n if (recentQueries.length == 0 ) { return }\n\n // key press == up arrow\n if (e.keyCode == 38) {\n // TODO: stash the current query, if there is one?\n if (queryPointer == recentQueries.length - 1) {\n // this is buggy.\n //recentQueries.push(queryElement.value);\n //queryPointer = recentQueries.length - 1;\n }\n\n if (queryPointer != null && queryPointer > 0) {\n queryPointer -= 1;\n queryElement.value = recentQueries[queryPointer];\n }\n }\n\n // key press == down arrow\n if (e.keyCode == 40) {\n if (queryPointer != null && queryPointer < recentQueries.length - 1) {\n queryPointer += 1;\n queryElement.value = recentQueries[queryPointer];\n }\n }\n};\n\nvar QueryError = React.createClass({\n render: function() {\n return React.createElement(\"div\", {className: \"alert alert-danger\"}, this.props.message)\n }\n});\n\nvar stringifyTags = function(tags) {\n var tagStrings = [];\n\n for(var index in tags) {\n tagStrings.push(index + \":\" + tags[index]);\n }\n\n return tagStrings.join(\", \");\n}\n\nvar DataTable = React.createClass({\n render: function() {\n var tables = this.props.series.map(function(series) {\n return React.createElement(\"div\", null,\n React.createElement(\"h1\", null, series.name),\n React.createElement(\"h2\", null, stringifyTags(series.tags)),\n React.createElement(\"table\", {className: \"table\"},\n React.createElement(TableHeader, {data: series.columns}),\n React.createElement(TableBody, {data: series})\n )\n );\n });\n\n return React.createElement(\"div\", null, tables);\n }\n});\n\nvar TableHeader = React.createClass({\n render: function() {\n var headers = this.props.data.map(function(column) {\n return React.createElement(\"th\", null, column);\n });\n\n return React.createElement(\"tr\", null, headers);\n }\n});\n\nvar TableBody = React.createClass({\n render: function() {\n var tableRows = this.props.data.values.map(function (row) {\n return React.createElement(TableRow, {data: row});\n });\n\n return React.createElement(\"tbody\", null, tableRows);\n }\n});\n\nvar TableRow = React.createClass({\n render: function() {\n var tableData = this.props.data.map(function (data, index) {\n if (index == 0) {\n return React.createElement(\"td\", {className: \"timestamp\"}, null, data);\n } else {\n return React.createElement(\"td\", null, pretty(data));\n }\n });\n\n return React.createElement(\"tr\", null, tableData);\n }\n});\n\nvar pretty = function(val) {\n if (typeof val == 'string') {\n return \"\\\"\" + val + \"\\\"\";\n } else if (typeof val == 'boolean' ){\n return val.toString();\n } else {\n return val;\n }\n}\n\nvar chooseDatabase = function (databaseName) {\n currentlySelectedDatabase = databaseName;\n document.getElementById(\"content-current-database\").innerHTML = currentlySelectedDatabase;\n}\n\nvar getDatabases = function () {\n var q = \"SHOW DATABASES\";\n var query = $.get(connectionString() + \"/query\", {q: q, db: currentlySelectedDatabase});\n\n query.fail(handleRequestError);\n\n query.done(function (data) {\n hideSettings();\n hideDatabaseWarning();\n\n var firstRow = data.results[0];\n if (firstRow.error) {\n showDatabaseWarning(firstRow.error);\n return;\n }\n\n var series = getSeriesFromJSON(data);\n var values = series[0].values;\n\n if ((values == null) || (values.length == 0)) {\n availableDatabases = [];\n updateDatabaseList();\n\n showDatabaseWarning(\"No databases found.\")\n } else {\n availableDatabases = values.map(function(value) {\n return value[0];\n }).sort();\n\n if (currentlySelectedDatabase == null) {\n chooseDatabase(availableDatabases[0]);\n } else if (availableDatabases.indexOf(currentlySelectedDatabase) == -1) {\n chooseDatabase(availableDatabases[0]);\n }\n updateDatabaseList();\n }\n });\n}\n\nvar updateDatabaseList = function() {\n var databaseList = $(\"ul#content-database-list\");\n\n databaseList.empty();\n availableDatabases.forEach(function(database) {\n var li = $(\"
  • \" + database + \"
  • \");\n databaseList.append(li);\n });\n\n if (availableDatabases.length == 0) {\n document.getElementById(\"content-current-database\").innerHTML = \"…\";\n }\n}\n\n// when the page is ready, start everything up\n$(document).ready(function () {\n loadSettings();\n\n // bind to the settings cog in the navbar\n $(\"#action-settings\").click(function (e) {\n $(\"#settings\").toggle();\n });\n\n // bind to the save button in the settings form\n $(\"#form-settings\").submit(function (e) {\n updateSettings();\n });\n\n // bind to the items in the query template dropdown\n $(\"ul#action-template label\").click(function (e) {\n var el = $(e.target);\n $(\"input#query\").val(el.data(\"query\")).focus();\n });\n\n $(\"ul#content-database-list\").on(\"click\", function(e) {\n if (e.target.tagName != \"A\") { return; }\n\n chooseDatabase(e.target.innerHTML);\n e.preventDefault();\n })\n\n // load the Write Data modal\n $(\"button#action-send\").click(function (e) {\n var data = $(\"textarea#content-data\").val();\n\n var startTime = new Date().getTime();\n var write = $.post(connectionString() + \"/write?db=\" + currentlySelectedDatabase, data, function() {\n });\n\n write.fail(function (e) {\n if (e.status == 400) {\n showModalError(\"Failed to write: \" + e.responseText)\n }\n else {\n showModalError(\"Failed to contact server: \" + e.statusText)\n }\n });\n\n write.done(function (data) {\n var endTime = new Date().getTime();\n var elapsed = endTime - startTime;\n showModalSuccess(\"Write succeeded. (\" + elapsed + \"ms)\");\n });\n\n });\n\n // handle submit actions on the query bar\n var form = document.getElementById('query-form');\n form.addEventListener(\"submit\", handleSubmit);\n\n // handle keypresses on the query bar so we can get arrow keys and enter\n var query = document.getElementById('query');\n query.addEventListener(\"keydown\", handleKeypress);\n\n // make sure we start out with the query bar in focus\n document.getElementById('query').focus();\n})\nPK\x07\x08\xd7\x93a@U5\x00\x00U5\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00js/vendor/bootstrap-3.3.5.min.js/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\nif(\"undefined\"==typeof jQuery)throw new Error(\"Bootstrap's JavaScript requires jQuery\");+function(a){\"use strict\";var b=a.fn.jquery.split(\" \")[0].split(\".\");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error(\"Bootstrap's JavaScript requires jQuery version 1.9.1 or higher\")}(jQuery),+function(a){\"use strict\";function b(){var a=document.createElement(\"bootstrap\"),b={WebkitTransition:\"webkitTransitionEnd\",MozTransition:\"transitionend\",OTransition:\"oTransitionEnd otransitionend\",transition:\"transitionend\"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(\"bsTransitionEnd\",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var c=a(this),e=c.data(\"bs.alert\");e||c.data(\"bs.alert\",e=new d(this)),\"string\"==typeof b&&e[b].call(c)})}var c='[data-dismiss=\"alert\"]',d=function(b){a(b).on(\"click\",c,this.close)};d.VERSION=\"3.3.5\",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger(\"closed.bs.alert\").remove()}var e=a(this),f=e.attr(\"data-target\");f||(f=e.attr(\"href\"),f=f&&f.replace(/.*(?=#[^\\s]*$)/,\"\"));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(\".alert\")),g.trigger(b=a.Event(\"close.bs.alert\")),b.isDefaultPrevented()||(g.removeClass(\"in\"),a.support.transition&&g.hasClass(\"fade\")?g.one(\"bsTransitionEnd\",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on(\"click.bs.alert.data-api\",c,d.prototype.close)}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.button\"),f=\"object\"==typeof b&&b;e||d.data(\"bs.button\",e=new c(this,f)),\"toggle\"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION=\"3.3.5\",c.DEFAULTS={loadingText:\"loading...\"},c.prototype.setState=function(b){var c=\"disabled\",d=this.$element,e=d.is(\"input\")?\"val\":\"html\",f=d.data();b+=\"Text\",null==f.resetText&&d.data(\"resetText\",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),\"loadingText\"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle=\"buttons\"]');if(b.length){var c=this.$element.find(\"input\");\"radio\"==c.prop(\"type\")?(c.prop(\"checked\")&&(a=!1),b.find(\".active\").removeClass(\"active\"),this.$element.addClass(\"active\")):\"checkbox\"==c.prop(\"type\")&&(c.prop(\"checked\")!==this.$element.hasClass(\"active\")&&(a=!1),this.$element.toggleClass(\"active\")),c.prop(\"checked\",this.$element.hasClass(\"active\")),a&&c.trigger(\"change\")}else this.$element.attr(\"aria-pressed\",!this.$element.hasClass(\"active\")),this.$element.toggleClass(\"active\")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on(\"click.bs.button.data-api\",'[data-toggle^=\"button\"]',function(c){var d=a(c.target);d.hasClass(\"btn\")||(d=d.closest(\".btn\")),b.call(d,\"toggle\"),a(c.target).is('input[type=\"radio\"]')||a(c.target).is('input[type=\"checkbox\"]')||c.preventDefault()}).on(\"focus.bs.button.data-api blur.bs.button.data-api\",'[data-toggle^=\"button\"]',function(b){a(b.target).closest(\".btn\").toggleClass(\"focus\",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.carousel\"),f=a.extend({},c.DEFAULTS,d.data(),\"object\"==typeof b&&b),g=\"string\"==typeof b?b:f.slide;e||d.data(\"bs.carousel\",e=new c(this,f)),\"number\"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(\".carousel-indicators\"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on(\"keydown.bs.carousel\",a.proxy(this.keydown,this)),\"hover\"==this.options.pause&&!(\"ontouchstart\"in document.documentElement)&&this.$element.on(\"mouseenter.bs.carousel\",a.proxy(this.pause,this)).on(\"mouseleave.bs.carousel\",a.proxy(this.cycle,this))};c.VERSION=\"3.3.5\",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:\"hover\",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(\".item\"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d=\"prev\"==a&&0===c||\"next\"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e=\"prev\"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(\".item.active\"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one(\"slid.bs.carousel\",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?\"next\":\"prev\",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(\".next, .prev\").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide(\"next\")},c.prototype.prev=function(){return this.sliding?void 0:this.slide(\"prev\")},c.prototype.slide=function(b,d){var e=this.$element.find(\".item.active\"),f=d||this.getItemForDirection(b,e),g=this.interval,h=\"next\"==b?\"left\":\"right\",i=this;if(f.hasClass(\"active\"))return this.sliding=!1;var j=f[0],k=a.Event(\"slide.bs.carousel\",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(\".active\").removeClass(\"active\");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass(\"active\")}var m=a.Event(\"slid.bs.carousel\",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass(\"slide\")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one(\"bsTransitionEnd\",function(){f.removeClass([b,h].join(\" \")).addClass(\"active\"),e.removeClass([\"active\",h].join(\" \")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass(\"active\"),f.addClass(\"active\"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr(\"data-target\")||(d=e.attr(\"href\"))&&d.replace(/.*(?=#[^\\s]+$)/,\"\"));if(f.hasClass(\"carousel\")){var g=a.extend({},f.data(),e.data()),h=e.attr(\"data-slide-to\");h&&(g.interval=!1),b.call(f,g),h&&f.data(\"bs.carousel\").to(h),c.preventDefault()}};a(document).on(\"click.bs.carousel.data-api\",\"[data-slide]\",e).on(\"click.bs.carousel.data-api\",\"[data-slide-to]\",e),a(window).on(\"load\",function(){a('[data-ride=\"carousel\"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){\"use strict\";function b(b){var c,d=b.attr(\"data-target\")||(c=b.attr(\"href\"))&&c.replace(/.*(?=#[^\\s]+$)/,\"\");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data(\"bs.collapse\"),f=a.extend({},d.DEFAULTS,c.data(),\"object\"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data(\"bs.collapse\",e=new d(this,f)),\"string\"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle=\"collapse\"][href=\"#'+b.id+'\"],[data-toggle=\"collapse\"][data-target=\"#'+b.id+'\"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION=\"3.3.5\",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass(\"width\");return a?\"width\":\"height\"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass(\"in\")){var b,e=this.$parent&&this.$parent.children(\".panel\").children(\".in, .collapsing\");if(!(e&&e.length&&(b=e.data(\"bs.collapse\"),b&&b.transitioning))){var f=a.Event(\"show.bs.collapse\");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,\"hide\"),b||e.data(\"bs.collapse\",null));var g=this.dimension();this.$element.removeClass(\"collapse\").addClass(\"collapsing\")[g](0).attr(\"aria-expanded\",!0),this.$trigger.removeClass(\"collapsed\").attr(\"aria-expanded\",!0),this.transitioning=1;var h=function(){this.$element.removeClass(\"collapsing\").addClass(\"collapse in\")[g](\"\"),this.transitioning=0,this.$element.trigger(\"shown.bs.collapse\")};if(!a.support.transition)return h.call(this);var i=a.camelCase([\"scroll\",g].join(\"-\"));this.$element.one(\"bsTransitionEnd\",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass(\"in\")){var b=a.Event(\"hide.bs.collapse\");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass(\"collapsing\").removeClass(\"collapse in\").attr(\"aria-expanded\",!1),this.$trigger.addClass(\"collapsed\").attr(\"aria-expanded\",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass(\"collapsing\").addClass(\"collapse\").trigger(\"hidden.bs.collapse\")};return a.support.transition?void this.$element[c](0).one(\"bsTransitionEnd\",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass(\"in\")?\"hide\":\"show\"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle=\"collapse\"][data-parent=\"'+this.options.parent+'\"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass(\"in\");a.attr(\"aria-expanded\",c),b.toggleClass(\"collapsed\",!c).attr(\"aria-expanded\",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on(\"click.bs.collapse.data-api\",'[data-toggle=\"collapse\"]',function(d){var e=a(this);e.attr(\"data-target\")||d.preventDefault();var f=b(e),g=f.data(\"bs.collapse\"),h=g?\"toggle\":e.data();c.call(f,h)})}(jQuery),+function(a){\"use strict\";function b(b){var c=b.attr(\"data-target\");c||(c=b.attr(\"href\"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\\s]*$)/,\"\"));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass(\"open\")&&(c&&\"click\"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event(\"hide.bs.dropdown\",f)),c.isDefaultPrevented()||(d.attr(\"aria-expanded\",\"false\"),e.removeClass(\"open\").trigger(\"hidden.bs.dropdown\",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data(\"bs.dropdown\");d||c.data(\"bs.dropdown\",d=new g(this)),\"string\"==typeof b&&d[b].call(c)})}var e=\".dropdown-backdrop\",f='[data-toggle=\"dropdown\"]',g=function(b){a(b).on(\"click.bs.dropdown\",this.toggle)};g.VERSION=\"3.3.5\",g.prototype.toggle=function(d){var e=a(this);if(!e.is(\".disabled, :disabled\")){var f=b(e),g=f.hasClass(\"open\");if(c(),!g){\"ontouchstart\"in document.documentElement&&!f.closest(\".navbar-nav\").length&&a(document.createElement(\"div\")).addClass(\"dropdown-backdrop\").insertAfter(a(this)).on(\"click\",c);var h={relatedTarget:this};if(f.trigger(d=a.Event(\"show.bs.dropdown\",h)),d.isDefaultPrevented())return;e.trigger(\"focus\").attr(\"aria-expanded\",\"true\"),f.toggleClass(\"open\").trigger(\"shown.bs.dropdown\",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(\".disabled, :disabled\")){var e=b(d),g=e.hasClass(\"open\");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger(\"focus\"),d.trigger(\"click\");var h=\" li:not(.disabled):visible a\",i=e.find(\".dropdown-menu\"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:\"\",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:\"\"})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:\"\",paddingRight:\"\"})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:\"hover focus\",title:\"\",delay:0,html:!1,container:!1,viewport:{selector:\"body\",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error(\"`selector` option must be specified when initializing \"+this.type+\" on the window.document object!\");for(var e=this.options.trigger.split(\" \"),f=e.length;f--;){var g=e[f];if(\"click\"==g)this.$element.on(\"click.\"+this.type,this.options.selector,a.proxy(this.toggle,this));else if(\"manual\"!=g){var h=\"hover\"==g?\"mouseenter\":\"focusin\",i=\"hover\"==g?\"mouseleave\":\"focusout\";this.$element.on(h+\".\"+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+\".\"+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:\"manual\",selector:\"\"}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&\"number\"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data(\"bs.\"+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c)),b instanceof a.Event&&(c.inState[\"focusin\"==b.type?\"focus\":\"hover\"]=!0),c.tip().hasClass(\"in\")||\"in\"==c.hoverState?void(c.hoverState=\"in\"):(clearTimeout(c.timeout),c.hoverState=\"in\",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){\"in\"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data(\"bs.\"+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c)),b instanceof a.Event&&(c.inState[\"focusout\"==b.type?\"focus\":\"hover\"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState=\"out\",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){\"out\"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event(\"show.bs.\"+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr(\"id\",g),this.$element.attr(\"aria-describedby\",g),this.options.animation&&f.addClass(\"fade\");var h=\"function\"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\\s?auto?\\s?/i,j=i.test(h);j&&(h=h.replace(i,\"\")||\"top\"),f.detach().css({top:0,left:0,display:\"block\"}).addClass(h).data(\"bs.\"+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger(\"inserted.bs.\"+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h=\"bottom\"==h&&k.bottom+m>o.bottom?\"top\":\"top\"==h&&k.top-mo.width?\"left\":\"left\"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr(\"data-original-title\")||(\"function\"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+\" `template` option must consist of exactly 1 top-level element!\");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(\".tooltip-arrow\")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data(\"bs.\"+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass(\"in\")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off(\".\"+a.type).removeData(\"bs.\"+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.popover\"),f=\"object\"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data(\"bs.popover\",e=new c(this,f)),\"string\"==typeof b&&e[b]())})}var c=function(a,b){this.init(\"popover\",a,b)};if(!a.fn.tooltip)throw new Error(\"Popover requires tooltip.js\");c.VERSION=\"3.3.5\",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:\"right\",trigger:\"click\",content:\"\",template:'

    '}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(\".popover-title\")[this.options.html?\"html\":\"text\"](b),a.find(\".popover-content\").children().detach().end()[this.options.html?\"string\"==typeof c?\"html\":\"append\":\"text\"](c),a.removeClass(\"fade top bottom left right in\"),a.find(\".popover-title\").html()||a.find(\".popover-title\").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr(\"data-content\")||(\"function\"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(\".arrow\")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){\"use strict\";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||\"\")+\" .nav li > a\",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on(\"scroll.bs.scrollspy\",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data(\"bs.scrollspy\"),f=\"object\"==typeof c&&c;e||d.data(\"bs.scrollspy\",e=new b(this,f)),\"string\"==typeof c&&e[c]()})}b.VERSION=\"3.3.5\",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c=\"offset\",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c=\"position\",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data(\"target\")||b.attr(\"href\"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(\":visible\")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active\").removeClass(\"active\").end().find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!1),b.addClass(\"active\").find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!0),h?(b[0].offsetWidth,b.addClass(\"in\")):b.removeClass(\"fade\"),b.parent(\".dropdown-menu\").length&&b.closest(\"li.dropdown\").addClass(\"active\").end().find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!0),e&&e()}var g=d.find(\"> .active\"),h=e&&a.support.transition&&(g.length&&g.hasClass(\"fade\")||!!d.find(\"> .fade\").length);g.length&&h?g.one(\"bsTransitionEnd\",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass(\"in\")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),\"show\")};a(document).on(\"click.bs.tab.data-api\",'[data-toggle=\"tab\"]',e).on(\"click.bs.tab.data-api\",'[data-toggle=\"pill\"]',e)}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.affix\"),f=\"object\"==typeof b&&b;e||d.data(\"bs.affix\",e=new c(this,f)),\"string\"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on(\"scroll.bs.affix.data-api\",a.proxy(this.checkPosition,this)).on(\"click.bs.affix.data-api\",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION=\"3.3.5\",c.RESET=\"affix affix-top affix-bottom\",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&\"top\"==this.affixed)return c>e?\"top\":!1;if(\"bottom\"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:\"bottom\":a-d>=e+g?!1:\"bottom\";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?\"top\":null!=d&&i+j>=a-d?\"bottom\":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass(\"affix\");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(\":visible\")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());\"object\"!=typeof d&&(f=e=d),\"function\"==typeof e&&(e=d.top(this.$element)),\"function\"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css(\"top\",\"\");var i=\"affix\"+(h?\"-\"+h:\"\"),j=a.Event(i+\".bs.affix\");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin=\"bottom\"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace(\"affix\",\"affixed\")+\".bs.affix\")}\"bottom\"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on(\"load\",function(){a('[data-spy=\"affix\"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);PK\x07\x08^\xbfIn\xd0\x8f\x00\x00\xd0\x8f\x00\x00PK\x03\x04\x14\x00\x08\x00\x00\x00\xd15\xf5F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00js/vendor/jquery-2.1.4.min.js/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m=\"2.1.4\",n=function(a,b){return new n.fn.init(a,b)},o=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,p=/^-ms-/,q=/-([\\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:\"\",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:\"jQuery\"+(m+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return\"object\"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,\"isPrototypeOf\")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?h[i.call(a)]||\"object\":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf(\"use strict\")?(b=l.createElement(\"script\"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,\"ms-\").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(o,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,\"string\"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return\"string\"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"),function(a,b){h[\"[object \"+b+\"]\"]=b.toLowerCase()});function s(a){var b=\"length\"in a&&a.length,c=n.type(a);return\"function\"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",L=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",M=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",N=M.replace(\"w\",\"w#\"),O=\"\\\\[\"+L+\"*(\"+M+\")(?:\"+L+\"*([*^$|!~]?=)\"+L+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+N+\"))|)\"+L+\"*\\\\]\",P=\":(\"+M+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+O+\")*)|.*)\\\\)|)\",Q=new RegExp(L+\"+\",\"g\"),R=new RegExp(\"^\"+L+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+L+\"+$\",\"g\"),S=new RegExp(\"^\"+L+\"*,\"+L+\"*\"),T=new RegExp(\"^\"+L+\"*([>+~]|\"+L+\")\"+L+\"*\"),U=new RegExp(\"=\"+L+\"*([^\\\\]'\\\"]*?)\"+L+\"*\\\\]\",\"g\"),V=new RegExp(P),W=new RegExp(\"^\"+N+\"$\"),X={ID:new RegExp(\"^#(\"+M+\")\"),CLASS:new RegExp(\"^\\\\.(\"+M+\")\"),TAG:new RegExp(\"^(\"+M.replace(\"w\",\"w*\")+\")\"),ATTR:new RegExp(\"^\"+O),PSEUDO:new RegExp(\"^\"+P),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+L+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+L+\"*(?:([+-]|)\"+L+\"*(\\\\d+)|))\"+L+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+K+\")$\",\"i\"),needsContext:new RegExp(\"^\"+L+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+L+\"*((?:-\\\\d)?\\\\d*)\"+L+\"*\\\\)|)(?=[^-]|$)\",\"i\")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\\d$/i,$=/^[^{]+\\{\\s*\\[native \\w/,_=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,aa=/[+~]/,ba=/'|\\\\/g,ca=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+L+\"?|(\"+L+\")|.)\",\"ig\"),da=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,\"string\"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&\"object\"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute(\"id\"))?s=r.replace(ba,\"\\\\$&\"):b.setAttribute(\"id\",s),s=\"[id='\"+s+\"'] \",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(\",\")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute(\"id\")}}}return i(a.replace(R,\"$1\"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement(\"div\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split(\"|\"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&\"undefined\"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\"HTML\"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener(\"unload\",ea,!1):e.attachEvent&&e.attachEvent(\"onunload\",ea)),p=!f(g),c.attributes=ja(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(\"undefined\"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c=\"undefined\"!=typeof a.getAttributeNode&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return\"undefined\"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML=\"\",a.querySelectorAll(\"[msallowcapture^='']\").length&&q.push(\"[*^$]=\"+L+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+L+\"*(?:value|\"+K+\")\"),a.querySelectorAll(\"[id~=\"+u+\"-]\").length||q.push(\"~=\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\"),a.querySelectorAll(\"a#\"+u+\"+*\").length||q.push(\".#.+[+~]\")}),ja(function(a){var b=g.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+L+\"*[*^$|!~]?=\"),a.querySelectorAll(\":enabled\").length||q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,\"div\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",P)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,\"='$1']\"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||\"\").replace(ca,da),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+L+\")\"+a+\"(\"+L+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||\"undefined\"!=typeof a.getAttribute&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?\"!=\"===b:b?(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e.replace(Q,\" \")+\" \").indexOf(c)>-1:\"|=\"===b?e===c||e.slice(0,c.length+1)===c+\"-\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,\"$1\"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||\"\")||ga.error(\"unsupported lang: \"+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&\"parentNode\"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(R,\"$1\"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q=\"0\",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG(\"*\",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement(\"div\"))}),ja(function(a){return a.innerHTML=\"\",\"#\"===a.firstChild.getAttribute(\"href\")})||ka(\"type|href|height|width\",function(a,b,c){return c?void 0:a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML=\"\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||ka(\"value\",function(a,b,c){return c||\"input\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute(\"disabled\")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[\":\"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,w=/^.[^:#\\[\\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if(\"string\"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+\" \"+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,\"string\"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if(\"string\"==typeof a){if(c=\"<\"===a[0]&&\">\"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?\"undefined\"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||\"string\"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?\"string\"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,\"parentNode\")},parentsUntil:function(a,b,c){return n.dir(a,\"parentNode\",c)},next:function(a){return D(a,\"nextSibling\")},prev:function(a){return D(a,\"previousSibling\")},nextAll:function(a){return n.dir(a,\"nextSibling\")},prevAll:function(a){return n.dir(a,\"previousSibling\")},nextUntil:function(a,b,c){return n.dir(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return n.dir(a,\"previousSibling\",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a=\"string\"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);\"function\"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&\"string\"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[[\"resolve\",\"done\",n.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",n.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",n.Callbacks(\"memory\")]],c=\"pending\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+\"With\"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\"With\"](this===e?d:this,arguments),this},e[f[0]+\"With\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler(\"ready\"),n(l).off(\"ready\"))))}});function I(){l.removeEventListener(\"DOMContentLoaded\",I,!1),a.removeEventListener(\"load\",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),\"complete\"===l.readyState?setTimeout(n.ready):(l.addEventListener(\"DOMContentLoaded\",I,!1),a.addEventListener(\"load\",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if(\"string\"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&\"string\"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d=\"data-\"+b.replace(O,\"-$1\").toLowerCase(),c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c?!0:\"false\"===c?!1:\"null\"===c?null:+c+\"\"===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){\nreturn M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,\"hasDataAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,\"hasDataAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf(\"-\")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||\"fx\")+\"queue\",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\"fx\";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks(\"once memory\").add(function(){L.remove(a,[b+\"queue\",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.lengthx\",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U=\"undefined\";k.focusinBubbles=\"onfocusin\"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||\"\").match(E)||[\"\"],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(\".\")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||\"\").match(E)||[\"\"],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+p.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&(\"**\"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,\"events\"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,\"type\")?b.type:b,r=j.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(\".\")>=0&&(r=q.split(\".\"),q=r.shift(),r.sort()),k=q.indexOf(\":\")<0&&\"on\"+q,b=b[n.expando]?b:new n.Event(q,\"object\"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join(\".\"),b.namespace_re=b.namespace?new RegExp(\"(^|\\\\.)\"+r.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,\"events\")||{})[b.type]&&L.get(g,\"handle\"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,\"events\")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||\"click\"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||\"click\"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\\/>/gi,ba=/<([\\w:]+)/,ca=/<|&#?\\w+;/,da=/<(?:script|style|link)/i,ea=/checked\\s*(?:[^=]|=\\s*.checked.)/i,fa=/^$|\\/(?:java|ecma)script/i,ga=/^true\\/(.*)/,ha=/^\\s*\\s*$/g,ia={option:[1,\"\"],thead:[1,\"\",\"
    \"],col:[2,\"\",\"
    \"],tr:[2,\"\",\"
    \"],td:[3,\"\",\"
    \"],_default:[0,\"\",\"\"]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,\"table\")&&n.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a.appendChild(a.ownerDocument.createElement(\"tbody\")):a}function ka(a){return a.type=(null!==a.getAttribute(\"type\"))+\"/\"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],\"globalEval\",!b||L.get(b[c],\"globalEval\"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):a.querySelectorAll?a.querySelectorAll(b||\"*\"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();\"input\"===c&&T.test(a.type)?b.checked=a.checked:(\"input\"===c||\"textarea\"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,\"script\"),g.length>0&&ma(g,!i&&oa(a,\"script\")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if(\"object\"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement(\"div\")),g=(ba.exec(e)||[\"\",\"\"])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,\"<$1>\")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=\"\"}else l.push(b.createTextNode(e));k.textContent=\"\",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),\"script\"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||\"\")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,\"script\")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent=\"\");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if(\"string\"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=a.replace(aa,\"<$1>\");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&\"string\"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,\"script\"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,\"script\"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||\"\")&&!L.access(h,\"globalEval\")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,\"\")))}return this}}),n.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],\"display\");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),\"none\"!==c&&c||(qa=(qa||n(\"